ETH Price: $4,049.62 (+4.13%)

Token

KangarooMob (KMOB)
 

Overview

Max Total Supply

40 KMOB

Holders

10

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
3 KMOB
0x2f2A4785a70295016C8357d48bAF2804edB2c390
Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information
# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
KangarooMob

Compiler Version
v0.8.19+commit.7dd6d404

Optimization Enabled:
Yes with 1000 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2023-03-04
*/

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

// File @openzeppelin/contracts/utils/[email protected]

// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
  function _msgSender() internal view virtual returns (address) {
    return msg.sender;
  }

  function _msgData() internal view virtual returns (bytes calldata) {
    return msg.data;
  }
}

// File @openzeppelin/contracts/access/[email protected]

// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
  address private _owner;

  event OwnershipTransferred(
    address indexed previousOwner,
    address indexed newOwner
  );

  /**
   * @dev Initializes the contract setting the deployer as the initial owner.
   */
  constructor() {
    _transferOwnership(_msgSender());
  }

  /**
   * @dev Throws if called by any account other than the owner.
   */
  modifier onlyOwner() {
    _checkOwner();
    _;
  }

  /**
   * @dev Returns the address of the current owner.
   */
  function owner() public view virtual returns (address) {
    return _owner;
  }

  /**
   * @dev Throws if the sender is not the owner.
   */
  function _checkOwner() internal view virtual {
    require(owner() == _msgSender(), "Ownable: caller is not the owner");
  }

  /**
   * @dev Leaves the contract without owner. It will not be possible to call
   * `onlyOwner` functions anymore. Can only be called by the current owner.
   *
   * NOTE: Renouncing ownership will leave the contract without an owner,
   * thereby removing any functionality that is only available to the owner.
   */
  function renounceOwnership() public virtual onlyOwner {
    _transferOwnership(address(0));
  }

  /**
   * @dev Transfers ownership of the contract to a new account (`newOwner`).
   * Can only be called by the current owner.
   */
  function transferOwnership(address newOwner) public virtual onlyOwner {
    require(newOwner != address(0), "Ownable: new owner is the zero address");
    _transferOwnership(newOwner);
  }

  /**
   * @dev Transfers ownership of the contract to a new account (`newOwner`).
   * Internal function without access restriction.
   */
  function _transferOwnership(address newOwner) internal virtual {
    address oldOwner = _owner;
    _owner = newOwner;
    emit OwnershipTransferred(oldOwner, newOwner);
  }
}

// File @openzeppelin/contracts/utils/introspection/[email protected]

// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)

/**
 * @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/[email protected]

// OpenZeppelin Contracts (last updated v4.6.0) (interfaces/IERC2981.sol)

/**
 * @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/[email protected]

// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)

/**
 * @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/[email protected]

// OpenZeppelin Contracts (last updated v4.7.0) (token/common/ERC2981.sol)

/**
 * @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/utils/math/[email protected]

// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)

/**
 * @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/[email protected]

// OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol)

/**
 * @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/cryptography/[email protected]

// OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/ECDSA.sol)

/**
 * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
 *
 * These functions can be used to verify that a message was signed by the holder
 * of the private keys of a given address.
 */
library ECDSA {
  enum RecoverError {
    NoError,
    InvalidSignature,
    InvalidSignatureLength,
    InvalidSignatureS,
    InvalidSignatureV // Deprecated in v4.8
  }

  function _throwError(RecoverError error) private pure {
    if (error == RecoverError.NoError) {
      return; // no error: do nothing
    } else if (error == RecoverError.InvalidSignature) {
      revert("ECDSA: invalid signature");
    } else if (error == RecoverError.InvalidSignatureLength) {
      revert("ECDSA: invalid signature length");
    } else if (error == RecoverError.InvalidSignatureS) {
      revert("ECDSA: invalid signature 's' value");
    }
  }

  /**
   * @dev Returns the address that signed a hashed message (`hash`) with
   * `signature` or error string. This address can then be used for verification purposes.
   *
   * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
   * this function rejects them by requiring the `s` value to be in the lower
   * half order, and the `v` value to be either 27 or 28.
   *
   * IMPORTANT: `hash` _must_ be the result of a hash operation for the
   * verification to be secure: it is possible to craft signatures that
   * recover to arbitrary addresses for non-hashed data. A safe way to ensure
   * this is by receiving a hash of the original message (which may otherwise
   * be too long), and then calling {toEthSignedMessageHash} on it.
   *
   * Documentation for signature generation:
   * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]
   * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]
   *
   * _Available since v4.3._
   */
  function tryRecover(
    bytes32 hash,
    bytes memory signature
  ) internal pure returns (address, RecoverError) {
    if (signature.length == 65) {
      bytes32 r;
      bytes32 s;
      uint8 v;
      // ecrecover takes the signature parameters, and the only way to get them
      // currently is to use assembly.
      /// @solidity memory-safe-assembly
      assembly {
        r := mload(add(signature, 0x20))
        s := mload(add(signature, 0x40))
        v := byte(0, mload(add(signature, 0x60)))
      }
      return tryRecover(hash, v, r, s);
    } else {
      return (address(0), RecoverError.InvalidSignatureLength);
    }
  }

  /**
   * @dev Returns the address that signed a hashed message (`hash`) with
   * `signature`. This address can then be used for verification purposes.
   *
   * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
   * this function rejects them by requiring the `s` value to be in the lower
   * half order, and the `v` value to be either 27 or 28.
   *
   * IMPORTANT: `hash` _must_ be the result of a hash operation for the
   * verification to be secure: it is possible to craft signatures that
   * recover to arbitrary addresses for non-hashed data. A safe way to ensure
   * this is by receiving a hash of the original message (which may otherwise
   * be too long), and then calling {toEthSignedMessageHash} on it.
   */
  function recover(
    bytes32 hash,
    bytes memory signature
  ) internal pure returns (address) {
    (address recovered, RecoverError error) = tryRecover(hash, signature);
    _throwError(error);
    return recovered;
  }

  /**
   * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.
   *
   * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]
   *
   * _Available since v4.3._
   */
  function tryRecover(
    bytes32 hash,
    bytes32 r,
    bytes32 vs
  ) internal pure returns (address, RecoverError) {
    bytes32 s = vs &
      bytes32(
        0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
      );
    uint8 v = uint8((uint256(vs) >> 255) + 27);
    return tryRecover(hash, v, r, s);
  }

  /**
   * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.
   *
   * _Available since v4.2._
   */
  function recover(
    bytes32 hash,
    bytes32 r,
    bytes32 vs
  ) internal pure returns (address) {
    (address recovered, RecoverError error) = tryRecover(hash, r, vs);
    _throwError(error);
    return recovered;
  }

  /**
   * @dev Overload of {ECDSA-tryRecover} that receives the `v`,
   * `r` and `s` signature fields separately.
   *
   * _Available since v4.3._
   */
  function tryRecover(
    bytes32 hash,
    uint8 v,
    bytes32 r,
    bytes32 s
  ) internal pure returns (address, RecoverError) {
    // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature
    // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines
    // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most
    // signatures from current libraries generate a unique signature with an s-value in the lower half order.
    //
    // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value
    // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or
    // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept
    // these malleable signatures as well.
    if (
      uint256(s) >
      0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0
    ) {
      return (address(0), RecoverError.InvalidSignatureS);
    }

    // If the signature is valid (and not malleable), return the signer address
    address signer = ecrecover(hash, v, r, s);
    if (signer == address(0)) {
      return (address(0), RecoverError.InvalidSignature);
    }

    return (signer, RecoverError.NoError);
  }

  /**
   * @dev Overload of {ECDSA-recover} that receives the `v`,
   * `r` and `s` signature fields separately.
   */
  function recover(
    bytes32 hash,
    uint8 v,
    bytes32 r,
    bytes32 s
  ) internal pure returns (address) {
    (address recovered, RecoverError error) = tryRecover(hash, v, r, s);
    _throwError(error);
    return recovered;
  }

  /**
   * @dev Returns an Ethereum Signed Message, created from a `hash`. This
   * produces hash corresponding to the one signed with the
   * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
   * JSON-RPC method as part of EIP-191.
   *
   * See {recover}.
   */
  function toEthSignedMessageHash(
    bytes32 hash
  ) internal pure returns (bytes32) {
    // 32 is the length in bytes of hash,
    // enforced by the type signature above
    return
      keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
  }

  /**
   * @dev Returns an Ethereum Signed Message, created from `s`. This
   * produces hash corresponding to the one signed with the
   * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
   * JSON-RPC method as part of EIP-191.
   *
   * See {recover}.
   */
  function toEthSignedMessageHash(
    bytes memory s
  ) internal pure returns (bytes32) {
    return
      keccak256(
        abi.encodePacked(
          "\x19Ethereum Signed Message:\n",
          Strings.toString(s.length),
          s
        )
      );
  }

  /**
   * @dev Returns an Ethereum Signed Typed Data, created from a
   * `domainSeparator` and a `structHash`. This produces hash corresponding
   * to the one signed with the
   * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]
   * JSON-RPC method as part of EIP-712.
   *
   * See {recover}.
   */
  function toTypedDataHash(
    bytes32 domainSeparator,
    bytes32 structHash
  ) internal pure returns (bytes32) {
    return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash));
  }
}

// File contracts/OperatorFilterer.sol

/// @notice Optimized and flexible operator filterer to abide to OpenSea's
/// mandatory on-chain royalty enforcement in order for new collections to
/// receive royalties.
/// For more information, see:
/// See: https://github.com/ProjectOpenSea/operator-filter-registry
abstract contract OperatorFilterer {
  /// @dev The default OpenSea operator blocklist subscription.
  address internal constant _DEFAULT_SUBSCRIPTION =
    0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6;

  /// @dev The OpenSea operator filter registry.
  address internal constant _OPERATOR_FILTER_REGISTRY =
    0x000000000000AAeB6D7670E522A718067333cd4E;

  /// @dev Registers the current contract to OpenSea's operator filter,
  /// and subscribe to the default OpenSea operator blocklist.
  /// Note: Will not revert nor update existing settings for repeated registration.
  function _registerForOperatorFiltering() internal virtual {
    _registerForOperatorFiltering(_DEFAULT_SUBSCRIPTION, true);
  }

  /// @dev Registers the current contract to OpenSea's operator filter.
  /// Note: Will not revert nor update existing settings for repeated registration.
  function _registerForOperatorFiltering(
    address subscriptionOrRegistrantToCopy,
    bool subscribe
  ) internal virtual {
    /// @solidity memory-safe-assembly
    assembly {
      let functionSelector := 0x7d3e3dbe // `registerAndSubscribe(address,address)`.

      // Clean the upper 96 bits of `subscriptionOrRegistrantToCopy` in case they are dirty.
      subscriptionOrRegistrantToCopy := shr(
        96,
        shl(96, subscriptionOrRegistrantToCopy)
      )

      for {

      } iszero(subscribe) {

      } {
        if iszero(subscriptionOrRegistrantToCopy) {
          functionSelector := 0x4420e486 // `register(address)`.
          break
        }
        functionSelector := 0xa0af2903 // `registerAndCopyEntries(address,address)`.
        break
      }
      // Store the function selector.
      mstore(0x00, shl(224, functionSelector))
      // Store the `address(this)`.
      mstore(0x04, address())
      // Store the `subscriptionOrRegistrantToCopy`.
      mstore(0x24, subscriptionOrRegistrantToCopy)
      // Register into the registry.
      if iszero(
        call(gas(), _OPERATOR_FILTER_REGISTRY, 0, 0x00, 0x44, 0x00, 0x04)
      ) {
        // If the function selector has not been overwritten,
        // it is an out-of-gas error.
        if eq(shr(224, mload(0x00)), functionSelector) {
          // To prevent gas under-estimation.
          revert(0, 0)
        }
      }
      // Restore the part of the free memory pointer that was overwritten,
      // which is guaranteed to be zero, because of Solidity's memory size limits.
      mstore(0x24, 0)
    }
  }

  /// @dev Modifier to guard a function and revert if the caller is a blocked operator.
  modifier onlyAllowedOperator(address from) virtual {
    if (from != msg.sender) {
      if (!_isPriorityOperator(msg.sender)) {
        if (_operatorFilteringEnabled()) _revertIfBlocked(msg.sender);
      }
    }
    _;
  }

  /// @dev Modifier to guard a function from approving a blocked operator..
  modifier onlyAllowedOperatorApproval(address operator) virtual {
    if (!_isPriorityOperator(operator)) {
      if (_operatorFilteringEnabled()) _revertIfBlocked(operator);
    }
    _;
  }

  /// @dev Helper function that reverts if the `operator` is blocked by the registry.
  function _revertIfBlocked(address operator) private view {
    /// @solidity memory-safe-assembly
    assembly {
      // Store the function selector of `isOperatorAllowed(address,address)`,
      // shifted left by 6 bytes, which is enough for 8tb of memory.
      // We waste 6-3 = 3 bytes to save on 6 runtime gas (PUSH1 0x224 SHL).
      mstore(0x00, 0xc6171134001122334455)
      // Store the `address(this)`.
      mstore(0x1a, address())
      // Store the `operator`.
      mstore(0x3a, operator)

      // `isOperatorAllowed` always returns true if it does not revert.
      if iszero(
        staticcall(gas(), _OPERATOR_FILTER_REGISTRY, 0x16, 0x44, 0x00, 0x00)
      ) {
        // Bubble up the revert if the staticcall reverts.
        returndatacopy(0x00, 0x00, returndatasize())
        revert(0x00, returndatasize())
      }

      // We'll skip checking if `from` is inside the blacklist.
      // Even though that can block transferring out of wrapper contracts,
      // we don't want tokens to be stuck.

      // Restore the part of the free memory pointer that was overwritten,
      // which is guaranteed to be zero, if less than 8tb of memory is used.
      mstore(0x3a, 0)
    }
  }

  /// @dev For deriving contracts to override, so that operator filtering
  /// can be turned on / off.
  /// Returns true by default.
  function _operatorFilteringEnabled() internal view virtual returns (bool) {
    return true;
  }

  /// @dev For deriving contracts to override, so that preferred marketplaces can
  /// skip operator filtering, helping users save gas.
  /// Returns false for all inputs by default.
  function _isPriorityOperator(address) internal view virtual returns (bool) {
    return false;
  }
}

// File erc721a/contracts/[email protected]

// ERC721A Contracts v4.2.3
// Creator: Chiru Labs

/**
 * @dev Interface of ERC721A.
 */
interface IERC721A {
  /**
   * The caller must own the token or be an approved operator.
   */
  error ApprovalCallerNotOwnerNorApproved();

  /**
   * The token does not exist.
   */
  error ApprovalQueryForNonexistentToken();

  /**
   * Cannot query the balance for the zero address.
   */
  error BalanceQueryForZeroAddress();

  /**
   * Cannot mint to the zero address.
   */
  error MintToZeroAddress();

  /**
   * The quantity of tokens minted must be more than zero.
   */
  error MintZeroQuantity();

  /**
   * The token does not exist.
   */
  error OwnerQueryForNonexistentToken();

  /**
   * The caller must own the token or be an approved operator.
   */
  error TransferCallerNotOwnerNorApproved();

  /**
   * The token must be owned by `from`.
   */
  error TransferFromIncorrectOwner();

  /**
   * Cannot safely transfer to a contract that does not implement the
   * ERC721Receiver interface.
   */
  error TransferToNonERC721ReceiverImplementer();

  /**
   * Cannot transfer to the zero address.
   */
  error TransferToZeroAddress();

  /**
   * The token does not exist.
   */
  error URIQueryForNonexistentToken();

  /**
   * The `quantity` minted with ERC2309 exceeds the safety limit.
   */
  error MintERC2309QuantityExceedsLimit();

  /**
   * The `extraData` cannot be set on an unintialized ownership slot.
   */
  error OwnershipNotInitializedForExtraData();

  // =============================================================
  //                            STRUCTS
  // =============================================================

  struct TokenOwnership {
    // The address of the owner.
    address addr;
    // Stores the start time of ownership with minimal overhead for tokenomics.
    uint64 startTimestamp;
    // Whether the token has been burned.
    bool burned;
    // Arbitrary data similar to `startTimestamp` that can be set via {_extraData}.
    uint24 extraData;
  }

  // =============================================================
  //                         TOKEN COUNTERS
  // =============================================================

  /**
   * @dev Returns the total number of tokens in existence.
   * Burned tokens will reduce the count.
   * To get the total number of tokens minted, please see {_totalMinted}.
   */
  function totalSupply() external view returns (uint256);

  // =============================================================
  //                            IERC165
  // =============================================================

  /**
   * @dev Returns true if this contract implements the interface defined by
   * `interfaceId`. See the corresponding
   * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified)
   * to learn more about how these ids are created.
   *
   * This function call must use less than 30000 gas.
   */
  function supportsInterface(bytes4 interfaceId) external view returns (bool);

  // =============================================================
  //                            IERC721
  // =============================================================

  /**
   * @dev Emitted when `tokenId` token is transferred from `from` to `to`.
   */
  event Transfer(
    address indexed from,
    address indexed to,
    uint256 indexed tokenId
  );

  /**
   * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
   */
  event Approval(
    address indexed owner,
    address indexed approved,
    uint256 indexed tokenId
  );

  /**
   * @dev Emitted when `owner` enables or disables
   * (`approved`) `operator` to manage all of its assets.
   */
  event ApprovalForAll(
    address indexed owner,
    address indexed operator,
    bool approved
  );

  /**
   * @dev Returns the number of tokens in `owner`'s account.
   */
  function balanceOf(address owner) external view returns (uint256 balance);

  /**
   * @dev Returns the owner of the `tokenId` token.
   *
   * Requirements:
   *
   * - `tokenId` must exist.
   */
  function ownerOf(uint256 tokenId) external view returns (address owner);

  /**
   * @dev Safely transfers `tokenId` token from `from` to `to`,
   * checking first that contract recipients are aware of the ERC721 protocol
   * to prevent tokens from being forever locked.
   *
   * Requirements:
   *
   * - `from` cannot be the zero address.
   * - `to` cannot be the zero address.
   * - `tokenId` token must exist and be owned by `from`.
   * - If the caller is not `from`, it must be have been allowed to move
   * this token by either {approve} or {setApprovalForAll}.
   * - If `to` refers to a smart contract, it must implement
   * {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
   *
   * Emits a {Transfer} event.
   */
  function safeTransferFrom(
    address from,
    address to,
    uint256 tokenId,
    bytes calldata data
  ) external payable;

  /**
   * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`.
   */
  function safeTransferFrom(
    address from,
    address to,
    uint256 tokenId
  ) external payable;

  /**
   * @dev Transfers `tokenId` from `from` to `to`.
   *
   * WARNING: Usage of this method is discouraged, use {safeTransferFrom}
   * whenever possible.
   *
   * Requirements:
   *
   * - `from` cannot be the zero address.
   * - `to` cannot be the zero address.
   * - `tokenId` token must be owned by `from`.
   * - If the caller is not `from`, it must be approved to move this token
   * by either {approve} or {setApprovalForAll}.
   *
   * Emits a {Transfer} event.
   */
  function transferFrom(
    address from,
    address to,
    uint256 tokenId
  ) external payable;

  /**
   * @dev Gives permission to `to` to transfer `tokenId` token to another account.
   * The approval is cleared when the token is transferred.
   *
   * Only a single account can be approved at a time, so approving the
   * zero address clears previous approvals.
   *
   * Requirements:
   *
   * - The caller must own the token or be an approved operator.
   * - `tokenId` must exist.
   *
   * Emits an {Approval} event.
   */
  function approve(address to, uint256 tokenId) external payable;

  /**
   * @dev Approve or remove `operator` as an operator for the caller.
   * Operators can call {transferFrom} or {safeTransferFrom}
   * for any token owned by the caller.
   *
   * Requirements:
   *
   * - The `operator` cannot be the caller.
   *
   * Emits an {ApprovalForAll} event.
   */
  function setApprovalForAll(address operator, bool _approved) external;

  /**
   * @dev Returns the account approved for `tokenId` token.
   *
   * Requirements:
   *
   * - `tokenId` must exist.
   */
  function getApproved(
    uint256 tokenId
  ) external view returns (address operator);

  /**
   * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
   *
   * See {setApprovalForAll}.
   */
  function isApprovedForAll(
    address owner,
    address operator
  ) external view returns (bool);

  // =============================================================
  //                        IERC721Metadata
  // =============================================================

  /**
   * @dev Returns the token collection name.
   */
  function name() external view returns (string memory);

  /**
   * @dev Returns the token collection symbol.
   */
  function symbol() external view returns (string memory);

  /**
   * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
   */
  function tokenURI(uint256 tokenId) external view returns (string memory);

  // =============================================================
  //                           IERC2309
  // =============================================================

  /**
   * @dev Emitted when tokens in `fromTokenId` to `toTokenId`
   * (inclusive) is transferred from `from` to `to`, as defined in the
   * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309) standard.
   *
   * See {_mintERC2309} for more details.
   */
  event ConsecutiveTransfer(
    uint256 indexed fromTokenId,
    uint256 toTokenId,
    address indexed from,
    address indexed to
  );
}

// File erc721a/contracts/[email protected]

// ERC721A Contracts v4.2.3
// Creator: Chiru Labs

/**
 * @dev Interface of ERC721 token receiver.
 */
interface ERC721A__IERC721Receiver {
  function onERC721Received(
    address operator,
    address from,
    uint256 tokenId,
    bytes calldata data
  ) external returns (bytes4);
}

/**
 * @title ERC721A
 *
 * @dev Implementation of the [ERC721](https://eips.ethereum.org/EIPS/eip-721)
 * Non-Fungible Token Standard, including the Metadata extension.
 * Optimized for lower gas during batch mints.
 *
 * Token IDs are minted in sequential order (e.g. 0, 1, 2, 3, ...)
 * starting from `_startTokenId()`.
 *
 * Assumptions:
 *
 * - An owner cannot have more than 2**64 - 1 (max value of uint64) of supply.
 * - The maximum token ID cannot exceed 2**256 - 1 (max value of uint256).
 */
contract ERC721A is IERC721A {
  // Bypass for a `--via-ir` bug (https://github.com/chiru-labs/ERC721A/pull/364).
  struct TokenApprovalRef {
    address value;
  }

  // =============================================================
  //                           CONSTANTS
  // =============================================================

  // Mask of an entry in packed address data.
  uint256 private constant _BITMASK_ADDRESS_DATA_ENTRY = (1 << 64) - 1;

  // The bit position of `numberMinted` in packed address data.
  uint256 private constant _BITPOS_NUMBER_MINTED = 64;

  // The bit position of `numberBurned` in packed address data.
  uint256 private constant _BITPOS_NUMBER_BURNED = 128;

  // The bit position of `aux` in packed address data.
  uint256 private constant _BITPOS_AUX = 192;

  // Mask of all 256 bits in packed address data except the 64 bits for `aux`.
  uint256 private constant _BITMASK_AUX_COMPLEMENT = (1 << 192) - 1;

  // The bit position of `startTimestamp` in packed ownership.
  uint256 private constant _BITPOS_START_TIMESTAMP = 160;

  // The bit mask of the `burned` bit in packed ownership.
  uint256 private constant _BITMASK_BURNED = 1 << 224;

  // The bit position of the `nextInitialized` bit in packed ownership.
  uint256 private constant _BITPOS_NEXT_INITIALIZED = 225;

  // The bit mask of the `nextInitialized` bit in packed ownership.
  uint256 private constant _BITMASK_NEXT_INITIALIZED = 1 << 225;

  // The bit position of `extraData` in packed ownership.
  uint256 private constant _BITPOS_EXTRA_DATA = 232;

  // Mask of all 256 bits in a packed ownership except the 24 bits for `extraData`.
  uint256 private constant _BITMASK_EXTRA_DATA_COMPLEMENT = (1 << 232) - 1;

  // The mask of the lower 160 bits for addresses.
  uint256 private constant _BITMASK_ADDRESS = (1 << 160) - 1;

  // The maximum `quantity` that can be minted with {_mintERC2309}.
  // This limit is to prevent overflows on the address data entries.
  // For a limit of 5000, a total of 3.689e15 calls to {_mintERC2309}
  // is required to cause an overflow, which is unrealistic.
  uint256 private constant _MAX_MINT_ERC2309_QUANTITY_LIMIT = 5000;

  // The `Transfer` event signature is given by:
  // `keccak256(bytes("Transfer(address,address,uint256)"))`.
  bytes32 private constant _TRANSFER_EVENT_SIGNATURE =
    0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef;

  // =============================================================
  //                            STORAGE
  // =============================================================

  // The next token ID to be minted.
  uint256 private _currentIndex;

  // The number of tokens burned.
  uint256 private _burnCounter;

  // Token name
  string private _name;

  // Token symbol
  string private _symbol;

  // Mapping from token ID to ownership details
  // An empty struct value does not necessarily mean the token is unowned.
  // See {_packedOwnershipOf} implementation for details.
  //
  // Bits Layout:
  // - [0..159]   `addr`
  // - [160..223] `startTimestamp`
  // - [224]      `burned`
  // - [225]      `nextInitialized`
  // - [232..255] `extraData`
  mapping(uint256 => uint256) private _packedOwnerships;

  // Mapping owner address to address data.
  //
  // Bits Layout:
  // - [0..63]    `balance`
  // - [64..127]  `numberMinted`
  // - [128..191] `numberBurned`
  // - [192..255] `aux`
  mapping(address => uint256) private _packedAddressData;

  // Mapping from token ID to approved address.
  mapping(uint256 => TokenApprovalRef) private _tokenApprovals;

  // Mapping from owner to operator approvals
  mapping(address => mapping(address => bool)) private _operatorApprovals;

  // =============================================================
  //                          CONSTRUCTOR
  // =============================================================

  constructor(string memory name_, string memory symbol_) {
    _name = name_;
    _symbol = symbol_;
    _currentIndex = _startTokenId();
  }

  // =============================================================
  //                   TOKEN COUNTING OPERATIONS
  // =============================================================

  /**
   * @dev Returns the starting token ID.
   * To change the starting token ID, please override this function.
   */
  function _startTokenId() internal view virtual returns (uint256) {
    return 0;
  }

  /**
   * @dev Returns the next token ID to be minted.
   */
  function _nextTokenId() internal view virtual returns (uint256) {
    return _currentIndex;
  }

  /**
   * @dev Returns the total number of tokens in existence.
   * Burned tokens will reduce the count.
   * To get the total number of tokens minted, please see {_totalMinted}.
   */
  function totalSupply() public view virtual override returns (uint256) {
    // Counter underflow is impossible as _burnCounter cannot be incremented
    // more than `_currentIndex - _startTokenId()` times.
    unchecked {
      return _currentIndex - _burnCounter - _startTokenId();
    }
  }

  /**
   * @dev Returns the total amount of tokens minted in the contract.
   */
  function _totalMinted() internal view virtual returns (uint256) {
    // Counter underflow is impossible as `_currentIndex` does not decrement,
    // and it is initialized to `_startTokenId()`.
    unchecked {
      return _currentIndex - _startTokenId();
    }
  }

  /**
   * @dev Returns the total number of tokens burned.
   */
  function _totalBurned() internal view virtual returns (uint256) {
    return _burnCounter;
  }

  // =============================================================
  //                    ADDRESS DATA OPERATIONS
  // =============================================================

  /**
   * @dev Returns the number of tokens in `owner`'s account.
   */
  function balanceOf(
    address owner
  ) public view virtual override returns (uint256) {
    if (owner == address(0)) revert BalanceQueryForZeroAddress();
    return _packedAddressData[owner] & _BITMASK_ADDRESS_DATA_ENTRY;
  }

  /**
   * Returns the number of tokens minted by `owner`.
   */
  function _numberMinted(address owner) internal view returns (uint256) {
    return
      (_packedAddressData[owner] >> _BITPOS_NUMBER_MINTED) &
      _BITMASK_ADDRESS_DATA_ENTRY;
  }

  /**
   * Returns the number of tokens burned by or on behalf of `owner`.
   */
  function _numberBurned(address owner) internal view returns (uint256) {
    return
      (_packedAddressData[owner] >> _BITPOS_NUMBER_BURNED) &
      _BITMASK_ADDRESS_DATA_ENTRY;
  }

  /**
   * Returns the auxiliary data for `owner`. (e.g. number of whitelist mint slots used).
   */
  function _getAux(address owner) internal view returns (uint64) {
    return uint64(_packedAddressData[owner] >> _BITPOS_AUX);
  }

  /**
   * Sets the auxiliary data for `owner`. (e.g. number of whitelist mint slots used).
   * If there are multiple variables, please pack them into a uint64.
   */
  function _setAux(address owner, uint64 aux) internal virtual {
    uint256 packed = _packedAddressData[owner];
    uint256 auxCasted;
    // Cast `aux` with assembly to avoid redundant masking.
    assembly {
      auxCasted := aux
    }
    packed = (packed & _BITMASK_AUX_COMPLEMENT) | (auxCasted << _BITPOS_AUX);
    _packedAddressData[owner] = packed;
  }

  // =============================================================
  //                            IERC165
  // =============================================================

  /**
   * @dev Returns true if this contract implements the interface defined by
   * `interfaceId`. See the corresponding
   * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified)
   * to learn more about how these ids are created.
   *
   * This function call must use less than 30000 gas.
   */
  function supportsInterface(
    bytes4 interfaceId
  ) public view virtual override returns (bool) {
    // The interface IDs are constants representing the first 4 bytes
    // of the XOR of all function selectors in the interface.
    // See: [ERC165](https://eips.ethereum.org/EIPS/eip-165)
    // (e.g. `bytes4(i.functionA.selector ^ i.functionB.selector ^ ...)`)
    return
      interfaceId == 0x01ffc9a7 || // ERC165 interface ID for ERC165.
      interfaceId == 0x80ac58cd || // ERC165 interface ID for ERC721.
      interfaceId == 0x5b5e139f; // ERC165 interface ID for ERC721Metadata.
  }

  // =============================================================
  //                        IERC721Metadata
  // =============================================================

  /**
   * @dev Returns the token collection name.
   */
  function name() public view virtual override returns (string memory) {
    return _name;
  }

  /**
   * @dev Returns the token collection symbol.
   */
  function symbol() public view virtual override returns (string memory) {
    return _symbol;
  }

  /**
   * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
   */
  function tokenURI(
    uint256 tokenId
  ) public view virtual override returns (string memory) {
    if (!_exists(tokenId)) revert URIQueryForNonexistentToken();

    string memory baseURI = _baseURI();
    return
      bytes(baseURI).length != 0
        ? string(abi.encodePacked(baseURI, _toString(tokenId)))
        : "";
  }

  /**
   * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each
   * token will be the concatenation of the `baseURI` and the `tokenId`. Empty
   * by default, it can be overridden in child contracts.
   */
  function _baseURI() internal view virtual returns (string memory) {
    return "";
  }

  // =============================================================
  //                     OWNERSHIPS OPERATIONS
  // =============================================================

  /**
   * @dev Returns the owner of the `tokenId` token.
   *
   * Requirements:
   *
   * - `tokenId` must exist.
   */
  function ownerOf(
    uint256 tokenId
  ) public view virtual override returns (address) {
    return address(uint160(_packedOwnershipOf(tokenId)));
  }

  /**
   * @dev Gas spent here starts off proportional to the maximum mint batch size.
   * It gradually moves to O(1) as tokens get transferred around over time.
   */
  function _ownershipOf(
    uint256 tokenId
  ) internal view virtual returns (TokenOwnership memory) {
    return _unpackedOwnership(_packedOwnershipOf(tokenId));
  }

  /**
   * @dev Returns the unpacked `TokenOwnership` struct at `index`.
   */
  function _ownershipAt(
    uint256 index
  ) internal view virtual returns (TokenOwnership memory) {
    return _unpackedOwnership(_packedOwnerships[index]);
  }

  /**
   * @dev Initializes the ownership slot minted at `index` for efficiency purposes.
   */
  function _initializeOwnershipAt(uint256 index) internal virtual {
    if (_packedOwnerships[index] == 0) {
      _packedOwnerships[index] = _packedOwnershipOf(index);
    }
  }

  /**
   * Returns the packed ownership data of `tokenId`.
   */
  function _packedOwnershipOf(uint256 tokenId) private view returns (uint256) {
    uint256 curr = tokenId;

    unchecked {
      if (_startTokenId() <= curr)
        if (curr < _currentIndex) {
          uint256 packed = _packedOwnerships[curr];
          // If not burned.
          if (packed & _BITMASK_BURNED == 0) {
            // Invariant:
            // There will always be an initialized ownership slot
            // (i.e. `ownership.addr != address(0) && ownership.burned == false`)
            // before an unintialized ownership slot
            // (i.e. `ownership.addr == address(0) && ownership.burned == false`)
            // Hence, `curr` will not underflow.
            //
            // We can directly compare the packed value.
            // If the address is zero, packed will be zero.
            while (packed == 0) {
              packed = _packedOwnerships[--curr];
            }
            return packed;
          }
        }
    }
    revert OwnerQueryForNonexistentToken();
  }

  /**
   * @dev Returns the unpacked `TokenOwnership` struct from `packed`.
   */
  function _unpackedOwnership(
    uint256 packed
  ) private pure returns (TokenOwnership memory ownership) {
    ownership.addr = address(uint160(packed));
    ownership.startTimestamp = uint64(packed >> _BITPOS_START_TIMESTAMP);
    ownership.burned = packed & _BITMASK_BURNED != 0;
    ownership.extraData = uint24(packed >> _BITPOS_EXTRA_DATA);
  }

  /**
   * @dev Packs ownership data into a single uint256.
   */
  function _packOwnershipData(
    address owner,
    uint256 flags
  ) private view returns (uint256 result) {
    assembly {
      // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean.
      owner := and(owner, _BITMASK_ADDRESS)
      // `owner | (block.timestamp << _BITPOS_START_TIMESTAMP) | flags`.
      result := or(owner, or(shl(_BITPOS_START_TIMESTAMP, timestamp()), flags))
    }
  }

  /**
   * @dev Returns the `nextInitialized` flag set if `quantity` equals 1.
   */
  function _nextInitializedFlag(
    uint256 quantity
  ) private pure returns (uint256 result) {
    // For branchless setting of the `nextInitialized` flag.
    assembly {
      // `(quantity == 1) << _BITPOS_NEXT_INITIALIZED`.
      result := shl(_BITPOS_NEXT_INITIALIZED, eq(quantity, 1))
    }
  }

  // =============================================================
  //                      APPROVAL OPERATIONS
  // =============================================================

  /**
   * @dev Gives permission to `to` to transfer `tokenId` token to another account.
   * The approval is cleared when the token is transferred.
   *
   * Only a single account can be approved at a time, so approving the
   * zero address clears previous approvals.
   *
   * Requirements:
   *
   * - The caller must own the token or be an approved operator.
   * - `tokenId` must exist.
   *
   * Emits an {Approval} event.
   */
  function approve(
    address to,
    uint256 tokenId
  ) public payable virtual override {
    address owner = ownerOf(tokenId);

    if (_msgSenderERC721A() != owner)
      if (!isApprovedForAll(owner, _msgSenderERC721A())) {
        revert ApprovalCallerNotOwnerNorApproved();
      }

    _tokenApprovals[tokenId].value = to;
    emit Approval(owner, to, tokenId);
  }

  /**
   * @dev Returns the account approved for `tokenId` token.
   *
   * Requirements:
   *
   * - `tokenId` must exist.
   */
  function getApproved(
    uint256 tokenId
  ) public view virtual override returns (address) {
    if (!_exists(tokenId)) revert ApprovalQueryForNonexistentToken();

    return _tokenApprovals[tokenId].value;
  }

  /**
   * @dev Approve or remove `operator` as an operator for the caller.
   * Operators can call {transferFrom} or {safeTransferFrom}
   * for any token owned by the caller.
   *
   * Requirements:
   *
   * - The `operator` cannot be the caller.
   *
   * Emits an {ApprovalForAll} event.
   */
  function setApprovalForAll(
    address operator,
    bool approved
  ) public virtual override {
    _operatorApprovals[_msgSenderERC721A()][operator] = approved;
    emit ApprovalForAll(_msgSenderERC721A(), operator, approved);
  }

  /**
   * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
   *
   * See {setApprovalForAll}.
   */
  function isApprovedForAll(
    address owner,
    address operator
  ) public view virtual override returns (bool) {
    return _operatorApprovals[owner][operator];
  }

  /**
   * @dev Returns whether `tokenId` exists.
   *
   * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
   *
   * Tokens start existing when they are minted. See {_mint}.
   */
  function _exists(uint256 tokenId) internal view virtual returns (bool) {
    return
      _startTokenId() <= tokenId &&
      tokenId < _currentIndex && // If within bounds,
      _packedOwnerships[tokenId] & _BITMASK_BURNED == 0; // and not burned.
  }

  /**
   * @dev Returns whether `msgSender` is equal to `approvedAddress` or `owner`.
   */
  function _isSenderApprovedOrOwner(
    address approvedAddress,
    address owner,
    address msgSender
  ) private pure returns (bool result) {
    assembly {
      // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean.
      owner := and(owner, _BITMASK_ADDRESS)
      // Mask `msgSender` to the lower 160 bits, in case the upper bits somehow aren't clean.
      msgSender := and(msgSender, _BITMASK_ADDRESS)
      // `msgSender == owner || msgSender == approvedAddress`.
      result := or(eq(msgSender, owner), eq(msgSender, approvedAddress))
    }
  }

  /**
   * @dev Returns the storage slot and value for the approved address of `tokenId`.
   */
  function _getApprovedSlotAndAddress(
    uint256 tokenId
  )
    private
    view
    returns (uint256 approvedAddressSlot, address approvedAddress)
  {
    TokenApprovalRef storage tokenApproval = _tokenApprovals[tokenId];
    // The following is equivalent to `approvedAddress = _tokenApprovals[tokenId].value`.
    assembly {
      approvedAddressSlot := tokenApproval.slot
      approvedAddress := sload(approvedAddressSlot)
    }
  }

  // =============================================================
  //                      TRANSFER OPERATIONS
  // =============================================================

  /**
   * @dev Transfers `tokenId` from `from` to `to`.
   *
   * Requirements:
   *
   * - `from` cannot be the zero address.
   * - `to` cannot be the zero address.
   * - `tokenId` token must be owned by `from`.
   * - If the caller is not `from`, it must be approved to move this token
   * by either {approve} or {setApprovalForAll}.
   *
   * Emits a {Transfer} event.
   */
  function transferFrom(
    address from,
    address to,
    uint256 tokenId
  ) public payable virtual override {
    uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId);

    if (address(uint160(prevOwnershipPacked)) != from)
      revert TransferFromIncorrectOwner();

    (
      uint256 approvedAddressSlot,
      address approvedAddress
    ) = _getApprovedSlotAndAddress(tokenId);

    // The nested ifs save around 20+ gas over a compound boolean condition.
    if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A()))
      if (!isApprovedForAll(from, _msgSenderERC721A()))
        revert TransferCallerNotOwnerNorApproved();

    if (to == address(0)) revert TransferToZeroAddress();

    _beforeTokenTransfers(from, to, tokenId, 1);

    // Clear approvals from the previous owner.
    assembly {
      if approvedAddress {
        // This is equivalent to `delete _tokenApprovals[tokenId]`.
        sstore(approvedAddressSlot, 0)
      }
    }

    // Underflow of the sender's balance is impossible because we check for
    // ownership above and the recipient's balance can't realistically overflow.
    // Counter overflow is incredibly unrealistic as `tokenId` would have to be 2**256.
    unchecked {
      // We can directly increment and decrement the balances.
      --_packedAddressData[from]; // Updates: `balance -= 1`.
      ++_packedAddressData[to]; // Updates: `balance += 1`.

      // Updates:
      // - `address` to the next owner.
      // - `startTimestamp` to the timestamp of transfering.
      // - `burned` to `false`.
      // - `nextInitialized` to `true`.
      _packedOwnerships[tokenId] = _packOwnershipData(
        to,
        _BITMASK_NEXT_INITIALIZED |
          _nextExtraData(from, to, prevOwnershipPacked)
      );

      // If the next slot may not have been initialized (i.e. `nextInitialized == false`) .
      if (prevOwnershipPacked & _BITMASK_NEXT_INITIALIZED == 0) {
        uint256 nextTokenId = tokenId + 1;
        // If the next slot's address is zero and not burned (i.e. packed value is zero).
        if (_packedOwnerships[nextTokenId] == 0) {
          // If the next slot is within bounds.
          if (nextTokenId != _currentIndex) {
            // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`.
            _packedOwnerships[nextTokenId] = prevOwnershipPacked;
          }
        }
      }
    }

    emit Transfer(from, to, tokenId);
    _afterTokenTransfers(from, to, tokenId, 1);
  }

  /**
   * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`.
   */
  function safeTransferFrom(
    address from,
    address to,
    uint256 tokenId
  ) public payable virtual override {
    safeTransferFrom(from, to, tokenId, "");
  }

  /**
   * @dev Safely transfers `tokenId` token from `from` to `to`.
   *
   * Requirements:
   *
   * - `from` cannot be the zero address.
   * - `to` cannot be the zero address.
   * - `tokenId` token must exist and be owned by `from`.
   * - If the caller is not `from`, it must be approved to move this token
   * by either {approve} or {setApprovalForAll}.
   * - If `to` refers to a smart contract, it must implement
   * {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
   *
   * Emits a {Transfer} event.
   */
  function safeTransferFrom(
    address from,
    address to,
    uint256 tokenId,
    bytes memory _data
  ) public payable virtual override {
    transferFrom(from, to, tokenId);
    if (to.code.length != 0)
      if (!_checkContractOnERC721Received(from, to, tokenId, _data)) {
        revert TransferToNonERC721ReceiverImplementer();
      }
  }

  /**
   * @dev Hook that is called before a set of serially-ordered token IDs
   * are about to be transferred. This includes minting.
   * And also called before burning one token.
   *
   * `startTokenId` - the first token ID to be transferred.
   * `quantity` - the amount to be transferred.
   *
   * Calling conditions:
   *
   * - When `from` and `to` are both non-zero, `from`'s `tokenId` will be
   * transferred to `to`.
   * - When `from` is zero, `tokenId` will be minted for `to`.
   * - When `to` is zero, `tokenId` will be burned by `from`.
   * - `from` and `to` are never both zero.
   */
  function _beforeTokenTransfers(
    address from,
    address to,
    uint256 startTokenId,
    uint256 quantity
  ) internal virtual {}

  /**
   * @dev Hook that is called after a set of serially-ordered token IDs
   * have been transferred. This includes minting.
   * And also called after one token has been burned.
   *
   * `startTokenId` - the first token ID to be transferred.
   * `quantity` - the amount to be transferred.
   *
   * Calling conditions:
   *
   * - When `from` and `to` are both non-zero, `from`'s `tokenId` has been
   * transferred to `to`.
   * - When `from` is zero, `tokenId` has been minted for `to`.
   * - When `to` is zero, `tokenId` has been burned by `from`.
   * - `from` and `to` are never both zero.
   */
  function _afterTokenTransfers(
    address from,
    address to,
    uint256 startTokenId,
    uint256 quantity
  ) internal virtual {}

  /**
   * @dev Private function to invoke {IERC721Receiver-onERC721Received} on a target contract.
   *
   * `from` - Previous owner of the given token ID.
   * `to` - Target address that will receive the token.
   * `tokenId` - Token ID to be transferred.
   * `_data` - Optional data to send along with the call.
   *
   * Returns whether the call correctly returned the expected magic value.
   */
  function _checkContractOnERC721Received(
    address from,
    address to,
    uint256 tokenId,
    bytes memory _data
  ) private returns (bool) {
    try
      ERC721A__IERC721Receiver(to).onERC721Received(
        _msgSenderERC721A(),
        from,
        tokenId,
        _data
      )
    returns (bytes4 retval) {
      return retval == ERC721A__IERC721Receiver(to).onERC721Received.selector;
    } catch (bytes memory reason) {
      if (reason.length == 0) {
        revert TransferToNonERC721ReceiverImplementer();
      } else {
        assembly {
          revert(add(32, reason), mload(reason))
        }
      }
    }
  }

  // =============================================================
  //                        MINT OPERATIONS
  // =============================================================

  /**
   * @dev Mints `quantity` tokens and transfers them to `to`.
   *
   * Requirements:
   *
   * - `to` cannot be the zero address.
   * - `quantity` must be greater than 0.
   *
   * Emits a {Transfer} event for each mint.
   */
  function _mint(address to, uint256 quantity) internal virtual {
    uint256 startTokenId = _currentIndex;
    if (quantity == 0) revert MintZeroQuantity();

    _beforeTokenTransfers(address(0), to, startTokenId, quantity);

    // Overflows are incredibly unrealistic.
    // `balance` and `numberMinted` have a maximum limit of 2**64.
    // `tokenId` has a maximum limit of 2**256.
    unchecked {
      // Updates:
      // - `balance += quantity`.
      // - `numberMinted += quantity`.
      //
      // We can directly add to the `balance` and `numberMinted`.
      _packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1);

      // Updates:
      // - `address` to the owner.
      // - `startTimestamp` to the timestamp of minting.
      // - `burned` to `false`.
      // - `nextInitialized` to `quantity == 1`.
      _packedOwnerships[startTokenId] = _packOwnershipData(
        to,
        _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0)
      );

      uint256 toMasked;
      uint256 end = startTokenId + quantity;

      // Use assembly to loop and emit the `Transfer` event for gas savings.
      // The duplicated `log4` removes an extra check and reduces stack juggling.
      // The assembly, together with the surrounding Solidity code, have been
      // delicately arranged to nudge the compiler into producing optimized opcodes.
      assembly {
        // Mask `to` to the lower 160 bits, in case the upper bits somehow aren't clean.
        toMasked := and(to, _BITMASK_ADDRESS)
        // Emit the `Transfer` event.
        log4(
          0, // Start of data (0, since no data).
          0, // End of data (0, since no data).
          _TRANSFER_EVENT_SIGNATURE, // Signature.
          0, // `address(0)`.
          toMasked, // `to`.
          startTokenId // `tokenId`.
        )

        // The `iszero(eq(,))` check ensures that large values of `quantity`
        // that overflows uint256 will make the loop run out of gas.
        // The compiler will optimize the `iszero` away for performance.
        for {
          let tokenId := add(startTokenId, 1)
        } iszero(eq(tokenId, end)) {
          tokenId := add(tokenId, 1)
        } {
          // Emit the `Transfer` event. Similar to above.
          log4(0, 0, _TRANSFER_EVENT_SIGNATURE, 0, toMasked, tokenId)
        }
      }
      if (toMasked == 0) revert MintToZeroAddress();

      _currentIndex = end;
    }
    _afterTokenTransfers(address(0), to, startTokenId, quantity);
  }

  /**
   * @dev Mints `quantity` tokens and transfers them to `to`.
   *
   * This function is intended for efficient minting only during contract creation.
   *
   * It emits only one {ConsecutiveTransfer} as defined in
   * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309),
   * instead of a sequence of {Transfer} event(s).
   *
   * Calling this function outside of contract creation WILL make your contract
   * non-compliant with the ERC721 standard.
   * For full ERC721 compliance, substituting ERC721 {Transfer} event(s) with the ERC2309
   * {ConsecutiveTransfer} event is only permissible during contract creation.
   *
   * Requirements:
   *
   * - `to` cannot be the zero address.
   * - `quantity` must be greater than 0.
   *
   * Emits a {ConsecutiveTransfer} event.
   */
  function _mintERC2309(address to, uint256 quantity) internal virtual {
    uint256 startTokenId = _currentIndex;
    if (to == address(0)) revert MintToZeroAddress();
    if (quantity == 0) revert MintZeroQuantity();
    if (quantity > _MAX_MINT_ERC2309_QUANTITY_LIMIT)
      revert MintERC2309QuantityExceedsLimit();

    _beforeTokenTransfers(address(0), to, startTokenId, quantity);

    // Overflows are unrealistic due to the above check for `quantity` to be below the limit.
    unchecked {
      // Updates:
      // - `balance += quantity`.
      // - `numberMinted += quantity`.
      //
      // We can directly add to the `balance` and `numberMinted`.
      _packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1);

      // Updates:
      // - `address` to the owner.
      // - `startTimestamp` to the timestamp of minting.
      // - `burned` to `false`.
      // - `nextInitialized` to `quantity == 1`.
      _packedOwnerships[startTokenId] = _packOwnershipData(
        to,
        _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0)
      );

      emit ConsecutiveTransfer(
        startTokenId,
        startTokenId + quantity - 1,
        address(0),
        to
      );

      _currentIndex = startTokenId + quantity;
    }
    _afterTokenTransfers(address(0), to, startTokenId, quantity);
  }

  /**
   * @dev Safely mints `quantity` tokens and transfers them to `to`.
   *
   * Requirements:
   *
   * - If `to` refers to a smart contract, it must implement
   * {IERC721Receiver-onERC721Received}, which is called for each safe transfer.
   * - `quantity` must be greater than 0.
   *
   * See {_mint}.
   *
   * Emits a {Transfer} event for each mint.
   */
  function _safeMint(
    address to,
    uint256 quantity,
    bytes memory _data
  ) internal virtual {
    _mint(to, quantity);

    unchecked {
      if (to.code.length != 0) {
        uint256 end = _currentIndex;
        uint256 index = end - quantity;
        do {
          if (!_checkContractOnERC721Received(address(0), to, index++, _data)) {
            revert TransferToNonERC721ReceiverImplementer();
          }
        } while (index < end);
        // Reentrancy protection.
        if (_currentIndex != end) revert();
      }
    }
  }

  /**
   * @dev Equivalent to `_safeMint(to, quantity, '')`.
   */
  function _safeMint(address to, uint256 quantity) internal virtual {
    _safeMint(to, quantity, "");
  }

  // =============================================================
  //                        BURN OPERATIONS
  // =============================================================

  /**
   * @dev Equivalent to `_burn(tokenId, false)`.
   */
  function _burn(uint256 tokenId) internal virtual {
    _burn(tokenId, false);
  }

  /**
   * @dev Destroys `tokenId`.
   * The approval is cleared when the token is burned.
   *
   * Requirements:
   *
   * - `tokenId` must exist.
   *
   * Emits a {Transfer} event.
   */
  function _burn(uint256 tokenId, bool approvalCheck) internal virtual {
    uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId);

    address from = address(uint160(prevOwnershipPacked));

    (
      uint256 approvedAddressSlot,
      address approvedAddress
    ) = _getApprovedSlotAndAddress(tokenId);

    if (approvalCheck) {
      // The nested ifs save around 20+ gas over a compound boolean condition.
      if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A()))
        if (!isApprovedForAll(from, _msgSenderERC721A()))
          revert TransferCallerNotOwnerNorApproved();
    }

    _beforeTokenTransfers(from, address(0), tokenId, 1);

    // Clear approvals from the previous owner.
    assembly {
      if approvedAddress {
        // This is equivalent to `delete _tokenApprovals[tokenId]`.
        sstore(approvedAddressSlot, 0)
      }
    }

    // Underflow of the sender's balance is impossible because we check for
    // ownership above and the recipient's balance can't realistically overflow.
    // Counter overflow is incredibly unrealistic as `tokenId` would have to be 2**256.
    unchecked {
      // Updates:
      // - `balance -= 1`.
      // - `numberBurned += 1`.
      //
      // We can directly decrement the balance, and increment the number burned.
      // This is equivalent to `packed -= 1; packed += 1 << _BITPOS_NUMBER_BURNED;`.
      _packedAddressData[from] += (1 << _BITPOS_NUMBER_BURNED) - 1;

      // Updates:
      // - `address` to the last owner.
      // - `startTimestamp` to the timestamp of burning.
      // - `burned` to `true`.
      // - `nextInitialized` to `true`.
      _packedOwnerships[tokenId] = _packOwnershipData(
        from,
        (_BITMASK_BURNED | _BITMASK_NEXT_INITIALIZED) |
          _nextExtraData(from, address(0), prevOwnershipPacked)
      );

      // If the next slot may not have been initialized (i.e. `nextInitialized == false`) .
      if (prevOwnershipPacked & _BITMASK_NEXT_INITIALIZED == 0) {
        uint256 nextTokenId = tokenId + 1;
        // If the next slot's address is zero and not burned (i.e. packed value is zero).
        if (_packedOwnerships[nextTokenId] == 0) {
          // If the next slot is within bounds.
          if (nextTokenId != _currentIndex) {
            // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`.
            _packedOwnerships[nextTokenId] = prevOwnershipPacked;
          }
        }
      }
    }

    emit Transfer(from, address(0), tokenId);
    _afterTokenTransfers(from, address(0), tokenId, 1);

    // Overflow not possible, as _burnCounter cannot be exceed _currentIndex times.
    unchecked {
      _burnCounter++;
    }
  }

  // =============================================================
  //                     EXTRA DATA OPERATIONS
  // =============================================================

  /**
   * @dev Directly sets the extra data for the ownership data `index`.
   */
  function _setExtraDataAt(uint256 index, uint24 extraData) internal virtual {
    uint256 packed = _packedOwnerships[index];
    if (packed == 0) revert OwnershipNotInitializedForExtraData();
    uint256 extraDataCasted;
    // Cast `extraData` with assembly to avoid redundant masking.
    assembly {
      extraDataCasted := extraData
    }
    packed =
      (packed & _BITMASK_EXTRA_DATA_COMPLEMENT) |
      (extraDataCasted << _BITPOS_EXTRA_DATA);
    _packedOwnerships[index] = packed;
  }

  /**
   * @dev Called during each token transfer to set the 24bit `extraData` field.
   * Intended to be overridden by the cosumer contract.
   *
   * `previousExtraData` - the value of `extraData` before transfer.
   *
   * Calling conditions:
   *
   * - When `from` and `to` are both non-zero, `from`'s `tokenId` will be
   * transferred to `to`.
   * - When `from` is zero, `tokenId` will be minted for `to`.
   * - When `to` is zero, `tokenId` will be burned by `from`.
   * - `from` and `to` are never both zero.
   */
  function _extraData(
    address from,
    address to,
    uint24 previousExtraData
  ) internal view virtual returns (uint24) {}

  /**
   * @dev Returns the next extra data for the packed ownership data.
   * The returned result is shifted into position.
   */
  function _nextExtraData(
    address from,
    address to,
    uint256 prevOwnershipPacked
  ) private view returns (uint256) {
    uint24 extraData = uint24(prevOwnershipPacked >> _BITPOS_EXTRA_DATA);
    return uint256(_extraData(from, to, extraData)) << _BITPOS_EXTRA_DATA;
  }

  // =============================================================
  //                       OTHER OPERATIONS
  // =============================================================

  /**
   * @dev Returns the message sender (defaults to `msg.sender`).
   *
   * If you are writing GSN compatible contracts, you need to override this function.
   */
  function _msgSenderERC721A() internal view virtual returns (address) {
    return msg.sender;
  }

  /**
   * @dev Converts a uint256 to its ASCII string decimal representation.
   */
  function _toString(
    uint256 value
  ) internal pure virtual returns (string memory str) {
    assembly {
      // The maximum value of a uint256 contains 78 digits (1 byte per digit), but
      // we allocate 0xa0 bytes to keep the free memory pointer 32-byte word aligned.
      // We will need 1 word for the trailing zeros padding, 1 word for the length,
      // and 3 words for a maximum of 78 digits. Total: 5 * 0x20 = 0xa0.
      let m := add(mload(0x40), 0xa0)
      // Update the free memory pointer to allocate.
      mstore(0x40, m)
      // Assign the `str` to the end.
      str := sub(m, 0x20)
      // Zeroize the slot after the string.
      mstore(str, 0)

      // Cache the end of the memory to calculate the length later.
      let end := str

      // We write the string from rightmost digit to leftmost digit.
      // The following is essentially a do-while loop that also handles the zero case.
      // prettier-ignore
      for { let temp := value } 1 {} {
                str := sub(str, 1)
                // Write the character to the pointer.
                // The ASCII index of the '0' character is 48.
                mstore8(str, add(48, mod(temp, 10)))
                // Keep dividing `temp` until zero.
                temp := div(temp, 10)
                // prettier-ignore
                if iszero(temp) { break }
            }

      let length := sub(end, str)
      // Move the pointer 32 bytes leftwards to make room for the length.
      str := sub(str, 0x20)
      // Store the length.
      mstore(str, length)
    }
  }
}

// File erc721a/contracts/extensions/[email protected]

// ERC721A Contracts v4.2.3
// Creator: Chiru Labs

/**
 * @dev Interface of ERC721AQueryable.
 */
interface IERC721AQueryable is IERC721A {
  /**
   * Invalid query range (`start` >= `stop`).
   */
  error InvalidQueryRange();

  /**
   * @dev Returns the `TokenOwnership` struct at `tokenId` without reverting.
   *
   * If the `tokenId` is out of bounds:
   *
   * - `addr = address(0)`
   * - `startTimestamp = 0`
   * - `burned = false`
   * - `extraData = 0`
   *
   * If the `tokenId` is burned:
   *
   * - `addr = <Address of owner before token was burned>`
   * - `startTimestamp = <Timestamp when token was burned>`
   * - `burned = true`
   * - `extraData = <Extra data when token was burned>`
   *
   * Otherwise:
   *
   * - `addr = <Address of owner>`
   * - `startTimestamp = <Timestamp of start of ownership>`
   * - `burned = false`
   * - `extraData = <Extra data at start of ownership>`
   */
  function explicitOwnershipOf(
    uint256 tokenId
  ) external view returns (TokenOwnership memory);

  /**
   * @dev Returns an array of `TokenOwnership` structs at `tokenIds` in order.
   * See {ERC721AQueryable-explicitOwnershipOf}
   */
  function explicitOwnershipsOf(
    uint256[] memory tokenIds
  ) external view returns (TokenOwnership[] memory);

  /**
   * @dev Returns an array of token IDs owned by `owner`,
   * in the range [`start`, `stop`)
   * (i.e. `start <= tokenId < stop`).
   *
   * This function allows for tokens to be queried if the collection
   * grows too big for a single call of {ERC721AQueryable-tokensOfOwner}.
   *
   * Requirements:
   *
   * - `start < stop`
   */
  function tokensOfOwnerIn(
    address owner,
    uint256 start,
    uint256 stop
  ) external view returns (uint256[] memory);

  /**
   * @dev Returns an array of token IDs owned by `owner`.
   *
   * This function scans the ownership mapping and is O(`totalSupply`) in complexity.
   * It is meant to be called off-chain.
   *
   * See {ERC721AQueryable-tokensOfOwnerIn} for splitting the scan into
   * multiple smaller scans if the collection is large enough to cause
   * an out-of-gas error (10K collections should be fine).
   */
  function tokensOfOwner(
    address owner
  ) external view returns (uint256[] memory);
}

// File erc721a/contracts/extensions/[email protected]

// ERC721A Contracts v4.2.3
// Creator: Chiru Labs

/**
 * @title ERC721AQueryable.
 *
 * @dev ERC721A subclass with convenience query functions.
 */
abstract contract ERC721AQueryable is ERC721A, IERC721AQueryable {
  /**
   * @dev Returns the `TokenOwnership` struct at `tokenId` without reverting.
   *
   * If the `tokenId` is out of bounds:
   *
   * - `addr = address(0)`
   * - `startTimestamp = 0`
   * - `burned = false`
   * - `extraData = 0`
   *
   * If the `tokenId` is burned:
   *
   * - `addr = <Address of owner before token was burned>`
   * - `startTimestamp = <Timestamp when token was burned>`
   * - `burned = true`
   * - `extraData = <Extra data when token was burned>`
   *
   * Otherwise:
   *
   * - `addr = <Address of owner>`
   * - `startTimestamp = <Timestamp of start of ownership>`
   * - `burned = false`
   * - `extraData = <Extra data at start of ownership>`
   */
  function explicitOwnershipOf(
    uint256 tokenId
  ) public view virtual override returns (TokenOwnership memory) {
    TokenOwnership memory ownership;
    if (tokenId < _startTokenId() || tokenId >= _nextTokenId()) {
      return ownership;
    }
    ownership = _ownershipAt(tokenId);
    if (ownership.burned) {
      return ownership;
    }
    return _ownershipOf(tokenId);
  }

  /**
   * @dev Returns an array of `TokenOwnership` structs at `tokenIds` in order.
   * See {ERC721AQueryable-explicitOwnershipOf}
   */
  function explicitOwnershipsOf(
    uint256[] calldata tokenIds
  ) external view virtual override returns (TokenOwnership[] memory) {
    unchecked {
      uint256 tokenIdsLength = tokenIds.length;
      TokenOwnership[] memory ownerships = new TokenOwnership[](tokenIdsLength);
      for (uint256 i; i != tokenIdsLength; ++i) {
        ownerships[i] = explicitOwnershipOf(tokenIds[i]);
      }
      return ownerships;
    }
  }

  /**
   * @dev Returns an array of token IDs owned by `owner`,
   * in the range [`start`, `stop`)
   * (i.e. `start <= tokenId < stop`).
   *
   * This function allows for tokens to be queried if the collection
   * grows too big for a single call of {ERC721AQueryable-tokensOfOwner}.
   *
   * Requirements:
   *
   * - `start < stop`
   */
  function tokensOfOwnerIn(
    address owner,
    uint256 start,
    uint256 stop
  ) external view virtual override returns (uint256[] memory) {
    unchecked {
      if (start >= stop) revert InvalidQueryRange();
      uint256 tokenIdsIdx;
      uint256 stopLimit = _nextTokenId();
      // Set `start = max(start, _startTokenId())`.
      if (start < _startTokenId()) {
        start = _startTokenId();
      }
      // Set `stop = min(stop, stopLimit)`.
      if (stop > stopLimit) {
        stop = stopLimit;
      }
      uint256 tokenIdsMaxLength = balanceOf(owner);
      // Set `tokenIdsMaxLength = min(balanceOf(owner), stop - start)`,
      // to cater for cases where `balanceOf(owner)` is too big.
      if (start < stop) {
        uint256 rangeLength = stop - start;
        if (rangeLength < tokenIdsMaxLength) {
          tokenIdsMaxLength = rangeLength;
        }
      } else {
        tokenIdsMaxLength = 0;
      }
      uint256[] memory tokenIds = new uint256[](tokenIdsMaxLength);
      if (tokenIdsMaxLength == 0) {
        return tokenIds;
      }
      // We need to call `explicitOwnershipOf(start)`,
      // because the slot at `start` may not be initialized.
      TokenOwnership memory ownership = explicitOwnershipOf(start);
      address currOwnershipAddr;
      // If the starting slot exists (i.e. not burned), initialize `currOwnershipAddr`.
      // `ownership.address` will not be zero, as `start` is clamped to the valid token ID range.
      if (!ownership.burned) {
        currOwnershipAddr = ownership.addr;
      }
      for (
        uint256 i = start;
        i != stop && tokenIdsIdx != tokenIdsMaxLength;
        ++i
      ) {
        ownership = _ownershipAt(i);
        if (ownership.burned) {
          continue;
        }
        if (ownership.addr != address(0)) {
          currOwnershipAddr = ownership.addr;
        }
        if (currOwnershipAddr == owner) {
          tokenIds[tokenIdsIdx++] = i;
        }
      }
      // Downsize the array to fit.
      assembly {
        mstore(tokenIds, tokenIdsIdx)
      }
      return tokenIds;
    }
  }

  /**
   * @dev Returns an array of token IDs owned by `owner`.
   *
   * This function scans the ownership mapping and is O(`totalSupply`) in complexity.
   * It is meant to be called off-chain.
   *
   * See {ERC721AQueryable-tokensOfOwnerIn} for splitting the scan into
   * multiple smaller scans if the collection is large enough to cause
   * an out-of-gas error (10K collections should be fine).
   */
  function tokensOfOwner(
    address owner
  ) external view virtual override returns (uint256[] memory) {
    unchecked {
      uint256 tokenIdsIdx;
      address currOwnershipAddr;
      uint256 tokenIdsLength = balanceOf(owner);
      uint256[] memory tokenIds = new uint256[](tokenIdsLength);
      TokenOwnership memory ownership;
      for (uint256 i = _startTokenId(); tokenIdsIdx != tokenIdsLength; ++i) {
        ownership = _ownershipAt(i);
        if (ownership.burned) {
          continue;
        }
        if (ownership.addr != address(0)) {
          currOwnershipAddr = ownership.addr;
        }
        if (currOwnershipAddr == owner) {
          tokenIds[tokenIdsIdx++] = i;
        }
      }
      return tokenIds;
    }
  }
}

// File contracts/KangarooMob.sol

contract KangarooMob is ERC721AQueryable, OperatorFilterer, Ownable, ERC2981 {
  using ECDSA for bytes32;
  uint256 public constant MAX_SUPPLY = 1778;
  uint256 public constant PRESALE_SUPPLY = 778;
  uint256 public constant PRESALE_ALLOWANCE = 4;
  uint256 public constant PRESALE_PRICE = 0.025 ether;
  uint256 public constant PRICE = 0.03 ether;
  bool public operatorFilteringEnabled;
  bool public metadataLocked;
  string public baseURI;
  string public provenanceHash;
  string private _contractUri;
  address private _signerAddress;
  mapping(string => bool) private _usedNonces;
  enum SaleState {
    Closed,
    Presale,
    PublicSale
  }
  SaleState public saleState;

  constructor() ERC721A("KangarooMob", "KMOB") {
    _registerForOperatorFiltering();
    operatorFilteringEnabled = true;
    _setDefaultRoyalty(msg.sender, 500);
    saleState = SaleState.Closed;
  }

  modifier notLocked() {
    require(!metadataLocked, "METADATA_LOCKED");
    _;
  }

  function setContractURI(
    string calldata contractUri
  ) external onlyOwner notLocked {
    _contractUri = contractUri;
  }

  function contractURI() public view returns (string memory) {
    return _contractUri;
  }

  function setProvenance(
    string calldata newProvenanceHash
  ) external onlyOwner notLocked {
    provenanceHash = newProvenanceHash;
  }

  function lockMetadata() external onlyOwner {
    metadataLocked = true;
  }

  function setSaleState(uint state) external onlyOwner {
    require(state < 3, "INVALID_SALE_STATE");
    saleState = SaleState(state);
  }

  function setSignerAddress(address signerAddress) external onlyOwner {
    _signerAddress = signerAddress;
  }

  function setBaseURI(string calldata newBaseURI) external onlyOwner notLocked {
    baseURI = newBaseURI;
  }

  function _baseURI() internal view override returns (string memory) {
    return baseURI;
  }

  function presaleMint(
    uint256 amount,
    string calldata nonce,
    bytes calldata signature
  ) external payable {
    require(saleState == SaleState.Presale, "PRESALE_INACTIVE");
    require(_totalMinted() + amount < PRESALE_SUPPLY, "EXCEEDS_PRESALE_SUPPLY");
    require(
      _numberMinted(_msgSender()) + amount < PRESALE_ALLOWANCE,
      "EXCEEDS_PRESALE_ALLOWANCE"
    );
    _mintNFT(amount, PRESALE_PRICE, nonce, signature);
  }

  function publicMint(
    uint256 amount,
    string calldata nonce,
    bytes calldata signature
  ) external payable {
    require(saleState == SaleState.PublicSale, "SALE_INACTIVE");
    require(_totalMinted() + amount < MAX_SUPPLY, "EXCEEDS_MAX_SUPPLY");
    _mintNFT(amount, PRICE, nonce, signature);
  }

  function _mintNFT(
    uint256 amount,
    uint256 price,
    string memory nonce,
    bytes memory signature
  ) private {
    require(msg.value >= amount * price, "WRONG_ETH_AMOUNT");
    require(!_usedNonces[nonce], "INVALID_HASH");
    require(
      keccak256(abi.encodePacked(_msgSender(), amount, nonce))
        .toEthSignedMessageHash()
        .recover(signature) == _signerAddress,
      "INVALID_SIGNATURE"
    );
    _usedNonces[nonce] = true;
    _mint(_msgSender(), amount);
  }

  function reserveTokens(uint256 amount) external onlyOwner {
    require(_totalMinted() + amount < MAX_SUPPLY, "EXCEEDS_MAX_SUPPLY");
    _mint(_msgSender(), amount);
  }

  function withdraw() external onlyOwner {
    uint onePercent = address(this).balance / 100;
    address payable Owner1 = payable(
      0x9316D2F0Edb9304077b549EeB27b6b7924a609F7
    );
    address payable Owner2 = payable(
      0x637c99d3E0Ca88c828925DAAaddB1B505075B576
    );
    Owner1.transfer(onePercent * 80);
    Owner2.transfer(onePercent * 20);
  }

  function _startTokenId() internal pure override returns (uint256) {
    return 1;
  }

  function setApprovalForAll(
    address operator,
    bool approved
  ) public override(IERC721A, ERC721A) onlyAllowedOperatorApproval(operator) {
    super.setApprovalForAll(operator, approved);
  }

  function approve(
    address operator,
    uint256 tokenId
  )
    public
    payable
    override(IERC721A, ERC721A)
    onlyAllowedOperatorApproval(operator)
  {
    super.approve(operator, tokenId);
  }

  function transferFrom(
    address from,
    address to,
    uint256 tokenId
  ) public payable override(IERC721A, ERC721A) onlyAllowedOperator(from) {
    super.transferFrom(from, to, tokenId);
  }

  function safeTransferFrom(
    address from,
    address to,
    uint256 tokenId
  ) public payable override(IERC721A, ERC721A) onlyAllowedOperator(from) {
    super.safeTransferFrom(from, to, tokenId);
  }

  function safeTransferFrom(
    address from,
    address to,
    uint256 tokenId,
    bytes memory data
  ) public payable override(IERC721A, ERC721A) onlyAllowedOperator(from) {
    super.safeTransferFrom(from, to, tokenId, data);
  }

  function supportsInterface(
    bytes4 interfaceId
  ) public view virtual override(IERC721A, ERC721A, ERC2981) returns (bool) {
    return
      ERC721A.supportsInterface(interfaceId) ||
      ERC2981.supportsInterface(interfaceId);
  }

  function setDefaultRoyalty(
    address receiver,
    uint96 feeNumerator
  ) public onlyOwner {
    _setDefaultRoyalty(receiver, feeNumerator);
  }

  function setOperatorFilteringEnabled(bool value) public onlyOwner {
    operatorFilteringEnabled = value;
  }

  function _operatorFilteringEnabled() internal view override returns (bool) {
    return operatorFilteringEnabled;
  }

  function _isPriorityOperator(
    address operator
  ) internal pure override returns (bool) {
    return operator == address(0x1E0049783F008A0085193E00003D00cd54003c71);
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"InvalidQueryRange","type":"error"},{"inputs":[],"name":"MintERC2309QuantityExceedsLimit","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"OwnershipNotInitializedForExtraData","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toTokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"ConsecutiveTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"MAX_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PRESALE_ALLOWANCE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PRESALE_PRICE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PRESALE_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PRICE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"explicitOwnershipOf","outputs":[{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint64","name":"startTimestamp","type":"uint64"},{"internalType":"bool","name":"burned","type":"bool"},{"internalType":"uint24","name":"extraData","type":"uint24"}],"internalType":"struct IERC721A.TokenOwnership","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"explicitOwnershipsOf","outputs":[{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint64","name":"startTimestamp","type":"uint64"},{"internalType":"bool","name":"burned","type":"bool"},{"internalType":"uint24","name":"extraData","type":"uint24"}],"internalType":"struct IERC721A.TokenOwnership[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lockMetadata","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"metadataLocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"operatorFilteringEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"string","name":"nonce","type":"string"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"presaleMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"provenanceHash","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"string","name":"nonce","type":"string"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"publicMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"reserveTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"saleState","outputs":[{"internalType":"enum KangarooMob.SaleState","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"newBaseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"contractUri","type":"string"}],"name":"setContractURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint96","name":"feeNumerator","type":"uint96"}],"name":"setDefaultRoyalty","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"value","type":"bool"}],"name":"setOperatorFilteringEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"newProvenanceHash","type":"string"}],"name":"setProvenance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"state","type":"uint256"}],"name":"setSaleState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"signerAddress","type":"address"}],"name":"setSignerAddress","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":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"tokensOfOwner","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"stop","type":"uint256"}],"name":"tokensOfOwnerIn","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040523480156200001157600080fd5b506040518060400160405280600b81526020016a25b0b733b0b937b7a6b7b160a91b8152506040518060400160405280600481526020016325a6a7a160e11b815250816002908162000064919062000354565b50600362000073828262000354565b50506001600055506200008633620000bb565b620000906200010d565b600b805460ff19166001179055620000ab336101f462000130565b6011805460ff1916905562000420565b600880546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6200012e733cc6cdda760b79bafa08df41ecfa224f810dceb6600162000235565b565b6127106001600160601b0382161115620001a45760405162461bcd60e51b815260206004820152602a60248201527f455243323938313a20726f79616c7479206665652077696c6c206578636565646044820152692073616c65507269636560b01b60648201526084015b60405180910390fd5b6001600160a01b038216620001fc5760405162461bcd60e51b815260206004820152601960248201527f455243323938313a20696e76616c69642072656365697665720000000000000060448201526064016200019b565b604080518082019091526001600160a01b039092168083526001600160601b039091166020909201829052600160a01b90910217600955565b6001600160a01b0390911690637d3e3dbe816200026557826200025e5750634420e48662000265565b5063a0af29035b8060e01b60005230600452826024526004600060446000806daaeb6d7670e522a718067333cd4e5af1620002a5578060005160e01c03620002a557600080fd5b5060006024525050565b634e487b7160e01b600052604160045260246000fd5b600181811c90821680620002da57607f821691505b602082108103620002fb57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200034f57600081815260208120601f850160051c810160208610156200032a5750805b601f850160051c820191505b818110156200034b5782815560010162000336565b5050505b505050565b81516001600160401b03811115620003705762000370620002af565b6200038881620003818454620002c5565b8462000301565b602080601f831160018114620003c05760008415620003a75750858301515b600019600386901b1c1916600185901b1785556200034b565b600085815260208120601f198616915b82811015620003f157888601518255948401946001909101908401620003d0565b5085821015620004105787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b61306e80620004306000396000f3fe6080604052600436106102f25760003560e01c806373138e4f1161018f578063b7c0b8e8116100e1578063d031370b1161008a578063f2fde38b11610064578063f2fde38b1461081e578063fb796e6c1461083e578063ffe630b51461085857600080fd5b8063d031370b146107a0578063e8a3d485146107c0578063e985e9c5146107d557600080fd5b8063c6ab67a3116100bb578063c6ab67a314610758578063c87b56dd1461076d578063d00e3a531461078d57600080fd5b8063b7c0b8e8146106f8578063b88d4fde14610718578063c23dc68f1461072b57600080fd5b80639041ed7811610143578063989bdbb61161011d578063989bdbb6146106a357806399a2557a146106b8578063a22cb465146106d857600080fd5b80639041ed7814610659578063938e3d7b1461066e57806395d89b411461068e57600080fd5b80638462151c116101745780638462151c146105f35780638d859f3e146106205780638da5cb5b1461063b57600080fd5b806373138e4f146105ca5780637ec45245146105e057600080fd5b80633ccfd60b1161024857806362dc6e21116101fc5780636c0360eb116101d65780636c0360eb1461058057806370a0823114610595578063715018a6146105b557600080fd5b806362dc6e21146105265780636352211e1461054157806369d2ceb11461056157600080fd5b806355f804b31161022d57806355f804b3146104b25780635bbb2177146104d2578063603f4d52146104ff57600080fd5b80633ccfd60b1461048a57806342842e0e1461049f57600080fd5b8063084c4088116102aa57806323b872dd1161028457806323b872dd146104225780632a55205a1461043557806332cb6b0c1461047457600080fd5b8063084c4088146103c8578063095ea7b3146103e857806318160ddd146103fb57600080fd5b8063046dc166116102db578063046dc1661461034e57806306fdde031461036e578063081812fc1461039057600080fd5b806301ffc9a7146102f757806304634d8d1461032c575b600080fd5b34801561030357600080fd5b506103176103123660046127a5565b610878565b60405190151581526020015b60405180910390f35b34801561033857600080fd5b5061034c6103473660046127de565b610898565b005b34801561035a57600080fd5b5061034c610369366004612826565b6108ae565b34801561037a57600080fd5b506103836108e5565b6040516103239190612891565b34801561039c57600080fd5b506103b06103ab3660046128a4565b610977565b6040516001600160a01b039091168152602001610323565b3480156103d457600080fd5b5061034c6103e33660046128a4565b6109d4565b61034c6103f63660046128bd565b610a67565b34801561040757600080fd5b5060015460005403600019015b604051908152602001610323565b61034c6104303660046128e7565b610aaf565b34801561044157600080fd5b50610455610450366004612923565b610b00565b604080516001600160a01b039093168352602083019190915201610323565b34801561048057600080fd5b506104146106f281565b34801561049657600080fd5b5061034c610bbd565b61034c6104ad3660046128e7565b610c76565b3480156104be57600080fd5b5061034c6104cd366004612987565b610cc1565b3480156104de57600080fd5b506104f26104ed3660046129c9565b610d20565b6040516103239190612a3e565b34801561050b57600080fd5b506011546105199060ff1681565b6040516103239190612ad1565b34801561053257600080fd5b506104146658d15e1762800081565b34801561054d57600080fd5b506103b061055c3660046128a4565b610dec565b34801561056d57600080fd5b50600b5461031790610100900460ff1681565b34801561058c57600080fd5b50610383610df7565b3480156105a157600080fd5b506104146105b0366004612826565b610e85565b3480156105c157600080fd5b5061034c610eed565b3480156105d657600080fd5b5061041461030a81565b61034c6105ee366004612af9565b610f01565b3480156105ff57600080fd5b5061061361060e366004612826565b611052565b6040516103239190612b73565b34801561062c57600080fd5b50610414666a94d74f43000081565b34801561064757600080fd5b506008546001600160a01b03166103b0565b34801561066557600080fd5b50610414600481565b34801561067a57600080fd5b5061034c610689366004612987565b611156565b34801561069a57600080fd5b506103836111b5565b3480156106af57600080fd5b5061034c6111c4565b3480156106c457600080fd5b506106136106d3366004612bab565b6111dd565b3480156106e457600080fd5b5061034c6106f3366004612bee565b61137e565b34801561070457600080fd5b5061034c610713366004612c21565b6113c1565b61034c610726366004612c52565b6113dc565b34801561073757600080fd5b5061074b6107463660046128a4565b611428565b6040516103239190612d2e565b34801561076457600080fd5b506103836114b0565b34801561077957600080fd5b506103836107883660046128a4565b6114bd565b61034c61079b366004612af9565b611559565b3480156107ac57600080fd5b5061034c6107bb3660046128a4565b61171b565b3480156107cc57600080fd5b50610383611798565b3480156107e157600080fd5b506103176107f0366004612d73565b6001600160a01b03918216600090815260076020908152604080832093909416825291909152205460ff1690565b34801561082a57600080fd5b5061034c610839366004612826565b6117a7565b34801561084a57600080fd5b50600b546103179060ff1681565b34801561086457600080fd5b5061034c610873366004612987565b611834565b600061088382611893565b80610892575061089282611913565b92915050565b6108a0611961565b6108aa82826119bb565b5050565b6108b6611961565b600f805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b6060600280546108f490612d9d565b80601f016020809104026020016040519081016040528092919081815260200182805461092090612d9d565b801561096d5780601f106109425761010080835404028352916020019161096d565b820191906000526020600020905b81548152906001019060200180831161095057829003601f168201915b5050505050905090565b600061098282611ad5565b6109b8576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506000908152600660205260409020546001600160a01b031690565b6109dc611961565b60038110610a315760405162461bcd60e51b815260206004820152601260248201527f494e56414c49445f53414c455f5354415445000000000000000000000000000060448201526064015b60405180910390fd5b806002811115610a4357610a43612abb565b6011805460ff19166001836002811115610a5f57610a5f612abb565b021790555050565b81731e0049783f008a0085193e00003d00cd54003c716001600160a01b03821614610aa057600b5460ff1615610aa057610aa081611b0a565b610aaa8383611b4e565b505050565b826001600160a01b0381163314610aef57731e0049783f008a0085193e00003d00cd54003c713314610aef57600b5460ff1615610aef57610aef33611b0a565b610afa848484611c14565b50505050565b6000828152600a602090815260408083208151808301909252546001600160a01b038116808352600160a01b9091046bffffffffffffffffffffffff16928201929092528291610b7f5750604080518082019091526009546001600160a01b0381168252600160a01b90046bffffffffffffffffffffffff1660208201525b602081015160009061271090610ba3906bffffffffffffffffffffffff1687612ded565b610bad9190612e04565b91519350909150505b9250929050565b610bc5611961565b6000610bd2606447612e04565b9050739316d2f0edb9304077b549eeb27b6b7924a609f773637c99d3e0ca88c828925daaaddb1b505075b576816108fc610c0d856050612ded565b6040518115909202916000818181858888f19350505050158015610c35573d6000803e3d6000fd5b506001600160a01b0381166108fc610c4e856014612ded565b6040518115909202916000818181858888f19350505050158015610afa573d6000803e3d6000fd5b826001600160a01b0381163314610cb657731e0049783f008a0085193e00003d00cd54003c713314610cb657600b5460ff1615610cb657610cb633611b0a565b610afa848484611df9565b610cc9611961565b600b54610100900460ff1615610d135760405162461bcd60e51b815260206004820152600f60248201526e135155105110551057d313d0d2d151608a1b6044820152606401610a28565b600c610aaa828483612e6c565b60608160008167ffffffffffffffff811115610d3e57610d3e612c3c565b604051908082528060200260200182016040528015610d9057816020015b604080516080810182526000808252602080830182905292820181905260608201528252600019909201910181610d5c5790505b50905060005b828114610de357610dbe868683818110610db257610db2612f2c565b90506020020135611428565b828281518110610dd057610dd0612f2c565b6020908102919091010152600101610d96565b50949350505050565b600061089282611e14565b600c8054610e0490612d9d565b80601f0160208091040260200160405190810160405280929190818152602001828054610e3090612d9d565b8015610e7d5780601f10610e5257610100808354040283529160200191610e7d565b820191906000526020600020905b815481529060010190602001808311610e6057829003601f168201915b505050505081565b60006001600160a01b038216610ec7576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506001600160a01b031660009081526005602052604090205467ffffffffffffffff1690565b610ef5611961565b610eff6000611e9c565b565b600260115460ff166002811115610f1a57610f1a612abb565b14610f675760405162461bcd60e51b815260206004820152600d60248201527f53414c455f494e414354495645000000000000000000000000000000000000006044820152606401610a28565b6106f285610f786000546000190190565b610f829190612f42565b10610fcf5760405162461bcd60e51b815260206004820152601260248201527f455843454544535f4d41585f535550504c5900000000000000000000000000006044820152606401610a28565b61104b85666a94d74f43000086868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8a018190048102820181019092528881529250889150879081908401838280828437600092019190915250611efb92505050565b5050505050565b6060600080600061106285610e85565b905060008167ffffffffffffffff81111561107f5761107f612c3c565b6040519080825280602002602001820160405280156110a8578160200160208202803683370190505b5060408051608081018252600080825260208201819052918101829052606081019190915290915060015b83861461114a576110e3816120ea565b915081604001516111425781516001600160a01b03161561110357815194505b876001600160a01b0316856001600160a01b031603611142578083878060010198508151811061113557611135612f2c565b6020026020010181815250505b6001016110d3565b50909695505050505050565b61115e611961565b600b54610100900460ff16156111a85760405162461bcd60e51b815260206004820152600f60248201526e135155105110551057d313d0d2d151608a1b6044820152606401610a28565b600e610aaa828483612e6c565b6060600380546108f490612d9d565b6111cc611961565b600b805461ff001916610100179055565b6060818310611218576040517f32c1995a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008061122460005490565b9050600185101561123457600194505b80841115611240578093505b600061124b87610e85565b90508486101561126a5785850381811015611264578091505b5061126e565b5060005b60008167ffffffffffffffff81111561128957611289612c3c565b6040519080825280602002602001820160405280156112b2578160200160208202803683370190505b509050816000036112c857935061137792505050565b60006112d388611428565b9050600081604001516112e4575080515b885b8881141580156112f65750848714155b1561136b57611304816120ea565b925082604001516113635782516001600160a01b03161561132457825191505b8a6001600160a01b0316826001600160a01b031603611363578084888060010199508151811061135657611356612f2c565b6020026020010181815250505b6001016112e6565b50505092835250909150505b9392505050565b81731e0049783f008a0085193e00003d00cd54003c716001600160a01b038216146113b757600b5460ff16156113b7576113b781611b0a565b610aaa8383612169565b6113c9611961565b600b805460ff1916911515919091179055565b836001600160a01b038116331461141c57731e0049783f008a0085193e00003d00cd54003c71331461141c57600b5460ff161561141c5761141c33611b0a565b61104b858585856121d5565b604080516080810182526000808252602082018190529181018290526060810191909152604080516080810182526000808252602082018190529181018290526060810191909152600183108061148157506000548310155b1561148c5792915050565b611495836120ea565b90508060400151156114a75792915050565b61137783612219565b600d8054610e0490612d9d565b60606114c882611ad5565b6114fe576040517fa14c4b5000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611508612291565b905080516000036115285760405180602001604052806000815250611377565b80611532846122a0565b604051602001611543929190612f55565b6040516020818303038152906040529392505050565b600160115460ff16600281111561157257611572612abb565b146115bf5760405162461bcd60e51b815260206004820152601060248201527f50524553414c455f494e414354495645000000000000000000000000000000006044820152606401610a28565b61030a856115d06000546000190190565b6115da9190612f42565b106116275760405162461bcd60e51b815260206004820152601660248201527f455843454544535f50524553414c455f535550504c59000000000000000000006044820152606401610a28565b3360009081526005602052604090819020546004916116529188911c67ffffffffffffffff16612f42565b1061169f5760405162461bcd60e51b815260206004820152601960248201527f455843454544535f50524553414c455f414c4c4f57414e4345000000000000006044820152606401610a28565b61104b856658d15e1762800086868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8a018190048102820181019092528881529250889150879081908401838280828437600092019190915250611efb92505050565b611723611961565b6106f2816117346000546000190190565b61173e9190612f42565b1061178b5760405162461bcd60e51b815260206004820152601260248201527f455843454544535f4d41585f535550504c5900000000000000000000000000006044820152606401610a28565b61179533826122e4565b50565b6060600e80546108f490612d9d565b6117af611961565b6001600160a01b03811661182b5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610a28565b61179581611e9c565b61183c611961565b600b54610100900460ff16156118865760405162461bcd60e51b815260206004820152600f60248201526e135155105110551057d313d0d2d151608a1b6044820152606401610a28565b600d610aaa828483612e6c565b60006301ffc9a760e01b6001600160e01b0319831614806118dd57507f80ac58cd000000000000000000000000000000000000000000000000000000006001600160e01b03198316145b806108925750506001600160e01b0319167f5b5e139f000000000000000000000000000000000000000000000000000000001490565b60006001600160e01b031982167f2a55205a00000000000000000000000000000000000000000000000000000000148061089257506301ffc9a760e01b6001600160e01b0319831614610892565b6008546001600160a01b03163314610eff5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610a28565b6127106bffffffffffffffffffffffff82161115611a415760405162461bcd60e51b815260206004820152602a60248201527f455243323938313a20726f79616c7479206665652077696c6c2065786365656460448201527f2073616c655072696365000000000000000000000000000000000000000000006064820152608401610a28565b6001600160a01b038216611a975760405162461bcd60e51b815260206004820152601960248201527f455243323938313a20696e76616c6964207265636569766572000000000000006044820152606401610a28565b604080518082019091526001600160a01b039092168083526bffffffffffffffffffffffff9091166020909201829052600160a01b90910217600955565b600081600111158015611ae9575060005482105b8015610892575050600090815260046020526040902054600160e01b161590565b69c617113400112233445560005230601a5280603a52600080604460166daaeb6d7670e522a718067333cd4e5afa611b46573d6000803e3d6000fd5b6000603a5250565b6000611b5982610dec565b9050336001600160a01b03821614611bab57611b7581336107f0565b611bab576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260066020526040808220805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b6000611c1f82611e14565b9050836001600160a01b0316816001600160a01b031614611c6c576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008281526006602052604090208054338082146001600160a01b03881690911417611cd257611c9c86336107f0565b611cd2576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b038516611d12576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8015611d1d57600082555b6001600160a01b038681166000908152600560205260408082208054600019019055918716808252919020805460010190554260a01b17600160e11b17600085815260046020526040812091909155600160e11b84169003611daf57600184016000818152600460205260408120549003611dad576000548114611dad5760008181526004602052604090208490555b505b83856001600160a01b0316876001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45b505050505050565b610aaa838383604051806020016040528060008152506113dc565b60008180600111611e6a57600054811015611e6a5760008181526004602052604081205490600160e01b82169003611e68575b80600003611377575060001901600081815260046020526040902054611e47565b505b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600880546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b611f058385612ded565b341015611f545760405162461bcd60e51b815260206004820152601060248201527f57524f4e475f4554485f414d4f554e54000000000000000000000000000000006044820152606401610a28565b601082604051611f649190612f84565b9081526040519081900360200190205460ff1615611fc45760405162461bcd60e51b815260206004820152600c60248201527f494e56414c49445f4841534800000000000000000000000000000000000000006044820152606401610a28565b600f546001600160a01b03166120528261204c338887604051602001611fec93929190612fa0565b60408051601f1981840301815282825280516020918201207f19457468657265756d205369676e6564204d6573736167653a0a33320000000084830152603c8085019190915282518085039091018152605c909301909152815191012090565b90612415565b6001600160a01b0316146120a85760405162461bcd60e51b815260206004820152601160248201527f494e56414c49445f5349474e41545552450000000000000000000000000000006044820152606401610a28565b60016010836040516120ba9190612f84565b908152604051908190036020019020805491151560ff19909216919091179055610afa6120e43390565b856122e4565b60408051608081018252600080825260208201819052918101829052606081019190915260008281526004602052604090205461089290604080516080810182526001600160a01b038316815260a083901c67ffffffffffffffff166020820152600160e01b831615159181019190915260e89190911c606082015290565b3360008181526007602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6121e0848484610aaf565b6001600160a01b0383163b15610afa576121fc84848484612439565b610afa576040516368d2bf6b60e11b815260040160405180910390fd5b60408051608081018252600080825260208201819052918101829052606081019190915261089261224983611e14565b604080516080810182526001600160a01b038316815260a083901c67ffffffffffffffff166020820152600160e01b831615159181019190915260e89190911c606082015290565b6060600c80546108f490612d9d565b606060a06040510180604052602081039150506000815280825b600183039250600a81066030018353600a9004806122ba5750819003601f19909101908152919050565b6000805490829003612322576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b03831660008181526005602090815260408083208054680100000000000000018802019055848352600490915281206001851460e11b4260a01b178317905582840190839083907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8180a4600183015b8181146123d157808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600101612399565b508160000361240c576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005550505050565b60008060006124248585612524565b9150915061243181612566565b509392505050565b604051630a85bd0160e11b81526000906001600160a01b0385169063150b7a029061246e903390899088908890600401612fdf565b6020604051808303816000875af19250505080156124a9575060408051601f3d908101601f191682019092526124a69181019061301b565b60015b612507573d8080156124d7576040519150601f19603f3d011682016040523d82523d6000602084013e6124dc565b606091505b5080516000036124ff576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050949350505050565b600080825160410361255a5760208301516040840151606085015160001a61254e878285856126cb565b94509450505050610bb6565b50600090506002610bb6565b600081600481111561257a5761257a612abb565b036125825750565b600181600481111561259657612596612abb565b036125e35760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610a28565b60028160048111156125f7576125f7612abb565b036126445760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610a28565b600381600481111561265857612658612abb565b036117955760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610a28565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156127025750600090506003612786565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612756573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661277f57600060019250925050612786565b9150600090505b94509492505050565b6001600160e01b03198116811461179557600080fd5b6000602082840312156127b757600080fd5b81356113778161278f565b80356001600160a01b03811681146127d957600080fd5b919050565b600080604083850312156127f157600080fd5b6127fa836127c2565b915060208301356bffffffffffffffffffffffff8116811461281b57600080fd5b809150509250929050565b60006020828403121561283857600080fd5b611377826127c2565b60005b8381101561285c578181015183820152602001612844565b50506000910152565b6000815180845261287d816020860160208601612841565b601f01601f19169290920160200192915050565b6020815260006113776020830184612865565b6000602082840312156128b657600080fd5b5035919050565b600080604083850312156128d057600080fd5b6128d9836127c2565b946020939093013593505050565b6000806000606084860312156128fc57600080fd5b612905846127c2565b9250612913602085016127c2565b9150604084013590509250925092565b6000806040838503121561293657600080fd5b50508035926020909101359150565b60008083601f84011261295757600080fd5b50813567ffffffffffffffff81111561296f57600080fd5b602083019150836020828501011115610bb657600080fd5b6000806020838503121561299a57600080fd5b823567ffffffffffffffff8111156129b157600080fd5b6129bd85828601612945565b90969095509350505050565b600080602083850312156129dc57600080fd5b823567ffffffffffffffff808211156129f457600080fd5b818501915085601f830112612a0857600080fd5b813581811115612a1757600080fd5b8660208260051b8501011115612a2c57600080fd5b60209290920196919550909350505050565b6020808252825182820181905260009190848201906040850190845b8181101561114a57612aa88385516001600160a01b03815116825267ffffffffffffffff602082015116602083015260408101511515604083015262ffffff60608201511660608301525050565b9284019260809290920191600101612a5a565b634e487b7160e01b600052602160045260246000fd5b6020810160038310612af357634e487b7160e01b600052602160045260246000fd5b91905290565b600080600080600060608688031215612b1157600080fd5b85359450602086013567ffffffffffffffff80821115612b3057600080fd5b612b3c89838a01612945565b90965094506040880135915080821115612b5557600080fd5b50612b6288828901612945565b969995985093965092949392505050565b6020808252825182820181905260009190848201906040850190845b8181101561114a57835183529284019291840191600101612b8f565b600080600060608486031215612bc057600080fd5b612bc9846127c2565b95602085013595506040909401359392505050565b803580151581146127d957600080fd5b60008060408385031215612c0157600080fd5b612c0a836127c2565b9150612c1860208401612bde565b90509250929050565b600060208284031215612c3357600080fd5b61137782612bde565b634e487b7160e01b600052604160045260246000fd5b60008060008060808587031215612c6857600080fd5b612c71856127c2565b9350612c7f602086016127c2565b925060408501359150606085013567ffffffffffffffff80821115612ca357600080fd5b818701915087601f830112612cb757600080fd5b813581811115612cc957612cc9612c3c565b604051601f8201601f19908116603f01168101908382118183101715612cf157612cf1612c3c565b816040528281528a6020848701011115612d0a57600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b81516001600160a01b0316815260208083015167ffffffffffffffff169082015260408083015115159082015260608083015162ffffff169082015260808101610892565b60008060408385031215612d8657600080fd5b612d8f836127c2565b9150612c18602084016127c2565b600181811c90821680612db157607f821691505b602082108103612dd157634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b808202811582820484141761089257610892612dd7565b600082612e2157634e487b7160e01b600052601260045260246000fd5b500490565b601f821115610aaa57600081815260208120601f850160051c81016020861015612e4d5750805b601f850160051c820191505b81811015611df157828155600101612e59565b67ffffffffffffffff831115612e8457612e84612c3c565b612e9883612e928354612d9d565b83612e26565b6000601f841160018114612ecc5760008515612eb45750838201355b600019600387901b1c1916600186901b17835561104b565b600083815260209020601f19861690835b82811015612efd5786850135825560209485019460019092019101612edd565b5086821015612f1a5760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b634e487b7160e01b600052603260045260246000fd5b8082018082111561089257610892612dd7565b60008351612f67818460208801612841565b835190830190612f7b818360208801612841565b01949350505050565b60008251612f96818460208701612841565b9190910192915050565b6bffffffffffffffffffffffff198460601b16815282601482015260008251612fd0816034850160208701612841565b91909101603401949350505050565b60006001600160a01b038087168352808616602084015250836040830152608060608301526130116080830184612865565b9695505050505050565b60006020828403121561302d57600080fd5b81516113778161278f56fea2646970667358221220d3115df550d9643b73471bc6a721e5fc4b253539e733568dea0076f2a9772b8064736f6c63430008130033

Deployed Bytecode

0x6080604052600436106102f25760003560e01c806373138e4f1161018f578063b7c0b8e8116100e1578063d031370b1161008a578063f2fde38b11610064578063f2fde38b1461081e578063fb796e6c1461083e578063ffe630b51461085857600080fd5b8063d031370b146107a0578063e8a3d485146107c0578063e985e9c5146107d557600080fd5b8063c6ab67a3116100bb578063c6ab67a314610758578063c87b56dd1461076d578063d00e3a531461078d57600080fd5b8063b7c0b8e8146106f8578063b88d4fde14610718578063c23dc68f1461072b57600080fd5b80639041ed7811610143578063989bdbb61161011d578063989bdbb6146106a357806399a2557a146106b8578063a22cb465146106d857600080fd5b80639041ed7814610659578063938e3d7b1461066e57806395d89b411461068e57600080fd5b80638462151c116101745780638462151c146105f35780638d859f3e146106205780638da5cb5b1461063b57600080fd5b806373138e4f146105ca5780637ec45245146105e057600080fd5b80633ccfd60b1161024857806362dc6e21116101fc5780636c0360eb116101d65780636c0360eb1461058057806370a0823114610595578063715018a6146105b557600080fd5b806362dc6e21146105265780636352211e1461054157806369d2ceb11461056157600080fd5b806355f804b31161022d57806355f804b3146104b25780635bbb2177146104d2578063603f4d52146104ff57600080fd5b80633ccfd60b1461048a57806342842e0e1461049f57600080fd5b8063084c4088116102aa57806323b872dd1161028457806323b872dd146104225780632a55205a1461043557806332cb6b0c1461047457600080fd5b8063084c4088146103c8578063095ea7b3146103e857806318160ddd146103fb57600080fd5b8063046dc166116102db578063046dc1661461034e57806306fdde031461036e578063081812fc1461039057600080fd5b806301ffc9a7146102f757806304634d8d1461032c575b600080fd5b34801561030357600080fd5b506103176103123660046127a5565b610878565b60405190151581526020015b60405180910390f35b34801561033857600080fd5b5061034c6103473660046127de565b610898565b005b34801561035a57600080fd5b5061034c610369366004612826565b6108ae565b34801561037a57600080fd5b506103836108e5565b6040516103239190612891565b34801561039c57600080fd5b506103b06103ab3660046128a4565b610977565b6040516001600160a01b039091168152602001610323565b3480156103d457600080fd5b5061034c6103e33660046128a4565b6109d4565b61034c6103f63660046128bd565b610a67565b34801561040757600080fd5b5060015460005403600019015b604051908152602001610323565b61034c6104303660046128e7565b610aaf565b34801561044157600080fd5b50610455610450366004612923565b610b00565b604080516001600160a01b039093168352602083019190915201610323565b34801561048057600080fd5b506104146106f281565b34801561049657600080fd5b5061034c610bbd565b61034c6104ad3660046128e7565b610c76565b3480156104be57600080fd5b5061034c6104cd366004612987565b610cc1565b3480156104de57600080fd5b506104f26104ed3660046129c9565b610d20565b6040516103239190612a3e565b34801561050b57600080fd5b506011546105199060ff1681565b6040516103239190612ad1565b34801561053257600080fd5b506104146658d15e1762800081565b34801561054d57600080fd5b506103b061055c3660046128a4565b610dec565b34801561056d57600080fd5b50600b5461031790610100900460ff1681565b34801561058c57600080fd5b50610383610df7565b3480156105a157600080fd5b506104146105b0366004612826565b610e85565b3480156105c157600080fd5b5061034c610eed565b3480156105d657600080fd5b5061041461030a81565b61034c6105ee366004612af9565b610f01565b3480156105ff57600080fd5b5061061361060e366004612826565b611052565b6040516103239190612b73565b34801561062c57600080fd5b50610414666a94d74f43000081565b34801561064757600080fd5b506008546001600160a01b03166103b0565b34801561066557600080fd5b50610414600481565b34801561067a57600080fd5b5061034c610689366004612987565b611156565b34801561069a57600080fd5b506103836111b5565b3480156106af57600080fd5b5061034c6111c4565b3480156106c457600080fd5b506106136106d3366004612bab565b6111dd565b3480156106e457600080fd5b5061034c6106f3366004612bee565b61137e565b34801561070457600080fd5b5061034c610713366004612c21565b6113c1565b61034c610726366004612c52565b6113dc565b34801561073757600080fd5b5061074b6107463660046128a4565b611428565b6040516103239190612d2e565b34801561076457600080fd5b506103836114b0565b34801561077957600080fd5b506103836107883660046128a4565b6114bd565b61034c61079b366004612af9565b611559565b3480156107ac57600080fd5b5061034c6107bb3660046128a4565b61171b565b3480156107cc57600080fd5b50610383611798565b3480156107e157600080fd5b506103176107f0366004612d73565b6001600160a01b03918216600090815260076020908152604080832093909416825291909152205460ff1690565b34801561082a57600080fd5b5061034c610839366004612826565b6117a7565b34801561084a57600080fd5b50600b546103179060ff1681565b34801561086457600080fd5b5061034c610873366004612987565b611834565b600061088382611893565b80610892575061089282611913565b92915050565b6108a0611961565b6108aa82826119bb565b5050565b6108b6611961565b600f805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b6060600280546108f490612d9d565b80601f016020809104026020016040519081016040528092919081815260200182805461092090612d9d565b801561096d5780601f106109425761010080835404028352916020019161096d565b820191906000526020600020905b81548152906001019060200180831161095057829003601f168201915b5050505050905090565b600061098282611ad5565b6109b8576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506000908152600660205260409020546001600160a01b031690565b6109dc611961565b60038110610a315760405162461bcd60e51b815260206004820152601260248201527f494e56414c49445f53414c455f5354415445000000000000000000000000000060448201526064015b60405180910390fd5b806002811115610a4357610a43612abb565b6011805460ff19166001836002811115610a5f57610a5f612abb565b021790555050565b81731e0049783f008a0085193e00003d00cd54003c716001600160a01b03821614610aa057600b5460ff1615610aa057610aa081611b0a565b610aaa8383611b4e565b505050565b826001600160a01b0381163314610aef57731e0049783f008a0085193e00003d00cd54003c713314610aef57600b5460ff1615610aef57610aef33611b0a565b610afa848484611c14565b50505050565b6000828152600a602090815260408083208151808301909252546001600160a01b038116808352600160a01b9091046bffffffffffffffffffffffff16928201929092528291610b7f5750604080518082019091526009546001600160a01b0381168252600160a01b90046bffffffffffffffffffffffff1660208201525b602081015160009061271090610ba3906bffffffffffffffffffffffff1687612ded565b610bad9190612e04565b91519350909150505b9250929050565b610bc5611961565b6000610bd2606447612e04565b9050739316d2f0edb9304077b549eeb27b6b7924a609f773637c99d3e0ca88c828925daaaddb1b505075b576816108fc610c0d856050612ded565b6040518115909202916000818181858888f19350505050158015610c35573d6000803e3d6000fd5b506001600160a01b0381166108fc610c4e856014612ded565b6040518115909202916000818181858888f19350505050158015610afa573d6000803e3d6000fd5b826001600160a01b0381163314610cb657731e0049783f008a0085193e00003d00cd54003c713314610cb657600b5460ff1615610cb657610cb633611b0a565b610afa848484611df9565b610cc9611961565b600b54610100900460ff1615610d135760405162461bcd60e51b815260206004820152600f60248201526e135155105110551057d313d0d2d151608a1b6044820152606401610a28565b600c610aaa828483612e6c565b60608160008167ffffffffffffffff811115610d3e57610d3e612c3c565b604051908082528060200260200182016040528015610d9057816020015b604080516080810182526000808252602080830182905292820181905260608201528252600019909201910181610d5c5790505b50905060005b828114610de357610dbe868683818110610db257610db2612f2c565b90506020020135611428565b828281518110610dd057610dd0612f2c565b6020908102919091010152600101610d96565b50949350505050565b600061089282611e14565b600c8054610e0490612d9d565b80601f0160208091040260200160405190810160405280929190818152602001828054610e3090612d9d565b8015610e7d5780601f10610e5257610100808354040283529160200191610e7d565b820191906000526020600020905b815481529060010190602001808311610e6057829003601f168201915b505050505081565b60006001600160a01b038216610ec7576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506001600160a01b031660009081526005602052604090205467ffffffffffffffff1690565b610ef5611961565b610eff6000611e9c565b565b600260115460ff166002811115610f1a57610f1a612abb565b14610f675760405162461bcd60e51b815260206004820152600d60248201527f53414c455f494e414354495645000000000000000000000000000000000000006044820152606401610a28565b6106f285610f786000546000190190565b610f829190612f42565b10610fcf5760405162461bcd60e51b815260206004820152601260248201527f455843454544535f4d41585f535550504c5900000000000000000000000000006044820152606401610a28565b61104b85666a94d74f43000086868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8a018190048102820181019092528881529250889150879081908401838280828437600092019190915250611efb92505050565b5050505050565b6060600080600061106285610e85565b905060008167ffffffffffffffff81111561107f5761107f612c3c565b6040519080825280602002602001820160405280156110a8578160200160208202803683370190505b5060408051608081018252600080825260208201819052918101829052606081019190915290915060015b83861461114a576110e3816120ea565b915081604001516111425781516001600160a01b03161561110357815194505b876001600160a01b0316856001600160a01b031603611142578083878060010198508151811061113557611135612f2c565b6020026020010181815250505b6001016110d3565b50909695505050505050565b61115e611961565b600b54610100900460ff16156111a85760405162461bcd60e51b815260206004820152600f60248201526e135155105110551057d313d0d2d151608a1b6044820152606401610a28565b600e610aaa828483612e6c565b6060600380546108f490612d9d565b6111cc611961565b600b805461ff001916610100179055565b6060818310611218576040517f32c1995a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008061122460005490565b9050600185101561123457600194505b80841115611240578093505b600061124b87610e85565b90508486101561126a5785850381811015611264578091505b5061126e565b5060005b60008167ffffffffffffffff81111561128957611289612c3c565b6040519080825280602002602001820160405280156112b2578160200160208202803683370190505b509050816000036112c857935061137792505050565b60006112d388611428565b9050600081604001516112e4575080515b885b8881141580156112f65750848714155b1561136b57611304816120ea565b925082604001516113635782516001600160a01b03161561132457825191505b8a6001600160a01b0316826001600160a01b031603611363578084888060010199508151811061135657611356612f2c565b6020026020010181815250505b6001016112e6565b50505092835250909150505b9392505050565b81731e0049783f008a0085193e00003d00cd54003c716001600160a01b038216146113b757600b5460ff16156113b7576113b781611b0a565b610aaa8383612169565b6113c9611961565b600b805460ff1916911515919091179055565b836001600160a01b038116331461141c57731e0049783f008a0085193e00003d00cd54003c71331461141c57600b5460ff161561141c5761141c33611b0a565b61104b858585856121d5565b604080516080810182526000808252602082018190529181018290526060810191909152604080516080810182526000808252602082018190529181018290526060810191909152600183108061148157506000548310155b1561148c5792915050565b611495836120ea565b90508060400151156114a75792915050565b61137783612219565b600d8054610e0490612d9d565b60606114c882611ad5565b6114fe576040517fa14c4b5000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611508612291565b905080516000036115285760405180602001604052806000815250611377565b80611532846122a0565b604051602001611543929190612f55565b6040516020818303038152906040529392505050565b600160115460ff16600281111561157257611572612abb565b146115bf5760405162461bcd60e51b815260206004820152601060248201527f50524553414c455f494e414354495645000000000000000000000000000000006044820152606401610a28565b61030a856115d06000546000190190565b6115da9190612f42565b106116275760405162461bcd60e51b815260206004820152601660248201527f455843454544535f50524553414c455f535550504c59000000000000000000006044820152606401610a28565b3360009081526005602052604090819020546004916116529188911c67ffffffffffffffff16612f42565b1061169f5760405162461bcd60e51b815260206004820152601960248201527f455843454544535f50524553414c455f414c4c4f57414e4345000000000000006044820152606401610a28565b61104b856658d15e1762800086868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8a018190048102820181019092528881529250889150879081908401838280828437600092019190915250611efb92505050565b611723611961565b6106f2816117346000546000190190565b61173e9190612f42565b1061178b5760405162461bcd60e51b815260206004820152601260248201527f455843454544535f4d41585f535550504c5900000000000000000000000000006044820152606401610a28565b61179533826122e4565b50565b6060600e80546108f490612d9d565b6117af611961565b6001600160a01b03811661182b5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610a28565b61179581611e9c565b61183c611961565b600b54610100900460ff16156118865760405162461bcd60e51b815260206004820152600f60248201526e135155105110551057d313d0d2d151608a1b6044820152606401610a28565b600d610aaa828483612e6c565b60006301ffc9a760e01b6001600160e01b0319831614806118dd57507f80ac58cd000000000000000000000000000000000000000000000000000000006001600160e01b03198316145b806108925750506001600160e01b0319167f5b5e139f000000000000000000000000000000000000000000000000000000001490565b60006001600160e01b031982167f2a55205a00000000000000000000000000000000000000000000000000000000148061089257506301ffc9a760e01b6001600160e01b0319831614610892565b6008546001600160a01b03163314610eff5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610a28565b6127106bffffffffffffffffffffffff82161115611a415760405162461bcd60e51b815260206004820152602a60248201527f455243323938313a20726f79616c7479206665652077696c6c2065786365656460448201527f2073616c655072696365000000000000000000000000000000000000000000006064820152608401610a28565b6001600160a01b038216611a975760405162461bcd60e51b815260206004820152601960248201527f455243323938313a20696e76616c6964207265636569766572000000000000006044820152606401610a28565b604080518082019091526001600160a01b039092168083526bffffffffffffffffffffffff9091166020909201829052600160a01b90910217600955565b600081600111158015611ae9575060005482105b8015610892575050600090815260046020526040902054600160e01b161590565b69c617113400112233445560005230601a5280603a52600080604460166daaeb6d7670e522a718067333cd4e5afa611b46573d6000803e3d6000fd5b6000603a5250565b6000611b5982610dec565b9050336001600160a01b03821614611bab57611b7581336107f0565b611bab576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260066020526040808220805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b6000611c1f82611e14565b9050836001600160a01b0316816001600160a01b031614611c6c576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008281526006602052604090208054338082146001600160a01b03881690911417611cd257611c9c86336107f0565b611cd2576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b038516611d12576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8015611d1d57600082555b6001600160a01b038681166000908152600560205260408082208054600019019055918716808252919020805460010190554260a01b17600160e11b17600085815260046020526040812091909155600160e11b84169003611daf57600184016000818152600460205260408120549003611dad576000548114611dad5760008181526004602052604090208490555b505b83856001600160a01b0316876001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45b505050505050565b610aaa838383604051806020016040528060008152506113dc565b60008180600111611e6a57600054811015611e6a5760008181526004602052604081205490600160e01b82169003611e68575b80600003611377575060001901600081815260046020526040902054611e47565b505b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600880546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b611f058385612ded565b341015611f545760405162461bcd60e51b815260206004820152601060248201527f57524f4e475f4554485f414d4f554e54000000000000000000000000000000006044820152606401610a28565b601082604051611f649190612f84565b9081526040519081900360200190205460ff1615611fc45760405162461bcd60e51b815260206004820152600c60248201527f494e56414c49445f4841534800000000000000000000000000000000000000006044820152606401610a28565b600f546001600160a01b03166120528261204c338887604051602001611fec93929190612fa0565b60408051601f1981840301815282825280516020918201207f19457468657265756d205369676e6564204d6573736167653a0a33320000000084830152603c8085019190915282518085039091018152605c909301909152815191012090565b90612415565b6001600160a01b0316146120a85760405162461bcd60e51b815260206004820152601160248201527f494e56414c49445f5349474e41545552450000000000000000000000000000006044820152606401610a28565b60016010836040516120ba9190612f84565b908152604051908190036020019020805491151560ff19909216919091179055610afa6120e43390565b856122e4565b60408051608081018252600080825260208201819052918101829052606081019190915260008281526004602052604090205461089290604080516080810182526001600160a01b038316815260a083901c67ffffffffffffffff166020820152600160e01b831615159181019190915260e89190911c606082015290565b3360008181526007602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6121e0848484610aaf565b6001600160a01b0383163b15610afa576121fc84848484612439565b610afa576040516368d2bf6b60e11b815260040160405180910390fd5b60408051608081018252600080825260208201819052918101829052606081019190915261089261224983611e14565b604080516080810182526001600160a01b038316815260a083901c67ffffffffffffffff166020820152600160e01b831615159181019190915260e89190911c606082015290565b6060600c80546108f490612d9d565b606060a06040510180604052602081039150506000815280825b600183039250600a81066030018353600a9004806122ba5750819003601f19909101908152919050565b6000805490829003612322576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b03831660008181526005602090815260408083208054680100000000000000018802019055848352600490915281206001851460e11b4260a01b178317905582840190839083907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8180a4600183015b8181146123d157808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600101612399565b508160000361240c576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005550505050565b60008060006124248585612524565b9150915061243181612566565b509392505050565b604051630a85bd0160e11b81526000906001600160a01b0385169063150b7a029061246e903390899088908890600401612fdf565b6020604051808303816000875af19250505080156124a9575060408051601f3d908101601f191682019092526124a69181019061301b565b60015b612507573d8080156124d7576040519150601f19603f3d011682016040523d82523d6000602084013e6124dc565b606091505b5080516000036124ff576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050949350505050565b600080825160410361255a5760208301516040840151606085015160001a61254e878285856126cb565b94509450505050610bb6565b50600090506002610bb6565b600081600481111561257a5761257a612abb565b036125825750565b600181600481111561259657612596612abb565b036125e35760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610a28565b60028160048111156125f7576125f7612abb565b036126445760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610a28565b600381600481111561265857612658612abb565b036117955760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610a28565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156127025750600090506003612786565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612756573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661277f57600060019250925050612786565b9150600090505b94509492505050565b6001600160e01b03198116811461179557600080fd5b6000602082840312156127b757600080fd5b81356113778161278f565b80356001600160a01b03811681146127d957600080fd5b919050565b600080604083850312156127f157600080fd5b6127fa836127c2565b915060208301356bffffffffffffffffffffffff8116811461281b57600080fd5b809150509250929050565b60006020828403121561283857600080fd5b611377826127c2565b60005b8381101561285c578181015183820152602001612844565b50506000910152565b6000815180845261287d816020860160208601612841565b601f01601f19169290920160200192915050565b6020815260006113776020830184612865565b6000602082840312156128b657600080fd5b5035919050565b600080604083850312156128d057600080fd5b6128d9836127c2565b946020939093013593505050565b6000806000606084860312156128fc57600080fd5b612905846127c2565b9250612913602085016127c2565b9150604084013590509250925092565b6000806040838503121561293657600080fd5b50508035926020909101359150565b60008083601f84011261295757600080fd5b50813567ffffffffffffffff81111561296f57600080fd5b602083019150836020828501011115610bb657600080fd5b6000806020838503121561299a57600080fd5b823567ffffffffffffffff8111156129b157600080fd5b6129bd85828601612945565b90969095509350505050565b600080602083850312156129dc57600080fd5b823567ffffffffffffffff808211156129f457600080fd5b818501915085601f830112612a0857600080fd5b813581811115612a1757600080fd5b8660208260051b8501011115612a2c57600080fd5b60209290920196919550909350505050565b6020808252825182820181905260009190848201906040850190845b8181101561114a57612aa88385516001600160a01b03815116825267ffffffffffffffff602082015116602083015260408101511515604083015262ffffff60608201511660608301525050565b9284019260809290920191600101612a5a565b634e487b7160e01b600052602160045260246000fd5b6020810160038310612af357634e487b7160e01b600052602160045260246000fd5b91905290565b600080600080600060608688031215612b1157600080fd5b85359450602086013567ffffffffffffffff80821115612b3057600080fd5b612b3c89838a01612945565b90965094506040880135915080821115612b5557600080fd5b50612b6288828901612945565b969995985093965092949392505050565b6020808252825182820181905260009190848201906040850190845b8181101561114a57835183529284019291840191600101612b8f565b600080600060608486031215612bc057600080fd5b612bc9846127c2565b95602085013595506040909401359392505050565b803580151581146127d957600080fd5b60008060408385031215612c0157600080fd5b612c0a836127c2565b9150612c1860208401612bde565b90509250929050565b600060208284031215612c3357600080fd5b61137782612bde565b634e487b7160e01b600052604160045260246000fd5b60008060008060808587031215612c6857600080fd5b612c71856127c2565b9350612c7f602086016127c2565b925060408501359150606085013567ffffffffffffffff80821115612ca357600080fd5b818701915087601f830112612cb757600080fd5b813581811115612cc957612cc9612c3c565b604051601f8201601f19908116603f01168101908382118183101715612cf157612cf1612c3c565b816040528281528a6020848701011115612d0a57600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b81516001600160a01b0316815260208083015167ffffffffffffffff169082015260408083015115159082015260608083015162ffffff169082015260808101610892565b60008060408385031215612d8657600080fd5b612d8f836127c2565b9150612c18602084016127c2565b600181811c90821680612db157607f821691505b602082108103612dd157634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b808202811582820484141761089257610892612dd7565b600082612e2157634e487b7160e01b600052601260045260246000fd5b500490565b601f821115610aaa57600081815260208120601f850160051c81016020861015612e4d5750805b601f850160051c820191505b81811015611df157828155600101612e59565b67ffffffffffffffff831115612e8457612e84612c3c565b612e9883612e928354612d9d565b83612e26565b6000601f841160018114612ecc5760008515612eb45750838201355b600019600387901b1c1916600186901b17835561104b565b600083815260209020601f19861690835b82811015612efd5786850135825560209485019460019092019101612edd565b5086821015612f1a5760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b634e487b7160e01b600052603260045260246000fd5b8082018082111561089257610892612dd7565b60008351612f67818460208801612841565b835190830190612f7b818360208801612841565b01949350505050565b60008251612f96818460208701612841565b9190910192915050565b6bffffffffffffffffffffffff198460601b16815282601482015260008251612fd0816034850160208701612841565b91909101603401949350505050565b60006001600160a01b038087168352808616602084015250836040830152608060608301526130116080830184612865565b9695505050505050565b60006020828403121561302d57600080fd5b81516113778161278f56fea2646970667358221220d3115df550d9643b73471bc6a721e5fc4b253539e733568dea0076f2a9772b8064736f6c63430008130033

Deployed Bytecode Sourcemap

93621:5836:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;98626:243;;;;;;;;;;-1:-1:-1;98626:243:0;;;;;:::i;:::-;;:::i;:::-;;;611:14:1;;604:22;586:41;;574:2;559:18;98626:243:0;;;;;;;;98875:153;;;;;;;;;;-1:-1:-1;98875:153:0;;;;;:::i;:::-;;:::i;:::-;;95241:111;;;;;;;;;;-1:-1:-1;95241:111:0;;;;;:::i;:::-;;:::i;55885:94::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;61911:218::-;;;;;;;;;;-1:-1:-1;61911:218:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;2506:55:1;;;2488:74;;2476:2;2461:18;61911:218:0;2342:226:1;95094:141:0;;;;;;;;;;-1:-1:-1;95094:141:0;;;;;:::i;:::-;;:::i;97728:216::-;;;;;;:::i;:::-;;:::i;51848:299::-;;;;;;;;;;-1:-1:-1;97505:1:0;52104:12;51909:7;52088:13;:28;-1:-1:-1;;52088:46:0;51848:299;;;2978:25:1;;;2966:2;2951:18;51848:299:0;2832:177:1;97950:204:0;;;;;;:::i;:::-;;:::i;7817:436::-;;;;;;;;;;-1:-1:-1;7817:436:0;;;;;:::i;:::-;;:::i;:::-;;;;-1:-1:-1;;;;;3792:55:1;;;3774:74;;3879:2;3864:18;;3857:34;;;;3747:18;7817:436:0;3600:297:1;93731:41:0;;;;;;;;;;;;93768:4;93731:41;;97050:369;;;;;;;;;;;;;:::i;98160:212::-;;;;;;:::i;:::-;;:::i;95358:110::-;;;;;;;;;;-1:-1:-1;95358:110:0;;;;;:::i;:::-;;:::i;89419:440::-;;;;;;;;;;-1:-1:-1;89419:440:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;94293:26::-;;;;;;;;;;-1:-1:-1;94293:26:0;;;;;;;;;;;;;;;:::i;93876:51::-;;;;;;;;;;;;93916:11;93876:51;;57231:156;;;;;;;;;;-1:-1:-1;57231:156:0;;;;;:::i;:::-;;:::i;94020:26::-;;;;;;;;;;-1:-1:-1;94020:26:0;;;;;;;;;;;94051:21;;;;;;;;;;;;;:::i;52948:233::-;;;;;;;;;;-1:-1:-1;52948:233:0;;;;;:::i;:::-;;:::i;2708:97::-;;;;;;;;;;;;;:::i;93777:44::-;;;;;;;;;;;;93818:3;93777:44;;96035:316;;;;;;:::i;:::-;;:::i;92811:766::-;;;;;;;;;;-1:-1:-1;92811:766:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;93932:42::-;;;;;;;;;;;;93964:10;93932:42;;2096:81;;;;;;;;;;-1:-1:-1;2165:6:0;;-1:-1:-1;;;;;2165:6:0;2096:81;;93826:45;;;;;;;;;;;;93870:1;93826:45;;94627:131;;;;;;;;;;-1:-1:-1;94627:131:0;;;;;:::i;:::-;;:::i;56047:98::-;;;;;;;;;;;;;:::i;95011:77::-;;;;;;;;;;;;;:::i;90221:2165::-;;;;;;;;;;-1:-1:-1;90221:2165:0;;;;;:::i;:::-;;:::i;97518:204::-;;;;;;;;;;-1:-1:-1;97518:204:0;;;;;:::i;:::-;;:::i;99034:111::-;;;;;;;;;;-1:-1:-1;99034:111:0;;;;;:::i;:::-;;:::i;98378:242::-;;;;;;:::i;:::-;;:::i;88874:396::-;;;;;;;;;;-1:-1:-1;88874:396:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;94077:28::-;;;;;;;;;;;;;:::i;56243:339::-;;;;;;;;;;-1:-1:-1;56243:339:0;;;;;:::i;:::-;;:::i;95574:455::-;;;;;;:::i;:::-;;:::i;96872:172::-;;;;;;;;;;-1:-1:-1;96872:172:0;;;;;:::i;:::-;;:::i;94764:91::-;;;;;;;;;;;;;:::i;62829:173::-;;;;;;;;;;-1:-1:-1;62829:173:0;;;;;:::i;:::-;-1:-1:-1;;;;;62961:25:0;;;62941:4;62961:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;62829:173;2950:191;;;;;;;;;;-1:-1:-1;2950:191:0;;;;;:::i;:::-;;:::i;93979:36::-;;;;;;;;;;-1:-1:-1;93979:36:0;;;;;;;;94861:144;;;;;;;;;;-1:-1:-1;94861:144:0;;;;;:::i;:::-;;:::i;98626:243::-;98749:4;98776:38;98802:11;98776:25;:38::i;:::-;:87;;;;98825:38;98851:11;98825:25;:38::i;:::-;98762:101;98626:243;-1:-1:-1;;98626:243:0:o;98875:153::-;1996:13;:11;:13::i;:::-;98980:42:::1;98999:8;99009:12;98980:18;:42::i;:::-;98875:153:::0;;:::o;95241:111::-;1996:13;:11;:13::i;:::-;95316:14:::1;:30:::0;;-1:-1:-1;;95316:30:0::1;-1:-1:-1::0;;;;;95316:30:0;;;::::1;::::0;;;::::1;::::0;;95241:111::o;55885:94::-;55939:13;55968:5;55961:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;55885:94;:::o;61911:218::-;61997:7;62018:16;62026:7;62018;:16::i;:::-;62013:64;;62043:34;;;;;;;;;;;;;;62013:64;-1:-1:-1;62093:24:0;;;;:15;:24;;;;;:30;-1:-1:-1;;;;;62093:30:0;;61911:218::o;95094:141::-;1996:13;:11;:13::i;:::-;95170:1:::1;95162:5;:9;95154:40;;;::::0;-1:-1:-1;;;95154:40:0;;11870:2:1;95154:40:0::1;::::0;::::1;11852:21:1::0;11909:2;11889:18;;;11882:30;11948:20;11928:18;;;11921:48;11986:18;;95154:40:0::1;;;;;;;;;95223:5;95213:16;;;;;;;;:::i;:::-;95201:9;:28:::0;;-1:-1:-1;;95201:28:0::1;::::0;;::::1;::::0;::::1;;;;;;:::i;:::-;;;;;;95094:141:::0;:::o;97728:216::-;97886:8;99405:42;-1:-1:-1;;;;;99385:63:0;;;35478:112;;99240:24;;;;35523:59;;;35556:26;35573:8;35556:16;:26::i;:::-;97906:32:::1;97920:8;97930:7;97906:13;:32::i;:::-;97728:216:::0;;;:::o;97950:204::-;98098:4;-1:-1:-1;;;;;35156:18:0;;35164:10;35156:18;35152:160;;99405:42;35210:10;99385:63;35185:120;;99240:24;;;;35234:61;;;35267:28;35284:10;35267:16;:28::i;:::-;98111:37:::1;98130:4;98136:2;98140:7;98111:18;:37::i;:::-;97950:204:::0;;;;:::o;7817:436::-;7929:7;7983:27;;;:17;:27;;;;;;;;7954:56;;;;;;;;;-1:-1:-1;;;;;7954:56:0;;;;;-1:-1:-1;;;7954:56:0;;;;;;;;;;;;7929:7;;8019:82;;-1:-1:-1;8064:29:0;;;;;;;;;8074:19;8064:29;-1:-1:-1;;;;;8064:29:0;;;;-1:-1:-1;;;8064:29:0;;;;;;;;8019:82;8147:23;;;;8109:21;;8603:5;;8134:36;;8133:65;8134:36;:10;:36;:::i;:::-;8133:65;;;;:::i;:::-;8215:16;;;-1:-1:-1;8109:89:0;;-1:-1:-1;;7817:436:0;;;;;;:::o;97050:369::-;1996:13;:11;:13::i;:::-;97096:15:::1;97114:27;97138:3;97114:21;:27;:::i;:::-;97096:45:::0;-1:-1:-1;97189:42:0::1;97286;97189::::0;97342:32:::1;97358:15;97096:45:::0;97371:2:::1;97358:15;:::i;:::-;97342:32;::::0;;::::1;::::0;;::::1;::::0;::::1;::::0;;;;;;::::1;;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;;;;;97381:15:0;::::1;:32;97397:15;:10:::0;97410:2:::1;97397:15;:::i;:::-;97381:32;::::0;;::::1;::::0;;::::1;::::0;::::1;::::0;;;;;;::::1;;;;;;;;;;;;;::::0;::::1;;;;98160:212:::0;98312:4;-1:-1:-1;;;;;35156:18:0;;35164:10;35156:18;35152:160;;99405:42;35210:10;99385:63;35185:120;;99240:24;;;;35234:61;;;35267:28;35284:10;35267:16;:28::i;:::-;98325:41:::1;98348:4;98354:2;98358:7;98325:22;:41::i;95358:110::-:0;1996:13;:11;:13::i;:::-;94573:14:::1;::::0;::::1;::::0;::::1;;;94572:15;94564:43;;;::::0;-1:-1:-1;;;94564:43:0;;12858:2:1;94564:43:0::1;::::0;::::1;12840:21:1::0;12897:2;12877:18;;;12870:30;-1:-1:-1;;;12916:18:1;;;12909:45;12971:18;;94564:43:0::1;12656:339:1::0;94564:43:0::1;95442:7:::2;:20;95452:10:::0;;95442:7;:20:::2;:::i;89419:440::-:0;89528:23;89604:8;89579:22;89604:8;89665:36;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;89665:36:0;;-1:-1:-1;;89665:36:0;;;;;;;;;;;;89628:73;;89715:9;89710:111;89731:14;89726:1;:19;89710:111;;89779:32;89799:8;;89808:1;89799:11;;;;;;;:::i;:::-;;;;;;;89779:19;:32::i;:::-;89763:10;89774:1;89763:13;;;;;;;;:::i;:::-;;;;;;;;;;:48;89747:3;;89710:111;;;-1:-1:-1;89836:10:0;89419:440;-1:-1:-1;;;;89419:440:0:o;57231:156::-;57313:7;57352:27;57371:7;57352:18;:27::i;94051:21::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;52948:233::-;53030:7;-1:-1:-1;;;;;53050:19:0;;53046:60;;53078:28;;;;;;;;;;;;;;53046:60;-1:-1:-1;;;;;;53120:25:0;;;;;:18;:25;;;;;;47393:13;53120:55;;52948:233::o;2708:97::-;1996:13;:11;:13::i;:::-;2769:30:::1;2796:1;2769:18;:30::i;:::-;2708:97::o:0;96035:316::-;96185:20;96172:9;;;;:33;;;;;;;;:::i;:::-;;96164:59;;;;-1:-1:-1;;;96164:59:0;;15449:2:1;96164:59:0;;;15431:21:1;15488:2;15468:18;;;15461:30;15527:15;15507:18;;;15500:43;15560:18;;96164:59:0;15247:337:1;96164:59:0;93768:4;96255:6;96238:14;52292:7;52465:13;-1:-1:-1;;52465:31:0;;52237:272;96238:14;:23;;;;:::i;:::-;:36;96230:67;;;;-1:-1:-1;;;96230:67:0;;15921:2:1;96230:67:0;;;15903:21:1;15960:2;15940:18;;;15933:30;15999:20;15979:18;;;15972:48;16037:18;;96230:67:0;15719:342:1;96230:67:0;96304:41;96313:6;93964:10;96328:5;;96304:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;96304:41:0;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;96335:9:0;;-1:-1:-1;96335:9:0;;;;96304:41;;96335:9;;;;96304:41;;;;;;;;;-1:-1:-1;96304:8:0;;-1:-1:-1;;;96304:41:0:i;:::-;96035:316;;;;;:::o;92811:766::-;92899:16;92943:19;92971:25;93005:22;93030:16;93040:5;93030:9;:16::i;:::-;93005:41;;93055:25;93097:14;93083:29;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;93083:29:0;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;93055:57:0;;-1:-1:-1;97505:1:0;93161:380;93210:14;93195:11;:29;93161:380;;93254:15;93267:1;93254:12;:15::i;:::-;93242:27;;93284:9;:16;;;93315:8;93280:55;93349:14;;-1:-1:-1;;;;;93349:28:0;;93345:93;;93412:14;;;-1:-1:-1;93345:93:0;93473:5;-1:-1:-1;;;;;93452:26:0;:17;-1:-1:-1;;;;;93452:26:0;;93448:84;;93519:1;93493:8;93502:13;;;;;;93493:23;;;;;;;;:::i;:::-;;;;;;:27;;;;;93448:84;93226:3;;93161:380;;;-1:-1:-1;93556:8:0;;92811:766;-1:-1:-1;;;;;;92811:766:0:o;94627:131::-;1996:13;:11;:13::i;:::-;94573:14:::1;::::0;::::1;::::0;::::1;;;94572:15;94564:43;;;::::0;-1:-1:-1;;;94564:43:0;;12858:2:1;94564:43:0::1;::::0;::::1;12840:21:1::0;12897:2;12877:18;;;12870:30;-1:-1:-1;;;12916:18:1;;;12909:45;12971:18;;94564:43:0::1;12656:339:1::0;94564:43:0::1;94726:12:::2;:26;94741:11:::0;;94726:12;:26:::2;:::i;56047:98::-:0;56103:13;56132:7;56125:14;;;;;:::i;95011:77::-;1996:13;:11;:13::i;:::-;95061:14:::1;:21:::0;;-1:-1:-1;;95061:21:0::1;;;::::0;;95011:77::o;90221:2165::-;90350:16;90407:4;90398:5;:13;90394:45;;90420:19;;;;;;;;;;;;;;90394:45;90448:19;90476:17;90496:14;51608:7;51631:13;;51553:97;90496:14;90476:34;-1:-1:-1;97505:1:0;90576:5;:23;90572:73;;;97505:1;90612:23;;90572:73;90709:9;90702:4;:16;90698:59;;;90738:9;90731:16;;90698:59;90765:25;90793:16;90803:5;90793:9;:16::i;:::-;90765:44;;90969:4;90961:5;:12;90957:224;;;91008:12;;;91035:31;;;91031:93;;;91101:11;91081:31;;91031:93;90975:158;90957:224;;;-1:-1:-1;91170:1:0;90957:224;91189:25;91231:17;91217:32;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;91217:32:0;;91189:60;;91262:17;91283:1;91262:22;91258:64;;91304:8;-1:-1:-1;91297:15:0;;-1:-1:-1;;;91297:15:0;91258:64;91448:31;91482:26;91502:5;91482:19;:26::i;:::-;91448:60;;91517:25;91744:9;:16;;;91739:78;;-1:-1:-1;91793:14:0;;91739:78;91852:5;91825:422;91873:4;91868:1;:9;;:45;;;;;91896:17;91881:11;:32;;91868:45;91825:422;;;91960:15;91973:1;91960:12;:15::i;:::-;91948:27;;91990:9;:16;;;92021:8;91986:55;92055:14;;-1:-1:-1;;;;;92055:28:0;;92051:93;;92118:14;;;-1:-1:-1;92051:93:0;92179:5;-1:-1:-1;;;;;92158:26:0;:17;-1:-1:-1;;;;;92158:26:0;;92154:84;;92225:1;92199:8;92208:13;;;;;;92199:23;;;;;;;;:::i;:::-;;;;;;:27;;;;;92154:84;91924:3;;91825:422;;;-1:-1:-1;;;92312:29:0;;;-1:-1:-1;92319:8:0;;-1:-1:-1;;90221:2165:0;;;;;;:::o;97518:204::-;97656:8;99405:42;-1:-1:-1;;;;;99385:63:0;;;35478:112;;99240:24;;;;35523:59;;;35556:26;35573:8;35556:16;:26::i;:::-;97673:43:::1;97697:8;97707;97673:23;:43::i;99034:111::-:0;1996:13;:11;:13::i;:::-;99107:24:::1;:32:::0;;-1:-1:-1;;99107:32:0::1;::::0;::::1;;::::0;;;::::1;::::0;;99034:111::o;98378:242::-;98554:4;-1:-1:-1;;;;;35156:18:0;;35164:10;35156:18;35152:160;;99405:42;35210:10;99385:63;35185:120;;99240:24;;;;35234:61;;;35267:28;35284:10;35267:16;:28::i;:::-;98567:47:::1;98590:4;98596:2;98600:7;98609:4;98567:22;:47::i;88874:396::-:0;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;97505:1:0;89040:7;:25;:54;;;-1:-1:-1;51608:7:0;51631:13;89069:7;:25;;89040:54;89036:93;;;89112:9;88874:396;-1:-1:-1;;88874:396:0:o;89036:93::-;89147:21;89160:7;89147:12;:21::i;:::-;89135:33;;89179:9;:16;;;89175:55;;;89213:9;88874:396;-1:-1:-1;;88874:396:0:o;89175:55::-;89243:21;89256:7;89243:12;:21::i;94077:28::-;;;;;;;:::i;56243:339::-;56326:13;56353:16;56361:7;56353;:16::i;:::-;56348:59;;56378:29;;;;;;;;;;;;;;56348:59;56416:21;56440:10;:8;:10::i;:::-;56416:34;;56477:7;56471:21;56496:1;56471:26;:105;;;;;;;;;;;;;;;;;56533:7;56542:18;56552:7;56542:9;:18::i;:::-;56516:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;56457:119;56243:339;-1:-1:-1;;;56243:339:0:o;95574:455::-;95725:17;95712:9;;;;:30;;;;;;;;:::i;:::-;;95704:59;;;;-1:-1:-1;;;95704:59:0;;16769:2:1;95704:59:0;;;16751:21:1;16808:2;16788:18;;;16781:30;16847:18;16827;;;16820:46;16883:18;;95704:59:0;16567:340:1;95704:59:0;93818:3;95795:6;95778:14;52292:7;52465:13;-1:-1:-1;;52465:31:0;;52237:272;95778:14;:23;;;;:::i;:::-;:40;95770:75;;;;-1:-1:-1;;;95770:75:0;;17114:2:1;95770:75:0;;;17096:21:1;17153:2;17133:18;;;17126:30;17192:24;17172:18;;;17165:52;17234:18;;95770:75:0;16912:346:1;95770:75:0;791:10;53316:7;53347:25;;;:18;:25;;47527:2;53347:25;;;;;93870:1;;95868:36;;95898:6;;53347:50;47393:13;53346:89;95868:36;:::i;:::-;:56;95852:115;;;;-1:-1:-1;;;95852:115:0;;17465:2:1;95852:115:0;;;17447:21:1;17504:2;17484:18;;;17477:30;17543:27;17523:18;;;17516:55;17588:18;;95852:115:0;17263:349:1;95852:115:0;95974:49;95983:6;93916:11;96006:5;;95974:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;95974:49:0;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;96013:9:0;;-1:-1:-1;96013:9:0;;;;95974:49;;96013:9;;;;95974:49;;;;;;;;;-1:-1:-1;95974:8:0;;-1:-1:-1;;;95974:49:0:i;96872:172::-;1996:13;:11;:13::i;:::-;93768:4:::1;96962:6;96945:14;52292:7:::0;52465:13;-1:-1:-1;;52465:31:0;;52237:272;96945:14:::1;:23;;;;:::i;:::-;:36;96937:67;;;::::0;-1:-1:-1;;;96937:67:0;;15921:2:1;96937:67:0::1;::::0;::::1;15903:21:1::0;15960:2;15940:18;;;15933:30;15999:20;15979:18;;;15972:48;16037:18;;96937:67:0::1;15719:342:1::0;96937:67:0::1;97011:27;791:10:::0;97031:6:::1;97011:5;:27::i;:::-;96872:172:::0;:::o;94764:91::-;94808:13;94837:12;94830:19;;;;;:::i;2950:191::-;1996:13;:11;:13::i;:::-;-1:-1:-1;;;;;3035:22:0;::::1;3027:73;;;::::0;-1:-1:-1;;;3027:73:0;;17819:2:1;3027:73:0::1;::::0;::::1;17801:21:1::0;17858:2;17838:18;;;17831:30;17897:34;17877:18;;;17870:62;17968:8;17948:18;;;17941:36;17994:19;;3027:73:0::1;17617:402:1::0;3027:73:0::1;3107:28;3126:8;3107:18;:28::i;94861:144::-:0;1996:13;:11;:13::i;:::-;94573:14:::1;::::0;::::1;::::0;::::1;;;94572:15;94564:43;;;::::0;-1:-1:-1;;;94564:43:0;;12858:2:1;94564:43:0::1;::::0;::::1;12840:21:1::0;12897:2;12877:18;;;12870:30;-1:-1:-1;;;12916:18:1;;;12909:45;12971:18;;94564:43:0::1;12656:339:1::0;94564:43:0::1;94965:14:::2;:34;94982:17:::0;;94965:14;:34:::2;:::i;55027:609::-:0;55122:4;-1:-1:-1;;;;;;;;;55420:25:0;;;;:96;;-1:-1:-1;55491:25:0;-1:-1:-1;;;;;;55491:25:0;;;55420:96;:167;;;-1:-1:-1;;;;;;;;55562:25:0;;;;55027:609::o;7537:233::-;7649:4;-1:-1:-1;;;;;;7676:41:0;;7691:26;7676:41;;:88;;-1:-1:-1;;;;;;;;;;6149:40:0;;;7728:36;6034:161;2247:126;2165:6;;-1:-1:-1;;;;;2165:6:0;791:10;2307:23;2299:68;;;;-1:-1:-1;;;2299:68:0;;18226:2:1;2299:68:0;;;18208:21:1;;;18245:18;;;18238:30;18304:34;18284:18;;;18277:62;18356:18;;2299:68:0;18024:356:1;8867:354:0;8603:5;8989:33;;;;;8973:109;;;;-1:-1:-1;;;8973:109:0;;18587:2:1;8973:109:0;;;18569:21:1;18626:2;18606:18;;;18599:30;18665:34;18645:18;;;18638:62;18736:12;18716:18;;;18709:40;18766:19;;8973:109:0;18385:406:1;8973:109:0;-1:-1:-1;;;;;9097:22:0;;9089:60;;;;-1:-1:-1;;;9089:60:0;;18998:2:1;9089:60:0;;;18980:21:1;19037:2;19017:18;;;19010:30;19076:27;19056:18;;;19049:55;19121:18;;9089:60:0;18796:349:1;9089:60:0;9180:35;;;;;;;;;-1:-1:-1;;;;;9180:35:0;;;;;;;;;;;;;;;;;-1:-1:-1;;;9158:57:0;;;;:19;:57;8867:354::o;63244:258::-;63309:4;63355:7;97505:1;63336:26;;:60;;;;;63383:13;;63373:7;:23;63336:60;:141;;;;-1:-1:-1;;63428:26:0;;;;:17;:26;;;;;;-1:-1:-1;;;63428:44:0;:49;;63244:258::o;35696:1237::-;36057:22;36051:4;36044:36;36138:9;36132:4;36125:23;36201:8;36195:4;36188:22;36376:4;36370;36364;36358;36331:25;36324:5;36313:68;36293:262;;36489:16;36483:4;36477;36462:44;36529:16;36523:4;36516:30;36293:262;36919:1;36913:4;36906:15;35696:1237;:::o;61383:385::-;61483:13;61499:16;61507:7;61499;:16::i;:::-;61483:32;-1:-1:-1;791:10:0;-1:-1:-1;;;;;61528:28:0;;;61524:155;;61570:44;61587:5;791:10;62829:173;:::i;61570:44::-;61565:114;;61634:35;;;;;;;;;;;;;;61565:114;61687:24;;;;:15;:24;;;;;;:35;;-1:-1:-1;;61687:35:0;-1:-1:-1;;;;;61687:35:0;;;;;;;;;61734:28;;61687:24;;61734:28;;;;;;;61476:292;61383:385;;:::o;65344:2575::-;65468:27;65498;65517:7;65498:18;:27::i;:::-;65468:57;;65579:4;-1:-1:-1;;;;;65538:45:0;65554:19;-1:-1:-1;;;;;65538:45:0;;65534:93;;65599:28;;;;;;;;;;;;;;65534:93;65645:27;64512:24;;;:15;:24;;;;;64720:26;;791:10;64159:30;;;-1:-1:-1;;;;;63876:28:0;;64137:20;;;64134:56;65836:183;;65923:43;65940:4;791:10;62829:173;:::i;65923:43::-;65918:101;;65984:35;;;;;;;;;;;;;;65918:101;-1:-1:-1;;;;;66032:16:0;;66028:52;;66057:23;;;;;;;;;;;;;;66028:52;66211:15;66208:138;;;66335:1;66314:19;66307:30;66208:138;-1:-1:-1;;;;;66694:24:0;;;;;;;:18;:24;;;;;;66692:26;;-1:-1:-1;;66692:26:0;;;66757:22;;;;;;;;;66755:24;;-1:-1:-1;66755:24:0;;;60307:11;60282:23;60278:41;60265:63;-1:-1:-1;;;60265:63:0;67014:26;;;;:17;:26;;;;;:164;;;;-1:-1:-1;;;67286:47:0;;:52;;67282:535;;67383:1;67373:11;;67351:19;67490:30;;;:17;:30;;;;;;:35;;67486:322;;67608:13;;67593:11;:28;67589:208;;67731:30;;;;:17;:30;;;;;:52;;;67589:208;67340:477;67282:535;67856:7;67852:2;-1:-1:-1;;;;;67837:27:0;67846:4;-1:-1:-1;;;;;67837:27:0;;;;;;;;;;;67871:42;65461:2458;;;65344:2575;;;:::o;68007:173::-;68135:39;68152:4;68158:2;68162:7;68135:39;;;;;;;;;;;;:16;:39::i;58348:1037::-;58415:7;58446;;97505:1;58485:23;58481:847;;58530:13;;58523:4;:20;58519:809;;;58558:14;58575:23;;;:17;:23;;;;;;;-1:-1:-1;;;58644:24:0;;:29;;58640:677;;59189:87;59196:6;59206:1;59196:11;59189:87;;-1:-1:-1;;;59253:6:0;59235:25;;;;:17;:25;;;;;;59189:87;;58640:677;58545:783;58519:809;59348:31;;;;;;;;;;;;;;3291:177;3380:6;;;-1:-1:-1;;;;;3393:17:0;;;-1:-1:-1;;3393:17:0;;;;;;;3422:40;;3380:6;;;3393:17;3380:6;;3422:40;;3361:16;;3422:40;3354:114;3291:177;:::o;96357:509::-;96512:14;96521:5;96512:6;:14;:::i;:::-;96499:9;:27;;96491:56;;;;-1:-1:-1;;;96491:56:0;;19352:2:1;96491:56:0;;;19334:21:1;19391:2;19371:18;;;19364:30;19430:18;19410;;;19403:46;19466:18;;96491:56:0;19150:340:1;96491:56:0;96563:11;96575:5;96563:18;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;96562:19;96554:44;;;;-1:-1:-1;;;96554:44:0;;19991:2:1;96554:44:0;;;19973:21:1;20030:2;20010:18;;;20003:30;20069:14;20049:18;;;20042:42;20101:18;;96554:44:0;19789:336:1;96554:44:0;96745:14;;-1:-1:-1;;;;;96745:14:0;96621:120;96731:9;96621:91;791:10;96662:6;96670:5;96631:45;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;96631:45:0;;;;;;;;;96621:56;;96631:45;96621:56;;;;21198:66:1;30995:58:0;;;21186:79:1;21281:12;;;;21274:28;;;;30995:58:0;;;;;;;;;;21318:12:1;;;;30995:58:0;;;30985:69;;;;;;30788:272;96621:91;:109;;:120::i;:::-;-1:-1:-1;;;;;96621:138:0;;96605:189;;;;-1:-1:-1;;;96605:189:0;;20812:2:1;96605:189:0;;;20794:21:1;20851:2;20831:18;;;20824:30;20890:19;20870:18;;;20863:47;20927:18;;96605:189:0;20610:341:1;96605:189:0;96822:4;96801:11;96813:5;96801:18;;;;;;:::i;:::-;;;;;;;;;;;;;;:25;;;;;-1:-1:-1;;96801:25:0;;;;;;;;;96833:27;96839:12;791:10;;715:92;96839:12;96853:6;96833:5;:27::i;57824:165::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57958:24:0;;;;:17;:24;;;;;;57939:44;;-1:-1:-1;;;;;;;;;;;;;59592:41:0;;;;48032:3;59674:33;;;59640:68;;-1:-1:-1;;;59640:68:0;-1:-1:-1;;;59734:24:0;;:29;;-1:-1:-1;;;59715:48:0;;;;48537:3;59799:28;;;;-1:-1:-1;;;59770:58:0;-1:-1:-1;59476:358:0;62445:239;791:10;62551:39;;;;:18;:39;;;;;;;;-1:-1:-1;;;;;62551:49:0;;;;;;;;;;;;:60;;-1:-1:-1;;62551:60:0;;;;;;;;;;62623:55;;586:41:1;;;62551:49:0;;791:10;62623:55;;559:18:1;62623:55:0;;;;;;;62445:239;;:::o;68746:359::-;68899:31;68912:4;68918:2;68922:7;68899:12;:31::i;:::-;-1:-1:-1;;;;;68941:14:0;;;:19;68937:163;;68974:56;69005:4;69011:2;69015:7;69024:5;68974:30;:56::i;:::-;68969:131;;69050:40;;-1:-1:-1;;;69050:40:0;;;;;;;;;;;57566:170;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57683:47:0;57702:27;57721:7;57702:18;:27::i;:::-;-1:-1:-1;;;;;;;;;;;;;59592:41:0;;;;48032:3;59674:33;;;59640:68;;-1:-1:-1;;;59640:68:0;-1:-1:-1;;;59734:24:0;;:29;;-1:-1:-1;;;59715:48:0;;;;48537:3;59799:28;;;;-1:-1:-1;;;59770:58:0;-1:-1:-1;59476:358:0;95474:94;95526:13;95555:7;95548:14;;;;;:::i;83851:1613::-;83926:17;84326:4;84319;84313:11;84309:22;84406:1;84400:4;84393:15;84469:4;84466:1;84462:12;84455:19;;;84539:1;84534:3;84527:14;84631:3;84846:5;84828:428;84894:1;84889:3;84885:11;84878:18;;85065:2;85059:4;85055:13;85051:2;85047:22;85042:3;85034:36;85159:2;85149:13;;85216:25;84828:428;85216:25;-1:-1:-1;85280:13:0;;;-1:-1:-1;;85383:14:0;;;85433:19;;;85383:14;83851:1613;-1:-1:-1;83851:1613:0:o;72156:2578::-;72225:20;72248:13;;;72272;;;72268:44;;72294:18;;;;;;;;;;;;;;72268:44;-1:-1:-1;;;;;72744:22:0;;;;;;:18;:22;;;;47527:2;72744:22;;;:71;;72782:32;72770:45;;72744:71;;;73022:31;;;:17;:31;;;;;-1:-1:-1;60714:15:0;;60688:24;60684:46;60307:11;60282:23;60278:41;60275:52;60265:63;;73022:151;;73223:23;;;;73022:31;;72744:22;;73896:25;72744:22;;73779:267;74330:1;74316:12;74312:20;74280:282;74363:3;74354:7;74351:16;74280:282;;74543:7;74533:8;74530:1;74503:25;74500:1;74497;74492:59;74406:1;74393:15;74280:282;;;74284:59;74583:8;74595:1;74583:13;74579:45;;74605:19;;;;;;;;;;;;;;74579:45;74635:13;:19;-1:-1:-1;97728:216:0;;;:::o;27305:232::-;27398:7;27415:17;27434:18;27456:27;27467:4;27473:9;27456:10;:27::i;:::-;27414:69;;;;27490:18;27502:5;27490:11;:18::i;:::-;-1:-1:-1;27522:9:0;27305:232;-1:-1:-1;;;27305:232:0:o;71063:659::-;71232:133;;-1:-1:-1;;;71232:133:0;;71208:4;;-1:-1:-1;;;;;71232:45:0;;;;;:133;;791:10;;71318:4;;71333:7;;71351:5;;71232:133;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;71232:133:0;;;;;;;;-1:-1:-1;;71232:133:0;;;;;;;;;;;;:::i;:::-;;;71221:496;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;71525:6;:13;71542:1;71525:18;71521:189;;71563:40;;-1:-1:-1;;;71563:40:0;;;;;;;;;;;71521:189;71682:6;71676:13;71667:6;71663:2;71659:15;71652:38;71221:496;-1:-1:-1;;;;;;71411:64:0;-1:-1:-1;;;71411:64:0;;-1:-1:-1;71063:659:0;;;;;;:::o;25869:664::-;25965:7;25974:12;25999:9;:16;26019:2;25999:22;25995:533;;26293:4;26278:20;;26272:27;26335:4;26320:20;;26314:27;26385:4;26370:20;;26364:27;26032:9;26356:36;26416:25;26427:4;26356:36;26272:27;26314;26416:10;:25::i;:::-;26409:32;;;;;;;;;25995:533;-1:-1:-1;26480:1:0;;-1:-1:-1;26484:35:0;26464:56;;24350:475;24424:20;24415:5;:29;;;;;;;;:::i;:::-;;24411:409;;24350:475;:::o;24411:409::-;24512:29;24503:5;:38;;;;;;;;:::i;:::-;;24499:321;;24552:34;;-1:-1:-1;;;24552:34:0;;22314:2:1;24552:34:0;;;22296:21:1;22353:2;22333:18;;;22326:30;22392:26;22372:18;;;22365:54;22436:18;;24552:34:0;22112:348:1;24499:321:0;24613:35;24604:5;:44;;;;;;;;:::i;:::-;;24600:220;;24659:41;;-1:-1:-1;;;24659:41:0;;22667:2:1;24659:41:0;;;22649:21:1;22706:2;22686:18;;;22679:30;22745:33;22725:18;;;22718:61;22796:18;;24659:41:0;22465:355:1;24600:220:0;24727:30;24718:5;:39;;;;;;;;:::i;:::-;;24714:106;;24768:44;;-1:-1:-1;;;24768:44:0;;23027:2:1;24768:44:0;;;23009:21:1;23066:2;23046:18;;;23039:30;23105:34;23085:18;;;23078:62;23176:4;23156:18;;;23149:32;23198:19;;24768:44:0;22825:398:1;28685:1445:0;28798:7;;29707:66;29687:86;;29675:174;;;-1:-1:-1;29806:1:0;;-1:-1:-1;29810:30:0;29790:51;;29675:174;29955:24;;;29938:14;29955:24;;;;;;;;;23455:25:1;;;23528:4;23516:17;;23496:18;;;23489:45;;;;23550:18;;;23543:34;;;23593:18;;;23586:34;;;29955:24:0;;23427:19:1;;29955:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;29955:24:0;;-1:-1:-1;;29955:24:0;;;-1:-1:-1;;;;;;;29990:20:0;;29986:93;;30037:1;30041:29;30021:50;;;;;;;29986:93;30095:6;-1:-1:-1;30103:20:0;;-1:-1:-1;28685:1445:0;;;;;;;;:::o;14:177:1:-;-1:-1:-1;;;;;;92:5:1;88:78;81:5;78:89;68:117;;181:1;178;171:12;196:245;254:6;307:2;295:9;286:7;282:23;278:32;275:52;;;323:1;320;313:12;275:52;362:9;349:23;381:30;405:5;381:30;:::i;638:196::-;706:20;;-1:-1:-1;;;;;755:54:1;;745:65;;735:93;;824:1;821;814:12;735:93;638:196;;;:::o;839:366::-;906:6;914;967:2;955:9;946:7;942:23;938:32;935:52;;;983:1;980;973:12;935:52;1006:29;1025:9;1006:29;:::i;:::-;996:39;;1085:2;1074:9;1070:18;1057:32;1129:26;1122:5;1118:38;1111:5;1108:49;1098:77;;1171:1;1168;1161:12;1098:77;1194:5;1184:15;;;839:366;;;;;:::o;1210:186::-;1269:6;1322:2;1310:9;1301:7;1297:23;1293:32;1290:52;;;1338:1;1335;1328:12;1290:52;1361:29;1380:9;1361:29;:::i;1401:250::-;1486:1;1496:113;1510:6;1507:1;1504:13;1496:113;;;1586:11;;;1580:18;1567:11;;;1560:39;1532:2;1525:10;1496:113;;;-1:-1:-1;;1643:1:1;1625:16;;1618:27;1401:250::o;1656:271::-;1698:3;1736:5;1730:12;1763:6;1758:3;1751:19;1779:76;1848:6;1841:4;1836:3;1832:14;1825:4;1818:5;1814:16;1779:76;:::i;:::-;1909:2;1888:15;-1:-1:-1;;1884:29:1;1875:39;;;;1916:4;1871:50;;1656:271;-1:-1:-1;;1656:271:1:o;1932:220::-;2081:2;2070:9;2063:21;2044:4;2101:45;2142:2;2131:9;2127:18;2119:6;2101:45;:::i;2157:180::-;2216:6;2269:2;2257:9;2248:7;2244:23;2240:32;2237:52;;;2285:1;2282;2275:12;2237:52;-1:-1:-1;2308:23:1;;2157:180;-1:-1:-1;2157:180:1:o;2573:254::-;2641:6;2649;2702:2;2690:9;2681:7;2677:23;2673:32;2670:52;;;2718:1;2715;2708:12;2670:52;2741:29;2760:9;2741:29;:::i;:::-;2731:39;2817:2;2802:18;;;;2789:32;;-1:-1:-1;;;2573:254:1:o;3014:328::-;3091:6;3099;3107;3160:2;3148:9;3139:7;3135:23;3131:32;3128:52;;;3176:1;3173;3166:12;3128:52;3199:29;3218:9;3199:29;:::i;:::-;3189:39;;3247:38;3281:2;3270:9;3266:18;3247:38;:::i;:::-;3237:48;;3332:2;3321:9;3317:18;3304:32;3294:42;;3014:328;;;;;:::o;3347:248::-;3415:6;3423;3476:2;3464:9;3455:7;3451:23;3447:32;3444:52;;;3492:1;3489;3482:12;3444:52;-1:-1:-1;;3515:23:1;;;3585:2;3570:18;;;3557:32;;-1:-1:-1;3347:248:1:o;3902:348::-;3954:8;3964:6;4018:3;4011:4;4003:6;3999:17;3995:27;3985:55;;4036:1;4033;4026:12;3985:55;-1:-1:-1;4059:20:1;;4102:18;4091:30;;4088:50;;;4134:1;4131;4124:12;4088:50;4171:4;4163:6;4159:17;4147:29;;4223:3;4216:4;4207:6;4199;4195:19;4191:30;4188:39;4185:59;;;4240:1;4237;4230:12;4255:411;4326:6;4334;4387:2;4375:9;4366:7;4362:23;4358:32;4355:52;;;4403:1;4400;4393:12;4355:52;4443:9;4430:23;4476:18;4468:6;4465:30;4462:50;;;4508:1;4505;4498:12;4462:50;4547:59;4598:7;4589:6;4578:9;4574:22;4547:59;:::i;:::-;4625:8;;4521:85;;-1:-1:-1;4255:411:1;-1:-1:-1;;;;4255:411:1:o;4671:615::-;4757:6;4765;4818:2;4806:9;4797:7;4793:23;4789:32;4786:52;;;4834:1;4831;4824:12;4786:52;4874:9;4861:23;4903:18;4944:2;4936:6;4933:14;4930:34;;;4960:1;4957;4950:12;4930:34;4998:6;4987:9;4983:22;4973:32;;5043:7;5036:4;5032:2;5028:13;5024:27;5014:55;;5065:1;5062;5055:12;5014:55;5105:2;5092:16;5131:2;5123:6;5120:14;5117:34;;;5147:1;5144;5137:12;5117:34;5200:7;5195:2;5185:6;5182:1;5178:14;5174:2;5170:23;5166:32;5163:45;5160:65;;;5221:1;5218;5211:12;5160:65;5252:2;5244:11;;;;;5274:6;;-1:-1:-1;4671:615:1;;-1:-1:-1;;;;4671:615:1:o;5668:724::-;5903:2;5955:21;;;6025:13;;5928:18;;;6047:22;;;5874:4;;5903:2;6126:15;;;;6100:2;6085:18;;;5874:4;6169:197;6183:6;6180:1;6177:13;6169:197;;;6232:52;6280:3;6271:6;6265:13;-1:-1:-1;;;;;5381:5:1;5375:12;5371:61;5366:3;5359:74;5494:18;5486:4;5479:5;5475:16;5469:23;5465:48;5458:4;5453:3;5449:14;5442:72;5577:4;5570:5;5566:16;5560:23;5553:31;5546:39;5539:4;5534:3;5530:14;5523:63;5647:8;5639:4;5632:5;5628:16;5622:23;5618:38;5611:4;5606:3;5602:14;5595:62;;;5291:372;6232:52;6341:15;;;;6313:4;6304:14;;;;;6205:1;6198:9;6169:197;;6397:184;-1:-1:-1;;;6446:1:1;6439:88;6546:4;6543:1;6536:15;6570:4;6567:1;6560:15;6586:399;6732:2;6717:18;;6765:1;6754:13;;6744:201;;-1:-1:-1;;;6798:1:1;6791:88;6902:4;6899:1;6892:15;6930:4;6927:1;6920:15;6744:201;6954:25;;;6586:399;:::o;6990:788::-;7090:6;7098;7106;7114;7122;7175:2;7163:9;7154:7;7150:23;7146:32;7143:52;;;7191:1;7188;7181:12;7143:52;7227:9;7214:23;7204:33;;7288:2;7277:9;7273:18;7260:32;7311:18;7352:2;7344:6;7341:14;7338:34;;;7368:1;7365;7358:12;7338:34;7407:59;7458:7;7449:6;7438:9;7434:22;7407:59;:::i;:::-;7485:8;;-1:-1:-1;7381:85:1;-1:-1:-1;7573:2:1;7558:18;;7545:32;;-1:-1:-1;7589:16:1;;;7586:36;;;7618:1;7615;7608:12;7586:36;;7657:61;7710:7;7699:8;7688:9;7684:24;7657:61;:::i;:::-;6990:788;;;;-1:-1:-1;6990:788:1;;-1:-1:-1;7737:8:1;;7631:87;6990:788;-1:-1:-1;;;6990:788:1:o;7783:632::-;7954:2;8006:21;;;8076:13;;7979:18;;;8098:22;;;7925:4;;7954:2;8177:15;;;;8151:2;8136:18;;;7925:4;8220:169;8234:6;8231:1;8228:13;8220:169;;;8295:13;;8283:26;;8364:15;;;;8329:12;;;;8256:1;8249:9;8220:169;;8420:322;8497:6;8505;8513;8566:2;8554:9;8545:7;8541:23;8537:32;8534:52;;;8582:1;8579;8572:12;8534:52;8605:29;8624:9;8605:29;:::i;:::-;8595:39;8681:2;8666:18;;8653:32;;-1:-1:-1;8732:2:1;8717:18;;;8704:32;;8420:322;-1:-1:-1;;;8420:322:1:o;8747:160::-;8812:20;;8868:13;;8861:21;8851:32;;8841:60;;8897:1;8894;8887:12;8912:254;8977:6;8985;9038:2;9026:9;9017:7;9013:23;9009:32;9006:52;;;9054:1;9051;9044:12;9006:52;9077:29;9096:9;9077:29;:::i;:::-;9067:39;;9125:35;9156:2;9145:9;9141:18;9125:35;:::i;:::-;9115:45;;8912:254;;;;;:::o;9171:180::-;9227:6;9280:2;9268:9;9259:7;9255:23;9251:32;9248:52;;;9296:1;9293;9286:12;9248:52;9319:26;9335:9;9319:26;:::i;9356:184::-;-1:-1:-1;;;9405:1:1;9398:88;9505:4;9502:1;9495:15;9529:4;9526:1;9519:15;9545:1138;9640:6;9648;9656;9664;9717:3;9705:9;9696:7;9692:23;9688:33;9685:53;;;9734:1;9731;9724:12;9685:53;9757:29;9776:9;9757:29;:::i;:::-;9747:39;;9805:38;9839:2;9828:9;9824:18;9805:38;:::i;:::-;9795:48;;9890:2;9879:9;9875:18;9862:32;9852:42;;9945:2;9934:9;9930:18;9917:32;9968:18;10009:2;10001:6;9998:14;9995:34;;;10025:1;10022;10015:12;9995:34;10063:6;10052:9;10048:22;10038:32;;10108:7;10101:4;10097:2;10093:13;10089:27;10079:55;;10130:1;10127;10120:12;10079:55;10166:2;10153:16;10188:2;10184;10181:10;10178:36;;;10194:18;;:::i;:::-;10269:2;10263:9;10237:2;10323:13;;-1:-1:-1;;10319:22:1;;;10343:2;10315:31;10311:40;10299:53;;;10367:18;;;10387:22;;;10364:46;10361:72;;;10413:18;;:::i;:::-;10453:10;10449:2;10442:22;10488:2;10480:6;10473:18;10528:7;10523:2;10518;10514;10510:11;10506:20;10503:33;10500:53;;;10549:1;10546;10539:12;10500:53;10605:2;10600;10596;10592:11;10587:2;10579:6;10575:15;10562:46;10650:1;10645:2;10640;10632:6;10628:15;10624:24;10617:35;10671:6;10661:16;;;;;;;9545:1138;;;;;;;:::o;10688:268::-;5375:12;;-1:-1:-1;;;;;5371:61:1;5359:74;;5486:4;5475:16;;;5469:23;5494:18;5465:48;5449:14;;;5442:72;5577:4;5566:16;;;5560:23;5553:31;5546:39;5530:14;;;5523:63;5639:4;5628:16;;;5622:23;5647:8;5618:38;5602:14;;;5595:62;10886:3;10871:19;;10899:51;5291:372;10961:260;11029:6;11037;11090:2;11078:9;11069:7;11065:23;11061:32;11058:52;;;11106:1;11103;11096:12;11058:52;11129:29;11148:9;11129:29;:::i;:::-;11119:39;;11177:38;11211:2;11200:9;11196:18;11177:38;:::i;11226:437::-;11305:1;11301:12;;;;11348;;;11369:61;;11423:4;11415:6;11411:17;11401:27;;11369:61;11476:2;11468:6;11465:14;11445:18;11442:38;11439:218;;-1:-1:-1;;;11510:1:1;11503:88;11614:4;11611:1;11604:15;11642:4;11639:1;11632:15;11439:218;;11226:437;;;:::o;12015:184::-;-1:-1:-1;;;12064:1:1;12057:88;12164:4;12161:1;12154:15;12188:4;12185:1;12178:15;12204:168;12277:9;;;12308;;12325:15;;;12319:22;;12305:37;12295:71;;12346:18;;:::i;12377:274::-;12417:1;12443;12433:189;;-1:-1:-1;;;12475:1:1;12468:88;12579:4;12576:1;12569:15;12607:4;12604:1;12597:15;12433:189;-1:-1:-1;12636:9:1;;12377:274::o;13126:545::-;13228:2;13223:3;13220:11;13217:448;;;13264:1;13289:5;13285:2;13278:17;13334:4;13330:2;13320:19;13404:2;13392:10;13388:19;13385:1;13381:27;13375:4;13371:38;13440:4;13428:10;13425:20;13422:47;;;-1:-1:-1;13463:4:1;13422:47;13518:2;13513:3;13509:12;13506:1;13502:20;13496:4;13492:31;13482:41;;13573:82;13591:2;13584:5;13581:13;13573:82;;;13636:17;;;13617:1;13606:13;13573:82;;13847:1206;13971:18;13966:3;13963:27;13960:53;;;13993:18;;:::i;:::-;14022:94;14112:3;14072:38;14104:4;14098:11;14072:38;:::i;:::-;14066:4;14022:94;:::i;:::-;14142:1;14167:2;14162:3;14159:11;14184:1;14179:616;;;;14839:1;14856:3;14853:93;;;-1:-1:-1;14912:19:1;;;14899:33;14853:93;-1:-1:-1;;13804:1:1;13800:11;;;13796:24;13792:29;13782:40;13828:1;13824:11;;;13779:57;14959:78;;14152:895;;14179:616;13073:1;13066:14;;;13110:4;13097:18;;-1:-1:-1;;14215:17:1;;;14316:9;14338:229;14352:7;14349:1;14346:14;14338:229;;;14441:19;;;14428:33;14413:49;;14548:4;14533:20;;;;14501:1;14489:14;;;;14368:12;14338:229;;;14342:3;14595;14586:7;14583:16;14580:159;;;14719:1;14715:6;14709:3;14703;14700:1;14696:11;14692:21;14688:34;14684:39;14671:9;14666:3;14662:19;14649:33;14645:79;14637:6;14630:95;14580:159;;;14782:1;14776:3;14773:1;14769:11;14765:19;14759:4;14752:33;14152:895;;13847:1206;;;:::o;15058:184::-;-1:-1:-1;;;15107:1:1;15100:88;15207:4;15204:1;15197:15;15231:4;15228:1;15221:15;15589:125;15654:9;;;15675:10;;;15672:36;;;15688:18;;:::i;16066:496::-;16245:3;16283:6;16277:13;16299:66;16358:6;16353:3;16346:4;16338:6;16334:17;16299:66;:::i;:::-;16428:13;;16387:16;;;;16450:70;16428:13;16387:16;16497:4;16485:17;;16450:70;:::i;:::-;16536:20;;16066:496;-1:-1:-1;;;;16066:496:1:o;19495:289::-;19626:3;19664:6;19658:13;19680:66;19739:6;19734:3;19727:4;19719:6;19715:17;19680:66;:::i;:::-;19762:16;;;;;19495:289;-1:-1:-1;;19495:289:1:o;20130:475::-;20372:26;20368:31;20359:6;20355:2;20351:15;20347:53;20342:3;20335:66;20431:6;20426:2;20421:3;20417:12;20410:28;20317:3;20467:6;20461:13;20483:75;20551:6;20546:2;20541:3;20537:12;20530:4;20522:6;20518:17;20483:75;:::i;:::-;20578:16;;;;20596:2;20574:25;;20130:475;-1:-1:-1;;;;20130:475:1:o;21341:512::-;21535:4;-1:-1:-1;;;;;21645:2:1;21637:6;21633:15;21622:9;21615:34;21697:2;21689:6;21685:15;21680:2;21669:9;21665:18;21658:43;;21737:6;21732:2;21721:9;21717:18;21710:34;21780:3;21775:2;21764:9;21760:18;21753:31;21801:46;21842:3;21831:9;21827:19;21819:6;21801:46;:::i;:::-;21793:54;21341:512;-1:-1:-1;;;;;;21341:512:1:o;21858:249::-;21927:6;21980:2;21968:9;21959:7;21955:23;21951:32;21948:52;;;21996:1;21993;21986:12;21948:52;22028:9;22022:16;22047:30;22071:5;22047:30;:::i

Swarm Source

ipfs://d3115df550d9643b73471bc6a721e5fc4b253539e733568dea0076f2a9772b80
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.