ETH Price: $3,334.90 (-3.83%)
Gas: 9.05 Gwei

Token

Animal Society (AS)
 

Overview

Max Total Supply

7,777 AS

Holders

3,302

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
2 AS
0xea812441aafcadfe4a348de0acdee824b15ae3b2
Loading...
Loading
Loading...
Loading
Loading...
Loading

OVERVIEW

Welcome to the Official Animal Society Collection Is time to #EndJpegCivilWar #UniteInAnimalSociety

# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
AnimalSociety

Compiler Version
v0.8.7+commit.e28d00a7

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2021-10-21
*/

// SPDX-License-Identifier: MIT
// File: @openzeppelin/contracts/utils/cryptography/ECDSA.sol



pragma solidity ^0.8.0;

/**
 * @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
    }

    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");
        } else if (error == RecoverError.InvalidSignatureV) {
            revert("ECDSA: invalid signature 'v' 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) {
        // Check the signature length
        // - case 65: r,s,v signature (standard)
        // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._
        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.
            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 if (signature.length == 64) {
            bytes32 r;
            bytes32 vs;
            // ecrecover takes the signature parameters, and the only way to get them
            // currently is to use assembly.
            assembly {
                r := mload(add(signature, 0x20))
                vs := mload(add(signature, 0x40))
            }
            return tryRecover(hash, r, vs);
        } 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;
        uint8 v;
        assembly {
            s := and(vs, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            v := add(shr(255, vs), 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 (v != 27 && v != 28) {
            return (address(0), RecoverError.InvalidSignatureV);
        }

        // 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 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: @openzeppelin/contracts/utils/Strings.sol



pragma solidity ^0.8.0;

/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        // Inspired by OraclizeAPI's implementation - MIT licence
        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol

        if (value == 0) {
            return "0";
        }
        uint256 temp = value;
        uint256 digits;
        while (temp != 0) {
            digits++;
            temp /= 10;
        }
        bytes memory buffer = new bytes(digits);
        while (value != 0) {
            digits -= 1;
            buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
            value /= 10;
        }
        return string(buffer);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        if (value == 0) {
            return "0x00";
        }
        uint256 temp = value;
        uint256 length = 0;
        while (temp != 0) {
            length++;
            temp >>= 8;
        }
        return toHexString(value, length);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
     */
    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
        bytes memory buffer = new bytes(2 * length + 2);
        buffer[0] = "0";
        buffer[1] = "x";
        for (uint256 i = 2 * length + 1; i > 1; --i) {
            buffer[i] = _HEX_SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }
}

// File: @openzeppelin/contracts/utils/Context.sol



pragma solidity ^0.8.0;

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

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

// File: @openzeppelin/contracts/access/Ownable.sol



pragma solidity ^0.8.0;


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

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

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

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

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        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 {
        _setOwner(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");
        _setOwner(newOwner);
    }

    function _setOwner(address newOwner) private {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

// File: @openzeppelin/contracts/utils/Address.sol



pragma solidity ^0.8.0;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

        uint256 size;
        assembly {
            size := extcodesize(account)
        }
        return size > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        (bool success, ) = recipient.call{value: amount}("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain `call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCall(target, data, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        require(isContract(target), "Address: call to non-contract");

        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        require(isContract(target), "Address: static call to non-contract");

        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(isContract(target), "Address: delegate call to non-contract");

        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

// File: @openzeppelin/contracts/token/ERC721/IERC721Receiver.sol



pragma solidity ^0.8.0;

/**
 * @title ERC721 token receiver interface
 * @dev Interface for any contract that wants to support safeTransfers
 * from ERC721 asset contracts.
 */
interface IERC721Receiver {
    /**
     * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
     * by `operator` from `from`, this function is called.
     *
     * It must return its Solidity selector to confirm the token transfer.
     * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.
     *
     * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`.
     */
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}

// File: @openzeppelin/contracts/utils/introspection/IERC165.sol



pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[EIP].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

// File: @openzeppelin/contracts/utils/introspection/ERC165.sol



pragma solidity ^0.8.0;


/**
 * @dev Implementation of the {IERC165} interface.
 *
 * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
 * for the additional interface id that will be supported. For example:
 *
 * ```solidity
 * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
 *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
 * }
 * ```
 *
 * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
 */
abstract contract ERC165 is IERC165 {
    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return interfaceId == type(IERC165).interfaceId;
    }
}

// File: @openzeppelin/contracts/token/ERC721/IERC721.sol



pragma solidity ^0.8.0;


/**
 * @dev Required interface of an ERC721 compliant contract.
 */
interface IERC721 is IERC165 {
    /**
     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.
     */
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);

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

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

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

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

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, 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
    ) external;

    /**
     * @dev Transfers `tokenId` token 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;

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

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

    /**
     * @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 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);

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes calldata data
    ) external;
}

// File: @openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol



pragma solidity ^0.8.0;


/**
 * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Enumerable is IERC721 {
    /**
     * @dev Returns the total amount of tokens stored by the contract.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns a token ID owned by `owner` at a given `index` of its token list.
     * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId);

    /**
     * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.
     * Use along with {totalSupply} to enumerate all tokens.
     */
    function tokenByIndex(uint256 index) external view returns (uint256);
}

// File: @openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol



pragma solidity ^0.8.0;


/**
 * @title ERC-721 Non-Fungible Token Standard, optional metadata extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Metadata is IERC721 {
    /**
     * @dev Returns the token collection name.
     */
    function name() external view returns (string memory);

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

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

// File: @openzeppelin/contracts/token/ERC721/ERC721.sol



pragma solidity ^0.8.0;








/**
 * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
 * the Metadata extension, but not including the Enumerable extension, which is available separately as
 * {ERC721Enumerable}.
 */
contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
    using Address for address;
    using Strings for uint256;

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

    // Mapping from token ID to owner address
    mapping(uint256 => address) private _owners;

    // Mapping owner address to token count
    mapping(address => uint256) private _balances;

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

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

    /**
     * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.
     */
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
        return
            interfaceId == type(IERC721).interfaceId ||
            interfaceId == type(IERC721Metadata).interfaceId ||
            super.supportsInterface(interfaceId);
    }

    /**
     * @dev See {IERC721-balanceOf}.
     */
    function balanceOf(address owner) public view virtual override returns (uint256) {
        require(owner != address(0), "ERC721: balance query for the zero address");
        return _balances[owner];
    }

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId) public view virtual override returns (address) {
        address owner = _owners[tokenId];
        require(owner != address(0), "ERC721: owner query for nonexistent token");
        return owner;
    }

    /**
     * @dev See {IERC721Metadata-name}.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev See {IERC721Metadata-symbol}.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev See {IERC721Metadata-tokenURI}.
     */
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");

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

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

    /**
     * @dev See {IERC721-approve}.
     */
    function approve(address to, uint256 tokenId) public virtual override {
        address owner = ERC721.ownerOf(tokenId);
        require(to != owner, "ERC721: approval to current owner");

        require(
            _msgSender() == owner || isApprovedForAll(owner, _msgSender()),
            "ERC721: approve caller is not owner nor approved for all"
        );

        _approve(to, tokenId);
    }

    /**
     * @dev See {IERC721-getApproved}.
     */
    function getApproved(uint256 tokenId) public view virtual override returns (address) {
        require(_exists(tokenId), "ERC721: approved query for nonexistent token");

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev See {IERC721-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        require(operator != _msgSender(), "ERC721: approve to caller");

        _operatorApprovals[_msgSender()][operator] = approved;
        emit ApprovalForAll(_msgSender(), operator, approved);
    }

    /**
     * @dev See {IERC721-isApprovedForAll}.
     */
    function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
        return _operatorApprovals[owner][operator];
    }

    /**
     * @dev See {IERC721-transferFrom}.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        //solhint-disable-next-line max-line-length
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");

        _transfer(from, to, tokenId);
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        safeTransferFrom(from, to, tokenId, "");
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) public virtual override {
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
        _safeTransfer(from, to, tokenId, _data);
    }

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * `_data` is additional data, it has no specified format and it is sent in call to `to`.
     *
     * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.
     * implement alternative mechanisms to perform token transfer, such as signature-based.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function _safeTransfer(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) internal virtual {
        _transfer(from, to, tokenId);
        require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
    }

    /**
     * @dev Returns whether `tokenId` exists.
     *
     * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
     *
     * Tokens start existing when they are minted (`_mint`),
     * and stop existing when they are burned (`_burn`).
     */
    function _exists(uint256 tokenId) internal view virtual returns (bool) {
        return _owners[tokenId] != address(0);
    }

    /**
     * @dev Returns whether `spender` is allowed to manage `tokenId`.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {
        require(_exists(tokenId), "ERC721: operator query for nonexistent token");
        address owner = ERC721.ownerOf(tokenId);
        return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));
    }

    /**
     * @dev Safely mints `tokenId` and transfers it to `to`.
     *
     * Requirements:
     *
     * - `tokenId` must not exist.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function _safeMint(address to, uint256 tokenId) internal virtual {
        _safeMint(to, tokenId, "");
    }

    /**
     * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is
     * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
     */
    function _safeMint(
        address to,
        uint256 tokenId,
        bytes memory _data
    ) internal virtual {
        _mint(to, tokenId);
        require(
            _checkOnERC721Received(address(0), to, tokenId, _data),
            "ERC721: transfer to non ERC721Receiver implementer"
        );
    }

    /**
     * @dev Mints `tokenId` and transfers it to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible
     *
     * Requirements:
     *
     * - `tokenId` must not exist.
     * - `to` cannot be the zero address.
     *
     * Emits a {Transfer} event.
     */
    function _mint(address to, uint256 tokenId) internal virtual {
        require(to != address(0), "ERC721: mint to the zero address");
        require(!_exists(tokenId), "ERC721: token already minted");

        _beforeTokenTransfer(address(0), to, tokenId);

        _balances[to] += 1;
        _owners[tokenId] = to;

        emit Transfer(address(0), to, tokenId);
    }

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

        _beforeTokenTransfer(owner, address(0), tokenId);

        // Clear approvals
        _approve(address(0), tokenId);

        _balances[owner] -= 1;
        delete _owners[tokenId];

        emit Transfer(owner, address(0), tokenId);
    }

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *  As opposed to {transferFrom}, this imposes no restrictions on msg.sender.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     *
     * Emits a {Transfer} event.
     */
    function _transfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual {
        require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer of token that is not own");
        require(to != address(0), "ERC721: transfer to the zero address");

        _beforeTokenTransfer(from, to, tokenId);

        // Clear approvals from the previous owner
        _approve(address(0), tokenId);

        _balances[from] -= 1;
        _balances[to] += 1;
        _owners[tokenId] = to;

        emit Transfer(from, to, tokenId);
    }

    /**
     * @dev Approve `to` to operate on `tokenId`
     *
     * Emits a {Approval} event.
     */
    function _approve(address to, uint256 tokenId) internal virtual {
        _tokenApprovals[tokenId] = to;
        emit Approval(ERC721.ownerOf(tokenId), to, tokenId);
    }

    /**
     * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.
     * The call is not executed if the target address is not a contract.
     *
     * @param from address representing the previous owner of the given token ID
     * @param to target address that will receive the tokens
     * @param tokenId uint256 ID of the token to be transferred
     * @param _data bytes optional data to send along with the call
     * @return bool whether the call correctly returned the expected magic value
     */
    function _checkOnERC721Received(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) private returns (bool) {
        if (to.isContract()) {
            try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) {
                return retval == IERC721Receiver.onERC721Received.selector;
            } catch (bytes memory reason) {
                if (reason.length == 0) {
                    revert("ERC721: transfer to non ERC721Receiver implementer");
                } else {
                    assembly {
                        revert(add(32, reason), mload(reason))
                    }
                }
            }
        } else {
            return true;
        }
    }

    /**
     * @dev Hook that is called before any token transfer. This includes minting
     * and burning.
     *
     * 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, ``from``'s `tokenId` will be burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual {}
}

// File: @openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol



pragma solidity ^0.8.0;



/**
 * @dev This implements an optional extension of {ERC721} defined in the EIP that adds
 * enumerability of all the token ids in the contract as well as all token ids owned by each
 * account.
 */
abstract contract ERC721Enumerable is ERC721, IERC721Enumerable {
    // Mapping from owner to list of owned token IDs
    mapping(address => mapping(uint256 => uint256)) private _ownedTokens;

    // Mapping from token ID to index of the owner tokens list
    mapping(uint256 => uint256) private _ownedTokensIndex;

    // Array with all token ids, used for enumeration
    uint256[] private _allTokens;

    // Mapping from token id to position in the allTokens array
    mapping(uint256 => uint256) private _allTokensIndex;

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) {
        return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId);
    }

    /**
     * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {
        require(index < ERC721.balanceOf(owner), "ERC721Enumerable: owner index out of bounds");
        return _ownedTokens[owner][index];
    }

    /**
     * @dev See {IERC721Enumerable-totalSupply}.
     */
    function totalSupply() public view virtual override returns (uint256) {
        return _allTokens.length;
    }

    /**
     * @dev See {IERC721Enumerable-tokenByIndex}.
     */
    function tokenByIndex(uint256 index) public view virtual override returns (uint256) {
        require(index < ERC721Enumerable.totalSupply(), "ERC721Enumerable: global index out of bounds");
        return _allTokens[index];
    }

    /**
     * @dev Hook that is called before any token transfer. This includes minting
     * and burning.
     *
     * 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, ``from``'s `tokenId` will be burned.
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual override {
        super._beforeTokenTransfer(from, to, tokenId);

        if (from == address(0)) {
            _addTokenToAllTokensEnumeration(tokenId);
        } else if (from != to) {
            _removeTokenFromOwnerEnumeration(from, tokenId);
        }
        if (to == address(0)) {
            _removeTokenFromAllTokensEnumeration(tokenId);
        } else if (to != from) {
            _addTokenToOwnerEnumeration(to, tokenId);
        }
    }

    /**
     * @dev Private function to add a token to this extension's ownership-tracking data structures.
     * @param to address representing the new owner of the given token ID
     * @param tokenId uint256 ID of the token to be added to the tokens list of the given address
     */
    function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {
        uint256 length = ERC721.balanceOf(to);
        _ownedTokens[to][length] = tokenId;
        _ownedTokensIndex[tokenId] = length;
    }

    /**
     * @dev Private function to add a token to this extension's token tracking data structures.
     * @param tokenId uint256 ID of the token to be added to the tokens list
     */
    function _addTokenToAllTokensEnumeration(uint256 tokenId) private {
        _allTokensIndex[tokenId] = _allTokens.length;
        _allTokens.push(tokenId);
    }

    /**
     * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that
     * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for
     * gas optimizations e.g. when performing a transfer operation (avoiding double writes).
     * This has O(1) time complexity, but alters the order of the _ownedTokens array.
     * @param from address representing the previous owner of the given token ID
     * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address
     */
    function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {
        // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and
        // then delete the last slot (swap and pop).

        uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;
        uint256 tokenIndex = _ownedTokensIndex[tokenId];

        // When the token to delete is the last token, the swap operation is unnecessary
        if (tokenIndex != lastTokenIndex) {
            uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];

            _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
            _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index
        }

        // This also deletes the contents at the last position of the array
        delete _ownedTokensIndex[tokenId];
        delete _ownedTokens[from][lastTokenIndex];
    }

    /**
     * @dev Private function to remove a token from this extension's token tracking data structures.
     * This has O(1) time complexity, but alters the order of the _allTokens array.
     * @param tokenId uint256 ID of the token to be removed from the tokens list
     */
    function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {
        // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and
        // then delete the last slot (swap and pop).

        uint256 lastTokenIndex = _allTokens.length - 1;
        uint256 tokenIndex = _allTokensIndex[tokenId];

        // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so
        // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding
        // an 'if' statement (like in _removeTokenFromOwnerEnumeration)
        uint256 lastTokenId = _allTokens[lastTokenIndex];

        _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
        _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index

        // This also deletes the contents at the last position of the array
        delete _allTokensIndex[tokenId];
        _allTokens.pop();
    }
}

// File: AS.sol


pragma solidity ^0.8.4;

/*
    Animal Society
*/


contract AnimalSociety is ERC721Enumerable, Ownable {
    using Strings for uint256;
    using ECDSA for bytes32;

    uint256 public constant AS_GIFT = 350;
    uint256 public constant AS_SALE = 9649;
    uint256 public constant AS_MAX = AS_GIFT + AS_SALE;
    uint256 public constant AS_PRICE = 0.05 ether;
    uint256 public constant AS_MINT = 3;
    uint256 public constant MAX_3 = 1000;
    uint256 public constant MAX_2 = 2400;
    
    mapping(address => uint256) public listPurchases;
    mapping(string => bool) private _usedNonces;
    uint256 public used3;
    uint256 public used2;
    
    string private _contractURI;
    string private _tokenBaseURI = "https://animalsocietynft.com/api/metadata/";
    address private _devAddress = 0xa65159C939FbED795164bb40F7507d9E5D54Ff22; 
    address private _signerAddress = 0xC3E4371297DEAF3eA9D78466d96b1D6098162247;

    string public proof;
    uint256 public giftedAmount;
    uint256 public publicAmountMinted;
    bool public saleLive;
    bool public locked;
    
    constructor() ERC721("Animal Society", "AS") { }
    
    modifier notLocked {
        require(!locked, "Contract metadata methods are locked");
        _;
    }
    
    function hashTransaction(address sender, uint256 qty, string memory nonce) private pure returns(bytes32) {
          bytes32 hash = keccak256(abi.encodePacked(
            "\x19Ethereum Signed Message:\n32",
            keccak256(abi.encodePacked(sender, qty, nonce)))
          );
          
          return hash;
    }
    
    function matchAddresSigner(bytes32 hash, bytes memory signature) private view returns(bool) {
        return _signerAddress == hash.recover(signature);
    }
    
    function checkMaxMints(uint256 qty) private view returns(bool) {
        bool available;
        if( qty > 2) {   // if else statement
            available = used3 < MAX_3;
        } else if( qty > 1 ){
            available = used2 < MAX_2;
        } else {
            available = true;
        }       
        return available;
    }
    
    function buy(bytes32 hash, bytes memory signature, string memory nonce, uint256 tokenQuantity) external payable {
        require(saleLive, "SALE_CLOSED");
        require(matchAddresSigner(hash, signature), "DIRECT_MINT_DISALLOWED");
        require(!_usedNonces[nonce], "HASH_USED");
        require(hashTransaction(msg.sender, tokenQuantity, nonce) == hash, "HASH_FAIL");
        require(totalSupply() < AS_MAX, "OUT_OF_STOCK");
        require(publicAmountMinted + tokenQuantity <= AS_MAX, "EXCEED_PUBLIC");
        require(listPurchases[msg.sender] + tokenQuantity <= AS_MINT, "EXCEED_ALLOC");
        require(tokenQuantity <= AS_MINT, "EXCEED_AS_MINT");
        require(checkMaxMints(listPurchases[msg.sender] + tokenQuantity), "EXCEED_MINT_LIMITS");
        require(AS_PRICE * tokenQuantity <= msg.value, "INSUFFICIENT_ETH");
       
        if(listPurchases[msg.sender] > 2){
            used3--;
        }else if(listPurchases[msg.sender] > 1){
            used2--;
        }
        
        for(uint256 i = 0; i < tokenQuantity; i++) {
            publicAmountMinted++;
             listPurchases[msg.sender]++;
            _safeMint(msg.sender, totalSupply() + 1);
        }
        
        if(listPurchases[msg.sender] > 2){
            used3++;
        }else if(listPurchases[msg.sender] > 1){
            used2++;
        }
        
        _usedNonces[nonce] = true;
    }

    
    function gift(address[] calldata receivers) external onlyOwner {
        require(totalSupply() + receivers.length <= AS_MAX, "MAX_MINT");
        require(giftedAmount + receivers.length <= AS_GIFT, "GIFTS_EMPTY");
        
        for (uint256 i = 0; i < receivers.length; i++) {
            giftedAmount++;
            _safeMint(receivers[i], totalSupply() + 1);
        }
    }
    
    
     function claimReserved(address recipient, uint256 amount) external onlyOwner {
        require(totalSupply() + amount <= AS_MAX, "MAX_MINT");
        require(giftedAmount + amount <= AS_GIFT, "GIFTS_EMPTY");
        
        for (uint256 i = 0; i < amount; i++) {
            giftedAmount++;
            _safeMint(recipient, totalSupply() + 1);
        }
    }
    
    
    function withdraw() external onlyOwner {
        payable(_devAddress).transfer(address(this).balance / 4);
        payable(msg.sender).transfer(address(this).balance);
    }
    
    function purchasedCount(address addr) external view returns (uint256) {
        return listPurchases[addr];
    }
    
    // Owner functions for enabling presale, sale, revealing and setting the provenance hash
    function lockMetadata() external onlyOwner {
        locked = true;
    }
    
    function toggleSaleStatus() external onlyOwner {
        saleLive = !saleLive;
    }
    
    function setSignerAddress(address addr) external onlyOwner {
        _signerAddress = addr;
    }
    
    function setProvenanceHash(string calldata hash) external onlyOwner notLocked {
        proof = hash;
    }
    
    function setContractURI(string calldata URI) external onlyOwner notLocked {
        _contractURI = URI;
    }
    
    function setBaseURI(string calldata URI) external onlyOwner notLocked {
        _tokenBaseURI = URI;
    }
    
    function contractURI() public view returns (string memory) {
        return _contractURI;
    }
    
    function tokenURI(uint256 tokenId) public view override(ERC721) returns (string memory) {
        require(_exists(tokenId), "Cannot query non-existent token");
        return string(abi.encodePacked(_tokenBaseURI, tokenId.toString()));
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"AS_GIFT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"AS_MAX","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"AS_MINT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"AS_PRICE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"AS_SALE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_2","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_3","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"hash","type":"bytes32"},{"internalType":"bytes","name":"signature","type":"bytes"},{"internalType":"string","name":"nonce","type":"string"},{"internalType":"uint256","name":"tokenQuantity","type":"uint256"}],"name":"buy","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"claimReserved","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"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":"receivers","type":"address[]"}],"name":"gift","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"giftedAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"listPurchases","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lockMetadata","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"locked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proof","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"publicAmountMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"purchasedCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"saleLive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":"URI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"URI","type":"string"}],"name":"setContractURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"hash","type":"string"}],"name":"setProvenanceHash","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","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":[],"name":"toggleSaleStatus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"used2","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"used3","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60e0604052602a608081815290620032ac60a039805162000029916010916020909101906200015f565b50601180546001600160a01b031990811673a65159c939fbed795164bb40f7507d9e5d54ff22179091556012805490911673c3e4371297deaf3ea9d78466d96b1d60981622471790553480156200007f57600080fd5b50604080518082018252600e81526d416e696d616c20536f636965747960901b602080830191825283518085019094526002845261415360f01b908401528151919291620000d0916000916200015f565b508051620000e69060019060208401906200015f565b50505062000103620000fd6200010960201b60201c565b6200010d565b62000242565b3390565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b8280546200016d9062000205565b90600052602060002090601f016020900481019282620001915760008555620001dc565b82601f10620001ac57805160ff1916838001178555620001dc565b82800160010185558215620001dc579182015b82811115620001dc578251825591602001919060010190620001bf565b50620001ea929150620001ee565b5090565b5b80821115620001ea5760008155600101620001ef565b600181811c908216806200021a57607f821691505b602082108114156200023c57634e487b7160e01b600052602260045260246000fd5b50919050565b61305a80620002526000396000f3fe60806040526004361061027d5760003560e01c806370a082311161014f578063a22cb465116100c1578063e081b7811161007a578063e081b78114610716578063e60ad04114610730578063e8a3d4851461075d578063e985e9c514610772578063f2fde38b146107bb578063faf924cf146107db57600080fd5b8063a22cb4651461064b578063b88d4fde1461066b578063ba2a06551461068b578063beb837f6146106c1578063c87b56dd146106d7578063cf309012146106f757600080fd5b8063938e3d7b11610113578063938e3d7b146105c2578063940f1ada146105e257806395d89b41146105f8578063989bdbb61461060d57806399483443146106225780639ec70f191461063857600080fd5b806370a0823114610543578063715018a614610563578063772064c3146105785780638da5cb5b1461058e5780638e4b752c146105ac57600080fd5b806323b872dd116101f35780634f6ccce7116101ac5780634f6ccce71461049c57806355f804b3146104bc57806360c8205d146104dc5780636352211e146104f257806363c886f51461051257806368ef67a31461052857600080fd5b806323b872dd146103fd5780632f745c591461041d578063334934191461043d5780633ccfd60b1461045257806341b613021461046757806342842e0e1461047c57600080fd5b8063095ea7b311610245578063095ea7b3146103485780631096952314610368578063163e1e611461038857806318160ddd146103a85780631b57190e146103c75780631b5757f2146103dd57600080fd5b806301ffc9a714610282578063046dc166146102b7578063049c5c49146102d957806306fdde03146102ee578063081812fc14610310575b600080fd5b34801561028e57600080fd5b506102a261029d366004612b12565b6107f0565b60405190151581526020015b60405180910390f35b3480156102c357600080fd5b506102d76102d23660046128bc565b61081b565b005b3480156102e557600080fd5b506102d7610870565b3480156102fa57600080fd5b506103036108ae565b6040516102ae9190612d4c565b34801561031c57600080fd5b5061033061032b366004612bac565b610940565b6040516001600160a01b0390911681526020016102ae565b34801561035457600080fd5b506102d76103633660046129ea565b6109d5565b34801561037457600080fd5b506102d7610383366004612b4c565b610aeb565b34801561039457600080fd5b506102d76103a3366004612a14565b610b49565b3480156103b457600080fd5b506008545b6040519081526020016102ae565b3480156103d357600080fd5b506103b960145481565b3480156103e957600080fd5b506102d76103f83660046129ea565b610c8c565b34801561040957600080fd5b506102d761041836600461290a565b610d9d565b34801561042957600080fd5b506103b96104383660046129ea565b610dce565b34801561044957600080fd5b506103b9610e64565b34801561045e57600080fd5b506102d7610e75565b34801561047357600080fd5b506103b9600381565b34801561048857600080fd5b506102d761049736600461290a565b610f11565b3480156104a857600080fd5b506103b96104b7366004612bac565b610f2c565b3480156104c857600080fd5b506102d76104d7366004612b4c565b610fbf565b3480156104e857600080fd5b506103b9600e5481565b3480156104fe57600080fd5b5061033061050d366004612bac565b61101d565b34801561051e57600080fd5b506103b96125b181565b34801561053457600080fd5b506103b966b1a2bc2ec5000081565b34801561054f57600080fd5b506103b961055e3660046128bc565b611094565b34801561056f57600080fd5b506102d761111b565b34801561058457600080fd5b506103b961096081565b34801561059a57600080fd5b50600a546001600160a01b0316610330565b3480156105b857600080fd5b506103b96103e881565b3480156105ce57600080fd5b506102d76105dd366004612b4c565b611151565b3480156105ee57600080fd5b506103b960155481565b34801561060457600080fd5b506103036111af565b34801561061957600080fd5b506102d76111be565b34801561062e57600080fd5b506103b961015e81565b6102d7610646366004612a89565b6111f9565b34801561065757600080fd5b506102d76106663660046129ae565b61167d565b34801561067757600080fd5b506102d7610686366004612946565b611742565b34801561069757600080fd5b506103b96106a63660046128bc565b6001600160a01b03166000908152600b602052604090205490565b3480156106cd57600080fd5b506103b9600d5481565b3480156106e357600080fd5b506103036106f2366004612bac565b61177a565b34801561070357600080fd5b506016546102a290610100900460ff1681565b34801561072257600080fd5b506016546102a29060ff1681565b34801561073c57600080fd5b506103b961074b3660046128bc565b600b6020526000908152604090205481565b34801561076957600080fd5b50610303611813565b34801561077e57600080fd5b506102a261078d3660046128d7565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b3480156107c757600080fd5b506102d76107d63660046128bc565b611822565b3480156107e757600080fd5b506103036118ba565b60006001600160e01b0319821663780e9d6360e01b1480610815575061081582611948565b92915050565b600a546001600160a01b0316331461084e5760405162461bcd60e51b815260040161084590612db1565b60405180910390fd5b601280546001600160a01b0319166001600160a01b0392909216919091179055565b600a546001600160a01b0316331461089a5760405162461bcd60e51b815260040161084590612db1565b6016805460ff19811660ff90911615179055565b6060600080546108bd90612f20565b80601f01602080910402602001604051908101604052809291908181526020018280546108e990612f20565b80156109365780601f1061090b57610100808354040283529160200191610936565b820191906000526020600020905b81548152906001019060200180831161091957829003601f168201915b5050505050905090565b6000818152600260205260408120546001600160a01b03166109b95760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610845565b506000908152600460205260409020546001600160a01b031690565b60006109e08261101d565b9050806001600160a01b0316836001600160a01b03161415610a4e5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610845565b336001600160a01b0382161480610a6a5750610a6a813361078d565b610adc5760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610845565b610ae68383611998565b505050565b600a546001600160a01b03163314610b155760405162461bcd60e51b815260040161084590612db1565b601654610100900460ff1615610b3d5760405162461bcd60e51b815260040161084590612de6565b610ae66013838361276a565b600a546001600160a01b03163314610b735760405162461bcd60e51b815260040161084590612db1565b610b816125b161015e612e7b565b81610b8b60085490565b610b959190612e7b565b1115610bce5760405162461bcd60e51b815260206004820152600860248201526713505617d352539560c21b6044820152606401610845565b60145461015e90610be0908390612e7b565b1115610c1c5760405162461bcd60e51b815260206004820152600b60248201526a47494654535f454d50545960a81b6044820152606401610845565b60005b81811015610ae65760148054906000610c3783612f5b565b9190505550610c7a838383818110610c5157610c51612fe2565b9050602002016020810190610c6691906128bc565b6008545b610c75906001612e7b565b611a06565b80610c8481612f5b565b915050610c1f565b600a546001600160a01b03163314610cb65760405162461bcd60e51b815260040161084590612db1565b610cc46125b161015e612e7b565b81610cce60085490565b610cd89190612e7b565b1115610d115760405162461bcd60e51b815260206004820152600860248201526713505617d352539560c21b6044820152606401610845565b61015e81601454610d229190612e7b565b1115610d5e5760405162461bcd60e51b815260206004820152600b60248201526a47494654535f454d50545960a81b6044820152606401610845565b60005b81811015610ae65760148054906000610d7983612f5b565b9190505550610d8b83610c6a60085490565b80610d9581612f5b565b915050610d61565b610da73382611a24565b610dc35760405162461bcd60e51b815260040161084590612e2a565b610ae6838383611b1b565b6000610dd983611094565b8210610e3b5760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610845565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b610e726125b161015e612e7b565b81565b600a546001600160a01b03163314610e9f5760405162461bcd60e51b815260040161084590612db1565b6011546001600160a01b03166108fc610eb9600447612e93565b6040518115909202916000818181858888f19350505050158015610ee1573d6000803e3d6000fd5b5060405133904780156108fc02916000818181858888f19350505050158015610f0e573d6000803e3d6000fd5b50565b610ae683838360405180602001604052806000815250611742565b6000610f3760085490565b8210610f9a5760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610845565b60088281548110610fad57610fad612fe2565b90600052602060002001549050919050565b600a546001600160a01b03163314610fe95760405162461bcd60e51b815260040161084590612db1565b601654610100900460ff16156110115760405162461bcd60e51b815260040161084590612de6565b610ae66010838361276a565b6000818152600260205260408120546001600160a01b0316806108155760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b6064820152608401610845565b60006001600160a01b0382166110ff5760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610845565b506001600160a01b031660009081526003602052604090205490565b600a546001600160a01b031633146111455760405162461bcd60e51b815260040161084590612db1565b61114f6000611cc6565b565b600a546001600160a01b0316331461117b5760405162461bcd60e51b815260040161084590612db1565b601654610100900460ff16156111a35760405162461bcd60e51b815260040161084590612de6565b610ae6600f838361276a565b6060600180546108bd90612f20565b600a546001600160a01b031633146111e85760405162461bcd60e51b815260040161084590612db1565b6016805461ff001916610100179055565b60165460ff166112395760405162461bcd60e51b815260206004820152600b60248201526a14d0531157d0d313d4d15160aa1b6044820152606401610845565b6112438484611d18565b6112885760405162461bcd60e51b81526020600482015260166024820152751112549150d517d352539517d11254d0531313d5d15160521b6044820152606401610845565b600c826040516112989190612c4c565b9081526040519081900360200190205460ff16156112e45760405162461bcd60e51b8152602060048201526009602482015268121054d217d554d15160ba1b6044820152606401610845565b836112f0338385611d3c565b146113295760405162461bcd60e51b8152602060048201526009602482015268121054d217d190525360ba1b6044820152606401610845565b6113376125b161015e612e7b565b600854106113765760405162461bcd60e51b815260206004820152600c60248201526b4f55545f4f465f53544f434b60a01b6044820152606401610845565b6113846125b161015e612e7b565b816015546113929190612e7b565b11156113d05760405162461bcd60e51b815260206004820152600d60248201526c4558434545445f5055424c494360981b6044820152606401610845565b336000908152600b60205260409020546003906113ee908390612e7b565b111561142b5760405162461bcd60e51b815260206004820152600c60248201526b4558434545445f414c4c4f4360a01b6044820152606401610845565b600381111561146d5760405162461bcd60e51b815260206004820152600e60248201526d115610d1515117d054d7d352539560921b6044820152606401610845565b336000908152600b60205260409020546114919061148c908390612e7b565b611dbe565b6114d25760405162461bcd60e51b81526020600482015260126024820152714558434545445f4d494e545f4c494d49545360701b6044820152606401610845565b346114e48266b1a2bc2ec50000612ea7565b11156115255760405162461bcd60e51b815260206004820152601060248201526f0929ca6aa8c8c9286928a9ca8be8aa8960831b6044820152606401610845565b336000908152600b60205260409020546002101561155757600d805490600061154d83612f09565b9190505550611585565b336000908152600b60205260409020546001101561158557600e805490600061157f83612f09565b91905055505b60005b818110156115e457601580549060006115a083612f5b565b9091555050336000908152600b602052604081208054916115c083612f5b565b91905055506115d233610c6a60085490565b806115dc81612f5b565b915050611588565b50336000908152600b60205260409020546002101561161757600d805490600061160d83612f5b565b9190505550611645565b336000908152600b60205260409020546001101561164557600e805490600061163f83612f5b565b91905055505b6001600c836040516116579190612c4c565b908152604051908190036020019020805491151560ff1990921691909117905550505050565b6001600160a01b0382163314156116d65760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610845565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b61174c3383611a24565b6117685760405162461bcd60e51b815260040161084590612e2a565b61177484848484611df8565b50505050565b6000818152600260205260409020546060906001600160a01b03166117e15760405162461bcd60e51b815260206004820152601f60248201527f43616e6e6f74207175657279206e6f6e2d6578697374656e7420746f6b656e006044820152606401610845565b60106117ec83611e2b565b6040516020016117fd929190612c68565b6040516020818303038152906040529050919050565b6060600f80546108bd90612f20565b600a546001600160a01b0316331461184c5760405162461bcd60e51b815260040161084590612db1565b6001600160a01b0381166118b15760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610845565b610f0e81611cc6565b601380546118c790612f20565b80601f01602080910402602001604051908101604052809291908181526020018280546118f390612f20565b80156119405780601f1061191557610100808354040283529160200191611940565b820191906000526020600020905b81548152906001019060200180831161192357829003601f168201915b505050505081565b60006001600160e01b031982166380ac58cd60e01b148061197957506001600160e01b03198216635b5e139f60e01b145b8061081557506301ffc9a760e01b6001600160e01b0319831614610815565b600081815260046020526040902080546001600160a01b0319166001600160a01b03841690811790915581906119cd8261101d565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b611a20828260405180602001604052806000815250611f29565b5050565b6000818152600260205260408120546001600160a01b0316611a9d5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610845565b6000611aa88361101d565b9050806001600160a01b0316846001600160a01b03161480611ae35750836001600160a01b0316611ad884610940565b6001600160a01b0316145b80611b1357506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b949350505050565b826001600160a01b0316611b2e8261101d565b6001600160a01b031614611b965760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b6064820152608401610845565b6001600160a01b038216611bf85760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610845565b611c03838383611f5c565b611c0e600082611998565b6001600160a01b0383166000908152600360205260408120805460019290611c37908490612ec6565b90915550506001600160a01b0382166000908152600360205260408120805460019290611c65908490612e7b565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000611d248383612014565b6012546001600160a01b039182169116149392505050565b600080848484604051602001611d5493929190612c0d565b60408051601f198184030181529082905280516020918201207f19457468657265756d205369676e6564204d6573736167653a0a33320000000091830191909152603c820152605c0160408051808303601f19018152919052805160209091012095945050505050565b6000806002831115611dd8576103e8600d54109050610815565b6001831115611def57610960600e54109050610815565b50600192915050565b611e03848484611b1b565b611e0f84848484612038565b6117745760405162461bcd60e51b815260040161084590612d5f565b606081611e4f5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115611e795780611e6381612f5b565b9150611e729050600a83612e93565b9150611e53565b60008167ffffffffffffffff811115611e9457611e94612ff8565b6040519080825280601f01601f191660200182016040528015611ebe576020820181803683370190505b5090505b8415611b1357611ed3600183612ec6565b9150611ee0600a86612f76565b611eeb906030612e7b565b60f81b818381518110611f0057611f00612fe2565b60200101906001600160f81b031916908160001a905350611f22600a86612e93565b9450611ec2565b611f338383612145565b611f406000848484612038565b610ae65760405162461bcd60e51b815260040161084590612d5f565b6001600160a01b038316611fb757611fb281600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b611fda565b816001600160a01b0316836001600160a01b031614611fda57611fda8382612293565b6001600160a01b038216611ff157610ae681612330565b826001600160a01b0316826001600160a01b031614610ae657610ae682826123df565b60008060006120238585612423565b9150915061203081612493565b509392505050565b60006001600160a01b0384163b1561213a57604051630a85bd0160e11b81526001600160a01b0385169063150b7a029061207c903390899088908890600401612d0f565b602060405180830381600087803b15801561209657600080fd5b505af19250505080156120c6575060408051601f3d908101601f191682019092526120c391810190612b2f565b60015b612120573d8080156120f4576040519150601f19603f3d011682016040523d82523d6000602084013e6120f9565b606091505b5080516121185760405162461bcd60e51b815260040161084590612d5f565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611b13565b506001949350505050565b6001600160a01b03821661219b5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610845565b6000818152600260205260409020546001600160a01b0316156122005760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610845565b61220c60008383611f5c565b6001600160a01b0382166000908152600360205260408120805460019290612235908490612e7b565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b600060016122a084611094565b6122aa9190612ec6565b6000838152600760205260409020549091508082146122fd576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b60085460009061234290600190612ec6565b6000838152600960205260408120546008805493945090928490811061236a5761236a612fe2565b90600052602060002001549050806008838154811061238b5761238b612fe2565b60009182526020808320909101929092558281526009909152604080822084905585825281205560088054806123c3576123c3612fcc565b6001900381819060005260206000200160009055905550505050565b60006123ea83611094565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b60008082516041141561245a5760208301516040840151606085015160001a61244e8782858561264e565b9450945050505061248c565b825160401415612484576020830151604084015161247986838361273b565b93509350505061248c565b506000905060025b9250929050565b60008160048111156124a7576124a7612fb6565b14156124b05750565b60018160048111156124c4576124c4612fb6565b14156125125760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610845565b600281600481111561252657612526612fb6565b14156125745760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610845565b600381600481111561258857612588612fb6565b14156125e15760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610845565b60048160048111156125f5576125f5612fb6565b1415610f0e5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b6064820152608401610845565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156126855750600090506003612732565b8460ff16601b1415801561269d57508460ff16601c14155b156126ae5750600090506004612732565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612702573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661272b57600060019250925050612732565b9150600090505b94509492505050565b6000806001600160ff1b03831660ff84901c601b0161275c8782888561264e565b935093505050935093915050565b82805461277690612f20565b90600052602060002090601f01602090048101928261279857600085556127de565b82601f106127b15782800160ff198235161785556127de565b828001600101855582156127de579182015b828111156127de5782358255916020019190600101906127c3565b506127ea9291506127ee565b5090565b5b808211156127ea57600081556001016127ef565b600067ffffffffffffffff8084111561281e5761281e612ff8565b604051601f8501601f19908116603f0116810190828211818310171561284657612846612ff8565b8160405280935085815286868601111561285f57600080fd5b858560208301376000602087830101525050509392505050565b80356001600160a01b038116811461289057600080fd5b919050565b600082601f8301126128a657600080fd5b6128b583833560208501612803565b9392505050565b6000602082840312156128ce57600080fd5b6128b582612879565b600080604083850312156128ea57600080fd5b6128f383612879565b915061290160208401612879565b90509250929050565b60008060006060848603121561291f57600080fd5b61292884612879565b925061293660208501612879565b9150604084013590509250925092565b6000806000806080858703121561295c57600080fd5b61296585612879565b935061297360208601612879565b925060408501359150606085013567ffffffffffffffff81111561299657600080fd5b6129a287828801612895565b91505092959194509250565b600080604083850312156129c157600080fd5b6129ca83612879565b9150602083013580151581146129df57600080fd5b809150509250929050565b600080604083850312156129fd57600080fd5b612a0683612879565b946020939093013593505050565b60008060208385031215612a2757600080fd5b823567ffffffffffffffff80821115612a3f57600080fd5b818501915085601f830112612a5357600080fd5b813581811115612a6257600080fd5b8660208260051b8501011115612a7757600080fd5b60209290920196919550909350505050565b60008060008060808587031215612a9f57600080fd5b84359350602085013567ffffffffffffffff80821115612abe57600080fd5b612aca88838901612895565b94506040870135915080821115612ae057600080fd5b508501601f81018713612af257600080fd5b612b0187823560208401612803565b949793965093946060013593505050565b600060208284031215612b2457600080fd5b81356128b58161300e565b600060208284031215612b4157600080fd5b81516128b58161300e565b60008060208385031215612b5f57600080fd5b823567ffffffffffffffff80821115612b7757600080fd5b818501915085601f830112612b8b57600080fd5b813581811115612b9a57600080fd5b866020828501011115612a7757600080fd5b600060208284031215612bbe57600080fd5b5035919050565b60008151808452612bdd816020860160208601612edd565b601f01601f19169290920160200192915050565b60008151612c03818560208601612edd565b9290920192915050565b6bffffffffffffffffffffffff198460601b16815282601482015260008251612c3d816034850160208701612edd565b91909101603401949350505050565b60008251612c5e818460208701612edd565b9190910192915050565b600080845481600182811c915080831680612c8457607f831692505b6020808410821415612ca457634e487b7160e01b86526022600452602486fd5b818015612cb85760018114612cc957612cf6565b60ff19861689528489019650612cf6565b60008b81526020902060005b86811015612cee5781548b820152908501908301612cd5565b505084890196505b505050505050612d068185612bf1565b95945050505050565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090612d4290830184612bc5565b9695505050505050565b6020815260006128b56020830184612bc5565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526024908201527f436f6e7472616374206d65746164617461206d6574686f647320617265206c6f60408201526318dad95960e21b606082015260800190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b60008219821115612e8e57612e8e612f8a565b500190565b600082612ea257612ea2612fa0565b500490565b6000816000190483118215151615612ec157612ec1612f8a565b500290565b600082821015612ed857612ed8612f8a565b500390565b60005b83811015612ef8578181015183820152602001612ee0565b838111156117745750506000910152565b600081612f1857612f18612f8a565b506000190190565b600181811c90821680612f3457607f821691505b60208210811415612f5557634e487b7160e01b600052602260045260246000fd5b50919050565b6000600019821415612f6f57612f6f612f8a565b5060010190565b600082612f8557612f85612fa0565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160e01b031981168114610f0e57600080fdfea264697066735822122068167c4b63c438bd3669dbef7f38e33dfb5b0266dba909fb54417a93f7bc728464736f6c6343000807003368747470733a2f2f616e696d616c736f63696574796e66742e636f6d2f6170692f6d657461646174612f

Deployed Bytecode

0x60806040526004361061027d5760003560e01c806370a082311161014f578063a22cb465116100c1578063e081b7811161007a578063e081b78114610716578063e60ad04114610730578063e8a3d4851461075d578063e985e9c514610772578063f2fde38b146107bb578063faf924cf146107db57600080fd5b8063a22cb4651461064b578063b88d4fde1461066b578063ba2a06551461068b578063beb837f6146106c1578063c87b56dd146106d7578063cf309012146106f757600080fd5b8063938e3d7b11610113578063938e3d7b146105c2578063940f1ada146105e257806395d89b41146105f8578063989bdbb61461060d57806399483443146106225780639ec70f191461063857600080fd5b806370a0823114610543578063715018a614610563578063772064c3146105785780638da5cb5b1461058e5780638e4b752c146105ac57600080fd5b806323b872dd116101f35780634f6ccce7116101ac5780634f6ccce71461049c57806355f804b3146104bc57806360c8205d146104dc5780636352211e146104f257806363c886f51461051257806368ef67a31461052857600080fd5b806323b872dd146103fd5780632f745c591461041d578063334934191461043d5780633ccfd60b1461045257806341b613021461046757806342842e0e1461047c57600080fd5b8063095ea7b311610245578063095ea7b3146103485780631096952314610368578063163e1e611461038857806318160ddd146103a85780631b57190e146103c75780631b5757f2146103dd57600080fd5b806301ffc9a714610282578063046dc166146102b7578063049c5c49146102d957806306fdde03146102ee578063081812fc14610310575b600080fd5b34801561028e57600080fd5b506102a261029d366004612b12565b6107f0565b60405190151581526020015b60405180910390f35b3480156102c357600080fd5b506102d76102d23660046128bc565b61081b565b005b3480156102e557600080fd5b506102d7610870565b3480156102fa57600080fd5b506103036108ae565b6040516102ae9190612d4c565b34801561031c57600080fd5b5061033061032b366004612bac565b610940565b6040516001600160a01b0390911681526020016102ae565b34801561035457600080fd5b506102d76103633660046129ea565b6109d5565b34801561037457600080fd5b506102d7610383366004612b4c565b610aeb565b34801561039457600080fd5b506102d76103a3366004612a14565b610b49565b3480156103b457600080fd5b506008545b6040519081526020016102ae565b3480156103d357600080fd5b506103b960145481565b3480156103e957600080fd5b506102d76103f83660046129ea565b610c8c565b34801561040957600080fd5b506102d761041836600461290a565b610d9d565b34801561042957600080fd5b506103b96104383660046129ea565b610dce565b34801561044957600080fd5b506103b9610e64565b34801561045e57600080fd5b506102d7610e75565b34801561047357600080fd5b506103b9600381565b34801561048857600080fd5b506102d761049736600461290a565b610f11565b3480156104a857600080fd5b506103b96104b7366004612bac565b610f2c565b3480156104c857600080fd5b506102d76104d7366004612b4c565b610fbf565b3480156104e857600080fd5b506103b9600e5481565b3480156104fe57600080fd5b5061033061050d366004612bac565b61101d565b34801561051e57600080fd5b506103b96125b181565b34801561053457600080fd5b506103b966b1a2bc2ec5000081565b34801561054f57600080fd5b506103b961055e3660046128bc565b611094565b34801561056f57600080fd5b506102d761111b565b34801561058457600080fd5b506103b961096081565b34801561059a57600080fd5b50600a546001600160a01b0316610330565b3480156105b857600080fd5b506103b96103e881565b3480156105ce57600080fd5b506102d76105dd366004612b4c565b611151565b3480156105ee57600080fd5b506103b960155481565b34801561060457600080fd5b506103036111af565b34801561061957600080fd5b506102d76111be565b34801561062e57600080fd5b506103b961015e81565b6102d7610646366004612a89565b6111f9565b34801561065757600080fd5b506102d76106663660046129ae565b61167d565b34801561067757600080fd5b506102d7610686366004612946565b611742565b34801561069757600080fd5b506103b96106a63660046128bc565b6001600160a01b03166000908152600b602052604090205490565b3480156106cd57600080fd5b506103b9600d5481565b3480156106e357600080fd5b506103036106f2366004612bac565b61177a565b34801561070357600080fd5b506016546102a290610100900460ff1681565b34801561072257600080fd5b506016546102a29060ff1681565b34801561073c57600080fd5b506103b961074b3660046128bc565b600b6020526000908152604090205481565b34801561076957600080fd5b50610303611813565b34801561077e57600080fd5b506102a261078d3660046128d7565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b3480156107c757600080fd5b506102d76107d63660046128bc565b611822565b3480156107e757600080fd5b506103036118ba565b60006001600160e01b0319821663780e9d6360e01b1480610815575061081582611948565b92915050565b600a546001600160a01b0316331461084e5760405162461bcd60e51b815260040161084590612db1565b60405180910390fd5b601280546001600160a01b0319166001600160a01b0392909216919091179055565b600a546001600160a01b0316331461089a5760405162461bcd60e51b815260040161084590612db1565b6016805460ff19811660ff90911615179055565b6060600080546108bd90612f20565b80601f01602080910402602001604051908101604052809291908181526020018280546108e990612f20565b80156109365780601f1061090b57610100808354040283529160200191610936565b820191906000526020600020905b81548152906001019060200180831161091957829003601f168201915b5050505050905090565b6000818152600260205260408120546001600160a01b03166109b95760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610845565b506000908152600460205260409020546001600160a01b031690565b60006109e08261101d565b9050806001600160a01b0316836001600160a01b03161415610a4e5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610845565b336001600160a01b0382161480610a6a5750610a6a813361078d565b610adc5760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610845565b610ae68383611998565b505050565b600a546001600160a01b03163314610b155760405162461bcd60e51b815260040161084590612db1565b601654610100900460ff1615610b3d5760405162461bcd60e51b815260040161084590612de6565b610ae66013838361276a565b600a546001600160a01b03163314610b735760405162461bcd60e51b815260040161084590612db1565b610b816125b161015e612e7b565b81610b8b60085490565b610b959190612e7b565b1115610bce5760405162461bcd60e51b815260206004820152600860248201526713505617d352539560c21b6044820152606401610845565b60145461015e90610be0908390612e7b565b1115610c1c5760405162461bcd60e51b815260206004820152600b60248201526a47494654535f454d50545960a81b6044820152606401610845565b60005b81811015610ae65760148054906000610c3783612f5b565b9190505550610c7a838383818110610c5157610c51612fe2565b9050602002016020810190610c6691906128bc565b6008545b610c75906001612e7b565b611a06565b80610c8481612f5b565b915050610c1f565b600a546001600160a01b03163314610cb65760405162461bcd60e51b815260040161084590612db1565b610cc46125b161015e612e7b565b81610cce60085490565b610cd89190612e7b565b1115610d115760405162461bcd60e51b815260206004820152600860248201526713505617d352539560c21b6044820152606401610845565b61015e81601454610d229190612e7b565b1115610d5e5760405162461bcd60e51b815260206004820152600b60248201526a47494654535f454d50545960a81b6044820152606401610845565b60005b81811015610ae65760148054906000610d7983612f5b565b9190505550610d8b83610c6a60085490565b80610d9581612f5b565b915050610d61565b610da73382611a24565b610dc35760405162461bcd60e51b815260040161084590612e2a565b610ae6838383611b1b565b6000610dd983611094565b8210610e3b5760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610845565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b610e726125b161015e612e7b565b81565b600a546001600160a01b03163314610e9f5760405162461bcd60e51b815260040161084590612db1565b6011546001600160a01b03166108fc610eb9600447612e93565b6040518115909202916000818181858888f19350505050158015610ee1573d6000803e3d6000fd5b5060405133904780156108fc02916000818181858888f19350505050158015610f0e573d6000803e3d6000fd5b50565b610ae683838360405180602001604052806000815250611742565b6000610f3760085490565b8210610f9a5760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610845565b60088281548110610fad57610fad612fe2565b90600052602060002001549050919050565b600a546001600160a01b03163314610fe95760405162461bcd60e51b815260040161084590612db1565b601654610100900460ff16156110115760405162461bcd60e51b815260040161084590612de6565b610ae66010838361276a565b6000818152600260205260408120546001600160a01b0316806108155760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b6064820152608401610845565b60006001600160a01b0382166110ff5760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610845565b506001600160a01b031660009081526003602052604090205490565b600a546001600160a01b031633146111455760405162461bcd60e51b815260040161084590612db1565b61114f6000611cc6565b565b600a546001600160a01b0316331461117b5760405162461bcd60e51b815260040161084590612db1565b601654610100900460ff16156111a35760405162461bcd60e51b815260040161084590612de6565b610ae6600f838361276a565b6060600180546108bd90612f20565b600a546001600160a01b031633146111e85760405162461bcd60e51b815260040161084590612db1565b6016805461ff001916610100179055565b60165460ff166112395760405162461bcd60e51b815260206004820152600b60248201526a14d0531157d0d313d4d15160aa1b6044820152606401610845565b6112438484611d18565b6112885760405162461bcd60e51b81526020600482015260166024820152751112549150d517d352539517d11254d0531313d5d15160521b6044820152606401610845565b600c826040516112989190612c4c565b9081526040519081900360200190205460ff16156112e45760405162461bcd60e51b8152602060048201526009602482015268121054d217d554d15160ba1b6044820152606401610845565b836112f0338385611d3c565b146113295760405162461bcd60e51b8152602060048201526009602482015268121054d217d190525360ba1b6044820152606401610845565b6113376125b161015e612e7b565b600854106113765760405162461bcd60e51b815260206004820152600c60248201526b4f55545f4f465f53544f434b60a01b6044820152606401610845565b6113846125b161015e612e7b565b816015546113929190612e7b565b11156113d05760405162461bcd60e51b815260206004820152600d60248201526c4558434545445f5055424c494360981b6044820152606401610845565b336000908152600b60205260409020546003906113ee908390612e7b565b111561142b5760405162461bcd60e51b815260206004820152600c60248201526b4558434545445f414c4c4f4360a01b6044820152606401610845565b600381111561146d5760405162461bcd60e51b815260206004820152600e60248201526d115610d1515117d054d7d352539560921b6044820152606401610845565b336000908152600b60205260409020546114919061148c908390612e7b565b611dbe565b6114d25760405162461bcd60e51b81526020600482015260126024820152714558434545445f4d494e545f4c494d49545360701b6044820152606401610845565b346114e48266b1a2bc2ec50000612ea7565b11156115255760405162461bcd60e51b815260206004820152601060248201526f0929ca6aa8c8c9286928a9ca8be8aa8960831b6044820152606401610845565b336000908152600b60205260409020546002101561155757600d805490600061154d83612f09565b9190505550611585565b336000908152600b60205260409020546001101561158557600e805490600061157f83612f09565b91905055505b60005b818110156115e457601580549060006115a083612f5b565b9091555050336000908152600b602052604081208054916115c083612f5b565b91905055506115d233610c6a60085490565b806115dc81612f5b565b915050611588565b50336000908152600b60205260409020546002101561161757600d805490600061160d83612f5b565b9190505550611645565b336000908152600b60205260409020546001101561164557600e805490600061163f83612f5b565b91905055505b6001600c836040516116579190612c4c565b908152604051908190036020019020805491151560ff1990921691909117905550505050565b6001600160a01b0382163314156116d65760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610845565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b61174c3383611a24565b6117685760405162461bcd60e51b815260040161084590612e2a565b61177484848484611df8565b50505050565b6000818152600260205260409020546060906001600160a01b03166117e15760405162461bcd60e51b815260206004820152601f60248201527f43616e6e6f74207175657279206e6f6e2d6578697374656e7420746f6b656e006044820152606401610845565b60106117ec83611e2b565b6040516020016117fd929190612c68565b6040516020818303038152906040529050919050565b6060600f80546108bd90612f20565b600a546001600160a01b0316331461184c5760405162461bcd60e51b815260040161084590612db1565b6001600160a01b0381166118b15760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610845565b610f0e81611cc6565b601380546118c790612f20565b80601f01602080910402602001604051908101604052809291908181526020018280546118f390612f20565b80156119405780601f1061191557610100808354040283529160200191611940565b820191906000526020600020905b81548152906001019060200180831161192357829003601f168201915b505050505081565b60006001600160e01b031982166380ac58cd60e01b148061197957506001600160e01b03198216635b5e139f60e01b145b8061081557506301ffc9a760e01b6001600160e01b0319831614610815565b600081815260046020526040902080546001600160a01b0319166001600160a01b03841690811790915581906119cd8261101d565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b611a20828260405180602001604052806000815250611f29565b5050565b6000818152600260205260408120546001600160a01b0316611a9d5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610845565b6000611aa88361101d565b9050806001600160a01b0316846001600160a01b03161480611ae35750836001600160a01b0316611ad884610940565b6001600160a01b0316145b80611b1357506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b949350505050565b826001600160a01b0316611b2e8261101d565b6001600160a01b031614611b965760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b6064820152608401610845565b6001600160a01b038216611bf85760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610845565b611c03838383611f5c565b611c0e600082611998565b6001600160a01b0383166000908152600360205260408120805460019290611c37908490612ec6565b90915550506001600160a01b0382166000908152600360205260408120805460019290611c65908490612e7b565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000611d248383612014565b6012546001600160a01b039182169116149392505050565b600080848484604051602001611d5493929190612c0d565b60408051601f198184030181529082905280516020918201207f19457468657265756d205369676e6564204d6573736167653a0a33320000000091830191909152603c820152605c0160408051808303601f19018152919052805160209091012095945050505050565b6000806002831115611dd8576103e8600d54109050610815565b6001831115611def57610960600e54109050610815565b50600192915050565b611e03848484611b1b565b611e0f84848484612038565b6117745760405162461bcd60e51b815260040161084590612d5f565b606081611e4f5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115611e795780611e6381612f5b565b9150611e729050600a83612e93565b9150611e53565b60008167ffffffffffffffff811115611e9457611e94612ff8565b6040519080825280601f01601f191660200182016040528015611ebe576020820181803683370190505b5090505b8415611b1357611ed3600183612ec6565b9150611ee0600a86612f76565b611eeb906030612e7b565b60f81b818381518110611f0057611f00612fe2565b60200101906001600160f81b031916908160001a905350611f22600a86612e93565b9450611ec2565b611f338383612145565b611f406000848484612038565b610ae65760405162461bcd60e51b815260040161084590612d5f565b6001600160a01b038316611fb757611fb281600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b611fda565b816001600160a01b0316836001600160a01b031614611fda57611fda8382612293565b6001600160a01b038216611ff157610ae681612330565b826001600160a01b0316826001600160a01b031614610ae657610ae682826123df565b60008060006120238585612423565b9150915061203081612493565b509392505050565b60006001600160a01b0384163b1561213a57604051630a85bd0160e11b81526001600160a01b0385169063150b7a029061207c903390899088908890600401612d0f565b602060405180830381600087803b15801561209657600080fd5b505af19250505080156120c6575060408051601f3d908101601f191682019092526120c391810190612b2f565b60015b612120573d8080156120f4576040519150601f19603f3d011682016040523d82523d6000602084013e6120f9565b606091505b5080516121185760405162461bcd60e51b815260040161084590612d5f565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611b13565b506001949350505050565b6001600160a01b03821661219b5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610845565b6000818152600260205260409020546001600160a01b0316156122005760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610845565b61220c60008383611f5c565b6001600160a01b0382166000908152600360205260408120805460019290612235908490612e7b565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b600060016122a084611094565b6122aa9190612ec6565b6000838152600760205260409020549091508082146122fd576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b60085460009061234290600190612ec6565b6000838152600960205260408120546008805493945090928490811061236a5761236a612fe2565b90600052602060002001549050806008838154811061238b5761238b612fe2565b60009182526020808320909101929092558281526009909152604080822084905585825281205560088054806123c3576123c3612fcc565b6001900381819060005260206000200160009055905550505050565b60006123ea83611094565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b60008082516041141561245a5760208301516040840151606085015160001a61244e8782858561264e565b9450945050505061248c565b825160401415612484576020830151604084015161247986838361273b565b93509350505061248c565b506000905060025b9250929050565b60008160048111156124a7576124a7612fb6565b14156124b05750565b60018160048111156124c4576124c4612fb6565b14156125125760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610845565b600281600481111561252657612526612fb6565b14156125745760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610845565b600381600481111561258857612588612fb6565b14156125e15760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610845565b60048160048111156125f5576125f5612fb6565b1415610f0e5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b6064820152608401610845565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156126855750600090506003612732565b8460ff16601b1415801561269d57508460ff16601c14155b156126ae5750600090506004612732565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612702573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661272b57600060019250925050612732565b9150600090505b94509492505050565b6000806001600160ff1b03831660ff84901c601b0161275c8782888561264e565b935093505050935093915050565b82805461277690612f20565b90600052602060002090601f01602090048101928261279857600085556127de565b82601f106127b15782800160ff198235161785556127de565b828001600101855582156127de579182015b828111156127de5782358255916020019190600101906127c3565b506127ea9291506127ee565b5090565b5b808211156127ea57600081556001016127ef565b600067ffffffffffffffff8084111561281e5761281e612ff8565b604051601f8501601f19908116603f0116810190828211818310171561284657612846612ff8565b8160405280935085815286868601111561285f57600080fd5b858560208301376000602087830101525050509392505050565b80356001600160a01b038116811461289057600080fd5b919050565b600082601f8301126128a657600080fd5b6128b583833560208501612803565b9392505050565b6000602082840312156128ce57600080fd5b6128b582612879565b600080604083850312156128ea57600080fd5b6128f383612879565b915061290160208401612879565b90509250929050565b60008060006060848603121561291f57600080fd5b61292884612879565b925061293660208501612879565b9150604084013590509250925092565b6000806000806080858703121561295c57600080fd5b61296585612879565b935061297360208601612879565b925060408501359150606085013567ffffffffffffffff81111561299657600080fd5b6129a287828801612895565b91505092959194509250565b600080604083850312156129c157600080fd5b6129ca83612879565b9150602083013580151581146129df57600080fd5b809150509250929050565b600080604083850312156129fd57600080fd5b612a0683612879565b946020939093013593505050565b60008060208385031215612a2757600080fd5b823567ffffffffffffffff80821115612a3f57600080fd5b818501915085601f830112612a5357600080fd5b813581811115612a6257600080fd5b8660208260051b8501011115612a7757600080fd5b60209290920196919550909350505050565b60008060008060808587031215612a9f57600080fd5b84359350602085013567ffffffffffffffff80821115612abe57600080fd5b612aca88838901612895565b94506040870135915080821115612ae057600080fd5b508501601f81018713612af257600080fd5b612b0187823560208401612803565b949793965093946060013593505050565b600060208284031215612b2457600080fd5b81356128b58161300e565b600060208284031215612b4157600080fd5b81516128b58161300e565b60008060208385031215612b5f57600080fd5b823567ffffffffffffffff80821115612b7757600080fd5b818501915085601f830112612b8b57600080fd5b813581811115612b9a57600080fd5b866020828501011115612a7757600080fd5b600060208284031215612bbe57600080fd5b5035919050565b60008151808452612bdd816020860160208601612edd565b601f01601f19169290920160200192915050565b60008151612c03818560208601612edd565b9290920192915050565b6bffffffffffffffffffffffff198460601b16815282601482015260008251612c3d816034850160208701612edd565b91909101603401949350505050565b60008251612c5e818460208701612edd565b9190910192915050565b600080845481600182811c915080831680612c8457607f831692505b6020808410821415612ca457634e487b7160e01b86526022600452602486fd5b818015612cb85760018114612cc957612cf6565b60ff19861689528489019650612cf6565b60008b81526020902060005b86811015612cee5781548b820152908501908301612cd5565b505084890196505b505050505050612d068185612bf1565b95945050505050565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090612d4290830184612bc5565b9695505050505050565b6020815260006128b56020830184612bc5565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526024908201527f436f6e7472616374206d65746164617461206d6574686f647320617265206c6f60408201526318dad95960e21b606082015260800190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b60008219821115612e8e57612e8e612f8a565b500190565b600082612ea257612ea2612fa0565b500490565b6000816000190483118215151615612ec157612ec1612f8a565b500290565b600082821015612ed857612ed8612f8a565b500390565b60005b83811015612ef8578181015183820152602001612ee0565b838111156117745750506000910152565b600081612f1857612f18612f8a565b506000190190565b600181811c90821680612f3457607f821691505b60208210811415612f5557634e487b7160e01b600052602260045260246000fd5b50919050565b6000600019821415612f6f57612f6f612f8a565b5060010190565b600082612f8557612f85612fa0565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160e01b031981168114610f0e57600080fdfea264697066735822122068167c4b63c438bd3669dbef7f38e33dfb5b0266dba909fb54417a93f7bc728464736f6c63430008070033

Deployed Bytecode Sourcemap

52234:5758:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46006:224;;;;;;;;;;-1:-1:-1;46006:224:0;;;;;:::i;:::-;;:::i;:::-;;;9342:14:1;;9335:22;9317:41;;9305:2;9290:18;46006:224:0;;;;;;;;57161:99;;;;;;;;;;-1:-1:-1;57161:99:0;;;;;:::i;:::-;;:::i;:::-;;57063:86;;;;;;;;;;;;;:::i;33898:100::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;35457:221::-;;;;;;;;;;-1:-1:-1;35457:221:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;8640:32:1;;;8622:51;;8610:2;8595:18;35457:221:0;8476:203:1;34980:411:0;;;;;;;;;;-1:-1:-1;34980:411:0;;;;;:::i;:::-;;:::i;57272:109::-;;;;;;;;;;-1:-1:-1;57272:109:0;;;;;:::i;:::-;;:::i;55775:387::-;;;;;;;;;;-1:-1:-1;55775:387:0;;;;;:::i;:::-;;:::i;46646:113::-;;;;;;;;;;-1:-1:-1;46734:10:0;:17;46646:113;;;23317:25:1;;;23305:2;23290:18;46646:113:0;23171:177:1;53160:27:0;;;;;;;;;;;;;;;;56181:368;;;;;;;;;;-1:-1:-1;56181:368:0;;;;;:::i;:::-;;:::i;36347:339::-;;;;;;;;;;-1:-1:-1;36347:339:0;;;;;:::i;:::-;;:::i;46314:256::-;;;;;;;;;;-1:-1:-1;46314:256:0;;;;;:::i;:::-;;:::i;52446:50::-;;;;;;;;;;;;;:::i;56567:176::-;;;;;;;;;;;;;:::i;52555:35::-;;;;;;;;;;;;52589:1;52555:35;;36757:185;;;;;;;;;;-1:-1:-1;36757:185:0;;;;;:::i;:::-;;:::i;46836:233::-;;;;;;;;;;-1:-1:-1;46836:233:0;;;;;:::i;:::-;;:::i;57516:108::-;;;;;;;;;;-1:-1:-1;57516:108:0;;;;;:::i;:::-;;:::i;52821:20::-;;;;;;;;;;;;;;;;33592:239;;;;;;;;;;-1:-1:-1;33592:239:0;;;;;:::i;:::-;;:::i;52401:38::-;;;;;;;;;;;;52435:4;52401:38;;52503:45;;;;;;;;;;;;52538:10;52503:45;;33322:208;;;;;;;;;;-1:-1:-1;33322:208:0;;;;;:::i;:::-;;:::i;13597:94::-;;;;;;;;;;;;;:::i;52640:36::-;;;;;;;;;;;;52672:4;52640:36;;12946:87;;;;;;;;;;-1:-1:-1;13019:6:0;;-1:-1:-1;;;;;13019:6:0;12946:87;;52597:36;;;;;;;;;;;;52629:4;52597:36;;57393:111;;;;;;;;;;-1:-1:-1;57393:111:0;;;;;:::i;:::-;;:::i;53194:33::-;;;;;;;;;;;;;;;;34067:104;;;;;;;;;;;;;:::i;56976:75::-;;;;;;;;;;;;;:::i;52357:37::-;;;;;;;;;;;;52391:3;52357:37;;54341:1420;;;;;;:::i;:::-;;:::i;35750:295::-;;;;;;;;;;-1:-1:-1;35750:295:0;;;;;:::i;:::-;;:::i;37013:328::-;;;;;;;;;;-1:-1:-1;37013:328:0;;;;;:::i;:::-;;:::i;56755:115::-;;;;;;;;;;-1:-1:-1;56755:115:0;;;;;:::i;:::-;-1:-1:-1;;;;;56843:19:0;56816:7;56843:19;;;:13;:19;;;;;;;56755:115;52794:20;;;;;;;;;;;;;;;;57745:244;;;;;;;;;;-1:-1:-1;57745:244:0;;;;;:::i;:::-;;:::i;53261:18::-;;;;;;;;;;-1:-1:-1;53261:18:0;;;;;;;;;;;53234:20;;;;;;;;;;-1:-1:-1;53234:20:0;;;;;;;;52689:48;;;;;;;;;;-1:-1:-1;52689:48:0;;;;;:::i;:::-;;;;;;;;;;;;;;57636:97;;;;;;;;;;;;;:::i;36116:164::-;;;;;;;;;;-1:-1:-1;36116:164:0;;;;;:::i;:::-;-1:-1:-1;;;;;36237:25:0;;;36213:4;36237:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;36116:164;13846:192;;;;;;;;;;-1:-1:-1;13846:192:0;;;;;:::i;:::-;;:::i;53134:19::-;;;;;;;;;;;;;:::i;46006:224::-;46108:4;-1:-1:-1;;;;;;46132:50:0;;-1:-1:-1;;;46132:50:0;;:90;;;46186:36;46210:11;46186:23;:36::i;:::-;46125:97;46006:224;-1:-1:-1;;46006:224:0:o;57161:99::-;13019:6;;-1:-1:-1;;;;;13019:6:0;11814:10;13166:23;13158:68;;;;-1:-1:-1;;;13158:68:0;;;;;;;:::i;:::-;;;;;;;;;57231:14:::1;:21:::0;;-1:-1:-1;;;;;;57231:21:0::1;-1:-1:-1::0;;;;;57231:21:0;;;::::1;::::0;;;::::1;::::0;;57161:99::o;57063:86::-;13019:6;;-1:-1:-1;;;;;13019:6:0;11814:10;13166:23;13158:68;;;;-1:-1:-1;;;13158:68:0;;;;;;;:::i;:::-;57133:8:::1;::::0;;-1:-1:-1;;57121:20:0;::::1;57133:8;::::0;;::::1;57132:9;57121:20;::::0;;57063:86::o;33898:100::-;33952:13;33985:5;33978:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;33898:100;:::o;35457:221::-;35533:7;38940:16;;;:7;:16;;;;;;-1:-1:-1;;;;;38940:16:0;35553:73;;;;-1:-1:-1;;;35553:73:0;;18139:2:1;35553:73:0;;;18121:21:1;18178:2;18158:18;;;18151:30;18217:34;18197:18;;;18190:62;-1:-1:-1;;;18268:18:1;;;18261:42;18320:19;;35553:73:0;17937:408:1;35553:73:0;-1:-1:-1;35646:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;35646:24:0;;35457:221::o;34980:411::-;35061:13;35077:23;35092:7;35077:14;:23::i;:::-;35061:39;;35125:5;-1:-1:-1;;;;;35119:11:0;:2;-1:-1:-1;;;;;35119:11:0;;;35111:57;;;;-1:-1:-1;;;35111:57:0;;20428:2:1;35111:57:0;;;20410:21:1;20467:2;20447:18;;;20440:30;20506:34;20486:18;;;20479:62;-1:-1:-1;;;20557:18:1;;;20550:31;20598:19;;35111:57:0;20226:397:1;35111:57:0;11814:10;-1:-1:-1;;;;;35203:21:0;;;;:62;;-1:-1:-1;35228:37:0;35245:5;11814:10;36116:164;:::i;35228:37::-;35181:168;;;;-1:-1:-1;;;35181:168:0;;15793:2:1;35181:168:0;;;15775:21:1;15832:2;15812:18;;;15805:30;15871:34;15851:18;;;15844:62;15942:26;15922:18;;;15915:54;15986:19;;35181:168:0;15591:420:1;35181:168:0;35362:21;35371:2;35375:7;35362:8;:21::i;:::-;35050:341;34980:411;;:::o;57272:109::-;13019:6;;-1:-1:-1;;;;;13019:6:0;11814:10;13166:23;13158:68;;;;-1:-1:-1;;;13158:68:0;;;;;;;:::i;:::-;53391:6:::1;::::0;::::1;::::0;::::1;;;53390:7;53382:56;;;;-1:-1:-1::0;;;53382:56:0::1;;;;;;;:::i;:::-;57361:12:::2;:5;57369:4:::0;;57361:12:::2;:::i;55775:387::-:0;13019:6;;-1:-1:-1;;;;;13019:6:0;11814:10;13166:23;13158:68;;;;-1:-1:-1;;;13158:68:0;;;;;;;:::i;:::-;52479:17:::1;52435:4;52391:3;52479:17;:::i;:::-;55873:9:::0;55857:13:::1;46734:10:::0;:17;;46646:113;55857:13:::1;:32;;;;:::i;:::-;:42;;55849:63;;;::::0;-1:-1:-1;;;55849:63:0;;17442:2:1;55849:63:0::1;::::0;::::1;17424:21:1::0;17481:1;17461:18;;;17454:29;-1:-1:-1;;;17499:18:1;;;17492:38;17547:18;;55849:63:0::1;17240:331:1::0;55849:63:0::1;55931:12;::::0;52391:3:::1;::::0;55931:31:::1;::::0;55946:9;;55931:31:::1;:::i;:::-;:42;;55923:66;;;::::0;-1:-1:-1;;;55923:66:0;;18913:2:1;55923:66:0::1;::::0;::::1;18895:21:1::0;18952:2;18932:18;;;18925:30;-1:-1:-1;;;18971:18:1;;;18964:41;19022:18;;55923:66:0::1;18711:335:1::0;55923:66:0::1;56015:9;56010:145;56030:20:::0;;::::1;56010:145;;;56072:12;:14:::0;;;:12:::1;:14;::::0;::::1;:::i;:::-;;;;;;56101:42;56111:9;;56121:1;56111:12;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;46734:10:::0;:17;56125:13:::1;:17;::::0;56141:1:::1;56125:17;:::i;:::-;56101:9;:42::i;:::-;56052:3:::0;::::1;::::0;::::1;:::i;:::-;;;;56010:145;;56181:368:::0;13019:6;;-1:-1:-1;;;;;13019:6:0;11814:10;13166:23;13158:68;;;;-1:-1:-1;;;13158:68:0;;;;;;;:::i;:::-;52479:17:::1;52435:4;52391:3;52479:17;:::i;:::-;56293:6;56277:13;46734:10:::0;:17;;46646:113;56277:13:::1;:22;;;;:::i;:::-;:32;;56269:53;;;::::0;-1:-1:-1;;;56269:53:0;;17442:2:1;56269:53:0::1;::::0;::::1;17424:21:1::0;17481:1;17461:18;;;17454:29;-1:-1:-1;;;17499:18:1;;;17492:38;17547:18;;56269:53:0::1;17240:331:1::0;56269:53:0::1;52391:3;56356:6;56341:12;;:21;;;;:::i;:::-;:32;;56333:56;;;::::0;-1:-1:-1;;;56333:56:0;;18913:2:1;56333:56:0::1;::::0;::::1;18895:21:1::0;18952:2;18932:18;;;18925:30;-1:-1:-1;;;18971:18:1;;;18964:41;19022:18;;56333:56:0::1;18711:335:1::0;56333:56:0::1;56415:9;56410:132;56434:6;56430:1;:10;56410:132;;;56462:12;:14:::0;;;:12:::1;:14;::::0;::::1;:::i;:::-;;;;;;56491:39;56501:9;56512:13;46734:10:::0;:17;;46646:113;56491:39:::1;56442:3:::0;::::1;::::0;::::1;:::i;:::-;;;;56410:132;;36347:339:::0;36542:41;11814:10;36575:7;36542:18;:41::i;:::-;36534:103;;;;-1:-1:-1;;;36534:103:0;;;;;;;:::i;:::-;36650:28;36660:4;36666:2;36670:7;36650:9;:28::i;46314:256::-;46411:7;46447:23;46464:5;46447:16;:23::i;:::-;46439:5;:31;46431:87;;;;-1:-1:-1;;;46431:87:0;;11262:2:1;46431:87:0;;;11244:21:1;11301:2;11281:18;;;11274:30;11340:34;11320:18;;;11313:62;-1:-1:-1;;;11391:18:1;;;11384:41;11442:19;;46431:87:0;11060:407:1;46431:87:0;-1:-1:-1;;;;;;46536:19:0;;;;;;;;:12;:19;;;;;;;;:26;;;;;;;;;46314:256::o;52446:50::-;52479:17;52435:4;52391:3;52479:17;:::i;:::-;52446:50;:::o;56567:176::-;13019:6;;-1:-1:-1;;;;;13019:6:0;11814:10;13166:23;13158:68;;;;-1:-1:-1;;;13158:68:0;;;;;;;:::i;:::-;56625:11:::1;::::0;-1:-1:-1;;;;;56625:11:0::1;56617:56;56647:25;56671:1;56647:21;:25;:::i;:::-;56617:56;::::0;;::::1;::::0;;::::1;::::0;::::1;::::0;;;;;;::::1;;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;56684:51:0::1;::::0;56692:10:::1;::::0;56713:21:::1;56684:51:::0;::::1;;;::::0;::::1;::::0;;;56713:21;56692:10;56684:51;::::1;;;;;;;;;;;;;::::0;::::1;;;;;;56567:176::o:0;36757:185::-;36895:39;36912:4;36918:2;36922:7;36895:39;;;;;;;;;;;;:16;:39::i;46836:233::-;46911:7;46947:30;46734:10;:17;;46646:113;46947:30;46939:5;:38;46931:95;;;;-1:-1:-1;;;46931:95:0;;21927:2:1;46931:95:0;;;21909:21:1;21966:2;21946:18;;;21939:30;22005:34;21985:18;;;21978:62;-1:-1:-1;;;22056:18:1;;;22049:42;22108:19;;46931:95:0;21725:408:1;46931:95:0;47044:10;47055:5;47044:17;;;;;;;;:::i;:::-;;;;;;;;;47037:24;;46836:233;;;:::o;57516:108::-;13019:6;;-1:-1:-1;;;;;13019:6:0;11814:10;13166:23;13158:68;;;;-1:-1:-1;;;13158:68:0;;;;;;;:::i;:::-;53391:6:::1;::::0;::::1;::::0;::::1;;;53390:7;53382:56;;;;-1:-1:-1::0;;;53382:56:0::1;;;;;;;:::i;:::-;57597:19:::2;:13;57613:3:::0;;57597:19:::2;:::i;33592:239::-:0;33664:7;33700:16;;;:7;:16;;;;;;-1:-1:-1;;;;;33700:16:0;33735:19;33727:73;;;;-1:-1:-1;;;33727:73:0;;16629:2:1;33727:73:0;;;16611:21:1;16668:2;16648:18;;;16641:30;16707:34;16687:18;;;16680:62;-1:-1:-1;;;16758:18:1;;;16751:39;16807:19;;33727:73:0;16427:405:1;33322:208:0;33394:7;-1:-1:-1;;;;;33422:19:0;;33414:74;;;;-1:-1:-1;;;33414:74:0;;16218:2:1;33414:74:0;;;16200:21:1;16257:2;16237:18;;;16230:30;16296:34;16276:18;;;16269:62;-1:-1:-1;;;16347:18:1;;;16340:40;16397:19;;33414:74:0;16016:406:1;33414:74:0;-1:-1:-1;;;;;;33506:16:0;;;;;:9;:16;;;;;;;33322:208::o;13597:94::-;13019:6;;-1:-1:-1;;;;;13019:6:0;11814:10;13166:23;13158:68;;;;-1:-1:-1;;;13158:68:0;;;;;;;:::i;:::-;13662:21:::1;13680:1;13662:9;:21::i;:::-;13597:94::o:0;57393:111::-;13019:6;;-1:-1:-1;;;;;13019:6:0;11814:10;13166:23;13158:68;;;;-1:-1:-1;;;13158:68:0;;;;;;;:::i;:::-;53391:6:::1;::::0;::::1;::::0;::::1;;;53390:7;53382:56;;;;-1:-1:-1::0;;;53382:56:0::1;;;;;;;:::i;:::-;57478:18:::2;:12;57493:3:::0;;57478:18:::2;:::i;34067:104::-:0;34123:13;34156:7;34149:14;;;;;:::i;56976:75::-;13019:6;;-1:-1:-1;;;;;13019:6:0;11814:10;13166:23;13158:68;;;;-1:-1:-1;;;13158:68:0;;;;;;;:::i;:::-;57030:6:::1;:13:::0;;-1:-1:-1;;57030:13:0::1;;;::::0;;56976:75::o;54341:1420::-;54472:8;;;;54464:32;;;;-1:-1:-1;;;54464:32:0;;14360:2:1;54464:32:0;;;14342:21:1;14399:2;14379:18;;;14372:30;-1:-1:-1;;;14418:18:1;;;14411:41;14469:18;;54464:32:0;14158:335:1;54464:32:0;54515:34;54533:4;54539:9;54515:17;:34::i;:::-;54507:69;;;;-1:-1:-1;;;54507:69:0;;10551:2:1;54507:69:0;;;10533:21:1;10590:2;10570:18;;;10563:30;-1:-1:-1;;;10609:18:1;;;10602:52;10671:18;;54507:69:0;10349:346:1;54507:69:0;54596:11;54608:5;54596:18;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;54595:19;54587:41;;;;-1:-1:-1;;;54587:41:0;;21172:2:1;54587:41:0;;;21154:21:1;21211:1;21191:18;;;21184:29;-1:-1:-1;;;21229:18:1;;;21222:39;21278:18;;54587:41:0;20970:332:1;54587:41:0;54700:4;54647:49;54663:10;54675:13;54690:5;54647:15;:49::i;:::-;:57;54639:79;;;;-1:-1:-1;;;54639:79:0;;15456:2:1;54639:79:0;;;15438:21:1;15495:1;15475:18;;;15468:29;-1:-1:-1;;;15513:18:1;;;15506:39;15562:18;;54639:79:0;15254:332:1;54639:79:0;52479:17;52435:4;52391:3;52479:17;:::i;:::-;46734:10;:17;54737:22;54729:47;;;;-1:-1:-1;;;54729:47:0;;13616:2:1;54729:47:0;;;13598:21:1;13655:2;13635:18;;;13628:30;-1:-1:-1;;;13674:18:1;;;13667:42;13726:18;;54729:47:0;13414:336:1;54729:47:0;52479:17;52435:4;52391:3;52479:17;:::i;:::-;54816:13;54795:18;;:34;;;;:::i;:::-;:44;;54787:70;;;;-1:-1:-1;;;54787:70:0;;20830:2:1;54787:70:0;;;20812:21:1;20869:2;20849:18;;;20842:30;-1:-1:-1;;;20888:18:1;;;20881:43;20941:18;;54787:70:0;20628:337:1;54787:70:0;54890:10;54876:25;;;;:13;:25;;;;;;52589:1;;54876:41;;54904:13;;54876:41;:::i;:::-;:52;;54868:77;;;;-1:-1:-1;;;54868:77:0;;22340:2:1;54868:77:0;;;22322:21:1;22379:2;22359:18;;;22352:30;-1:-1:-1;;;22398:18:1;;;22391:42;22450:18;;54868:77:0;22138:336:1;54868:77:0;52589:1;54964:13;:24;;54956:51;;;;-1:-1:-1;;;54956:51:0;;15113:2:1;54956:51:0;;;15095:21:1;15152:2;15132:18;;;15125:30;-1:-1:-1;;;15171:18:1;;;15164:44;15225:18;;54956:51:0;14911:338:1;54956:51:0;55054:10;55040:25;;;;:13;:25;;;;;;55026:56;;55040:41;;55068:13;;55040:41;:::i;:::-;55026:13;:56::i;:::-;55018:87;;;;-1:-1:-1;;;55018:87:0;;23026:2:1;55018:87:0;;;23008:21:1;23065:2;23045:18;;;23038:30;-1:-1:-1;;;23084:18:1;;;23077:48;23142:18;;55018:87:0;22824:342:1;55018:87:0;55152:9;55124:24;55135:13;52538:10;55124:24;:::i;:::-;:37;;55116:66;;;;-1:-1:-1;;;55116:66:0;;22681:2:1;55116:66:0;;;22663:21:1;22720:2;22700:18;;;22693:30;-1:-1:-1;;;22739:18:1;;;22732:46;22795:18;;55116:66:0;22479:340:1;55116:66:0;55219:10;55205:25;;;;:13;:25;;;;;;55233:1;-1:-1:-1;55202:139:0;;;55250:5;:7;;;:5;:7;;;:::i;:::-;;;;;;55202:139;;;55291:10;55277:25;;;;:13;:25;;;;;;55305:1;-1:-1:-1;55274:67:0;;;55322:5;:7;;;:5;:7;;;:::i;:::-;;;;;;55274:67;55365:9;55361:188;55384:13;55380:1;:17;55361:188;;;55419:18;:20;;;:18;:20;;;:::i;:::-;;;;-1:-1:-1;;55469:10:0;55455:25;;;;:13;:25;;;;;:27;;;;;;:::i;:::-;;;;;;55497:40;55507:10;55519:13;46734:10;:17;;46646:113;55497:40;55399:3;;;;:::i;:::-;;;;55361:188;;;-1:-1:-1;55586:10:0;55572:25;;;;:13;:25;;;;;;55600:1;-1:-1:-1;55569:139:0;;;55617:5;:7;;;:5;:7;;;:::i;:::-;;;;;;55569:139;;;55658:10;55644:25;;;;:13;:25;;;;;;55672:1;-1:-1:-1;55641:67:0;;;55689:5;:7;;;:5;:7;;;:::i;:::-;;;;;;55641:67;55749:4;55728:11;55740:5;55728:18;;;;;;:::i;:::-;;;;;;;;;;;;;;:25;;;;;-1:-1:-1;;55728:25:0;;;;;;;;;-1:-1:-1;;;;54341:1420:0:o;35750:295::-;-1:-1:-1;;;;;35853:24:0;;11814:10;35853:24;;35845:62;;;;-1:-1:-1;;;35845:62:0;;13262:2:1;35845:62:0;;;13244:21:1;13301:2;13281:18;;;13274:30;13340:27;13320:18;;;13313:55;13385:18;;35845:62:0;13060:349:1;35845:62:0;11814:10;35920:32;;;;:18;:32;;;;;;;;-1:-1:-1;;;;;35920:42:0;;;;;;;;;;;;:53;;-1:-1:-1;;35920:53:0;;;;;;;;;;35989:48;;9317:41:1;;;35920:42:0;;11814:10;35989:48;;9290:18:1;35989:48:0;;;;;;;35750:295;;:::o;37013:328::-;37188:41;11814:10;37221:7;37188:18;:41::i;:::-;37180:103;;;;-1:-1:-1;;;37180:103:0;;;;;;;:::i;:::-;37294:39;37308:4;37314:2;37318:7;37327:5;37294:13;:39::i;:::-;37013:328;;;;:::o;57745:244::-;38916:4;38940:16;;;:7;:16;;;;;;57818:13;;-1:-1:-1;;;;;38940:16:0;57844:60;;;;-1:-1:-1;;;57844:60:0;;20068:2:1;57844:60:0;;;20050:21:1;20107:2;20087:18;;;20080:30;20146:33;20126:18;;;20119:61;20197:18;;57844:60:0;19866:355:1;57844:60:0;57946:13;57961:18;:7;:16;:18::i;:::-;57929:51;;;;;;;;;:::i;:::-;;;;;;;;;;;;;57915:66;;57745:244;;;:::o;57636:97::-;57680:13;57713:12;57706:19;;;;;:::i;13846:192::-;13019:6;;-1:-1:-1;;;;;13019:6:0;11814:10;13166:23;13158:68;;;;-1:-1:-1;;;13158:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;13935:22:0;::::1;13927:73;;;::::0;-1:-1:-1;;;13927:73:0;;12093:2:1;13927:73:0::1;::::0;::::1;12075:21:1::0;12132:2;12112:18;;;12105:30;12171:34;12151:18;;;12144:62;-1:-1:-1;;;12222:18:1;;;12215:36;12268:19;;13927:73:0::1;11891:402:1::0;13927:73:0::1;14011:19;14021:8;14011:9;:19::i;53134:::-:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;32953:305::-;33055:4;-1:-1:-1;;;;;;33092:40:0;;-1:-1:-1;;;33092:40:0;;:105;;-1:-1:-1;;;;;;;33149:48:0;;-1:-1:-1;;;33149:48:0;33092:105;:158;;;-1:-1:-1;;;;;;;;;;25041:40:0;;;33214:36;24932:157;42833:174;42908:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;42908:29:0;-1:-1:-1;;;;;42908:29:0;;;;;;;;:24;;42962:23;42908:24;42962:14;:23::i;:::-;-1:-1:-1;;;;;42953:46:0;;;;;;;;;;;42833:174;;:::o;39835:110::-;39911:26;39921:2;39925:7;39911:26;;;;;;;;;;;;:9;:26::i;:::-;39835:110;;:::o;39145:348::-;39238:4;38940:16;;;:7;:16;;;;;;-1:-1:-1;;;;;38940:16:0;39255:73;;;;-1:-1:-1;;;39255:73:0;;14700:2:1;39255:73:0;;;14682:21:1;14739:2;14719:18;;;14712:30;14778:34;14758:18;;;14751:62;-1:-1:-1;;;14829:18:1;;;14822:42;14881:19;;39255:73:0;14498:408:1;39255:73:0;39339:13;39355:23;39370:7;39355:14;:23::i;:::-;39339:39;;39408:5;-1:-1:-1;;;;;39397:16:0;:7;-1:-1:-1;;;;;39397:16:0;;:51;;;;39441:7;-1:-1:-1;;;;;39417:31:0;:20;39429:7;39417:11;:20::i;:::-;-1:-1:-1;;;;;39417:31:0;;39397:51;:87;;;-1:-1:-1;;;;;;36237:25:0;;;36213:4;36237:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;39452:32;39389:96;39145:348;-1:-1:-1;;;;39145:348:0:o;42137:578::-;42296:4;-1:-1:-1;;;;;42269:31:0;:23;42284:7;42269:14;:23::i;:::-;-1:-1:-1;;;;;42269:31:0;;42261:85;;;;-1:-1:-1;;;42261:85:0;;19253:2:1;42261:85:0;;;19235:21:1;19292:2;19272:18;;;19265:30;19331:34;19311:18;;;19304:62;-1:-1:-1;;;19382:18:1;;;19375:39;19431:19;;42261:85:0;19051:405:1;42261:85:0;-1:-1:-1;;;;;42365:16:0;;42357:65;;;;-1:-1:-1;;;42357:65:0;;12857:2:1;42357:65:0;;;12839:21:1;12896:2;12876:18;;;12869:30;12935:34;12915:18;;;12908:62;-1:-1:-1;;;12986:18:1;;;12979:34;13030:19;;42357:65:0;12655:400:1;42357:65:0;42435:39;42456:4;42462:2;42466:7;42435:20;:39::i;:::-;42539:29;42556:1;42560:7;42539:8;:29::i;:::-;-1:-1:-1;;;;;42581:15:0;;;;;;:9;:15;;;;;:20;;42600:1;;42581:15;:20;;42600:1;;42581:20;:::i;:::-;;;;-1:-1:-1;;;;;;;42612:13:0;;;;;;:9;:13;;;;;:18;;42629:1;;42612:13;:18;;42629:1;;42612:18;:::i;:::-;;;;-1:-1:-1;;42641:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;42641:21:0;-1:-1:-1;;;;;42641:21:0;;;;;;;;;42680:27;;42641:16;;42680:27;;;;;;;42137:578;;;:::o;14046:173::-;14121:6;;;-1:-1:-1;;;;;14138:17:0;;;-1:-1:-1;;;;;;14138:17:0;;;;;;;14171:40;;14121:6;;;14138:17;14121:6;;14171:40;;14102:16;;14171:40;14091:128;14046:173;:::o;53810:159::-;53896:4;53938:23;:4;53951:9;53938:12;:23::i;:::-;53920:14;;-1:-1:-1;;;;;53920:41:0;;;:14;;:41;;53810:159;-1:-1:-1;;;53810:159:0:o;53470:328::-;53566:7;53588:12;53720:6;53728:3;53733:5;53703:36;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;53703:36:0;;;;;;;;;;53693:47;;53703:36;53693:47;;;;8333:66:1;53613:128:0;;;8321:79:1;;;;8416:12;;;8409:28;8453:12;;53613:128:0;;;;;;-1:-1:-1;;53613:128:0;;;;;;53603:151;;53613:128;53603:151;;;;;53470:328;-1:-1:-1;;;;;53470:328:0:o;53981:348::-;54038:4;54055:14;54090:1;54084:3;:7;54080:208;;;52629:4;54143:5;;:13;54131:25;;54080:208;;;54184:1;54178:3;:7;54174:114;;;52672:4;54214:5;;:13;54202:25;;54174:114;;;-1:-1:-1;54272:4:0;54312:9;53981:348;-1:-1:-1;;53981:348:0:o;38223:315::-;38380:28;38390:4;38396:2;38400:7;38380:9;:28::i;:::-;38427:48;38450:4;38456:2;38460:7;38469:5;38427:22;:48::i;:::-;38419:111;;;;-1:-1:-1;;;38419:111:0;;;;;;;:::i;9350:723::-;9406:13;9627:10;9623:53;;-1:-1:-1;;9654:10:0;;;;;;;;;;;;-1:-1:-1;;;9654:10:0;;;;;9350:723::o;9623:53::-;9701:5;9686:12;9742:78;9749:9;;9742:78;;9775:8;;;;:::i;:::-;;-1:-1:-1;9798:10:0;;-1:-1:-1;9806:2:0;9798:10;;:::i;:::-;;;9742:78;;;9830:19;9862:6;9852:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;9852:17:0;;9830:39;;9880:154;9887:10;;9880:154;;9914:11;9924:1;9914:11;;:::i;:::-;;-1:-1:-1;9983:10:0;9991:2;9983:5;:10;:::i;:::-;9970:24;;:2;:24;:::i;:::-;9957:39;;9940:6;9947;9940:14;;;;;;;;:::i;:::-;;;;:56;-1:-1:-1;;;;;9940:56:0;;;;;;;;-1:-1:-1;10011:11:0;10020:2;10011:11;;:::i;:::-;;;9880:154;;40172:321;40302:18;40308:2;40312:7;40302:5;:18::i;:::-;40353:54;40384:1;40388:2;40392:7;40401:5;40353:22;:54::i;:::-;40331:154;;;;-1:-1:-1;;;40331:154:0;;;;;;;:::i;47682:589::-;-1:-1:-1;;;;;47888:18:0;;47884:187;;47923:40;47955:7;49098:10;:17;;49071:24;;;;:15;:24;;;;;:44;;;49126:24;;;;;;;;;;;;48994:164;47923:40;47884:187;;;47993:2;-1:-1:-1;;;;;47985:10:0;:4;-1:-1:-1;;;;;47985:10:0;;47981:90;;48012:47;48045:4;48051:7;48012:32;:47::i;:::-;-1:-1:-1;;;;;48085:16:0;;48081:183;;48118:45;48155:7;48118:36;:45::i;48081:183::-;48191:4;-1:-1:-1;;;;;48185:10:0;:2;-1:-1:-1;;;;;48185:10:0;;48181:83;;48212:40;48240:2;48244:7;48212:27;:40::i;4368:231::-;4446:7;4467:17;4486:18;4508:27;4519:4;4525:9;4508:10;:27::i;:::-;4466:69;;;;4546:18;4558:5;4546:11;:18::i;:::-;-1:-1:-1;4582:9:0;4368:231;-1:-1:-1;;;4368:231:0:o;43572:799::-;43727:4;-1:-1:-1;;;;;43748:13:0;;15315:20;15363:8;43744:620;;43784:72;;-1:-1:-1;;;43784:72:0;;-1:-1:-1;;;;;43784:36:0;;;;;:72;;11814:10;;43835:4;;43841:7;;43850:5;;43784:72;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;43784:72:0;;;;;;;;-1:-1:-1;;43784:72:0;;;;;;;;;;;;:::i;:::-;;;43780:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;44026:13:0;;44022:272;;44069:60;;-1:-1:-1;;;44069:60:0;;;;;;;:::i;44022:272::-;44244:6;44238:13;44229:6;44225:2;44221:15;44214:38;43780:529;-1:-1:-1;;;;;;43907:51:0;-1:-1:-1;;;43907:51:0;;-1:-1:-1;43900:58:0;;43744:620;-1:-1:-1;44348:4:0;43572:799;;;;;;:::o;40829:382::-;-1:-1:-1;;;;;40909:16:0;;40901:61;;;;-1:-1:-1;;;40901:61:0;;17778:2:1;40901:61:0;;;17760:21:1;;;17797:18;;;17790:30;17856:34;17836:18;;;17829:62;17908:18;;40901:61:0;17576:356:1;40901:61:0;38916:4;38940:16;;;:7;:16;;;;;;-1:-1:-1;;;;;38940:16:0;:30;40973:58;;;;-1:-1:-1;;;40973:58:0;;12500:2:1;40973:58:0;;;12482:21:1;12539:2;12519:18;;;12512:30;12578;12558:18;;;12551:58;12626:18;;40973:58:0;12298:352:1;40973:58:0;41044:45;41073:1;41077:2;41081:7;41044:20;:45::i;:::-;-1:-1:-1;;;;;41102:13:0;;;;;;:9;:13;;;;;:18;;41119:1;;41102:13;:18;;41119:1;;41102:18;:::i;:::-;;;;-1:-1:-1;;41131:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;41131:21:0;-1:-1:-1;;;;;41131:21:0;;;;;;;;41170:33;;41131:16;;;41170:33;;41131:16;;41170:33;40829:382;;:::o;49785:988::-;50051:22;50101:1;50076:22;50093:4;50076:16;:22::i;:::-;:26;;;;:::i;:::-;50113:18;50134:26;;;:17;:26;;;;;;50051:51;;-1:-1:-1;50267:28:0;;;50263:328;;-1:-1:-1;;;;;50334:18:0;;50312:19;50334:18;;;:12;:18;;;;;;;;:34;;;;;;;;;50385:30;;;;;;:44;;;50502:30;;:17;:30;;;;;:43;;;50263:328;-1:-1:-1;50687:26:0;;;;:17;:26;;;;;;;;50680:33;;;-1:-1:-1;;;;;50731:18:0;;;;;:12;:18;;;;;:34;;;;;;;50724:41;49785:988::o;51068:1079::-;51346:10;:17;51321:22;;51346:21;;51366:1;;51346:21;:::i;:::-;51378:18;51399:24;;;:15;:24;;;;;;51772:10;:26;;51321:46;;-1:-1:-1;51399:24:0;;51321:46;;51772:26;;;;;;:::i;:::-;;;;;;;;;51750:48;;51836:11;51811:10;51822;51811:22;;;;;;;;:::i;:::-;;;;;;;;;;;;:36;;;;51916:28;;;:15;:28;;;;;;;:41;;;52088:24;;;;;52081:31;52123:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;51139:1008;;;51068:1079;:::o;48572:221::-;48657:14;48674:20;48691:2;48674:16;:20::i;:::-;-1:-1:-1;;;;;48705:16:0;;;;;;;:12;:16;;;;;;;;:24;;;;;;;;:34;;;48750:26;;;:17;:26;;;;;;:35;;;;-1:-1:-1;48572:221:0:o;2258:1308::-;2339:7;2348:12;2573:9;:16;2593:2;2573:22;2569:990;;;2869:4;2854:20;;2848:27;2919:4;2904:20;;2898:27;2977:4;2962:20;;2956:27;2612:9;2948:36;3020:25;3031:4;2948:36;2848:27;2898;3020:10;:25::i;:::-;3013:32;;;;;;;;;2569:990;3067:9;:16;3087:2;3067:22;3063:496;;;3342:4;3327:20;;3321:27;3393:4;3378:20;;3372:27;3435:23;3446:4;3321:27;3372;3435:10;:23::i;:::-;3428:30;;;;;;;;3063:496;-1:-1:-1;3507:1:0;;-1:-1:-1;3511:35:0;3063:496;2258:1308;;;;;:::o;529:643::-;607:20;598:5;:29;;;;;;;;:::i;:::-;;594:571;;;529:643;:::o;594:571::-;705:29;696:5;:38;;;;;;;;:::i;:::-;;692:473;;;751:34;;-1:-1:-1;;;751:34:0;;10198:2:1;751:34:0;;;10180:21:1;10237:2;10217:18;;;10210:30;10276:26;10256:18;;;10249:54;10320:18;;751:34:0;9996:348:1;692:473:0;816:35;807:5;:44;;;;;;;;:::i;:::-;;803:362;;;868:41;;-1:-1:-1;;;868:41:0;;10902:2:1;868:41:0;;;10884:21:1;10941:2;10921:18;;;10914:30;10980:33;10960:18;;;10953:61;11031:18;;868:41:0;10700:355:1;803:362:0;940:30;931:5;:39;;;;;;;;:::i;:::-;;927:238;;;987:44;;-1:-1:-1;;;987:44:0;;13957:2:1;987:44:0;;;13939:21:1;13996:2;13976:18;;;13969:30;14035:34;14015:18;;;14008:62;-1:-1:-1;;;14086:18:1;;;14079:32;14128:19;;987:44:0;13755:398:1;927:238:0;1062:30;1053:5;:39;;;;;;;;:::i;:::-;;1049:116;;;1109:44;;-1:-1:-1;;;1109:44:0;;17039:2:1;1109:44:0;;;17021:21:1;17078:2;17058:18;;;17051:30;17117:34;17097:18;;;17090:62;-1:-1:-1;;;17168:18:1;;;17161:32;17210:19;;1109:44:0;16837:398:1;5867:1632:0;5998:7;;6932:66;6919:79;;6915:163;;;-1:-1:-1;7031:1:0;;-1:-1:-1;7035:30:0;7015:51;;6915:163;7092:1;:7;;7097:2;7092:7;;:18;;;;;7103:1;:7;;7108:2;7103:7;;7092:18;7088:102;;;-1:-1:-1;7143:1:0;;-1:-1:-1;7147:30:0;7127:51;;7088:102;7304:24;;;7287:14;7304:24;;;;;;;;;9596:25:1;;;9669:4;9657:17;;9637:18;;;9630:45;;;;9691:18;;;9684:34;;;9734:18;;;9727:34;;;7304:24:0;;9568:19:1;;7304:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;7304:24:0;;-1:-1:-1;;7304:24:0;;;-1:-1:-1;;;;;;;7343:20:0;;7339:103;;7396:1;7400:29;7380:50;;;;;;;7339:103;7462:6;-1:-1:-1;7470:20:0;;-1:-1:-1;5867:1632:0;;;;;;;;:::o;4862:391::-;4976:7;;-1:-1:-1;;;;;5077:75:0;;5179:3;5175:12;;;5189:2;5171:21;5220:25;5231:4;5171:21;5240:1;5077:75;5220:10;:25::i;:::-;5213:32;;;;;;4862:391;;;;;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:631:1;78:5;108:18;149:2;141:6;138:14;135:40;;;155:18;;:::i;:::-;230:2;224:9;198:2;284:15;;-1:-1:-1;;280:24:1;;;306:2;276:33;272:42;260:55;;;330:18;;;350:22;;;327:46;324:72;;;376:18;;:::i;:::-;416:10;412:2;405:22;445:6;436:15;;475:6;467;460:22;515:3;506:6;501:3;497:16;494:25;491:45;;;532:1;529;522:12;491:45;582:6;577:3;570:4;562:6;558:17;545:44;637:1;630:4;621:6;613;609:19;605:30;598:41;;;;14:631;;;;;:::o;650:173::-;718:20;;-1:-1:-1;;;;;767:31:1;;757:42;;747:70;;813:1;810;803:12;747:70;650:173;;;:::o;828:220::-;870:5;923:3;916:4;908:6;904:17;900:27;890:55;;941:1;938;931:12;890:55;963:79;1038:3;1029:6;1016:20;1009:4;1001:6;997:17;963:79;:::i;:::-;954:88;828:220;-1:-1:-1;;;828:220:1:o;1053:186::-;1112:6;1165:2;1153:9;1144:7;1140:23;1136:32;1133:52;;;1181:1;1178;1171:12;1133:52;1204:29;1223:9;1204:29;:::i;1244:260::-;1312:6;1320;1373:2;1361:9;1352:7;1348:23;1344:32;1341:52;;;1389:1;1386;1379:12;1341:52;1412:29;1431:9;1412:29;:::i;:::-;1402:39;;1460:38;1494:2;1483:9;1479:18;1460:38;:::i;:::-;1450:48;;1244:260;;;;;:::o;1509:328::-;1586:6;1594;1602;1655:2;1643:9;1634:7;1630:23;1626:32;1623:52;;;1671:1;1668;1661:12;1623:52;1694:29;1713:9;1694:29;:::i;:::-;1684:39;;1742:38;1776:2;1765:9;1761:18;1742:38;:::i;:::-;1732:48;;1827:2;1816:9;1812:18;1799:32;1789:42;;1509:328;;;;;:::o;1842:537::-;1937:6;1945;1953;1961;2014:3;2002:9;1993:7;1989:23;1985:33;1982:53;;;2031:1;2028;2021:12;1982:53;2054:29;2073:9;2054:29;:::i;:::-;2044:39;;2102:38;2136:2;2125:9;2121:18;2102:38;:::i;:::-;2092:48;;2187:2;2176:9;2172:18;2159:32;2149:42;;2242:2;2231:9;2227:18;2214:32;2269:18;2261:6;2258:30;2255:50;;;2301:1;2298;2291:12;2255:50;2324:49;2365:7;2356:6;2345:9;2341:22;2324:49;:::i;:::-;2314:59;;;1842:537;;;;;;;:::o;2384:347::-;2449:6;2457;2510:2;2498:9;2489:7;2485:23;2481:32;2478:52;;;2526:1;2523;2516:12;2478:52;2549:29;2568:9;2549:29;:::i;:::-;2539:39;;2628:2;2617:9;2613:18;2600:32;2675:5;2668:13;2661:21;2654:5;2651:32;2641:60;;2697:1;2694;2687:12;2641:60;2720:5;2710:15;;;2384:347;;;;;:::o;2736:254::-;2804:6;2812;2865:2;2853:9;2844:7;2840:23;2836:32;2833:52;;;2881:1;2878;2871:12;2833:52;2904:29;2923:9;2904:29;:::i;:::-;2894:39;2980:2;2965:18;;;;2952:32;;-1:-1:-1;;;2736:254:1:o;2995:615::-;3081:6;3089;3142:2;3130:9;3121:7;3117:23;3113:32;3110:52;;;3158:1;3155;3148:12;3110:52;3198:9;3185:23;3227:18;3268:2;3260:6;3257:14;3254:34;;;3284:1;3281;3274:12;3254:34;3322:6;3311:9;3307:22;3297:32;;3367:7;3360:4;3356:2;3352:13;3348:27;3338:55;;3389:1;3386;3379:12;3338:55;3429:2;3416:16;3455:2;3447:6;3444:14;3441:34;;;3471:1;3468;3461:12;3441:34;3524:7;3519:2;3509:6;3506:1;3502:14;3498:2;3494:23;3490:32;3487:45;3484:65;;;3545:1;3542;3535:12;3484:65;3576:2;3568:11;;;;;3598:6;;-1:-1:-1;2995:615:1;;-1:-1:-1;;;;2995:615:1:o;3615:806::-;3720:6;3728;3736;3744;3797:3;3785:9;3776:7;3772:23;3768:33;3765:53;;;3814:1;3811;3804:12;3765:53;3850:9;3837:23;3827:33;;3911:2;3900:9;3896:18;3883:32;3934:18;3975:2;3967:6;3964:14;3961:34;;;3991:1;3988;3981:12;3961:34;4014:49;4055:7;4046:6;4035:9;4031:22;4014:49;:::i;:::-;4004:59;;4116:2;4105:9;4101:18;4088:32;4072:48;;4145:2;4135:8;4132:16;4129:36;;;4161:1;4158;4151:12;4129:36;-1:-1:-1;4184:24:1;;4239:4;4231:13;;4227:27;-1:-1:-1;4217:55:1;;4268:1;4265;4258:12;4217:55;4291:73;4356:7;4351:2;4338:16;4333:2;4329;4325:11;4291:73;:::i;:::-;3615:806;;;;-1:-1:-1;4281:83:1;;4411:2;4396:18;4383:32;;-1:-1:-1;;;3615:806:1:o;4426:245::-;4484:6;4537:2;4525:9;4516:7;4512:23;4508:32;4505:52;;;4553:1;4550;4543:12;4505:52;4592:9;4579:23;4611:30;4635:5;4611:30;:::i;4676:249::-;4745:6;4798:2;4786:9;4777:7;4773:23;4769:32;4766:52;;;4814:1;4811;4804:12;4766:52;4846:9;4840:16;4865:30;4889:5;4865:30;:::i;4930:592::-;5001:6;5009;5062:2;5050:9;5041:7;5037:23;5033:32;5030:52;;;5078:1;5075;5068:12;5030:52;5118:9;5105:23;5147:18;5188:2;5180:6;5177:14;5174:34;;;5204:1;5201;5194:12;5174:34;5242:6;5231:9;5227:22;5217:32;;5287:7;5280:4;5276:2;5272:13;5268:27;5258:55;;5309:1;5306;5299:12;5258:55;5349:2;5336:16;5375:2;5367:6;5364:14;5361:34;;;5391:1;5388;5381:12;5361:34;5436:7;5431:2;5422:6;5418:2;5414:15;5410:24;5407:37;5404:57;;;5457:1;5454;5447:12;5527:180;5586:6;5639:2;5627:9;5618:7;5614:23;5610:32;5607:52;;;5655:1;5652;5645:12;5607:52;-1:-1:-1;5678:23:1;;5527:180;-1:-1:-1;5527:180:1:o;5712:257::-;5753:3;5791:5;5785:12;5818:6;5813:3;5806:19;5834:63;5890:6;5883:4;5878:3;5874:14;5867:4;5860:5;5856:16;5834:63;:::i;:::-;5951:2;5930:15;-1:-1:-1;;5926:29:1;5917:39;;;;5958:4;5913:50;;5712:257;-1:-1:-1;;5712:257:1:o;5974:185::-;6016:3;6054:5;6048:12;6069:52;6114:6;6109:3;6102:4;6095:5;6091:16;6069:52;:::i;:::-;6137:16;;;;;5974:185;-1:-1:-1;;5974:185:1:o;6164:462::-;6406:26;6402:31;6393:6;6389:2;6385:15;6381:53;6376:3;6369:66;6465:6;6460:2;6455:3;6451:12;6444:28;6351:3;6501:6;6495:13;6517:62;6572:6;6567:2;6562:3;6558:12;6551:4;6543:6;6539:17;6517:62;:::i;:::-;6599:16;;;;6617:2;6595:25;;6164:462;-1:-1:-1;;;;6164:462:1:o;6631:276::-;6762:3;6800:6;6794:13;6816:53;6862:6;6857:3;6850:4;6842:6;6838:17;6816:53;:::i;:::-;6885:16;;;;;6631:276;-1:-1:-1;;6631:276:1:o;6912:1174::-;7088:3;7117:1;7150:6;7144:13;7180:3;7202:1;7230:9;7226:2;7222:18;7212:28;;7290:2;7279:9;7275:18;7312;7302:61;;7356:4;7348:6;7344:17;7334:27;;7302:61;7382:2;7430;7422:6;7419:14;7399:18;7396:38;7393:165;;;-1:-1:-1;;;7457:33:1;;7513:4;7510:1;7503:15;7543:4;7464:3;7531:17;7393:165;7574:18;7601:104;;;;7719:1;7714:320;;;;7567:467;;7601:104;-1:-1:-1;;7634:24:1;;7622:37;;7679:16;;;;-1:-1:-1;7601:104:1;;7714:320;23426:1;23419:14;;;23463:4;23450:18;;7809:1;7823:165;7837:6;7834:1;7831:13;7823:165;;;7915:14;;7902:11;;;7895:35;7958:16;;;;7852:10;;7823:165;;;7827:3;;8017:6;8012:3;8008:16;8001:23;;7567:467;;;;;;;8050:30;8076:3;8068:6;8050:30;:::i;:::-;8043:37;6912:1174;-1:-1:-1;;;;;6912:1174:1:o;8684:488::-;-1:-1:-1;;;;;8953:15:1;;;8935:34;;9005:15;;9000:2;8985:18;;8978:43;9052:2;9037:18;;9030:34;;;9100:3;9095:2;9080:18;;9073:31;;;8878:4;;9121:45;;9146:19;;9138:6;9121:45;:::i;:::-;9113:53;8684:488;-1:-1:-1;;;;;;8684:488:1:o;9772:219::-;9921:2;9910:9;9903:21;9884:4;9941:44;9981:2;9970:9;9966:18;9958:6;9941:44;:::i;11472:414::-;11674:2;11656:21;;;11713:2;11693:18;;;11686:30;11752:34;11747:2;11732:18;;11725:62;-1:-1:-1;;;11818:2:1;11803:18;;11796:48;11876:3;11861:19;;11472:414::o;18350:356::-;18552:2;18534:21;;;18571:18;;;18564:30;18630:34;18625:2;18610:18;;18603:62;18697:2;18682:18;;18350:356::o;19461:400::-;19663:2;19645:21;;;19702:2;19682:18;;;19675:30;19741:34;19736:2;19721:18;;19714:62;-1:-1:-1;;;19807:2:1;19792:18;;19785:34;19851:3;19836:19;;19461:400::o;21307:413::-;21509:2;21491:21;;;21548:2;21528:18;;;21521:30;21587:34;21582:2;21567:18;;21560:62;-1:-1:-1;;;21653:2:1;21638:18;;21631:47;21710:3;21695:19;;21307:413::o;23479:128::-;23519:3;23550:1;23546:6;23543:1;23540:13;23537:39;;;23556:18;;:::i;:::-;-1:-1:-1;23592:9:1;;23479:128::o;23612:120::-;23652:1;23678;23668:35;;23683:18;;:::i;:::-;-1:-1:-1;23717:9:1;;23612:120::o;23737:168::-;23777:7;23843:1;23839;23835:6;23831:14;23828:1;23825:21;23820:1;23813:9;23806:17;23802:45;23799:71;;;23850:18;;:::i;:::-;-1:-1:-1;23890:9:1;;23737:168::o;23910:125::-;23950:4;23978:1;23975;23972:8;23969:34;;;23983:18;;:::i;:::-;-1:-1:-1;24020:9:1;;23910:125::o;24040:258::-;24112:1;24122:113;24136:6;24133:1;24130:13;24122:113;;;24212:11;;;24206:18;24193:11;;;24186:39;24158:2;24151:10;24122:113;;;24253:6;24250:1;24247:13;24244:48;;;-1:-1:-1;;24288:1:1;24270:16;;24263:27;24040:258::o;24303:136::-;24342:3;24370:5;24360:39;;24379:18;;:::i;:::-;-1:-1:-1;;;24415:18:1;;24303:136::o;24444:380::-;24523:1;24519:12;;;;24566;;;24587:61;;24641:4;24633:6;24629:17;24619:27;;24587:61;24694:2;24686:6;24683:14;24663:18;24660:38;24657:161;;;24740:10;24735:3;24731:20;24728:1;24721:31;24775:4;24772:1;24765:15;24803:4;24800:1;24793:15;24657:161;;24444:380;;;:::o;24829:135::-;24868:3;-1:-1:-1;;24889:17:1;;24886:43;;;24909:18;;:::i;:::-;-1:-1:-1;24956:1:1;24945:13;;24829:135::o;24969:112::-;25001:1;25027;25017:35;;25032:18;;:::i;:::-;-1:-1:-1;25066:9:1;;24969:112::o;25086:127::-;25147:10;25142:3;25138:20;25135:1;25128:31;25178:4;25175:1;25168:15;25202:4;25199:1;25192:15;25218:127;25279:10;25274:3;25270:20;25267:1;25260:31;25310:4;25307:1;25300:15;25334:4;25331:1;25324:15;25350:127;25411:10;25406:3;25402:20;25399:1;25392:31;25442:4;25439:1;25432:15;25466:4;25463:1;25456:15;25482:127;25543:10;25538:3;25534:20;25531:1;25524:31;25574:4;25571:1;25564:15;25598:4;25595:1;25588:15;25614:127;25675:10;25670:3;25666:20;25663:1;25656:31;25706:4;25703:1;25696:15;25730:4;25727:1;25720:15;25746:127;25807:10;25802:3;25798:20;25795:1;25788:31;25838:4;25835:1;25828:15;25862:4;25859:1;25852:15;25878:131;-1:-1:-1;;;;;;25952:32:1;;25942:43;;25932:71;;25999:1;25996;25989:12

Swarm Source

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