ETH Price: $3,370.88 (-3.31%)

Token

Quadrums (QDRMS)
 

Overview

Max Total Supply

1,024 QDRMS

Holders

566

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
1 QDRMS
0x12535ae8cb6050e7933e4fd8b64ff1e8aa87e093
Loading...
Loading
Loading...
Loading
Loading...
Loading

OVERVIEW

Quadrums is a generative grid-based art collection composed of abstract and colorful geometric shapes. 1,024 unique NFTs with 20 color palettes, 12 shape types, and inifinite possible outcomes.

# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
Quadrums

Compiler Version
v0.8.0+commit.c7dfd78e

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, None license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2021-09-15
*/

// quadrums.art - Generative NFT Collection

// File: http://github.com/OpenZeppelin/openzeppelin-contracts/contracts/utils/Strings.sol

pragma solidity 0.8.0;

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

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

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

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

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

// File: http://github.com/OpenZeppelin/openzeppelin-contracts/contracts/utils/EnumerableMap.sol

pragma solidity 0.8.0;

/**
 * @dev Library for managing an enumerable variant of Solidity's
 * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`]
 * type.
 *
 * Maps have the following properties:
 *
 * - Entries are added, removed, and checked for existence in constant time
 * (O(1)).
 * - Entries are enumerated in O(n). No guarantees are made on the ordering.
 *
 * ```
 * contract Example {
 *     // Add the library methods
 *     using EnumerableMap for EnumerableMap.UintToAddressMap;
 *
 *     // Declare a set state variable
 *     EnumerableMap.UintToAddressMap private myMap;
 * }
 * ```
 *
 * As of v3.0.0, only maps of type `uint256 -> address` (`UintToAddressMap`) are
 * supported.
 */
library EnumerableMap {
    // To implement this library for multiple types with as little code
    // repetition as possible, we write it in terms of a generic Map type with
    // bytes32 keys and values.
    // The Map implementation uses private functions, and user-facing
    // implementations (such as Uint256ToAddressMap) are just wrappers around
    // the underlying Map.
    // This means that we can only create new EnumerableMaps for types that fit
    // in bytes32.

    struct MapEntry {
        bytes32 _key;
        bytes32 _value;
    }

    struct Map {
        // Storage of map keys and values
        MapEntry[] _entries;
        // Position of the entry defined by a key in the `entries` array, plus 1
        // because index 0 means a key is not in the map.
        mapping(bytes32 => uint256) _indexes;
    }

    /**
     * @dev Adds a key-value pair to a map, or updates the value for an existing
     * key. O(1).
     *
     * Returns true if the key was added to the map, that is if it was not
     * already present.
     */
    function _set(
        Map storage map,
        bytes32 key,
        bytes32 value
    ) private returns (bool) {
        // We read and store the key's index to prevent multiple reads from the same storage slot
        uint256 keyIndex = map._indexes[key];

        if (keyIndex == 0) {
            // Equivalent to !contains(map, key)
            map._entries.push(MapEntry({_key: key, _value: value}));
            // The entry is stored at length-1, but we add 1 to all indexes
            // and use 0 as a sentinel value
            map._indexes[key] = map._entries.length;
            return true;
        } else {
            map._entries[keyIndex - 1]._value = value;
            return false;
        }
    }

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

        if (keyIndex != 0) {
            // Equivalent to contains(map, key)
            // To delete a key-value pair from the _entries array in O(1), we swap the entry to delete with the last one
            // in the array, and then remove the last entry (sometimes called as 'swap and pop').
            // This modifies the order of the array, as noted in {at}.

            uint256 toDeleteIndex = keyIndex - 1;
            uint256 lastIndex = map._entries.length - 1;

            // When the entry to delete is the last one, the swap operation is unnecessary. However, since this occurs
            // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.

            MapEntry storage lastEntry = map._entries[lastIndex];

            // Move the last entry to the index where the entry to delete is
            map._entries[toDeleteIndex] = lastEntry;
            // Update the index for the moved entry
            map._indexes[lastEntry._key] = toDeleteIndex + 1; // All indexes are 1-based

            // Delete the slot where the moved entry was stored
            map._entries.pop();

            // Delete the index for the deleted slot
            delete map._indexes[key];

            return true;
        } else {
            return false;
        }
    }

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

    /**
     * @dev Returns the number of key-value pairs in the map. O(1).
     */
    function _length(Map storage map) private view returns (uint256) {
        return map._entries.length;
    }

    /**
     * @dev Returns the key-value pair stored at position `index` in the map. O(1).
     *
     * Note that there are no guarantees on the ordering of entries inside the
     * array, and it may change when more entries are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function _at(Map storage map, uint256 index)
        private
        view
        returns (bytes32, bytes32)
    {
        require(
            map._entries.length > index,
            "EnumerableMap: index out of bounds"
        );

        MapEntry storage entry = map._entries[index];
        return (entry._key, entry._value);
    }

    /**
     * @dev Tries to returns the value associated with `key`.  O(1).
     * Does not revert if `key` is not in the map.
     */
    function _tryGet(Map storage map, bytes32 key)
        private
        view
        returns (bool, bytes32)
    {
        uint256 keyIndex = map._indexes[key];
        if (keyIndex == 0) return (false, 0); // Equivalent to contains(map, key)
        return (true, map._entries[keyIndex - 1]._value); // All indexes are 1-based
    }

    /**
     * @dev Returns the value associated with `key`.  O(1).
     *
     * Requirements:
     *
     * - `key` must be in the map.
     */
    function _get(Map storage map, bytes32 key) private view returns (bytes32) {
        uint256 keyIndex = map._indexes[key];
        require(keyIndex != 0, "EnumerableMap: nonexistent key"); // Equivalent to contains(map, key)
        return map._entries[keyIndex - 1]._value; // All indexes are 1-based
    }

    /**
     * @dev Same as {_get}, with a custom error message when `key` is not in the map.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {_tryGet}.
     */
    function _get(
        Map storage map,
        bytes32 key,
        string memory errorMessage
    ) private view returns (bytes32) {
        uint256 keyIndex = map._indexes[key];
        require(keyIndex != 0, errorMessage); // Equivalent to contains(map, key)
        return map._entries[keyIndex - 1]._value; // All indexes are 1-based
    }

    // UintToAddressMap

    struct UintToAddressMap {
        Map _inner;
    }

    /**
     * @dev Adds a key-value pair to a map, or updates the value for an existing
     * key. O(1).
     *
     * Returns true if the key was added to the map, that is if it was not
     * already present.
     */
    function set(
        UintToAddressMap storage map,
        uint256 key,
        address value
    ) internal returns (bool) {
        return _set(map._inner, bytes32(key), bytes32(uint256(uint160(value))));
    }

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

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

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

    /**
     * @dev Returns the element 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(UintToAddressMap storage map, uint256 index)
        internal
        view
        returns (uint256, address)
    {
        (bytes32 key, bytes32 value) = _at(map._inner, index);
        return (uint256(key), address(uint160(uint256(value))));
    }

    /**
     * @dev Tries to returns the value associated with `key`.  O(1).
     * Does not revert if `key` is not in the map.
     *
     * _Available since v3.4._
     */
    function tryGet(UintToAddressMap storage map, uint256 key)
        internal
        view
        returns (bool, address)
    {
        (bool success, bytes32 value) = _tryGet(map._inner, bytes32(key));
        return (success, address(uint160(uint256(value))));
    }

    /**
     * @dev Returns the value associated with `key`.  O(1).
     *
     * Requirements:
     *
     * - `key` must be in the map.
     */
    function get(UintToAddressMap storage map, uint256 key)
        internal
        view
        returns (address)
    {
        return address(uint160(uint256(_get(map._inner, bytes32(key)))));
    }

    /**
     * @dev Same as {get}, with a custom error message when `key` is not in the map.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryGet}.
     */
    function get(
        UintToAddressMap storage map,
        uint256 key,
        string memory errorMessage
    ) internal view returns (address) {
        return
            address(
                uint160(uint256(_get(map._inner, bytes32(key), errorMessage)))
            );
    }
}

// File: http://github.com/OpenZeppelin/openzeppelin-contracts/contracts/utils/EnumerableSet.sol

pragma solidity 0.8.0;

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

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

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

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

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

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

            // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs
            // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.

            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] = toDeleteIndex + 1; // All indexes are 1-based

            // 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)
    {
        require(
            set._values.length > index,
            "EnumerableSet: index out of bounds"
        );
        return set._values[index];
    }

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

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

    // UintSet

    struct UintSet {
        Set _inner;
    }

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

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

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

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

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

// File: http://github.com/OpenZeppelin/openzeppelin-contracts/contracts/utils/Address.sol

pragma solidity 0.8.0;

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

        uint256 size;
        // solhint-disable-next-line no-inline-assembly
        assembly {
            size := extcodesize(account)
        }
        return size > 0;
    }

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

        // solhint-disable-next-line avoid-low-level-calls, avoid-call-value
        (bool success, ) = recipient.call{value: amount}("");
        require(
            success,
            "Address: unable to send value, recipient may have reverted"
        );
    }

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

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

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

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

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.call{value: value}(
            data
        );
        return _verifyCallResult(success, returndata, errorMessage);
    }

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

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

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.staticcall(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

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

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

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

    function _verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) private pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

                // solhint-disable-next-line no-inline-assembly
                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

// File: http://github.com/OpenZeppelin/openzeppelin-contracts/contracts/introspection/ERC165.sol

pragma solidity 0.8.0;

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

// File: http://github.com/OpenZeppelin/openzeppelin-contracts/contracts/token/ERC721/IERC721.sol

pragma solidity 0.8.0;

/**
 * @dev Implementation of the {IERC165} interface.
 *
 * Contracts may inherit from this and call {_registerInterface} to declare
 * their support of an interface.
 */
abstract contract ERC165 is IERC165 {
    /**
     * @dev Mapping of interface ids to whether or not it's supported.
     */
    mapping(bytes4 => bool) private _supportedInterfaces;

    constructor() {
        // Derived contracts need only register support for their own interfaces,
        // we register support for ERC165 itself here
        _registerInterface(type(IERC165).interfaceId);
    }

    /**
     * @dev See {IERC165-supportsInterface}.
     *
     * Time complexity O(1), guaranteed to always use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId)
        public
        view
        virtual
        override
        returns (bool)
    {
        return _supportedInterfaces[interfaceId];
    }

    /**
     * @dev Registers the contract as an implementer of the interface defined by
     * `interfaceId`. Support of the actual ERC165 interface is automatic and
     * registering its interface id is not required.
     *
     * See {IERC165-supportsInterface}.
     *
     * Requirements:
     *
     * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).
     */
    function _registerInterface(bytes4 interfaceId) internal virtual {
        require(interfaceId != 0xffffffff, "ERC165: invalid interface id");
        _supportedInterfaces[interfaceId] = true;
    }
}

// File: http://github.com/OpenZeppelin/openzeppelin-contracts/contracts/token/ERC721/IERC721Receiver.sol

pragma solidity 0.8.0;

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

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

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

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

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

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

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

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

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

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

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

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

pragma solidity 0.8.0;

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

// File: http://github.com/OpenZeppelin/openzeppelin-contracts/contracts/token/ERC721/IERC721Enumerable.sol

pragma solidity 0.8.0;

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

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

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

// File: http://github.com/OpenZeppelin/openzeppelin-contracts/contracts/token/ERC721/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: http://github.com/OpenZeppelin/openzeppelin-contracts/contracts/introspection/IERC165.sol

// File: http://github.com/OpenZeppelin/openzeppelin-contracts/contracts/utils/Context.sol

pragma solidity 0.8.0;

/*
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with GSN 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) {
        this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
        return msg.data;
    }
}

// File: http://github.com/OpenZeppelin/openzeppelin-contracts/contracts/token/ERC721/ERC721.sol

pragma solidity 0.8.0;

/**
 * @title ERC721 Non-Fungible Token Standard basic implementation
 * @dev see https://eips.ethereum.org/EIPS/eip-721
 */
contract ERC721 is
    Context,
    ERC165,
    IERC721,
    IERC721Metadata,
    IERC721Enumerable
{
    using Address for address;
    using EnumerableSet for EnumerableSet.UintSet;
    using EnumerableMap for EnumerableMap.UintToAddressMap;
    using Strings for uint256;

    // Mapping from holder address to their (enumerable) set of owned tokens
    mapping(address => EnumerableSet.UintSet) private _holderTokens;

    // Enumerable mapping from token ids to their owners
    EnumerableMap.UintToAddressMap private _tokenOwners;

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

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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

    // Optional mapping for token URIs
    mapping(uint256 => string) private _tokenURIs;

    // Base URI
    string private _baseURI;

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

        // register the supported interfaces to conform to ERC721 via ERC165
        _registerInterface(type(IERC721).interfaceId);
        _registerInterface(type(IERC721Metadata).interfaceId);
        _registerInterface(type(IERC721Enumerable).interfaceId);
    }

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

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId)
        public
        view
        virtual
        override
        returns (address)
    {
        return
            _tokenOwners.get(
                tokenId,
                "ERC721: owner query for nonexistent token"
            );
    }

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

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

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

        string memory _tokenURI = _tokenURIs[tokenId];
        string memory base = baseURI();

        // If there is no base URI, return the token URI.
        if (bytes(base).length == 0) {
            return _tokenURI;
        }
        // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).
        if (bytes(_tokenURI).length > 0) {
            return string(abi.encodePacked(base, _tokenURI));
        }
        // If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.
        return string(abi.encodePacked(base, tokenId.toString()));
    }

    /**
     * @dev Returns the base URI set via {_setBaseURI}. This will be
     * automatically added as a prefix in {tokenURI} to each token's URI, or
     * to the token ID if no specific URI is set for that token ID.
     */
    function baseURI() public view virtual returns (string memory) {
        return _baseURI;
    }

    /**
     * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.
     */
    function tokenOfOwnerByIndex(address owner, uint256 index)
        public
        view
        virtual
        override
        returns (uint256)
    {
        return _holderTokens[owner].at(index);
    }

    /**
     * @dev See {IERC721Enumerable-totalSupply}.
     */
    function totalSupply() public view virtual override returns (uint256) {
        // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds
        return _tokenOwners.length();
    }

    /**
     * @dev See {IERC721Enumerable-tokenByIndex}.
     */
    function tokenByIndex(uint256 index)
        public
        view
        virtual
        override
        returns (uint256)
    {
        (uint256 tokenId, ) = _tokenOwners.at(index);
        return tokenId;
    }

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

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

        _approve(to, tokenId);
    }

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

        return _tokenApprovals[tokenId];
    }

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

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

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

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

        _transfer(from, to, tokenId);
    }

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

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

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

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

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

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

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

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

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

        _holderTokens[to].add(tokenId);

        _tokenOwners.set(tokenId, to);

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

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

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

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

        // Clear metadata (if any)
        if (bytes(_tokenURIs[tokenId]).length != 0) {
            delete _tokenURIs[tokenId];
        }

        _holderTokens[owner].remove(tokenId);

        _tokenOwners.remove(tokenId);

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

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

        _beforeTokenTransfer(from, to, tokenId);

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

        _holderTokens[from].remove(tokenId);
        _holderTokens[to].add(tokenId);

        _tokenOwners.set(tokenId, to);
        emit Transfer(from, to, tokenId);
    }

    /**
     * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function _setTokenURI(uint256 tokenId, string memory _tokenURI)
        internal
        virtual
    {
        require(
            _exists(tokenId),
            "ERC721Metadata: URI set of nonexistent token"
        );
        _tokenURIs[tokenId] = _tokenURI;
    }

    /**
     * @dev Internal function to set the base URI for all token IDs. It is
     * automatically added as a prefix to the value returned in {tokenURI},
     * or to the token ID if {tokenURI} is empty.
     */
    function _setBaseURI(string memory baseURI_) internal virtual {
        _baseURI = baseURI_;
    }

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

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

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

// File: http://github.com/OpenZeppelin/openzeppelin-contracts/contracts/access/Ownable.sol

pragma solidity 0.8.0;

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

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

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        address msgSender = _msgSender();
        _owner = msgSender;
        emit OwnershipTransferred(address(0), msgSender);
    }

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

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
        _;
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        emit OwnershipTransferred(_owner, address(0));
        _owner = 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"
        );
        emit OwnershipTransferred(_owner, newOwner);
        _owner = newOwner;
    }
}

// File: https://github.com/OpenZeppelin/openzeppelin-contracts/contracts/utils/math/SafeMath.sol

pragma solidity 0.8.0;

// CAUTION
// This version of SafeMath should only be used with Solidity 0.8 or later,
// because it relies on the compiler's built in overflow checks.

/**
 * @dev Wrappers over Solidity's arithmetic operations.
 *
 * NOTE: `SafeMath` is no longer needed starting with Solidity 0.8. The compiler
 * now has built in overflow checking.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryAdd(uint256 a, uint256 b)
        internal
        pure
        returns (bool, uint256)
    {
        unchecked {
            uint256 c = a + b;
            if (c < a) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the substraction of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function trySub(uint256 a, uint256 b)
        internal
        pure
        returns (bool, uint256)
    {
        unchecked {
            if (b > a) return (false, 0);
            return (true, a - b);
        }
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryMul(uint256 a, uint256 b)
        internal
        pure
        returns (bool, uint256)
    {
        unchecked {
            // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
            // benefit is lost if 'b' is also tested.
            // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
            if (a == 0) return (true, 0);
            uint256 c = a * b;
            if (c / a != b) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the division of two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryDiv(uint256 a, uint256 b)
        internal
        pure
        returns (bool, uint256)
    {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a / b);
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryMod(uint256 a, uint256 b)
        internal
        pure
        returns (bool, uint256)
    {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a % b);
        }
    }

    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        return a + b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        return a - b;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        return a * b;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator.
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        return a % b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {trySub}.
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b <= a, errorMessage);
            return a - b;
        }
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b > 0, errorMessage);
            return a / b;
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting with custom message when dividing by zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryMod}.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b > 0, errorMessage);
            return a % b;
        }
    }
}

pragma solidity 0.8.0;

// SPDX-License-Identifier: UNLICENSED

contract Quadrums is ERC721, Ownable {
    using SafeMath for uint256;
    using Strings for uint256;
    uint256 public constant MAX_QUADRUMS = 1024;
    bool public hasSaleStarted = false;
    mapping(uint256 => uint256) public creationDates;
    mapping(uint256 => address) public creators;

    // these will be set in future
    string public METADATA_PROVENANCE_HASH = "";
    string public GENERATOR_ADDRESS =
        "https://quadrums.art/api/generator/";
    string public IPFS_GENERATOR_ADDRESS = "";
    string public SCRIPT = "";
    // e.s added minter address to hash algorithm
    constructor() ERC721("Quadrums", "QDRMS") {
        setBaseURI("https://quadrums.art/api/token/");
        _safeMint(msg.sender, 1);
        creationDates[0] = block.number;
        creators[0] = msg.sender;
        SCRIPT = "";
    }

    function tokensOfOwner(address _owner)
        external
        view
        returns (uint256[] memory)
    {
        uint256 tokenCount = balanceOf(_owner);
        if (tokenCount == 0) {
            // Return an empty array
            return new uint256[](0);
        } else {
            uint256[] memory result = new uint256[](tokenCount);
            uint256 index;
            for (index = 0; index < tokenCount; index++) {
                result[index] = tokenOfOwnerByIndex(_owner, index);
            }
            return result;
        }
    }

    function calculatePrice() public pure returns (uint256) {
        return 40000000000000000;
    }

    function mint(uint256 maxQuadrums) public payable {
        require(totalSupply() < MAX_QUADRUMS, "Sale has already ended");
        require(
            maxQuadrums > 0 && maxQuadrums <= 10,
            "You can claim minimum 1, maximum 10"
        );
        require(
            totalSupply().add(maxQuadrums) <= MAX_QUADRUMS,
            "Exceeds MAX_QUADRUMS"
        );
        require(
            msg.value >= calculatePrice().mul(maxQuadrums),
            "Ether value sent is below the price"
        );

        for (uint256 i = 0; i < maxQuadrums; i++) {
            uint256 mintIndex = totalSupply();
            _safeMint(msg.sender, mintIndex + 1);
            creationDates[mintIndex] = block.number;
            creators[mintIndex] = msg.sender;
        }
    }

    // ONLYOWNER FUNCTIONS

    function setProvenanceHash(string memory _hash) public onlyOwner {
        METADATA_PROVENANCE_HASH = _hash;
    }

    function setGeneratorIPFSHash(string memory _hash) public onlyOwner {
        IPFS_GENERATOR_ADDRESS = _hash;
    }

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

    function startDrop() public onlyOwner {
        hasSaleStarted = true;
    }

    function pauseDrop() public onlyOwner {
        hasSaleStarted = false;
    }

    function withdrawAll() public payable onlyOwner {
        require(payable(msg.sender).send(address(this).balance));
    }

    function tokenHash(uint256 tokenId) public view returns (bytes32) {
        require(_exists(tokenId), "DOES NOT EXIST");
        return
            bytes32(
                keccak256(
                    abi.encodePacked(
                        address(this),
                        creationDates[tokenId],
                        creators[tokenId],
                        tokenId
                    )
                )
            );
    }

    function generatorAddress(uint256 tokenId)
        public
        view
        returns (string memory)
    {
        require(_exists(tokenId), "DOES NOT EXIST");
        return string(abi.encodePacked(GENERATOR_ADDRESS, tokenId.toString()));
    }

    function IPFSgeneratorAddress(uint256 tokenId)
        public
        view
        returns (string memory)
    {
        require(_exists(tokenId), "DOES NOT EXIST");
        return
            string(
                abi.encodePacked(IPFS_GENERATOR_ADDRESS, tokenId.toString())
            );
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"GENERATOR_ADDRESS","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"IPFS_GENERATOR_ADDRESS","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"IPFSgeneratorAddress","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_QUADRUMS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"METADATA_PROVENANCE_HASH","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SCRIPT","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"calculatePrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"creationDates","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"creators","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"generatorAddress","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"hasSaleStarted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"maxQuadrums","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","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":"pauseDrop","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"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":"string","name":"_hash","type":"string"}],"name":"setGeneratorIPFSHash","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_hash","type":"string"}],"name":"setProvenanceHash","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startDrop","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":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"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":[{"internalType":"address","name":"_owner","type":"address"}],"name":"tokensOfOwner","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":"withdrawAll","outputs":[],"stateMutability":"payable","type":"function"}]

60806040526000600a60146101000a81548160ff02191690831515021790555060405180602001604052806000815250600d90805190602001906200004692919062000c3a565b5060405180606001604052806023815260200162005bc160239139600e90805190602001906200007892919062000c3a565b5060405180602001604052806000815250600f9080519060200190620000a092919062000c3a565b506040518060200160405280600081525060109080519060200190620000c892919062000c3a565b50348015620000d657600080fd5b506040518060400160405280600881526020017f5175616472756d730000000000000000000000000000000000000000000000008152506040518060400160405280600581526020017f5144524d53000000000000000000000000000000000000000000000000000000815250620001747f01ffc9a700000000000000000000000000000000000000000000000000000000620003dd60201b60201c565b81600690805190602001906200018c92919062000c3a565b508060079080519060200190620001a592919062000c3a565b50620001d77f80ac58cd00000000000000000000000000000000000000000000000000000000620003dd60201b60201c565b620002087f5b5e139f00000000000000000000000000000000000000000000000000000000620003dd60201b60201c565b620002397f780e9d6300000000000000000000000000000000000000000000000000000000620003dd60201b60201c565b505060006200024d620004b560201b60201c565b905080600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a350620003326040518060400160405280601f81526020017f68747470733a2f2f7175616472756d732e6172742f6170692f746f6b656e2f00815250620004bd60201b60201c565b620003453360016200056060201b60201c565b43600b60008081526020019081526020016000208190555033600c600080815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506040518060200160405280600081525060109080519060200190620003d692919062000c3a565b50620011c5565b63ffffffff60e01b817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141562000449576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620004409062000f76565b60405180910390fd5b6001600080837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b600033905090565b620004cd620004b560201b60201c565b73ffffffffffffffffffffffffffffffffffffffff16620004f36200058660201b60201c565b73ffffffffffffffffffffffffffffffffffffffff16146200054c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620005439062000fdc565b60405180910390fd5b6200055d81620005b060201b60201c565b50565b62000582828260405180602001604052806000815250620005cc60201b60201c565b5050565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b8060099080519060200190620005c892919062000c3a565b5050565b620005de83836200063a60201b60201c565b620005f36000848484620007ec60201b60201c565b62000635576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200062c9062000f54565b60405180910390fd5b505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415620006ad576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620006a49062000fba565b60405180910390fd5b620006be81620009a660201b60201c565b1562000701576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620006f89062000f98565b60405180910390fd5b6200071560008383620009ca60201b60201c565b6200076d81600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020620009cf60201b620021bb1790919060201c565b506200078b81836002620009f160201b620021d5179092919060201c565b50808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050565b60006200081a8473ffffffffffffffffffffffffffffffffffffffff1662000a2e60201b6200220a1760201c565b1562000999578373ffffffffffffffffffffffffffffffffffffffff1663150b7a026200084c620004b560201b60201c565b8786866040518563ffffffff1660e01b815260040162000870949392919062000f00565b602060405180830381600087803b1580156200088b57600080fd5b505af1925050508015620008bf57506040513d601f19601f82011682018060405250810190620008bc919062000d01565b60015b62000948573d8060008114620008f2576040519150601f19603f3d011682016040523d82523d6000602084013e620008f7565b606091505b5060008151141562000940576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620009379062000f54565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149150506200099e565b600190505b949350505050565b6000620009c382600262000a4160201b6200221d1790919060201c565b9050919050565b505050565b6000620009e9836000018360001b62000a6360201b60201c565b905092915050565b600062000a25846000018460001b8473ffffffffffffffffffffffffffffffffffffffff1660001b62000add60201b60201c565b90509392505050565b600080823b905060008111915050919050565b600062000a5b836000018360001b62000bf460201b60201c565b905092915050565b600062000a77838362000c1760201b60201c565b62000ad257826000018290806001815401808255809150506001900390600052602060002001600090919091909150558260000180549050836001016000848152602001908152602001600020819055506001905062000ad7565b600090505b92915050565b600080846001016000858152602001908152602001600020549050600081141562000b865784600001604051806040016040528086815260200185815250908060018154018082558091505060019003906000526020600020906002020160009091909190915060008201518160000155602082015181600101555050846000018054905085600101600086815260200190815260200160002081905550600191505062000bed565b828560000160018362000b9a91906200102b565b8154811062000bd2577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002090600202016001018190555060009150505b9392505050565b600080836001016000848152602001908152602001600020541415905092915050565b600080836001016000848152602001908152602001600020541415905092915050565b82805462000c489062001106565b90600052602060002090601f01602090048101928262000c6c576000855562000cb8565b82601f1062000c8757805160ff191683800117855562000cb8565b8280016001018555821562000cb8579182015b8281111562000cb757825182559160200191906001019062000c9a565b5b50905062000cc7919062000ccb565b5090565b5b8082111562000ce657600081600090555060010162000ccc565b5090565b60008151905062000cfb81620011ab565b92915050565b60006020828403121562000d1457600080fd5b600062000d248482850162000cea565b91505092915050565b62000d388162001066565b82525050565b600062000d4b8262000ffe565b62000d57818562001009565b935062000d69818560208601620010d0565b62000d74816200119a565b840191505092915050565b600062000d8e6032836200101a565b91507f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008301527f63656976657220696d706c656d656e74657200000000000000000000000000006020830152604082019050919050565b600062000df6601c836200101a565b91507f4552433136353a20696e76616c696420696e74657266616365206964000000006000830152602082019050919050565b600062000e38601c836200101a565b91507f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006000830152602082019050919050565b600062000e7a6020836200101a565b91507f4552433732313a206d696e7420746f20746865207a65726f20616464726573736000830152602082019050919050565b600062000ebc6020836200101a565b91507f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726000830152602082019050919050565b62000efa81620010c6565b82525050565b600060808201905062000f17600083018762000d2d565b62000f26602083018662000d2d565b62000f35604083018562000eef565b818103606083015262000f49818462000d3e565b905095945050505050565b6000602082019050818103600083015262000f6f8162000d7f565b9050919050565b6000602082019050818103600083015262000f918162000de7565b9050919050565b6000602082019050818103600083015262000fb38162000e29565b9050919050565b6000602082019050818103600083015262000fd58162000e6b565b9050919050565b6000602082019050818103600083015262000ff78162000ead565b9050919050565b600081519050919050565b600082825260208201905092915050565b600082825260208201905092915050565b60006200103882620010c6565b91506200104583620010c6565b9250828210156200105b576200105a6200113c565b5b828203905092915050565b60006200107382620010a6565b9050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b60005b83811015620010f0578082015181840152602081019050620010d3565b8381111562001100576000848401525b50505050565b600060028204905060018216806200111f57607f821691505b602082108114156200113657620011356200116b565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000601f19601f8301169050919050565b620011b6816200107a565b8114620011c257600080fd5b50565b6149ec80620011d56000396000f3fe60806040526004361061023b5760003560e01c8063753853c11161012e578063a3864397116100ab578063d348b4091161006f578063d348b4091461088f578063de69fe88146108ba578063e985e9c5146108e5578063f0c9dc6014610922578063f2fde38b1461094d5761023b565b8063a386439714610772578063b88d4fde146107af578063c87b56dd146107d8578063c8a0122614610815578063cd53d08e146108525761023b565b80638da5cb5b116100f25780638da5cb5b1461069a57806395d89b41146106c55780639758e904146106f0578063a0712d681461072d578063a22cb465146107495761023b565b8063753853c1146105d45780638285d4a3146105ff5780638462151c1461062a578063853828b614610667578063891cc177146106715761023b565b80632f745c59116101bc5780636352211e116101805780636352211e146104db57806363d96941146105185780636c0360eb1461055557806370a0823114610580578063715018a6146105bd5761023b565b80632f745c59146103f857806334d84c7b1461043557806342842e0e1461044c5780634f6ccce71461047557806355f804b3146104b25761023b565b806318160ddd1161020357806318160ddd146103375780631c8b232d1461036257806323b872dd1461038d5780632808c92c146103b65780632ee2ac36146103cd5761023b565b806301ffc9a71461024057806306fdde031461027d578063081812fc146102a8578063095ea7b3146102e5578063109695231461030e575b600080fd5b34801561024c57600080fd5b50610267600480360381019061026291906135ad565b610976565b6040516102749190614153565b60405180910390f35b34801561028957600080fd5b506102926109dd565b60405161029f9190614189565b60405180910390f35b3480156102b457600080fd5b506102cf60048036038101906102ca9190613640565b610a6f565b6040516102dc91906140ca565b60405180910390f35b3480156102f157600080fd5b5061030c60048036038101906103079190613571565b610af4565b005b34801561031a57600080fd5b50610335600480360381019061033091906135ff565b610c0c565b005b34801561034357600080fd5b5061034c610ca2565b604051610359919061446b565b60405180910390f35b34801561036e57600080fd5b50610377610cb3565b6040516103849190614153565b60405180910390f35b34801561039957600080fd5b506103b460048036038101906103af919061346b565b610cc6565b005b3480156103c257600080fd5b506103cb610d26565b005b3480156103d957600080fd5b506103e2610dbf565b6040516103ef9190614189565b60405180910390f35b34801561040457600080fd5b5061041f600480360381019061041a9190613571565b610e4d565b60405161042c919061446b565b60405180910390f35b34801561044157600080fd5b5061044a610ea8565b005b34801561045857600080fd5b50610473600480360381019061046e919061346b565b610f41565b005b34801561048157600080fd5b5061049c60048036038101906104979190613640565b610f61565b6040516104a9919061446b565b60405180910390f35b3480156104be57600080fd5b506104d960048036038101906104d491906135ff565b610f84565b005b3480156104e757600080fd5b5061050260048036038101906104fd9190613640565b61100c565b60405161050f91906140ca565b60405180910390f35b34801561052457600080fd5b5061053f600480360381019061053a9190613640565b611043565b60405161054c9190614189565b60405180910390f35b34801561056157600080fd5b5061056a6110bf565b6040516105779190614189565b60405180910390f35b34801561058c57600080fd5b506105a760048036038101906105a29190613406565b611151565b6040516105b4919061446b565b60405180910390f35b3480156105c957600080fd5b506105d2611210565b005b3480156105e057600080fd5b506105e961134d565b6040516105f69190614189565b60405180910390f35b34801561060b57600080fd5b506106146113db565b604051610621919061446b565b60405180910390f35b34801561063657600080fd5b50610651600480360381019061064c9190613406565b6113e1565b60405161065e9190614131565b60405180910390f35b61066f61155d565b005b34801561067d57600080fd5b50610698600480360381019061069391906135ff565b611619565b005b3480156106a657600080fd5b506106af6116af565b6040516106bc91906140ca565b60405180910390f35b3480156106d157600080fd5b506106da6116d9565b6040516106e79190614189565b60405180910390f35b3480156106fc57600080fd5b5061071760048036038101906107129190613640565b61176b565b6040516107249190614189565b60405180910390f35b61074760048036038101906107429190613640565b6117e7565b005b34801561075557600080fd5b50610770600480360381019061076b9190613535565b6119eb565b005b34801561077e57600080fd5b5061079960048036038101906107949190613640565b611b6c565b6040516107a6919061416e565b60405180910390f35b3480156107bb57600080fd5b506107d660048036038101906107d191906134ba565b611c30565b005b3480156107e457600080fd5b506107ff60048036038101906107fa9190613640565b611c92565b60405161080c9190614189565b60405180910390f35b34801561082157600080fd5b5061083c60048036038101906108379190613640565b611e05565b604051610849919061446b565b60405180910390f35b34801561085e57600080fd5b5061087960048036038101906108749190613640565b611e1d565b60405161088691906140ca565b60405180910390f35b34801561089b57600080fd5b506108a4611e50565b6040516108b1919061446b565b60405180910390f35b3480156108c657600080fd5b506108cf611e5f565b6040516108dc9190614189565b60405180910390f35b3480156108f157600080fd5b5061090c6004803603810190610907919061342f565b611eed565b6040516109199190614153565b60405180910390f35b34801561092e57600080fd5b50610937611f81565b6040516109449190614189565b60405180910390f35b34801561095957600080fd5b50610974600480360381019061096f9190613406565b61200f565b005b6000806000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060009054906101000a900460ff169050919050565b6060600680546109ec9061477d565b80601f0160208091040260200160405190810160405280929190818152602001828054610a189061477d565b8015610a655780601f10610a3a57610100808354040283529160200191610a65565b820191906000526020600020905b815481529060010190602001808311610a4857829003601f168201915b5050505050905090565b6000610a7a82612237565b610ab9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ab09061436b565b60405180910390fd5b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610aff8261100c565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610b70576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b67906143eb565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610b8f612254565b73ffffffffffffffffffffffffffffffffffffffff161480610bbe5750610bbd81610bb8612254565b611eed565b5b610bfd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bf4906142ab565b60405180910390fd5b610c07838361225c565b505050565b610c14612254565b73ffffffffffffffffffffffffffffffffffffffff16610c326116af565b73ffffffffffffffffffffffffffffffffffffffff1614610c88576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c7f9061438b565b60405180910390fd5b80600d9080519060200190610c9e92919061322a565b5050565b6000610cae6002612315565b905090565b600a60149054906101000a900460ff1681565b610cd7610cd1612254565b8261232a565b610d16576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d0d9061442b565b60405180910390fd5b610d21838383612408565b505050565b610d2e612254565b73ffffffffffffffffffffffffffffffffffffffff16610d4c6116af565b73ffffffffffffffffffffffffffffffffffffffff1614610da2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d999061438b565b60405180910390fd5b6000600a60146101000a81548160ff021916908315150217905550565b600e8054610dcc9061477d565b80601f0160208091040260200160405190810160405280929190818152602001828054610df89061477d565b8015610e455780601f10610e1a57610100808354040283529160200191610e45565b820191906000526020600020905b815481529060010190602001808311610e2857829003601f168201915b505050505081565b6000610ea082600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061261f90919063ffffffff16565b905092915050565b610eb0612254565b73ffffffffffffffffffffffffffffffffffffffff16610ece6116af565b73ffffffffffffffffffffffffffffffffffffffff1614610f24576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f1b9061438b565b60405180910390fd5b6001600a60146101000a81548160ff021916908315150217905550565b610f5c83838360405180602001604052806000815250611c30565b505050565b600080610f7883600261263990919063ffffffff16565b50905080915050919050565b610f8c612254565b73ffffffffffffffffffffffffffffffffffffffff16610faa6116af565b73ffffffffffffffffffffffffffffffffffffffff1614611000576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ff79061438b565b60405180910390fd5b61100981612665565b50565b600061103c8260405180606001604052806029815260200161498e60299139600261267f9092919063ffffffff16565b9050919050565b606061104e82612237565b61108d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110849061444b565b60405180910390fd5b600e6110988361269e565b6040516020016110a99291906140a6565b6040516020818303038152906040529050919050565b6060600980546110ce9061477d565b80601f01602080910402602001604051908101604052809291908181526020018280546110fa9061477d565b80156111475780601f1061111c57610100808354040283529160200191611147565b820191906000526020600020905b81548152906001019060200180831161112a57829003601f168201915b5050505050905090565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156111c2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111b9906142cb565b60405180910390fd5b611209600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061284b565b9050919050565b611218612254565b73ffffffffffffffffffffffffffffffffffffffff166112366116af565b73ffffffffffffffffffffffffffffffffffffffff161461128c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112839061438b565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a36000600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b600f805461135a9061477d565b80601f01602080910402602001604051908101604052809291908181526020018280546113869061477d565b80156113d35780601f106113a8576101008083540402835291602001916113d3565b820191906000526020600020905b8154815290600101906020018083116113b657829003601f168201915b505050505081565b61040081565b606060006113ee83611151565b9050600081141561147157600067ffffffffffffffff81111561143a577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280602002602001820160405280156114685781602001602082028036833780820191505090505b50915050611558565b60008167ffffffffffffffff8111156114b3577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280602002602001820160405280156114e15781602001602082028036833780820191505090505b50905060005b82811015611551576114f98582610e4d565b828281518110611532577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020026020010181815250508080611549906147af565b9150506114e7565b8193505050505b919050565b611565612254565b73ffffffffffffffffffffffffffffffffffffffff166115836116af565b73ffffffffffffffffffffffffffffffffffffffff16146115d9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115d09061438b565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f1935050505061161757600080fd5b565b611621612254565b73ffffffffffffffffffffffffffffffffffffffff1661163f6116af565b73ffffffffffffffffffffffffffffffffffffffff1614611695576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161168c9061438b565b60405180910390fd5b80600f90805190602001906116ab92919061322a565b5050565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6060600780546116e89061477d565b80601f01602080910402602001604051908101604052809291908181526020018280546117149061477d565b80156117615780601f1061173657610100808354040283529160200191611761565b820191906000526020600020905b81548152906001019060200180831161174457829003601f168201915b5050505050905090565b606061177682612237565b6117b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117ac9061444b565b60405180910390fd5b600f6117c08361269e565b6040516020016117d19291906140a6565b6040516020818303038152906040529050919050565b6104006117f2610ca2565b10611832576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118299061440b565b60405180910390fd5b6000811180156118435750600a8111155b611882576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118799061434b565b60405180910390fd5b61040061189f82611891610ca2565b61286090919063ffffffff16565b11156118e0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118d79061428b565b60405180910390fd5b6118fa816118ec611e50565b61287690919063ffffffff16565b34101561193c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611933906142eb565b60405180910390fd5b60005b818110156119e7576000611951610ca2565b90506119693360018361196491906145a8565b61288c565b43600b60008381526020019081526020016000208190555033600c600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505080806119df906147af565b91505061193f565b5050565b6119f3612254565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611a61576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a589061424b565b60405180910390fd5b8060056000611a6e612254565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16611b1b612254565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051611b609190614153565b60405180910390a35050565b6000611b7782612237565b611bb6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bad9061444b565b60405180910390fd5b30600b600084815260200190815260200160002054600c600085815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1684604051602001611c139493929190614034565b604051602081830303815290604052805190602001209050919050565b611c41611c3b612254565b8361232a565b611c80576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c779061442b565b60405180910390fd5b611c8c848484846128aa565b50505050565b6060611c9d82612237565b611cdc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cd3906143cb565b60405180910390fd5b6000600860008481526020019081526020016000208054611cfc9061477d565b80601f0160208091040260200160405190810160405280929190818152602001828054611d289061477d565b8015611d755780601f10611d4a57610100808354040283529160200191611d75565b820191906000526020600020905b815481529060010190602001808311611d5857829003601f168201915b505050505090506000611d866110bf565b9050600081511415611d9c578192505050611e00565b600082511115611dd1578082604051602001611db9929190614082565b60405160208183030381529060405292505050611e00565b80611ddb8561269e565b604051602001611dec929190614082565b604051602081830303815290604052925050505b919050565b600b6020528060005260406000206000915090505481565b600c6020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000668e1bc9bf040000905090565b60108054611e6c9061477d565b80601f0160208091040260200160405190810160405280929190818152602001828054611e989061477d565b8015611ee55780601f10611eba57610100808354040283529160200191611ee5565b820191906000526020600020905b815481529060010190602001808311611ec857829003601f168201915b505050505081565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b600d8054611f8e9061477d565b80601f0160208091040260200160405190810160405280929190818152602001828054611fba9061477d565b80156120075780601f10611fdc57610100808354040283529160200191612007565b820191906000526020600020905b815481529060010190602001808311611fea57829003601f168201915b505050505081565b612017612254565b73ffffffffffffffffffffffffffffffffffffffff166120356116af565b73ffffffffffffffffffffffffffffffffffffffff161461208b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120829061438b565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156120fb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120f2906141eb565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60006121cd836000018360001b612906565b905092915050565b6000612201846000018460001b8473ffffffffffffffffffffffffffffffffffffffff1660001b612976565b90509392505050565b600080823b905060008111915050919050565b600061222f836000018360001b612a88565b905092915050565b600061224d82600261221d90919063ffffffff16565b9050919050565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff166122cf8361100c565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600061232382600001612aab565b9050919050565b600061233582612237565b612374576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161236b9061426b565b60405180910390fd5b600061237f8361100c565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614806123ee57508373ffffffffffffffffffffffffffffffffffffffff166123d684610a6f565b73ffffffffffffffffffffffffffffffffffffffff16145b806123ff57506123fe8185611eed565b5b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff166124288261100c565b73ffffffffffffffffffffffffffffffffffffffff161461247e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612475906143ab565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156124ee576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124e59061422b565b60405180910390fd5b6124f9838383612abc565b61250460008261225c565b61255581600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020612ac190919063ffffffff16565b506125a781600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206121bb90919063ffffffff16565b506125be818360026121d59092919063ffffffff16565b50808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b600061262e8360000183612adb565b60001c905092915050565b60008060008061264c8660000186612b75565b915091508160001c8160001c9350935050509250929050565b806009908051906020019061267b92919061322a565b5050565b6000612692846000018460001b84612c25565b60001c90509392505050565b606060008214156126e6576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050612846565b600082905060005b60008214612718578080612701906147af565b915050600a8261271191906145fe565b91506126ee565b60008167ffffffffffffffff81111561275a577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280601f01601f19166020018201604052801561278c5781602001600182028036833780820191505090505b5090505b6000851461283f576001826127a59190614689565b9150600a856127b49190614826565b60306127c091906145a8565b60f81b8183815181106127fc577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a8561283891906145fe565b9450612790565b8093505050505b919050565b600061285982600001612cec565b9050919050565b6000818361286e91906145a8565b905092915050565b60008183612884919061462f565b905092915050565b6128a6828260405180602001604052806000815250612cfd565b5050565b6128b5848484612408565b6128c184848484612d58565b612900576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128f7906141cb565b60405180910390fd5b50505050565b60006129128383612eef565b61296b578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050612970565b600090505b92915050565b6000808460010160008581526020019081526020016000205490506000811415612a1d57846000016040518060400160405280868152602001858152509080600181540180825580915050600190039060005260206000209060020201600090919091909150600082015181600001556020820151816001015550508460000180549050856001016000868152602001908152602001600020819055506001915050612a81565b8285600001600183612a2f9190614689565b81548110612a66577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002090600202016001018190555060009150505b9392505050565b600080836001016000848152602001908152602001600020541415905092915050565b600081600001805490509050919050565b505050565b6000612ad3836000018360001b612f12565b905092915050565b600081836000018054905011612b26576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b1d906141ab565b60405180910390fd5b826000018281548110612b62577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154905092915050565b60008082846000018054905011612bc1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612bb89061430b565b60405180910390fd5b6000846000018481548110612bff577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b906000526020600020906002020190508060000154816001015492509250509250929050565b60008084600101600085815260200190815260200160002054905060008114158390612c87576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c7e9190614189565b60405180910390fd5b5084600001600182612c999190614689565b81548110612cd0577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000209060020201600101549150509392505050565b600081600001805490509050919050565b612d07838361309c565b612d146000848484612d58565b612d53576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d4a906141cb565b60405180910390fd5b505050565b6000612d798473ffffffffffffffffffffffffffffffffffffffff1661220a565b15612ee2578373ffffffffffffffffffffffffffffffffffffffff1663150b7a02612da2612254565b8786866040518563ffffffff1660e01b8152600401612dc494939291906140e5565b602060405180830381600087803b158015612dde57600080fd5b505af1925050508015612e0f57506040513d601f19601f82011682018060405250810190612e0c91906135d6565b60015b612e92573d8060008114612e3f576040519150601f19603f3d011682016040523d82523d6000602084013e612e44565b606091505b50600081511415612e8a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e81906141cb565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050612ee7565b600190505b949350505050565b600080836001016000848152602001908152602001600020541415905092915050565b60008083600101600084815260200190815260200160002054905060008114613090576000600182612f449190614689565b9050600060018660000180549050612f5c9190614689565b90506000866000018281548110612f9c577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154905080876000018481548110612fe6577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b906000526020600020018190555060018361300191906145a8565b8760010160008381526020019081526020016000208190555086600001805480613054577f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050613096565b60009150505b92915050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561310c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016131039061432b565b60405180910390fd5b61311581612237565b15613155576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161314c9061420b565b60405180910390fd5b61316160008383612abc565b6131b281600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206121bb90919063ffffffff16565b506131c9818360026121d59092919063ffffffff16565b50808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050565b8280546132369061477d565b90600052602060002090601f016020900481019282613258576000855561329f565b82601f1061327157805160ff191683800117855561329f565b8280016001018555821561329f579182015b8281111561329e578251825591602001919060010190613283565b5b5090506132ac91906132b0565b5090565b5b808211156132c95760008160009055506001016132b1565b5090565b60006132e06132db846144b7565b614486565b9050828152602081018484840111156132f857600080fd5b61330384828561473b565b509392505050565b600061331e613319846144e7565b614486565b90508281526020810184848401111561333657600080fd5b61334184828561473b565b509392505050565b60008135905061335881614931565b92915050565b60008135905061336d81614948565b92915050565b6000813590506133828161495f565b92915050565b6000815190506133978161495f565b92915050565b600082601f8301126133ae57600080fd5b81356133be8482602086016132cd565b91505092915050565b600082601f8301126133d857600080fd5b81356133e884826020860161330b565b91505092915050565b60008135905061340081614976565b92915050565b60006020828403121561341857600080fd5b600061342684828501613349565b91505092915050565b6000806040838503121561344257600080fd5b600061345085828601613349565b925050602061346185828601613349565b9150509250929050565b60008060006060848603121561348057600080fd5b600061348e86828701613349565b935050602061349f86828701613349565b92505060406134b0868287016133f1565b9150509250925092565b600080600080608085870312156134d057600080fd5b60006134de87828801613349565b94505060206134ef87828801613349565b9350506040613500878288016133f1565b925050606085013567ffffffffffffffff81111561351d57600080fd5b6135298782880161339d565b91505092959194509250565b6000806040838503121561354857600080fd5b600061355685828601613349565b92505060206135678582860161335e565b9150509250929050565b6000806040838503121561358457600080fd5b600061359285828601613349565b92505060206135a3858286016133f1565b9150509250929050565b6000602082840312156135bf57600080fd5b60006135cd84828501613373565b91505092915050565b6000602082840312156135e857600080fd5b60006135f684828501613388565b91505092915050565b60006020828403121561361157600080fd5b600082013567ffffffffffffffff81111561362b57600080fd5b613637848285016133c7565b91505092915050565b60006020828403121561365257600080fd5b6000613660848285016133f1565b91505092915050565b60006136758383613fff565b60208301905092915050565b61368a816146bd565b82525050565b6136a161369c826146bd565b6147f8565b82525050565b60006136b28261453c565b6136bc818561456a565b93506136c783614517565b8060005b838110156136f85781516136df8882613669565b97506136ea8361455d565b9250506001810190506136cb565b5085935050505092915050565b61370e816146cf565b82525050565b61371d816146db565b82525050565b600061372e82614547565b613738818561457b565b935061374881856020860161474a565b61375181614913565b840191505092915050565b600061376782614552565b613771818561458c565b935061378181856020860161474a565b61378a81614913565b840191505092915050565b60006137a082614552565b6137aa818561459d565b93506137ba81856020860161474a565b80840191505092915050565b600081546137d38161477d565b6137dd818661459d565b945060018216600081146137f857600181146138095761383c565b60ff1983168652818601935061383c565b61381285614527565b60005b8381101561383457815481890152600182019150602081019050613815565b838801955050505b50505092915050565b600061385260228361458c565b91507f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e60008301527f64730000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006138b860328361458c565b91507f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008301527f63656976657220696d706c656d656e74657200000000000000000000000000006020830152604082019050919050565b600061391e60268361458c565b91507f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008301527f64647265737300000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613984601c8361458c565b91507f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006000830152602082019050919050565b60006139c460248361458c565b91507f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008301527f72657373000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613a2a60198361458c565b91507f4552433732313a20617070726f766520746f2063616c6c6572000000000000006000830152602082019050919050565b6000613a6a602c8361458c565b91507f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860008301527f697374656e7420746f6b656e00000000000000000000000000000000000000006020830152604082019050919050565b6000613ad060148361458c565b91507f45786365656473204d41585f5155414452554d530000000000000000000000006000830152602082019050919050565b6000613b1060388361458c565b91507f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760008301527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006020830152604082019050919050565b6000613b76602a8361458c565b91507f4552433732313a2062616c616e636520717565727920666f7220746865207a6560008301527f726f2061646472657373000000000000000000000000000000000000000000006020830152604082019050919050565b6000613bdc60238361458c565b91507f45746865722076616c75652073656e742069732062656c6f772074686520707260008301527f69636500000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613c4260228361458c565b91507f456e756d657261626c654d61703a20696e646578206f7574206f6620626f756e60008301527f64730000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613ca860208361458c565b91507f4552433732313a206d696e7420746f20746865207a65726f20616464726573736000830152602082019050919050565b6000613ce860238361458c565b91507f596f752063616e20636c61696d206d696e696d756d20312c206d6178696d756d60008301527f20313000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613d4e602c8361458c565b91507f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860008301527f697374656e7420746f6b656e00000000000000000000000000000000000000006020830152604082019050919050565b6000613db460208361458c565b91507f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726000830152602082019050919050565b6000613df460298361458c565b91507f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960008301527f73206e6f74206f776e00000000000000000000000000000000000000000000006020830152604082019050919050565b6000613e5a602f8361458c565b91507f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008301527f6e6578697374656e7420746f6b656e00000000000000000000000000000000006020830152604082019050919050565b6000613ec060218361458c565b91507f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008301527f72000000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613f2660168361458c565b91507f53616c652068617320616c726561647920656e646564000000000000000000006000830152602082019050919050565b6000613f6660318361458c565b91507f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60008301527f776e6572206e6f7220617070726f7665640000000000000000000000000000006020830152604082019050919050565b6000613fcc600e8361458c565b91507f444f4553204e4f542045584953540000000000000000000000000000000000006000830152602082019050919050565b61400881614731565b82525050565b61401781614731565b82525050565b61402e61402982614731565b61481c565b82525050565b60006140408287613690565b601482019150614050828661401d565b6020820191506140608285613690565b601482019150614070828461401d565b60208201915081905095945050505050565b600061408e8285613795565b915061409a8284613795565b91508190509392505050565b60006140b282856137c6565b91506140be8284613795565b91508190509392505050565b60006020820190506140df6000830184613681565b92915050565b60006080820190506140fa6000830187613681565b6141076020830186613681565b614114604083018561400e565b81810360608301526141268184613723565b905095945050505050565b6000602082019050818103600083015261414b81846136a7565b905092915050565b60006020820190506141686000830184613705565b92915050565b60006020820190506141836000830184613714565b92915050565b600060208201905081810360008301526141a3818461375c565b905092915050565b600060208201905081810360008301526141c481613845565b9050919050565b600060208201905081810360008301526141e4816138ab565b9050919050565b6000602082019050818103600083015261420481613911565b9050919050565b6000602082019050818103600083015261422481613977565b9050919050565b60006020820190508181036000830152614244816139b7565b9050919050565b6000602082019050818103600083015261426481613a1d565b9050919050565b6000602082019050818103600083015261428481613a5d565b9050919050565b600060208201905081810360008301526142a481613ac3565b9050919050565b600060208201905081810360008301526142c481613b03565b9050919050565b600060208201905081810360008301526142e481613b69565b9050919050565b6000602082019050818103600083015261430481613bcf565b9050919050565b6000602082019050818103600083015261432481613c35565b9050919050565b6000602082019050818103600083015261434481613c9b565b9050919050565b6000602082019050818103600083015261436481613cdb565b9050919050565b6000602082019050818103600083015261438481613d41565b9050919050565b600060208201905081810360008301526143a481613da7565b9050919050565b600060208201905081810360008301526143c481613de7565b9050919050565b600060208201905081810360008301526143e481613e4d565b9050919050565b6000602082019050818103600083015261440481613eb3565b9050919050565b6000602082019050818103600083015261442481613f19565b9050919050565b6000602082019050818103600083015261444481613f59565b9050919050565b6000602082019050818103600083015261446481613fbf565b9050919050565b6000602082019050614480600083018461400e565b92915050565b6000604051905081810181811067ffffffffffffffff821117156144ad576144ac6148e4565b5b8060405250919050565b600067ffffffffffffffff8211156144d2576144d16148e4565b5b601f19601f8301169050602081019050919050565b600067ffffffffffffffff821115614502576145016148e4565b5b601f19601f8301169050602081019050919050565b6000819050602082019050919050565b60008190508160005260206000209050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b60006145b382614731565b91506145be83614731565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156145f3576145f2614857565b5b828201905092915050565b600061460982614731565b915061461483614731565b92508261462457614623614886565b5b828204905092915050565b600061463a82614731565b915061464583614731565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561467e5761467d614857565b5b828202905092915050565b600061469482614731565b915061469f83614731565b9250828210156146b2576146b1614857565b5b828203905092915050565b60006146c882614711565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b8381101561476857808201518184015260208101905061474d565b83811115614777576000848401525b50505050565b6000600282049050600182168061479557607f821691505b602082108114156147a9576147a86148b5565b5b50919050565b60006147ba82614731565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156147ed576147ec614857565b5b600182019050919050565b60006148038261480a565b9050919050565b600061481582614924565b9050919050565b6000819050919050565b600061483182614731565b915061483c83614731565b92508261484c5761484b614886565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b60008160601b9050919050565b61493a816146bd565b811461494557600080fd5b50565b614951816146cf565b811461495c57600080fd5b50565b614968816146e5565b811461497357600080fd5b50565b61497f81614731565b811461498a57600080fd5b5056fe4552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656ea2646970667358221220df8b747d5d39fdfb8b3be88e8e83552fbcc20f13244707ebcf0afa9d2922b6bf64736f6c6343000800003368747470733a2f2f7175616472756d732e6172742f6170692f67656e657261746f722f

Deployed Bytecode

0x60806040526004361061023b5760003560e01c8063753853c11161012e578063a3864397116100ab578063d348b4091161006f578063d348b4091461088f578063de69fe88146108ba578063e985e9c5146108e5578063f0c9dc6014610922578063f2fde38b1461094d5761023b565b8063a386439714610772578063b88d4fde146107af578063c87b56dd146107d8578063c8a0122614610815578063cd53d08e146108525761023b565b80638da5cb5b116100f25780638da5cb5b1461069a57806395d89b41146106c55780639758e904146106f0578063a0712d681461072d578063a22cb465146107495761023b565b8063753853c1146105d45780638285d4a3146105ff5780638462151c1461062a578063853828b614610667578063891cc177146106715761023b565b80632f745c59116101bc5780636352211e116101805780636352211e146104db57806363d96941146105185780636c0360eb1461055557806370a0823114610580578063715018a6146105bd5761023b565b80632f745c59146103f857806334d84c7b1461043557806342842e0e1461044c5780634f6ccce71461047557806355f804b3146104b25761023b565b806318160ddd1161020357806318160ddd146103375780631c8b232d1461036257806323b872dd1461038d5780632808c92c146103b65780632ee2ac36146103cd5761023b565b806301ffc9a71461024057806306fdde031461027d578063081812fc146102a8578063095ea7b3146102e5578063109695231461030e575b600080fd5b34801561024c57600080fd5b50610267600480360381019061026291906135ad565b610976565b6040516102749190614153565b60405180910390f35b34801561028957600080fd5b506102926109dd565b60405161029f9190614189565b60405180910390f35b3480156102b457600080fd5b506102cf60048036038101906102ca9190613640565b610a6f565b6040516102dc91906140ca565b60405180910390f35b3480156102f157600080fd5b5061030c60048036038101906103079190613571565b610af4565b005b34801561031a57600080fd5b50610335600480360381019061033091906135ff565b610c0c565b005b34801561034357600080fd5b5061034c610ca2565b604051610359919061446b565b60405180910390f35b34801561036e57600080fd5b50610377610cb3565b6040516103849190614153565b60405180910390f35b34801561039957600080fd5b506103b460048036038101906103af919061346b565b610cc6565b005b3480156103c257600080fd5b506103cb610d26565b005b3480156103d957600080fd5b506103e2610dbf565b6040516103ef9190614189565b60405180910390f35b34801561040457600080fd5b5061041f600480360381019061041a9190613571565b610e4d565b60405161042c919061446b565b60405180910390f35b34801561044157600080fd5b5061044a610ea8565b005b34801561045857600080fd5b50610473600480360381019061046e919061346b565b610f41565b005b34801561048157600080fd5b5061049c60048036038101906104979190613640565b610f61565b6040516104a9919061446b565b60405180910390f35b3480156104be57600080fd5b506104d960048036038101906104d491906135ff565b610f84565b005b3480156104e757600080fd5b5061050260048036038101906104fd9190613640565b61100c565b60405161050f91906140ca565b60405180910390f35b34801561052457600080fd5b5061053f600480360381019061053a9190613640565b611043565b60405161054c9190614189565b60405180910390f35b34801561056157600080fd5b5061056a6110bf565b6040516105779190614189565b60405180910390f35b34801561058c57600080fd5b506105a760048036038101906105a29190613406565b611151565b6040516105b4919061446b565b60405180910390f35b3480156105c957600080fd5b506105d2611210565b005b3480156105e057600080fd5b506105e961134d565b6040516105f69190614189565b60405180910390f35b34801561060b57600080fd5b506106146113db565b604051610621919061446b565b60405180910390f35b34801561063657600080fd5b50610651600480360381019061064c9190613406565b6113e1565b60405161065e9190614131565b60405180910390f35b61066f61155d565b005b34801561067d57600080fd5b50610698600480360381019061069391906135ff565b611619565b005b3480156106a657600080fd5b506106af6116af565b6040516106bc91906140ca565b60405180910390f35b3480156106d157600080fd5b506106da6116d9565b6040516106e79190614189565b60405180910390f35b3480156106fc57600080fd5b5061071760048036038101906107129190613640565b61176b565b6040516107249190614189565b60405180910390f35b61074760048036038101906107429190613640565b6117e7565b005b34801561075557600080fd5b50610770600480360381019061076b9190613535565b6119eb565b005b34801561077e57600080fd5b5061079960048036038101906107949190613640565b611b6c565b6040516107a6919061416e565b60405180910390f35b3480156107bb57600080fd5b506107d660048036038101906107d191906134ba565b611c30565b005b3480156107e457600080fd5b506107ff60048036038101906107fa9190613640565b611c92565b60405161080c9190614189565b60405180910390f35b34801561082157600080fd5b5061083c60048036038101906108379190613640565b611e05565b604051610849919061446b565b60405180910390f35b34801561085e57600080fd5b5061087960048036038101906108749190613640565b611e1d565b60405161088691906140ca565b60405180910390f35b34801561089b57600080fd5b506108a4611e50565b6040516108b1919061446b565b60405180910390f35b3480156108c657600080fd5b506108cf611e5f565b6040516108dc9190614189565b60405180910390f35b3480156108f157600080fd5b5061090c6004803603810190610907919061342f565b611eed565b6040516109199190614153565b60405180910390f35b34801561092e57600080fd5b50610937611f81565b6040516109449190614189565b60405180910390f35b34801561095957600080fd5b50610974600480360381019061096f9190613406565b61200f565b005b6000806000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060009054906101000a900460ff169050919050565b6060600680546109ec9061477d565b80601f0160208091040260200160405190810160405280929190818152602001828054610a189061477d565b8015610a655780601f10610a3a57610100808354040283529160200191610a65565b820191906000526020600020905b815481529060010190602001808311610a4857829003601f168201915b5050505050905090565b6000610a7a82612237565b610ab9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ab09061436b565b60405180910390fd5b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610aff8261100c565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610b70576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b67906143eb565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610b8f612254565b73ffffffffffffffffffffffffffffffffffffffff161480610bbe5750610bbd81610bb8612254565b611eed565b5b610bfd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bf4906142ab565b60405180910390fd5b610c07838361225c565b505050565b610c14612254565b73ffffffffffffffffffffffffffffffffffffffff16610c326116af565b73ffffffffffffffffffffffffffffffffffffffff1614610c88576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c7f9061438b565b60405180910390fd5b80600d9080519060200190610c9e92919061322a565b5050565b6000610cae6002612315565b905090565b600a60149054906101000a900460ff1681565b610cd7610cd1612254565b8261232a565b610d16576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d0d9061442b565b60405180910390fd5b610d21838383612408565b505050565b610d2e612254565b73ffffffffffffffffffffffffffffffffffffffff16610d4c6116af565b73ffffffffffffffffffffffffffffffffffffffff1614610da2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d999061438b565b60405180910390fd5b6000600a60146101000a81548160ff021916908315150217905550565b600e8054610dcc9061477d565b80601f0160208091040260200160405190810160405280929190818152602001828054610df89061477d565b8015610e455780601f10610e1a57610100808354040283529160200191610e45565b820191906000526020600020905b815481529060010190602001808311610e2857829003601f168201915b505050505081565b6000610ea082600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061261f90919063ffffffff16565b905092915050565b610eb0612254565b73ffffffffffffffffffffffffffffffffffffffff16610ece6116af565b73ffffffffffffffffffffffffffffffffffffffff1614610f24576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f1b9061438b565b60405180910390fd5b6001600a60146101000a81548160ff021916908315150217905550565b610f5c83838360405180602001604052806000815250611c30565b505050565b600080610f7883600261263990919063ffffffff16565b50905080915050919050565b610f8c612254565b73ffffffffffffffffffffffffffffffffffffffff16610faa6116af565b73ffffffffffffffffffffffffffffffffffffffff1614611000576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ff79061438b565b60405180910390fd5b61100981612665565b50565b600061103c8260405180606001604052806029815260200161498e60299139600261267f9092919063ffffffff16565b9050919050565b606061104e82612237565b61108d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110849061444b565b60405180910390fd5b600e6110988361269e565b6040516020016110a99291906140a6565b6040516020818303038152906040529050919050565b6060600980546110ce9061477d565b80601f01602080910402602001604051908101604052809291908181526020018280546110fa9061477d565b80156111475780601f1061111c57610100808354040283529160200191611147565b820191906000526020600020905b81548152906001019060200180831161112a57829003601f168201915b5050505050905090565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156111c2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111b9906142cb565b60405180910390fd5b611209600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061284b565b9050919050565b611218612254565b73ffffffffffffffffffffffffffffffffffffffff166112366116af565b73ffffffffffffffffffffffffffffffffffffffff161461128c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112839061438b565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a36000600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b600f805461135a9061477d565b80601f01602080910402602001604051908101604052809291908181526020018280546113869061477d565b80156113d35780601f106113a8576101008083540402835291602001916113d3565b820191906000526020600020905b8154815290600101906020018083116113b657829003601f168201915b505050505081565b61040081565b606060006113ee83611151565b9050600081141561147157600067ffffffffffffffff81111561143a577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280602002602001820160405280156114685781602001602082028036833780820191505090505b50915050611558565b60008167ffffffffffffffff8111156114b3577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280602002602001820160405280156114e15781602001602082028036833780820191505090505b50905060005b82811015611551576114f98582610e4d565b828281518110611532577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020026020010181815250508080611549906147af565b9150506114e7565b8193505050505b919050565b611565612254565b73ffffffffffffffffffffffffffffffffffffffff166115836116af565b73ffffffffffffffffffffffffffffffffffffffff16146115d9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115d09061438b565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f1935050505061161757600080fd5b565b611621612254565b73ffffffffffffffffffffffffffffffffffffffff1661163f6116af565b73ffffffffffffffffffffffffffffffffffffffff1614611695576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161168c9061438b565b60405180910390fd5b80600f90805190602001906116ab92919061322a565b5050565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6060600780546116e89061477d565b80601f01602080910402602001604051908101604052809291908181526020018280546117149061477d565b80156117615780601f1061173657610100808354040283529160200191611761565b820191906000526020600020905b81548152906001019060200180831161174457829003601f168201915b5050505050905090565b606061177682612237565b6117b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117ac9061444b565b60405180910390fd5b600f6117c08361269e565b6040516020016117d19291906140a6565b6040516020818303038152906040529050919050565b6104006117f2610ca2565b10611832576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118299061440b565b60405180910390fd5b6000811180156118435750600a8111155b611882576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118799061434b565b60405180910390fd5b61040061189f82611891610ca2565b61286090919063ffffffff16565b11156118e0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118d79061428b565b60405180910390fd5b6118fa816118ec611e50565b61287690919063ffffffff16565b34101561193c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611933906142eb565b60405180910390fd5b60005b818110156119e7576000611951610ca2565b90506119693360018361196491906145a8565b61288c565b43600b60008381526020019081526020016000208190555033600c600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505080806119df906147af565b91505061193f565b5050565b6119f3612254565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611a61576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a589061424b565b60405180910390fd5b8060056000611a6e612254565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16611b1b612254565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051611b609190614153565b60405180910390a35050565b6000611b7782612237565b611bb6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bad9061444b565b60405180910390fd5b30600b600084815260200190815260200160002054600c600085815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1684604051602001611c139493929190614034565b604051602081830303815290604052805190602001209050919050565b611c41611c3b612254565b8361232a565b611c80576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c779061442b565b60405180910390fd5b611c8c848484846128aa565b50505050565b6060611c9d82612237565b611cdc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cd3906143cb565b60405180910390fd5b6000600860008481526020019081526020016000208054611cfc9061477d565b80601f0160208091040260200160405190810160405280929190818152602001828054611d289061477d565b8015611d755780601f10611d4a57610100808354040283529160200191611d75565b820191906000526020600020905b815481529060010190602001808311611d5857829003601f168201915b505050505090506000611d866110bf565b9050600081511415611d9c578192505050611e00565b600082511115611dd1578082604051602001611db9929190614082565b60405160208183030381529060405292505050611e00565b80611ddb8561269e565b604051602001611dec929190614082565b604051602081830303815290604052925050505b919050565b600b6020528060005260406000206000915090505481565b600c6020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000668e1bc9bf040000905090565b60108054611e6c9061477d565b80601f0160208091040260200160405190810160405280929190818152602001828054611e989061477d565b8015611ee55780601f10611eba57610100808354040283529160200191611ee5565b820191906000526020600020905b815481529060010190602001808311611ec857829003601f168201915b505050505081565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b600d8054611f8e9061477d565b80601f0160208091040260200160405190810160405280929190818152602001828054611fba9061477d565b80156120075780601f10611fdc57610100808354040283529160200191612007565b820191906000526020600020905b815481529060010190602001808311611fea57829003601f168201915b505050505081565b612017612254565b73ffffffffffffffffffffffffffffffffffffffff166120356116af565b73ffffffffffffffffffffffffffffffffffffffff161461208b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120829061438b565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156120fb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120f2906141eb565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60006121cd836000018360001b612906565b905092915050565b6000612201846000018460001b8473ffffffffffffffffffffffffffffffffffffffff1660001b612976565b90509392505050565b600080823b905060008111915050919050565b600061222f836000018360001b612a88565b905092915050565b600061224d82600261221d90919063ffffffff16565b9050919050565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff166122cf8361100c565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600061232382600001612aab565b9050919050565b600061233582612237565b612374576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161236b9061426b565b60405180910390fd5b600061237f8361100c565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614806123ee57508373ffffffffffffffffffffffffffffffffffffffff166123d684610a6f565b73ffffffffffffffffffffffffffffffffffffffff16145b806123ff57506123fe8185611eed565b5b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff166124288261100c565b73ffffffffffffffffffffffffffffffffffffffff161461247e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612475906143ab565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156124ee576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124e59061422b565b60405180910390fd5b6124f9838383612abc565b61250460008261225c565b61255581600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020612ac190919063ffffffff16565b506125a781600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206121bb90919063ffffffff16565b506125be818360026121d59092919063ffffffff16565b50808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b600061262e8360000183612adb565b60001c905092915050565b60008060008061264c8660000186612b75565b915091508160001c8160001c9350935050509250929050565b806009908051906020019061267b92919061322a565b5050565b6000612692846000018460001b84612c25565b60001c90509392505050565b606060008214156126e6576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050612846565b600082905060005b60008214612718578080612701906147af565b915050600a8261271191906145fe565b91506126ee565b60008167ffffffffffffffff81111561275a577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280601f01601f19166020018201604052801561278c5781602001600182028036833780820191505090505b5090505b6000851461283f576001826127a59190614689565b9150600a856127b49190614826565b60306127c091906145a8565b60f81b8183815181106127fc577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a8561283891906145fe565b9450612790565b8093505050505b919050565b600061285982600001612cec565b9050919050565b6000818361286e91906145a8565b905092915050565b60008183612884919061462f565b905092915050565b6128a6828260405180602001604052806000815250612cfd565b5050565b6128b5848484612408565b6128c184848484612d58565b612900576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128f7906141cb565b60405180910390fd5b50505050565b60006129128383612eef565b61296b578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050612970565b600090505b92915050565b6000808460010160008581526020019081526020016000205490506000811415612a1d57846000016040518060400160405280868152602001858152509080600181540180825580915050600190039060005260206000209060020201600090919091909150600082015181600001556020820151816001015550508460000180549050856001016000868152602001908152602001600020819055506001915050612a81565b8285600001600183612a2f9190614689565b81548110612a66577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002090600202016001018190555060009150505b9392505050565b600080836001016000848152602001908152602001600020541415905092915050565b600081600001805490509050919050565b505050565b6000612ad3836000018360001b612f12565b905092915050565b600081836000018054905011612b26576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b1d906141ab565b60405180910390fd5b826000018281548110612b62577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154905092915050565b60008082846000018054905011612bc1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612bb89061430b565b60405180910390fd5b6000846000018481548110612bff577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b906000526020600020906002020190508060000154816001015492509250509250929050565b60008084600101600085815260200190815260200160002054905060008114158390612c87576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c7e9190614189565b60405180910390fd5b5084600001600182612c999190614689565b81548110612cd0577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000209060020201600101549150509392505050565b600081600001805490509050919050565b612d07838361309c565b612d146000848484612d58565b612d53576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d4a906141cb565b60405180910390fd5b505050565b6000612d798473ffffffffffffffffffffffffffffffffffffffff1661220a565b15612ee2578373ffffffffffffffffffffffffffffffffffffffff1663150b7a02612da2612254565b8786866040518563ffffffff1660e01b8152600401612dc494939291906140e5565b602060405180830381600087803b158015612dde57600080fd5b505af1925050508015612e0f57506040513d601f19601f82011682018060405250810190612e0c91906135d6565b60015b612e92573d8060008114612e3f576040519150601f19603f3d011682016040523d82523d6000602084013e612e44565b606091505b50600081511415612e8a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e81906141cb565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050612ee7565b600190505b949350505050565b600080836001016000848152602001908152602001600020541415905092915050565b60008083600101600084815260200190815260200160002054905060008114613090576000600182612f449190614689565b9050600060018660000180549050612f5c9190614689565b90506000866000018281548110612f9c577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154905080876000018481548110612fe6577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b906000526020600020018190555060018361300191906145a8565b8760010160008381526020019081526020016000208190555086600001805480613054577f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050613096565b60009150505b92915050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561310c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016131039061432b565b60405180910390fd5b61311581612237565b15613155576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161314c9061420b565b60405180910390fd5b61316160008383612abc565b6131b281600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206121bb90919063ffffffff16565b506131c9818360026121d59092919063ffffffff16565b50808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050565b8280546132369061477d565b90600052602060002090601f016020900481019282613258576000855561329f565b82601f1061327157805160ff191683800117855561329f565b8280016001018555821561329f579182015b8281111561329e578251825591602001919060010190613283565b5b5090506132ac91906132b0565b5090565b5b808211156132c95760008160009055506001016132b1565b5090565b60006132e06132db846144b7565b614486565b9050828152602081018484840111156132f857600080fd5b61330384828561473b565b509392505050565b600061331e613319846144e7565b614486565b90508281526020810184848401111561333657600080fd5b61334184828561473b565b509392505050565b60008135905061335881614931565b92915050565b60008135905061336d81614948565b92915050565b6000813590506133828161495f565b92915050565b6000815190506133978161495f565b92915050565b600082601f8301126133ae57600080fd5b81356133be8482602086016132cd565b91505092915050565b600082601f8301126133d857600080fd5b81356133e884826020860161330b565b91505092915050565b60008135905061340081614976565b92915050565b60006020828403121561341857600080fd5b600061342684828501613349565b91505092915050565b6000806040838503121561344257600080fd5b600061345085828601613349565b925050602061346185828601613349565b9150509250929050565b60008060006060848603121561348057600080fd5b600061348e86828701613349565b935050602061349f86828701613349565b92505060406134b0868287016133f1565b9150509250925092565b600080600080608085870312156134d057600080fd5b60006134de87828801613349565b94505060206134ef87828801613349565b9350506040613500878288016133f1565b925050606085013567ffffffffffffffff81111561351d57600080fd5b6135298782880161339d565b91505092959194509250565b6000806040838503121561354857600080fd5b600061355685828601613349565b92505060206135678582860161335e565b9150509250929050565b6000806040838503121561358457600080fd5b600061359285828601613349565b92505060206135a3858286016133f1565b9150509250929050565b6000602082840312156135bf57600080fd5b60006135cd84828501613373565b91505092915050565b6000602082840312156135e857600080fd5b60006135f684828501613388565b91505092915050565b60006020828403121561361157600080fd5b600082013567ffffffffffffffff81111561362b57600080fd5b613637848285016133c7565b91505092915050565b60006020828403121561365257600080fd5b6000613660848285016133f1565b91505092915050565b60006136758383613fff565b60208301905092915050565b61368a816146bd565b82525050565b6136a161369c826146bd565b6147f8565b82525050565b60006136b28261453c565b6136bc818561456a565b93506136c783614517565b8060005b838110156136f85781516136df8882613669565b97506136ea8361455d565b9250506001810190506136cb565b5085935050505092915050565b61370e816146cf565b82525050565b61371d816146db565b82525050565b600061372e82614547565b613738818561457b565b935061374881856020860161474a565b61375181614913565b840191505092915050565b600061376782614552565b613771818561458c565b935061378181856020860161474a565b61378a81614913565b840191505092915050565b60006137a082614552565b6137aa818561459d565b93506137ba81856020860161474a565b80840191505092915050565b600081546137d38161477d565b6137dd818661459d565b945060018216600081146137f857600181146138095761383c565b60ff1983168652818601935061383c565b61381285614527565b60005b8381101561383457815481890152600182019150602081019050613815565b838801955050505b50505092915050565b600061385260228361458c565b91507f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e60008301527f64730000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006138b860328361458c565b91507f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008301527f63656976657220696d706c656d656e74657200000000000000000000000000006020830152604082019050919050565b600061391e60268361458c565b91507f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008301527f64647265737300000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613984601c8361458c565b91507f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006000830152602082019050919050565b60006139c460248361458c565b91507f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008301527f72657373000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613a2a60198361458c565b91507f4552433732313a20617070726f766520746f2063616c6c6572000000000000006000830152602082019050919050565b6000613a6a602c8361458c565b91507f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860008301527f697374656e7420746f6b656e00000000000000000000000000000000000000006020830152604082019050919050565b6000613ad060148361458c565b91507f45786365656473204d41585f5155414452554d530000000000000000000000006000830152602082019050919050565b6000613b1060388361458c565b91507f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760008301527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006020830152604082019050919050565b6000613b76602a8361458c565b91507f4552433732313a2062616c616e636520717565727920666f7220746865207a6560008301527f726f2061646472657373000000000000000000000000000000000000000000006020830152604082019050919050565b6000613bdc60238361458c565b91507f45746865722076616c75652073656e742069732062656c6f772074686520707260008301527f69636500000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613c4260228361458c565b91507f456e756d657261626c654d61703a20696e646578206f7574206f6620626f756e60008301527f64730000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613ca860208361458c565b91507f4552433732313a206d696e7420746f20746865207a65726f20616464726573736000830152602082019050919050565b6000613ce860238361458c565b91507f596f752063616e20636c61696d206d696e696d756d20312c206d6178696d756d60008301527f20313000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613d4e602c8361458c565b91507f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860008301527f697374656e7420746f6b656e00000000000000000000000000000000000000006020830152604082019050919050565b6000613db460208361458c565b91507f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726000830152602082019050919050565b6000613df460298361458c565b91507f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960008301527f73206e6f74206f776e00000000000000000000000000000000000000000000006020830152604082019050919050565b6000613e5a602f8361458c565b91507f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008301527f6e6578697374656e7420746f6b656e00000000000000000000000000000000006020830152604082019050919050565b6000613ec060218361458c565b91507f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008301527f72000000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613f2660168361458c565b91507f53616c652068617320616c726561647920656e646564000000000000000000006000830152602082019050919050565b6000613f6660318361458c565b91507f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60008301527f776e6572206e6f7220617070726f7665640000000000000000000000000000006020830152604082019050919050565b6000613fcc600e8361458c565b91507f444f4553204e4f542045584953540000000000000000000000000000000000006000830152602082019050919050565b61400881614731565b82525050565b61401781614731565b82525050565b61402e61402982614731565b61481c565b82525050565b60006140408287613690565b601482019150614050828661401d565b6020820191506140608285613690565b601482019150614070828461401d565b60208201915081905095945050505050565b600061408e8285613795565b915061409a8284613795565b91508190509392505050565b60006140b282856137c6565b91506140be8284613795565b91508190509392505050565b60006020820190506140df6000830184613681565b92915050565b60006080820190506140fa6000830187613681565b6141076020830186613681565b614114604083018561400e565b81810360608301526141268184613723565b905095945050505050565b6000602082019050818103600083015261414b81846136a7565b905092915050565b60006020820190506141686000830184613705565b92915050565b60006020820190506141836000830184613714565b92915050565b600060208201905081810360008301526141a3818461375c565b905092915050565b600060208201905081810360008301526141c481613845565b9050919050565b600060208201905081810360008301526141e4816138ab565b9050919050565b6000602082019050818103600083015261420481613911565b9050919050565b6000602082019050818103600083015261422481613977565b9050919050565b60006020820190508181036000830152614244816139b7565b9050919050565b6000602082019050818103600083015261426481613a1d565b9050919050565b6000602082019050818103600083015261428481613a5d565b9050919050565b600060208201905081810360008301526142a481613ac3565b9050919050565b600060208201905081810360008301526142c481613b03565b9050919050565b600060208201905081810360008301526142e481613b69565b9050919050565b6000602082019050818103600083015261430481613bcf565b9050919050565b6000602082019050818103600083015261432481613c35565b9050919050565b6000602082019050818103600083015261434481613c9b565b9050919050565b6000602082019050818103600083015261436481613cdb565b9050919050565b6000602082019050818103600083015261438481613d41565b9050919050565b600060208201905081810360008301526143a481613da7565b9050919050565b600060208201905081810360008301526143c481613de7565b9050919050565b600060208201905081810360008301526143e481613e4d565b9050919050565b6000602082019050818103600083015261440481613eb3565b9050919050565b6000602082019050818103600083015261442481613f19565b9050919050565b6000602082019050818103600083015261444481613f59565b9050919050565b6000602082019050818103600083015261446481613fbf565b9050919050565b6000602082019050614480600083018461400e565b92915050565b6000604051905081810181811067ffffffffffffffff821117156144ad576144ac6148e4565b5b8060405250919050565b600067ffffffffffffffff8211156144d2576144d16148e4565b5b601f19601f8301169050602081019050919050565b600067ffffffffffffffff821115614502576145016148e4565b5b601f19601f8301169050602081019050919050565b6000819050602082019050919050565b60008190508160005260206000209050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b60006145b382614731565b91506145be83614731565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156145f3576145f2614857565b5b828201905092915050565b600061460982614731565b915061461483614731565b92508261462457614623614886565b5b828204905092915050565b600061463a82614731565b915061464583614731565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561467e5761467d614857565b5b828202905092915050565b600061469482614731565b915061469f83614731565b9250828210156146b2576146b1614857565b5b828203905092915050565b60006146c882614711565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b8381101561476857808201518184015260208101905061474d565b83811115614777576000848401525b50505050565b6000600282049050600182168061479557607f821691505b602082108114156147a9576147a86148b5565b5b50919050565b60006147ba82614731565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156147ed576147ec614857565b5b600182019050919050565b60006148038261480a565b9050919050565b600061481582614924565b9050919050565b6000819050919050565b600061483182614731565b915061483c83614731565b92508261484c5761484b614886565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b60008160601b9050919050565b61493a816146bd565b811461494557600080fd5b50565b614951816146cf565b811461495c57600080fd5b50565b614968816146e5565b811461497357600080fd5b50565b61497f81614731565b811461498a57600080fd5b5056fe4552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656ea2646970667358221220df8b747d5d39fdfb8b3be88e8e83552fbcc20f13244707ebcf0afa9d2922b6bf64736f6c63430008000033

Deployed Bytecode Sourcemap

69790:4081:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;33482:200;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;45676:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;48684:308;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;48183:435;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;72173:116;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;47611:211;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;69949:34;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;49743:376;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;72615:79;;;;;;;;;;;;;:::i;:::-;;70183:80;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;47323:212;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;72529:78;;;;;;;;;;;;;:::i;:::-;;50190:185;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;47899:222;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;72422:99;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;45320:289;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;73298:254;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;47142:97;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;44950:308;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;61751:148;;;;;;;;;;;;;:::i;:::-;;70270:41;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;69899:43;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;70649:572;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;72702:123;;;:::i;:::-;;72297:117;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;61100:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;45845:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;73560:308;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;71336:799;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;49064:327;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;72833:457;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;50446:365;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;46020:879;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;69990:48;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;70045:43;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;71229:99;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;70318:25;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;49462:214;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;70133:43;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;62054:281;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;33482:200;33612:4;33641:20;:33;33662:11;33641:33;;;;;;;;;;;;;;;;;;;;;;;;;;;33634:40;;33482:200;;;:::o;45676:100::-;45730:13;45763:5;45756:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45676:100;:::o;48684:308::-;48805:7;48852:16;48860:7;48852;:16::i;:::-;48830:110;;;;;;;;;;;;:::i;:::-;;;;;;;;;48960:15;:24;48976:7;48960:24;;;;;;;;;;;;;;;;;;;;;48953:31;;48684:308;;;:::o;48183:435::-;48264:13;48280:23;48295:7;48280:14;:23::i;:::-;48264:39;;48328:5;48322:11;;:2;:11;;;;48314:57;;;;;;;;;;;;:::i;:::-;;;;;;;;;48422:5;48406:21;;:12;:10;:12::i;:::-;:21;;;:86;;;;48448:44;48472:5;48479:12;:10;:12::i;:::-;48448:23;:44::i;:::-;48406:86;48384:192;;;;;;;;;;;;:::i;:::-;;;;;;;;;48589:21;48598:2;48602:7;48589:8;:21::i;:::-;48183:435;;;:::o;72173:116::-;61331:12;:10;:12::i;:::-;61320:23;;:7;:5;:7::i;:::-;:23;;;61312:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;72276:5:::1;72249:24;:32;;;;;;;;;;;;:::i;:::-;;72173:116:::0;:::o;47611:211::-;47672:7;47793:21;:12;:19;:21::i;:::-;47786:28;;47611:211;:::o;69949:34::-;;;;;;;;;;;;;:::o;49743:376::-;49952:41;49971:12;:10;:12::i;:::-;49985:7;49952:18;:41::i;:::-;49930:140;;;;;;;;;;;;:::i;:::-;;;;;;;;;50083:28;50093:4;50099:2;50103:7;50083:9;:28::i;:::-;49743:376;;;:::o;72615:79::-;61331:12;:10;:12::i;:::-;61320:23;;:7;:5;:7::i;:::-;:23;;;61312:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;72681:5:::1;72664:14;;:22;;;;;;;;;;;;;;;;;;72615:79::o:0;70183:80::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;47323:212::-;47465:7;47497:30;47521:5;47497:13;:20;47511:5;47497:20;;;;;;;;;;;;;;;:23;;:30;;;;:::i;:::-;47490:37;;47323:212;;;;:::o;72529:78::-;61331:12;:10;:12::i;:::-;61320:23;;:7;:5;:7::i;:::-;:23;;;61312:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;72595:4:::1;72578:14;;:21;;;;;;;;;;;;;;;;;;72529:78::o:0;50190:185::-;50328:39;50345:4;50351:2;50355:7;50328:39;;;;;;;;;;;;:16;:39::i;:::-;50190:185;;;:::o;47899:222::-;48019:7;48045:15;48066:22;48082:5;48066:12;:15;;:22;;;;:::i;:::-;48044:44;;;48106:7;48099:14;;;47899:222;;;:::o;72422:99::-;61331:12;:10;:12::i;:::-;61320:23;;:7;:5;:7::i;:::-;:23;;;61312:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;72493:20:::1;72505:7;72493:11;:20::i;:::-;72422:99:::0;:::o;45320:289::-;45437:7;45482:119;45517:7;45482:119;;;;;;;;;;;;;;;;;:12;:16;;:119;;;;;:::i;:::-;45462:139;;45320:289;;;:::o;73298:254::-;73389:13;73428:16;73436:7;73428;:16::i;:::-;73420:43;;;;;;;;;;;;:::i;:::-;;;;;;;;;73505:17;73524:18;:7;:16;:18::i;:::-;73488:55;;;;;;;;;:::i;:::-;;;;;;;;;;;;;73474:70;;73298:254;;;:::o;47142:97::-;47190:13;47223:8;47216:15;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47142:97;:::o;44950:308::-;45067:7;45131:1;45114:19;;:5;:19;;;;45092:111;;;;;;;;;;;;:::i;:::-;;;;;;;;;45221:29;:13;:20;45235:5;45221:20;;;;;;;;;;;;;;;:27;:29::i;:::-;45214:36;;44950:308;;;:::o;61751:148::-;61331:12;:10;:12::i;:::-;61320:23;;:7;:5;:7::i;:::-;:23;;;61312:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;61858:1:::1;61821:40;;61842:6;;;;;;;;;;;61821:40;;;;;;;;;;;;61889:1;61872:6;;:19;;;;;;;;;;;;;;;;;;61751:148::o:0;70270:41::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;69899:43::-;69938:4;69899:43;:::o;70649:572::-;70738:16;70772:18;70793:17;70803:6;70793:9;:17::i;:::-;70772:38;;70839:1;70825:10;:15;70821:393;;;70916:1;70902:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;70895:23;;;;;70821:393;70951:23;70991:10;70977:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;70951:51;;71017:13;71045:130;71069:10;71061:5;:18;71045:130;;;71125:34;71145:6;71153:5;71125:19;:34::i;:::-;71109:6;71116:5;71109:13;;;;;;;;;;;;;;;;;;;;;:50;;;;;71081:7;;;;;:::i;:::-;;;;71045:130;;;71196:6;71189:13;;;;;70649:572;;;;:::o;72702:123::-;61331:12;:10;:12::i;:::-;61320:23;;:7;:5;:7::i;:::-;:23;;;61312:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;72777:10:::1;72769:24;;:47;72794:21;72769:47;;;;;;;;;;;;;;;;;;;;;;;72761:56;;;::::0;::::1;;72702:123::o:0;72297:117::-;61331:12;:10;:12::i;:::-;61320:23;;:7;:5;:7::i;:::-;:23;;;61312:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;72401:5:::1;72376:22;:30;;;;;;;;;;;;:::i;:::-;;72297:117:::0;:::o;61100:87::-;61146:7;61173:6;;;;;;;;;;;61166:13;;61100:87;:::o;45845:104::-;45901:13;45934:7;45927:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45845:104;:::o;73560:308::-;73655:13;73694:16;73702:7;73694;:16::i;:::-;73686:43;;;;;;;;;;;;:::i;:::-;;;;;;;;;73802:22;73826:18;:7;:16;:18::i;:::-;73785:60;;;;;;;;;:::i;:::-;;;;;;;;;;;;;73740:120;;73560:308;;;:::o;71336:799::-;69938:4;71405:13;:11;:13::i;:::-;:28;71397:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;71507:1;71493:11;:15;:36;;;;;71527:2;71512:11;:17;;71493:36;71471:121;;;;;;;;;;;;:::i;:::-;;;;;;;;;69938:4;71625:30;71643:11;71625:13;:11;:13::i;:::-;:17;;:30;;;;:::i;:::-;:46;;71603:116;;;;;;;;;;;;:::i;:::-;;;;;;;;;71765:33;71786:11;71765:16;:14;:16::i;:::-;:20;;:33;;;;:::i;:::-;71752:9;:46;;71730:131;;;;;;;;;;;;:::i;:::-;;;;;;;;;71879:9;71874:254;71898:11;71894:1;:15;71874:254;;;71931:17;71951:13;:11;:13::i;:::-;71931:33;;71979:36;71989:10;72013:1;72001:9;:13;;;;:::i;:::-;71979:9;:36::i;:::-;72057:12;72030:13;:24;72044:9;72030:24;;;;;;;;;;;:39;;;;72106:10;72084:8;:19;72093:9;72084:19;;;;;;;;;;;;:32;;;;;;;;;;;;;;;;;;71874:254;71911:3;;;;;:::i;:::-;;;;71874:254;;;;71336:799;:::o;49064:327::-;49211:12;:10;:12::i;:::-;49199:24;;:8;:24;;;;49191:62;;;;;;;;;;;;:::i;:::-;;;;;;;;;49311:8;49266:18;:32;49285:12;:10;:12::i;:::-;49266:32;;;;;;;;;;;;;;;:42;49299:8;49266:42;;;;;;;;;;;;;;;;:53;;;;;;;;;;;;;;;;;;49364:8;49335:48;;49350:12;:10;:12::i;:::-;49335:48;;;49374:8;49335:48;;;;;;:::i;:::-;;;;;;;;49064:327;;:::o;72833:457::-;72890:7;72918:16;72926:7;72918;:16::i;:::-;72910:43;;;;;;;;;;;;:::i;:::-;;;;;;;;;73093:4;73125:13;:22;73139:7;73125:22;;;;;;;;;;;;73174:8;:17;73183:7;73174:17;;;;;;;;;;;;;;;;;;;;;73218:7;73042:206;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;73010:257;;;;;;72964:318;;72833:457;;;:::o;50446:365::-;50635:41;50654:12;:10;:12::i;:::-;50668:7;50635:18;:41::i;:::-;50613:140;;;;;;;;;;;;:::i;:::-;;;;;;;;;50764:39;50778:4;50784:2;50788:7;50797:5;50764:13;:39::i;:::-;50446:365;;;;:::o;46020:879::-;46138:13;46191:16;46199:7;46191;:16::i;:::-;46169:113;;;;;;;;;;;;:::i;:::-;;;;;;;;;46295:23;46321:10;:19;46332:7;46321:19;;;;;;;;;;;46295:45;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46351:18;46372:9;:7;:9::i;:::-;46351:30;;46479:1;46463:4;46457:18;:23;46453:72;;;46504:9;46497:16;;;;;;46453:72;46655:1;46635:9;46629:23;:27;46625:108;;;46704:4;46710:9;46687:33;;;;;;;;;:::i;:::-;;;;;;;;;;;;;46673:48;;;;;;46625:108;46865:4;46871:18;:7;:16;:18::i;:::-;46848:42;;;;;;;;;:::i;:::-;;;;;;;;;;;;;46834:57;;;;46020:879;;;;:::o;69990:48::-;;;;;;;;;;;;;;;;;:::o;70045:43::-;;;;;;;;;;;;;;;;;;;;;;:::o;71229:99::-;71276:7;71303:17;71296:24;;71229:99;:::o;70318:25::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;49462:214::-;49604:4;49633:18;:25;49652:5;49633:25;;;;;;;;;;;;;;;:35;49659:8;49633:35;;;;;;;;;;;;;;;;;;;;;;;;;49626:42;;49462:214;;;;:::o;70133:43::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;62054:281::-;61331:12;:10;:12::i;:::-;61320:23;;:7;:5;:7::i;:::-;:23;;;61312:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;62177:1:::1;62157:22;;:8;:22;;;;62135:110;;;;;;;;;;;;:::i;:::-;;;;;;;;;62290:8;62261:38;;62282:6;;;;;;;;;;;62261:38;;;;;;;;;;;;62319:8;62310:6;;:17;;;;;;;;;;;;;;;;;;62054:281:::0;:::o;21511:131::-;21578:4;21602:32;21607:3;:10;;21627:5;21619:14;;21602:4;:32::i;:::-;21595:39;;21511:131;;;;:::o;9684:219::-;9807:4;9831:64;9836:3;:10;;9856:3;9848:12;;9886:5;9870:23;;9862:32;;9831:4;:64::i;:::-;9824:71;;9684:219;;;;;:::o;23773:444::-;23833:4;24041:12;24165:7;24153:20;24145:28;;24208:1;24201:4;:8;24194:15;;;23773:444;;;:::o;10318:183::-;10429:4;10458:35;10468:3;:10;;10488:3;10480:12;;10458:9;:35::i;:::-;10451:42;;10318:183;;;;:::o;52358:127::-;52423:4;52447:30;52469:7;52447:12;:21;;:30;;;;:::i;:::-;52440:37;;52358:127;;;:::o;42743:98::-;42796:7;42823:10;42816:17;;42743:98;:::o;59018:183::-;59111:2;59084:15;:24;59100:7;59084:24;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;59167:7;59163:2;59129:46;;59138:23;59153:7;59138:14;:23::i;:::-;59129:46;;;;;;;;;;;;59018:183;;:::o;10589:155::-;10685:7;10717:19;10725:3;:10;;10717:7;:19::i;:::-;10710:26;;10589:155;;;:::o;52652:459::-;52781:4;52825:16;52833:7;52825;:16::i;:::-;52803:110;;;;;;;;;;;;:::i;:::-;;;;;;;;;52924:13;52940:23;52955:7;52940:14;:23::i;:::-;52924:39;;52993:5;52982:16;;:7;:16;;;:64;;;;53039:7;53015:31;;:20;53027:7;53015:11;:20::i;:::-;:31;;;52982:64;:120;;;;53063:39;53087:5;53094:7;53063:23;:39::i;:::-;52982:120;52974:129;;;52652:459;;;;:::o;55963:668::-;56136:4;56109:31;;:23;56124:7;56109:14;:23::i;:::-;:31;;;56087:122;;;;;;;;;;;;:::i;:::-;;;;;;;;;56260:1;56246:16;;:2;:16;;;;56238:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;56316:39;56337:4;56343:2;56347:7;56316:20;:39::i;:::-;56420:29;56437:1;56441:7;56420:8;:29::i;:::-;56462:35;56489:7;56462:13;:19;56476:4;56462:19;;;;;;;;;;;;;;;:26;;:35;;;;:::i;:::-;;56508:30;56530:7;56508:13;:17;56522:2;56508:17;;;;;;;;;;;;;;;:21;;:30;;;;:::i;:::-;;56551:29;56568:7;56577:2;56551:12;:16;;:29;;;;;:::i;:::-;;56615:7;56611:2;56596:27;;56605:4;56596:27;;;;;;;;;;;;55963:668;;;:::o;22796:169::-;22894:7;22934:22;22938:3;:10;;22950:5;22934:3;:22::i;:::-;22926:31;;22919:38;;22796:169;;;;:::o;11092:268::-;11199:7;11208;11234:11;11247:13;11264:22;11268:3;:10;;11280:5;11264:3;:22::i;:::-;11233:53;;;;11313:3;11305:12;;11343:5;11335:14;;11297:55;;;;;;11092:268;;;;;:::o;57292:100::-;57376:8;57365;:19;;;;;;;;;;;;:::i;:::-;;57292:100;:::o;12474:292::-;12615:7;12697:44;12702:3;:10;;12722:3;12714:12;;12728;12697:4;:44::i;:::-;12689:53;;12635:123;;12474:292;;;;;:::o;389:723::-;445:13;675:1;666:5;:10;662:53;;;693:10;;;;;;;;;;;;;;;;;;;;;662:53;725:12;740:5;725:20;;756:14;781:78;796:1;788:4;:9;781:78;;814:8;;;;;:::i;:::-;;;;845:2;837:10;;;;;:::i;:::-;;;781:78;;;869:19;901:6;891:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;869:39;;919:154;935:1;926:5;:10;919:154;;963:1;953:11;;;;;:::i;:::-;;;1030:2;1022:5;:10;;;;:::i;:::-;1009:2;:24;;;;:::i;:::-;996:39;;979:6;986;979:14;;;;;;;;;;;;;;;;;;;:56;;;;;;;;;;;1059:2;1050:11;;;;;:::i;:::-;;;919:154;;;1097:6;1083:21;;;;;389:723;;;;:::o;22328:114::-;22388:7;22415:19;22423:3;:10;;22415:7;:19::i;:::-;22408:26;;22328:114;;;:::o;65330:98::-;65388:7;65419:1;65415;:5;;;;:::i;:::-;65408:12;;65330:98;;;;:::o;66068:::-;66126:7;66157:1;66153;:5;;;;:::i;:::-;66146:12;;66068:98;;;;:::o;53454:110::-;53530:26;53540:2;53544:7;53530:26;;;;;;;;;;;;:9;:26::i;:::-;53454:110;;:::o;51693:352::-;51850:28;51860:4;51866:2;51870:7;51850:9;:28::i;:::-;51911:48;51934:4;51940:2;51944:7;51953:5;51911:22;:48::i;:::-;51889:148;;;;;;;;;;;;:::i;:::-;;;;;;;;;51693:352;;;;:::o;14519:414::-;14582:4;14604:21;14614:3;14619:5;14604:9;:21::i;:::-;14599:327;;14642:3;:11;;14659:5;14642:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14825:3;:11;;:18;;;;14803:3;:12;;:19;14816:5;14803:19;;;;;;;;;;;:40;;;;14865:4;14858:11;;;;14599:327;14909:5;14902:12;;14519:414;;;;;:::o;4124:737::-;4234:4;4350:16;4369:3;:12;;:17;4382:3;4369:17;;;;;;;;;;;;4350:36;;4415:1;4403:8;:13;4399:455;;;4483:3;:12;;4501:36;;;;;;;;4517:3;4501:36;;;;4530:5;4501:36;;;4483:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4696:3;:12;;:19;;;;4676:3;:12;;:17;4689:3;4676:17;;;;;;;;;;;:39;;;;4737:4;4730:11;;;;;4399:455;4810:5;4774:3;:12;;4798:1;4787:8;:12;;;;:::i;:::-;4774:26;;;;;;;;;;;;;;;;;;;;;;;;;;:33;;:41;;;;4837:5;4830:12;;;4124:737;;;;;;:::o;6682:157::-;6780:4;6830:1;6809:3;:12;;:17;6822:3;6809:17;;;;;;;;;;;;:22;;6802:29;;6682:157;;;;:::o;6934:110::-;6990:7;7017:3;:12;;:19;;;;7010:26;;6934:110;;;:::o;59814:126::-;;;;:::o;21818:160::-;21906:4;21935:35;21943:3;:10;;21963:5;21955:14;;21935:7;:35::i;:::-;21928:42;;21818:160;;;;:::o;17462:273::-;17556:7;17624:5;17603:3;:11;;:18;;;;:26;17581:110;;;;;;;;;;;;:::i;:::-;;;;;;;;;17709:3;:11;;17721:5;17709:18;;;;;;;;;;;;;;;;;;;;;;;;17702:25;;17462:273;;;;:::o;7409:348::-;7503:7;7512;7581:5;7559:3;:12;;:19;;;;:27;7537:111;;;;;;;;;;;;:::i;:::-;;;;;;;;;7661:22;7686:3;:12;;7699:5;7686:19;;;;;;;;;;;;;;;;;;;;;;;;;;7661:44;;7724:5;:10;;;7736:5;:12;;;7716:33;;;;;7409:348;;;;;:::o;9007:353::-;9135:7;9155:16;9174:3;:12;;:17;9187:3;9174:17;;;;;;;;;;;;9155:36;;9222:1;9210:8;:13;;9225:12;9202:36;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;9292:3;:12;;9316:1;9305:8;:12;;;;:::i;:::-;9292:26;;;;;;;;;;;;;;;;;;;;;;;;;;:33;;;9285:40;;;9007:353;;;;;:::o;16999:109::-;17055:7;17082:3;:11;;:18;;;;17075:25;;16999:109;;;:::o;53791:321::-;53921:18;53927:2;53931:7;53921:5;:18::i;:::-;53972:54;54003:1;54007:2;54011:7;54020:5;53972:22;:54::i;:::-;53950:154;;;;;;;;;;;;:::i;:::-;;;;;;;;;53791:321;;;:::o;57957:1053::-;58112:4;58133:15;:2;:13;;;:15::i;:::-;58129:874;;;58202:2;58186:36;;;58245:12;:10;:12::i;:::-;58280:4;58307:7;58337:5;58186:175;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;58165:783;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58565:1;58548:6;:13;:18;58544:389;;;58591:108;;;;;;;;;;:::i;:::-;;;;;;;;58544:389;58883:6;58877:13;58868:6;58864:2;58860:15;58853:38;58165:783;58435:45;;;58425:55;;;:6;:55;;;;58418:62;;;;;58129:874;58987:4;58980:11;;57957:1053;;;;;;;:::o;16752:161::-;16852:4;16904:1;16881:3;:12;;:19;16894:5;16881:19;;;;;;;;;;;;:24;;16874:31;;16752:161;;;;:::o;15109:1557::-;15175:4;15293:18;15314:3;:12;;:19;15327:5;15314:19;;;;;;;;;;;;15293:40;;15364:1;15350:10;:15;15346:1313;;15725:21;15762:1;15749:10;:14;;;;:::i;:::-;15725:38;;15778:17;15819:1;15798:3;:11;;:18;;;;:22;;;;:::i;:::-;15778:42;;16065:17;16085:3;:11;;16097:9;16085:22;;;;;;;;;;;;;;;;;;;;;;;;16065:42;;16231:9;16202:3;:11;;16214:13;16202:26;;;;;;;;;;;;;;;;;;;;;;;:38;;;;16350:1;16334:13;:17;;;;:::i;:::-;16308:3;:12;;:23;16321:9;16308:23;;;;;;;;;;;:43;;;;16460:3;:11;;:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16555:3;:12;;:19;16568:5;16555:19;;;;;;;;;;;16548:26;;;16598:4;16591:11;;;;;;;;15346:1313;16642:5;16635:12;;;15109:1557;;;;;:::o;54448:404::-;54542:1;54528:16;;:2;:16;;;;54520:61;;;;;;;;;;;;:::i;:::-;;;;;;;;;54601:16;54609:7;54601;:16::i;:::-;54600:17;54592:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;54663:45;54692:1;54696:2;54700:7;54663:20;:45::i;:::-;54721:30;54743:7;54721:13;:17;54735:2;54721:17;;;;;;;;;;;;;;;:21;;:30;;;;:::i;:::-;;54764:29;54781:7;54790:2;54764:12;:16;;:29;;;;;:::i;:::-;;54836:7;54832:2;54811:33;;54828:1;54811:33;;;;;;;;;;;;54448:404;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;:::o;7:342:1:-;;109:64;124:48;165:6;124:48;:::i;:::-;109:64;:::i;:::-;100:73;;196:6;189:5;182:21;234:4;227:5;223:16;272:3;263:6;258:3;254:16;251:25;248:2;;;289:1;286;279:12;248:2;302:41;336:6;331:3;326;302:41;:::i;:::-;90:259;;;;;;:::o;355:344::-;;458:65;473:49;515:6;473:49;:::i;:::-;458:65;:::i;:::-;449:74;;546:6;539:5;532:21;584:4;577:5;573:16;622:3;613:6;608:3;604:16;601:25;598:2;;;639:1;636;629:12;598:2;652:41;686:6;681:3;676;652:41;:::i;:::-;439:260;;;;;;:::o;705:139::-;;789:6;776:20;767:29;;805:33;832:5;805:33;:::i;:::-;757:87;;;;:::o;850:133::-;;931:6;918:20;909:29;;947:30;971:5;947:30;:::i;:::-;899:84;;;;:::o;989:137::-;;1072:6;1059:20;1050:29;;1088:32;1114:5;1088:32;:::i;:::-;1040:86;;;;:::o;1132:141::-;;1219:6;1213:13;1204:22;;1235:32;1261:5;1235:32;:::i;:::-;1194:79;;;;:::o;1292:271::-;;1396:3;1389:4;1381:6;1377:17;1373:27;1363:2;;1414:1;1411;1404:12;1363:2;1454:6;1441:20;1479:78;1553:3;1545:6;1538:4;1530:6;1526:17;1479:78;:::i;:::-;1470:87;;1353:210;;;;;:::o;1583:273::-;;1688:3;1681:4;1673:6;1669:17;1665:27;1655:2;;1706:1;1703;1696:12;1655:2;1746:6;1733:20;1771:79;1846:3;1838:6;1831:4;1823:6;1819:17;1771:79;:::i;:::-;1762:88;;1645:211;;;;;:::o;1862:139::-;;1946:6;1933:20;1924:29;;1962:33;1989:5;1962:33;:::i;:::-;1914:87;;;;:::o;2007:262::-;;2115:2;2103:9;2094:7;2090:23;2086:32;2083:2;;;2131:1;2128;2121:12;2083:2;2174:1;2199:53;2244:7;2235:6;2224:9;2220:22;2199:53;:::i;:::-;2189:63;;2145:117;2073:196;;;;:::o;2275:407::-;;;2400:2;2388:9;2379:7;2375:23;2371:32;2368:2;;;2416:1;2413;2406:12;2368:2;2459:1;2484:53;2529:7;2520:6;2509:9;2505:22;2484:53;:::i;:::-;2474:63;;2430:117;2586:2;2612:53;2657:7;2648:6;2637:9;2633:22;2612:53;:::i;:::-;2602:63;;2557:118;2358:324;;;;;:::o;2688:552::-;;;;2830:2;2818:9;2809:7;2805:23;2801:32;2798:2;;;2846:1;2843;2836:12;2798:2;2889:1;2914:53;2959:7;2950:6;2939:9;2935:22;2914:53;:::i;:::-;2904:63;;2860:117;3016:2;3042:53;3087:7;3078:6;3067:9;3063:22;3042:53;:::i;:::-;3032:63;;2987:118;3144:2;3170:53;3215:7;3206:6;3195:9;3191:22;3170:53;:::i;:::-;3160:63;;3115:118;2788:452;;;;;:::o;3246:809::-;;;;;3414:3;3402:9;3393:7;3389:23;3385:33;3382:2;;;3431:1;3428;3421:12;3382:2;3474:1;3499:53;3544:7;3535:6;3524:9;3520:22;3499:53;:::i;:::-;3489:63;;3445:117;3601:2;3627:53;3672:7;3663:6;3652:9;3648:22;3627:53;:::i;:::-;3617:63;;3572:118;3729:2;3755:53;3800:7;3791:6;3780:9;3776:22;3755:53;:::i;:::-;3745:63;;3700:118;3885:2;3874:9;3870:18;3857:32;3916:18;3908:6;3905:30;3902:2;;;3948:1;3945;3938:12;3902:2;3976:62;4030:7;4021:6;4010:9;4006:22;3976:62;:::i;:::-;3966:72;;3828:220;3372:683;;;;;;;:::o;4061:401::-;;;4183:2;4171:9;4162:7;4158:23;4154:32;4151:2;;;4199:1;4196;4189:12;4151:2;4242:1;4267:53;4312:7;4303:6;4292:9;4288:22;4267:53;:::i;:::-;4257:63;;4213:117;4369:2;4395:50;4437:7;4428:6;4417:9;4413:22;4395:50;:::i;:::-;4385:60;;4340:115;4141:321;;;;;:::o;4468:407::-;;;4593:2;4581:9;4572:7;4568:23;4564:32;4561:2;;;4609:1;4606;4599:12;4561:2;4652:1;4677:53;4722:7;4713:6;4702:9;4698:22;4677:53;:::i;:::-;4667:63;;4623:117;4779:2;4805:53;4850:7;4841:6;4830:9;4826:22;4805:53;:::i;:::-;4795:63;;4750:118;4551:324;;;;;:::o;4881:260::-;;4988:2;4976:9;4967:7;4963:23;4959:32;4956:2;;;5004:1;5001;4994:12;4956:2;5047:1;5072:52;5116:7;5107:6;5096:9;5092:22;5072:52;:::i;:::-;5062:62;;5018:116;4946:195;;;;:::o;5147:282::-;;5265:2;5253:9;5244:7;5240:23;5236:32;5233:2;;;5281:1;5278;5271:12;5233:2;5324:1;5349:63;5404:7;5395:6;5384:9;5380:22;5349:63;:::i;:::-;5339:73;;5295:127;5223:206;;;;:::o;5435:375::-;;5553:2;5541:9;5532:7;5528:23;5524:32;5521:2;;;5569:1;5566;5559:12;5521:2;5640:1;5629:9;5625:17;5612:31;5670:18;5662:6;5659:30;5656:2;;;5702:1;5699;5692:12;5656:2;5730:63;5785:7;5776:6;5765:9;5761:22;5730:63;:::i;:::-;5720:73;;5583:220;5511:299;;;;:::o;5816:262::-;;5924:2;5912:9;5903:7;5899:23;5895:32;5892:2;;;5940:1;5937;5930:12;5892:2;5983:1;6008:53;6053:7;6044:6;6033:9;6029:22;6008:53;:::i;:::-;5998:63;;5954:117;5882:196;;;;:::o;6084:179::-;;6174:46;6216:3;6208:6;6174:46;:::i;:::-;6252:4;6247:3;6243:14;6229:28;;6164:99;;;;:::o;6269:118::-;6356:24;6374:5;6356:24;:::i;:::-;6351:3;6344:37;6334:53;;:::o;6393:157::-;6498:45;6518:24;6536:5;6518:24;:::i;:::-;6498:45;:::i;:::-;6493:3;6486:58;6476:74;;:::o;6586:732::-;;6734:54;6782:5;6734:54;:::i;:::-;6804:86;6883:6;6878:3;6804:86;:::i;:::-;6797:93;;6914:56;6964:5;6914:56;:::i;:::-;6993:7;7024:1;7009:284;7034:6;7031:1;7028:13;7009:284;;;7110:6;7104:13;7137:63;7196:3;7181:13;7137:63;:::i;:::-;7130:70;;7223:60;7276:6;7223:60;:::i;:::-;7213:70;;7069:224;7056:1;7053;7049:9;7044:14;;7009:284;;;7013:14;7309:3;7302:10;;6710:608;;;;;;;:::o;7324:109::-;7405:21;7420:5;7405:21;:::i;:::-;7400:3;7393:34;7383:50;;:::o;7439:118::-;7526:24;7544:5;7526:24;:::i;:::-;7521:3;7514:37;7504:53;;:::o;7563:360::-;;7677:38;7709:5;7677:38;:::i;:::-;7731:70;7794:6;7789:3;7731:70;:::i;:::-;7724:77;;7810:52;7855:6;7850:3;7843:4;7836:5;7832:16;7810:52;:::i;:::-;7887:29;7909:6;7887:29;:::i;:::-;7882:3;7878:39;7871:46;;7653:270;;;;;:::o;7929:364::-;;8045:39;8078:5;8045:39;:::i;:::-;8100:71;8164:6;8159:3;8100:71;:::i;:::-;8093:78;;8180:52;8225:6;8220:3;8213:4;8206:5;8202:16;8180:52;:::i;:::-;8257:29;8279:6;8257:29;:::i;:::-;8252:3;8248:39;8241:46;;8021:272;;;;;:::o;8299:377::-;;8433:39;8466:5;8433:39;:::i;:::-;8488:89;8570:6;8565:3;8488:89;:::i;:::-;8481:96;;8586:52;8631:6;8626:3;8619:4;8612:5;8608:16;8586:52;:::i;:::-;8663:6;8658:3;8654:16;8647:23;;8409:267;;;;;:::o;8706:845::-;;8846:5;8840:12;8875:36;8901:9;8875:36;:::i;:::-;8927:89;9009:6;9004:3;8927:89;:::i;:::-;8920:96;;9047:1;9036:9;9032:17;9063:1;9058:137;;;;9209:1;9204:341;;;;9025:520;;9058:137;9142:4;9138:9;9127;9123:25;9118:3;9111:38;9178:6;9173:3;9169:16;9162:23;;9058:137;;9204:341;9271:38;9303:5;9271:38;:::i;:::-;9331:1;9345:154;9359:6;9356:1;9353:13;9345:154;;;9433:7;9427:14;9423:1;9418:3;9414:11;9407:35;9483:1;9474:7;9470:15;9459:26;;9381:4;9378:1;9374:12;9369:17;;9345:154;;;9528:6;9523:3;9519:16;9512:23;;9211:334;;9025:520;;8813:738;;;;;;:::o;9557:366::-;;9720:67;9784:2;9779:3;9720:67;:::i;:::-;9713:74;;9817:34;9813:1;9808:3;9804:11;9797:55;9883:4;9878:2;9873:3;9869:12;9862:26;9914:2;9909:3;9905:12;9898:19;;9703:220;;;:::o;9929:382::-;;10092:67;10156:2;10151:3;10092:67;:::i;:::-;10085:74;;10189:34;10185:1;10180:3;10176:11;10169:55;10255:20;10250:2;10245:3;10241:12;10234:42;10302:2;10297:3;10293:12;10286:19;;10075:236;;;:::o;10317:370::-;;10480:67;10544:2;10539:3;10480:67;:::i;:::-;10473:74;;10577:34;10573:1;10568:3;10564:11;10557:55;10643:8;10638:2;10633:3;10629:12;10622:30;10678:2;10673:3;10669:12;10662:19;;10463:224;;;:::o;10693:326::-;;10856:67;10920:2;10915:3;10856:67;:::i;:::-;10849:74;;10953:30;10949:1;10944:3;10940:11;10933:51;11010:2;11005:3;11001:12;10994:19;;10839:180;;;:::o;11025:368::-;;11188:67;11252:2;11247:3;11188:67;:::i;:::-;11181:74;;11285:34;11281:1;11276:3;11272:11;11265:55;11351:6;11346:2;11341:3;11337:12;11330:28;11384:2;11379:3;11375:12;11368:19;;11171:222;;;:::o;11399:323::-;;11562:67;11626:2;11621:3;11562:67;:::i;:::-;11555:74;;11659:27;11655:1;11650:3;11646:11;11639:48;11713:2;11708:3;11704:12;11697:19;;11545:177;;;:::o;11728:376::-;;11891:67;11955:2;11950:3;11891:67;:::i;:::-;11884:74;;11988:34;11984:1;11979:3;11975:11;11968:55;12054:14;12049:2;12044:3;12040:12;12033:36;12095:2;12090:3;12086:12;12079:19;;11874:230;;;:::o;12110:318::-;;12273:67;12337:2;12332:3;12273:67;:::i;:::-;12266:74;;12370:22;12366:1;12361:3;12357:11;12350:43;12419:2;12414:3;12410:12;12403:19;;12256:172;;;:::o;12434:388::-;;12597:67;12661:2;12656:3;12597:67;:::i;:::-;12590:74;;12694:34;12690:1;12685:3;12681:11;12674:55;12760:26;12755:2;12750:3;12746:12;12739:48;12813:2;12808:3;12804:12;12797:19;;12580:242;;;:::o;12828:374::-;;12991:67;13055:2;13050:3;12991:67;:::i;:::-;12984:74;;13088:34;13084:1;13079:3;13075:11;13068:55;13154:12;13149:2;13144:3;13140:12;13133:34;13193:2;13188:3;13184:12;13177:19;;12974:228;;;:::o;13208:367::-;;13371:67;13435:2;13430:3;13371:67;:::i;:::-;13364:74;;13468:34;13464:1;13459:3;13455:11;13448:55;13534:5;13529:2;13524:3;13520:12;13513:27;13566:2;13561:3;13557:12;13550:19;;13354:221;;;:::o;13581:366::-;;13744:67;13808:2;13803:3;13744:67;:::i;:::-;13737:74;;13841:34;13837:1;13832:3;13828:11;13821:55;13907:4;13902:2;13897:3;13893:12;13886:26;13938:2;13933:3;13929:12;13922:19;;13727:220;;;:::o;13953:330::-;;14116:67;14180:2;14175:3;14116:67;:::i;:::-;14109:74;;14213:34;14209:1;14204:3;14200:11;14193:55;14274:2;14269:3;14265:12;14258:19;;14099:184;;;:::o;14289:367::-;;14452:67;14516:2;14511:3;14452:67;:::i;:::-;14445:74;;14549:34;14545:1;14540:3;14536:11;14529:55;14615:5;14610:2;14605:3;14601:12;14594:27;14647:2;14642:3;14638:12;14631:19;;14435:221;;;:::o;14662:376::-;;14825:67;14889:2;14884:3;14825:67;:::i;:::-;14818:74;;14922:34;14918:1;14913:3;14909:11;14902:55;14988:14;14983:2;14978:3;14974:12;14967:36;15029:2;15024:3;15020:12;15013:19;;14808:230;;;:::o;15044:330::-;;15207:67;15271:2;15266:3;15207:67;:::i;:::-;15200:74;;15304:34;15300:1;15295:3;15291:11;15284:55;15365:2;15360:3;15356:12;15349:19;;15190:184;;;:::o;15380:373::-;;15543:67;15607:2;15602:3;15543:67;:::i;:::-;15536:74;;15640:34;15636:1;15631:3;15627:11;15620:55;15706:11;15701:2;15696:3;15692:12;15685:33;15744:2;15739:3;15735:12;15728:19;;15526:227;;;:::o;15759:379::-;;15922:67;15986:2;15981:3;15922:67;:::i;:::-;15915:74;;16019:34;16015:1;16010:3;16006:11;15999:55;16085:17;16080:2;16075:3;16071:12;16064:39;16129:2;16124:3;16120:12;16113:19;;15905:233;;;:::o;16144:365::-;;16307:67;16371:2;16366:3;16307:67;:::i;:::-;16300:74;;16404:34;16400:1;16395:3;16391:11;16384:55;16470:3;16465:2;16460:3;16456:12;16449:25;16500:2;16495:3;16491:12;16484:19;;16290:219;;;:::o;16515:320::-;;16678:67;16742:2;16737:3;16678:67;:::i;:::-;16671:74;;16775:24;16771:1;16766:3;16762:11;16755:45;16826:2;16821:3;16817:12;16810:19;;16661:174;;;:::o;16841:381::-;;17004:67;17068:2;17063:3;17004:67;:::i;:::-;16997:74;;17101:34;17097:1;17092:3;17088:11;17081:55;17167:19;17162:2;17157:3;17153:12;17146:41;17213:2;17208:3;17204:12;17197:19;;16987:235;;;:::o;17228:312::-;;17391:67;17455:2;17450:3;17391:67;:::i;:::-;17384:74;;17488:16;17484:1;17479:3;17475:11;17468:37;17531:2;17526:3;17522:12;17515:19;;17374:166;;;:::o;17546:108::-;17623:24;17641:5;17623:24;:::i;:::-;17618:3;17611:37;17601:53;;:::o;17660:118::-;17747:24;17765:5;17747:24;:::i;:::-;17742:3;17735:37;17725:53;;:::o;17784:157::-;17889:45;17909:24;17927:5;17909:24;:::i;:::-;17889:45;:::i;:::-;17884:3;17877:58;17867:74;;:::o;17947:679::-;;18158:75;18229:3;18220:6;18158:75;:::i;:::-;18258:2;18253:3;18249:12;18242:19;;18271:75;18342:3;18333:6;18271:75;:::i;:::-;18371:2;18366:3;18362:12;18355:19;;18384:75;18455:3;18446:6;18384:75;:::i;:::-;18484:2;18479:3;18475:12;18468:19;;18497:75;18568:3;18559:6;18497:75;:::i;:::-;18597:2;18592:3;18588:12;18581:19;;18617:3;18610:10;;18147:479;;;;;;;:::o;18632:435::-;;18834:95;18925:3;18916:6;18834:95;:::i;:::-;18827:102;;18946:95;19037:3;19028:6;18946:95;:::i;:::-;18939:102;;19058:3;19051:10;;18816:251;;;;;:::o;19073:429::-;;19272:92;19360:3;19351:6;19272:92;:::i;:::-;19265:99;;19381:95;19472:3;19463:6;19381:95;:::i;:::-;19374:102;;19493:3;19486:10;;19254:248;;;;;:::o;19508:222::-;;19639:2;19628:9;19624:18;19616:26;;19652:71;19720:1;19709:9;19705:17;19696:6;19652:71;:::i;:::-;19606:124;;;;:::o;19736:640::-;;19969:3;19958:9;19954:19;19946:27;;19983:71;20051:1;20040:9;20036:17;20027:6;19983:71;:::i;:::-;20064:72;20132:2;20121:9;20117:18;20108:6;20064:72;:::i;:::-;20146;20214:2;20203:9;20199:18;20190:6;20146:72;:::i;:::-;20265:9;20259:4;20255:20;20250:2;20239:9;20235:18;20228:48;20293:76;20364:4;20355:6;20293:76;:::i;:::-;20285:84;;19936:440;;;;;;;:::o;20382:373::-;;20563:2;20552:9;20548:18;20540:26;;20612:9;20606:4;20602:20;20598:1;20587:9;20583:17;20576:47;20640:108;20743:4;20734:6;20640:108;:::i;:::-;20632:116;;20530:225;;;;:::o;20761:210::-;;20886:2;20875:9;20871:18;20863:26;;20899:65;20961:1;20950:9;20946:17;20937:6;20899:65;:::i;:::-;20853:118;;;;:::o;20977:222::-;;21108:2;21097:9;21093:18;21085:26;;21121:71;21189:1;21178:9;21174:17;21165:6;21121:71;:::i;:::-;21075:124;;;;:::o;21205:313::-;;21356:2;21345:9;21341:18;21333:26;;21405:9;21399:4;21395:20;21391:1;21380:9;21376:17;21369:47;21433:78;21506:4;21497:6;21433:78;:::i;:::-;21425:86;;21323:195;;;;:::o;21524:419::-;;21728:2;21717:9;21713:18;21705:26;;21777:9;21771:4;21767:20;21763:1;21752:9;21748:17;21741:47;21805:131;21931:4;21805:131;:::i;:::-;21797:139;;21695:248;;;:::o;21949:419::-;;22153:2;22142:9;22138:18;22130:26;;22202:9;22196:4;22192:20;22188:1;22177:9;22173:17;22166:47;22230:131;22356:4;22230:131;:::i;:::-;22222:139;;22120:248;;;:::o;22374:419::-;;22578:2;22567:9;22563:18;22555:26;;22627:9;22621:4;22617:20;22613:1;22602:9;22598:17;22591:47;22655:131;22781:4;22655:131;:::i;:::-;22647:139;;22545:248;;;:::o;22799:419::-;;23003:2;22992:9;22988:18;22980:26;;23052:9;23046:4;23042:20;23038:1;23027:9;23023:17;23016:47;23080:131;23206:4;23080:131;:::i;:::-;23072:139;;22970:248;;;:::o;23224:419::-;;23428:2;23417:9;23413:18;23405:26;;23477:9;23471:4;23467:20;23463:1;23452:9;23448:17;23441:47;23505:131;23631:4;23505:131;:::i;:::-;23497:139;;23395:248;;;:::o;23649:419::-;;23853:2;23842:9;23838:18;23830:26;;23902:9;23896:4;23892:20;23888:1;23877:9;23873:17;23866:47;23930:131;24056:4;23930:131;:::i;:::-;23922:139;;23820:248;;;:::o;24074:419::-;;24278:2;24267:9;24263:18;24255:26;;24327:9;24321:4;24317:20;24313:1;24302:9;24298:17;24291:47;24355:131;24481:4;24355:131;:::i;:::-;24347:139;;24245:248;;;:::o;24499:419::-;;24703:2;24692:9;24688:18;24680:26;;24752:9;24746:4;24742:20;24738:1;24727:9;24723:17;24716:47;24780:131;24906:4;24780:131;:::i;:::-;24772:139;;24670:248;;;:::o;24924:419::-;;25128:2;25117:9;25113:18;25105:26;;25177:9;25171:4;25167:20;25163:1;25152:9;25148:17;25141:47;25205:131;25331:4;25205:131;:::i;:::-;25197:139;;25095:248;;;:::o;25349:419::-;;25553:2;25542:9;25538:18;25530:26;;25602:9;25596:4;25592:20;25588:1;25577:9;25573:17;25566:47;25630:131;25756:4;25630:131;:::i;:::-;25622:139;;25520:248;;;:::o;25774:419::-;;25978:2;25967:9;25963:18;25955:26;;26027:9;26021:4;26017:20;26013:1;26002:9;25998:17;25991:47;26055:131;26181:4;26055:131;:::i;:::-;26047:139;;25945:248;;;:::o;26199:419::-;;26403:2;26392:9;26388:18;26380:26;;26452:9;26446:4;26442:20;26438:1;26427:9;26423:17;26416:47;26480:131;26606:4;26480:131;:::i;:::-;26472:139;;26370:248;;;:::o;26624:419::-;;26828:2;26817:9;26813:18;26805:26;;26877:9;26871:4;26867:20;26863:1;26852:9;26848:17;26841:47;26905:131;27031:4;26905:131;:::i;:::-;26897:139;;26795:248;;;:::o;27049:419::-;;27253:2;27242:9;27238:18;27230:26;;27302:9;27296:4;27292:20;27288:1;27277:9;27273:17;27266:47;27330:131;27456:4;27330:131;:::i;:::-;27322:139;;27220:248;;;:::o;27474:419::-;;27678:2;27667:9;27663:18;27655:26;;27727:9;27721:4;27717:20;27713:1;27702:9;27698:17;27691:47;27755:131;27881:4;27755:131;:::i;:::-;27747:139;;27645:248;;;:::o;27899:419::-;;28103:2;28092:9;28088:18;28080:26;;28152:9;28146:4;28142:20;28138:1;28127:9;28123:17;28116:47;28180:131;28306:4;28180:131;:::i;:::-;28172:139;;28070:248;;;:::o;28324:419::-;;28528:2;28517:9;28513:18;28505:26;;28577:9;28571:4;28567:20;28563:1;28552:9;28548:17;28541:47;28605:131;28731:4;28605:131;:::i;:::-;28597:139;;28495:248;;;:::o;28749:419::-;;28953:2;28942:9;28938:18;28930:26;;29002:9;28996:4;28992:20;28988:1;28977:9;28973:17;28966:47;29030:131;29156:4;29030:131;:::i;:::-;29022:139;;28920:248;;;:::o;29174:419::-;;29378:2;29367:9;29363:18;29355:26;;29427:9;29421:4;29417:20;29413:1;29402:9;29398:17;29391:47;29455:131;29581:4;29455:131;:::i;:::-;29447:139;;29345:248;;;:::o;29599:419::-;;29803:2;29792:9;29788:18;29780:26;;29852:9;29846:4;29842:20;29838:1;29827:9;29823:17;29816:47;29880:131;30006:4;29880:131;:::i;:::-;29872:139;;29770:248;;;:::o;30024:419::-;;30228:2;30217:9;30213:18;30205:26;;30277:9;30271:4;30267:20;30263:1;30252:9;30248:17;30241:47;30305:131;30431:4;30305:131;:::i;:::-;30297:139;;30195:248;;;:::o;30449:419::-;;30653:2;30642:9;30638:18;30630:26;;30702:9;30696:4;30692:20;30688:1;30677:9;30673:17;30666:47;30730:131;30856:4;30730:131;:::i;:::-;30722:139;;30620:248;;;:::o;30874:222::-;;31005:2;30994:9;30990:18;30982:26;;31018:71;31086:1;31075:9;31071:17;31062:6;31018:71;:::i;:::-;30972:124;;;;:::o;31102:283::-;;31168:2;31162:9;31152:19;;31210:4;31202:6;31198:17;31317:6;31305:10;31302:22;31281:18;31269:10;31266:34;31263:62;31260:2;;;31328:18;;:::i;:::-;31260:2;31368:10;31364:2;31357:22;31142:243;;;;:::o;31391:331::-;;31542:18;31534:6;31531:30;31528:2;;;31564:18;;:::i;:::-;31528:2;31649:4;31645:9;31638:4;31630:6;31626:17;31622:33;31614:41;;31710:4;31704;31700:15;31692:23;;31457:265;;;:::o;31728:332::-;;31880:18;31872:6;31869:30;31866:2;;;31902:18;;:::i;:::-;31866:2;31987:4;31983:9;31976:4;31968:6;31964:17;31960:33;31952:41;;32048:4;32042;32038:15;32030:23;;31795:265;;;:::o;32066:132::-;;32156:3;32148:11;;32186:4;32181:3;32177:14;32169:22;;32138:60;;;:::o;32204:141::-;;32276:3;32268:11;;32299:3;32296:1;32289:14;32333:4;32330:1;32320:18;32312:26;;32258:87;;;:::o;32351:114::-;;32452:5;32446:12;32436:22;;32425:40;;;:::o;32471:98::-;;32556:5;32550:12;32540:22;;32529:40;;;:::o;32575:99::-;;32661:5;32655:12;32645:22;;32634:40;;;:::o;32680:113::-;;32782:4;32777:3;32773:14;32765:22;;32755:38;;;:::o;32799:184::-;;32932:6;32927:3;32920:19;32972:4;32967:3;32963:14;32948:29;;32910:73;;;;:::o;32989:168::-;;33106:6;33101:3;33094:19;33146:4;33141:3;33137:14;33122:29;;33084:73;;;;:::o;33163:169::-;;33281:6;33276:3;33269:19;33321:4;33316:3;33312:14;33297:29;;33259:73;;;;:::o;33338:148::-;;33477:3;33462:18;;33452:34;;;;:::o;33492:305::-;;33551:20;33569:1;33551:20;:::i;:::-;33546:25;;33585:20;33603:1;33585:20;:::i;:::-;33580:25;;33739:1;33671:66;33667:74;33664:1;33661:81;33658:2;;;33745:18;;:::i;:::-;33658:2;33789:1;33786;33782:9;33775:16;;33536:261;;;;:::o;33803:185::-;;33860:20;33878:1;33860:20;:::i;:::-;33855:25;;33894:20;33912:1;33894:20;:::i;:::-;33889:25;;33933:1;33923:2;;33938:18;;:::i;:::-;33923:2;33980:1;33977;33973:9;33968:14;;33845:143;;;;:::o;33994:348::-;;34057:20;34075:1;34057:20;:::i;:::-;34052:25;;34091:20;34109:1;34091:20;:::i;:::-;34086:25;;34279:1;34211:66;34207:74;34204:1;34201:81;34196:1;34189:9;34182:17;34178:105;34175:2;;;34286:18;;:::i;:::-;34175:2;34334:1;34331;34327:9;34316:20;;34042:300;;;;:::o;34348:191::-;;34408:20;34426:1;34408:20;:::i;:::-;34403:25;;34442:20;34460:1;34442:20;:::i;:::-;34437:25;;34481:1;34478;34475:8;34472:2;;;34486:18;;:::i;:::-;34472:2;34531:1;34528;34524:9;34516:17;;34393:146;;;;:::o;34545:96::-;;34611:24;34629:5;34611:24;:::i;:::-;34600:35;;34590:51;;;:::o;34647:90::-;;34724:5;34717:13;34710:21;34699:32;;34689:48;;;:::o;34743:77::-;;34809:5;34798:16;;34788:32;;;:::o;34826:149::-;;34902:66;34895:5;34891:78;34880:89;;34870:105;;;:::o;34981:126::-;;35058:42;35051:5;35047:54;35036:65;;35026:81;;;:::o;35113:77::-;;35179:5;35168:16;;35158:32;;;:::o;35196:154::-;35280:6;35275:3;35270;35257:30;35342:1;35333:6;35328:3;35324:16;35317:27;35247:103;;;:::o;35356:307::-;35424:1;35434:113;35448:6;35445:1;35442:13;35434:113;;;35533:1;35528:3;35524:11;35518:18;35514:1;35509:3;35505:11;35498:39;35470:2;35467:1;35463:10;35458:15;;35434:113;;;35565:6;35562:1;35559:13;35556:2;;;35645:1;35636:6;35631:3;35627:16;35620:27;35556:2;35405:258;;;;:::o;35669:320::-;;35750:1;35744:4;35740:12;35730:22;;35797:1;35791:4;35787:12;35818:18;35808:2;;35874:4;35866:6;35862:17;35852:27;;35808:2;35936;35928:6;35925:14;35905:18;35902:38;35899:2;;;35955:18;;:::i;:::-;35899:2;35720:269;;;;:::o;35995:233::-;;36057:24;36075:5;36057:24;:::i;:::-;36048:33;;36103:66;36096:5;36093:77;36090:2;;;36173:18;;:::i;:::-;36090:2;36220:1;36213:5;36209:13;36202:20;;36038:190;;;:::o;36234:100::-;;36302:26;36322:5;36302:26;:::i;:::-;36291:37;;36281:53;;;:::o;36340:94::-;;36408:20;36422:5;36408:20;:::i;:::-;36397:31;;36387:47;;;:::o;36440:79::-;;36508:5;36497:16;;36487:32;;;:::o;36525:176::-;;36574:20;36592:1;36574:20;:::i;:::-;36569:25;;36608:20;36626:1;36608:20;:::i;:::-;36603:25;;36647:1;36637:2;;36652:18;;:::i;:::-;36637:2;36693:1;36690;36686:9;36681:14;;36559:142;;;;:::o;36707:180::-;36755:77;36752:1;36745:88;36852:4;36849:1;36842:15;36876:4;36873:1;36866:15;36893:180;36941:77;36938:1;36931:88;37038:4;37035:1;37028:15;37062:4;37059:1;37052:15;37079:180;37127:77;37124:1;37117:88;37224:4;37221:1;37214:15;37248:4;37245:1;37238:15;37265:180;37313:77;37310:1;37303:88;37410:4;37407:1;37400:15;37434:4;37431:1;37424:15;37451:102;;37543:2;37539:7;37534:2;37527:5;37523:14;37519:28;37509:38;;37499:54;;;:::o;37559:94::-;;37640:5;37636:2;37632:14;37611:35;;37601:52;;;:::o;37659:122::-;37732:24;37750:5;37732:24;:::i;:::-;37725:5;37722:35;37712:2;;37771:1;37768;37761:12;37712:2;37702:79;:::o;37787:116::-;37857:21;37872:5;37857:21;:::i;:::-;37850:5;37847:32;37837:2;;37893:1;37890;37883:12;37837:2;37827:76;:::o;37909:120::-;37981:23;37998:5;37981:23;:::i;:::-;37974:5;37971:34;37961:2;;38019:1;38016;38009:12;37961:2;37951:78;:::o;38035:122::-;38108:24;38126:5;38108:24;:::i;:::-;38101:5;38098:35;38088:2;;38147:1;38144;38137:12;38088:2;38078:79;:::o

Swarm Source

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