ETH Price: $3,416.32 (+1.73%)
Gas: 7 Gwei

Token

SorcererTown (ST)
 

Overview

Max Total Supply

176 ST

Holders

69

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A

Other Info

Balance
1 ST
0x47a714a89150978447838e889eea1d0896f7e034
Loading...
Loading
Loading...
Loading
Loading...
Loading

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

Contract Source Code Verified (Exact Match)

Contract Name:
SorcererTown

Compiler Version
v0.8.17+commit.8df45f5f

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2022-11-26
*/

// SPDX-License-Identifier: MIT

// File: operator-filter-registry/src/IOperatorFilterRegistry.sol

pragma solidity ^0.8.13;

interface IOperatorFilterRegistry {
    function isOperatorAllowed(address registrant, address operator)
        external
        view
        returns (bool);

    function register(address registrant) external;

    function registerAndSubscribe(address registrant, address subscription)
        external;

    function registerAndCopyEntries(
        address registrant,
        address registrantToCopy
    ) external;

    function updateOperator(
        address registrant,
        address operator,
        bool filtered
    ) external;

    function updateOperators(
        address registrant,
        address[] calldata operators,
        bool filtered
    ) external;

    function updateCodeHash(
        address registrant,
        bytes32 codehash,
        bool filtered
    ) external;

    function updateCodeHashes(
        address registrant,
        bytes32[] calldata codeHashes,
        bool filtered
    ) external;

    function subscribe(address registrant, address registrantToSubscribe)
        external;

    function unsubscribe(address registrant, bool copyExistingEntries) external;

    function subscriptionOf(address addr) external returns (address registrant);

    function subscribers(address registrant)
        external
        returns (address[] memory);

    function subscriberAt(address registrant, uint256 index)
        external
        returns (address);

    function copyEntriesOf(address registrant, address registrantToCopy)
        external;

    function isOperatorFiltered(address registrant, address operator)
        external
        returns (bool);

    function isCodeHashOfFiltered(address registrant, address operatorWithCode)
        external
        returns (bool);

    function isCodeHashFiltered(address registrant, bytes32 codeHash)
        external
        returns (bool);

    function filteredOperators(address addr)
        external
        returns (address[] memory);

    function filteredCodeHashes(address addr)
        external
        returns (bytes32[] memory);

    function filteredOperatorAt(address registrant, uint256 index)
        external
        returns (address);

    function filteredCodeHashAt(address registrant, uint256 index)
        external
        returns (bytes32);

    function isRegistered(address addr) external returns (bool);

    function codeHashOf(address addr) external returns (bytes32);
}

// File: operator-filter-registry/src/OperatorFilterer.sol

pragma solidity ^0.8.13;

abstract contract OperatorFilterer {
    error OperatorNotAllowed(address operator);

    IOperatorFilterRegistry constant operatorFilterRegistry =
        IOperatorFilterRegistry(0x000000000000AAeB6D7670E522A718067333cd4E);

    constructor(address subscriptionOrRegistrantToCopy, bool subscribe) {
        // If an inheriting token contract is deployed to a network without the registry deployed, the modifier
        // will not revert, but the contract will need to be registered with the registry once it is deployed in
        // order for the modifier to filter addresses.
        if (address(operatorFilterRegistry).code.length > 0) {
            if (subscribe) {
                operatorFilterRegistry.registerAndSubscribe(
                    address(this),
                    subscriptionOrRegistrantToCopy
                );
            } else {
                if (subscriptionOrRegistrantToCopy != address(0)) {
                    operatorFilterRegistry.registerAndCopyEntries(
                        address(this),
                        subscriptionOrRegistrantToCopy
                    );
                } else {
                    operatorFilterRegistry.register(address(this));
                }
            }
        }
    }

    modifier onlyAllowedOperator(address from) virtual {
        // Check registry code length to facilitate testing in environments without a deployed registry.
        if (address(operatorFilterRegistry).code.length > 0) {
            // Allow spending tokens from addresses with balance
            // Note that this still allows listings and marketplaces with escrow to transfer tokens if transferred
            // from an EOA.
            if (from == msg.sender) {
                _;
                return;
            }
            if (
                !(operatorFilterRegistry.isOperatorAllowed(
                    address(this),
                    msg.sender
                ) &&
                    operatorFilterRegistry.isOperatorAllowed(
                        address(this),
                        from
                    ))
            ) {
                revert OperatorNotAllowed(msg.sender);
            }
        }
        _;
    }
}

// File: operator-filter-registry/src/DefaultOperatorFilterer.sol

pragma solidity ^0.8.13;

abstract contract DefaultOperatorFilterer is OperatorFilterer {
    address constant DEFAULT_SUBSCRIPTION =
        address(0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6);

    constructor() OperatorFilterer(DEFAULT_SUBSCRIPTION, true) {}
}

// File: contracts/hoshiko.sol

// File: @openzeppelin/contracts/security/ReentrancyGuard.sol

// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)

//1b0014041a0a15

pragma solidity ^0.8.0;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        // On the first call to nonReentrant, _notEntered will be true
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _status = _ENTERED;

        _;

        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = _NOT_ENTERED;
    }
}

// File: @openzeppelin/contracts/utils/cryptography/MerkleProof.sol

// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/MerkleProof.sol)

pragma solidity ^0.8.0;

/**
 * @dev These functions deal with verification of Merkle Tree proofs.
 *
 * The proofs can be generated using the JavaScript library
 * https://github.com/miguelmota/merkletreejs[merkletreejs].
 * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled.
 *
 * See `test/utils/cryptography/MerkleProof.test.js` for some examples.
 *
 * WARNING: You should avoid using leaf values that are 64 bytes long prior to
 * hashing, or use a hash function other than keccak256 for hashing leaves.
 * This is because the concatenation of a sorted pair of internal nodes in
 * the merkle tree could be reinterpreted as a leaf value.
 */
library MerkleProof {
    /**
     * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree
     * defined by `root`. For this, a `proof` must be provided, containing
     * sibling hashes on the branch from the leaf to the root of the tree. Each
     * pair of leaves and each pair of pre-images are assumed to be sorted.
     */
    function verify(
        bytes32[] memory proof,
        bytes32 root,
        bytes32 leaf
    ) internal pure returns (bool) {
        return processProof(proof, leaf) == root;
    }

    /**
     * @dev Calldata version of {verify}
     *
     * _Available since v4.7._
     */
    function verifyCalldata(
        bytes32[] calldata proof,
        bytes32 root,
        bytes32 leaf
    ) internal pure returns (bool) {
        return processProofCalldata(proof, leaf) == root;
    }

    /**
     * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up
     * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt
     * hash matches the root of the tree. When processing the proof, the pairs
     * of leafs & pre-images are assumed to be sorted.
     *
     * _Available since v4.4._
     */
    function processProof(bytes32[] memory proof, bytes32 leaf)
        internal
        pure
        returns (bytes32)
    {
        bytes32 computedHash = leaf;
        for (uint256 i = 0; i < proof.length; i++) {
            computedHash = _hashPair(computedHash, proof[i]);
        }
        return computedHash;
    }

    /**
     * @dev Calldata version of {processProof}
     *
     * _Available since v4.7._
     */
    function processProofCalldata(bytes32[] calldata proof, bytes32 leaf)
        internal
        pure
        returns (bytes32)
    {
        bytes32 computedHash = leaf;
        for (uint256 i = 0; i < proof.length; i++) {
            computedHash = _hashPair(computedHash, proof[i]);
        }
        return computedHash;
    }

    /**
     * @dev Returns true if the `leaves` can be proved to be a part of a Merkle tree defined by
     * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}.
     *
     * _Available since v4.7._
     */
    function multiProofVerify(
        bytes32[] memory proof,
        bool[] memory proofFlags,
        bytes32 root,
        bytes32[] memory leaves
    ) internal pure returns (bool) {
        return processMultiProof(proof, proofFlags, leaves) == root;
    }

    /**
     * @dev Calldata version of {multiProofVerify}
     *
     * _Available since v4.7._
     */
    function multiProofVerifyCalldata(
        bytes32[] calldata proof,
        bool[] calldata proofFlags,
        bytes32 root,
        bytes32[] memory leaves
    ) internal pure returns (bool) {
        return processMultiProofCalldata(proof, proofFlags, leaves) == root;
    }

    /**
     * @dev Returns the root of a tree reconstructed from `leaves` and the sibling nodes in `proof`,
     * consuming from one or the other at each step according to the instructions given by
     * `proofFlags`.
     *
     * _Available since v4.7._
     */
    function processMultiProof(
        bytes32[] memory proof,
        bool[] memory proofFlags,
        bytes32[] memory leaves
    ) internal pure returns (bytes32 merkleRoot) {
        // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by
        // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the
        // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of
        // the merkle tree.
        uint256 leavesLen = leaves.length;
        uint256 totalHashes = proofFlags.length;

        // Check proof validity.
        require(
            leavesLen + proof.length - 1 == totalHashes,
            "MerkleProof: invalid multiproof"
        );

        // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using
        // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop".
        bytes32[] memory hashes = new bytes32[](totalHashes);
        uint256 leafPos = 0;
        uint256 hashPos = 0;
        uint256 proofPos = 0;
        // At each step, we compute the next hash using two values:
        // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we
        //   get the next hash.
        // - depending on the flag, either another value for the "main queue" (merging branches) or an element from the
        //   `proof` array.
        for (uint256 i = 0; i < totalHashes; i++) {
            bytes32 a = leafPos < leavesLen
                ? leaves[leafPos++]
                : hashes[hashPos++];
            bytes32 b = proofFlags[i]
                ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]
                : proof[proofPos++];
            hashes[i] = _hashPair(a, b);
        }

        if (totalHashes > 0) {
            return hashes[totalHashes - 1];
        } else if (leavesLen > 0) {
            return leaves[0];
        } else {
            return proof[0];
        }
    }

    /**
     * @dev Calldata version of {processMultiProof}
     *
     * _Available since v4.7._
     */
    function processMultiProofCalldata(
        bytes32[] calldata proof,
        bool[] calldata proofFlags,
        bytes32[] memory leaves
    ) internal pure returns (bytes32 merkleRoot) {
        // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by
        // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the
        // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of
        // the merkle tree.
        uint256 leavesLen = leaves.length;
        uint256 totalHashes = proofFlags.length;

        // Check proof validity.
        require(
            leavesLen + proof.length - 1 == totalHashes,
            "MerkleProof: invalid multiproof"
        );

        // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using
        // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop".
        bytes32[] memory hashes = new bytes32[](totalHashes);
        uint256 leafPos = 0;
        uint256 hashPos = 0;
        uint256 proofPos = 0;
        // At each step, we compute the next hash using two values:
        // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we
        //   get the next hash.
        // - depending on the flag, either another value for the "main queue" (merging branches) or an element from the
        //   `proof` array.
        for (uint256 i = 0; i < totalHashes; i++) {
            bytes32 a = leafPos < leavesLen
                ? leaves[leafPos++]
                : hashes[hashPos++];
            bytes32 b = proofFlags[i]
                ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]
                : proof[proofPos++];
            hashes[i] = _hashPair(a, b);
        }

        if (totalHashes > 0) {
            return hashes[totalHashes - 1];
        } else if (leavesLen > 0) {
            return leaves[0];
        } else {
            return proof[0];
        }
    }

    function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) {
        return a < b ? _efficientHash(a, b) : _efficientHash(b, a);
    }

    function _efficientHash(bytes32 a, bytes32 b)
        private
        pure
        returns (bytes32 value)
    {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, a)
            mstore(0x20, b)
            value := keccak256(0x00, 0x40)
        }
    }
}

pragma solidity ^0.8.4;

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

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

    /**
     * The caller cannot approve to their own address.
     */
    error ApproveToCaller();

    /**
     * The caller cannot approve to the current owner.
     */
    error ApprovalToCurrentOwner();

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

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

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

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

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

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

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

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

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

    struct TokenOwnership {
        // The address of the owner.
        address addr;
        // Keeps track of the start time of ownership with minimal overhead for tokenomics.
        uint64 startTimestamp;
        // Whether the token has been burned.
        bool burned;
    }

    /**
     * @dev Returns the total amount of tokens stored by the contract.
     *
     * Burned tokens are calculated here, use `_totalMinted()` if you want to count just minted tokens.
     */
    function totalSupply() external view returns (uint256);

    // ==============================
    //            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);

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

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

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

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

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

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

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

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must 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 Approve or remove `operator` as an operator for the caller.
     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
     *
     * Requirements:
     *
     * - The `operator` cannot be the caller.
     *
     * Emits an {ApprovalForAll} event.
     */
    function setApprovalForAll(address operator, bool _approved) external;

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

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

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

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

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

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

// File: https://github.com/chiru-labs/ERC721A/blob/main/contracts/ERC721A.sol

// ERC721A Contracts v3.3.0
// Creator: Chiru Labs

pragma solidity ^0.8.4;

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

/**
 * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
 * the Metadata extension. Built to optimize for lower gas during batch mints.
 *
 * Assumes serials are sequentially minted starting at _startTokenId() (defaults to 0, e.g. 0, 1, 2, 3..).
 *
 * Assumes that an owner cannot have more than 2**64 - 1 (max value of uint64) of supply.
 *
 * Assumes that the maximum token id cannot exceed 2**256 - 1 (max value of uint256).
 */
contract ERC721A is IERC721A {
    // Mask of an entry in packed address data.
    uint256 private constant BITMASK_ADDRESS_DATA_ENTRY = (1 << 64) - 1;

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

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

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

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

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

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

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

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

    // The tokenId of the next token to be minted.
    uint256 private _currentIndex;

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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

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

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

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

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

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

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

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

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

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

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId)
        public
        view
        virtual
        override
        returns (bool)
    {
        // The interface IDs are constants representing the first 4 bytes of the XOR of
        // all function selectors in the interface. See: https://eips.ethereum.org/EIPS/eip-165
        // e.g. `bytes4(i.functionA.selector ^ i.functionB.selector ^ ...)`
        return
            interfaceId == 0x01ffc9a7 || // ERC165 interface ID for ERC165.
            interfaceId == 0x80ac58cd || // ERC165 interface ID for ERC721.
            interfaceId == 0x5b5e139f; // ERC165 interface ID for ERC721Metadata.
    }

    /**
     * @dev See {IERC721-balanceOf}.
     */
    function balanceOf(address owner) public view override returns (uint256) {
        if (owner == address(0)) revert BalanceQueryForZeroAddress();
        return _packedAddressData[owner] & BITMASK_ADDRESS_DATA_ENTRY;
    }

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

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

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

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

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

        unchecked {
            if (_startTokenId() <= curr)
                if (curr < _currentIndex) {
                    uint256 packed = _packedOwnerships[curr];
                    // If not burned.
                    if (packed & BITMASK_BURNED == 0) {
                        // Invariant:
                        // There will always be an ownership that has an address and is not burned
                        // before an ownership that does not have an address and is not burned.
                        // Hence, curr will not underflow.
                        //
                        // We can directly compare the packed value.
                        // If the address is zero, packed is zero.
                        while (packed == 0) {
                            packed = _packedOwnerships[--curr];
                        }
                        return packed;
                    }
                }
        }
        revert OwnerQueryForNonexistentToken();
    }

    /**
     * Returns the unpacked `TokenOwnership` struct from `packed`.
     */
    function _unpackedOwnership(uint256 packed)
        private
        pure
        returns (TokenOwnership memory ownership)
    {
        ownership.addr = address(uint160(packed));
        ownership.startTimestamp = uint64(packed >> BITPOS_START_TIMESTAMP);
        ownership.burned = packed & BITMASK_BURNED != 0;
    }

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

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

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

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId) public view override returns (address) {
        return address(uint160(_packedOwnershipOf(tokenId)));
    }

    /**
     * @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)
    {
        if (!_exists(tokenId)) revert URIQueryForNonexistentToken();

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

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

    /**
     * @dev Casts the address to uint256 without masking.
     */
    function _addressToUint256(address value)
        private
        pure
        returns (uint256 result)
    {
        assembly {
            result := value
        }
    }

    /**
     * @dev Casts the boolean to uint256 without branching.
     */
    function _boolToUint256(bool value) private pure returns (uint256 result) {
        assembly {
            result := value
        }
    }

    /**
     * @dev See {IERC721-approve}.
     */
    function approve(address to, uint256 tokenId) public override {
        address owner = address(uint160(_packedOwnershipOf(tokenId)));
        if (to == owner) revert ApprovalToCurrentOwner();

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

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

    /**
     * @dev See {IERC721-getApproved}.
     */
    function getApproved(uint256 tokenId)
        public
        view
        override
        returns (address)
    {
        if (!_exists(tokenId)) revert ApprovalQueryForNonexistentToken();

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev See {IERC721-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved)
        public
        virtual
        override
    {
        if (operator == _msgSenderERC721A()) revert ApproveToCaller();

        _operatorApprovals[_msgSenderERC721A()][operator] = approved;
        emit ApprovalForAll(_msgSenderERC721A(), 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 {
        _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 {
        _transfer(from, to, tokenId);
        if (to.code.length != 0)
            if (!_checkContractOnERC721Received(from, to, tokenId, _data)) {
                revert TransferToNonERC721ReceiverImplementer();
            }
    }

    /**
     * @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`),
     */
    function _exists(uint256 tokenId) internal view returns (bool) {
        return
            _startTokenId() <= tokenId &&
            tokenId < _currentIndex && // If within bounds,
            _packedOwnerships[tokenId] & BITMASK_BURNED == 0; // and not burned.
    }

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

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

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

        // Overflows are incredibly unrealistic.
        // balance or numberMinted overflow if current value of either + quantity > 1.8e19 (2**64) - 1
        // updatedIndex overflows if _currentIndex + quantity > 1.2e77 (2**256) - 1
        unchecked {
            // Updates:
            // - `balance += quantity`.
            // - `numberMinted += quantity`.
            //
            // We can directly add to the balance and number minted.
            _packedAddressData[to] +=
                quantity *
                ((1 << BITPOS_NUMBER_MINTED) | 1);

            // Updates:
            // - `address` to the owner.
            // - `startTimestamp` to the timestamp of minting.
            // - `burned` to `false`.
            // - `nextInitialized` to `quantity == 1`.
            _packedOwnerships[startTokenId] =
                _addressToUint256(to) |
                (block.timestamp << BITPOS_START_TIMESTAMP) |
                (_boolToUint256(quantity == 1) << BITPOS_NEXT_INITIALIZED);

            uint256 updatedIndex = startTokenId;
            uint256 end = updatedIndex + quantity;

            if (to.code.length != 0) {
                do {
                    emit Transfer(address(0), to, updatedIndex);
                    if (
                        !_checkContractOnERC721Received(
                            address(0),
                            to,
                            updatedIndex++,
                            _data
                        )
                    ) {
                        revert TransferToNonERC721ReceiverImplementer();
                    }
                } while (updatedIndex < end);
                // Reentrancy protection
                if (_currentIndex != startTokenId) revert();
            } else {
                do {
                    emit Transfer(address(0), to, updatedIndex++);
                } while (updatedIndex < end);
            }
            _currentIndex = updatedIndex;
        }
        _afterTokenTransfers(address(0), to, startTokenId, quantity);
    }

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

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

        // Overflows are incredibly unrealistic.
        // balance or numberMinted overflow if current value of either + quantity > 1.8e19 (2**64) - 1
        // updatedIndex overflows if _currentIndex + quantity > 1.2e77 (2**256) - 1
        unchecked {
            // Updates:
            // - `balance += quantity`.
            // - `numberMinted += quantity`.
            //
            // We can directly add to the balance and number minted.
            _packedAddressData[to] +=
                quantity *
                ((1 << BITPOS_NUMBER_MINTED) | 1);

            // Updates:
            // - `address` to the owner.
            // - `startTimestamp` to the timestamp of minting.
            // - `burned` to `false`.
            // - `nextInitialized` to `quantity == 1`.
            _packedOwnerships[startTokenId] =
                _addressToUint256(to) |
                (block.timestamp << BITPOS_START_TIMESTAMP) |
                (_boolToUint256(quantity == 1) << BITPOS_NEXT_INITIALIZED);

            uint256 updatedIndex = startTokenId;
            uint256 end = updatedIndex + quantity;

            do {
                emit Transfer(address(0), to, updatedIndex++);
            } while (updatedIndex < end);

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

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *
     * 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
    ) private {
        uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId);

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

        bool isApprovedOrOwner = (_msgSenderERC721A() == from ||
            isApprovedForAll(from, _msgSenderERC721A()) ||
            getApproved(tokenId) == _msgSenderERC721A());

        if (!isApprovedOrOwner) revert TransferCallerNotOwnerNorApproved();
        if (to == address(0)) revert TransferToZeroAddress();

        _beforeTokenTransfers(from, to, tokenId, 1);

        // Clear approvals from the previous owner.
        delete _tokenApprovals[tokenId];

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

            // Updates:
            // - `address` to the next owner.
            // - `startTimestamp` to the timestamp of transfering.
            // - `burned` to `false`.
            // - `nextInitialized` to `true`.
            _packedOwnerships[tokenId] =
                _addressToUint256(to) |
                (block.timestamp << BITPOS_START_TIMESTAMP) |
                BITMASK_NEXT_INITIALIZED;

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

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

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

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

        address from = address(uint160(prevOwnershipPacked));

        if (approvalCheck) {
            bool isApprovedOrOwner = (_msgSenderERC721A() == from ||
                isApprovedForAll(from, _msgSenderERC721A()) ||
                getApproved(tokenId) == _msgSenderERC721A());

            if (!isApprovedOrOwner) revert TransferCallerNotOwnerNorApproved();
        }

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

        // Clear approvals from the previous owner.
        delete _tokenApprovals[tokenId];

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

            // Updates:
            // - `address` to the last owner.
            // - `startTimestamp` to the timestamp of burning.
            // - `burned` to `true`.
            // - `nextInitialized` to `true`.
            _packedOwnerships[tokenId] =
                _addressToUint256(from) |
                (block.timestamp << BITPOS_START_TIMESTAMP) |
                BITMASK_BURNED |
                BITMASK_NEXT_INITIALIZED;

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

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

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

    /**
     * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target 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 _checkContractOnERC721Received(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) private returns (bool) {
        try
            ERC721A__IERC721Receiver(to).onERC721Received(
                _msgSenderERC721A(),
                from,
                tokenId,
                _data
            )
        returns (bytes4 retval) {
            return
                retval ==
                ERC721A__IERC721Receiver(to).onERC721Received.selector;
        } catch (bytes memory reason) {
            if (reason.length == 0) {
                revert TransferToNonERC721ReceiverImplementer();
            } else {
                assembly {
                    revert(add(32, reason), mload(reason))
                }
            }
        }
    }

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

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

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

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function _toString(uint256 value)
        internal
        pure
        returns (string memory ptr)
    {
        assembly {
            // The maximum value of a uint256 contains 78 digits (1 byte per digit),
            // but we allocate 128 bytes to keep the free memory pointer 32-byte word aliged.
            // We will need 1 32-byte word to store the length,
            // and 3 32-byte words to store a maximum of 78 digits. Total: 32 + 3 * 32 = 128.
            ptr := add(mload(0x40), 128)
            // Update the free memory pointer to allocate.
            mstore(0x40, ptr)

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

            // We write the string from the rightmost digit to the leftmost digit.
            // The following is essentially a do-while loop that also handles the zero case.
            // Costs a bit more than early returning for the zero case,
            // but cheaper in terms of deployment and overall runtime costs.
            for {
                // Initialize and perform the first pass without check.
                let temp := value
                // Move the pointer 1 byte leftwards to point to an empty character slot.
                ptr := sub(ptr, 1)
                // Write the character to the pointer. 48 is the ASCII index of '0'.
                mstore8(ptr, add(48, mod(temp, 10)))
                temp := div(temp, 10)
            } temp {
                // Keep dividing `temp` until zero.
                temp := div(temp, 10)
            } {
                // Body of the for loop.
                ptr := sub(ptr, 1)
                mstore8(ptr, add(48, mod(temp, 10)))
            }

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

// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Strings.sol

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

pragma solidity ^0.8.0;

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

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        // 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);
    }

    /**
     * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.
     */
    function toHexString(address addr) internal pure returns (string memory) {
        return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
    }
}

// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Context.sol

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

pragma solidity ^0.8.0;

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

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

// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol

// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)

pragma solidity ^0.8.0;

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

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

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

    /**
     * @dev 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 {
        _transferOwnership(address(0));
    }

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

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

// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Address.sol

// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)

pragma solidity ^0.8.1;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     *
     * [IMPORTANT]
     * ====
     * You shouldn't rely on `isContract` to protect against flash loan attacks!
     *
     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
     * constructor.
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize/address.code.length, which returns 0
        // for contracts in construction, since the code is only stored at the end
        // of the constructor execution.

        return account.code.length > 0;
    }

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

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

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

// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)

pragma solidity ^0.8.0;

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

// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/introspection/IERC165.sol

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

pragma solidity ^0.8.0;

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

// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/introspection/ERC165.sol

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

pragma solidity ^0.8.0;

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

// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/IERC721.sol

// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

    /**
     * @dev Transfers `tokenId` token from `from` to `to`.
     *
     * WARNING: 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 Approve or remove `operator` as an operator for the caller.
     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
     *
     * Requirements:
     *
     * - The `operator` cannot be the caller.
     *
     * Emits an {ApprovalForAll} event.
     */
    function setApprovalForAll(address operator, bool _approved) external;

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

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

// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/extensions/IERC721Metadata.sol

// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)

pragma solidity ^0.8.0;

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

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

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

// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/ERC721.sol

// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/ERC721.sol)

pragma solidity ^0.8.0;

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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

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

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

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

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

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

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

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId)
        public
        view
        virtual
        override
        returns (address)
    {
        address owner = _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 overridden in child contracts.
     */
    function _baseURI() internal view virtual returns (string memory) {
        return "";
    }

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

        require(
            _msgSender() == owner || isApprovedForAll(owner, _msgSender()),
            "ERC721: approve caller is not 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
    {
        _setApprovalForAll(_msgSender(), operator, approved);
    }

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

    /**
     * @dev See {IERC721-transferFrom}.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        //solhint-disable-next-line max-line-length
        require(
            _isApprovedOrOwner(_msgSender(), tokenId),
            "ERC721: 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 ||
            isApprovedForAll(owner, spender) ||
            getApproved(tokenId) == spender);
    }

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

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

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

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

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

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

        _afterTokenTransfer(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);

        _afterTokenTransfer(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 from incorrect owner"
        );
        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);

        _afterTokenTransfer(from, to, tokenId);
    }

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

    /**
     * @dev Approve `operator` to operate on all of `owner` tokens
     *
     * Emits an {ApprovalForAll} event.
     */
    function _setApprovalForAll(
        address owner,
        address operator,
        bool approved
    ) internal virtual {
        require(owner != operator, "ERC721: approve to caller");
        _operatorApprovals[owner][operator] = approved;
        emit ApprovalForAll(owner, operator, approved);
    }

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

    /**
     * @dev Hook that is called after any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _afterTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual {}
}

pragma solidity ^0.8.0;

contract SorcererTown is
    ERC721A,
    Ownable,
    ReentrancyGuard,
    DefaultOperatorFilterer
{
    using Strings for uint256;

    string private baseURI;

    uint256 public price = 0.0098 ether;

    uint256 public maxPerWallet = 3;

    uint256 public maxSupply = 999;

    bytes32 whitelistRoot;

    string public hiddenURI =
        "ipfs://bafybeifw5ltdvs7ve6baha42wc5lybdc6fly57t3rpoz57s6v7vz374lqu/sorcerer.json";

    bool public revealed = false;
    bool public whitelistSale = true;
    bool public publicEnabled = false;

    constructor() ERC721A("SorcererTown", "ST") {}

    modifier callerIsUser() {
        require(tx.origin == msg.sender, "The caller is another contract");
        _;
    }

    function whitelistMint(bytes32[] calldata _merkleProof, uint256 count)
        external
        payable
        nonReentrant
    {
        bytes32 leaf = keccak256(abi.encodePacked(msg.sender));
        require(msg.value >= price * count, "Please send the exact amount.");
        require(
            MerkleProof.verify(_merkleProof, whitelistRoot, leaf),
            "Incorrect Whitelist Proof"
        );
        require(totalSupply() + count <= maxSupply, "No more");
        require(count > 0, "Please enter a number");
        require(whitelistSale, "Minting is not live yet");
        require(
            _numberMinted(msg.sender) + count <= maxPerWallet,
            "Can not mint more than 3"
        );

        _mint(msg.sender, count);
    }

    function publicMint(uint256 count) external payable nonReentrant {
        require(msg.value >= count * price, "Please send the exact amount.");
        require(totalSupply() + count <= maxSupply, "No more NFT left");
        require(
            _numberMinted(msg.sender) + count <= maxPerWallet,
            "Can not mint more than 3"
        );
        require(count > 0, "Please enter a number");
        require(publicEnabled, "Minting is not live yet");

        _mint(msg.sender, count);
    }

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

    function _mintedAmount(address minter) external view returns (uint256) {
        return _numberMinted(minter);
    }

    function tokenURI(uint256 tokenId)
        public
        view
        virtual
        override
        returns (string memory)
    {
        require(
            _exists(tokenId),
            "ERC721AMetadata: URI query for nonexistent token"
        );
        if (revealed == false) {
            return hiddenURI;
        }

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

    function setBaseURI(string memory uri) public onlyOwner {
        baseURI = uri;
    }

    function setPreSaleRoot(bytes32 _presaleRoot) external onlyOwner {
        whitelistRoot = _presaleRoot;
    }

    function setMaxPerWallet(uint256 amount) external onlyOwner {
        maxPerWallet = amount;
    }

    function setPrice(uint256 _newPrice) external onlyOwner {
        price = _newPrice;
    }

    function setMaxSupply(uint256 _newSupply) external onlyOwner {
        maxSupply = _newSupply;
    }

    function flipWhitelist(bool status) external onlyOwner {
        whitelistSale = status;
    }

    function flipPublic(bool status) external onlyOwner {
        publicEnabled = status;
    }

    function reveal() external onlyOwner {
        revealed = !revealed;
    }

    function batchmint(uint256 _mintAmount, address destination)
        public
        onlyOwner
    {
        require(_mintAmount > 0, "need to mint at least 1 NFT");
        uint256 supply = totalSupply();
        require(supply + _mintAmount <= maxSupply, "max NFT limit exceeded");

        _safeMint(destination, _mintAmount);
    }

    function withdraw() external onlyOwner {
        (bool success, ) = payable(msg.sender).call{
            value: address(this).balance
        }("");
        require(success, "Transfer failed.");
    }

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

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

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

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"ApprovalToCurrentOwner","type":"error"},{"inputs":[],"name":"ApproveToCaller","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"OperatorNotAllowed","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"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":[{"internalType":"address","name":"minter","type":"address"}],"name":"_mintedAmount","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":"uint256","name":"_mintAmount","type":"uint256"},{"internalType":"address","name":"destination","type":"address"}],"name":"batchmint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"status","type":"bool"}],"name":"flipPublic","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"status","type":"bool"}],"name":"flipWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"hiddenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxPerWallet","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"price","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"publicEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"count","type":"uint256"}],"name":"publicMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"reveal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"revealed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"uri","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"setMaxPerWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newSupply","type":"uint256"}],"name":"setMaxSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_presaleRoot","type":"bytes32"}],"name":"setPreSaleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newPrice","type":"uint256"}],"name":"setPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"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":[{"internalType":"bytes32[]","name":"_merkleProof","type":"bytes32[]"},{"internalType":"uint256","name":"count","type":"uint256"}],"name":"whitelistMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"whitelistSale","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040526622d10c4ecc8000600b556003600c556103e7600d55604051806080016040528060508152602001620051ec60509139600f9081620000449190620006d5565b506000601060006101000a81548160ff0219169083151502179055506001601060016101000a81548160ff0219169083151502179055506000601060026101000a81548160ff021916908315150217905550348015620000a357600080fd5b50733cc6cdda760b79bafa08df41ecfa224f810dceb660016040518060400160405280600c81526020017f536f726365726572546f776e00000000000000000000000000000000000000008152506040518060400160405280600281526020017f53540000000000000000000000000000000000000000000000000000000000008152508160029081620001389190620006d5565b5080600390816200014a9190620006d5565b506200015b6200038860201b60201c565b600081905550505062000183620001776200038d60201b60201c565b6200039560201b60201c565b600160098190555060006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b11156200038057801562000246576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff16637d3e3dbe30846040518363ffffffff1660e01b81526004016200020c92919062000801565b600060405180830381600087803b1580156200022757600080fd5b505af11580156200023c573d6000803e3d6000fd5b505050506200037f565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161462000300576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663a0af290330846040518363ffffffff1660e01b8152600401620002c692919062000801565b600060405180830381600087803b158015620002e157600080fd5b505af1158015620002f6573d6000803e3d6000fd5b505050506200037e565b6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff16634420e486306040518263ffffffff1660e01b81526004016200034991906200082e565b600060405180830381600087803b1580156200036457600080fd5b505af115801562000379573d6000803e3d6000fd5b505050505b5b5b50506200084b565b600090565b600033905090565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680620004dd57607f821691505b602082108103620004f357620004f262000495565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026200055d7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826200051e565b6200056986836200051e565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b6000620005b6620005b0620005aa8462000581565b6200058b565b62000581565b9050919050565b6000819050919050565b620005d28362000595565b620005ea620005e182620005bd565b8484546200052b565b825550505050565b600090565b62000601620005f2565b6200060e818484620005c7565b505050565b5b8181101562000636576200062a600082620005f7565b60018101905062000614565b5050565b601f82111562000685576200064f81620004f9565b6200065a846200050e565b810160208510156200066a578190505b6200068262000679856200050e565b83018262000613565b50505b505050565b600082821c905092915050565b6000620006aa600019846008026200068a565b1980831691505092915050565b6000620006c5838362000697565b9150826002028217905092915050565b620006e0826200045b565b67ffffffffffffffff811115620006fc57620006fb62000466565b5b620007088254620004c4565b620007158282856200063a565b600060209050601f8311600181146200074d576000841562000738578287015190505b620007448582620006b7565b865550620007b4565b601f1984166200075d86620004f9565b60005b82811015620007875784890151825560018201915060208501945060208101905062000760565b86831015620007a75784890151620007a3601f89168262000697565b8355505b6001600288020188555050505b505050505050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620007e982620007bc565b9050919050565b620007fb81620007dc565b82525050565b6000604082019050620008186000830185620007f0565b620008276020830184620007f0565b9392505050565b6000602082019050620008456000830184620007f0565b92915050565b614991806200085b6000396000f3fe60806040526004361061021a5760003560e01c80637bcf36ae11610123578063b88d4fde116100ab578063e985e9c51161006f578063e985e9c514610769578063ed64892b146107a6578063f2fde38b146107e3578063f55e7fc71461080c578063fe042d49146108355761021a565b8063b88d4fde14610686578063bbb81279146106af578063c87b56dd146106d8578063d5abeb0114610715578063e268e4d3146107405761021a565b806395d89b41116100f257806395d89b41146105c55780639b001f45146105f0578063a035b1fe1461061b578063a22cb46514610646578063a475b5dd1461066f5761021a565b80637bcf36ae1461051d5780638cc54e7f146105465780638da5cb5b1461057157806391b7f5ed1461059c5761021a565b80633ccfd60b116101a657806355f804b31161017557806355f804b31461043a5780636352211e146104635780636f8b44b0146104a057806370a08231146104c9578063715018a6146105065761021a565b80633ccfd60b146103a457806342842e0e146103bb578063453c2310146103e4578063518302271461040f5761021a565b806318160ddd116101ed57806318160ddd146102ed57806323b872dd146103185780632904e6d9146103415780632db115441461035d57806331ffd6f1146103795761021a565b806301ffc9a71461021f57806306fdde031461025c578063081812fc14610287578063095ea7b3146102c4575b600080fd5b34801561022b57600080fd5b50610246600480360381019061024191906133f2565b61085e565b604051610253919061343a565b60405180910390f35b34801561026857600080fd5b506102716108f0565b60405161027e91906134e5565b60405180910390f35b34801561029357600080fd5b506102ae60048036038101906102a9919061353d565b610982565b6040516102bb91906135ab565b60405180910390f35b3480156102d057600080fd5b506102eb60048036038101906102e691906135f2565b6109fe565b005b3480156102f957600080fd5b50610302610ba4565b60405161030f9190613641565b60405180910390f35b34801561032457600080fd5b5061033f600480360381019061033a919061365c565b610bbb565b005b61035b60048036038101906103569190613714565b610d9d565b005b6103776004803603810190610372919061353d565b61104b565b005b34801561038557600080fd5b5061038e61123e565b60405161039b919061343a565b60405180910390f35b3480156103b057600080fd5b506103b9611251565b005b3480156103c757600080fd5b506103e260048036038101906103dd919061365c565b61137c565b005b3480156103f057600080fd5b506103f961155e565b6040516104069190613641565b60405180910390f35b34801561041b57600080fd5b50610424611564565b604051610431919061343a565b60405180910390f35b34801561044657600080fd5b50610461600480360381019061045c91906138a4565b611577565b005b34801561046f57600080fd5b5061048a6004803603810190610485919061353d565b611606565b60405161049791906135ab565b60405180910390f35b3480156104ac57600080fd5b506104c760048036038101906104c2919061353d565b611618565b005b3480156104d557600080fd5b506104f060048036038101906104eb91906138ed565b61169e565b6040516104fd9190613641565b60405180910390f35b34801561051257600080fd5b5061051b611756565b005b34801561052957600080fd5b50610544600480360381019061053f919061391a565b6117de565b005b34801561055257600080fd5b5061055b611908565b60405161056891906134e5565b60405180910390f35b34801561057d57600080fd5b50610586611996565b60405161059391906135ab565b60405180910390f35b3480156105a857600080fd5b506105c360048036038101906105be919061353d565b6119c0565b005b3480156105d157600080fd5b506105da611a46565b6040516105e791906134e5565b60405180910390f35b3480156105fc57600080fd5b50610605611ad8565b604051610612919061343a565b60405180910390f35b34801561062757600080fd5b50610630611aeb565b60405161063d9190613641565b60405180910390f35b34801561065257600080fd5b5061066d60048036038101906106689190613986565b611af1565b005b34801561067b57600080fd5b50610684611c68565b005b34801561069257600080fd5b506106ad60048036038101906106a89190613a67565b611d10565b005b3480156106bb57600080fd5b506106d660048036038101906106d19190613aea565b611ef5565b005b3480156106e457600080fd5b506106ff60048036038101906106fa919061353d565b611f8e565b60405161070c91906134e5565b60405180910390f35b34801561072157600080fd5b5061072a6120e3565b6040516107379190613641565b60405180910390f35b34801561074c57600080fd5b506107676004803603810190610762919061353d565b6120e9565b005b34801561077557600080fd5b50610790600480360381019061078b9190613b17565b61216f565b60405161079d919061343a565b60405180910390f35b3480156107b257600080fd5b506107cd60048036038101906107c891906138ed565b612203565b6040516107da9190613641565b60405180910390f35b3480156107ef57600080fd5b5061080a600480360381019061080591906138ed565b612215565b005b34801561081857600080fd5b50610833600480360381019061082e9190613aea565b61230c565b005b34801561084157600080fd5b5061085c60048036038101906108579190613b8d565b6123a5565b005b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806108b957506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806108e95750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b6060600280546108ff90613be9565b80601f016020809104026020016040519081016040528092919081815260200182805461092b90613be9565b80156109785780601f1061094d57610100808354040283529160200191610978565b820191906000526020600020905b81548152906001019060200180831161095b57829003601f168201915b5050505050905090565b600061098d8261242b565b6109c3576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610a098261248a565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610a70576040517f943f7b8c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610a8f612556565b73ffffffffffffffffffffffffffffffffffffffff1614610af257610abb81610ab6612556565b61216f565b610af1576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b6000610bae61255e565b6001546000540303905090565b8260006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115610d8b573373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610c2d57610c28848484612563565b610d97565b6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430336040518363ffffffff1660e01b8152600401610c76929190613c1a565b602060405180830381865afa158015610c93573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cb79190613c58565b8015610d4957506daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430836040518363ffffffff1660e01b8152600401610d07929190613c1a565b602060405180830381865afa158015610d24573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d489190613c58565b5b610d8a57336040517fede71dcc000000000000000000000000000000000000000000000000000000008152600401610d8191906135ab565b60405180910390fd5b5b610d96848484612563565b5b50505050565b600260095403610de2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dd990613cd1565b60405180910390fd5b6002600981905550600033604051602001610dfd9190613d39565b60405160208183030381529060405280519060200120905081600b54610e239190613d83565b341015610e65576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e5c90613e11565b60405180910390fd5b610eb3848480806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050600e5483612573565b610ef2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ee990613e7d565b60405180910390fd5b600d5482610efe610ba4565b610f089190613e9d565b1115610f49576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f4090613f1d565b60405180910390fd5b60008211610f8c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f8390613f89565b60405180910390fd5b601060019054906101000a900460ff16610fdb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fd290613ff5565b60405180910390fd5b600c5482610fe83361258a565b610ff29190613e9d565b1115611033576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161102a90614061565b60405180910390fd5b61103d33836125e1565b506001600981905550505050565b600260095403611090576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161108790613cd1565b60405180910390fd5b6002600981905550600b54816110a69190613d83565b3410156110e8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110df90613e11565b60405180910390fd5b600d54816110f4610ba4565b6110fe9190613e9d565b111561113f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611136906140cd565b60405180910390fd5b600c548161114c3361258a565b6111569190613e9d565b1115611197576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161118e90614061565b60405180910390fd5b600081116111da576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111d190613f89565b60405180910390fd5b601060029054906101000a900460ff16611229576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161122090613ff5565b60405180910390fd5b61123333826125e1565b600160098190555050565b601060019054906101000a900460ff1681565b6112596127b3565b73ffffffffffffffffffffffffffffffffffffffff16611277611996565b73ffffffffffffffffffffffffffffffffffffffff16146112cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112c490614139565b60405180910390fd5b60003373ffffffffffffffffffffffffffffffffffffffff16476040516112f39061418a565b60006040518083038185875af1925050503d8060008114611330576040519150601f19603f3d011682016040523d82523d6000602084013e611335565b606091505b5050905080611379576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611370906141eb565b60405180910390fd5b50565b8260006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b111561154c573373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036113ee576113e98484846127bb565b611558565b6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430336040518363ffffffff1660e01b8152600401611437929190613c1a565b602060405180830381865afa158015611454573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114789190613c58565b801561150a57506daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430836040518363ffffffff1660e01b81526004016114c8929190613c1a565b602060405180830381865afa1580156114e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115099190613c58565b5b61154b57336040517fede71dcc00000000000000000000000000000000000000000000000000000000815260040161154291906135ab565b60405180910390fd5b5b6115578484846127bb565b5b50505050565b600c5481565b601060009054906101000a900460ff1681565b61157f6127b3565b73ffffffffffffffffffffffffffffffffffffffff1661159d611996565b73ffffffffffffffffffffffffffffffffffffffff16146115f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115ea90614139565b60405180910390fd5b80600a908161160291906143b7565b5050565b60006116118261248a565b9050919050565b6116206127b3565b73ffffffffffffffffffffffffffffffffffffffff1661163e611996565b73ffffffffffffffffffffffffffffffffffffffff1614611694576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161168b90614139565b60405180910390fd5b80600d8190555050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611705576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b61175e6127b3565b73ffffffffffffffffffffffffffffffffffffffff1661177c611996565b73ffffffffffffffffffffffffffffffffffffffff16146117d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117c990614139565b60405180910390fd5b6117dc60006127db565b565b6117e66127b3565b73ffffffffffffffffffffffffffffffffffffffff16611804611996565b73ffffffffffffffffffffffffffffffffffffffff161461185a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161185190614139565b60405180910390fd5b6000821161189d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611894906144d5565b60405180910390fd5b60006118a7610ba4565b9050600d5483826118b89190613e9d565b11156118f9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118f090614541565b60405180910390fd5b61190382846128a1565b505050565b600f805461191590613be9565b80601f016020809104026020016040519081016040528092919081815260200182805461194190613be9565b801561198e5780601f106119635761010080835404028352916020019161198e565b820191906000526020600020905b81548152906001019060200180831161197157829003601f168201915b505050505081565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6119c86127b3565b73ffffffffffffffffffffffffffffffffffffffff166119e6611996565b73ffffffffffffffffffffffffffffffffffffffff1614611a3c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a3390614139565b60405180910390fd5b80600b8190555050565b606060038054611a5590613be9565b80601f0160208091040260200160405190810160405280929190818152602001828054611a8190613be9565b8015611ace5780601f10611aa357610100808354040283529160200191611ace565b820191906000526020600020905b815481529060010190602001808311611ab157829003601f168201915b5050505050905090565b601060029054906101000a900460ff1681565b600b5481565b611af9612556565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611b5d576040517fb06307db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060076000611b6a612556565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16611c17612556565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051611c5c919061343a565b60405180910390a35050565b611c706127b3565b73ffffffffffffffffffffffffffffffffffffffff16611c8e611996565b73ffffffffffffffffffffffffffffffffffffffff1614611ce4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cdb90614139565b60405180910390fd5b601060009054906101000a900460ff1615601060006101000a81548160ff021916908315150217905550565b8360006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115611ee1573373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611d8357611d7e858585856128bf565b611eee565b6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430336040518363ffffffff1660e01b8152600401611dcc929190613c1a565b602060405180830381865afa158015611de9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e0d9190613c58565b8015611e9f57506daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430836040518363ffffffff1660e01b8152600401611e5d929190613c1a565b602060405180830381865afa158015611e7a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e9e9190613c58565b5b611ee057336040517fede71dcc000000000000000000000000000000000000000000000000000000008152600401611ed791906135ab565b60405180910390fd5b5b611eed858585856128bf565b5b5050505050565b611efd6127b3565b73ffffffffffffffffffffffffffffffffffffffff16611f1b611996565b73ffffffffffffffffffffffffffffffffffffffff1614611f71576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f6890614139565b60405180910390fd5b80601060016101000a81548160ff02191690831515021790555050565b6060611f998261242b565b611fd8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fcf906145d3565b60405180910390fd5b60001515601060009054906101000a900460ff1615150361208557600f805461200090613be9565b80601f016020809104026020016040519081016040528092919081815260200182805461202c90613be9565b80156120795780601f1061204e57610100808354040283529160200191612079565b820191906000526020600020905b81548152906001019060200180831161205c57829003601f168201915b505050505090506120de565b600061208f612932565b905060008151116120af57604051806020016040528060008152506120da565b806120b9846129c4565b6040516020016120ca92919061467b565b6040516020818303038152906040525b9150505b919050565b600d5481565b6120f16127b3565b73ffffffffffffffffffffffffffffffffffffffff1661210f611996565b73ffffffffffffffffffffffffffffffffffffffff1614612165576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161215c90614139565b60405180910390fd5b80600c8190555050565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b600061220e8261258a565b9050919050565b61221d6127b3565b73ffffffffffffffffffffffffffffffffffffffff1661223b611996565b73ffffffffffffffffffffffffffffffffffffffff1614612291576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161228890614139565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612300576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122f79061471c565b60405180910390fd5b612309816127db565b50565b6123146127b3565b73ffffffffffffffffffffffffffffffffffffffff16612332611996565b73ffffffffffffffffffffffffffffffffffffffff1614612388576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161237f90614139565b60405180910390fd5b80601060026101000a81548160ff02191690831515021790555050565b6123ad6127b3565b73ffffffffffffffffffffffffffffffffffffffff166123cb611996565b73ffffffffffffffffffffffffffffffffffffffff1614612421576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161241890614139565b60405180910390fd5b80600e8190555050565b60008161243661255e565b11158015612445575060005482105b8015612483575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b6000808290508061249961255e565b1161251f5760005481101561251e5760006004600083815260200190815260200160002054905060007c010000000000000000000000000000000000000000000000000000000082160361251c575b600081036125125760046000836001900393508381526020019081526020016000205490506124e8565b8092505050612551565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b600033905090565b600090565b61256e838383612b24565b505050565b6000826125808584612ecb565b1490509392505050565b600067ffffffffffffffff6040600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054901c169050919050565b600080549050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361264d576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008203612687576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6126946000848385612f21565b600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555060e16126f960018414612f27565b901b60a042901b61270985612f31565b171760046000838152602001908152602001600020819055506000819050600083820190505b818060010192508573ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a480821061272f578160008190555050506127ae6000848385612f3b565b505050565b600033905090565b6127d683838360405180602001604052806000815250611d10565b505050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6128bb828260405180602001604052806000815250612f41565b5050565b6128ca848484612b24565b60008373ffffffffffffffffffffffffffffffffffffffff163b1461292c576128f5848484846131f4565b61292b576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b6060600a805461294190613be9565b80601f016020809104026020016040519081016040528092919081815260200182805461296d90613be9565b80156129ba5780601f1061298f576101008083540402835291602001916129ba565b820191906000526020600020905b81548152906001019060200180831161299d57829003601f168201915b5050505050905090565b606060008203612a0b576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050612b1f565b600082905060005b60008214612a3d578080612a269061473c565b915050600a82612a3691906147b3565b9150612a13565b60008167ffffffffffffffff811115612a5957612a58613779565b5b6040519080825280601f01601f191660200182016040528015612a8b5781602001600182028036833780820191505090505b5090505b60008514612b1857600182612aa491906147e4565b9150600a85612ab39190614818565b6030612abf9190613e9d565b60f81b818381518110612ad557612ad4614849565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a85612b1191906147b3565b9450612a8f565b8093505050505b919050565b6000612b2f8261248a565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614612b96576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008473ffffffffffffffffffffffffffffffffffffffff16612bb7612556565b73ffffffffffffffffffffffffffffffffffffffff161480612be65750612be585612be0612556565b61216f565b5b80612c2b5750612bf4612556565b73ffffffffffffffffffffffffffffffffffffffff16612c1384610982565b73ffffffffffffffffffffffffffffffffffffffff16145b905080612c64576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603612cca576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612cd78585856001612f21565b6006600084815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008154600101919050819055507c020000000000000000000000000000000000000000000000000000000060a042901b612dd486612f31565b1717600460008581526020019081526020016000208190555060007c0200000000000000000000000000000000000000000000000000000000831603612e5c5760006001840190506000600460008381526020019081526020016000205403612e5a576000548114612e59578260046000838152602001908152602001600020819055505b5b505b828473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4612ec48585856001612f3b565b5050505050565b60008082905060005b8451811015612f1657612f0182868381518110612ef457612ef3614849565b5b6020026020010151613344565b91508080612f0e9061473c565b915050612ed4565b508091505092915050565b50505050565b6000819050919050565b6000819050919050565b50505050565b600080549050600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603612fad576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008303612fe7576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612ff46000858386612f21565b600160406001901b178302600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555060e161305960018514612f27565b901b60a042901b61306986612f31565b1717600460008381526020019081526020016000208190555060008190506000848201905060008673ffffffffffffffffffffffffffffffffffffffff163b1461316d575b818673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461311d60008784806001019550876131f4565b613153576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8082106130ae57826000541461316857600080fd5b6131d8565b5b818060010192508673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a480821061316e575b8160008190555050506131ee6000858386612f3b565b50505050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a0261321a612556565b8786866040518563ffffffff1660e01b815260040161323c94939291906148cd565b6020604051808303816000875af192505050801561327857506040513d601f19601f82011682018060405250810190613275919061492e565b60015b6132f1573d80600081146132a8576040519150601f19603f3d011682016040523d82523d6000602084013e6132ad565b606091505b5060008151036132e9576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b600081831061335c57613357828461336f565b613367565b613366838361336f565b5b905092915050565b600082600052816020526040600020905092915050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6133cf8161339a565b81146133da57600080fd5b50565b6000813590506133ec816133c6565b92915050565b60006020828403121561340857613407613390565b5b6000613416848285016133dd565b91505092915050565b60008115159050919050565b6134348161341f565b82525050565b600060208201905061344f600083018461342b565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561348f578082015181840152602081019050613474565b60008484015250505050565b6000601f19601f8301169050919050565b60006134b782613455565b6134c18185613460565b93506134d1818560208601613471565b6134da8161349b565b840191505092915050565b600060208201905081810360008301526134ff81846134ac565b905092915050565b6000819050919050565b61351a81613507565b811461352557600080fd5b50565b60008135905061353781613511565b92915050565b60006020828403121561355357613552613390565b5b600061356184828501613528565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006135958261356a565b9050919050565b6135a58161358a565b82525050565b60006020820190506135c0600083018461359c565b92915050565b6135cf8161358a565b81146135da57600080fd5b50565b6000813590506135ec816135c6565b92915050565b6000806040838503121561360957613608613390565b5b6000613617858286016135dd565b925050602061362885828601613528565b9150509250929050565b61363b81613507565b82525050565b60006020820190506136566000830184613632565b92915050565b60008060006060848603121561367557613674613390565b5b6000613683868287016135dd565b9350506020613694868287016135dd565b92505060406136a586828701613528565b9150509250925092565b600080fd5b600080fd5b600080fd5b60008083601f8401126136d4576136d36136af565b5b8235905067ffffffffffffffff8111156136f1576136f06136b4565b5b60208301915083602082028301111561370d5761370c6136b9565b5b9250929050565b60008060006040848603121561372d5761372c613390565b5b600084013567ffffffffffffffff81111561374b5761374a613395565b5b613757868287016136be565b9350935050602061376a86828701613528565b9150509250925092565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6137b18261349b565b810181811067ffffffffffffffff821117156137d0576137cf613779565b5b80604052505050565b60006137e3613386565b90506137ef82826137a8565b919050565b600067ffffffffffffffff82111561380f5761380e613779565b5b6138188261349b565b9050602081019050919050565b82818337600083830152505050565b6000613847613842846137f4565b6137d9565b90508281526020810184848401111561386357613862613774565b5b61386e848285613825565b509392505050565b600082601f83011261388b5761388a6136af565b5b813561389b848260208601613834565b91505092915050565b6000602082840312156138ba576138b9613390565b5b600082013567ffffffffffffffff8111156138d8576138d7613395565b5b6138e484828501613876565b91505092915050565b60006020828403121561390357613902613390565b5b6000613911848285016135dd565b91505092915050565b6000806040838503121561393157613930613390565b5b600061393f85828601613528565b9250506020613950858286016135dd565b9150509250929050565b6139638161341f565b811461396e57600080fd5b50565b6000813590506139808161395a565b92915050565b6000806040838503121561399d5761399c613390565b5b60006139ab858286016135dd565b92505060206139bc85828601613971565b9150509250929050565b600067ffffffffffffffff8211156139e1576139e0613779565b5b6139ea8261349b565b9050602081019050919050565b6000613a0a613a05846139c6565b6137d9565b905082815260208101848484011115613a2657613a25613774565b5b613a31848285613825565b509392505050565b600082601f830112613a4e57613a4d6136af565b5b8135613a5e8482602086016139f7565b91505092915050565b60008060008060808587031215613a8157613a80613390565b5b6000613a8f878288016135dd565b9450506020613aa0878288016135dd565b9350506040613ab187828801613528565b925050606085013567ffffffffffffffff811115613ad257613ad1613395565b5b613ade87828801613a39565b91505092959194509250565b600060208284031215613b0057613aff613390565b5b6000613b0e84828501613971565b91505092915050565b60008060408385031215613b2e57613b2d613390565b5b6000613b3c858286016135dd565b9250506020613b4d858286016135dd565b9150509250929050565b6000819050919050565b613b6a81613b57565b8114613b7557600080fd5b50565b600081359050613b8781613b61565b92915050565b600060208284031215613ba357613ba2613390565b5b6000613bb184828501613b78565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680613c0157607f821691505b602082108103613c1457613c13613bba565b5b50919050565b6000604082019050613c2f600083018561359c565b613c3c602083018461359c565b9392505050565b600081519050613c528161395a565b92915050565b600060208284031215613c6e57613c6d613390565b5b6000613c7c84828501613c43565b91505092915050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000613cbb601f83613460565b9150613cc682613c85565b602082019050919050565b60006020820190508181036000830152613cea81613cae565b9050919050565b60008160601b9050919050565b6000613d0982613cf1565b9050919050565b6000613d1b82613cfe565b9050919050565b613d33613d2e8261358a565b613d10565b82525050565b6000613d458284613d22565b60148201915081905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000613d8e82613507565b9150613d9983613507565b9250828202613da781613507565b91508282048414831517613dbe57613dbd613d54565b5b5092915050565b7f506c656173652073656e642074686520657861637420616d6f756e742e000000600082015250565b6000613dfb601d83613460565b9150613e0682613dc5565b602082019050919050565b60006020820190508181036000830152613e2a81613dee565b9050919050565b7f496e636f72726563742057686974656c6973742050726f6f6600000000000000600082015250565b6000613e67601983613460565b9150613e7282613e31565b602082019050919050565b60006020820190508181036000830152613e9681613e5a565b9050919050565b6000613ea882613507565b9150613eb383613507565b9250828201905080821115613ecb57613eca613d54565b5b92915050565b7f4e6f206d6f726500000000000000000000000000000000000000000000000000600082015250565b6000613f07600783613460565b9150613f1282613ed1565b602082019050919050565b60006020820190508181036000830152613f3681613efa565b9050919050565b7f506c6561736520656e7465722061206e756d6265720000000000000000000000600082015250565b6000613f73601583613460565b9150613f7e82613f3d565b602082019050919050565b60006020820190508181036000830152613fa281613f66565b9050919050565b7f4d696e74696e67206973206e6f74206c69766520796574000000000000000000600082015250565b6000613fdf601783613460565b9150613fea82613fa9565b602082019050919050565b6000602082019050818103600083015261400e81613fd2565b9050919050565b7f43616e206e6f74206d696e74206d6f7265207468616e20330000000000000000600082015250565b600061404b601883613460565b915061405682614015565b602082019050919050565b6000602082019050818103600083015261407a8161403e565b9050919050565b7f4e6f206d6f7265204e4654206c65667400000000000000000000000000000000600082015250565b60006140b7601083613460565b91506140c282614081565b602082019050919050565b600060208201905081810360008301526140e6816140aa565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000614123602083613460565b915061412e826140ed565b602082019050919050565b6000602082019050818103600083015261415281614116565b9050919050565b600081905092915050565b50565b6000614174600083614159565b915061417f82614164565b600082019050919050565b600061419582614167565b9150819050919050565b7f5472616e73666572206661696c65642e00000000000000000000000000000000600082015250565b60006141d5601083613460565b91506141e08261419f565b602082019050919050565b60006020820190508181036000830152614204816141c8565b9050919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b60006008830261426d7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82614230565b6142778683614230565b95508019841693508086168417925050509392505050565b6000819050919050565b60006142b46142af6142aa84613507565b61428f565b613507565b9050919050565b6000819050919050565b6142ce83614299565b6142e26142da826142bb565b84845461423d565b825550505050565b600090565b6142f76142ea565b6143028184846142c5565b505050565b5b818110156143265761431b6000826142ef565b600181019050614308565b5050565b601f82111561436b5761433c8161420b565b61434584614220565b81016020851015614354578190505b61436861436085614220565b830182614307565b50505b505050565b600082821c905092915050565b600061438e60001984600802614370565b1980831691505092915050565b60006143a7838361437d565b9150826002028217905092915050565b6143c082613455565b67ffffffffffffffff8111156143d9576143d8613779565b5b6143e38254613be9565b6143ee82828561432a565b600060209050601f831160018114614421576000841561440f578287015190505b614419858261439b565b865550614481565b601f19841661442f8661420b565b60005b8281101561445757848901518255600182019150602085019450602081019050614432565b868310156144745784890151614470601f89168261437d565b8355505b6001600288020188555050505b505050505050565b7f6e65656420746f206d696e74206174206c656173742031204e46540000000000600082015250565b60006144bf601b83613460565b91506144ca82614489565b602082019050919050565b600060208201905081810360008301526144ee816144b2565b9050919050565b7f6d6178204e4654206c696d697420657863656564656400000000000000000000600082015250565b600061452b601683613460565b9150614536826144f5565b602082019050919050565b6000602082019050818103600083015261455a8161451e565b9050919050565b7f455243373231414d657461646174613a2055524920717565727920666f72206e60008201527f6f6e6578697374656e7420746f6b656e00000000000000000000000000000000602082015250565b60006145bd603083613460565b91506145c882614561565b604082019050919050565b600060208201905081810360008301526145ec816145b0565b9050919050565b600081905092915050565b600061460982613455565b61461381856145f3565b9350614623818560208601613471565b80840191505092915050565b7f2e6a736f6e000000000000000000000000000000000000000000000000000000600082015250565b60006146656005836145f3565b91506146708261462f565b600582019050919050565b600061468782856145fe565b915061469382846145fe565b915061469e82614658565b91508190509392505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000614706602683613460565b9150614711826146aa565b604082019050919050565b60006020820190508181036000830152614735816146f9565b9050919050565b600061474782613507565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361477957614778613d54565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60006147be82613507565b91506147c983613507565b9250826147d9576147d8614784565b5b828204905092915050565b60006147ef82613507565b91506147fa83613507565b925082820390508181111561481257614811613d54565b5b92915050565b600061482382613507565b915061482e83613507565b92508261483e5761483d614784565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600081519050919050565b600082825260208201905092915050565b600061489f82614878565b6148a98185614883565b93506148b9818560208601613471565b6148c28161349b565b840191505092915050565b60006080820190506148e2600083018761359c565b6148ef602083018661359c565b6148fc6040830185613632565b818103606083015261490e8184614894565b905095945050505050565b600081519050614928816133c6565b92915050565b60006020828403121561494457614943613390565b5b600061495284828501614919565b9150509291505056fea264697066735822122050cc927874ebf95e61426ba4b5062aba891301cbd33ec045ecb0f5ab3d09e22d64736f6c63430008110033697066733a2f2f626166796265696677356c74647673377665366261686134327763356c7962646336666c793537743372706f7a353773367637767a3337346c71752f736f7263657265722e6a736f6e

Deployed Bytecode

0x60806040526004361061021a5760003560e01c80637bcf36ae11610123578063b88d4fde116100ab578063e985e9c51161006f578063e985e9c514610769578063ed64892b146107a6578063f2fde38b146107e3578063f55e7fc71461080c578063fe042d49146108355761021a565b8063b88d4fde14610686578063bbb81279146106af578063c87b56dd146106d8578063d5abeb0114610715578063e268e4d3146107405761021a565b806395d89b41116100f257806395d89b41146105c55780639b001f45146105f0578063a035b1fe1461061b578063a22cb46514610646578063a475b5dd1461066f5761021a565b80637bcf36ae1461051d5780638cc54e7f146105465780638da5cb5b1461057157806391b7f5ed1461059c5761021a565b80633ccfd60b116101a657806355f804b31161017557806355f804b31461043a5780636352211e146104635780636f8b44b0146104a057806370a08231146104c9578063715018a6146105065761021a565b80633ccfd60b146103a457806342842e0e146103bb578063453c2310146103e4578063518302271461040f5761021a565b806318160ddd116101ed57806318160ddd146102ed57806323b872dd146103185780632904e6d9146103415780632db115441461035d57806331ffd6f1146103795761021a565b806301ffc9a71461021f57806306fdde031461025c578063081812fc14610287578063095ea7b3146102c4575b600080fd5b34801561022b57600080fd5b50610246600480360381019061024191906133f2565b61085e565b604051610253919061343a565b60405180910390f35b34801561026857600080fd5b506102716108f0565b60405161027e91906134e5565b60405180910390f35b34801561029357600080fd5b506102ae60048036038101906102a9919061353d565b610982565b6040516102bb91906135ab565b60405180910390f35b3480156102d057600080fd5b506102eb60048036038101906102e691906135f2565b6109fe565b005b3480156102f957600080fd5b50610302610ba4565b60405161030f9190613641565b60405180910390f35b34801561032457600080fd5b5061033f600480360381019061033a919061365c565b610bbb565b005b61035b60048036038101906103569190613714565b610d9d565b005b6103776004803603810190610372919061353d565b61104b565b005b34801561038557600080fd5b5061038e61123e565b60405161039b919061343a565b60405180910390f35b3480156103b057600080fd5b506103b9611251565b005b3480156103c757600080fd5b506103e260048036038101906103dd919061365c565b61137c565b005b3480156103f057600080fd5b506103f961155e565b6040516104069190613641565b60405180910390f35b34801561041b57600080fd5b50610424611564565b604051610431919061343a565b60405180910390f35b34801561044657600080fd5b50610461600480360381019061045c91906138a4565b611577565b005b34801561046f57600080fd5b5061048a6004803603810190610485919061353d565b611606565b60405161049791906135ab565b60405180910390f35b3480156104ac57600080fd5b506104c760048036038101906104c2919061353d565b611618565b005b3480156104d557600080fd5b506104f060048036038101906104eb91906138ed565b61169e565b6040516104fd9190613641565b60405180910390f35b34801561051257600080fd5b5061051b611756565b005b34801561052957600080fd5b50610544600480360381019061053f919061391a565b6117de565b005b34801561055257600080fd5b5061055b611908565b60405161056891906134e5565b60405180910390f35b34801561057d57600080fd5b50610586611996565b60405161059391906135ab565b60405180910390f35b3480156105a857600080fd5b506105c360048036038101906105be919061353d565b6119c0565b005b3480156105d157600080fd5b506105da611a46565b6040516105e791906134e5565b60405180910390f35b3480156105fc57600080fd5b50610605611ad8565b604051610612919061343a565b60405180910390f35b34801561062757600080fd5b50610630611aeb565b60405161063d9190613641565b60405180910390f35b34801561065257600080fd5b5061066d60048036038101906106689190613986565b611af1565b005b34801561067b57600080fd5b50610684611c68565b005b34801561069257600080fd5b506106ad60048036038101906106a89190613a67565b611d10565b005b3480156106bb57600080fd5b506106d660048036038101906106d19190613aea565b611ef5565b005b3480156106e457600080fd5b506106ff60048036038101906106fa919061353d565b611f8e565b60405161070c91906134e5565b60405180910390f35b34801561072157600080fd5b5061072a6120e3565b6040516107379190613641565b60405180910390f35b34801561074c57600080fd5b506107676004803603810190610762919061353d565b6120e9565b005b34801561077557600080fd5b50610790600480360381019061078b9190613b17565b61216f565b60405161079d919061343a565b60405180910390f35b3480156107b257600080fd5b506107cd60048036038101906107c891906138ed565b612203565b6040516107da9190613641565b60405180910390f35b3480156107ef57600080fd5b5061080a600480360381019061080591906138ed565b612215565b005b34801561081857600080fd5b50610833600480360381019061082e9190613aea565b61230c565b005b34801561084157600080fd5b5061085c60048036038101906108579190613b8d565b6123a5565b005b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806108b957506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806108e95750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b6060600280546108ff90613be9565b80601f016020809104026020016040519081016040528092919081815260200182805461092b90613be9565b80156109785780601f1061094d57610100808354040283529160200191610978565b820191906000526020600020905b81548152906001019060200180831161095b57829003601f168201915b5050505050905090565b600061098d8261242b565b6109c3576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610a098261248a565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610a70576040517f943f7b8c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610a8f612556565b73ffffffffffffffffffffffffffffffffffffffff1614610af257610abb81610ab6612556565b61216f565b610af1576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b6000610bae61255e565b6001546000540303905090565b8260006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115610d8b573373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610c2d57610c28848484612563565b610d97565b6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430336040518363ffffffff1660e01b8152600401610c76929190613c1a565b602060405180830381865afa158015610c93573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cb79190613c58565b8015610d4957506daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430836040518363ffffffff1660e01b8152600401610d07929190613c1a565b602060405180830381865afa158015610d24573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d489190613c58565b5b610d8a57336040517fede71dcc000000000000000000000000000000000000000000000000000000008152600401610d8191906135ab565b60405180910390fd5b5b610d96848484612563565b5b50505050565b600260095403610de2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dd990613cd1565b60405180910390fd5b6002600981905550600033604051602001610dfd9190613d39565b60405160208183030381529060405280519060200120905081600b54610e239190613d83565b341015610e65576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e5c90613e11565b60405180910390fd5b610eb3848480806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050600e5483612573565b610ef2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ee990613e7d565b60405180910390fd5b600d5482610efe610ba4565b610f089190613e9d565b1115610f49576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f4090613f1d565b60405180910390fd5b60008211610f8c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f8390613f89565b60405180910390fd5b601060019054906101000a900460ff16610fdb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fd290613ff5565b60405180910390fd5b600c5482610fe83361258a565b610ff29190613e9d565b1115611033576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161102a90614061565b60405180910390fd5b61103d33836125e1565b506001600981905550505050565b600260095403611090576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161108790613cd1565b60405180910390fd5b6002600981905550600b54816110a69190613d83565b3410156110e8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110df90613e11565b60405180910390fd5b600d54816110f4610ba4565b6110fe9190613e9d565b111561113f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611136906140cd565b60405180910390fd5b600c548161114c3361258a565b6111569190613e9d565b1115611197576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161118e90614061565b60405180910390fd5b600081116111da576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111d190613f89565b60405180910390fd5b601060029054906101000a900460ff16611229576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161122090613ff5565b60405180910390fd5b61123333826125e1565b600160098190555050565b601060019054906101000a900460ff1681565b6112596127b3565b73ffffffffffffffffffffffffffffffffffffffff16611277611996565b73ffffffffffffffffffffffffffffffffffffffff16146112cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112c490614139565b60405180910390fd5b60003373ffffffffffffffffffffffffffffffffffffffff16476040516112f39061418a565b60006040518083038185875af1925050503d8060008114611330576040519150601f19603f3d011682016040523d82523d6000602084013e611335565b606091505b5050905080611379576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611370906141eb565b60405180910390fd5b50565b8260006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b111561154c573373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036113ee576113e98484846127bb565b611558565b6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430336040518363ffffffff1660e01b8152600401611437929190613c1a565b602060405180830381865afa158015611454573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114789190613c58565b801561150a57506daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430836040518363ffffffff1660e01b81526004016114c8929190613c1a565b602060405180830381865afa1580156114e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115099190613c58565b5b61154b57336040517fede71dcc00000000000000000000000000000000000000000000000000000000815260040161154291906135ab565b60405180910390fd5b5b6115578484846127bb565b5b50505050565b600c5481565b601060009054906101000a900460ff1681565b61157f6127b3565b73ffffffffffffffffffffffffffffffffffffffff1661159d611996565b73ffffffffffffffffffffffffffffffffffffffff16146115f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115ea90614139565b60405180910390fd5b80600a908161160291906143b7565b5050565b60006116118261248a565b9050919050565b6116206127b3565b73ffffffffffffffffffffffffffffffffffffffff1661163e611996565b73ffffffffffffffffffffffffffffffffffffffff1614611694576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161168b90614139565b60405180910390fd5b80600d8190555050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611705576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b61175e6127b3565b73ffffffffffffffffffffffffffffffffffffffff1661177c611996565b73ffffffffffffffffffffffffffffffffffffffff16146117d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117c990614139565b60405180910390fd5b6117dc60006127db565b565b6117e66127b3565b73ffffffffffffffffffffffffffffffffffffffff16611804611996565b73ffffffffffffffffffffffffffffffffffffffff161461185a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161185190614139565b60405180910390fd5b6000821161189d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611894906144d5565b60405180910390fd5b60006118a7610ba4565b9050600d5483826118b89190613e9d565b11156118f9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118f090614541565b60405180910390fd5b61190382846128a1565b505050565b600f805461191590613be9565b80601f016020809104026020016040519081016040528092919081815260200182805461194190613be9565b801561198e5780601f106119635761010080835404028352916020019161198e565b820191906000526020600020905b81548152906001019060200180831161197157829003601f168201915b505050505081565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6119c86127b3565b73ffffffffffffffffffffffffffffffffffffffff166119e6611996565b73ffffffffffffffffffffffffffffffffffffffff1614611a3c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a3390614139565b60405180910390fd5b80600b8190555050565b606060038054611a5590613be9565b80601f0160208091040260200160405190810160405280929190818152602001828054611a8190613be9565b8015611ace5780601f10611aa357610100808354040283529160200191611ace565b820191906000526020600020905b815481529060010190602001808311611ab157829003601f168201915b5050505050905090565b601060029054906101000a900460ff1681565b600b5481565b611af9612556565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611b5d576040517fb06307db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060076000611b6a612556565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16611c17612556565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051611c5c919061343a565b60405180910390a35050565b611c706127b3565b73ffffffffffffffffffffffffffffffffffffffff16611c8e611996565b73ffffffffffffffffffffffffffffffffffffffff1614611ce4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cdb90614139565b60405180910390fd5b601060009054906101000a900460ff1615601060006101000a81548160ff021916908315150217905550565b8360006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115611ee1573373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611d8357611d7e858585856128bf565b611eee565b6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430336040518363ffffffff1660e01b8152600401611dcc929190613c1a565b602060405180830381865afa158015611de9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e0d9190613c58565b8015611e9f57506daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430836040518363ffffffff1660e01b8152600401611e5d929190613c1a565b602060405180830381865afa158015611e7a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e9e9190613c58565b5b611ee057336040517fede71dcc000000000000000000000000000000000000000000000000000000008152600401611ed791906135ab565b60405180910390fd5b5b611eed858585856128bf565b5b5050505050565b611efd6127b3565b73ffffffffffffffffffffffffffffffffffffffff16611f1b611996565b73ffffffffffffffffffffffffffffffffffffffff1614611f71576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f6890614139565b60405180910390fd5b80601060016101000a81548160ff02191690831515021790555050565b6060611f998261242b565b611fd8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fcf906145d3565b60405180910390fd5b60001515601060009054906101000a900460ff1615150361208557600f805461200090613be9565b80601f016020809104026020016040519081016040528092919081815260200182805461202c90613be9565b80156120795780601f1061204e57610100808354040283529160200191612079565b820191906000526020600020905b81548152906001019060200180831161205c57829003601f168201915b505050505090506120de565b600061208f612932565b905060008151116120af57604051806020016040528060008152506120da565b806120b9846129c4565b6040516020016120ca92919061467b565b6040516020818303038152906040525b9150505b919050565b600d5481565b6120f16127b3565b73ffffffffffffffffffffffffffffffffffffffff1661210f611996565b73ffffffffffffffffffffffffffffffffffffffff1614612165576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161215c90614139565b60405180910390fd5b80600c8190555050565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b600061220e8261258a565b9050919050565b61221d6127b3565b73ffffffffffffffffffffffffffffffffffffffff1661223b611996565b73ffffffffffffffffffffffffffffffffffffffff1614612291576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161228890614139565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612300576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122f79061471c565b60405180910390fd5b612309816127db565b50565b6123146127b3565b73ffffffffffffffffffffffffffffffffffffffff16612332611996565b73ffffffffffffffffffffffffffffffffffffffff1614612388576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161237f90614139565b60405180910390fd5b80601060026101000a81548160ff02191690831515021790555050565b6123ad6127b3565b73ffffffffffffffffffffffffffffffffffffffff166123cb611996565b73ffffffffffffffffffffffffffffffffffffffff1614612421576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161241890614139565b60405180910390fd5b80600e8190555050565b60008161243661255e565b11158015612445575060005482105b8015612483575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b6000808290508061249961255e565b1161251f5760005481101561251e5760006004600083815260200190815260200160002054905060007c010000000000000000000000000000000000000000000000000000000082160361251c575b600081036125125760046000836001900393508381526020019081526020016000205490506124e8565b8092505050612551565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b600033905090565b600090565b61256e838383612b24565b505050565b6000826125808584612ecb565b1490509392505050565b600067ffffffffffffffff6040600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054901c169050919050565b600080549050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361264d576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008203612687576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6126946000848385612f21565b600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555060e16126f960018414612f27565b901b60a042901b61270985612f31565b171760046000838152602001908152602001600020819055506000819050600083820190505b818060010192508573ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a480821061272f578160008190555050506127ae6000848385612f3b565b505050565b600033905090565b6127d683838360405180602001604052806000815250611d10565b505050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6128bb828260405180602001604052806000815250612f41565b5050565b6128ca848484612b24565b60008373ffffffffffffffffffffffffffffffffffffffff163b1461292c576128f5848484846131f4565b61292b576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b6060600a805461294190613be9565b80601f016020809104026020016040519081016040528092919081815260200182805461296d90613be9565b80156129ba5780601f1061298f576101008083540402835291602001916129ba565b820191906000526020600020905b81548152906001019060200180831161299d57829003601f168201915b5050505050905090565b606060008203612a0b576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050612b1f565b600082905060005b60008214612a3d578080612a269061473c565b915050600a82612a3691906147b3565b9150612a13565b60008167ffffffffffffffff811115612a5957612a58613779565b5b6040519080825280601f01601f191660200182016040528015612a8b5781602001600182028036833780820191505090505b5090505b60008514612b1857600182612aa491906147e4565b9150600a85612ab39190614818565b6030612abf9190613e9d565b60f81b818381518110612ad557612ad4614849565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a85612b1191906147b3565b9450612a8f565b8093505050505b919050565b6000612b2f8261248a565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614612b96576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008473ffffffffffffffffffffffffffffffffffffffff16612bb7612556565b73ffffffffffffffffffffffffffffffffffffffff161480612be65750612be585612be0612556565b61216f565b5b80612c2b5750612bf4612556565b73ffffffffffffffffffffffffffffffffffffffff16612c1384610982565b73ffffffffffffffffffffffffffffffffffffffff16145b905080612c64576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603612cca576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612cd78585856001612f21565b6006600084815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008154600101919050819055507c020000000000000000000000000000000000000000000000000000000060a042901b612dd486612f31565b1717600460008581526020019081526020016000208190555060007c0200000000000000000000000000000000000000000000000000000000831603612e5c5760006001840190506000600460008381526020019081526020016000205403612e5a576000548114612e59578260046000838152602001908152602001600020819055505b5b505b828473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4612ec48585856001612f3b565b5050505050565b60008082905060005b8451811015612f1657612f0182868381518110612ef457612ef3614849565b5b6020026020010151613344565b91508080612f0e9061473c565b915050612ed4565b508091505092915050565b50505050565b6000819050919050565b6000819050919050565b50505050565b600080549050600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603612fad576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008303612fe7576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612ff46000858386612f21565b600160406001901b178302600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555060e161305960018514612f27565b901b60a042901b61306986612f31565b1717600460008381526020019081526020016000208190555060008190506000848201905060008673ffffffffffffffffffffffffffffffffffffffff163b1461316d575b818673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461311d60008784806001019550876131f4565b613153576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8082106130ae57826000541461316857600080fd5b6131d8565b5b818060010192508673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a480821061316e575b8160008190555050506131ee6000858386612f3b565b50505050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a0261321a612556565b8786866040518563ffffffff1660e01b815260040161323c94939291906148cd565b6020604051808303816000875af192505050801561327857506040513d601f19601f82011682018060405250810190613275919061492e565b60015b6132f1573d80600081146132a8576040519150601f19603f3d011682016040523d82523d6000602084013e6132ad565b606091505b5060008151036132e9576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b600081831061335c57613357828461336f565b613367565b613366838361336f565b5b905092915050565b600082600052816020526040600020905092915050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6133cf8161339a565b81146133da57600080fd5b50565b6000813590506133ec816133c6565b92915050565b60006020828403121561340857613407613390565b5b6000613416848285016133dd565b91505092915050565b60008115159050919050565b6134348161341f565b82525050565b600060208201905061344f600083018461342b565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561348f578082015181840152602081019050613474565b60008484015250505050565b6000601f19601f8301169050919050565b60006134b782613455565b6134c18185613460565b93506134d1818560208601613471565b6134da8161349b565b840191505092915050565b600060208201905081810360008301526134ff81846134ac565b905092915050565b6000819050919050565b61351a81613507565b811461352557600080fd5b50565b60008135905061353781613511565b92915050565b60006020828403121561355357613552613390565b5b600061356184828501613528565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006135958261356a565b9050919050565b6135a58161358a565b82525050565b60006020820190506135c0600083018461359c565b92915050565b6135cf8161358a565b81146135da57600080fd5b50565b6000813590506135ec816135c6565b92915050565b6000806040838503121561360957613608613390565b5b6000613617858286016135dd565b925050602061362885828601613528565b9150509250929050565b61363b81613507565b82525050565b60006020820190506136566000830184613632565b92915050565b60008060006060848603121561367557613674613390565b5b6000613683868287016135dd565b9350506020613694868287016135dd565b92505060406136a586828701613528565b9150509250925092565b600080fd5b600080fd5b600080fd5b60008083601f8401126136d4576136d36136af565b5b8235905067ffffffffffffffff8111156136f1576136f06136b4565b5b60208301915083602082028301111561370d5761370c6136b9565b5b9250929050565b60008060006040848603121561372d5761372c613390565b5b600084013567ffffffffffffffff81111561374b5761374a613395565b5b613757868287016136be565b9350935050602061376a86828701613528565b9150509250925092565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6137b18261349b565b810181811067ffffffffffffffff821117156137d0576137cf613779565b5b80604052505050565b60006137e3613386565b90506137ef82826137a8565b919050565b600067ffffffffffffffff82111561380f5761380e613779565b5b6138188261349b565b9050602081019050919050565b82818337600083830152505050565b6000613847613842846137f4565b6137d9565b90508281526020810184848401111561386357613862613774565b5b61386e848285613825565b509392505050565b600082601f83011261388b5761388a6136af565b5b813561389b848260208601613834565b91505092915050565b6000602082840312156138ba576138b9613390565b5b600082013567ffffffffffffffff8111156138d8576138d7613395565b5b6138e484828501613876565b91505092915050565b60006020828403121561390357613902613390565b5b6000613911848285016135dd565b91505092915050565b6000806040838503121561393157613930613390565b5b600061393f85828601613528565b9250506020613950858286016135dd565b9150509250929050565b6139638161341f565b811461396e57600080fd5b50565b6000813590506139808161395a565b92915050565b6000806040838503121561399d5761399c613390565b5b60006139ab858286016135dd565b92505060206139bc85828601613971565b9150509250929050565b600067ffffffffffffffff8211156139e1576139e0613779565b5b6139ea8261349b565b9050602081019050919050565b6000613a0a613a05846139c6565b6137d9565b905082815260208101848484011115613a2657613a25613774565b5b613a31848285613825565b509392505050565b600082601f830112613a4e57613a4d6136af565b5b8135613a5e8482602086016139f7565b91505092915050565b60008060008060808587031215613a8157613a80613390565b5b6000613a8f878288016135dd565b9450506020613aa0878288016135dd565b9350506040613ab187828801613528565b925050606085013567ffffffffffffffff811115613ad257613ad1613395565b5b613ade87828801613a39565b91505092959194509250565b600060208284031215613b0057613aff613390565b5b6000613b0e84828501613971565b91505092915050565b60008060408385031215613b2e57613b2d613390565b5b6000613b3c858286016135dd565b9250506020613b4d858286016135dd565b9150509250929050565b6000819050919050565b613b6a81613b57565b8114613b7557600080fd5b50565b600081359050613b8781613b61565b92915050565b600060208284031215613ba357613ba2613390565b5b6000613bb184828501613b78565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680613c0157607f821691505b602082108103613c1457613c13613bba565b5b50919050565b6000604082019050613c2f600083018561359c565b613c3c602083018461359c565b9392505050565b600081519050613c528161395a565b92915050565b600060208284031215613c6e57613c6d613390565b5b6000613c7c84828501613c43565b91505092915050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000613cbb601f83613460565b9150613cc682613c85565b602082019050919050565b60006020820190508181036000830152613cea81613cae565b9050919050565b60008160601b9050919050565b6000613d0982613cf1565b9050919050565b6000613d1b82613cfe565b9050919050565b613d33613d2e8261358a565b613d10565b82525050565b6000613d458284613d22565b60148201915081905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000613d8e82613507565b9150613d9983613507565b9250828202613da781613507565b91508282048414831517613dbe57613dbd613d54565b5b5092915050565b7f506c656173652073656e642074686520657861637420616d6f756e742e000000600082015250565b6000613dfb601d83613460565b9150613e0682613dc5565b602082019050919050565b60006020820190508181036000830152613e2a81613dee565b9050919050565b7f496e636f72726563742057686974656c6973742050726f6f6600000000000000600082015250565b6000613e67601983613460565b9150613e7282613e31565b602082019050919050565b60006020820190508181036000830152613e9681613e5a565b9050919050565b6000613ea882613507565b9150613eb383613507565b9250828201905080821115613ecb57613eca613d54565b5b92915050565b7f4e6f206d6f726500000000000000000000000000000000000000000000000000600082015250565b6000613f07600783613460565b9150613f1282613ed1565b602082019050919050565b60006020820190508181036000830152613f3681613efa565b9050919050565b7f506c6561736520656e7465722061206e756d6265720000000000000000000000600082015250565b6000613f73601583613460565b9150613f7e82613f3d565b602082019050919050565b60006020820190508181036000830152613fa281613f66565b9050919050565b7f4d696e74696e67206973206e6f74206c69766520796574000000000000000000600082015250565b6000613fdf601783613460565b9150613fea82613fa9565b602082019050919050565b6000602082019050818103600083015261400e81613fd2565b9050919050565b7f43616e206e6f74206d696e74206d6f7265207468616e20330000000000000000600082015250565b600061404b601883613460565b915061405682614015565b602082019050919050565b6000602082019050818103600083015261407a8161403e565b9050919050565b7f4e6f206d6f7265204e4654206c65667400000000000000000000000000000000600082015250565b60006140b7601083613460565b91506140c282614081565b602082019050919050565b600060208201905081810360008301526140e6816140aa565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000614123602083613460565b915061412e826140ed565b602082019050919050565b6000602082019050818103600083015261415281614116565b9050919050565b600081905092915050565b50565b6000614174600083614159565b915061417f82614164565b600082019050919050565b600061419582614167565b9150819050919050565b7f5472616e73666572206661696c65642e00000000000000000000000000000000600082015250565b60006141d5601083613460565b91506141e08261419f565b602082019050919050565b60006020820190508181036000830152614204816141c8565b9050919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b60006008830261426d7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82614230565b6142778683614230565b95508019841693508086168417925050509392505050565b6000819050919050565b60006142b46142af6142aa84613507565b61428f565b613507565b9050919050565b6000819050919050565b6142ce83614299565b6142e26142da826142bb565b84845461423d565b825550505050565b600090565b6142f76142ea565b6143028184846142c5565b505050565b5b818110156143265761431b6000826142ef565b600181019050614308565b5050565b601f82111561436b5761433c8161420b565b61434584614220565b81016020851015614354578190505b61436861436085614220565b830182614307565b50505b505050565b600082821c905092915050565b600061438e60001984600802614370565b1980831691505092915050565b60006143a7838361437d565b9150826002028217905092915050565b6143c082613455565b67ffffffffffffffff8111156143d9576143d8613779565b5b6143e38254613be9565b6143ee82828561432a565b600060209050601f831160018114614421576000841561440f578287015190505b614419858261439b565b865550614481565b601f19841661442f8661420b565b60005b8281101561445757848901518255600182019150602085019450602081019050614432565b868310156144745784890151614470601f89168261437d565b8355505b6001600288020188555050505b505050505050565b7f6e65656420746f206d696e74206174206c656173742031204e46540000000000600082015250565b60006144bf601b83613460565b91506144ca82614489565b602082019050919050565b600060208201905081810360008301526144ee816144b2565b9050919050565b7f6d6178204e4654206c696d697420657863656564656400000000000000000000600082015250565b600061452b601683613460565b9150614536826144f5565b602082019050919050565b6000602082019050818103600083015261455a8161451e565b9050919050565b7f455243373231414d657461646174613a2055524920717565727920666f72206e60008201527f6f6e6578697374656e7420746f6b656e00000000000000000000000000000000602082015250565b60006145bd603083613460565b91506145c882614561565b604082019050919050565b600060208201905081810360008301526145ec816145b0565b9050919050565b600081905092915050565b600061460982613455565b61461381856145f3565b9350614623818560208601613471565b80840191505092915050565b7f2e6a736f6e000000000000000000000000000000000000000000000000000000600082015250565b60006146656005836145f3565b91506146708261462f565b600582019050919050565b600061468782856145fe565b915061469382846145fe565b915061469e82614658565b91508190509392505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000614706602683613460565b9150614711826146aa565b604082019050919050565b60006020820190508181036000830152614735816146f9565b9050919050565b600061474782613507565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361477957614778613d54565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60006147be82613507565b91506147c983613507565b9250826147d9576147d8614784565b5b828204905092915050565b60006147ef82613507565b91506147fa83613507565b925082820390508181111561481257614811613d54565b5b92915050565b600061482382613507565b915061482e83613507565b92508261483e5761483d614784565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600081519050919050565b600082825260208201905092915050565b600061489f82614878565b6148a98185614883565b93506148b9818560208601613471565b6148c28161349b565b840191505092915050565b60006080820190506148e2600083018761359c565b6148ef602083018661359c565b6148fc6040830185613632565b818103606083015261490e8184614894565b905095945050505050565b600081519050614928816133c6565b92915050565b60006020828403121561494457614943613390565b5b600061495284828501614919565b9150509291505056fea264697066735822122050cc927874ebf95e61426ba4b5062aba891301cbd33ec045ecb0f5ab3d09e22d64736f6c63430008110033

Deployed Bytecode Sourcemap

96379:5067:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30321:665;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;35577:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;37774:245;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;37234:474;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;29375:315;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;100786:197;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;97134:774;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;97916:511;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;96870:32;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;100572:206;;;;;;;;;;;;;:::i;:::-;;100991:205;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;96600:31;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;96835:28;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;99398:88;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;35366:144;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;99822:102;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;31050:224;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;61825:103;;;;;;;;;;;;;:::i;:::-;;100221:343;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;96709:117;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;61174:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;99722:92;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;35746:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;96909:33;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;96556:35;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;38091:340;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;100137:76;;;;;;;;;;;;;:::i;:::-;;101204:239;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;99932:96;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;98677:713;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;96640:30;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;99614:100;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;38502:214;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;98551:118;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;62083:238;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;100036:93;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;99494:112;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;30321:665;30451:4;30771:10;30756:25;;:11;:25;;;;:102;;;;30848:10;30833:25;;:11;:25;;;;30756:102;:179;;;;30925:10;30910:25;;:11;:25;;;;30756:179;30736:199;;30321:665;;;:::o;35577:100::-;35631:13;35664:5;35657:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;35577:100;:::o;37774:245::-;37878:7;37908:16;37916:7;37908;:16::i;:::-;37903:64;;37933:34;;;;;;;;;;;;;;37903:64;37987:15;:24;38003:7;37987:24;;;;;;;;;;;;;;;;;;;;;37980:31;;37774:245;;;:::o;37234:474::-;37307:13;37339:27;37358:7;37339:18;:27::i;:::-;37307:61;;37389:5;37383:11;;:2;:11;;;37379:48;;37403:24;;;;;;;;;;;;;;37379:48;37467:5;37444:28;;:19;:17;:19::i;:::-;:28;;;37440:175;;37492:44;37509:5;37516:19;:17;:19::i;:::-;37492:16;:44::i;:::-;37487:128;;37564:35;;;;;;;;;;;;;;37487:128;37440:175;37654:2;37627:15;:24;37643:7;37627:24;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;37692:7;37688:2;37672:28;;37681:5;37672:28;;;;;;;;;;;;37296:412;37234:474;;:::o;29375:315::-;29428:7;29656:15;:13;:15::i;:::-;29641:12;;29625:13;;:28;:46;29618:53;;29375:315;:::o;100786:197::-;100921:4;4214:1;2894:42;4168:43;;;:47;4164:789;;;4455:10;4447:18;;:4;:18;;;4443:85;;100938:37:::1;100957:4;100963:2;100967:7;100938:18;:37::i;:::-;4506:7:::0;;4443:85;2894:42;4566:40;;;4637:4;4665:10;4566:128;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:287;;;;;2894:42;4719:40;;;4794:4;4826;4719:134;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4566:287;4542:400;;4915:10;4896:30;;;;;;;;;;;:::i;:::-;;;;;;;;4542:400;4164:789;100938:37:::1;100957:4;100963:2;100967:7;100938:18;:37::i;:::-;100786:197:::0;;;;;:::o;97134:774::-;7186:1;7784:7;;:19;7776:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;7186:1;7917:7;:18;;;;97278:12:::1;97320:10;97303:28;;;;;;;;:::i;:::-;;;;;;;;;;;;;97293:39;;;;;;97278:54;;97372:5;97364;;:13;;;;:::i;:::-;97351:9;:26;;97343:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;97444:53;97463:12;;97444:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;97477:13;;97492:4;97444:18;:53::i;:::-;97422:128;;;;;;;;;;;;:::i;:::-;;;;;;;;;97594:9;;97585:5;97569:13;:11;:13::i;:::-;:21;;;;:::i;:::-;:34;;97561:54;;;;;;;;;;;;:::i;:::-;;;;;;;;;97642:1;97634:5;:9;97626:43;;;;;;;;;;;;:::i;:::-;;;;;;;;;97688:13;;;;;;;;;;;97680:49;;;;;;;;;;;;:::i;:::-;;;;;;;;;97799:12;;97790:5;97762:25;97776:10;97762:13;:25::i;:::-;:33;;;;:::i;:::-;:49;;97740:123;;;;;;;;;;;;:::i;:::-;;;;;;;;;97876:24;97882:10;97894:5;97876;:24::i;:::-;97267:641;7142:1:::0;8096:7;:22;;;;97134:774;;;:::o;97916:511::-;7186:1;7784:7;;:19;7776:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;7186:1;7917:7;:18;;;;98021:5:::1;;98013;:13;;;;:::i;:::-;98000:9;:26;;97992:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;98104:9;;98095:5;98079:13;:11;:13::i;:::-;:21;;;;:::i;:::-;:34;;98071:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;98204:12;;98195:5;98167:25;98181:10;98167:13;:25::i;:::-;:33;;;;:::i;:::-;:49;;98145:123;;;;;;;;;;;;:::i;:::-;;;;;;;;;98295:1;98287:5;:9;98279:43;;;;;;;;;;;;:::i;:::-;;;;;;;;;98341:13;;;;;;;;;;;98333:49;;;;;;;;;;;;:::i;:::-;;;;;;;;;98395:24;98401:10;98413:5;98395;:24::i;:::-;7142:1:::0;8096:7;:22;;;;97916:511;:::o;96870:32::-;;;;;;;;;;;;;:::o;100572:206::-;61405:12;:10;:12::i;:::-;61394:23;;:7;:5;:7::i;:::-;:23;;;61386:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;100623:12:::1;100649:10;100641:24;;100687:21;100641:82;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;100622:101;;;100742:7;100734:36;;;;;;;;;;;;:::i;:::-;;;;;;;;;100611:167;100572:206::o:0;100991:205::-;101130:4;4214:1;2894:42;4168:43;;;:47;4164:789;;;4455:10;4447:18;;:4;:18;;;4443:85;;101147:41:::1;101170:4;101176:2;101180:7;101147:22;:41::i;:::-;4506:7:::0;;4443:85;2894:42;4566:40;;;4637:4;4665:10;4566:128;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:287;;;;;2894:42;4719:40;;;4794:4;4826;4719:134;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4566:287;4542:400;;4915:10;4896:30;;;;;;;;;;;:::i;:::-;;;;;;;;4542:400;4164:789;101147:41:::1;101170:4;101176:2;101180:7;101147:22;:41::i;:::-;100991:205:::0;;;;;:::o;96600:31::-;;;;:::o;96835:28::-;;;;;;;;;;;;;:::o;99398:88::-;61405:12;:10;:12::i;:::-;61394:23;;:7;:5;:7::i;:::-;:23;;;61386:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;99475:3:::1;99465:7;:13;;;;;;:::i;:::-;;99398:88:::0;:::o;35366:144::-;35430:7;35473:27;35492:7;35473:18;:27::i;:::-;35450:52;;35366:144;;;:::o;99822:102::-;61405:12;:10;:12::i;:::-;61394:23;;:7;:5;:7::i;:::-;:23;;;61386:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;99906:10:::1;99894:9;:22;;;;99822:102:::0;:::o;31050:224::-;31114:7;31155:1;31138:19;;:5;:19;;;31134:60;;31166:28;;;;;;;;;;;;;;31134:60;26345:13;31212:18;:25;31231:5;31212:25;;;;;;;;;;;;;;;;:54;31205:61;;31050:224;;;:::o;61825:103::-;61405:12;:10;:12::i;:::-;61394:23;;:7;:5;:7::i;:::-;:23;;;61386:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;61890:30:::1;61917:1;61890:18;:30::i;:::-;61825:103::o:0;100221:343::-;61405:12;:10;:12::i;:::-;61394:23;;:7;:5;:7::i;:::-;:23;;;61386:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;100355:1:::1;100341:11;:15;100333:55;;;;;;;;;;;;:::i;:::-;;;;;;;;;100399:14;100416:13;:11;:13::i;:::-;100399:30;;100472:9;;100457:11;100448:6;:20;;;;:::i;:::-;:33;;100440:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;100521:35;100531:11;100544;100521:9;:35::i;:::-;100322:242;100221:343:::0;;:::o;96709:117::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;61174:87::-;61220:7;61247:6;;;;;;;;;;;61240:13;;61174:87;:::o;99722:92::-;61405:12;:10;:12::i;:::-;61394:23;;:7;:5;:7::i;:::-;:23;;;61386:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;99797:9:::1;99789:5;:17;;;;99722:92:::0;:::o;35746:104::-;35802:13;35835:7;35828:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;35746:104;:::o;96909:33::-;;;;;;;;;;;;;:::o;96556:35::-;;;;:::o;38091:340::-;38234:19;:17;:19::i;:::-;38222:31;;:8;:31;;;38218:61;;38262:17;;;;;;;;;;;;;;38218:61;38344:8;38292:18;:39;38311:19;:17;:19::i;:::-;38292:39;;;;;;;;;;;;;;;:49;38332:8;38292:49;;;;;;;;;;;;;;;;:60;;;;;;;;;;;;;;;;;;38404:8;38368:55;;38383:19;:17;:19::i;:::-;38368:55;;;38414:8;38368:55;;;;;;:::i;:::-;;;;;;;;38091:340;;:::o;100137:76::-;61405:12;:10;:12::i;:::-;61394:23;;:7;:5;:7::i;:::-;:23;;;61386:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;100197:8:::1;;;;;;;;;;;100196:9;100185:8;;:20;;;;;;;;;;;;;;;;;;100137:76::o:0;101204:239::-;101371:4;4214:1;2894:42;4168:43;;;:47;4164:789;;;4455:10;4447:18;;:4;:18;;;4443:85;;101388:47:::1;101411:4;101417:2;101421:7;101430:4;101388:22;:47::i;:::-;4506:7:::0;;4443:85;2894:42;4566:40;;;4637:4;4665:10;4566:128;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:287;;;;;2894:42;4719:40;;;4794:4;4826;4719:134;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4566:287;4542:400;;4915:10;4896:30;;;;;;;;;;;:::i;:::-;;;;;;;;4542:400;4164:789;101388:47:::1;101411:4;101417:2;101421:7;101430:4;101388:22;:47::i;:::-;101204:239:::0;;;;;;:::o;99932:96::-;61405:12;:10;:12::i;:::-;61394:23;;:7;:5;:7::i;:::-;:23;;;61386:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;100014:6:::1;99998:13;;:22;;;;;;;;;;;;;;;;;;99932:96:::0;:::o;98677:713::-;98795:13;98848:16;98856:7;98848;:16::i;:::-;98826:114;;;;;;;;;;;;:::i;:::-;;;;;;;;;98967:5;98955:17;;:8;;;;;;;;;;;:17;;;98951:66;;98996:9;98989:16;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;98951:66;99029:28;99060:10;:8;:10::i;:::-;99029:41;;99132:1;99107:14;99101:28;:32;:281;;;;;;;;;;;;;;;;;99225:14;99266:18;:7;:16;:18::i;:::-;99182:159;;;;;;;;;:::i;:::-;;;;;;;;;;;;;99101:281;99081:301;;;98677:713;;;;:::o;96640:30::-;;;;:::o;99614:100::-;61405:12;:10;:12::i;:::-;61394:23;;:7;:5;:7::i;:::-;:23;;;61386:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;99700:6:::1;99685:12;:21;;;;99614:100:::0;:::o;38502:214::-;38644:4;38673:18;:25;38692:5;38673:25;;;;;;;;;;;;;;;:35;38699:8;38673:35;;;;;;;;;;;;;;;;;;;;;;;;;38666:42;;38502:214;;;;:::o;98551:118::-;98613:7;98640:21;98654:6;98640:13;:21::i;:::-;98633:28;;98551:118;;;:::o;62083:238::-;61405:12;:10;:12::i;:::-;61394:23;;:7;:5;:7::i;:::-;:23;;;61386:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;62206:1:::1;62186:22;;:8;:22;;::::0;62164:110:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;62285:28;62304:8;62285:18;:28::i;:::-;62083:238:::0;:::o;100036:93::-;61405:12;:10;:12::i;:::-;61394:23;;:7;:5;:7::i;:::-;:23;;;61386:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;100115:6:::1;100099:13;;:22;;;;;;;;;;;;;;;;;;100036:93:::0;:::o;99494:112::-;61405:12;:10;:12::i;:::-;61394:23;;:7;:5;:7::i;:::-;:23;;;61386:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;99586:12:::1;99570:13;:28;;;;99494:112:::0;:::o;39931:273::-;39988:4;40044:7;40025:15;:13;:15::i;:::-;:26;;:66;;;;;40078:13;;40068:7;:23;40025:66;:152;;;;;40176:1;27115:8;40129:17;:26;40147:7;40129:26;;;;;;;;;;;;:43;:48;40025:152;40005:172;;39931:273;;;:::o;32753:1161::-;32847:7;32872:12;32887:7;32872:22;;32955:4;32936:15;:13;:15::i;:::-;:23;32932:915;;32989:13;;32982:4;:20;32978:869;;;33027:14;33044:17;:23;33062:4;33044:23;;;;;;;;;;;;33027:40;;33160:1;27115:8;33133:6;:23;:28;33129:699;;33652:113;33669:1;33659:6;:11;33652:113;;33712:17;:25;33730:6;;;;;;;33712:25;;;;;;;;;;;;33703:34;;33652:113;;;33798:6;33791:13;;;;;;33129:699;33004:843;32978:869;32932:915;33875:31;;;;;;;;;;;;;;32753:1161;;;;:::o;54299:105::-;54359:7;54386:10;54379:17;;54299:105;:::o;28899:92::-;28955:7;28899:92;:::o;38783:170::-;38917:28;38927:4;38933:2;38937:7;38917:9;:28::i;:::-;38783:170;;;:::o;9350:190::-;9475:4;9528;9499:25;9512:5;9519:4;9499:12;:25::i;:::-;:33;9492:40;;9350:190;;;;;:::o;31356:202::-;31417:7;26345:13;26482:2;31458:18;:25;31477:5;31458:25;;;;;;;;;;;;;;;;:49;;31457:93;31437:113;;31356:202;;;:::o;43485:1690::-;43550:20;43573:13;;43550:36;;43615:1;43601:16;;:2;:16;;;43597:48;;43626:19;;;;;;;;;;;;;;43597:48;43672:1;43660:8;:13;43656:44;;43682:18;;;;;;;;;;;;;;43656:44;43713:61;43743:1;43747:2;43751:12;43765:8;43713:21;:61::i;:::-;44351:1;26482:2;44322:1;:25;;44321:31;44292:8;:61;44249:18;:22;44268:2;44249:22;;;;;;;;;;;;;;;;:104;;;;;;;;;;;27258:3;44752:29;44779:1;44767:8;:13;44752:14;:29::i;:::-;:56;;26999:3;44689:15;:41;;44647:21;44665:2;44647:17;:21::i;:::-;:84;:162;44596:17;:31;44614:12;44596:31;;;;;;;;;;;:213;;;;44826:20;44849:12;44826:35;;44876:11;44905:8;44890:12;:23;44876:37;;44930:111;44982:14;;;;;;44978:2;44957:40;;44974:1;44957:40;;;;;;;;;;;;45036:3;45021:12;:18;44930:111;;45073:12;45057:13;:28;;;;44026:1071;;45107:60;45136:1;45140:2;45144:12;45158:8;45107:20;:60::i;:::-;43539:1636;43485:1690;;:::o;59824:98::-;59877:7;59904:10;59897:17;;59824:98;:::o;39024:185::-;39162:39;39179:4;39185:2;39189:7;39162:39;;;;;;;;;;;;:16;:39::i;:::-;39024:185;;;:::o;62481:191::-;62555:16;62574:6;;;;;;;;;;;62555:25;;62600:8;62591:6;;:17;;;;;;;;;;;;;;;;;;62655:8;62624:40;;62645:8;62624:40;;;;;;;;;;;;62544:128;62481:191;:::o;40288:104::-;40357:27;40367:2;40371:8;40357:27;;;;;;;;;;;;:9;:27::i;:::-;40288:104;;:::o;39280:396::-;39447:28;39457:4;39463:2;39467:7;39447:9;:28::i;:::-;39508:1;39490:2;:14;;;:19;39486:183;;39529:56;39560:4;39566:2;39570:7;39579:5;39529:30;:56::i;:::-;39524:145;;39613:40;;;;;;;;;;;;;;39524:145;39486:183;39280:396;;;;:::o;98435:108::-;98495:13;98528:7;98521:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;98435:108;:::o;56995:723::-;57051:13;57281:1;57272:5;:10;57268:53;;57299:10;;;;;;;;;;;;;;;;;;;;;57268:53;57331:12;57346:5;57331:20;;57362:14;57387:78;57402:1;57394:4;:9;57387:78;;57420:8;;;;;:::i;:::-;;;;57451:2;57443:10;;;;;:::i;:::-;;;57387:78;;;57475:19;57507:6;57497:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57475:39;;57525:154;57541:1;57532:5;:10;57525:154;;57569:1;57559:11;;;;;:::i;:::-;;;57636:2;57628:5;:10;;;;:::i;:::-;57615:2;:24;;;;:::i;:::-;57602:39;;57585:6;57592;57585:14;;;;;;;;:::i;:::-;;;;;:56;;;;;;;;;;;57665:2;57656:11;;;;;:::i;:::-;;;57525:154;;;57703:6;57689:21;;;;;56995:723;;;;:::o;45429:2528::-;45544:27;45574;45593:7;45574:18;:27::i;:::-;45544:57;;45659:4;45618:45;;45634:19;45618:45;;;45614:99;;45685:28;;;;;;;;;;;;;;45614:99;45726:22;45775:4;45752:27;;:19;:17;:19::i;:::-;:27;;;:87;;;;45796:43;45813:4;45819:19;:17;:19::i;:::-;45796:16;:43::i;:::-;45752:87;:147;;;;45880:19;:17;:19::i;:::-;45856:43;;:20;45868:7;45856:11;:20::i;:::-;:43;;;45752:147;45726:174;;45918:17;45913:66;;45944:35;;;;;;;;;;;;;;45913:66;46008:1;45994:16;;:2;:16;;;45990:52;;46019:23;;;;;;;;;;;;;;45990:52;46055:43;46077:4;46083:2;46087:7;46096:1;46055:21;:43::i;:::-;46171:15;:24;46187:7;46171:24;;;;;;;;;;;;46164:31;;;;;;;;;;;46563:18;:24;46582:4;46563:24;;;;;;;;;;;;;;;;46561:26;;;;;;;;;;;;46632:18;:22;46651:2;46632:22;;;;;;;;;;;;;;;;46630:24;;;;;;;;;;;27393:8;26999:3;47013:15;:41;;46971:21;46989:2;46971:17;:21::i;:::-;:84;:128;46925:17;:26;46943:7;46925:26;;;;;;;;;;;:174;;;;47269:1;27393:8;47219:19;:46;:51;47215:626;;47291:19;47323:1;47313:7;:11;47291:33;;47480:1;47446:17;:30;47464:11;47446:30;;;;;;;;;;;;:35;47442:384;;47584:13;;47569:11;:28;47565:242;;47764:19;47731:17;:30;47749:11;47731:30;;;;;;;;;;;:52;;;;47565:242;47442:384;47272:569;47215:626;47888:7;47884:2;47869:27;;47878:4;47869:27;;;;;;;;;;;;47907:42;47928:4;47934:2;47938:7;47947:1;47907:20;:42::i;:::-;45533:2424;;45429:2528;;;:::o;10217:328::-;10327:7;10352:20;10375:4;10352:27;;10395:9;10390:118;10414:5;:12;10410:1;:16;10390:118;;;10463:33;10473:12;10487:5;10493:1;10487:8;;;;;;;;:::i;:::-;;;;;;;;10463:9;:33::i;:::-;10448:48;;10428:3;;;;;:::i;:::-;;;;10390:118;;;;10525:12;10518:19;;;10217:328;;;;:::o;53132:159::-;;;;;:::o;37030:142::-;37088:14;37149:5;37139:15;;37030:142;;;:::o;36763:180::-;36854:14;36920:5;36910:15;;36763:180;;;:::o;53950:158::-;;;;;:::o;40765:2461::-;40888:20;40911:13;;40888:36;;40953:1;40939:16;;:2;:16;;;40935:48;;40964:19;;;;;;;;;;;;;;40935:48;41010:1;40998:8;:13;40994:44;;41020:18;;;;;;;;;;;;;;40994:44;41051:61;41081:1;41085:2;41089:12;41103:8;41051:21;:61::i;:::-;41689:1;26482:2;41660:1;:25;;41659:31;41630:8;:61;41587:18;:22;41606:2;41587:22;;;;;;;;;;;;;;;;:104;;;;;;;;;;;27258:3;42090:29;42117:1;42105:8;:13;42090:14;:29::i;:::-;:56;;26999:3;42027:15;:41;;41985:21;42003:2;41985:17;:21::i;:::-;:84;:162;41934:17;:31;41952:12;41934:31;;;;;;;;;;;:213;;;;42164:20;42187:12;42164:35;;42214:11;42243:8;42228:12;:23;42214:37;;42290:1;42272:2;:14;;;:19;42268:826;;42312:504;42368:12;42364:2;42343:38;;42360:1;42343:38;;;;;;;;;;;;42435:212;42504:1;42537:2;42570:14;;;;;;42615:5;42435:30;:212::i;:::-;42404:365;;42705:40;;;;;;;;;;;;;;42404:365;42811:3;42796:12;:18;42312:504;;42897:12;42880:13;;:29;42876:43;;42911:8;;;42876:43;42268:826;;;42960:119;43016:14;;;;;;43012:2;42991:40;;43008:1;42991:40;;;;;;;;;;;;43074:3;43059:12;:18;42960:119;;42268:826;43124:12;43108:13;:28;;;;41364:1784;;43158:60;43187:1;43191:2;43195:12;43209:8;43158:20;:60::i;:::-;40877:2349;40765:2461;;;:::o;51653:831::-;51816:4;51875:2;51850:45;;;51914:19;:17;:19::i;:::-;51952:4;51975:7;52001:5;51850:171;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;51833:644;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52252:1;52235:6;:13;:18;52231:235;;52281:40;;;;;;;;;;;;;;52231:235;52424:6;52418:13;52409:6;52405:2;52401:15;52394:38;51833:644;52121:54;;;52094:81;;;:6;:81;;;;52070:105;;;51653:831;;;;;;:::o;16698:149::-;16761:7;16792:1;16788;:5;:51;;16819:20;16834:1;16837;16819:14;:20::i;:::-;16788:51;;;16796:20;16811:1;16814;16796:14;:20::i;:::-;16788:51;16781:58;;16698:149;;;;:::o;16855:300::-;16950:13;17062:1;17056:4;17049:15;17091:1;17085:4;17078:15;17132:4;17126;17116:21;17107:30;;16855:300;;;;:::o;7:75:1:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:149;370:7;410:66;403:5;399:78;388:89;;334:149;;;:::o;489:120::-;561:23;578:5;561:23;:::i;:::-;554:5;551:34;541:62;;599:1;596;589:12;541:62;489:120;:::o;615:137::-;660:5;698:6;685:20;676:29;;714:32;740:5;714:32;:::i;:::-;615:137;;;;:::o;758:327::-;816:6;865:2;853:9;844:7;840:23;836:32;833:119;;;871:79;;:::i;:::-;833:119;991:1;1016:52;1060:7;1051:6;1040:9;1036:22;1016:52;:::i;:::-;1006:62;;962:116;758:327;;;;:::o;1091:90::-;1125:7;1168:5;1161:13;1154:21;1143:32;;1091:90;;;:::o;1187:109::-;1268:21;1283:5;1268:21;:::i;:::-;1263:3;1256:34;1187:109;;:::o;1302:210::-;1389:4;1427:2;1416:9;1412:18;1404:26;;1440:65;1502:1;1491:9;1487:17;1478:6;1440:65;:::i;:::-;1302:210;;;;:::o;1518:99::-;1570:6;1604:5;1598:12;1588:22;;1518:99;;;:::o;1623:169::-;1707:11;1741:6;1736:3;1729:19;1781:4;1776:3;1772:14;1757:29;;1623:169;;;;:::o;1798:246::-;1879:1;1889:113;1903:6;1900:1;1897:13;1889:113;;;1988:1;1983:3;1979:11;1973:18;1969:1;1964:3;1960:11;1953:39;1925:2;1922:1;1918:10;1913:15;;1889:113;;;2036:1;2027:6;2022:3;2018:16;2011:27;1860:184;1798:246;;;:::o;2050:102::-;2091:6;2142:2;2138:7;2133:2;2126:5;2122:14;2118:28;2108:38;;2050:102;;;:::o;2158:377::-;2246:3;2274:39;2307:5;2274:39;:::i;:::-;2329:71;2393:6;2388:3;2329:71;:::i;:::-;2322:78;;2409:65;2467:6;2462:3;2455:4;2448:5;2444:16;2409:65;:::i;:::-;2499:29;2521:6;2499:29;:::i;:::-;2494:3;2490:39;2483:46;;2250:285;2158:377;;;;:::o;2541:313::-;2654:4;2692:2;2681:9;2677:18;2669:26;;2741:9;2735:4;2731:20;2727:1;2716:9;2712:17;2705:47;2769:78;2842:4;2833:6;2769:78;:::i;:::-;2761:86;;2541:313;;;;:::o;2860:77::-;2897:7;2926:5;2915:16;;2860:77;;;:::o;2943:122::-;3016:24;3034:5;3016:24;:::i;:::-;3009:5;3006:35;2996:63;;3055:1;3052;3045:12;2996:63;2943:122;:::o;3071:139::-;3117:5;3155:6;3142:20;3133:29;;3171:33;3198:5;3171:33;:::i;:::-;3071:139;;;;:::o;3216:329::-;3275:6;3324:2;3312:9;3303:7;3299:23;3295:32;3292:119;;;3330:79;;:::i;:::-;3292:119;3450:1;3475:53;3520:7;3511:6;3500:9;3496:22;3475:53;:::i;:::-;3465:63;;3421:117;3216:329;;;;:::o;3551:126::-;3588:7;3628:42;3621:5;3617:54;3606:65;;3551:126;;;:::o;3683:96::-;3720:7;3749:24;3767:5;3749:24;:::i;:::-;3738:35;;3683:96;;;:::o;3785:118::-;3872:24;3890:5;3872:24;:::i;:::-;3867:3;3860:37;3785:118;;:::o;3909:222::-;4002:4;4040:2;4029:9;4025:18;4017:26;;4053:71;4121:1;4110:9;4106:17;4097:6;4053:71;:::i;:::-;3909:222;;;;:::o;4137:122::-;4210:24;4228:5;4210:24;:::i;:::-;4203:5;4200:35;4190:63;;4249:1;4246;4239:12;4190:63;4137:122;:::o;4265:139::-;4311:5;4349:6;4336:20;4327:29;;4365:33;4392:5;4365:33;:::i;:::-;4265:139;;;;:::o;4410:474::-;4478:6;4486;4535:2;4523:9;4514:7;4510:23;4506:32;4503:119;;;4541:79;;:::i;:::-;4503:119;4661:1;4686:53;4731:7;4722:6;4711:9;4707:22;4686:53;:::i;:::-;4676:63;;4632:117;4788:2;4814:53;4859:7;4850:6;4839:9;4835:22;4814:53;:::i;:::-;4804:63;;4759:118;4410:474;;;;;:::o;4890:118::-;4977:24;4995:5;4977:24;:::i;:::-;4972:3;4965:37;4890:118;;:::o;5014:222::-;5107:4;5145:2;5134:9;5130:18;5122:26;;5158:71;5226:1;5215:9;5211:17;5202:6;5158:71;:::i;:::-;5014:222;;;;:::o;5242:619::-;5319:6;5327;5335;5384:2;5372:9;5363:7;5359:23;5355:32;5352:119;;;5390:79;;:::i;:::-;5352:119;5510:1;5535:53;5580:7;5571:6;5560:9;5556:22;5535:53;:::i;:::-;5525:63;;5481:117;5637:2;5663:53;5708:7;5699:6;5688:9;5684:22;5663:53;:::i;:::-;5653:63;;5608:118;5765:2;5791:53;5836:7;5827:6;5816:9;5812:22;5791:53;:::i;:::-;5781:63;;5736:118;5242:619;;;;;:::o;5867:117::-;5976:1;5973;5966:12;5990:117;6099:1;6096;6089:12;6113:117;6222:1;6219;6212:12;6253:568;6326:8;6336:6;6386:3;6379:4;6371:6;6367:17;6363:27;6353:122;;6394:79;;:::i;:::-;6353:122;6507:6;6494:20;6484:30;;6537:18;6529:6;6526:30;6523:117;;;6559:79;;:::i;:::-;6523:117;6673:4;6665:6;6661:17;6649:29;;6727:3;6719:4;6711:6;6707:17;6697:8;6693:32;6690:41;6687:128;;;6734:79;;:::i;:::-;6687:128;6253:568;;;;;:::o;6827:704::-;6922:6;6930;6938;6987:2;6975:9;6966:7;6962:23;6958:32;6955:119;;;6993:79;;:::i;:::-;6955:119;7141:1;7130:9;7126:17;7113:31;7171:18;7163:6;7160:30;7157:117;;;7193:79;;:::i;:::-;7157:117;7306:80;7378:7;7369:6;7358:9;7354:22;7306:80;:::i;:::-;7288:98;;;;7084:312;7435:2;7461:53;7506:7;7497:6;7486:9;7482:22;7461:53;:::i;:::-;7451:63;;7406:118;6827:704;;;;;:::o;7537:117::-;7646:1;7643;7636:12;7660:180;7708:77;7705:1;7698:88;7805:4;7802:1;7795:15;7829:4;7826:1;7819:15;7846:281;7929:27;7951:4;7929:27;:::i;:::-;7921:6;7917:40;8059:6;8047:10;8044:22;8023:18;8011:10;8008:34;8005:62;8002:88;;;8070:18;;:::i;:::-;8002:88;8110:10;8106:2;8099:22;7889:238;7846:281;;:::o;8133:129::-;8167:6;8194:20;;:::i;:::-;8184:30;;8223:33;8251:4;8243:6;8223:33;:::i;:::-;8133:129;;;:::o;8268:308::-;8330:4;8420:18;8412:6;8409:30;8406:56;;;8442:18;;:::i;:::-;8406:56;8480:29;8502:6;8480:29;:::i;:::-;8472:37;;8564:4;8558;8554:15;8546:23;;8268:308;;;:::o;8582:146::-;8679:6;8674:3;8669;8656:30;8720:1;8711:6;8706:3;8702:16;8695:27;8582:146;;;:::o;8734:425::-;8812:5;8837:66;8853:49;8895:6;8853:49;:::i;:::-;8837:66;:::i;:::-;8828:75;;8926:6;8919:5;8912:21;8964:4;8957:5;8953:16;9002:3;8993:6;8988:3;8984:16;8981:25;8978:112;;;9009:79;;:::i;:::-;8978:112;9099:54;9146:6;9141:3;9136;9099:54;:::i;:::-;8818:341;8734:425;;;;;:::o;9179:340::-;9235:5;9284:3;9277:4;9269:6;9265:17;9261:27;9251:122;;9292:79;;:::i;:::-;9251:122;9409:6;9396:20;9434:79;9509:3;9501:6;9494:4;9486:6;9482:17;9434:79;:::i;:::-;9425:88;;9241:278;9179:340;;;;:::o;9525:509::-;9594:6;9643:2;9631:9;9622:7;9618:23;9614:32;9611:119;;;9649:79;;:::i;:::-;9611:119;9797:1;9786:9;9782:17;9769:31;9827:18;9819:6;9816:30;9813:117;;;9849:79;;:::i;:::-;9813:117;9954:63;10009:7;10000:6;9989:9;9985:22;9954:63;:::i;:::-;9944:73;;9740:287;9525:509;;;;:::o;10040:329::-;10099:6;10148:2;10136:9;10127:7;10123:23;10119:32;10116:119;;;10154:79;;:::i;:::-;10116:119;10274:1;10299:53;10344:7;10335:6;10324:9;10320:22;10299:53;:::i;:::-;10289:63;;10245:117;10040:329;;;;:::o;10375:474::-;10443:6;10451;10500:2;10488:9;10479:7;10475:23;10471:32;10468:119;;;10506:79;;:::i;:::-;10468:119;10626:1;10651:53;10696:7;10687:6;10676:9;10672:22;10651:53;:::i;:::-;10641:63;;10597:117;10753:2;10779:53;10824:7;10815:6;10804:9;10800:22;10779:53;:::i;:::-;10769:63;;10724:118;10375:474;;;;;:::o;10855:116::-;10925:21;10940:5;10925:21;:::i;:::-;10918:5;10915:32;10905:60;;10961:1;10958;10951:12;10905:60;10855:116;:::o;10977:133::-;11020:5;11058:6;11045:20;11036:29;;11074:30;11098:5;11074:30;:::i;:::-;10977:133;;;;:::o;11116:468::-;11181:6;11189;11238:2;11226:9;11217:7;11213:23;11209:32;11206:119;;;11244:79;;:::i;:::-;11206:119;11364:1;11389:53;11434:7;11425:6;11414:9;11410:22;11389:53;:::i;:::-;11379:63;;11335:117;11491:2;11517:50;11559:7;11550:6;11539:9;11535:22;11517:50;:::i;:::-;11507:60;;11462:115;11116:468;;;;;:::o;11590:307::-;11651:4;11741:18;11733:6;11730:30;11727:56;;;11763:18;;:::i;:::-;11727:56;11801:29;11823:6;11801:29;:::i;:::-;11793:37;;11885:4;11879;11875:15;11867:23;;11590:307;;;:::o;11903:423::-;11980:5;12005:65;12021:48;12062:6;12021:48;:::i;:::-;12005:65;:::i;:::-;11996:74;;12093:6;12086:5;12079:21;12131:4;12124:5;12120:16;12169:3;12160:6;12155:3;12151:16;12148:25;12145:112;;;12176:79;;:::i;:::-;12145:112;12266:54;12313:6;12308:3;12303;12266:54;:::i;:::-;11986:340;11903:423;;;;;:::o;12345:338::-;12400:5;12449:3;12442:4;12434:6;12430:17;12426:27;12416:122;;12457:79;;:::i;:::-;12416:122;12574:6;12561:20;12599:78;12673:3;12665:6;12658:4;12650:6;12646:17;12599:78;:::i;:::-;12590:87;;12406:277;12345:338;;;;:::o;12689:943::-;12784:6;12792;12800;12808;12857:3;12845:9;12836:7;12832:23;12828:33;12825:120;;;12864:79;;:::i;:::-;12825:120;12984:1;13009:53;13054:7;13045:6;13034:9;13030:22;13009:53;:::i;:::-;12999:63;;12955:117;13111:2;13137:53;13182:7;13173:6;13162:9;13158:22;13137:53;:::i;:::-;13127:63;;13082:118;13239:2;13265:53;13310:7;13301:6;13290:9;13286:22;13265:53;:::i;:::-;13255:63;;13210:118;13395:2;13384:9;13380:18;13367:32;13426:18;13418:6;13415:30;13412:117;;;13448:79;;:::i;:::-;13412:117;13553:62;13607:7;13598:6;13587:9;13583:22;13553:62;:::i;:::-;13543:72;;13338:287;12689:943;;;;;;;:::o;13638:323::-;13694:6;13743:2;13731:9;13722:7;13718:23;13714:32;13711:119;;;13749:79;;:::i;:::-;13711:119;13869:1;13894:50;13936:7;13927:6;13916:9;13912:22;13894:50;:::i;:::-;13884:60;;13840:114;13638:323;;;;:::o;13967:474::-;14035:6;14043;14092:2;14080:9;14071:7;14067:23;14063:32;14060:119;;;14098:79;;:::i;:::-;14060:119;14218:1;14243:53;14288:7;14279:6;14268:9;14264:22;14243:53;:::i;:::-;14233:63;;14189:117;14345:2;14371:53;14416:7;14407:6;14396:9;14392:22;14371:53;:::i;:::-;14361:63;;14316:118;13967:474;;;;;:::o;14447:77::-;14484:7;14513:5;14502:16;;14447:77;;;:::o;14530:122::-;14603:24;14621:5;14603:24;:::i;:::-;14596:5;14593:35;14583:63;;14642:1;14639;14632:12;14583:63;14530:122;:::o;14658:139::-;14704:5;14742:6;14729:20;14720:29;;14758:33;14785:5;14758:33;:::i;:::-;14658:139;;;;:::o;14803:329::-;14862:6;14911:2;14899:9;14890:7;14886:23;14882:32;14879:119;;;14917:79;;:::i;:::-;14879:119;15037:1;15062:53;15107:7;15098:6;15087:9;15083:22;15062:53;:::i;:::-;15052:63;;15008:117;14803:329;;;;:::o;15138:180::-;15186:77;15183:1;15176:88;15283:4;15280:1;15273:15;15307:4;15304:1;15297:15;15324:320;15368:6;15405:1;15399:4;15395:12;15385:22;;15452:1;15446:4;15442:12;15473:18;15463:81;;15529:4;15521:6;15517:17;15507:27;;15463:81;15591:2;15583:6;15580:14;15560:18;15557:38;15554:84;;15610:18;;:::i;:::-;15554:84;15375:269;15324:320;;;:::o;15650:332::-;15771:4;15809:2;15798:9;15794:18;15786:26;;15822:71;15890:1;15879:9;15875:17;15866:6;15822:71;:::i;:::-;15903:72;15971:2;15960:9;15956:18;15947:6;15903:72;:::i;:::-;15650:332;;;;;:::o;15988:137::-;16042:5;16073:6;16067:13;16058:22;;16089:30;16113:5;16089:30;:::i;:::-;15988:137;;;;:::o;16131:345::-;16198:6;16247:2;16235:9;16226:7;16222:23;16218:32;16215:119;;;16253:79;;:::i;:::-;16215:119;16373:1;16398:61;16451:7;16442:6;16431:9;16427:22;16398:61;:::i;:::-;16388:71;;16344:125;16131:345;;;;:::o;16482:181::-;16622:33;16618:1;16610:6;16606:14;16599:57;16482:181;:::o;16669:366::-;16811:3;16832:67;16896:2;16891:3;16832:67;:::i;:::-;16825:74;;16908:93;16997:3;16908:93;:::i;:::-;17026:2;17021:3;17017:12;17010:19;;16669:366;;;:::o;17041:419::-;17207:4;17245:2;17234:9;17230:18;17222:26;;17294:9;17288:4;17284:20;17280:1;17269:9;17265:17;17258:47;17322:131;17448:4;17322:131;:::i;:::-;17314:139;;17041:419;;;:::o;17466:94::-;17499:8;17547:5;17543:2;17539:14;17518:35;;17466:94;;;:::o;17566:::-;17605:7;17634:20;17648:5;17634:20;:::i;:::-;17623:31;;17566:94;;;:::o;17666:100::-;17705:7;17734:26;17754:5;17734:26;:::i;:::-;17723:37;;17666:100;;;:::o;17772:157::-;17877:45;17897:24;17915:5;17897:24;:::i;:::-;17877:45;:::i;:::-;17872:3;17865:58;17772:157;;:::o;17935:256::-;18047:3;18062:75;18133:3;18124:6;18062:75;:::i;:::-;18162:2;18157:3;18153:12;18146:19;;18182:3;18175:10;;17935:256;;;;:::o;18197:180::-;18245:77;18242:1;18235:88;18342:4;18339:1;18332:15;18366:4;18363:1;18356:15;18383:410;18423:7;18446:20;18464:1;18446:20;:::i;:::-;18441:25;;18480:20;18498:1;18480:20;:::i;:::-;18475:25;;18535:1;18532;18528:9;18557:30;18575:11;18557:30;:::i;:::-;18546:41;;18736:1;18727:7;18723:15;18720:1;18717:22;18697:1;18690:9;18670:83;18647:139;;18766:18;;:::i;:::-;18647:139;18431:362;18383:410;;;;:::o;18799:179::-;18939:31;18935:1;18927:6;18923:14;18916:55;18799:179;:::o;18984:366::-;19126:3;19147:67;19211:2;19206:3;19147:67;:::i;:::-;19140:74;;19223:93;19312:3;19223:93;:::i;:::-;19341:2;19336:3;19332:12;19325:19;;18984:366;;;:::o;19356:419::-;19522:4;19560:2;19549:9;19545:18;19537:26;;19609:9;19603:4;19599:20;19595:1;19584:9;19580:17;19573:47;19637:131;19763:4;19637:131;:::i;:::-;19629:139;;19356:419;;;:::o;19781:175::-;19921:27;19917:1;19909:6;19905:14;19898:51;19781:175;:::o;19962:366::-;20104:3;20125:67;20189:2;20184:3;20125:67;:::i;:::-;20118:74;;20201:93;20290:3;20201:93;:::i;:::-;20319:2;20314:3;20310:12;20303:19;;19962:366;;;:::o;20334:419::-;20500:4;20538:2;20527:9;20523:18;20515:26;;20587:9;20581:4;20577:20;20573:1;20562:9;20558:17;20551:47;20615:131;20741:4;20615:131;:::i;:::-;20607:139;;20334:419;;;:::o;20759:191::-;20799:3;20818:20;20836:1;20818:20;:::i;:::-;20813:25;;20852:20;20870:1;20852:20;:::i;:::-;20847:25;;20895:1;20892;20888:9;20881:16;;20916:3;20913:1;20910:10;20907:36;;;20923:18;;:::i;:::-;20907:36;20759:191;;;;:::o;20956:157::-;21096:9;21092:1;21084:6;21080:14;21073:33;20956:157;:::o;21119:365::-;21261:3;21282:66;21346:1;21341:3;21282:66;:::i;:::-;21275:73;;21357:93;21446:3;21357:93;:::i;:::-;21475:2;21470:3;21466:12;21459:19;;21119:365;;;:::o;21490:419::-;21656:4;21694:2;21683:9;21679:18;21671:26;;21743:9;21737:4;21733:20;21729:1;21718:9;21714:17;21707:47;21771:131;21897:4;21771:131;:::i;:::-;21763:139;;21490:419;;;:::o;21915:171::-;22055:23;22051:1;22043:6;22039:14;22032:47;21915:171;:::o;22092:366::-;22234:3;22255:67;22319:2;22314:3;22255:67;:::i;:::-;22248:74;;22331:93;22420:3;22331:93;:::i;:::-;22449:2;22444:3;22440:12;22433:19;;22092:366;;;:::o;22464:419::-;22630:4;22668:2;22657:9;22653:18;22645:26;;22717:9;22711:4;22707:20;22703:1;22692:9;22688:17;22681:47;22745:131;22871:4;22745:131;:::i;:::-;22737:139;;22464:419;;;:::o;22889:173::-;23029:25;23025:1;23017:6;23013:14;23006:49;22889:173;:::o;23068:366::-;23210:3;23231:67;23295:2;23290:3;23231:67;:::i;:::-;23224:74;;23307:93;23396:3;23307:93;:::i;:::-;23425:2;23420:3;23416:12;23409:19;;23068:366;;;:::o;23440:419::-;23606:4;23644:2;23633:9;23629:18;23621:26;;23693:9;23687:4;23683:20;23679:1;23668:9;23664:17;23657:47;23721:131;23847:4;23721:131;:::i;:::-;23713:139;;23440:419;;;:::o;23865:174::-;24005:26;24001:1;23993:6;23989:14;23982:50;23865:174;:::o;24045:366::-;24187:3;24208:67;24272:2;24267:3;24208:67;:::i;:::-;24201:74;;24284:93;24373:3;24284:93;:::i;:::-;24402:2;24397:3;24393:12;24386:19;;24045:366;;;:::o;24417:419::-;24583:4;24621:2;24610:9;24606:18;24598:26;;24670:9;24664:4;24660:20;24656:1;24645:9;24641:17;24634:47;24698:131;24824:4;24698:131;:::i;:::-;24690:139;;24417:419;;;:::o;24842:166::-;24982:18;24978:1;24970:6;24966:14;24959:42;24842:166;:::o;25014:366::-;25156:3;25177:67;25241:2;25236:3;25177:67;:::i;:::-;25170:74;;25253:93;25342:3;25253:93;:::i;:::-;25371:2;25366:3;25362:12;25355:19;;25014:366;;;:::o;25386:419::-;25552:4;25590:2;25579:9;25575:18;25567:26;;25639:9;25633:4;25629:20;25625:1;25614:9;25610:17;25603:47;25667:131;25793:4;25667:131;:::i;:::-;25659:139;;25386:419;;;:::o;25811:182::-;25951:34;25947:1;25939:6;25935:14;25928:58;25811:182;:::o;25999:366::-;26141:3;26162:67;26226:2;26221:3;26162:67;:::i;:::-;26155:74;;26238:93;26327:3;26238:93;:::i;:::-;26356:2;26351:3;26347:12;26340:19;;25999:366;;;:::o;26371:419::-;26537:4;26575:2;26564:9;26560:18;26552:26;;26624:9;26618:4;26614:20;26610:1;26599:9;26595:17;26588:47;26652:131;26778:4;26652:131;:::i;:::-;26644:139;;26371:419;;;:::o;26796:147::-;26897:11;26934:3;26919:18;;26796:147;;;;:::o;26949:114::-;;:::o;27069:398::-;27228:3;27249:83;27330:1;27325:3;27249:83;:::i;:::-;27242:90;;27341:93;27430:3;27341:93;:::i;:::-;27459:1;27454:3;27450:11;27443:18;;27069:398;;;:::o;27473:379::-;27657:3;27679:147;27822:3;27679:147;:::i;:::-;27672:154;;27843:3;27836:10;;27473:379;;;:::o;27858:166::-;27998:18;27994:1;27986:6;27982:14;27975:42;27858:166;:::o;28030:366::-;28172:3;28193:67;28257:2;28252:3;28193:67;:::i;:::-;28186:74;;28269:93;28358:3;28269:93;:::i;:::-;28387:2;28382:3;28378:12;28371:19;;28030:366;;;:::o;28402:419::-;28568:4;28606:2;28595:9;28591:18;28583:26;;28655:9;28649:4;28645:20;28641:1;28630:9;28626:17;28619:47;28683:131;28809:4;28683:131;:::i;:::-;28675:139;;28402:419;;;:::o;28827:141::-;28876:4;28899:3;28891:11;;28922:3;28919:1;28912:14;28956:4;28953:1;28943:18;28935:26;;28827:141;;;:::o;28974:93::-;29011:6;29058:2;29053;29046:5;29042:14;29038:23;29028:33;;28974:93;;;:::o;29073:107::-;29117:8;29167:5;29161:4;29157:16;29136:37;;29073:107;;;;:::o;29186:393::-;29255:6;29305:1;29293:10;29289:18;29328:97;29358:66;29347:9;29328:97;:::i;:::-;29446:39;29476:8;29465:9;29446:39;:::i;:::-;29434:51;;29518:4;29514:9;29507:5;29503:21;29494:30;;29567:4;29557:8;29553:19;29546:5;29543:30;29533:40;;29262:317;;29186:393;;;;;:::o;29585:60::-;29613:3;29634:5;29627:12;;29585:60;;;:::o;29651:142::-;29701:9;29734:53;29752:34;29761:24;29779:5;29761:24;:::i;:::-;29752:34;:::i;:::-;29734:53;:::i;:::-;29721:66;;29651:142;;;:::o;29799:75::-;29842:3;29863:5;29856:12;;29799:75;;;:::o;29880:269::-;29990:39;30021:7;29990:39;:::i;:::-;30051:91;30100:41;30124:16;30100:41;:::i;:::-;30092:6;30085:4;30079:11;30051:91;:::i;:::-;30045:4;30038:105;29956:193;29880:269;;;:::o;30155:73::-;30200:3;30155:73;:::o;30234:189::-;30311:32;;:::i;:::-;30352:65;30410:6;30402;30396:4;30352:65;:::i;:::-;30287:136;30234:189;;:::o;30429:186::-;30489:120;30506:3;30499:5;30496:14;30489:120;;;30560:39;30597:1;30590:5;30560:39;:::i;:::-;30533:1;30526:5;30522:13;30513:22;;30489:120;;;30429:186;;:::o;30621:543::-;30722:2;30717:3;30714:11;30711:446;;;30756:38;30788:5;30756:38;:::i;:::-;30840:29;30858:10;30840:29;:::i;:::-;30830:8;30826:44;31023:2;31011:10;31008:18;31005:49;;;31044:8;31029:23;;31005:49;31067:80;31123:22;31141:3;31123:22;:::i;:::-;31113:8;31109:37;31096:11;31067:80;:::i;:::-;30726:431;;30711:446;30621:543;;;:::o;31170:117::-;31224:8;31274:5;31268:4;31264:16;31243:37;;31170:117;;;;:::o;31293:169::-;31337:6;31370:51;31418:1;31414:6;31406:5;31403:1;31399:13;31370:51;:::i;:::-;31366:56;31451:4;31445;31441:15;31431:25;;31344:118;31293:169;;;;:::o;31467:295::-;31543:4;31689:29;31714:3;31708:4;31689:29;:::i;:::-;31681:37;;31751:3;31748:1;31744:11;31738:4;31735:21;31727:29;;31467:295;;;;:::o;31767:1395::-;31884:37;31917:3;31884:37;:::i;:::-;31986:18;31978:6;31975:30;31972:56;;;32008:18;;:::i;:::-;31972:56;32052:38;32084:4;32078:11;32052:38;:::i;:::-;32137:67;32197:6;32189;32183:4;32137:67;:::i;:::-;32231:1;32255:4;32242:17;;32287:2;32279:6;32276:14;32304:1;32299:618;;;;32961:1;32978:6;32975:77;;;33027:9;33022:3;33018:19;33012:26;33003:35;;32975:77;33078:67;33138:6;33131:5;33078:67;:::i;:::-;33072:4;33065:81;32934:222;32269:887;;32299:618;32351:4;32347:9;32339:6;32335:22;32385:37;32417:4;32385:37;:::i;:::-;32444:1;32458:208;32472:7;32469:1;32466:14;32458:208;;;32551:9;32546:3;32542:19;32536:26;32528:6;32521:42;32602:1;32594:6;32590:14;32580:24;;32649:2;32638:9;32634:18;32621:31;;32495:4;32492:1;32488:12;32483:17;;32458:208;;;32694:6;32685:7;32682:19;32679:179;;;32752:9;32747:3;32743:19;32737:26;32795:48;32837:4;32829:6;32825:17;32814:9;32795:48;:::i;:::-;32787:6;32780:64;32702:156;32679:179;32904:1;32900;32892:6;32888:14;32884:22;32878:4;32871:36;32306:611;;;32269:887;;31859:1303;;;31767:1395;;:::o;33168:177::-;33308:29;33304:1;33296:6;33292:14;33285:53;33168:177;:::o;33351:366::-;33493:3;33514:67;33578:2;33573:3;33514:67;:::i;:::-;33507:74;;33590:93;33679:3;33590:93;:::i;:::-;33708:2;33703:3;33699:12;33692:19;;33351:366;;;:::o;33723:419::-;33889:4;33927:2;33916:9;33912:18;33904:26;;33976:9;33970:4;33966:20;33962:1;33951:9;33947:17;33940:47;34004:131;34130:4;34004:131;:::i;:::-;33996:139;;33723:419;;;:::o;34148:172::-;34288:24;34284:1;34276:6;34272:14;34265:48;34148:172;:::o;34326:366::-;34468:3;34489:67;34553:2;34548:3;34489:67;:::i;:::-;34482:74;;34565:93;34654:3;34565:93;:::i;:::-;34683:2;34678:3;34674:12;34667:19;;34326:366;;;:::o;34698:419::-;34864:4;34902:2;34891:9;34887:18;34879:26;;34951:9;34945:4;34941:20;34937:1;34926:9;34922:17;34915:47;34979:131;35105:4;34979:131;:::i;:::-;34971:139;;34698:419;;;:::o;35123:235::-;35263:34;35259:1;35251:6;35247:14;35240:58;35332:18;35327:2;35319:6;35315:15;35308:43;35123:235;:::o;35364:366::-;35506:3;35527:67;35591:2;35586:3;35527:67;:::i;:::-;35520:74;;35603:93;35692:3;35603:93;:::i;:::-;35721:2;35716:3;35712:12;35705:19;;35364:366;;;:::o;35736:419::-;35902:4;35940:2;35929:9;35925:18;35917:26;;35989:9;35983:4;35979:20;35975:1;35964:9;35960:17;35953:47;36017:131;36143:4;36017:131;:::i;:::-;36009:139;;35736:419;;;:::o;36161:148::-;36263:11;36300:3;36285:18;;36161:148;;;;:::o;36315:390::-;36421:3;36449:39;36482:5;36449:39;:::i;:::-;36504:89;36586:6;36581:3;36504:89;:::i;:::-;36497:96;;36602:65;36660:6;36655:3;36648:4;36641:5;36637:16;36602:65;:::i;:::-;36692:6;36687:3;36683:16;36676:23;;36425:280;36315:390;;;;:::o;36711:155::-;36851:7;36847:1;36839:6;36835:14;36828:31;36711:155;:::o;36872:400::-;37032:3;37053:84;37135:1;37130:3;37053:84;:::i;:::-;37046:91;;37146:93;37235:3;37146:93;:::i;:::-;37264:1;37259:3;37255:11;37248:18;;36872:400;;;:::o;37278:701::-;37559:3;37581:95;37672:3;37663:6;37581:95;:::i;:::-;37574:102;;37693:95;37784:3;37775:6;37693:95;:::i;:::-;37686:102;;37805:148;37949:3;37805:148;:::i;:::-;37798:155;;37970:3;37963:10;;37278:701;;;;;:::o;37985:225::-;38125:34;38121:1;38113:6;38109:14;38102:58;38194:8;38189:2;38181:6;38177:15;38170:33;37985:225;:::o;38216:366::-;38358:3;38379:67;38443:2;38438:3;38379:67;:::i;:::-;38372:74;;38455:93;38544:3;38455:93;:::i;:::-;38573:2;38568:3;38564:12;38557:19;;38216:366;;;:::o;38588:419::-;38754:4;38792:2;38781:9;38777:18;38769:26;;38841:9;38835:4;38831:20;38827:1;38816:9;38812:17;38805:47;38869:131;38995:4;38869:131;:::i;:::-;38861:139;;38588:419;;;:::o;39013:233::-;39052:3;39075:24;39093:5;39075:24;:::i;:::-;39066:33;;39121:66;39114:5;39111:77;39108:103;;39191:18;;:::i;:::-;39108:103;39238:1;39231:5;39227:13;39220:20;;39013:233;;;:::o;39252:180::-;39300:77;39297:1;39290:88;39397:4;39394:1;39387:15;39421:4;39418:1;39411:15;39438:185;39478:1;39495:20;39513:1;39495:20;:::i;:::-;39490:25;;39529:20;39547:1;39529:20;:::i;:::-;39524:25;;39568:1;39558:35;;39573:18;;:::i;:::-;39558:35;39615:1;39612;39608:9;39603:14;;39438:185;;;;:::o;39629:194::-;39669:4;39689:20;39707:1;39689:20;:::i;:::-;39684:25;;39723:20;39741:1;39723:20;:::i;:::-;39718:25;;39767:1;39764;39760:9;39752:17;;39791:1;39785:4;39782:11;39779:37;;;39796:18;;:::i;:::-;39779:37;39629:194;;;;:::o;39829:176::-;39861:1;39878:20;39896:1;39878:20;:::i;:::-;39873:25;;39912:20;39930:1;39912:20;:::i;:::-;39907:25;;39951:1;39941:35;;39956:18;;:::i;:::-;39941:35;39997:1;39994;39990:9;39985:14;;39829:176;;;;:::o;40011:180::-;40059:77;40056:1;40049:88;40156:4;40153:1;40146:15;40180:4;40177:1;40170:15;40197:98;40248:6;40282:5;40276:12;40266:22;;40197:98;;;:::o;40301:168::-;40384:11;40418:6;40413:3;40406:19;40458:4;40453:3;40449:14;40434:29;;40301:168;;;;:::o;40475:373::-;40561:3;40589:38;40621:5;40589:38;:::i;:::-;40643:70;40706:6;40701:3;40643:70;:::i;:::-;40636:77;;40722:65;40780:6;40775:3;40768:4;40761:5;40757:16;40722:65;:::i;:::-;40812:29;40834:6;40812:29;:::i;:::-;40807:3;40803:39;40796:46;;40565:283;40475:373;;;;:::o;40854:640::-;41049:4;41087:3;41076:9;41072:19;41064:27;;41101:71;41169:1;41158:9;41154:17;41145:6;41101:71;:::i;:::-;41182:72;41250:2;41239:9;41235:18;41226:6;41182:72;:::i;:::-;41264;41332:2;41321:9;41317:18;41308:6;41264:72;:::i;:::-;41383:9;41377:4;41373:20;41368:2;41357:9;41353:18;41346:48;41411:76;41482:4;41473:6;41411:76;:::i;:::-;41403:84;;40854:640;;;;;;;:::o;41500:141::-;41556:5;41587:6;41581:13;41572:22;;41603:32;41629:5;41603:32;:::i;:::-;41500:141;;;;:::o;41647:349::-;41716:6;41765:2;41753:9;41744:7;41740:23;41736:32;41733:119;;;41771:79;;:::i;:::-;41733:119;41891:1;41916:63;41971:7;41962:6;41951:9;41947:22;41916:63;:::i;:::-;41906:73;;41862:127;41647:349;;;;:::o

Swarm Source

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