ETH Price: $3,014.30 (+4.63%)
Gas: 2 Gwei

Token

DeApes (DA)
 

Overview

Max Total Supply

5,000 DA

Holders

1,484

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
5 DA
0x6ae1798089095453897b0609858310fd6c089991
Loading...
Loading
Loading...
Loading
Loading...
Loading

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

Contract Source Code Verified (Exact Match)

Contract Name:
DeApes

Compiler Version
v0.8.19+commit.7dd6d404

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

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

/**
 *Submitted for verification at Etherscan.io on 2022-12-28
*/

// SPDX-License-Identifier: MIT
// File: @openzeppelin/contracts/utils/structs/EnumerableSet.sol


// OpenZeppelin Contracts (last updated v4.8.0) (utils/structs/EnumerableSet.sol)
// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.

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.
 *
 * [WARNING]
 * ====
 * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure
 * unusable.
 * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.
 *
 * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an
 * array of EnumerableSet.
 * ====
 */
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) {
        bytes32[] memory store = _values(set._inner);
        bytes32[] memory result;

        /// @solidity memory-safe-assembly
        assembly {
            result := store
        }

        return result;
    }

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

        /// @solidity memory-safe-assembly
        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 in 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;

        /// @solidity memory-safe-assembly
        assembly {
            result := store
        }

        return result;
    }
}

// File: contracts/IOperatorFilterRegistry.sol


pragma solidity ^0.8.13;

interface IOperatorFilterRegistry {
    function isOperatorAllowed(address registrant, address operator) external view returns (bool);
    function register(address registrant) external;
    function registerAndSubscribe(address registrant, address subscription) external;
    function registerAndCopyEntries(address registrant, address registrantToCopy) external;
    function unregister(address addr) external;
    function updateOperator(address registrant, address operator, bool filtered) external;
    function updateOperators(address registrant, address[] calldata operators, bool filtered) external;
    function updateCodeHash(address registrant, bytes32 codehash, bool filtered) external;
    function updateCodeHashes(address registrant, bytes32[] calldata codeHashes, bool filtered) external;
    function subscribe(address registrant, address registrantToSubscribe) external;
    function unsubscribe(address registrant, bool copyExistingEntries) external;
    function subscriptionOf(address addr) external returns (address registrant);
    function subscribers(address registrant) external returns (address[] memory);
    function subscriberAt(address registrant, uint256 index) external returns (address);
    function copyEntriesOf(address registrant, address registrantToCopy) external;
    function isOperatorFiltered(address registrant, address operator) external returns (bool);
    function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool);
    function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool);
    function filteredOperators(address addr) external returns (address[] memory);
    function filteredCodeHashes(address addr) external returns (bytes32[] memory);
    function filteredOperatorAt(address registrant, uint256 index) external returns (address);
    function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32);
    function isRegistered(address addr) external returns (bool);
    function codeHashOf(address addr) external returns (bytes32);
}
// File: contracts/OperatorFilterer.sol


// OpenZeppelin Contracts (last updated v4.8.0) (access/Ownable2Step.sol)

pragma solidity ^0.8.0;

/**
 * @dev Contract module which provides access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership} and {acceptOwnership}.
 *
 * This module is used through inheritance. It will make available all functions
 * from parent (Ownable).
 */



pragma solidity ^0.8.13;

/**
 * @title  OwnedRegistrant
 * @notice Ownable contract that registers itself with the OperatorFilterRegistry and administers its own entries,
 *         to facilitate a subscription whose ownership can be transferred.
 */

pragma solidity ^0.8.13;

contract OperatorFilterRegistryErrorsAndEvents {
    error CannotFilterEOAs();
    error AddressAlreadyFiltered(address operator);
    error AddressNotFiltered(address operator);
    error CodeHashAlreadyFiltered(bytes32 codeHash);
    error CodeHashNotFiltered(bytes32 codeHash);
    error OnlyAddressOrOwner();
    error NotRegistered(address registrant);
    error AlreadyRegistered();
    error AlreadySubscribed(address subscription);
    error NotSubscribed();
    error CannotUpdateWhileSubscribed(address subscription);
    error CannotSubscribeToSelf();
    error CannotSubscribeToZeroAddress();
    error NotOwnable();
    error AddressFiltered(address filtered);
    error CodeHashFiltered(address account, bytes32 codeHash);
    error CannotSubscribeToRegistrantWithSubscription(address registrant);
    error CannotCopyFromSelf();

    event RegistrationUpdated(address indexed registrant, bool indexed registered);
    event OperatorUpdated(address indexed registrant, address indexed operator, bool indexed filtered);
    event OperatorsUpdated(address indexed registrant, address[] operators, bool indexed filtered);
    event CodeHashUpdated(address indexed registrant, bytes32 indexed codeHash, bool indexed filtered);
    event CodeHashesUpdated(address indexed registrant, bytes32[] codeHashes, bool indexed filtered);
    event SubscriptionUpdated(address indexed registrant, address indexed subscription, bool indexed subscribed);
}

pragma solidity ^0.8.13;

/**
 * @title  OperatorFilterRegistry
 * @notice Borrows heavily from the QQL BlacklistOperatorFilter contract:
 *         https://github.com/qql-art/contracts/blob/main/contracts/BlacklistOperatorFilter.sol
 * @notice This contracts allows tokens or token owners to register specific addresses or codeHashes that may be
 * *       restricted according to the isOperatorAllowed function.
 */
contract OperatorFilterRegistry is IOperatorFilterRegistry, OperatorFilterRegistryErrorsAndEvents {
    using EnumerableSet for EnumerableSet.AddressSet;
    using EnumerableSet for EnumerableSet.Bytes32Set;

    /// @dev initialized accounts have a nonzero codehash (see https://eips.ethereum.org/EIPS/eip-1052)
    /// Note that this will also be a smart contract's codehash when making calls from its constructor.
    bytes32 constant EOA_CODEHASH = keccak256("");

    mapping(address => EnumerableSet.AddressSet) private _filteredOperators;
    mapping(address => EnumerableSet.Bytes32Set) private _filteredCodeHashes;
    mapping(address => address) private _registrations;
    mapping(address => EnumerableSet.AddressSet) private _subscribers;

    /**
     * @notice restricts method caller to the address or EIP-173 "owner()"
     */
    modifier onlyAddressOrOwner(address addr) {
        if (msg.sender != addr) {
            try Ownable(addr).owner() returns (address owner) {
                if (msg.sender != owner) {
                    revert OnlyAddressOrOwner();
                }
            } catch (bytes memory reason) {
                if (reason.length == 0) {
                    revert NotOwnable();
                } else {
                    /// @solidity memory-safe-assembly
                    assembly {
                        revert(add(32, reason), mload(reason))
                    }
                }
            }
        }
        _;
    }

    /**
     * @notice Returns true if operator is not filtered for a given token, either by address or codeHash. Also returns
     *         true if supplied registrant address is not registered.
     */
    function isOperatorAllowed(address registrant, address operator) external view returns (bool) {
        address registration = _registrations[registrant];
        if (registration != address(0)) {
            EnumerableSet.AddressSet storage filteredOperatorsRef;
            EnumerableSet.Bytes32Set storage filteredCodeHashesRef;

            filteredOperatorsRef = _filteredOperators[registration];
            filteredCodeHashesRef = _filteredCodeHashes[registration];

            if (filteredOperatorsRef.contains(operator)) {
                revert AddressFiltered(operator);
            }
            if (operator.code.length > 0) {
                bytes32 codeHash = operator.codehash;
                if (filteredCodeHashesRef.contains(codeHash)) {
                    revert CodeHashFiltered(operator, codeHash);
                }
            }
        }
        return true;
    }

    //////////////////
    // AUTH METHODS //
    //////////////////

    /**
     * @notice Registers an address with the registry. May be called by address itself or by EIP-173 owner.
     */
    function register(address registrant) external onlyAddressOrOwner(registrant) {
        if (_registrations[registrant] != address(0)) {
            revert AlreadyRegistered();
        }
        _registrations[registrant] = registrant;
        emit RegistrationUpdated(registrant, true);
    }

    /**
     * @notice Unregisters an address with the registry and removes its subscription. May be called by address itself or by EIP-173 owner.
     *         Note that this does not remove any filtered addresses or codeHashes.
     *         Also note that any subscriptions to this registrant will still be active and follow the existing filtered addresses and codehashes.
     */
    function unregister(address registrant) external onlyAddressOrOwner(registrant) {
        address registration = _registrations[registrant];
        if (registration == address(0)) {
            revert NotRegistered(registrant);
        }
        if (registration != registrant) {
            _subscribers[registration].remove(registrant);
            emit SubscriptionUpdated(registrant, registration, false);
        }
        _registrations[registrant] = address(0);
        emit RegistrationUpdated(registrant, false);
    }

    /**
     * @notice Registers an address with the registry and "subscribes" to another address's filtered operators and codeHashes.
     */
    function registerAndSubscribe(address registrant, address subscription) external onlyAddressOrOwner(registrant) {
        address registration = _registrations[registrant];
        if (registration != address(0)) {
            revert AlreadyRegistered();
        }
        if (registrant == subscription) {
            revert CannotSubscribeToSelf();
        }
        address subscriptionRegistration = _registrations[subscription];
        if (subscriptionRegistration == address(0)) {
            revert NotRegistered(subscription);
        }
        if (subscriptionRegistration != subscription) {
            revert CannotSubscribeToRegistrantWithSubscription(subscription);
        }

        _registrations[registrant] = subscription;
        _subscribers[subscription].add(registrant);
        emit RegistrationUpdated(registrant, true);
        emit SubscriptionUpdated(registrant, subscription, true);
    }

    /**
     * @notice Registers an address with the registry and copies the filtered operators and codeHashes from another
     *         address without subscribing.
     */
    function registerAndCopyEntries(address registrant, address registrantToCopy)
        external
        onlyAddressOrOwner(registrant)
    {
        if (registrantToCopy == registrant) {
            revert CannotCopyFromSelf();
        }
        address registration = _registrations[registrant];
        if (registration != address(0)) {
            revert AlreadyRegistered();
        }
        address registrantRegistration = _registrations[registrantToCopy];
        if (registrantRegistration == address(0)) {
            revert NotRegistered(registrantToCopy);
        }
        _registrations[registrant] = registrant;
        emit RegistrationUpdated(registrant, true);
        _copyEntries(registrant, registrantToCopy);
    }

    /**
     * @notice Update an operator address for a registered address - when filtered is true, the operator is filtered.
     */
    function updateOperator(address registrant, address operator, bool filtered)
        external
        onlyAddressOrOwner(registrant)
    {
        address registration = _registrations[registrant];
        if (registration == address(0)) {
            revert NotRegistered(registrant);
        }
        if (registration != registrant) {
            revert CannotUpdateWhileSubscribed(registration);
        }
        EnumerableSet.AddressSet storage filteredOperatorsRef = _filteredOperators[registrant];

        if (!filtered) {
            bool removed = filteredOperatorsRef.remove(operator);
            if (!removed) {
                revert AddressNotFiltered(operator);
            }
        } else {
            bool added = filteredOperatorsRef.add(operator);
            if (!added) {
                revert AddressAlreadyFiltered(operator);
            }
        }
        emit OperatorUpdated(registrant, operator, filtered);
    }

    /**
     * @notice Update a codeHash for a registered address - when filtered is true, the codeHash is filtered.
     */
    function updateCodeHash(address registrant, bytes32 codeHash, bool filtered)
        external
        onlyAddressOrOwner(registrant)
    {
        if (codeHash == EOA_CODEHASH) {
            revert CannotFilterEOAs();
        }
        address registration = _registrations[registrant];
        if (registration == address(0)) {
            revert NotRegistered(registrant);
        }
        if (registration != registrant) {
            revert CannotUpdateWhileSubscribed(registration);
        }
        EnumerableSet.Bytes32Set storage filteredCodeHashesRef = _filteredCodeHashes[registrant];

        if (!filtered) {
            bool removed = filteredCodeHashesRef.remove(codeHash);
            if (!removed) {
                revert CodeHashNotFiltered(codeHash);
            }
        } else {
            bool added = filteredCodeHashesRef.add(codeHash);
            if (!added) {
                revert CodeHashAlreadyFiltered(codeHash);
            }
        }
        emit CodeHashUpdated(registrant, codeHash, filtered);
    }

    /**
     * @notice Update multiple operators for a registered address - when filtered is true, the operators will be filtered. Reverts on duplicates.
     */
    function updateOperators(address registrant, address[] calldata operators, bool filtered)
        external
        onlyAddressOrOwner(registrant)
    {
        address registration = _registrations[registrant];
        if (registration == address(0)) {
            revert NotRegistered(registrant);
        }
        if (registration != registrant) {
            revert CannotUpdateWhileSubscribed(registration);
        }
        EnumerableSet.AddressSet storage filteredOperatorsRef = _filteredOperators[registrant];
        uint256 operatorsLength = operators.length;
        unchecked {
            if (!filtered) {
                for (uint256 i = 0; i < operatorsLength; ++i) {
                    address operator = operators[i];
                    bool removed = filteredOperatorsRef.remove(operator);
                    if (!removed) {
                        revert AddressNotFiltered(operator);
                    }
                }
            } else {
                for (uint256 i = 0; i < operatorsLength; ++i) {
                    address operator = operators[i];
                    bool added = filteredOperatorsRef.add(operator);
                    if (!added) {
                        revert AddressAlreadyFiltered(operator);
                    }
                }
            }
        }
        emit OperatorsUpdated(registrant, operators, filtered);
    }

    /**
     * @notice Update multiple codeHashes for a registered address - when filtered is true, the codeHashes will be filtered. Reverts on duplicates.
     */
    function updateCodeHashes(address registrant, bytes32[] calldata codeHashes, bool filtered)
        external
        onlyAddressOrOwner(registrant)
    {
        address registration = _registrations[registrant];
        if (registration == address(0)) {
            revert NotRegistered(registrant);
        }
        if (registration != registrant) {
            revert CannotUpdateWhileSubscribed(registration);
        }
        EnumerableSet.Bytes32Set storage filteredCodeHashesRef = _filteredCodeHashes[registrant];
        uint256 codeHashesLength = codeHashes.length;
        unchecked {
            if (!filtered) {
                for (uint256 i = 0; i < codeHashesLength; ++i) {
                    bytes32 codeHash = codeHashes[i];
                    bool removed = filteredCodeHashesRef.remove(codeHash);
                    if (!removed) {
                        revert CodeHashNotFiltered(codeHash);
                    }
                }
            } else {
                for (uint256 i = 0; i < codeHashesLength; ++i) {
                    bytes32 codeHash = codeHashes[i];
                    if (codeHash == EOA_CODEHASH) {
                        revert CannotFilterEOAs();
                    }
                    bool added = filteredCodeHashesRef.add(codeHash);
                    if (!added) {
                        revert CodeHashAlreadyFiltered(codeHash);
                    }
                }
            }
        }
        emit CodeHashesUpdated(registrant, codeHashes, filtered);
    }

    /**
     * @notice Subscribe an address to another registrant's filtered operators and codeHashes. Will remove previous
     *         subscription if present.
     *         Note that accounts with subscriptions may go on to subscribe to other accounts - in this case,
     *         subscriptions will not be forwarded. Instead the former subscription's existing entries will still be
     *         used.
     */
    function subscribe(address registrant, address newSubscription) external onlyAddressOrOwner(registrant) {
        if (registrant == newSubscription) {
            revert CannotSubscribeToSelf();
        }
        if (newSubscription == address(0)) {
            revert CannotSubscribeToZeroAddress();
        }
        address registration = _registrations[registrant];
        if (registration == address(0)) {
            revert NotRegistered(registrant);
        }
        if (registration == newSubscription) {
            revert AlreadySubscribed(newSubscription);
        }
        address newSubscriptionRegistration = _registrations[newSubscription];
        if (newSubscriptionRegistration == address(0)) {
            revert NotRegistered(newSubscription);
        }
        if (newSubscriptionRegistration != newSubscription) {
            revert CannotSubscribeToRegistrantWithSubscription(newSubscription);
        }

        if (registration != registrant) {
            _subscribers[registration].remove(registrant);
            emit SubscriptionUpdated(registrant, registration, false);
        }
        _registrations[registrant] = newSubscription;
        _subscribers[newSubscription].add(registrant);
        emit SubscriptionUpdated(registrant, newSubscription, true);
    }

    /**
     * @notice Unsubscribe an address from its current subscribed registrant, and optionally copy its filtered operators and codeHashes.
     */
    function unsubscribe(address registrant, bool copyExistingEntries) external onlyAddressOrOwner(registrant) {
        address registration = _registrations[registrant];
        if (registration == address(0)) {
            revert NotRegistered(registrant);
        }
        if (registration == registrant) {
            revert NotSubscribed();
        }
        _subscribers[registration].remove(registrant);
        _registrations[registrant] = registrant;
        emit SubscriptionUpdated(registrant, registration, false);
        if (copyExistingEntries) {
            _copyEntries(registrant, registration);
        }
    }

    /**
     * @notice Copy filtered operators and codeHashes from a different registrantToCopy to addr.
     */
    function copyEntriesOf(address registrant, address registrantToCopy) external onlyAddressOrOwner(registrant) {
        if (registrant == registrantToCopy) {
            revert CannotCopyFromSelf();
        }
        address registration = _registrations[registrant];
        if (registration == address(0)) {
            revert NotRegistered(registrant);
        }
        if (registration != registrant) {
            revert CannotUpdateWhileSubscribed(registration);
        }
        address registrantRegistration = _registrations[registrantToCopy];
        if (registrantRegistration == address(0)) {
            revert NotRegistered(registrantToCopy);
        }
        _copyEntries(registrant, registrantToCopy);
    }

    /// @dev helper to copy entries from registrantToCopy to registrant and emit events
    function _copyEntries(address registrant, address registrantToCopy) private {
        EnumerableSet.AddressSet storage filteredOperatorsRef = _filteredOperators[registrantToCopy];
        EnumerableSet.Bytes32Set storage filteredCodeHashesRef = _filteredCodeHashes[registrantToCopy];
        uint256 filteredOperatorsLength = filteredOperatorsRef.length();
        uint256 filteredCodeHashesLength = filteredCodeHashesRef.length();
        unchecked {
            for (uint256 i = 0; i < filteredOperatorsLength; ++i) {
                address operator = filteredOperatorsRef.at(i);
                bool added = _filteredOperators[registrant].add(operator);
                if (added) {
                    emit OperatorUpdated(registrant, operator, true);
                }
            }
            for (uint256 i = 0; i < filteredCodeHashesLength; ++i) {
                bytes32 codehash = filteredCodeHashesRef.at(i);
                bool added = _filteredCodeHashes[registrant].add(codehash);
                if (added) {
                    emit CodeHashUpdated(registrant, codehash, true);
                }
            }
        }
    }

    //////////////////
    // VIEW METHODS //
    //////////////////

    /**
     * @notice Get the subscription address of a given registrant, if any.
     */
    function subscriptionOf(address registrant) external view returns (address subscription) {
        subscription = _registrations[registrant];
        if (subscription == address(0)) {
            revert NotRegistered(registrant);
        } else if (subscription == registrant) {
            subscription = address(0);
        }
    }

    /**
     * @notice Get the set of addresses subscribed to a given registrant.
     *         Note that order is not guaranteed as updates are made.
     */
    function subscribers(address registrant) external view returns (address[] memory) {
        return _subscribers[registrant].values();
    }

    /**
     * @notice Get the subscriber at a given index in the set of addresses subscribed to a given registrant.
     *         Note that order is not guaranteed as updates are made.
     */
    function subscriberAt(address registrant, uint256 index) external view returns (address) {
        return _subscribers[registrant].at(index);
    }

    /**
     * @notice Returns true if operator is filtered by a given address or its subscription.
     */
    function isOperatorFiltered(address registrant, address operator) external view returns (bool) {
        address registration = _registrations[registrant];
        if (registration != registrant) {
            return _filteredOperators[registration].contains(operator);
        }
        return _filteredOperators[registrant].contains(operator);
    }

    /**
     * @notice Returns true if a codeHash is filtered by a given address or its subscription.
     */
    function isCodeHashFiltered(address registrant, bytes32 codeHash) external view returns (bool) {
        address registration = _registrations[registrant];
        if (registration != registrant) {
            return _filteredCodeHashes[registration].contains(codeHash);
        }
        return _filteredCodeHashes[registrant].contains(codeHash);
    }

    /**
     * @notice Returns true if the hash of an address's code is filtered by a given address or its subscription.
     */
    function isCodeHashOfFiltered(address registrant, address operatorWithCode) external view returns (bool) {
        bytes32 codeHash = operatorWithCode.codehash;
        address registration = _registrations[registrant];
        if (registration != registrant) {
            return _filteredCodeHashes[registration].contains(codeHash);
        }
        return _filteredCodeHashes[registrant].contains(codeHash);
    }

    /**
     * @notice Returns true if an address has registered
     */
    function isRegistered(address registrant) external view returns (bool) {
        return _registrations[registrant] != address(0);
    }

    /**
     * @notice Returns a list of filtered operators for a given address or its subscription.
     */
    function filteredOperators(address registrant) external view returns (address[] memory) {
        address registration = _registrations[registrant];
        if (registration != registrant) {
            return _filteredOperators[registration].values();
        }
        return _filteredOperators[registrant].values();
    }

    /**
     * @notice Returns the set of filtered codeHashes for a given address or its subscription.
     *         Note that order is not guaranteed as updates are made.
     */
    function filteredCodeHashes(address registrant) external view returns (bytes32[] memory) {
        address registration = _registrations[registrant];
        if (registration != registrant) {
            return _filteredCodeHashes[registration].values();
        }
        return _filteredCodeHashes[registrant].values();
    }

    /**
     * @notice Returns the filtered operator at the given index of the set of filtered operators for a given address or
     *         its subscription.
     *         Note that order is not guaranteed as updates are made.
     */
    function filteredOperatorAt(address registrant, uint256 index) external view returns (address) {
        address registration = _registrations[registrant];
        if (registration != registrant) {
            return _filteredOperators[registration].at(index);
        }
        return _filteredOperators[registrant].at(index);
    }

    /**
     * @notice Returns the filtered codeHash at the given index of the list of filtered codeHashes for a given address or
     *         its subscription.
     *         Note that order is not guaranteed as updates are made.
     */
    function filteredCodeHashAt(address registrant, uint256 index) external view returns (bytes32) {
        address registration = _registrations[registrant];
        if (registration != registrant) {
            return _filteredCodeHashes[registration].at(index);
        }
        return _filteredCodeHashes[registrant].at(index);
    }

    /// @dev Convenience method to compute the code hash of an arbitrary contract
    function codeHashOf(address a) external view returns (bytes32) {
        return a.codehash;
    }
}


pragma solidity ^0.8.13;


abstract contract OperatorFilterer {
    error OperatorNotAllowed(address operator);

    IOperatorFilterRegistry public constant OPERATOR_FILTER_REGISTRY =
        IOperatorFilterRegistry(0x000000000000AAeB6D7670E522A718067333cd4E);

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

    modifier onlyAllowedOperator(address from) virtual {
        // Allow spending tokens from addresses with balance
        // Note that this still allows listings and marketplaces with escrow to transfer tokens if transferred
        // from an EOA.
        if (from != msg.sender) {
            _checkFilterOperator(msg.sender);
        }
        _;
    }

    modifier onlyAllowedOperatorApproval(address operator) virtual {
        _checkFilterOperator(operator);
        _;
    }

    function _checkFilterOperator(address operator) internal view virtual {
        // Check registry code length to facilitate testing in environments without a deployed registry.
        if (address(OPERATOR_FILTER_REGISTRY).code.length > 0) {
            if (!OPERATOR_FILTER_REGISTRY.isOperatorAllowed(address(this), operator)) {
                revert OperatorNotAllowed(operator);
            }
        }
    }
}


// File: contracts/DefaultOperatorFilterer.sol


pragma solidity ^0.8.13;


/**
 * @title  DefaultOperatorFilterer
 * @notice Inherits from OperatorFilterer and automatically subscribes to the default OpenSea subscription.
 */
abstract contract DefaultOperatorFilterer is OperatorFilterer {
    address constant DEFAULT_SUBSCRIPTION = address(0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6);

    constructor() OperatorFilterer(DEFAULT_SUBSCRIPTION, true) {}
}
// File: @openzeppelin/contracts/utils/math/Math.sol


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

pragma solidity ^0.8.0;

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    enum Rounding {
        Down, // Toward negative infinity
        Up, // Toward infinity
        Zero // Toward zero
    }

    /**
     * @dev Returns the largest of two numbers.
     */
    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a > b ? a : b;
    }

    /**
     * @dev Returns the smallest of two numbers.
     */
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two numbers. The result is rounded towards
     * zero.
     */
    function average(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b) / 2 can overflow.
        return (a & b) + (a ^ b) / 2;
    }

    /**
     * @dev Returns the ceiling of the division of two numbers.
     *
     * This differs from standard division with `/` in that it rounds up instead
     * of rounding down.
     */
    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b - 1) / b can overflow on addition, so we distribute.
        return a == 0 ? 0 : (a - 1) / b + 1;
    }

    /**
     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)
     * with further edits by Uniswap Labs also under MIT license.
     */
    function mulDiv(
        uint256 x,
        uint256 y,
        uint256 denominator
    ) internal pure returns (uint256 result) {
        unchecked {
            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
            // variables such that product = prod1 * 2^256 + prod0.
            uint256 prod0; // Least significant 256 bits of the product
            uint256 prod1; // Most significant 256 bits of the product
            assembly {
                let mm := mulmod(x, y, not(0))
                prod0 := mul(x, y)
                prod1 := sub(sub(mm, prod0), lt(mm, prod0))
            }

            // Handle non-overflow cases, 256 by 256 division.
            if (prod1 == 0) {
                return prod0 / denominator;
            }

            // Make sure the result is less than 2^256. Also prevents denominator == 0.
            require(denominator > prod1);

            ///////////////////////////////////////////////
            // 512 by 256 division.
            ///////////////////////////////////////////////

            // Make division exact by subtracting the remainder from [prod1 prod0].
            uint256 remainder;
            assembly {
                // Compute remainder using mulmod.
                remainder := mulmod(x, y, denominator)

                // Subtract 256 bit number from 512 bit number.
                prod1 := sub(prod1, gt(remainder, prod0))
                prod0 := sub(prod0, remainder)
            }

            // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.
            // See https://cs.stackexchange.com/q/138556/92363.

            // Does not overflow because the denominator cannot be zero at this stage in the function.
            uint256 twos = denominator & (~denominator + 1);
            assembly {
                // Divide denominator by twos.
                denominator := div(denominator, twos)

                // Divide [prod1 prod0] by twos.
                prod0 := div(prod0, twos)

                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
                twos := add(div(sub(0, twos), twos), 1)
            }

            // Shift in bits from prod1 into prod0.
            prod0 |= prod1 * twos;

            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
            // four bits. That is, denominator * inv = 1 mod 2^4.
            uint256 inverse = (3 * denominator) ^ 2;

            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works
            // in modular arithmetic, doubling the correct bits in each step.
            inverse *= 2 - denominator * inverse; // inverse mod 2^8
            inverse *= 2 - denominator * inverse; // inverse mod 2^16
            inverse *= 2 - denominator * inverse; // inverse mod 2^32
            inverse *= 2 - denominator * inverse; // inverse mod 2^64
            inverse *= 2 - denominator * inverse; // inverse mod 2^128
            inverse *= 2 - denominator * inverse; // inverse mod 2^256

            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
            // is no longer required.
            result = prod0 * inverse;
            return result;
        }
    }

    /**
     * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
     */
    function mulDiv(
        uint256 x,
        uint256 y,
        uint256 denominator,
        Rounding rounding
    ) internal pure returns (uint256) {
        uint256 result = mulDiv(x, y, denominator);
        if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
            result += 1;
        }
        return result;
    }

    /**
     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.
     *
     * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
     */
    function sqrt(uint256 a) internal pure returns (uint256) {
        if (a == 0) {
            return 0;
        }

        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
        //
        // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
        // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
        //
        // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
        // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
        // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
        //
        // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
        uint256 result = 1 << (log2(a) >> 1);

        // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
        // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
        // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
        // into the expected uint128 result.
        unchecked {
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            return min(result, a / result);
        }
    }

    /**
     * @notice Calculates sqrt(a), following the selected rounding direction.
     */
    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = sqrt(a);
            return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 2, rounded down, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 128;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 64;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 32;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 16;
            }
            if (value >> 8 > 0) {
                value >>= 8;
                result += 8;
            }
            if (value >> 4 > 0) {
                value >>= 4;
                result += 4;
            }
            if (value >> 2 > 0) {
                value >>= 2;
                result += 2;
            }
            if (value >> 1 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log2(value);
            return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 10, rounded down, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >= 10**64) {
                value /= 10**64;
                result += 64;
            }
            if (value >= 10**32) {
                value /= 10**32;
                result += 32;
            }
            if (value >= 10**16) {
                value /= 10**16;
                result += 16;
            }
            if (value >= 10**8) {
                value /= 10**8;
                result += 8;
            }
            if (value >= 10**4) {
                value /= 10**4;
                result += 4;
            }
            if (value >= 10**2) {
                value /= 10**2;
                result += 2;
            }
            if (value >= 10**1) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log10(value);
            return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 256, rounded down, of a positive value.
     * Returns 0 if given 0.
     *
     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
     */
    function log256(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 16;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 8;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 4;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 2;
            }
            if (value >> 8 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log256(value);
            return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);
        }
    }
}

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


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

pragma solidity ^0.8.0;


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

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        unchecked {
            uint256 length = Math.log10(value) + 1;
            string memory buffer = new string(length);
            uint256 ptr;
            /// @solidity memory-safe-assembly
            assembly {
                ptr := add(buffer, add(32, length))
            }
            while (true) {
                ptr--;
                /// @solidity memory-safe-assembly
                assembly {
                    mstore8(ptr, byte(mod(value, 10), _SYMBOLS))
                }
                value /= 10;
                if (value == 0) break;
            }
            return buffer;
        }
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        unchecked {
            return toHexString(value, Math.log256(value) + 1);
        }
    }

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

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

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


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

pragma solidity ^0.8.1;

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

        return account.code.length > 0;
    }

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

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

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

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

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

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

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

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

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

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
     * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
     *
     * _Available since v4.8._
     */
    function verifyCallResultFromTarget(
        address target,
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        if (success) {
            if (returndata.length == 0) {
                // only check isContract if the call was successful and the return data is empty
                // otherwise we already know that it was a contract
                require(isContract(target), "Address: call to non-contract");
            }
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    /**
     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason or using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    function _revert(bytes memory returndata, string memory errorMessage) private pure {
        // Look for revert reason and bubble it up if present
        if (returndata.length > 0) {
            // The easiest way to bubble the revert reason is using memory via assembly
            /// @solidity memory-safe-assembly
            assembly {
                let returndata_size := mload(returndata)
                revert(add(32, returndata), returndata_size)
            }
        } else {
            revert(errorMessage);
        }
    }
}

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


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

pragma solidity ^0.8.0;

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

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


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



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


// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.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);
}



pragma solidity ^0.8.0;


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

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


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

pragma solidity ^0.8.0;


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

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

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

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

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

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

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

    /**
     * @dev Transfers `tokenId` token from `from` to `to`.
     *
     * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721
     * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must
     * understand this adds an external call which potentially creates a reentrancy vulnerability.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

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

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

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

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

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

pragma solidity ^0.8.0;



interface IERC721Enumerable is IERC721 {
  
    function totalSupply() external view returns (uint256);


    function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);


    function tokenByIndex(uint256 index) external view returns (uint256);
}

pragma solidity ^0.8.0;

abstract contract ReentrancyGuard {

    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }


    modifier nonReentrant() {
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

        _status = _ENTERED;

        _;

        _status = _NOT_ENTERED;
    }
}


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

pragma solidity ^0.8.0;

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

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

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


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

pragma solidity ^0.8.0;




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


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

pragma solidity ^0.8.0;

contract ERC721A is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable, DefaultOperatorFilterer {
    using Address for address;
    using Strings for uint256;

    struct TokenOwnership {
        address addr;
        uint64 startTimestamp;
    }

    struct AddressData {
        uint128 balance;
        uint128 numberMinted;
    }

    uint256 internal currentIndex;

    string private _name;

    string private _symbol;

    mapping(uint256 => TokenOwnership) internal _ownerships;

    mapping(address => AddressData) private _addressData;

    mapping(uint256 => address) private _tokenApprovals;

    mapping(address => mapping(address => bool)) private _operatorApprovals;

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

    function totalSupply() public view override returns (uint256) {
        return currentIndex;
    }

    function tokenByIndex(uint256 index) public view override returns (uint256) {
        require(index < totalSupply(), "ERC721A: global index out of bounds");
        return index;
    }

    function tokenOfOwnerByIndex(address owner, uint256 index) public view override returns (uint256) {
        require(index < balanceOf(owner), "ERC721A: owner index out of bounds");
        uint256 numMintedSoFar = totalSupply();
        uint256 tokenIdsIdx;
        address currOwnershipAddr;

        unchecked {
            for (uint256 i; i < numMintedSoFar; i++) {
                TokenOwnership memory ownership = _ownerships[i];
                if (ownership.addr != address(0)) {
                    currOwnershipAddr = ownership.addr;
                }
                if (currOwnershipAddr == owner) {
                    if (tokenIdsIdx == index) {
                        return i;
                    }
                    tokenIdsIdx++;
                }
            }
        }

        revert("ERC721A: unable to get token of owner by index");
    }


    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
        return
            interfaceId == type(IERC721).interfaceId ||
            interfaceId == type(IERC721Metadata).interfaceId ||
            interfaceId == type(IERC721Enumerable).interfaceId ||
            super.supportsInterface(interfaceId);
    }

    function balanceOf(address owner) public view override returns (uint256) {
        require(owner != address(0), "ERC721A: balance query for the zero address");
        return uint256(_addressData[owner].balance);
    }

    function _numberMinted(address owner) internal view returns (uint256) {
        require(owner != address(0), "ERC721A: number minted query for the zero address");
        return uint256(_addressData[owner].numberMinted);
    }

    function ownershipOf(uint256 tokenId) internal view returns (TokenOwnership memory) {
        require(_exists(tokenId), "ERC721A: owner query for nonexistent token");

        unchecked {
            for (uint256 curr = tokenId; curr >= 0; curr--) {
                TokenOwnership memory ownership = _ownerships[curr];
                if (ownership.addr != address(0)) {
                    return ownership;
                }
            }
        }

        revert("ERC721A: unable to determine the owner of token");
    }

    function ownerOf(uint256 tokenId) public view override returns (address) {
        return ownershipOf(tokenId).addr;
    }

    function name() public view virtual override returns (string memory) {
        return _name;
    }

    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    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())) : "";
    }

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


    function approve(address to, uint256 tokenId) public virtual override onlyAllowedOperator(to) {
        address owner = ERC721A.ownerOf(tokenId);
        require(to != owner, "ERC721A: approval to current owner");

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

        _approve(to, tokenId, owner);
    }

    function getApproved(uint256 tokenId) public view override returns (address) {
        require(_exists(tokenId), "ERC721A: approved query for nonexistent token");

        return _tokenApprovals[tokenId];
    }

    function setApprovalForAll(address operator, bool approved) public virtual override onlyAllowedOperator(operator) {
        require(operator != _msgSender(), "ERC721A: approve to caller");

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

    function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
        return _operatorApprovals[owner][operator];
    }

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

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

    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) public virtual override onlyAllowedOperator(from){
        _transfer(from, to, tokenId);
        require(
            _checkOnERC721Received(from, to, tokenId, _data),
            "ERC721A: transfer to non ERC721Receiver implementer"
        );
    }

    function _exists(uint256 tokenId) internal view returns (bool) {
        return tokenId < currentIndex;
    }

    function _safeMint(address to, uint256 quantity) internal {
        _safeMint(to, quantity, "");
    }

    function _safeMint(
        address to,
        uint256 quantity,
        bytes memory _data
    ) internal {
        _mint(to, quantity, _data, true);
    }

    function _mint(
        address to,
        uint256 quantity,
        bytes memory _data,
        bool safe
    ) internal {
        uint256 startTokenId = currentIndex;
        require(to != address(0), "ERC721A: mint to the zero address");
        require(quantity != 0, "ERC721A: quantity must be greater than 0");

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

        unchecked {
            _addressData[to].balance += uint128(quantity);
            _addressData[to].numberMinted += uint128(quantity);

            _ownerships[startTokenId].addr = to;
            _ownerships[startTokenId].startTimestamp = uint64(block.timestamp);

            uint256 updatedIndex = startTokenId;

            for (uint256 i; i < quantity; i++) {
                emit Transfer(address(0), to, updatedIndex);
                if (safe) {
                    require(
                        _checkOnERC721Received(address(0), to, updatedIndex, _data),
                        "ERC721A: transfer to non ERC721Receiver implementer"
                    );
                }

                updatedIndex++;
            }

            currentIndex = updatedIndex;
        }

        _afterTokenTransfers(address(0), to, startTokenId, quantity);
    }
 
    function _transfer(
        address from,
        address to,
        uint256 tokenId
    ) private {
        TokenOwnership memory prevOwnership = ownershipOf(tokenId);

        bool isApprovedOrOwner = (_msgSender() == prevOwnership.addr ||
            getApproved(tokenId) == _msgSender() ||
            isApprovedForAll(prevOwnership.addr, _msgSender()));

        require(isApprovedOrOwner, "ERC721A: transfer caller is not owner nor approved");

        require(prevOwnership.addr == from, "ERC721A: transfer from incorrect owner");
        require(to != address(0), "ERC721A: transfer to the zero address");

        _beforeTokenTransfers(from, to, tokenId, 1);

        _approve(address(0), tokenId, prevOwnership.addr);

        
        unchecked {
            _addressData[from].balance -= 1;
            _addressData[to].balance += 1;

            _ownerships[tokenId].addr = to;
            _ownerships[tokenId].startTimestamp = uint64(block.timestamp);

            uint256 nextTokenId = tokenId + 1;
            if (_ownerships[nextTokenId].addr == address(0)) {
                if (_exists(nextTokenId)) {
                    _ownerships[nextTokenId].addr = prevOwnership.addr;
                    _ownerships[nextTokenId].startTimestamp = prevOwnership.startTimestamp;
                }
            }
        }

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

    function _approve(
        address to,
        uint256 tokenId,
        address owner
    ) private {
        _tokenApprovals[tokenId] = to;
        emit Approval(owner, to, tokenId);
    }

    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(to).onERC721Received.selector;
            } catch (bytes memory reason) {
                if (reason.length == 0) {
                    revert("ERC721A: transfer to non ERC721Receiver implementer");
                } else {
                    assembly {
                        revert(add(32, reason), mload(reason))
                    }
                }
            }
        } else {
            return true;
        }
    }

    function _beforeTokenTransfers(
        address from,
        address to,
        uint256 startTokenId,
        uint256 quantity
    ) internal virtual {}

    function _afterTokenTransfers(
        address from,
        address to,
        uint256 startTokenId,
        uint256 quantity
    ) internal virtual {}
}


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

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

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

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

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

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

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

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

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

abstract contract Ownable2Step is Ownable {
    address private _pendingOwner;

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

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

    /**
     * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual override onlyOwner {
        _pendingOwner = newOwner;
        emit OwnershipTransferStarted(owner(), newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual override {
        delete _pendingOwner;
        super._transferOwnership(newOwner);
    }

    /**
     * @dev The new owner accepts the ownership transfer.
     */
    function acceptOwnership() external {
        address sender = _msgSender();
        require(pendingOwner() == sender, "Ownable2Step: caller is not the new owner");
        _transferOwnership(sender);
    }
}

contract OwnedRegistrant is Ownable2Step {
    address constant registry = 0x000000000000AAeB6D7670E522A718067333cd4E;

    constructor(address _owner) {
        IOperatorFilterRegistry(registry).register(address(this));
        transferOwnership(_owner);
    }
}


pragma solidity ^0.8.13;

/**
 * @title  UpdatableOperatorFilterer
 * @notice Abstract contract whose constructor automatically registers and optionally subscribes to or copies another
 *         registrant's entries in the OperatorFilterRegistry. This contract allows the Owner to update the
 *         OperatorFilterRegistry address via updateOperatorFilterRegistryAddress, including to the zero address,
 *         which will bypass registry checks.
 *         Note that OpenSea will still disable creator fee enforcement if filtered operators begin fulfilling orders
 *         on-chain, eg, if the registry is revoked or bypassed.
 * @dev    This smart contract is meant to be inherited by token contracts so they can use the following:
 *         - `onlyAllowedOperator` modifier for `transferFrom` and `safeTransferFrom` methods.
 *         - `onlyAllowedOperatorApproval` modifier for `approve` and `setApprovalForAll` methods.
 */
abstract contract UpdatableOperatorFilterer {
    error OperatorNotAllowed(address operator);
    error OnlyOwner();

    IOperatorFilterRegistry public operatorFilterRegistry;

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

    modifier onlyAllowedOperator(address from) virtual {
        // Allow spending tokens from addresses with balance
        // Note that this still allows listings and marketplaces with escrow to transfer tokens if transferred
        // from an EOA.
        if (from != msg.sender) {
            _checkFilterOperator(msg.sender);
        }
        _;
    }

    modifier onlyAllowedOperatorApproval(address operator) virtual {
        _checkFilterOperator(operator);
        _;
    }

    /**
     * @notice Update the address that the contract will make OperatorFilter checks against. When set to the zero
     *         address, checks will be bypassed. OnlyOwner.
     */
    function updateOperatorFilterRegistryAddress(address newRegistry) public virtual {
        if (msg.sender != owner()) {
            revert OnlyOwner();
        }
        operatorFilterRegistry = IOperatorFilterRegistry(newRegistry);
    }

    /**
     * @dev assume the contract has an owner, but leave specific Ownable implementation up to inheriting contract
     */
    function owner() public view virtual returns (address);

    function _checkFilterOperator(address operator) internal view virtual {
        IOperatorFilterRegistry registry = operatorFilterRegistry;
        // Check registry code length to facilitate testing in environments without a deployed registry.
        if (address(registry) != address(0) && address(registry).code.length > 0) {
            if (!registry.isOperatorAllowed(address(this), operator)) {
                revert OperatorNotAllowed(operator);
            }
        }
    }
}


pragma solidity ^0.8.13;

/**
 * @title  RevokableOperatorFilterer
 * @notice This contract is meant to allow contracts to permanently skip OperatorFilterRegistry checks if desired. The
 *         Registry itself has an "unregister" function, but if the contract is ownable, the owner can re-register at
 *         any point. As implemented, this abstract contract allows the contract owner to permanently skip the
 *         OperatorFilterRegistry checks by calling revokeOperatorFilterRegistry. Once done, the registry
 *         address cannot be further updated.
 *         Note that OpenSea will still disable creator fee enforcement if filtered operators begin fulfilling orders
 *         on-chain, eg, if the registry is revoked or bypassed.
 */
abstract contract RevokableOperatorFilterer is UpdatableOperatorFilterer {
    error RegistryHasBeenRevoked();
    error InitialRegistryAddressCannotBeZeroAddress();

    bool public isOperatorFilterRegistryRevoked;

    constructor(address _registry, address subscriptionOrRegistrantToCopy, bool subscribe)
        UpdatableOperatorFilterer(_registry, subscriptionOrRegistrantToCopy, subscribe)
    {
        // don't allow creating a contract with a permanently revoked registry
        if (_registry == address(0)) {
            revert InitialRegistryAddressCannotBeZeroAddress();
        }
    }

    function _checkFilterOperator(address operator) internal view virtual override {
        if (address(operatorFilterRegistry) != address(0)) {
            super._checkFilterOperator(operator);
        }
    }

    /**
     * @notice Update the address that the contract will make OperatorFilter checks against. When set to the zero
     *         address, checks will be permanently bypassed, and the address cannot be updated again. OnlyOwner.
     */
    function updateOperatorFilterRegistryAddress(address newRegistry) public override {
        if (msg.sender != owner()) {
            revert OnlyOwner();
        }
        // if registry has been revoked, do not allow further updates
        if (isOperatorFilterRegistryRevoked) {
            revert RegistryHasBeenRevoked();
        }

        operatorFilterRegistry = IOperatorFilterRegistry(newRegistry);
    }

    /**
     * @notice Revoke the OperatorFilterRegistry address, permanently bypassing checks. OnlyOwner.
     */
    function revokeOperatorFilterRegistry() public {
        if (msg.sender != owner()) {
            revert OnlyOwner();
        }
        // if registry has been revoked, do not allow further updates
        if (isOperatorFilterRegistryRevoked) {
            revert RegistryHasBeenRevoked();
        }

        // set to zero address to bypass checks
        operatorFilterRegistry = IOperatorFilterRegistry(address(0));
        isOperatorFilterRegistryRevoked = true;
    }
}

pragma solidity ^0.8.13;

/**
 * @title  RevokableDefaultOperatorFilterer
 * @notice Inherits from RevokableOperatorFilterer and automatically subscribes to the default OpenSea subscription.
 *         Note that OpenSea will disable creator fee enforcement if filtered operators begin fulfilling orders
 *         on-chain, eg, if the registry is revoked or bypassed.
 */
abstract contract RevokableDefaultOperatorFilterer is RevokableOperatorFilterer {
    address constant DEFAULT_SUBSCRIPTION = address(0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6);

    constructor() RevokableOperatorFilterer(0x000000000000AAeB6D7670E522A718067333cd4E, DEFAULT_SUBSCRIPTION, true) {}
}


pragma solidity ^0.8.9;

contract DeApes is ERC721A, Ownable, ReentrancyGuard {
    using Strings for uint256;
    
    uint   private _totalStake;
    address private _bozoContract; 
    uint   public price             = 0.005 ether;
    uint   public maxTx          = 20;
    uint   public maxSupply          = 5000;
    uint256 public reservedSupply = 10;
    string private baseURI;
    bool   public mintLive;  
    uint   public maxFreePerWallet        = 1;
    uint   public freeMinted = 0;
    uint   public totalFreeAvailable = 5000;
    
    mapping(address => uint256) public _senderFreeMinted;

    constructor() ERC721A("DeApes", "DA") {}

    function tokenURI(uint256 _tokenId) public view virtual override returns (string memory) {
        require(_exists(_tokenId),"ERC721Metadata: URI query for nonexistent token");
        string memory currentBaseURI = _baseURI();
        return bytes(currentBaseURI).length > 0
            ? string(abi.encodePacked(currentBaseURI,Strings.toString(_tokenId),".json"))
            : "";
    }

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

    function mint(uint256 amount) external payable {
        
        if ((freeMinted < totalFreeAvailable) && (_senderFreeMinted[msg.sender] < maxFreePerWallet)) { 
            require(mintLive, "not live yet");
            require(msg.value >= (amount * price) - price, "Eth Amount Invalid");
            require(totalSupply() + amount <= maxSupply, "No more supply");
            require(amount <= maxTx, "Max per TX reached.");
            _senderFreeMinted[msg.sender] = maxFreePerWallet;
            freeMinted += maxFreePerWallet;   
        }
        else{
            require(mintLive, "not live yet");
            require(msg.value >= amount * price, "Eth Amount Invalid");
            require(totalSupply() + amount <= maxSupply, "No more supply");
            require(amount <= maxTx, "Max per TX reached.");
        }

        _safeMint(msg.sender, amount);
    }

    function reservedMint(uint256 Amount) external onlyOwner
    {
        uint256 Remaining = reservedSupply;

        require(totalSupply() + Amount <= maxSupply, "No more supply to be minted");
        require(Remaining >= Amount, "Reserved Supply Minted");
    
        reservedSupply = Remaining - Amount;
        _safeMint(msg.sender, Amount);
    }

    function enableMinting() external onlyOwner {
      mintLive = !mintLive;
    }

   function setBaseUri(string memory baseuri_) public onlyOwner {
        baseURI = baseuri_;
    }

    function setCost(uint256 price_) external onlyOwner {
        price = price_;
    }

    function costInspect() public view returns (uint256) {
        return price;
    }

     function setmaxTx(uint256 _MaxTx) external onlyOwner {
        maxTx = _MaxTx;
    }

    function setMaxTotalFreeAvailable(uint256 MaxTotalFree_) external onlyOwner {
        totalFreeAvailable = MaxTotalFree_;
    }

    function setmaxFreePerWallet(uint256 maxFreePerWallet_) external onlyOwner {
        maxFreePerWallet = maxFreePerWallet_;
    }

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

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

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

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

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

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

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"OperatorNotAllowed","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"OPERATOR_FILTER_REGISTRY","outputs":[{"internalType":"contract IOperatorFilterRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"_senderFreeMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"costInspect","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"enableMinting","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"freeMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxFreePerWallet","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxTx","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"mintLive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"price","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"Amount","type":"uint256"}],"name":"reservedMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"reservedSupply","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":"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":"baseuri_","type":"string"}],"name":"setBaseUri","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"price_","type":"uint256"}],"name":"setCost","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"MaxTotalFree_","type":"uint256"}],"name":"setMaxTotalFreeAvailable","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"maxFreePerWallet_","type":"uint256"}],"name":"setmaxFreePerWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_MaxTx","type":"uint256"}],"name":"setmaxTx","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalFreeAvailable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040526611c37937e08000600b556014600c55611388600d55600a600e55600160115560006012556113886013553480156200003c57600080fd5b506040518060400160405280600681526020017f44654170657300000000000000000000000000000000000000000000000000008152506040518060400160405280600281526020017f4441000000000000000000000000000000000000000000000000000000000000815250733cc6cdda760b79bafa08df41ecfa224f810dceb6600160006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115620002b55780156200017b576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff16637d3e3dbe30846040518363ffffffff1660e01b8152600401620001419291906200041e565b600060405180830381600087803b1580156200015c57600080fd5b505af115801562000171573d6000803e3d6000fd5b50505050620002b4565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161462000235576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663a0af290330846040518363ffffffff1660e01b8152600401620001fb9291906200041e565b600060405180830381600087803b1580156200021657600080fd5b505af11580156200022b573d6000803e3d6000fd5b50505050620002b3565b6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff16634420e486306040518263ffffffff1660e01b81526004016200027e91906200044b565b600060405180830381600087803b1580156200029957600080fd5b505af1158015620002ae573d6000803e3d6000fd5b505050505b5b5b50508160019081620002c89190620006e2565b508060029081620002da9190620006e2565b505050620002fd620002f16200030b60201b60201c565b6200031360201b60201c565b6001600881905550620007c9565b600033905090565b6000600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006200040682620003d9565b9050919050565b6200041881620003f9565b82525050565b60006040820190506200043560008301856200040d565b6200044460208301846200040d565b9392505050565b60006020820190506200046260008301846200040d565b92915050565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680620004ea57607f821691505b6020821081036200050057620004ff620004a2565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026200056a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826200052b565b6200057686836200052b565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b6000620005c3620005bd620005b7846200058e565b62000598565b6200058e565b9050919050565b6000819050919050565b620005df83620005a2565b620005f7620005ee82620005ca565b84845462000538565b825550505050565b600090565b6200060e620005ff565b6200061b818484620005d4565b505050565b5b8181101562000643576200063760008262000604565b60018101905062000621565b5050565b601f82111562000692576200065c8162000506565b62000667846200051b565b8101602085101562000677578190505b6200068f62000686856200051b565b83018262000620565b50505b505050565b600082821c905092915050565b6000620006b76000198460080262000697565b1980831691505092915050565b6000620006d28383620006a4565b9150826002028217905092915050565b620006ed8262000468565b67ffffffffffffffff81111562000709576200070862000473565b5b620007158254620004d1565b6200072282828562000647565b600060209050601f8311600181146200075a576000841562000745578287015190505b620007518582620006c4565b865550620007c1565b601f1984166200076a8662000506565b60005b8281101562000794578489015182556001820191506020850194506020810190506200076d565b86831015620007b45784890151620007b0601f891682620006a4565b8355505b6001600288020188555050505b505050505050565b614ae480620007d96000396000f3fe6080604052600436106102305760003560e01c80638c74bf0e1161012e578063b88d4fde116100ab578063e02a61421161006f578063e02a61421461081c578063e797ec1b14610859578063e8656fcc14610870578063e985e9c51461089b578063f2fde38b146108d857610230565b8063b88d4fde14610735578063b94116011461075e578063c87b56dd14610789578063d10a1a2b146107c6578063d5abeb01146107f157610230565b8063a0712d68116100f2578063a0712d6814610673578063a0bcfc7f1461068f578063a22cb465146106b8578063a7027357146106e1578063b0c2b5611461070c57610230565b80638c74bf0e146105a05780638da5cb5b146105c95780639254d4f4146105f457806395d89b411461061d578063a035b1fe1461064857610230565b806342842e0e116101bc5780636352211e116101805780636352211e146104b95780636bf67d71146104f657806370a0823114610521578063715018a61461055e5780637437681e1461057557610230565b806342842e0e146103d657806344a0d68a146103ff57806344d19d2b146104285780634f6ccce714610453578063536c35761461049057610230565b806318160ddd1161020357806318160ddd1461030357806323b872dd1461032e5780632f745c59146103575780633ccfd60b1461039457806341f43434146103ab57610230565b806301ffc9a71461023557806306fdde0314610272578063081812fc1461029d578063095ea7b3146102da575b600080fd5b34801561024157600080fd5b5061025c60048036038101906102579190612feb565b610901565b6040516102699190613033565b60405180910390f35b34801561027e57600080fd5b50610287610a4b565b60405161029491906130de565b60405180910390f35b3480156102a957600080fd5b506102c460048036038101906102bf9190613136565b610add565b6040516102d191906131a4565b60405180910390f35b3480156102e657600080fd5b5061030160048036038101906102fc91906131eb565b610b62565b005b34801561030f57600080fd5b50610318610b7b565b604051610325919061323a565b60405180910390f35b34801561033a57600080fd5b5061035560048036038101906103509190613255565b610b84565b005b34801561036357600080fd5b5061037e600480360381019061037991906131eb565b610bd3565b60405161038b919061323a565b60405180910390f35b3480156103a057600080fd5b506103a9610dc3565b005b3480156103b757600080fd5b506103c0610ecf565b6040516103cd9190613307565b60405180910390f35b3480156103e257600080fd5b506103fd60048036038101906103f89190613255565b610ee1565b005b34801561040b57600080fd5b5061042660048036038101906104219190613136565b610f30565b005b34801561043457600080fd5b5061043d610f42565b60405161044a919061323a565b60405180910390f35b34801561045f57600080fd5b5061047a60048036038101906104759190613136565b610f48565b604051610487919061323a565b60405180910390f35b34801561049c57600080fd5b506104b760048036038101906104b29190613136565b610f9b565b005b3480156104c557600080fd5b506104e060048036038101906104db9190613136565b610fad565b6040516104ed91906131a4565b60405180910390f35b34801561050257600080fd5b5061050b610fc3565b604051610518919061323a565b60405180910390f35b34801561052d57600080fd5b5061054860048036038101906105439190613322565b610fc9565b604051610555919061323a565b60405180910390f35b34801561056a57600080fd5b506105736110b1565b005b34801561058157600080fd5b5061058a6110c5565b604051610597919061323a565b60405180910390f35b3480156105ac57600080fd5b506105c760048036038101906105c29190613136565b6110cb565b005b3480156105d557600080fd5b506105de611194565b6040516105eb91906131a4565b60405180910390f35b34801561060057600080fd5b5061061b60048036038101906106169190613136565b6111be565b005b34801561062957600080fd5b506106326111d0565b60405161063f91906130de565b60405180910390f35b34801561065457600080fd5b5061065d611262565b60405161066a919061323a565b60405180910390f35b61068d60048036038101906106889190613136565b611268565b005b34801561069b57600080fd5b506106b660048036038101906106b19190613484565b6115b7565b005b3480156106c457600080fd5b506106df60048036038101906106da91906134f9565b6115d2565b005b3480156106ed57600080fd5b506106f66115eb565b604051610703919061323a565b60405180910390f35b34801561071857600080fd5b50610733600480360381019061072e9190613136565b6115f1565b005b34801561074157600080fd5b5061075c600480360381019061075791906135da565b611603565b005b34801561076a57600080fd5b50610773611654565b604051610780919061323a565b60405180910390f35b34801561079557600080fd5b506107b060048036038101906107ab9190613136565b61165e565b6040516107bd91906130de565b60405180910390f35b3480156107d257600080fd5b506107db611705565b6040516107e8919061323a565b60405180910390f35b3480156107fd57600080fd5b5061080661170b565b604051610813919061323a565b60405180910390f35b34801561082857600080fd5b50610843600480360381019061083e9190613322565b611711565b604051610850919061323a565b60405180910390f35b34801561086557600080fd5b5061086e611729565b005b34801561087c57600080fd5b5061088561175d565b6040516108929190613033565b60405180910390f35b3480156108a757600080fd5b506108c260048036038101906108bd919061365d565b611770565b6040516108cf9190613033565b60405180910390f35b3480156108e457600080fd5b506108ff60048036038101906108fa9190613322565b611804565b005b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806109cc57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610a3457507f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610a445750610a4382611887565b5b9050919050565b606060018054610a5a906136cc565b80601f0160208091040260200160405190810160405280929190818152602001828054610a86906136cc565b8015610ad35780601f10610aa857610100808354040283529160200191610ad3565b820191906000526020600020905b815481529060010190602001808311610ab657829003601f168201915b5050505050905090565b6000610ae8826118f1565b610b27576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b1e9061376f565b60405180910390fd5b6005600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b81610b6c816118fe565b610b7683836119fb565b505050565b60008054905090565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610bc257610bc1336118fe565b5b610bcd848484611b52565b50505050565b6000610bde83610fc9565b8210610c1f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c1690613801565b60405180910390fd5b6000610c29610b7b565b905060008060005b83811015610d81576000600360008381526020019081526020016000206040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff16815250509050600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff1614610d2357806000015192505b8773ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610d7357868403610d6a578195505050505050610dbd565b83806001019450505b508080600101915050610c31565b506040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610db490613893565b60405180910390fd5b92915050565b610dcb611ba1565b600260085403610e10576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e07906138ff565b60405180910390fd5b600260088190555060003373ffffffffffffffffffffffffffffffffffffffff1647604051610e3e90613950565b60006040518083038185875af1925050503d8060008114610e7b576040519150601f19603f3d011682016040523d82523d6000602084013e610e80565b606091505b5050905080610ec4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ebb906139b1565b60405180910390fd5b506001600881905550565b6daaeb6d7670e522a718067333cd4e81565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610f1f57610f1e336118fe565b5b610f2a848484611c1f565b50505050565b610f38611ba1565b80600b8190555050565b600e5481565b6000610f52610b7b565b8210610f93576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f8a90613a43565b60405180910390fd5b819050919050565b610fa3611ba1565b8060138190555050565b6000610fb882611c7e565b600001519050919050565b60135481565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611039576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161103090613ad5565b60405180910390fd5b600460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff169050919050565b6110b9611ba1565b6110c36000611e18565b565b600c5481565b6110d3611ba1565b6000600e549050600d54826110e6610b7b565b6110f09190613b24565b1115611131576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161112890613ba4565b60405180910390fd5b81811015611174576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161116b90613c10565b60405180910390fd5b81816111809190613c30565b600e819055506111903383611ede565b5050565b6000600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6111c6611ba1565b8060118190555050565b6060600280546111df906136cc565b80601f016020809104026020016040519081016040528092919081815260200182805461120b906136cc565b80156112585780601f1061122d57610100808354040283529160200191611258565b820191906000526020600020905b81548152906001019060200180831161123b57829003601f168201915b5050505050905090565b600b5481565b6013546012541080156112bb5750601154601460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054105b1561146e57601060009054906101000a900460ff1661130f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161130690613cb0565b60405180910390fd5b600b54600b54826113209190613cd0565b61132a9190613c30565b34101561136c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161136390613d5e565b60405180910390fd5b600d5481611378610b7b565b6113829190613b24565b11156113c3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113ba90613dca565b60405180910390fd5b600c54811115611408576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113ff90613e36565b60405180910390fd5b601154601460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550601154601260008282546114629190613b24565b925050819055506115aa565b601060009054906101000a900460ff166114bd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114b490613cb0565b60405180910390fd5b600b54816114cb9190613cd0565b34101561150d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161150490613d5e565b60405180910390fd5b600d5481611519610b7b565b6115239190613b24565b1115611564576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161155b90613dca565b60405180910390fd5b600c548111156115a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115a090613e36565b60405180910390fd5b5b6115b43382611ede565b50565b6115bf611ba1565b80600f90816115ce9190613ff8565b5050565b816115dc816118fe565b6115e68383611efc565b505050565b60115481565b6115f9611ba1565b80600c8190555050565b833373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461164157611640336118fe565b5b61164d858585856120bb565b5050505050565b6000600b54905090565b6060611669826118f1565b6116a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161169f9061413c565b60405180910390fd5b60006116b2612156565b905060008151116116d257604051806020016040528060008152506116fd565b806116dc846121e8565b6040516020016116ed9291906141e4565b6040516020818303038152906040525b915050919050565b60125481565b600d5481565b60146020528060005260406000206000915090505481565b611731611ba1565b601060009054906101000a900460ff1615601060006101000a81548160ff021916908315150217905550565b601060009054906101000a900460ff1681565b6000600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b61180c611ba1565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361187b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161187290614285565b60405180910390fd5b61188481611e18565b50565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b6000805482109050919050565b60006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b11156119f8576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430836040518363ffffffff1660e01b81526004016119759291906142a5565b602060405180830381865afa158015611992573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119b691906142e3565b6119f757806040517fede71dcc0000000000000000000000000000000000000000000000000000000081526004016119ee91906131a4565b60405180910390fd5b5b50565b813373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611a3957611a38336118fe565b5b6000611a4483610fad565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603611ab4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611aab90614382565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16611ad36122b6565b73ffffffffffffffffffffffffffffffffffffffff161480611b025750611b0181611afc6122b6565b611770565b5b611b41576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b3890614414565b60405180910390fd5b611b4c8484836122be565b50505050565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611b9057611b8f336118fe565b5b611b9b848484612370565b50505050565b611ba96122b6565b73ffffffffffffffffffffffffffffffffffffffff16611bc7611194565b73ffffffffffffffffffffffffffffffffffffffff1614611c1d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c1490614480565b60405180910390fd5b565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611c5d57611c5c336118fe565b5b611c7884848460405180602001604052806000815250611603565b50505050565b611c86612f45565b611c8f826118f1565b611cce576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cc590614512565b60405180910390fd5b60008290505b60008110611dd7576000600360008381526020019081526020016000206040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff16815250509050600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff1614611dc8578092505050611e13565b50808060019003915050611cd4565b506040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e0a906145a4565b60405180910390fd5b919050565b6000600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b611ef88282604051806020016040528060008152506128ae565b5050565b813373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611f3a57611f39336118fe565b5b611f426122b6565b73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611faf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fa690614610565b60405180910390fd5b8160066000611fbc6122b6565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508273ffffffffffffffffffffffffffffffffffffffff166120696122b6565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31846040516120ae9190613033565b60405180910390a3505050565b833373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146120f9576120f8336118fe565b5b612104858585612370565b612110858585856128c0565b61214f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612146906146a2565b60405180910390fd5b5050505050565b6060600f8054612165906136cc565b80601f0160208091040260200160405190810160405280929190818152602001828054612191906136cc565b80156121de5780601f106121b3576101008083540402835291602001916121de565b820191906000526020600020905b8154815290600101906020018083116121c157829003601f168201915b5050505050905090565b6060600060016121f784612a47565b01905060008167ffffffffffffffff81111561221657612215613359565b5b6040519080825280601f01601f1916602001820160405280156122485781602001600182028036833780820191505090505b509050600082602001820190505b6001156122ab578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a858161229f5761229e6146c2565b5b04945060008503612256575b819350505050919050565b600033905090565b826005600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b600061237b82611c7e565b90506000816000015173ffffffffffffffffffffffffffffffffffffffff166123a26122b6565b73ffffffffffffffffffffffffffffffffffffffff1614806123fe57506123c76122b6565b73ffffffffffffffffffffffffffffffffffffffff166123e684610add565b73ffffffffffffffffffffffffffffffffffffffff16145b8061241a575061241982600001516124146122b6565b611770565b5b90508061245c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161245390614763565b60405180910390fd5b8473ffffffffffffffffffffffffffffffffffffffff16826000015173ffffffffffffffffffffffffffffffffffffffff16146124ce576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124c5906147f5565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff160361253d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161253490614887565b60405180910390fd5b61254a8585856001612b9a565b61255a60008484600001516122be565b6001600460008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008282829054906101000a90046fffffffffffffffffffffffffffffffff160392506101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055506001600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008282829054906101000a90046fffffffffffffffffffffffffffffffff160192506101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550836003600085815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550426003600085815260200190815260200160002060000160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506000600184019050600073ffffffffffffffffffffffffffffffffffffffff166003600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff160361283e5761279d816118f1565b1561283d5782600001516003600083815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555082602001516003600083815260200190815260200160002060000160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055505b5b50828473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46128a78585856001612ba0565b5050505050565b6128bb8383836001612ba6565b505050565b60006128e18473ffffffffffffffffffffffffffffffffffffffff16612f22565b15612a3a578373ffffffffffffffffffffffffffffffffffffffff1663150b7a0261290a6122b6565b8786866040518563ffffffff1660e01b815260040161292c94939291906148fc565b6020604051808303816000875af192505050801561296857506040513d601f19601f82011682018060405250810190612965919061495d565b60015b6129ea573d8060008114612998576040519150601f19603f3d011682016040523d82523d6000602084013e61299d565b606091505b5060008151036129e2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129d9906146a2565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050612a3f565b600190505b949350505050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310612aa5577a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008381612a9b57612a9a6146c2565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310612ae2576d04ee2d6d415b85acef81000000008381612ad857612ad76146c2565b5b0492506020810190505b662386f26fc100008310612b1157662386f26fc100008381612b0757612b066146c2565b5b0492506010810190505b6305f5e1008310612b3a576305f5e1008381612b3057612b2f6146c2565b5b0492506008810190505b6127108310612b5f576127108381612b5557612b546146c2565b5b0492506004810190505b60648310612b825760648381612b7857612b776146c2565b5b0492506002810190505b600a8310612b91576001810190505b80915050919050565b50505050565b50505050565b600080549050600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603612c1b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c12906149fc565b60405180910390fd5b60008403612c5e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c5590614a8e565b60405180910390fd5b612c6b6000868387612b9a565b83600460008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008282829054906101000a90046fffffffffffffffffffffffffffffffff160192506101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555083600460008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160108282829054906101000a90046fffffffffffffffffffffffffffffffff160192506101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550846003600083815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550426003600083815260200190815260200160002060000160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550600081905060005b85811015612f0557818773ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a48315612ef057612eb060008884886128c0565b612eef576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ee6906146a2565b60405180910390fd5b5b81806001019250508080600101915050612e39565b508060008190555050612f1b6000868387612ba0565b5050505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b6040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600067ffffffffffffffff1681525090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612fc881612f93565b8114612fd357600080fd5b50565b600081359050612fe581612fbf565b92915050565b60006020828403121561300157613000612f89565b5b600061300f84828501612fd6565b91505092915050565b60008115159050919050565b61302d81613018565b82525050565b60006020820190506130486000830184613024565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561308857808201518184015260208101905061306d565b60008484015250505050565b6000601f19601f8301169050919050565b60006130b08261304e565b6130ba8185613059565b93506130ca81856020860161306a565b6130d381613094565b840191505092915050565b600060208201905081810360008301526130f881846130a5565b905092915050565b6000819050919050565b61311381613100565b811461311e57600080fd5b50565b6000813590506131308161310a565b92915050565b60006020828403121561314c5761314b612f89565b5b600061315a84828501613121565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061318e82613163565b9050919050565b61319e81613183565b82525050565b60006020820190506131b96000830184613195565b92915050565b6131c881613183565b81146131d357600080fd5b50565b6000813590506131e5816131bf565b92915050565b6000806040838503121561320257613201612f89565b5b6000613210858286016131d6565b925050602061322185828601613121565b9150509250929050565b61323481613100565b82525050565b600060208201905061324f600083018461322b565b92915050565b60008060006060848603121561326e5761326d612f89565b5b600061327c868287016131d6565b935050602061328d868287016131d6565b925050604061329e86828701613121565b9150509250925092565b6000819050919050565b60006132cd6132c86132c384613163565b6132a8565b613163565b9050919050565b60006132df826132b2565b9050919050565b60006132f1826132d4565b9050919050565b613301816132e6565b82525050565b600060208201905061331c60008301846132f8565b92915050565b60006020828403121561333857613337612f89565b5b6000613346848285016131d6565b91505092915050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61339182613094565b810181811067ffffffffffffffff821117156133b0576133af613359565b5b80604052505050565b60006133c3612f7f565b90506133cf8282613388565b919050565b600067ffffffffffffffff8211156133ef576133ee613359565b5b6133f882613094565b9050602081019050919050565b82818337600083830152505050565b6000613427613422846133d4565b6133b9565b90508281526020810184848401111561344357613442613354565b5b61344e848285613405565b509392505050565b600082601f83011261346b5761346a61334f565b5b813561347b848260208601613414565b91505092915050565b60006020828403121561349a57613499612f89565b5b600082013567ffffffffffffffff8111156134b8576134b7612f8e565b5b6134c484828501613456565b91505092915050565b6134d681613018565b81146134e157600080fd5b50565b6000813590506134f3816134cd565b92915050565b600080604083850312156135105761350f612f89565b5b600061351e858286016131d6565b925050602061352f858286016134e4565b9150509250929050565b600067ffffffffffffffff82111561355457613553613359565b5b61355d82613094565b9050602081019050919050565b600061357d61357884613539565b6133b9565b90508281526020810184848401111561359957613598613354565b5b6135a4848285613405565b509392505050565b600082601f8301126135c1576135c061334f565b5b81356135d184826020860161356a565b91505092915050565b600080600080608085870312156135f4576135f3612f89565b5b6000613602878288016131d6565b9450506020613613878288016131d6565b935050604061362487828801613121565b925050606085013567ffffffffffffffff81111561364557613644612f8e565b5b613651878288016135ac565b91505092959194509250565b6000806040838503121561367457613673612f89565b5b6000613682858286016131d6565b9250506020613693858286016131d6565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806136e457607f821691505b6020821081036136f7576136f661369d565b5b50919050565b7f455243373231413a20617070726f76656420717565727920666f72206e6f6e6560008201527f78697374656e7420746f6b656e00000000000000000000000000000000000000602082015250565b6000613759602d83613059565b9150613764826136fd565b604082019050919050565b600060208201905081810360008301526137888161374c565b9050919050565b7f455243373231413a206f776e657220696e646578206f7574206f6620626f756e60008201527f6473000000000000000000000000000000000000000000000000000000000000602082015250565b60006137eb602283613059565b91506137f68261378f565b604082019050919050565b6000602082019050818103600083015261381a816137de565b9050919050565b7f455243373231413a20756e61626c6520746f2067657420746f6b656e206f662060008201527f6f776e657220627920696e646578000000000000000000000000000000000000602082015250565b600061387d602e83613059565b915061388882613821565b604082019050919050565b600060208201905081810360008301526138ac81613870565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b60006138e9601f83613059565b91506138f4826138b3565b602082019050919050565b60006020820190508181036000830152613918816138dc565b9050919050565b600081905092915050565b50565b600061393a60008361391f565b91506139458261392a565b600082019050919050565b600061395b8261392d565b9150819050919050565b7f5472616e73666572206661696c65642e00000000000000000000000000000000600082015250565b600061399b601083613059565b91506139a682613965565b602082019050919050565b600060208201905081810360008301526139ca8161398e565b9050919050565b7f455243373231413a20676c6f62616c20696e646578206f7574206f6620626f7560008201527f6e64730000000000000000000000000000000000000000000000000000000000602082015250565b6000613a2d602383613059565b9150613a38826139d1565b604082019050919050565b60006020820190508181036000830152613a5c81613a20565b9050919050565b7f455243373231413a2062616c616e636520717565727920666f7220746865207a60008201527f65726f2061646472657373000000000000000000000000000000000000000000602082015250565b6000613abf602b83613059565b9150613aca82613a63565b604082019050919050565b60006020820190508181036000830152613aee81613ab2565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000613b2f82613100565b9150613b3a83613100565b9250828201905080821115613b5257613b51613af5565b5b92915050565b7f4e6f206d6f726520737570706c7920746f206265206d696e7465640000000000600082015250565b6000613b8e601b83613059565b9150613b9982613b58565b602082019050919050565b60006020820190508181036000830152613bbd81613b81565b9050919050565b7f526573657276656420537570706c79204d696e74656400000000000000000000600082015250565b6000613bfa601683613059565b9150613c0582613bc4565b602082019050919050565b60006020820190508181036000830152613c2981613bed565b9050919050565b6000613c3b82613100565b9150613c4683613100565b9250828203905081811115613c5e57613c5d613af5565b5b92915050565b7f6e6f74206c697665207965740000000000000000000000000000000000000000600082015250565b6000613c9a600c83613059565b9150613ca582613c64565b602082019050919050565b60006020820190508181036000830152613cc981613c8d565b9050919050565b6000613cdb82613100565b9150613ce683613100565b9250828202613cf481613100565b91508282048414831517613d0b57613d0a613af5565b5b5092915050565b7f45746820416d6f756e7420496e76616c69640000000000000000000000000000600082015250565b6000613d48601283613059565b9150613d5382613d12565b602082019050919050565b60006020820190508181036000830152613d7781613d3b565b9050919050565b7f4e6f206d6f726520737570706c79000000000000000000000000000000000000600082015250565b6000613db4600e83613059565b9150613dbf82613d7e565b602082019050919050565b60006020820190508181036000830152613de381613da7565b9050919050565b7f4d61782070657220545820726561636865642e00000000000000000000000000600082015250565b6000613e20601383613059565b9150613e2b82613dea565b602082019050919050565b60006020820190508181036000830152613e4f81613e13565b9050919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302613eb87fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82613e7b565b613ec28683613e7b565b95508019841693508086168417925050509392505050565b6000613ef5613ef0613eeb84613100565b6132a8565b613100565b9050919050565b6000819050919050565b613f0f83613eda565b613f23613f1b82613efc565b848454613e88565b825550505050565b600090565b613f38613f2b565b613f43818484613f06565b505050565b5b81811015613f6757613f5c600082613f30565b600181019050613f49565b5050565b601f821115613fac57613f7d81613e56565b613f8684613e6b565b81016020851015613f95578190505b613fa9613fa185613e6b565b830182613f48565b50505b505050565b600082821c905092915050565b6000613fcf60001984600802613fb1565b1980831691505092915050565b6000613fe88383613fbe565b9150826002028217905092915050565b6140018261304e565b67ffffffffffffffff81111561401a57614019613359565b5b61402482546136cc565b61402f828285613f6b565b600060209050601f8311600181146140625760008415614050578287015190505b61405a8582613fdc565b8655506140c2565b601f19841661407086613e56565b60005b8281101561409857848901518255600182019150602085019450602081019050614073565b868310156140b557848901516140b1601f891682613fbe565b8355505b6001600288020188555050505b505050505050565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b6000614126602f83613059565b9150614131826140ca565b604082019050919050565b6000602082019050818103600083015261415581614119565b9050919050565b600081905092915050565b60006141728261304e565b61417c818561415c565b935061418c81856020860161306a565b80840191505092915050565b7f2e6a736f6e000000000000000000000000000000000000000000000000000000600082015250565b60006141ce60058361415c565b91506141d982614198565b600582019050919050565b60006141f08285614167565b91506141fc8284614167565b9150614207826141c1565b91508190509392505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b600061426f602683613059565b915061427a82614213565b604082019050919050565b6000602082019050818103600083015261429e81614262565b9050919050565b60006040820190506142ba6000830185613195565b6142c76020830184613195565b9392505050565b6000815190506142dd816134cd565b92915050565b6000602082840312156142f9576142f8612f89565b5b6000614307848285016142ce565b91505092915050565b7f455243373231413a20617070726f76616c20746f2063757272656e74206f776e60008201527f6572000000000000000000000000000000000000000000000000000000000000602082015250565b600061436c602283613059565b915061437782614310565b604082019050919050565b6000602082019050818103600083015261439b8161435f565b9050919050565b7f455243373231413a20617070726f76652063616c6c6572206973206e6f74206f60008201527f776e6572206e6f7220617070726f76656420666f7220616c6c00000000000000602082015250565b60006143fe603983613059565b9150614409826143a2565b604082019050919050565b6000602082019050818103600083015261442d816143f1565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b600061446a602083613059565b915061447582614434565b602082019050919050565b600060208201905081810360008301526144998161445d565b9050919050565b7f455243373231413a206f776e657220717565727920666f72206e6f6e6578697360008201527f74656e7420746f6b656e00000000000000000000000000000000000000000000602082015250565b60006144fc602a83613059565b9150614507826144a0565b604082019050919050565b6000602082019050818103600083015261452b816144ef565b9050919050565b7f455243373231413a20756e61626c6520746f2064657465726d696e652074686560008201527f206f776e6572206f6620746f6b656e0000000000000000000000000000000000602082015250565b600061458e602f83613059565b915061459982614532565b604082019050919050565b600060208201905081810360008301526145bd81614581565b9050919050565b7f455243373231413a20617070726f766520746f2063616c6c6572000000000000600082015250565b60006145fa601a83613059565b9150614605826145c4565b602082019050919050565b60006020820190508181036000830152614629816145ed565b9050919050565b7f455243373231413a207472616e7366657220746f206e6f6e204552433732315260008201527f6563656976657220696d706c656d656e74657200000000000000000000000000602082015250565b600061468c603383613059565b915061469782614630565b604082019050919050565b600060208201905081810360008301526146bb8161467f565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f455243373231413a207472616e736665722063616c6c6572206973206e6f742060008201527f6f776e6572206e6f7220617070726f7665640000000000000000000000000000602082015250565b600061474d603283613059565b9150614758826146f1565b604082019050919050565b6000602082019050818103600083015261477c81614740565b9050919050565b7f455243373231413a207472616e736665722066726f6d20696e636f727265637460008201527f206f776e65720000000000000000000000000000000000000000000000000000602082015250565b60006147df602683613059565b91506147ea82614783565b604082019050919050565b6000602082019050818103600083015261480e816147d2565b9050919050565b7f455243373231413a207472616e7366657220746f20746865207a65726f20616460008201527f6472657373000000000000000000000000000000000000000000000000000000602082015250565b6000614871602583613059565b915061487c82614815565b604082019050919050565b600060208201905081810360008301526148a081614864565b9050919050565b600081519050919050565b600082825260208201905092915050565b60006148ce826148a7565b6148d881856148b2565b93506148e881856020860161306a565b6148f181613094565b840191505092915050565b60006080820190506149116000830187613195565b61491e6020830186613195565b61492b604083018561322b565b818103606083015261493d81846148c3565b905095945050505050565b60008151905061495781612fbf565b92915050565b60006020828403121561497357614972612f89565b5b600061498184828501614948565b91505092915050565b7f455243373231413a206d696e7420746f20746865207a65726f2061646472657360008201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b60006149e6602183613059565b91506149f18261498a565b604082019050919050565b60006020820190508181036000830152614a15816149d9565b9050919050565b7f455243373231413a207175616e74697479206d7573742062652067726561746560008201527f72207468616e2030000000000000000000000000000000000000000000000000602082015250565b6000614a78602883613059565b9150614a8382614a1c565b604082019050919050565b60006020820190508181036000830152614aa781614a6b565b905091905056fea264697066735822122064144292b69dd7a2dec2b80ff458380abed66226cde58328f59154a2084dac1564736f6c63430008130033

Deployed Bytecode

0x6080604052600436106102305760003560e01c80638c74bf0e1161012e578063b88d4fde116100ab578063e02a61421161006f578063e02a61421461081c578063e797ec1b14610859578063e8656fcc14610870578063e985e9c51461089b578063f2fde38b146108d857610230565b8063b88d4fde14610735578063b94116011461075e578063c87b56dd14610789578063d10a1a2b146107c6578063d5abeb01146107f157610230565b8063a0712d68116100f2578063a0712d6814610673578063a0bcfc7f1461068f578063a22cb465146106b8578063a7027357146106e1578063b0c2b5611461070c57610230565b80638c74bf0e146105a05780638da5cb5b146105c95780639254d4f4146105f457806395d89b411461061d578063a035b1fe1461064857610230565b806342842e0e116101bc5780636352211e116101805780636352211e146104b95780636bf67d71146104f657806370a0823114610521578063715018a61461055e5780637437681e1461057557610230565b806342842e0e146103d657806344a0d68a146103ff57806344d19d2b146104285780634f6ccce714610453578063536c35761461049057610230565b806318160ddd1161020357806318160ddd1461030357806323b872dd1461032e5780632f745c59146103575780633ccfd60b1461039457806341f43434146103ab57610230565b806301ffc9a71461023557806306fdde0314610272578063081812fc1461029d578063095ea7b3146102da575b600080fd5b34801561024157600080fd5b5061025c60048036038101906102579190612feb565b610901565b6040516102699190613033565b60405180910390f35b34801561027e57600080fd5b50610287610a4b565b60405161029491906130de565b60405180910390f35b3480156102a957600080fd5b506102c460048036038101906102bf9190613136565b610add565b6040516102d191906131a4565b60405180910390f35b3480156102e657600080fd5b5061030160048036038101906102fc91906131eb565b610b62565b005b34801561030f57600080fd5b50610318610b7b565b604051610325919061323a565b60405180910390f35b34801561033a57600080fd5b5061035560048036038101906103509190613255565b610b84565b005b34801561036357600080fd5b5061037e600480360381019061037991906131eb565b610bd3565b60405161038b919061323a565b60405180910390f35b3480156103a057600080fd5b506103a9610dc3565b005b3480156103b757600080fd5b506103c0610ecf565b6040516103cd9190613307565b60405180910390f35b3480156103e257600080fd5b506103fd60048036038101906103f89190613255565b610ee1565b005b34801561040b57600080fd5b5061042660048036038101906104219190613136565b610f30565b005b34801561043457600080fd5b5061043d610f42565b60405161044a919061323a565b60405180910390f35b34801561045f57600080fd5b5061047a60048036038101906104759190613136565b610f48565b604051610487919061323a565b60405180910390f35b34801561049c57600080fd5b506104b760048036038101906104b29190613136565b610f9b565b005b3480156104c557600080fd5b506104e060048036038101906104db9190613136565b610fad565b6040516104ed91906131a4565b60405180910390f35b34801561050257600080fd5b5061050b610fc3565b604051610518919061323a565b60405180910390f35b34801561052d57600080fd5b5061054860048036038101906105439190613322565b610fc9565b604051610555919061323a565b60405180910390f35b34801561056a57600080fd5b506105736110b1565b005b34801561058157600080fd5b5061058a6110c5565b604051610597919061323a565b60405180910390f35b3480156105ac57600080fd5b506105c760048036038101906105c29190613136565b6110cb565b005b3480156105d557600080fd5b506105de611194565b6040516105eb91906131a4565b60405180910390f35b34801561060057600080fd5b5061061b60048036038101906106169190613136565b6111be565b005b34801561062957600080fd5b506106326111d0565b60405161063f91906130de565b60405180910390f35b34801561065457600080fd5b5061065d611262565b60405161066a919061323a565b60405180910390f35b61068d60048036038101906106889190613136565b611268565b005b34801561069b57600080fd5b506106b660048036038101906106b19190613484565b6115b7565b005b3480156106c457600080fd5b506106df60048036038101906106da91906134f9565b6115d2565b005b3480156106ed57600080fd5b506106f66115eb565b604051610703919061323a565b60405180910390f35b34801561071857600080fd5b50610733600480360381019061072e9190613136565b6115f1565b005b34801561074157600080fd5b5061075c600480360381019061075791906135da565b611603565b005b34801561076a57600080fd5b50610773611654565b604051610780919061323a565b60405180910390f35b34801561079557600080fd5b506107b060048036038101906107ab9190613136565b61165e565b6040516107bd91906130de565b60405180910390f35b3480156107d257600080fd5b506107db611705565b6040516107e8919061323a565b60405180910390f35b3480156107fd57600080fd5b5061080661170b565b604051610813919061323a565b60405180910390f35b34801561082857600080fd5b50610843600480360381019061083e9190613322565b611711565b604051610850919061323a565b60405180910390f35b34801561086557600080fd5b5061086e611729565b005b34801561087c57600080fd5b5061088561175d565b6040516108929190613033565b60405180910390f35b3480156108a757600080fd5b506108c260048036038101906108bd919061365d565b611770565b6040516108cf9190613033565b60405180910390f35b3480156108e457600080fd5b506108ff60048036038101906108fa9190613322565b611804565b005b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806109cc57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610a3457507f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610a445750610a4382611887565b5b9050919050565b606060018054610a5a906136cc565b80601f0160208091040260200160405190810160405280929190818152602001828054610a86906136cc565b8015610ad35780601f10610aa857610100808354040283529160200191610ad3565b820191906000526020600020905b815481529060010190602001808311610ab657829003601f168201915b5050505050905090565b6000610ae8826118f1565b610b27576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b1e9061376f565b60405180910390fd5b6005600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b81610b6c816118fe565b610b7683836119fb565b505050565b60008054905090565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610bc257610bc1336118fe565b5b610bcd848484611b52565b50505050565b6000610bde83610fc9565b8210610c1f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c1690613801565b60405180910390fd5b6000610c29610b7b565b905060008060005b83811015610d81576000600360008381526020019081526020016000206040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff16815250509050600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff1614610d2357806000015192505b8773ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610d7357868403610d6a578195505050505050610dbd565b83806001019450505b508080600101915050610c31565b506040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610db490613893565b60405180910390fd5b92915050565b610dcb611ba1565b600260085403610e10576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e07906138ff565b60405180910390fd5b600260088190555060003373ffffffffffffffffffffffffffffffffffffffff1647604051610e3e90613950565b60006040518083038185875af1925050503d8060008114610e7b576040519150601f19603f3d011682016040523d82523d6000602084013e610e80565b606091505b5050905080610ec4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ebb906139b1565b60405180910390fd5b506001600881905550565b6daaeb6d7670e522a718067333cd4e81565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610f1f57610f1e336118fe565b5b610f2a848484611c1f565b50505050565b610f38611ba1565b80600b8190555050565b600e5481565b6000610f52610b7b565b8210610f93576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f8a90613a43565b60405180910390fd5b819050919050565b610fa3611ba1565b8060138190555050565b6000610fb882611c7e565b600001519050919050565b60135481565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611039576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161103090613ad5565b60405180910390fd5b600460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff169050919050565b6110b9611ba1565b6110c36000611e18565b565b600c5481565b6110d3611ba1565b6000600e549050600d54826110e6610b7b565b6110f09190613b24565b1115611131576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161112890613ba4565b60405180910390fd5b81811015611174576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161116b90613c10565b60405180910390fd5b81816111809190613c30565b600e819055506111903383611ede565b5050565b6000600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6111c6611ba1565b8060118190555050565b6060600280546111df906136cc565b80601f016020809104026020016040519081016040528092919081815260200182805461120b906136cc565b80156112585780601f1061122d57610100808354040283529160200191611258565b820191906000526020600020905b81548152906001019060200180831161123b57829003601f168201915b5050505050905090565b600b5481565b6013546012541080156112bb5750601154601460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054105b1561146e57601060009054906101000a900460ff1661130f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161130690613cb0565b60405180910390fd5b600b54600b54826113209190613cd0565b61132a9190613c30565b34101561136c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161136390613d5e565b60405180910390fd5b600d5481611378610b7b565b6113829190613b24565b11156113c3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113ba90613dca565b60405180910390fd5b600c54811115611408576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113ff90613e36565b60405180910390fd5b601154601460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550601154601260008282546114629190613b24565b925050819055506115aa565b601060009054906101000a900460ff166114bd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114b490613cb0565b60405180910390fd5b600b54816114cb9190613cd0565b34101561150d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161150490613d5e565b60405180910390fd5b600d5481611519610b7b565b6115239190613b24565b1115611564576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161155b90613dca565b60405180910390fd5b600c548111156115a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115a090613e36565b60405180910390fd5b5b6115b43382611ede565b50565b6115bf611ba1565b80600f90816115ce9190613ff8565b5050565b816115dc816118fe565b6115e68383611efc565b505050565b60115481565b6115f9611ba1565b80600c8190555050565b833373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461164157611640336118fe565b5b61164d858585856120bb565b5050505050565b6000600b54905090565b6060611669826118f1565b6116a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161169f9061413c565b60405180910390fd5b60006116b2612156565b905060008151116116d257604051806020016040528060008152506116fd565b806116dc846121e8565b6040516020016116ed9291906141e4565b6040516020818303038152906040525b915050919050565b60125481565b600d5481565b60146020528060005260406000206000915090505481565b611731611ba1565b601060009054906101000a900460ff1615601060006101000a81548160ff021916908315150217905550565b601060009054906101000a900460ff1681565b6000600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b61180c611ba1565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361187b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161187290614285565b60405180910390fd5b61188481611e18565b50565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b6000805482109050919050565b60006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b11156119f8576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430836040518363ffffffff1660e01b81526004016119759291906142a5565b602060405180830381865afa158015611992573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119b691906142e3565b6119f757806040517fede71dcc0000000000000000000000000000000000000000000000000000000081526004016119ee91906131a4565b60405180910390fd5b5b50565b813373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611a3957611a38336118fe565b5b6000611a4483610fad565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603611ab4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611aab90614382565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16611ad36122b6565b73ffffffffffffffffffffffffffffffffffffffff161480611b025750611b0181611afc6122b6565b611770565b5b611b41576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b3890614414565b60405180910390fd5b611b4c8484836122be565b50505050565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611b9057611b8f336118fe565b5b611b9b848484612370565b50505050565b611ba96122b6565b73ffffffffffffffffffffffffffffffffffffffff16611bc7611194565b73ffffffffffffffffffffffffffffffffffffffff1614611c1d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c1490614480565b60405180910390fd5b565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611c5d57611c5c336118fe565b5b611c7884848460405180602001604052806000815250611603565b50505050565b611c86612f45565b611c8f826118f1565b611cce576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cc590614512565b60405180910390fd5b60008290505b60008110611dd7576000600360008381526020019081526020016000206040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff16815250509050600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff1614611dc8578092505050611e13565b50808060019003915050611cd4565b506040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e0a906145a4565b60405180910390fd5b919050565b6000600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b611ef88282604051806020016040528060008152506128ae565b5050565b813373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611f3a57611f39336118fe565b5b611f426122b6565b73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611faf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fa690614610565b60405180910390fd5b8160066000611fbc6122b6565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508273ffffffffffffffffffffffffffffffffffffffff166120696122b6565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31846040516120ae9190613033565b60405180910390a3505050565b833373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146120f9576120f8336118fe565b5b612104858585612370565b612110858585856128c0565b61214f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612146906146a2565b60405180910390fd5b5050505050565b6060600f8054612165906136cc565b80601f0160208091040260200160405190810160405280929190818152602001828054612191906136cc565b80156121de5780601f106121b3576101008083540402835291602001916121de565b820191906000526020600020905b8154815290600101906020018083116121c157829003601f168201915b5050505050905090565b6060600060016121f784612a47565b01905060008167ffffffffffffffff81111561221657612215613359565b5b6040519080825280601f01601f1916602001820160405280156122485781602001600182028036833780820191505090505b509050600082602001820190505b6001156122ab578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a858161229f5761229e6146c2565b5b04945060008503612256575b819350505050919050565b600033905090565b826005600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b600061237b82611c7e565b90506000816000015173ffffffffffffffffffffffffffffffffffffffff166123a26122b6565b73ffffffffffffffffffffffffffffffffffffffff1614806123fe57506123c76122b6565b73ffffffffffffffffffffffffffffffffffffffff166123e684610add565b73ffffffffffffffffffffffffffffffffffffffff16145b8061241a575061241982600001516124146122b6565b611770565b5b90508061245c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161245390614763565b60405180910390fd5b8473ffffffffffffffffffffffffffffffffffffffff16826000015173ffffffffffffffffffffffffffffffffffffffff16146124ce576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124c5906147f5565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff160361253d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161253490614887565b60405180910390fd5b61254a8585856001612b9a565b61255a60008484600001516122be565b6001600460008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008282829054906101000a90046fffffffffffffffffffffffffffffffff160392506101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055506001600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008282829054906101000a90046fffffffffffffffffffffffffffffffff160192506101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550836003600085815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550426003600085815260200190815260200160002060000160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506000600184019050600073ffffffffffffffffffffffffffffffffffffffff166003600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff160361283e5761279d816118f1565b1561283d5782600001516003600083815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555082602001516003600083815260200190815260200160002060000160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055505b5b50828473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46128a78585856001612ba0565b5050505050565b6128bb8383836001612ba6565b505050565b60006128e18473ffffffffffffffffffffffffffffffffffffffff16612f22565b15612a3a578373ffffffffffffffffffffffffffffffffffffffff1663150b7a0261290a6122b6565b8786866040518563ffffffff1660e01b815260040161292c94939291906148fc565b6020604051808303816000875af192505050801561296857506040513d601f19601f82011682018060405250810190612965919061495d565b60015b6129ea573d8060008114612998576040519150601f19603f3d011682016040523d82523d6000602084013e61299d565b606091505b5060008151036129e2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129d9906146a2565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050612a3f565b600190505b949350505050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310612aa5577a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008381612a9b57612a9a6146c2565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310612ae2576d04ee2d6d415b85acef81000000008381612ad857612ad76146c2565b5b0492506020810190505b662386f26fc100008310612b1157662386f26fc100008381612b0757612b066146c2565b5b0492506010810190505b6305f5e1008310612b3a576305f5e1008381612b3057612b2f6146c2565b5b0492506008810190505b6127108310612b5f576127108381612b5557612b546146c2565b5b0492506004810190505b60648310612b825760648381612b7857612b776146c2565b5b0492506002810190505b600a8310612b91576001810190505b80915050919050565b50505050565b50505050565b600080549050600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603612c1b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c12906149fc565b60405180910390fd5b60008403612c5e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c5590614a8e565b60405180910390fd5b612c6b6000868387612b9a565b83600460008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008282829054906101000a90046fffffffffffffffffffffffffffffffff160192506101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555083600460008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160108282829054906101000a90046fffffffffffffffffffffffffffffffff160192506101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550846003600083815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550426003600083815260200190815260200160002060000160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550600081905060005b85811015612f0557818773ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a48315612ef057612eb060008884886128c0565b612eef576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ee6906146a2565b60405180910390fd5b5b81806001019250508080600101915050612e39565b508060008190555050612f1b6000868387612ba0565b5050505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b6040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600067ffffffffffffffff1681525090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612fc881612f93565b8114612fd357600080fd5b50565b600081359050612fe581612fbf565b92915050565b60006020828403121561300157613000612f89565b5b600061300f84828501612fd6565b91505092915050565b60008115159050919050565b61302d81613018565b82525050565b60006020820190506130486000830184613024565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561308857808201518184015260208101905061306d565b60008484015250505050565b6000601f19601f8301169050919050565b60006130b08261304e565b6130ba8185613059565b93506130ca81856020860161306a565b6130d381613094565b840191505092915050565b600060208201905081810360008301526130f881846130a5565b905092915050565b6000819050919050565b61311381613100565b811461311e57600080fd5b50565b6000813590506131308161310a565b92915050565b60006020828403121561314c5761314b612f89565b5b600061315a84828501613121565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061318e82613163565b9050919050565b61319e81613183565b82525050565b60006020820190506131b96000830184613195565b92915050565b6131c881613183565b81146131d357600080fd5b50565b6000813590506131e5816131bf565b92915050565b6000806040838503121561320257613201612f89565b5b6000613210858286016131d6565b925050602061322185828601613121565b9150509250929050565b61323481613100565b82525050565b600060208201905061324f600083018461322b565b92915050565b60008060006060848603121561326e5761326d612f89565b5b600061327c868287016131d6565b935050602061328d868287016131d6565b925050604061329e86828701613121565b9150509250925092565b6000819050919050565b60006132cd6132c86132c384613163565b6132a8565b613163565b9050919050565b60006132df826132b2565b9050919050565b60006132f1826132d4565b9050919050565b613301816132e6565b82525050565b600060208201905061331c60008301846132f8565b92915050565b60006020828403121561333857613337612f89565b5b6000613346848285016131d6565b91505092915050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61339182613094565b810181811067ffffffffffffffff821117156133b0576133af613359565b5b80604052505050565b60006133c3612f7f565b90506133cf8282613388565b919050565b600067ffffffffffffffff8211156133ef576133ee613359565b5b6133f882613094565b9050602081019050919050565b82818337600083830152505050565b6000613427613422846133d4565b6133b9565b90508281526020810184848401111561344357613442613354565b5b61344e848285613405565b509392505050565b600082601f83011261346b5761346a61334f565b5b813561347b848260208601613414565b91505092915050565b60006020828403121561349a57613499612f89565b5b600082013567ffffffffffffffff8111156134b8576134b7612f8e565b5b6134c484828501613456565b91505092915050565b6134d681613018565b81146134e157600080fd5b50565b6000813590506134f3816134cd565b92915050565b600080604083850312156135105761350f612f89565b5b600061351e858286016131d6565b925050602061352f858286016134e4565b9150509250929050565b600067ffffffffffffffff82111561355457613553613359565b5b61355d82613094565b9050602081019050919050565b600061357d61357884613539565b6133b9565b90508281526020810184848401111561359957613598613354565b5b6135a4848285613405565b509392505050565b600082601f8301126135c1576135c061334f565b5b81356135d184826020860161356a565b91505092915050565b600080600080608085870312156135f4576135f3612f89565b5b6000613602878288016131d6565b9450506020613613878288016131d6565b935050604061362487828801613121565b925050606085013567ffffffffffffffff81111561364557613644612f8e565b5b613651878288016135ac565b91505092959194509250565b6000806040838503121561367457613673612f89565b5b6000613682858286016131d6565b9250506020613693858286016131d6565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806136e457607f821691505b6020821081036136f7576136f661369d565b5b50919050565b7f455243373231413a20617070726f76656420717565727920666f72206e6f6e6560008201527f78697374656e7420746f6b656e00000000000000000000000000000000000000602082015250565b6000613759602d83613059565b9150613764826136fd565b604082019050919050565b600060208201905081810360008301526137888161374c565b9050919050565b7f455243373231413a206f776e657220696e646578206f7574206f6620626f756e60008201527f6473000000000000000000000000000000000000000000000000000000000000602082015250565b60006137eb602283613059565b91506137f68261378f565b604082019050919050565b6000602082019050818103600083015261381a816137de565b9050919050565b7f455243373231413a20756e61626c6520746f2067657420746f6b656e206f662060008201527f6f776e657220627920696e646578000000000000000000000000000000000000602082015250565b600061387d602e83613059565b915061388882613821565b604082019050919050565b600060208201905081810360008301526138ac81613870565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b60006138e9601f83613059565b91506138f4826138b3565b602082019050919050565b60006020820190508181036000830152613918816138dc565b9050919050565b600081905092915050565b50565b600061393a60008361391f565b91506139458261392a565b600082019050919050565b600061395b8261392d565b9150819050919050565b7f5472616e73666572206661696c65642e00000000000000000000000000000000600082015250565b600061399b601083613059565b91506139a682613965565b602082019050919050565b600060208201905081810360008301526139ca8161398e565b9050919050565b7f455243373231413a20676c6f62616c20696e646578206f7574206f6620626f7560008201527f6e64730000000000000000000000000000000000000000000000000000000000602082015250565b6000613a2d602383613059565b9150613a38826139d1565b604082019050919050565b60006020820190508181036000830152613a5c81613a20565b9050919050565b7f455243373231413a2062616c616e636520717565727920666f7220746865207a60008201527f65726f2061646472657373000000000000000000000000000000000000000000602082015250565b6000613abf602b83613059565b9150613aca82613a63565b604082019050919050565b60006020820190508181036000830152613aee81613ab2565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000613b2f82613100565b9150613b3a83613100565b9250828201905080821115613b5257613b51613af5565b5b92915050565b7f4e6f206d6f726520737570706c7920746f206265206d696e7465640000000000600082015250565b6000613b8e601b83613059565b9150613b9982613b58565b602082019050919050565b60006020820190508181036000830152613bbd81613b81565b9050919050565b7f526573657276656420537570706c79204d696e74656400000000000000000000600082015250565b6000613bfa601683613059565b9150613c0582613bc4565b602082019050919050565b60006020820190508181036000830152613c2981613bed565b9050919050565b6000613c3b82613100565b9150613c4683613100565b9250828203905081811115613c5e57613c5d613af5565b5b92915050565b7f6e6f74206c697665207965740000000000000000000000000000000000000000600082015250565b6000613c9a600c83613059565b9150613ca582613c64565b602082019050919050565b60006020820190508181036000830152613cc981613c8d565b9050919050565b6000613cdb82613100565b9150613ce683613100565b9250828202613cf481613100565b91508282048414831517613d0b57613d0a613af5565b5b5092915050565b7f45746820416d6f756e7420496e76616c69640000000000000000000000000000600082015250565b6000613d48601283613059565b9150613d5382613d12565b602082019050919050565b60006020820190508181036000830152613d7781613d3b565b9050919050565b7f4e6f206d6f726520737570706c79000000000000000000000000000000000000600082015250565b6000613db4600e83613059565b9150613dbf82613d7e565b602082019050919050565b60006020820190508181036000830152613de381613da7565b9050919050565b7f4d61782070657220545820726561636865642e00000000000000000000000000600082015250565b6000613e20601383613059565b9150613e2b82613dea565b602082019050919050565b60006020820190508181036000830152613e4f81613e13565b9050919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302613eb87fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82613e7b565b613ec28683613e7b565b95508019841693508086168417925050509392505050565b6000613ef5613ef0613eeb84613100565b6132a8565b613100565b9050919050565b6000819050919050565b613f0f83613eda565b613f23613f1b82613efc565b848454613e88565b825550505050565b600090565b613f38613f2b565b613f43818484613f06565b505050565b5b81811015613f6757613f5c600082613f30565b600181019050613f49565b5050565b601f821115613fac57613f7d81613e56565b613f8684613e6b565b81016020851015613f95578190505b613fa9613fa185613e6b565b830182613f48565b50505b505050565b600082821c905092915050565b6000613fcf60001984600802613fb1565b1980831691505092915050565b6000613fe88383613fbe565b9150826002028217905092915050565b6140018261304e565b67ffffffffffffffff81111561401a57614019613359565b5b61402482546136cc565b61402f828285613f6b565b600060209050601f8311600181146140625760008415614050578287015190505b61405a8582613fdc565b8655506140c2565b601f19841661407086613e56565b60005b8281101561409857848901518255600182019150602085019450602081019050614073565b868310156140b557848901516140b1601f891682613fbe565b8355505b6001600288020188555050505b505050505050565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b6000614126602f83613059565b9150614131826140ca565b604082019050919050565b6000602082019050818103600083015261415581614119565b9050919050565b600081905092915050565b60006141728261304e565b61417c818561415c565b935061418c81856020860161306a565b80840191505092915050565b7f2e6a736f6e000000000000000000000000000000000000000000000000000000600082015250565b60006141ce60058361415c565b91506141d982614198565b600582019050919050565b60006141f08285614167565b91506141fc8284614167565b9150614207826141c1565b91508190509392505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b600061426f602683613059565b915061427a82614213565b604082019050919050565b6000602082019050818103600083015261429e81614262565b9050919050565b60006040820190506142ba6000830185613195565b6142c76020830184613195565b9392505050565b6000815190506142dd816134cd565b92915050565b6000602082840312156142f9576142f8612f89565b5b6000614307848285016142ce565b91505092915050565b7f455243373231413a20617070726f76616c20746f2063757272656e74206f776e60008201527f6572000000000000000000000000000000000000000000000000000000000000602082015250565b600061436c602283613059565b915061437782614310565b604082019050919050565b6000602082019050818103600083015261439b8161435f565b9050919050565b7f455243373231413a20617070726f76652063616c6c6572206973206e6f74206f60008201527f776e6572206e6f7220617070726f76656420666f7220616c6c00000000000000602082015250565b60006143fe603983613059565b9150614409826143a2565b604082019050919050565b6000602082019050818103600083015261442d816143f1565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b600061446a602083613059565b915061447582614434565b602082019050919050565b600060208201905081810360008301526144998161445d565b9050919050565b7f455243373231413a206f776e657220717565727920666f72206e6f6e6578697360008201527f74656e7420746f6b656e00000000000000000000000000000000000000000000602082015250565b60006144fc602a83613059565b9150614507826144a0565b604082019050919050565b6000602082019050818103600083015261452b816144ef565b9050919050565b7f455243373231413a20756e61626c6520746f2064657465726d696e652074686560008201527f206f776e6572206f6620746f6b656e0000000000000000000000000000000000602082015250565b600061458e602f83613059565b915061459982614532565b604082019050919050565b600060208201905081810360008301526145bd81614581565b9050919050565b7f455243373231413a20617070726f766520746f2063616c6c6572000000000000600082015250565b60006145fa601a83613059565b9150614605826145c4565b602082019050919050565b60006020820190508181036000830152614629816145ed565b9050919050565b7f455243373231413a207472616e7366657220746f206e6f6e204552433732315260008201527f6563656976657220696d706c656d656e74657200000000000000000000000000602082015250565b600061468c603383613059565b915061469782614630565b604082019050919050565b600060208201905081810360008301526146bb8161467f565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f455243373231413a207472616e736665722063616c6c6572206973206e6f742060008201527f6f776e6572206e6f7220617070726f7665640000000000000000000000000000602082015250565b600061474d603283613059565b9150614758826146f1565b604082019050919050565b6000602082019050818103600083015261477c81614740565b9050919050565b7f455243373231413a207472616e736665722066726f6d20696e636f727265637460008201527f206f776e65720000000000000000000000000000000000000000000000000000602082015250565b60006147df602683613059565b91506147ea82614783565b604082019050919050565b6000602082019050818103600083015261480e816147d2565b9050919050565b7f455243373231413a207472616e7366657220746f20746865207a65726f20616460008201527f6472657373000000000000000000000000000000000000000000000000000000602082015250565b6000614871602583613059565b915061487c82614815565b604082019050919050565b600060208201905081810360008301526148a081614864565b9050919050565b600081519050919050565b600082825260208201905092915050565b60006148ce826148a7565b6148d881856148b2565b93506148e881856020860161306a565b6148f181613094565b840191505092915050565b60006080820190506149116000830187613195565b61491e6020830186613195565b61492b604083018561322b565b818103606083015261493d81846148c3565b905095945050505050565b60008151905061495781612fbf565b92915050565b60006020828403121561497357614972612f89565b5b600061498184828501614948565b91505092915050565b7f455243373231413a206d696e7420746f20746865207a65726f2061646472657360008201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b60006149e6602183613059565b91506149f18261498a565b604082019050919050565b60006020820190508181036000830152614a15816149d9565b9050919050565b7f455243373231413a207175616e74697479206d7573742062652067726561746560008201527f72207468616e2030000000000000000000000000000000000000000000000000602082015250565b6000614a78602883613059565b9150614a8382614a1c565b604082019050919050565b60006020820190508181036000830152614aa781614a6b565b905091905056fea264697066735822122064144292b69dd7a2dec2b80ff458380abed66226cde58328f59154a2084dac1564736f6c63430008130033

Deployed Bytecode Sourcemap

100822:4309:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;80500:372;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;82023:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;83143:214;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;104191:157;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;79301:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;104356:163;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;79604:886;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;104942:186;;;;;;;;;;;;;:::i;:::-;;40348:143;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;104527:171;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;103452:85;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;101128:34;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;79409:187;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;103732:129;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;81891:124;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;101312:39;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;80880:221;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;90948:103;;;;;;;;;;;;;:::i;:::-;;101042:33;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;102890:360;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;90300:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;103869:130;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;82131:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;100990:45;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;101992:890;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;103346:98;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;104007:176;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;101229:41;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;103638:86;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;104706:228;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;103545:84;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;101473:395;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;101277:28;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;101082:39;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;101364:52;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;103258:81;;;;;;;;;;;;;:::i;:::-;;101198:22;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;83699:164;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;91206:201;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;80500:372;80602:4;80654:25;80639:40;;;:11;:40;;;;:105;;;;80711:33;80696:48;;;:11;:48;;;;80639:105;:172;;;;80776:35;80761:50;;;:11;:50;;;;80639:172;:225;;;;80828:36;80852:11;80828:23;:36::i;:::-;80639:225;80619:245;;80500:372;;;:::o;82023:100::-;82077:13;82110:5;82103:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;82023:100;:::o;83143:214::-;83211:7;83239:16;83247:7;83239;:16::i;:::-;83231:74;;;;;;;;;;;;:::i;:::-;;;;;;;;;83325:15;:24;83341:7;83325:24;;;;;;;;;;;;;;;;;;;;;83318:31;;83143:214;;;:::o;104191:157::-;104287:8;41869:30;41890:8;41869:20;:30::i;:::-;104308:32:::1;104322:8;104332:7;104308:13;:32::i;:::-;104191:157:::0;;;:::o;79301:100::-;79354:7;79381:12;;79374:19;;79301:100;:::o;104356:163::-;104457:4;41697:10;41689:18;;:4;:18;;;41685:83;;41724:32;41745:10;41724:20;:32::i;:::-;41685:83;104474:37:::1;104493:4;104499:2;104503:7;104474:18;:37::i;:::-;104356:163:::0;;;;:::o;79604:886::-;79693:7;79729:16;79739:5;79729:9;:16::i;:::-;79721:5;:24;79713:71;;;;;;;;;;;;:::i;:::-;;;;;;;;;79795:22;79820:13;:11;:13::i;:::-;79795:38;;79844:19;79874:25;79942:9;79937:466;79957:14;79953:1;:18;79937:466;;;79997:31;80031:11;:14;80043:1;80031:14;;;;;;;;;;;79997:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;80094:1;80068:28;;:9;:14;;;:28;;;80064:111;;80141:9;:14;;;80121:34;;80064:111;80218:5;80197:26;;:17;:26;;;80193:195;;80267:5;80252:11;:20;80248:85;;80308:1;80301:8;;;;;;;;;80248:85;80355:13;;;;;;;80193:195;79978:425;79973:3;;;;;;;79937:466;;;;80426:56;;;;;;;;;;:::i;:::-;;;;;;;;79604:886;;;;;:::o;104942:186::-;90186:13;:11;:13::i;:::-;76983:1:::1;77133:7;;:19:::0;77125:63:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;76983:1;77201:7;:18;;;;105006:12:::2;105024:10;:15;;105047:21;105024:49;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;105005:68;;;105092:7;105084:36;;;;;;;;;;;;:::i;:::-;;;;;;;;;104994:134;76939:1:::1;77246:7;:22;;;;104942:186::o:0;40348:143::-;40448:42;40348:143;:::o;104527:171::-;104632:4;41697:10;41689:18;;:4;:18;;;41685:83;;41724:32;41745:10;41724:20;:32::i;:::-;41685:83;104649:41:::1;104672:4;104678:2;104682:7;104649:22;:41::i;:::-;104527:171:::0;;;;:::o;103452:85::-;90186:13;:11;:13::i;:::-;103523:6:::1;103515:5;:14;;;;103452:85:::0;:::o;101128:34::-;;;;:::o;79409:187::-;79476:7;79512:13;:11;:13::i;:::-;79504:5;:21;79496:69;;;;;;;;;;;;:::i;:::-;;;;;;;;;79583:5;79576:12;;79409:187;;;:::o;103732:129::-;90186:13;:11;:13::i;:::-;103840::::1;103819:18;:34;;;;103732:129:::0;:::o;81891:124::-;81955:7;81982:20;81994:7;81982:11;:20::i;:::-;:25;;;81975:32;;81891:124;;;:::o;101312:39::-;;;;:::o;80880:221::-;80944:7;80989:1;80972:19;;:5;:19;;;80964:75;;;;;;;;;;;;:::i;:::-;;;;;;;;;81065:12;:19;81078:5;81065:19;;;;;;;;;;;;;;;:27;;;;;;;;;;;;81057:36;;81050:43;;80880:221;;;:::o;90948:103::-;90186:13;:11;:13::i;:::-;91013:30:::1;91040:1;91013:18;:30::i;:::-;90948:103::o:0;101042:33::-;;;;:::o;102890:360::-;90186:13;:11;:13::i;:::-;102963:17:::1;102983:14;;102963:34;;103044:9;;103034:6;103018:13;:11;:13::i;:::-;:22;;;;:::i;:::-;:35;;103010:75;;;;;;;;;;;;:::i;:::-;;;;;;;;;103117:6;103104:9;:19;;103096:54;;;;;;;;;;;;:::i;:::-;;;;;;;;;103196:6;103184:9;:18;;;;:::i;:::-;103167:14;:35;;;;103213:29;103223:10;103235:6;103213:9;:29::i;:::-;102952:298;102890:360:::0;:::o;90300:87::-;90346:7;90373:6;;;;;;;;;;;90366:13;;90300:87;:::o;103869:130::-;90186:13;:11;:13::i;:::-;103974:17:::1;103955:16;:36;;;;103869:130:::0;:::o;82131:104::-;82187:13;82220:7;82213:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;82131:104;:::o;100990:45::-;;;;:::o;101992:890::-;102078:18;;102065:10;;:31;102064:87;;;;;102134:16;;102102:17;:29;102120:10;102102:29;;;;;;;;;;;;;;;;:48;102064:87;102060:773;;;102177:8;;;;;;;;;;;102169:33;;;;;;;;;;;;:::i;:::-;;;;;;;;;102257:5;;102248;;102239:6;:14;;;;:::i;:::-;102238:24;;;;:::i;:::-;102225:9;:37;;102217:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;102334:9;;102324:6;102308:13;:11;:13::i;:::-;:22;;;;:::i;:::-;:35;;102300:62;;;;;;;;;;;;:::i;:::-;;;;;;;;;102395:5;;102385:6;:15;;102377:47;;;;;;;;;;;;:::i;:::-;;;;;;;;;102471:16;;102439:17;:29;102457:10;102439:29;;;;;;;;;;;;;;;:48;;;;102516:16;;102502:10;;:30;;;;;;;:::i;:::-;;;;;;;;102060:773;;;102584:8;;;;;;;;;;;102576:33;;;;;;;;;;;;:::i;:::-;;;;;;;;;102654:5;;102645:6;:14;;;;:::i;:::-;102632:9;:27;;102624:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;102731:9;;102721:6;102705:13;:11;:13::i;:::-;:22;;;;:::i;:::-;:35;;102697:62;;;;;;;;;;;;:::i;:::-;;;;;;;;;102792:5;;102782:6;:15;;102774:47;;;;;;;;;;;;:::i;:::-;;;;;;;;;102060:773;102845:29;102855:10;102867:6;102845:9;:29::i;:::-;101992:890;:::o;103346:98::-;90186:13;:11;:13::i;:::-;103428:8:::1;103418:7;:18;;;;;;:::i;:::-;;103346:98:::0;:::o;104007:176::-;104111:8;41869:30;41890:8;41869:20;:30::i;:::-;104132:43:::1;104156:8;104166;104132:23;:43::i;:::-;104007:176:::0;;;:::o;101229:41::-;;;;:::o;103638:86::-;90186:13;:11;:13::i;:::-;103710:6:::1;103702:5;:14;;;;103638:86:::0;:::o;104706:228::-;104857:4;41697:10;41689:18;;:4;:18;;;41685:83;;41724:32;41745:10;41724:20;:32::i;:::-;41685:83;104879:47:::1;104902:4;104908:2;104912:7;104921:4;104879:22;:47::i;:::-;104706:228:::0;;;;;:::o;103545:84::-;103589:7;103616:5;;103609:12;;103545:84;:::o;101473:395::-;101547:13;101581:17;101589:8;101581:7;:17::i;:::-;101573:76;;;;;;;;;;;;:::i;:::-;;;;;;;;;101660:28;101691:10;:8;:10::i;:::-;101660:41;;101750:1;101725:14;101719:28;:32;:141;;;;;;;;;;;;;;;;;101791:14;101806:26;101823:8;101806:16;:26::i;:::-;101774:67;;;;;;;;;:::i;:::-;;;;;;;;;;;;;101719:141;101712:148;;;101473:395;;;:::o;101277:28::-;;;;:::o;101082:39::-;;;;:::o;101364:52::-;;;;;;;;;;;;;;;;;:::o;103258:81::-;90186:13;:11;:13::i;:::-;103323:8:::1;;;;;;;;;;;103322:9;103311:8;;:20;;;;;;;;;;;;;;;;;;103258:81::o:0;101198:22::-;;;;;;;;;;;;;:::o;83699:164::-;83796:4;83820:18;:25;83839:5;83820:25;;;;;;;;;;;;;;;:35;83846:8;83820:35;;;;;;;;;;;;;;;;;;;;;;;;;83813:42;;83699:164;;;;:::o;91206:201::-;90186:13;:11;:13::i;:::-;91315:1:::1;91295:22;;:8;:22;;::::0;91287:73:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;91371:28;91390:8;91371:18;:28::i;:::-;91206:201:::0;:::o;70370:157::-;70455:4;70494:25;70479:40;;;:11;:40;;;;70472:47;;70370:157;;;:::o;84689:111::-;84746:4;84780:12;;84770:7;:22;84763:29;;84689:111;;;:::o;41927:419::-;42166:1;40448:42;42118:45;;;:49;42114:225;;;40448:42;42189;;;42240:4;42247:8;42189:67;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;42184:144;;42303:8;42284:28;;;;;;;;;;;:::i;:::-;;;;;;;;42184:144;42114:225;41927:419;:::o;82690:445::-;82780:2;41697:10;41689:18;;:4;:18;;;41685:83;;41724:32;41745:10;41724:20;:32::i;:::-;41685:83;82795:13:::1;82811:24;82827:7;82811:15;:24::i;:::-;82795:40;;82860:5;82854:11;;:2;:11;;::::0;82846:58:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;82955:5;82939:21;;:12;:10;:12::i;:::-;:21;;;:62;;;;82964:37;82981:5;82988:12;:10;:12::i;:::-;82964:16;:37::i;:::-;82939:62;82917:169;;;;;;;;;;;;:::i;:::-;;;;;;;;;83099:28;83108:2;83112:7;83121:5;83099:8;:28::i;:::-;82784:351;82690:445:::0;;;:::o;83871:195::-;84014:4;41697:10;41689:18;;:4;:18;;;41685:83;;41724:32;41745:10;41724:20;:32::i;:::-;41685:83;84030:28:::1;84040:4;84046:2;84050:7;84030:9;:28::i;:::-;83871:195:::0;;;;:::o;90465:132::-;90540:12;:10;:12::i;:::-;90529:23;;:7;:5;:7::i;:::-;:23;;;90521:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;90465:132::o;84074:211::-;84221:4;41697:10;41689:18;;:4;:18;;;41685:83;;41724:32;41745:10;41724:20;:32::i;:::-;41685:83;84238:39:::1;84255:4;84261:2;84265:7;84238:39;;;;;;;;;;;::::0;:16:::1;:39::i;:::-;84074:211:::0;;;;:::o;81346:537::-;81407:21;;:::i;:::-;81449:16;81457:7;81449;:16::i;:::-;81441:71;;;;;;;;;;;;:::i;:::-;;;;;;;;;81555:12;81570:7;81555:22;;81550:245;81587:1;81579:4;:9;81550:245;;81617:31;81651:11;:17;81663:4;81651:17;;;;;;;;;;;81617:51;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;81717:1;81691:28;;:9;:14;;;:28;;;81687:93;;81751:9;81744:16;;;;;;81687:93;81598:197;81590:6;;;;;;;;81550:245;;;;81818:57;;;;;;;;;;:::i;:::-;;;;;;;;81346:537;;;;:::o;91567:191::-;91641:16;91660:6;;;;;;;;;;;91641:25;;91686:8;91677:6;;:17;;;;;;;;;;;;;;;;;;91741:8;91710:40;;91731:8;91710:40;;;;;;;;;;;;91630:128;91567:191;:::o;84808:104::-;84877:27;84887:2;84891:8;84877:27;;;;;;;;;;;;:9;:27::i;:::-;84808:104;;:::o;83365:326::-;83469:8;41697:10;41689:18;;:4;:18;;;41685:83;;41724:32;41745:10;41724:20;:32::i;:::-;41685:83;83510:12:::1;:10;:12::i;:::-;83498:24;;:8;:24;;::::0;83490:63:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;83611:8;83566:18;:32;83585:12;:10;:12::i;:::-;83566:32;;;;;;;;;;;;;;;:42;83599:8;83566:42;;;;;;;;;;;;;;;;:53;;;;;;;;;;;;;;;;;;83664:8;83635:48;;83650:12;:10;:12::i;:::-;83635:48;;;83674:8;83635:48;;;;;;:::i;:::-;;;;;;;;83365:326:::0;;;:::o;84293:388::-;84469:4;41697:10;41689:18;;:4;:18;;;41685:83;;41724:32;41745:10;41724:20;:32::i;:::-;41685:83;84485:28:::1;84495:4;84501:2;84505:7;84485:9;:28::i;:::-;84546:48;84569:4;84575:2;84579:7;84588:5;84546:22;:48::i;:::-;84524:149;;;;;;;;;;;;:::i;:::-;;;;;;;;;84293:388:::0;;;;;:::o;101876:108::-;101936:13;101969:7;101962:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;101876:108;:::o;56132:716::-;56188:13;56239:14;56276:1;56256:17;56267:5;56256:10;:17::i;:::-;:21;56239:38;;56292:20;56326:6;56315:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56292:41;;56348:11;56477:6;56473:2;56469:15;56461:6;56457:28;56450:35;;56514:288;56521:4;56514:288;;;56546:5;;;;;;;;56688:8;56683:2;56676:5;56672:14;56667:30;56662:3;56654:44;56744:2;56735:11;;;;;;:::i;:::-;;;;;56778:1;56769:5;:10;56514:288;56765:21;56514:288;56823:6;56816:13;;;;;56132:716;;;:::o;77908:98::-;77961:7;77988:10;77981:17;;77908:98;:::o;87873:196::-;88015:2;87988:15;:24;88004:7;87988:24;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;88053:7;88049:2;88033:28;;88042:5;88033:28;;;;;;;;;;;;87873:196;;;:::o;86398:1467::-;86513:35;86551:20;86563:7;86551:11;:20::i;:::-;86513:58;;86584:22;86626:13;:18;;;86610:34;;:12;:10;:12::i;:::-;:34;;;:87;;;;86685:12;:10;:12::i;:::-;86661:36;;:20;86673:7;86661:11;:20::i;:::-;:36;;;86610:87;:154;;;;86714:50;86731:13;:18;;;86751:12;:10;:12::i;:::-;86714:16;:50::i;:::-;86610:154;86584:181;;86786:17;86778:80;;;;;;;;;;;;:::i;:::-;;;;;;;;;86901:4;86879:26;;:13;:18;;;:26;;;86871:77;;;;;;;;;;;;:::i;:::-;;;;;;;;;86981:1;86967:16;;:2;:16;;;86959:66;;;;;;;;;;;;:::i;:::-;;;;;;;;;87038:43;87060:4;87066:2;87070:7;87079:1;87038:21;:43::i;:::-;87094:49;87111:1;87115:7;87124:13;:18;;;87094:8;:49::i;:::-;87221:1;87191:12;:18;87204:4;87191:18;;;;;;;;;;;;;;;:26;;;:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;87265:1;87237:12;:16;87250:2;87237:16;;;;;;;;;;;;;;;:24;;;:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;87311:2;87283:11;:20;87295:7;87283:20;;;;;;;;;;;:25;;;:30;;;;;;;;;;;;;;;;;;87373:15;87328:11;:20;87340:7;87328:20;;;;;;;;;;;:35;;;:61;;;;;;;;;;;;;;;;;;87406:19;87438:1;87428:7;:11;87406:33;;87499:1;87458:43;;:11;:24;87470:11;87458:24;;;;;;;;;;;:29;;;;;;;;;;;;:43;;;87454:295;;87526:20;87534:11;87526:7;:20::i;:::-;87522:212;;;87603:13;:18;;;87571:11;:24;87583:11;87571:24;;;;;;;;;;;:29;;;:50;;;;;;;;;;;;;;;;;;87686:13;:28;;;87644:11;:24;87656:11;87644:24;;;;;;;;;;;:39;;;:70;;;;;;;;;;;;;;;;;;87522:212;87454:295;87166:594;87796:7;87792:2;87777:27;;87786:4;87777:27;;;;;;;;;;;;87815:42;87836:4;87842:2;87846:7;87855:1;87815:20;:42::i;:::-;86502:1363;;86398:1467;;;:::o;84920:163::-;85043:32;85049:2;85053:8;85063:5;85070:4;85043:5;:32::i;:::-;84920:163;;;:::o;88077:804::-;88232:4;88253:15;:2;:13;;;:15::i;:::-;88249:625;;;88305:2;88289:36;;;88326:12;:10;:12::i;:::-;88340:4;88346:7;88355:5;88289:72;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;88285:534;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;88552:1;88535:6;:13;:18;88531:273;;88578:61;;;;;;;;;;:::i;:::-;;;;;;;;88531:273;88754:6;88748:13;88739:6;88735:2;88731:15;88724:38;88285:534;88422:45;;;88412:55;;;:6;:55;;;;88405:62;;;;;88249:625;88858:4;88851:11;;88077:804;;;;;;;:::o;52998:922::-;53051:7;53071:14;53088:1;53071:18;;53138:6;53129:5;:15;53125:102;;53174:6;53165:15;;;;;;:::i;:::-;;;;;53209:2;53199:12;;;;53125:102;53254:6;53245:5;:15;53241:102;;53290:6;53281:15;;;;;;:::i;:::-;;;;;53325:2;53315:12;;;;53241:102;53370:6;53361:5;:15;53357:102;;53406:6;53397:15;;;;;;:::i;:::-;;;;;53441:2;53431:12;;;;53357:102;53486:5;53477;:14;53473:99;;53521:5;53512:14;;;;;;:::i;:::-;;;;;53555:1;53545:11;;;;53473:99;53599:5;53590;:14;53586:99;;53634:5;53625:14;;;;;;:::i;:::-;;;;;53668:1;53658:11;;;;53586:99;53712:5;53703;:14;53699:99;;53747:5;53738:14;;;;;;:::i;:::-;;;;;53781:1;53771:11;;;;53699:99;53825:5;53816;:14;53812:66;;53861:1;53851:11;;;;53812:66;53906:6;53899:13;;;52998:922;;;:::o;88889:159::-;;;;;:::o;89056:158::-;;;;;:::o;85091:1298::-;85230:20;85253:12;;85230:35;;85298:1;85284:16;;:2;:16;;;85276:62;;;;;;;;;;;;:::i;:::-;;;;;;;;;85369:1;85357:8;:13;85349:66;;;;;;;;;;;;:::i;:::-;;;;;;;;;85428:61;85458:1;85462:2;85466:12;85480:8;85428:21;:61::i;:::-;85563:8;85527:12;:16;85540:2;85527:16;;;;;;;;;;;;;;;:24;;;:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;85628:8;85587:12;:16;85600:2;85587:16;;;;;;;;;;;;;;;:29;;;:50;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;85687:2;85654:11;:25;85666:12;85654:25;;;;;;;;;;;:30;;;:35;;;;;;;;;;;;;;;;;;85754:15;85704:11;:25;85716:12;85704:25;;;;;;;;;;;:40;;;:66;;;;;;;;;;;;;;;;;;85787:20;85810:12;85787:35;;85844:9;85839:415;85859:8;85855:1;:12;85839:415;;;85923:12;85919:2;85898:38;;85915:1;85898:38;;;;;;;;;;;;85959:4;85955:249;;;86022:59;86053:1;86057:2;86061:12;86075:5;86022:22;:59::i;:::-;85988:196;;;;;;;;;;;;:::i;:::-;;;;;;;;;85955:249;86224:14;;;;;;;85869:3;;;;;;;85839:415;;;;86285:12;86270;:27;;;;85502:807;86321:60;86350:1;86354:2;86358:12;86372:8;86321:20;:60::i;:::-;85219:1170;85091:1298;;;;:::o;59259:326::-;59319:4;59576:1;59554:7;:19;;;:23;59547:30;;59259:326;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;:::o;7:75:1:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:149;370:7;410:66;403:5;399:78;388:89;;334:149;;;:::o;489:120::-;561:23;578:5;561:23;:::i;:::-;554:5;551:34;541:62;;599:1;596;589:12;541:62;489:120;:::o;615:137::-;660:5;698:6;685:20;676:29;;714:32;740:5;714:32;:::i;:::-;615:137;;;;:::o;758:327::-;816:6;865:2;853:9;844:7;840:23;836:32;833:119;;;871:79;;:::i;:::-;833:119;991:1;1016:52;1060:7;1051:6;1040:9;1036:22;1016:52;:::i;:::-;1006:62;;962:116;758:327;;;;:::o;1091:90::-;1125:7;1168:5;1161:13;1154:21;1143:32;;1091:90;;;:::o;1187:109::-;1268:21;1283:5;1268:21;:::i;:::-;1263:3;1256:34;1187:109;;:::o;1302:210::-;1389:4;1427:2;1416:9;1412:18;1404:26;;1440:65;1502:1;1491:9;1487:17;1478:6;1440:65;:::i;:::-;1302:210;;;;:::o;1518:99::-;1570:6;1604:5;1598:12;1588:22;;1518:99;;;:::o;1623:169::-;1707:11;1741:6;1736:3;1729:19;1781:4;1776:3;1772:14;1757:29;;1623:169;;;;:::o;1798:246::-;1879:1;1889:113;1903:6;1900:1;1897:13;1889:113;;;1988:1;1983:3;1979:11;1973:18;1969:1;1964:3;1960:11;1953:39;1925:2;1922:1;1918:10;1913:15;;1889:113;;;2036:1;2027:6;2022:3;2018:16;2011:27;1860:184;1798:246;;;:::o;2050:102::-;2091:6;2142:2;2138:7;2133:2;2126:5;2122:14;2118:28;2108:38;;2050:102;;;:::o;2158:377::-;2246:3;2274:39;2307:5;2274:39;:::i;:::-;2329:71;2393:6;2388:3;2329:71;:::i;:::-;2322:78;;2409:65;2467:6;2462:3;2455:4;2448:5;2444:16;2409:65;:::i;:::-;2499:29;2521:6;2499:29;:::i;:::-;2494:3;2490:39;2483:46;;2250:285;2158:377;;;;:::o;2541:313::-;2654:4;2692:2;2681:9;2677:18;2669:26;;2741:9;2735:4;2731:20;2727:1;2716:9;2712:17;2705:47;2769:78;2842:4;2833:6;2769:78;:::i;:::-;2761:86;;2541:313;;;;:::o;2860:77::-;2897:7;2926:5;2915:16;;2860:77;;;:::o;2943:122::-;3016:24;3034:5;3016:24;:::i;:::-;3009:5;3006:35;2996:63;;3055:1;3052;3045:12;2996:63;2943:122;:::o;3071:139::-;3117:5;3155:6;3142:20;3133:29;;3171:33;3198:5;3171:33;:::i;:::-;3071:139;;;;:::o;3216:329::-;3275:6;3324:2;3312:9;3303:7;3299:23;3295:32;3292:119;;;3330:79;;:::i;:::-;3292:119;3450:1;3475:53;3520:7;3511:6;3500:9;3496:22;3475:53;:::i;:::-;3465:63;;3421:117;3216:329;;;;:::o;3551:126::-;3588:7;3628:42;3621:5;3617:54;3606:65;;3551:126;;;:::o;3683:96::-;3720:7;3749:24;3767:5;3749:24;:::i;:::-;3738:35;;3683:96;;;:::o;3785:118::-;3872:24;3890:5;3872:24;:::i;:::-;3867:3;3860:37;3785:118;;:::o;3909:222::-;4002:4;4040:2;4029:9;4025:18;4017:26;;4053:71;4121:1;4110:9;4106:17;4097:6;4053:71;:::i;:::-;3909:222;;;;:::o;4137:122::-;4210:24;4228:5;4210:24;:::i;:::-;4203:5;4200:35;4190:63;;4249:1;4246;4239:12;4190:63;4137:122;:::o;4265:139::-;4311:5;4349:6;4336:20;4327:29;;4365:33;4392:5;4365:33;:::i;:::-;4265:139;;;;:::o;4410:474::-;4478:6;4486;4535:2;4523:9;4514:7;4510:23;4506:32;4503:119;;;4541:79;;:::i;:::-;4503:119;4661:1;4686:53;4731:7;4722:6;4711:9;4707:22;4686:53;:::i;:::-;4676:63;;4632:117;4788:2;4814:53;4859:7;4850:6;4839:9;4835:22;4814:53;:::i;:::-;4804:63;;4759:118;4410:474;;;;;:::o;4890:118::-;4977:24;4995:5;4977:24;:::i;:::-;4972:3;4965:37;4890:118;;:::o;5014:222::-;5107:4;5145:2;5134:9;5130:18;5122:26;;5158:71;5226:1;5215:9;5211:17;5202:6;5158:71;:::i;:::-;5014:222;;;;:::o;5242:619::-;5319:6;5327;5335;5384:2;5372:9;5363:7;5359:23;5355:32;5352:119;;;5390:79;;:::i;:::-;5352:119;5510:1;5535:53;5580:7;5571:6;5560:9;5556:22;5535:53;:::i;:::-;5525:63;;5481:117;5637:2;5663:53;5708:7;5699:6;5688:9;5684:22;5663:53;:::i;:::-;5653:63;;5608:118;5765:2;5791:53;5836:7;5827:6;5816:9;5812:22;5791:53;:::i;:::-;5781:63;;5736:118;5242:619;;;;;:::o;5867:60::-;5895:3;5916:5;5909:12;;5867:60;;;:::o;5933:142::-;5983:9;6016:53;6034:34;6043:24;6061:5;6043:24;:::i;:::-;6034:34;:::i;:::-;6016:53;:::i;:::-;6003:66;;5933:142;;;:::o;6081:126::-;6131:9;6164:37;6195:5;6164:37;:::i;:::-;6151:50;;6081:126;;;:::o;6213:157::-;6294:9;6327:37;6358:5;6327:37;:::i;:::-;6314:50;;6213:157;;;:::o;6376:193::-;6494:68;6556:5;6494:68;:::i;:::-;6489:3;6482:81;6376:193;;:::o;6575:284::-;6699:4;6737:2;6726:9;6722:18;6714:26;;6750:102;6849:1;6838:9;6834:17;6825:6;6750:102;:::i;:::-;6575:284;;;;:::o;6865:329::-;6924:6;6973:2;6961:9;6952:7;6948:23;6944:32;6941:119;;;6979:79;;:::i;:::-;6941:119;7099:1;7124:53;7169:7;7160:6;7149:9;7145:22;7124:53;:::i;:::-;7114:63;;7070:117;6865:329;;;;:::o;7200:117::-;7309:1;7306;7299:12;7323:117;7432:1;7429;7422:12;7446:180;7494:77;7491:1;7484:88;7591:4;7588:1;7581:15;7615:4;7612:1;7605:15;7632:281;7715:27;7737:4;7715:27;:::i;:::-;7707:6;7703:40;7845:6;7833:10;7830:22;7809:18;7797:10;7794:34;7791:62;7788:88;;;7856:18;;:::i;:::-;7788:88;7896:10;7892:2;7885:22;7675:238;7632:281;;:::o;7919:129::-;7953:6;7980:20;;:::i;:::-;7970:30;;8009:33;8037:4;8029:6;8009:33;:::i;:::-;7919:129;;;:::o;8054:308::-;8116:4;8206:18;8198:6;8195:30;8192:56;;;8228:18;;:::i;:::-;8192:56;8266:29;8288:6;8266:29;:::i;:::-;8258:37;;8350:4;8344;8340:15;8332:23;;8054:308;;;:::o;8368:146::-;8465:6;8460:3;8455;8442:30;8506:1;8497:6;8492:3;8488:16;8481:27;8368:146;;;:::o;8520:425::-;8598:5;8623:66;8639:49;8681:6;8639:49;:::i;:::-;8623:66;:::i;:::-;8614:75;;8712:6;8705:5;8698:21;8750:4;8743:5;8739:16;8788:3;8779:6;8774:3;8770:16;8767:25;8764:112;;;8795:79;;:::i;:::-;8764:112;8885:54;8932:6;8927:3;8922;8885:54;:::i;:::-;8604:341;8520:425;;;;;:::o;8965:340::-;9021:5;9070:3;9063:4;9055:6;9051:17;9047:27;9037:122;;9078:79;;:::i;:::-;9037:122;9195:6;9182:20;9220:79;9295:3;9287:6;9280:4;9272:6;9268:17;9220:79;:::i;:::-;9211:88;;9027:278;8965:340;;;;:::o;9311:509::-;9380:6;9429:2;9417:9;9408:7;9404:23;9400:32;9397:119;;;9435:79;;:::i;:::-;9397:119;9583:1;9572:9;9568:17;9555:31;9613:18;9605:6;9602:30;9599:117;;;9635:79;;:::i;:::-;9599:117;9740:63;9795:7;9786:6;9775:9;9771:22;9740:63;:::i;:::-;9730:73;;9526:287;9311:509;;;;:::o;9826:116::-;9896:21;9911:5;9896:21;:::i;:::-;9889:5;9886:32;9876:60;;9932:1;9929;9922:12;9876:60;9826:116;:::o;9948:133::-;9991:5;10029:6;10016:20;10007:29;;10045:30;10069:5;10045:30;:::i;:::-;9948:133;;;;:::o;10087:468::-;10152:6;10160;10209:2;10197:9;10188:7;10184:23;10180:32;10177:119;;;10215:79;;:::i;:::-;10177:119;10335:1;10360:53;10405:7;10396:6;10385:9;10381:22;10360:53;:::i;:::-;10350:63;;10306:117;10462:2;10488:50;10530:7;10521:6;10510:9;10506:22;10488:50;:::i;:::-;10478:60;;10433:115;10087:468;;;;;:::o;10561:307::-;10622:4;10712:18;10704:6;10701:30;10698:56;;;10734:18;;:::i;:::-;10698:56;10772:29;10794:6;10772:29;:::i;:::-;10764:37;;10856:4;10850;10846:15;10838:23;;10561:307;;;:::o;10874:423::-;10951:5;10976:65;10992:48;11033:6;10992:48;:::i;:::-;10976:65;:::i;:::-;10967:74;;11064:6;11057:5;11050:21;11102:4;11095:5;11091:16;11140:3;11131:6;11126:3;11122:16;11119:25;11116:112;;;11147:79;;:::i;:::-;11116:112;11237:54;11284:6;11279:3;11274;11237:54;:::i;:::-;10957:340;10874:423;;;;;:::o;11316:338::-;11371:5;11420:3;11413:4;11405:6;11401:17;11397:27;11387:122;;11428:79;;:::i;:::-;11387:122;11545:6;11532:20;11570:78;11644:3;11636:6;11629:4;11621:6;11617:17;11570:78;:::i;:::-;11561:87;;11377:277;11316:338;;;;:::o;11660:943::-;11755:6;11763;11771;11779;11828:3;11816:9;11807:7;11803:23;11799:33;11796:120;;;11835:79;;:::i;:::-;11796:120;11955:1;11980:53;12025:7;12016:6;12005:9;12001:22;11980:53;:::i;:::-;11970:63;;11926:117;12082:2;12108:53;12153:7;12144:6;12133:9;12129:22;12108:53;:::i;:::-;12098:63;;12053:118;12210:2;12236:53;12281:7;12272:6;12261:9;12257:22;12236:53;:::i;:::-;12226:63;;12181:118;12366:2;12355:9;12351:18;12338:32;12397:18;12389:6;12386:30;12383:117;;;12419:79;;:::i;:::-;12383:117;12524:62;12578:7;12569:6;12558:9;12554:22;12524:62;:::i;:::-;12514:72;;12309:287;11660:943;;;;;;;:::o;12609:474::-;12677:6;12685;12734:2;12722:9;12713:7;12709:23;12705:32;12702:119;;;12740:79;;:::i;:::-;12702:119;12860:1;12885:53;12930:7;12921:6;12910:9;12906:22;12885:53;:::i;:::-;12875:63;;12831:117;12987:2;13013:53;13058:7;13049:6;13038:9;13034:22;13013:53;:::i;:::-;13003:63;;12958:118;12609:474;;;;;:::o;13089:180::-;13137:77;13134:1;13127:88;13234:4;13231:1;13224:15;13258:4;13255:1;13248:15;13275:320;13319:6;13356:1;13350:4;13346:12;13336:22;;13403:1;13397:4;13393:12;13424:18;13414:81;;13480:4;13472:6;13468:17;13458:27;;13414:81;13542:2;13534:6;13531:14;13511:18;13508:38;13505:84;;13561:18;;:::i;:::-;13505:84;13326:269;13275:320;;;:::o;13601:232::-;13741:34;13737:1;13729:6;13725:14;13718:58;13810:15;13805:2;13797:6;13793:15;13786:40;13601:232;:::o;13839:366::-;13981:3;14002:67;14066:2;14061:3;14002:67;:::i;:::-;13995:74;;14078:93;14167:3;14078:93;:::i;:::-;14196:2;14191:3;14187:12;14180:19;;13839:366;;;:::o;14211:419::-;14377:4;14415:2;14404:9;14400:18;14392:26;;14464:9;14458:4;14454:20;14450:1;14439:9;14435:17;14428:47;14492:131;14618:4;14492:131;:::i;:::-;14484:139;;14211:419;;;:::o;14636:221::-;14776:34;14772:1;14764:6;14760:14;14753:58;14845:4;14840:2;14832:6;14828:15;14821:29;14636:221;:::o;14863:366::-;15005:3;15026:67;15090:2;15085:3;15026:67;:::i;:::-;15019:74;;15102:93;15191:3;15102:93;:::i;:::-;15220:2;15215:3;15211:12;15204:19;;14863:366;;;:::o;15235:419::-;15401:4;15439:2;15428:9;15424:18;15416:26;;15488:9;15482:4;15478:20;15474:1;15463:9;15459:17;15452:47;15516:131;15642:4;15516:131;:::i;:::-;15508:139;;15235:419;;;:::o;15660:233::-;15800:34;15796:1;15788:6;15784:14;15777:58;15869:16;15864:2;15856:6;15852:15;15845:41;15660:233;:::o;15899:366::-;16041:3;16062:67;16126:2;16121:3;16062:67;:::i;:::-;16055:74;;16138:93;16227:3;16138:93;:::i;:::-;16256:2;16251:3;16247:12;16240:19;;15899:366;;;:::o;16271:419::-;16437:4;16475:2;16464:9;16460:18;16452:26;;16524:9;16518:4;16514:20;16510:1;16499:9;16495:17;16488:47;16552:131;16678:4;16552:131;:::i;:::-;16544:139;;16271:419;;;:::o;16696:181::-;16836:33;16832:1;16824:6;16820:14;16813:57;16696:181;:::o;16883:366::-;17025:3;17046:67;17110:2;17105:3;17046:67;:::i;:::-;17039:74;;17122:93;17211:3;17122:93;:::i;:::-;17240:2;17235:3;17231:12;17224:19;;16883:366;;;:::o;17255:419::-;17421:4;17459:2;17448:9;17444:18;17436:26;;17508:9;17502:4;17498:20;17494:1;17483:9;17479:17;17472:47;17536:131;17662:4;17536:131;:::i;:::-;17528:139;;17255:419;;;:::o;17680:147::-;17781:11;17818:3;17803:18;;17680:147;;;;:::o;17833:114::-;;:::o;17953:398::-;18112:3;18133:83;18214:1;18209:3;18133:83;:::i;:::-;18126:90;;18225:93;18314:3;18225:93;:::i;:::-;18343:1;18338:3;18334:11;18327:18;;17953:398;;;:::o;18357:379::-;18541:3;18563:147;18706:3;18563:147;:::i;:::-;18556:154;;18727:3;18720:10;;18357:379;;;:::o;18742:166::-;18882:18;18878:1;18870:6;18866:14;18859:42;18742:166;:::o;18914:366::-;19056:3;19077:67;19141:2;19136:3;19077:67;:::i;:::-;19070:74;;19153:93;19242:3;19153:93;:::i;:::-;19271:2;19266:3;19262:12;19255:19;;18914:366;;;:::o;19286:419::-;19452:4;19490:2;19479:9;19475:18;19467:26;;19539:9;19533:4;19529:20;19525:1;19514:9;19510:17;19503:47;19567:131;19693:4;19567:131;:::i;:::-;19559:139;;19286:419;;;:::o;19711:222::-;19851:34;19847:1;19839:6;19835:14;19828:58;19920:5;19915:2;19907:6;19903:15;19896:30;19711:222;:::o;19939:366::-;20081:3;20102:67;20166:2;20161:3;20102:67;:::i;:::-;20095:74;;20178:93;20267:3;20178:93;:::i;:::-;20296:2;20291:3;20287:12;20280:19;;19939:366;;;:::o;20311:419::-;20477:4;20515:2;20504:9;20500:18;20492:26;;20564:9;20558:4;20554:20;20550:1;20539:9;20535:17;20528:47;20592:131;20718:4;20592:131;:::i;:::-;20584:139;;20311:419;;;:::o;20736:230::-;20876:34;20872:1;20864:6;20860:14;20853:58;20945:13;20940:2;20932:6;20928:15;20921:38;20736:230;:::o;20972:366::-;21114:3;21135:67;21199:2;21194:3;21135:67;:::i;:::-;21128:74;;21211:93;21300:3;21211:93;:::i;:::-;21329:2;21324:3;21320:12;21313:19;;20972:366;;;:::o;21344:419::-;21510:4;21548:2;21537:9;21533:18;21525:26;;21597:9;21591:4;21587:20;21583:1;21572:9;21568:17;21561:47;21625:131;21751:4;21625:131;:::i;:::-;21617:139;;21344:419;;;:::o;21769:180::-;21817:77;21814:1;21807:88;21914:4;21911:1;21904:15;21938:4;21935:1;21928:15;21955:191;21995:3;22014:20;22032:1;22014:20;:::i;:::-;22009:25;;22048:20;22066:1;22048:20;:::i;:::-;22043:25;;22091:1;22088;22084:9;22077:16;;22112:3;22109:1;22106:10;22103:36;;;22119:18;;:::i;:::-;22103:36;21955:191;;;;:::o;22152:177::-;22292:29;22288:1;22280:6;22276:14;22269:53;22152:177;:::o;22335:366::-;22477:3;22498:67;22562:2;22557:3;22498:67;:::i;:::-;22491:74;;22574:93;22663:3;22574:93;:::i;:::-;22692:2;22687:3;22683:12;22676:19;;22335:366;;;:::o;22707:419::-;22873:4;22911:2;22900:9;22896:18;22888:26;;22960:9;22954:4;22950:20;22946:1;22935:9;22931:17;22924:47;22988:131;23114:4;22988:131;:::i;:::-;22980:139;;22707:419;;;:::o;23132:172::-;23272:24;23268:1;23260:6;23256:14;23249:48;23132:172;:::o;23310:366::-;23452:3;23473:67;23537:2;23532:3;23473:67;:::i;:::-;23466:74;;23549:93;23638:3;23549:93;:::i;:::-;23667:2;23662:3;23658:12;23651:19;;23310:366;;;:::o;23682:419::-;23848:4;23886:2;23875:9;23871:18;23863:26;;23935:9;23929:4;23925:20;23921:1;23910:9;23906:17;23899:47;23963:131;24089:4;23963:131;:::i;:::-;23955:139;;23682:419;;;:::o;24107:194::-;24147:4;24167:20;24185:1;24167:20;:::i;:::-;24162:25;;24201:20;24219:1;24201:20;:::i;:::-;24196:25;;24245:1;24242;24238:9;24230:17;;24269:1;24263:4;24260:11;24257:37;;;24274:18;;:::i;:::-;24257:37;24107:194;;;;:::o;24307:162::-;24447:14;24443:1;24435:6;24431:14;24424:38;24307:162;:::o;24475:366::-;24617:3;24638:67;24702:2;24697:3;24638:67;:::i;:::-;24631:74;;24714:93;24803:3;24714:93;:::i;:::-;24832:2;24827:3;24823:12;24816:19;;24475:366;;;:::o;24847:419::-;25013:4;25051:2;25040:9;25036:18;25028:26;;25100:9;25094:4;25090:20;25086:1;25075:9;25071:17;25064:47;25128:131;25254:4;25128:131;:::i;:::-;25120:139;;24847:419;;;:::o;25272:410::-;25312:7;25335:20;25353:1;25335:20;:::i;:::-;25330:25;;25369:20;25387:1;25369:20;:::i;:::-;25364:25;;25424:1;25421;25417:9;25446:30;25464:11;25446:30;:::i;:::-;25435:41;;25625:1;25616:7;25612:15;25609:1;25606:22;25586:1;25579:9;25559:83;25536:139;;25655:18;;:::i;:::-;25536:139;25320:362;25272:410;;;;:::o;25688:168::-;25828:20;25824:1;25816:6;25812:14;25805:44;25688:168;:::o;25862:366::-;26004:3;26025:67;26089:2;26084:3;26025:67;:::i;:::-;26018:74;;26101:93;26190:3;26101:93;:::i;:::-;26219:2;26214:3;26210:12;26203:19;;25862:366;;;:::o;26234:419::-;26400:4;26438:2;26427:9;26423:18;26415:26;;26487:9;26481:4;26477:20;26473:1;26462:9;26458:17;26451:47;26515:131;26641:4;26515:131;:::i;:::-;26507:139;;26234:419;;;:::o;26659:164::-;26799:16;26795:1;26787:6;26783:14;26776:40;26659:164;:::o;26829:366::-;26971:3;26992:67;27056:2;27051:3;26992:67;:::i;:::-;26985:74;;27068:93;27157:3;27068:93;:::i;:::-;27186:2;27181:3;27177:12;27170:19;;26829:366;;;:::o;27201:419::-;27367:4;27405:2;27394:9;27390:18;27382:26;;27454:9;27448:4;27444:20;27440:1;27429:9;27425:17;27418:47;27482:131;27608:4;27482:131;:::i;:::-;27474:139;;27201:419;;;:::o;27626:169::-;27766:21;27762:1;27754:6;27750:14;27743:45;27626:169;:::o;27801:366::-;27943:3;27964:67;28028:2;28023:3;27964:67;:::i;:::-;27957:74;;28040:93;28129:3;28040:93;:::i;:::-;28158:2;28153:3;28149:12;28142:19;;27801:366;;;:::o;28173:419::-;28339:4;28377:2;28366:9;28362:18;28354:26;;28426:9;28420:4;28416:20;28412:1;28401:9;28397:17;28390:47;28454:131;28580:4;28454:131;:::i;:::-;28446:139;;28173:419;;;:::o;28598:141::-;28647:4;28670:3;28662:11;;28693:3;28690:1;28683:14;28727:4;28724:1;28714:18;28706:26;;28598:141;;;:::o;28745:93::-;28782:6;28829:2;28824;28817:5;28813:14;28809:23;28799:33;;28745:93;;;:::o;28844:107::-;28888:8;28938:5;28932:4;28928:16;28907:37;;28844:107;;;;:::o;28957:393::-;29026:6;29076:1;29064:10;29060:18;29099:97;29129:66;29118:9;29099:97;:::i;:::-;29217:39;29247:8;29236:9;29217:39;:::i;:::-;29205:51;;29289:4;29285:9;29278:5;29274:21;29265:30;;29338:4;29328:8;29324:19;29317:5;29314:30;29304:40;;29033:317;;28957:393;;;;;:::o;29356:142::-;29406:9;29439:53;29457:34;29466:24;29484:5;29466:24;:::i;:::-;29457:34;:::i;:::-;29439:53;:::i;:::-;29426:66;;29356:142;;;:::o;29504:75::-;29547:3;29568:5;29561:12;;29504:75;;;:::o;29585:269::-;29695:39;29726:7;29695:39;:::i;:::-;29756:91;29805:41;29829:16;29805:41;:::i;:::-;29797:6;29790:4;29784:11;29756:91;:::i;:::-;29750:4;29743:105;29661:193;29585:269;;;:::o;29860:73::-;29905:3;29860:73;:::o;29939:189::-;30016:32;;:::i;:::-;30057:65;30115:6;30107;30101:4;30057:65;:::i;:::-;29992:136;29939:189;;:::o;30134:186::-;30194:120;30211:3;30204:5;30201:14;30194:120;;;30265:39;30302:1;30295:5;30265:39;:::i;:::-;30238:1;30231:5;30227:13;30218:22;;30194:120;;;30134:186;;:::o;30326:543::-;30427:2;30422:3;30419:11;30416:446;;;30461:38;30493:5;30461:38;:::i;:::-;30545:29;30563:10;30545:29;:::i;:::-;30535:8;30531:44;30728:2;30716:10;30713:18;30710:49;;;30749:8;30734:23;;30710:49;30772:80;30828:22;30846:3;30828:22;:::i;:::-;30818:8;30814:37;30801:11;30772:80;:::i;:::-;30431:431;;30416:446;30326:543;;;:::o;30875:117::-;30929:8;30979:5;30973:4;30969:16;30948:37;;30875:117;;;;:::o;30998:169::-;31042:6;31075:51;31123:1;31119:6;31111:5;31108:1;31104:13;31075:51;:::i;:::-;31071:56;31156:4;31150;31146:15;31136:25;;31049:118;30998:169;;;;:::o;31172:295::-;31248:4;31394:29;31419:3;31413:4;31394:29;:::i;:::-;31386:37;;31456:3;31453:1;31449:11;31443:4;31440:21;31432:29;;31172:295;;;;:::o;31472:1395::-;31589:37;31622:3;31589:37;:::i;:::-;31691:18;31683:6;31680:30;31677:56;;;31713:18;;:::i;:::-;31677:56;31757:38;31789:4;31783:11;31757:38;:::i;:::-;31842:67;31902:6;31894;31888:4;31842:67;:::i;:::-;31936:1;31960:4;31947:17;;31992:2;31984:6;31981:14;32009:1;32004:618;;;;32666:1;32683:6;32680:77;;;32732:9;32727:3;32723:19;32717:26;32708:35;;32680:77;32783:67;32843:6;32836:5;32783:67;:::i;:::-;32777:4;32770:81;32639:222;31974:887;;32004:618;32056:4;32052:9;32044:6;32040:22;32090:37;32122:4;32090:37;:::i;:::-;32149:1;32163:208;32177:7;32174:1;32171:14;32163:208;;;32256:9;32251:3;32247:19;32241:26;32233:6;32226:42;32307:1;32299:6;32295:14;32285:24;;32354:2;32343:9;32339:18;32326:31;;32200:4;32197:1;32193:12;32188:17;;32163:208;;;32399:6;32390:7;32387:19;32384:179;;;32457:9;32452:3;32448:19;32442:26;32500:48;32542:4;32534:6;32530:17;32519:9;32500:48;:::i;:::-;32492:6;32485:64;32407:156;32384:179;32609:1;32605;32597:6;32593:14;32589:22;32583:4;32576:36;32011:611;;;31974:887;;31564:1303;;;31472:1395;;:::o;32873:234::-;33013:34;33009:1;33001:6;32997:14;32990:58;33082:17;33077:2;33069:6;33065:15;33058:42;32873:234;:::o;33113:366::-;33255:3;33276:67;33340:2;33335:3;33276:67;:::i;:::-;33269:74;;33352:93;33441:3;33352:93;:::i;:::-;33470:2;33465:3;33461:12;33454:19;;33113:366;;;:::o;33485:419::-;33651:4;33689:2;33678:9;33674:18;33666:26;;33738:9;33732:4;33728:20;33724:1;33713:9;33709:17;33702:47;33766:131;33892:4;33766:131;:::i;:::-;33758:139;;33485:419;;;:::o;33910:148::-;34012:11;34049:3;34034:18;;33910:148;;;;:::o;34064:390::-;34170:3;34198:39;34231:5;34198:39;:::i;:::-;34253:89;34335:6;34330:3;34253:89;:::i;:::-;34246:96;;34351:65;34409:6;34404:3;34397:4;34390:5;34386:16;34351:65;:::i;:::-;34441:6;34436:3;34432:16;34425:23;;34174:280;34064:390;;;;:::o;34460:155::-;34600:7;34596:1;34588:6;34584:14;34577:31;34460:155;:::o;34621:400::-;34781:3;34802:84;34884:1;34879:3;34802:84;:::i;:::-;34795:91;;34895:93;34984:3;34895:93;:::i;:::-;35013:1;35008:3;35004:11;34997:18;;34621:400;;;:::o;35027:701::-;35308:3;35330:95;35421:3;35412:6;35330:95;:::i;:::-;35323:102;;35442:95;35533:3;35524:6;35442:95;:::i;:::-;35435:102;;35554:148;35698:3;35554:148;:::i;:::-;35547:155;;35719:3;35712:10;;35027:701;;;;;:::o;35734:225::-;35874:34;35870:1;35862:6;35858:14;35851:58;35943:8;35938:2;35930:6;35926:15;35919:33;35734:225;:::o;35965:366::-;36107:3;36128:67;36192:2;36187:3;36128:67;:::i;:::-;36121:74;;36204:93;36293:3;36204:93;:::i;:::-;36322:2;36317:3;36313:12;36306:19;;35965:366;;;:::o;36337:419::-;36503:4;36541:2;36530:9;36526:18;36518:26;;36590:9;36584:4;36580:20;36576:1;36565:9;36561:17;36554:47;36618:131;36744:4;36618:131;:::i;:::-;36610:139;;36337:419;;;:::o;36762:332::-;36883:4;36921:2;36910:9;36906:18;36898:26;;36934:71;37002:1;36991:9;36987:17;36978:6;36934:71;:::i;:::-;37015:72;37083:2;37072:9;37068:18;37059:6;37015:72;:::i;:::-;36762:332;;;;;:::o;37100:137::-;37154:5;37185:6;37179:13;37170:22;;37201:30;37225:5;37201:30;:::i;:::-;37100:137;;;;:::o;37243:345::-;37310:6;37359:2;37347:9;37338:7;37334:23;37330:32;37327:119;;;37365:79;;:::i;:::-;37327:119;37485:1;37510:61;37563:7;37554:6;37543:9;37539:22;37510:61;:::i;:::-;37500:71;;37456:125;37243:345;;;;:::o;37594:221::-;37734:34;37730:1;37722:6;37718:14;37711:58;37803:4;37798:2;37790:6;37786:15;37779:29;37594:221;:::o;37821:366::-;37963:3;37984:67;38048:2;38043:3;37984:67;:::i;:::-;37977:74;;38060:93;38149:3;38060:93;:::i;:::-;38178:2;38173:3;38169:12;38162:19;;37821:366;;;:::o;38193:419::-;38359:4;38397:2;38386:9;38382:18;38374:26;;38446:9;38440:4;38436:20;38432:1;38421:9;38417:17;38410:47;38474:131;38600:4;38474:131;:::i;:::-;38466:139;;38193:419;;;:::o;38618:244::-;38758:34;38754:1;38746:6;38742:14;38735:58;38827:27;38822:2;38814:6;38810:15;38803:52;38618:244;:::o;38868:366::-;39010:3;39031:67;39095:2;39090:3;39031:67;:::i;:::-;39024:74;;39107:93;39196:3;39107:93;:::i;:::-;39225:2;39220:3;39216:12;39209:19;;38868:366;;;:::o;39240:419::-;39406:4;39444:2;39433:9;39429:18;39421:26;;39493:9;39487:4;39483:20;39479:1;39468:9;39464:17;39457:47;39521:131;39647:4;39521:131;:::i;:::-;39513:139;;39240:419;;;:::o;39665:182::-;39805:34;39801:1;39793:6;39789:14;39782:58;39665:182;:::o;39853:366::-;39995:3;40016:67;40080:2;40075:3;40016:67;:::i;:::-;40009:74;;40092:93;40181:3;40092:93;:::i;:::-;40210:2;40205:3;40201:12;40194:19;;39853:366;;;:::o;40225:419::-;40391:4;40429:2;40418:9;40414:18;40406:26;;40478:9;40472:4;40468:20;40464:1;40453:9;40449:17;40442:47;40506:131;40632:4;40506:131;:::i;:::-;40498:139;;40225:419;;;:::o;40650:229::-;40790:34;40786:1;40778:6;40774:14;40767:58;40859:12;40854:2;40846:6;40842:15;40835:37;40650:229;:::o;40885:366::-;41027:3;41048:67;41112:2;41107:3;41048:67;:::i;:::-;41041:74;;41124:93;41213:3;41124:93;:::i;:::-;41242:2;41237:3;41233:12;41226:19;;40885:366;;;:::o;41257:419::-;41423:4;41461:2;41450:9;41446:18;41438:26;;41510:9;41504:4;41500:20;41496:1;41485:9;41481:17;41474:47;41538:131;41664:4;41538:131;:::i;:::-;41530:139;;41257:419;;;:::o;41682:234::-;41822:34;41818:1;41810:6;41806:14;41799:58;41891:17;41886:2;41878:6;41874:15;41867:42;41682:234;:::o;41922:366::-;42064:3;42085:67;42149:2;42144:3;42085:67;:::i;:::-;42078:74;;42161:93;42250:3;42161:93;:::i;:::-;42279:2;42274:3;42270:12;42263:19;;41922:366;;;:::o;42294:419::-;42460:4;42498:2;42487:9;42483:18;42475:26;;42547:9;42541:4;42537:20;42533:1;42522:9;42518:17;42511:47;42575:131;42701:4;42575:131;:::i;:::-;42567:139;;42294:419;;;:::o;42719:176::-;42859:28;42855:1;42847:6;42843:14;42836:52;42719:176;:::o;42901:366::-;43043:3;43064:67;43128:2;43123:3;43064:67;:::i;:::-;43057:74;;43140:93;43229:3;43140:93;:::i;:::-;43258:2;43253:3;43249:12;43242:19;;42901:366;;;:::o;43273:419::-;43439:4;43477:2;43466:9;43462:18;43454:26;;43526:9;43520:4;43516:20;43512:1;43501:9;43497:17;43490:47;43554:131;43680:4;43554:131;:::i;:::-;43546:139;;43273:419;;;:::o;43698:238::-;43838:34;43834:1;43826:6;43822:14;43815:58;43907:21;43902:2;43894:6;43890:15;43883:46;43698:238;:::o;43942:366::-;44084:3;44105:67;44169:2;44164:3;44105:67;:::i;:::-;44098:74;;44181:93;44270:3;44181:93;:::i;:::-;44299:2;44294:3;44290:12;44283:19;;43942:366;;;:::o;44314:419::-;44480:4;44518:2;44507:9;44503:18;44495:26;;44567:9;44561:4;44557:20;44553:1;44542:9;44538:17;44531:47;44595:131;44721:4;44595:131;:::i;:::-;44587:139;;44314:419;;;:::o;44739:180::-;44787:77;44784:1;44777:88;44884:4;44881:1;44874:15;44908:4;44905:1;44898:15;44925:237;45065:34;45061:1;45053:6;45049:14;45042:58;45134:20;45129:2;45121:6;45117:15;45110:45;44925:237;:::o;45168:366::-;45310:3;45331:67;45395:2;45390:3;45331:67;:::i;:::-;45324:74;;45407:93;45496:3;45407:93;:::i;:::-;45525:2;45520:3;45516:12;45509:19;;45168:366;;;:::o;45540:419::-;45706:4;45744:2;45733:9;45729:18;45721:26;;45793:9;45787:4;45783:20;45779:1;45768:9;45764:17;45757:47;45821:131;45947:4;45821:131;:::i;:::-;45813:139;;45540:419;;;:::o;45965:225::-;46105:34;46101:1;46093:6;46089:14;46082:58;46174:8;46169:2;46161:6;46157:15;46150:33;45965:225;:::o;46196:366::-;46338:3;46359:67;46423:2;46418:3;46359:67;:::i;:::-;46352:74;;46435:93;46524:3;46435:93;:::i;:::-;46553:2;46548:3;46544:12;46537:19;;46196:366;;;:::o;46568:419::-;46734:4;46772:2;46761:9;46757:18;46749:26;;46821:9;46815:4;46811:20;46807:1;46796:9;46792:17;46785:47;46849:131;46975:4;46849:131;:::i;:::-;46841:139;;46568:419;;;:::o;46993:224::-;47133:34;47129:1;47121:6;47117:14;47110:58;47202:7;47197:2;47189:6;47185:15;47178:32;46993:224;:::o;47223:366::-;47365:3;47386:67;47450:2;47445:3;47386:67;:::i;:::-;47379:74;;47462:93;47551:3;47462:93;:::i;:::-;47580:2;47575:3;47571:12;47564:19;;47223:366;;;:::o;47595:419::-;47761:4;47799:2;47788:9;47784:18;47776:26;;47848:9;47842:4;47838:20;47834:1;47823:9;47819:17;47812:47;47876:131;48002:4;47876:131;:::i;:::-;47868:139;;47595:419;;;:::o;48020:98::-;48071:6;48105:5;48099:12;48089:22;;48020:98;;;:::o;48124:168::-;48207:11;48241:6;48236:3;48229:19;48281:4;48276:3;48272:14;48257:29;;48124:168;;;;:::o;48298:373::-;48384:3;48412:38;48444:5;48412:38;:::i;:::-;48466:70;48529:6;48524:3;48466:70;:::i;:::-;48459:77;;48545:65;48603:6;48598:3;48591:4;48584:5;48580:16;48545:65;:::i;:::-;48635:29;48657:6;48635:29;:::i;:::-;48630:3;48626:39;48619:46;;48388:283;48298:373;;;;:::o;48677:640::-;48872:4;48910:3;48899:9;48895:19;48887:27;;48924:71;48992:1;48981:9;48977:17;48968:6;48924:71;:::i;:::-;49005:72;49073:2;49062:9;49058:18;49049:6;49005:72;:::i;:::-;49087;49155:2;49144:9;49140:18;49131:6;49087:72;:::i;:::-;49206:9;49200:4;49196:20;49191:2;49180:9;49176:18;49169:48;49234:76;49305:4;49296:6;49234:76;:::i;:::-;49226:84;;48677:640;;;;;;;:::o;49323:141::-;49379:5;49410:6;49404:13;49395:22;;49426:32;49452:5;49426:32;:::i;:::-;49323:141;;;;:::o;49470:349::-;49539:6;49588:2;49576:9;49567:7;49563:23;49559:32;49556:119;;;49594:79;;:::i;:::-;49556:119;49714:1;49739:63;49794:7;49785:6;49774:9;49770:22;49739:63;:::i;:::-;49729:73;;49685:127;49470:349;;;;:::o;49825:220::-;49965:34;49961:1;49953:6;49949:14;49942:58;50034:3;50029:2;50021:6;50017:15;50010:28;49825:220;:::o;50051:366::-;50193:3;50214:67;50278:2;50273:3;50214:67;:::i;:::-;50207:74;;50290:93;50379:3;50290:93;:::i;:::-;50408:2;50403:3;50399:12;50392:19;;50051:366;;;:::o;50423:419::-;50589:4;50627:2;50616:9;50612:18;50604:26;;50676:9;50670:4;50666:20;50662:1;50651:9;50647:17;50640:47;50704:131;50830:4;50704:131;:::i;:::-;50696:139;;50423:419;;;:::o;50848:227::-;50988:34;50984:1;50976:6;50972:14;50965:58;51057:10;51052:2;51044:6;51040:15;51033:35;50848:227;:::o;51081:366::-;51223:3;51244:67;51308:2;51303:3;51244:67;:::i;:::-;51237:74;;51320:93;51409:3;51320:93;:::i;:::-;51438:2;51433:3;51429:12;51422:19;;51081:366;;;:::o;51453:419::-;51619:4;51657:2;51646:9;51642:18;51634:26;;51706:9;51700:4;51696:20;51692:1;51681:9;51677:17;51670:47;51734:131;51860:4;51734:131;:::i;:::-;51726:139;;51453:419;;;:::o

Swarm Source

ipfs://64144292b69dd7a2dec2b80ff458380abed66226cde58328f59154a2084dac15
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.