ETH Price: $3,483.29 (+3.61%)
Gas: 2 Gwei

Token

UnitedPunksUnion (UPU)
 

Overview

Max Total Supply

3,629 UPU

Holders

1,198

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A

Other Info

Balance
1 UPU
0xa85819617a048287Ae2f5bA42740D7d71C9e439C
Loading...
Loading
Loading...
Loading
Loading...
Loading

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

Contract Source Code Verified (Exact Match)

Contract Name:
UnitedPunksUnion

Compiler Version
v0.8.4+commit.c7e474f2

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2021-07-01
*/

// SPDX-License-Identifier: MIT

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;


contract UnitedPunksUnion is ERC721, Ownable {
    
    using SafeMath for uint256;
    uint public constant MAX_UNITEDPUNKSUNION = 13666;
    bool public hasSaleStarted = true;
    uint public constant UNITEDPUNKSUNION_PRICE = 30000000000000000;

    string public METADATA_PROVENANCE_HASH = "";
    
    constructor() ERC721("UnitedPunksUnion","UPU")  { }
    
    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 buy(uint256 numPunks) public payable {
        require(totalSupply() < MAX_UNITEDPUNKSUNION, "Sale has already ended");
        require(numPunks > 0 && numPunks <= 20, "You can adopt minimum 1, maximum 20 United Union Punks");
        require(totalSupply().add(numPunks) <= MAX_UNITEDPUNKSUNION, "Exceeds MAX_UNITEDPUNKSUNION");
        require(msg.value >= UNITEDPUNKSUNION_PRICE.mul(numPunks), "Ether value sent is below the price");

        for (uint i = 0; i < numPunks; i++) {
            uint mintIndex = totalSupply();
            _safeMint(msg.sender, mintIndex);
        }

    }
        function getPrice(uint _count) public view returns (uint256) {
        uint256 returnVal = 0;
        if(totalSupply() <= MAX_UNITEDPUNKSUNION ){
           returnVal = UNITEDPUNKSUNION_PRICE * _count; // 0.03 ETH
        }

        return returnVal;
    }

    // ONLYOWNER FUNCTIONS
    
    function setProvenanceHash(string memory _hash) public onlyOwner {
        METADATA_PROVENANCE_HASH = _hash;
    }
    
function giveGift(address _address, uint numPunks) public onlyOwner {
        uint mintIndex = totalSupply();
        require(mintIndex < 240);
        require(totalSupply().add(numPunks) <= 240, "Exceeds MAX_UNITEDPUNKSUNION");
        for (uint i = 0; i < numPunks; i++) {
            _safeMint(_address, mintIndex + i);
        }
    }
    
    function setBaseURI(string memory baseURI) public onlyOwner {
        _setBaseURI(baseURI);
    }
    
    function startDrop() public onlyOwner {
        hasSaleStarted = true;
    }
    
    function pauseDrop() public onlyOwner {
        hasSaleStarted = false;
    }
    
    function withdraw() public payable onlyOwner {
        require(payable(msg.sender).send(address(this).balance));
    }
    
}

// Upgraded United CryptoPunks Smart Contract "United Punks Union"
// Punks not dead!
// Special thanks to @berkozdemir @mmtiglioglu

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":"MAX_UNITEDPUNKSUNION","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":"UNITEDPUNKSUNION_PRICE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"numPunks","type":"uint256"}],"name":"buy","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_count","type":"uint256"}],"name":"getPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"},{"internalType":"uint256","name":"numPunks","type":"uint256"}],"name":"giveGift","outputs":[],"stateMutability":"nonpayable","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":[],"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":"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":"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":"withdraw","outputs":[],"stateMutability":"payable","type":"function"}]

60806040526001600a60146101000a81548160ff02191690831515021790555060405180602001604052806000815250600b90805190602001906200004692919062000350565b503480156200005457600080fd5b506040518060400160405280601081526020017f556e6974656450756e6b73556e696f6e000000000000000000000000000000008152506040518060400160405280600381526020017f5550550000000000000000000000000000000000000000000000000000000000815250620000f27f01ffc9a7000000000000000000000000000000000000000000000000000000006200027060201b60201c565b81600690805190602001906200010a92919062000350565b5080600790805190602001906200012392919062000350565b50620001557f80ac58cd000000000000000000000000000000000000000000000000000000006200027060201b60201c565b620001867f5b5e139f000000000000000000000000000000000000000000000000000000006200027060201b60201c565b620001b77f780e9d63000000000000000000000000000000000000000000000000000000006200027060201b60201c565b50506000620001cb6200034860201b60201c565b905080600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a350620004e8565b63ffffffff60e01b817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161415620002dc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620002d39062000427565b60405180910390fd5b6001600080837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b600033905090565b8280546200035e906200045a565b90600052602060002090601f016020900481019282620003825760008555620003ce565b82601f106200039d57805160ff1916838001178555620003ce565b82800160010185558215620003ce579182015b82811115620003cd578251825591602001919060010190620003b0565b5b509050620003dd9190620003e1565b5090565b5b80821115620003fc576000816000905550600101620003e2565b5090565b60006200040f601c8362000449565b91506200041c82620004bf565b602082019050919050565b60006020820190508181036000830152620004428162000400565b9050919050565b600082825260208201905092915050565b600060028204905060018216806200047357607f821691505b602082108114156200048a576200048962000490565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4552433136353a20696e76616c696420696e7465726661636520696400000000600082015250565b6143ea80620004f86000396000f3fe6080604052600436106101ee5760003560e01c806355f804b31161010d57806395d89b41116100a0578063d96a094a1161006f578063d96a094a146106ca578063e7572230146106e6578063e985e9c514610723578063f0c9dc6014610760578063f2fde38b1461078b576101ee565b806395d89b4114610610578063a22cb4651461063b578063b88d4fde14610664578063c87b56dd1461068d576101ee565b806370a08231116100dc57806370a0823114610554578063715018a6146105915780638462151c146105a85780638da5cb5b146105e5576101ee565b806355f804b3146104985780636352211e146104c1578063648cfea2146104fe5780636c0360eb14610529576101ee565b80632808c92c116101855780633ccfd60b116101545780633ccfd60b146103ff57806342842e0e146104095780634f6ccce7146104325780635433f23c1461046f576101ee565b80632808c92c146103695780632f745c59146103805780633486ad83146103bd57806334d84c7b146103e8576101ee565b806310969523116101c157806310969523146102c157806318160ddd146102ea5780631c8b232d1461031557806323b872dd14610340576101ee565b806301ffc9a7146101f357806306fdde0314610230578063081812fc1461025b578063095ea7b314610298575b600080fd5b3480156101ff57600080fd5b5061021a6004803603810190610215919061308b565b6107b4565b6040516102279190613628565b60405180910390f35b34801561023c57600080fd5b5061024561081b565b6040516102529190613643565b60405180910390f35b34801561026757600080fd5b50610282600480360381019061027d919061311e565b6108ad565b60405161028f919061359f565b60405180910390f35b3480156102a457600080fd5b506102bf60048036038101906102ba919061304f565b610932565b005b3480156102cd57600080fd5b506102e860048036038101906102e391906130dd565b610a4a565b005b3480156102f657600080fd5b506102ff610ae0565b60405161030c9190613905565b60405180910390f35b34801561032157600080fd5b5061032a610af1565b6040516103379190613628565b60405180910390f35b34801561034c57600080fd5b5061036760048036038101906103629190612f49565b610b04565b005b34801561037557600080fd5b5061037e610b64565b005b34801561038c57600080fd5b506103a760048036038101906103a2919061304f565b610bfd565b6040516103b49190613905565b60405180910390f35b3480156103c957600080fd5b506103d2610c58565b6040516103df9190613905565b60405180910390f35b3480156103f457600080fd5b506103fd610c63565b005b610407610cfc565b005b34801561041557600080fd5b50610430600480360381019061042b9190612f49565b610db8565b005b34801561043e57600080fd5b506104596004803603810190610454919061311e565b610dd8565b6040516104669190613905565b60405180910390f35b34801561047b57600080fd5b506104966004803603810190610491919061304f565b610dfb565b005b3480156104a457600080fd5b506104bf60048036038101906104ba91906130dd565b610f26565b005b3480156104cd57600080fd5b506104e860048036038101906104e3919061311e565b610fae565b6040516104f5919061359f565b60405180910390f35b34801561050a57600080fd5b50610513610fe5565b6040516105209190613905565b60405180910390f35b34801561053557600080fd5b5061053e610feb565b60405161054b9190613643565b60405180910390f35b34801561056057600080fd5b5061057b60048036038101906105769190612ee4565b61107d565b6040516105889190613905565b60405180910390f35b34801561059d57600080fd5b506105a661113c565b005b3480156105b457600080fd5b506105cf60048036038101906105ca9190612ee4565b611279565b6040516105dc9190613606565b60405180910390f35b3480156105f157600080fd5b506105fa6113f5565b604051610607919061359f565b60405180910390f35b34801561061c57600080fd5b5061062561141f565b6040516106329190613643565b60405180910390f35b34801561064757600080fd5b50610662600480360381019061065d9190613013565b6114b1565b005b34801561067057600080fd5b5061068b60048036038101906106869190612f98565b611632565b005b34801561069957600080fd5b506106b460048036038101906106af919061311e565b611694565b6040516106c19190613643565b60405180910390f35b6106e460048036038101906106df919061311e565b611807565b005b3480156106f257600080fd5b5061070d6004803603810190610708919061311e565b611995565b60405161071a9190613905565b60405180910390f35b34801561072f57600080fd5b5061074a60048036038101906107459190612f0d565b6119cb565b6040516107579190613628565b60405180910390f35b34801561076c57600080fd5b50610775611a5f565b6040516107829190613643565b60405180910390f35b34801561079757600080fd5b506107b260048036038101906107ad9190612ee4565b611aed565b005b6000806000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060009054906101000a900460ff169050919050565b60606006805461082a90613bee565b80601f016020809104026020016040519081016040528092919081815260200182805461085690613bee565b80156108a35780601f10610878576101008083540402835291602001916108a3565b820191906000526020600020905b81548152906001019060200180831161088657829003601f168201915b5050505050905090565b60006108b882611c99565b6108f7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ee90613805565b60405180910390fd5b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600061093d82610fae565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156109ae576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109a590613885565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166109cd611cb6565b73ffffffffffffffffffffffffffffffffffffffff1614806109fc57506109fb816109f6611cb6565b6119cb565b5b610a3b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a3290613745565b60405180910390fd5b610a458383611cbe565b505050565b610a52611cb6565b73ffffffffffffffffffffffffffffffffffffffff16610a706113f5565b73ffffffffffffffffffffffffffffffffffffffff1614610ac6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610abd90613825565b60405180910390fd5b80600b9080519060200190610adc929190612d08565b5050565b6000610aec6002611d77565b905090565b600a60149054906101000a900460ff1681565b610b15610b0f611cb6565b82611d8c565b610b54576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b4b906138e5565b60405180910390fd5b610b5f838383611e6a565b505050565b610b6c611cb6565b73ffffffffffffffffffffffffffffffffffffffff16610b8a6113f5565b73ffffffffffffffffffffffffffffffffffffffff1614610be0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bd790613825565b60405180910390fd5b6000600a60146101000a81548160ff021916908315150217905550565b6000610c5082600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061208190919063ffffffff16565b905092915050565b666a94d74f43000081565b610c6b611cb6565b73ffffffffffffffffffffffffffffffffffffffff16610c896113f5565b73ffffffffffffffffffffffffffffffffffffffff1614610cdf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cd690613825565b60405180910390fd5b6001600a60146101000a81548160ff021916908315150217905550565b610d04611cb6565b73ffffffffffffffffffffffffffffffffffffffff16610d226113f5565b73ffffffffffffffffffffffffffffffffffffffff1614610d78576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d6f90613825565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f19350505050610db657600080fd5b565b610dd383838360405180602001604052806000815250611632565b505050565b600080610def83600261209b90919063ffffffff16565b50905080915050919050565b610e03611cb6565b73ffffffffffffffffffffffffffffffffffffffff16610e216113f5565b73ffffffffffffffffffffffffffffffffffffffff1614610e77576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e6e90613825565b60405180910390fd5b6000610e81610ae0565b905060f08110610e9057600080fd5b60f0610eac83610e9e610ae0565b6120c790919063ffffffff16565b1115610eed576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ee4906138c5565b60405180910390fd5b60005b82811015610f2057610f0d848284610f089190613a23565b6120dd565b8080610f1890613c51565b915050610ef0565b50505050565b610f2e611cb6565b73ffffffffffffffffffffffffffffffffffffffff16610f4c6113f5565b73ffffffffffffffffffffffffffffffffffffffff1614610fa2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f9990613825565b60405180910390fd5b610fab816120fb565b50565b6000610fde8260405180606001604052806029815260200161438c6029913960026121159092919063ffffffff16565b9050919050565b61356281565b606060098054610ffa90613bee565b80601f016020809104026020016040519081016040528092919081815260200182805461102690613bee565b80156110735780601f1061104857610100808354040283529160200191611073565b820191906000526020600020905b81548152906001019060200180831161105657829003601f168201915b5050505050905090565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156110ee576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110e590613765565b60405180910390fd5b611135600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020612134565b9050919050565b611144611cb6565b73ffffffffffffffffffffffffffffffffffffffff166111626113f5565b73ffffffffffffffffffffffffffffffffffffffff16146111b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111af90613825565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a36000600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b606060006112868361107d565b9050600081141561130957600067ffffffffffffffff8111156112d2577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280602002602001820160405280156113005781602001602082028036833780820191505090505b509150506113f0565b60008167ffffffffffffffff81111561134b577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280602002602001820160405280156113795781602001602082028036833780820191505090505b50905060005b828110156113e9576113918582610bfd565b8282815181106113ca577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101818152505080806113e190613c51565b91505061137f565b8193505050505b919050565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60606007805461142e90613bee565b80601f016020809104026020016040519081016040528092919081815260200182805461145a90613bee565b80156114a75780601f1061147c576101008083540402835291602001916114a7565b820191906000526020600020905b81548152906001019060200180831161148a57829003601f168201915b5050505050905090565b6114b9611cb6565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611527576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161151e90613705565b60405180910390fd5b8060056000611534611cb6565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff166115e1611cb6565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516116269190613628565b60405180910390a35050565b61164361163d611cb6565b83611d8c565b611682576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611679906138e5565b60405180910390fd5b61168e84848484612149565b50505050565b606061169f82611c99565b6116de576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116d590613865565b60405180910390fd5b60006008600084815260200190815260200160002080546116fe90613bee565b80601f016020809104026020016040519081016040528092919081815260200182805461172a90613bee565b80156117775780601f1061174c57610100808354040283529160200191611777565b820191906000526020600020905b81548152906001019060200180831161175a57829003601f168201915b505050505090506000611788610feb565b905060008151141561179e578192505050611802565b6000825111156117d35780826040516020016117bb92919061357b565b60405160208183030381529060405292505050611802565b806117dd856121a5565b6040516020016117ee92919061357b565b604051602081830303815290604052925050505b919050565b613562611812610ae0565b10611852576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611849906138a5565b60405180910390fd5b600081118015611863575060148111155b6118a2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611899906137c5565b60405180910390fd5b6135626118bf826118b1610ae0565b6120c790919063ffffffff16565b1115611900576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118f7906138c5565b60405180910390fd5b61191a81666a94d74f43000061235290919063ffffffff16565b34101561195c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161195390613785565b60405180910390fd5b60005b81811015611991576000611971610ae0565b905061197d33826120dd565b50808061198990613c51565b91505061195f565b5050565b600080600090506135626119a7610ae0565b116119c25782666a94d74f4300006119bf9190613aaa565b90505b80915050919050565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b600b8054611a6c90613bee565b80601f0160208091040260200160405190810160405280929190818152602001828054611a9890613bee565b8015611ae55780601f10611aba57610100808354040283529160200191611ae5565b820191906000526020600020905b815481529060010190602001808311611ac857829003601f168201915b505050505081565b611af5611cb6565b73ffffffffffffffffffffffffffffffffffffffff16611b136113f5565b73ffffffffffffffffffffffffffffffffffffffff1614611b69576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b6090613825565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611bd9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bd0906136a5565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000611caf82600261236890919063ffffffff16565b9050919050565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16611d3183610fae565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000611d8582600001612382565b9050919050565b6000611d9782611c99565b611dd6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611dcd90613725565b60405180910390fd5b6000611de183610fae565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480611e5057508373ffffffffffffffffffffffffffffffffffffffff16611e38846108ad565b73ffffffffffffffffffffffffffffffffffffffff16145b80611e615750611e6081856119cb565b5b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff16611e8a82610fae565b73ffffffffffffffffffffffffffffffffffffffff1614611ee0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ed790613845565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611f50576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f47906136e5565b60405180910390fd5b611f5b838383612393565b611f66600082611cbe565b611fb781600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061239890919063ffffffff16565b5061200981600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206123b290919063ffffffff16565b50612020818360026123cc9092919063ffffffff16565b50808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b60006120908360000183612401565b60001c905092915050565b6000806000806120ae866000018661249b565b915091508160001c8160001c9350935050509250929050565b600081836120d59190613a23565b905092915050565b6120f782826040518060200160405280600081525061254b565b5050565b8060099080519060200190612111929190612d08565b5050565b6000612128846000018460001b846125a6565b60001c90509392505050565b60006121428260000161266d565b9050919050565b612154848484611e6a565b6121608484848461267e565b61219f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161219690613685565b60405180910390fd5b50505050565b606060008214156121ed576040518060400160405280600181526020017f3000000000000000000000000000000000000000000000000000000000000000815250905061234d565b600082905060005b6000821461221f57808061220890613c51565b915050600a826122189190613a79565b91506121f5565b60008167ffffffffffffffff811115612261577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280601f01601f1916602001820160405280156122935781602001600182028036833780820191505090505b5090505b60008514612346576001826122ac9190613b04565b9150600a856122bb9190613c9a565b60306122c79190613a23565b60f81b818381518110612303577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a8561233f9190613a79565b9450612297565b8093505050505b919050565b600081836123609190613aaa565b905092915050565b600061237a836000018360001b612815565b905092915050565b600081600001805490509050919050565b505050565b60006123aa836000018360001b612838565b905092915050565b60006123c4836000018360001b6129c2565b905092915050565b60006123f8846000018460001b8473ffffffffffffffffffffffffffffffffffffffff1660001b612a32565b90509392505050565b60008183600001805490501161244c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161244390613665565b60405180910390fd5b826000018281548110612488577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154905092915050565b600080828460000180549050116124e7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124de906137a5565b60405180910390fd5b6000846000018481548110612525577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b906000526020600020906002020190508060000154816001015492509250509250929050565b6125558383612b44565b612562600084848461267e565b6125a1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161259890613685565b60405180910390fd5b505050565b60008084600101600085815260200190815260200160002054905060008114158390612608576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125ff9190613643565b60405180910390fd5b508460000160018261261a9190613b04565b81548110612651577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000209060020201600101549150509392505050565b600081600001805490509050919050565b600061269f8473ffffffffffffffffffffffffffffffffffffffff16612cd2565b15612808578373ffffffffffffffffffffffffffffffffffffffff1663150b7a026126c8611cb6565b8786866040518563ffffffff1660e01b81526004016126ea94939291906135ba565b602060405180830381600087803b15801561270457600080fd5b505af192505050801561273557506040513d601f19601f8201168201806040525081019061273291906130b4565b60015b6127b8573d8060008114612765576040519150601f19603f3d011682016040523d82523d6000602084013e61276a565b606091505b506000815114156127b0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127a790613685565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161491505061280d565b600190505b949350505050565b600080836001016000848152602001908152602001600020541415905092915050565b600080836001016000848152602001908152602001600020549050600081146129b657600060018261286a9190613b04565b90506000600186600001805490506128829190613b04565b905060008660000182815481106128c2577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b906000526020600020015490508087600001848154811061290c577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002001819055506001836129279190613a23565b876001016000838152602001908152602001600020819055508660000180548061297a577f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600190038181906000526020600020016000905590558660010160008781526020019081526020016000206000905560019450505050506129bc565b60009150505b92915050565b60006129ce8383612ce5565b612a27578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050612a2c565b600090505b92915050565b6000808460010160008581526020019081526020016000205490506000811415612ad957846000016040518060400160405280868152602001858152509080600181540180825580915050600190039060005260206000209060020201600090919091909150600082015181600001556020820151816001015550508460000180549050856001016000868152602001908152602001600020819055506001915050612b3d565b8285600001600183612aeb9190613b04565b81548110612b22577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002090600202016001018190555060009150505b9392505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612bb4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612bab906137e5565b60405180910390fd5b612bbd81611c99565b15612bfd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612bf4906136c5565b60405180910390fd5b612c0960008383612393565b612c5a81600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206123b290919063ffffffff16565b50612c71818360026123cc9092919063ffffffff16565b50808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050565b600080823b905060008111915050919050565b600080836001016000848152602001908152602001600020541415905092915050565b828054612d1490613bee565b90600052602060002090601f016020900481019282612d365760008555612d7d565b82601f10612d4f57805160ff1916838001178555612d7d565b82800160010185558215612d7d579182015b82811115612d7c578251825591602001919060010190612d61565b5b509050612d8a9190612d8e565b5090565b5b80821115612da7576000816000905550600101612d8f565b5090565b6000612dbe612db984613945565b613920565b905082815260208101848484011115612dd657600080fd5b612de1848285613bac565b509392505050565b6000612dfc612df784613976565b613920565b905082815260208101848484011115612e1457600080fd5b612e1f848285613bac565b509392505050565b600081359050612e368161432f565b92915050565b600081359050612e4b81614346565b92915050565b600081359050612e608161435d565b92915050565b600081519050612e758161435d565b92915050565b600082601f830112612e8c57600080fd5b8135612e9c848260208601612dab565b91505092915050565b600082601f830112612eb657600080fd5b8135612ec6848260208601612de9565b91505092915050565b600081359050612ede81614374565b92915050565b600060208284031215612ef657600080fd5b6000612f0484828501612e27565b91505092915050565b60008060408385031215612f2057600080fd5b6000612f2e85828601612e27565b9250506020612f3f85828601612e27565b9150509250929050565b600080600060608486031215612f5e57600080fd5b6000612f6c86828701612e27565b9350506020612f7d86828701612e27565b9250506040612f8e86828701612ecf565b9150509250925092565b60008060008060808587031215612fae57600080fd5b6000612fbc87828801612e27565b9450506020612fcd87828801612e27565b9350506040612fde87828801612ecf565b925050606085013567ffffffffffffffff811115612ffb57600080fd5b61300787828801612e7b565b91505092959194509250565b6000806040838503121561302657600080fd5b600061303485828601612e27565b925050602061304585828601612e3c565b9150509250929050565b6000806040838503121561306257600080fd5b600061307085828601612e27565b925050602061308185828601612ecf565b9150509250929050565b60006020828403121561309d57600080fd5b60006130ab84828501612e51565b91505092915050565b6000602082840312156130c657600080fd5b60006130d484828501612e66565b91505092915050565b6000602082840312156130ef57600080fd5b600082013567ffffffffffffffff81111561310957600080fd5b61311584828501612ea5565b91505092915050565b60006020828403121561313057600080fd5b600061313e84828501612ecf565b91505092915050565b6000613153838361355d565b60208301905092915050565b61316881613b38565b82525050565b6000613179826139b7565b61318381856139e5565b935061318e836139a7565b8060005b838110156131bf5781516131a68882613147565b97506131b1836139d8565b925050600181019050613192565b5085935050505092915050565b6131d581613b4a565b82525050565b60006131e6826139c2565b6131f081856139f6565b9350613200818560208601613bbb565b61320981613d87565b840191505092915050565b600061321f826139cd565b6132298185613a07565b9350613239818560208601613bbb565b61324281613d87565b840191505092915050565b6000613258826139cd565b6132628185613a18565b9350613272818560208601613bbb565b80840191505092915050565b600061328b602283613a07565b915061329682613d98565b604082019050919050565b60006132ae603283613a07565b91506132b982613de7565b604082019050919050565b60006132d1602683613a07565b91506132dc82613e36565b604082019050919050565b60006132f4601c83613a07565b91506132ff82613e85565b602082019050919050565b6000613317602483613a07565b915061332282613eae565b604082019050919050565b600061333a601983613a07565b915061334582613efd565b602082019050919050565b600061335d602c83613a07565b915061336882613f26565b604082019050919050565b6000613380603883613a07565b915061338b82613f75565b604082019050919050565b60006133a3602a83613a07565b91506133ae82613fc4565b604082019050919050565b60006133c6602383613a07565b91506133d182614013565b604082019050919050565b60006133e9602283613a07565b91506133f482614062565b604082019050919050565b600061340c603683613a07565b9150613417826140b1565b604082019050919050565b600061342f602083613a07565b915061343a82614100565b602082019050919050565b6000613452602c83613a07565b915061345d82614129565b604082019050919050565b6000613475602083613a07565b915061348082614178565b602082019050919050565b6000613498602983613a07565b91506134a3826141a1565b604082019050919050565b60006134bb602f83613a07565b91506134c6826141f0565b604082019050919050565b60006134de602183613a07565b91506134e98261423f565b604082019050919050565b6000613501601683613a07565b915061350c8261428e565b602082019050919050565b6000613524601c83613a07565b915061352f826142b7565b602082019050919050565b6000613547603183613a07565b9150613552826142e0565b604082019050919050565b61356681613ba2565b82525050565b61357581613ba2565b82525050565b6000613587828561324d565b9150613593828461324d565b91508190509392505050565b60006020820190506135b4600083018461315f565b92915050565b60006080820190506135cf600083018761315f565b6135dc602083018661315f565b6135e9604083018561356c565b81810360608301526135fb81846131db565b905095945050505050565b60006020820190508181036000830152613620818461316e565b905092915050565b600060208201905061363d60008301846131cc565b92915050565b6000602082019050818103600083015261365d8184613214565b905092915050565b6000602082019050818103600083015261367e8161327e565b9050919050565b6000602082019050818103600083015261369e816132a1565b9050919050565b600060208201905081810360008301526136be816132c4565b9050919050565b600060208201905081810360008301526136de816132e7565b9050919050565b600060208201905081810360008301526136fe8161330a565b9050919050565b6000602082019050818103600083015261371e8161332d565b9050919050565b6000602082019050818103600083015261373e81613350565b9050919050565b6000602082019050818103600083015261375e81613373565b9050919050565b6000602082019050818103600083015261377e81613396565b9050919050565b6000602082019050818103600083015261379e816133b9565b9050919050565b600060208201905081810360008301526137be816133dc565b9050919050565b600060208201905081810360008301526137de816133ff565b9050919050565b600060208201905081810360008301526137fe81613422565b9050919050565b6000602082019050818103600083015261381e81613445565b9050919050565b6000602082019050818103600083015261383e81613468565b9050919050565b6000602082019050818103600083015261385e8161348b565b9050919050565b6000602082019050818103600083015261387e816134ae565b9050919050565b6000602082019050818103600083015261389e816134d1565b9050919050565b600060208201905081810360008301526138be816134f4565b9050919050565b600060208201905081810360008301526138de81613517565b9050919050565b600060208201905081810360008301526138fe8161353a565b9050919050565b600060208201905061391a600083018461356c565b92915050565b600061392a61393b565b90506139368282613c20565b919050565b6000604051905090565b600067ffffffffffffffff8211156139605761395f613d58565b5b61396982613d87565b9050602081019050919050565b600067ffffffffffffffff82111561399157613990613d58565b5b61399a82613d87565b9050602081019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b6000613a2e82613ba2565b9150613a3983613ba2565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115613a6e57613a6d613ccb565b5b828201905092915050565b6000613a8482613ba2565b9150613a8f83613ba2565b925082613a9f57613a9e613cfa565b5b828204905092915050565b6000613ab582613ba2565b9150613ac083613ba2565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615613af957613af8613ccb565b5b828202905092915050565b6000613b0f82613ba2565b9150613b1a83613ba2565b925082821015613b2d57613b2c613ccb565b5b828203905092915050565b6000613b4382613b82565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b83811015613bd9578082015181840152602081019050613bbe565b83811115613be8576000848401525b50505050565b60006002820490506001821680613c0657607f821691505b60208210811415613c1a57613c19613d29565b5b50919050565b613c2982613d87565b810181811067ffffffffffffffff82111715613c4857613c47613d58565b5b80604052505050565b6000613c5c82613ba2565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415613c8f57613c8e613ccb565b5b600182019050919050565b6000613ca582613ba2565b9150613cb083613ba2565b925082613cc057613cbf613cfa565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b7f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e60008201527f6473000000000000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b7f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860008201527f697374656e7420746f6b656e0000000000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760008201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000602082015250565b7f4552433732313a2062616c616e636520717565727920666f7220746865207a6560008201527f726f206164647265737300000000000000000000000000000000000000000000602082015250565b7f45746865722076616c75652073656e742069732062656c6f772074686520707260008201527f6963650000000000000000000000000000000000000000000000000000000000602082015250565b7f456e756d657261626c654d61703a20696e646578206f7574206f6620626f756e60008201527f6473000000000000000000000000000000000000000000000000000000000000602082015250565b7f596f752063616e2061646f7074206d696e696d756d20312c206d6178696d756d60008201527f20323020556e6974656420556e696f6e2050756e6b7300000000000000000000602082015250565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b7f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860008201527f697374656e7420746f6b656e0000000000000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960008201527f73206e6f74206f776e0000000000000000000000000000000000000000000000602082015250565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b7f53616c652068617320616c726561647920656e64656400000000000000000000600082015250565b7f45786365656473204d41585f554e4954454450554e4b53554e494f4e00000000600082015250565b7f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60008201527f776e6572206e6f7220617070726f766564000000000000000000000000000000602082015250565b61433881613b38565b811461434357600080fd5b50565b61434f81613b4a565b811461435a57600080fd5b50565b61436681613b56565b811461437157600080fd5b50565b61437d81613ba2565b811461438857600080fd5b5056fe4552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656ea26469706673582212209d5860775cb3748c6459447482495126e0a093c9dc04c6ab187ea7678abef25e64736f6c63430008040033

Deployed Bytecode

0x6080604052600436106101ee5760003560e01c806355f804b31161010d57806395d89b41116100a0578063d96a094a1161006f578063d96a094a146106ca578063e7572230146106e6578063e985e9c514610723578063f0c9dc6014610760578063f2fde38b1461078b576101ee565b806395d89b4114610610578063a22cb4651461063b578063b88d4fde14610664578063c87b56dd1461068d576101ee565b806370a08231116100dc57806370a0823114610554578063715018a6146105915780638462151c146105a85780638da5cb5b146105e5576101ee565b806355f804b3146104985780636352211e146104c1578063648cfea2146104fe5780636c0360eb14610529576101ee565b80632808c92c116101855780633ccfd60b116101545780633ccfd60b146103ff57806342842e0e146104095780634f6ccce7146104325780635433f23c1461046f576101ee565b80632808c92c146103695780632f745c59146103805780633486ad83146103bd57806334d84c7b146103e8576101ee565b806310969523116101c157806310969523146102c157806318160ddd146102ea5780631c8b232d1461031557806323b872dd14610340576101ee565b806301ffc9a7146101f357806306fdde0314610230578063081812fc1461025b578063095ea7b314610298575b600080fd5b3480156101ff57600080fd5b5061021a6004803603810190610215919061308b565b6107b4565b6040516102279190613628565b60405180910390f35b34801561023c57600080fd5b5061024561081b565b6040516102529190613643565b60405180910390f35b34801561026757600080fd5b50610282600480360381019061027d919061311e565b6108ad565b60405161028f919061359f565b60405180910390f35b3480156102a457600080fd5b506102bf60048036038101906102ba919061304f565b610932565b005b3480156102cd57600080fd5b506102e860048036038101906102e391906130dd565b610a4a565b005b3480156102f657600080fd5b506102ff610ae0565b60405161030c9190613905565b60405180910390f35b34801561032157600080fd5b5061032a610af1565b6040516103379190613628565b60405180910390f35b34801561034c57600080fd5b5061036760048036038101906103629190612f49565b610b04565b005b34801561037557600080fd5b5061037e610b64565b005b34801561038c57600080fd5b506103a760048036038101906103a2919061304f565b610bfd565b6040516103b49190613905565b60405180910390f35b3480156103c957600080fd5b506103d2610c58565b6040516103df9190613905565b60405180910390f35b3480156103f457600080fd5b506103fd610c63565b005b610407610cfc565b005b34801561041557600080fd5b50610430600480360381019061042b9190612f49565b610db8565b005b34801561043e57600080fd5b506104596004803603810190610454919061311e565b610dd8565b6040516104669190613905565b60405180910390f35b34801561047b57600080fd5b506104966004803603810190610491919061304f565b610dfb565b005b3480156104a457600080fd5b506104bf60048036038101906104ba91906130dd565b610f26565b005b3480156104cd57600080fd5b506104e860048036038101906104e3919061311e565b610fae565b6040516104f5919061359f565b60405180910390f35b34801561050a57600080fd5b50610513610fe5565b6040516105209190613905565b60405180910390f35b34801561053557600080fd5b5061053e610feb565b60405161054b9190613643565b60405180910390f35b34801561056057600080fd5b5061057b60048036038101906105769190612ee4565b61107d565b6040516105889190613905565b60405180910390f35b34801561059d57600080fd5b506105a661113c565b005b3480156105b457600080fd5b506105cf60048036038101906105ca9190612ee4565b611279565b6040516105dc9190613606565b60405180910390f35b3480156105f157600080fd5b506105fa6113f5565b604051610607919061359f565b60405180910390f35b34801561061c57600080fd5b5061062561141f565b6040516106329190613643565b60405180910390f35b34801561064757600080fd5b50610662600480360381019061065d9190613013565b6114b1565b005b34801561067057600080fd5b5061068b60048036038101906106869190612f98565b611632565b005b34801561069957600080fd5b506106b460048036038101906106af919061311e565b611694565b6040516106c19190613643565b60405180910390f35b6106e460048036038101906106df919061311e565b611807565b005b3480156106f257600080fd5b5061070d6004803603810190610708919061311e565b611995565b60405161071a9190613905565b60405180910390f35b34801561072f57600080fd5b5061074a60048036038101906107459190612f0d565b6119cb565b6040516107579190613628565b60405180910390f35b34801561076c57600080fd5b50610775611a5f565b6040516107829190613643565b60405180910390f35b34801561079757600080fd5b506107b260048036038101906107ad9190612ee4565b611aed565b005b6000806000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060009054906101000a900460ff169050919050565b60606006805461082a90613bee565b80601f016020809104026020016040519081016040528092919081815260200182805461085690613bee565b80156108a35780601f10610878576101008083540402835291602001916108a3565b820191906000526020600020905b81548152906001019060200180831161088657829003601f168201915b5050505050905090565b60006108b882611c99565b6108f7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ee90613805565b60405180910390fd5b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600061093d82610fae565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156109ae576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109a590613885565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166109cd611cb6565b73ffffffffffffffffffffffffffffffffffffffff1614806109fc57506109fb816109f6611cb6565b6119cb565b5b610a3b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a3290613745565b60405180910390fd5b610a458383611cbe565b505050565b610a52611cb6565b73ffffffffffffffffffffffffffffffffffffffff16610a706113f5565b73ffffffffffffffffffffffffffffffffffffffff1614610ac6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610abd90613825565b60405180910390fd5b80600b9080519060200190610adc929190612d08565b5050565b6000610aec6002611d77565b905090565b600a60149054906101000a900460ff1681565b610b15610b0f611cb6565b82611d8c565b610b54576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b4b906138e5565b60405180910390fd5b610b5f838383611e6a565b505050565b610b6c611cb6565b73ffffffffffffffffffffffffffffffffffffffff16610b8a6113f5565b73ffffffffffffffffffffffffffffffffffffffff1614610be0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bd790613825565b60405180910390fd5b6000600a60146101000a81548160ff021916908315150217905550565b6000610c5082600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061208190919063ffffffff16565b905092915050565b666a94d74f43000081565b610c6b611cb6565b73ffffffffffffffffffffffffffffffffffffffff16610c896113f5565b73ffffffffffffffffffffffffffffffffffffffff1614610cdf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cd690613825565b60405180910390fd5b6001600a60146101000a81548160ff021916908315150217905550565b610d04611cb6565b73ffffffffffffffffffffffffffffffffffffffff16610d226113f5565b73ffffffffffffffffffffffffffffffffffffffff1614610d78576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d6f90613825565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f19350505050610db657600080fd5b565b610dd383838360405180602001604052806000815250611632565b505050565b600080610def83600261209b90919063ffffffff16565b50905080915050919050565b610e03611cb6565b73ffffffffffffffffffffffffffffffffffffffff16610e216113f5565b73ffffffffffffffffffffffffffffffffffffffff1614610e77576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e6e90613825565b60405180910390fd5b6000610e81610ae0565b905060f08110610e9057600080fd5b60f0610eac83610e9e610ae0565b6120c790919063ffffffff16565b1115610eed576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ee4906138c5565b60405180910390fd5b60005b82811015610f2057610f0d848284610f089190613a23565b6120dd565b8080610f1890613c51565b915050610ef0565b50505050565b610f2e611cb6565b73ffffffffffffffffffffffffffffffffffffffff16610f4c6113f5565b73ffffffffffffffffffffffffffffffffffffffff1614610fa2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f9990613825565b60405180910390fd5b610fab816120fb565b50565b6000610fde8260405180606001604052806029815260200161438c6029913960026121159092919063ffffffff16565b9050919050565b61356281565b606060098054610ffa90613bee565b80601f016020809104026020016040519081016040528092919081815260200182805461102690613bee565b80156110735780601f1061104857610100808354040283529160200191611073565b820191906000526020600020905b81548152906001019060200180831161105657829003601f168201915b5050505050905090565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156110ee576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110e590613765565b60405180910390fd5b611135600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020612134565b9050919050565b611144611cb6565b73ffffffffffffffffffffffffffffffffffffffff166111626113f5565b73ffffffffffffffffffffffffffffffffffffffff16146111b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111af90613825565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a36000600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b606060006112868361107d565b9050600081141561130957600067ffffffffffffffff8111156112d2577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280602002602001820160405280156113005781602001602082028036833780820191505090505b509150506113f0565b60008167ffffffffffffffff81111561134b577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280602002602001820160405280156113795781602001602082028036833780820191505090505b50905060005b828110156113e9576113918582610bfd565b8282815181106113ca577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101818152505080806113e190613c51565b91505061137f565b8193505050505b919050565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60606007805461142e90613bee565b80601f016020809104026020016040519081016040528092919081815260200182805461145a90613bee565b80156114a75780601f1061147c576101008083540402835291602001916114a7565b820191906000526020600020905b81548152906001019060200180831161148a57829003601f168201915b5050505050905090565b6114b9611cb6565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611527576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161151e90613705565b60405180910390fd5b8060056000611534611cb6565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff166115e1611cb6565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516116269190613628565b60405180910390a35050565b61164361163d611cb6565b83611d8c565b611682576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611679906138e5565b60405180910390fd5b61168e84848484612149565b50505050565b606061169f82611c99565b6116de576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116d590613865565b60405180910390fd5b60006008600084815260200190815260200160002080546116fe90613bee565b80601f016020809104026020016040519081016040528092919081815260200182805461172a90613bee565b80156117775780601f1061174c57610100808354040283529160200191611777565b820191906000526020600020905b81548152906001019060200180831161175a57829003601f168201915b505050505090506000611788610feb565b905060008151141561179e578192505050611802565b6000825111156117d35780826040516020016117bb92919061357b565b60405160208183030381529060405292505050611802565b806117dd856121a5565b6040516020016117ee92919061357b565b604051602081830303815290604052925050505b919050565b613562611812610ae0565b10611852576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611849906138a5565b60405180910390fd5b600081118015611863575060148111155b6118a2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611899906137c5565b60405180910390fd5b6135626118bf826118b1610ae0565b6120c790919063ffffffff16565b1115611900576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118f7906138c5565b60405180910390fd5b61191a81666a94d74f43000061235290919063ffffffff16565b34101561195c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161195390613785565b60405180910390fd5b60005b81811015611991576000611971610ae0565b905061197d33826120dd565b50808061198990613c51565b91505061195f565b5050565b600080600090506135626119a7610ae0565b116119c25782666a94d74f4300006119bf9190613aaa565b90505b80915050919050565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b600b8054611a6c90613bee565b80601f0160208091040260200160405190810160405280929190818152602001828054611a9890613bee565b8015611ae55780601f10611aba57610100808354040283529160200191611ae5565b820191906000526020600020905b815481529060010190602001808311611ac857829003601f168201915b505050505081565b611af5611cb6565b73ffffffffffffffffffffffffffffffffffffffff16611b136113f5565b73ffffffffffffffffffffffffffffffffffffffff1614611b69576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b6090613825565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611bd9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bd0906136a5565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000611caf82600261236890919063ffffffff16565b9050919050565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16611d3183610fae565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000611d8582600001612382565b9050919050565b6000611d9782611c99565b611dd6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611dcd90613725565b60405180910390fd5b6000611de183610fae565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480611e5057508373ffffffffffffffffffffffffffffffffffffffff16611e38846108ad565b73ffffffffffffffffffffffffffffffffffffffff16145b80611e615750611e6081856119cb565b5b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff16611e8a82610fae565b73ffffffffffffffffffffffffffffffffffffffff1614611ee0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ed790613845565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611f50576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f47906136e5565b60405180910390fd5b611f5b838383612393565b611f66600082611cbe565b611fb781600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061239890919063ffffffff16565b5061200981600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206123b290919063ffffffff16565b50612020818360026123cc9092919063ffffffff16565b50808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b60006120908360000183612401565b60001c905092915050565b6000806000806120ae866000018661249b565b915091508160001c8160001c9350935050509250929050565b600081836120d59190613a23565b905092915050565b6120f782826040518060200160405280600081525061254b565b5050565b8060099080519060200190612111929190612d08565b5050565b6000612128846000018460001b846125a6565b60001c90509392505050565b60006121428260000161266d565b9050919050565b612154848484611e6a565b6121608484848461267e565b61219f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161219690613685565b60405180910390fd5b50505050565b606060008214156121ed576040518060400160405280600181526020017f3000000000000000000000000000000000000000000000000000000000000000815250905061234d565b600082905060005b6000821461221f57808061220890613c51565b915050600a826122189190613a79565b91506121f5565b60008167ffffffffffffffff811115612261577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280601f01601f1916602001820160405280156122935781602001600182028036833780820191505090505b5090505b60008514612346576001826122ac9190613b04565b9150600a856122bb9190613c9a565b60306122c79190613a23565b60f81b818381518110612303577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a8561233f9190613a79565b9450612297565b8093505050505b919050565b600081836123609190613aaa565b905092915050565b600061237a836000018360001b612815565b905092915050565b600081600001805490509050919050565b505050565b60006123aa836000018360001b612838565b905092915050565b60006123c4836000018360001b6129c2565b905092915050565b60006123f8846000018460001b8473ffffffffffffffffffffffffffffffffffffffff1660001b612a32565b90509392505050565b60008183600001805490501161244c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161244390613665565b60405180910390fd5b826000018281548110612488577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154905092915050565b600080828460000180549050116124e7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124de906137a5565b60405180910390fd5b6000846000018481548110612525577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b906000526020600020906002020190508060000154816001015492509250509250929050565b6125558383612b44565b612562600084848461267e565b6125a1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161259890613685565b60405180910390fd5b505050565b60008084600101600085815260200190815260200160002054905060008114158390612608576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125ff9190613643565b60405180910390fd5b508460000160018261261a9190613b04565b81548110612651577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000209060020201600101549150509392505050565b600081600001805490509050919050565b600061269f8473ffffffffffffffffffffffffffffffffffffffff16612cd2565b15612808578373ffffffffffffffffffffffffffffffffffffffff1663150b7a026126c8611cb6565b8786866040518563ffffffff1660e01b81526004016126ea94939291906135ba565b602060405180830381600087803b15801561270457600080fd5b505af192505050801561273557506040513d601f19601f8201168201806040525081019061273291906130b4565b60015b6127b8573d8060008114612765576040519150601f19603f3d011682016040523d82523d6000602084013e61276a565b606091505b506000815114156127b0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127a790613685565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161491505061280d565b600190505b949350505050565b600080836001016000848152602001908152602001600020541415905092915050565b600080836001016000848152602001908152602001600020549050600081146129b657600060018261286a9190613b04565b90506000600186600001805490506128829190613b04565b905060008660000182815481106128c2577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b906000526020600020015490508087600001848154811061290c577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002001819055506001836129279190613a23565b876001016000838152602001908152602001600020819055508660000180548061297a577f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600190038181906000526020600020016000905590558660010160008781526020019081526020016000206000905560019450505050506129bc565b60009150505b92915050565b60006129ce8383612ce5565b612a27578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050612a2c565b600090505b92915050565b6000808460010160008581526020019081526020016000205490506000811415612ad957846000016040518060400160405280868152602001858152509080600181540180825580915050600190039060005260206000209060020201600090919091909150600082015181600001556020820151816001015550508460000180549050856001016000868152602001908152602001600020819055506001915050612b3d565b8285600001600183612aeb9190613b04565b81548110612b22577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002090600202016001018190555060009150505b9392505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612bb4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612bab906137e5565b60405180910390fd5b612bbd81611c99565b15612bfd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612bf4906136c5565b60405180910390fd5b612c0960008383612393565b612c5a81600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206123b290919063ffffffff16565b50612c71818360026123cc9092919063ffffffff16565b50808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050565b600080823b905060008111915050919050565b600080836001016000848152602001908152602001600020541415905092915050565b828054612d1490613bee565b90600052602060002090601f016020900481019282612d365760008555612d7d565b82601f10612d4f57805160ff1916838001178555612d7d565b82800160010185558215612d7d579182015b82811115612d7c578251825591602001919060010190612d61565b5b509050612d8a9190612d8e565b5090565b5b80821115612da7576000816000905550600101612d8f565b5090565b6000612dbe612db984613945565b613920565b905082815260208101848484011115612dd657600080fd5b612de1848285613bac565b509392505050565b6000612dfc612df784613976565b613920565b905082815260208101848484011115612e1457600080fd5b612e1f848285613bac565b509392505050565b600081359050612e368161432f565b92915050565b600081359050612e4b81614346565b92915050565b600081359050612e608161435d565b92915050565b600081519050612e758161435d565b92915050565b600082601f830112612e8c57600080fd5b8135612e9c848260208601612dab565b91505092915050565b600082601f830112612eb657600080fd5b8135612ec6848260208601612de9565b91505092915050565b600081359050612ede81614374565b92915050565b600060208284031215612ef657600080fd5b6000612f0484828501612e27565b91505092915050565b60008060408385031215612f2057600080fd5b6000612f2e85828601612e27565b9250506020612f3f85828601612e27565b9150509250929050565b600080600060608486031215612f5e57600080fd5b6000612f6c86828701612e27565b9350506020612f7d86828701612e27565b9250506040612f8e86828701612ecf565b9150509250925092565b60008060008060808587031215612fae57600080fd5b6000612fbc87828801612e27565b9450506020612fcd87828801612e27565b9350506040612fde87828801612ecf565b925050606085013567ffffffffffffffff811115612ffb57600080fd5b61300787828801612e7b565b91505092959194509250565b6000806040838503121561302657600080fd5b600061303485828601612e27565b925050602061304585828601612e3c565b9150509250929050565b6000806040838503121561306257600080fd5b600061307085828601612e27565b925050602061308185828601612ecf565b9150509250929050565b60006020828403121561309d57600080fd5b60006130ab84828501612e51565b91505092915050565b6000602082840312156130c657600080fd5b60006130d484828501612e66565b91505092915050565b6000602082840312156130ef57600080fd5b600082013567ffffffffffffffff81111561310957600080fd5b61311584828501612ea5565b91505092915050565b60006020828403121561313057600080fd5b600061313e84828501612ecf565b91505092915050565b6000613153838361355d565b60208301905092915050565b61316881613b38565b82525050565b6000613179826139b7565b61318381856139e5565b935061318e836139a7565b8060005b838110156131bf5781516131a68882613147565b97506131b1836139d8565b925050600181019050613192565b5085935050505092915050565b6131d581613b4a565b82525050565b60006131e6826139c2565b6131f081856139f6565b9350613200818560208601613bbb565b61320981613d87565b840191505092915050565b600061321f826139cd565b6132298185613a07565b9350613239818560208601613bbb565b61324281613d87565b840191505092915050565b6000613258826139cd565b6132628185613a18565b9350613272818560208601613bbb565b80840191505092915050565b600061328b602283613a07565b915061329682613d98565b604082019050919050565b60006132ae603283613a07565b91506132b982613de7565b604082019050919050565b60006132d1602683613a07565b91506132dc82613e36565b604082019050919050565b60006132f4601c83613a07565b91506132ff82613e85565b602082019050919050565b6000613317602483613a07565b915061332282613eae565b604082019050919050565b600061333a601983613a07565b915061334582613efd565b602082019050919050565b600061335d602c83613a07565b915061336882613f26565b604082019050919050565b6000613380603883613a07565b915061338b82613f75565b604082019050919050565b60006133a3602a83613a07565b91506133ae82613fc4565b604082019050919050565b60006133c6602383613a07565b91506133d182614013565b604082019050919050565b60006133e9602283613a07565b91506133f482614062565b604082019050919050565b600061340c603683613a07565b9150613417826140b1565b604082019050919050565b600061342f602083613a07565b915061343a82614100565b602082019050919050565b6000613452602c83613a07565b915061345d82614129565b604082019050919050565b6000613475602083613a07565b915061348082614178565b602082019050919050565b6000613498602983613a07565b91506134a3826141a1565b604082019050919050565b60006134bb602f83613a07565b91506134c6826141f0565b604082019050919050565b60006134de602183613a07565b91506134e98261423f565b604082019050919050565b6000613501601683613a07565b915061350c8261428e565b602082019050919050565b6000613524601c83613a07565b915061352f826142b7565b602082019050919050565b6000613547603183613a07565b9150613552826142e0565b604082019050919050565b61356681613ba2565b82525050565b61357581613ba2565b82525050565b6000613587828561324d565b9150613593828461324d565b91508190509392505050565b60006020820190506135b4600083018461315f565b92915050565b60006080820190506135cf600083018761315f565b6135dc602083018661315f565b6135e9604083018561356c565b81810360608301526135fb81846131db565b905095945050505050565b60006020820190508181036000830152613620818461316e565b905092915050565b600060208201905061363d60008301846131cc565b92915050565b6000602082019050818103600083015261365d8184613214565b905092915050565b6000602082019050818103600083015261367e8161327e565b9050919050565b6000602082019050818103600083015261369e816132a1565b9050919050565b600060208201905081810360008301526136be816132c4565b9050919050565b600060208201905081810360008301526136de816132e7565b9050919050565b600060208201905081810360008301526136fe8161330a565b9050919050565b6000602082019050818103600083015261371e8161332d565b9050919050565b6000602082019050818103600083015261373e81613350565b9050919050565b6000602082019050818103600083015261375e81613373565b9050919050565b6000602082019050818103600083015261377e81613396565b9050919050565b6000602082019050818103600083015261379e816133b9565b9050919050565b600060208201905081810360008301526137be816133dc565b9050919050565b600060208201905081810360008301526137de816133ff565b9050919050565b600060208201905081810360008301526137fe81613422565b9050919050565b6000602082019050818103600083015261381e81613445565b9050919050565b6000602082019050818103600083015261383e81613468565b9050919050565b6000602082019050818103600083015261385e8161348b565b9050919050565b6000602082019050818103600083015261387e816134ae565b9050919050565b6000602082019050818103600083015261389e816134d1565b9050919050565b600060208201905081810360008301526138be816134f4565b9050919050565b600060208201905081810360008301526138de81613517565b9050919050565b600060208201905081810360008301526138fe8161353a565b9050919050565b600060208201905061391a600083018461356c565b92915050565b600061392a61393b565b90506139368282613c20565b919050565b6000604051905090565b600067ffffffffffffffff8211156139605761395f613d58565b5b61396982613d87565b9050602081019050919050565b600067ffffffffffffffff82111561399157613990613d58565b5b61399a82613d87565b9050602081019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b6000613a2e82613ba2565b9150613a3983613ba2565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115613a6e57613a6d613ccb565b5b828201905092915050565b6000613a8482613ba2565b9150613a8f83613ba2565b925082613a9f57613a9e613cfa565b5b828204905092915050565b6000613ab582613ba2565b9150613ac083613ba2565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615613af957613af8613ccb565b5b828202905092915050565b6000613b0f82613ba2565b9150613b1a83613ba2565b925082821015613b2d57613b2c613ccb565b5b828203905092915050565b6000613b4382613b82565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b83811015613bd9578082015181840152602081019050613bbe565b83811115613be8576000848401525b50505050565b60006002820490506001821680613c0657607f821691505b60208210811415613c1a57613c19613d29565b5b50919050565b613c2982613d87565b810181811067ffffffffffffffff82111715613c4857613c47613d58565b5b80604052505050565b6000613c5c82613ba2565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415613c8f57613c8e613ccb565b5b600182019050919050565b6000613ca582613ba2565b9150613cb083613ba2565b925082613cc057613cbf613cfa565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b7f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e60008201527f6473000000000000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b7f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860008201527f697374656e7420746f6b656e0000000000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760008201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000602082015250565b7f4552433732313a2062616c616e636520717565727920666f7220746865207a6560008201527f726f206164647265737300000000000000000000000000000000000000000000602082015250565b7f45746865722076616c75652073656e742069732062656c6f772074686520707260008201527f6963650000000000000000000000000000000000000000000000000000000000602082015250565b7f456e756d657261626c654d61703a20696e646578206f7574206f6620626f756e60008201527f6473000000000000000000000000000000000000000000000000000000000000602082015250565b7f596f752063616e2061646f7074206d696e696d756d20312c206d6178696d756d60008201527f20323020556e6974656420556e696f6e2050756e6b7300000000000000000000602082015250565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b7f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860008201527f697374656e7420746f6b656e0000000000000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960008201527f73206e6f74206f776e0000000000000000000000000000000000000000000000602082015250565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b7f53616c652068617320616c726561647920656e64656400000000000000000000600082015250565b7f45786365656473204d41585f554e4954454450554e4b53554e494f4e00000000600082015250565b7f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60008201527f776e6572206e6f7220617070726f766564000000000000000000000000000000602082015250565b61433881613b38565b811461434357600080fd5b50565b61434f81613b4a565b811461435a57600080fd5b50565b61436681613b56565b811461437157600080fd5b50565b61437d81613ba2565b811461438857600080fd5b5056fe4552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656ea26469706673582212209d5860775cb3748c6459447482495126e0a093c9dc04c6ab187ea7678abef25e64736f6c63430008040033

Deployed Bytecode Sourcemap

65940:2755:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31683:150;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;43371:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;46157:221;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;45687:404;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;67793:116;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;45165:211;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;66087:33;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;47047:305;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;68475:79;;;;;;;;;;;;;:::i;:::-;;44927:162;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;66127:63;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;68385:78;;;;;;;;;;;;;:::i;:::-;;68566:120;;;:::i;:::-;;47423:151;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;45453:172;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;67917:345;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;68274:99;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;43127:177;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;66031:49;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;44746:97;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;42832:221;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;58230:148;;;;;;;;;;;;;:::i;:::-;;66318:540;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;57579:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;43540:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;46450:295;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;47645:285;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;43715:792;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;66869:609;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;67488:263;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;46816:164;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;66199:43;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;58533:244;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;31683:150;31768:4;31792:20;:33;31813:11;31792:33;;;;;;;;;;;;;;;;;;;;;;;;;;;31785:40;;31683:150;;;:::o;43371:100::-;43425:13;43458:5;43451:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43371:100;:::o;46157:221::-;46233:7;46261:16;46269:7;46261;:16::i;:::-;46253:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;46346:15;:24;46362:7;46346:24;;;;;;;;;;;;;;;;;;;;;46339:31;;46157:221;;;:::o;45687:404::-;45768:13;45784:23;45799:7;45784:14;:23::i;:::-;45768:39;;45832:5;45826:11;;:2;:11;;;;45818:57;;;;;;;;;;;;:::i;:::-;;;;;;;;;45912:5;45896:21;;:12;:10;:12::i;:::-;:21;;;:69;;;;45921:44;45945:5;45952:12;:10;:12::i;:::-;45921:23;:44::i;:::-;45896:69;45888:161;;;;;;;;;;;;:::i;:::-;;;;;;;;;46062:21;46071:2;46075:7;46062:8;:21::i;:::-;45687:404;;;:::o;67793:116::-;57810:12;:10;:12::i;:::-;57799:23;;:7;:5;:7::i;:::-;:23;;;57791:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;67896:5:::1;67869:24;:32;;;;;;;;;;;;:::i;:::-;;67793:116:::0;:::o;45165:211::-;45226:7;45347:21;:12;:19;:21::i;:::-;45340:28;;45165:211;:::o;66087:33::-;;;;;;;;;;;;;:::o;47047:305::-;47208:41;47227:12;:10;:12::i;:::-;47241:7;47208:18;:41::i;:::-;47200:103;;;;;;;;;;;;:::i;:::-;;;;;;;;;47316:28;47326:4;47332:2;47336:7;47316:9;:28::i;:::-;47047:305;;;:::o;68475:79::-;57810:12;:10;:12::i;:::-;57799:23;;:7;:5;:7::i;:::-;:23;;;57791:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;68541:5:::1;68524:14;;:22;;;;;;;;;;;;;;;;;;68475:79::o:0;44927:162::-;45024:7;45051:30;45075:5;45051:13;:20;45065:5;45051:20;;;;;;;;;;;;;;;:23;;:30;;;;:::i;:::-;45044:37;;44927:162;;;;:::o;66127:63::-;66173:17;66127:63;:::o;68385:78::-;57810:12;:10;:12::i;:::-;57799:23;;:7;:5;:7::i;:::-;:23;;;57791:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;68451:4:::1;68434:14;;:21;;;;;;;;;;;;;;;;;;68385:78::o:0;68566:120::-;57810:12;:10;:12::i;:::-;57799:23;;:7;:5;:7::i;:::-;:23;;;57791:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;68638:10:::1;68630:24;;:47;68655:21;68630:47;;;;;;;;;;;;;;;;;;;;;;;68622:56;;;::::0;::::1;;68566:120::o:0;47423:151::-;47527:39;47544:4;47550:2;47554:7;47527:39;;;;;;;;;;;;:16;:39::i;:::-;47423:151;;;:::o;45453:172::-;45528:7;45549:15;45570:22;45586:5;45570:12;:15;;:22;;;;:::i;:::-;45548:44;;;45610:7;45603:14;;;45453:172;;;:::o;67917:345::-;57810:12;:10;:12::i;:::-;57799:23;;:7;:5;:7::i;:::-;:23;;;57791:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;67996:14:::1;68013:13;:11;:13::i;:::-;67996:30;;68057:3;68045:9;:15;68037:24;;;::::0;::::1;;68111:3;68080:27;68098:8;68080:13;:11;:13::i;:::-;:17;;:27;;;;:::i;:::-;:34;;68072:75;;;;;;;;;;;;:::i;:::-;;;;;;;;;68163:6;68158:97;68179:8;68175:1;:12;68158:97;;;68209:34;68219:8;68241:1;68229:9;:13;;;;:::i;:::-;68209:9;:34::i;:::-;68189:3;;;;;:::i;:::-;;;;68158:97;;;;57870:1;67917:345:::0;;:::o;68274:99::-;57810:12;:10;:12::i;:::-;57799:23;;:7;:5;:7::i;:::-;:23;;;57791:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;68345:20:::1;68357:7;68345:11;:20::i;:::-;68274:99:::0;:::o;43127:177::-;43199:7;43226:70;43243:7;43226:70;;;;;;;;;;;;;;;;;:12;:16;;:70;;;;;:::i;:::-;43219:77;;43127:177;;;:::o;66031:49::-;66075:5;66031:49;:::o;44746:97::-;44794:13;44827:8;44820:15;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44746:97;:::o;42832:221::-;42904:7;42949:1;42932:19;;:5;:19;;;;42924:74;;;;;;;;;;;;:::i;:::-;;;;;;;;;43016:29;:13;:20;43030:5;43016:20;;;;;;;;;;;;;;;:27;:29::i;:::-;43009:36;;42832:221;;;:::o;58230:148::-;57810:12;:10;:12::i;:::-;57799:23;;:7;:5;:7::i;:::-;:23;;;57791:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;58337:1:::1;58300:40;;58321:6;;;;;;;;;;;58300:40;;;;;;;;;;;;58368:1;58351:6;;:19;;;;;;;;;;;;;;;;;;58230:148::o:0;66318:540::-;66379:16;66409:18;66430:17;66440:6;66430:9;:17::i;:::-;66409:38;;66476:1;66462:10;:15;66458:393;;;66553:1;66539:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66532:23;;;;;66458:393;66588:23;66628:10;66614:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66588:51;;66654:13;66682:130;66706:10;66698:5;:18;66682:130;;;66762:34;66782:6;66790:5;66762:19;:34::i;:::-;66746:6;66753:5;66746:13;;;;;;;;;;;;;;;;;;;;;:50;;;;;66718:7;;;;;:::i;:::-;;;;66682:130;;;66833:6;66826:13;;;;;66318:540;;;;:::o;57579:87::-;57625:7;57652:6;;;;;;;;;;;57645:13;;57579:87;:::o;43540:104::-;43596:13;43629:7;43622:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43540:104;:::o;46450:295::-;46565:12;:10;:12::i;:::-;46553:24;;:8;:24;;;;46545:62;;;;;;;;;;;;:::i;:::-;;;;;;;;;46665:8;46620:18;:32;46639:12;:10;:12::i;:::-;46620:32;;;;;;;;;;;;;;;:42;46653:8;46620:42;;;;;;;;;;;;;;;;:53;;;;;;;;;;;;;;;;;;46718:8;46689:48;;46704:12;:10;:12::i;:::-;46689:48;;;46728:8;46689:48;;;;;;:::i;:::-;;;;;;;;46450:295;;:::o;47645:285::-;47777:41;47796:12;:10;:12::i;:::-;47810:7;47777:18;:41::i;:::-;47769:103;;;;;;;;;;;;:::i;:::-;;;;;;;;;47883:39;47897:4;47903:2;47907:7;47916:5;47883:13;:39::i;:::-;47645:285;;;;:::o;43715:792::-;43788:13;43822:16;43830:7;43822;:16::i;:::-;43814:76;;;;;;;;;;;;:::i;:::-;;;;;;;;;43903:23;43929:10;:19;43940:7;43929:19;;;;;;;;;;;43903:45;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43959:18;43980:9;:7;:9::i;:::-;43959:30;;44087:1;44071:4;44065:18;:23;44061:72;;;44112:9;44105:16;;;;;;44061:72;44263:1;44243:9;44237:23;:27;44233:108;;;44312:4;44318:9;44295:33;;;;;;;;;:::i;:::-;;;;;;;;;;;;;44281:48;;;;;;44233:108;44473:4;44479:18;:7;:16;:18::i;:::-;44456:42;;;;;;;;;:::i;:::-;;;;;;;;;;;;;44442:57;;;;43715:792;;;;:::o;66869:609::-;66075:5;66934:13;:11;:13::i;:::-;:36;66926:71;;;;;;;;;;;;:::i;:::-;;;;;;;;;67027:1;67016:8;:12;:30;;;;;67044:2;67032:8;:14;;67016:30;67008:97;;;;;;;;;;;;:::i;:::-;;;;;;;;;66075:5;67124:27;67142:8;67124:13;:11;:13::i;:::-;:17;;:27;;;;:::i;:::-;:51;;67116:92;;;;;;;;;;;;:::i;:::-;;;;;;;;;67240:36;67267:8;66173:17;67240:26;;:36;;;;:::i;:::-;67227:9;:49;;67219:97;;;;;;;;;;;;:::i;:::-;;;;;;;;;67334:6;67329:140;67350:8;67346:1;:12;67329:140;;;67380:14;67397:13;:11;:13::i;:::-;67380:30;;67425:32;67435:10;67447:9;67425;:32::i;:::-;67329:140;67360:3;;;;;:::i;:::-;;;;67329:140;;;;66869:609;:::o;67488:263::-;67540:7;67560:17;67580:1;67560:21;;66075:5;67595:13;:11;:13::i;:::-;:37;67592:123;;67685:6;66173:17;67660:31;;;;:::i;:::-;67648:43;;67592:123;67734:9;67727:16;;;67488:263;;;:::o;46816:164::-;46913:4;46937:18;:25;46956:5;46937:25;;;;;;;;;;;;;;;:35;46963:8;46937:35;;;;;;;;;;;;;;;;;;;;;;;;;46930:42;;46816:164;;;;:::o;66199:43::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;58533:244::-;57810:12;:10;:12::i;:::-;57799:23;;:7;:5;:7::i;:::-;:23;;;57791:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;58642:1:::1;58622:22;;:8;:22;;;;58614:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;58732:8;58703:38;;58724:6;;;;;;;;;;;58703:38;;;;;;;;;;;;58761:8;58752:6;;:17;;;;;;;;;;;;;;;;;;58533:244:::0;:::o;49397:127::-;49462:4;49486:30;49508:7;49486:12;:21;;:30;;;;:::i;:::-;49479:37;;49397:127;;;:::o;40614:98::-;40667:7;40694:10;40687:17;;40614:98;:::o;55543:183::-;55636:2;55609:15;:24;55625:7;55609:24;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;55692:7;55688:2;55654:46;;55663:23;55678:7;55663:14;:23::i;:::-;55654:46;;;;;;;;;;;;55543:183;;:::o;10140:123::-;10209:7;10236:19;10244:3;:10;;10236:7;:19::i;:::-;10229:26;;10140:123;;;:::o;49691:355::-;49784:4;49809:16;49817:7;49809;:16::i;:::-;49801:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;49885:13;49901:23;49916:7;49901:14;:23::i;:::-;49885:39;;49954:5;49943:16;;:7;:16;;;:51;;;;49987:7;49963:31;;:20;49975:7;49963:11;:20::i;:::-;:31;;;49943:51;:94;;;;49998:39;50022:5;50029:7;49998:23;:39::i;:::-;49943:94;49935:103;;;49691:355;;;;:::o;52827:599::-;52952:4;52925:31;;:23;52940:7;52925:14;:23::i;:::-;:31;;;52917:85;;;;;;;;;;;;:::i;:::-;;;;;;;;;53053:1;53039:16;;:2;:16;;;;53031:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;53109:39;53130:4;53136:2;53140:7;53109:20;:39::i;:::-;53213:29;53230:1;53234:7;53213:8;:29::i;:::-;53255:35;53282:7;53255:13;:19;53269:4;53255:19;;;;;;;;;;;;;;;:26;;:35;;;;:::i;:::-;;53301:30;53323:7;53301:13;:17;53315:2;53301:17;;;;;;;;;;;;;;;:21;;:30;;;;:::i;:::-;;53344:29;53361:7;53370:2;53344:12;:16;;:29;;;;;:::i;:::-;;53410:7;53406:2;53391:27;;53400:4;53391:27;;;;;;;;;;;;52827:599;;;:::o;21714:137::-;21785:7;21820:22;21824:3;:10;;21836:5;21820:3;:22::i;:::-;21812:31;;21805:38;;21714:137;;;;:::o;10602:236::-;10682:7;10691;10712:11;10725:13;10742:22;10746:3;:10;;10758:5;10742:3;:22::i;:::-;10711:53;;;;10791:3;10783:12;;10821:5;10813:14;;10775:55;;;;;;10602:236;;;;;:::o;61619:98::-;61677:7;61708:1;61704;:5;;;;:::i;:::-;61697:12;;61619:98;;;;:::o;50389:110::-;50465:26;50475:2;50479:7;50465:26;;;;;;;;;;;;:9;:26::i;:::-;50389:110;;:::o;54027:100::-;54111:8;54100;:19;;;;;;;;;;;;:::i;:::-;;54027:100;:::o;11888:213::-;11995:7;12046:44;12051:3;:10;;12071:3;12063:12;;12077;12046:4;:44::i;:::-;12038:53;;12015:78;;11888:213;;;;;:::o;21256:114::-;21316:7;21343:19;21351:3;:10;;21343:7;:19::i;:::-;21336:26;;21256:114;;;:::o;48812:272::-;48926:28;48936:4;48942:2;48946:7;48926:9;:28::i;:::-;48973:48;48996:4;49002:2;49006:7;49015:5;48973:22;:48::i;:::-;48965:111;;;;;;;;;;;;:::i;:::-;;;;;;;;;48812:272;;;;:::o;284:723::-;340:13;570:1;561:5;:10;557:53;;;588:10;;;;;;;;;;;;;;;;;;;;;557:53;620:12;635:5;620:20;;651:14;676:78;691:1;683:4;:9;676:78;;709:8;;;;;:::i;:::-;;;;740:2;732:10;;;;;:::i;:::-;;;676:78;;;764:19;796:6;786:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;764:39;;814:154;830:1;821:5;:10;814:154;;858:1;848:11;;;;;:::i;:::-;;;925:2;917:5;:10;;;;:::i;:::-;904:2;:24;;;;:::i;:::-;891:39;;874:6;881;874:14;;;;;;;;;;;;;;;;;;;:56;;;;;;;;;;;954:2;945:11;;;;;:::i;:::-;;;814:154;;;992:6;978:21;;;;;284:723;;;;:::o;62357:98::-;62415:7;62446:1;62442;:5;;;;:::i;:::-;62435:12;;62357:98;;;;:::o;9901:151::-;9985:4;10009:35;10019:3;:10;;10039:3;10031:12;;10009:9;:35::i;:::-;10002:42;;9901:151;;;;:::o;6719:110::-;6775:7;6802:3;:12;;:19;;;;6795:26;;6719:110;;;:::o;56339:93::-;;;;:::o;20801:137::-;20871:4;20895:35;20903:3;:10;;20923:5;20915:14;;20895:7;:35::i;:::-;20888:42;;20801:137;;;;:::o;20494:131::-;20561:4;20585:32;20590:3;:10;;20610:5;20602:14;;20585:4;:32::i;:::-;20578:39;;20494:131;;;;:::o;9324:185::-;9413:4;9437:64;9442:3;:10;;9462:3;9454:12;;9492:5;9476:23;;9468:32;;9437:4;:64::i;:::-;9430:71;;9324:185;;;;;:::o;16752:204::-;16819:7;16868:5;16847:3;:11;;:18;;;;:26;16839:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;16930:3;:11;;16942:5;16930:18;;;;;;;;;;;;;;;;;;;;;;;;16923:25;;16752:204;;;;:::o;7184:279::-;7251:7;7260;7310:5;7288:3;:12;;:19;;;;:27;7280:74;;;;;;;;;;;;:::i;:::-;;;;;;;;;7367:22;7392:3;:12;;7405:5;7392:19;;;;;;;;;;;;;;;;;;;;;;;;;;7367:44;;7430:5;:10;;;7442:5;:12;;;7422:33;;;;;7184:279;;;;;:::o;50726:250::-;50822:18;50828:2;50832:7;50822:5;:18::i;:::-;50859:54;50890:1;50894:2;50898:7;50907:5;50859:22;:54::i;:::-;50851:117;;;;;;;;;;;;:::i;:::-;;;;;;;;;50726:250;;;:::o;8681:319::-;8775:7;8795:16;8814:3;:12;;:17;8827:3;8814:17;;;;;;;;;;;;8795:36;;8862:1;8850:8;:13;;8865:12;8842:36;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;8932:3;:12;;8956:1;8945:8;:12;;;;:::i;:::-;8932:26;;;;;;;;;;;;;;;;;;;;;;;;;;:33;;;8925:40;;;8681:319;;;;;:::o;16299:109::-;16355:7;16382:3;:11;;:18;;;;16375:25;;16299:109;;;:::o;54692:843::-;54813:4;54839:15;:2;:13;;;:15::i;:::-;54835:693;;;54891:2;54875:36;;;54912:12;:10;:12::i;:::-;54926:4;54932:7;54941:5;54875:72;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;54871:602;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;55138:1;55121:6;:13;:18;55117:341;;;55164:60;;;;;;;;;;:::i;:::-;;;;;;;;55117:341;55408:6;55402:13;55393:6;55389:2;55385:15;55378:38;54871:602;55008:45;;;54998:55;;;:6;:55;;;;54991:62;;;;;54835:693;55512:4;55505:11;;54692:843;;;;;;;:::o;6499:125::-;6570:4;6615:1;6594:3;:12;;:17;6607:3;6594:17;;;;;;;;;;;;:22;;6587:29;;6499:125;;;;:::o;14454:1544::-;14520:4;14638:18;14659:3;:12;;:19;14672:5;14659:19;;;;;;;;;;;;14638:40;;14709:1;14695:10;:15;14691:1300;;15057:21;15094:1;15081:10;:14;;;;:::i;:::-;15057:38;;15110:17;15151:1;15130:3;:11;;:18;;;;:22;;;;:::i;:::-;15110:42;;15397:17;15417:3;:11;;15429:9;15417:22;;;;;;;;;;;;;;;;;;;;;;;;15397:42;;15563:9;15534:3;:11;;15546:13;15534:26;;;;;;;;;;;;;;;;;;;;;;;:38;;;;15682:1;15666:13;:17;;;;:::i;:::-;15640:3;:12;;:23;15653:9;15640:23;;;;;;;;;;;:43;;;;15792:3;:11;;:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15887:3;:12;;:19;15900:5;15887:19;;;;;;;;;;;15880:26;;;15930:4;15923:11;;;;;;;;14691:1300;15974:5;15967:12;;;14454:1544;;;;;:::o;13864:414::-;13927:4;13949:21;13959:3;13964:5;13949:9;:21::i;:::-;13944:327;;13987:3;:11;;14004:5;13987:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14170:3;:11;;:18;;;;14148:3;:12;;:19;14161:5;14148:19;;;;;;;;;;;:40;;;;14210:4;14203:11;;;;13944:327;14254:5;14247:12;;13864:414;;;;;:::o;3999:692::-;4075:4;4191:16;4210:3;:12;;:17;4223:3;4210:17;;;;;;;;;;;;4191:36;;4256:1;4244:8;:13;4240:444;;;4311:3;:12;;4329:38;;;;;;;;4346:3;4329:38;;;;4359:5;4329:38;;;4311:57;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4526:3;:12;;:19;;;;4506:3;:12;;:17;4519:3;4506:17;;;;;;;;;;;:39;;;;4567:4;4560:11;;;;;4240:444;4640:5;4604:3;:12;;4628:1;4617:8;:12;;;;:::i;:::-;4604:26;;;;;;;;;;;;;;;;;;;;;;;;;;:33;;:41;;;;4667:5;4660:12;;;3999:692;;;;;;:::o;51312:404::-;51406:1;51392:16;;:2;:16;;;;51384:61;;;;;;;;;;;;:::i;:::-;;;;;;;;;51465:16;51473:7;51465;:16::i;:::-;51464:17;51456:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;51527:45;51556:1;51560:2;51564:7;51527:20;:45::i;:::-;51585:30;51607:7;51585:13;:17;51599:2;51585:17;;;;;;;;;;;;;;;:21;;:30;;;;:::i;:::-;;51628:29;51645:7;51654:2;51628:12;:16;;:29;;;;;:::i;:::-;;51700:7;51696:2;51675:33;;51692:1;51675:33;;;;;;;;;;;;51312:404;;:::o;22666:422::-;22726:4;22934:12;23045:7;23033:20;23025:28;;23079:1;23072:4;:8;23065:15;;;22666:422;;;:::o;16084:129::-;16157:4;16204:1;16181:3;:12;;:19;16194:5;16181:19;;;;;;;;;;;;:24;;16174:31;;16084:129;;;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;:::o;7:343:1:-;84:5;109:65;125:48;166:6;125:48;:::i;:::-;109:65;:::i;:::-;100:74;;197:6;190:5;183:21;235:4;228:5;224:16;273:3;264:6;259:3;255:16;252:25;249:2;;;290:1;287;280:12;249:2;303:41;337:6;332:3;327;303:41;:::i;:::-;90:260;;;;;;:::o;356:345::-;434:5;459:66;475:49;517:6;475:49;:::i;:::-;459:66;:::i;:::-;450:75;;548:6;541:5;534:21;586:4;579:5;575:16;624:3;615:6;610:3;606:16;603:25;600:2;;;641:1;638;631:12;600:2;654:41;688:6;683:3;678;654:41;:::i;:::-;440:261;;;;;;:::o;707:139::-;753:5;791:6;778:20;769:29;;807:33;834:5;807:33;:::i;:::-;759:87;;;;:::o;852:133::-;895:5;933:6;920:20;911:29;;949:30;973:5;949:30;:::i;:::-;901:84;;;;:::o;991:137::-;1036:5;1074:6;1061:20;1052:29;;1090:32;1116:5;1090:32;:::i;:::-;1042:86;;;;:::o;1134:141::-;1190:5;1221:6;1215:13;1206:22;;1237:32;1263:5;1237:32;:::i;:::-;1196:79;;;;:::o;1294:271::-;1349:5;1398:3;1391:4;1383:6;1379:17;1375:27;1365:2;;1416:1;1413;1406:12;1365:2;1456:6;1443:20;1481:78;1555:3;1547:6;1540:4;1532:6;1528:17;1481:78;:::i;:::-;1472:87;;1355:210;;;;;:::o;1585:273::-;1641:5;1690:3;1683:4;1675:6;1671:17;1667:27;1657:2;;1708:1;1705;1698:12;1657:2;1748:6;1735:20;1773:79;1848:3;1840:6;1833:4;1825:6;1821:17;1773:79;:::i;:::-;1764:88;;1647:211;;;;;:::o;1864:139::-;1910:5;1948:6;1935:20;1926:29;;1964:33;1991:5;1964:33;:::i;:::-;1916:87;;;;:::o;2009:262::-;2068:6;2117:2;2105:9;2096:7;2092:23;2088:32;2085:2;;;2133:1;2130;2123:12;2085:2;2176:1;2201:53;2246:7;2237:6;2226:9;2222:22;2201:53;:::i;:::-;2191:63;;2147:117;2075:196;;;;:::o;2277:407::-;2345:6;2353;2402:2;2390:9;2381:7;2377:23;2373:32;2370:2;;;2418:1;2415;2408:12;2370:2;2461:1;2486:53;2531:7;2522:6;2511:9;2507:22;2486:53;:::i;:::-;2476:63;;2432:117;2588:2;2614:53;2659:7;2650:6;2639:9;2635:22;2614:53;:::i;:::-;2604:63;;2559:118;2360:324;;;;;:::o;2690:552::-;2767:6;2775;2783;2832:2;2820:9;2811:7;2807:23;2803:32;2800:2;;;2848:1;2845;2838:12;2800:2;2891:1;2916:53;2961:7;2952:6;2941:9;2937:22;2916:53;:::i;:::-;2906:63;;2862:117;3018:2;3044:53;3089:7;3080:6;3069:9;3065:22;3044:53;:::i;:::-;3034:63;;2989:118;3146:2;3172:53;3217:7;3208:6;3197:9;3193:22;3172:53;:::i;:::-;3162:63;;3117:118;2790:452;;;;;:::o;3248:809::-;3343:6;3351;3359;3367;3416:3;3404:9;3395:7;3391:23;3387:33;3384:2;;;3433:1;3430;3423:12;3384:2;3476:1;3501:53;3546:7;3537:6;3526:9;3522:22;3501:53;:::i;:::-;3491:63;;3447:117;3603:2;3629:53;3674:7;3665:6;3654:9;3650:22;3629:53;:::i;:::-;3619:63;;3574:118;3731:2;3757:53;3802:7;3793:6;3782:9;3778:22;3757:53;:::i;:::-;3747:63;;3702:118;3887:2;3876:9;3872:18;3859:32;3918:18;3910:6;3907:30;3904:2;;;3950:1;3947;3940:12;3904:2;3978:62;4032:7;4023:6;4012:9;4008:22;3978:62;:::i;:::-;3968:72;;3830:220;3374:683;;;;;;;:::o;4063:401::-;4128:6;4136;4185:2;4173:9;4164:7;4160:23;4156:32;4153:2;;;4201:1;4198;4191:12;4153:2;4244:1;4269:53;4314:7;4305:6;4294:9;4290:22;4269:53;:::i;:::-;4259:63;;4215:117;4371:2;4397:50;4439:7;4430:6;4419:9;4415:22;4397:50;:::i;:::-;4387:60;;4342:115;4143:321;;;;;:::o;4470:407::-;4538:6;4546;4595:2;4583:9;4574:7;4570:23;4566:32;4563:2;;;4611:1;4608;4601:12;4563:2;4654:1;4679:53;4724:7;4715:6;4704:9;4700:22;4679:53;:::i;:::-;4669:63;;4625:117;4781:2;4807:53;4852:7;4843:6;4832:9;4828:22;4807:53;:::i;:::-;4797:63;;4752:118;4553:324;;;;;:::o;4883:260::-;4941:6;4990:2;4978:9;4969:7;4965:23;4961:32;4958:2;;;5006:1;5003;4996:12;4958:2;5049:1;5074:52;5118:7;5109:6;5098:9;5094:22;5074:52;:::i;:::-;5064:62;;5020:116;4948:195;;;;:::o;5149:282::-;5218:6;5267:2;5255:9;5246:7;5242:23;5238:32;5235:2;;;5283:1;5280;5273:12;5235:2;5326:1;5351:63;5406:7;5397:6;5386:9;5382:22;5351:63;:::i;:::-;5341:73;;5297:127;5225:206;;;;:::o;5437:375::-;5506:6;5555:2;5543:9;5534:7;5530:23;5526:32;5523:2;;;5571:1;5568;5561:12;5523:2;5642:1;5631:9;5627:17;5614:31;5672:18;5664:6;5661:30;5658:2;;;5704:1;5701;5694:12;5658:2;5732:63;5787:7;5778:6;5767:9;5763:22;5732:63;:::i;:::-;5722:73;;5585:220;5513:299;;;;:::o;5818:262::-;5877:6;5926:2;5914:9;5905:7;5901:23;5897:32;5894:2;;;5942:1;5939;5932:12;5894:2;5985:1;6010:53;6055:7;6046:6;6035:9;6031:22;6010:53;:::i;:::-;6000:63;;5956:117;5884:196;;;;:::o;6086:179::-;6155:10;6176:46;6218:3;6210:6;6176:46;:::i;:::-;6254:4;6249:3;6245:14;6231:28;;6166:99;;;;:::o;6271:118::-;6358:24;6376:5;6358:24;:::i;:::-;6353:3;6346:37;6336:53;;:::o;6425:732::-;6544:3;6573:54;6621:5;6573:54;:::i;:::-;6643:86;6722:6;6717:3;6643:86;:::i;:::-;6636:93;;6753:56;6803:5;6753:56;:::i;:::-;6832:7;6863:1;6848:284;6873:6;6870:1;6867:13;6848:284;;;6949:6;6943:13;6976:63;7035:3;7020:13;6976:63;:::i;:::-;6969:70;;7062:60;7115:6;7062:60;:::i;:::-;7052:70;;6908:224;6895:1;6892;6888:9;6883:14;;6848:284;;;6852:14;7148:3;7141:10;;6549:608;;;;;;;:::o;7163:109::-;7244:21;7259:5;7244:21;:::i;:::-;7239:3;7232:34;7222:50;;:::o;7278:360::-;7364:3;7392:38;7424:5;7392:38;:::i;:::-;7446:70;7509:6;7504:3;7446:70;:::i;:::-;7439:77;;7525:52;7570:6;7565:3;7558:4;7551:5;7547:16;7525:52;:::i;:::-;7602:29;7624:6;7602:29;:::i;:::-;7597:3;7593:39;7586:46;;7368:270;;;;;:::o;7644:364::-;7732:3;7760:39;7793:5;7760:39;:::i;:::-;7815:71;7879:6;7874:3;7815:71;:::i;:::-;7808:78;;7895:52;7940:6;7935:3;7928:4;7921:5;7917:16;7895:52;:::i;:::-;7972:29;7994:6;7972:29;:::i;:::-;7967:3;7963:39;7956:46;;7736:272;;;;;:::o;8014:377::-;8120:3;8148:39;8181:5;8148:39;:::i;:::-;8203:89;8285:6;8280:3;8203:89;:::i;:::-;8196:96;;8301:52;8346:6;8341:3;8334:4;8327:5;8323:16;8301:52;:::i;:::-;8378:6;8373:3;8369:16;8362:23;;8124:267;;;;;:::o;8397:366::-;8539:3;8560:67;8624:2;8619:3;8560:67;:::i;:::-;8553:74;;8636:93;8725:3;8636:93;:::i;:::-;8754:2;8749:3;8745:12;8738:19;;8543:220;;;:::o;8769:366::-;8911:3;8932:67;8996:2;8991:3;8932:67;:::i;:::-;8925:74;;9008:93;9097:3;9008:93;:::i;:::-;9126:2;9121:3;9117:12;9110:19;;8915:220;;;:::o;9141:366::-;9283:3;9304:67;9368:2;9363:3;9304:67;:::i;:::-;9297:74;;9380:93;9469:3;9380:93;:::i;:::-;9498:2;9493:3;9489:12;9482:19;;9287:220;;;:::o;9513:366::-;9655:3;9676:67;9740:2;9735:3;9676:67;:::i;:::-;9669:74;;9752:93;9841:3;9752:93;:::i;:::-;9870:2;9865:3;9861:12;9854:19;;9659:220;;;:::o;9885:366::-;10027:3;10048:67;10112:2;10107:3;10048:67;:::i;:::-;10041:74;;10124:93;10213:3;10124:93;:::i;:::-;10242:2;10237:3;10233:12;10226:19;;10031:220;;;:::o;10257:366::-;10399:3;10420:67;10484:2;10479:3;10420:67;:::i;:::-;10413:74;;10496:93;10585:3;10496:93;:::i;:::-;10614:2;10609:3;10605:12;10598:19;;10403:220;;;:::o;10629:366::-;10771:3;10792:67;10856:2;10851:3;10792:67;:::i;:::-;10785:74;;10868:93;10957:3;10868:93;:::i;:::-;10986:2;10981:3;10977:12;10970:19;;10775:220;;;:::o;11001:366::-;11143:3;11164:67;11228:2;11223:3;11164:67;:::i;:::-;11157:74;;11240:93;11329:3;11240:93;:::i;:::-;11358:2;11353:3;11349:12;11342:19;;11147:220;;;:::o;11373:366::-;11515:3;11536:67;11600:2;11595:3;11536:67;:::i;:::-;11529:74;;11612:93;11701:3;11612:93;:::i;:::-;11730:2;11725:3;11721:12;11714:19;;11519:220;;;:::o;11745:366::-;11887:3;11908:67;11972:2;11967:3;11908:67;:::i;:::-;11901:74;;11984:93;12073:3;11984:93;:::i;:::-;12102:2;12097:3;12093:12;12086:19;;11891:220;;;:::o;12117:366::-;12259:3;12280:67;12344:2;12339:3;12280:67;:::i;:::-;12273:74;;12356:93;12445:3;12356:93;:::i;:::-;12474:2;12469:3;12465:12;12458:19;;12263:220;;;:::o;12489:366::-;12631:3;12652:67;12716:2;12711:3;12652:67;:::i;:::-;12645:74;;12728:93;12817:3;12728:93;:::i;:::-;12846:2;12841:3;12837:12;12830:19;;12635:220;;;:::o;12861:366::-;13003:3;13024:67;13088:2;13083:3;13024:67;:::i;:::-;13017:74;;13100:93;13189:3;13100:93;:::i;:::-;13218:2;13213:3;13209:12;13202:19;;13007:220;;;:::o;13233:366::-;13375:3;13396:67;13460:2;13455:3;13396:67;:::i;:::-;13389:74;;13472:93;13561:3;13472:93;:::i;:::-;13590:2;13585:3;13581:12;13574:19;;13379:220;;;:::o;13605:366::-;13747:3;13768:67;13832:2;13827:3;13768:67;:::i;:::-;13761:74;;13844:93;13933:3;13844:93;:::i;:::-;13962:2;13957:3;13953:12;13946:19;;13751:220;;;:::o;13977:366::-;14119:3;14140:67;14204:2;14199:3;14140:67;:::i;:::-;14133:74;;14216:93;14305:3;14216:93;:::i;:::-;14334:2;14329:3;14325:12;14318:19;;14123:220;;;:::o;14349:366::-;14491:3;14512:67;14576:2;14571:3;14512:67;:::i;:::-;14505:74;;14588:93;14677:3;14588:93;:::i;:::-;14706:2;14701:3;14697:12;14690:19;;14495:220;;;:::o;14721:366::-;14863:3;14884:67;14948:2;14943:3;14884:67;:::i;:::-;14877:74;;14960:93;15049:3;14960:93;:::i;:::-;15078:2;15073:3;15069:12;15062:19;;14867:220;;;:::o;15093:366::-;15235:3;15256:67;15320:2;15315:3;15256:67;:::i;:::-;15249:74;;15332:93;15421:3;15332:93;:::i;:::-;15450:2;15445:3;15441:12;15434:19;;15239:220;;;:::o;15465:366::-;15607:3;15628:67;15692:2;15687:3;15628:67;:::i;:::-;15621:74;;15704:93;15793:3;15704:93;:::i;:::-;15822:2;15817:3;15813:12;15806:19;;15611:220;;;:::o;15837:366::-;15979:3;16000:67;16064:2;16059:3;16000:67;:::i;:::-;15993:74;;16076:93;16165:3;16076:93;:::i;:::-;16194:2;16189:3;16185:12;16178:19;;15983:220;;;:::o;16209:108::-;16286:24;16304:5;16286:24;:::i;:::-;16281:3;16274:37;16264:53;;:::o;16323:118::-;16410:24;16428:5;16410:24;:::i;:::-;16405:3;16398:37;16388:53;;:::o;16447:435::-;16627:3;16649:95;16740:3;16731:6;16649:95;:::i;:::-;16642:102;;16761:95;16852:3;16843:6;16761:95;:::i;:::-;16754:102;;16873:3;16866:10;;16631:251;;;;;:::o;16888:222::-;16981:4;17019:2;17008:9;17004:18;16996:26;;17032:71;17100:1;17089:9;17085:17;17076:6;17032:71;:::i;:::-;16986:124;;;;:::o;17116:640::-;17311:4;17349:3;17338:9;17334:19;17326:27;;17363:71;17431:1;17420:9;17416:17;17407:6;17363:71;:::i;:::-;17444:72;17512:2;17501:9;17497:18;17488:6;17444:72;:::i;:::-;17526;17594:2;17583:9;17579:18;17570:6;17526:72;:::i;:::-;17645:9;17639:4;17635:20;17630:2;17619:9;17615:18;17608:48;17673:76;17744:4;17735:6;17673:76;:::i;:::-;17665:84;;17316:440;;;;;;;:::o;17762:373::-;17905:4;17943:2;17932:9;17928:18;17920:26;;17992:9;17986:4;17982:20;17978:1;17967:9;17963:17;17956:47;18020:108;18123:4;18114:6;18020:108;:::i;:::-;18012:116;;17910:225;;;;:::o;18141:210::-;18228:4;18266:2;18255:9;18251:18;18243:26;;18279:65;18341:1;18330:9;18326:17;18317:6;18279:65;:::i;:::-;18233:118;;;;:::o;18357:313::-;18470:4;18508:2;18497:9;18493:18;18485:26;;18557:9;18551:4;18547:20;18543:1;18532:9;18528:17;18521:47;18585:78;18658:4;18649:6;18585:78;:::i;:::-;18577:86;;18475:195;;;;:::o;18676:419::-;18842:4;18880:2;18869:9;18865:18;18857:26;;18929:9;18923:4;18919:20;18915:1;18904:9;18900:17;18893:47;18957:131;19083:4;18957:131;:::i;:::-;18949:139;;18847:248;;;:::o;19101:419::-;19267:4;19305:2;19294:9;19290:18;19282:26;;19354:9;19348:4;19344:20;19340:1;19329:9;19325:17;19318:47;19382:131;19508:4;19382:131;:::i;:::-;19374:139;;19272:248;;;:::o;19526:419::-;19692:4;19730:2;19719:9;19715:18;19707:26;;19779:9;19773:4;19769:20;19765:1;19754:9;19750:17;19743:47;19807:131;19933:4;19807:131;:::i;:::-;19799:139;;19697:248;;;:::o;19951:419::-;20117:4;20155:2;20144:9;20140:18;20132:26;;20204:9;20198:4;20194:20;20190:1;20179:9;20175:17;20168:47;20232:131;20358:4;20232:131;:::i;:::-;20224:139;;20122:248;;;:::o;20376:419::-;20542:4;20580:2;20569:9;20565:18;20557:26;;20629:9;20623:4;20619:20;20615:1;20604:9;20600:17;20593:47;20657:131;20783:4;20657:131;:::i;:::-;20649:139;;20547:248;;;:::o;20801:419::-;20967:4;21005:2;20994:9;20990:18;20982:26;;21054:9;21048:4;21044:20;21040:1;21029:9;21025:17;21018:47;21082:131;21208:4;21082:131;:::i;:::-;21074:139;;20972:248;;;:::o;21226:419::-;21392:4;21430:2;21419:9;21415:18;21407:26;;21479:9;21473:4;21469:20;21465:1;21454:9;21450:17;21443:47;21507:131;21633:4;21507:131;:::i;:::-;21499:139;;21397:248;;;:::o;21651:419::-;21817:4;21855:2;21844:9;21840:18;21832:26;;21904:9;21898:4;21894:20;21890:1;21879:9;21875:17;21868:47;21932:131;22058:4;21932:131;:::i;:::-;21924:139;;21822:248;;;:::o;22076:419::-;22242:4;22280:2;22269:9;22265:18;22257:26;;22329:9;22323:4;22319:20;22315:1;22304:9;22300:17;22293:47;22357:131;22483:4;22357:131;:::i;:::-;22349:139;;22247:248;;;:::o;22501:419::-;22667:4;22705:2;22694:9;22690:18;22682:26;;22754:9;22748:4;22744:20;22740:1;22729:9;22725:17;22718:47;22782:131;22908:4;22782:131;:::i;:::-;22774:139;;22672:248;;;:::o;22926:419::-;23092:4;23130:2;23119:9;23115:18;23107:26;;23179:9;23173:4;23169:20;23165:1;23154:9;23150:17;23143:47;23207:131;23333:4;23207:131;:::i;:::-;23199:139;;23097:248;;;:::o;23351:419::-;23517:4;23555:2;23544:9;23540:18;23532:26;;23604:9;23598:4;23594:20;23590:1;23579:9;23575:17;23568:47;23632:131;23758:4;23632:131;:::i;:::-;23624:139;;23522:248;;;:::o;23776:419::-;23942:4;23980:2;23969:9;23965:18;23957:26;;24029:9;24023:4;24019:20;24015:1;24004:9;24000:17;23993:47;24057:131;24183:4;24057:131;:::i;:::-;24049:139;;23947:248;;;:::o;24201:419::-;24367:4;24405:2;24394:9;24390:18;24382:26;;24454:9;24448:4;24444:20;24440:1;24429:9;24425:17;24418:47;24482:131;24608:4;24482:131;:::i;:::-;24474:139;;24372:248;;;:::o;24626:419::-;24792:4;24830:2;24819:9;24815:18;24807:26;;24879:9;24873:4;24869:20;24865:1;24854:9;24850:17;24843:47;24907:131;25033:4;24907:131;:::i;:::-;24899:139;;24797:248;;;:::o;25051:419::-;25217:4;25255:2;25244:9;25240:18;25232:26;;25304:9;25298:4;25294:20;25290:1;25279:9;25275:17;25268:47;25332:131;25458:4;25332:131;:::i;:::-;25324:139;;25222:248;;;:::o;25476:419::-;25642:4;25680:2;25669:9;25665:18;25657:26;;25729:9;25723:4;25719:20;25715:1;25704:9;25700:17;25693:47;25757:131;25883:4;25757:131;:::i;:::-;25749:139;;25647:248;;;:::o;25901:419::-;26067:4;26105:2;26094:9;26090:18;26082:26;;26154:9;26148:4;26144:20;26140:1;26129:9;26125:17;26118:47;26182:131;26308:4;26182:131;:::i;:::-;26174:139;;26072:248;;;:::o;26326:419::-;26492:4;26530:2;26519:9;26515:18;26507:26;;26579:9;26573:4;26569:20;26565:1;26554:9;26550:17;26543:47;26607:131;26733:4;26607:131;:::i;:::-;26599:139;;26497:248;;;:::o;26751:419::-;26917:4;26955:2;26944:9;26940:18;26932:26;;27004:9;26998:4;26994:20;26990:1;26979:9;26975:17;26968:47;27032:131;27158:4;27032:131;:::i;:::-;27024:139;;26922:248;;;:::o;27176:419::-;27342:4;27380:2;27369:9;27365:18;27357:26;;27429:9;27423:4;27419:20;27415:1;27404:9;27400:17;27393:47;27457:131;27583:4;27457:131;:::i;:::-;27449:139;;27347:248;;;:::o;27601:222::-;27694:4;27732:2;27721:9;27717:18;27709:26;;27745:71;27813:1;27802:9;27798:17;27789:6;27745:71;:::i;:::-;27699:124;;;;:::o;27829:129::-;27863:6;27890:20;;:::i;:::-;27880:30;;27919:33;27947:4;27939:6;27919:33;:::i;:::-;27870:88;;;:::o;27964:75::-;27997:6;28030:2;28024:9;28014:19;;28004:35;:::o;28045:307::-;28106:4;28196:18;28188:6;28185:30;28182:2;;;28218:18;;:::i;:::-;28182:2;28256:29;28278:6;28256:29;:::i;:::-;28248:37;;28340:4;28334;28330:15;28322:23;;28111:241;;;:::o;28358:308::-;28420:4;28510:18;28502:6;28499:30;28496:2;;;28532:18;;:::i;:::-;28496:2;28570:29;28592:6;28570:29;:::i;:::-;28562:37;;28654:4;28648;28644:15;28636:23;;28425:241;;;:::o;28672:132::-;28739:4;28762:3;28754:11;;28792:4;28787:3;28783:14;28775:22;;28744:60;;;:::o;28810:114::-;28877:6;28911:5;28905:12;28895:22;;28884:40;;;:::o;28930:98::-;28981:6;29015:5;29009:12;28999:22;;28988:40;;;:::o;29034:99::-;29086:6;29120:5;29114:12;29104:22;;29093:40;;;:::o;29139:113::-;29209:4;29241;29236:3;29232:14;29224:22;;29214:38;;;:::o;29258:184::-;29357:11;29391:6;29386:3;29379:19;29431:4;29426:3;29422:14;29407:29;;29369:73;;;;:::o;29448:168::-;29531:11;29565:6;29560:3;29553:19;29605:4;29600:3;29596:14;29581:29;;29543:73;;;;:::o;29622:169::-;29706:11;29740:6;29735:3;29728:19;29780:4;29775:3;29771:14;29756:29;;29718:73;;;;:::o;29797:148::-;29899:11;29936:3;29921:18;;29911:34;;;;:::o;29951:305::-;29991:3;30010:20;30028:1;30010:20;:::i;:::-;30005:25;;30044:20;30062:1;30044:20;:::i;:::-;30039:25;;30198:1;30130:66;30126:74;30123:1;30120:81;30117:2;;;30204:18;;:::i;:::-;30117:2;30248:1;30245;30241:9;30234:16;;29995:261;;;;:::o;30262:185::-;30302:1;30319:20;30337:1;30319:20;:::i;:::-;30314:25;;30353:20;30371:1;30353:20;:::i;:::-;30348:25;;30392:1;30382:2;;30397:18;;:::i;:::-;30382:2;30439:1;30436;30432:9;30427:14;;30304:143;;;;:::o;30453:348::-;30493:7;30516:20;30534:1;30516:20;:::i;:::-;30511:25;;30550:20;30568:1;30550:20;:::i;:::-;30545:25;;30738:1;30670:66;30666:74;30663:1;30660:81;30655:1;30648:9;30641:17;30637:105;30634:2;;;30745:18;;:::i;:::-;30634:2;30793:1;30790;30786:9;30775:20;;30501:300;;;;:::o;30807:191::-;30847:4;30867:20;30885:1;30867:20;:::i;:::-;30862:25;;30901:20;30919:1;30901:20;:::i;:::-;30896:25;;30940:1;30937;30934:8;30931:2;;;30945:18;;:::i;:::-;30931:2;30990:1;30987;30983:9;30975:17;;30852:146;;;;:::o;31004:96::-;31041:7;31070:24;31088:5;31070:24;:::i;:::-;31059:35;;31049:51;;;:::o;31106:90::-;31140:7;31183:5;31176:13;31169:21;31158:32;;31148:48;;;:::o;31202:149::-;31238:7;31278:66;31271:5;31267:78;31256:89;;31246:105;;;:::o;31357:126::-;31394:7;31434:42;31427:5;31423:54;31412:65;;31402:81;;;:::o;31489:77::-;31526:7;31555:5;31544:16;;31534:32;;;:::o;31572:154::-;31656:6;31651:3;31646;31633:30;31718:1;31709:6;31704:3;31700:16;31693:27;31623:103;;;:::o;31732:307::-;31800:1;31810:113;31824:6;31821:1;31818:13;31810:113;;;31909:1;31904:3;31900:11;31894:18;31890:1;31885:3;31881:11;31874:39;31846:2;31843:1;31839:10;31834:15;;31810:113;;;31941:6;31938:1;31935:13;31932:2;;;32021:1;32012:6;32007:3;32003:16;31996:27;31932:2;31781:258;;;;:::o;32045:320::-;32089:6;32126:1;32120:4;32116:12;32106:22;;32173:1;32167:4;32163:12;32194:18;32184:2;;32250:4;32242:6;32238:17;32228:27;;32184:2;32312;32304:6;32301:14;32281:18;32278:38;32275:2;;;32331:18;;:::i;:::-;32275:2;32096:269;;;;:::o;32371:281::-;32454:27;32476:4;32454:27;:::i;:::-;32446:6;32442:40;32584:6;32572:10;32569:22;32548:18;32536:10;32533:34;32530:62;32527:2;;;32595:18;;:::i;:::-;32527:2;32635:10;32631:2;32624:22;32414:238;;;:::o;32658:233::-;32697:3;32720:24;32738:5;32720:24;:::i;:::-;32711:33;;32766:66;32759:5;32756:77;32753:2;;;32836:18;;:::i;:::-;32753:2;32883:1;32876:5;32872:13;32865:20;;32701:190;;;:::o;32897:176::-;32929:1;32946:20;32964:1;32946:20;:::i;:::-;32941:25;;32980:20;32998:1;32980:20;:::i;:::-;32975:25;;33019:1;33009:2;;33024:18;;:::i;:::-;33009:2;33065:1;33062;33058:9;33053:14;;32931:142;;;;:::o;33079:180::-;33127:77;33124:1;33117:88;33224:4;33221:1;33214:15;33248:4;33245:1;33238:15;33265:180;33313:77;33310:1;33303:88;33410:4;33407:1;33400:15;33434:4;33431:1;33424:15;33451:180;33499:77;33496:1;33489:88;33596:4;33593:1;33586:15;33620:4;33617:1;33610:15;33637:180;33685:77;33682:1;33675:88;33782:4;33779:1;33772:15;33806:4;33803:1;33796:15;33823:102;33864:6;33915:2;33911:7;33906:2;33899:5;33895:14;33891:28;33881:38;;33871:54;;;:::o;33931:221::-;34071:34;34067:1;34059:6;34055:14;34048:58;34140:4;34135:2;34127:6;34123:15;34116:29;34037:115;:::o;34158:237::-;34298:34;34294:1;34286:6;34282:14;34275:58;34367:20;34362:2;34354:6;34350:15;34343:45;34264:131;:::o;34401:225::-;34541:34;34537:1;34529:6;34525:14;34518:58;34610:8;34605:2;34597:6;34593:15;34586:33;34507:119;:::o;34632:178::-;34772:30;34768:1;34760:6;34756:14;34749:54;34738:72;:::o;34816:223::-;34956:34;34952:1;34944:6;34940:14;34933:58;35025:6;35020:2;35012:6;35008:15;35001:31;34922:117;:::o;35045:175::-;35185:27;35181:1;35173:6;35169:14;35162:51;35151:69;:::o;35226:231::-;35366:34;35362:1;35354:6;35350:14;35343:58;35435:14;35430:2;35422:6;35418:15;35411:39;35332:125;:::o;35463:243::-;35603:34;35599:1;35591:6;35587:14;35580:58;35672:26;35667:2;35659:6;35655:15;35648:51;35569:137;:::o;35712:229::-;35852:34;35848:1;35840:6;35836:14;35829:58;35921:12;35916:2;35908:6;35904:15;35897:37;35818:123;:::o;35947:222::-;36087:34;36083:1;36075:6;36071:14;36064:58;36156:5;36151:2;36143:6;36139:15;36132:30;36053:116;:::o;36175:221::-;36315:34;36311:1;36303:6;36299:14;36292:58;36384:4;36379:2;36371:6;36367:15;36360:29;36281:115;:::o;36402:241::-;36542:34;36538:1;36530:6;36526:14;36519:58;36611:24;36606:2;36598:6;36594:15;36587:49;36508:135;:::o;36649:182::-;36789:34;36785:1;36777:6;36773:14;36766:58;36755:76;:::o;36837:231::-;36977:34;36973:1;36965:6;36961:14;36954:58;37046:14;37041:2;37033:6;37029:15;37022:39;36943:125;:::o;37074:182::-;37214:34;37210:1;37202:6;37198:14;37191:58;37180:76;:::o;37262:228::-;37402:34;37398:1;37390:6;37386:14;37379:58;37471:11;37466:2;37458:6;37454:15;37447:36;37368:122;:::o;37496:234::-;37636:34;37632:1;37624:6;37620:14;37613:58;37705:17;37700:2;37692:6;37688:15;37681:42;37602:128;:::o;37736:220::-;37876:34;37872:1;37864:6;37860:14;37853:58;37945:3;37940:2;37932:6;37928:15;37921:28;37842:114;:::o;37962:172::-;38102:24;38098:1;38090:6;38086:14;38079:48;38068:66;:::o;38140:178::-;38280:30;38276:1;38268:6;38264:14;38257:54;38246:72;:::o;38324:236::-;38464:34;38460:1;38452:6;38448:14;38441:58;38533:19;38528:2;38520:6;38516:15;38509:44;38430:130;:::o;38566:122::-;38639:24;38657:5;38639:24;:::i;:::-;38632:5;38629:35;38619:2;;38678:1;38675;38668:12;38619:2;38609:79;:::o;38694:116::-;38764:21;38779:5;38764:21;:::i;:::-;38757:5;38754:32;38744:2;;38800:1;38797;38790:12;38744:2;38734:76;:::o;38816:120::-;38888:23;38905:5;38888:23;:::i;:::-;38881:5;38878:34;38868:2;;38926:1;38923;38916:12;38868:2;38858:78;:::o;38942:122::-;39015:24;39033:5;39015:24;:::i;:::-;39008:5;39005:35;38995:2;;39054:1;39051;39044:12;38995:2;38985:79;:::o

Swarm Source

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