ERC-721
Overview
Max Total Supply
34 PEPENFT
Holders
33
Market
Volume (24H)
N/A
Min Price (24H)
N/A
Max Price (24H)
N/A
Other Info
Token Contract
Balance
1 PEPENFTLoading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
PepeNFT
Compiler Version
v0.8.9+commit.e5eed63a
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2023-05-07 */ // 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/extensions/IERC20Metadata.sol // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.0; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); } // 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: @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/token/ERC20/ERC20.sol // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/ERC20.sol) pragma solidity ^0.8.0; /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20PresetMinterPauser}. * * TIP: For a detailed writeup see our guide * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * We have followed general OpenZeppelin Contracts guidelines: functions revert * instead returning `false` on failure. This behavior is nonetheless * conventional and does not conflict with the expectations of ERC20 * applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ contract ERC20 is Context, IERC20, IERC20Metadata { mapping(address => uint256) private _balances; mapping(address => mapping(address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; /** * @dev Sets the values for {name} and {symbol}. * * The default value of {decimals} is 18. To select a different value for * {decimals} you should overload it. * * All two of these values are immutable: they can only be set once during * construction. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev Returns the name of the token. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5.05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the value {ERC20} uses, unless this function is * overridden; * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view virtual override returns (uint8) { return 18; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual override returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `to` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address to, uint256 amount) public virtual override returns (bool) { address owner = _msgSender(); _transfer(owner, to, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on * `transferFrom`. This is semantically equivalent to an infinite approval. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public virtual override returns (bool) { address owner = _msgSender(); _approve(owner, spender, amount); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}. * * NOTE: Does not update the allowance if the current allowance * is the maximum `uint256`. * * Requirements: * * - `from` and `to` cannot be the zero address. * - `from` must have a balance of at least `amount`. * - the caller must have allowance for ``from``'s tokens of at least * `amount`. */ function transferFrom( address from, address to, uint256 amount ) public virtual override returns (bool) { address spender = _msgSender(); _spendAllowance(from, spender, amount); _transfer(from, to, amount); return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { address owner = _msgSender(); _approve(owner, spender, allowance(owner, spender) + addedValue); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { address owner = _msgSender(); uint256 currentAllowance = allowance(owner, spender); require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero"); unchecked { _approve(owner, spender, currentAllowance - subtractedValue); } return true; } /** * @dev Moves `amount` of tokens from `from` to `to`. * * This internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `from` must have a balance of at least `amount`. */ function _transfer( address from, address to, uint256 amount ) internal virtual { require(from != address(0), "ERC20: transfer from the zero address"); require(to != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(from, to, amount); uint256 fromBalance = _balances[from]; require(fromBalance >= amount, "ERC20: transfer amount exceeds balance"); unchecked { _balances[from] = fromBalance - amount; // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by // decrementing then incrementing. _balances[to] += amount; } emit Transfer(from, to, amount); _afterTokenTransfer(from, to, amount); } /** @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. */ function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); _totalSupply += amount; unchecked { // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above. _balances[account] += amount; } emit Transfer(address(0), account, amount); _afterTokenTransfer(address(0), account, amount); } /** * @dev Destroys `amount` tokens from `account`, reducing the * total supply. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); uint256 accountBalance = _balances[account]; require(accountBalance >= amount, "ERC20: burn amount exceeds balance"); unchecked { _balances[account] = accountBalance - amount; // Overflow not possible: amount <= accountBalance <= totalSupply. _totalSupply -= amount; } emit Transfer(account, address(0), amount); _afterTokenTransfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. * * This internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function _approve( address owner, address spender, uint256 amount ) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Updates `owner` s allowance for `spender` based on spent `amount`. * * Does not update the allowance amount in case of infinite allowance. * Revert if not enough allowance is available. * * Might emit an {Approval} event. */ function _spendAllowance( address owner, address spender, uint256 amount ) internal virtual { uint256 currentAllowance = allowance(owner, spender); if (currentAllowance != type(uint256).max) { require(currentAllowance >= amount, "ERC20: insufficient allowance"); unchecked { _approve(owner, spender, currentAllowance - amount); } } } /** * @dev Hook that is called before any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * will be transferred to `to`. * - when `from` is zero, `amount` tokens will be minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 amount ) internal virtual {} /** * @dev Hook that is called after any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * has been transferred to `to`. * - when `from` is zero, `amount` tokens have been minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens have been burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer( address from, address to, uint256 amount ) internal virtual {} } // 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: contracts/Pepe.sol pragma solidity ^0.8.9; contract PepeToken is Ownable, ERC20 { bool public limited; uint256 public maxHoldingAmount; uint256 public minHoldingAmount; address public uniswapV2Pair; mapping(address => bool) public blacklists; constructor(uint256 _totalSupply) ERC20("Pepe", "PEPE") { _mint(msg.sender, _totalSupply); } function blacklist(address _address, bool _isBlacklisting) external onlyOwner { blacklists[_address] = _isBlacklisting; } function setRule(bool _limited, address _uniswapV2Pair, uint256 _maxHoldingAmount, uint256 _minHoldingAmount) external onlyOwner { limited = _limited; uniswapV2Pair = _uniswapV2Pair; maxHoldingAmount = _maxHoldingAmount; minHoldingAmount = _minHoldingAmount; } function _beforeTokenTransfer( address from, address to, uint256 amount ) override internal virtual { require(!blacklists[to] && !blacklists[from], "Blacklisted"); if (uniswapV2Pair == address(0)) { require(from == owner() || to == owner(), "trading is not started"); return; } if (limited && from == uniswapV2Pair) { require(super.balanceOf(to) + amount <= maxHoldingAmount && super.balanceOf(to) + amount >= minHoldingAmount, "Forbid"); } } function burn(uint256 value) external { _burn(msg.sender, value); } } // File: contracts/Dividends.sol pragma solidity ^0.8.9; /** * Standard SafeMath, stripped down to just add/sub/mul/div */ library SafeMath { function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } function sub(uint256 a, uint256 b) internal pure returns (uint256) { return sub(a, b, "SafeMath: subtraction overflow"); } function sub( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { require(b <= a, errorMessage); uint256 c = a - b; return c; } function mul(uint256 a, uint256 b) internal pure returns (uint256) { if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } function div(uint256 a, uint256 b) internal pure returns (uint256) { return div(a, b, "SafeMath: division by zero"); } function div( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { // Solidity only automatically asserts when dividing by 0 require(b > 0, errorMessage); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } } interface IDEXFactory { function createPair( address tokenA, address tokenB ) external returns (address pair); } interface IDEXRouter { function factory() external pure returns (address); function WETH() external pure returns (address); function swapExactETHForTokens( uint256 amountOutMin, address[] calldata path, address to, uint256 deadline ) external payable returns (uint256[] memory amounts); } interface IDividendDistributor { function setShare(address shareholder, uint256 amount) external; function deposit(uint256 amount) external; function claimDividend(address shareholder) external; function getDividendsClaimedOf( address shareholder ) external returns (uint256); } contract DividendDistributor is IDividendDistributor { using SafeMath for uint256; address public _token; address public _owner; address public immutable PEPE = address(0x6982508145454Ce325dDbE47a25d4ec3d2311933); //UNI struct Share { uint256 amount; uint256 totalExcluded; uint256 totalClaimed; } address[] private shareholders; mapping(address => uint256) private shareholderIndexes; mapping(address => Share) public shares; uint256 public totalShares; uint256 public totalDividends; uint256 public totalClaimed; uint256 public dividendsPerShare; uint256 private dividendsPerShareAccuracyFactor = 10 ** 36; modifier onlyToken() { require(msg.sender == _token); _; } modifier onlyOwner() { require(msg.sender == _owner); _; } constructor(address owner) { _token = msg.sender; _owner = owner; } receive() external payable {} function setShare( address shareholder, uint256 amount ) external override onlyToken { if (shares[shareholder].amount > 0) { distributeDividend(shareholder); } if (amount > 0 && shares[shareholder].amount == 0) { addShareholder(shareholder); } else if (amount == 0 && shares[shareholder].amount > 0) { removeShareholder(shareholder); } totalShares = totalShares.sub(shares[shareholder].amount).add(amount); shares[shareholder].amount = amount; shares[shareholder].totalExcluded = getCumulativeDividends( shares[shareholder].amount ); } function deposit(uint256 amount) external override onlyToken { if (amount > 0) { totalDividends = totalDividends.add(amount); dividendsPerShare = dividendsPerShare.add( dividendsPerShareAccuracyFactor.mul(amount).div(totalShares) ); } } function distributeDividend(address shareholder) internal { if (shares[shareholder].amount == 0) { return; } uint256 amount = getClaimableDividendOf(shareholder); if (amount > 0) { totalClaimed = totalClaimed.add(amount); shares[shareholder].totalClaimed = shares[shareholder] .totalClaimed .add(amount); shares[shareholder].totalExcluded = getCumulativeDividends( shares[shareholder].amount ); IERC20(PEPE).transfer(shareholder, amount); } } function claimDividend(address shareholder) external override onlyToken { distributeDividend(shareholder); } function getClaimableDividendOf( address shareholder ) public view returns (uint256) { if (shares[shareholder].amount == 0) { return 0; } uint256 shareholderTotalDividends = getCumulativeDividends( shares[shareholder].amount ); uint256 shareholderTotalExcluded = shares[shareholder].totalExcluded; if (shareholderTotalDividends <= shareholderTotalExcluded) { return 0; } return shareholderTotalDividends.sub(shareholderTotalExcluded); } function getCumulativeDividends( uint256 share ) internal view returns (uint256) { return share.mul(dividendsPerShare).div(dividendsPerShareAccuracyFactor); } function addShareholder(address shareholder) internal { shareholderIndexes[shareholder] = shareholders.length; shareholders.push(shareholder); } function removeShareholder(address shareholder) internal { shareholders[shareholderIndexes[shareholder]] = shareholders[ shareholders.length - 1 ]; shareholderIndexes[ shareholders[shareholders.length - 1] ] = shareholderIndexes[shareholder]; shareholders.pop(); } function manualSend(uint256 amount, address holder) external onlyOwner { uint256 contractETHBalance = address(this).balance; payable(holder).transfer(amount > 0 ? amount : contractETHBalance); } function getDividendsClaimedOf( address shareholder ) external view returns (uint256) { require( shares[shareholder].amount > 0, "You're not a PRINTER shareholder!" ); return shares[shareholder].totalClaimed; } } // File: @openzeppelin/contracts/utils/Address.sol // OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } // File: @openzeppelin/contracts/token/ERC721/IERC721Receiver.sol // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol) pragma solidity ^0.8.0; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); } // File: @openzeppelin/contracts/utils/introspection/IERC165.sol // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) 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/interfaces/IERC2981.sol // OpenZeppelin Contracts (last updated v4.6.0) (interfaces/IERC2981.sol) pragma solidity ^0.8.0; /** * @dev Interface for the NFT Royalty Standard. * * A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal * support for royalty payments across all NFT marketplaces and ecosystem participants. * * _Available since v4.5._ */ interface IERC2981 is IERC165 { /** * @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of * exchange. The royalty amount is denominated and should be paid in that same unit of exchange. */ function royaltyInfo(uint256 tokenId, uint256 salePrice) external view returns (address receiver, uint256 royaltyAmount); } // 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/common/ERC2981.sol // OpenZeppelin Contracts (last updated v4.7.0) (token/common/ERC2981.sol) pragma solidity ^0.8.0; /** * @dev Implementation of the NFT Royalty Standard, a standardized way to retrieve royalty payment information. * * Royalty information can be specified globally for all token ids via {_setDefaultRoyalty}, and/or individually for * specific token ids via {_setTokenRoyalty}. The latter takes precedence over the first. * * Royalty is specified as a fraction of sale price. {_feeDenominator} is overridable but defaults to 10000, meaning the * fee is specified in basis points by default. * * IMPORTANT: ERC-2981 only specifies a way to signal royalty information and does not enforce its payment. See * https://eips.ethereum.org/EIPS/eip-2981#optional-royalty-payments[Rationale] in the EIP. Marketplaces are expected to * voluntarily pay royalties together with sales, but note that this standard is not yet widely supported. * * _Available since v4.5._ */ abstract contract ERC2981 is IERC2981, ERC165 { struct RoyaltyInfo { address receiver; uint96 royaltyFraction; } RoyaltyInfo private _defaultRoyaltyInfo; mapping(uint256 => RoyaltyInfo) private _tokenRoyaltyInfo; /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) { return interfaceId == type(IERC2981).interfaceId || super.supportsInterface(interfaceId); } /** * @inheritdoc IERC2981 */ function royaltyInfo(uint256 _tokenId, uint256 _salePrice) public view virtual override returns (address, uint256) { RoyaltyInfo memory royalty = _tokenRoyaltyInfo[_tokenId]; if (royalty.receiver == address(0)) { royalty = _defaultRoyaltyInfo; } uint256 royaltyAmount = (_salePrice * royalty.royaltyFraction) / _feeDenominator(); return (royalty.receiver, royaltyAmount); } /** * @dev The denominator with which to interpret the fee set in {_setTokenRoyalty} and {_setDefaultRoyalty} as a * fraction of the sale price. Defaults to 10000 so fees are expressed in basis points, but may be customized by an * override. */ function _feeDenominator() internal pure virtual returns (uint96) { return 10000; } /** * @dev Sets the royalty information that all ids in this contract will default to. * * Requirements: * * - `receiver` cannot be the zero address. * - `feeNumerator` cannot be greater than the fee denominator. */ function _setDefaultRoyalty(address receiver, uint96 feeNumerator) internal virtual { require(feeNumerator <= _feeDenominator(), "ERC2981: royalty fee will exceed salePrice"); require(receiver != address(0), "ERC2981: invalid receiver"); _defaultRoyaltyInfo = RoyaltyInfo(receiver, feeNumerator); } /** * @dev Removes default royalty information. */ function _deleteDefaultRoyalty() internal virtual { delete _defaultRoyaltyInfo; } /** * @dev Sets the royalty information for a specific token id, overriding the global default. * * Requirements: * * - `receiver` cannot be the zero address. * - `feeNumerator` cannot be greater than the fee denominator. */ function _setTokenRoyalty( uint256 tokenId, address receiver, uint96 feeNumerator ) internal virtual { require(feeNumerator <= _feeDenominator(), "ERC2981: royalty fee will exceed salePrice"); require(receiver != address(0), "ERC2981: Invalid parameters"); _tokenRoyaltyInfo[tokenId] = RoyaltyInfo(receiver, feeNumerator); } /** * @dev Resets royalty information for the token id back to the global default. */ function _resetTokenRoyalty(uint256 tokenId) internal virtual { delete _tokenRoyaltyInfo[tokenId]; } } // 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/IERC721Enumerable.sol // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol) pragma solidity ^0.8.0; /** * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Enumerable is IERC721 { /** * @dev Returns the total amount of tokens stored by the contract. */ function totalSupply() external view returns (uint256); /** * @dev Returns a token ID owned by `owner` at a given `index` of its token list. * Use along with {balanceOf} to enumerate all of ``owner``'s tokens. */ function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256); /** * @dev Returns a token ID at a given `index` of all the tokens stored by the contract. * Use along with {totalSupply} to enumerate all tokens. */ function tokenByIndex(uint256 index) external view returns (uint256); } // 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/token/ERC721/ERC721.sol // OpenZeppelin Contracts (last updated v4.8.2) (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 {} /** * @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 {} /** * @dev Unsafe write access to the balances, used by extensions that "mint" tokens using an {ownerOf} override. * * WARNING: Anyone calling this MUST ensure that the balances remain consistent with the ownership. The invariant * being that for any address `a` the value returned by `balanceOf(a)` must be equal to the number of tokens such * that `ownerOf(tokenId)` is `a`. */ // solhint-disable-next-line func-name-mixedcase function __unsafe_increaseBalance(address account, uint256 amount) internal { _balances[account] += amount; } } // File: @openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721URIStorage.sol) pragma solidity ^0.8.0; /** * @dev ERC721 token with storage based token URI management. */ abstract contract ERC721URIStorage is ERC721 { using Strings for uint256; // Optional mapping for token URIs mapping(uint256 => string) private _tokenURIs; /** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { _requireMinted(tokenId); string memory _tokenURI = _tokenURIs[tokenId]; string memory base = _baseURI(); // If there is no base URI, return the token URI. if (bytes(base).length == 0) { return _tokenURI; } // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked). if (bytes(_tokenURI).length > 0) { return string(abi.encodePacked(base, _tokenURI)); } return super.tokenURI(tokenId); } /** * @dev Sets `_tokenURI` as the tokenURI of `tokenId`. * * Requirements: * * - `tokenId` must exist. */ function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual { require(_exists(tokenId), "ERC721URIStorage: URI set of nonexistent token"); _tokenURIs[tokenId] = _tokenURI; } /** * @dev See {ERC721-_burn}. This override additionally checks to see if a * token-specific URI was set for the token, and if so, it deletes the token URI from * the storage mapping. */ function _burn(uint256 tokenId) internal virtual override { super._burn(tokenId); if (bytes(_tokenURIs[tokenId]).length != 0) { delete _tokenURIs[tokenId]; } } } // File: @openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/extensions/ERC721Enumerable.sol) pragma solidity ^0.8.0; /** * @dev This implements an optional extension of {ERC721} defined in the EIP that adds * enumerability of all the token ids in the contract as well as all token ids owned by each * account. */ abstract contract ERC721Enumerable is ERC721, IERC721Enumerable { // Mapping from owner to list of owned token IDs mapping(address => mapping(uint256 => uint256)) private _ownedTokens; // Mapping from token ID to index of the owner tokens list mapping(uint256 => uint256) private _ownedTokensIndex; // Array with all token ids, used for enumeration uint256[] private _allTokens; // Mapping from token id to position in the allTokens array mapping(uint256 => uint256) private _allTokensIndex; /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) { return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}. */ function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) { require(index < ERC721.balanceOf(owner), "ERC721Enumerable: owner index out of bounds"); return _ownedTokens[owner][index]; } /** * @dev See {IERC721Enumerable-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _allTokens.length; } /** * @dev See {IERC721Enumerable-tokenByIndex}. */ function tokenByIndex(uint256 index) public view virtual override returns (uint256) { require(index < ERC721Enumerable.totalSupply(), "ERC721Enumerable: global index out of bounds"); return _allTokens[index]; } /** * @dev See {ERC721-_beforeTokenTransfer}. */ function _beforeTokenTransfer( address from, address to, uint256 firstTokenId, uint256 batchSize ) internal virtual override { super._beforeTokenTransfer(from, to, firstTokenId, batchSize); if (batchSize > 1) { // Will only trigger during construction. Batch transferring (minting) is not available afterwards. revert("ERC721Enumerable: consecutive transfers not supported"); } uint256 tokenId = firstTokenId; if (from == address(0)) { _addTokenToAllTokensEnumeration(tokenId); } else if (from != to) { _removeTokenFromOwnerEnumeration(from, tokenId); } if (to == address(0)) { _removeTokenFromAllTokensEnumeration(tokenId); } else if (to != from) { _addTokenToOwnerEnumeration(to, tokenId); } } /** * @dev Private function to add a token to this extension's ownership-tracking data structures. * @param to address representing the new owner of the given token ID * @param tokenId uint256 ID of the token to be added to the tokens list of the given address */ function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private { uint256 length = ERC721.balanceOf(to); _ownedTokens[to][length] = tokenId; _ownedTokensIndex[tokenId] = length; } /** * @dev Private function to add a token to this extension's token tracking data structures. * @param tokenId uint256 ID of the token to be added to the tokens list */ function _addTokenToAllTokensEnumeration(uint256 tokenId) private { _allTokensIndex[tokenId] = _allTokens.length; _allTokens.push(tokenId); } /** * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for * gas optimizations e.g. when performing a transfer operation (avoiding double writes). * This has O(1) time complexity, but alters the order of the _ownedTokens array. * @param from address representing the previous owner of the given token ID * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address */ function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private { // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and // then delete the last slot (swap and pop). uint256 lastTokenIndex = ERC721.balanceOf(from) - 1; uint256 tokenIndex = _ownedTokensIndex[tokenId]; // When the token to delete is the last token, the swap operation is unnecessary if (tokenIndex != lastTokenIndex) { uint256 lastTokenId = _ownedTokens[from][lastTokenIndex]; _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index } // This also deletes the contents at the last position of the array delete _ownedTokensIndex[tokenId]; delete _ownedTokens[from][lastTokenIndex]; } /** * @dev Private function to remove a token from this extension's token tracking data structures. * This has O(1) time complexity, but alters the order of the _allTokens array. * @param tokenId uint256 ID of the token to be removed from the tokens list */ function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private { // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and // then delete the last slot (swap and pop). uint256 lastTokenIndex = _allTokens.length - 1; uint256 tokenIndex = _allTokensIndex[tokenId]; // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding // an 'if' statement (like in _removeTokenFromOwnerEnumeration) uint256 lastTokenId = _allTokens[lastTokenIndex]; _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index // This also deletes the contents at the last position of the array delete _allTokensIndex[tokenId]; _allTokens.pop(); } } // File: contracts/PepeNFT.sol pragma solidity ^0.8.9; // ERC 721 Imports for NFT contract standard // ERC 2981 Imports for royalty standard // Counters Imports for token ID management contract PepeNFT is ERC721, ERC721Enumerable, ERC721URIStorage, ERC2981, Ownable { using Counters for Counters.Counter; using SafeMath for uint256; // PEPE dividend contract related // ----------------------------------------- address private WETH; mapping(address => bool) private isDividendExempt; IDEXRouter public router; address public immutable UNISWAPV2_ROUTER_ADDRESS = address(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D); DividendDistributor private distributor; // ----------------------------------------- // all related to NFT // ----------------------------------------- Counters.Counter private _tokenIdCounter; bool _isMintingActive = false; // ipfs uri relared string private base; string private tokenPrefix; string private tokenExtension; // price per token is 0.01 ETH uint256 public ETH_PRICE = 10000000000000000; // price per token is 10M PEPE uint256 public PEPE_PRICE = 10000000000000000000000000; // max number of tokens to mint uint256 public constant MAX_TOKENS = 10000; // max number of tokens to mint per transaction uint256 public constant MAX_TOKENS_PER_TX = 20; // max number of tokens to mint per wallet uint256 public constant MAX_TOKENS_PER_WALLET = 100; // royalties are 2% of the sale price, denoted in BPS (1/10000) uint256 public constant ROYALTY_FEE = 200; // address of PEPE token. We will be accepting this token as payment alongside ETH address public immutable PEPE_TOKEN_ADDRESS = address(0x6982508145454Ce325dDbE47a25d4ec3d2311933); IERC20 private pepeContract; // ----------------------------------------- // make sure to have / at the end of base URI constructor() ERC721("Pepe NFT", "PEPENFT") { base = "ipfs://bafybeicthcikij6lgf32yecyxrfayj222ci3l5bae7hneyhakz64slri7e/"; tokenPrefix = "pepe_"; tokenExtension = ".json"; // this is uniswap v2 router address pepeContract = IERC20(PEPE_TOKEN_ADDRESS); router = IDEXRouter(UNISWAPV2_ROUTER_ADDRESS); WETH = router.WETH(); distributor = new DividendDistributor(owner()); isDividendExempt[address(this)] = true; _tokenIdCounter.increment(); } function setPrice(uint256 newETHPrice, uint256 newPEPEPrice) public onlyOwner { ETH_PRICE = newETHPrice; PEPE_PRICE = newPEPEPrice; } function approve(address to, uint256 tokenId) public virtual override { super.approve(to, tokenId); } function setApprovalForAll(address operator, bool approved) public virtual override { super.setApprovalForAll(operator, approved); } // airdrop first 69 tokens to wallets given to the function function airdrop(address[] calldata wallets, bool[] calldata allowed) public onlyOwner { require(!_isMintingActive && totalSupply() == 0, "Minting is active"); for (uint256 i = 0; i < wallets.length; i++) { mintNFT(wallets[i]); if (allowed[i]) { setShare(wallets[i], false); } } } // helper to flip the minting switch function flipMintingState() public onlyOwner { _isMintingActive = !_isMintingActive; } // base URI for token metadata. setter and getter function _baseURI() internal view override returns (string memory) { return base; } function mintNFT(address to) private { uint256 tokenId = _tokenIdCounter.current(); _tokenIdCounter.increment(); _safeMint(to, tokenId); string memory tokenUri = string( abi.encodePacked( tokenPrefix, Strings.toString(tokenId), tokenExtension ) ); _setTokenURI(tokenId, tokenUri); } function _mintNFTs(address to, uint256 numberOfTokens) private { for (uint256 i = 0; i < numberOfTokens; i++) { mintNFT(to); } } function getShareMultiplier(uint256 tokenId) internal pure returns (uint256) { uint256 multiplier = 2; if (tokenId > 0 && tokenId < 1001) { multiplier = 10; } else if (tokenId > 1000 && tokenId < 2001) { multiplier = 9; } else if (tokenId > 2000 && tokenId < 3001) { multiplier = 8; } else if (tokenId > 3000 && tokenId < 4001) { multiplier = 7; } else if (tokenId > 4000 && tokenId < 5001) { multiplier = 6; } else if (tokenId > 5000 && tokenId < 6001) { multiplier = 5; } else if (tokenId > 6000 && tokenId < 7001) { multiplier = 4; } else if (tokenId > 7000 && tokenId < 8001) { multiplier = 3; } return multiplier; } function getShare(address holder) internal view returns (uint256) { uint256 share = 0; uint256 balance = balanceOf(holder); for (uint256 i = 0; i < balance; i++) { uint256 tokenId = tokenOfOwnerByIndex(holder, i); uint256 multiplier = getShareMultiplier(tokenId); share = share.add(multiplier); } return share; } function setShare(address sender, bool callDeposit) internal { // set the holder's share to the current balance if (!isDividendExempt[sender]) { try distributor.setShare(sender, getShare(sender)) {} catch {} } if (callDeposit) { depositDividends(); } } function mintNFTs(uint256 numberOfTokens, bool buyWithPepe) external payable { require(_isMintingActive, "Minting is not active"); require( numberOfTokens <= MAX_TOKENS_PER_TX, "Max tokens per transaction exceeded" ); require( balanceOf(msg.sender).add(numberOfTokens) <= MAX_TOKENS_PER_WALLET, "Max tokens per wallet exceeded" ); require( totalSupply().add(numberOfTokens) <= MAX_TOKENS, "Not enough tokens left. Decrease the number of tokens to mint" ); if (buyWithPepe) { uint256 pepeAmount = PEPE_PRICE.mul(numberOfTokens); require( pepeContract.balanceOf(msg.sender) >= pepeAmount, "Not enough PEPE sent" ); _mintNFTs(msg.sender, numberOfTokens); // send to contract pepeContract.transferFrom( msg.sender, address(this), pepeAmount.mul(8000).div(10000) ); // send to owner pepeContract.transferFrom( msg.sender, owner(), pepeAmount.mul(2000).div(10000) ); } else { require( msg.value >= ETH_PRICE.mul(numberOfTokens), "Not enough ETH sent" ); _mintNFTs(msg.sender, numberOfTokens); // use 30% of the ETH to buy the token uint256 ethToSwap = msg.value.mul(7000).div(10000); swapETHForPEPE(ethToSwap); // send the remaining ETH to the owner payable(owner()).transfer(msg.value.sub(ethToSwap)); } setShare(msg.sender, true); } function royaltyInfo(uint256, uint256 salePrice) public view override returns (address receiver, uint256 royaltyAmount) { return (address(this), (salePrice.mul(ROYALTY_FEE)).div(10000)); } receive() external payable { // when we receive ETH, we swap one half for PEPE and deposit the other half to owner swapETHForPEPE(msg.value.div(2)); payable(owner()).transfer(msg.value.div(2)); depositDividends(); } // The following functions are overrides required by Solidity. function _beforeTokenTransfer( address from, address to, uint256 tokenId, uint256 batchSize ) internal override(ERC721, ERC721Enumerable) { super._beforeTokenTransfer(from, to, tokenId, batchSize); // check if from and to are both not zero address if (from != address(0) && to != address(0)) { setShare(from, true); setShare(to, true); } } function _burn(uint256 tokenId) internal override(ERC721, ERC721URIStorage) { super._burn(tokenId); } function tokenURI(uint256 tokenId) public view override(ERC721, ERC721URIStorage) returns (string memory) { return super.tokenURI(tokenId); } function supportsInterface(bytes4 interfaceId) public view override(ERC721, ERC721Enumerable, ERC2981) returns (bool) { return super.supportsInterface(interfaceId); } // PEPE and distrubutor related functions function depositDividends() internal { uint256 dividends = pepeContract.balanceOf(address(this)); bool success = pepeContract.transfer(address(distributor), dividends); if (success) { distributor.deposit(dividends); } } function swapETHForPEPE(uint256 ethAmount) internal { address[] memory path = new address[](2); path[0] = WETH; path[1] = PEPE_TOKEN_ADDRESS; // make the swap router.swapExactETHForTokens{value: ethAmount}( 0, path, address(this), block.timestamp.add(300) ); } function setIsDividendExempt(address holder, bool exempt) public onlyOwner { require(holder != address(this)); isDividendExempt[holder] = exempt; if (exempt) { distributor.setShare(holder, 0); } else { distributor.setShare(holder, balanceOf(holder)); } } function claimDividend() external { distributor.claimDividend(msg.sender); } function claimDividendFor(address holder) external onlyOwner { distributor.claimDividend(holder); } function getClaimableDividendOf(address shareholder) public view returns (uint256) { return distributor.getClaimableDividendOf(shareholder); } function getTotalDividends() external view returns (uint256) { return distributor.totalDividends(); } function getTotalClaimed() external view returns (uint256) { return distributor.totalClaimed(); } function getDividendsClaimedOf(address shareholder) external view returns (uint256) { return distributor.getDividendsClaimedOf(shareholder); } function manualSend(address toAddress) external onlyOwner { payable(toAddress).transfer(address(this).balance); pepeContract.transfer(toAddress, pepeContract.balanceOf(address(this))); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"ETH_PRICE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_TOKENS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_TOKENS_PER_TX","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_TOKENS_PER_WALLET","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PEPE_PRICE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PEPE_TOKEN_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ROYALTY_FEE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"UNISWAPV2_ROUTER_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"wallets","type":"address[]"},{"internalType":"bool[]","name":"allowed","type":"bool[]"}],"name":"airdrop","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimDividend","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"holder","type":"address"}],"name":"claimDividendFor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"flipMintingState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"shareholder","type":"address"}],"name":"getClaimableDividendOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"shareholder","type":"address"}],"name":"getDividendsClaimedOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalClaimed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalDividends","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"toAddress","type":"address"}],"name":"manualSend","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"numberOfTokens","type":"uint256"},{"internalType":"bool","name":"buyWithPepe","type":"bool"}],"name":"mintNFTs","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"router","outputs":[{"internalType":"contract IDEXRouter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"royaltyAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"holder","type":"address"},{"internalType":"bool","name":"exempt","type":"bool"}],"name":"setIsDividendExempt","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newETHPrice","type":"uint256"},{"internalType":"uint256","name":"newPEPEPrice","type":"uint256"}],"name":"setPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60c0604052737a250d5630b4cf539739df2c5dacb4c659f2488d6080526013805460ff19169055662386f26fc100006017556a084595161401484a000000601855736982508145454ce325ddbe47a25d4ec3d231193360a0523480156200006557600080fd5b50604080518082018252600881526714195c194813919560c21b6020808301918252835180850190945260078452661411541153919560ca1b908401528151919291620000b59160009162000331565b508051620000cb90600190602084019062000331565b505050620000e8620000e2620002d260201b60201c565b620002d6565b60405180608001604052806043815260200162004863604391398051620001189160149160209091019062000331565b5060408051808201909152600580825264706570655f60d81b6020909201918252620001479160159162000331565b5060408051808201909152600580825264173539b7b760d91b6020909201918252620001769160169162000331565b5060a051601980546001600160a01b03199081166001600160a01b03938416179091556080516010805490921692169182179055604080516315ab88c960e31b8152905163ad5c464891600480820192602092909190829003018186803b158015620001e157600080fd5b505afa158015620001f6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200021c9190620003e5565b600e80546001600160a01b0319166001600160a01b03928316179055600d54166040516200024a90620003c0565b6001600160a01b039091168152602001604051809103906000f08015801562000277573d6000803e3d6000fd5b50601180546001600160a01b0319166001600160a01b0392909216919091179055306000908152600f60209081526040909120805460ff19166001179055620002cc9060129062000328811b6200194e17901c565b62000454565b3390565b600d80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b80546001019055565b8280546200033f9062000417565b90600052602060002090601f016020900481019282620003635760008555620003ae565b82601f106200037e57805160ff1916838001178555620003ae565b82800160010185558215620003ae579182015b82811115620003ae57825182559160200191906001019062000391565b50620003bc929150620003ce565b5090565b610da88062003abb83390190565b5b80821115620003bc5760008155600101620003cf565b600060208284031215620003f857600080fd5b81516001600160a01b03811681146200041057600080fd5b9392505050565b600181811c908216806200042c57607f821691505b602082108114156200044e57634e487b7160e01b600052602260045260246000fd5b50919050565b60805160a05161363a62000481600039600081816102fb0152610890015260006105cf015261363a6000f3fe60806040526004361061024a5760003560e01c80638832bc2911610139578063d81049ef116100b6578063f2fde38b1161007a578063f2fde38b14610737578063f47c84c514610757578063f655ff221461076d578063f708a64f14610782578063f7d97577146107a2578063f887ea40146107c257600080fd5b8063d81049ef14610691578063e0c23b94146106a4578063e985e9c5146106b9578063edf3525314610702578063f0fc6bca1461072257600080fd5b8063a22cb465116100fd578063a22cb46514610606578063a85e1dea14610626578063b88d4fde1461063c578063c87b56dd1461065c578063d1bdb1d11461067c57600080fd5b80638832bc29146105695780638da5cb5b1461057f5780638ecc37fb1461059d578063932da039146105bd57806395d89b41146105f157600080fd5b8063335477fc116101c75780636352211e1161018b5780636352211e146104ea57806367ee5f091461050a57806370a082311461051f578063715018a61461053f578063736a83a11461055457600080fd5b8063335477fc1461045557806342842e0e1461046a5780634f6ccce71461048a5780635cc33f74146104aa57806360a6f45a146104ca57600080fd5b806316334de71161020e57806316334de71461039757806318160ddd146103b757806323b872dd146103d65780632a55205a146103f65780632f745c591461043557600080fd5b806301ffc9a7146102b45780630323fd6e146102e957806306fdde0314610335578063081812fc14610357578063095ea7b31461037757600080fd5b366102af5761026261025d3460026107e2565b61082d565b600d546001600160a01b03166108fc61027c3460026107e2565b6040518115909202916000818181858888f193505050501580156102a4573d6000803e3d6000fd5b506102ad61096c565b005b600080fd5b3480156102c057600080fd5b506102d46102cf366004612daa565b610ae2565b60405190151581526020015b60405180910390f35b3480156102f557600080fd5b5061031d7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020016102e0565b34801561034157600080fd5b5061034a610aed565b6040516102e09190612e1f565b34801561036357600080fd5b5061031d610372366004612e32565b610b7f565b34801561038357600080fd5b506102ad610392366004612e67565b610ba6565b3480156103a357600080fd5b506102ad6103b2366004612ed6565b610bb0565b3480156103c357600080fd5b506008545b6040519081526020016102e0565b3480156103e257600080fd5b506102ad6103f1366004612f42565b610cc0565b34801561040257600080fd5b50610416610411366004612f7e565b610cf1565b604080516001600160a01b0390931683526020830191909152016102e0565b34801561044157600080fd5b506103c8610450366004612e67565b610d18565b34801561046157600080fd5b506103c860c881565b34801561047657600080fd5b506102ad610485366004612f42565b610dae565b34801561049657600080fd5b506103c86104a5366004612e32565b610dc9565b3480156104b657600080fd5b506103c86104c5366004612fa0565b610e5c565b3480156104d657600080fd5b506102ad6104e5366004612fa0565b610edb565b3480156104f657600080fd5b5061031d610505366004612e32565b61101c565b34801561051657600080fd5b506103c861107c565b34801561052b57600080fd5b506103c861053a366004612fa0565b6110fe565b34801561054b57600080fd5b506102ad611184565b34801561056057600080fd5b506103c8611198565b34801561057557600080fd5b506103c860175481565b34801561058b57600080fd5b50600d546001600160a01b031661031d565b3480156105a957600080fd5b506103c86105b8366004612fa0565b6111dd565b3480156105c957600080fd5b5061031d7f000000000000000000000000000000000000000000000000000000000000000081565b3480156105fd57600080fd5b5061034a611210565b34801561061257600080fd5b506102ad610621366004612fc9565b61121f565b34801561063257600080fd5b506103c860185481565b34801561064857600080fd5b506102ad610657366004613047565b611229565b34801561066857600080fd5b5061034a610677366004612e32565b611261565b34801561068857600080fd5b506103c8606481565b6102ad61069f366004613107565b61126c565b3480156106b057600080fd5b506103c8601481565b3480156106c557600080fd5b506102d46106d436600461312c565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b34801561070e57600080fd5b506102ad61071d366004612fa0565b61171a565b34801561072e57600080fd5b506102ad61177d565b34801561074357600080fd5b506102ad610752366004612fa0565b6117d6565b34801561076357600080fd5b506103c861271081565b34801561077957600080fd5b506102ad61184f565b34801561078e57600080fd5b506102ad61079d366004612fc9565b61186b565b3480156107ae57600080fd5b506102ad6107bd366004612f7e565b61193b565b3480156107ce57600080fd5b5060105461031d906001600160a01b031681565b600061082483836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250611957565b90505b92915050565b6040805160028082526060820183526000926020830190803683375050600e5482519293506001600160a01b03169183915060009061086e5761086e61315f565b60200260200101906001600160a01b031690816001600160a01b0316815250507f0000000000000000000000000000000000000000000000000000000000000000816001815181106108c2576108c261315f565b6001600160a01b03928316602091820292909201015260105416637ff36ab583600084306108f24261012c61198e565b6040518663ffffffff1660e01b81526004016109119493929190613175565b6000604051808303818588803b15801561092a57600080fd5b505af115801561093e573d6000803e3d6000fd5b50505050506040513d6000823e601f3d908101601f1916820160405261096791908101906131df565b505050565b6019546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a082319060240160206040518083038186803b1580156109b057600080fd5b505afa1580156109c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109e89190613285565b60195460115460405163a9059cbb60e01b81526001600160a01b0391821660048201526024810184905292935060009291169063a9059cbb90604401602060405180830381600087803b158015610a3e57600080fd5b505af1158015610a52573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a76919061329e565b90508015610ade5760115460405163b6b55f2560e01b8152600481018490526001600160a01b039091169063b6b55f25906024015b600060405180830381600087803b158015610ac557600080fd5b505af1158015610ad9573d6000803e3d6000fd5b505050505b5050565b6000610827826119ed565b606060008054610afc906132bb565b80601f0160208091040260200160405190810160405280929190818152602001828054610b28906132bb565b8015610b755780601f10610b4a57610100808354040283529160200191610b75565b820191906000526020600020905b815481529060010190602001808311610b5857829003601f168201915b5050505050905090565b6000610b8a82611a12565b506000908152600460205260409020546001600160a01b031690565b610ade8282611a71565b610bb8611b82565b60135460ff16158015610bcb5750600854155b610c105760405162461bcd60e51b81526020600482015260116024820152704d696e74696e672069732061637469766560781b60448201526064015b60405180910390fd5b60005b83811015610cb957610c4a858583818110610c3057610c3061315f565b9050602002016020810190610c459190612fa0565b611bdc565b828282818110610c5c57610c5c61315f565b9050602002016020810190610c7191906132f6565b15610ca757610ca7858583818110610c8b57610c8b61315f565b9050602002016020810190610ca09190612fa0565b6000611c3d565b80610cb181613329565b915050610c13565b5050505050565b610cca3382611cdf565b610ce65760405162461bcd60e51b8152600401610c0790613344565b610967838383611d5e565b60008030610d0c612710610d068660c8611ecf565b906107e2565b915091505b9250929050565b6000610d23836110fe565b8210610d855760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610c07565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b61096783838360405180602001604052806000815250611229565b6000610dd460085490565b8210610e375760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610c07565b60088281548110610e4a57610e4a61315f565b90600052602060002001549050919050565b601154604051631730cfdd60e21b81526001600160a01b0383811660048301526000921690635cc33f74906024015b60206040518083038186803b158015610ea357600080fd5b505afa158015610eb7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108279190613285565b610ee3611b82565b6040516001600160a01b038216904780156108fc02916000818181858888f19350505050158015610f18573d6000803e3d6000fd5b506019546040516370a0823160e01b81523060048201526001600160a01b039091169063a9059cbb90839083906370a082319060240160206040518083038186803b158015610f6657600080fd5b505afa158015610f7a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f9e9190613285565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381600087803b158015610fe457600080fd5b505af1158015610ff8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ade919061329e565b6000818152600260205260408120546001600160a01b0316806108275760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610c07565b6011546040805163997664d760e01b815290516000926001600160a01b03169163997664d7916004808301926020929190829003018186803b1580156110c157600080fd5b505afa1580156110d5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110f99190613285565b905090565b60006001600160a01b0382166111685760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b6064820152608401610c07565b506001600160a01b031660009081526003602052604090205490565b61118c611b82565b6111966000611f4e565b565b6011546040805163d54ad2a160e01b815290516000926001600160a01b03169163d54ad2a1916004808301926020929190829003018186803b1580156110c157600080fd5b601154604051638ecc37fb60e01b81526001600160a01b0383811660048301526000921690638ecc37fb90602401610e8b565b606060018054610afc906132bb565b610ade8282611fa0565b6112333383611cdf565b61124f5760405162461bcd60e51b8152600401610c0790613344565b61125b84848484611fab565b50505050565b606061082782611fde565b60135460ff166112b65760405162461bcd60e51b81526020600482015260156024820152744d696e74696e67206973206e6f742061637469766560581b6044820152606401610c07565b60148211156113135760405162461bcd60e51b815260206004820152602360248201527f4d617820746f6b656e7320706572207472616e73616374696f6e20657863656560448201526219195960ea1b6064820152608401610c07565b606461132883611322336110fe565b9061198e565b11156113765760405162461bcd60e51b815260206004820152601e60248201527f4d617820746f6b656e73207065722077616c6c657420657863656564656400006044820152606401610c07565b6127106113868361132260085490565b11156113fa5760405162461bcd60e51b815260206004820152603d60248201527f4e6f7420656e6f75676820746f6b656e73206c6566742e20446563726561736560448201527f20746865206e756d626572206f6620746f6b656e7320746f206d696e740000006064820152608401610c07565b8015611650576018546000906114109084611ecf565b6019546040516370a0823160e01b815233600482015291925082916001600160a01b03909116906370a082319060240160206040518083038186803b15801561145857600080fd5b505afa15801561146c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114909190613285565b10156114d55760405162461bcd60e51b8152602060048201526014602482015273139bdd08195b9bdd59da0814115411481cd95b9d60621b6044820152606401610c07565b6114df33846120da565b6019546001600160a01b03166323b872dd3330611504612710610d0687611f40611ecf565b6040516001600160e01b031960e086901b1681526001600160a01b0393841660048201529290911660248301526044820152606401602060405180830381600087803b15801561155357600080fd5b505af1158015611567573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061158b919061329e565b506019546001600160a01b03166323b872dd336115b0600d546001600160a01b031690565b6115c2612710610d06876107d0611ecf565b6040516001600160e01b031960e086901b1681526001600160a01b0393841660048201529290911660248301526044820152606401602060405180830381600087803b15801561161157600080fd5b505af1158015611625573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611649919061329e565b505061170f565b60175461165d9083611ecf565b3410156116a25760405162461bcd60e51b8152602060048201526013602482015272139bdd08195b9bdd59da08115512081cd95b9d606a1b6044820152606401610c07565b6116ac33836120da565b60006116c0612710610d0634611b58611ecf565b90506116cb8161082d565b600d546001600160a01b03166108fc6116e43484612100565b6040518115909202916000818181858888f1935050505015801561170c573d6000803e3d6000fd5b50505b610ade336001611c3d565b611722611b82565b601154604051630afbf02f60e11b81526001600160a01b038381166004830152909116906315f7e05e90602401600060405180830381600087803b15801561176957600080fd5b505af1158015610cb9573d6000803e3d6000fd5b601154604051630afbf02f60e11b81523360048201526001600160a01b03909116906315f7e05e90602401600060405180830381600087803b1580156117c257600080fd5b505af115801561125b573d6000803e3d6000fd5b6117de611b82565b6001600160a01b0381166118435760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610c07565b61184c81611f4e565b50565b611857611b82565b6013805460ff19811660ff90911615179055565b611873611b82565b6001600160a01b03821630141561188957600080fd5b6001600160a01b0382166000908152600f60205260409020805460ff191682158015919091179091556118ef57601154604051630a5b654b60e11b81526001600160a01b03848116600483015260006024830152909116906314b6ca9690604401610aab565b6011546001600160a01b03166314b6ca968361190a816110fe565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401610aab565b611943611b82565b601791909155601855565b80546001019055565b600081836119785760405162461bcd60e51b8152600401610c079190612e1f565b5060006119858486613391565b95945050505050565b60008061199b83856133b3565b9050838110156108245760405162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f7700000000006044820152606401610c07565b60006001600160e01b0319821663152a902d60e11b1480610827575061082782612142565b6000818152600260205260409020546001600160a01b031661184c5760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610c07565b6000611a7c8261101c565b9050806001600160a01b0316836001600160a01b03161415611aea5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610c07565b336001600160a01b0382161480611b065750611b0681336106d4565b611b785760405162461bcd60e51b815260206004820152603d60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c0000006064820152608401610c07565b6109678383612167565b600d546001600160a01b031633146111965760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c07565b6000611be760125490565b9050611bf7601280546001019055565b611c0182826121d5565b60006015611c0e836121ef565b6016604051602001611c2293929190613465565b6040516020818303038152906040529050610967828261228c565b6001600160a01b0382166000908152600f602052604090205460ff16611cd1576011546001600160a01b03166314b6ca9683611c7881612326565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b158015611cbe57600080fd5b505af1925050508015611ccf575060015b505b8015610ade57610ade61096c565b600080611ceb8361101c565b9050806001600160a01b0316846001600160a01b03161480611d3257506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b80611d565750836001600160a01b0316611d4b84610b7f565b6001600160a01b0316145b949350505050565b826001600160a01b0316611d718261101c565b6001600160a01b031614611d975760405162461bcd60e51b8152600401610c0790613498565b6001600160a01b038216611df95760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610c07565b611e068383836001612385565b826001600160a01b0316611e198261101c565b6001600160a01b031614611e3f5760405162461bcd60e51b8152600401610c0790613498565b600081815260046020908152604080832080546001600160a01b03199081169091556001600160a01b0387811680865260038552838620805460001901905590871680865283862080546001019055868652600290945282852080549092168417909155905184937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600082611ede57506000610827565b6000611eea83856134dd565b905082611ef78583613391565b146108245760405162461bcd60e51b815260206004820152602160248201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6044820152607760f81b6064820152608401610c07565b600d80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b610ade3383836123cc565b611fb6848484611d5e565b611fc28484848461249b565b61125b5760405162461bcd60e51b8152600401610c07906134fc565b6060611fe982611a12565b6000828152600a602052604081208054612002906132bb565b80601f016020809104026020016040519081016040528092919081815260200182805461202e906132bb565b801561207b5780601f106120505761010080835404028352916020019161207b565b820191906000526020600020905b81548152906001019060200180831161205e57829003601f168201915b50505050509050600061208c6125a8565b905080516000141561209f575092915050565b8151156120d15780826040516020016120b992919061354e565b60405160208183030381529060405292505050919050565b611d56846125b7565b60005b81811015610967576120ee83611bdc565b806120f881613329565b9150506120dd565b600061082483836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525061261e565b60006001600160e01b0319821663780e9d6360e01b148061082757506108278261264f565b600081815260046020526040902080546001600160a01b0319166001600160a01b038416908117909155819061219c8261101c565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b610ade82826040518060200160405280600081525061269f565b606060006121fc836126d2565b600101905060008167ffffffffffffffff81111561221c5761221c613000565b6040519080825280601f01601f191660200182016040528015612246576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a850494508461227f57612284565b612250565b509392505050565b6000828152600260205260409020546001600160a01b03166123075760405162461bcd60e51b815260206004820152602e60248201527f45524337323155524953746f726167653a2055524920736574206f66206e6f6e60448201526d32bc34b9ba32b73a103a37b5b2b760911b6064820152608401610c07565b6000828152600a60209081526040909120825161096792840190612cfb565b60008080612333846110fe565b905060005b8181101561237c57600061234c8683610d18565b90506000612359826127aa565b9050612365858261198e565b94505050808061237490613329565b915050612338565b50909392505050565b612391848484846128a5565b6001600160a01b038416158015906123b157506001600160a01b03831615155b1561125b576123c1846001611c3d565b61125b836001611c3d565b816001600160a01b0316836001600160a01b0316141561242e5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610c07565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b60006001600160a01b0384163b1561259d57604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906124df90339089908890889060040161357d565b602060405180830381600087803b1580156124f957600080fd5b505af1925050508015612529575060408051601f3d908101601f19168201909252612526918101906135ba565b60015b612583573d808015612557576040519150601f19603f3d011682016040523d82523d6000602084013e61255c565b606091505b50805161257b5760405162461bcd60e51b8152600401610c07906134fc565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611d56565b506001949350505050565b606060148054610afc906132bb565b60606125c282611a12565b60006125cc6125a8565b905060008151116125ec5760405180602001604052806000815250612617565b806125f6846121ef565b60405160200161260792919061354e565b6040516020818303038152906040525b9392505050565b600081848411156126425760405162461bcd60e51b8152600401610c079190612e1f565b50600061198584866135d7565b60006001600160e01b031982166380ac58cd60e01b148061268057506001600160e01b03198216635b5e139f60e01b145b8061082757506301ffc9a760e01b6001600160e01b0319831614610827565b6126a983836129d2565b6126b6600084848461249b565b6109675760405162461bcd60e51b8152600401610c07906134fc565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b83106127115772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef8100000000831061273d576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc10000831061275b57662386f26fc10000830492506010015b6305f5e1008310612773576305f5e100830492506008015b612710831061278757612710830492506004015b60648310612799576064830492506002015b600a83106108275760010192915050565b6000600282158015906127be57506103e983105b156127cb5750600a610827565b6103e8831180156127dd57506107d183105b156127ea57506009610827565b6107d0831180156127fc5750610bb983105b1561280957506008610827565b610bb88311801561281b5750610fa183105b1561282857506007610827565b610fa08311801561283a575061138983105b1561284757506006610827565b61138883118015612859575061177183105b1561286657506005610827565b611770831180156128785750611b5983105b1561288557506004610827565b611b58831180156128975750611f4183105b156108275750600392915050565b60018111156129145760405162461bcd60e51b815260206004820152603560248201527f455243373231456e756d657261626c653a20636f6e7365637574697665207472604482015274185b9cd9995c9cc81b9bdd081cdd5c1c1bdc9d1959605a1b6064820152608401610c07565b816001600160a01b0385166129705761296b81600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b612993565b836001600160a01b0316856001600160a01b031614612993576129938582612b6b565b6001600160a01b0384166129af576129aa81612c08565b610cb9565b846001600160a01b0316846001600160a01b031614610cb957610cb98482612cb7565b6001600160a01b038216612a285760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610c07565b6000818152600260205260409020546001600160a01b031615612a8d5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610c07565b612a9b600083836001612385565b6000818152600260205260409020546001600160a01b031615612b005760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610c07565b6001600160a01b038216600081815260036020908152604080832080546001019055848352600290915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60006001612b78846110fe565b612b8291906135d7565b600083815260076020526040902054909150808214612bd5576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b600854600090612c1a906001906135d7565b60008381526009602052604081205460088054939450909284908110612c4257612c4261315f565b906000526020600020015490508060088381548110612c6357612c6361315f565b6000918252602080832090910192909255828152600990915260408082208490558582528120556008805480612c9b57612c9b6135ee565b6001900381819060005260206000200160009055905550505050565b6000612cc2836110fe565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b828054612d07906132bb565b90600052602060002090601f016020900481019282612d295760008555612d6f565b82601f10612d4257805160ff1916838001178555612d6f565b82800160010185558215612d6f579182015b82811115612d6f578251825591602001919060010190612d54565b50612d7b929150612d7f565b5090565b5b80821115612d7b5760008155600101612d80565b6001600160e01b03198116811461184c57600080fd5b600060208284031215612dbc57600080fd5b813561082481612d94565b60005b83811015612de2578181015183820152602001612dca565b8381111561125b5750506000910152565b60008151808452612e0b816020860160208601612dc7565b601f01601f19169290920160200192915050565b6020815260006108246020830184612df3565b600060208284031215612e4457600080fd5b5035919050565b80356001600160a01b0381168114612e6257600080fd5b919050565b60008060408385031215612e7a57600080fd5b612e8383612e4b565b946020939093013593505050565b60008083601f840112612ea357600080fd5b50813567ffffffffffffffff811115612ebb57600080fd5b6020830191508360208260051b8501011115610d1157600080fd5b60008060008060408587031215612eec57600080fd5b843567ffffffffffffffff80821115612f0457600080fd5b612f1088838901612e91565b90965094506020870135915080821115612f2957600080fd5b50612f3687828801612e91565b95989497509550505050565b600080600060608486031215612f5757600080fd5b612f6084612e4b565b9250612f6e60208501612e4b565b9150604084013590509250925092565b60008060408385031215612f9157600080fd5b50508035926020909101359150565b600060208284031215612fb257600080fd5b61082482612e4b565b801515811461184c57600080fd5b60008060408385031215612fdc57600080fd5b612fe583612e4b565b91506020830135612ff581612fbb565b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561303f5761303f613000565b604052919050565b6000806000806080858703121561305d57600080fd5b61306685612e4b565b93506020613075818701612e4b565b935060408601359250606086013567ffffffffffffffff8082111561309957600080fd5b818801915088601f8301126130ad57600080fd5b8135818111156130bf576130bf613000565b6130d1601f8201601f19168501613016565b915080825289848285010111156130e757600080fd5b808484018584013760008482840101525080935050505092959194509250565b6000806040838503121561311a57600080fd5b823591506020830135612ff581612fbb565b6000806040838503121561313f57600080fd5b61314883612e4b565b915061315660208401612e4b565b90509250929050565b634e487b7160e01b600052603260045260246000fd5b600060808201868352602060808185015281875180845260a086019150828901935060005b818110156131bf5784516001600160a01b03168352938301939183019160010161319a565b50506001600160a01b039690961660408501525050506060015292915050565b600060208083850312156131f257600080fd5b825167ffffffffffffffff8082111561320a57600080fd5b818501915085601f83011261321e57600080fd5b81518181111561323057613230613000565b8060051b9150613241848301613016565b818152918301840191848101908884111561325b57600080fd5b938501935b8385101561327957845182529385019390850190613260565b98975050505050505050565b60006020828403121561329757600080fd5b5051919050565b6000602082840312156132b057600080fd5b815161082481612fbb565b600181811c908216806132cf57607f821691505b602082108114156132f057634e487b7160e01b600052602260045260246000fd5b50919050565b60006020828403121561330857600080fd5b813561082481612fbb565b634e487b7160e01b600052601160045260246000fd5b600060001982141561333d5761333d613313565b5060010190565b6020808252602d908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526c1c881bdc88185c1c1c9bdd9959609a1b606082015260800190565b6000826133ae57634e487b7160e01b600052601260045260246000fd5b500490565b600082198211156133c6576133c6613313565b500190565b8054600090600181811c90808316806133e557607f831692505b602080841082141561340757634e487b7160e01b600052602260045260246000fd5b81801561341b576001811461342c57613459565b60ff19861689528489019650613459565b60008881526020902060005b868110156134515781548b820152908501908301613438565b505084890196505b50505050505092915050565b600061347182866133cb565b8451613481818360208901612dc7565b61348d818301866133cb565b979650505050505050565b60208082526025908201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060408201526437bbb732b960d91b606082015260800190565b60008160001904831182151516156134f7576134f7613313565b500290565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b60008351613560818460208801612dc7565b835190830190613574818360208801612dc7565b01949350505050565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906135b090830184612df3565b9695505050505050565b6000602082840312156135cc57600080fd5b815161082481612d94565b6000828210156135e9576135e9613313565b500390565b634e487b7160e01b600052603160045260246000fdfea26469706673582212200a9933e4cfb0939a917e059b5428fd5464d9ba03ae52920bb3d2e9a2bff4b13c64736f6c6343000809003360a0604052736982508145454ce325ddbe47a25d4ec3d23119336080526ec097ce7bc90715b34b9f100000000060095534801561003b57600080fd5b50604051610da8380380610da883398101604081905261005a9161008d565b60008054336001600160a01b031991821617909155600180549091166001600160a01b03929092169190911790556100bd565b60006020828403121561009f57600080fd5b81516001600160a01b03811681146100b657600080fd5b9392505050565b608051610cc96100df600039600081816102bb015261073d0152610cc96000f3fe6080604052600436106100e15760003560e01c8063b2bdfa7b1161007f578063d54ad2a111610059578063d54ad2a11461027d578063e2d2e21914610293578063e4fbaecb146102a9578063ecd0c0c3146102dd57600080fd5b8063b2bdfa7b146101ce578063b6b55f2514610206578063ce7c2ac21461022657600080fd5b80633a98ef39116100bb5780633a98ef391461014f5780635cc33f74146101785780638ecc37fb14610198578063997664d7146101b857600080fd5b80631014edf5146100ed57806314b6ca961461010f57806315f7e05e1461012f57600080fd5b366100e857005b600080fd5b3480156100f957600080fd5b5061010d610108366004610ae0565b6102fd565b005b34801561011b57600080fd5b5061010d61012a366004610b0c565b61035d565b34801561013b57600080fd5b5061010d61014a366004610b36565b6104d5565b34801561015b57600080fd5b5061016560055481565b6040519081526020015b60405180910390f35b34801561018457600080fd5b50610165610193366004610b36565b6104f8565b3480156101a457600080fd5b506101656101b3366004610b36565b61058b565b3480156101c457600080fd5b5061016560065481565b3480156101da57600080fd5b506001546101ee906001600160a01b031681565b6040516001600160a01b03909116815260200161016f565b34801561021257600080fd5b5061010d610221366004610b51565b610614565b34801561023257600080fd5b50610262610241366004610b36565b60046020526000908152604090208054600182015460029092015490919083565b6040805193845260208401929092529082015260600161016f565b34801561028957600080fd5b5061016560075481565b34801561029f57600080fd5b5061016560085481565b3480156102b557600080fd5b506101ee7f000000000000000000000000000000000000000000000000000000000000000081565b3480156102e957600080fd5b506000546101ee906001600160a01b031681565b6001546001600160a01b0316331461031457600080fd5b476001600160a01b0382166108fc8461032d578261032f565b845b6040518115909202916000818181858888f19350505050158015610357573d6000803e3d6000fd5b50505050565b6000546001600160a01b0316331461037457600080fd5b6001600160a01b0382166000908152600460205260409020541561039b5761039b8261066e565b6000811180156103c157506001600160a01b038216600090815260046020526040902054155b1561042757600280546001600160a01b0384166000818152600360205260408120839055600183018455929092527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace0180546001600160a01b031916909117905561045a565b8015801561044c57506001600160a01b03821660009081526004602052604090205415155b1561045a5761045a826107bf565b6001600160a01b03821660009081526004602052604090205460055461048b918391610485916108d4565b9061091f565b6005556001600160a01b03821660009081526004602052604090208190556104b28161097e565b6001600160a01b0390921660009081526004602052604090206001019190915550565b6000546001600160a01b031633146104ec57600080fd5b6104f58161066e565b50565b6001600160a01b03811660009081526004602052604081205461056c5760405162461bcd60e51b815260206004820152602160248201527f596f75277265206e6f742061205052494e544552207368617265686f6c6465726044820152602160f81b60648201526084015b60405180910390fd5b506001600160a01b031660009081526004602052604090206002015490565b6001600160a01b0381166000908152600460205260408120546105b057506000919050565b6001600160a01b0382166000908152600460205260408120546105d29061097e565b6001600160a01b038416600090815260046020526040902060010154909150808211610602575060009392505050565b61060c82826108d4565b949350505050565b6000546001600160a01b0316331461062b57600080fd5b80156104f55760065461063e908261091f565b6006556005546009546106689161065f91610659908561099b565b90610a1a565b6008549061091f565b60085550565b6001600160a01b03811660009081526004602052604090205461068e5750565b60006106998261058b565b905080156107bb576007546106ae908261091f565b6007556001600160a01b0382166000908152600460205260409020600201546106d7908261091f565b6001600160a01b03831660009081526004602052604090206002810191909155546107019061097e565b6001600160a01b03838116600081815260046020819052604091829020600101949094555163a9059cbb60e01b815292830152602482018390527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb90604401602060405180830381600087803b15801561078157600080fd5b505af1158015610795573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107b99190610b6a565b505b5050565b600280546107cf90600190610ba2565b815481106107df576107df610bb9565b60009182526020808320909101546001600160a01b038481168452600390925260409092205460028054929093169291811061081d5761081d610bb9565b600091825260208083209190910180546001600160a01b0319166001600160a01b0394851617905591831681526003918290526040812054600280549193929161086990600190610ba2565b8154811061087957610879610bb9565b60009182526020808320909101546001600160a01b0316835282019290925260400190205560028054806108af576108af610bcf565b600082815260209020810160001990810180546001600160a01b031916905501905550565b600061091683836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250610a5c565b90505b92915050565b60008061092c8385610be5565b9050838110156109165760405162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f7700000000006044820152606401610563565b60006109196009546106596008548561099b90919063ffffffff16565b6000826109aa57506000610919565b60006109b68385610bfd565b9050826109c38583610c1c565b146109165760405162461bcd60e51b815260206004820152602160248201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6044820152607760f81b6064820152608401610563565b600061091683836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250610a96565b60008184841115610a805760405162461bcd60e51b81526004016105639190610c3e565b506000610a8d8486610ba2565b95945050505050565b60008183610ab75760405162461bcd60e51b81526004016105639190610c3e565b506000610a8d8486610c1c565b80356001600160a01b0381168114610adb57600080fd5b919050565b60008060408385031215610af357600080fd5b82359150610b0360208401610ac4565b90509250929050565b60008060408385031215610b1f57600080fd5b610b2883610ac4565b946020939093013593505050565b600060208284031215610b4857600080fd5b61091682610ac4565b600060208284031215610b6357600080fd5b5035919050565b600060208284031215610b7c57600080fd5b8151801515811461091657600080fd5b634e487b7160e01b600052601160045260246000fd5b600082821015610bb457610bb4610b8c565b500390565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60008219821115610bf857610bf8610b8c565b500190565b6000816000190483118215151615610c1757610c17610b8c565b500290565b600082610c3957634e487b7160e01b600052601260045260246000fd5b500490565b600060208083528351808285015260005b81811015610c6b57858101830151858201604001528201610c4f565b81811115610c7d576000604083870101525b50601f01601f191692909201604001939250505056fea2646970667358221220c818e5374217cd773b73bece1cad159ee66df6de3eabfe3f4c6369317132d5c264736f6c63430008090033697066733a2f2f6261667962656963746863696b696a366c676633327965637978726661796a3232326369336c3562616537686e657968616b7a3634736c726937652f
Deployed Bytecode
0x60806040526004361061024a5760003560e01c80638832bc2911610139578063d81049ef116100b6578063f2fde38b1161007a578063f2fde38b14610737578063f47c84c514610757578063f655ff221461076d578063f708a64f14610782578063f7d97577146107a2578063f887ea40146107c257600080fd5b8063d81049ef14610691578063e0c23b94146106a4578063e985e9c5146106b9578063edf3525314610702578063f0fc6bca1461072257600080fd5b8063a22cb465116100fd578063a22cb46514610606578063a85e1dea14610626578063b88d4fde1461063c578063c87b56dd1461065c578063d1bdb1d11461067c57600080fd5b80638832bc29146105695780638da5cb5b1461057f5780638ecc37fb1461059d578063932da039146105bd57806395d89b41146105f157600080fd5b8063335477fc116101c75780636352211e1161018b5780636352211e146104ea57806367ee5f091461050a57806370a082311461051f578063715018a61461053f578063736a83a11461055457600080fd5b8063335477fc1461045557806342842e0e1461046a5780634f6ccce71461048a5780635cc33f74146104aa57806360a6f45a146104ca57600080fd5b806316334de71161020e57806316334de71461039757806318160ddd146103b757806323b872dd146103d65780632a55205a146103f65780632f745c591461043557600080fd5b806301ffc9a7146102b45780630323fd6e146102e957806306fdde0314610335578063081812fc14610357578063095ea7b31461037757600080fd5b366102af5761026261025d3460026107e2565b61082d565b600d546001600160a01b03166108fc61027c3460026107e2565b6040518115909202916000818181858888f193505050501580156102a4573d6000803e3d6000fd5b506102ad61096c565b005b600080fd5b3480156102c057600080fd5b506102d46102cf366004612daa565b610ae2565b60405190151581526020015b60405180910390f35b3480156102f557600080fd5b5061031d7f0000000000000000000000006982508145454ce325ddbe47a25d4ec3d231193381565b6040516001600160a01b0390911681526020016102e0565b34801561034157600080fd5b5061034a610aed565b6040516102e09190612e1f565b34801561036357600080fd5b5061031d610372366004612e32565b610b7f565b34801561038357600080fd5b506102ad610392366004612e67565b610ba6565b3480156103a357600080fd5b506102ad6103b2366004612ed6565b610bb0565b3480156103c357600080fd5b506008545b6040519081526020016102e0565b3480156103e257600080fd5b506102ad6103f1366004612f42565b610cc0565b34801561040257600080fd5b50610416610411366004612f7e565b610cf1565b604080516001600160a01b0390931683526020830191909152016102e0565b34801561044157600080fd5b506103c8610450366004612e67565b610d18565b34801561046157600080fd5b506103c860c881565b34801561047657600080fd5b506102ad610485366004612f42565b610dae565b34801561049657600080fd5b506103c86104a5366004612e32565b610dc9565b3480156104b657600080fd5b506103c86104c5366004612fa0565b610e5c565b3480156104d657600080fd5b506102ad6104e5366004612fa0565b610edb565b3480156104f657600080fd5b5061031d610505366004612e32565b61101c565b34801561051657600080fd5b506103c861107c565b34801561052b57600080fd5b506103c861053a366004612fa0565b6110fe565b34801561054b57600080fd5b506102ad611184565b34801561056057600080fd5b506103c8611198565b34801561057557600080fd5b506103c860175481565b34801561058b57600080fd5b50600d546001600160a01b031661031d565b3480156105a957600080fd5b506103c86105b8366004612fa0565b6111dd565b3480156105c957600080fd5b5061031d7f0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d81565b3480156105fd57600080fd5b5061034a611210565b34801561061257600080fd5b506102ad610621366004612fc9565b61121f565b34801561063257600080fd5b506103c860185481565b34801561064857600080fd5b506102ad610657366004613047565b611229565b34801561066857600080fd5b5061034a610677366004612e32565b611261565b34801561068857600080fd5b506103c8606481565b6102ad61069f366004613107565b61126c565b3480156106b057600080fd5b506103c8601481565b3480156106c557600080fd5b506102d46106d436600461312c565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b34801561070e57600080fd5b506102ad61071d366004612fa0565b61171a565b34801561072e57600080fd5b506102ad61177d565b34801561074357600080fd5b506102ad610752366004612fa0565b6117d6565b34801561076357600080fd5b506103c861271081565b34801561077957600080fd5b506102ad61184f565b34801561078e57600080fd5b506102ad61079d366004612fc9565b61186b565b3480156107ae57600080fd5b506102ad6107bd366004612f7e565b61193b565b3480156107ce57600080fd5b5060105461031d906001600160a01b031681565b600061082483836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250611957565b90505b92915050565b6040805160028082526060820183526000926020830190803683375050600e5482519293506001600160a01b03169183915060009061086e5761086e61315f565b60200260200101906001600160a01b031690816001600160a01b0316815250507f0000000000000000000000006982508145454ce325ddbe47a25d4ec3d2311933816001815181106108c2576108c261315f565b6001600160a01b03928316602091820292909201015260105416637ff36ab583600084306108f24261012c61198e565b6040518663ffffffff1660e01b81526004016109119493929190613175565b6000604051808303818588803b15801561092a57600080fd5b505af115801561093e573d6000803e3d6000fd5b50505050506040513d6000823e601f3d908101601f1916820160405261096791908101906131df565b505050565b6019546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a082319060240160206040518083038186803b1580156109b057600080fd5b505afa1580156109c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109e89190613285565b60195460115460405163a9059cbb60e01b81526001600160a01b0391821660048201526024810184905292935060009291169063a9059cbb90604401602060405180830381600087803b158015610a3e57600080fd5b505af1158015610a52573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a76919061329e565b90508015610ade5760115460405163b6b55f2560e01b8152600481018490526001600160a01b039091169063b6b55f25906024015b600060405180830381600087803b158015610ac557600080fd5b505af1158015610ad9573d6000803e3d6000fd5b505050505b5050565b6000610827826119ed565b606060008054610afc906132bb565b80601f0160208091040260200160405190810160405280929190818152602001828054610b28906132bb565b8015610b755780601f10610b4a57610100808354040283529160200191610b75565b820191906000526020600020905b815481529060010190602001808311610b5857829003601f168201915b5050505050905090565b6000610b8a82611a12565b506000908152600460205260409020546001600160a01b031690565b610ade8282611a71565b610bb8611b82565b60135460ff16158015610bcb5750600854155b610c105760405162461bcd60e51b81526020600482015260116024820152704d696e74696e672069732061637469766560781b60448201526064015b60405180910390fd5b60005b83811015610cb957610c4a858583818110610c3057610c3061315f565b9050602002016020810190610c459190612fa0565b611bdc565b828282818110610c5c57610c5c61315f565b9050602002016020810190610c7191906132f6565b15610ca757610ca7858583818110610c8b57610c8b61315f565b9050602002016020810190610ca09190612fa0565b6000611c3d565b80610cb181613329565b915050610c13565b5050505050565b610cca3382611cdf565b610ce65760405162461bcd60e51b8152600401610c0790613344565b610967838383611d5e565b60008030610d0c612710610d068660c8611ecf565b906107e2565b915091505b9250929050565b6000610d23836110fe565b8210610d855760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610c07565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b61096783838360405180602001604052806000815250611229565b6000610dd460085490565b8210610e375760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610c07565b60088281548110610e4a57610e4a61315f565b90600052602060002001549050919050565b601154604051631730cfdd60e21b81526001600160a01b0383811660048301526000921690635cc33f74906024015b60206040518083038186803b158015610ea357600080fd5b505afa158015610eb7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108279190613285565b610ee3611b82565b6040516001600160a01b038216904780156108fc02916000818181858888f19350505050158015610f18573d6000803e3d6000fd5b506019546040516370a0823160e01b81523060048201526001600160a01b039091169063a9059cbb90839083906370a082319060240160206040518083038186803b158015610f6657600080fd5b505afa158015610f7a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f9e9190613285565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381600087803b158015610fe457600080fd5b505af1158015610ff8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ade919061329e565b6000818152600260205260408120546001600160a01b0316806108275760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610c07565b6011546040805163997664d760e01b815290516000926001600160a01b03169163997664d7916004808301926020929190829003018186803b1580156110c157600080fd5b505afa1580156110d5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110f99190613285565b905090565b60006001600160a01b0382166111685760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b6064820152608401610c07565b506001600160a01b031660009081526003602052604090205490565b61118c611b82565b6111966000611f4e565b565b6011546040805163d54ad2a160e01b815290516000926001600160a01b03169163d54ad2a1916004808301926020929190829003018186803b1580156110c157600080fd5b601154604051638ecc37fb60e01b81526001600160a01b0383811660048301526000921690638ecc37fb90602401610e8b565b606060018054610afc906132bb565b610ade8282611fa0565b6112333383611cdf565b61124f5760405162461bcd60e51b8152600401610c0790613344565b61125b84848484611fab565b50505050565b606061082782611fde565b60135460ff166112b65760405162461bcd60e51b81526020600482015260156024820152744d696e74696e67206973206e6f742061637469766560581b6044820152606401610c07565b60148211156113135760405162461bcd60e51b815260206004820152602360248201527f4d617820746f6b656e7320706572207472616e73616374696f6e20657863656560448201526219195960ea1b6064820152608401610c07565b606461132883611322336110fe565b9061198e565b11156113765760405162461bcd60e51b815260206004820152601e60248201527f4d617820746f6b656e73207065722077616c6c657420657863656564656400006044820152606401610c07565b6127106113868361132260085490565b11156113fa5760405162461bcd60e51b815260206004820152603d60248201527f4e6f7420656e6f75676820746f6b656e73206c6566742e20446563726561736560448201527f20746865206e756d626572206f6620746f6b656e7320746f206d696e740000006064820152608401610c07565b8015611650576018546000906114109084611ecf565b6019546040516370a0823160e01b815233600482015291925082916001600160a01b03909116906370a082319060240160206040518083038186803b15801561145857600080fd5b505afa15801561146c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114909190613285565b10156114d55760405162461bcd60e51b8152602060048201526014602482015273139bdd08195b9bdd59da0814115411481cd95b9d60621b6044820152606401610c07565b6114df33846120da565b6019546001600160a01b03166323b872dd3330611504612710610d0687611f40611ecf565b6040516001600160e01b031960e086901b1681526001600160a01b0393841660048201529290911660248301526044820152606401602060405180830381600087803b15801561155357600080fd5b505af1158015611567573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061158b919061329e565b506019546001600160a01b03166323b872dd336115b0600d546001600160a01b031690565b6115c2612710610d06876107d0611ecf565b6040516001600160e01b031960e086901b1681526001600160a01b0393841660048201529290911660248301526044820152606401602060405180830381600087803b15801561161157600080fd5b505af1158015611625573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611649919061329e565b505061170f565b60175461165d9083611ecf565b3410156116a25760405162461bcd60e51b8152602060048201526013602482015272139bdd08195b9bdd59da08115512081cd95b9d606a1b6044820152606401610c07565b6116ac33836120da565b60006116c0612710610d0634611b58611ecf565b90506116cb8161082d565b600d546001600160a01b03166108fc6116e43484612100565b6040518115909202916000818181858888f1935050505015801561170c573d6000803e3d6000fd5b50505b610ade336001611c3d565b611722611b82565b601154604051630afbf02f60e11b81526001600160a01b038381166004830152909116906315f7e05e90602401600060405180830381600087803b15801561176957600080fd5b505af1158015610cb9573d6000803e3d6000fd5b601154604051630afbf02f60e11b81523360048201526001600160a01b03909116906315f7e05e90602401600060405180830381600087803b1580156117c257600080fd5b505af115801561125b573d6000803e3d6000fd5b6117de611b82565b6001600160a01b0381166118435760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610c07565b61184c81611f4e565b50565b611857611b82565b6013805460ff19811660ff90911615179055565b611873611b82565b6001600160a01b03821630141561188957600080fd5b6001600160a01b0382166000908152600f60205260409020805460ff191682158015919091179091556118ef57601154604051630a5b654b60e11b81526001600160a01b03848116600483015260006024830152909116906314b6ca9690604401610aab565b6011546001600160a01b03166314b6ca968361190a816110fe565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401610aab565b611943611b82565b601791909155601855565b80546001019055565b600081836119785760405162461bcd60e51b8152600401610c079190612e1f565b5060006119858486613391565b95945050505050565b60008061199b83856133b3565b9050838110156108245760405162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f7700000000006044820152606401610c07565b60006001600160e01b0319821663152a902d60e11b1480610827575061082782612142565b6000818152600260205260409020546001600160a01b031661184c5760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610c07565b6000611a7c8261101c565b9050806001600160a01b0316836001600160a01b03161415611aea5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610c07565b336001600160a01b0382161480611b065750611b0681336106d4565b611b785760405162461bcd60e51b815260206004820152603d60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c0000006064820152608401610c07565b6109678383612167565b600d546001600160a01b031633146111965760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c07565b6000611be760125490565b9050611bf7601280546001019055565b611c0182826121d5565b60006015611c0e836121ef565b6016604051602001611c2293929190613465565b6040516020818303038152906040529050610967828261228c565b6001600160a01b0382166000908152600f602052604090205460ff16611cd1576011546001600160a01b03166314b6ca9683611c7881612326565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b158015611cbe57600080fd5b505af1925050508015611ccf575060015b505b8015610ade57610ade61096c565b600080611ceb8361101c565b9050806001600160a01b0316846001600160a01b03161480611d3257506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b80611d565750836001600160a01b0316611d4b84610b7f565b6001600160a01b0316145b949350505050565b826001600160a01b0316611d718261101c565b6001600160a01b031614611d975760405162461bcd60e51b8152600401610c0790613498565b6001600160a01b038216611df95760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610c07565b611e068383836001612385565b826001600160a01b0316611e198261101c565b6001600160a01b031614611e3f5760405162461bcd60e51b8152600401610c0790613498565b600081815260046020908152604080832080546001600160a01b03199081169091556001600160a01b0387811680865260038552838620805460001901905590871680865283862080546001019055868652600290945282852080549092168417909155905184937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600082611ede57506000610827565b6000611eea83856134dd565b905082611ef78583613391565b146108245760405162461bcd60e51b815260206004820152602160248201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6044820152607760f81b6064820152608401610c07565b600d80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b610ade3383836123cc565b611fb6848484611d5e565b611fc28484848461249b565b61125b5760405162461bcd60e51b8152600401610c07906134fc565b6060611fe982611a12565b6000828152600a602052604081208054612002906132bb565b80601f016020809104026020016040519081016040528092919081815260200182805461202e906132bb565b801561207b5780601f106120505761010080835404028352916020019161207b565b820191906000526020600020905b81548152906001019060200180831161205e57829003601f168201915b50505050509050600061208c6125a8565b905080516000141561209f575092915050565b8151156120d15780826040516020016120b992919061354e565b60405160208183030381529060405292505050919050565b611d56846125b7565b60005b81811015610967576120ee83611bdc565b806120f881613329565b9150506120dd565b600061082483836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525061261e565b60006001600160e01b0319821663780e9d6360e01b148061082757506108278261264f565b600081815260046020526040902080546001600160a01b0319166001600160a01b038416908117909155819061219c8261101c565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b610ade82826040518060200160405280600081525061269f565b606060006121fc836126d2565b600101905060008167ffffffffffffffff81111561221c5761221c613000565b6040519080825280601f01601f191660200182016040528015612246576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a850494508461227f57612284565b612250565b509392505050565b6000828152600260205260409020546001600160a01b03166123075760405162461bcd60e51b815260206004820152602e60248201527f45524337323155524953746f726167653a2055524920736574206f66206e6f6e60448201526d32bc34b9ba32b73a103a37b5b2b760911b6064820152608401610c07565b6000828152600a60209081526040909120825161096792840190612cfb565b60008080612333846110fe565b905060005b8181101561237c57600061234c8683610d18565b90506000612359826127aa565b9050612365858261198e565b94505050808061237490613329565b915050612338565b50909392505050565b612391848484846128a5565b6001600160a01b038416158015906123b157506001600160a01b03831615155b1561125b576123c1846001611c3d565b61125b836001611c3d565b816001600160a01b0316836001600160a01b0316141561242e5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610c07565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b60006001600160a01b0384163b1561259d57604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906124df90339089908890889060040161357d565b602060405180830381600087803b1580156124f957600080fd5b505af1925050508015612529575060408051601f3d908101601f19168201909252612526918101906135ba565b60015b612583573d808015612557576040519150601f19603f3d011682016040523d82523d6000602084013e61255c565b606091505b50805161257b5760405162461bcd60e51b8152600401610c07906134fc565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611d56565b506001949350505050565b606060148054610afc906132bb565b60606125c282611a12565b60006125cc6125a8565b905060008151116125ec5760405180602001604052806000815250612617565b806125f6846121ef565b60405160200161260792919061354e565b6040516020818303038152906040525b9392505050565b600081848411156126425760405162461bcd60e51b8152600401610c079190612e1f565b50600061198584866135d7565b60006001600160e01b031982166380ac58cd60e01b148061268057506001600160e01b03198216635b5e139f60e01b145b8061082757506301ffc9a760e01b6001600160e01b0319831614610827565b6126a983836129d2565b6126b6600084848461249b565b6109675760405162461bcd60e51b8152600401610c07906134fc565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b83106127115772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef8100000000831061273d576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc10000831061275b57662386f26fc10000830492506010015b6305f5e1008310612773576305f5e100830492506008015b612710831061278757612710830492506004015b60648310612799576064830492506002015b600a83106108275760010192915050565b6000600282158015906127be57506103e983105b156127cb5750600a610827565b6103e8831180156127dd57506107d183105b156127ea57506009610827565b6107d0831180156127fc5750610bb983105b1561280957506008610827565b610bb88311801561281b5750610fa183105b1561282857506007610827565b610fa08311801561283a575061138983105b1561284757506006610827565b61138883118015612859575061177183105b1561286657506005610827565b611770831180156128785750611b5983105b1561288557506004610827565b611b58831180156128975750611f4183105b156108275750600392915050565b60018111156129145760405162461bcd60e51b815260206004820152603560248201527f455243373231456e756d657261626c653a20636f6e7365637574697665207472604482015274185b9cd9995c9cc81b9bdd081cdd5c1c1bdc9d1959605a1b6064820152608401610c07565b816001600160a01b0385166129705761296b81600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b612993565b836001600160a01b0316856001600160a01b031614612993576129938582612b6b565b6001600160a01b0384166129af576129aa81612c08565b610cb9565b846001600160a01b0316846001600160a01b031614610cb957610cb98482612cb7565b6001600160a01b038216612a285760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610c07565b6000818152600260205260409020546001600160a01b031615612a8d5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610c07565b612a9b600083836001612385565b6000818152600260205260409020546001600160a01b031615612b005760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610c07565b6001600160a01b038216600081815260036020908152604080832080546001019055848352600290915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60006001612b78846110fe565b612b8291906135d7565b600083815260076020526040902054909150808214612bd5576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b600854600090612c1a906001906135d7565b60008381526009602052604081205460088054939450909284908110612c4257612c4261315f565b906000526020600020015490508060088381548110612c6357612c6361315f565b6000918252602080832090910192909255828152600990915260408082208490558582528120556008805480612c9b57612c9b6135ee565b6001900381819060005260206000200160009055905550505050565b6000612cc2836110fe565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b828054612d07906132bb565b90600052602060002090601f016020900481019282612d295760008555612d6f565b82601f10612d4257805160ff1916838001178555612d6f565b82800160010185558215612d6f579182015b82811115612d6f578251825591602001919060010190612d54565b50612d7b929150612d7f565b5090565b5b80821115612d7b5760008155600101612d80565b6001600160e01b03198116811461184c57600080fd5b600060208284031215612dbc57600080fd5b813561082481612d94565b60005b83811015612de2578181015183820152602001612dca565b8381111561125b5750506000910152565b60008151808452612e0b816020860160208601612dc7565b601f01601f19169290920160200192915050565b6020815260006108246020830184612df3565b600060208284031215612e4457600080fd5b5035919050565b80356001600160a01b0381168114612e6257600080fd5b919050565b60008060408385031215612e7a57600080fd5b612e8383612e4b565b946020939093013593505050565b60008083601f840112612ea357600080fd5b50813567ffffffffffffffff811115612ebb57600080fd5b6020830191508360208260051b8501011115610d1157600080fd5b60008060008060408587031215612eec57600080fd5b843567ffffffffffffffff80821115612f0457600080fd5b612f1088838901612e91565b90965094506020870135915080821115612f2957600080fd5b50612f3687828801612e91565b95989497509550505050565b600080600060608486031215612f5757600080fd5b612f6084612e4b565b9250612f6e60208501612e4b565b9150604084013590509250925092565b60008060408385031215612f9157600080fd5b50508035926020909101359150565b600060208284031215612fb257600080fd5b61082482612e4b565b801515811461184c57600080fd5b60008060408385031215612fdc57600080fd5b612fe583612e4b565b91506020830135612ff581612fbb565b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561303f5761303f613000565b604052919050565b6000806000806080858703121561305d57600080fd5b61306685612e4b565b93506020613075818701612e4b565b935060408601359250606086013567ffffffffffffffff8082111561309957600080fd5b818801915088601f8301126130ad57600080fd5b8135818111156130bf576130bf613000565b6130d1601f8201601f19168501613016565b915080825289848285010111156130e757600080fd5b808484018584013760008482840101525080935050505092959194509250565b6000806040838503121561311a57600080fd5b823591506020830135612ff581612fbb565b6000806040838503121561313f57600080fd5b61314883612e4b565b915061315660208401612e4b565b90509250929050565b634e487b7160e01b600052603260045260246000fd5b600060808201868352602060808185015281875180845260a086019150828901935060005b818110156131bf5784516001600160a01b03168352938301939183019160010161319a565b50506001600160a01b039690961660408501525050506060015292915050565b600060208083850312156131f257600080fd5b825167ffffffffffffffff8082111561320a57600080fd5b818501915085601f83011261321e57600080fd5b81518181111561323057613230613000565b8060051b9150613241848301613016565b818152918301840191848101908884111561325b57600080fd5b938501935b8385101561327957845182529385019390850190613260565b98975050505050505050565b60006020828403121561329757600080fd5b5051919050565b6000602082840312156132b057600080fd5b815161082481612fbb565b600181811c908216806132cf57607f821691505b602082108114156132f057634e487b7160e01b600052602260045260246000fd5b50919050565b60006020828403121561330857600080fd5b813561082481612fbb565b634e487b7160e01b600052601160045260246000fd5b600060001982141561333d5761333d613313565b5060010190565b6020808252602d908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526c1c881bdc88185c1c1c9bdd9959609a1b606082015260800190565b6000826133ae57634e487b7160e01b600052601260045260246000fd5b500490565b600082198211156133c6576133c6613313565b500190565b8054600090600181811c90808316806133e557607f831692505b602080841082141561340757634e487b7160e01b600052602260045260246000fd5b81801561341b576001811461342c57613459565b60ff19861689528489019650613459565b60008881526020902060005b868110156134515781548b820152908501908301613438565b505084890196505b50505050505092915050565b600061347182866133cb565b8451613481818360208901612dc7565b61348d818301866133cb565b979650505050505050565b60208082526025908201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060408201526437bbb732b960d91b606082015260800190565b60008160001904831182151516156134f7576134f7613313565b500290565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b60008351613560818460208801612dc7565b835190830190613574818360208801612dc7565b01949350505050565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906135b090830184612df3565b9695505050505050565b6000602082840312156135cc57600080fd5b815161082481612d94565b6000828210156135e9576135e9613313565b500390565b634e487b7160e01b600052603160045260246000fdfea26469706673582212200a9933e4cfb0939a917e059b5428fd5464d9ba03ae52920bb3d2e9a2bff4b13c64736f6c63430008090033
Deployed Bytecode Sourcemap
96937:11488:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;105070:32;105085:16;:9;105099:1;105085:13;:16::i;:::-;105070:14;:32::i;:::-;35811:6;;-1:-1:-1;;;;;35811:6:0;105113:43;105139:16;:9;105153:1;105139:13;:16::i;:::-;105113:43;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;105167:18;:16;:18::i;:::-;96937:11488;;;;;106078:221;;;;;;;;;;-1:-1:-1;106078:221:0;;;;;:::i;:::-;;:::i;:::-;;;565:14:1;;558:22;540:41;;528:2;513:18;106078:221:0;;;;;;;;98541:106;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;756:32:1;;;738:51;;726:2;711:18;98541:106:0;592:203:1;72534:100:0;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;74046:171::-;;;;;;;;;;-1:-1:-1;74046:171:0;;;;;:::i;:::-;;:::i;99529:115::-;;;;;;;;;;-1:-1:-1;99529:115:0;;;;;:::i;:::-;;:::i;99903:393::-;;;;;;;;;;-1:-1:-1;99903:393:0;;;;;:::i;:::-;;:::i;91428:113::-;;;;;;;;;;-1:-1:-1;91516:10:0;:17;91428:113;;;3466:25:1;;;3454:2;3439:18;91428:113:0;3320:177:1;74746:335:0;;;;;;;;;;-1:-1:-1;74746:335:0;;;;;:::i;:::-;;:::i;104686:243::-;;;;;;;;;;-1:-1:-1;104686:243:0;;;;;:::i;:::-;;:::i;:::-;;;;-1:-1:-1;;;;;4280:32:1;;;4262:51;;4344:2;4329:18;;4322:34;;;;4235:18;104686:243:0;4088:274:1;91096:256:0;;;;;;;;;;-1:-1:-1;91096:256:0;;;;;:::i;:::-;;:::i;98403:41::-;;;;;;;;;;;;98441:3;98403:41;;75152:185;;;;;;;;;;-1:-1:-1;75152:185:0;;;;;:::i;:::-;;:::i;91618:233::-;;;;;;;;;;-1:-1:-1;91618:233:0;;;;;:::i;:::-;;:::i;108017:188::-;;;;;;;;;;-1:-1:-1;108017:188:0;;;;;:::i;:::-;;:::i;108213:209::-;;;;;;;;;;-1:-1:-1;108213:209:0;;;;;:::i;:::-;;:::i;72244:223::-;;;;;;;;;;-1:-1:-1;72244:223:0;;;;;:::i;:::-;;:::i;107775:115::-;;;;;;;;;;;;;:::i;71975:207::-;;;;;;;;;;-1:-1:-1;71975:207:0;;;;;:::i;:::-;;:::i;36386:103::-;;;;;;;;;;;;;:::i;107898:111::-;;;;;;;;;;;;;:::i;97878:44::-;;;;;;;;;;;;;;;;35738:87;;;;;;;;;;-1:-1:-1;35811:6:0;;-1:-1:-1;;;;;35811:6:0;35738:87;;107579:188;;;;;;;;;;-1:-1:-1;107579:188:0;;;;;:::i;:::-;;:::i;97335:112::-;;;;;;;;;;;;;;;72703:104;;;;;;;;;;;;;:::i;99652:178::-;;;;;;;;;;-1:-1:-1;99652:178:0;;;;;:::i;:::-;;:::i;97967:54::-;;;;;;;;;;;;;;;;75408:322;;;;;;;;;;-1:-1:-1;75408:322:0;;;;;:::i;:::-;;:::i;105874:196::-;;;;;;;;;;-1:-1:-1;105874:196:0;;;;;:::i;:::-;;:::i;98274:51::-;;;;;;;;;;;;98322:3;98274:51;;102825:1853;;;;;;:::i;:::-;;:::i;98171:46::-;;;;;;;;;;;;98215:2;98171:46;;74515:164;;;;;;;;;;-1:-1:-1;74515:164:0;;;;;:::i;:::-;-1:-1:-1;;;;;74636:25:0;;;74612:4;74636:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;74515:164;107458:113;;;;;;;;;;-1:-1:-1;107458:113:0;;;;;:::i;:::-;;:::i;107360:90::-;;;;;;;;;;;;;:::i;36644:201::-;;;;;;;;;;-1:-1:-1;36644:201:0;;;;;:::i;:::-;;:::i;98067:42::-;;;;;;;;;;;;98104:5;98067:42;;100346:100;;;;;;;;;;;;;:::i;107022:330::-;;;;;;;;;;-1:-1:-1;107022:330:0;;;;;:::i;:::-;;:::i;99342:179::-;;;;;;;;;;-1:-1:-1;99342:179:0;;;;;:::i;:::-;;:::i;97304:24::-;;;;;;;;;;-1:-1:-1;97304:24:0;;;;-1:-1:-1;;;;;97304:24:0;;;39715:132;39773:7;39800:39;39804:1;39807;39800:39;;;;;;;;;;;;;;;;;:3;:39::i;:::-;39793:46;;39715:132;;;;;:::o;106641:373::-;106728:16;;;106742:1;106728:16;;;;;;;;106704:21;;106728:16;;;;;;;;-1:-1:-1;;106765:4:0;;106755:7;;;;-1:-1:-1;;;;;;106765:4:0;;106755:7;;-1:-1:-1;106765:4:0;;106755:7;;;;:::i;:::-;;;;;;:14;-1:-1:-1;;;;;106755:14:0;;;-1:-1:-1;;;;;106755:14:0;;;;;106790:18;106780:4;106785:1;106780:7;;;;;;;;:::i;:::-;-1:-1:-1;;;;;106780:28:0;;;:7;;;;;;;;;:28;106847:6;;;:28;106883:9;106847:6;106924:4;106951;106971:24;:15;106991:3;106971:19;:24::i;:::-;106847:159;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;106847:159:0;;;;;;;;;;;;:::i;:::-;;106693:321;106641:373;:::o;106356:277::-;106424:12;;:37;;-1:-1:-1;;;106424:37:0;;106455:4;106424:37;;;738:51:1;106404:17:0;;-1:-1:-1;;;;;106424:12:0;;:22;;711:18:1;;106424:37:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;106489:12;;106519:11;;106489:54;;-1:-1:-1;;;106489:54:0;;-1:-1:-1;;;;;106519:11:0;;;106489:54;;;4262:51:1;4329:18;;;4322:34;;;106404:57:0;;-1:-1:-1;106474:12:0;;106489;;;:21;;4235:18:1;;106489:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;106474:69;;106560:7;106556:70;;;106584:11;;:30;;-1:-1:-1;;;106584:30:0;;;;;3466:25:1;;;-1:-1:-1;;;;;106584:11:0;;;;:19;;3439:18:1;;106584:30:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;106556:70;106393:240;;106356:277::o;106078:221::-;106226:4;106255:36;106279:11;106255:23;:36::i;72534:100::-;72588:13;72621:5;72614:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;72534:100;:::o;74046:171::-;74122:7;74142:23;74157:7;74142:14;:23::i;:::-;-1:-1:-1;74185:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;74185:24:0;;74046:171::o;99529:115::-;99610:26;99624:2;99628:7;99610:13;:26::i;99903:393::-;35624:13;:11;:13::i;:::-;100033:16:::1;::::0;::::1;;100032:17;:39:::0;::::1;;;-1:-1:-1::0;91516:10:0;:17;100053:18;100032:39:::1;100024:69;;;::::0;-1:-1:-1;;;100024:69:0;;10216:2:1;100024:69:0::1;::::0;::::1;10198:21:1::0;10255:2;10235:18;;;10228:30;-1:-1:-1;;;10274:18:1;;;10267:47;10331:18;;100024:69:0::1;;;;;;;;;100111:9;100106:183;100126:18:::0;;::::1;100106:183;;;100166:19;100174:7;;100182:1;100174:10;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;100166:7;:19::i;:::-;100204:7;;100212:1;100204:10;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;100200:78;;;100235:27;100244:7;;100252:1;100244:10;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;100256:5;100235:8;:27::i;:::-;100146:3:::0;::::1;::::0;::::1;:::i;:::-;;;;100106:183;;;;99903:393:::0;;;;:::o;74746:335::-;74941:41;21037:10;74974:7;74941:18;:41::i;:::-;74933:99;;;;-1:-1:-1;;;74933:99:0;;;;;;;:::i;:::-;75045:28;75055:4;75061:2;75065:7;75045:9;:28::i;104686:243::-;104801:16;;104874:4;104881:39;104914:5;104882:26;:9;98441:3;104882:13;:26::i;:::-;104881:32;;:39::i;:::-;104858:63;;;;104686:243;;;;;;:::o;91096:256::-;91193:7;91229:23;91246:5;91229:16;:23::i;:::-;91221:5;:31;91213:87;;;;-1:-1:-1;;;91213:87:0;;11494:2:1;91213:87:0;;;11476:21:1;11533:2;11513:18;;;11506:30;11572:34;11552:18;;;11545:62;-1:-1:-1;;;11623:18:1;;;11616:41;11674:19;;91213:87:0;11292:407:1;91213:87:0;-1:-1:-1;;;;;;91318:19:0;;;;;;;;:12;:19;;;;;;;;:26;;;;;;;;;91096:256::o;75152:185::-;75290:39;75307:4;75313:2;75317:7;75290:39;;;;;;;;;;;;:16;:39::i;91618:233::-;91693:7;91729:30;91516:10;:17;;91428:113;91729:30;91721:5;:38;91713:95;;;;-1:-1:-1;;;91713:95:0;;11906:2:1;91713:95:0;;;11888:21:1;11945:2;11925:18;;;11918:30;11984:34;11964:18;;;11957:62;-1:-1:-1;;;12035:18:1;;;12028:42;12087:19;;91713:95:0;11704:408:1;91713:95:0;91826:10;91837:5;91826:17;;;;;;;;:::i;:::-;;;;;;;;;91819:24;;91618:233;;;:::o;108017:188::-;108151:11;;:46;;-1:-1:-1;;;108151:46:0;;-1:-1:-1;;;;;756:32:1;;;108151:46:0;;;738:51:1;108119:7:0;;108151:11;;:33;;711:18:1;;108151:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;108213:209::-;35624:13;:11;:13::i;:::-;108282:50:::1;::::0;-1:-1:-1;;;;;108282:27:0;::::1;::::0;108310:21:::1;108282:50:::0;::::1;;;::::0;::::1;::::0;;;108310:21;108282:27;:50;::::1;;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;108343:12:0::1;::::0;108376:37:::1;::::0;-1:-1:-1;;;108376:37:0;;108407:4:::1;108376:37;::::0;::::1;738:51:1::0;-1:-1:-1;;;;;108343:12:0;;::::1;::::0;:21:::1;::::0;108365:9;;108343:12;;108376:22:::1;::::0;711:18:1;;108376:37:0::1;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;108343:71;::::0;-1:-1:-1;;;;;;108343:71:0::1;::::0;;;;;;-1:-1:-1;;;;;4280:32:1;;;108343:71:0::1;::::0;::::1;4262:51:1::0;4329:18;;;4322:34;4235:18;;108343:71:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;72244:223::-:0;72316:7;77131:16;;;:7;:16;;;;;;-1:-1:-1;;;;;77131:16:0;;72380:56;;;;-1:-1:-1;;;72380:56:0;;12319:2:1;72380:56:0;;;12301:21:1;12358:2;12338:18;;;12331:30;-1:-1:-1;;;12377:18:1;;;12370:54;12441:18;;72380:56:0;12117:348:1;107775:115:0;107854:11;;:28;;;-1:-1:-1;;;107854:28:0;;;;107827:7;;-1:-1:-1;;;;;107854:11:0;;:26;;:28;;;;;;;;;;;;;;:11;:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;107847:35;;107775:115;:::o;71975:207::-;72047:7;-1:-1:-1;;;;;72075:19:0;;72067:73;;;;-1:-1:-1;;;72067:73:0;;12672:2:1;72067:73:0;;;12654:21:1;12711:2;12691:18;;;12684:30;12750:34;12730:18;;;12723:62;-1:-1:-1;;;12801:18:1;;;12794:39;12850:19;;72067:73:0;12470:405:1;72067:73:0;-1:-1:-1;;;;;;72158:16:0;;;;;:9;:16;;;;;;;71975:207::o;36386:103::-;35624:13;:11;:13::i;:::-;36451:30:::1;36478:1;36451:18;:30::i;:::-;36386:103::o:0;107898:111::-;107975:11;;:26;;;-1:-1:-1;;;107975:26:0;;;;107948:7;;-1:-1:-1;;;;;107975:11:0;;:24;;:26;;;;;;;;;;;;;;:11;:26;;;;;;;;;;107579:188;107712:11;;:47;;-1:-1:-1;;;107712:47:0;;-1:-1:-1;;;;;756:32:1;;;107712:47:0;;;738:51:1;107680:7:0;;107712:11;;:34;;711:18:1;;107712:47:0;592:203:1;72703:104:0;72759:13;72792:7;72785:14;;;;;:::i;99652:178::-;99779:43;99803:8;99813;99779:23;:43::i;75408:322::-;75582:41;21037:10;75615:7;75582:18;:41::i;:::-;75574:99;;;;-1:-1:-1;;;75574:99:0;;;;;;;:::i;:::-;75684:38;75698:4;75704:2;75708:7;75717:4;75684:13;:38::i;:::-;75408:322;;;;:::o;105874:196::-;106001:13;106039:23;106054:7;106039:14;:23::i;102825:1853::-;102944:16;;;;102936:50;;;;-1:-1:-1;;;102936:50:0;;13082:2:1;102936:50:0;;;13064:21:1;13121:2;13101:18;;;13094:30;-1:-1:-1;;;13140:18:1;;;13133:51;13201:18;;102936:50:0;12880:345:1;102936:50:0;98215:2;103019:14;:35;;102997:120;;;;-1:-1:-1;;;102997:120:0;;13432:2:1;102997:120:0;;;13414:21:1;13471:2;13451:18;;;13444:30;13510:34;13490:18;;;13483:62;-1:-1:-1;;;13561:18:1;;;13554:33;13604:19;;102997:120:0;13230:399:1;102997:120:0;98322:3;103150:41;103176:14;103150:21;103160:10;103150:9;:21::i;:::-;:25;;:41::i;:::-;:66;;103128:146;;;;-1:-1:-1;;;103128:146:0;;13836:2:1;103128:146:0;;;13818:21:1;13875:2;13855:18;;;13848:30;13914:32;13894:18;;;13887:60;13964:18;;103128:146:0;13634:354:1;103128:146:0;98104:5;103307:33;103325:14;103307:13;91516:10;:17;;91428:113;103307:33;:47;;103285:158;;;;-1:-1:-1;;;103285:158:0;;14195:2:1;103285:158:0;;;14177:21:1;14234:2;14214:18;;;14207:30;14273:34;14253:18;;;14246:62;14344:31;14324:18;;;14317:59;14393:19;;103285:158:0;13993:425:1;103285:158:0;103460:11;103456:1176;;;103509:10;;103488:18;;103509:30;;103524:14;103509;:30::i;:::-;103580:12;;:34;;-1:-1:-1;;;103580:34:0;;103603:10;103580:34;;;738:51:1;103488::0;;-1:-1:-1;103488:51:0;;-1:-1:-1;;;;;103580:12:0;;;;:22;;711:18:1;;103580:34:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:48;;103554:130;;;;-1:-1:-1;;;103554:130:0;;14625:2:1;103554:130:0;;;14607:21:1;14664:2;14644:18;;;14637:30;-1:-1:-1;;;14683:18:1;;;14676:50;14743:18;;103554:130:0;14423:344:1;103554:130:0;103701:37;103711:10;103723:14;103701:9;:37::i;:::-;103788:12;;-1:-1:-1;;;;;103788:12:0;:25;103832:10;103869:4;103893:31;103918:5;103893:20;:10;103908:4;103893:14;:20::i;:31::-;103788:151;;-1:-1:-1;;;;;;103788:151:0;;;;;;;-1:-1:-1;;;;;15030:15:1;;;103788:151:0;;;15012:34:1;15082:15;;;;15062:18;;;15055:43;15114:18;;;15107:34;14947:18;;103788:151:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;103986:12:0;;-1:-1:-1;;;;;103986:12:0;:25;104030:10;104059:7;35811:6;;-1:-1:-1;;;;;35811:6:0;;35738:87;104059:7;104085:31;104110:5;104085:20;:10;104100:4;104085:14;:20::i;:31::-;103986:145;;-1:-1:-1;;;;;;103986:145:0;;;;;;;-1:-1:-1;;;;;15030:15:1;;;103986:145:0;;;15012:34:1;15082:15;;;;15062:18;;;15055:43;15114:18;;;15107:34;14947:18;;103986:145:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;103473:670;103456:1176;;;104203:9;;:29;;104217:14;104203:13;:29::i;:::-;104190:9;:42;;104164:123;;;;-1:-1:-1;;;104164:123:0;;15354:2:1;104164:123:0;;;15336:21:1;15393:2;15373:18;;;15366:30;-1:-1:-1;;;15412:18:1;;;15405:49;15471:18;;104164:123:0;15152:343:1;104164:123:0;104304:37;104314:10;104326:14;104304:9;:37::i;:::-;104410:17;104430:30;104454:5;104430:19;:9;104444:4;104430:13;:19::i;:30::-;104410:50;;104475:25;104490:9;104475:14;:25::i;:::-;35811:6;;-1:-1:-1;;;;;35811:6:0;104569:51;104595:24;:9;104609;104595:13;:24::i;:::-;104569:51;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;104149:483;103456:1176;104644:26;104653:10;104665:4;104644:8;:26::i;107458:113::-;35624:13;:11;:13::i;:::-;107530:11:::1;::::0;:33:::1;::::0;-1:-1:-1;;;107530:33:0;;-1:-1:-1;;;;;756:32:1;;;107530:33:0::1;::::0;::::1;738:51:1::0;107530:11:0;;::::1;::::0;:25:::1;::::0;711:18:1;;107530:33:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;107360:90:::0;107405:11;;:37;;-1:-1:-1;;;107405:37:0;;107431:10;107405:37;;;738:51:1;-1:-1:-1;;;;;107405:11:0;;;;:25;;711:18:1;;107405:37:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36644:201;35624:13;:11;:13::i;:::-;-1:-1:-1;;;;;36733:22:0;::::1;36725:73;;;::::0;-1:-1:-1;;;36725:73:0;;15702:2:1;36725:73:0::1;::::0;::::1;15684:21:1::0;15741:2;15721:18;;;15714:30;15780:34;15760:18;;;15753:62;-1:-1:-1;;;15831:18:1;;;15824:36;15877:19;;36725:73:0::1;15500:402:1::0;36725:73:0::1;36809:28;36828:8;36809:18;:28::i;:::-;36644:201:::0;:::o;100346:100::-;35624:13;:11;:13::i;:::-;100422:16:::1;::::0;;-1:-1:-1;;100402:36:0;::::1;100422:16;::::0;;::::1;100421:17;100402:36;::::0;;100346:100::o;107022:330::-;35624:13;:11;:13::i;:::-;-1:-1:-1;;;;;107116:23:0;::::1;107134:4;107116:23;;107108:32;;;::::0;::::1;;-1:-1:-1::0;;;;;107151:24:0;::::1;;::::0;;;:16:::1;:24;::::0;;;;:33;;-1:-1:-1;;107151:33:0::1;::::0;::::1;::::0;::::1;::::0;;;::::1;::::0;;;107195:150:::1;;107222:11;::::0;:31:::1;::::0;-1:-1:-1;;;107222:31:0;;-1:-1:-1;;;;;4280:32:1;;;107222:31:0::1;::::0;::::1;4262:51:1::0;107222:11:0::1;4329:18:1::0;;;4322:34;107222:11:0;;::::1;::::0;:20:::1;::::0;4235:18:1;;107222:31:0::1;4088:274:1::0;107195:150:0::1;107286:11;::::0;-1:-1:-1;;;;;107286:11:0::1;:20;107307:6:::0;107315:17:::1;107307:6:::0;107315:9:::1;:17::i;:::-;107286:47;::::0;-1:-1:-1;;;;;;107286:47:0::1;::::0;;;;;;-1:-1:-1;;;;;4280:32:1;;;107286:47:0::1;::::0;::::1;4262:51:1::0;4329:18;;;4322:34;4235:18;;107286:47:0::1;4088:274:1::0;99342:179:0;35624:13;:11;:13::i;:::-;99454:9:::1;:23:::0;;;;99488:10:::1;:25:::0;99342:179::o;4608:127::-;4697:19;;4715:1;4697:19;;;4608:127::o;39855:379::-;39975:7;40077:12;40070:5;40062:28;;;;-1:-1:-1;;;40062:28:0;;;;;;;;:::i;:::-;-1:-1:-1;40101:9:0;40113:5;40117:1;40113;:5;:::i;:::-;40101:17;39855:379;-1:-1:-1;;;;;39855:379:0:o;38890:181::-;38948:7;;38980:5;38984:1;38980;:5;:::i;:::-;38968:17;;39009:1;39004;:6;;38996:46;;;;-1:-1:-1;;;38996:46:0;;16883:2:1;38996:46:0;;;16865:21:1;16922:2;16902:18;;;16895:30;16961:29;16941:18;;;16934:57;17008:18;;38996:46:0;16681:351:1;60435:215:0;60537:4;-1:-1:-1;;;;;;60561:41:0;;-1:-1:-1;;;60561:41:0;;:81;;;60606:36;60630:11;60606:23;:36::i;83865:135::-;77533:4;77131:16;;;:7;:16;;;;;;-1:-1:-1;;;;;77131:16:0;83939:53;;;;-1:-1:-1;;;83939:53:0;;12319:2:1;83939:53:0;;;12301:21:1;12358:2;12338:18;;;12331:30;-1:-1:-1;;;12377:18:1;;;12370:54;12441:18;;83939:53:0;12117:348:1;73564:416:0;73645:13;73661:23;73676:7;73661:14;:23::i;:::-;73645:39;;73709:5;-1:-1:-1;;;;;73703:11:0;:2;-1:-1:-1;;;;;73703:11:0;;;73695:57;;;;-1:-1:-1;;;73695:57:0;;17239:2:1;73695:57:0;;;17221:21:1;17278:2;17258:18;;;17251:30;17317:34;17297:18;;;17290:62;-1:-1:-1;;;17368:18:1;;;17361:31;17409:19;;73695:57:0;17037:397:1;73695:57:0;21037:10;-1:-1:-1;;;;;73787:21:0;;;;:62;;-1:-1:-1;73812:37:0;73829:5;21037:10;74515:164;:::i;73812:37::-;73765:173;;;;-1:-1:-1;;;73765:173:0;;17641:2:1;73765:173:0;;;17623:21:1;17680:2;17660:18;;;17653:30;17719:34;17699:18;;;17692:62;17790:31;17770:18;;;17763:59;17839:19;;73765:173:0;17439:425:1;73765:173:0;73951:21;73960:2;73964:7;73951:8;:21::i;35903:132::-;35811:6;;-1:-1:-1;;;;;35811:6:0;21037:10;35967:23;35959:68;;;;-1:-1:-1;;;35959:68:0;;18071:2:1;35959:68:0;;;18053:21:1;;;18090:18;;;18083:30;18149:34;18129:18;;;18122:62;18201:18;;35959:68:0;17869:356:1;100614:418:0;100662:15;100680:25;:15;4578:14;;4486:114;100680:25;100662:43;;100716:27;:15;4697:19;;4715:1;4697:19;;;4608:127;100716:27;100754:22;100764:2;100768:7;100754:9;:22::i;:::-;100787;100868:11;100898:25;100915:7;100898:16;:25::i;:::-;100942:14;100833:138;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;100787:195;;100993:31;101006:7;101015:8;100993:12;:31::i;102489:328::-;-1:-1:-1;;;;;102624:24:0;;;;;;:16;:24;;;;;;;;102619:119;;102669:11;;-1:-1:-1;;;;;102669:11:0;:20;102690:6;102698:16;102690:6;102698:8;:16::i;:::-;102669:46;;-1:-1:-1;;;;;;102669:46:0;;;;;;;-1:-1:-1;;;;;4280:32:1;;;102669:46:0;;;4262:51:1;4329:18;;;4322:34;4235:18;;102669:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;102665:62;;102752:11;102748:62;;;102780:18;:16;:18::i;77763:264::-;77856:4;77873:13;77889:23;77904:7;77889:14;:23::i;:::-;77873:39;;77942:5;-1:-1:-1;;;;;77931:16:0;:7;-1:-1:-1;;;;;77931:16:0;;:52;;;-1:-1:-1;;;;;;74636:25:0;;;74612:4;74636:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;77951:32;77931:87;;;;78011:7;-1:-1:-1;;;;;77987:31:0;:20;77999:7;77987:11;:20::i;:::-;-1:-1:-1;;;;;77987:31:0;;77931:87;77923:96;77763:264;-1:-1:-1;;;;77763:264:0:o;81762:1263::-;81921:4;-1:-1:-1;;;;;81894:31:0;:23;81909:7;81894:14;:23::i;:::-;-1:-1:-1;;;;;81894:31:0;;81886:81;;;;-1:-1:-1;;;81886:81:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;81986:16:0;;81978:65;;;;-1:-1:-1;;;81978:65:0;;20403:2:1;81978:65:0;;;20385:21:1;20442:2;20422:18;;;20415:30;20481:34;20461:18;;;20454:62;-1:-1:-1;;;20532:18:1;;;20525:34;20576:19;;81978:65:0;20201:400:1;81978:65:0;82056:42;82077:4;82083:2;82087:7;82096:1;82056:20;:42::i;:::-;82228:4;-1:-1:-1;;;;;82201:31:0;:23;82216:7;82201:14;:23::i;:::-;-1:-1:-1;;;;;82201:31:0;;82193:81;;;;-1:-1:-1;;;82193:81:0;;;;;;;:::i;:::-;82346:24;;;;:15;:24;;;;;;;;82339:31;;-1:-1:-1;;;;;;82339:31:0;;;;;;-1:-1:-1;;;;;82822:15:0;;;;;;:9;:15;;;;;:20;;-1:-1:-1;;82822:20:0;;;82857:13;;;;;;;;;:18;;82339:31;82857:18;;;82897:16;;;:7;:16;;;;;;:21;;;;;;;;;;82936:27;;82362:7;;82936:27;;;106847:159;106693:321;106641:373;:::o;39457:250::-;39515:7;39539:6;39535:47;;-1:-1:-1;39569:1:0;39562:8;;39535:47;39594:9;39606:5;39610:1;39606;:5;:::i;:::-;39594:17;-1:-1:-1;39639:1:0;39630:5;39634:1;39594:17;39630:5;:::i;:::-;:10;39622:56;;;;-1:-1:-1;;;39622:56:0;;20981:2:1;39622:56:0;;;20963:21:1;21020:2;21000:18;;;20993:30;21059:34;21039:18;;;21032:62;-1:-1:-1;;;21110:18:1;;;21103:31;21151:19;;39622:56:0;20779:397:1;37005:191:0;37098:6;;;-1:-1:-1;;;;;37115:17:0;;;-1:-1:-1;;;;;;37115:17:0;;;;;;;37148:40;;37098:6;;;37115:17;37098:6;;37148:40;;37079:16;;37148:40;37068:128;37005:191;:::o;74289:155::-;74384:52;21037:10;74417:8;74427;74384:18;:52::i;76611:313::-;76767:28;76777:4;76783:2;76787:7;76767:9;:28::i;:::-;76814:47;76837:4;76843:2;76847:7;76856:4;76814:22;:47::i;:::-;76806:110;;;;-1:-1:-1;;;76806:110:0;;;;;;;:::i;88327:624::-;88400:13;88426:23;88441:7;88426:14;:23::i;:::-;88462;88488:19;;;:10;:19;;;;;88462:45;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;88518:18;88539:10;:8;:10::i;:::-;88518:31;;88631:4;88625:18;88647:1;88625:23;88621:72;;;-1:-1:-1;88672:9:0;88327:624;-1:-1:-1;;88327:624:0:o;88621:72::-;88797:23;;:27;88793:108;;88872:4;88878:9;88855:33;;;;;;;;;:::i;:::-;;;;;;;;;;;;;88841:48;;;;88327:624;;;:::o;88793:108::-;88920:23;88935:7;88920:14;:23::i;101040:164::-;101119:9;101114:83;101138:14;101134:1;:18;101114:83;;;101174:11;101182:2;101174:7;:11::i;:::-;101154:3;;;;:::i;:::-;;;;101114:83;;39079:136;39137:7;39164:43;39168:1;39171;39164:43;;;;;;;;;;;;;;;;;:3;:43::i;90788:224::-;90890:4;-1:-1:-1;;;;;;90914:50:0;;-1:-1:-1;;;90914:50:0;;:90;;;90968:36;90992:11;90968:23;:36::i;83144:174::-;83219:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;83219:29:0;-1:-1:-1;;;;;83219:29:0;;;;;;;;:24;;83273:23;83219:24;83273:14;:23::i;:::-;-1:-1:-1;;;;;83264:46:0;;;;;;;;;;;83144:174;;:::o;78369:110::-;78445:26;78455:2;78459:7;78445:26;;;;;;;;;;;;:9;:26::i;18384:716::-;18440:13;18491:14;18508:17;18519:5;18508:10;:17::i;:::-;18528:1;18508:21;18491:38;;18544:20;18578:6;18567:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;18567:18:0;-1:-1:-1;18544:41:0;-1:-1:-1;18709:28:0;;;18725:2;18709:28;18766:288;-1:-1:-1;;18798:5:0;-1:-1:-1;;;18935:2:0;18924:14;;18919:30;18798:5;18906:44;18996:2;18987:11;;;-1:-1:-1;19021:10:0;19017:21;;19033:5;;19017:21;18766:288;;;-1:-1:-1;19075:6:0;18384:716;-1:-1:-1;;;18384:716:0:o;89107:217::-;77533:4;77131:16;;;:7;:16;;;;;;-1:-1:-1;;;;;77131:16:0;89199:75;;;;-1:-1:-1;;;89199:75:0;;22277:2:1;89199:75:0;;;22259:21:1;22316:2;22296:18;;;22289:30;22355:34;22335:18;;;22328:62;-1:-1:-1;;;22406:18:1;;;22399:44;22460:19;;89199:75:0;22075:410:1;89199:75:0;89285:19;;;;:10;:19;;;;;;;;:31;;;;;;;;:::i;102080:401::-;102137:7;;;102203:17;102213:6;102203:9;:17::i;:::-;102185:35;;102236:9;102231:220;102255:7;102251:1;:11;102231:220;;;102284:15;102302:30;102322:6;102330:1;102302:19;:30::i;:::-;102284:48;;102347:18;102368:27;102387:7;102368:18;:27::i;:::-;102347:48;-1:-1:-1;102418:21:0;:5;102347:48;102418:9;:21::i;:::-;102410:29;;102269:182;;102264:3;;;;;:::i;:::-;;;;102231:220;;;-1:-1:-1;102468:5:0;;102080:401;-1:-1:-1;;;102080:401:0:o;105271:449::-;105461:56;105488:4;105494:2;105498:7;105507:9;105461:26;:56::i;:::-;-1:-1:-1;;;;;105593:18:0;;;;;;:38;;-1:-1:-1;;;;;;105615:16:0;;;;105593:38;105589:124;;;105648:20;105657:4;105663;105648:8;:20::i;:::-;105683:18;105692:2;105696:4;105683:8;:18::i;83461:315::-;83616:8;-1:-1:-1;;;;;83607:17:0;:5;-1:-1:-1;;;;;83607:17:0;;;83599:55;;;;-1:-1:-1;;;83599:55:0;;22692:2:1;83599:55:0;;;22674:21:1;22731:2;22711:18;;;22704:30;22770:27;22750:18;;;22743:55;22815:18;;83599:55:0;22490:349:1;83599:55:0;-1:-1:-1;;;;;83665:25:0;;;;;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;:46;;-1:-1:-1;;83665:46:0;;;;;;;;;;83727:41;;540::1;;;83727::0;;513:18:1;83727:41:0;;;;;;;83461:315;;;:::o;84564:853::-;84718:4;-1:-1:-1;;;;;84739:13:0;;47251:19;:23;84735:675;;84775:71;;-1:-1:-1;;;84775:71:0;;-1:-1:-1;;;;;84775:36:0;;;;;:71;;21037:10;;84826:4;;84832:7;;84841:4;;84775:71;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;84775:71:0;;;;;;;;-1:-1:-1;;84775:71:0;;;;;;;;;;;;:::i;:::-;;;84771:584;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;85016:13:0;;85012:328;;85059:60;;-1:-1:-1;;;85059:60:0;;;;;;;:::i;85012:328::-;85290:6;85284:13;85275:6;85271:2;85267:15;85260:38;84771:584;-1:-1:-1;;;;;;84897:51:0;-1:-1:-1;;;84897:51:0;;-1:-1:-1;84890:58:0;;84735:675;-1:-1:-1;85394:4:0;84564:853;;;;;;:::o;100509:97::-;100561:13;100594:4;100587:11;;;;;:::i;72878:281::-;72951:13;72977:23;72992:7;72977:14;:23::i;:::-;73013:21;73037:10;:8;:10::i;:::-;73013:34;;73089:1;73071:7;73065:21;:25;:86;;;;;;;;;;;;;;;;;73117:7;73126:18;:7;:16;:18::i;:::-;73100:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;73065:86;73058:93;72878:281;-1:-1:-1;;;72878:281:0:o;39223:226::-;39343:7;39379:12;39371:6;;;;39363:29;;;;-1:-1:-1;;;39363:29:0;;;;;;;;:::i;:::-;-1:-1:-1;39403:9:0;39415:5;39419:1;39415;:5;:::i;71606:305::-;71708:4;-1:-1:-1;;;;;;71745:40:0;;-1:-1:-1;;;71745:40:0;;:105;;-1:-1:-1;;;;;;;71802:48:0;;-1:-1:-1;;;71802:48:0;71745:105;:158;;;-1:-1:-1;;;;;;;;;;58994:40:0;;;71867:36;58885:157;78706:319;78835:18;78841:2;78845:7;78835:5;:18::i;:::-;78886:53;78917:1;78921:2;78925:7;78934:4;78886:22;:53::i;:::-;78864:153;;;;-1:-1:-1;;;78864:153:0;;;;;;;:::i;15250:922::-;15303:7;;-1:-1:-1;;;15381:15:0;;15377:102;;-1:-1:-1;;;15417:15:0;;;-1:-1:-1;15461:2:0;15451:12;15377:102;15506:6;15497:5;:15;15493:102;;15542:6;15533:15;;;-1:-1:-1;15577:2:0;15567:12;15493:102;15622:6;15613:5;:15;15609:102;;15658:6;15649:15;;;-1:-1:-1;15693:2:0;15683:12;15609:102;15738:5;15729;:14;15725:99;;15773:5;15764:14;;;-1:-1:-1;15807:1:0;15797:11;15725:99;15851:5;15842;:14;15838:99;;15886:5;15877:14;;;-1:-1:-1;15920:1:0;15910:11;15838:99;15964:5;15955;:14;15951:99;;15999:5;15990:14;;;-1:-1:-1;16033:1:0;16023:11;15951:99;16077:5;16068;:14;16064:66;;16113:1;16103:11;16158:6;15250:922;-1:-1:-1;;15250:922:0:o;101212:860::-;101307:7;101353:1;101369:11;;;;;:29;;;101394:4;101384:7;:14;101369:29;101365:672;;;-1:-1:-1;101428:2:0;101365:672;;;101462:4;101452:7;:14;:32;;;;;101480:4;101470:7;:14;101452:32;101448:589;;;-1:-1:-1;101514:1:0;101448:589;;;101547:4;101537:7;:14;:32;;;;;101565:4;101555:7;:14;101537:32;101533:504;;;-1:-1:-1;101599:1:0;101533:504;;;101632:4;101622:7;:14;:32;;;;;101650:4;101640:7;:14;101622:32;101618:419;;;-1:-1:-1;101684:1:0;101618:419;;;101717:4;101707:7;:14;:32;;;;;101735:4;101725:7;:14;101707:32;101703:334;;;-1:-1:-1;101769:1:0;101703:334;;;101802:4;101792:7;:14;:32;;;;;101820:4;101810:7;:14;101792:32;101788:249;;;-1:-1:-1;101854:1:0;101788:249;;;101887:4;101877:7;:14;:32;;;;;101905:4;101895:7;:14;101877:32;101873:164;;;-1:-1:-1;101939:1:0;101873:164;;;101972:4;101962:7;:14;:32;;;;;101990:4;101980:7;:14;101962:32;101958:79;;;-1:-1:-1;102024:1:0;102054:10;101212:860;-1:-1:-1;;101212:860:0:o;91925:915::-;92192:1;92180:9;:13;92176:222;;;92323:63;;-1:-1:-1;;;92323:63:0;;23924:2:1;92323:63:0;;;23906:21:1;23963:2;23943:18;;;23936:30;24002:34;23982:18;;;23975:62;-1:-1:-1;;;24053:18:1;;;24046:51;24114:19;;92323:63:0;23722:417:1;92176:222:0;92428:12;-1:-1:-1;;;;;92457:18:0;;92453:187;;92492:40;92524:7;93667:10;:17;;93640:24;;;;:15;:24;;;;;:44;;;93695:24;;;;;;;;;;;;93563:164;92492:40;92453:187;;;92562:2;-1:-1:-1;;;;;92554:10:0;:4;-1:-1:-1;;;;;92554:10:0;;92550:90;;92581:47;92614:4;92620:7;92581:32;:47::i;:::-;-1:-1:-1;;;;;92654:16:0;;92650:183;;92687:45;92724:7;92687:36;:45::i;:::-;92650:183;;;92760:4;-1:-1:-1;;;;;92754:10:0;:2;-1:-1:-1;;;;;92754:10:0;;92750:83;;92781:40;92809:2;92813:7;92781:27;:40::i;79361:942::-;-1:-1:-1;;;;;79441:16:0;;79433:61;;;;-1:-1:-1;;;79433:61:0;;24346:2:1;79433:61:0;;;24328:21:1;;;24365:18;;;24358:30;24424:34;24404:18;;;24397:62;24476:18;;79433:61:0;24144:356:1;79433:61:0;77533:4;77131:16;;;:7;:16;;;;;;-1:-1:-1;;;;;77131:16:0;77557:31;79505:58;;;;-1:-1:-1;;;79505:58:0;;24707:2:1;79505:58:0;;;24689:21:1;24746:2;24726:18;;;24719:30;24785;24765:18;;;24758:58;24833:18;;79505:58:0;24505:352:1;79505:58:0;79576:48;79605:1;79609:2;79613:7;79622:1;79576:20;:48::i;:::-;77533:4;77131:16;;;:7;:16;;;;;;-1:-1:-1;;;;;77131:16:0;77557:31;79714:58;;;;-1:-1:-1;;;79714:58:0;;24707:2:1;79714:58:0;;;24689:21:1;24746:2;24726:18;;;24719:30;24785;24765:18;;;24758:58;24833:18;;79714:58:0;24505:352:1;79714:58:0;-1:-1:-1;;;;;80121:13:0;;;;;;:9;:13;;;;;;;;:18;;80138:1;80121:18;;;80163:16;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;80163:21:0;;;;;80202:33;80171:7;;80121:13;;80202:33;;80121:13;;80202:33;106393:240;;106356:277::o;94354:988::-;94620:22;94670:1;94645:22;94662:4;94645:16;:22::i;:::-;:26;;;;:::i;:::-;94682:18;94703:26;;;:17;:26;;;;;;94620:51;;-1:-1:-1;94836:28:0;;;94832:328;;-1:-1:-1;;;;;94903:18:0;;94881:19;94903:18;;;:12;:18;;;;;;;;:34;;;;;;;;;94954:30;;;;;;:44;;;95071:30;;:17;:30;;;;;:43;;;94832:328;-1:-1:-1;95256:26:0;;;;:17;:26;;;;;;;;95249:33;;;-1:-1:-1;;;;;95300:18:0;;;;;:12;:18;;;;;:34;;;;;;;95293:41;94354:988::o;95637:1079::-;95915:10;:17;95890:22;;95915:21;;95935:1;;95915:21;:::i;:::-;95947:18;95968:24;;;:15;:24;;;;;;96341:10;:26;;95890:46;;-1:-1:-1;95968:24:0;;95890:46;;96341:26;;;;;;:::i;:::-;;;;;;;;;96319:48;;96405:11;96380:10;96391;96380:22;;;;;;;;:::i;:::-;;;;;;;;;;;;:36;;;;96485:28;;;:15;:28;;;;;;;:41;;;96657:24;;;;;96650:31;96692:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;95708:1008;;;95637:1079;:::o;93141:221::-;93226:14;93243:20;93260:2;93243:16;:20::i;:::-;-1:-1:-1;;;;;93274:16:0;;;;;;;:12;:16;;;;;;;;:24;;;;;;;;:34;;;93319:26;;;:17;:26;;;;;;:35;;;;-1:-1:-1;93141:221:0:o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:131:1;-1:-1:-1;;;;;;88:32:1;;78:43;;68:71;;135:1;132;125:12;150:245;208:6;261:2;249:9;240:7;236:23;232:32;229:52;;;277:1;274;267:12;229:52;316:9;303:23;335:30;359:5;335:30;:::i;800:258::-;872:1;882:113;896:6;893:1;890:13;882:113;;;972:11;;;966:18;953:11;;;946:39;918:2;911:10;882:113;;;1013:6;1010:1;1007:13;1004:48;;;-1:-1:-1;;1048:1:1;1030:16;;1023:27;800:258::o;1063:::-;1105:3;1143:5;1137:12;1170:6;1165:3;1158:19;1186:63;1242:6;1235:4;1230:3;1226:14;1219:4;1212:5;1208:16;1186:63;:::i;:::-;1303:2;1282:15;-1:-1:-1;;1278:29:1;1269:39;;;;1310:4;1265:50;;1063:258;-1:-1:-1;;1063:258:1:o;1326:220::-;1475:2;1464:9;1457:21;1438:4;1495:45;1536:2;1525:9;1521:18;1513:6;1495:45;:::i;1551:180::-;1610:6;1663:2;1651:9;1642:7;1638:23;1634:32;1631:52;;;1679:1;1676;1669:12;1631:52;-1:-1:-1;1702:23:1;;1551:180;-1:-1:-1;1551:180:1:o;1736:173::-;1804:20;;-1:-1:-1;;;;;1853:31:1;;1843:42;;1833:70;;1899:1;1896;1889:12;1833:70;1736:173;;;:::o;1914:254::-;1982:6;1990;2043:2;2031:9;2022:7;2018:23;2014:32;2011:52;;;2059:1;2056;2049:12;2011:52;2082:29;2101:9;2082:29;:::i;:::-;2072:39;2158:2;2143:18;;;;2130:32;;-1:-1:-1;;;1914:254:1:o;2173:367::-;2236:8;2246:6;2300:3;2293:4;2285:6;2281:17;2277:27;2267:55;;2318:1;2315;2308:12;2267:55;-1:-1:-1;2341:20:1;;2384:18;2373:30;;2370:50;;;2416:1;2413;2406:12;2370:50;2453:4;2445:6;2441:17;2429:29;;2513:3;2506:4;2496:6;2493:1;2489:14;2481:6;2477:27;2473:38;2470:47;2467:67;;;2530:1;2527;2520:12;2545:770;2664:6;2672;2680;2688;2741:2;2729:9;2720:7;2716:23;2712:32;2709:52;;;2757:1;2754;2747:12;2709:52;2797:9;2784:23;2826:18;2867:2;2859:6;2856:14;2853:34;;;2883:1;2880;2873:12;2853:34;2922:70;2984:7;2975:6;2964:9;2960:22;2922:70;:::i;:::-;3011:8;;-1:-1:-1;2896:96:1;-1:-1:-1;3099:2:1;3084:18;;3071:32;;-1:-1:-1;3115:16:1;;;3112:36;;;3144:1;3141;3134:12;3112:36;;3183:72;3247:7;3236:8;3225:9;3221:24;3183:72;:::i;:::-;2545:770;;;;-1:-1:-1;3274:8:1;-1:-1:-1;;;;2545:770:1:o;3502:328::-;3579:6;3587;3595;3648:2;3636:9;3627:7;3623:23;3619:32;3616:52;;;3664:1;3661;3654:12;3616:52;3687:29;3706:9;3687:29;:::i;:::-;3677:39;;3735:38;3769:2;3758:9;3754:18;3735:38;:::i;:::-;3725:48;;3820:2;3809:9;3805:18;3792:32;3782:42;;3502:328;;;;;:::o;3835:248::-;3903:6;3911;3964:2;3952:9;3943:7;3939:23;3935:32;3932:52;;;3980:1;3977;3970:12;3932:52;-1:-1:-1;;4003:23:1;;;4073:2;4058:18;;;4045:32;;-1:-1:-1;3835:248:1:o;4367:186::-;4426:6;4479:2;4467:9;4458:7;4454:23;4450:32;4447:52;;;4495:1;4492;4485:12;4447:52;4518:29;4537:9;4518:29;:::i;4558:118::-;4644:5;4637:13;4630:21;4623:5;4620:32;4610:60;;4666:1;4663;4656:12;4681:315;4746:6;4754;4807:2;4795:9;4786:7;4782:23;4778:32;4775:52;;;4823:1;4820;4813:12;4775:52;4846:29;4865:9;4846:29;:::i;:::-;4836:39;;4925:2;4914:9;4910:18;4897:32;4938:28;4960:5;4938:28;:::i;:::-;4985:5;4975:15;;;4681:315;;;;;:::o;5001:127::-;5062:10;5057:3;5053:20;5050:1;5043:31;5093:4;5090:1;5083:15;5117:4;5114:1;5107:15;5133:275;5204:2;5198:9;5269:2;5250:13;;-1:-1:-1;;5246:27:1;5234:40;;5304:18;5289:34;;5325:22;;;5286:62;5283:88;;;5351:18;;:::i;:::-;5387:2;5380:22;5133:275;;-1:-1:-1;5133:275:1:o;5413:980::-;5508:6;5516;5524;5532;5585:3;5573:9;5564:7;5560:23;5556:33;5553:53;;;5602:1;5599;5592:12;5553:53;5625:29;5644:9;5625:29;:::i;:::-;5615:39;;5673:2;5694:38;5728:2;5717:9;5713:18;5694:38;:::i;:::-;5684:48;;5779:2;5768:9;5764:18;5751:32;5741:42;;5834:2;5823:9;5819:18;5806:32;5857:18;5898:2;5890:6;5887:14;5884:34;;;5914:1;5911;5904:12;5884:34;5952:6;5941:9;5937:22;5927:32;;5997:7;5990:4;5986:2;5982:13;5978:27;5968:55;;6019:1;6016;6009:12;5968:55;6055:2;6042:16;6077:2;6073;6070:10;6067:36;;;6083:18;;:::i;:::-;6125:53;6168:2;6149:13;;-1:-1:-1;;6145:27:1;6141:36;;6125:53;:::i;:::-;6112:66;;6201:2;6194:5;6187:17;6241:7;6236:2;6231;6227;6223:11;6219:20;6216:33;6213:53;;;6262:1;6259;6252:12;6213:53;6317:2;6312;6308;6304:11;6299:2;6292:5;6288:14;6275:45;6361:1;6356:2;6351;6344:5;6340:14;6336:23;6329:34;;6382:5;6372:15;;;;;5413:980;;;;;;;:::o;6398:309::-;6463:6;6471;6524:2;6512:9;6503:7;6499:23;6495:32;6492:52;;;6540:1;6537;6530:12;6492:52;6576:9;6563:23;6553:33;;6636:2;6625:9;6621:18;6608:32;6649:28;6671:5;6649:28;:::i;6712:260::-;6780:6;6788;6841:2;6829:9;6820:7;6816:23;6812:32;6809:52;;;6857:1;6854;6847:12;6809:52;6880:29;6899:9;6880:29;:::i;:::-;6870:39;;6928:38;6962:2;6951:9;6947:18;6928:38;:::i;:::-;6918:48;;6712:260;;;;;:::o;7204:127::-;7265:10;7260:3;7256:20;7253:1;7246:31;7296:4;7293:1;7286:15;7320:4;7317:1;7310:15;7336:908;7570:4;7618:3;7607:9;7603:19;7649:6;7638:9;7631:25;7675:2;7713:3;7708:2;7697:9;7693:18;7686:31;7737:6;7772;7766:13;7803:6;7795;7788:22;7841:3;7830:9;7826:19;7819:26;;7880:2;7872:6;7868:15;7854:29;;7901:1;7911:195;7925:6;7922:1;7919:13;7911:195;;;7990:13;;-1:-1:-1;;;;;7986:39:1;7974:52;;8081:15;;;;8046:12;;;;8022:1;7940:9;7911:195;;;-1:-1:-1;;;;;;;8162:32:1;;;;8157:2;8142:18;;8135:60;-1:-1:-1;;;8226:2:1;8211:18;8204:34;8123:3;7336:908;-1:-1:-1;;7336:908:1:o;8249:936::-;8344:6;8375:2;8418;8406:9;8397:7;8393:23;8389:32;8386:52;;;8434:1;8431;8424:12;8386:52;8467:9;8461:16;8496:18;8537:2;8529:6;8526:14;8523:34;;;8553:1;8550;8543:12;8523:34;8591:6;8580:9;8576:22;8566:32;;8636:7;8629:4;8625:2;8621:13;8617:27;8607:55;;8658:1;8655;8648:12;8607:55;8687:2;8681:9;8709:2;8705;8702:10;8699:36;;;8715:18;;:::i;:::-;8761:2;8758:1;8754:10;8744:20;;8784:28;8808:2;8804;8800:11;8784:28;:::i;:::-;8846:15;;;8916:11;;;8912:20;;;8877:12;;;;8944:19;;;8941:39;;;8976:1;8973;8966:12;8941:39;9000:11;;;;9020:135;9036:6;9031:3;9028:15;9020:135;;;9102:10;;9090:23;;9053:12;;;;9133;;;;9020:135;;;9174:5;8249:936;-1:-1:-1;;;;;;;;8249:936:1:o;9190:184::-;9260:6;9313:2;9301:9;9292:7;9288:23;9284:32;9281:52;;;9329:1;9326;9319:12;9281:52;-1:-1:-1;9352:16:1;;9190:184;-1:-1:-1;9190:184:1:o;9379:245::-;9446:6;9499:2;9487:9;9478:7;9474:23;9470:32;9467:52;;;9515:1;9512;9505:12;9467:52;9547:9;9541:16;9566:28;9588:5;9566:28;:::i;9629:380::-;9708:1;9704:12;;;;9751;;;9772:61;;9826:4;9818:6;9814:17;9804:27;;9772:61;9879:2;9871:6;9868:14;9848:18;9845:38;9842:161;;;9925:10;9920:3;9916:20;9913:1;9906:31;9960:4;9957:1;9950:15;9988:4;9985:1;9978:15;9842:161;;9629:380;;;:::o;10360:241::-;10416:6;10469:2;10457:9;10448:7;10444:23;10440:32;10437:52;;;10485:1;10482;10475:12;10437:52;10524:9;10511:23;10543:28;10565:5;10543:28;:::i;10606:127::-;10667:10;10662:3;10658:20;10655:1;10648:31;10698:4;10695:1;10688:15;10722:4;10719:1;10712:15;10738:135;10777:3;-1:-1:-1;;10798:17:1;;10795:43;;;10818:18;;:::i;:::-;-1:-1:-1;10865:1:1;10854:13;;10738:135::o;10878:409::-;11080:2;11062:21;;;11119:2;11099:18;;;11092:30;11158:34;11153:2;11138:18;;11131:62;-1:-1:-1;;;11224:2:1;11209:18;;11202:43;11277:3;11262:19;;10878:409::o;16326:217::-;16366:1;16392;16382:132;;16436:10;16431:3;16427:20;16424:1;16417:31;16471:4;16468:1;16461:15;16499:4;16496:1;16489:15;16382:132;-1:-1:-1;16528:9:1;;16326:217::o;16548:128::-;16588:3;16619:1;16615:6;16612:1;16609:13;16606:39;;;16625:18;;:::i;:::-;-1:-1:-1;16661:9:1;;16548:128::o;18356:973::-;18441:12;;18406:3;;18496:1;18516:18;;;;18569;;;;18596:61;;18650:4;18642:6;18638:17;18628:27;;18596:61;18676:2;18724;18716:6;18713:14;18693:18;18690:38;18687:161;;;18770:10;18765:3;18761:20;18758:1;18751:31;18805:4;18802:1;18795:15;18833:4;18830:1;18823:15;18687:161;18864:18;18891:104;;;;19009:1;19004:319;;;;18857:466;;18891:104;-1:-1:-1;;18924:24:1;;18912:37;;18969:16;;;;-1:-1:-1;18891:104:1;;19004:319;18303:1;18296:14;;;18340:4;18327:18;;19098:1;19112:165;19126:6;19123:1;19120:13;19112:165;;;19204:14;;19191:11;;;19184:35;19247:16;;;;19141:10;;19112:165;;;19116:3;;19306:6;19301:3;19297:16;19290:23;;18857:466;;;;;;;18356:973;;;;:::o;19334:456::-;19555:3;19583:38;19617:3;19609:6;19583:38;:::i;:::-;19650:6;19644:13;19666:52;19711:6;19707:2;19700:4;19692:6;19688:17;19666:52;:::i;:::-;19734:50;19776:6;19772:2;19768:15;19760:6;19734:50;:::i;:::-;19727:57;19334:456;-1:-1:-1;;;;;;;19334:456:1:o;19795:401::-;19997:2;19979:21;;;20036:2;20016:18;;;20009:30;20075:34;20070:2;20055:18;;20048:62;-1:-1:-1;;;20141:2:1;20126:18;;20119:35;20186:3;20171:19;;19795:401::o;20606:168::-;20646:7;20712:1;20708;20704:6;20700:14;20697:1;20694:21;20689:1;20682:9;20675:17;20671:45;20668:71;;;20719:18;;:::i;:::-;-1:-1:-1;20759:9:1;;20606:168::o;21181:414::-;21383:2;21365:21;;;21422:2;21402:18;;;21395:30;21461:34;21456:2;21441:18;;21434:62;-1:-1:-1;;;21527:2:1;21512:18;;21505:48;21585:3;21570:19;;21181:414::o;21600:470::-;21779:3;21817:6;21811:13;21833:53;21879:6;21874:3;21867:4;21859:6;21855:17;21833:53;:::i;:::-;21949:13;;21908:16;;;;21971:57;21949:13;21908:16;22005:4;21993:17;;21971:57;:::i;:::-;22044:20;;21600:470;-1:-1:-1;;;;21600:470:1:o;22844:489::-;-1:-1:-1;;;;;23113:15:1;;;23095:34;;23165:15;;23160:2;23145:18;;23138:43;23212:2;23197:18;;23190:34;;;23260:3;23255:2;23240:18;;23233:31;;;23038:4;;23281:46;;23307:19;;23299:6;23281:46;:::i;:::-;23273:54;22844:489;-1:-1:-1;;;;;;22844:489:1:o;23338:249::-;23407:6;23460:2;23448:9;23439:7;23435:23;23431:32;23428:52;;;23476:1;23473;23466:12;23428:52;23508:9;23502:16;23527:30;23551:5;23527:30;:::i;23592:125::-;23632:4;23660:1;23657;23654:8;23651:34;;;23665:18;;:::i;:::-;-1:-1:-1;23702:9:1;;23592:125::o;24862:127::-;24923:10;24918:3;24914:20;24911:1;24904:31;24954:4;24951:1;24944:15;24978:4;24975:1;24968:15
Swarm Source
ipfs://c818e5374217cd773b73bece1cad159ee66df6de3eabfe3f4c6369317132d5c2
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.