Polygon Sponsored slots available. Book your slot here!
ERC-20
Overview
Max Total Supply
0 ERC-20: GHMarket
Holders
0
Total Transfers
-
Market
Price
$0.00 @ 0.000000 POL
Onchain Market Cap
$0.00
Circulating Supply Market Cap
-
Other Info
Token Contract (WITH 0 Decimals)
Loading...
Loading
Loading...
Loading
Loading...
Loading
Contract Name:
GHMarketplace
Compiler Version
v0.8.17+commit.8df45f5f
Contract Source Code (Solidity)
/** *Submitted for verification at polygonscan.com on 2022-11-25 */ // 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: @openzeppelin/contracts/security/ReentrancyGuard.sol // OpenZeppelin Contracts (last updated v4.8.0) (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be _NOT_ENTERED require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } } // 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/Context.sol // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } } // File: @openzeppelin/contracts/access/Ownable.sol // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) pragma solidity ^0.8.0; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } } // File: @openzeppelin/contracts/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/token/ERC721/utils/ERC721Holder.sol // OpenZeppelin Contracts v4.4.1 (token/ERC721/utils/ERC721Holder.sol) pragma solidity ^0.8.0; /** * @dev Implementation of the {IERC721Receiver} interface. * * Accepts all token transfers. * Make sure the contract is able to use its token with {IERC721-safeTransferFrom}, {IERC721-approve} or {IERC721-setApprovalForAll}. */ contract ERC721Holder is IERC721Receiver { /** * @dev See {IERC721Receiver-onERC721Received}. * * Always returns `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received( address, address, uint256, bytes memory ) public virtual override returns (bytes4) { return this.onERC721Received.selector; } } // File: @openzeppelin/contracts/utils/introspection/IERC165.sol // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } // File: @openzeppelin/contracts/utils/introspection/ERC165.sol // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } } // File: @openzeppelin/contracts/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/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/ERC721.sol // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/ERC721.sol) pragma solidity ^0.8.0; /** * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including * the Metadata extension, but not including the Enumerable extension, which is available separately as * {ERC721Enumerable}. */ contract ERC721 is Context, ERC165, IERC721, IERC721Metadata { using Address for address; using Strings for uint256; // Token name string private _name; // Token symbol string private _symbol; // Mapping from token ID to owner address mapping(uint256 => address) private _owners; // Mapping owner address to token count mapping(address => uint256) private _balances; // Mapping from token ID to approved address mapping(uint256 => address) private _tokenApprovals; // Mapping from owner to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; /** * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { return interfaceId == type(IERC721).interfaceId || interfaceId == type(IERC721Metadata).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721-balanceOf}. */ function balanceOf(address owner) public view virtual override returns (uint256) { require(owner != address(0), "ERC721: address zero is not a valid owner"); return _balances[owner]; } /** * @dev See {IERC721-ownerOf}. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { address owner = _ownerOf(tokenId); require(owner != address(0), "ERC721: invalid token ID"); return owner; } /** * @dev See {IERC721Metadata-name}. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev See {IERC721Metadata-symbol}. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { _requireMinted(tokenId); string memory baseURI = _baseURI(); return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : ""; } /** * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each * token will be the concatenation of the `baseURI` and the `tokenId`. Empty * by default, can be overridden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ""; } /** * @dev See {IERC721-approve}. */ function approve(address to, uint256 tokenId) public virtual override { address owner = ERC721.ownerOf(tokenId); require(to != owner, "ERC721: approval to current owner"); require( _msgSender() == owner || isApprovedForAll(owner, _msgSender()), "ERC721: approve caller is not token owner or approved for all" ); _approve(to, tokenId); } /** * @dev See {IERC721-getApproved}. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { _requireMinted(tokenId); return _tokenApprovals[tokenId]; } /** * @dev See {IERC721-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual override { _setApprovalForAll(_msgSender(), operator, approved); } /** * @dev See {IERC721-isApprovedForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev See {IERC721-transferFrom}. */ function transferFrom( address from, address to, uint256 tokenId ) public virtual override { //solhint-disable-next-line max-line-length require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved"); _transfer(from, to, tokenId); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 tokenId ) public virtual override { safeTransferFrom(from, to, tokenId, ""); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes memory data ) public virtual override { require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved"); _safeTransfer(from, to, tokenId, data); } /** * @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. * * `data` is additional data, it has no specified format and it is sent in call to `to`. * * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g. * implement alternative mechanisms to perform token transfer, such as signature-based. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeTransfer( address from, address to, uint256 tokenId, bytes memory data ) internal virtual { _transfer(from, to, tokenId); require(_checkOnERC721Received(from, to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer"); } /** * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist */ function _ownerOf(uint256 tokenId) internal view virtual returns (address) { return _owners[tokenId]; } /** * @dev Returns whether `tokenId` exists. * * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}. * * Tokens start existing when they are minted (`_mint`), * and stop existing when they are burned (`_burn`). */ function _exists(uint256 tokenId) internal view virtual returns (bool) { return _ownerOf(tokenId) != address(0); } /** * @dev Returns whether `spender` is allowed to manage `tokenId`. * * Requirements: * * - `tokenId` must exist. */ function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) { address owner = ERC721.ownerOf(tokenId); return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender); } /** * @dev Safely mints `tokenId` and transfers it to `to`. * * Requirements: * * - `tokenId` must not exist. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeMint(address to, uint256 tokenId) internal virtual { _safeMint(to, tokenId, ""); } /** * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. */ function _safeMint( address to, uint256 tokenId, bytes memory data ) internal virtual { _mint(to, tokenId); require( _checkOnERC721Received(address(0), to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer" ); } /** * @dev Mints `tokenId` and transfers it to `to`. * * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible * * Requirements: * * - `tokenId` must not exist. * - `to` cannot be the zero address. * * Emits a {Transfer} event. */ function _mint(address to, uint256 tokenId) internal virtual { require(to != address(0), "ERC721: mint to the zero address"); require(!_exists(tokenId), "ERC721: token already minted"); _beforeTokenTransfer(address(0), to, tokenId, 1); // Check that tokenId was not minted by `_beforeTokenTransfer` hook require(!_exists(tokenId), "ERC721: token already minted"); unchecked { // Will not overflow unless all 2**256 token ids are minted to the same owner. // Given that tokens are minted one by one, it is impossible in practice that // this ever happens. Might change if we allow batch minting. // The ERC fails to describe this case. _balances[to] += 1; } _owners[tokenId] = to; emit Transfer(address(0), to, tokenId); _afterTokenTransfer(address(0), to, tokenId, 1); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * This is an internal function that does not check if the sender is authorized to operate on the token. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId) internal virtual { address owner = ERC721.ownerOf(tokenId); _beforeTokenTransfer(owner, address(0), tokenId, 1); // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook owner = ERC721.ownerOf(tokenId); // Clear approvals delete _tokenApprovals[tokenId]; unchecked { // Cannot overflow, as that would require more tokens to be burned/transferred // out than the owner initially received through minting and transferring in. _balances[owner] -= 1; } delete _owners[tokenId]; emit Transfer(owner, address(0), tokenId); _afterTokenTransfer(owner, address(0), tokenId, 1); } /** * @dev Transfers `tokenId` from `from` to `to`. * As opposed to {transferFrom}, this imposes no restrictions on msg.sender. * * Requirements: * * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * * Emits a {Transfer} event. */ function _transfer( address from, address to, uint256 tokenId ) internal virtual { require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner"); require(to != address(0), "ERC721: transfer to the zero address"); _beforeTokenTransfer(from, to, tokenId, 1); // Check that tokenId was not transferred by `_beforeTokenTransfer` hook require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner"); // Clear approvals from the previous owner delete _tokenApprovals[tokenId]; unchecked { // `_balances[from]` cannot overflow for the same reason as described in `_burn`: // `from`'s balance is the number of token held, which is at least one before the current // transfer. // `_balances[to]` could overflow in the conditions described in `_mint`. That would require // all 2**256 token ids to be minted, which in practice is impossible. _balances[from] -= 1; _balances[to] += 1; } _owners[tokenId] = to; emit Transfer(from, to, tokenId); _afterTokenTransfer(from, to, tokenId, 1); } /** * @dev Approve `to` to operate on `tokenId` * * Emits an {Approval} event. */ function _approve(address to, uint256 tokenId) internal virtual { _tokenApprovals[tokenId] = to; emit Approval(ERC721.ownerOf(tokenId), to, tokenId); } /** * @dev Approve `operator` to operate on all of `owner` tokens * * Emits an {ApprovalForAll} event. */ function _setApprovalForAll( address owner, address operator, bool approved ) internal virtual { require(owner != operator, "ERC721: approve to caller"); _operatorApprovals[owner][operator] = approved; emit ApprovalForAll(owner, operator, approved); } /** * @dev Reverts if the `tokenId` has not been minted yet. */ function _requireMinted(uint256 tokenId) internal view virtual { require(_exists(tokenId), "ERC721: invalid token ID"); } /** * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address. * The call is not executed if the target address is not a contract. * * @param from address representing the previous owner of the given token ID * @param to target address that will receive the tokens * @param tokenId uint256 ID of the token to be transferred * @param data bytes optional data to send along with the call * @return bool whether the call correctly returned the expected magic value */ 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.onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert("ERC721: transfer to non ERC721Receiver implementer"); } else { /// @solidity memory-safe-assembly assembly { revert(add(32, reason), mload(reason)) } } } } else { return true; } } /** * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`. * - When `from` is zero, the tokens will be minted for `to`. * - When `to` is zero, ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * - `batchSize` is non-zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256, /* firstTokenId */ uint256 batchSize ) internal virtual { if (batchSize > 1) { if (from != address(0)) { _balances[from] -= batchSize; } if (to != address(0)) { _balances[to] += batchSize; } } } /** * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`. * - When `from` is zero, the tokens were minted for `to`. * - When `to` is zero, ``from``'s tokens were burned. * - `from` and `to` are never both zero. * - `batchSize` is non-zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer( address from, address to, uint256 firstTokenId, uint256 batchSize ) internal virtual {} } // File: @openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); } // File: @openzeppelin/contracts/token/ERC20/IERC20.sol // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); } // File: @openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; function safeTransfer( IERC20 token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom( IERC20 token, address from, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove( IERC20 token, address spender, uint256 value ) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance( IERC20 token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } function safePermit( IERC20Permit token, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { uint256 nonceBefore = token.nonces(owner); token.permit(owner, spender, value, deadline, v, r, s); uint256 nonceAfter = token.nonces(owner); require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } } // File: @openzeppelin/contracts/utils/Counters.sol // OpenZeppelin Contracts v4.4.1 (utils/Counters.sol) pragma solidity ^0.8.0; /** * @title Counters * @author Matt Condon (@shrugs) * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number * of elements in a mapping, issuing ERC721 ids, or counting request ids. * * Include with `using Counters for Counters.Counter;` */ library Counters { struct Counter { // This variable should never be directly accessed by users of the library: interactions must be restricted to // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add // this feature: see https://github.com/ethereum/solidity/issues/4637 uint256 _value; // default: 0 } function current(Counter storage counter) internal view returns (uint256) { return counter._value; } function increment(Counter storage counter) internal { unchecked { counter._value += 1; } } function decrement(Counter storage counter) internal { uint256 value = counter._value; require(value > 0, "Counter: decrement overflow"); unchecked { counter._value = value - 1; } } function reset(Counter storage counter) internal { counter._value = 0; } } // File: Marketplace.sol pragma solidity ^0.8.9; // Marketplace smart contract inherits ERC721 interface contract GHMarketplace is ReentrancyGuard, ERC721Holder, Ownable { using Counters for Counters.Counter; using SafeERC20 for IERC20; using EnumerableSet for EnumerableSet.UintSet; using EnumerableSet for EnumerableSet.AddressSet; EnumerableSet.AddressSet private _admins; EnumerableSet.AddressSet private _devs; uint256 public adminTrandingFee; // admin fee(10 = 1%, 100 = 10%) uint256 public devTrandingFee; // developer fee(10 = 1%, 100 = 10%) struct Item { uint256 price; address seller; uint256 createdAt; } struct Collection { uint256 collectionId; string name; uint256 tradingFee; // trading fee (100 = 1%, 500 = 5%, 5 = 0.05%) } // this contract's token collection name string public name; // this contract's token symbol string public symbol; string private _baseURI; IERC20 private _currency; // token(currency) to trade the items/packs. Counters.Counter private _collectionIds; EnumerableSet.AddressSet private _collectionAddressSet; mapping(string => bool) private _typeExists; string[] private _types; mapping(string => EnumerableSet.UintSet) _tokenIdsOfType; mapping(address => mapping(uint256 => Item)) private _itemDetails; // Item details (price + seller address) for a given collection and a tokenId mapping(address => EnumerableSet.UintSet) private _itemTokenIds; // Set of tokenIds for a collection mapping(address => Collection) private _collections; // Details about the collections mapping(address => mapping(address => EnumerableSet.UintSet)) private _tokenIdsOfSeller; // Item order is cancelled event ItemCancel( address indexed collection, address indexed seller, uint256 indexed tokenId ); // Item order is created event ItemNew( address indexed collection, address indexed seller, uint256 indexed tokenId, uint256 itemPrice ); // Item order is updated event ItemUpdate( address indexed collection, address indexed seller, uint256 indexed tokenId, uint256 itemPrice ); // Collection is closed for trading and new listings event packBurned(uint256 indexed packId); // New collection is added event packNew( string indexed name, address indexed creator, uint256 tradingFee, uint256 creatorFee ); // New collection is added event CollectionNew( address indexed collection, string name, uint256 tradingFee ); // Existing collection is updated event CollectionUpdate( address indexed collection, string name, uint256 tradingFee ); // Pending revenue is claimed event RevenueClaim(address indexed claimer, uint256 amount); // Item order is matched by a trade event Trade( address indexed collection, uint256 indexed tokenId, address indexed seller, address buyer, uint256 itemPrice, uint256 netPrice, bool withBNB ); constructor(address _gotchiAddr, address _packAddr, address currency_, address[] memory admins_, address[] memory devs_) { _currency = IERC20(currency_); name="GHMarket"; addCollection("Gotchi Collection", _gotchiAddr, 1000); addCollection("Pack Collection", _packAddr, 1000); for(uint i=0 ; i<admins_.length ; i++) { _admins.add(admins_[i]); } for(uint i=0 ; i<devs_.length ; i++) { _devs.add(devs_[i]); } //_admins.add(owner()); devTrandingFee = 500; adminTrandingFee = 500; } /** * @notice set ERC-20 token address to mint new NFT * @param currency_ minting token address */ function setCurrency(IERC20 currency_) external onlyOwner { require(currency_ != _currency, "ERROR: The same token already setted."); _currency = IERC20(currency_); } /** * @notice set percent of trading fee for admins and developers * @param _adminFee percent for all admins in whole trading fee * @param _devFee percent for all developers in whole trading fee */ function setTradingFees(uint _adminFee, uint _devFee) external onlyOwner { devTrandingFee = _devFee; adminTrandingFee = _adminFee; } /** * @notice add one account to admin list for getting trading fee * @param _admin account address */ function addAdmin(address _admin) external onlyOwner { _admins.add(_admin); } /** * @notice remove one account in admin list for getting trading fee * @param _admin account address */ function removeAdmin(address _admin) external onlyOwner { _admins.remove(_admin); } /** * @notice add one account to developer list for getting trading fee. * @param _dev account address */ function addDev(address _dev) external onlyOwner { _devs.add(_dev); } /** * @notice remove one address in developer list for trading fee. * @param _dev account address */ function removeDev(address _dev) external onlyOwner { _devs.remove(_dev); } /** * @notice Create item order * @param _collection: contract address of the NFT * @param _tokenId: token Id for sell * @param _itemPrice: token price price for sell * @param _type: token type */ function createItemOrder( address _collection, uint256 _tokenId, uint256 _itemPrice, string calldata _type ) external nonReentrant { // Transfer NFT to this contract IERC721(_collection).safeTransferFrom( address(msg.sender), address(this), _tokenId ); if(!compareStrings(_type, "type-pack")) { if(!_typeExists[_type]) { _types.push(_type); _typeExists[_type] = true; } _tokenIdsOfType[_type].add(_tokenId); } // Adjust the information _tokenIdsOfSeller[msg.sender][_collection].add(_tokenId); _itemDetails[_collection][_tokenId] = Item({ seller: msg.sender, price: _itemPrice, createdAt: block.timestamp }); // Add tokenId to the itemTokenIds set _itemTokenIds[_collection].add(_tokenId); // Emit event emit ItemNew(_collection, msg.sender, _tokenId, _itemPrice); } /** * @notice Cancel existing item order * @param _collection: contract address of the NFT * @param _type: type of the NFT * @param _tokenId: tokenId of the NFT */ function cancelItemOrder( address _collection, string calldata _type, uint256 _tokenId) external nonReentrant { // Verify the sender has listed it require( _tokenIdsOfSeller[msg.sender][_collection].contains( _tokenId ), "Order: Token not listed" ); if(!compareStrings(_type, "type-pack")) { require(_typeExists[_type], "This type does not exists"); _tokenIdsOfType[_type].remove(_tokenId); } // Adjust the information _tokenIdsOfSeller[msg.sender][_collection].remove( _tokenId ); delete _itemDetails[_collection][_tokenId]; // Add tokenId to the itemTokenIds set _itemTokenIds[_collection].remove(_tokenId); // Transfer the NFT back to the user IERC721(_collection).transferFrom( address(this), address(msg.sender), _tokenId ); // Emit event emit ItemCancel(_collection, msg.sender, _tokenId); } /** * @notice Modify existing item order * @param _collection: contract address of the NFT * @param _tokenId: tokenId of the NFT * @param _newPrice: new price for listing (in wei) */ function modifyItemOrder( address _collection, uint256 _tokenId, uint256 _newPrice ) external nonReentrant { Item storage selItem = _itemDetails[_collection][_tokenId]; require(selItem.seller == msg.sender, "Token owner error."); selItem.price = _newPrice; // Emit event emit ItemUpdate(_collection, msg.sender, _tokenId, _newPrice); } /** * @notice Add a new collection * @param _name: collection name * @param _collection: collection address * @param _tradingFee: trading fee (100 = 1%, 500 = 5%, 5 = 0.05%) * @dev Callable by admin */ function addCollection( string memory _name, address _collection, uint256 _tradingFee ) public onlyOwner { require( !_collectionAddressSet.remove(_collection), "Operations: Collection already listed" ); require( IERC721(_collection).supportsInterface(0x80ac58cd), "Operations: Not ERC721" ); _collectionAddressSet.add(_collection); uint256 _collectionId = _collectionIds.current(); _collections[_collection] = Collection({ collectionId: _collectionId, name : _name, tradingFee: _tradingFee }); _collectionIds.increment(); emit CollectionNew(_collection, _name, _tradingFee); } /** * @notice Modify collection characteristics * @param _id: collection id * @param _collection: collection address * @param _name: collection name * @param _tradingFee: trading fee (100 = 1%, 500 = 5%, 5 = 0.05%) * @dev Callable by admin */ function modifyCollection( uint256 _id, address _collection, string calldata _name, uint256 _tradingFee ) external onlyOwner { require( _collectionAddressSet.contains(_collection), "Operations: Collection not listed" ); address originalAddr = _collectionAddressSet.at(_id); Collection memory originalCollection = _collections[originalAddr]; _collections[_collection] = Collection({ collectionId : originalCollection.collectionId, name: _name, tradingFee: _tradingFee }); emit CollectionUpdate( _collection, _name, _tradingFee ); } /** * @notice Buy token with WBNB by matching the price of an existing item order * @param _collection: contract address of the NFT * @param _tokenId: tokenId of the NFT purchased * @param _price: price (must be equal to the itemPrice set by the seller) * @param _type: type */ function buyToken( address _collection, uint256 _tokenId, uint256 _price, string calldata _type ) external nonReentrant { require( _itemTokenIds[_collection].contains(_tokenId), "Buy: Not for sale" ); Item memory itemOrder = _itemDetails[_collection][_tokenId]; // Front-running protection require(_price == itemOrder.price, "Buy: Incorrect price"); require(msg.sender != itemOrder.seller, "Buy: Buyer cannot be seller"); if(!compareStrings(_type, "type-pack")) { if(_typeExists[_type]) { _tokenIdsOfType[_type].remove(_tokenId); } } // Calculate the net price (collected by seller), trading fee (collected by treasury), creator fee (collected by creator) ( uint256 netPrice, uint256 tradingFee ) = _calculatePriceAndFees(_collection, _price); if(tradingFee > 0) { uint256 devReward = tradingFee * devTrandingFee / 1000 / _devs.length(); uint256 adminReward = tradingFee * adminTrandingFee / 1000 / _admins.length(); for(uint i=0 ; i<_admins.length(); i++) { _currency.safeTransferFrom(msg.sender, _admins.at(i), adminReward); } for(uint i=0 ; i<_devs.length(); i++) { _currency.safeTransferFrom(msg.sender, _devs.at(i), devReward); } } _currency.safeTransferFrom(msg.sender, itemOrder.seller, netPrice); _tokenIdsOfSeller[itemOrder.seller][_collection].remove( _tokenId ); _itemTokenIds[_collection].remove(_tokenId); delete _itemDetails[_collection][_tokenId]; // Transfer NFT to buyer IERC721(_collection).safeTransferFrom( address(this), address(msg.sender), _tokenId ); // Emit event emit Trade( _collection, _tokenId, itemOrder.seller, msg.sender, _price, netPrice, false ); } /** * @notice Set token base URI for hosting domain. * @param _URI hosting domain */ function setBaseURI(string calldata _URI) external onlyOwner { _baseURI = _URI; } /** * @notice Calculate price and associated fees for a collection * @param _collection: address of the collection * @param _itemPrice: listed price */ function _calculatePriceAndFees( address _collection, uint256 _itemPrice ) internal view returns ( uint256 netPrice, uint256 tradingFee ) { tradingFee = (_itemPrice * _collections[_collection].tradingFee) / 10000; netPrice = _itemPrice - tradingFee; return (netPrice, tradingFee); } function viewItemsByType(string calldata _type) external view returns(uint256[] memory, string[] memory, Item[] memory) { uint256 itemCount = _tokenIdsOfType[_type].length(); Item[] memory items_ = new Item[](itemCount); uint256[] memory ids_ = new uint256[](itemCount); string[] memory URIs_ = new string[](itemCount); for(uint256 i=0 ; i<itemCount ; i++) { items_[i] = _itemDetails[_collectionAddressSet.at(0)][_tokenIdsOfType[_type].at(i)]; URIs_[i] = IERC721Metadata(_collectionAddressSet.at(0)).tokenURI(_tokenIdsOfType[_type].at(i)); ids_[i] = _tokenIdsOfType[_type].at(i); } return (ids_, URIs_, items_); } /** * @notice Check items for an array of tokenIds in a collection * @param collection: address of the collection * @param tokenIds: array of tokenId */ function viewItemsByCollectionAndTokenIds( address collection, uint256[] calldata tokenIds ) external view returns (bool[] memory statuses, Item[] memory itemInfo) { uint256 length = tokenIds.length; statuses = new bool[](length); itemInfo = new Item[](length); for (uint256 i = 0; i < length; i++) { if (_itemTokenIds[collection].contains(tokenIds[i])) { statuses[i] = true; } else { statuses[i] = false; } itemInfo[i] = _itemDetails[collection][tokenIds[i]]; } return (statuses, itemInfo); } /** * @notice return order item detail * @param _collection collection address * @param _tokenId token id */ function viewItemByCollectionAndTokenId( address _collection, uint256 _tokenId ) external view returns(bool status, Item memory itemInfo){ if (_itemTokenIds[_collection].contains(_tokenId)) { status = true; } else { status = false; } itemInfo = _itemDetails[_collection][_tokenId]; } /** * @notice View item orders for a given collection across all sellers * @param collection: address of the collection */ function viewItemsByCollection( address collection ) external view returns ( uint256[] memory tokenIds, string[] memory tokenURIs, Item[] memory itemInfo ) { uint256 length = _itemTokenIds[collection].length(); tokenIds = new uint256[](length); itemInfo = new Item[](length); tokenURIs = new string[](length); for (uint256 i = 0; i < length; i++) { tokenIds[i] = _itemTokenIds[collection].at(i); itemInfo[i] = _itemDetails[collection][tokenIds[i]]; tokenURIs[i] = IERC721Metadata(collection).tokenURI(tokenIds[i]); } return (tokenIds, tokenURIs, itemInfo); } /** * @notice View item orders for a given collection and a seller * @param collection: address of the collection * @param seller: address of the seller */ function viewItemsByCollectionAndSeller( address collection, address seller ) external view returns ( uint256[] memory tokenIds, string[] memory tokenURIs, Item[] memory itemInfo ) { uint256 length = _tokenIdsOfSeller[seller][collection].length(); tokenIds = new uint256[](length); tokenURIs = new string[](length); itemInfo = new Item[](length); for (uint256 i = 0; i < length; i++) { tokenIds[i] = _tokenIdsOfSeller[seller][collection].at( i ); itemInfo[i] = _itemDetails[collection][tokenIds[i]]; tokenURIs[i] = IERC721Metadata(collection).tokenURI(tokenIds[i]); } return (tokenIds, tokenURIs, itemInfo); } // return all collections function viewCollections() external view returns ( address[] memory collectionAddresses, Collection[] memory collectionDetails ) { uint256 length = _collectionAddressSet.length(); collectionAddresses = new address[](length); collectionDetails = new Collection[](length); for (uint256 i = 0; i < length; i++) { collectionAddresses[i] = _collectionAddressSet.at( i); collectionDetails[i] = _collections[collectionAddresses[i]]; } return (collectionAddresses, collectionDetails); } function admins() external view returns(address[] memory ) { address[] memory admins_ = new address[](_admins.length()); for(uint i=0 ; i<_admins.length() ; i++) { admins_[i] = _admins.at(i); } return admins_; } function devs() external view returns(address[] memory) { address[] memory devs_ = new address[](_devs.length()); for(uint i=0 ; i<_devs.length() ; i++) { devs_[i] = _devs.at(i); } return devs_; } function compareStrings(string memory a, string memory b) public pure returns (bool) { return (keccak256(abi.encodePacked((a))) == keccak256(abi.encodePacked((b)))); } function types() external view returns(string[] memory) { return _types; } function baseURI() external view returns(string memory) { return _baseURI; } function token() external view returns(address) { return address(_currency); } function destroy(address apocalypse) public onlyOwner{ selfdestruct(payable(apocalypse)); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_gotchiAddr","type":"address"},{"internalType":"address","name":"_packAddr","type":"address"},{"internalType":"address","name":"currency_","type":"address"},{"internalType":"address[]","name":"admins_","type":"address[]"},{"internalType":"address[]","name":"devs_","type":"address[]"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"collection","type":"address"},{"indexed":false,"internalType":"string","name":"name","type":"string"},{"indexed":false,"internalType":"uint256","name":"tradingFee","type":"uint256"}],"name":"CollectionNew","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"collection","type":"address"},{"indexed":false,"internalType":"string","name":"name","type":"string"},{"indexed":false,"internalType":"uint256","name":"tradingFee","type":"uint256"}],"name":"CollectionUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"collection","type":"address"},{"indexed":true,"internalType":"address","name":"seller","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ItemCancel","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"collection","type":"address"},{"indexed":true,"internalType":"address","name":"seller","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"itemPrice","type":"uint256"}],"name":"ItemNew","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"collection","type":"address"},{"indexed":true,"internalType":"address","name":"seller","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"itemPrice","type":"uint256"}],"name":"ItemUpdate","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":"claimer","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"RevenueClaim","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"collection","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"seller","type":"address"},{"indexed":false,"internalType":"address","name":"buyer","type":"address"},{"indexed":false,"internalType":"uint256","name":"itemPrice","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"netPrice","type":"uint256"},{"indexed":false,"internalType":"bool","name":"withBNB","type":"bool"}],"name":"Trade","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"packId","type":"uint256"}],"name":"packBurned","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"string","name":"name","type":"string"},{"indexed":true,"internalType":"address","name":"creator","type":"address"},{"indexed":false,"internalType":"uint256","name":"tradingFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"creatorFee","type":"uint256"}],"name":"packNew","type":"event"},{"inputs":[{"internalType":"address","name":"_admin","type":"address"}],"name":"addAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"address","name":"_collection","type":"address"},{"internalType":"uint256","name":"_tradingFee","type":"uint256"}],"name":"addCollection","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_dev","type":"address"}],"name":"addDev","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"adminTrandingFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"admins","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_collection","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_price","type":"uint256"},{"internalType":"string","name":"_type","type":"string"}],"name":"buyToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_collection","type":"address"},{"internalType":"string","name":"_type","type":"string"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"cancelItemOrder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"a","type":"string"},{"internalType":"string","name":"b","type":"string"}],"name":"compareStrings","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"_collection","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_itemPrice","type":"uint256"},{"internalType":"string","name":"_type","type":"string"}],"name":"createItemOrder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"apocalypse","type":"address"}],"name":"destroy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"devTrandingFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"devs","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"},{"internalType":"address","name":"_collection","type":"address"},{"internalType":"string","name":"_name","type":"string"},{"internalType":"uint256","name":"_tradingFee","type":"uint256"}],"name":"modifyCollection","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_collection","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_newPrice","type":"uint256"}],"name":"modifyItemOrder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_admin","type":"address"}],"name":"removeAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_dev","type":"address"}],"name":"removeDev","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_URI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"currency_","type":"address"}],"name":"setCurrency","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_adminFee","type":"uint256"},{"internalType":"uint256","name":"_devFee","type":"uint256"}],"name":"setTradingFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"types","outputs":[{"internalType":"string[]","name":"","type":"string[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"viewCollections","outputs":[{"internalType":"address[]","name":"collectionAddresses","type":"address[]"},{"components":[{"internalType":"uint256","name":"collectionId","type":"uint256"},{"internalType":"string","name":"name","type":"string"},{"internalType":"uint256","name":"tradingFee","type":"uint256"}],"internalType":"struct GHMarketplace.Collection[]","name":"collectionDetails","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_collection","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"viewItemByCollectionAndTokenId","outputs":[{"internalType":"bool","name":"status","type":"bool"},{"components":[{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"address","name":"seller","type":"address"},{"internalType":"uint256","name":"createdAt","type":"uint256"}],"internalType":"struct GHMarketplace.Item","name":"itemInfo","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"collection","type":"address"}],"name":"viewItemsByCollection","outputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"internalType":"string[]","name":"tokenURIs","type":"string[]"},{"components":[{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"address","name":"seller","type":"address"},{"internalType":"uint256","name":"createdAt","type":"uint256"}],"internalType":"struct GHMarketplace.Item[]","name":"itemInfo","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"collection","type":"address"},{"internalType":"address","name":"seller","type":"address"}],"name":"viewItemsByCollectionAndSeller","outputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"internalType":"string[]","name":"tokenURIs","type":"string[]"},{"components":[{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"address","name":"seller","type":"address"},{"internalType":"uint256","name":"createdAt","type":"uint256"}],"internalType":"struct GHMarketplace.Item[]","name":"itemInfo","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"collection","type":"address"},{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"viewItemsByCollectionAndTokenIds","outputs":[{"internalType":"bool[]","name":"statuses","type":"bool[]"},{"components":[{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"address","name":"seller","type":"address"},{"internalType":"uint256","name":"createdAt","type":"uint256"}],"internalType":"struct GHMarketplace.Item[]","name":"itemInfo","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_type","type":"string"}],"name":"viewItemsByType","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"string[]","name":"","type":"string[]"},{"components":[{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"address","name":"seller","type":"address"},{"internalType":"uint256","name":"createdAt","type":"uint256"}],"internalType":"struct GHMarketplace.Item[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60806040523480156200001157600080fd5b506040516200426f3803806200426f833981016040819052620000349162000728565b60016000556200004433620001c6565b600b80546001600160a01b0319166001600160a01b0385161790556040805180820190915260088082526711d213585c9ad95d60c21b6020830152906200008c90826200085a565b5060408051808201909152601181527023b7ba31b4349021b7b63632b1ba34b7b760791b6020820152620000c490866103e862000218565b60408051808201909152600f81526e2830b1b59021b7b63632b1ba34b7b760891b6020820152620000f990856103e862000218565b60005b825181101562000153576200013d8382815181106200011f576200011f62000926565b602002602001015160026200045060201b6200262d1790919060201c565b50806200014a8162000952565b915050620000fc565b5060005b8151811015620001ae57620001988282815181106200017a576200017a62000926565b602002602001015160046200045060201b6200262d1790919060201c565b5080620001a58162000952565b91505062000157565b50506101f460078190556006555062000a1c92505050565b600180546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6200022262000470565b6200023d82600d620004ce60201b620026491790919060201c565b156200029e5760405162461bcd60e51b815260206004820152602560248201527f4f7065726174696f6e733a20436f6c6c656374696f6e20616c7265616479206c6044820152641a5cdd195960da1b60648201526084015b60405180910390fd5b6040516301ffc9a760e01b81526380ac58cd60e01b60048201526001600160a01b038316906301ffc9a790602401602060405180830381865afa158015620002ea573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200031091906200096e565b6200035e5760405162461bcd60e51b815260206004820152601660248201527f4f7065726174696f6e733a204e6f742045524337323100000000000000000000604482015260640162000295565b6200037982600d6200045060201b6200262d1790919060201c565b50600062000393600c620004e560201b6200265e1760201c565b6040805160608101825282815260208082018881528284018790526001600160a01b03881660009081526014909252929020815181559151929350916001820190620003e090826200085a565b506040820151816002015590505062000405600c620004e960201b620026621760201c565b826001600160a01b03167ff6288881352812416d08de8002a5a6c3e3661b6446594b5fc502d7fbb70473aa85846040516200044292919062000999565b60405180910390a250505050565b600062000467836001600160a01b038416620004f2565b90505b92915050565b6001546001600160a01b03163314620004cc5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640162000295565b565b600062000467836001600160a01b03841662000544565b5490565b80546001019055565b60008181526001830160205260408120546200053b575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556200046a565b5060006200046a565b600081815260018301602052604081205480156200063d5760006200056b600183620009f0565b85549091506000906200058190600190620009f0565b9050818114620005ed576000866000018281548110620005a557620005a562000926565b9060005260206000200154905080876000018481548110620005cb57620005cb62000926565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000601576200060162000a06565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506200046a565b60009150506200046a565b80516001600160a01b03811681146200066057600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200068d57600080fd5b815160206001600160401b0380831115620006ac57620006ac62000665565b8260051b604051601f19603f83011681018181108482111715620006d457620006d462000665565b604052938452858101830193838101925087851115620006f357600080fd5b83870191505b848210156200071d576200070d8262000648565b83529183019190830190620006f9565b979650505050505050565b600080600080600060a086880312156200074157600080fd5b6200074c8662000648565b94506200075c6020870162000648565b93506200076c6040870162000648565b60608701519093506001600160401b03808211156200078a57600080fd5b6200079889838a016200067b565b93506080880151915080821115620007af57600080fd5b50620007be888289016200067b565b9150509295509295909350565b600181811c90821680620007e057607f821691505b6020821081036200080157634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200085557600081815260208120601f850160051c81016020861015620008305750805b601f850160051c820191505b8181101562000851578281556001016200083c565b5050505b505050565b81516001600160401b0381111562000876576200087662000665565b6200088e81620008878454620007cb565b8462000807565b602080601f831160018114620008c65760008415620008ad5750858301515b600019600386901b1c1916600185901b17855562000851565b600085815260208120601f198616915b82811015620008f757888601518255948401946001909101908401620008d6565b5085821015620009165787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016200096757620009676200093c565b5060010190565b6000602082840312156200098157600080fd5b815180151581146200099257600080fd5b9392505050565b604081526000835180604084015260005b81811015620009c95760208187018101516060868401015201620009aa565b506000606082850101526060601f19601f8301168401019150508260208301529392505050565b818103818111156200046a576200046a6200093c565b634e487b7160e01b600052603160045260246000fd5b6138438062000a2c6000396000f3fe608060405234801561001057600080fd5b50600436106102055760003560e01c80638da5cb5b1161011a578063a846268d116100ad578063ccbff9791161007c578063ccbff97914610477578063dd5952d51461048c578063f2fde38b1461049f578063fc0c546a146104b2578063fda5ecb1146104c357600080fd5b8063a846268d14610425578063b91d3ace1461042e578063bed34bba14610441578063c4026d7b1461046457600080fd5b806395d89b41116100e957806395d89b41146103e9578063972e5650146103f15780639a96f82914610408578063a5de36191461041d57600080fd5b80638da5cb5b1461037d5780638e038d31146103a2578063920c2e71146103b557806393121f17146103d657600080fd5b80634387e7d61161019d57806367eb08001161016c57806367eb0800146103235780636c0360eb146103395780637048027514610341578063715018a61461035457806375bc66e11461035c57600080fd5b80634387e7d6146102c8578063537f6b07146102ea57806355f804b3146102fd57806360baa6511461031057600080fd5b80631785f53c116101d95780631785f53c1461027c578063279beb4d1461028f5780632f84c391146102a25780634222da47146102b557600080fd5b8062f55d9d1461020a57806306fdde031461021f5780630e6b123f1461023d578063150b7a0214610250575b600080fd5b61021d610218366004612c1c565b6104d6565b005b6102276104ea565b6040516102349190612c89565b60405180910390f35b61021d61024b366004612cdd565b610578565b61026361025e366004612df1565b610a23565b6040516001600160e01b03199091168152602001610234565b61021d61028a366004612c1c565b610a34565b61021d61029d366004612e70565b610a4b565b61021d6102b0366004612c1c565b610c79565b61021d6102c3366004612ed3565b610d0f565b6102db6102d6366004612f08565b610ddb565b60405161023493929190612ff8565b61021d6102f8366004613084565b6110b6565b61021d61030b3660046130dd565b61129f565b61021d61031e366004612cdd565b6112b4565b61032b61154a565b604051610234929190613157565b61022761177c565b61021d61034f366004612c1c565b61180e565b61021d611821565b61036f61036a3660046131e8565b611835565b604051610234929190613214565b6001546001600160a01b03165b6040516001600160a01b039091168152602001610234565b61021d6103b0366004613247565b6118c4565b6103c86103c33660046132a2565b611b5b565b604051610234929190613329565b6102db6103e4366004612c1c565b611d3d565b610227611ffc565b6103fa60075481565b604051908152602001610234565b610410612009565b6040516102349190613378565b6104106120bb565b6103fa60065481565b61021d61043c366004612c1c565b612167565b61045461044f36600461338b565b61217a565b6040519015158152602001610234565b61021d610472366004612c1c565b6121d4565b61047f6121e7565b60405161023491906133ee565b6102db61049a3660046130dd565b6122c0565b61021d6104ad366004612c1c565b6125a4565b600b546001600160a01b031661038a565b61021d6104d1366004613401565b61261d565b6104de61266b565b806001600160a01b0316ff5b600880546104f790613423565b80601f016020809104026020016040519081016040528092919081815260200182805461052390613423565b80156105705780601f1061054557610100808354040283529160200191610570565b820191906000526020600020905b81548152906001019060200180831161055357829003601f168201915b505050505081565b6105806126c5565b6001600160a01b03851660009081526013602052604090206105a2908561271e565b6105e75760405162461bcd60e51b81526020600482015260116024820152704275793a204e6f7420666f722073616c6560781b60448201526064015b60405180910390fd5b6001600160a01b0380861660009081526012602090815260408083208884528252918290208251606081018452815480825260018301549095169281019290925260020154918101919091529084146106795760405162461bcd60e51b81526020600482015260146024820152734275793a20496e636f727265637420707269636560601b60448201526064016105de565b60208101516001600160a01b031633036106d55760405162461bcd60e51b815260206004820152601b60248201527f4275793a2042757965722063616e6e6f742062652073656c6c6572000000000060448201526064016105de565b61073583838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526009815268747970652d7061636b60b81b6020820152915061217a9050565b61079057600f838360405161074b929190613457565b9081526040519081900360200190205460ff16156107905761078e8560118585604051610779929190613457565b90815260405190819003602001902090612736565b505b60008061079d8887612742565b909250905080156108a55760006107b4600461278e565b6103e8600754846107c5919061347d565b6107cf9190613494565b6107d99190613494565b905060006107e7600261278e565b6103e8600654856107f8919061347d565b6108029190613494565b61080c9190613494565b905060005b61081b600261278e565b8110156108575761084533610831600284612798565b600b546001600160a01b03169190856127a4565b8061084f816134b6565b915050610811565b5060005b610865600461278e565b8110156108a15761088f3361087b600484612798565b600b546001600160a01b03169190866127a4565b80610899816134b6565b91505061085b565b5050505b6020830151600b546108c5916001600160a01b03909116903390856127a4565b6020808401516001600160a01b039081166000908152601583526040808220928c1682529190925290206108f99088612736565b506001600160a01b038816600090815260136020526040902061091c9088612736565b506001600160a01b03881660008181526012602090815260408083208b84529091528082208281556001810180546001600160a01b03191690556002019190915551632142170760e11b81526342842e0e9061098090309033908c906004016134cf565b600060405180830381600087803b15801561099a57600080fd5b505af11580156109ae573d6000803e3d6000fd5b50505050602083810151604080513381529283018990528201849052600060608301526001600160a01b039081169189918b16907fdaac0e40b8f01e970d08d4e8ae57ac31a5845fffde104c43f05e19bbec78491e9060800160405180910390a4505050610a1c6001600055565b5050505050565b630a85bd0160e11b5b949350505050565b610a3c61266b565b610a47600282612649565b5050565b610a5361266b565b610a5e600d856127fc565b610ab45760405162461bcd60e51b815260206004820152602160248201527f4f7065726174696f6e733a20436f6c6c656374696f6e206e6f74206c697374656044820152601960fa1b60648201526084016105de565b6000610ac1600d87612798565b9050600060146000836001600160a01b03166001600160a01b0316815260200190815260200160002060405180606001604052908160008201548152602001600182018054610b0f90613423565b80601f0160208091040260200160405190810160405280929190818152602001828054610b3b90613423565b8015610b885780601f10610b5d57610100808354040283529160200191610b88565b820191906000526020600020905b815481529060010190602001808311610b6b57829003601f168201915b50505050508152602001600282015481525050905060405180606001604052808260000151815260200186868080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525093855250505060209182018690526001600160a01b0389168152601482526040902082518155908201516001820190610c1d9082613541565b5060408201518160020155905050856001600160a01b03167f6372fb8b86e63b48ca0eef5ce77bd126d9c90d12f3a4f28891b44b87ccff59a6868686604051610c6893929190613600565b60405180910390a250505050505050565b610c8161266b565b600b546001600160a01b0390811690821603610ced5760405162461bcd60e51b815260206004820152602560248201527f4552524f523a205468652073616d6520746f6b656e20616c72656164792073656044820152643a3a32b21760d91b60648201526084016105de565b600b80546001600160a01b0319166001600160a01b0392909216919091179055565b610d176126c5565b6001600160a01b038084166000908152601260209081526040808320868452909152902060018101549091163314610d865760405162461bcd60e51b81526020600482015260126024820152712a37b5b2b71037bbb732b91032b93937b91760711b60448201526064016105de565b818155604051828152839033906001600160a01b038716907f57de30fdde0901babf4cc7f2ebae9f5ed2caa4b9049fb27b77b02b280240b9609060200160405180910390a450610dd66001600055565b505050565b6001600160a01b03808216600090815260156020908152604080832093861683529290529081206060918291829190610e139061278e565b9050806001600160401b03811115610e2d57610e2d612d46565b604051908082528060200260200182016040528015610e56578160200160208202803683370190505b509350806001600160401b03811115610e7157610e71612d46565b604051908082528060200260200182016040528015610ea457816020015b6060815260200190600190039081610e8f5790505b509250806001600160401b03811115610ebf57610ebf612d46565b604051908082528060200260200182016040528015610ef857816020015b610ee5612bdd565b815260200190600190039081610edd5790505b50915060005b818110156110ad576001600160a01b038087166000908152601560209081526040808320938b16835292905220610f359082612798565b858281518110610f4757610f47613639565b60200260200101818152505060126000886001600160a01b03166001600160a01b031681526020019081526020016000206000868381518110610f8c57610f8c613639565b602090810291909101810151825281810192909252604090810160002081516060810183528154815260018201546001600160a01b03169381019390935260020154908201528351849083908110610fe657610fe6613639565b6020026020010181905250866001600160a01b031663c87b56dd86838151811061101257611012613639565b60200260200101516040518263ffffffff1660e01b815260040161103891815260200190565b600060405180830381865afa158015611055573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261107d919081019061364f565b84828151811061108f5761108f613639565b602002602001018190525080806110a5906134b6565b915050610efe565b50509250925092565b6110be61266b565b6110c9600d83612649565b156111245760405162461bcd60e51b815260206004820152602560248201527f4f7065726174696f6e733a20436f6c6c656374696f6e20616c7265616479206c6044820152641a5cdd195960da1b60648201526084016105de565b6040516301ffc9a760e01b81526380ac58cd60e01b60048201526001600160a01b038316906301ffc9a790602401602060405180830381865afa15801561116f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061119391906136c5565b6111d85760405162461bcd60e51b81526020600482015260166024820152754f7065726174696f6e733a204e6f742045524337323160501b60448201526064016105de565b6111e3600d8361262d565b5060006111ef600c5490565b6040805160608101825282815260208082018881528284018790526001600160a01b0388166000908152601490925292902081518155915192935091600182019061123a9082613541565b5060408201518160020155905050611256600c80546001019055565b826001600160a01b03167ff6288881352812416d08de8002a5a6c3e3661b6446594b5fc502d7fbb70473aa85846040516112919291906136e7565b60405180910390a250505050565b6112a761266b565b600a610dd6828483613709565b6112bc6126c5565b604051632142170760e11b81526001600160a01b038616906342842e0e906112ec903390309089906004016134cf565b600060405180830381600087803b15801561130657600080fd5b505af115801561131a573d6000803e3d6000fd5b5050505061137e82828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526009815268747970652d7061636b60b81b6020820152915061217a9050565b61144b57600f8282604051611394929190613457565b9081526040519081900360200190205460ff1661141e57601080546001810182556000919091527f1b6847dc741a1b0cd08d278845f9d819d87b734759afb55fe2de5cb82a9ae672016113e8828483613709565b506001600f83836040516113fd929190613457565b908152604051908190036020019020805491151560ff199092169190911790555b6114498460118484604051611434929190613457565b9081526040519081900360200190209061281e565b505b3360009081526015602090815260408083206001600160a01b03891684529091529020611478908561281e565b5060408051606081018252848152336020808301918252428385019081526001600160a01b038a81166000818152601285528781208c825285528781209651875594516001870180546001600160a01b031916919093161790915590516002909401939093559181526013909152206114f1908561281e565b5083336001600160a01b0316866001600160a01b03167f3cc87011b90d6f3426d765406c57316ea5e9d82283ae531fb5b3eadab72ffc128660405161153891815260200190565b60405180910390a4610a1c6001600055565b6060806000611559600d61278e565b9050806001600160401b0381111561157357611573612d46565b60405190808252806020026020018201604052801561159c578160200160208202803683370190505b509250806001600160401b038111156115b7576115b7612d46565b60405190808252806020026020018201604052801561160c57816020015b6115f960405180606001604052806000815260200160608152602001600081525090565b8152602001906001900390816115d55790505b50915060005b8181101561177657611625600d82612798565b84828151811061163757611637613639565b60200260200101906001600160a01b031690816001600160a01b0316815250506014600085838151811061166d5761166d613639565b60200260200101516001600160a01b03166001600160a01b03168152602001908152602001600020604051806060016040529081600082015481526020016001820180546116ba90613423565b80601f01602080910402602001604051908101604052809291908181526020018280546116e690613423565b80156117335780601f1061170857610100808354040283529160200191611733565b820191906000526020600020905b81548152906001019060200180831161171657829003601f168201915b5050505050815260200160028201548152505083828151811061175857611758613639565b6020026020010181905250808061176e906134b6565b915050611612565b50509091565b6060600a805461178b90613423565b80601f01602080910402602001604051908101604052809291908181526020018280546117b790613423565b80156118045780601f106117d957610100808354040283529160200191611804565b820191906000526020600020905b8154815290600101906020018083116117e757829003601f168201915b5050505050905090565b61181661266b565b610a4760028261262d565b61182961266b565b611833600061282a565b565b600061183f612bdd565b6001600160a01b0384166000908152601360205260409020611861908461271e565b1561186f5760019150611874565b600091505b506001600160a01b03928316600090815260126020908152604080832094835293815290839020835160608101855281548152600182015490951691850191909152600201549183019190915291565b6118cc6126c5565b3360009081526015602090815260408083206001600160a01b038816845290915290206118f9908261271e565b6119455760405162461bcd60e51b815260206004820152601760248201527f4f726465723a20546f6b656e206e6f74206c697374656400000000000000000060448201526064016105de565b6119a583838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526009815268747970652d7061636b60b81b6020820152915061217a9050565b611a3257600f83836040516119bb929190613457565b9081526040519081900360200190205460ff16611a1a5760405162461bcd60e51b815260206004820152601960248201527f54686973207479706520646f6573206e6f74206578697374730000000000000060448201526064016105de565b611a308160118585604051610779929190613457565b505b3360009081526015602090815260408083206001600160a01b03881684529091529020611a5f9082612736565b506001600160a01b038416600081815260126020908152604080832085845282528083208381556001810180546001600160a01b03191690556002018390559282526013905220611ab09082612736565b506040516323b872dd60e01b81526001600160a01b038516906323b872dd90611ae1903090339086906004016134cf565b600060405180830381600087803b158015611afb57600080fd5b505af1158015611b0f573d6000803e3d6000fd5b50506040518392503391506001600160a01b038716907fafbb223ce72219b6597689a4504d478bc445e0e829cd6f7bf117e49624980fdc90600090a4611b556001600055565b50505050565b60608082806001600160401b03811115611b7757611b77612d46565b604051908082528060200260200182016040528015611ba0578160200160208202803683370190505b509250806001600160401b03811115611bbb57611bbb612d46565b604051908082528060200260200182016040528015611bf457816020015b611be1612bdd565b815260200190600190039081611bd95790505b50915060005b81811015611d3357611c3e868683818110611c1757611c17613639565b6001600160a01b038b1660009081526013602090815260409091209391020135905061271e565b15611c6c576001848281518110611c5757611c57613639565b91151560209283029190910190910152611c91565b6000848281518110611c8057611c80613639565b911515602092830291909101909101525b6001600160a01b038716600090815260126020526040812090878784818110611cbc57611cbc613639565b6020908102929092013583525081810192909252604090810160002081516060810183528154815260018201546001600160a01b03169381019390935260020154908201528351849083908110611d1557611d15613639565b60200260200101819052508080611d2b906134b6565b915050611bfa565b5050935093915050565b6001600160a01b03811660009081526013602052604081206060918291829190611d669061278e565b9050806001600160401b03811115611d8057611d80612d46565b604051908082528060200260200182016040528015611da9578160200160208202803683370190505b509350806001600160401b03811115611dc457611dc4612d46565b604051908082528060200260200182016040528015611dfd57816020015b611dea612bdd565b815260200190600190039081611de25790505b509150806001600160401b03811115611e1857611e18612d46565b604051908082528060200260200182016040528015611e4b57816020015b6060815260200190600190039081611e365790505b50925060005b81811015611ff3576001600160a01b0386166000908152601360205260409020611e7b9082612798565b858281518110611e8d57611e8d613639565b60200260200101818152505060126000876001600160a01b03166001600160a01b031681526020019081526020016000206000868381518110611ed257611ed2613639565b602090810291909101810151825281810192909252604090810160002081516060810183528154815260018201546001600160a01b03169381019390935260020154908201528351849083908110611f2c57611f2c613639565b6020026020010181905250856001600160a01b031663c87b56dd868381518110611f5857611f58613639565b60200260200101516040518263ffffffff1660e01b8152600401611f7e91815260200190565b600060405180830381865afa158015611f9b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611fc3919081019061364f565b848281518110611fd557611fd5613639565b60200260200101819052508080611feb906134b6565b915050611e51565b50509193909250565b600980546104f790613423565b60606000612017600461278e565b6001600160401b0381111561202e5761202e612d46565b604051908082528060200260200182016040528015612057578160200160208202803683370190505b50905060005b612067600461278e565b8110156120b557612079600482612798565b82828151811061208b5761208b613639565b6001600160a01b0390921660209283029190910190910152806120ad816134b6565b91505061205d565b50919050565b606060006120c9600261278e565b6001600160401b038111156120e0576120e0612d46565b604051908082528060200260200182016040528015612109578160200160208202803683370190505b50905060005b612119600261278e565b8110156120b55761212b600282612798565b82828151811061213d5761213d613639565b6001600160a01b03909216602092830291909101909101528061215f816134b6565b91505061210f565b61216f61266b565b610a4760048261262d565b60008160405160200161218d91906137c8565b60405160208183030381529060405280519060200120836040516020016121b491906137c8565b604051602081830303815290604052805190602001201490505b92915050565b6121dc61266b565b610a47600482612649565b60606010805480602002602001604051908101604052809291908181526020016000905b828210156122b757838290600052602060002001805461222a90613423565b80601f016020809104026020016040519081016040528092919081815260200182805461225690613423565b80156122a35780601f10612278576101008083540402835291602001916122a3565b820191906000526020600020905b81548152906001019060200180831161228657829003601f168201915b50505050508152602001906001019061220b565b50505050905090565b606080606060006122ef601187876040516122dc929190613457565b908152602001604051809103902061278e565b90506000816001600160401b0381111561230b5761230b612d46565b60405190808252806020026020018201604052801561234457816020015b612331612bdd565b8152602001906001900390816123295790505b5090506000826001600160401b0381111561236157612361612d46565b60405190808252806020026020018201604052801561238a578160200160208202803683370190505b5090506000836001600160401b038111156123a7576123a7612d46565b6040519080825280602002602001820160405280156123da57816020015b60608152602001906001900390816123c55790505b50905060005b8481101561259457601260006123f7600d82612798565b6001600160a01b03166001600160a01b0316815260200190815260200160002060006124448360118e8e60405161242f929190613457565b90815260405190819003602001902090612798565b8152602080820192909252604090810160002081516060810183528154815260018201546001600160a01b0316938101939093526002015490820152845185908390811061249457612494613639565b60209081029190910101526124ab600d6000612798565b6001600160a01b031663c87b56dd6124cf8360118e8e60405161242f929190613457565b6040518263ffffffff1660e01b81526004016124ed91815260200190565b600060405180830381865afa15801561250a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612532919081019061364f565b82828151811061254457612544613639565b60200260200101819052506125658160118c8c60405161242f929190613457565b83828151811061257757612577613639565b60209081029190910101528061258c816134b6565b9150506123e0565b5090955093509150509250925092565b6125ac61266b565b6001600160a01b0381166126115760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016105de565b61261a8161282a565b50565b61262561266b565b600755600655565b6000612642836001600160a01b03841661287c565b9392505050565b6000612642836001600160a01b0384166128cb565b5490565b80546001019055565b6001546001600160a01b031633146118335760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016105de565b6002600054036127175760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016105de565b6002600055565b60008181526001830160205260408120541515612642565b600061264283836128cb565b6001600160a01b03821660009081526014602052604081206002015481906127109061276e908561347d565b6127789190613494565b905061278481846137e4565b91505b9250929050565b60006121ce825490565b600061264283836129be565b611b55846323b872dd60e01b8585856040516024016127c5939291906134cf565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526129e8565b6001600160a01b03811660009081526001830160205260408120541515612642565b6000612642838361287c565b600180546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60008181526001830160205260408120546128c3575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556121ce565b5060006121ce565b600081815260018301602052604081205480156129b45760006128ef6001836137e4565b8554909150600090612903906001906137e4565b905081811461296857600086600001828154811061292357612923613639565b906000526020600020015490508087600001848154811061294657612946613639565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612979576129796137f7565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506121ce565b60009150506121ce565b60008260000182815481106129d5576129d5613639565b9060005260206000200154905092915050565b6000612a3d826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612aba9092919063ffffffff16565b805190915015610dd65780806020019051810190612a5b91906136c5565b610dd65760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016105de565b6060610a2c848460008585600080866001600160a01b03168587604051612ae191906137c8565b60006040518083038185875af1925050503d8060008114612b1e576040519150601f19603f3d011682016040523d82523d6000602084013e612b23565b606091505b5091509150612b3487838387612b3f565b979650505050505050565b60608315612bae578251600003612ba7576001600160a01b0385163b612ba75760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016105de565b5081610a2c565b610a2c8383815115612bc35781518083602001fd5b8060405162461bcd60e51b81526004016105de9190612c89565b60405180606001604052806000815260200160006001600160a01b03168152602001600081525090565b6001600160a01b038116811461261a57600080fd5b600060208284031215612c2e57600080fd5b813561264281612c07565b60005b83811015612c54578181015183820152602001612c3c565b50506000910152565b60008151808452612c75816020860160208601612c39565b601f01601f19169290920160200192915050565b6020815260006126426020830184612c5d565b60008083601f840112612cae57600080fd5b5081356001600160401b03811115612cc557600080fd5b60208301915083602082850101111561278757600080fd5b600080600080600060808688031215612cf557600080fd5b8535612d0081612c07565b9450602086013593506040860135925060608601356001600160401b03811115612d2957600080fd5b612d3588828901612c9c565b969995985093965092949392505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715612d8457612d84612d46565b604052919050565b60006001600160401b03821115612da557612da5612d46565b50601f01601f191660200190565b6000612dc6612dc184612d8c565b612d5c565b9050828152838383011115612dda57600080fd5b828260208301376000602084830101529392505050565b60008060008060808587031215612e0757600080fd5b8435612e1281612c07565b93506020850135612e2281612c07565b92506040850135915060608501356001600160401b03811115612e4457600080fd5b8501601f81018713612e5557600080fd5b612e6487823560208401612db3565b91505092959194509250565b600080600080600060808688031215612e8857600080fd5b853594506020860135612e9a81612c07565b935060408601356001600160401b03811115612eb557600080fd5b612ec188828901612c9c565b96999598509660600135949350505050565b600080600060608486031215612ee857600080fd5b8335612ef381612c07565b95602085013595506040909401359392505050565b60008060408385031215612f1b57600080fd5b8235612f2681612c07565b91506020830135612f3681612c07565b809150509250929050565b600081518084526020808501808196508360051b8101915082860160005b85811015612f89578284038952612f77848351612c5d565b98850198935090840190600101612f5f565b5091979650505050505050565b600081518084526020808501945080840160005b83811015612fed57612fda878351805182526020808201516001600160a01b031690830152604090810151910152565b6060969096019590820190600101612faa565b509495945050505050565b606080825284519082018190526000906020906080840190828801845b8281101561303157815184529284019290840190600101613015565b505050838103828501526130458187612f41565b915050828103604084015261305a8185612f96565b9695505050505050565b600082601f83011261307557600080fd5b61264283833560208501612db3565b60008060006060848603121561309957600080fd5b83356001600160401b038111156130af57600080fd5b6130bb86828701613064565b93505060208401356130cc81612c07565b929592945050506040919091013590565b600080602083850312156130f057600080fd5b82356001600160401b0381111561310657600080fd5b61311285828601612c9c565b90969095509350505050565b600081518084526020808501945080840160005b83811015612fed5781516001600160a01b031687529582019590820190600101613132565b6000604080835261316a8184018661311e565b6020848203818601528186518084528284019150828160051b85010183890160005b838110156131d857601f1987840301855281516060815185528782015181898701526131ba82870182612c5d565b928b0151958b0195909552509486019492509085019060010161318c565b50909a9950505050505050505050565b600080604083850312156131fb57600080fd5b823561320681612c07565b946020939093013593505050565b8215158152608081016126426020830184805182526020808201516001600160a01b031690830152604090810151910152565b6000806000806060858703121561325d57600080fd5b843561326881612c07565b935060208501356001600160401b0381111561328357600080fd5b61328f87828801612c9c565b9598909750949560400135949350505050565b6000806000604084860312156132b757600080fd5b83356132c281612c07565b925060208401356001600160401b03808211156132de57600080fd5b818601915086601f8301126132f257600080fd5b81358181111561330157600080fd5b8760208260051b850101111561331657600080fd5b6020830194508093505050509250925092565b604080825283519082018190526000906020906060840190828701845b82811015613364578151151584529284019290840190600101613346565b5050508381038285015261305a8186612f96565b602081526000612642602083018461311e565b6000806040838503121561339e57600080fd5b82356001600160401b03808211156133b557600080fd5b6133c186838701613064565b935060208501359150808211156133d757600080fd5b506133e485828601613064565b9150509250929050565b6020815260006126426020830184612f41565b6000806040838503121561341457600080fd5b50508035926020909101359150565b600181811c9082168061343757607f821691505b6020821081036120b557634e487b7160e01b600052602260045260246000fd5b8183823760009101908152919050565b634e487b7160e01b600052601160045260246000fd5b80820281158282048414176121ce576121ce613467565b6000826134b157634e487b7160e01b600052601260045260246000fd5b500490565b6000600182016134c8576134c8613467565b5060010190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b601f821115610dd657600081815260208120601f850160051c8101602086101561351a5750805b601f850160051c820191505b8181101561353957828155600101613526565b505050505050565b81516001600160401b0381111561355a5761355a612d46565b61356e816135688454613423565b846134f3565b602080601f8311600181146135a3576000841561358b5750858301515b600019600386901b1c1916600185901b178555613539565b600085815260208120601f198616915b828110156135d2578886015182559484019460019091019084016135b3565b50858210156135f05787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b604081528260408201528284606083013760006060848301015260006060601f19601f8601168301019050826020830152949350505050565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561366157600080fd5b81516001600160401b0381111561367757600080fd5b8201601f8101841361368857600080fd5b8051613696612dc182612d8c565b8181528560208385010111156136ab57600080fd5b6136bc826020830160208601612c39565b95945050505050565b6000602082840312156136d757600080fd5b8151801515811461264257600080fd5b6040815260006136fa6040830185612c5d565b90508260208301529392505050565b6001600160401b0383111561372057613720612d46565b6137348361372e8354613423565b836134f3565b6000601f84116001811461376857600085156137505750838201355b600019600387901b1c1916600186901b178355610a1c565b600083815260209020601f19861690835b828110156137995786850135825560209485019460019092019101613779565b50868210156137b65760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b600082516137da818460208701612c39565b9190910192915050565b818103818111156121ce576121ce613467565b634e487b7160e01b600052603160045260246000fdfea26469706673582212208aa449f8ab8f895565cc541e541bf512150ee00c885e7a4e9b83ac0bbc68944464736f6c634300081100330000000000000000000000007fb60450e7fad82e60ea7539c60d65397c13f1120000000000000000000000007acef2fc6af68936b79123a5f60ade832656bf78000000000000000000000000385eeac5cb85a38a9a07a70c73e0a3271cfb54a700000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000b99746f5525307d0bd3405d4d09583e81f8ad02000000000000000000000000000000000000000000000000000000000000000010000000000000000000000004b3d55b1d237d45c555876f48e6373c840789e04
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106102055760003560e01c80638da5cb5b1161011a578063a846268d116100ad578063ccbff9791161007c578063ccbff97914610477578063dd5952d51461048c578063f2fde38b1461049f578063fc0c546a146104b2578063fda5ecb1146104c357600080fd5b8063a846268d14610425578063b91d3ace1461042e578063bed34bba14610441578063c4026d7b1461046457600080fd5b806395d89b41116100e957806395d89b41146103e9578063972e5650146103f15780639a96f82914610408578063a5de36191461041d57600080fd5b80638da5cb5b1461037d5780638e038d31146103a2578063920c2e71146103b557806393121f17146103d657600080fd5b80634387e7d61161019d57806367eb08001161016c57806367eb0800146103235780636c0360eb146103395780637048027514610341578063715018a61461035457806375bc66e11461035c57600080fd5b80634387e7d6146102c8578063537f6b07146102ea57806355f804b3146102fd57806360baa6511461031057600080fd5b80631785f53c116101d95780631785f53c1461027c578063279beb4d1461028f5780632f84c391146102a25780634222da47146102b557600080fd5b8062f55d9d1461020a57806306fdde031461021f5780630e6b123f1461023d578063150b7a0214610250575b600080fd5b61021d610218366004612c1c565b6104d6565b005b6102276104ea565b6040516102349190612c89565b60405180910390f35b61021d61024b366004612cdd565b610578565b61026361025e366004612df1565b610a23565b6040516001600160e01b03199091168152602001610234565b61021d61028a366004612c1c565b610a34565b61021d61029d366004612e70565b610a4b565b61021d6102b0366004612c1c565b610c79565b61021d6102c3366004612ed3565b610d0f565b6102db6102d6366004612f08565b610ddb565b60405161023493929190612ff8565b61021d6102f8366004613084565b6110b6565b61021d61030b3660046130dd565b61129f565b61021d61031e366004612cdd565b6112b4565b61032b61154a565b604051610234929190613157565b61022761177c565b61021d61034f366004612c1c565b61180e565b61021d611821565b61036f61036a3660046131e8565b611835565b604051610234929190613214565b6001546001600160a01b03165b6040516001600160a01b039091168152602001610234565b61021d6103b0366004613247565b6118c4565b6103c86103c33660046132a2565b611b5b565b604051610234929190613329565b6102db6103e4366004612c1c565b611d3d565b610227611ffc565b6103fa60075481565b604051908152602001610234565b610410612009565b6040516102349190613378565b6104106120bb565b6103fa60065481565b61021d61043c366004612c1c565b612167565b61045461044f36600461338b565b61217a565b6040519015158152602001610234565b61021d610472366004612c1c565b6121d4565b61047f6121e7565b60405161023491906133ee565b6102db61049a3660046130dd565b6122c0565b61021d6104ad366004612c1c565b6125a4565b600b546001600160a01b031661038a565b61021d6104d1366004613401565b61261d565b6104de61266b565b806001600160a01b0316ff5b600880546104f790613423565b80601f016020809104026020016040519081016040528092919081815260200182805461052390613423565b80156105705780601f1061054557610100808354040283529160200191610570565b820191906000526020600020905b81548152906001019060200180831161055357829003601f168201915b505050505081565b6105806126c5565b6001600160a01b03851660009081526013602052604090206105a2908561271e565b6105e75760405162461bcd60e51b81526020600482015260116024820152704275793a204e6f7420666f722073616c6560781b60448201526064015b60405180910390fd5b6001600160a01b0380861660009081526012602090815260408083208884528252918290208251606081018452815480825260018301549095169281019290925260020154918101919091529084146106795760405162461bcd60e51b81526020600482015260146024820152734275793a20496e636f727265637420707269636560601b60448201526064016105de565b60208101516001600160a01b031633036106d55760405162461bcd60e51b815260206004820152601b60248201527f4275793a2042757965722063616e6e6f742062652073656c6c6572000000000060448201526064016105de565b61073583838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526009815268747970652d7061636b60b81b6020820152915061217a9050565b61079057600f838360405161074b929190613457565b9081526040519081900360200190205460ff16156107905761078e8560118585604051610779929190613457565b90815260405190819003602001902090612736565b505b60008061079d8887612742565b909250905080156108a55760006107b4600461278e565b6103e8600754846107c5919061347d565b6107cf9190613494565b6107d99190613494565b905060006107e7600261278e565b6103e8600654856107f8919061347d565b6108029190613494565b61080c9190613494565b905060005b61081b600261278e565b8110156108575761084533610831600284612798565b600b546001600160a01b03169190856127a4565b8061084f816134b6565b915050610811565b5060005b610865600461278e565b8110156108a15761088f3361087b600484612798565b600b546001600160a01b03169190866127a4565b80610899816134b6565b91505061085b565b5050505b6020830151600b546108c5916001600160a01b03909116903390856127a4565b6020808401516001600160a01b039081166000908152601583526040808220928c1682529190925290206108f99088612736565b506001600160a01b038816600090815260136020526040902061091c9088612736565b506001600160a01b03881660008181526012602090815260408083208b84529091528082208281556001810180546001600160a01b03191690556002019190915551632142170760e11b81526342842e0e9061098090309033908c906004016134cf565b600060405180830381600087803b15801561099a57600080fd5b505af11580156109ae573d6000803e3d6000fd5b50505050602083810151604080513381529283018990528201849052600060608301526001600160a01b039081169189918b16907fdaac0e40b8f01e970d08d4e8ae57ac31a5845fffde104c43f05e19bbec78491e9060800160405180910390a4505050610a1c6001600055565b5050505050565b630a85bd0160e11b5b949350505050565b610a3c61266b565b610a47600282612649565b5050565b610a5361266b565b610a5e600d856127fc565b610ab45760405162461bcd60e51b815260206004820152602160248201527f4f7065726174696f6e733a20436f6c6c656374696f6e206e6f74206c697374656044820152601960fa1b60648201526084016105de565b6000610ac1600d87612798565b9050600060146000836001600160a01b03166001600160a01b0316815260200190815260200160002060405180606001604052908160008201548152602001600182018054610b0f90613423565b80601f0160208091040260200160405190810160405280929190818152602001828054610b3b90613423565b8015610b885780601f10610b5d57610100808354040283529160200191610b88565b820191906000526020600020905b815481529060010190602001808311610b6b57829003601f168201915b50505050508152602001600282015481525050905060405180606001604052808260000151815260200186868080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525093855250505060209182018690526001600160a01b0389168152601482526040902082518155908201516001820190610c1d9082613541565b5060408201518160020155905050856001600160a01b03167f6372fb8b86e63b48ca0eef5ce77bd126d9c90d12f3a4f28891b44b87ccff59a6868686604051610c6893929190613600565b60405180910390a250505050505050565b610c8161266b565b600b546001600160a01b0390811690821603610ced5760405162461bcd60e51b815260206004820152602560248201527f4552524f523a205468652073616d6520746f6b656e20616c72656164792073656044820152643a3a32b21760d91b60648201526084016105de565b600b80546001600160a01b0319166001600160a01b0392909216919091179055565b610d176126c5565b6001600160a01b038084166000908152601260209081526040808320868452909152902060018101549091163314610d865760405162461bcd60e51b81526020600482015260126024820152712a37b5b2b71037bbb732b91032b93937b91760711b60448201526064016105de565b818155604051828152839033906001600160a01b038716907f57de30fdde0901babf4cc7f2ebae9f5ed2caa4b9049fb27b77b02b280240b9609060200160405180910390a450610dd66001600055565b505050565b6001600160a01b03808216600090815260156020908152604080832093861683529290529081206060918291829190610e139061278e565b9050806001600160401b03811115610e2d57610e2d612d46565b604051908082528060200260200182016040528015610e56578160200160208202803683370190505b509350806001600160401b03811115610e7157610e71612d46565b604051908082528060200260200182016040528015610ea457816020015b6060815260200190600190039081610e8f5790505b509250806001600160401b03811115610ebf57610ebf612d46565b604051908082528060200260200182016040528015610ef857816020015b610ee5612bdd565b815260200190600190039081610edd5790505b50915060005b818110156110ad576001600160a01b038087166000908152601560209081526040808320938b16835292905220610f359082612798565b858281518110610f4757610f47613639565b60200260200101818152505060126000886001600160a01b03166001600160a01b031681526020019081526020016000206000868381518110610f8c57610f8c613639565b602090810291909101810151825281810192909252604090810160002081516060810183528154815260018201546001600160a01b03169381019390935260020154908201528351849083908110610fe657610fe6613639565b6020026020010181905250866001600160a01b031663c87b56dd86838151811061101257611012613639565b60200260200101516040518263ffffffff1660e01b815260040161103891815260200190565b600060405180830381865afa158015611055573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261107d919081019061364f565b84828151811061108f5761108f613639565b602002602001018190525080806110a5906134b6565b915050610efe565b50509250925092565b6110be61266b565b6110c9600d83612649565b156111245760405162461bcd60e51b815260206004820152602560248201527f4f7065726174696f6e733a20436f6c6c656374696f6e20616c7265616479206c6044820152641a5cdd195960da1b60648201526084016105de565b6040516301ffc9a760e01b81526380ac58cd60e01b60048201526001600160a01b038316906301ffc9a790602401602060405180830381865afa15801561116f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061119391906136c5565b6111d85760405162461bcd60e51b81526020600482015260166024820152754f7065726174696f6e733a204e6f742045524337323160501b60448201526064016105de565b6111e3600d8361262d565b5060006111ef600c5490565b6040805160608101825282815260208082018881528284018790526001600160a01b0388166000908152601490925292902081518155915192935091600182019061123a9082613541565b5060408201518160020155905050611256600c80546001019055565b826001600160a01b03167ff6288881352812416d08de8002a5a6c3e3661b6446594b5fc502d7fbb70473aa85846040516112919291906136e7565b60405180910390a250505050565b6112a761266b565b600a610dd6828483613709565b6112bc6126c5565b604051632142170760e11b81526001600160a01b038616906342842e0e906112ec903390309089906004016134cf565b600060405180830381600087803b15801561130657600080fd5b505af115801561131a573d6000803e3d6000fd5b5050505061137e82828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526009815268747970652d7061636b60b81b6020820152915061217a9050565b61144b57600f8282604051611394929190613457565b9081526040519081900360200190205460ff1661141e57601080546001810182556000919091527f1b6847dc741a1b0cd08d278845f9d819d87b734759afb55fe2de5cb82a9ae672016113e8828483613709565b506001600f83836040516113fd929190613457565b908152604051908190036020019020805491151560ff199092169190911790555b6114498460118484604051611434929190613457565b9081526040519081900360200190209061281e565b505b3360009081526015602090815260408083206001600160a01b03891684529091529020611478908561281e565b5060408051606081018252848152336020808301918252428385019081526001600160a01b038a81166000818152601285528781208c825285528781209651875594516001870180546001600160a01b031916919093161790915590516002909401939093559181526013909152206114f1908561281e565b5083336001600160a01b0316866001600160a01b03167f3cc87011b90d6f3426d765406c57316ea5e9d82283ae531fb5b3eadab72ffc128660405161153891815260200190565b60405180910390a4610a1c6001600055565b6060806000611559600d61278e565b9050806001600160401b0381111561157357611573612d46565b60405190808252806020026020018201604052801561159c578160200160208202803683370190505b509250806001600160401b038111156115b7576115b7612d46565b60405190808252806020026020018201604052801561160c57816020015b6115f960405180606001604052806000815260200160608152602001600081525090565b8152602001906001900390816115d55790505b50915060005b8181101561177657611625600d82612798565b84828151811061163757611637613639565b60200260200101906001600160a01b031690816001600160a01b0316815250506014600085838151811061166d5761166d613639565b60200260200101516001600160a01b03166001600160a01b03168152602001908152602001600020604051806060016040529081600082015481526020016001820180546116ba90613423565b80601f01602080910402602001604051908101604052809291908181526020018280546116e690613423565b80156117335780601f1061170857610100808354040283529160200191611733565b820191906000526020600020905b81548152906001019060200180831161171657829003601f168201915b5050505050815260200160028201548152505083828151811061175857611758613639565b6020026020010181905250808061176e906134b6565b915050611612565b50509091565b6060600a805461178b90613423565b80601f01602080910402602001604051908101604052809291908181526020018280546117b790613423565b80156118045780601f106117d957610100808354040283529160200191611804565b820191906000526020600020905b8154815290600101906020018083116117e757829003601f168201915b5050505050905090565b61181661266b565b610a4760028261262d565b61182961266b565b611833600061282a565b565b600061183f612bdd565b6001600160a01b0384166000908152601360205260409020611861908461271e565b1561186f5760019150611874565b600091505b506001600160a01b03928316600090815260126020908152604080832094835293815290839020835160608101855281548152600182015490951691850191909152600201549183019190915291565b6118cc6126c5565b3360009081526015602090815260408083206001600160a01b038816845290915290206118f9908261271e565b6119455760405162461bcd60e51b815260206004820152601760248201527f4f726465723a20546f6b656e206e6f74206c697374656400000000000000000060448201526064016105de565b6119a583838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526009815268747970652d7061636b60b81b6020820152915061217a9050565b611a3257600f83836040516119bb929190613457565b9081526040519081900360200190205460ff16611a1a5760405162461bcd60e51b815260206004820152601960248201527f54686973207479706520646f6573206e6f74206578697374730000000000000060448201526064016105de565b611a308160118585604051610779929190613457565b505b3360009081526015602090815260408083206001600160a01b03881684529091529020611a5f9082612736565b506001600160a01b038416600081815260126020908152604080832085845282528083208381556001810180546001600160a01b03191690556002018390559282526013905220611ab09082612736565b506040516323b872dd60e01b81526001600160a01b038516906323b872dd90611ae1903090339086906004016134cf565b600060405180830381600087803b158015611afb57600080fd5b505af1158015611b0f573d6000803e3d6000fd5b50506040518392503391506001600160a01b038716907fafbb223ce72219b6597689a4504d478bc445e0e829cd6f7bf117e49624980fdc90600090a4611b556001600055565b50505050565b60608082806001600160401b03811115611b7757611b77612d46565b604051908082528060200260200182016040528015611ba0578160200160208202803683370190505b509250806001600160401b03811115611bbb57611bbb612d46565b604051908082528060200260200182016040528015611bf457816020015b611be1612bdd565b815260200190600190039081611bd95790505b50915060005b81811015611d3357611c3e868683818110611c1757611c17613639565b6001600160a01b038b1660009081526013602090815260409091209391020135905061271e565b15611c6c576001848281518110611c5757611c57613639565b91151560209283029190910190910152611c91565b6000848281518110611c8057611c80613639565b911515602092830291909101909101525b6001600160a01b038716600090815260126020526040812090878784818110611cbc57611cbc613639565b6020908102929092013583525081810192909252604090810160002081516060810183528154815260018201546001600160a01b03169381019390935260020154908201528351849083908110611d1557611d15613639565b60200260200101819052508080611d2b906134b6565b915050611bfa565b5050935093915050565b6001600160a01b03811660009081526013602052604081206060918291829190611d669061278e565b9050806001600160401b03811115611d8057611d80612d46565b604051908082528060200260200182016040528015611da9578160200160208202803683370190505b509350806001600160401b03811115611dc457611dc4612d46565b604051908082528060200260200182016040528015611dfd57816020015b611dea612bdd565b815260200190600190039081611de25790505b509150806001600160401b03811115611e1857611e18612d46565b604051908082528060200260200182016040528015611e4b57816020015b6060815260200190600190039081611e365790505b50925060005b81811015611ff3576001600160a01b0386166000908152601360205260409020611e7b9082612798565b858281518110611e8d57611e8d613639565b60200260200101818152505060126000876001600160a01b03166001600160a01b031681526020019081526020016000206000868381518110611ed257611ed2613639565b602090810291909101810151825281810192909252604090810160002081516060810183528154815260018201546001600160a01b03169381019390935260020154908201528351849083908110611f2c57611f2c613639565b6020026020010181905250856001600160a01b031663c87b56dd868381518110611f5857611f58613639565b60200260200101516040518263ffffffff1660e01b8152600401611f7e91815260200190565b600060405180830381865afa158015611f9b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611fc3919081019061364f565b848281518110611fd557611fd5613639565b60200260200101819052508080611feb906134b6565b915050611e51565b50509193909250565b600980546104f790613423565b60606000612017600461278e565b6001600160401b0381111561202e5761202e612d46565b604051908082528060200260200182016040528015612057578160200160208202803683370190505b50905060005b612067600461278e565b8110156120b557612079600482612798565b82828151811061208b5761208b613639565b6001600160a01b0390921660209283029190910190910152806120ad816134b6565b91505061205d565b50919050565b606060006120c9600261278e565b6001600160401b038111156120e0576120e0612d46565b604051908082528060200260200182016040528015612109578160200160208202803683370190505b50905060005b612119600261278e565b8110156120b55761212b600282612798565b82828151811061213d5761213d613639565b6001600160a01b03909216602092830291909101909101528061215f816134b6565b91505061210f565b61216f61266b565b610a4760048261262d565b60008160405160200161218d91906137c8565b60405160208183030381529060405280519060200120836040516020016121b491906137c8565b604051602081830303815290604052805190602001201490505b92915050565b6121dc61266b565b610a47600482612649565b60606010805480602002602001604051908101604052809291908181526020016000905b828210156122b757838290600052602060002001805461222a90613423565b80601f016020809104026020016040519081016040528092919081815260200182805461225690613423565b80156122a35780601f10612278576101008083540402835291602001916122a3565b820191906000526020600020905b81548152906001019060200180831161228657829003601f168201915b50505050508152602001906001019061220b565b50505050905090565b606080606060006122ef601187876040516122dc929190613457565b908152602001604051809103902061278e565b90506000816001600160401b0381111561230b5761230b612d46565b60405190808252806020026020018201604052801561234457816020015b612331612bdd565b8152602001906001900390816123295790505b5090506000826001600160401b0381111561236157612361612d46565b60405190808252806020026020018201604052801561238a578160200160208202803683370190505b5090506000836001600160401b038111156123a7576123a7612d46565b6040519080825280602002602001820160405280156123da57816020015b60608152602001906001900390816123c55790505b50905060005b8481101561259457601260006123f7600d82612798565b6001600160a01b03166001600160a01b0316815260200190815260200160002060006124448360118e8e60405161242f929190613457565b90815260405190819003602001902090612798565b8152602080820192909252604090810160002081516060810183528154815260018201546001600160a01b0316938101939093526002015490820152845185908390811061249457612494613639565b60209081029190910101526124ab600d6000612798565b6001600160a01b031663c87b56dd6124cf8360118e8e60405161242f929190613457565b6040518263ffffffff1660e01b81526004016124ed91815260200190565b600060405180830381865afa15801561250a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612532919081019061364f565b82828151811061254457612544613639565b60200260200101819052506125658160118c8c60405161242f929190613457565b83828151811061257757612577613639565b60209081029190910101528061258c816134b6565b9150506123e0565b5090955093509150509250925092565b6125ac61266b565b6001600160a01b0381166126115760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016105de565b61261a8161282a565b50565b61262561266b565b600755600655565b6000612642836001600160a01b03841661287c565b9392505050565b6000612642836001600160a01b0384166128cb565b5490565b80546001019055565b6001546001600160a01b031633146118335760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016105de565b6002600054036127175760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016105de565b6002600055565b60008181526001830160205260408120541515612642565b600061264283836128cb565b6001600160a01b03821660009081526014602052604081206002015481906127109061276e908561347d565b6127789190613494565b905061278481846137e4565b91505b9250929050565b60006121ce825490565b600061264283836129be565b611b55846323b872dd60e01b8585856040516024016127c5939291906134cf565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526129e8565b6001600160a01b03811660009081526001830160205260408120541515612642565b6000612642838361287c565b600180546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60008181526001830160205260408120546128c3575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556121ce565b5060006121ce565b600081815260018301602052604081205480156129b45760006128ef6001836137e4565b8554909150600090612903906001906137e4565b905081811461296857600086600001828154811061292357612923613639565b906000526020600020015490508087600001848154811061294657612946613639565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612979576129796137f7565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506121ce565b60009150506121ce565b60008260000182815481106129d5576129d5613639565b9060005260206000200154905092915050565b6000612a3d826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612aba9092919063ffffffff16565b805190915015610dd65780806020019051810190612a5b91906136c5565b610dd65760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016105de565b6060610a2c848460008585600080866001600160a01b03168587604051612ae191906137c8565b60006040518083038185875af1925050503d8060008114612b1e576040519150601f19603f3d011682016040523d82523d6000602084013e612b23565b606091505b5091509150612b3487838387612b3f565b979650505050505050565b60608315612bae578251600003612ba7576001600160a01b0385163b612ba75760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016105de565b5081610a2c565b610a2c8383815115612bc35781518083602001fd5b8060405162461bcd60e51b81526004016105de9190612c89565b60405180606001604052806000815260200160006001600160a01b03168152602001600081525090565b6001600160a01b038116811461261a57600080fd5b600060208284031215612c2e57600080fd5b813561264281612c07565b60005b83811015612c54578181015183820152602001612c3c565b50506000910152565b60008151808452612c75816020860160208601612c39565b601f01601f19169290920160200192915050565b6020815260006126426020830184612c5d565b60008083601f840112612cae57600080fd5b5081356001600160401b03811115612cc557600080fd5b60208301915083602082850101111561278757600080fd5b600080600080600060808688031215612cf557600080fd5b8535612d0081612c07565b9450602086013593506040860135925060608601356001600160401b03811115612d2957600080fd5b612d3588828901612c9c565b969995985093965092949392505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715612d8457612d84612d46565b604052919050565b60006001600160401b03821115612da557612da5612d46565b50601f01601f191660200190565b6000612dc6612dc184612d8c565b612d5c565b9050828152838383011115612dda57600080fd5b828260208301376000602084830101529392505050565b60008060008060808587031215612e0757600080fd5b8435612e1281612c07565b93506020850135612e2281612c07565b92506040850135915060608501356001600160401b03811115612e4457600080fd5b8501601f81018713612e5557600080fd5b612e6487823560208401612db3565b91505092959194509250565b600080600080600060808688031215612e8857600080fd5b853594506020860135612e9a81612c07565b935060408601356001600160401b03811115612eb557600080fd5b612ec188828901612c9c565b96999598509660600135949350505050565b600080600060608486031215612ee857600080fd5b8335612ef381612c07565b95602085013595506040909401359392505050565b60008060408385031215612f1b57600080fd5b8235612f2681612c07565b91506020830135612f3681612c07565b809150509250929050565b600081518084526020808501808196508360051b8101915082860160005b85811015612f89578284038952612f77848351612c5d565b98850198935090840190600101612f5f565b5091979650505050505050565b600081518084526020808501945080840160005b83811015612fed57612fda878351805182526020808201516001600160a01b031690830152604090810151910152565b6060969096019590820190600101612faa565b509495945050505050565b606080825284519082018190526000906020906080840190828801845b8281101561303157815184529284019290840190600101613015565b505050838103828501526130458187612f41565b915050828103604084015261305a8185612f96565b9695505050505050565b600082601f83011261307557600080fd5b61264283833560208501612db3565b60008060006060848603121561309957600080fd5b83356001600160401b038111156130af57600080fd5b6130bb86828701613064565b93505060208401356130cc81612c07565b929592945050506040919091013590565b600080602083850312156130f057600080fd5b82356001600160401b0381111561310657600080fd5b61311285828601612c9c565b90969095509350505050565b600081518084526020808501945080840160005b83811015612fed5781516001600160a01b031687529582019590820190600101613132565b6000604080835261316a8184018661311e565b6020848203818601528186518084528284019150828160051b85010183890160005b838110156131d857601f1987840301855281516060815185528782015181898701526131ba82870182612c5d565b928b0151958b0195909552509486019492509085019060010161318c565b50909a9950505050505050505050565b600080604083850312156131fb57600080fd5b823561320681612c07565b946020939093013593505050565b8215158152608081016126426020830184805182526020808201516001600160a01b031690830152604090810151910152565b6000806000806060858703121561325d57600080fd5b843561326881612c07565b935060208501356001600160401b0381111561328357600080fd5b61328f87828801612c9c565b9598909750949560400135949350505050565b6000806000604084860312156132b757600080fd5b83356132c281612c07565b925060208401356001600160401b03808211156132de57600080fd5b818601915086601f8301126132f257600080fd5b81358181111561330157600080fd5b8760208260051b850101111561331657600080fd5b6020830194508093505050509250925092565b604080825283519082018190526000906020906060840190828701845b82811015613364578151151584529284019290840190600101613346565b5050508381038285015261305a8186612f96565b602081526000612642602083018461311e565b6000806040838503121561339e57600080fd5b82356001600160401b03808211156133b557600080fd5b6133c186838701613064565b935060208501359150808211156133d757600080fd5b506133e485828601613064565b9150509250929050565b6020815260006126426020830184612f41565b6000806040838503121561341457600080fd5b50508035926020909101359150565b600181811c9082168061343757607f821691505b6020821081036120b557634e487b7160e01b600052602260045260246000fd5b8183823760009101908152919050565b634e487b7160e01b600052601160045260246000fd5b80820281158282048414176121ce576121ce613467565b6000826134b157634e487b7160e01b600052601260045260246000fd5b500490565b6000600182016134c8576134c8613467565b5060010190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b601f821115610dd657600081815260208120601f850160051c8101602086101561351a5750805b601f850160051c820191505b8181101561353957828155600101613526565b505050505050565b81516001600160401b0381111561355a5761355a612d46565b61356e816135688454613423565b846134f3565b602080601f8311600181146135a3576000841561358b5750858301515b600019600386901b1c1916600185901b178555613539565b600085815260208120601f198616915b828110156135d2578886015182559484019460019091019084016135b3565b50858210156135f05787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b604081528260408201528284606083013760006060848301015260006060601f19601f8601168301019050826020830152949350505050565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561366157600080fd5b81516001600160401b0381111561367757600080fd5b8201601f8101841361368857600080fd5b8051613696612dc182612d8c565b8181528560208385010111156136ab57600080fd5b6136bc826020830160208601612c39565b95945050505050565b6000602082840312156136d757600080fd5b8151801515811461264257600080fd5b6040815260006136fa6040830185612c5d565b90508260208301529392505050565b6001600160401b0383111561372057613720612d46565b6137348361372e8354613423565b836134f3565b6000601f84116001811461376857600085156137505750838201355b600019600387901b1c1916600186901b178355610a1c565b600083815260209020601f19861690835b828110156137995786850135825560209485019460019092019101613779565b50868210156137b65760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b600082516137da818460208701612c39565b9190910192915050565b818103818111156121ce576121ce613467565b634e487b7160e01b600052603160045260246000fdfea26469706673582212208aa449f8ab8f895565cc541e541bf512150ee00c885e7a4e9b83ac0bbc68944464736f6c63430008110033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000007fb60450e7fad82e60ea7539c60d65397c13f1120000000000000000000000007acef2fc6af68936b79123a5f60ade832656bf78000000000000000000000000385eeac5cb85a38a9a07a70c73e0a3271cfb54a700000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000b99746f5525307d0bd3405d4d09583e81f8ad02000000000000000000000000000000000000000000000000000000000000000010000000000000000000000004b3d55b1d237d45c555876f48e6373c840789e04
-----Decoded View---------------
Arg [0] : _gotchiAddr (address): 0x7Fb60450e7FAd82E60ea7539c60D65397c13f112
Arg [1] : _packAddr (address): 0x7ACEf2FC6aF68936b79123a5F60ADE832656Bf78
Arg [2] : currency_ (address): 0x385Eeac5cB85A38A9a07A70c73e0a3271CfB54A7
Arg [3] : admins_ (address[]): 0xb99746f5525307d0BD3405d4d09583e81f8ad020
Arg [4] : devs_ (address[]): 0x4b3D55b1d237d45c555876f48e6373c840789E04
-----Encoded View---------------
9 Constructor Arguments found :
Arg [0] : 0000000000000000000000007fb60450e7fad82e60ea7539c60d65397c13f112
Arg [1] : 0000000000000000000000007acef2fc6af68936b79123a5f60ade832656bf78
Arg [2] : 000000000000000000000000385eeac5cb85a38a9a07a70c73e0a3271cfb54a7
Arg [3] : 00000000000000000000000000000000000000000000000000000000000000a0
Arg [4] : 00000000000000000000000000000000000000000000000000000000000000e0
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [6] : 000000000000000000000000b99746f5525307d0bd3405d4d09583e81f8ad020
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [8] : 0000000000000000000000004b3d55b1d237d45c555876f48e6373c840789e04
Deployed Bytecode Sourcemap
82901:20238:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;103037:99;;;;;;:::i;:::-;;:::i;:::-;;83714:18;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;94178:2244;;;;;;:::i;:::-;;:::i;36808:207::-;;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;;4104:33:1;;;4086:52;;4074:2;4059:18;36808:207:0;3942:202:1;87843:97:0;;;;;;:::i;:::-;;:::i;93087:764::-;;;;;;:::i;:::-;;:::i;86902:189::-;;;;;;:::i;:::-;;:::i;91310:419::-;;;;;;:::i;:::-;;:::i;100454:856::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;:::i;91980:805::-;;;;;;:::i;:::-;;:::i;96539:95::-;;;;;;:::i;:::-;;:::i;88629:1100::-;;;;;;:::i;:::-;;:::i;101349:662::-;;;:::i;:::-;;;;;;;;:::i;102839:90::-;;;:::i;87615:91::-;;;;;;:::i;:::-;;:::i;34323:103::-;;;:::i;98962:373::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;33675:87::-;33748:6;;-1:-1:-1;;;;;33748:6:0;33675:87;;;-1:-1:-1;;;;;12049:32:1;;;12031:51;;12019:2;12004:18;33675:87:0;11885:203:1;89940:1144:0;;;;;;:::i;:::-;;:::i;98151:669::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;99489:765::-;;;;;;:::i;:::-;;:::i;83776:20::-;;;:::i;83324:29::-;;;;;;;;;14482:25:1;;;14470:2;14455:18;83324:29:0;14336:177:1;102292:250:0;;;:::i;:::-;;;;;;;:::i;102019:265::-;;;:::i;83253:31::-;;;;;;88078:83;;;;;;:::i;:::-;;:::i;102550:181::-;;;;;;:::i;:::-;;:::i;:::-;;;15497:14:1;;15490:22;15472:41;;15460:2;15445:18;102550:181:0;15332:187:1;88294:89:0;;;;;;:::i;:::-;;:::i;102743:88::-;;;:::i;:::-;;;;;;;:::i;97241:720::-;;;;;;:::i;:::-;;:::i;34581:201::-;;;;;;:::i;:::-;;:::i;102937:92::-;103011:9;;-1:-1:-1;;;;;103011:9:0;102937:92;;87326:155;;;;;;:::i;:::-;;:::i;103037:99::-;33561:13;:11;:13::i;:::-;103116:10:::1;-1:-1:-1::0;;;;;103095:33:0::1;;83714:18:::0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;94178:2244::-;15747:21;:19;:21::i;:::-;-1:-1:-1;;;;;94382:26:0;::::1;;::::0;;;:13:::1;:26;::::0;;;;:45:::1;::::0;94418:8;94382:35:::1;:45::i;:::-;94360:112;;;::::0;-1:-1:-1;;;94360:112:0;;16649:2:1;94360:112:0::1;::::0;::::1;16631:21:1::0;16688:2;16668:18;;;16661:30;-1:-1:-1;;;16707:18:1;;;16700:47;16764:18;;94360:112:0::1;;;;;;;;;-1:-1:-1::0;;;;;94509:25:0;;::::1;94485:21;94509:25:::0;;;:12:::1;:25;::::0;;;;;;;:35;;;;;;;;;94485:59;;::::1;::::0;::::1;::::0;;;;;;;::::1;::::0;::::1;::::0;;;::::1;::::0;;::::1;::::0;;;;::::1;;::::0;;;;;;;;;94602:25;::::1;94594:58;;;::::0;-1:-1:-1;;;94594:58:0;;16995:2:1;94594:58:0::1;::::0;::::1;16977:21:1::0;17034:2;17014:18;;;17007:30;-1:-1:-1;;;17053:18:1;;;17046:50;17113:18;;94594:58:0::1;16793:344:1::0;94594:58:0::1;94685:16;::::0;::::1;::::0;-1:-1:-1;;;;;94671:30:0::1;:10;:30:::0;94663:70:::1;;;::::0;-1:-1:-1;;;94663:70:0;;17344:2:1;94663:70:0::1;::::0;::::1;17326:21:1::0;17383:2;17363:18;;;17356:30;17422:29;17402:18;;;17395:57;17469:18;;94663:70:0::1;17142:351:1::0;94663:70:0::1;94750:34;94765:5;;94750:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;;94750:34:0::1;::::0;;;;::::1;::::0;;;::::1;::::0;;-1:-1:-1;;;94750:34:0::1;::::0;::::1;::::0;;-1:-1:-1;94750:14:0::1;::::0;-1:-1:-1;94750:34:0:i:1;:::-;94746:159;;94804:11;94816:5;;94804:18;;;;;;;:::i;:::-;::::0;;;::::1;::::0;;;;;::::1;::::0;;;;::::1;;94801:93;;;94839:39;94869:8;94839:15;94855:5;;94839:22;;;;;;;:::i;:::-;::::0;;;::::1;::::0;;;;;::::1;::::0;;;;:29:::1;:39::i;:::-;;94801:93;95063:16;95094:18:::0;95126:43:::1;95149:11;95162:6;95126:22;:43::i;:::-;95048:121:::0;;-1:-1:-1;95048:121:0;-1:-1:-1;95185:14:0;;95182:521:::1;;95218:17;95275:14;:5;:12;:14::i;:::-;95268:4;95251:14;;95238:10;:27;;;;:::i;:::-;:34;;;;:::i;:::-;:51;;;;:::i;:::-;95218:71;;95306:19;95367:16;:7;:14;:16::i;:::-;95360:4;95341:16;;95328:10;:29;;;;:::i;:::-;:36;;;;:::i;:::-;:55;;;;:::i;:::-;95306:77;;95404:6;95400:141;95417:16;:7;:14;:16::i;:::-;95415:1;:18;95400:141;;;95459:66;95486:10;95498:13;:7;95509:1:::0;95498:10:::1;:13::i;:::-;95459:9;::::0;-1:-1:-1;;;;;95459:9:0::1;::::0;:66;95513:11;95459:26:::1;:66::i;:::-;95435:3:::0;::::1;::::0;::::1;:::i;:::-;;;;95400:141;;;;95561:6;95557:135;95574:14;:5;:12;:14::i;:::-;95572:1;:16;95557:135;;;95614:62;95641:10;95653:11;:5;95662:1:::0;95653:8:::1;:11::i;:::-;95614:9;::::0;-1:-1:-1;;;;;95614:9:0::1;::::0;:62;95666:9;95614:26:::1;:62::i;:::-;95590:3:::0;::::1;::::0;::::1;:::i;:::-;;;;95557:135;;;;95201:502;;95182:521;95752:16;::::0;::::1;::::0;95713:9:::1;::::0;:66:::1;::::0;-1:-1:-1;;;;;95713:9:0;;::::1;::::0;95740:10:::1;::::0;95770:8;95713:26:::1;:66::i;:::-;95818:16;::::0;;::::1;::::0;-1:-1:-1;;;;;95800:35:0;;::::1;;::::0;;;:17:::1;:35:::0;;;;;;:48;;::::1;::::0;;;;;;;;:89:::1;::::0;95870:8;95800:55:::1;:89::i;:::-;-1:-1:-1::0;;;;;;95902:26:0;::::1;;::::0;;;:13:::1;:26;::::0;;;;:43:::1;::::0;95936:8;95902:33:::1;:43::i;:::-;-1:-1:-1::0;;;;;;95965:25:0;::::1;;::::0;;;:12:::1;:25;::::0;;;;;;;:35;;;;;;;;;95958:42;;;::::1;::::0;::::1;::::0;;-1:-1:-1;;;;;;95958:42:0::1;::::0;;::::1;;::::0;;;;96055:133;-1:-1:-1;;;96055:133:0;;:37:::1;::::0;:133:::1;::::0;96115:4:::1;::::0;96143:10:::1;::::0;95991:8;;96055:133:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;;;96298:16:0::1;::::0;;::::1;::::0;96229:185:::1;::::0;;96329:10:::1;19048:51:1::0;;19115:18;;;19108:34;;;19158:18;;19151:34;;;-1:-1:-1;19216:2:1;19201:18;;19194:50;-1:-1:-1;;;;;96229:185:0;;::::1;::::0;96275:8;;96229:185;::::1;::::0;::::1;::::0;19035:3:1;19020:19;96229:185:0::1;;;;;;;94339:2083;;;15791:20:::0;15185:1;16311:7;:22;16128:213;15791:20;94178:2244;;;;;:::o;36808:207::-;-1:-1:-1;;;36808:207:0;;;;;;;:::o;87843:97::-;33561:13;:11;:13::i;:::-;87910:22:::1;:7;87925:6:::0;87910:14:::1;:22::i;:::-;;87843:97:::0;:::o;93087:764::-;33561:13;:11;:13::i;:::-;93286:43:::1;:21;93317:11:::0;93286:30:::1;:43::i;:::-;93264:126;;;::::0;-1:-1:-1;;;93264:126:0;;19457:2:1;93264:126:0::1;::::0;::::1;19439:21:1::0;19496:2;19476:18;;;19469:30;19535:34;19515:18;;;19508:62;-1:-1:-1;;;19586:18:1;;;19579:31;19627:19;;93264:126:0::1;19255:397:1::0;93264:126:0::1;93403:20;93426:29;:21;93451:3:::0;93426:24:::1;:29::i;:::-;93403:52;;93466:36;93505:12;:26;93518:12;-1:-1:-1::0;;;;;93505:26:0::1;-1:-1:-1::0;;;;;93505:26:0::1;;;;;;;;;;;;93466:65;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;93578:148;;;;;;;;93619:18;:31;;;93578:148;;;;93671:5;;93578:148;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;-1:-1:-1;93578:148:0;;;-1:-1:-1;;;93578:148:0::1;::::0;;::::1;::::0;;;-1:-1:-1;;;;;93550:25:0;::::1;::::0;;:12:::1;:25:::0;;;;;:176;;;;;;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;;::::1;:::i;:::-;;;;;;;;;;;;;93775:11;-1:-1:-1::0;;;;;93744:99:0::1;;93801:5;;93821:11;93744:99;;;;;;;;:::i;:::-;;;;;;;;93253:598;;93087:764:::0;;;;;:::o;86902:189::-;33561:13;:11;:13::i;:::-;86992:9:::1;::::0;-1:-1:-1;;;;;86992:9:0;;::::1;86979:22:::0;;::::1;::::0;86971:72:::1;;;::::0;-1:-1:-1;;;86971:72:0;;22531:2:1;86971:72:0::1;::::0;::::1;22513:21:1::0;22570:2;22550:18;;;22543:30;22609:34;22589:18;;;22582:62;-1:-1:-1;;;22660:18:1;;;22653:35;22705:19;;86971:72:0::1;22329:401:1::0;86971:72:0::1;87054:9;:29:::0;;-1:-1:-1;;;;;;87054:29:0::1;-1:-1:-1::0;;;;;87054:29:0;;;::::1;::::0;;;::::1;::::0;;86902:189::o;91310:419::-;15747:21;:19;:21::i;:::-;-1:-1:-1;;;;;91485:25:0;;::::1;91462:20;91485:25:::0;;;:12:::1;:25;::::0;;;;;;;:35;;;;;;;;91539:14:::1;::::0;::::1;::::0;91485:35;;91539:14:::1;91557:10;91539:28;91531:59;;;::::0;-1:-1:-1;;;91531:59:0;;22937:2:1;91531:59:0::1;::::0;::::1;22919:21:1::0;22976:2;22956:18;;;22949:30;-1:-1:-1;;;22995:18:1;;;22988:48;23053:18;;91531:59:0::1;22735:342:1::0;91531:59:0::1;91601:25:::0;;;91665:56:::1;::::0;14482:25:1;;;91701:8:0;;91689:10:::1;::::0;-1:-1:-1;;;;;91665:56:0;::::1;::::0;::::1;::::0;14470:2:1;14455:18;91665:56:0::1;;;;;;;91449:280;15791:20:::0;15185:1;16311:7;:22;16128:213;15791:20;91310:419;;;:::o;100454:856::-;-1:-1:-1;;;;;100767:25:0;;;100749:14;100767:25;;;:17;:25;;;;;;;;:37;;;;;;;;;;;100619:25;;;;;;100749:14;100767:46;;:44;:46::i;:::-;100749:64;;100851:6;-1:-1:-1;;;;;100837:21:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;100837:21:0;;100826:32;;100894:6;-1:-1:-1;;;;;100881:20:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;100869:32;;100934:6;-1:-1:-1;;;;;100923:18:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;100912:29;;100959:9;100954:298;100978:6;100974:1;:10;100954:298;;;-1:-1:-1;;;;;101020:25:0;;;;;;;:17;:25;;;;;;;;:37;;;;;;;;;:75;;101079:1;101020:40;:75::i;:::-;101006:8;101015:1;101006:11;;;;;;;;:::i;:::-;;;;;;:89;;;;;101124:12;:24;101137:10;-1:-1:-1;;;;;101124:24:0;-1:-1:-1;;;;;101124:24:0;;;;;;;;;;;;:37;101149:8;101158:1;101149:11;;;;;;;;:::i;:::-;;;;;;;;;;;;101124:37;;;;;;;;;;;;;-1:-1:-1;101124:37:0;101110:51;;;;;;;;;;;;;;;-1:-1:-1;;;;;101110:51:0;;;;;;;;;;;;;;;:11;;:8;;101119:1;;101110:11;;;;;;:::i;:::-;;;;;;:51;;;;101207:10;-1:-1:-1;;;;;101191:36:0;;101228:8;101237:1;101228:11;;;;;;;;:::i;:::-;;;;;;;101191:49;;;;;;;;;;;;;14482:25:1;;14470:2;14455:18;;14336:177;101191:49:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;101191:49:0;;;;;;;;;;;;:::i;:::-;101176:9;101186:1;101176:12;;;;;;;;:::i;:::-;;;;;;:64;;;;100986:3;;;;;:::i;:::-;;;;100954:298;;;;101264:38;100454:856;;;;;:::o;91980:805::-;33561:13;:11;:13::i;:::-;92151:41:::1;:21;92180:11:::0;92151:28:::1;:41::i;:::-;92150:42;92128:129;;;::::0;-1:-1:-1;;;92128:129:0;;24069:2:1;92128:129:0::1;::::0;::::1;24051:21:1::0;24108:2;24088:18;;;24081:30;24147:34;24127:18;;;24120:62;-1:-1:-1;;;24198:18:1;;;24191:35;24243:19;;92128:129:0::1;23867:401:1::0;92128:129:0::1;92290:50;::::0;-1:-1:-1;;;92290:50:0;;-1:-1:-1;;;92290:50:0::1;::::0;::::1;24435:62:1::0;-1:-1:-1;;;;;92290:38:0;::::1;::::0;::::1;::::0;24408:18:1;;92290:50:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;92268:122;;;::::0;-1:-1:-1;;;92268:122:0;;24992:2:1;92268:122:0::1;::::0;::::1;24974:21:1::0;25031:2;25011:18;;;25004:30;-1:-1:-1;;;25050:18:1;;;25043:52;25112:18;;92268:122:0::1;24790:346:1::0;92268:122:0::1;92403:38;:21;92429:11:::0;92403:25:::1;:38::i;:::-;;92454:21;92479:24;:14;82272::::0;;82180:114;92479:24:::1;92544:130;::::0;;::::1;::::0;::::1;::::0;;;;;::::1;::::0;;::::1;::::0;;;;;;;;;-1:-1:-1;;;;;92516:25:0;::::1;-1:-1:-1::0;92516:25:0;;;:12:::1;:25:::0;;;;;;:158;;;;;;92454:49;;-1:-1:-1;92544:130:0;92516:158:::1;::::0;::::1;::::0;::::1;::::0;;::::1;:::i;:::-;;;;;;;;;;;;;92685:26;:14;82391:19:::0;;82409:1;82391:19;;;82302:127;92685:26:::1;92743:11;-1:-1:-1::0;;;;;92729:46:0::1;;92756:5;92763:11;92729:46;;;;;;;:::i;:::-;;;;;;;;92117:668;91980:805:::0;;;:::o;96539:95::-;33561:13;:11;:13::i;:::-;96611:8:::1;:15;96622:4:::0;;96611:8;:15:::1;:::i;88629:1100::-:0;15747:21;:19;:21::i;:::-;88856:133:::1;::::0;-1:-1:-1;;;88856:133:0;;-1:-1:-1;;;;;88856:37:0;::::1;::::0;::::1;::::0;:133:::1;::::0;88916:10:::1;::::0;88950:4:::1;::::0;88970:8;;88856:133:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;89006:34;89021:5;;89006:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;;89006:34:0::1;::::0;;;;::::1;::::0;;;::::1;::::0;;-1:-1:-1;;;89006:34:0::1;::::0;::::1;::::0;;-1:-1:-1;89006:14:0::1;::::0;-1:-1:-1;89006:34:0:i:1;:::-;89002:238;;89061:11;89073:5;;89061:18;;;;;;;:::i;:::-;::::0;;;::::1;::::0;;;;;::::1;::::0;;;;::::1;;89057:121;;89100:6;:18:::0;;::::1;::::0;::::1;::::0;;-1:-1:-1;89100:18:0;;;;;::::1;;89112:5:::0;;89100:18;::::1;:::i;:::-;;89158:4;89137:11;89149:5;;89137:18;;;;;;;:::i;:::-;::::0;;;::::1;::::0;;;;;::::1;::::0;;;:25;;;::::1;;-1:-1:-1::0;;89137:25:0;;::::1;::::0;;;::::1;::::0;;89057:121:::1;89192:36;89219:8;89192:15;89208:5;;89192:22;;;;;;;:::i;:::-;::::0;;;::::1;::::0;;;;;::::1;::::0;;;;:26:::1;:36::i;:::-;;89002:238;89305:10;89287:29;::::0;;;:17:::1;:29;::::0;;;;;;;-1:-1:-1;;;;;89287:42:0;::::1;::::0;;;;;;;:56:::1;::::0;89334:8;89287:46:::1;:56::i;:::-;-1:-1:-1::0;89402:123:0::1;::::0;;::::1;::::0;::::1;::::0;;;;;89430:10:::1;89402:123;::::0;;::::1;::::0;;;89498:15:::1;89402:123:::0;;;;;;-1:-1:-1;;;;;89364:25:0;;::::1;-1:-1:-1::0;89364:25:0;;;:12:::1;:25:::0;;;;;:35;;;;;;;;:161;;;;;;::::1;::::0;::::1;::::0;;-1:-1:-1;;;;;;89364:161:0::1;::::0;;;::::1;;::::0;;;;;::::1;::::0;;::::1;::::0;;;;89586:26;;;:13:::1;:26:::0;;;;:40:::1;::::0;89364:35;89586:30:::1;:40::i;:::-;;89700:8;89688:10;-1:-1:-1::0;;;;;89667:54:0::1;89675:11;-1:-1:-1::0;;;;;89667:54:0::1;;89710:10;89667:54;;;;14482:25:1::0;;14470:2;14455:18;;14336:177;89667:54:0::1;;;;;;;;15791:20:::0;15185:1;16311:7;:22;16128:213;101349:662;101440:36;101491:37;101570:14;101587:30;:21;:28;:30::i;:::-;101570:47;;101678:6;-1:-1:-1;;;;;101664:21:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;101664:21:0;;101642:43;;101733:6;-1:-1:-1;;;;;101716:24:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;101716:24:0;;;;;;;;;;;;;;;;;101696:44;;101758:9;101753:191;101777:6;101773:1;:10;101753:191;;;101830:28;:21;101856:1;101830:24;:28::i;:::-;101805:19;101825:1;101805:22;;;;;;;;:::i;:::-;;;;;;:53;-1:-1:-1;;;;;101805:53:0;;;-1:-1:-1;;;;;101805:53:0;;;;;101896:12;:36;101909:19;101929:1;101909:22;;;;;;;;:::i;:::-;;;;;;;-1:-1:-1;;;;;101896:36:0;-1:-1:-1;;;;;101896:36:0;;;;;;;;;;;;101873:59;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:17;101891:1;101873:20;;;;;;;;:::i;:::-;;;;;;:59;;;;101785:3;;;;;:::i;:::-;;;;101753:191;;;;101956:47;101349:662;;:::o;102839:90::-;102880:13;102913:8;102906:15;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;102839:90;:::o;87615:91::-;33561:13;:11;:13::i;:::-;87679:19:::1;:7;87691:6:::0;87679:11:::1;:19::i;34323:103::-:0;33561:13;:11;:13::i;:::-;34388:30:::1;34415:1;34388:18;:30::i;:::-;34323:103::o:0;98962:373::-;99088:11;99101:20;;:::i;:::-;-1:-1:-1;;;;;99137:26:0;;;;;;:13;:26;;;;;:45;;99173:8;99137:35;:45::i;:::-;99133:138;;;99208:4;99199:13;;99133:138;;;99254:5;99245:14;;99133:138;-1:-1:-1;;;;;;99292:25:0;;;;;;;:12;:25;;;;;;;;:35;;;;;;;;;;99281:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;98962:373;:::o;89940:1144::-;15747:21;:19;:21::i;:::-;90197:10:::1;90179:29;::::0;;;:17:::1;:29;::::0;;;;;;;-1:-1:-1;;;;;90179:42:0;::::1;::::0;;;;;;;:93:::1;::::0;90249:8;90179:51:::1;:93::i;:::-;90157:166;;;::::0;-1:-1:-1;;;90157:166:0;;26850:2:1;90157:166:0::1;::::0;::::1;26832:21:1::0;26889:2;26869:18;;;26862:30;26928:25;26908:18;;;26901:53;26971:18;;90157:166:0::1;26648:347:1::0;90157:166:0::1;90340:34;90355:5;;90340:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;;90340:34:0::1;::::0;;;;::::1;::::0;;;::::1;::::0;;-1:-1:-1;;;90340:34:0::1;::::0;::::1;::::0;;-1:-1:-1;90340:14:0::1;::::0;-1:-1:-1;90340:34:0:i:1;:::-;90336:177;;90399:11;90411:5;;90399:18;;;;;;;:::i;:::-;::::0;;;::::1;::::0;;;;;::::1;::::0;;;;::::1;;90391:56;;;::::0;-1:-1:-1;;;90391:56:0;;27202:2:1;90391:56:0::1;::::0;::::1;27184:21:1::0;27241:2;27221:18;;;27214:30;27280:27;27260:18;;;27253:55;27325:18;;90391:56:0::1;27000:349:1::0;90391:56:0::1;90462:39;90492:8;90462:15;90478:5;;90462:22;;;;;;;:::i;:39::-;;90336:177;90578:10;90560:29;::::0;;;:17:::1;:29;::::0;;;;;;;-1:-1:-1;;;;;90560:42:0;::::1;::::0;;;;;;;:83:::1;::::0;90624:8;90560:49:::1;:83::i;:::-;-1:-1:-1::0;;;;;;90663:25:0;::::1;;::::0;;;:12:::1;:25;::::0;;;;;;;:35;;;;;;;;90656:42;;;::::1;::::0;::::1;::::0;;-1:-1:-1;;;;;;90656:42:0::1;::::0;;::::1;;::::0;;;90759:26;;;:13:::1;:26:::0;;;:43:::1;::::0;90689:8;90759:33:::1;:43::i;:::-;-1:-1:-1::0;90861:129:0::1;::::0;-1:-1:-1;;;90861:129:0;;-1:-1:-1;;;;;90861:33:0;::::1;::::0;::::1;::::0;:129:::1;::::0;90917:4:::1;::::0;90945:10:::1;::::0;90971:8;;90861:129:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;91031:45:0::1;::::0;91067:8;;-1:-1:-1;91055:10:0::1;::::0;-1:-1:-1;;;;;;91031:45:0;::::1;::::0;::::1;::::0;;;::::1;15791:20:::0;15185:1;16311:7;:22;16128:213;15791:20;89940:1144;;;;:::o;98151:669::-;98290:22;;98366:8;;-1:-1:-1;;;;;98405:18:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;98405:18:0;;98394:29;;98456:6;-1:-1:-1;;;;;98445:18:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;98434:29;;98481:9;98476:297;98500:6;98496:1;:10;98476:297;;;98532:47;98567:8;;98576:1;98567:11;;;;;;;:::i;:::-;-1:-1:-1;;;;;98532:25:0;;;;;;:13;98567:11;98532:25;;;;;;;;98567:11;;;;;-1:-1:-1;98532:34:0;:47::i;:::-;98528:166;;;98614:4;98600:8;98609:1;98600:11;;;;;;;;:::i;:::-;:18;;;:11;;;;;;;;;;;:18;98528:166;;;98673:5;98659:8;98668:1;98659:11;;;;;;;;:::i;:::-;:19;;;:11;;;;;;;;;;;:19;98528:166;-1:-1:-1;;;;;98724:24:0;;;;;;:12;:24;;;;;;98749:8;;98758:1;98749:11;;;;;;;:::i;:::-;;;;;;;;;;98724:37;;-1:-1:-1;98724:37:0;;;;;;;;;;;-1:-1:-1;98724:37:0;98710:51;;;;;;;;;;;;;;;-1:-1:-1;;;;;98710:51:0;;;;;;;;;;;;;;;:11;;:8;;98719:1;;98710:11;;;;;;:::i;:::-;;;;;;:51;;;;98508:3;;;;;:::i;:::-;;;;98476:297;;;;98785:27;98151:669;;;;;;:::o;99489:765::-;-1:-1:-1;;;;;99767:25:0;;99750:14;99767:25;;;:13;:25;;;;;99620;;;;;;99750:14;99767:34;;:32;:34::i;:::-;99750:51;;99839:6;-1:-1:-1;;;;;99825:21:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;99825:21:0;;99814:32;;99879:6;-1:-1:-1;;;;;99868:18:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;99857:29;;99922:6;-1:-1:-1;;;;;99909:20:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;99897:32;;99947:9;99942:254;99966:6;99962:1;:10;99942:254;;;-1:-1:-1;;;;;100008:25:0;;;;;;:13;:25;;;;;:31;;100037:1;100008:28;:31::i;:::-;99994:8;100003:1;99994:11;;;;;;;;:::i;:::-;;;;;;:45;;;;;100068:12;:24;100081:10;-1:-1:-1;;;;;100068:24:0;-1:-1:-1;;;;;100068:24:0;;;;;;;;;;;;:37;100093:8;100102:1;100093:11;;;;;;;;:::i;:::-;;;;;;;;;;;;100068:37;;;;;;;;;;;;;-1:-1:-1;100068:37:0;100054:51;;;;;;;;;;;;;;;-1:-1:-1;;;;;100054:51:0;;;;;;;;;;;;;;;:11;;:8;;100063:1;;100054:11;;;;;;:::i;:::-;;;;;;:51;;;;100151:10;-1:-1:-1;;;;;100135:36:0;;100172:8;100181:1;100172:11;;;;;;;;:::i;:::-;;;;;;;100135:49;;;;;;;;;;;;;14482:25:1;;14470:2;14455:18;;14336:177;100135:49:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;100135:49:0;;;;;;;;;;;;:::i;:::-;100120:9;100130:1;100120:12;;;;;;;;:::i;:::-;;;;;;:64;;;;99974:3;;;;;:::i;:::-;;;;99942:254;;;;100208:38;99489:765;;;;;:::o;83776:20::-;;;;;;;:::i;102292:250::-;102330:16;102359:22;102398:14;:5;:12;:14::i;:::-;-1:-1:-1;;;;;102384:29:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;102384:29:0;;102359:54;;102428:6;102424:88;102441:14;:5;:12;:14::i;:::-;102439:1;:16;102424:88;;;102489:11;:5;102498:1;102489:8;:11::i;:::-;102478:5;102484:1;102478:8;;;;;;;;:::i;:::-;-1:-1:-1;;;;;102478:22:0;;;:8;;;;;;;;;;;:22;102458:3;;;;:::i;:::-;;;;102424:88;;;-1:-1:-1;102529:5:0;102292:250;-1:-1:-1;102292:250:0:o;102019:265::-;102059:16;102089:24;102130:16;:7;:14;:16::i;:::-;-1:-1:-1;;;;;102116:31:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;102116:31:0;;102089:58;;102162:6;102158:94;102175:16;:7;:14;:16::i;:::-;102173:1;:18;102158:94;;;102227:13;:7;102238:1;102227:10;:13::i;:::-;102214:7;102222:1;102214:10;;;;;;;;:::i;:::-;-1:-1:-1;;;;;102214:26:0;;;:10;;;;;;;;;;;:26;102194:3;;;;:::i;:::-;;;;102158:94;;88078:83;33561:13;:11;:13::i;:::-;88138:15:::1;:5;88148:4:::0;88138:9:::1;:15::i;102550:181::-:0;102629:4;102718:1;102700:21;;;;;;;;:::i;:::-;;;;;;;;;;;;;102690:32;;;;;;102682:1;102664:21;;;;;;;;:::i;:::-;;;;;;;;;;;;;102654:32;;;;;;:68;102646:77;;102550:181;;;;;:::o;88294:89::-;33561:13;:11;:13::i;:::-;88357:18:::1;:5;88370:4:::0;88357:12:::1;:18::i;102743:88::-:0;102782:15;102817:6;102810:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;102743:88;:::o;97241:720::-;97311:16;97329:15;97346:13;97372:17;97392:31;:15;97408:5;;97392:22;;;;;;;:::i;:::-;;;;;;;;;;;;;:29;:31::i;:::-;97372:51;;97434:20;97468:9;-1:-1:-1;;;;;97457:21:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;97434:44;;97489:21;97527:9;-1:-1:-1;;;;;97513:24:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;97513:24:0;;97489:48;;97548:21;97585:9;-1:-1:-1;;;;;97572:23:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;97548:47;;97610:9;97606:309;97626:9;97624:1;:11;97606:309;;;97670:12;:41;97683:27;:21;97670:41;97683:24;:27::i;:::-;-1:-1:-1;;;;;97670:41:0;-1:-1:-1;;;;;97670:41:0;;;;;;;;;;;;:71;97712:28;97738:1;97712:15;97728:5;;97712:22;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:25;:28::i;:::-;97670:71;;;;;;;;;;;;;;-1:-1:-1;97670:71:0;97658:83;;;;;;;;;;;;;;;-1:-1:-1;;;;;97658:83:0;;;;;;;;;;;;;;;:9;;:6;;97665:1;;97658:9;;;;;;:::i;:::-;;;;;;;;;;:83;97783:27;:21;97808:1;97783:24;:27::i;:::-;-1:-1:-1;;;;;97767:53:0;;97821:28;97847:1;97821:15;97837:5;;97821:22;;;;;;;:::i;:28::-;97767:83;;;;;;;;;;;;;14482:25:1;;14470:2;14455:18;;14336:177;97767:83:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;97767:83:0;;;;;;;;;;;;:::i;:::-;97756:5;97762:1;97756:8;;;;;;;;:::i;:::-;;;;;;:94;;;;97875:28;97901:1;97875:15;97891:5;;97875:22;;;;;;;:::i;:28::-;97865:4;97870:1;97865:7;;;;;;;;:::i;:::-;;;;;;;;;;:38;97638:3;;;;:::i;:::-;;;;97606:309;;;-1:-1:-1;97933:4:0;;-1:-1:-1;97939:5:0;-1:-1:-1;97946:6:0;-1:-1:-1;;97241:720:0;;;;;:::o;34581:201::-;33561:13;:11;:13::i;:::-;-1:-1:-1;;;;;34670:22:0;::::1;34662:73;;;::::0;-1:-1:-1;;;34662:73:0;;27850:2:1;34662:73:0::1;::::0;::::1;27832:21:1::0;27889:2;27869:18;;;27862:30;27928:34;27908:18;;;27901:62;-1:-1:-1;;;27979:18:1;;;27972:36;28025:19;;34662:73:0::1;27648:402:1::0;34662:73:0::1;34746:28;34765:8;34746:18;:28::i;:::-;34581:201:::0;:::o;87326:155::-;33561:13;:11;:13::i;:::-;87410:14:::1;:24:::0;87445:16:::1;:28:::0;87326:155::o;8609:152::-;8679:4;8703:50;8708:3;-1:-1:-1;;;;;8728:23:0;;8703:4;:50::i;:::-;8696:57;8609:152;-1:-1:-1;;;8609:152:0:o;8937:158::-;9010:4;9034:53;9042:3;-1:-1:-1;;;;;9062:23:0;;9034:7;:53::i;82180:114::-;82272:14;;82180:114::o;82302:127::-;82391:19;;82409:1;82391:19;;;82302:127::o;33840:132::-;33748:6;;-1:-1:-1;;;;;33748:6:0;32306:10;33904:23;33896:68;;;;-1:-1:-1;;;33896:68:0;;28257:2:1;33896:68:0;;;28239:21:1;;;28276:18;;;28269:30;28335:34;28315:18;;;28308:62;28387:18;;33896:68:0;28055:356:1;15827:293:0;15229:1;15961:7;;:19;15953:63;;;;-1:-1:-1;;;15953:63:0;;28618:2:1;15953:63:0;;;28600:21:1;28657:2;28637:18;;;28630:30;28696:33;28676:18;;;28669:61;28747:18;;15953:63:0;28416:355:1;15953:63:0;15229:1;16094:7;:18;15827:293::o;11701:146::-;11778:4;4533:19;;;:12;;;:19;;;;;;:24;;11802:37;4436:129;11478:137;11548:4;11572:35;11580:3;11600:5;11572:7;:35::i;96825:408::-;-1:-1:-1;;;;;97091:25:0;;96987:16;97091:25;;;:12;:25;;;;;:36;;;96987:16;;97131:5;;97078:49;;:10;:49;:::i;:::-;97077:59;;;;:::i;:::-;97064:72;-1:-1:-1;97160:23:0;97064:72;97160:10;:23;:::i;:::-;97149:34;;96825:408;;;;;;:::o;9434:117::-;9497:7;9524:19;9532:3;4734:18;;4651:109;9905:158;9979:7;10030:22;10034:3;10046:5;10030:3;:22::i;77737:248::-;77881:96;77901:5;77931:27;;;77960:4;77966:2;77970:5;77908:68;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;77908:68:0;;;;;;;;;;;;;;-1:-1:-1;;;;;77908:68:0;-1:-1:-1;;;;;;77908:68:0;;;;;;;;;;77881:19;:96::i;9181:167::-;-1:-1:-1;;;;;9315:23:0;;9261:4;4533:19;;;:12;;;:19;;;;;;:24;;9285:55;4436:129;11171:131;11238:4;11262:32;11267:3;11287:5;11262:4;:32::i;34942:191::-;35035:6;;;-1:-1:-1;;;;;35052:17:0;;;-1:-1:-1;;;;;;35052:17:0;;;;;;;35085:40;;35035:6;;;35052:17;35035:6;;35085:40;;35016:16;;35085:40;35005:128;34942:191;:::o;2340:414::-;2403:4;4533:19;;;:12;;;:19;;;;;;2420:327;;-1:-1:-1;2463:23:0;;;;;;;;:11;:23;;;;;;;;;;;;;2646:18;;2624:19;;;:12;;;:19;;;;;;:40;;;;2679:11;;2420:327;-1:-1:-1;2730:5:0;2723:12;;2930:1420;2996:4;3135:19;;;:12;;;:19;;;;;;3171:15;;3167:1176;;3546:21;3570:14;3583:1;3570:10;:14;:::i;:::-;3619:18;;3546:38;;-1:-1:-1;3599:17:0;;3619:22;;3640:1;;3619:22;:::i;:::-;3599:42;;3675:13;3662:9;:26;3658:405;;3709:17;3729:3;:11;;3741:9;3729:22;;;;;;;;:::i;:::-;;;;;;;;;3709:42;;3883:9;3854:3;:11;;3866:13;3854:26;;;;;;;;:::i;:::-;;;;;;;;;;;;:38;;;;3968:23;;;:12;;;:23;;;;;:36;;;3658:405;4144:17;;:3;;:17;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;4239:3;:12;;:19;4252:5;4239:19;;;;;;;;;;;4232:26;;;4282:4;4275:11;;;;;;;3167:1176;4326:5;4319:12;;;;;5114:120;5181:7;5208:3;:11;;5220:5;5208:18;;;;;;;;:::i;:::-;;;;;;;;;5201:25;;5114:120;;;;:::o;80585:716::-;81009:23;81035:69;81063:4;81035:69;;;;;;;;;;;;;;;;;81043:5;-1:-1:-1;;;;;81035:27:0;;;:69;;;;;:::i;:::-;81119:17;;81009:95;;-1:-1:-1;81119:21:0;81115:179;;81216:10;81205:30;;;;;;;;;;;;:::i;:::-;81197:85;;;;-1:-1:-1;;;81197:85:0;;29243:2:1;81197:85:0;;;29225:21:1;29282:2;29262:18;;;29255:30;29321:34;29301:18;;;29294:62;-1:-1:-1;;;29372:18:1;;;29365:40;29422:19;;81197:85:0;29041:406:1;48875:229:0;49012:12;49044:52;49066:6;49074:4;49080:1;49083:12;49012;50283;50297:23;50324:6;-1:-1:-1;;;;;50324:11:0;50343:5;50350:4;50324:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50282:73;;;;50373:69;50400:6;50408:7;50417:10;50429:12;50373:26;:69::i;:::-;50366:76;49995:455;-1:-1:-1;;;;;;;49995:455:0:o;52568:644::-;52753:12;52782:7;52778:427;;;52810:10;:17;52831:1;52810:22;52806:290;;-1:-1:-1;;;;;46413:19:0;;;53020:60;;;;-1:-1:-1;;;53020:60:0;;30353:2:1;53020:60:0;;;30335:21:1;30392:2;30372:18;;;30365:30;30431:31;30411:18;;;30404:59;30480:18;;53020:60:0;30151:353:1;53020:60:0;-1:-1:-1;53117:10:0;53110:17;;52778:427;53160:33;53168:10;53180:12;53915:17;;:21;53911:388;;54147:10;54141:17;54204:15;54191:10;54187:2;54183:19;54176:44;53911:388;54274:12;54267:20;;-1:-1:-1;;;54267:20:0;;;;;;;;:::i;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;14:131:1:-;-1:-1:-1;;;;;89:31:1;;79:42;;69:70;;135:1;132;125:12;150:247;209:6;262:2;250:9;241:7;237:23;233:32;230:52;;;278:1;275;268:12;230:52;317:9;304:23;336:31;361:5;336:31;:::i;402:250::-;487:1;497:113;511:6;508:1;505:13;497:113;;;587:11;;;581:18;568:11;;;561:39;533:2;526:10;497:113;;;-1:-1:-1;;644:1:1;626:16;;619:27;402:250::o;657:271::-;699:3;737:5;731:12;764:6;759:3;752:19;780:76;849:6;842:4;837:3;833:14;826:4;819:5;815:16;780:76;:::i;:::-;910:2;889:15;-1:-1:-1;;885:29:1;876:39;;;;917:4;872:50;;657:271;-1:-1:-1;;657:271:1:o;933:220::-;1082:2;1071:9;1064:21;1045:4;1102:45;1143:2;1132:9;1128:18;1120:6;1102:45;:::i;1158:348::-;1210:8;1220:6;1274:3;1267:4;1259:6;1255:17;1251:27;1241:55;;1292:1;1289;1282:12;1241:55;-1:-1:-1;1315:20:1;;-1:-1:-1;;;;;1347:30:1;;1344:50;;;1390:1;1387;1380:12;1344:50;1427:4;1419:6;1415:17;1403:29;;1479:3;1472:4;1463:6;1455;1451:19;1447:30;1444:39;1441:59;;;1496:1;1493;1486:12;1511:683;1609:6;1617;1625;1633;1641;1694:3;1682:9;1673:7;1669:23;1665:33;1662:53;;;1711:1;1708;1701:12;1662:53;1750:9;1737:23;1769:31;1794:5;1769:31;:::i;:::-;1819:5;-1:-1:-1;1871:2:1;1856:18;;1843:32;;-1:-1:-1;1922:2:1;1907:18;;1894:32;;-1:-1:-1;1977:2:1;1962:18;;1949:32;-1:-1:-1;;;;;1993:30:1;;1990:50;;;2036:1;2033;2026:12;1990:50;2075:59;2126:7;2117:6;2106:9;2102:22;2075:59;:::i;:::-;1511:683;;;;-1:-1:-1;1511:683:1;;-1:-1:-1;2153:8:1;;2049:85;1511:683;-1:-1:-1;;;1511:683:1:o;2199:127::-;2260:10;2255:3;2251:20;2248:1;2241:31;2291:4;2288:1;2281:15;2315:4;2312:1;2305:15;2331:275;2402:2;2396:9;2467:2;2448:13;;-1:-1:-1;;2444:27:1;2432:40;;-1:-1:-1;;;;;2487:34:1;;2523:22;;;2484:62;2481:88;;;2549:18;;:::i;:::-;2585:2;2578:22;2331:275;;-1:-1:-1;2331:275:1:o;2611:186::-;2659:4;-1:-1:-1;;;;;2684:6:1;2681:30;2678:56;;;2714:18;;:::i;:::-;-1:-1:-1;2780:2:1;2759:15;-1:-1:-1;;2755:29:1;2786:4;2751:40;;2611:186::o;2802:336::-;2866:5;2895:52;2911:35;2939:6;2911:35;:::i;:::-;2895:52;:::i;:::-;2886:61;;2970:6;2963:5;2956:21;3010:3;3001:6;2996:3;2992:16;2989:25;2986:45;;;3027:1;3024;3017:12;2986:45;3076:6;3071:3;3064:4;3057:5;3053:16;3040:43;3130:1;3123:4;3114:6;3107:5;3103:18;3099:29;3092:40;2802:336;;;;;:::o;3143:794::-;3238:6;3246;3254;3262;3315:3;3303:9;3294:7;3290:23;3286:33;3283:53;;;3332:1;3329;3322:12;3283:53;3371:9;3358:23;3390:31;3415:5;3390:31;:::i;:::-;3440:5;-1:-1:-1;3497:2:1;3482:18;;3469:32;3510:33;3469:32;3510:33;:::i;:::-;3562:7;-1:-1:-1;3616:2:1;3601:18;;3588:32;;-1:-1:-1;3671:2:1;3656:18;;3643:32;-1:-1:-1;;;;;3687:30:1;;3684:50;;;3730:1;3727;3720:12;3684:50;3753:22;;3806:4;3798:13;;3794:27;-1:-1:-1;3784:55:1;;3835:1;3832;3825:12;3784:55;3858:73;3923:7;3918:2;3905:16;3900:2;3896;3892:11;3858:73;:::i;:::-;3848:83;;;3143:794;;;;;;;:::o;4149:683::-;4247:6;4255;4263;4271;4279;4332:3;4320:9;4311:7;4307:23;4303:33;4300:53;;;4349:1;4346;4339:12;4300:53;4385:9;4372:23;4362:33;;4445:2;4434:9;4430:18;4417:32;4458:31;4483:5;4458:31;:::i;:::-;4508:5;-1:-1:-1;4564:2:1;4549:18;;4536:32;-1:-1:-1;;;;;4580:30:1;;4577:50;;;4623:1;4620;4613:12;4577:50;4662:59;4713:7;4704:6;4693:9;4689:22;4662:59;:::i;:::-;4149:683;;;;-1:-1:-1;4740:8:1;4822:2;4807:18;4794:32;;4149:683;-1:-1:-1;;;;4149:683:1:o;5104:383::-;5181:6;5189;5197;5250:2;5238:9;5229:7;5225:23;5221:32;5218:52;;;5266:1;5263;5256:12;5218:52;5305:9;5292:23;5324:31;5349:5;5324:31;:::i;:::-;5374:5;5426:2;5411:18;;5398:32;;-1:-1:-1;5477:2:1;5462:18;;;5449:32;;5104:383;-1:-1:-1;;;5104:383:1:o;5492:388::-;5560:6;5568;5621:2;5609:9;5600:7;5596:23;5592:32;5589:52;;;5637:1;5634;5627:12;5589:52;5676:9;5663:23;5695:31;5720:5;5695:31;:::i;:::-;5745:5;-1:-1:-1;5802:2:1;5787:18;;5774:32;5815:33;5774:32;5815:33;:::i;:::-;5867:7;5857:17;;;5492:388;;;;;:::o;5885:616::-;5937:3;5975:5;5969:12;6002:6;5997:3;5990:19;6028:4;6069:2;6064:3;6060:12;6094:11;6121;6114:18;;6171:6;6168:1;6164:14;6157:5;6153:26;6141:38;;6213:2;6206:5;6202:14;6234:1;6244:231;6258:6;6255:1;6252:13;6244:231;;;6329:5;6323:4;6319:16;6314:3;6307:29;6357:38;6390:4;6381:6;6375:13;6357:38;:::i;:::-;6453:12;;;;6349:46;-1:-1:-1;6418:15:1;;;;6280:1;6273:9;6244:231;;;-1:-1:-1;6491:4:1;;5885:616;-1:-1:-1;;;;;;;5885:616:1:o;6738:457::-;6795:3;6833:5;6827:12;6860:6;6855:3;6848:19;6886:4;6915:2;6910:3;6906:12;6899:19;;6952:2;6945:5;6941:14;6973:1;6983:187;6997:6;6994:1;6991:13;6983:187;;;7046:42;7084:3;7075:6;7069:13;6576:12;;6564:25;;6642:4;6631:16;;;6625:23;-1:-1:-1;;;;;6621:49:1;6605:14;;;6598:73;6720:4;6709:16;;;6703:23;6687:14;;6680:47;6506:227;7046:42;7117:4;7108:14;;;;;7145:15;;;;7019:1;7012:9;6983:187;;;-1:-1:-1;7186:3:1;;6738:457;-1:-1:-1;;;;;6738:457:1:o;7200:1078::-;7610:2;7622:21;;;7692:13;;7595:18;;;7714:22;;;7562:4;;7790;;7767:3;7752:19;;;7817:15;;;7562:4;7860:169;7874:6;7871:1;7868:13;7860:169;;;7935:13;;7923:26;;7969:12;;;;8004:15;;;;7896:1;7889:9;7860:169;;;7864:3;;;8074:9;8069:3;8065:19;8060:2;8049:9;8045:18;8038:47;8108:40;8144:3;8136:6;8108:40;:::i;:::-;8094:54;;;8196:9;8188:6;8184:22;8179:2;8168:9;8164:18;8157:50;8224:48;8265:6;8257;8224:48;:::i;:::-;8216:56;7200:1078;-1:-1:-1;;;;;;7200:1078:1:o;8283:221::-;8326:5;8379:3;8372:4;8364:6;8360:17;8356:27;8346:55;;8397:1;8394;8387:12;8346:55;8419:79;8494:3;8485:6;8472:20;8465:4;8457:6;8453:17;8419:79;:::i;8509:525::-;8596:6;8604;8612;8665:2;8653:9;8644:7;8640:23;8636:32;8633:52;;;8681:1;8678;8671:12;8633:52;8721:9;8708:23;-1:-1:-1;;;;;8746:6:1;8743:30;8740:50;;;8786:1;8783;8776:12;8740:50;8809;8851:7;8842:6;8831:9;8827:22;8809:50;:::i;:::-;8799:60;;;8909:2;8898:9;8894:18;8881:32;8922:31;8947:5;8922:31;:::i;:::-;8509:525;;8972:5;;-1:-1:-1;;;9024:2:1;9009:18;;;;8996:32;;8509:525::o;9039:411::-;9110:6;9118;9171:2;9159:9;9150:7;9146:23;9142:32;9139:52;;;9187:1;9184;9177:12;9139:52;9227:9;9214:23;-1:-1:-1;;;;;9252:6:1;9249:30;9246:50;;;9292:1;9289;9282:12;9246:50;9331:59;9382:7;9373:6;9362:9;9358:22;9331:59;:::i;:::-;9409:8;;9305:85;;-1:-1:-1;9039:411:1;-1:-1:-1;;;;9039:411:1:o;9455:461::-;9508:3;9546:5;9540:12;9573:6;9568:3;9561:19;9599:4;9628:2;9623:3;9619:12;9612:19;;9665:2;9658:5;9654:14;9686:1;9696:195;9710:6;9707:1;9704:13;9696:195;;;9775:13;;-1:-1:-1;;;;;9771:39:1;9759:52;;9831:12;;;;9866:15;;;;9807:1;9725:9;9696:195;;9921:1315;10197:4;10226:2;10255;10244:9;10237:21;10281:56;10333:2;10322:9;10318:18;10310:6;10281:56;:::i;:::-;10356:2;10406:9;10398:6;10394:22;10389:2;10378:9;10374:18;10367:50;10437:6;10472;10466:13;10503:6;10495;10488:22;10538:2;10530:6;10526:15;10519:22;;10597:2;10587:6;10584:1;10580:14;10572:6;10568:27;10564:36;10635:2;10627:6;10623:15;10656:1;10666:541;10680:6;10677:1;10674:13;10666:541;;;10770:2;10766:7;10757:6;10749;10745:19;10741:33;10736:3;10729:46;10804:6;10798:13;10834:4;10872:2;10866:9;10858:6;10851:25;10923:2;10919;10915:11;10909:18;10964:2;10959;10951:6;10947:15;10940:27;10994:48;11038:2;11030:6;11026:15;11012:12;10994:48;:::i;:::-;11085:11;;;11079:18;11062:15;;;11055:43;;;;-1:-1:-1;11185:12:1;;;;10980:62;-1:-1:-1;11150:15:1;;;;10702:1;10695:9;10666:541;;;-1:-1:-1;11224:6:1;;9921:1315;-1:-1:-1;;;;;;;;;;9921:1315:1:o;11241:315::-;11309:6;11317;11370:2;11358:9;11349:7;11345:23;11341:32;11338:52;;;11386:1;11383;11376:12;11338:52;11425:9;11412:23;11444:31;11469:5;11444:31;:::i;:::-;11494:5;11546:2;11531:18;;;;11518:32;;-1:-1:-1;;;11241:315:1:o;11561:319::-;11799:14;;11792:22;11774:41;;11761:3;11746:19;;11824:50;11870:2;11855:18;;11847:6;6576:12;;6564:25;;6642:4;6631:16;;;6625:23;-1:-1:-1;;;;;6621:49:1;6605:14;;;6598:73;6720:4;6709:16;;;6703:23;6687:14;;6680:47;6506:227;12093:614;12182:6;12190;12198;12206;12259:2;12247:9;12238:7;12234:23;12230:32;12227:52;;;12275:1;12272;12265:12;12227:52;12314:9;12301:23;12333:31;12358:5;12333:31;:::i;:::-;12383:5;-1:-1:-1;12439:2:1;12424:18;;12411:32;-1:-1:-1;;;;;12455:30:1;;12452:50;;;12498:1;12495;12488:12;12452:50;12537:59;12588:7;12579:6;12568:9;12564:22;12537:59;:::i;:::-;12093:614;;12615:8;;-1:-1:-1;12511:85:1;;12697:2;12682:18;12669:32;;12093:614;-1:-1:-1;;;;12093:614:1:o;12712:750::-;12807:6;12815;12823;12876:2;12864:9;12855:7;12851:23;12847:32;12844:52;;;12892:1;12889;12882:12;12844:52;12931:9;12918:23;12950:31;12975:5;12950:31;:::i;:::-;13000:5;-1:-1:-1;13056:2:1;13041:18;;13028:32;-1:-1:-1;;;;;13109:14:1;;;13106:34;;;13136:1;13133;13126:12;13106:34;13174:6;13163:9;13159:22;13149:32;;13219:7;13212:4;13208:2;13204:13;13200:27;13190:55;;13241:1;13238;13231:12;13190:55;13281:2;13268:16;13307:2;13299:6;13296:14;13293:34;;;13323:1;13320;13313:12;13293:34;13376:7;13371:2;13361:6;13358:1;13354:14;13350:2;13346:23;13342:32;13339:45;13336:65;;;13397:1;13394;13387:12;13336:65;13428:2;13424;13420:11;13410:21;;13450:6;13440:16;;;;;12712:750;;;;;:::o;13467:864::-;13773:2;13785:21;;;13855:13;;13758:18;;;13877:22;;;13725:4;;13952;;13930:2;13915:18;;;13979:15;;;13725:4;14022:185;14036:6;14033:1;14030:13;14022:185;;;14111:13;;14104:21;14097:29;14085:42;;14147:12;;;;14182:15;;;;14058:1;14051:9;14022:185;;;14026:3;;;14252:9;14247:3;14243:19;14238:2;14227:9;14223:18;14216:47;14280:45;14321:3;14313:6;14280:45;:::i;14518:261::-;14697:2;14686:9;14679:21;14660:4;14717:56;14769:2;14758:9;14754:18;14746:6;14717:56;:::i;14784:543::-;14872:6;14880;14933:2;14921:9;14912:7;14908:23;14904:32;14901:52;;;14949:1;14946;14939:12;14901:52;14989:9;14976:23;-1:-1:-1;;;;;15059:2:1;15051:6;15048:14;15045:34;;;15075:1;15072;15065:12;15045:34;15098:50;15140:7;15131:6;15120:9;15116:22;15098:50;:::i;:::-;15088:60;;15201:2;15190:9;15186:18;15173:32;15157:48;;15230:2;15220:8;15217:16;15214:36;;;15246:1;15243;15236:12;15214:36;;15269:52;15313:7;15302:8;15291:9;15287:24;15269:52;:::i;:::-;15259:62;;;14784:543;;;;;:::o;15524:280::-;15723:2;15712:9;15705:21;15686:4;15743:55;15794:2;15783:9;15779:18;15771:6;15743:55;:::i;15809:248::-;15877:6;15885;15938:2;15926:9;15917:7;15913:23;15909:32;15906:52;;;15954:1;15951;15944:12;15906:52;-1:-1:-1;;15977:23:1;;;16047:2;16032:18;;;16019:32;;-1:-1:-1;15809:248:1:o;16062:380::-;16141:1;16137:12;;;;16184;;;16205:61;;16259:4;16251:6;16247:17;16237:27;;16205:61;16312:2;16304:6;16301:14;16281:18;16278:38;16275:161;;16358:10;16353:3;16349:20;16346:1;16339:31;16393:4;16390:1;16383:15;16421:4;16418:1;16411:15;17498:273;17683:6;17675;17670:3;17657:33;17639:3;17709:16;;17734:13;;;17709:16;17498:273;-1:-1:-1;17498:273:1:o;17776:127::-;17837:10;17832:3;17828:20;17825:1;17818:31;17868:4;17865:1;17858:15;17892:4;17889:1;17882:15;17908:168;17981:9;;;18012;;18029:15;;;18023:22;;18009:37;17999:71;;18050:18;;:::i;18081:217::-;18121:1;18147;18137:132;;18191:10;18186:3;18182:20;18179:1;18172:31;18226:4;18223:1;18216:15;18254:4;18251:1;18244:15;18137:132;-1:-1:-1;18283:9:1;;18081:217::o;18303:135::-;18342:3;18363:17;;;18360:43;;18383:18;;:::i;:::-;-1:-1:-1;18430:1:1;18419:13;;18303:135::o;18443:375::-;-1:-1:-1;;;;;18701:15:1;;;18683:34;;18753:15;;;;18748:2;18733:18;;18726:43;18800:2;18785:18;;18778:34;;;;18633:2;18618:18;;18443:375::o;19783:545::-;19885:2;19880:3;19877:11;19874:448;;;19921:1;19946:5;19942:2;19935:17;19991:4;19987:2;19977:19;20061:2;20049:10;20045:19;20042:1;20038:27;20032:4;20028:38;20097:4;20085:10;20082:20;20079:47;;;-1:-1:-1;20120:4:1;20079:47;20175:2;20170:3;20166:12;20163:1;20159:20;20153:4;20149:31;20139:41;;20230:82;20248:2;20241:5;20238:13;20230:82;;;20293:17;;;20274:1;20263:13;20230:82;;;20234:3;;;19783:545;;;:::o;20504:1352::-;20630:3;20624:10;-1:-1:-1;;;;;20649:6:1;20646:30;20643:56;;;20679:18;;:::i;:::-;20708:97;20798:6;20758:38;20790:4;20784:11;20758:38;:::i;:::-;20752:4;20708:97;:::i;:::-;20860:4;;20924:2;20913:14;;20941:1;20936:663;;;;21643:1;21660:6;21657:89;;;-1:-1:-1;21712:19:1;;;21706:26;21657:89;-1:-1:-1;;20461:1:1;20457:11;;;20453:24;20449:29;20439:40;20485:1;20481:11;;;20436:57;21759:81;;20906:944;;20936:663;19730:1;19723:14;;;19767:4;19754:18;;-1:-1:-1;;20972:20:1;;;21090:236;21104:7;21101:1;21098:14;21090:236;;;21193:19;;;21187:26;21172:42;;21285:27;;;;21253:1;21241:14;;;;21120:19;;21090:236;;;21094:3;21354:6;21345:7;21342:19;21339:201;;;21415:19;;;21409:26;-1:-1:-1;;21498:1:1;21494:14;;;21510:3;21490:24;21486:37;21482:42;21467:58;21452:74;;21339:201;-1:-1:-1;;;;;21586:1:1;21570:14;;;21566:22;21553:36;;-1:-1:-1;20504:1352:1:o;21861:463::-;22048:2;22037:9;22030:21;22087:6;22082:2;22071:9;22067:18;22060:34;22144:6;22136;22131:2;22120:9;22116:18;22103:48;22200:1;22195:2;22186:6;22175:9;22171:22;22167:31;22160:42;22011:4;22270:2;22263;22259:7;22254:2;22246:6;22242:15;22238:29;22227:9;22223:45;22219:54;22211:62;;22311:6;22304:4;22293:9;22289:20;22282:36;21861:463;;;;;;:::o;23082:127::-;23143:10;23138:3;23134:20;23131:1;23124:31;23174:4;23171:1;23164:15;23198:4;23195:1;23188:15;23214:648;23294:6;23347:2;23335:9;23326:7;23322:23;23318:32;23315:52;;;23363:1;23360;23353:12;23315:52;23396:9;23390:16;-1:-1:-1;;;;;23421:6:1;23418:30;23415:50;;;23461:1;23458;23451:12;23415:50;23484:22;;23537:4;23529:13;;23525:27;-1:-1:-1;23515:55:1;;23566:1;23563;23556:12;23515:55;23595:2;23589:9;23620:48;23636:31;23664:2;23636:31;:::i;23620:48::-;23691:2;23684:5;23677:17;23731:7;23726:2;23721;23717;23713:11;23709:20;23706:33;23703:53;;;23752:1;23749;23742:12;23703:53;23765:67;23829:2;23824;23817:5;23813:14;23808:2;23804;23800:11;23765:67;:::i;:::-;23851:5;23214:648;-1:-1:-1;;;;;23214:648:1:o;24508:277::-;24575:6;24628:2;24616:9;24607:7;24603:23;24599:32;24596:52;;;24644:1;24641;24634:12;24596:52;24676:9;24670:16;24729:5;24722:13;24715:21;24708:5;24705:32;24695:60;;24751:1;24748;24741:12;25141:291;25318:2;25307:9;25300:21;25281:4;25338:45;25379:2;25368:9;25364:18;25356:6;25338:45;:::i;:::-;25330:53;;25419:6;25414:2;25403:9;25399:18;25392:34;25141:291;;;;;:::o;25437:1206::-;-1:-1:-1;;;;;25556:3:1;25553:27;25550:53;;;25583:18;;:::i;:::-;25612:94;25702:3;25662:38;25694:4;25688:11;25662:38;:::i;:::-;25656:4;25612:94;:::i;:::-;25732:1;25757:2;25752:3;25749:11;25774:1;25769:616;;;;26429:1;26446:3;26443:93;;;-1:-1:-1;26502:19:1;;;26489:33;26443:93;-1:-1:-1;;20461:1:1;20457:11;;;20453:24;20449:29;20439:40;20485:1;20481:11;;;20436:57;26549:78;;25742:895;;25769:616;19730:1;19723:14;;;19767:4;19754:18;;-1:-1:-1;;25805:17:1;;;25906:9;25928:229;25942:7;25939:1;25936:14;25928:229;;;26031:19;;;26018:33;26003:49;;26138:4;26123:20;;;;26091:1;26079:14;;;;25958:12;25928:229;;;25932:3;26185;26176:7;26173:16;26170:159;;;26309:1;26305:6;26299:3;26293;26290:1;26286:11;26282:21;26278:34;26274:39;26261:9;26256:3;26252:19;26239:33;26235:79;26227:6;26220:95;26170:159;;;26372:1;26366:3;26363:1;26359:11;26355:19;26349:4;26342:33;25742:895;;25437:1206;;;:::o;27354:289::-;27485:3;27523:6;27517:13;27539:66;27598:6;27593:3;27586:4;27578:6;27574:17;27539:66;:::i;:::-;27621:16;;;;;27354:289;-1:-1:-1;;27354:289:1:o;28776:128::-;28843:9;;;28864:11;;;28861:37;;;28878:18;;:::i;28909:127::-;28970:10;28965:3;28961:20;28958:1;28951:31;29001:4;28998:1;28991:15;29025:4;29022:1;29015:15
Swarm Source
ipfs://8aa449f8ab8f895565cc541e541bf512150ee00c885e7a4e9b83ac0bbc689444
Loading...
Loading
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.