MATIC Price: $0.506163 (+1.61%)
Gas: 30.1 GWei
 

Overview

Max Total Supply

1,856 DEC

Holders

57

Total Transfers

-

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A

Other Info

Loading...
Loading
Loading...
Loading
Loading...
Loading

OVERVIEW

Dark Earth is a Cross-Platform Blockchain Gaming Ecosystem where the NFTs are shared between all the videogames of the ecosystem.

Contract Source Code Verified (Exact Match)

Contract Name:
DECollection

Compiler Version
v0.8.15+commit.e14f2714

Optimization Enabled:
Yes with 350 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at polygonscan.com on 2022-06-22
*/

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


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

pragma solidity ^0.8.0;

/**
 * @title Counters
 * @author Matt Condon (@shrugs)
 * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number
 * of elements in a mapping, issuing ERC721 ids, or counting request ids.
 *
 * Include with `using Counters for Counters.Counter;`
 */
library Counters {
    struct Counter {
        // This variable should never be directly accessed by users of the library: interactions must be restricted to
        // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add
        // this feature: see https://github.com/ethereum/solidity/issues/4637
        uint256 _value; // default: 0
    }

    function current(Counter storage counter) internal view returns (uint256) {
        return counter._value;
    }

    function increment(Counter storage counter) internal {
        unchecked {
            counter._value += 1;
        }
    }

    function decrement(Counter storage counter) internal {
        uint256 value = counter._value;
        require(value > 0, "Counter: decrement overflow");
        unchecked {
            counter._value = value - 1;
        }
    }

    function reset(Counter storage counter) internal {
        counter._value = 0;
    }
}

// File: @openzeppelin/contracts/utils/structs/EnumerableSet.sol


// OpenZeppelin Contracts (last updated v4.6.0) (utils/structs/EnumerableSet.sol)

pragma solidity ^0.8.0;

/**
 * @dev Library for managing
 * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
 * types.
 *
 * Sets have the following properties:
 *
 * - Elements are added, removed, and checked for existence in constant time
 * (O(1)).
 * - Elements are enumerated in O(n). No guarantees are made on the ordering.
 *
 * ```
 * contract Example {
 *     // Add the library methods
 *     using EnumerableSet for EnumerableSet.AddressSet;
 *
 *     // Declare a set state variable
 *     EnumerableSet.AddressSet private mySet;
 * }
 * ```
 *
 * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
 * and `uint256` (`UintSet`) are supported.
 */
library EnumerableSet {
    // To implement this library for multiple types with as little code
    // repetition as possible, we write it in terms of a generic Set type with
    // bytes32 values.
    // The Set implementation uses private functions, and user-facing
    // implementations (such as AddressSet) are just wrappers around the
    // underlying Set.
    // This means that we can only create new EnumerableSets for types that fit
    // in bytes32.

    struct Set {
        // Storage of set values
        bytes32[] _values;
        // Position of the value in the `values` array, plus 1 because index 0
        // means a value is not in the set.
        mapping(bytes32 => uint256) _indexes;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function _add(Set storage set, bytes32 value) private returns (bool) {
        if (!_contains(set, value)) {
            set._values.push(value);
            // The value is stored at length-1, but we add 1 to all indexes
            // and use 0 as a sentinel value
            set._indexes[value] = set._values.length;
            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function _remove(Set storage set, bytes32 value) private returns (bool) {
        // We read and store the value's index to prevent multiple reads from the same storage slot
        uint256 valueIndex = set._indexes[value];

        if (valueIndex != 0) {
            // Equivalent to contains(set, value)
            // To delete an element from the _values array in O(1), we swap the element to delete with the last one in
            // the array, and then remove the last element (sometimes called as 'swap and pop').
            // This modifies the order of the array, as noted in {at}.

            uint256 toDeleteIndex = valueIndex - 1;
            uint256 lastIndex = set._values.length - 1;

            if (lastIndex != toDeleteIndex) {
                bytes32 lastValue = set._values[lastIndex];

                // Move the last value to the index where the value to delete is
                set._values[toDeleteIndex] = lastValue;
                // Update the index for the moved value
                set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex
            }

            // Delete the slot where the moved value was stored
            set._values.pop();

            // Delete the index for the deleted slot
            delete set._indexes[value];

            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function _contains(Set storage set, bytes32 value) private view returns (bool) {
        return set._indexes[value] != 0;
    }

    /**
     * @dev Returns the number of values on the set. O(1).
     */
    function _length(Set storage set) private view returns (uint256) {
        return set._values.length;
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function _at(Set storage set, uint256 index) private view returns (bytes32) {
        return set._values[index];
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function _values(Set storage set) private view returns (bytes32[] memory) {
        return set._values;
    }

    // Bytes32Set

    struct Bytes32Set {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
        return _add(set._inner, value);
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
        return _remove(set._inner, value);
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
        return _contains(set._inner, value);
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(Bytes32Set storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
        return _at(set._inner, index);
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {
        return _values(set._inner);
    }

    // AddressSet

    struct AddressSet {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(AddressSet storage set, address value) internal returns (bool) {
        return _add(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(AddressSet storage set, address value) internal returns (bool) {
        return _remove(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(AddressSet storage set, address value) internal view returns (bool) {
        return _contains(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(AddressSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(AddressSet storage set, uint256 index) internal view returns (address) {
        return address(uint160(uint256(_at(set._inner, index))));
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(AddressSet storage set) internal view returns (address[] memory) {
        bytes32[] memory store = _values(set._inner);
        address[] memory result;

        assembly {
            result := store
        }

        return result;
    }

    // UintSet

    struct UintSet {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(UintSet storage set, uint256 value) internal returns (bool) {
        return _add(set._inner, bytes32(value));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(UintSet storage set, uint256 value) internal returns (bool) {
        return _remove(set._inner, bytes32(value));
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(UintSet storage set, uint256 value) internal view returns (bool) {
        return _contains(set._inner, bytes32(value));
    }

    /**
     * @dev Returns the number of values on the set. O(1).
     */
    function length(UintSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(UintSet storage set, uint256 index) internal view returns (uint256) {
        return uint256(_at(set._inner, index));
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(UintSet storage set) internal view returns (uint256[] memory) {
        bytes32[] memory store = _values(set._inner);
        uint256[] memory result;

        assembly {
            result := store
        }

        return result;
    }
}

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


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

pragma solidity ^0.8.0;

/**
 * @dev External interface of AccessControl declared to support ERC165 detection.
 */
interface IAccessControl {
    /**
     * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
     *
     * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
     * {RoleAdminChanged} not being emitted signaling this.
     *
     * _Available since v3.1._
     */
    event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);

    /**
     * @dev Emitted when `account` is granted `role`.
     *
     * `sender` is the account that originated the contract call, an admin role
     * bearer except when using {AccessControl-_setupRole}.
     */
    event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Emitted when `account` is revoked `role`.
     *
     * `sender` is the account that originated the contract call:
     *   - if using `revokeRole`, it is the admin role bearer
     *   - if using `renounceRole`, it is the role bearer (i.e. `account`)
     */
    event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Returns `true` if `account` has been granted `role`.
     */
    function hasRole(bytes32 role, address account) external view returns (bool);

    /**
     * @dev Returns the admin role that controls `role`. See {grantRole} and
     * {revokeRole}.
     *
     * To change a role's admin, use {AccessControl-_setRoleAdmin}.
     */
    function getRoleAdmin(bytes32 role) external view returns (bytes32);

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function grantRole(bytes32 role, address account) external;

    /**
     * @dev Revokes `role` from `account`.
     *
     * If `account` had been granted `role`, emits a {RoleRevoked} event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function revokeRole(bytes32 role, address account) external;

    /**
     * @dev Revokes `role` from the calling account.
     *
     * Roles are often managed via {grantRole} and {revokeRole}: this function's
     * purpose is to provide a mechanism for accounts to lose their privileges
     * if they are compromised (such as when a trusted device is misplaced).
     *
     * If the calling account had been granted `role`, emits a {RoleRevoked}
     * event.
     *
     * Requirements:
     *
     * - the caller must be `account`.
     */
    function renounceRole(bytes32 role, address account) external;
}

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


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

pragma solidity ^0.8.0;


/**
 * @dev External interface of AccessControlEnumerable declared to support ERC165 detection.
 */
interface IAccessControlEnumerable is IAccessControl {
    /**
     * @dev Returns one of the accounts that have `role`. `index` must be a
     * value between 0 and {getRoleMemberCount}, non-inclusive.
     *
     * Role bearers are not sorted in any particular way, and their ordering may
     * change at any point.
     *
     * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure
     * you perform all queries on the same block. See the following
     * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]
     * for more information.
     */
    function getRoleMember(bytes32 role, uint256 index) external view returns (address);

    /**
     * @dev Returns the number of accounts that have `role`. Can be used
     * together with {getRoleMember} to enumerate all bearers of a role.
     */
    function getRoleMemberCount(bytes32 role) external view returns (uint256);
}

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


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

pragma solidity ^0.8.0;

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

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

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

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

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

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


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

pragma solidity ^0.8.0;


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

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

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

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

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

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

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

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

        return (signer, RecoverError.NoError);
    }

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

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

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

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

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


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

pragma solidity ^0.8.0;

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

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

// File: @openzeppelin/contracts/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: @openzeppelin/contracts/token/ERC721/IERC721Receiver.sol


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

pragma solidity ^0.8.0;

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

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


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

pragma solidity ^0.8.0;

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

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


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

pragma solidity ^0.8.0;


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

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


// OpenZeppelin Contracts (last updated v4.6.0) (access/AccessControl.sol)

pragma solidity ^0.8.0;





/**
 * @dev Contract module that allows children to implement role-based access
 * control mechanisms. This is a lightweight version that doesn't allow enumerating role
 * members except through off-chain means by accessing the contract event logs. Some
 * applications may benefit from on-chain enumerability, for those cases see
 * {AccessControlEnumerable}.
 *
 * Roles are referred to by their `bytes32` identifier. These should be exposed
 * in the external API and be unique. The best way to achieve this is by
 * using `public constant` hash digests:
 *
 * ```
 * bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
 * ```
 *
 * Roles can be used to represent a set of permissions. To restrict access to a
 * function call, use {hasRole}:
 *
 * ```
 * function foo() public {
 *     require(hasRole(MY_ROLE, msg.sender));
 *     ...
 * }
 * ```
 *
 * Roles can be granted and revoked dynamically via the {grantRole} and
 * {revokeRole} functions. Each role has an associated admin role, and only
 * accounts that have a role's admin role can call {grantRole} and {revokeRole}.
 *
 * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means
 * that only accounts with this role will be able to grant or revoke other
 * roles. More complex role relationships can be created by using
 * {_setRoleAdmin}.
 *
 * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to
 * grant and revoke this role. Extra precautions should be taken to secure
 * accounts that have been granted it.
 */
abstract contract AccessControl is Context, IAccessControl, ERC165 {
    struct RoleData {
        mapping(address => bool) members;
        bytes32 adminRole;
    }

    mapping(bytes32 => RoleData) private _roles;

    bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;

    /**
     * @dev Modifier that checks that an account has a specific role. Reverts
     * with a standardized message including the required role.
     *
     * The format of the revert reason is given by the following regular expression:
     *
     *  /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
     *
     * _Available since v4.1._
     */
    modifier onlyRole(bytes32 role) {
        _checkRole(role);
        _;
    }

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

    /**
     * @dev Returns `true` if `account` has been granted `role`.
     */
    function hasRole(bytes32 role, address account) public view virtual override returns (bool) {
        return _roles[role].members[account];
    }

    /**
     * @dev Revert with a standard message if `_msgSender()` is missing `role`.
     * Overriding this function changes the behavior of the {onlyRole} modifier.
     *
     * Format of the revert message is described in {_checkRole}.
     *
     * _Available since v4.6._
     */
    function _checkRole(bytes32 role) internal view virtual {
        _checkRole(role, _msgSender());
    }

    /**
     * @dev Revert with a standard message if `account` is missing `role`.
     *
     * The format of the revert reason is given by the following regular expression:
     *
     *  /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
     */
    function _checkRole(bytes32 role, address account) internal view virtual {
        if (!hasRole(role, account)) {
            revert(
                string(
                    abi.encodePacked(
                        "AccessControl: account ",
                        Strings.toHexString(uint160(account), 20),
                        " is missing role ",
                        Strings.toHexString(uint256(role), 32)
                    )
                )
            );
        }
    }

    /**
     * @dev Returns the admin role that controls `role`. See {grantRole} and
     * {revokeRole}.
     *
     * To change a role's admin, use {_setRoleAdmin}.
     */
    function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {
        return _roles[role].adminRole;
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
        _grantRole(role, account);
    }

    /**
     * @dev Revokes `role` from `account`.
     *
     * If `account` had been granted `role`, emits a {RoleRevoked} event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
        _revokeRole(role, account);
    }

    /**
     * @dev Revokes `role` from the calling account.
     *
     * Roles are often managed via {grantRole} and {revokeRole}: this function's
     * purpose is to provide a mechanism for accounts to lose their privileges
     * if they are compromised (such as when a trusted device is misplaced).
     *
     * If the calling account had been revoked `role`, emits a {RoleRevoked}
     * event.
     *
     * Requirements:
     *
     * - the caller must be `account`.
     */
    function renounceRole(bytes32 role, address account) public virtual override {
        require(account == _msgSender(), "AccessControl: can only renounce roles for self");

        _revokeRole(role, account);
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event. Note that unlike {grantRole}, this function doesn't perform any
     * checks on the calling account.
     *
     * [WARNING]
     * ====
     * This function should only be called from the constructor when setting
     * up the initial roles for the system.
     *
     * Using this function in any other way is effectively circumventing the admin
     * system imposed by {AccessControl}.
     * ====
     *
     * NOTE: This function is deprecated in favor of {_grantRole}.
     */
    function _setupRole(bytes32 role, address account) internal virtual {
        _grantRole(role, account);
    }

    /**
     * @dev Sets `adminRole` as ``role``'s admin role.
     *
     * Emits a {RoleAdminChanged} event.
     */
    function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
        bytes32 previousAdminRole = getRoleAdmin(role);
        _roles[role].adminRole = adminRole;
        emit RoleAdminChanged(role, previousAdminRole, adminRole);
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * Internal function without access restriction.
     */
    function _grantRole(bytes32 role, address account) internal virtual {
        if (!hasRole(role, account)) {
            _roles[role].members[account] = true;
            emit RoleGranted(role, account, _msgSender());
        }
    }

    /**
     * @dev Revokes `role` from `account`.
     *
     * Internal function without access restriction.
     */
    function _revokeRole(bytes32 role, address account) internal virtual {
        if (hasRole(role, account)) {
            _roles[role].members[account] = false;
            emit RoleRevoked(role, account, _msgSender());
        }
    }
}

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


// OpenZeppelin Contracts (last updated v4.5.0) (access/AccessControlEnumerable.sol)

pragma solidity ^0.8.0;




/**
 * @dev Extension of {AccessControl} that allows enumerating the members of each role.
 */
abstract contract AccessControlEnumerable is IAccessControlEnumerable, AccessControl {
    using EnumerableSet for EnumerableSet.AddressSet;

    mapping(bytes32 => EnumerableSet.AddressSet) private _roleMembers;

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

    /**
     * @dev Returns one of the accounts that have `role`. `index` must be a
     * value between 0 and {getRoleMemberCount}, non-inclusive.
     *
     * Role bearers are not sorted in any particular way, and their ordering may
     * change at any point.
     *
     * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure
     * you perform all queries on the same block. See the following
     * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]
     * for more information.
     */
    function getRoleMember(bytes32 role, uint256 index) public view virtual override returns (address) {
        return _roleMembers[role].at(index);
    }

    /**
     * @dev Returns the number of accounts that have `role`. Can be used
     * together with {getRoleMember} to enumerate all bearers of a role.
     */
    function getRoleMemberCount(bytes32 role) public view virtual override returns (uint256) {
        return _roleMembers[role].length();
    }

    /**
     * @dev Overload {_grantRole} to track enumerable memberships
     */
    function _grantRole(bytes32 role, address account) internal virtual override {
        super._grantRole(role, account);
        _roleMembers[role].add(account);
    }

    /**
     * @dev Overload {_revokeRole} to track enumerable memberships
     */
    function _revokeRole(bytes32 role, address account) internal virtual override {
        super._revokeRole(role, account);
        _roleMembers[role].remove(account);
    }
}

// File: @openzeppelin/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 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);
}

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


// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)

pragma solidity ^0.8.0;


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

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

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

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


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

pragma solidity ^0.8.0;


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

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

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

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


// OpenZeppelin Contracts (last updated v4.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: balance query for the zero address");
        return _balances[owner];
    }

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

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

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

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

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

    /**
     * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each
     * token will be the concatenation of the `baseURI` and the `tokenId`. Empty
     * by default, can be 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 a {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 a {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 {}
}

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


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

pragma solidity ^0.8.0;



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

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

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

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

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

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

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

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

    /**
     * @dev Hook that is called before any token transfer. This includes minting
     * and burning.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be
     * transferred to `to`.
     * - When `from` is zero, `tokenId` will be minted for `to`.
     * - When `to` is zero, ``from``'s `tokenId` will be burned.
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual override {
        super._beforeTokenTransfer(from, to, tokenId);

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

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

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

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

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

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

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

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

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

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

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

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

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

// File: DECollection.sol

/*
 _______       ___      .______       __  ___       _______      ___      .______      .___________. __    __  
|       \     /   \     |   _  \     |  |/  /      |   ____|    /   \     |   _  \     |           ||  |  |  | 
|  .--.  |   /  ^  \    |  |_)  |    |  '  /       |  |__      /  ^  \    |  |_)  |    `---|  |----`|  |__|  | 
|  |  |  |  /  /_\  \   |      /     |    <        |   __|    /  /_\  \   |      /         |  |     |   __   | 
|  '--'  | /  _____  \  |  |\  \----.|  .  \       |  |____  /  _____  \  |  |\  \----.    |  |     |  |  |  | 
|_______/ /__/     \__\ | _| `._____||__|\__\      |_______|/__/     \__\ | _| `._____|    |__|     |__|  |__| 
                                                                                                             
                                WWW.DARKEARTH.GG by Olympus Origin.
                        Coded by Jesús Sánchez Fernández & Juan Palomo Cisneros
*/

//SPDX-License-Identifier: MIT
pragma solidity 0.8.15;

// Smart Contracts imports





contract DECollection is ERC721Enumerable, AccessControlEnumerable {

    using Strings for uint256;
    using Counters for Counters.Counter;
    /**********************************************
     **********************************************
                       VARIABLES
    **********************************************                    
    **********************************************/

    // Variables de suspensión de funcionalidades
    bool private suspended = false; // Suspender funciones generales del SC

    // Wallet para comprobar la firma
    address private signAddr;

    string private _baseURIExtend;

    Counters.Counter private _tokenIdTracker;
    
    //Adds support for OpenSea
    bytes4 private constant _INTERFACE_ID_ERC2981 = 0x2a55205a;
    address private OpenSeaAddress = 0x58807baD0B376efc12F5AD86aAc70E78ed67deaE;

    //Roles of minter and burner
    bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
    bytes32 public constant BURNER_ROLE = keccak256("BURNER_ROLE");
    
    //Royaties address and amnount
    address payable private _royaltiesAddress;
    uint96 private _royaltiesBasicPoints;  
    uint96 private maxRoyaltiePoints = 1500;  

    // --> Control del Supply

    struct nftSup {
        uint256 sMax;
        Counters.Counter sNow;
        Counters.Counter burned;
    }

    // Mapeo tipo -> Supply
    mapping(uint256 => nftSup) private nftSupply;

    // --> Control tokenId + INFO
    struct nftInfo {
        uint256 tipo;
        uint256 serialNumber;
        bool usado;
    }

    mapping(uint256 => nftInfo) private tokenInfo;

    // Controlar la TX que ya se han registrado
    mapping(string => bool) private txRewarded;

    // Security - MultiOwner
    struct approveMap {
        address approveAddress;
        uint8 apprFunction;
    }

    mapping(address => bool) private owners;
    mapping(address => approveMap) private approvedFunction;
    Counters.Counter private _ownersTracker;

    // Burned control
    mapping(address => uint256[]) private burnedCards;
    
    /**********************************************
     **********************************************
                    CONSTRUCTOR
    **********************************************                    
    **********************************************/
    constructor() ERC721("Dark Earth Collection", "DEC") {

        // URI por defecto
        _baseURIExtend = "https://nft-hub.darkearth.gg/cards/";

        // Dirección que comprueba la firma
        signAddr = _msgSender();

        //Royaties address and amount
        _royaltiesAddress=payable(address(this)); //Contract creator by default
        _royaltiesBasicPoints=1000; //10% default

        // Multi-owner
        owners[0xBB092DA2b7c96854ac0b59893a098b0803156b6a] = true;
        _ownersTracker.increment();
		
        owners[0xd26260934A78B9092BFc5b2518E437B20FE953b2] = true;
        _ownersTracker.increment();
		
		owners[0xB1e2C0F0210d32830E91d2c5ba514FDdA367eC71] = true;
        _ownersTracker.increment();

    }

    /**********************************************
     **********************************************
                    ERC721 STANDARD
    **********************************************                    
    **********************************************/

    receive() external payable {}

    function withdraw(uint amount) external {
        require(checkApproved(_msgSender(), 5), "You do not have permissions");
        payable(_msgSender()).transfer(amount);
    }

    /**********************************************
     **********************************************
                BATCH TRANSFERENCIAS
    **********************************************                    
    **********************************************/

    function bulkSafeTransfer(address _from, address _to, uint256[] calldata tokenIds) external {
        for (uint256 index = 0; index < tokenIds.length; index++) {
            safeTransferFrom(_from, _to, tokenIds[index]);
        }
    }

    /**********************************************
     **********************************************
                    ROLES SYSTEM
    **********************************************                    
    **********************************************/

    function addRole(address _to, bytes32 rol, bool grant) external {
        require(checkApproved(_msgSender(), 3), "You have not been approved to run this function");
        
        if(grant) {
            _grantRole(rol, _to);
        } else {
            _revokeRole(rol, _to);
        }
    }

    /**********************************************
     **********************************************
                    SUPPLY SYSTEM
    **********************************************                    
    **********************************************/

    // Añadir supply masivo
    function addBulkSupply(uint[] calldata tipos, uint[] calldata amount) external {
        require(checkApproved(_msgSender(), 1), "You do not have permissions");
        require(tipos.length == amount.length, "Array sizes do not match");

        for(uint i = 0; i < tipos.length; i++) {
            nftSupply[tipos[i]].sMax = amount[i];
        }
    }

    function getMaxSupply(uint tipo) external view returns(uint) {
        return nftSupply[tipo].sMax;
    }

    function getNowSupply(uint tipo) external view returns(uint) {
        return nftSupply[tipo].sNow.current();
    }

    function getBurnedAmount(uint tipo) external view returns(uint) {
        return nftSupply[tipo].burned.current();
    }

    function getCirculatingSupply(uint tipo) public view returns(uint256) {
        return nftSupply[tipo].sNow.current() - nftSupply[tipo].burned.current();
    }

    function getDilutedMaxSupply(uint tipo) public view returns(uint256) {
        return nftSupply[tipo].sMax - nftSupply[tipo].burned.current();
    }

    // Comprobar el Supply de cada carta
    function checkSupply(uint tipo) internal view returns (bool) {

        bool respuesta = false;

        if(nftSupply[tipo].sNow.current() < nftSupply[tipo].sMax) {
            respuesta = true;
        }

        return respuesta;
    }

    /**********************************************
     **********************************************
                        BURNER
    **********************************************
    **********************************************/

    function burn(uint256 tokenId) public virtual {
        require(!suspended, "The contract is temporaly suspended.");
        require(ownerOf(tokenId) == _msgSender(), "Exception on Burn: Your are not the owner");

        uint tipo = getTokenType(tokenId);
        nftSupply[tipo].burned.increment();

        burnedCards[ownerOf(tokenId)].push(tokenId);

        _burn(tokenId);
    }

    function bulkBurn(uint256[] calldata tokenIds) external {
        for(uint i = 0; i < tokenIds.length; i++){
            burn(tokenIds[i]);
        }
    }

    function bulkAdminBurn(uint256[] calldata tokenIds) external {
        require(!suspended, "The contract is temporaly suspended");
        require(hasRole(BURNER_ROLE, _msgSender()), "Exception on Burn: You do not have permission");

        for(uint i = 0; i < tokenIds.length; i++){
            uint tipo = getTokenType(tokenIds[i]);
            nftSupply[tipo].burned.increment();
            burnedCards[ownerOf(tokenIds[i])].push(tokenIds[i]);
            _burn(tokenIds[i]);
        }
    }

    function getBurnedCardsByWallet(address wallet) external view returns(uint256[] memory) {
        return burnedCards[wallet];
    }

    function getBurnedLengthCardsByWallet(address wallet) external view returns(uint256) {
        return burnedCards[wallet].length;
    }

    /**********************************************
     **********************************************
                    MINTER
              SETTERS AND GETTERS
    **********************************************                    
    **********************************************/
    function mintCards(uint[] calldata cardsIds, string[] calldata txIds, bytes calldata firma) external {
        require(!suspended, "The contract is temporaly suspended.");
        require(isSigValid(generaMensaje(cardsIds, txIds), firma), "SIGNATURE ERROR: What are you trying to do?");
        require(!checkTx(txIds), "ERROR: This transaction is already in our system.");

        for(uint i = 0; i < cardsIds.length; i++) {
            require(checkSupply(cardsIds[i]), "SUPPLY ERROR: Not enough of this type.");
            mint(_msgSender(), cardsIds[i]);
        }
    }

    function adminMint(address _to, uint[] calldata cardsIds) external {
        require(!suspended, "The contract is temporaly suspended.");
        require(hasRole(MINTER_ROLE, _msgSender()), "You dont have Minter role! Sorry");
 
        for(uint i = 0; i < cardsIds.length; i++) {
            require(checkSupply(cardsIds[i]), "SUPPLY ERROR: Not enough of this type.");
            mint(_to, cardsIds[i]);
        }
    }

    function mint(address _to, uint _tipo) internal {
        // Aumento el Supply Actual de ese tipo
        nftSupply[_tipo].sNow.increment(); 

        // Aumento el contador
        _tokenIdTracker.increment();

        // Guardo ID del token -> Tipo
        tokenInfo[_tokenIdTracker.current()].serialNumber = nftSupply[_tipo].sNow.current();
        tokenInfo[_tokenIdTracker.current()].tipo = _tipo;
        tokenInfo[_tokenIdTracker.current()].usado = false;

        // Minteo la carta
        _safeMint(_to, _tokenIdTracker.current());
    } 

    /**********************************************
     **********************************************
                  SIGN SECURITY
    **********************************************                    
    **********************************************/

    // Genera el mensaje para poder verificar la firma
    function generaMensaje(uint[] memory cardsIds, string[] memory txIds) internal pure returns (string memory) {

        string memory mensaje;
        string memory aux;

        for(uint i = 0; i < cardsIds.length;i++){
            aux = string(abi.encodePacked(Strings.toString(cardsIds[i]),","));
            mensaje = string(abi.encodePacked(mensaje, aux));
        }

        for(uint j = 0; j < txIds.length; j++) {
            if(j == txIds.length-1) {
                mensaje = string(abi.encodePacked(mensaje, txIds[j]));
            } else {
                aux = string(abi.encodePacked(txIds[j],","));
                mensaje = string(abi.encodePacked(mensaje, aux));
            }
        }

        return mensaje;
    }

    // Comprobar firma
    function isSigValid (string memory message, bytes memory signature) internal view returns(bool) {
        return signAddr == ECDSA.recover(
            keccak256(abi.encodePacked(message)),
            signature
        );
    }

    function setSignAddr(address newSignAddr) external {
        require(newSignAddr != address(0), "Exception in setSignAddr: Address zero.");
        require(checkApproved(_msgSender(), 2), "You have not been approved to run this function.");
        signAddr = newSignAddr;
    }

    // Comprueba que la transacción no esté en el sistema
    // Si no la está añade
    function checkTx(string[] memory txIds) internal returns(bool) { 
        require(txIds.length > 0, "Exception in checkTx: There are not Tx Ids to check");
        bool respuesta = false;
        uint i = 0;

        while(!respuesta && i < txIds.length) {
            if(txRewarded[txIds[i]]) {
                respuesta = true;
            } else {
                txRewarded[txIds[i]] = true;
            }
            i += 1;
        }
         
        return respuesta;
    }

    /**********************************************
     **********************************************
                     REWARDS ZONE
    **********************************************                    
    **********************************************/

    function bulkSetUsedCard(uint256[] calldata tokenIds) external {
        require(tokenIds.length >0, "Exception in bulkSetUsedCard: Array has not Data");

        for(uint i = 0; i < tokenIds.length; i++) {
            require(_msgSender() == ownerOf(tokenIds[i]), "You do not have this NFT");
            require(exists(tokenIds[i]), "This token not exist");

            tokenInfo[tokenIds[i]].usado = true;
        }
    }

    function bulkAdminUsedCard(uint256[] calldata tokenIds, bool[] calldata toggle) external {
        require(tokenIds.length == toggle.length, "Exception in bulkAdminUsedCard: Array sizes");
        require(checkApproved(_msgSender(), 4), "You have not been approved to run this function");

        for(uint i = 0; i < tokenIds.length; i++) {
            require(exists(tokenIds[i]), "This token not exist");

            tokenInfo[tokenIds[i]].usado = toggle[i];
        }
    }

    /**********************************************
     **********************************************
                GETTERS NFTs POR TIPO
    **********************************************                    
    **********************************************/

    function isTxOnSystem(string memory txId) external view returns(bool) {
        return txRewarded[txId];
    }

    function getTokenInfo(uint256 tokenId) external view returns (uint256 typeNft, bool used) {
        require(exists(tokenId), "This token does not exist.");
        return (tokenInfo[tokenId].tipo, tokenInfo[tokenId].usado);
    }

    function getTokenSerial(uint256 tokenId) external view returns (string memory) {
        require(exists(tokenId), "This token does not exist.");

        uint tipo = getTokenType(tokenId);
        string memory nSerie = (tokenInfo[tokenId].serialNumber).toString();
        string memory nMax = (nftSupply[tipo].sMax).toString();

        string memory serial = string(abi.encodePacked(nSerie, "/", nMax));
        return serial;
    }

    function getTokenIds(address _owner) public view returns (uint256[] memory) {
        uint256 ownerTokenCount = balanceOf(_owner);
        uint256[] memory tokenIds = new uint256[](ownerTokenCount);
        for (uint256 i = 0; i < ownerTokenCount; i++)
            tokenIds[i] = tokenOfOwnerByIndex(_owner, i);

        return tokenIds;
    }

    function getTokenNotUsedIds(address _owner) external view returns (uint256[] memory) {
        
        uint256 ownerTokenCount = balanceOf(_owner);
        uint256[] memory tokenIds = new uint256[](ownerTokenCount);

        uint256 aux;
        uint256 contador = 0;

        for (uint256 i = 0; i < ownerTokenCount; i++) {

            aux = tokenOfOwnerByIndex(_owner, i);

            if(!tokenInfo[aux].usado) {
                tokenIds[contador] = aux;
                contador += 1;
            }

        }

        return clearArray(tokenIds, contador);
    }

    function getTokenType(uint256 tokenId) public view returns (uint256) {
        require(exists(tokenId), "That token does not exist.");
        return tokenInfo[tokenId].tipo;
    }

    function getTokenTypeCount(address _owner, uint256 tipo) public view returns (uint256) {
        
        uint256[] memory tokenIds = getTokenIds(_owner);
        uint256 contador = 0;
        uint256 aux;

        for(uint i = 0; i < tokenIds.length; i++) {
            aux = tokenIds[i];
            if(tokenInfo[aux].tipo == tipo)
                 contador += 1;
        }

        return contador;
    }

    function getTokenByType(address _owner, uint256 tipo) external view returns (uint256[] memory) {
        
        uint256[] memory tokens = getTokenIds(_owner);
        uint256[] memory tokensIds = new uint256[](tokens.length);

        uint8 k = 0;
        
        for(uint i = 0; i < tokens.length; i++){
            if(tokenInfo[tokens[i]].tipo == tipo) {
                tokensIds[k] = tokens[i];
                k += 1;
            }
        }

        require(k > 0, "ERROR: You dont have NFTs of this type.");
        return clearArray(tokensIds, k);
    }

    function clearArray(uint256[] memory array, uint256 size) internal pure returns(uint256[] memory) {
        uint256[] memory result = new uint[](size);
        for(uint256 i = 0; i < size; i++){
            result[i] = array[i];
        }
        return result;
    }

    /**********************************************
     **********************************************
                  GETTERs Y SETTERs
    **********************************************                    
    **********************************************/

    // Suspender funcionalidades general del SC
    function isSuspend() external view returns (bool) {
        return suspended;
    }

    function toggleSuspend(bool value) external {
        require(checkApproved(_msgSender(), 7), "You have not been approved to run this function.");
        suspended = value;
    }

    /**********************************************
     **********************************************
                   SPECIAL URI
    **********************************************                    
    **********************************************/

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

    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");

        string memory _tokenType = tokenInfo[tokenId].tipo.toString();
        string memory _base = _baseURI();

        string memory _msgUri;

        if(tokenInfo[tokenId].usado) {
            _msgUri = string(abi.encodePacked(_tokenType, "-used"));
        } else {
            _msgUri = string(_tokenType);
        }
            
        return string(abi.encodePacked(_base, _msgUri, ".json"));
    }

    function setBaseURI(string memory newUri) external {
        require(checkApproved(_msgSender(), 8), "You have not been approved to run this function.");
        _baseURIExtend = newUri;
    }

    /**********************************************
     **********************************************
                   ROYALTIES & OPENSEA
    **********************************************                    
    **********************************************/

    //Public wrapper of _exists
    function exists(uint256 tokenId) public view returns (bool) {
        return _exists(tokenId);
    }

    function royaltyInfo(uint256 _tokenId, uint256 _salePrice ) external view returns (address receiver, uint256 royaltyAmount) {
        if(exists(_tokenId))
            return(_royaltiesAddress, (_salePrice * _royaltiesBasicPoints)/10000);        
        return (address(0), 0); 
    }

    function setRoyaltiesAddress(address payable rAddress) external {
        require(rAddress != address(0), "Exception in setRoyaltiesAddress: Address zero.");
        require(checkApproved(_msgSender(), 9), "You have not been approved to run this function");
        _royaltiesAddress=rAddress;
    }

    function setRoyaltiesBasicPoints(uint96 rBasicPoints) external {
        require(checkApproved(_msgSender(), 10), "You have not been approved to run this function");
        require(rBasicPoints <= maxRoyaltiePoints, "Royaties error: Limit reached");
        
        _royaltiesBasicPoints=rBasicPoints;
    }  

    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721Enumerable, AccessControlEnumerable) returns (bool) {
        if(interfaceId == _INTERFACE_ID_ERC2981) {
            return true;
        }

        return super.supportsInterface(interfaceId);
    }

    /**
    * Override isApprovedForAll to auto-approve OS's proxy contract
    **/
    function isApprovedForAll(address _owner, address _operator) public override(ERC721, IERC721) view returns (bool isOperator) {
      // if OpenSea's ERC721 Proxy Address is detected, auto-return true
        if (_operator == OpenSeaAddress) {
            return true;
        }
        
        // otherwise, use the default ERC721.isApprovedForAll()
        return super.isApprovedForAll(_owner, _operator);
    }

    function setOpenSeaAddress(address newAdd) external {
        require(newAdd != address(0), "Exception in setOpenSeaAddress: Address zero.");
        require(checkApproved(_msgSender(), 11), "You have not been approved to run this function.");
        OpenSeaAddress = newAdd;
    }

    function getOpenSeaAddress() external view returns (address) {
        return OpenSeaAddress;
    }

    /*****************************************
                MULTI-OWNER SECURITY
    ******************************************/

    function existOwner(address addr) public view returns(bool) {
        return owners[addr];
    }

    function checkApproved(address user, uint8 idFunc) internal returns(bool) {
        require(existOwner(user), "This is not a wallet from a owner");
        bool aprobado = false;
        if(approvedFunction[user].apprFunction == idFunc) {
            aprobado = true;
            clearApprove(user);
        }
        return aprobado;
    }

    function approveOwner(uint8 idFunc, address owner) external {
        require(existOwner(_msgSender()), "You are not owner");
        require(existOwner(owner), "This is not a wallet from a owner");
        require(_msgSender() != owner, "You cannot authorize yourself");
        require(approvedFunction[owner].apprFunction == 0, "There is already a pending authorization for this owner.");
        approvedFunction[owner].apprFunction = idFunc;
        approvedFunction[owner].approveAddress = _msgSender();
    }

    function clearApprove(address owner) public {
        require(existOwner(_msgSender()), "You are not owner");
        require(existOwner(owner), "This is not a wallet from a owner");

        if (_msgSender() != owner) {
            require(approvedFunction[owner].approveAddress == _msgSender(), "You have not given this authorization");
        }

        approvedFunction[owner].apprFunction = 0;
        approvedFunction[owner].approveAddress = address(0);
    }

    /*****************************************
                CONTROL DE OWNERS
    ******************************************/

    function addOwner(address newOwner) external {
        require(checkApproved(_msgSender(), 12), "You have not been approved to run this function");
        
        owners[newOwner] = true;
        _ownersTracker.increment();
    }

    function delOwner(address addr) external {
        require(checkApproved(_msgSender(), 6), "You have not been approved to run this function");

        owners[addr] = false;
        _ownersTracker.decrement();
        approvedFunction[addr].apprFunction = 0;
        approvedFunction[addr].approveAddress = address(0);
    }
   
    function getTotalOwners() external view returns(uint){
        return _ownersTracker.current();
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"BURNER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINTER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tipos","type":"uint256[]"},{"internalType":"uint256[]","name":"amount","type":"uint256[]"}],"name":"addBulkSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"addOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"bytes32","name":"rol","type":"bytes32"},{"internalType":"bool","name":"grant","type":"bool"}],"name":"addRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256[]","name":"cardsIds","type":"uint256[]"}],"name":"adminMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"idFunc","type":"uint8"},{"internalType":"address","name":"owner","type":"address"}],"name":"approveOwner","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":"tokenIds","type":"uint256[]"}],"name":"bulkAdminBurn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"internalType":"bool[]","name":"toggle","type":"bool[]"}],"name":"bulkAdminUsedCard","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"bulkBurn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"bulkSafeTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"bulkSetUsedCard","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"clearApprove","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"delOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"existOwner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"exists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tipo","type":"uint256"}],"name":"getBurnedAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"}],"name":"getBurnedCardsByWallet","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"}],"name":"getBurnedLengthCardsByWallet","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tipo","type":"uint256"}],"name":"getCirculatingSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tipo","type":"uint256"}],"name":"getDilutedMaxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tipo","type":"uint256"}],"name":"getMaxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tipo","type":"uint256"}],"name":"getNowSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getOpenSeaAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getRoleMember","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMemberCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"uint256","name":"tipo","type":"uint256"}],"name":"getTokenByType","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"getTokenIds","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getTokenInfo","outputs":[{"internalType":"uint256","name":"typeNft","type":"uint256"},{"internalType":"bool","name":"used","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"getTokenNotUsedIds","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getTokenSerial","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getTokenType","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"uint256","name":"tipo","type":"uint256"}],"name":"getTokenTypeCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalOwners","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"isOperator","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isSuspend","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"txId","type":"string"}],"name":"isTxOnSystem","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"cardsIds","type":"uint256[]"},{"internalType":"string[]","name":"txIds","type":"string[]"},{"internalType":"bytes","name":"firma","type":"bytes"}],"name":"mintCards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"royaltyAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"newUri","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newAdd","type":"address"}],"name":"setOpenSeaAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"rAddress","type":"address"}],"name":"setRoyaltiesAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint96","name":"rBasicPoints","type":"uint96"}],"name":"setRoyaltiesBasicPoints","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newSignAddr","type":"address"}],"name":"setSignAddr","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":"bool","name":"value","type":"bool"}],"name":"toggleSuspend","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

6080604052600c805460ff19169055600f80546001600160a01b0319167358807bad0b376efc12f5ad86aac70e78ed67deae179055601180546001600160601b0319166105dc1790553480156200005557600080fd5b506040518060400160405280601581526020017f4461726b20456172746820436f6c6c656374696f6e00000000000000000000008152506040518060400160405280600381526020016244454360e81b8152508160009081620000b99190620002ef565b506001620000c88282620002ef565b5050506040518060600160405280602381526020016200596460239139600d90620000f49082620002ef565b50600c8054610100600160a81b031916610100330217905530607d60a31b1760105573bb092da2b7c96854ac0b59893a098b0803156b6a600052601560209081527faa73249110a0dbbf772f41db88213b618200d79444d65cd395ceba4323999869805460ff19166001179055620001789060179062000241811b62002eee17901c565b73d26260934a78b9092bfc5b2518e437b20fe953b2600052601560209081527f31ab9041820be233800041da899ad1138710735860d670cdc55afe8129739070805460ff19166001179055620001da9060179062002eee62000241821b17901c565b73b1e2c0f0210d32830e91d2c5ba514fdda367ec71600052601560209081527e3959751b0dc882fd97b1425c85e8b52dcbbcfe70a0f7b1f4374357edce306e805460ff191660011790556200023b9060179062002eee62000241821b17901c565b620003bb565b80546001019055565b634e487b7160e01b600052604160045260246000fd5b600181811c908216806200027557607f821691505b6020821081036200029657634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620002ea57600081815260208120601f850160051c81016020861015620002c55750805b601f850160051c820191505b81811015620002e657828155600101620002d1565b5050505b505050565b81516001600160401b038111156200030b576200030b6200024a565b62000323816200031c845462000260565b846200029c565b602080601f8311600181146200035b5760008415620003425750858301515b600019600386901b1c1916600185901b178555620002e6565b600085815260208120601f198616915b828110156200038c578886015182559484019460019091019084016200036b565b5085821015620003ab5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b61559980620003cb6000396000f3fe6080604052600436106103f35760003560e01c80636352211e11610208578063a22cb46511610118578063cb9b4a7d116100ab578063db23f9f31161007a578063db23f9f314610cce578063dc95c4a714610ce3578063df453c1414610d03578063e985e9c514610d23578063f547e3a714610d4357600080fd5b8063cb9b4a7d14610c3a578063d004b03614610c5a578063d539139314610c7a578063d547741f14610cae57600080fd5b8063b8b6c856116100e7578063b8b6c85614610ba9578063c87b56dd14610bc1578063c971723d14610be1578063ca15c87314610c1a57600080fd5b8063a22cb46514610b13578063a439b69114610b33578063ab40bb6014610b69578063b88d4fde14610b8957600080fd5b80638d61806b1161019b57806393909db41161016a57806393909db414610a8957806395d89b4114610aa95780639d9ea10b14610abe5780639e124d6914610ade578063a217fddf14610afe57600080fd5b80638d61806b146109e35780639010d07c14610a0357806391d1485414610a235780639238edef14610a6957600080fd5b806373984188116101d7578063739841881461094e57806376aed2e11461096e578063808665a41461098e5780638c7a63ae146109ae57600080fd5b80636352211e146108ce5780636ba9dc35146108ee5780637065cb481461090e57806370a082311461092e57600080fd5b8063282c51f31161030357806342842e0e116102965780634f6ccce7116102655780634f6ccce71461082157806355f804b3146108415780635a8d69c1146108615780635e495d7414610881578063601602ed146108ae57600080fd5b806342842e0e146107a157806342966c68146107c15780634a710448146107e15780634f558e791461080157600080fd5b80632f2ff15d116102d25780632f2ff15d146107215780632f745c591461074157806336568abe146107615780633f76fd051461078157600080fd5b8063282c51f3146106705780632a55205a146106a45780632b3c0703146106e35780632e1a7d4d1461070157600080fd5b80631444798f116103865780631e84af31116103555780631e84af31146105c057806323b872dd146105e0578063247b3eac14610600578063248a9ca31461062057806326147ae41461065057600080fd5b80631444798f1461054b5780631699d8751461056b57806318160ddd1461058b5780631b1ca1d4146105a057600080fd5b80630cabe208116103c25780630cabe208146104b05780630d54a3d8146104d05780630d887c7d146104fd57806311fdb52e1461052b57600080fd5b806301ffc9a7146103ff57806306fdde0314610434578063081812fc14610456578063095ea7b31461048e57600080fd5b366103fa57005b600080fd5b34801561040b57600080fd5b5061041f61041a36600461483c565b610d63565b60405190151581526020015b60405180910390f35b34801561044057600080fd5b50610449610d94565b60405161042b91906148b1565b34801561046257600080fd5b506104766104713660046148c4565b610e26565b6040516001600160a01b03909116815260200161042b565b34801561049a57600080fd5b506104ae6104a93660046148f2565b610ec0565b005b3480156104bc57600080fd5b506104ae6104cb366004614963565b610fd5565b3480156104dc57600080fd5b506104f06104eb3660046148f2565b6111b5565b60405161042b91906149a5565b34801561050957600080fd5b5061051d6105183660046148f2565b611324565b60405190815260200161042b565b34801561053757600080fd5b506104ae6105463660046149e9565b6113a4565b34801561055757600080fd5b506104ae610566366004614a17565b61145c565b34801561057757600080fd5b506104f0610586366004614add565b6116a3565b34801561059757600080fd5b5060085461051d565b3480156105ac57600080fd5b506104ae6105bb366004614b0f565b61170f565b3480156105cc57600080fd5b506104ae6105db366004614add565b611749565b3480156105ec57600080fd5b506104ae6105fb366004614b2a565b611878565b34801561060c57600080fd5b506104ae61061b366004614add565b6118f3565b34801561062c57600080fd5b5061051d61063b3660046148c4565b6000908152600a602052604090206001015490565b34801561065c57600080fd5b506104ae61066b366004614963565b6119b5565b34801561067c57600080fd5b5061051d7f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a84881565b3480156106b057600080fd5b506106c46106bf366004614b6b565b611b59565b604080516001600160a01b03909316835260208301919091520161042b565b3480156106ef57600080fd5b50600f546001600160a01b0316610476565b34801561070d57600080fd5b506104ae61071c3660046148c4565b611bbc565b34801561072d57600080fd5b506104ae61073c366004614b8d565b611c44565b34801561074d57600080fd5b5061051d61075c3660046148f2565b611c69565b34801561076d57600080fd5b506104ae61077c366004614b8d565b611cff565b34801561078d57600080fd5b506104ae61079c366004614bbd565b611d79565b3480156107ad57600080fd5b506104ae6107bc366004614b2a565b611eec565b3480156107cd57600080fd5b506104ae6107dc3660046148c4565b611f07565b3480156107ed57600080fd5b506104ae6107fc366004614c29565b612005565b34801561080d57600080fd5b5061041f61081c3660046148c4565b612046565b34801561082d57600080fd5b5061051d61083c3660046148c4565b612065565b34801561084d57600080fd5b506104ae61085c366004614d26565b6120f8565b34801561086d57600080fd5b5061051d61087c3660046148c4565b61212b565b34801561088d57600080fd5b5061051d61089c3660046148c4565b60009081526012602052604090205490565b3480156108ba57600080fd5b5061051d6108c93660046148c4565b61214e565b3480156108da57600080fd5b506104766108e93660046148c4565b612165565b3480156108fa57600080fd5b506104f0610909366004614add565b6121dc565b34801561091a57600080fd5b506104ae610929366004614add565b6122ae565b34801561093a57600080fd5b5061051d610949366004614add565b612309565b34801561095a57600080fd5b506104ae610969366004614add565b612390565b34801561097a57600080fd5b5061051d6109893660046148c4565b6123e1565b34801561099a57600080fd5b5061051d6109a93660046148c4565b61244b565b3480156109ba57600080fd5b506109ce6109c93660046148c4565b61246a565b6040805192835290151560208301520161042b565b3480156109ef57600080fd5b506104ae6109fe366004614d5b565b6124e4565b348015610a0f57600080fd5b50610476610a1e366004614b6b565b612626565b348015610a2f57600080fd5b5061041f610a3e366004614b8d565b6000918252600a602090815260408084206001600160a01b0393909316845291905290205460ff1690565b348015610a7557600080fd5b506104ae610a84366004614db0565b612645565b348015610a9557600080fd5b50610449610aa43660046148c4565b6127fc565b348015610ab557600080fd5b506104496128ca565b348015610aca57600080fd5b5061051d610ad93660046148c4565b6128d9565b348015610aea57600080fd5b506104ae610af9366004614963565b6128f0565b348015610b0a57600080fd5b5061051d600081565b348015610b1f57600080fd5b506104ae610b2e366004614de4565b61292e565b348015610b3f57600080fd5b5061051d610b4e366004614add565b6001600160a01b031660009081526018602052604090205490565b348015610b7557600080fd5b506104ae610b84366004614e19565b612939565b348015610b9557600080fd5b506104ae610ba4366004614e72565b612979565b348015610bb557600080fd5b50600c5460ff1661041f565b348015610bcd57600080fd5b50610449610bdc3660046148c4565b6129f5565b348015610bed57600080fd5b5061041f610bfc366004614add565b6001600160a01b031660009081526015602052604090205460ff1690565b348015610c2657600080fd5b5061051d610c353660046148c4565b612b0e565b348015610c4657600080fd5b5061041f610c55366004614d26565b612b25565b348015610c6657600080fd5b506104f0610c75366004614add565b612b50565b348015610c8657600080fd5b5061051d7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b348015610cba57600080fd5b506104ae610cc9366004614b8d565b612bf2565b348015610cda57600080fd5b5061051d612c17565b348015610cef57600080fd5b506104ae610cfe366004614add565b612c27565b348015610d0f57600080fd5b506104ae610d1e366004614add565b612cde565b348015610d2f57600080fd5b5061041f610d3e366004614ef2565b612d93565b348015610d4f57600080fd5b506104ae610d5e366004614bbd565b612de2565b6000636ad56fd360e11b6001600160e01b0319831601610d8557506001919050565b610d8e82612ef7565b92915050565b606060008054610da390614f10565b80601f0160208091040260200160405190810160405280929190818152602001828054610dcf90614f10565b8015610e1c5780601f10610df157610100808354040283529160200191610e1c565b820191906000526020600020905b815481529060010190602001808311610dff57829003601f168201915b5050505050905090565b6000818152600260205260408120546001600160a01b0316610ea45760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b6000610ecb82612165565b9050806001600160a01b0316836001600160a01b031603610f385760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610e9b565b336001600160a01b0382161480610f545750610f548133612d93565b610fc65760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610e9b565b610fd08383612f1c565b505050565b600c5460ff16156110345760405162461bcd60e51b815260206004820152602360248201527f54686520636f6e74726163742069732074656d706f72616c792073757370656e60448201526219195960ea1b6064820152608401610e9b565b61105e7f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a84833610a3e565b6110c05760405162461bcd60e51b815260206004820152602d60248201527f457863657074696f6e206f6e204275726e3a20596f7520646f206e6f7420686160448201526c3b32903832b936b4b9b9b4b7b760991b6064820152608401610e9b565b60005b81811015610fd05760006110ee8484848181106110e2576110e2614f4a565b905060200201356123e1565b60008181526012602052604090206002018054600101905590506018600061112d86868681811061112157611121614f4a565b90506020020135612165565b6001600160a01b03166001600160a01b0316815260200190815260200160002084848481811061115f5761115f614f4a565b835460018101855560009485526020948590209190940292909201359190920155506111a284848481811061119657611196614f4a565b90506020020135612f8a565b50806111ad81614f76565b9150506110c3565b606060006111c284612b50565b90506000815167ffffffffffffffff8111156111e0576111e0614c67565b604051908082528060200260200182016040528015611209578160200160208202803683370190505b5090506000805b83518110156112a957856013600086848151811061123057611230614f4a565b6020026020010151815260200190815260200160002060000154036112975783818151811061126157611261614f4a565b6020026020010151838360ff168151811061127e5761127e614f4a565b6020908102919091010152611294600183614f8f565b91505b806112a181614f76565b915050611210565b5060008160ff161161130d5760405162461bcd60e51b815260206004820152602760248201527f4552524f523a20596f7520646f6e742068617665204e465473206f662074686960448201526639903a3cb8329760c91b6064820152608401610e9b565b61131a828260ff16613031565b9695505050505050565b60008061133084612b50565b9050600080805b83518110156113995783818151811061135257611352614f4a565b602002602001015191508560136000848152602001908152602001600020600001540361138757611384600184614fb4565b92505b8061139181614f76565b915050611337565b509095945050505050565b6113af33600a6130ce565b6113cb5760405162461bcd60e51b8152600401610e9b90614fcc565b6011546bffffffffffffffffffffffff908116908216111561142f5760405162461bcd60e51b815260206004820152601d60248201527f526f796174696573206572726f723a204c696d697420726561636865640000006044820152606401610e9b565b601080546bffffffffffffffffffffffff909216600160a01b026001600160a01b03909216919091179055565b600c5460ff161561147f5760405162461bcd60e51b8152600401610e9b9061501b565b6115066114ca8787808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506114c5925088915089905061505f565b61313e565b83838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506132a892505050565b6115665760405162461bcd60e51b815260206004820152602b60248201527f5349474e4154555245204552524f523a20576861742061726520796f7520747260448201526a79696e6720746f20646f3f60a81b6064820152608401610e9b565b611578611573848661505f565b6132f8565b156115df5760405162461bcd60e51b815260206004820152603160248201527f4552524f523a2054686973207472616e73616374696f6e20697320616c726561604482015270323c9034b71037bab91039bcb9ba32b69760791b6064820152608401610e9b565b60005b8581101561169a5761160b8787838181106115ff576115ff614f4a565b90506020020135613436565b6116665760405162461bcd60e51b815260206004820152602660248201527f535550504c59204552524f523a204e6f7420656e6f756768206f662074686973604482015265103a3cb8329760d11b6064820152608401610e9b565b6116883388888481811061167c5761167c614f4a565b90506020020135613462565b8061169281614f76565b9150506115e2565b50505050505050565b6001600160a01b03811660009081526018602090815260409182902080548351818402810184019094528084526060939283018282801561170357602002820191906000526020600020905b8154815260200190600101908083116116ef575b50505050509050919050565b61171a3360076130ce565b6117365760405162461bcd60e51b8152600401610e9b906150e3565b600c805460ff1916911515919091179055565b61175233610bfc565b6117925760405162461bcd60e51b81526020600482015260116024820152702cb7ba9030b932903737ba1037bbb732b960791b6044820152606401610e9b565b6001600160a01b03811660009081526015602052604090205460ff166117ca5760405162461bcd60e51b8152600401610e9b90615133565b336001600160a01b03821614611851576001600160a01b038181166000908152601660205260409020541633146118515760405162461bcd60e51b815260206004820152602560248201527f596f752068617665206e6f7420676976656e207468697320617574686f72697a60448201526430ba34b7b760d91b6064820152608401610e9b565b6001600160a01b0316600090815260166020526040902080546001600160a81b0319169055565b6118823382613524565b6118e85760405162461bcd60e51b815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6044820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b6064820152608401610e9b565b610fd08383836135fb565b6001600160a01b0381166119595760405162461bcd60e51b815260206004820152602760248201527f457863657074696f6e20696e207365745369676e416464723a2041646472657360448201526639903d32b9379760c91b6064820152608401610e9b565b6119643360026130ce565b6119805760405162461bcd60e51b8152600401610e9b906150e3565b600c80546001600160a01b039092166101000274ffffffffffffffffffffffffffffffffffffffff0019909216919091179055565b80611a1b5760405162461bcd60e51b815260206004820152603060248201527f457863657074696f6e20696e2062756c6b53657455736564436172643a20417260448201526f72617920686173206e6f74204461746160801b6064820152608401610e9b565b60005b81811015610fd057611a3b83838381811061112157611121614f4a565b6001600160a01b0316336001600160a01b031614611a9b5760405162461bcd60e51b815260206004820152601860248201527f596f7520646f206e6f7420686176652074686973204e465400000000000000006044820152606401610e9b565b611abc838383818110611ab057611ab0614f4a565b90506020020135612046565b611aff5760405162461bcd60e51b8152602060048201526014602482015273151a1a5cc81d1bdad95b881b9bdd08195e1a5cdd60621b6044820152606401610e9b565b600160136000858585818110611b1757611b17614f4a565b90506020020135815260200190815260200160002060020160006101000a81548160ff0219169083151502179055508080611b5190614f76565b915050611a1e565b600080611b6584612046565b15611bae576010546001600160a01b0381169061271090611b9b90600160a01b90046bffffffffffffffffffffffff1686615174565b611ba591906151a9565b91509150611bb5565b5060009050805b9250929050565b611bc73360056130ce565b611c135760405162461bcd60e51b815260206004820152601b60248201527f596f7520646f206e6f742068617665207065726d697373696f6e7300000000006044820152606401610e9b565b604051339082156108fc029083906000818181858888f19350505050158015611c40573d6000803e3d6000fd5b5050565b6000828152600a6020526040902060010154611c5f816137a2565b610fd083836137ac565b6000611c7483612309565b8210611cd65760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610e9b565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b6001600160a01b0381163314611d6f5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608401610e9b565b611c4082826137ce565b828114611ddc5760405162461bcd60e51b815260206004820152602b60248201527f457863657074696f6e20696e2062756c6b41646d696e55736564436172643a2060448201526a41727261792073697a657360a81b6064820152608401610e9b565b611de73360046130ce565b611e035760405162461bcd60e51b8152600401610e9b90614fcc565b60005b83811015611ee557611e23858583818110611ab057611ab0614f4a565b611e665760405162461bcd60e51b8152602060048201526014602482015273151a1a5cc81d1bdad95b881b9bdd08195e1a5cdd60621b6044820152606401610e9b565b828282818110611e7857611e78614f4a565b9050602002016020810190611e8d9190614b0f565b60136000878785818110611ea357611ea3614f4a565b90506020020135815260200190815260200160002060020160006101000a81548160ff0219169083151502179055508080611edd90614f76565b915050611e06565b5050505050565b610fd083838360405180602001604052806000815250612979565b600c5460ff1615611f2a5760405162461bcd60e51b8152600401610e9b9061501b565b33611f3482612165565b6001600160a01b031614611f9c5760405162461bcd60e51b815260206004820152602960248201527f457863657074696f6e206f6e204275726e3a20596f757220617265206e6f74206044820152683a34329037bbb732b960b91b6064820152608401610e9b565b6000611fa7826123e1565b600081815260126020526040902060020180546001019055905060186000611fce84612165565b6001600160a01b031681526020808201929092526040016000908120805460018101825590825291902001829055611c4082612f8a565b6120103360036130ce565b61202c5760405162461bcd60e51b8152600401610e9b90614fcc565b801561203c57610fd082846137ac565b610fd082846137ce565b6000818152600260205260408120546001600160a01b03161515610d8e565b600061207060085490565b82106120d35760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610e9b565b600882815481106120e6576120e6614f4a565b90600052602060002001549050919050565b6121033360086130ce565b61211f5760405162461bcd60e51b8152600401610e9b906150e3565b600d611c40828261520b565b60008181526012602052604081206002810154600190910154610d8e91906152cb565b600081815260126020526040812060020154610d8e565b6000818152600260205260408120546001600160a01b031680610d8e5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b6064820152608401610e9b565b606060006121e983612309565b905060008167ffffffffffffffff81111561220657612206614c67565b60405190808252806020026020018201604052801561222f578160200160208202803683370190505b509050600080805b848110156122a3576122498782611c69565b60008181526013602052604090206002015490935060ff16612291578284838151811061227857612278614f4a565b602090810291909101015261228e600183614fb4565b91505b8061229b81614f76565b915050612237565b5061131a8382613031565b6122b933600c6130ce565b6122d55760405162461bcd60e51b8152600401610e9b90614fcc565b6001600160a01b0381166000908152601560205260409020805460ff19166001179055612306601780546001019055565b50565b60006001600160a01b0382166123745760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610e9b565b506001600160a01b031660009081526003602052604090205490565b61239b3360066130ce565b6123b75760405162461bcd60e51b8152600401610e9b90614fcc565b6001600160a01b0381166000908152601560205260409020805460ff1916905561185160176137f0565b60006123ec82612046565b6124385760405162461bcd60e51b815260206004820152601a60248201527f5468617420746f6b656e20646f6573206e6f742065786973742e0000000000006044820152606401610e9b565b5060009081526013602052604090205490565b600081815260126020526040812060028101549054610d8e91906152cb565b60008061247683612046565b6124c25760405162461bcd60e51b815260206004820152601a60248201527f5468697320746f6b656e20646f6573206e6f742065786973742e0000000000006044820152606401610e9b565b505060009081526013602052604090208054600290910154909160ff90911690565b600c5460ff16156125075760405162461bcd60e51b8152600401610e9b9061501b565b6125317f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a633610a3e565b61257d5760405162461bcd60e51b815260206004820181905260248201527f596f7520646f6e742068617665204d696e74657220726f6c652120536f7272796044820152606401610e9b565b60005b818110156126205761259d8383838181106115ff576115ff614f4a565b6125f85760405162461bcd60e51b815260206004820152602660248201527f535550504c59204552524f523a204e6f7420656e6f756768206f662074686973604482015265103a3cb8329760d11b6064820152608401610e9b565b61260e8484848481811061167c5761167c614f4a565b8061261881614f76565b915050612580565b50505050565b6000828152600b6020526040812061263e9083613847565b9392505050565b61264e33610bfc565b61268e5760405162461bcd60e51b81526020600482015260116024820152702cb7ba9030b932903737ba1037bbb732b960791b6044820152606401610e9b565b6001600160a01b03811660009081526015602052604090205460ff166126c65760405162461bcd60e51b8152600401610e9b90615133565b6001600160a01b038116330361271e5760405162461bcd60e51b815260206004820152601d60248201527f596f752063616e6e6f7420617574686f72697a6520796f757273656c660000006044820152606401610e9b565b6001600160a01b038116600090815260166020526040902054600160a01b900460ff16156127b45760405162461bcd60e51b815260206004820152603860248201527f546865726520697320616c726561647920612070656e64696e6720617574686f60448201527f72697a6174696f6e20666f722074686973206f776e65722e00000000000000006064820152608401610e9b565b6001600160a01b0316600090815260166020526040902080546001600160a01b031960ff93909316600160a01b02929092166001600160a81b03199092169190911733179055565b606061280782612046565b6128535760405162461bcd60e51b815260206004820152601a60248201527f5468697320746f6b656e20646f6573206e6f742065786973742e0000000000006044820152606401610e9b565b600061285e836123e1565b6000848152601360205260408120600101549192509061287d90613853565b6000838152601260205260408120549192509061289990613853565b9050600082826040516020016128b09291906152e2565b60408051601f198184030181529190529695505050505050565b606060018054610da390614f10565b600081815260126020526040812060010154610d8e565b60005b81811015610fd05761291c83838381811061291057612910614f4a565b90506020020135611f07565b8061292681614f76565b9150506128f3565b611c40338383613954565b60005b81811015611ee557612967858585858581811061295b5761295b614f4a565b90506020020135611eec565b8061297181614f76565b91505061293c565b6129833383613524565b6129e95760405162461bcd60e51b815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6044820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b6064820152608401610e9b565b61262084848484613a22565b6000818152600260205260409020546060906001600160a01b0316612a745760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610e9b565b600082815260136020526040812054612a8c90613853565b90506000612a98613a55565b60008581526013602052604090206002015490915060609060ff1615612adf5782604051602001612ac9919061531e565b6040516020818303038152906040529050612ae2565b50815b8181604051602001612af5929190615347565b6040516020818303038152906040529350505050919050565b6000818152600b60205260408120610d8e90613a64565b6000601482604051612b379190615386565b9081526040519081900360200190205460ff1692915050565b60606000612b5d83612309565b905060008167ffffffffffffffff811115612b7a57612b7a614c67565b604051908082528060200260200182016040528015612ba3578160200160208202803683370190505b50905060005b82811015612bea57612bbb8582611c69565b828281518110612bcd57612bcd614f4a565b602090810291909101015280612be281614f76565b915050612ba9565b509392505050565b6000828152600a6020526040902060010154612c0d816137a2565b610fd083836137ce565b6000612c2260175490565b905090565b6001600160a01b038116612c955760405162461bcd60e51b815260206004820152602f60248201527f457863657074696f6e20696e20736574526f79616c746965734164647265737360448201526e1d1020b2323932b9b9903d32b9379760891b6064820152608401610e9b565b612ca03360096130ce565b612cbc5760405162461bcd60e51b8152600401610e9b90614fcc565b601080546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b038116612d4a5760405162461bcd60e51b815260206004820152602d60248201527f457863657074696f6e20696e207365744f70656e536561416464726573733a2060448201526c20b2323932b9b9903d32b9379760991b6064820152608401610e9b565b612d5533600b6130ce565b612d715760405162461bcd60e51b8152600401610e9b906150e3565b600f80546001600160a01b0319166001600160a01b0392909216919091179055565b600f546000906001600160a01b0390811690831603612db457506001610d8e565b6001600160a01b0380841660009081526005602090815260408083209386168352929052205460ff1661263e565b612ded3360016130ce565b612e395760405162461bcd60e51b815260206004820152601b60248201527f596f7520646f206e6f742068617665207065726d697373696f6e7300000000006044820152606401610e9b565b828114612e885760405162461bcd60e51b815260206004820152601860248201527f41727261792073697a657320646f206e6f74206d6174636800000000000000006044820152606401610e9b565b60005b83811015611ee557828282818110612ea557612ea5614f4a565b9050602002013560126000878785818110612ec257612ec2614f4a565b602090810292909201358352508101919091526040016000205580612ee681614f76565b915050612e8b565b80546001019055565b60006001600160e01b03198216635a05180f60e01b1480610d8e5750610d8e82613a6e565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190612f5182612165565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000612f9582612165565b9050612fa381600084613a93565b612fae600083612f1c565b6001600160a01b0381166000908152600360205260408120805460019290612fd79084906152cb565b909155505060008281526002602052604080822080546001600160a01b0319169055518391906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b606060008267ffffffffffffffff81111561304e5761304e614c67565b604051908082528060200260200182016040528015613077578160200160208202803683370190505b50905060005b83811015612bea5784818151811061309757613097614f4a565b60200260200101518282815181106130b1576130b1614f4a565b6020908102919091010152806130c681614f76565b91505061307d565b6001600160a01b03821660009081526015602052604081205460ff166131065760405162461bcd60e51b8152600401610e9b90615133565b6001600160a01b03831660009081526016602052604081205460ff808516600160a01b909204160361263e5750600161263e84611749565b606080606060005b85518110156131c95761317186828151811061316457613164614f4a565b6020026020010151613853565b60405160200161318191906153a2565b604051602081830303815290604052915082826040516020016131a59291906153c7565b604051602081830303815290604052925080806131c190614f76565b915050613146565b5060005b845181101561329e57600185516131e491906152cb565b810361322c57828582815181106131fd576131fd614f4a565b60200260200101516040516020016132169291906153c7565b604051602081830303815290604052925061328c565b84818151811061323e5761323e614f4a565b602002602001015160405160200161325691906153a2565b6040516020818303038152906040529150828260405160200161327a9291906153c7565b60405160208183030381529060405292505b8061329681614f76565b9150506131cd565b5090949350505050565b60006132da836040516020016132be9190615386565b6040516020818303038152906040528051906020012083613b4b565b600c5461010090046001600160a01b03908116911614905092915050565b6000808251116133705760405162461bcd60e51b815260206004820152603360248201527f457863657074696f6e20696e20636865636b54783a205468657265206172652060448201527f6e6f742054782049647320746f20636865636b000000000000000000000000006064820152608401610e9b565b6000805b811580156133825750835181105b1561342f57601484828151811061339b5761339b614f4a565b60200260200101516040516133b09190615386565b9081526040519081900360200190205460ff16156133d1576001915061341d565b600160148583815181106133e7576133e7614f4a565b60200260200101516040516133fc9190615386565b908152604051908190036020019020805491151560ff199092169190911790555b613428600182614fb4565b9050613374565b5092915050565b600081815260126020526040812080548291613453906001015490565b1015610d8e5750600192915050565b60008181526012602052604090206134809060010180546001019055565b61348e600e80546001019055565b600081815260126020526040902060010154601360006134ad600e5490565b81526020019081526020016000206001018190555080601360006134d0600e5490565b8152602001908152602001600020600001819055506000601360006134f4600e5490565b81526020810191909152604001600020600201805460ff1916911515919091179055600e54611c40908390613b67565b6000818152600260205260408120546001600160a01b031661359d5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610e9b565b60006135a883612165565b9050806001600160a01b0316846001600160a01b031614806135cf57506135cf8185612d93565b806135f35750836001600160a01b03166135e884610e26565b6001600160a01b0316145b949350505050565b826001600160a01b031661360e82612165565b6001600160a01b0316146136725760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201526437bbb732b960d91b6064820152608401610e9b565b6001600160a01b0382166136d45760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610e9b565b6136df838383613a93565b6136ea600082612f1c565b6001600160a01b03831660009081526003602052604081208054600192906137139084906152cb565b90915550506001600160a01b0382166000908152600360205260408120805460019290613741908490614fb4565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6123068133613b81565b6137b68282613c01565b6000828152600b60205260409020610fd09082613ca3565b6137d88282613cb8565b6000828152600b60205260409020610fd09082613d3b565b80548061383f5760405162461bcd60e51b815260206004820152601b60248201527f436f756e7465723a2064656372656d656e74206f766572666c6f7700000000006044820152606401610e9b565b600019019055565b600061263e8383613d50565b60608160000361387a5750506040805180820190915260018152600360fc1b602082015290565b8160005b81156138a4578061388e81614f76565b915061389d9050600a836151a9565b915061387e565b60008167ffffffffffffffff8111156138bf576138bf614c67565b6040519080825280601f01601f1916602001820160405280156138e9576020820181803683370190505b5090505b84156135f3576138fe6001836152cb565b915061390b600a866153f6565b613916906030614fb4565b60f81b81838151811061392b5761392b614f4a565b60200101906001600160f81b031916908160001a90535061394d600a866151a9565b94506138ed565b816001600160a01b0316836001600160a01b0316036139b55760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610e9b565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b613a2d8484846135fb565b613a3984848484613d7a565b6126205760405162461bcd60e51b8152600401610e9b9061540a565b6060600d8054610da390614f10565b6000610d8e825490565b60006001600160e01b03198216637965db0b60e01b1480610d8e5750610d8e82613e7b565b6001600160a01b038316613aee57613ae981600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b613b11565b816001600160a01b0316836001600160a01b031614613b1157613b118382613ea0565b6001600160a01b038216613b2857610fd081613f3d565b826001600160a01b0316826001600160a01b031614610fd057610fd08282613fec565b6000806000613b5a8585614030565b91509150612bea8161409b565b611c40828260405180602001604052806000815250614251565b6000828152600a602090815260408083206001600160a01b038516845290915290205460ff16611c4057613bbf816001600160a01b03166014614284565b613bca836020614284565b604051602001613bdb92919061545c565b60408051601f198184030181529082905262461bcd60e51b8252610e9b916004016148b1565b6000828152600a602090815260408083206001600160a01b038516845290915290205460ff16611c40576000828152600a602090815260408083206001600160a01b03851684529091529020805460ff19166001179055613c5f3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b600061263e836001600160a01b038416614420565b6000828152600a602090815260408083206001600160a01b038516845290915290205460ff1615611c40576000828152600a602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b600061263e836001600160a01b03841661446f565b6000826000018281548110613d6757613d67614f4a565b9060005260206000200154905092915050565b60006001600160a01b0384163b15613e7057604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290613dbe9033908990889088906004016154d1565b6020604051808303816000875af1925050508015613df9575060408051601f3d908101601f19168201909252613df691810190615503565b60015b613e56573d808015613e27576040519150601f19603f3d011682016040523d82523d6000602084013e613e2c565b606091505b508051600003613e4e5760405162461bcd60e51b8152600401610e9b9061540a565b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490506135f3565b506001949350505050565b60006001600160e01b0319821663780e9d6360e01b1480610d8e5750610d8e82614562565b60006001613ead84612309565b613eb791906152cb565b600083815260076020526040902054909150808214613f0a576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b600854600090613f4f906001906152cb565b60008381526009602052604081205460088054939450909284908110613f7757613f77614f4a565b906000526020600020015490508060088381548110613f9857613f98614f4a565b6000918252602080832090910192909255828152600990915260408082208490558582528120556008805480613fd057613fd0615520565b6001900381819060005260206000200160009055905550505050565b6000613ff783612309565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b60008082516041036140665760208301516040840151606085015160001a61405a878285856145b2565b94509450505050611bb5565b825160400361408f576020830151604084015161408486838361469f565b935093505050611bb5565b50600090506002611bb5565b60008160048111156140af576140af615536565b036140b75750565b60018160048111156140cb576140cb615536565b036141185760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610e9b565b600281600481111561412c5761412c615536565b036141795760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610e9b565b600381600481111561418d5761418d615536565b036141e55760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610e9b565b60048160048111156141f9576141f9615536565b036123065760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b6064820152608401610e9b565b61425b83836146d8565b6142686000848484613d7a565b610fd05760405162461bcd60e51b8152600401610e9b9061540a565b60606000614293836002615174565b61429e906002614fb4565b67ffffffffffffffff8111156142b6576142b6614c67565b6040519080825280601f01601f1916602001820160405280156142e0576020820181803683370190505b509050600360fc1b816000815181106142fb576142fb614f4a565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061432a5761432a614f4a565b60200101906001600160f81b031916908160001a905350600061434e846002615174565b614359906001614fb4565b90505b60018111156143d1576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061438d5761438d614f4a565b1a60f81b8282815181106143a3576143a3614f4a565b60200101906001600160f81b031916908160001a90535060049490941c936143ca8161554c565b905061435c565b50831561263e5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610e9b565b600081815260018301602052604081205461446757508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610d8e565b506000610d8e565b600081815260018301602052604081205480156145585760006144936001836152cb565b85549091506000906144a7906001906152cb565b905081811461450c5760008660000182815481106144c7576144c7614f4a565b90600052602060002001549050808760000184815481106144ea576144ea614f4a565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061451d5761451d615520565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610d8e565b6000915050610d8e565b60006001600160e01b031982166380ac58cd60e01b148061459357506001600160e01b03198216635b5e139f60e01b145b80610d8e57506301ffc9a760e01b6001600160e01b0319831614610d8e565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156145e95750600090506003614696565b8460ff16601b1415801561460157508460ff16601c14155b156146125750600090506004614696565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015614666573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661468f57600060019250925050614696565b9150600090505b94509492505050565b6000806001600160ff1b038316816146bc60ff86901c601b614fb4565b90506146ca878288856145b2565b935093505050935093915050565b6001600160a01b03821661472e5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610e9b565b6000818152600260205260409020546001600160a01b0316156147935760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610e9b565b61479f60008383613a93565b6001600160a01b03821660009081526003602052604081208054600192906147c8908490614fb4565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6001600160e01b03198116811461230657600080fd5b60006020828403121561484e57600080fd5b813561263e81614826565b60005b8381101561487457818101518382015260200161485c565b838111156126205750506000910152565b6000815180845261489d816020860160208601614859565b601f01601f19169290920160200192915050565b60208152600061263e6020830184614885565b6000602082840312156148d657600080fd5b5035919050565b6001600160a01b038116811461230657600080fd5b6000806040838503121561490557600080fd5b8235614910816148dd565b946020939093013593505050565b60008083601f84011261493057600080fd5b50813567ffffffffffffffff81111561494857600080fd5b6020830191508360208260051b8501011115611bb557600080fd5b6000806020838503121561497657600080fd5b823567ffffffffffffffff81111561498d57600080fd5b6149998582860161491e565b90969095509350505050565b6020808252825182820181905260009190848201906040850190845b818110156149dd578351835292840192918401916001016149c1565b50909695505050505050565b6000602082840312156149fb57600080fd5b81356bffffffffffffffffffffffff8116811461263e57600080fd5b60008060008060008060608789031215614a3057600080fd5b863567ffffffffffffffff80821115614a4857600080fd5b614a548a838b0161491e565b90985096506020890135915080821115614a6d57600080fd5b614a798a838b0161491e565b90965094506040890135915080821115614a9257600080fd5b818901915089601f830112614aa657600080fd5b813581811115614ab557600080fd5b8a6020828501011115614ac757600080fd5b6020830194508093505050509295509295509295565b600060208284031215614aef57600080fd5b813561263e816148dd565b80358015158114614b0a57600080fd5b919050565b600060208284031215614b2157600080fd5b61263e82614afa565b600080600060608486031215614b3f57600080fd5b8335614b4a816148dd565b92506020840135614b5a816148dd565b929592945050506040919091013590565b60008060408385031215614b7e57600080fd5b50508035926020909101359150565b60008060408385031215614ba057600080fd5b823591506020830135614bb2816148dd565b809150509250929050565b60008060008060408587031215614bd357600080fd5b843567ffffffffffffffff80821115614beb57600080fd5b614bf78883890161491e565b90965094506020870135915080821115614c1057600080fd5b50614c1d8782880161491e565b95989497509550505050565b600080600060608486031215614c3e57600080fd5b8335614c49816148dd565b925060208401359150614c5e60408501614afa565b90509250925092565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715614ca657614ca6614c67565b604052919050565b600067ffffffffffffffff831115614cc857614cc8614c67565b614cdb601f8401601f1916602001614c7d565b9050828152838383011115614cef57600080fd5b828260208301376000602084830101529392505050565b600082601f830112614d1757600080fd5b61263e83833560208501614cae565b600060208284031215614d3857600080fd5b813567ffffffffffffffff811115614d4f57600080fd5b6135f384828501614d06565b600080600060408486031215614d7057600080fd5b8335614d7b816148dd565b9250602084013567ffffffffffffffff811115614d9757600080fd5b614da38682870161491e565b9497909650939450505050565b60008060408385031215614dc357600080fd5b823560ff81168114614dd457600080fd5b91506020830135614bb2816148dd565b60008060408385031215614df757600080fd5b8235614e02816148dd565b9150614e1060208401614afa565b90509250929050565b60008060008060608587031215614e2f57600080fd5b8435614e3a816148dd565b93506020850135614e4a816148dd565b9250604085013567ffffffffffffffff811115614e6657600080fd5b614c1d8782880161491e565b60008060008060808587031215614e8857600080fd5b8435614e93816148dd565b93506020850135614ea3816148dd565b925060408501359150606085013567ffffffffffffffff811115614ec657600080fd5b8501601f81018713614ed757600080fd5b614ee687823560208401614cae565b91505092959194509250565b60008060408385031215614f0557600080fd5b8235614dd4816148dd565b600181811c90821680614f2457607f821691505b602082108103614f4457634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600060018201614f8857614f88614f60565b5060010190565b600060ff821660ff84168060ff03821115614fac57614fac614f60565b019392505050565b60008219821115614fc757614fc7614f60565b500190565b6020808252602f908201527f596f752068617665206e6f74206265656e20617070726f76656420746f20727560408201526e37103a3434b990333ab731ba34b7b760891b606082015260800190565b60208082526024908201527f54686520636f6e74726163742069732074656d706f72616c792073757370656e6040820152633232b21760e11b606082015260800190565b600067ffffffffffffffff8084111561507a5761507a614c67565b8360051b602061508b818301614c7d565b8681529185019181810190368411156150a357600080fd5b865b848110156150d7578035868111156150bd5760008081fd5b6150c936828b01614d06565b8452509183019183016150a5565b50979650505050505050565b60208082526030908201527f596f752068617665206e6f74206265656e20617070726f76656420746f20727560408201526f37103a3434b990333ab731ba34b7b71760811b606082015260800190565b60208082526021908201527f54686973206973206e6f7420612077616c6c65742066726f6d2061206f776e656040820152603960f91b606082015260800190565b600081600019048311821515161561518e5761518e614f60565b500290565b634e487b7160e01b600052601260045260246000fd5b6000826151b8576151b8615193565b500490565b601f821115610fd057600081815260208120601f850160051c810160208610156151e45750805b601f850160051c820191505b81811015615203578281556001016151f0565b505050505050565b815167ffffffffffffffff81111561522557615225614c67565b615239816152338454614f10565b846151bd565b602080601f83116001811461526e57600084156152565750858301515b600019600386901b1c1916600185901b178555615203565b600085815260208120601f198616915b8281101561529d5788860151825594840194600190910190840161527e565b50858210156152bb5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6000828210156152dd576152dd614f60565b500390565b600083516152f4818460208801614859565b602f60f81b9083019081528351615312816001840160208801614859565b01600101949350505050565b60008251615330818460208701614859565b640b5d5cd95960da1b920191825250600501919050565b60008351615359818460208801614859565b83519083019061536d818360208801614859565b64173539b7b760d91b9101908152600501949350505050565b60008251615398818460208701614859565b9190910192915050565b600082516153b4818460208701614859565b600b60fa1b920191825250600101919050565b600083516153d9818460208801614859565b8351908301906153ed818360208801614859565b01949350505050565b60008261540557615405615193565b500690565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351615494816017850160208801614859565b7001034b99036b4b9b9b4b733903937b6329607d1b60179184019182015283516154c5816028840160208801614859565b01602801949350505050565b60006001600160a01b0380871683528086166020840152508360408301526080606083015261131a6080830184614885565b60006020828403121561551557600080fd5b815161263e81614826565b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052602160045260246000fd5b60008161555b5761555b614f60565b50600019019056fea2646970667358221220a5004ec34a849f4a9dc68ec41433d00eb8b1789b6184203e6c76fbaa04e95bed64736f6c634300080f003368747470733a2f2f6e66742d6875622e6461726b65617274682e67672f63617264732f

Deployed Bytecode

0x6080604052600436106103f35760003560e01c80636352211e11610208578063a22cb46511610118578063cb9b4a7d116100ab578063db23f9f31161007a578063db23f9f314610cce578063dc95c4a714610ce3578063df453c1414610d03578063e985e9c514610d23578063f547e3a714610d4357600080fd5b8063cb9b4a7d14610c3a578063d004b03614610c5a578063d539139314610c7a578063d547741f14610cae57600080fd5b8063b8b6c856116100e7578063b8b6c85614610ba9578063c87b56dd14610bc1578063c971723d14610be1578063ca15c87314610c1a57600080fd5b8063a22cb46514610b13578063a439b69114610b33578063ab40bb6014610b69578063b88d4fde14610b8957600080fd5b80638d61806b1161019b57806393909db41161016a57806393909db414610a8957806395d89b4114610aa95780639d9ea10b14610abe5780639e124d6914610ade578063a217fddf14610afe57600080fd5b80638d61806b146109e35780639010d07c14610a0357806391d1485414610a235780639238edef14610a6957600080fd5b806373984188116101d7578063739841881461094e57806376aed2e11461096e578063808665a41461098e5780638c7a63ae146109ae57600080fd5b80636352211e146108ce5780636ba9dc35146108ee5780637065cb481461090e57806370a082311461092e57600080fd5b8063282c51f31161030357806342842e0e116102965780634f6ccce7116102655780634f6ccce71461082157806355f804b3146108415780635a8d69c1146108615780635e495d7414610881578063601602ed146108ae57600080fd5b806342842e0e146107a157806342966c68146107c15780634a710448146107e15780634f558e791461080157600080fd5b80632f2ff15d116102d25780632f2ff15d146107215780632f745c591461074157806336568abe146107615780633f76fd051461078157600080fd5b8063282c51f3146106705780632a55205a146106a45780632b3c0703146106e35780632e1a7d4d1461070157600080fd5b80631444798f116103865780631e84af31116103555780631e84af31146105c057806323b872dd146105e0578063247b3eac14610600578063248a9ca31461062057806326147ae41461065057600080fd5b80631444798f1461054b5780631699d8751461056b57806318160ddd1461058b5780631b1ca1d4146105a057600080fd5b80630cabe208116103c25780630cabe208146104b05780630d54a3d8146104d05780630d887c7d146104fd57806311fdb52e1461052b57600080fd5b806301ffc9a7146103ff57806306fdde0314610434578063081812fc14610456578063095ea7b31461048e57600080fd5b366103fa57005b600080fd5b34801561040b57600080fd5b5061041f61041a36600461483c565b610d63565b60405190151581526020015b60405180910390f35b34801561044057600080fd5b50610449610d94565b60405161042b91906148b1565b34801561046257600080fd5b506104766104713660046148c4565b610e26565b6040516001600160a01b03909116815260200161042b565b34801561049a57600080fd5b506104ae6104a93660046148f2565b610ec0565b005b3480156104bc57600080fd5b506104ae6104cb366004614963565b610fd5565b3480156104dc57600080fd5b506104f06104eb3660046148f2565b6111b5565b60405161042b91906149a5565b34801561050957600080fd5b5061051d6105183660046148f2565b611324565b60405190815260200161042b565b34801561053757600080fd5b506104ae6105463660046149e9565b6113a4565b34801561055757600080fd5b506104ae610566366004614a17565b61145c565b34801561057757600080fd5b506104f0610586366004614add565b6116a3565b34801561059757600080fd5b5060085461051d565b3480156105ac57600080fd5b506104ae6105bb366004614b0f565b61170f565b3480156105cc57600080fd5b506104ae6105db366004614add565b611749565b3480156105ec57600080fd5b506104ae6105fb366004614b2a565b611878565b34801561060c57600080fd5b506104ae61061b366004614add565b6118f3565b34801561062c57600080fd5b5061051d61063b3660046148c4565b6000908152600a602052604090206001015490565b34801561065c57600080fd5b506104ae61066b366004614963565b6119b5565b34801561067c57600080fd5b5061051d7f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a84881565b3480156106b057600080fd5b506106c46106bf366004614b6b565b611b59565b604080516001600160a01b03909316835260208301919091520161042b565b3480156106ef57600080fd5b50600f546001600160a01b0316610476565b34801561070d57600080fd5b506104ae61071c3660046148c4565b611bbc565b34801561072d57600080fd5b506104ae61073c366004614b8d565b611c44565b34801561074d57600080fd5b5061051d61075c3660046148f2565b611c69565b34801561076d57600080fd5b506104ae61077c366004614b8d565b611cff565b34801561078d57600080fd5b506104ae61079c366004614bbd565b611d79565b3480156107ad57600080fd5b506104ae6107bc366004614b2a565b611eec565b3480156107cd57600080fd5b506104ae6107dc3660046148c4565b611f07565b3480156107ed57600080fd5b506104ae6107fc366004614c29565b612005565b34801561080d57600080fd5b5061041f61081c3660046148c4565b612046565b34801561082d57600080fd5b5061051d61083c3660046148c4565b612065565b34801561084d57600080fd5b506104ae61085c366004614d26565b6120f8565b34801561086d57600080fd5b5061051d61087c3660046148c4565b61212b565b34801561088d57600080fd5b5061051d61089c3660046148c4565b60009081526012602052604090205490565b3480156108ba57600080fd5b5061051d6108c93660046148c4565b61214e565b3480156108da57600080fd5b506104766108e93660046148c4565b612165565b3480156108fa57600080fd5b506104f0610909366004614add565b6121dc565b34801561091a57600080fd5b506104ae610929366004614add565b6122ae565b34801561093a57600080fd5b5061051d610949366004614add565b612309565b34801561095a57600080fd5b506104ae610969366004614add565b612390565b34801561097a57600080fd5b5061051d6109893660046148c4565b6123e1565b34801561099a57600080fd5b5061051d6109a93660046148c4565b61244b565b3480156109ba57600080fd5b506109ce6109c93660046148c4565b61246a565b6040805192835290151560208301520161042b565b3480156109ef57600080fd5b506104ae6109fe366004614d5b565b6124e4565b348015610a0f57600080fd5b50610476610a1e366004614b6b565b612626565b348015610a2f57600080fd5b5061041f610a3e366004614b8d565b6000918252600a602090815260408084206001600160a01b0393909316845291905290205460ff1690565b348015610a7557600080fd5b506104ae610a84366004614db0565b612645565b348015610a9557600080fd5b50610449610aa43660046148c4565b6127fc565b348015610ab557600080fd5b506104496128ca565b348015610aca57600080fd5b5061051d610ad93660046148c4565b6128d9565b348015610aea57600080fd5b506104ae610af9366004614963565b6128f0565b348015610b0a57600080fd5b5061051d600081565b348015610b1f57600080fd5b506104ae610b2e366004614de4565b61292e565b348015610b3f57600080fd5b5061051d610b4e366004614add565b6001600160a01b031660009081526018602052604090205490565b348015610b7557600080fd5b506104ae610b84366004614e19565b612939565b348015610b9557600080fd5b506104ae610ba4366004614e72565b612979565b348015610bb557600080fd5b50600c5460ff1661041f565b348015610bcd57600080fd5b50610449610bdc3660046148c4565b6129f5565b348015610bed57600080fd5b5061041f610bfc366004614add565b6001600160a01b031660009081526015602052604090205460ff1690565b348015610c2657600080fd5b5061051d610c353660046148c4565b612b0e565b348015610c4657600080fd5b5061041f610c55366004614d26565b612b25565b348015610c6657600080fd5b506104f0610c75366004614add565b612b50565b348015610c8657600080fd5b5061051d7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b348015610cba57600080fd5b506104ae610cc9366004614b8d565b612bf2565b348015610cda57600080fd5b5061051d612c17565b348015610cef57600080fd5b506104ae610cfe366004614add565b612c27565b348015610d0f57600080fd5b506104ae610d1e366004614add565b612cde565b348015610d2f57600080fd5b5061041f610d3e366004614ef2565b612d93565b348015610d4f57600080fd5b506104ae610d5e366004614bbd565b612de2565b6000636ad56fd360e11b6001600160e01b0319831601610d8557506001919050565b610d8e82612ef7565b92915050565b606060008054610da390614f10565b80601f0160208091040260200160405190810160405280929190818152602001828054610dcf90614f10565b8015610e1c5780601f10610df157610100808354040283529160200191610e1c565b820191906000526020600020905b815481529060010190602001808311610dff57829003601f168201915b5050505050905090565b6000818152600260205260408120546001600160a01b0316610ea45760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b6000610ecb82612165565b9050806001600160a01b0316836001600160a01b031603610f385760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610e9b565b336001600160a01b0382161480610f545750610f548133612d93565b610fc65760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610e9b565b610fd08383612f1c565b505050565b600c5460ff16156110345760405162461bcd60e51b815260206004820152602360248201527f54686520636f6e74726163742069732074656d706f72616c792073757370656e60448201526219195960ea1b6064820152608401610e9b565b61105e7f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a84833610a3e565b6110c05760405162461bcd60e51b815260206004820152602d60248201527f457863657074696f6e206f6e204275726e3a20596f7520646f206e6f7420686160448201526c3b32903832b936b4b9b9b4b7b760991b6064820152608401610e9b565b60005b81811015610fd05760006110ee8484848181106110e2576110e2614f4a565b905060200201356123e1565b60008181526012602052604090206002018054600101905590506018600061112d86868681811061112157611121614f4a565b90506020020135612165565b6001600160a01b03166001600160a01b0316815260200190815260200160002084848481811061115f5761115f614f4a565b835460018101855560009485526020948590209190940292909201359190920155506111a284848481811061119657611196614f4a565b90506020020135612f8a565b50806111ad81614f76565b9150506110c3565b606060006111c284612b50565b90506000815167ffffffffffffffff8111156111e0576111e0614c67565b604051908082528060200260200182016040528015611209578160200160208202803683370190505b5090506000805b83518110156112a957856013600086848151811061123057611230614f4a565b6020026020010151815260200190815260200160002060000154036112975783818151811061126157611261614f4a565b6020026020010151838360ff168151811061127e5761127e614f4a565b6020908102919091010152611294600183614f8f565b91505b806112a181614f76565b915050611210565b5060008160ff161161130d5760405162461bcd60e51b815260206004820152602760248201527f4552524f523a20596f7520646f6e742068617665204e465473206f662074686960448201526639903a3cb8329760c91b6064820152608401610e9b565b61131a828260ff16613031565b9695505050505050565b60008061133084612b50565b9050600080805b83518110156113995783818151811061135257611352614f4a565b602002602001015191508560136000848152602001908152602001600020600001540361138757611384600184614fb4565b92505b8061139181614f76565b915050611337565b509095945050505050565b6113af33600a6130ce565b6113cb5760405162461bcd60e51b8152600401610e9b90614fcc565b6011546bffffffffffffffffffffffff908116908216111561142f5760405162461bcd60e51b815260206004820152601d60248201527f526f796174696573206572726f723a204c696d697420726561636865640000006044820152606401610e9b565b601080546bffffffffffffffffffffffff909216600160a01b026001600160a01b03909216919091179055565b600c5460ff161561147f5760405162461bcd60e51b8152600401610e9b9061501b565b6115066114ca8787808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506114c5925088915089905061505f565b61313e565b83838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506132a892505050565b6115665760405162461bcd60e51b815260206004820152602b60248201527f5349474e4154555245204552524f523a20576861742061726520796f7520747260448201526a79696e6720746f20646f3f60a81b6064820152608401610e9b565b611578611573848661505f565b6132f8565b156115df5760405162461bcd60e51b815260206004820152603160248201527f4552524f523a2054686973207472616e73616374696f6e20697320616c726561604482015270323c9034b71037bab91039bcb9ba32b69760791b6064820152608401610e9b565b60005b8581101561169a5761160b8787838181106115ff576115ff614f4a565b90506020020135613436565b6116665760405162461bcd60e51b815260206004820152602660248201527f535550504c59204552524f523a204e6f7420656e6f756768206f662074686973604482015265103a3cb8329760d11b6064820152608401610e9b565b6116883388888481811061167c5761167c614f4a565b90506020020135613462565b8061169281614f76565b9150506115e2565b50505050505050565b6001600160a01b03811660009081526018602090815260409182902080548351818402810184019094528084526060939283018282801561170357602002820191906000526020600020905b8154815260200190600101908083116116ef575b50505050509050919050565b61171a3360076130ce565b6117365760405162461bcd60e51b8152600401610e9b906150e3565b600c805460ff1916911515919091179055565b61175233610bfc565b6117925760405162461bcd60e51b81526020600482015260116024820152702cb7ba9030b932903737ba1037bbb732b960791b6044820152606401610e9b565b6001600160a01b03811660009081526015602052604090205460ff166117ca5760405162461bcd60e51b8152600401610e9b90615133565b336001600160a01b03821614611851576001600160a01b038181166000908152601660205260409020541633146118515760405162461bcd60e51b815260206004820152602560248201527f596f752068617665206e6f7420676976656e207468697320617574686f72697a60448201526430ba34b7b760d91b6064820152608401610e9b565b6001600160a01b0316600090815260166020526040902080546001600160a81b0319169055565b6118823382613524565b6118e85760405162461bcd60e51b815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6044820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b6064820152608401610e9b565b610fd08383836135fb565b6001600160a01b0381166119595760405162461bcd60e51b815260206004820152602760248201527f457863657074696f6e20696e207365745369676e416464723a2041646472657360448201526639903d32b9379760c91b6064820152608401610e9b565b6119643360026130ce565b6119805760405162461bcd60e51b8152600401610e9b906150e3565b600c80546001600160a01b039092166101000274ffffffffffffffffffffffffffffffffffffffff0019909216919091179055565b80611a1b5760405162461bcd60e51b815260206004820152603060248201527f457863657074696f6e20696e2062756c6b53657455736564436172643a20417260448201526f72617920686173206e6f74204461746160801b6064820152608401610e9b565b60005b81811015610fd057611a3b83838381811061112157611121614f4a565b6001600160a01b0316336001600160a01b031614611a9b5760405162461bcd60e51b815260206004820152601860248201527f596f7520646f206e6f7420686176652074686973204e465400000000000000006044820152606401610e9b565b611abc838383818110611ab057611ab0614f4a565b90506020020135612046565b611aff5760405162461bcd60e51b8152602060048201526014602482015273151a1a5cc81d1bdad95b881b9bdd08195e1a5cdd60621b6044820152606401610e9b565b600160136000858585818110611b1757611b17614f4a565b90506020020135815260200190815260200160002060020160006101000a81548160ff0219169083151502179055508080611b5190614f76565b915050611a1e565b600080611b6584612046565b15611bae576010546001600160a01b0381169061271090611b9b90600160a01b90046bffffffffffffffffffffffff1686615174565b611ba591906151a9565b91509150611bb5565b5060009050805b9250929050565b611bc73360056130ce565b611c135760405162461bcd60e51b815260206004820152601b60248201527f596f7520646f206e6f742068617665207065726d697373696f6e7300000000006044820152606401610e9b565b604051339082156108fc029083906000818181858888f19350505050158015611c40573d6000803e3d6000fd5b5050565b6000828152600a6020526040902060010154611c5f816137a2565b610fd083836137ac565b6000611c7483612309565b8210611cd65760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610e9b565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b6001600160a01b0381163314611d6f5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608401610e9b565b611c4082826137ce565b828114611ddc5760405162461bcd60e51b815260206004820152602b60248201527f457863657074696f6e20696e2062756c6b41646d696e55736564436172643a2060448201526a41727261792073697a657360a81b6064820152608401610e9b565b611de73360046130ce565b611e035760405162461bcd60e51b8152600401610e9b90614fcc565b60005b83811015611ee557611e23858583818110611ab057611ab0614f4a565b611e665760405162461bcd60e51b8152602060048201526014602482015273151a1a5cc81d1bdad95b881b9bdd08195e1a5cdd60621b6044820152606401610e9b565b828282818110611e7857611e78614f4a565b9050602002016020810190611e8d9190614b0f565b60136000878785818110611ea357611ea3614f4a565b90506020020135815260200190815260200160002060020160006101000a81548160ff0219169083151502179055508080611edd90614f76565b915050611e06565b5050505050565b610fd083838360405180602001604052806000815250612979565b600c5460ff1615611f2a5760405162461bcd60e51b8152600401610e9b9061501b565b33611f3482612165565b6001600160a01b031614611f9c5760405162461bcd60e51b815260206004820152602960248201527f457863657074696f6e206f6e204275726e3a20596f757220617265206e6f74206044820152683a34329037bbb732b960b91b6064820152608401610e9b565b6000611fa7826123e1565b600081815260126020526040902060020180546001019055905060186000611fce84612165565b6001600160a01b031681526020808201929092526040016000908120805460018101825590825291902001829055611c4082612f8a565b6120103360036130ce565b61202c5760405162461bcd60e51b8152600401610e9b90614fcc565b801561203c57610fd082846137ac565b610fd082846137ce565b6000818152600260205260408120546001600160a01b03161515610d8e565b600061207060085490565b82106120d35760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610e9b565b600882815481106120e6576120e6614f4a565b90600052602060002001549050919050565b6121033360086130ce565b61211f5760405162461bcd60e51b8152600401610e9b906150e3565b600d611c40828261520b565b60008181526012602052604081206002810154600190910154610d8e91906152cb565b600081815260126020526040812060020154610d8e565b6000818152600260205260408120546001600160a01b031680610d8e5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b6064820152608401610e9b565b606060006121e983612309565b905060008167ffffffffffffffff81111561220657612206614c67565b60405190808252806020026020018201604052801561222f578160200160208202803683370190505b509050600080805b848110156122a3576122498782611c69565b60008181526013602052604090206002015490935060ff16612291578284838151811061227857612278614f4a565b602090810291909101015261228e600183614fb4565b91505b8061229b81614f76565b915050612237565b5061131a8382613031565b6122b933600c6130ce565b6122d55760405162461bcd60e51b8152600401610e9b90614fcc565b6001600160a01b0381166000908152601560205260409020805460ff19166001179055612306601780546001019055565b50565b60006001600160a01b0382166123745760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610e9b565b506001600160a01b031660009081526003602052604090205490565b61239b3360066130ce565b6123b75760405162461bcd60e51b8152600401610e9b90614fcc565b6001600160a01b0381166000908152601560205260409020805460ff1916905561185160176137f0565b60006123ec82612046565b6124385760405162461bcd60e51b815260206004820152601a60248201527f5468617420746f6b656e20646f6573206e6f742065786973742e0000000000006044820152606401610e9b565b5060009081526013602052604090205490565b600081815260126020526040812060028101549054610d8e91906152cb565b60008061247683612046565b6124c25760405162461bcd60e51b815260206004820152601a60248201527f5468697320746f6b656e20646f6573206e6f742065786973742e0000000000006044820152606401610e9b565b505060009081526013602052604090208054600290910154909160ff90911690565b600c5460ff16156125075760405162461bcd60e51b8152600401610e9b9061501b565b6125317f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a633610a3e565b61257d5760405162461bcd60e51b815260206004820181905260248201527f596f7520646f6e742068617665204d696e74657220726f6c652120536f7272796044820152606401610e9b565b60005b818110156126205761259d8383838181106115ff576115ff614f4a565b6125f85760405162461bcd60e51b815260206004820152602660248201527f535550504c59204552524f523a204e6f7420656e6f756768206f662074686973604482015265103a3cb8329760d11b6064820152608401610e9b565b61260e8484848481811061167c5761167c614f4a565b8061261881614f76565b915050612580565b50505050565b6000828152600b6020526040812061263e9083613847565b9392505050565b61264e33610bfc565b61268e5760405162461bcd60e51b81526020600482015260116024820152702cb7ba9030b932903737ba1037bbb732b960791b6044820152606401610e9b565b6001600160a01b03811660009081526015602052604090205460ff166126c65760405162461bcd60e51b8152600401610e9b90615133565b6001600160a01b038116330361271e5760405162461bcd60e51b815260206004820152601d60248201527f596f752063616e6e6f7420617574686f72697a6520796f757273656c660000006044820152606401610e9b565b6001600160a01b038116600090815260166020526040902054600160a01b900460ff16156127b45760405162461bcd60e51b815260206004820152603860248201527f546865726520697320616c726561647920612070656e64696e6720617574686f60448201527f72697a6174696f6e20666f722074686973206f776e65722e00000000000000006064820152608401610e9b565b6001600160a01b0316600090815260166020526040902080546001600160a01b031960ff93909316600160a01b02929092166001600160a81b03199092169190911733179055565b606061280782612046565b6128535760405162461bcd60e51b815260206004820152601a60248201527f5468697320746f6b656e20646f6573206e6f742065786973742e0000000000006044820152606401610e9b565b600061285e836123e1565b6000848152601360205260408120600101549192509061287d90613853565b6000838152601260205260408120549192509061289990613853565b9050600082826040516020016128b09291906152e2565b60408051601f198184030181529190529695505050505050565b606060018054610da390614f10565b600081815260126020526040812060010154610d8e565b60005b81811015610fd05761291c83838381811061291057612910614f4a565b90506020020135611f07565b8061292681614f76565b9150506128f3565b611c40338383613954565b60005b81811015611ee557612967858585858581811061295b5761295b614f4a565b90506020020135611eec565b8061297181614f76565b91505061293c565b6129833383613524565b6129e95760405162461bcd60e51b815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6044820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b6064820152608401610e9b565b61262084848484613a22565b6000818152600260205260409020546060906001600160a01b0316612a745760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610e9b565b600082815260136020526040812054612a8c90613853565b90506000612a98613a55565b60008581526013602052604090206002015490915060609060ff1615612adf5782604051602001612ac9919061531e565b6040516020818303038152906040529050612ae2565b50815b8181604051602001612af5929190615347565b6040516020818303038152906040529350505050919050565b6000818152600b60205260408120610d8e90613a64565b6000601482604051612b379190615386565b9081526040519081900360200190205460ff1692915050565b60606000612b5d83612309565b905060008167ffffffffffffffff811115612b7a57612b7a614c67565b604051908082528060200260200182016040528015612ba3578160200160208202803683370190505b50905060005b82811015612bea57612bbb8582611c69565b828281518110612bcd57612bcd614f4a565b602090810291909101015280612be281614f76565b915050612ba9565b509392505050565b6000828152600a6020526040902060010154612c0d816137a2565b610fd083836137ce565b6000612c2260175490565b905090565b6001600160a01b038116612c955760405162461bcd60e51b815260206004820152602f60248201527f457863657074696f6e20696e20736574526f79616c746965734164647265737360448201526e1d1020b2323932b9b9903d32b9379760891b6064820152608401610e9b565b612ca03360096130ce565b612cbc5760405162461bcd60e51b8152600401610e9b90614fcc565b601080546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b038116612d4a5760405162461bcd60e51b815260206004820152602d60248201527f457863657074696f6e20696e207365744f70656e536561416464726573733a2060448201526c20b2323932b9b9903d32b9379760991b6064820152608401610e9b565b612d5533600b6130ce565b612d715760405162461bcd60e51b8152600401610e9b906150e3565b600f80546001600160a01b0319166001600160a01b0392909216919091179055565b600f546000906001600160a01b0390811690831603612db457506001610d8e565b6001600160a01b0380841660009081526005602090815260408083209386168352929052205460ff1661263e565b612ded3360016130ce565b612e395760405162461bcd60e51b815260206004820152601b60248201527f596f7520646f206e6f742068617665207065726d697373696f6e7300000000006044820152606401610e9b565b828114612e885760405162461bcd60e51b815260206004820152601860248201527f41727261792073697a657320646f206e6f74206d6174636800000000000000006044820152606401610e9b565b60005b83811015611ee557828282818110612ea557612ea5614f4a565b9050602002013560126000878785818110612ec257612ec2614f4a565b602090810292909201358352508101919091526040016000205580612ee681614f76565b915050612e8b565b80546001019055565b60006001600160e01b03198216635a05180f60e01b1480610d8e5750610d8e82613a6e565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190612f5182612165565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000612f9582612165565b9050612fa381600084613a93565b612fae600083612f1c565b6001600160a01b0381166000908152600360205260408120805460019290612fd79084906152cb565b909155505060008281526002602052604080822080546001600160a01b0319169055518391906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b606060008267ffffffffffffffff81111561304e5761304e614c67565b604051908082528060200260200182016040528015613077578160200160208202803683370190505b50905060005b83811015612bea5784818151811061309757613097614f4a565b60200260200101518282815181106130b1576130b1614f4a565b6020908102919091010152806130c681614f76565b91505061307d565b6001600160a01b03821660009081526015602052604081205460ff166131065760405162461bcd60e51b8152600401610e9b90615133565b6001600160a01b03831660009081526016602052604081205460ff808516600160a01b909204160361263e5750600161263e84611749565b606080606060005b85518110156131c95761317186828151811061316457613164614f4a565b6020026020010151613853565b60405160200161318191906153a2565b604051602081830303815290604052915082826040516020016131a59291906153c7565b604051602081830303815290604052925080806131c190614f76565b915050613146565b5060005b845181101561329e57600185516131e491906152cb565b810361322c57828582815181106131fd576131fd614f4a565b60200260200101516040516020016132169291906153c7565b604051602081830303815290604052925061328c565b84818151811061323e5761323e614f4a565b602002602001015160405160200161325691906153a2565b6040516020818303038152906040529150828260405160200161327a9291906153c7565b60405160208183030381529060405292505b8061329681614f76565b9150506131cd565b5090949350505050565b60006132da836040516020016132be9190615386565b6040516020818303038152906040528051906020012083613b4b565b600c5461010090046001600160a01b03908116911614905092915050565b6000808251116133705760405162461bcd60e51b815260206004820152603360248201527f457863657074696f6e20696e20636865636b54783a205468657265206172652060448201527f6e6f742054782049647320746f20636865636b000000000000000000000000006064820152608401610e9b565b6000805b811580156133825750835181105b1561342f57601484828151811061339b5761339b614f4a565b60200260200101516040516133b09190615386565b9081526040519081900360200190205460ff16156133d1576001915061341d565b600160148583815181106133e7576133e7614f4a565b60200260200101516040516133fc9190615386565b908152604051908190036020019020805491151560ff199092169190911790555b613428600182614fb4565b9050613374565b5092915050565b600081815260126020526040812080548291613453906001015490565b1015610d8e5750600192915050565b60008181526012602052604090206134809060010180546001019055565b61348e600e80546001019055565b600081815260126020526040902060010154601360006134ad600e5490565b81526020019081526020016000206001018190555080601360006134d0600e5490565b8152602001908152602001600020600001819055506000601360006134f4600e5490565b81526020810191909152604001600020600201805460ff1916911515919091179055600e54611c40908390613b67565b6000818152600260205260408120546001600160a01b031661359d5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610e9b565b60006135a883612165565b9050806001600160a01b0316846001600160a01b031614806135cf57506135cf8185612d93565b806135f35750836001600160a01b03166135e884610e26565b6001600160a01b0316145b949350505050565b826001600160a01b031661360e82612165565b6001600160a01b0316146136725760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201526437bbb732b960d91b6064820152608401610e9b565b6001600160a01b0382166136d45760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610e9b565b6136df838383613a93565b6136ea600082612f1c565b6001600160a01b03831660009081526003602052604081208054600192906137139084906152cb565b90915550506001600160a01b0382166000908152600360205260408120805460019290613741908490614fb4565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6123068133613b81565b6137b68282613c01565b6000828152600b60205260409020610fd09082613ca3565b6137d88282613cb8565b6000828152600b60205260409020610fd09082613d3b565b80548061383f5760405162461bcd60e51b815260206004820152601b60248201527f436f756e7465723a2064656372656d656e74206f766572666c6f7700000000006044820152606401610e9b565b600019019055565b600061263e8383613d50565b60608160000361387a5750506040805180820190915260018152600360fc1b602082015290565b8160005b81156138a4578061388e81614f76565b915061389d9050600a836151a9565b915061387e565b60008167ffffffffffffffff8111156138bf576138bf614c67565b6040519080825280601f01601f1916602001820160405280156138e9576020820181803683370190505b5090505b84156135f3576138fe6001836152cb565b915061390b600a866153f6565b613916906030614fb4565b60f81b81838151811061392b5761392b614f4a565b60200101906001600160f81b031916908160001a90535061394d600a866151a9565b94506138ed565b816001600160a01b0316836001600160a01b0316036139b55760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610e9b565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b613a2d8484846135fb565b613a3984848484613d7a565b6126205760405162461bcd60e51b8152600401610e9b9061540a565b6060600d8054610da390614f10565b6000610d8e825490565b60006001600160e01b03198216637965db0b60e01b1480610d8e5750610d8e82613e7b565b6001600160a01b038316613aee57613ae981600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b613b11565b816001600160a01b0316836001600160a01b031614613b1157613b118382613ea0565b6001600160a01b038216613b2857610fd081613f3d565b826001600160a01b0316826001600160a01b031614610fd057610fd08282613fec565b6000806000613b5a8585614030565b91509150612bea8161409b565b611c40828260405180602001604052806000815250614251565b6000828152600a602090815260408083206001600160a01b038516845290915290205460ff16611c4057613bbf816001600160a01b03166014614284565b613bca836020614284565b604051602001613bdb92919061545c565b60408051601f198184030181529082905262461bcd60e51b8252610e9b916004016148b1565b6000828152600a602090815260408083206001600160a01b038516845290915290205460ff16611c40576000828152600a602090815260408083206001600160a01b03851684529091529020805460ff19166001179055613c5f3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b600061263e836001600160a01b038416614420565b6000828152600a602090815260408083206001600160a01b038516845290915290205460ff1615611c40576000828152600a602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b600061263e836001600160a01b03841661446f565b6000826000018281548110613d6757613d67614f4a565b9060005260206000200154905092915050565b60006001600160a01b0384163b15613e7057604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290613dbe9033908990889088906004016154d1565b6020604051808303816000875af1925050508015613df9575060408051601f3d908101601f19168201909252613df691810190615503565b60015b613e56573d808015613e27576040519150601f19603f3d011682016040523d82523d6000602084013e613e2c565b606091505b508051600003613e4e5760405162461bcd60e51b8152600401610e9b9061540a565b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490506135f3565b506001949350505050565b60006001600160e01b0319821663780e9d6360e01b1480610d8e5750610d8e82614562565b60006001613ead84612309565b613eb791906152cb565b600083815260076020526040902054909150808214613f0a576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b600854600090613f4f906001906152cb565b60008381526009602052604081205460088054939450909284908110613f7757613f77614f4a565b906000526020600020015490508060088381548110613f9857613f98614f4a565b6000918252602080832090910192909255828152600990915260408082208490558582528120556008805480613fd057613fd0615520565b6001900381819060005260206000200160009055905550505050565b6000613ff783612309565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b60008082516041036140665760208301516040840151606085015160001a61405a878285856145b2565b94509450505050611bb5565b825160400361408f576020830151604084015161408486838361469f565b935093505050611bb5565b50600090506002611bb5565b60008160048111156140af576140af615536565b036140b75750565b60018160048111156140cb576140cb615536565b036141185760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610e9b565b600281600481111561412c5761412c615536565b036141795760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610e9b565b600381600481111561418d5761418d615536565b036141e55760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610e9b565b60048160048111156141f9576141f9615536565b036123065760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b6064820152608401610e9b565b61425b83836146d8565b6142686000848484613d7a565b610fd05760405162461bcd60e51b8152600401610e9b9061540a565b60606000614293836002615174565b61429e906002614fb4565b67ffffffffffffffff8111156142b6576142b6614c67565b6040519080825280601f01601f1916602001820160405280156142e0576020820181803683370190505b509050600360fc1b816000815181106142fb576142fb614f4a565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061432a5761432a614f4a565b60200101906001600160f81b031916908160001a905350600061434e846002615174565b614359906001614fb4565b90505b60018111156143d1576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061438d5761438d614f4a565b1a60f81b8282815181106143a3576143a3614f4a565b60200101906001600160f81b031916908160001a90535060049490941c936143ca8161554c565b905061435c565b50831561263e5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610e9b565b600081815260018301602052604081205461446757508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610d8e565b506000610d8e565b600081815260018301602052604081205480156145585760006144936001836152cb565b85549091506000906144a7906001906152cb565b905081811461450c5760008660000182815481106144c7576144c7614f4a565b90600052602060002001549050808760000184815481106144ea576144ea614f4a565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061451d5761451d615520565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610d8e565b6000915050610d8e565b60006001600160e01b031982166380ac58cd60e01b148061459357506001600160e01b03198216635b5e139f60e01b145b80610d8e57506301ffc9a760e01b6001600160e01b0319831614610d8e565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156145e95750600090506003614696565b8460ff16601b1415801561460157508460ff16601c14155b156146125750600090506004614696565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015614666573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661468f57600060019250925050614696565b9150600090505b94509492505050565b6000806001600160ff1b038316816146bc60ff86901c601b614fb4565b90506146ca878288856145b2565b935093505050935093915050565b6001600160a01b03821661472e5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610e9b565b6000818152600260205260409020546001600160a01b0316156147935760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610e9b565b61479f60008383613a93565b6001600160a01b03821660009081526003602052604081208054600192906147c8908490614fb4565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6001600160e01b03198116811461230657600080fd5b60006020828403121561484e57600080fd5b813561263e81614826565b60005b8381101561487457818101518382015260200161485c565b838111156126205750506000910152565b6000815180845261489d816020860160208601614859565b601f01601f19169290920160200192915050565b60208152600061263e6020830184614885565b6000602082840312156148d657600080fd5b5035919050565b6001600160a01b038116811461230657600080fd5b6000806040838503121561490557600080fd5b8235614910816148dd565b946020939093013593505050565b60008083601f84011261493057600080fd5b50813567ffffffffffffffff81111561494857600080fd5b6020830191508360208260051b8501011115611bb557600080fd5b6000806020838503121561497657600080fd5b823567ffffffffffffffff81111561498d57600080fd5b6149998582860161491e565b90969095509350505050565b6020808252825182820181905260009190848201906040850190845b818110156149dd578351835292840192918401916001016149c1565b50909695505050505050565b6000602082840312156149fb57600080fd5b81356bffffffffffffffffffffffff8116811461263e57600080fd5b60008060008060008060608789031215614a3057600080fd5b863567ffffffffffffffff80821115614a4857600080fd5b614a548a838b0161491e565b90985096506020890135915080821115614a6d57600080fd5b614a798a838b0161491e565b90965094506040890135915080821115614a9257600080fd5b818901915089601f830112614aa657600080fd5b813581811115614ab557600080fd5b8a6020828501011115614ac757600080fd5b6020830194508093505050509295509295509295565b600060208284031215614aef57600080fd5b813561263e816148dd565b80358015158114614b0a57600080fd5b919050565b600060208284031215614b2157600080fd5b61263e82614afa565b600080600060608486031215614b3f57600080fd5b8335614b4a816148dd565b92506020840135614b5a816148dd565b929592945050506040919091013590565b60008060408385031215614b7e57600080fd5b50508035926020909101359150565b60008060408385031215614ba057600080fd5b823591506020830135614bb2816148dd565b809150509250929050565b60008060008060408587031215614bd357600080fd5b843567ffffffffffffffff80821115614beb57600080fd5b614bf78883890161491e565b90965094506020870135915080821115614c1057600080fd5b50614c1d8782880161491e565b95989497509550505050565b600080600060608486031215614c3e57600080fd5b8335614c49816148dd565b925060208401359150614c5e60408501614afa565b90509250925092565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715614ca657614ca6614c67565b604052919050565b600067ffffffffffffffff831115614cc857614cc8614c67565b614cdb601f8401601f1916602001614c7d565b9050828152838383011115614cef57600080fd5b828260208301376000602084830101529392505050565b600082601f830112614d1757600080fd5b61263e83833560208501614cae565b600060208284031215614d3857600080fd5b813567ffffffffffffffff811115614d4f57600080fd5b6135f384828501614d06565b600080600060408486031215614d7057600080fd5b8335614d7b816148dd565b9250602084013567ffffffffffffffff811115614d9757600080fd5b614da38682870161491e565b9497909650939450505050565b60008060408385031215614dc357600080fd5b823560ff81168114614dd457600080fd5b91506020830135614bb2816148dd565b60008060408385031215614df757600080fd5b8235614e02816148dd565b9150614e1060208401614afa565b90509250929050565b60008060008060608587031215614e2f57600080fd5b8435614e3a816148dd565b93506020850135614e4a816148dd565b9250604085013567ffffffffffffffff811115614e6657600080fd5b614c1d8782880161491e565b60008060008060808587031215614e8857600080fd5b8435614e93816148dd565b93506020850135614ea3816148dd565b925060408501359150606085013567ffffffffffffffff811115614ec657600080fd5b8501601f81018713614ed757600080fd5b614ee687823560208401614cae565b91505092959194509250565b60008060408385031215614f0557600080fd5b8235614dd4816148dd565b600181811c90821680614f2457607f821691505b602082108103614f4457634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600060018201614f8857614f88614f60565b5060010190565b600060ff821660ff84168060ff03821115614fac57614fac614f60565b019392505050565b60008219821115614fc757614fc7614f60565b500190565b6020808252602f908201527f596f752068617665206e6f74206265656e20617070726f76656420746f20727560408201526e37103a3434b990333ab731ba34b7b760891b606082015260800190565b60208082526024908201527f54686520636f6e74726163742069732074656d706f72616c792073757370656e6040820152633232b21760e11b606082015260800190565b600067ffffffffffffffff8084111561507a5761507a614c67565b8360051b602061508b818301614c7d565b8681529185019181810190368411156150a357600080fd5b865b848110156150d7578035868111156150bd5760008081fd5b6150c936828b01614d06565b8452509183019183016150a5565b50979650505050505050565b60208082526030908201527f596f752068617665206e6f74206265656e20617070726f76656420746f20727560408201526f37103a3434b990333ab731ba34b7b71760811b606082015260800190565b60208082526021908201527f54686973206973206e6f7420612077616c6c65742066726f6d2061206f776e656040820152603960f91b606082015260800190565b600081600019048311821515161561518e5761518e614f60565b500290565b634e487b7160e01b600052601260045260246000fd5b6000826151b8576151b8615193565b500490565b601f821115610fd057600081815260208120601f850160051c810160208610156151e45750805b601f850160051c820191505b81811015615203578281556001016151f0565b505050505050565b815167ffffffffffffffff81111561522557615225614c67565b615239816152338454614f10565b846151bd565b602080601f83116001811461526e57600084156152565750858301515b600019600386901b1c1916600185901b178555615203565b600085815260208120601f198616915b8281101561529d5788860151825594840194600190910190840161527e565b50858210156152bb5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6000828210156152dd576152dd614f60565b500390565b600083516152f4818460208801614859565b602f60f81b9083019081528351615312816001840160208801614859565b01600101949350505050565b60008251615330818460208701614859565b640b5d5cd95960da1b920191825250600501919050565b60008351615359818460208801614859565b83519083019061536d818360208801614859565b64173539b7b760d91b9101908152600501949350505050565b60008251615398818460208701614859565b9190910192915050565b600082516153b4818460208701614859565b600b60fa1b920191825250600101919050565b600083516153d9818460208801614859565b8351908301906153ed818360208801614859565b01949350505050565b60008261540557615405615193565b500690565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351615494816017850160208801614859565b7001034b99036b4b9b9b4b733903937b6329607d1b60179184019182015283516154c5816028840160208801614859565b01602801949350505050565b60006001600160a01b0380871683528086166020840152508360408301526080606083015261131a6080830184614885565b60006020828403121561551557600080fd5b815161263e81614826565b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052602160045260246000fd5b60008161555b5761555b614f60565b50600019019056fea2646970667358221220a5004ec34a849f4a9dc68ec41433d00eb8b1789b6184203e6c76fbaa04e95bed64736f6c634300080f0033

Deployed Bytecode Sourcemap

82320:23696:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;102362:287;;;;;;;;;;-1:-1:-1;102362:287:0;;;;;:::i;:::-;;:::i;:::-;;;565:14:1;;558:22;540:41;;528:2;513:18;102362:287:0;;;;;;;;61913:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;63473:221::-;;;;;;;;;;-1:-1:-1;63473:221:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;1692:55:1;;;1674:74;;1662:2;1647:18;63473:221:0;1528:226:1;62996:411:0;;;;;;;;;;-1:-1:-1;62996:411:0;;;;;:::i;:::-;;:::i;:::-;;89557:506;;;;;;;;;;-1:-1:-1;89557:506:0;;;;;:::i;:::-;;:::i;98346:580::-;;;;;;;;;;-1:-1:-1;98346:580:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;97918:420::-;;;;;;;;;;-1:-1:-1;97918:420:0;;;;;:::i;:::-;;:::i;:::-;;;3835:25:1;;;3823:2;3808:18;97918:420:0;3689:177:1;102038:314:0;;;;;;;;;;-1:-1:-1;102038:314:0;;;;;:::i;:::-;;:::i;90651:585::-;;;;;;;;;;-1:-1:-1;90651:585:0;;;;;:::i;:::-;;:::i;90071:133::-;;;;;;;;;;-1:-1:-1;90071:133:0;;;;;:::i;:::-;;:::i;75734:113::-;;;;;;;;;;-1:-1:-1;75822:10:0;:17;75734:113;;99627:182;;;;;;;;;;-1:-1:-1;99627:182:0;;;;;:::i;:::-;;:::i;104706:476::-;;;;;;;;;;-1:-1:-1;104706:476:0;;;;;:::i;:::-;;:::i;64223:339::-;;;;;;;;;;-1:-1:-1;64223:339:0;;;;;:::i;:::-;;:::i;93599:282::-;;;;;;;;;;-1:-1:-1;93599:282:0;;;;;:::i;:::-;;:::i;46835:131::-;;;;;;;;;;-1:-1:-1;46835:131:0;;;;;:::i;:::-;46909:7;46936:12;;;:6;:12;;;;;:22;;;;46835:131;94752:434;;;;;;;;;;-1:-1:-1;94752:434:0;;;;;:::i;:::-;;:::i;83315:62::-;;;;;;;;;;;;83353:24;83315:62;;101431:288;;;;;;;;;;-1:-1:-1;101431:288:0;;;;;:::i;:::-;;:::i;:::-;;;;-1:-1:-1;;;;;7281:55:1;;;7263:74;;7368:2;7353:18;;7346:34;;;;7236:18;101431:288:0;7089:297:1;103468:101:0;;;;;;;;;;-1:-1:-1;103547:14:0;;-1:-1:-1;;;;;103547:14:0;103468:101;;85800:178;;;;;;;;;;-1:-1:-1;85800:178:0;;;;;:::i;:::-;;:::i;47228:147::-;;;;;;;;;;-1:-1:-1;47228:147:0;;;;;:::i;:::-;;:::i;75402:256::-;;;;;;;;;;-1:-1:-1;75402:256:0;;;;;:::i;:::-;;:::i;48276:218::-;;;;;;;;;;-1:-1:-1;48276:218:0;;;;;:::i;:::-;;:::i;95194:487::-;;;;;;;;;;-1:-1:-1;95194:487:0;;;;;:::i;:::-;;:::i;64633:185::-;;;;;;;;;;-1:-1:-1;64633:185:0;;;;;:::i;:::-;;:::i;88987:395::-;;;;;;;;;;-1:-1:-1;88987:395:0;;;;;:::i;:::-;;:::i;86772:304::-;;;;;;;;;;-1:-1:-1;86772:304:0;;;;;:::i;:::-;;:::i;101321:102::-;;;;;;;;;;-1:-1:-1;101321:102:0;;;;;:::i;:::-;;:::i;75924:233::-;;;;;;;;;;-1:-1:-1;75924:233:0;;;;;:::i;:::-;;:::i;100812:195::-;;;;;;;;;;-1:-1:-1;100812:195:0;;;;;:::i;:::-;;:::i;88119:161::-;;;;;;;;;;-1:-1:-1;88119:161:0;;;;;:::i;:::-;;:::i;87749:107::-;;;;;;;;;;-1:-1:-1;87749:107:0;;;;;:::i;:::-;87804:4;87828:15;;;:9;:15;;;;;:20;;87749:107;87989:122;;;;;;;;;;-1:-1:-1;87989:122:0;;;;;:::i;:::-;;:::i;61607:239::-;;;;;;;;;;-1:-1:-1;61607:239:0;;;;;:::i;:::-;;:::i;97130:589::-;;;;;;;;;;-1:-1:-1;97130:589:0;;;;;:::i;:::-;;:::i;105324:236::-;;;;;;;;;;-1:-1:-1;105324:236:0;;;;;:::i;:::-;;:::i;61337:208::-;;;;;;;;;;-1:-1:-1;61337:208:0;;;;;:::i;:::-;;:::i;105568:331::-;;;;;;;;;;-1:-1:-1;105568:331:0;;;;;:::i;:::-;;:::i;97727:183::-;;;;;;;;;;-1:-1:-1;97727:183:0;;;;;:::i;:::-;;:::i;88288:150::-;;;;;;;;;;-1:-1:-1;88288:150:0;;;;;:::i;:::-;;:::i;96081:232::-;;;;;;;;;;-1:-1:-1;96081:232:0;;;;;:::i;:::-;;:::i;:::-;;;;10420:25:1;;;10488:14;;10481:22;10476:2;10461:18;;10454:50;10393:18;96081:232:0;10252:258:1;91244:429:0;;;;;;;;;;-1:-1:-1;91244:429:0;;;;;:::i;:::-;;:::i;51785:153::-;;;;;;;;;;-1:-1:-1;51785:153:0;;;;;:::i;:::-;;:::i;45295:147::-;;;;;;;;;;-1:-1:-1;45295:147:0;;;;;:::i;:::-;45381:4;45405:12;;;:6;:12;;;;;;;;-1:-1:-1;;;;;45405:29:0;;;;;;;;;;;;;;;45295:147;104176:522;;;;;;;;;;-1:-1:-1;104176:522:0;;;;;:::i;:::-;;:::i;96321:444::-;;;;;;;;;;-1:-1:-1;96321:444:0;;;;;:::i;:::-;;:::i;62082:104::-;;;;;;;;;;;;;:::i;87864:117::-;;;;;;;;;;-1:-1:-1;87864:117:0;;;;;:::i;:::-;;:::i;89390:159::-;;;;;;;;;;-1:-1:-1;89390:159:0;;;;;:::i;:::-;;:::i;44400:49::-;;;;;;;;;;-1:-1:-1;44400:49:0;44445:4;44400:49;;63766:155;;;;;;;;;;-1:-1:-1;63766:155:0;;;;;:::i;:::-;;:::i;90212:137::-;;;;;;;;;;-1:-1:-1;90212:137:0;;;;;:::i;:::-;-1:-1:-1;;;;;90315:19:0;90288:7;90315:19;;;:11;:19;;;;;:26;;90212:137;86257:240;;;;;;;;;;-1:-1:-1;86257:240:0;;;;;:::i;:::-;;:::i;64889:328::-;;;;;;;;;;-1:-1:-1;64889:328:0;;;;;:::i;:::-;;:::i;99534:85::-;;;;;;;;;;-1:-1:-1;99602:9:0;;;;99534:85;;100205:599;;;;;;;;;;-1:-1:-1;100205:599:0;;;;;:::i;:::-;;:::i;103714:98::-;;;;;;;;;;-1:-1:-1;103714:98:0;;;;;:::i;:::-;-1:-1:-1;;;;;103792:12:0;103768:4;103792:12;;;:6;:12;;;;;;;;;103714:98;52112:142;;;;;;;;;;-1:-1:-1;52112:142:0;;;;;:::i;:::-;;:::i;95961:112::-;;;;;;;;;;-1:-1:-1;95961:112:0;;;;;:::i;:::-;;:::i;96773:349::-;;;;;;;;;;-1:-1:-1;96773:349:0;;;;;:::i;:::-;;:::i;83246:62::-;;;;;;;;;;;;83284:24;83246:62;;47620:149;;;;;;;;;;-1:-1:-1;47620:149:0;;;;;:::i;:::-;;:::i;105910:103::-;;;;;;;;;;;;;:::i;101727:303::-;;;;;;;;;;-1:-1:-1;101727:303:0;;;;;:::i;:::-;;:::i;103174:286::-;;;;;;;;;;-1:-1:-1;103174:286:0;;;;;:::i;:::-;;:::i;102744:422::-;;;;;;;;;;-1:-1:-1;102744:422:0;;;;;:::i;:::-;;:::i;87382:359::-;;;;;;;;;;-1:-1:-1;87382:359:0;;;;;:::i;:::-;;:::i;102362:287::-;102490:4;-1:-1:-1;;;;;;;;;102510:36:0;;;102507:79;;-1:-1:-1;102570:4:0;;102362:287;-1:-1:-1;102362:287:0:o;102507:79::-;102605:36;102629:11;102605:23;:36::i;:::-;102598:43;102362:287;-1:-1:-1;;102362:287:0:o;61913:100::-;61967:13;62000:5;61993:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61913:100;:::o;63473:221::-;63549:7;66816:16;;;:7;:16;;;;;;-1:-1:-1;;;;;66816:16:0;63569:73;;;;-1:-1:-1;;;63569:73:0;;15616:2:1;63569:73:0;;;15598:21:1;15655:2;15635:18;;;15628:30;15694:34;15674:18;;;15667:62;-1:-1:-1;;;15745:18:1;;;15738:42;15797:19;;63569:73:0;;;;;;;;;-1:-1:-1;63662:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;63662:24:0;;63473:221::o;62996:411::-;63077:13;63093:23;63108:7;63093:14;:23::i;:::-;63077:39;;63141:5;-1:-1:-1;;;;;63135:11:0;:2;-1:-1:-1;;;;;63135:11:0;;63127:57;;;;-1:-1:-1;;;63127:57:0;;16029:2:1;63127:57:0;;;16011:21:1;16068:2;16048:18;;;16041:30;16107:34;16087:18;;;16080:62;-1:-1:-1;;;16158:18:1;;;16151:31;16199:19;;63127:57:0;15827:397:1;63127:57:0;30785:10;-1:-1:-1;;;;;63219:21:0;;;;:62;;-1:-1:-1;63244:37:0;63261:5;30785:10;102744:422;:::i;63244:37::-;63197:168;;;;-1:-1:-1;;;63197:168:0;;16431:2:1;63197:168:0;;;16413:21:1;16470:2;16450:18;;;16443:30;16509:34;16489:18;;;16482:62;16580:26;16560:18;;;16553:54;16624:19;;63197:168:0;16229:420:1;63197:168:0;63378:21;63387:2;63391:7;63378:8;:21::i;:::-;63066:341;62996:411;;:::o;89557:506::-;89638:9;;;;89637:10;89629:58;;;;-1:-1:-1;;;89629:58:0;;16856:2:1;89629:58:0;;;16838:21:1;16895:2;16875:18;;;16868:30;16934:34;16914:18;;;16907:62;-1:-1:-1;;;16985:18:1;;;16978:33;17028:19;;89629:58:0;16654:399:1;89629:58:0;89706:34;83353:24;30785:10;45295:147;:::i;89706:34::-;89698:92;;;;-1:-1:-1;;;89698:92:0;;17260:2:1;89698:92:0;;;17242:21:1;17299:2;17279:18;;;17272:30;17338:34;17318:18;;;17311:62;-1:-1:-1;;;17389:18:1;;;17382:43;17442:19;;89698:92:0;17058:409:1;89698:92:0;89807:6;89803:253;89819:19;;;89803:253;;;89859:9;89871:25;89884:8;;89893:1;89884:11;;;;;;;:::i;:::-;;;;;;;89871:12;:25::i;:::-;89911:15;;;;:9;:15;;;;;:22;;1083:19;;1101:1;1083:19;;;89911:15;-1:-1:-1;89960:11:0;:33;89972:20;89980:8;;89989:1;89980:11;;;;;;;:::i;:::-;;;;;;;89972:7;:20::i;:::-;-1:-1:-1;;;;;89960:33:0;-1:-1:-1;;;;;89960:33:0;;;;;;;;;;;;89999:8;;90008:1;89999:11;;;;;;;:::i;:::-;89960:51;;;;;;;-1:-1:-1;89960:51:0;;;89999:11;89960:51;;;;89999:11;;;;;;;;;89960:51;;;;;-1:-1:-1;90026:18:0;90032:8;;90041:1;90032:11;;;;;;;:::i;:::-;;;;;;;90026:5;:18::i;:::-;-1:-1:-1;89840:3:0;;;;:::i;:::-;;;;89803:253;;98346:580;98423:16;98462:23;98488:19;98500:6;98488:11;:19::i;:::-;98462:45;;98518:26;98561:6;:13;98547:28;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;98547:28:0;;98518:57;;98588:7;98624:6;98620:187;98640:6;:13;98636:1;:17;98620:187;;;98706:4;98677:9;:20;98687:6;98694:1;98687:9;;;;;;;;:::i;:::-;;;;;;;98677:20;;;;;;;;;;;:25;;;:33;98674:122;;98746:6;98753:1;98746:9;;;;;;;;:::i;:::-;;;;;;;98731;98741:1;98731:12;;;;;;;;;;:::i;:::-;;;;;;;;;;:24;98774:6;98779:1;98774:6;;:::i;:::-;;;98674:122;98655:3;;;;:::i;:::-;;;;98620:187;;;;98831:1;98827;:5;;;98819:57;;;;-1:-1:-1;;;98819:57:0;;18287:2:1;98819:57:0;;;18269:21:1;18326:2;18306:18;;;18299:30;18365:34;18345:18;;;18338:62;-1:-1:-1;;;18416:18:1;;;18409:37;18463:19;;98819:57:0;18085:403:1;98819:57:0;98894:24;98905:9;98916:1;98894:24;;:10;:24::i;:::-;98887:31;98346:580;-1:-1:-1;;;;;;98346:580:0:o;97918:420::-;97996:7;98026:25;98054:19;98066:6;98054:11;:19::i;:::-;98026:47;-1:-1:-1;98084:16:0;;;98139:164;98159:8;:15;98155:1;:19;98139:164;;;98202:8;98211:1;98202:11;;;;;;;;:::i;:::-;;;;;;;98196:17;;98254:4;98231:9;:14;98241:3;98231:14;;;;;;;;;;;:19;;;:27;98228:63;;98278:13;98290:1;98278:13;;:::i;:::-;;;98228:63;98176:3;;;;:::i;:::-;;;;98139:164;;;-1:-1:-1;98322:8:0;;97918:420;-1:-1:-1;;;;;97918:420:0:o;102038:314::-;102120:31;30785:10;102148:2;102120:13;:31::i;:::-;102112:91;;;;-1:-1:-1;;;102112:91:0;;;;;;;:::i;:::-;102238:17;;;;;;102222:33;;;;;102214:75;;;;-1:-1:-1;;;102214:75:0;;19244:2:1;102214:75:0;;;19226:21:1;19283:2;19263:18;;;19256:30;19322:31;19302:18;;;19295:59;19371:18;;102214:75:0;19042:353:1;102214:75:0;102310:21;:34;;;;;;-1:-1:-1;;;102310:34:0;-1:-1:-1;;;;;102310:34:0;;;;;;;;;102038:314::o;90651:585::-;90772:9;;;;90771:10;90763:59;;;;-1:-1:-1;;;90763:59:0;;;;;;;:::i;:::-;90841:49;90852:30;90866:8;;90852:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;90852:30:0;;-1:-1:-1;90876:5:0;;-1:-1:-1;90876:5:0;;-1:-1:-1;90852:30:0;:::i;:::-;:13;:30::i;:::-;90884:5;;90841:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;90841:10:0;;-1:-1:-1;;;90841:49:0:i;:::-;90833:105;;;;-1:-1:-1;;;90833:105:0;;20949:2:1;90833:105:0;;;20931:21:1;20988:2;20968:18;;;20961:30;21027:34;21007:18;;;21000:62;-1:-1:-1;;;21078:18:1;;;21071:41;21129:19;;90833:105:0;20747:407:1;90833:105:0;90958:14;;90966:5;;90958:14;:::i;:::-;:7;:14::i;:::-;90957:15;90949:77;;;;-1:-1:-1;;;90949:77:0;;21361:2:1;90949:77:0;;;21343:21:1;21400:2;21380:18;;;21373:30;21439:34;21419:18;;;21412:62;-1:-1:-1;;;21490:18:1;;;21483:47;21547:19;;90949:77:0;21159:413:1;90949:77:0;91043:6;91039:190;91055:19;;;91039:190;;;91104:24;91116:8;;91125:1;91116:11;;;;;;;:::i;:::-;;;;;;;91104;:24::i;:::-;91096:75;;;;-1:-1:-1;;;91096:75:0;;21779:2:1;91096:75:0;;;21761:21:1;21818:2;21798:18;;;21791:30;21857:34;21837:18;;;21830:62;-1:-1:-1;;;21908:18:1;;;21901:36;21954:19;;91096:75:0;21577:402:1;91096:75:0;91186:31;30785:10;91205:8;;91214:1;91205:11;;;;;;;:::i;:::-;;;;;;;91186:4;:31::i;:::-;91076:3;;;;:::i;:::-;;;;91039:190;;;;90651:585;;;;;;:::o;90071:133::-;-1:-1:-1;;;;;90177:19:0;;;;;;:11;:19;;;;;;;;;90170:26;;;;;;;;;;;;;;;;;90141:16;;90170:26;;;90177:19;90170:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;90071:133;;;:::o;99627:182::-;99690:30;30785:10;99718:1;99690:13;:30::i;:::-;99682:91;;;;-1:-1:-1;;;99682:91:0;;;;;;;:::i;:::-;99784:9;:17;;-1:-1:-1;;99784:17:0;;;;;;;;;;99627:182::o;104706:476::-;104769:24;30785:10;104780:12;30705:98;104769:24;104761:54;;;;-1:-1:-1;;;104761:54:0;;22603:2:1;104761:54:0;;;22585:21:1;22642:2;22622:18;;;22615:30;-1:-1:-1;;;22661:18:1;;;22654:47;22718:18;;104761:54:0;22401:341:1;104761:54:0;-1:-1:-1;;;;;103792:12:0;;103768:4;103792:12;;;:6;:12;;;;;;;;104826:63;;;;-1:-1:-1;;;104826:63:0;;;;;;;:::i;:::-;30785:10;-1:-1:-1;;;;;104906:21:0;;;104902:158;;-1:-1:-1;;;;;104952:23:0;;;;;;;:16;:23;;;;;:38;;30785:10;104952:54;104944:104;;;;-1:-1:-1;;;104944:104:0;;23351:2:1;104944:104:0;;;23333:21:1;23390:2;23370:18;;;23363:30;23429:34;23409:18;;;23402:62;-1:-1:-1;;;23480:18:1;;;23473:35;23525:19;;104944:104:0;23149:401:1;104944:104:0;-1:-1:-1;;;;;105072:23:0;105111:1;105072:23;;;:16;:23;;;;;:40;;-1:-1:-1;;;;;;105123:51:0;;;104706:476::o;64223:339::-;64418:41;30785:10;64451:7;64418:18;:41::i;:::-;64410:103;;;;-1:-1:-1;;;64410:103:0;;23757:2:1;64410:103:0;;;23739:21:1;23796:2;23776:18;;;23769:30;23835:34;23815:18;;;23808:62;-1:-1:-1;;;23886:18:1;;;23879:47;23943:19;;64410:103:0;23555:413:1;64410:103:0;64526:28;64536:4;64542:2;64546:7;64526:9;:28::i;93599:282::-;-1:-1:-1;;;;;93669:25:0;;93661:77;;;;-1:-1:-1;;;93661:77:0;;24175:2:1;93661:77:0;;;24157:21:1;24214:2;24194:18;;;24187:30;24253:34;24233:18;;;24226:62;-1:-1:-1;;;24304:18:1;;;24297:37;24351:19;;93661:77:0;23973:403:1;93661:77:0;93757:30;30785:10;93785:1;93757:13;:30::i;:::-;93749:91;;;;-1:-1:-1;;;93749:91:0;;;;;;;:::i;:::-;93851:8;:22;;-1:-1:-1;;;;;93851:22:0;;;;;-1:-1:-1;;93851:22:0;;;;;;;;;93599:282::o;94752:434::-;94834:18;94826:79;;;;-1:-1:-1;;;94826:79:0;;24583:2:1;94826:79:0;;;24565:21:1;24622:2;24602:18;;;24595:30;24661:34;24641:18;;;24634:62;-1:-1:-1;;;24712:18:1;;;24705:46;24768:19;;94826:79:0;24381:412:1;94826:79:0;94922:6;94918:261;94934:19;;;94918:261;;;94999:20;95007:8;;95016:1;95007:11;;;;;;;:::i;94999:20::-;-1:-1:-1;;;;;94983:36:0;30785:10;-1:-1:-1;;;;;94983:36:0;;94975:73;;;;-1:-1:-1;;;94975:73:0;;25000:2:1;94975:73:0;;;24982:21:1;25039:2;25019:18;;;25012:30;25078:26;25058:18;;;25051:54;25122:18;;94975:73:0;24798:348:1;94975:73:0;95071:19;95078:8;;95087:1;95078:11;;;;;;;:::i;:::-;;;;;;;95071:6;:19::i;:::-;95063:52;;;;-1:-1:-1;;;95063:52:0;;25353:2:1;95063:52:0;;;25335:21:1;25392:2;25372:18;;;25365:30;-1:-1:-1;;;25411:18:1;;;25404:50;25471:18;;95063:52:0;25151:344:1;95063:52:0;95163:4;95132:9;:22;95142:8;;95151:1;95142:11;;;;;;;:::i;:::-;;;;;;;95132:22;;;;;;;;;;;:28;;;:35;;;;;;;;;;;;;;;;;;94955:3;;;;;:::i;:::-;;;;94918:261;;101431:288;101514:16;101532:21;101569:16;101576:8;101569:6;:16::i;:::-;101566:103;;;101607:17;;-1:-1:-1;;;;;101607:17:0;;;101663:5;;101627:34;;-1:-1:-1;;;101640:21:0;;;;101627:10;:34;:::i;:::-;101626:42;;;;:::i;:::-;101600:69;;;;;;101566:103;-1:-1:-1;101704:1:0;;-1:-1:-1;101704:1:0;101431:288;;;;;;:::o;85800:178::-;85859:30;30785:10;85887:1;85859:13;:30::i;:::-;85851:70;;;;-1:-1:-1;;;85851:70:0;;26132:2:1;85851:70:0;;;26114:21:1;26171:2;26151:18;;;26144:30;26210:29;26190:18;;;26183:57;26257:18;;85851:70:0;25930:351:1;85851:70:0;85932:38;;30785:10;;85932:38;;;;;85963:6;;85932:38;;;;85963:6;30785:10;85932:38;;;;;;;;;;;;;;;;;;;;;85800:178;:::o;47228:147::-;46909:7;46936:12;;;:6;:12;;;;;:22;;;44891:16;44902:4;44891:10;:16::i;:::-;47342:25:::1;47353:4;47359:7;47342:10;:25::i;75402:256::-:0;75499:7;75535:23;75552:5;75535:16;:23::i;:::-;75527:5;:31;75519:87;;;;-1:-1:-1;;;75519:87:0;;26488:2:1;75519:87:0;;;26470:21:1;26527:2;26507:18;;;26500:30;26566:34;26546:18;;;26539:62;-1:-1:-1;;;26617:18:1;;;26610:41;26668:19;;75519:87:0;26286:407:1;75519:87:0;-1:-1:-1;;;;;;75624:19:0;;;;;;;;:12;:19;;;;;;;;:26;;;;;;;;;75402:256::o;48276:218::-;-1:-1:-1;;;;;48372:23:0;;30785:10;48372:23;48364:83;;;;-1:-1:-1;;;48364:83:0;;26900:2:1;48364:83:0;;;26882:21:1;26939:2;26919:18;;;26912:30;26978:34;26958:18;;;26951:62;-1:-1:-1;;;27029:18:1;;;27022:45;27084:19;;48364:83:0;26698:411:1;48364:83:0;48460:26;48472:4;48478:7;48460:11;:26::i;95194:487::-;95302:32;;;95294:88;;;;-1:-1:-1;;;95294:88:0;;27316:2:1;95294:88:0;;;27298:21:1;27355:2;27335:18;;;27328:30;27394:34;27374:18;;;27367:62;-1:-1:-1;;;27445:18:1;;;27438:41;27496:19;;95294:88:0;27114:407:1;95294:88:0;95401:30;30785:10;95429:1;95401:13;:30::i;:::-;95393:90;;;;-1:-1:-1;;;95393:90:0;;;;;;;:::i;:::-;95500:6;95496:178;95512:19;;;95496:178;;;95561:19;95568:8;;95577:1;95568:11;;;;;;;:::i;95561:19::-;95553:52;;;;-1:-1:-1;;;95553:52:0;;25353:2:1;95553:52:0;;;25335:21:1;25392:2;25372:18;;;25365:30;-1:-1:-1;;;25411:18:1;;;25404:50;25471:18;;95553:52:0;25151:344:1;95553:52:0;95653:6;;95660:1;95653:9;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;95622;:22;95632:8;;95641:1;95632:11;;;;;;;:::i;:::-;;;;;;;95622:22;;;;;;;;;;;:28;;;:40;;;;;;;;;;;;;;;;;;95533:3;;;;;:::i;:::-;;;;95496:178;;;;95194:487;;;;:::o;64633:185::-;64771:39;64788:4;64794:2;64798:7;64771:39;;;;;;;;;;;;:16;:39::i;88987:395::-;89053:9;;;;89052:10;89044:59;;;;-1:-1:-1;;;89044:59:0;;;;;;;:::i;:::-;30785:10;89122:16;89130:7;89122;:16::i;:::-;-1:-1:-1;;;;;89122:32:0;;89114:86;;;;-1:-1:-1;;;89114:86:0;;27728:2:1;89114:86:0;;;27710:21:1;27767:2;27747:18;;;27740:30;27806:34;27786:18;;;27779:62;-1:-1:-1;;;27857:18:1;;;27850:39;27906:19;;89114:86:0;27526:405:1;89114:86:0;89213:9;89225:21;89238:7;89225:12;:21::i;:::-;89257:15;;;;:9;:15;;;;;:22;;1083:19;;1101:1;1083:19;;;89257:15;-1:-1:-1;89304:11:0;:29;89316:16;89324:7;89316;:16::i;:::-;-1:-1:-1;;;;;89304:29:0;;;;;;;;;;;;;-1:-1:-1;89304:29:0;;;:43;;;;;;;;;;;;;;;;;89360:14;89339:7;89360:5;:14::i;86772:304::-;86855:30;30785:10;86883:1;86855:13;:30::i;:::-;86847:90;;;;-1:-1:-1;;;86847:90:0;;;;;;;:::i;:::-;86961:5;86958:111;;;86983:20;86994:3;86999;86983:10;:20::i;86958:111::-;87036:21;87048:3;87053;87036:11;:21::i;101321:102::-;101375:4;66816:16;;;:7;:16;;;;;;-1:-1:-1;;;;;66816:16:0;:30;;101399:16;66727:127;75924:233;75999:7;76035:30;75822:10;:17;;75734:113;76035:30;76027:5;:38;76019:95;;;;-1:-1:-1;;;76019:95:0;;28138:2:1;76019:95:0;;;28120:21:1;28177:2;28157:18;;;28150:30;28216:34;28196:18;;;28189:62;-1:-1:-1;;;28267:18:1;;;28260:42;28319:19;;76019:95:0;27936:408:1;76019:95:0;76132:10;76143:5;76132:17;;;;;;;;:::i;:::-;;;;;;;;;76125:24;;75924:233;;;:::o;100812:195::-;100882:30;30785:10;100910:1;100882:13;:30::i;:::-;100874:91;;;;-1:-1:-1;;;100874:91:0;;;;;;;:::i;:::-;100976:14;:23;100993:6;100976:14;:23;:::i;88119:161::-;88180:7;88240:15;;;:9;:15;;;;;:22;;;964:14;88207:20;;;;964:14;88207:65;;964:14;88207:65;:::i;87989:122::-;88047:4;88071:15;;;:9;:15;;;;;:22;;964:14;88071:32;872:114;61607:239;61679:7;61715:16;;;:7;:16;;;;;;-1:-1:-1;;;;;61715:16:0;;61742:73;;;;-1:-1:-1;;;61742:73:0;;30885:2:1;61742:73:0;;;30867:21:1;30924:2;30904:18;;;30897:30;30963:34;30943:18;;;30936:62;-1:-1:-1;;;31014:18:1;;;31007:39;31063:19;;61742:73:0;30683:405:1;97130:589:0;97197:16;97236:23;97262:17;97272:6;97262:9;:17::i;:::-;97236:43;;97290:25;97332:15;97318:30;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;97318:30:0;-1:-1:-1;97290:58:0;-1:-1:-1;97361:11:0;;;97416:246;97440:15;97436:1;:19;97416:246;;;97485:30;97505:6;97513:1;97485:19;:30::i;:::-;97536:14;;;;:9;:14;;;;;:20;;;97479:36;;-1:-1:-1;97536:20:0;;97532:117;;97598:3;97577:8;97586;97577:18;;;;;;;;:::i;:::-;;;;;;;;;;:24;97620:13;97632:1;97620:13;;:::i;:::-;;;97532:117;97457:3;;;;:::i;:::-;;;;97416:246;;;;97681:30;97692:8;97702;97681:10;:30::i;105324:236::-;105388:31;30785:10;105416:2;105388:13;:31::i;:::-;105380:91;;;;-1:-1:-1;;;105380:91:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;105492:16:0;;;;;;:6;:16;;;;;:23;;-1:-1:-1;;105492:23:0;105511:4;105492:23;;;105526:26;:14;1083:19;;1101:1;1083:19;;;994:127;105526:26;105324:236;:::o;61337:208::-;61409:7;-1:-1:-1;;;;;61437:19:0;;61429:74;;;;-1:-1:-1;;;61429:74:0;;31295:2:1;61429:74:0;;;31277:21:1;31334:2;31314:18;;;31307:30;31373:34;31353:18;;;31346:62;-1:-1:-1;;;31424:18:1;;;31417:40;31474:19;;61429:74:0;31093:406:1;61429:74:0;-1:-1:-1;;;;;;61521:16:0;;;;;:9;:16;;;;;;;61337:208::o;105568:331::-;105628:30;30785:10;105656:1;105628:13;:30::i;:::-;105620:90;;;;-1:-1:-1;;;105620:90:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;105723:12:0;;105738:5;105723:12;;;:6;:12;;;;;:20;;-1:-1:-1;;105723:20:0;;;105754:26;:14;:24;:26::i;97727:183::-;97787:7;97815:15;97822:7;97815:6;:15::i;:::-;97807:54;;;;-1:-1:-1;;;97807:54:0;;31706:2:1;97807:54:0;;;31688:21:1;31745:2;31725:18;;;31718:30;31784:28;31764:18;;;31757:56;31830:18;;97807:54:0;31504:350:1;97807:54:0;-1:-1:-1;97879:18:0;;;;:9;:18;;;;;:23;;97727:183::o;88288:150::-;88348:7;88398:15;;;:9;:15;;;;;:22;;;964:14;88375:20;;:55;;964:14;88375:55;:::i;96081:232::-;96143:15;96160:9;96190:15;96197:7;96190:6;:15::i;:::-;96182:54;;;;-1:-1:-1;;;96182:54:0;;32061:2:1;96182:54:0;;;32043:21:1;32100:2;32080:18;;;32073:30;32139:28;32119:18;;;32112:56;32185:18;;96182:54:0;31859:350:1;96182:54:0;-1:-1:-1;;96255:18:0;;;;:9;:18;;;;;:23;;96280:24;;;;;96255:23;;96280:24;;;;;96081:232::o;91244:429::-;91331:9;;;;91330:10;91322:59;;;;-1:-1:-1;;;91322:59:0;;;;;;;:::i;:::-;91400:34;83284:24;30785:10;45295:147;:::i;91400:34::-;91392:79;;;;-1:-1:-1;;;91392:79:0;;32416:2:1;91392:79:0;;;32398:21:1;;;32435:18;;;32428:30;32494:34;32474:18;;;32467:62;32546:18;;91392:79:0;32214:356:1;91392:79:0;91489:6;91485:181;91501:19;;;91485:181;;;91550:24;91562:8;;91571:1;91562:11;;;;;;;:::i;91550:24::-;91542:75;;;;-1:-1:-1;;;91542:75:0;;21779:2:1;91542:75:0;;;21761:21:1;21818:2;21798:18;;;21791:30;21857:34;21837:18;;;21830:62;-1:-1:-1;;;21908:18:1;;;21901:36;21954:19;;91542:75:0;21577:402:1;91542:75:0;91632:22;91637:3;91642:8;;91651:1;91642:11;;;;;;;:::i;91632:22::-;91522:3;;;;:::i;:::-;;;;91485:181;;;;91244:429;;;:::o;51785:153::-;51875:7;51902:18;;;:12;:18;;;;;:28;;51924:5;51902:21;:28::i;:::-;51895:35;51785:153;-1:-1:-1;;;51785:153:0:o;104176:522::-;104255:24;30785:10;104266:12;30705:98;104255:24;104247:54;;;;-1:-1:-1;;;104247:54:0;;22603:2:1;104247:54:0;;;22585:21:1;22642:2;22622:18;;;22615:30;-1:-1:-1;;;22661:18:1;;;22654:47;22718:18;;104247:54:0;22401:341:1;104247:54:0;-1:-1:-1;;;;;103792:12:0;;103768:4;103792:12;;;:6;:12;;;;;;;;104312:63;;;;-1:-1:-1;;;104312:63:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;104394:21:0;;30785:10;104394:21;104386:63;;;;-1:-1:-1;;;104386:63:0;;32777:2:1;104386:63:0;;;32759:21:1;32816:2;32796:18;;;32789:30;32855:31;32835:18;;;32828:59;32904:18;;104386:63:0;32575:353:1;104386:63:0;-1:-1:-1;;;;;104468:23:0;;;;;;:16;:23;;;;;:36;-1:-1:-1;;;104468:36:0;;;;:41;104460:110;;;;-1:-1:-1;;;104460:110:0;;33135:2:1;104460:110:0;;;33117:21:1;33174:2;33154:18;;;33147:30;33213:34;33193:18;;;33186:62;33284:26;33264:18;;;33257:54;33328:19;;104460:110:0;32933:420:1;104460:110:0;-1:-1:-1;;;;;104581:23:0;;;;;:16;:23;;;;;:45;;-1:-1:-1;;;;;;104581:45:0;;;;;-1:-1:-1;;;104581:45:0;104637:53;;;;-1:-1:-1;;;;;;104637:53:0;;;;;;;30785:10;104637:53;;;104176:522::o;96321:444::-;96385:13;96419:15;96426:7;96419:6;:15::i;:::-;96411:54;;;;-1:-1:-1;;;96411:54:0;;32061:2:1;96411:54:0;;;32043:21:1;32100:2;32080:18;;;32073:30;32139:28;32119:18;;;32112:56;32185:18;;96411:54:0;31859:350:1;96411:54:0;96478:9;96490:21;96503:7;96490:12;:21::i;:::-;96522:20;96546:18;;;:9;:18;;;;;:31;;;96478:33;;-1:-1:-1;96522:20:0;96545:44;;:42;:44::i;:::-;96600:18;96622:15;;;:9;:15;;;;;:20;96522:67;;-1:-1:-1;96600:18:0;96621:33;;:31;:33::i;:::-;96600:54;;96667:20;96714:6;96727:4;96697:35;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;96697:35:0;;;;;;;;;;96321:444;-1:-1:-1;;;;;;96321:444:0:o;62082:104::-;62138:13;62171:7;62164:14;;;;;:::i;87864:117::-;87919:4;87943:15;;;:9;:15;;;;;:20;;964:14;87943:30;872:114;89390:159;89461:6;89457:85;89473:19;;;89457:85;;;89513:17;89518:8;;89527:1;89518:11;;;;;;;:::i;:::-;;;;;;;89513:4;:17::i;:::-;89494:3;;;;:::i;:::-;;;;89457:85;;63766:155;63861:52;30785:10;63894:8;63904;63861:18;:52::i;86257:240::-;86365:13;86360:130;86384:23;;;86360:130;;;86433:45;86450:5;86457:3;86462:8;;86471:5;86462:15;;;;;;;:::i;:::-;;;;;;;86433:16;:45::i;:::-;86409:7;;;;:::i;:::-;;;;86360:130;;64889:328;65064:41;30785:10;65097:7;65064:18;:41::i;:::-;65056:103;;;;-1:-1:-1;;;65056:103:0;;23757:2:1;65056:103:0;;;23739:21:1;23796:2;23776:18;;;23769:30;23835:34;23815:18;;;23808:62;-1:-1:-1;;;23886:18:1;;;23879:47;23943:19;;65056:103:0;23555:413:1;65056:103:0;65170:39;65184:4;65190:2;65194:7;65203:5;65170:13;:39::i;100205:599::-;66792:4;66816:16;;;:7;:16;;;;;;100278:13;;-1:-1:-1;;;;;66816:16:0;100304:76;;;;-1:-1:-1;;;100304:76:0;;34179:2:1;100304:76:0;;;34161:21:1;34218:2;34198:18;;;34191:30;34257:34;34237:18;;;34230:62;-1:-1:-1;;;34308:18:1;;;34301:45;34363:19;;100304:76:0;33977:411:1;100304:76:0;100393:24;100420:18;;;:9;:18;;;;;:23;:34;;:32;:34::i;:::-;100393:61;;100465:19;100487:10;:8;:10::i;:::-;100547:18;;;;:9;:18;;;;;:24;;;100465:32;;-1:-1:-1;100510:21:0;;100547:24;;100544:172;;;100622:10;100605:37;;;;;;;;:::i;:::-;;;;;;;;;;;;;100588:55;;100544:172;;;-1:-1:-1;100693:10:0;100544:172;100771:5;100778:7;100754:41;;;;;;;;;:::i;:::-;;;;;;;;;;;;;100740:56;;;;;100205:599;;;:::o;52112:142::-;52192:7;52219:18;;;:12;:18;;;;;:27;;:25;:27::i;95961:112::-;96025:4;96049:10;96060:4;96049:16;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;95961:112;-1:-1:-1;;95961:112:0:o;96773:349::-;96831:16;96860:23;96886:17;96896:6;96886:9;:17::i;:::-;96860:43;;96914:25;96956:15;96942:30;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;96942:30:0;;96914:58;;96988:9;96983:103;97007:15;97003:1;:19;96983:103;;;97056:30;97076:6;97084:1;97056:19;:30::i;:::-;97042:8;97051:1;97042:11;;;;;;;;:::i;:::-;;;;;;;;;;:44;97024:3;;;;:::i;:::-;;;;96983:103;;;-1:-1:-1;97106:8:0;96773:349;-1:-1:-1;;;96773:349:0:o;47620:149::-;46909:7;46936:12;;;:6;:12;;;;;:22;;;44891:16;44902:4;44891:10;:16::i;:::-;47735:26:::1;47747:4;47753:7;47735:11;:26::i;105910:103::-:0;105958:4;105981:24;:14;964;;872:114;105981:24;105974:31;;105910:103;:::o;101727:303::-;-1:-1:-1;;;;;101810:22:0;;101802:82;;;;-1:-1:-1;;;101802:82:0;;35966:2:1;101802:82:0;;;35948:21:1;36005:2;35985:18;;;35978:30;36044:34;36024:18;;;36017:62;-1:-1:-1;;;36095:18:1;;;36088:45;36150:19;;101802:82:0;35764:411:1;101802:82:0;101903:30;30785:10;101931:1;101903:13;:30::i;:::-;101895:90;;;;-1:-1:-1;;;101895:90:0;;;;;;;:::i;:::-;101996:17;:26;;-1:-1:-1;;;;;;101996:26:0;-1:-1:-1;;;;;101996:26:0;;;;;;;;;;101727:303::o;103174:286::-;-1:-1:-1;;;;;103245:20:0;;103237:78;;;;-1:-1:-1;;;103237:78:0;;36382:2:1;103237:78:0;;;36364:21:1;36421:2;36401:18;;;36394:30;36460:34;36440:18;;;36433:62;-1:-1:-1;;;36511:18:1;;;36504:43;36564:19;;103237:78:0;36180:409:1;103237:78:0;103334:31;30785:10;103362:2;103334:13;:31::i;:::-;103326:92;;;;-1:-1:-1;;;103326:92:0;;;;;;;:::i;:::-;103429:14;:23;;-1:-1:-1;;;;;;103429:23:0;-1:-1:-1;;;;;103429:23:0;;;;;;;;;;103174:286::o;102744:422::-;102971:14;;102852:15;;-1:-1:-1;;;;;102971:14:0;;;102958:27;;;;102954:71;;-1:-1:-1;103009:4:0;103002:11;;102954:71;-1:-1:-1;;;;;64113:25:0;;;64089:4;64113:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;103117:41;63992:164;87382:359;87480:30;30785:10;87508:1;87480:13;:30::i;:::-;87472:70;;;;-1:-1:-1;;;87472:70:0;;26132:2:1;87472:70:0;;;26114:21:1;26171:2;26151:18;;;26144:30;26210:29;26190:18;;;26183:57;26257:18;;87472:70:0;25930:351:1;87472:70:0;87561:29;;;87553:66;;;;-1:-1:-1;;;87553:66:0;;36796:2:1;87553:66:0;;;36778:21:1;36835:2;36815:18;;;36808:30;36874:26;36854:18;;;36847:54;36918:18;;87553:66:0;36594:348:1;87553:66:0;87636:6;87632:102;87648:16;;;87632:102;;;87713:6;;87720:1;87713:9;;;;;;;:::i;:::-;;;;;;;87686;:19;87696:5;;87702:1;87696:8;;;;;;;:::i;:::-;;;;;;;;;;87686:19;;-1:-1:-1;87686:19:0;;;;;;;;-1:-1:-1;87686:19:0;:36;87666:3;;;;:::i;:::-;;;;87632:102;;994:127;1083:19;;1101:1;1083:19;;;994:127::o;50972:214::-;51057:4;-1:-1:-1;;;;;;51081:57:0;;-1:-1:-1;;;51081:57:0;;:97;;;51142:36;51166:11;51142:23;:36::i;70873:174::-;70948:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;70948:29:0;-1:-1:-1;;;;;70948:29:0;;;;;;;;:24;;71002:23;70948:24;71002:14;:23::i;:::-;-1:-1:-1;;;;;70993:46:0;;;;;;;;;;;70873:174;;:::o;69373:420::-;69433:13;69449:23;69464:7;69449:14;:23::i;:::-;69433:39;;69485:48;69506:5;69521:1;69525:7;69485:20;:48::i;:::-;69574:29;69591:1;69595:7;69574:8;:29::i;:::-;-1:-1:-1;;;;;69616:16:0;;;;;;:9;:16;;;;;:21;;69636:1;;69616:16;:21;;69636:1;;69616:21;:::i;:::-;;;;-1:-1:-1;;69655:16:0;;;;:7;:16;;;;;;69648:23;;-1:-1:-1;;;;;;69648:23:0;;;69689:36;69663:7;;69655:16;-1:-1:-1;;;;;69689:36:0;;;;;69655:16;;69689:36;85932:38;85800:178;:::o;98934:273::-;99014:16;99043:23;99080:4;99069:16;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;99069:16:0;;99043:42;;99100:9;99096:80;99119:4;99115:1;:8;99096:80;;;99156:5;99162:1;99156:8;;;;;;;;:::i;:::-;;;;;;;99144:6;99151:1;99144:9;;;;;;;;:::i;:::-;;;;;;;;;;:20;99125:3;;;;:::i;:::-;;;;99096:80;;103820:348;-1:-1:-1;;;;;103792:12:0;;103888:4;103792:12;;;:6;:12;;;;;;;;103905:62;;;;-1:-1:-1;;;103905:62:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;104013:22:0;;103978:13;104013:22;;;:16;:22;;;;;:35;:45;;;;-1:-1:-1;;;104013:35:0;;;;:45;104010:125;;-1:-1:-1;104086:4:0;104105:18;104118:4;104105:12;:18::i;92573:753::-;92666:13;92694:21;92726:17;92760:6;92756:195;92776:8;:15;92772:1;:19;92756:195;;;92841:29;92858:8;92867:1;92858:11;;;;;;;;:::i;:::-;;;;;;;92841:16;:29::i;:::-;92824:51;;;;;;;;:::i;:::-;;;;;;;;;;;;;92811:65;;92925:7;92934:3;92908:30;;;;;;;;;:::i;:::-;;;;;;;;;;;;;92891:48;;92792:3;;;;;:::i;:::-;;;;92756:195;;;;92967:6;92963:329;92983:5;:12;92979:1;:16;92963:329;;;93038:1;93025:5;:12;:14;;;;:::i;:::-;93020:1;:19;93017:264;;93094:7;93103:5;93109:1;93103:8;;;;;;;;:::i;:::-;;;;;;;93077:35;;;;;;;;;:::i;:::-;;;;;;;;;;;;;93060:53;;93017:264;;;93184:5;93190:1;93184:8;;;;;;;;:::i;:::-;;;;;;;93167:30;;;;;;;;:::i;:::-;;;;;;;;;;;;;93154:44;;93251:7;93260:3;93234:30;;;;;;;;;:::i;:::-;;;;;;;;;;;;;93217:48;;93017:264;92997:3;;;;:::i;:::-;;;;92963:329;;;-1:-1:-1;93311:7:0;;92573:753;-1:-1:-1;;;;92573:753:0:o;93358:233::-;93448:4;93484:99;93539:7;93522:25;;;;;;;;:::i;:::-;;;;;;;;;;;;;93512:36;;;;;;93563:9;93484:13;:99::i;:::-;93472:8;;;;;-1:-1:-1;;;;;93472:8:0;;;:111;;;;-1:-1:-1;93358:233:0;;;;:::o;93980:496::-;94037:4;94078:1;94063:5;:12;:16;94055:80;;;;-1:-1:-1;;;94055:80:0;;38068:2:1;94055:80:0;;;38050:21:1;38107:2;38087:18;;;38080:30;38146:34;38126:18;;;38119:62;38217:21;38197:18;;;38190:49;38256:19;;94055:80:0;37866:415:1;94055:80:0;94146:14;94179:6;94202:229;94209:9;94208:10;:30;;;;;94226:5;:12;94222:1;:16;94208:30;94202:229;;;94258:10;94269:5;94275:1;94269:8;;;;;;;;:::i;:::-;;;;;;;94258:20;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;94255:144;;;94311:4;94299:16;;94255:144;;;94379:4;94356:10;94367:5;94373:1;94367:8;;;;;;;;:::i;:::-;;;;;;;94356:20;;;;;;:::i;:::-;;;;;;;;;;;;;;:27;;;;;-1:-1:-1;;94356:27:0;;;;;;;;;94255:144;94413:6;94418:1;94413:6;;:::i;:::-;;;94202:229;;;-1:-1:-1;94459:9:0;93980:496;-1:-1:-1;;93980:496:0:o;88488:246::-;88543:4;88633:15;;;:9;:15;;;;;:20;;88543:4;;88600:30;;:20;;964:14;;872:114;88600:30;:53;88597:101;;;-1:-1:-1;88682:4:0;88717:9;88488:246;-1:-1:-1;;88488:246:0:o;91681:561::-;91789:16;;;;:9;:16;;;;;:33;;:21;;1083:19;;1101:1;1083:19;;;994:127;91789:33;91868:27;:15;1083:19;;1101:1;1083:19;;;994:127;91868:27;92000:16;;;;:9;:16;;;;;:21;;964:14;91948:9;:36;91958:25;:15;964:14;;872:114;91958:25;91948:36;;;;;;;;;;;:49;;:83;;;;92086:5;92042:9;:36;92052:25;:15;964:14;;872:114;92052:25;92042:36;;;;;;;;;;;:41;;:49;;;;92147:5;92102:9;:36;92112:25;:15;964:14;;872:114;92112:25;92102:36;;;;;;;;;;;-1:-1:-1;92102:36:0;:42;;:50;;-1:-1:-1;;92102:50:0;;;;;;;;;;92208:15;964:14;92193:41;;92203:3;;92193:9;:41::i;67021:348::-;67114:4;66816:16;;;:7;:16;;;;;;-1:-1:-1;;;;;66816:16:0;67131:73;;;;-1:-1:-1;;;67131:73:0;;38488:2:1;67131:73:0;;;38470:21:1;38527:2;38507:18;;;38500:30;38566:34;38546:18;;;38539:62;-1:-1:-1;;;38617:18:1;;;38610:42;38669:19;;67131:73:0;38286:408:1;67131:73:0;67215:13;67231:23;67246:7;67231:14;:23::i;:::-;67215:39;;67284:5;-1:-1:-1;;;;;67273:16:0;:7;-1:-1:-1;;;;;67273:16:0;;:52;;;;67293:32;67310:5;67317:7;67293:16;:32::i;:::-;67273:87;;;;67353:7;-1:-1:-1;;;;;67329:31:0;:20;67341:7;67329:11;:20::i;:::-;-1:-1:-1;;;;;67329:31:0;;67273:87;67265:96;67021:348;-1:-1:-1;;;;67021:348:0:o;70130:625::-;70289:4;-1:-1:-1;;;;;70262:31:0;:23;70277:7;70262:14;:23::i;:::-;-1:-1:-1;;;;;70262:31:0;;70254:81;;;;-1:-1:-1;;;70254:81:0;;38901:2:1;70254:81:0;;;38883:21:1;38940:2;38920:18;;;38913:30;38979:34;38959:18;;;38952:62;-1:-1:-1;;;39030:18:1;;;39023:35;39075:19;;70254:81:0;38699:401:1;70254:81:0;-1:-1:-1;;;;;70354:16:0;;70346:65;;;;-1:-1:-1;;;70346:65:0;;39307:2:1;70346:65:0;;;39289:21:1;39346:2;39326:18;;;39319:30;39385:34;39365:18;;;39358:62;-1:-1:-1;;;39436:18:1;;;39429:34;39480:19;;70346:65:0;39105:400:1;70346:65:0;70424:39;70445:4;70451:2;70455:7;70424:20;:39::i;:::-;70528:29;70545:1;70549:7;70528:8;:29::i;:::-;-1:-1:-1;;;;;70570:15:0;;;;;;:9;:15;;;;;:20;;70589:1;;70570:15;:20;;70589:1;;70570:20;:::i;:::-;;;;-1:-1:-1;;;;;;;70601:13:0;;;;;;:9;:13;;;;;:18;;70618:1;;70601:13;:18;;70618:1;;70601:18;:::i;:::-;;;;-1:-1:-1;;70630:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;70630:21:0;-1:-1:-1;;;;;70630:21:0;;;;;;;;;70669:27;;70630:16;;70669:27;;;;;;;63066:341;62996:411;;:::o;45746:105::-;45813:30;45824:4;30785:10;45813;:30::i;52347:169::-;52435:31;52452:4;52458:7;52435:16;:31::i;:::-;52477:18;;;;:12;:18;;;;;:31;;52500:7;52477:22;:31::i;52610:174::-;52699:32;52717:4;52723:7;52699:17;:32::i;:::-;52742:18;;;;:12;:18;;;;;:34;;52768:7;52742:25;:34::i;1129:235::-;1209:14;;1242:9;1234:49;;;;-1:-1:-1;;;1234:49:0;;39712:2:1;1234:49:0;;;39694:21:1;39751:2;39731:18;;;39724:30;39790:29;39770:18;;;39763:57;39837:18;;1234:49:0;39510:351:1;1234:49:0;-1:-1:-1;;1336:9:0;1319:26;;1129:235::o;10648:158::-;10722:7;10773:22;10777:3;10789:5;10773:3;:22::i;18733:723::-;18789:13;19010:5;19019:1;19010:10;19006:53;;-1:-1:-1;;19037:10:0;;;;;;;;;;;;-1:-1:-1;;;19037:10:0;;;;;18733:723::o;19006:53::-;19084:5;19069:12;19125:78;19132:9;;19125:78;;19158:8;;;;:::i;:::-;;-1:-1:-1;19181:10:0;;-1:-1:-1;19189:2:0;19181:10;;:::i;:::-;;;19125:78;;;19213:19;19245:6;19235:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;19235:17:0;;19213:39;;19263:154;19270:10;;19263:154;;19297:11;19307:1;19297:11;;:::i;:::-;;-1:-1:-1;19366:10:0;19374:2;19366:5;:10;:::i;:::-;19353:24;;:2;:24;:::i;:::-;19340:39;;19323:6;19330;19323:14;;;;;;;;:::i;:::-;;;;:56;-1:-1:-1;;;;;19323:56:0;;;;;;;;-1:-1:-1;19394:11:0;19403:2;19394:11;;:::i;:::-;;;19263:154;;71189:315;71344:8;-1:-1:-1;;;;;71335:17:0;:5;-1:-1:-1;;;;;71335:17:0;;71327:55;;;;-1:-1:-1;;;71327:55:0;;40185:2:1;71327:55:0;;;40167:21:1;40224:2;40204:18;;;40197:30;40263:27;40243:18;;;40236:55;40308:18;;71327:55:0;39983:349:1;71327:55:0;-1:-1:-1;;;;;71393:25:0;;;;;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;:46;;-1:-1:-1;;71393:46:0;;;;;;;;;;71455:41;;540::1;;;71455::0;;513:18:1;71455:41:0;;;;;;;71189:315;;;:::o;66099:::-;66256:28;66266:4;66272:2;66276:7;66256:9;:28::i;:::-;66303:48;66326:4;66332:2;66336:7;66345:5;66303:22;:48::i;:::-;66295:111;;;;-1:-1:-1;;;66295:111:0;;;;;;;:::i;100082:115::-;100142:13;100175:14;100168:21;;;;;:::i;10177:117::-;10240:7;10267:19;10275:3;5661:18;;5578:109;44999:204;45084:4;-1:-1:-1;;;;;;45108:47:0;;-1:-1:-1;;;45108:47:0;;:87;;;45159:36;45183:11;45159:23;:36::i;76770:589::-;-1:-1:-1;;;;;76976:18:0;;76972:187;;77011:40;77043:7;78186:10;:17;;78159:24;;;;:15;:24;;;;;:44;;;78214:24;;;;;;;;;;;;78082:164;77011:40;76972:187;;;77081:2;-1:-1:-1;;;;;77073:10:0;:4;-1:-1:-1;;;;;77073:10:0;;77069:90;;77100:47;77133:4;77139:7;77100:32;:47::i;:::-;-1:-1:-1;;;;;77173:16:0;;77169:183;;77206:45;77243:7;77206:36;:45::i;77169:183::-;77279:4;-1:-1:-1;;;;;77273:10:0;:2;-1:-1:-1;;;;;77273:10:0;;77269:83;;77300:40;77328:2;77332:7;77300:27;:40::i;24909:231::-;24987:7;25008:17;25027:18;25049:27;25060:4;25066:9;25049:10;:27::i;:::-;25007:69;;;;25087:18;25099:5;25087:11;:18::i;67711:110::-;67787:26;67797:2;67801:7;67787:26;;;;;;;;;;;;:9;:26::i;46141:505::-;45381:4;45405:12;;;:6;:12;;;;;;;;-1:-1:-1;;;;;45405:29:0;;;;;;;;;;;;46225:414;;46418:41;46446:7;-1:-1:-1;;;;;46418:41:0;46456:2;46418:19;:41::i;:::-;46532:38;46560:4;46567:2;46532:19;:38::i;:::-;46323:270;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;46323:270:0;;;;;;;;;;-1:-1:-1;;;46269:358:0;;;;;;;:::i;49777:238::-;45381:4;45405:12;;;:6;:12;;;;;;;;-1:-1:-1;;;;;45405:29:0;;;;;;;;;;;;49856:152;;49900:12;;;;:6;:12;;;;;;;;-1:-1:-1;;;;;49900:29:0;;;;;;;;;:36;;-1:-1:-1;;49900:36:0;49932:4;49900:36;;;49983:12;30785:10;;30705:98;49983:12;-1:-1:-1;;;;;49956:40:0;49974:7;-1:-1:-1;;;;;49956:40:0;49968:4;49956:40;;;;;;;;;;49777:238;;:::o;9352:152::-;9422:4;9446:50;9451:3;-1:-1:-1;;;;;9471:23:0;;9446:4;:50::i;50147:239::-;45381:4;45405:12;;;:6;:12;;;;;;;;-1:-1:-1;;;;;45405:29:0;;;;;;;;;;;;50227:152;;;50302:5;50270:12;;;:6;:12;;;;;;;;-1:-1:-1;;;;;50270:29:0;;;;;;;;;;:37;;-1:-1:-1;;50270:37:0;;;50327:40;30785:10;;50270:12;;50327:40;;50302:5;50327:40;50147:239;;:::o;9680:158::-;9753:4;9777:53;9785:3;-1:-1:-1;;;;;9805:23:0;;9777:7;:53::i;6041:120::-;6108:7;6135:3;:11;;6147:5;6135:18;;;;;;;;:::i;:::-;;;;;;;;;6128:25;;6041:120;;;;:::o;72069:799::-;72224:4;-1:-1:-1;;;;;72245:13:0;;32447:19;:23;72241:620;;72281:72;;-1:-1:-1;;;72281:72:0;;-1:-1:-1;;;;;72281:36:0;;;;;:72;;30785:10;;72332:4;;72338:7;;72347:5;;72281:72;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;72281:72:0;;;;;;;;-1:-1:-1;;72281:72:0;;;;;;;;;;;;:::i;:::-;;;72277:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;72523:6;:13;72540:1;72523:18;72519:272;;72566:60;;-1:-1:-1;;;72566:60:0;;;;;;;:::i;72519:272::-;72741:6;72735:13;72726:6;72722:2;72718:15;72711:38;72277:529;-1:-1:-1;;;;;;72404:51:0;-1:-1:-1;;;72404:51:0;;-1:-1:-1;72397:58:0;;72241:620;-1:-1:-1;72845:4:0;72069:799;;;;;;:::o;75094:224::-;75196:4;-1:-1:-1;;;;;;75220:50:0;;-1:-1:-1;;;75220:50:0;;:90;;;75274:36;75298:11;75274:23;:36::i;78873:988::-;79139:22;79189:1;79164:22;79181:4;79164:16;:22::i;:::-;:26;;;;:::i;:::-;79201:18;79222:26;;;:17;:26;;;;;;79139:51;;-1:-1:-1;79355:28:0;;;79351:328;;-1:-1:-1;;;;;79422:18:0;;79400:19;79422:18;;;:12;:18;;;;;;;;:34;;;;;;;;;79473:30;;;;;;:44;;;79590:30;;:17;:30;;;;;:43;;;79351:328;-1:-1:-1;79775:26:0;;;;:17;:26;;;;;;;;79768:33;;;-1:-1:-1;;;;;79819:18:0;;;;;:12;:18;;;;;:34;;;;;;;79812:41;78873:988::o;80156:1079::-;80434:10;:17;80409:22;;80434:21;;80454:1;;80434:21;:::i;:::-;80466:18;80487:24;;;:15;:24;;;;;;80860:10;:26;;80409:46;;-1:-1:-1;80487:24:0;;80409:46;;80860:26;;;;;;:::i;:::-;;;;;;;;;80838:48;;80924:11;80899:10;80910;80899:22;;;;;;;;:::i;:::-;;;;;;;;;;;;:36;;;;81004:28;;;:15;:28;;;;;;;:41;;;81176:24;;;;;81169:31;81211:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;80227:1008;;;80156:1079;:::o;77660:221::-;77745:14;77762:20;77779:2;77762:16;:20::i;:::-;-1:-1:-1;;;;;77793:16:0;;;;;;;:12;:16;;;;;;;;:24;;;;;;;;:34;;;77838:26;;;:17;:26;;;;;;:35;;;;-1:-1:-1;77660:221:0:o;22799:1308::-;22880:7;22889:12;23114:9;:16;23134:2;23114:22;23110:990;;23410:4;23395:20;;23389:27;23460:4;23445:20;;23439:27;23518:4;23503:20;;23497:27;23153:9;23489:36;23561:25;23572:4;23489:36;23389:27;23439;23561:10;:25::i;:::-;23554:32;;;;;;;;;23110:990;23608:9;:16;23628:2;23608:22;23604:496;;23883:4;23868:20;;23862:27;23934:4;23919:20;;23913:27;23976:23;23987:4;23862:27;23913;23976:10;:23::i;:::-;23969:30;;;;;;;;23604:496;-1:-1:-1;24048:1:0;;-1:-1:-1;24052:35:0;24032:56;;21070:643;21148:20;21139:5;:29;;;;;;;;:::i;:::-;;21135:571;;21070:643;:::o;21135:571::-;21246:29;21237:5;:38;;;;;;;;:::i;:::-;;21233:473;;21292:34;;-1:-1:-1;;;21292:34:0;;42784:2:1;21292:34:0;;;42766:21:1;42823:2;42803:18;;;42796:30;42862:26;42842:18;;;42835:54;42906:18;;21292:34:0;42582:348:1;21233:473:0;21357:35;21348:5;:44;;;;;;;;:::i;:::-;;21344:362;;21409:41;;-1:-1:-1;;;21409:41:0;;43137:2:1;21409:41:0;;;43119:21:1;43176:2;43156:18;;;43149:30;43215:33;43195:18;;;43188:61;43266:18;;21409:41:0;42935:355:1;21344:362:0;21481:30;21472:5;:39;;;;;;;;:::i;:::-;;21468:238;;21528:44;;-1:-1:-1;;;21528:44:0;;43497:2:1;21528:44:0;;;43479:21:1;43536:2;43516:18;;;43509:30;43575:34;43555:18;;;43548:62;-1:-1:-1;;;43626:18:1;;;43619:32;43668:19;;21528:44:0;43295:398:1;21468:238:0;21603:30;21594:5;:39;;;;;;;;:::i;:::-;;21590:116;;21650:44;;-1:-1:-1;;;21650:44:0;;43900:2:1;21650:44:0;;;43882:21:1;43939:2;43919:18;;;43912:30;43978:34;43958:18;;;43951:62;-1:-1:-1;;;44029:18:1;;;44022:32;44071:19;;21650:44:0;43698:398:1;68048:321:0;68178:18;68184:2;68188:7;68178:5;:18::i;:::-;68229:54;68260:1;68264:2;68268:7;68277:5;68229:22;:54::i;:::-;68207:154;;;;-1:-1:-1;;;68207:154:0;;;;;;;:::i;20034:451::-;20109:13;20135:19;20167:10;20171:6;20167:1;:10;:::i;:::-;:14;;20180:1;20167:14;:::i;:::-;20157:25;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;20157:25:0;;20135:47;;-1:-1:-1;;;20193:6:0;20200:1;20193:9;;;;;;;;:::i;:::-;;;;:15;-1:-1:-1;;;;;20193:15:0;;;;;;;;;-1:-1:-1;;;20219:6:0;20226:1;20219:9;;;;;;;;:::i;:::-;;;;:15;-1:-1:-1;;;;;20219:15:0;;;;;;;;-1:-1:-1;20250:9:0;20262:10;20266:6;20262:1;:10;:::i;:::-;:14;;20275:1;20262:14;:::i;:::-;20250:26;;20245:135;20282:1;20278;:5;20245:135;;;-1:-1:-1;;;20330:5:0;20338:3;20330:11;20317:25;;;;;;;:::i;:::-;;;;20305:6;20312:1;20305:9;;;;;;;;:::i;:::-;;;;:37;-1:-1:-1;;;;;20305:37:0;;;;;;;;-1:-1:-1;20367:1:0;20357:11;;;;;20285:3;;;:::i;:::-;;;20245:135;;;-1:-1:-1;20398:10:0;;20390:55;;;;-1:-1:-1;;;20390:55:0;;44444:2:1;20390:55:0;;;44426:21:1;;;44463:18;;;44456:30;44522:34;44502:18;;;44495:62;44574:18;;20390:55:0;44242:356:1;3267:414:0;3330:4;5460:19;;;:12;;;:19;;;;;;3347:327;;-1:-1:-1;3390:23:0;;;;;;;;:11;:23;;;;;;;;;;;;;3573:18;;3551:19;;;:12;;;:19;;;;;;:40;;;;3606:11;;3347:327;-1:-1:-1;3657:5:0;3650:12;;3857:1420;3923:4;4062:19;;;:12;;;:19;;;;;;4098:15;;4094:1176;;4473:21;4497:14;4510:1;4497:10;:14;:::i;:::-;4546:18;;4473:38;;-1:-1:-1;4526:17:0;;4546:22;;4567:1;;4546:22;:::i;:::-;4526:42;;4602:13;4589:9;:26;4585:405;;4636:17;4656:3;:11;;4668:9;4656:22;;;;;;;;:::i;:::-;;;;;;;;;4636:42;;4810:9;4781:3;:11;;4793:13;4781:26;;;;;;;;:::i;:::-;;;;;;;;;;;;:38;;;;4895:23;;;:12;;;:23;;;;;:36;;;4585:405;5071:17;;:3;;:17;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;5166:3;:12;;:19;5179:5;5166:19;;;;;;;;;;;5159:26;;;5209:4;5202:11;;;;;;;4094:1176;5253:5;5246:12;;;;;60968:305;61070:4;-1:-1:-1;;;;;;61107:40:0;;-1:-1:-1;;;61107:40:0;;:105;;-1:-1:-1;;;;;;;61164:48:0;;-1:-1:-1;;;61164:48:0;61107:105;:158;;;-1:-1:-1;;;;;;;;;;42367:40:0;;;61229:36;42258:157;26361:1632;26492:7;;27426:66;27413:79;;27409:163;;;-1:-1:-1;27525:1:0;;-1:-1:-1;27529:30:0;27509:51;;27409:163;27586:1;:7;;27591:2;27586:7;;:18;;;;;27597:1;:7;;27602:2;27597:7;;27586:18;27582:102;;;-1:-1:-1;27637:1:0;;-1:-1:-1;27641:30:0;27621:51;;27582:102;27798:24;;;27781:14;27798:24;;;;;;;;;44830:25:1;;;44903:4;44891:17;;44871:18;;;44864:45;;;;44925:18;;;44918:34;;;44968:18;;;44961:34;;;27798:24:0;;44802:19:1;;27798:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;27798:24:0;;-1:-1:-1;;27798:24:0;;;-1:-1:-1;;;;;;;27837:20:0;;27833:103;;27890:1;27894:29;27874:50;;;;;;;27833:103;27956:6;-1:-1:-1;27964:20:0;;-1:-1:-1;26361:1632:0;;;;;;;;:::o;25403:344::-;25517:7;;-1:-1:-1;;;;;25563:80:0;;25517:7;25670:25;25686:3;25671:18;;;25693:2;25670:25;:::i;:::-;25654:42;;25714:25;25725:4;25731:1;25734;25737;25714:10;:25::i;:::-;25707:32;;;;;;25403:344;;;;;;:::o;68705:439::-;-1:-1:-1;;;;;68785:16:0;;68777:61;;;;-1:-1:-1;;;68777:61:0;;45208:2:1;68777:61:0;;;45190:21:1;;;45227:18;;;45220:30;45286:34;45266:18;;;45259:62;45338:18;;68777:61:0;45006:356:1;68777:61:0;66792:4;66816:16;;;:7;:16;;;;;;-1:-1:-1;;;;;66816:16:0;:30;68849:58;;;;-1:-1:-1;;;68849:58:0;;45569:2:1;68849:58:0;;;45551:21:1;45608:2;45588:18;;;45581:30;45647;45627:18;;;45620:58;45695:18;;68849:58:0;45367:352:1;68849:58:0;68920:45;68949:1;68953:2;68957:7;68920:20;:45::i;:::-;-1:-1:-1;;;;;68978:13:0;;;;;;:9;:13;;;;;:18;;68995:1;;68978:13;:18;;68995:1;;68978:18;:::i;:::-;;;;-1:-1:-1;;69007:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;69007:21:0;-1:-1:-1;;;;;69007:21:0;;;;;;;;69046:33;;69007:16;;;69046:33;;69007:16;;69046:33;85932:38;85800:178;:::o;14:131:1:-;-1:-1:-1;;;;;;88:32:1;;78:43;;68:71;;135:1;132;125:12;150:245;208:6;261:2;249:9;240:7;236:23;232:32;229:52;;;277:1;274;267:12;229:52;316:9;303:23;335:30;359:5;335:30;:::i;592:258::-;664:1;674:113;688:6;685:1;682:13;674:113;;;764:11;;;758:18;745:11;;;738:39;710:2;703:10;674:113;;;805:6;802:1;799:13;796:48;;;-1:-1:-1;;840:1:1;822:16;;815:27;592:258::o;855:::-;897:3;935:5;929:12;962:6;957:3;950:19;978:63;1034:6;1027:4;1022:3;1018:14;1011:4;1004:5;1000:16;978:63;:::i;:::-;1095:2;1074:15;-1:-1:-1;;1070:29:1;1061:39;;;;1102:4;1057:50;;855:258;-1:-1:-1;;855:258:1:o;1118:220::-;1267:2;1256:9;1249:21;1230:4;1287:45;1328:2;1317:9;1313:18;1305:6;1287:45;:::i;1343:180::-;1402:6;1455:2;1443:9;1434:7;1430:23;1426:32;1423:52;;;1471:1;1468;1461:12;1423:52;-1:-1:-1;1494:23:1;;1343:180;-1:-1:-1;1343:180:1:o;1759:154::-;-1:-1:-1;;;;;1838:5:1;1834:54;1827:5;1824:65;1814:93;;1903:1;1900;1893:12;1918:315;1986:6;1994;2047:2;2035:9;2026:7;2022:23;2018:32;2015:52;;;2063:1;2060;2053:12;2015:52;2102:9;2089:23;2121:31;2146:5;2121:31;:::i;:::-;2171:5;2223:2;2208:18;;;;2195:32;;-1:-1:-1;;;1918:315:1:o;2238:367::-;2301:8;2311:6;2365:3;2358:4;2350:6;2346:17;2342:27;2332:55;;2383:1;2380;2373:12;2332:55;-1:-1:-1;2406:20:1;;2449:18;2438:30;;2435:50;;;2481:1;2478;2471:12;2435:50;2518:4;2510:6;2506:17;2494:29;;2578:3;2571:4;2561:6;2558:1;2554:14;2546:6;2542:27;2538:38;2535:47;2532:67;;;2595:1;2592;2585:12;2610:437;2696:6;2704;2757:2;2745:9;2736:7;2732:23;2728:32;2725:52;;;2773:1;2770;2763:12;2725:52;2813:9;2800:23;2846:18;2838:6;2835:30;2832:50;;;2878:1;2875;2868:12;2832:50;2917:70;2979:7;2970:6;2959:9;2955:22;2917:70;:::i;:::-;3006:8;;2891:96;;-1:-1:-1;2610:437:1;-1:-1:-1;;;;2610:437:1:o;3052:632::-;3223:2;3275:21;;;3345:13;;3248:18;;;3367:22;;;3194:4;;3223:2;3446:15;;;;3420:2;3405:18;;;3194:4;3489:169;3503:6;3500:1;3497:13;3489:169;;;3564:13;;3552:26;;3633:15;;;;3598:12;;;;3525:1;3518:9;3489:169;;;-1:-1:-1;3675:3:1;;3052:632;-1:-1:-1;;;;;;3052:632:1:o;3871:292::-;3929:6;3982:2;3970:9;3961:7;3957:23;3953:32;3950:52;;;3998:1;3995;3988:12;3950:52;4037:9;4024:23;4087:26;4080:5;4076:38;4069:5;4066:49;4056:77;;4129:1;4126;4119:12;4168:1233;4322:6;4330;4338;4346;4354;4362;4415:2;4403:9;4394:7;4390:23;4386:32;4383:52;;;4431:1;4428;4421:12;4383:52;4471:9;4458:23;4500:18;4541:2;4533:6;4530:14;4527:34;;;4557:1;4554;4547:12;4527:34;4596:70;4658:7;4649:6;4638:9;4634:22;4596:70;:::i;:::-;4685:8;;-1:-1:-1;4570:96:1;-1:-1:-1;4773:2:1;4758:18;;4745:32;;-1:-1:-1;4789:16:1;;;4786:36;;;4818:1;4815;4808:12;4786:36;4857:72;4921:7;4910:8;4899:9;4895:24;4857:72;:::i;:::-;4948:8;;-1:-1:-1;4831:98:1;-1:-1:-1;5036:2:1;5021:18;;5008:32;;-1:-1:-1;5052:16:1;;;5049:36;;;5081:1;5078;5071:12;5049:36;5119:8;5108:9;5104:24;5094:34;;5166:7;5159:4;5155:2;5151:13;5147:27;5137:55;;5188:1;5185;5178:12;5137:55;5228:2;5215:16;5254:2;5246:6;5243:14;5240:34;;;5270:1;5267;5260:12;5240:34;5315:7;5310:2;5301:6;5297:2;5293:15;5289:24;5286:37;5283:57;;;5336:1;5333;5326:12;5283:57;5367:2;5363;5359:11;5349:21;;5389:6;5379:16;;;;;4168:1233;;;;;;;;:::o;5406:247::-;5465:6;5518:2;5506:9;5497:7;5493:23;5489:32;5486:52;;;5534:1;5531;5524:12;5486:52;5573:9;5560:23;5592:31;5617:5;5592:31;:::i;5658:160::-;5723:20;;5779:13;;5772:21;5762:32;;5752:60;;5808:1;5805;5798:12;5752:60;5658:160;;;:::o;5823:180::-;5879:6;5932:2;5920:9;5911:7;5907:23;5903:32;5900:52;;;5948:1;5945;5938:12;5900:52;5971:26;5987:9;5971:26;:::i;6008:456::-;6085:6;6093;6101;6154:2;6142:9;6133:7;6129:23;6125:32;6122:52;;;6170:1;6167;6160:12;6122:52;6209:9;6196:23;6228:31;6253:5;6228:31;:::i;:::-;6278:5;-1:-1:-1;6335:2:1;6320:18;;6307:32;6348:33;6307:32;6348:33;:::i;:::-;6008:456;;6400:7;;-1:-1:-1;;;6454:2:1;6439:18;;;;6426:32;;6008:456::o;6836:248::-;6904:6;6912;6965:2;6953:9;6944:7;6940:23;6936:32;6933:52;;;6981:1;6978;6971:12;6933:52;-1:-1:-1;;7004:23:1;;;7074:2;7059:18;;;7046:32;;-1:-1:-1;6836:248:1:o;7391:315::-;7459:6;7467;7520:2;7508:9;7499:7;7495:23;7491:32;7488:52;;;7536:1;7533;7526:12;7488:52;7572:9;7559:23;7549:33;;7632:2;7621:9;7617:18;7604:32;7645:31;7670:5;7645:31;:::i;:::-;7695:5;7685:15;;;7391:315;;;;;:::o;7711:770::-;7830:6;7838;7846;7854;7907:2;7895:9;7886:7;7882:23;7878:32;7875:52;;;7923:1;7920;7913:12;7875:52;7963:9;7950:23;7992:18;8033:2;8025:6;8022:14;8019:34;;;8049:1;8046;8039:12;8019:34;8088:70;8150:7;8141:6;8130:9;8126:22;8088:70;:::i;:::-;8177:8;;-1:-1:-1;8062:96:1;-1:-1:-1;8265:2:1;8250:18;;8237:32;;-1:-1:-1;8281:16:1;;;8278:36;;;8310:1;8307;8300:12;8278:36;;8349:72;8413:7;8402:8;8391:9;8387:24;8349:72;:::i;:::-;7711:770;;;;-1:-1:-1;8440:8:1;-1:-1:-1;;;;7711:770:1:o;8486:383::-;8560:6;8568;8576;8629:2;8617:9;8608:7;8604:23;8600:32;8597:52;;;8645:1;8642;8635:12;8597:52;8684:9;8671:23;8703:31;8728:5;8703:31;:::i;:::-;8753:5;-1:-1:-1;8805:2:1;8790:18;;8777:32;;-1:-1:-1;8828:35:1;8859:2;8844:18;;8828:35;:::i;:::-;8818:45;;8486:383;;;;;:::o;8874:127::-;8935:10;8930:3;8926:20;8923:1;8916:31;8966:4;8963:1;8956:15;8990:4;8987:1;8980:15;9006:275;9077:2;9071:9;9142:2;9123:13;;-1:-1:-1;;9119:27:1;9107:40;;9177:18;9162:34;;9198:22;;;9159:62;9156:88;;;9224:18;;:::i;:::-;9260:2;9253:22;9006:275;;-1:-1:-1;9006:275:1:o;9286:407::-;9351:5;9385:18;9377:6;9374:30;9371:56;;;9407:18;;:::i;:::-;9445:57;9490:2;9469:15;;-1:-1:-1;;9465:29:1;9496:4;9461:40;9445:57;:::i;:::-;9436:66;;9525:6;9518:5;9511:21;9565:3;9556:6;9551:3;9547:16;9544:25;9541:45;;;9582:1;9579;9572:12;9541:45;9631:6;9626:3;9619:4;9612:5;9608:16;9595:43;9685:1;9678:4;9669:6;9662:5;9658:18;9654:29;9647:40;9286:407;;;;;:::o;9698:222::-;9741:5;9794:3;9787:4;9779:6;9775:17;9771:27;9761:55;;9812:1;9809;9802:12;9761:55;9834:80;9910:3;9901:6;9888:20;9881:4;9873:6;9869:17;9834:80;:::i;9925:322::-;9994:6;10047:2;10035:9;10026:7;10022:23;10018:32;10015:52;;;10063:1;10060;10053:12;10015:52;10103:9;10090:23;10136:18;10128:6;10125:30;10122:50;;;10168:1;10165;10158:12;10122:50;10191;10233:7;10224:6;10213:9;10209:22;10191:50;:::i;10515:572::-;10610:6;10618;10626;10679:2;10667:9;10658:7;10654:23;10650:32;10647:52;;;10695:1;10692;10685:12;10647:52;10734:9;10721:23;10753:31;10778:5;10753:31;:::i;:::-;10803:5;-1:-1:-1;10859:2:1;10844:18;;10831:32;10886:18;10875:30;;10872:50;;;10918:1;10915;10908:12;10872:50;10957:70;11019:7;11010:6;10999:9;10995:22;10957:70;:::i;:::-;10515:572;;11046:8;;-1:-1:-1;10931:96:1;;-1:-1:-1;;;;10515:572:1:o;11345:410::-;11411:6;11419;11472:2;11460:9;11451:7;11447:23;11443:32;11440:52;;;11488:1;11485;11478:12;11440:52;11527:9;11514:23;11577:4;11570:5;11566:16;11559:5;11556:27;11546:55;;11597:1;11594;11587:12;11546:55;11620:5;-1:-1:-1;11677:2:1;11662:18;;11649:32;11690:33;11649:32;11690:33;:::i;11760:315::-;11825:6;11833;11886:2;11874:9;11865:7;11861:23;11857:32;11854:52;;;11902:1;11899;11892:12;11854:52;11941:9;11928:23;11960:31;11985:5;11960:31;:::i;:::-;12010:5;-1:-1:-1;12034:35:1;12065:2;12050:18;;12034:35;:::i;:::-;12024:45;;11760:315;;;;;:::o;12080:713::-;12184:6;12192;12200;12208;12261:2;12249:9;12240:7;12236:23;12232:32;12229:52;;;12277:1;12274;12267:12;12229:52;12316:9;12303:23;12335:31;12360:5;12335:31;:::i;:::-;12385:5;-1:-1:-1;12442:2:1;12427:18;;12414:32;12455:33;12414:32;12455:33;:::i;:::-;12507:7;-1:-1:-1;12565:2:1;12550:18;;12537:32;12592:18;12581:30;;12578:50;;;12624:1;12621;12614:12;12578:50;12663:70;12725:7;12716:6;12705:9;12701:22;12663:70;:::i;12798:795::-;12893:6;12901;12909;12917;12970:3;12958:9;12949:7;12945:23;12941:33;12938:53;;;12987:1;12984;12977:12;12938:53;13026:9;13013:23;13045:31;13070:5;13045:31;:::i;:::-;13095:5;-1:-1:-1;13152:2:1;13137:18;;13124:32;13165:33;13124:32;13165:33;:::i;:::-;13217:7;-1:-1:-1;13271:2:1;13256:18;;13243:32;;-1:-1:-1;13326:2:1;13311:18;;13298:32;13353:18;13342:30;;13339:50;;;13385:1;13382;13375:12;13339:50;13408:22;;13461:4;13453:13;;13449:27;-1:-1:-1;13439:55:1;;13490:1;13487;13480:12;13439:55;13513:74;13579:7;13574:2;13561:16;13556:2;13552;13548:11;13513:74;:::i;:::-;13503:84;;;12798:795;;;;;;;:::o;13858:388::-;13926:6;13934;13987:2;13975:9;13966:7;13962:23;13958:32;13955:52;;;14003:1;14000;13993:12;13955:52;14042:9;14029:23;14061:31;14086:5;14061:31;:::i;15029:380::-;15108:1;15104:12;;;;15151;;;15172:61;;15226:4;15218:6;15214:17;15204:27;;15172:61;15279:2;15271:6;15268:14;15248:18;15245:38;15242:161;;15325:10;15320:3;15316:20;15313:1;15306:31;15360:4;15357:1;15350:15;15388:4;15385:1;15378:15;15242:161;;15029:380;;;:::o;17472:127::-;17533:10;17528:3;17524:20;17521:1;17514:31;17564:4;17561:1;17554:15;17588:4;17585:1;17578:15;17604:127;17665:10;17660:3;17656:20;17653:1;17646:31;17696:4;17693:1;17686:15;17720:4;17717:1;17710:15;17736:135;17775:3;17796:17;;;17793:43;;17816:18;;:::i;:::-;-1:-1:-1;17863:1:1;17852:13;;17736:135::o;17876:204::-;17914:3;17950:4;17947:1;17943:12;17982:4;17979:1;17975:12;18017:3;18011:4;18007:14;18002:3;17999:23;17996:49;;;18025:18;;:::i;:::-;18061:13;;17876:204;-1:-1:-1;;;17876:204:1:o;18493:128::-;18533:3;18564:1;18560:6;18557:1;18554:13;18551:39;;;18570:18;;:::i;:::-;-1:-1:-1;18606:9:1;;18493:128::o;18626:411::-;18828:2;18810:21;;;18867:2;18847:18;;;18840:30;18906:34;18901:2;18886:18;;18879:62;-1:-1:-1;;;18972:2:1;18957:18;;18950:45;19027:3;19012:19;;18626:411::o;19400:400::-;19602:2;19584:21;;;19641:2;19621:18;;;19614:30;19680:34;19675:2;19660:18;;19653:62;-1:-1:-1;;;19746:2:1;19731:18;;19724:34;19790:3;19775:19;;19400:400::o;19805:937::-;19943:9;19977:18;20018:2;20010:6;20007:14;20004:40;;;20024:18;;:::i;:::-;20070:6;20067:1;20063:14;20096:4;20120:28;20144:2;20140;20136:11;20120:28;:::i;:::-;20182:19;;;20252:14;;;;20217:12;;;;20289:14;20278:26;;20275:46;;;20317:1;20314;20307:12;20275:46;20341:5;20355:354;20371:6;20366:3;20363:15;20355:354;;;20457:3;20444:17;20493:2;20480:11;20477:19;20474:109;;;20537:1;20566:2;20562;20555:14;20474:109;20608:58;20651:14;20637:11;20630:5;20626:23;20608:58;:::i;:::-;20596:71;;-1:-1:-1;20687:12:1;;;;20388;;20355:354;;;-1:-1:-1;20731:5:1;19805:937;-1:-1:-1;;;;;;;19805:937:1:o;21984:412::-;22186:2;22168:21;;;22225:2;22205:18;;;22198:30;22264:34;22259:2;22244:18;;22237:62;-1:-1:-1;;;22330:2:1;22315:18;;22308:46;22386:3;22371:19;;21984:412::o;22747:397::-;22949:2;22931:21;;;22988:2;22968:18;;;22961:30;23027:34;23022:2;23007:18;;23000:62;-1:-1:-1;;;23093:2:1;23078:18;;23071:31;23134:3;23119:19;;22747:397::o;25500:168::-;25540:7;25606:1;25602;25598:6;25594:14;25591:1;25588:21;25583:1;25576:9;25569:17;25565:45;25562:71;;;25613:18;;:::i;:::-;-1:-1:-1;25653:9:1;;25500:168::o;25673:127::-;25734:10;25729:3;25725:20;25722:1;25715:31;25765:4;25762:1;25755:15;25789:4;25786:1;25779:15;25805:120;25845:1;25871;25861:35;;25876:18;;:::i;:::-;-1:-1:-1;25910:9:1;;25805:120::o;28475:545::-;28577:2;28572:3;28569:11;28566:448;;;28613:1;28638:5;28634:2;28627:17;28683:4;28679:2;28669:19;28753:2;28741:10;28737:19;28734:1;28730:27;28724:4;28720:38;28789:4;28777:10;28774:20;28771:47;;;-1:-1:-1;28812:4:1;28771:47;28867:2;28862:3;28858:12;28855:1;28851:20;28845:4;28841:31;28831:41;;28922:82;28940:2;28933:5;28930:13;28922:82;;;28985:17;;;28966:1;28955:13;28922:82;;;28926:3;;;28475:545;;;:::o;29196:1352::-;29322:3;29316:10;29349:18;29341:6;29338:30;29335:56;;;29371:18;;:::i;:::-;29400:97;29490:6;29450:38;29482:4;29476:11;29450:38;:::i;:::-;29444:4;29400:97;:::i;:::-;29552:4;;29616:2;29605:14;;29633:1;29628:663;;;;30335:1;30352:6;30349:89;;;-1:-1:-1;30404:19:1;;;30398:26;30349:89;-1:-1:-1;;29153:1:1;29149:11;;;29145:24;29141:29;29131:40;29177:1;29173:11;;;29128:57;30451:81;;29598:944;;29628:663;28422:1;28415:14;;;28459:4;28446:18;;-1:-1:-1;;29664:20:1;;;29782:236;29796:7;29793:1;29790:14;29782:236;;;29885:19;;;29879:26;29864:42;;29977:27;;;;29945:1;29933:14;;;;29812:19;;29782:236;;;29786:3;30046:6;30037:7;30034:19;30031:201;;;30107:19;;;30101:26;-1:-1:-1;;30190:1:1;30186:14;;;30202:3;30182:24;30178:37;30174:42;30159:58;30144:74;;30031:201;-1:-1:-1;;;;;30278:1:1;30262:14;;;30258:22;30245:36;;-1:-1:-1;29196:1352:1:o;30553:125::-;30593:4;30621:1;30618;30615:8;30612:34;;;30626:18;;:::i;:::-;-1:-1:-1;30663:9:1;;30553:125::o;33358:614::-;33638:3;33676:6;33670:13;33692:53;33738:6;33733:3;33726:4;33718:6;33714:17;33692:53;:::i;:::-;-1:-1:-1;;;33767:16:1;;;33792:18;;;33835:13;;33857:65;33835:13;33909:1;33898:13;;33891:4;33879:17;;33857:65;:::i;:::-;33942:20;33964:1;33938:28;;33358:614;-1:-1:-1;;;;33358:614:1:o;34393:443::-;34625:3;34663:6;34657:13;34679:53;34725:6;34720:3;34713:4;34705:6;34701:17;34679:53;:::i;:::-;-1:-1:-1;;;34754:16:1;;34779:22;;;-1:-1:-1;34828:1:1;34817:13;;34393:443;-1:-1:-1;34393:443:1:o;34841:637::-;35121:3;35159:6;35153:13;35175:53;35221:6;35216:3;35209:4;35201:6;35197:17;35175:53;:::i;:::-;35291:13;;35250:16;;;;35313:57;35291:13;35250:16;35347:4;35335:17;;35313:57;:::i;:::-;-1:-1:-1;;;35392:20:1;;35421:22;;;35470:1;35459:13;;34841:637;-1:-1:-1;;;;34841:637:1:o;35483:276::-;35614:3;35652:6;35646:13;35668:53;35714:6;35709:3;35702:4;35694:6;35690:17;35668:53;:::i;:::-;35737:16;;;;;35483:276;-1:-1:-1;;35483:276:1:o;36947:439::-;37179:3;37217:6;37211:13;37233:53;37279:6;37274:3;37267:4;37259:6;37255:17;37233:53;:::i;:::-;-1:-1:-1;;;37308:16:1;;37333:18;;;-1:-1:-1;37378:1:1;37367:13;;36947:439;-1:-1:-1;36947:439:1:o;37391:470::-;37570:3;37608:6;37602:13;37624:53;37670:6;37665:3;37658:4;37650:6;37646:17;37624:53;:::i;:::-;37740:13;;37699:16;;;;37762:57;37740:13;37699:16;37796:4;37784:17;;37762:57;:::i;:::-;37835:20;;37391:470;-1:-1:-1;;;;37391:470:1:o;39866:112::-;39898:1;39924;39914:35;;39929:18;;:::i;:::-;-1:-1:-1;39963:9:1;;39866:112::o;40337:414::-;40539:2;40521:21;;;40578:2;40558:18;;;40551:30;40617:34;40612:2;40597:18;;40590:62;-1:-1:-1;;;40683:2:1;40668:18;;40661:48;40741:3;40726:19;;40337:414::o;40756:786::-;41167:25;41162:3;41155:38;41137:3;41222:6;41216:13;41238:62;41293:6;41288:2;41283:3;41279:12;41272:4;41264:6;41260:17;41238:62;:::i;:::-;-1:-1:-1;;;41359:2:1;41319:16;;;41351:11;;;41344:40;41409:13;;41431:63;41409:13;41480:2;41472:11;;41465:4;41453:17;;41431:63;:::i;:::-;41514:17;41533:2;41510:26;;40756:786;-1:-1:-1;;;;40756:786:1:o;41547:512::-;41741:4;-1:-1:-1;;;;;41851:2:1;41843:6;41839:15;41828:9;41821:34;41903:2;41895:6;41891:15;41886:2;41875:9;41871:18;41864:43;;41943:6;41938:2;41927:9;41923:18;41916:34;41986:3;41981:2;41970:9;41966:18;41959:31;42007:46;42048:3;42037:9;42033:19;42025:6;42007:46;:::i;42064:249::-;42133:6;42186:2;42174:9;42165:7;42161:23;42157:32;42154:52;;;42202:1;42199;42192:12;42154:52;42234:9;42228:16;42253:30;42277:5;42253:30;:::i;42318:127::-;42379:10;42374:3;42370:20;42367:1;42360:31;42410:4;42407:1;42400:15;42434:4;42431:1;42424:15;42450:127;42511:10;42506:3;42502:20;42499:1;42492:31;42542:4;42539:1;42532:15;42566:4;42563:1;42556:15;44101:136;44140:3;44168:5;44158:39;;44177:18;;:::i;:::-;-1:-1:-1;;;44213:18:1;;44101:136::o

Swarm Source

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