unaiverse 0.1.0__py3-none-any.whl → 0.1.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of unaiverse might be problematic. Click here for more details.

@@ -135,6 +135,9 @@ class Node:
135
135
  self.last_alive_time = 0.
136
136
  self.skip_was_alive_check = os.getenv("NODE_IGNORE_ALIVE", "0") == "1"
137
137
 
138
+ # Alive messaging
139
+ self.run_start_time = 0.
140
+
138
141
  # Root server-related
139
142
  self.root_endpoint = 'https://unaiverse.io/api' # WARNING: EDITING THIS ADDRESS VIOLATES THE LICENSE
140
143
  self.node_token = ""
@@ -206,7 +209,7 @@ class Node:
206
209
  ips=None,
207
210
  enable_relay_service=offer_relay_facilities,
208
211
  enable_relay_client=allow_connection_through_relay,
209
- wait_public_reachability=os.getenv("NODE_WAIT_PUBLIC", "1") == "1",
212
+ knows_is_public=os.getenv("NODE_IS_PUBLIC", "0") == "1",
210
213
  port=int(os.getenv("NODE_STARTING_PORT", "0")))
211
214
 
212
215
  # Create another P2P node for the private world (it has fields 'addresses', and 'peer_id', and 'libp2p')
@@ -214,7 +217,7 @@ class Node:
214
217
  ips=None,
215
218
  enable_relay_service=offer_relay_facilities,
216
219
  enable_relay_client=allow_connection_through_relay,
217
- wait_public_reachability=os.getenv("NODE_WAIT_PUBLIC", "1") == "1",
220
+ knows_is_public=os.getenv("NODE_IS_PUBLIC", "0") == "1",
218
221
  port=(int(os.getenv("NODE_STARTING_PORT", "0")) + 3)
219
222
  if int(os.getenv("NODE_STARTING_PORT", "0")) > 0 else 0)
220
223
 
@@ -447,7 +450,6 @@ class Node:
447
450
  self.profile.get_dynamic_profile()})
448
451
  except Exception as e:
449
452
  self.err(f"Error while sending dynamic profile to from server [{e}]")
450
- raise GenException(f"Error while sending dynamic profile to from server [{e}]")
451
453
 
452
454
  def send_badges(self):
453
455
  """Sends new badges assigned by a world node to the root server and notifies the agents."""
@@ -768,8 +770,20 @@ class Node:
768
770
 
769
771
  # Main loop
770
772
  must_quit = False
773
+ self.run_start_time = self.clock.get_time()
771
774
  while not must_quit:
772
775
 
776
+ # Sending alive message every "K" seconds
777
+ if self.clock.get_time() - self.last_alive_time >= self.send_alive_every:
778
+ was_alive = self.send_alive()
779
+
780
+ # Checking only at the first run
781
+ if self.last_alive_time == 0 and was_alive and not self.skip_was_alive_check:
782
+ print(f"The node is already alive, maybe running in a different machine? "
783
+ f"(set env variable NODE_IGNORE_ALIVE=1 to ignore this control)")
784
+ break # Stopping the running cycle
785
+ self.last_alive_time = self.clock.get_time()
786
+
773
787
  # Check inspector
774
788
  if self.inspector_activated:
775
789
  if self.__inspector_told_to_pause:
@@ -916,17 +930,6 @@ class Node:
916
930
  self.get_node_token(peer_ids=[self.get_public_peer_id(), self.get_world_peer_id()])
917
931
  last_get_token_time = self.clock.get_time()
918
932
 
919
- # Sending alive message every "K" seconds
920
- if self.clock.get_time() - self.last_alive_time >= self.send_alive_every:
921
- was_alive = self.send_alive()
922
-
923
- # Checking only at the first run
924
- if self.last_alive_time == 0 and was_alive and not self.skip_was_alive_check:
925
- print(f"The node is already alive, maybe running in a different machine? "
926
- f"(set env variable NODE_IGNORE_ALIVE=1 to ignore this control)")
927
- break # Stopping the running cycle
928
- self.last_alive_time = self.clock.get_time()
929
-
930
933
  # Check for address changes every "N" seconds
931
934
  if self.clock.get_time() - last_address_check_time >= self.address_check_every:
932
935
  self.out("Performing periodic check for address changes...")
@@ -995,7 +998,7 @@ class Node:
995
998
  # Stop conditions
996
999
  if cycles is not None and ((self.clock.get_cycle() + 1) >= cycles):
997
1000
  break
998
- if max_time is not None and self.clock.get_time(passed=True) >= max_time:
1001
+ if max_time is not None and (self.clock.get_time() - self.run_start_time) >= max_time:
999
1002
  break
1000
1003
 
1001
1004
  except KeyboardInterrupt:
@@ -50,9 +50,20 @@ else: # Linux and other Unix-like
50
50
 
51
51
  lib_filename = f"{lib_name}{lib_ext}"
52
52
  lib_path = os.path.join(lib_dir, lib_filename)
53
- downloaded_shared_lib = None
54
53
 
55
- if not os.path.exists(lib_path):
54
+ if os.path.getmtime(go_source_file) > os.path.getmtime(lib_path):
55
+ print(f"INFO: Found a more recent Go source file, removing the existing library (if any)")
56
+ if os.path.exists(lib_path):
57
+ os.remove(lib_path)
58
+
59
+ # Possible states
60
+ shared_lib_was_downloaded = False
61
+ shared_lib_was_already_there = os.path.exists(lib_path)
62
+ must_recompile = False
63
+ reason_to_recompile = ""
64
+ _shared_lib = None # This is where the loaded library will stay
65
+
66
+ if not shared_lib_was_already_there:
56
67
  print(f"INFO: '{lib_filename}' not found. Attempting to automatically download it and save to '{lib_dir}'...")
57
68
  download_was_successful = False
58
69
  try:
@@ -65,20 +76,26 @@ if not os.path.exists(lib_path):
65
76
  download_was_successful = True
66
77
  print(f"INFO: Download complete")
67
78
  except Exception:
68
- print(f"INFO: Download failed, attempting to compile from source (requires a Go compiler)...")
79
+ pass
69
80
 
70
81
  if download_was_successful:
71
82
  try:
72
- downloaded_shared_lib = ctypes.CDLL(lib_path)
83
+ _shared_lib = ctypes.CDLL(lib_path)
84
+ shared_lib_was_downloaded = True
73
85
  except OSError as e:
74
- downloaded_shared_lib = None
86
+ _shared_lib = None
75
87
  if os.path.exists(lib_path):
76
88
  os.remove(lib_path)
77
- print(f"INFO: The downloaded library was not compatible with this platform and was deleted. "
78
- f"Attempting to compile from source (requires a Go compiler)...")
89
+ reason_to_recompile = "The downloaded library was not compatible with this platform and was deleted."
90
+ must_recompile = True
91
+ else:
92
+ reason_to_recompile = "Failed to download the library."
93
+ must_recompile = True
79
94
 
80
95
  # --- Automatically initialize Go module if needed ---
81
- if downloaded_shared_lib is None:
96
+ if must_recompile:
97
+ print(f"INFO: {reason_to_recompile}. Recompiling the libray - you need a Go compiler, or this procedure will fail "
98
+ f"(install it!)")
82
99
  if not os.path.exists(go_mod_file):
83
100
  print(f"INFO: 'go.mod' not found. Initializing Go module in '{lib_dir}'...")
84
101
  try:
@@ -106,28 +123,11 @@ if downloaded_shared_lib is None:
106
123
  )
107
124
  print("INFO: 'go.mod' and 'go.sum' created successfully.")
108
125
  except (subprocess.CalledProcessError, FileNotFoundError) as e:
109
- print("FATAL: Failed to initialize Go module.", file=sys.stderr)
110
- print("Please ensure Go is installed and in your system's PATH.", file=sys.stderr)
111
-
112
- # If 'go mod' failed, print its output for debugging
113
- if isinstance(e, subprocess.CalledProcessError):
114
- print(f"Go command stderr:\n{e.stderr}", file=sys.stderr)
126
+ print("FATAL: Failed to initialize Go module. Please ensure Go is installed and in your system's PATH.",
127
+ file=sys.stderr)
115
128
  raise e
116
129
 
117
- # --- Automatically build the shared library if it's missing or outdated ---
118
- rebuild_needed = False
119
- reason = ""
120
-
121
- if downloaded_shared_lib is None:
122
- if not os.path.exists(lib_path):
123
- rebuild_needed = True
124
- reason = f"the shared library '{lib_filename}' was not found."
125
- elif os.path.getmtime(go_source_file) > os.path.getmtime(lib_path):
126
- rebuild_needed = True
127
- reason = f"the last modification to '{go_source_file}' is more recent than the '{lib_filename}' last build."
128
-
129
- if rebuild_needed:
130
- print(f"INFO: Rebuilding shared library because {reason}")
130
+ # --- Automatically build the shared library if it's missing or outdated ---
131
131
  try:
132
132
  build_command = ["go", "build", "-buildmode=c-shared", "-ldflags", "-s -w", "-o", lib_filename, "lib.go"]
133
133
  print(f"Running command: {' '.join(build_command)}")
@@ -141,25 +141,18 @@ if rebuild_needed:
141
141
  if result.stdout:
142
142
  print(f"Go build stdout:\n{result.stdout}")
143
143
  print(f"INFO: Successfully built '{lib_filename}'.")
144
-
145
144
  except (subprocess.CalledProcessError, FileNotFoundError) as e:
146
- print(f"FATAL: Failed to build Go shared library.", file=sys.stderr)
147
- print("Please ensure Go is installed and in your system's PATH.", file=sys.stderr)
148
- if isinstance(e, subprocess.CalledProcessError):
149
- print(f"Go compiler stderr:\n{e.stderr}", file=sys.stderr)
145
+ print("FATAL: Failed to initialize Go module. Please ensure Go is installed and in your system's PATH.",
146
+ file=sys.stderr)
150
147
  raise e
151
148
 
152
- # --- Library Loading ---
153
- if downloaded_shared_lib is None:
149
+ # --- Library Loading (if not already downloaded and loaded-in-memory) ---
150
+ if _shared_lib is None:
154
151
  try:
155
152
  _shared_lib = ctypes.CDLL(lib_path)
156
-
157
- # Print(f"Successfully loaded Go library: {lib_path}")
158
153
  except OSError as e:
159
154
  print(f"Error loading shared library at {lib_path}: {e}", file=sys.stderr)
160
- raise
161
- else:
162
- _shared_lib = downloaded_shared_lib
155
+ raise e
163
156
 
164
157
  # --- Function Prototypes (argtypes and restype) ---
165
158
  # Using void* for returned C strings, requiring TypeInterface for conversion/freeing.
@@ -244,7 +237,6 @@ except ImportError:
244
237
  # Cast the loaded library object to the stub type
245
238
  _shared_lib_typed = cast(GoLibP2P, _shared_lib)
246
239
 
247
-
248
240
  # Attach the typed shared library object to the P2P class
249
241
  P2P.libp2p = _shared_lib_typed
250
242
  TypeInterface.libp2p = _shared_lib_typed # Attach to TypeInterface if needed
@@ -10,9 +10,9 @@ class GoLibP2P:
10
10
  """
11
11
  ...
12
12
 
13
- def CreateNode(self, instance: int, port: int, ips: List[str], enable_relay_client: int, enable_relay_service: int, wait_public_reachability: int, max_connections: int) -> bytes:
13
+ def CreateNode(self, instance: int, port: int, ips: List[str], enable_relay_client: int, enable_relay_service: int, knows_is_public: int, max_connections: int) -> bytes:
14
14
  """
15
- CreateNode(instance: int, port: int, ips: List[str], enable_relay_client: int, enable_relay_service: int, wait_public_reachability: int, max_connections: int) -> bytes
15
+ CreateNode(instance: int, port: int, ips: List[str], enable_relay_client: int, enable_relay_service: int, knows_is_public: int, max_connections: int) -> bytes
16
16
 
17
17
  Creates a node in the P2P network and returns a JSON string with node information.
18
18
  """
@@ -1137,7 +1137,7 @@ func InitializeLibrary(
1137
1137
  // - predefinedPortC (C.int): The TCP port to listen on (0 for random).
1138
1138
  // - enableRelayClientC (C.int): 1 if this node should enable relay communications (client mode)
1139
1139
  // - enableRelayServiceC (C.int): 1 to set this node as a relay service (server mode),
1140
- // - waitPublicC (C.int): 1 to try any possible attempt to be publicly reachable, 0 otherwise.
1140
+ // - knowsIsPublicC (C.int): 1 to assume public reachability, 0 otherwise (-> tries to assess it in any possible way).
1141
1141
  // - maxConnectionsC (C.int): The maximum number of connections this node can maintain.
1142
1142
  //
1143
1143
  // Returns:
@@ -1153,7 +1153,7 @@ func CreateNode(
1153
1153
  ipsJSONC *C.char,
1154
1154
  enableRelayClientC C.int,
1155
1155
  enableRelayServiceC C.int,
1156
- waitPublicC C.int,
1156
+ knowsIsPublicC C.int,
1157
1157
  maxConnectionsC C.int,
1158
1158
  ) *C.char {
1159
1159
 
@@ -1190,11 +1190,11 @@ func CreateNode(
1190
1190
  ipsJSON := C.GoString(ipsJSONC)
1191
1191
  enableRelayClient := int(enableRelayClientC) == 1
1192
1192
  enableRelayService := int(enableRelayServiceC) == 1
1193
- waitPublic := int(waitPublicC) == 1
1193
+ knowsIsPublic := int(knowsIsPublicC) == 1
1194
1194
  maxConnections := int(maxConnectionsC)
1195
1195
 
1196
- log.Printf("[GO] 🔧 Instance %d: Config: Port=%d, IPsJSON=%s, EnableRelayClient=%t, EnableRelayService=%t, WaitToBePublic=%t, MaxConnections=%d",
1197
- instanceIndex, predefinedPort, ipsJSON, enableRelayClient, enableRelayService, waitPublic, maxConnections)
1196
+ log.Printf("[GO] 🔧 Instance %d: Config: Port=%d, IPsJSON=%s, EnableRelayClient=%t, EnableRelayService=%t, KnowsIsPublic=%t, MaxConnections=%d",
1197
+ instanceIndex, predefinedPort, ipsJSON, enableRelayClient, enableRelayService, knowsIsPublic, maxConnections)
1198
1198
 
1199
1199
  // --- 4. Libp2p Options Assembly ---
1200
1200
  listenAddrs, err := getListenAddrs(ipsJSON, predefinedPort)
@@ -1246,7 +1246,7 @@ func CreateNode(
1246
1246
  // Prepare discovering the bootstrap peers
1247
1247
  var idht *dht.IpfsDHT
1248
1248
  isPublic := false
1249
- if waitPublic {
1249
+ if !knowsIsPublic {
1250
1250
  // Add any possible option to be publicly reachable
1251
1251
  options = append(
1252
1252
  options,
@@ -1266,11 +1266,8 @@ func CreateNode(
1266
1266
  }),)
1267
1267
  log.Printf("[GO] - Instance %d: Trying to be publicly reachable.\n", instanceIndex)
1268
1268
  } else {
1269
- if enableRelayService {
1270
- // If not trying to be public, we can set the reachability to public to consent local deployment and relay exploitation.
1271
- options = append(options, libp2p.ForceReachabilityPublic())
1272
- isPublic = true // We assume it's public if we are a relay service and not trying to be public ourselves.
1273
- }
1269
+ options = append(options, libp2p.ForceReachabilityPublic())
1270
+ isPublic = true
1274
1271
  }
1275
1272
 
1276
1273
  // Create the libp2p Host instance with the configured options for this instance.
@@ -1300,9 +1297,9 @@ func CreateNode(
1300
1297
  // Give discovery mechanisms a moment to find the public address.
1301
1298
  log.Printf("[GO] ⏳ Instance %d: Waiting for address discovery and NAT to settle...\n", instanceIndex)
1302
1299
 
1303
- if waitPublic {
1300
+ if !knowsIsPublic {
1304
1301
  // --- 🎯 : Wait for Public Reachability ---
1305
- // This replaces your old address polling loop. We wait a maximum of 30 seconds.
1302
+ // This replaces the old address polling loop. We wait a maximum of 30 seconds.
1306
1303
  isPublic = waitForPublicReachability(instanceHost, 30*time.Second)
1307
1304
  if !isPublic {
1308
1305
  log.Printf("[GO] ⚠️ Instance %d: The node may not be directly dialable.", instanceIndex)
@@ -89,7 +89,7 @@ class P2P:
89
89
 
90
90
  # Configure Python logging based on the flag
91
91
  if not enable_logging:
92
- logger.setLevel(logging.WARNING)
92
+ logger.setLevel(logging.CRITICAL)
93
93
  else:
94
94
  logger.setLevel(logging.INFO)
95
95
 
@@ -124,7 +124,7 @@ class P2P:
124
124
  ips: List[str] = None,
125
125
  enable_relay_client: bool = True,
126
126
  enable_relay_service: bool = False,
127
- wait_public_reachability: bool = False,
127
+ knows_is_public: bool = False,
128
128
  max_connections: int = 1000,
129
129
  ) -> None:
130
130
  """
@@ -135,7 +135,7 @@ class P2P:
135
135
  ips: A list of specific IP addresses to listen on. Defaults to ["0.0.0.0"].
136
136
  enable_relay_client: Enable listening to relayed connections for this node.
137
137
  enable_relay_service: Enable relay service capabilities for this node.
138
- wait_public_reachability: Tries every possible attempt to make the node publicly reachable (UPnP, HolePunching, AutoNat via DHT...).
138
+ knows_is_public: If you already know that the node is public this forces its public reachability. Otherwise it tries every possible attempt to make the node publicly reachable (UPnP, HolePunching, AutoNat via DHT...).
139
139
  max_connections: Maximum number of connections this node can handle.
140
140
 
141
141
  Raises:
@@ -168,7 +168,7 @@ class P2P:
168
168
  self._ips = ips if ips is not None else []
169
169
  self._enable_relay_client = enable_relay_client or enable_relay_service
170
170
  self._enable_relay_service = enable_relay_service
171
- self._wait_public_reachability = wait_public_reachability
171
+ self._knows_is_public = knows_is_public
172
172
  self._max_connections = max_connections
173
173
  self._peer_id: Optional[str] = None
174
174
  self._peer_map: Dict[str, Any] = {} # Map to store peer info {peer_id: info}
@@ -185,7 +185,7 @@ class P2P:
185
185
  P2P._type_interface.to_go_json(self._ips),
186
186
  P2P._type_interface.to_go_bool(enable_relay_client),
187
187
  P2P._type_interface.to_go_bool(enable_relay_service),
188
- P2P._type_interface.to_go_bool(wait_public_reachability),
188
+ P2P._type_interface.to_go_bool(knows_is_public),
189
189
  P2P._type_interface.to_go_int(max_connections),
190
190
  )
191
191
  result = P2P._type_interface.from_go_ptr_to_json(result_ptr)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: unaiverse
3
- Version: 0.1.0
3
+ Version: 0.1.1
4
4
  Summary: UNaIVERSE: A Collectionless AI Project. The new web of humans & AI Agents, built on privacy, control, and reduced energy consumption.
5
5
  Author-email: Stefano Melacci <stefano.melacci@unisi.it>, Christian Di Maio <christian.dimaio@phd.unipi.it>, Tommaso Guidi <tommaso.guidi.1998@gmail.com>
6
6
  Maintainer-email: Stefano Melacci <stefano.melacci@unisi.it>, Christian Di Maio <christian.dimaio@phd.unipi.it>, Tommaso Guidi <tommaso.guidi.1998@gmail.com>
@@ -18,18 +18,18 @@ unaiverse/modules/hl/hl_utils.py,sha256=Xt2eWuwak6kDtTy2hQ1Ps8_M_REtte9HA-PzfCov
18
18
  unaiverse/networking/__init__.py,sha256=qc3A8KJpTLFM6hefwmqj-wAaUULtzXivaXsr-xKKYGU,2460
19
19
  unaiverse/networking/node/__init__.py,sha256=DEXbZzPt7dgall1TZKODuQIXhjq3lr39QCBISGUSWww,2508
20
20
  unaiverse/networking/node/connpool.py,sha256=hctRoYYGZA2D7sy1elIgE7o4umm8B9dZKq-QI0bgE24,52726
21
- unaiverse/networking/node/node.py,sha256=Yk1jKT1kGyN27rGdgMt3UI1yBWtleB481r3Rvgn_qsM,117718
21
+ unaiverse/networking/node/node.py,sha256=q740PylBIqHm6jKN32A1_meYUhbmHdDWmZ9ySJ7sMkY,117733
22
22
  unaiverse/networking/node/profile.py,sha256=lbB35MoI20oDxDqb97zH2NNNUCGJs8-8KIGNjjmnTio,20203
23
23
  unaiverse/networking/node/tokens.py,sha256=UHyPnl6TDvPitrkP2AYAIegSWq4CpvsjRvmio3T-3nA,5281
24
- unaiverse/networking/p2p/__init__.py,sha256=3pnA6pda8iBnrjmSdfQE0nIonl46jV_VAKSUbzfwskc,12427
24
+ unaiverse/networking/p2p/__init__.py,sha256=miT4Jp08mUgUFOYh9uyV0ZpTrd3N0trX3GBwTaEpuw8,12027
25
25
  unaiverse/networking/p2p/golibp2p.py,sha256=ibVCLERzM2JgPP_A5FTooCoxYW5Zm2HBbzX28aQIFzo,2450
26
- unaiverse/networking/p2p/golibp2p.pyi,sha256=htLy7CDtTJrFQ3Hd8_Az4TXPIcuKeFzlXvJOBKXLmpI,4097
27
- unaiverse/networking/p2p/lib.go,sha256=NSOYlUr8_7spZ5KJxXqwmTn8Ynsh0OlmWE9Ci4nO4Io,108903
26
+ unaiverse/networking/p2p/golibp2p.pyi,sha256=ri7ZL8LQHx2rnwhXmQ9q2RiaTXeU6nitw1lB_L5Bhq4,4079
27
+ unaiverse/networking/p2p/lib.go,sha256=l40IsZEC4a70LfJr8qzl8YDuh-fAcOaqaMPDLNG7IkI,108699
28
28
  unaiverse/networking/p2p/lib_types.py,sha256=b7NJmN636o-X3TEWdp4YVIJ9Snr8AGT0GUuaYITZ6PY,13956
29
29
  unaiverse/networking/p2p/message_pb2.py,sha256=-kEXvIYJZqGOh47i5e7qYHZdsKJ5uQtfDVQrnrAewCg,5697
30
30
  unaiverse/networking/p2p/messages.py,sha256=6fN-3INvnUoWu_YwQPfx4WRx8DD7LEOu511nRWKI-fM,12287
31
31
  unaiverse/networking/p2p/mylogger.py,sha256=-WW6qT39rptXwUlpQg1BuU7u8o9MKLF_-Cbe7EaQKsc,4773
32
- unaiverse/networking/p2p/p2p.py,sha256=k7gz71Pdtt9CUWqqManH9rKOKWmQVKKzRERfsgkIda0,47020
32
+ unaiverse/networking/p2p/p2p.py,sha256=JSGhIBmz4KMsC0RfkvgQS-7Tu5QveW1sYwDmTuwBHSU,47070
33
33
  unaiverse/streamlib/__init__.py,sha256=VpsL7-gwML7nbrMQumtEDpuEH4g7iNqQaCzd-zX49cQ,2447
34
34
  unaiverse/streamlib/streamlib.py,sha256=yz6G8eez3VnF_fvA9G3KS-WCoLvPYlk0IdqdB9dDzOI,10366
35
35
  unaiverse/utils/__init__.py,sha256=_iomQ_GviAS5c4ZVBrm1h_rLYWH-f-T9SI-b0697gn0,2464
@@ -38,8 +38,8 @@ unaiverse/utils/lone_wolf.json,sha256=_rHfeqV8gqvPc0h-cZF7mPCG0Z4HuVkV-mKoXXwjbN
38
38
  unaiverse/utils/misc.py,sha256=4J3HotzosgsnEr9MgeuQmdrrISPuKl85oOAuKAfcz-U,12085
39
39
  unaiverse/utils/sandbox.py,sha256=S_eocNIGTyckovYMxmWb56wsCG7M-mxmGHqdLavSWQA,14436
40
40
  unaiverse/utils/server.py,sha256=hCxHTNmYGrgGYrwZ5RaQ9kdmmfqWuIVTUdPYLCwpTQU,21974
41
- unaiverse-0.1.0.dist-info/licenses/LICENSE,sha256=02v7juVPTazXHV7TG9WtaWrtmeC3BAd49itKH_SiHOs,1396
42
- unaiverse-0.1.0.dist-info/METADATA,sha256=Mtu8lB9_zq3N3FoNLJZJEYhFsazxBTRKWAVgL9PnEPQ,18212
43
- unaiverse-0.1.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
44
- unaiverse-0.1.0.dist-info/top_level.txt,sha256=0rP09tH9hv17TDQs66OHbJaRSnADpZsDsODy6JVsTtw,10
45
- unaiverse-0.1.0.dist-info/RECORD,,
41
+ unaiverse-0.1.1.dist-info/licenses/LICENSE,sha256=02v7juVPTazXHV7TG9WtaWrtmeC3BAd49itKH_SiHOs,1396
42
+ unaiverse-0.1.1.dist-info/METADATA,sha256=wze9o2fuWikX1Bcv8mJq_eduX1-_zaeDKSElyN4-KyI,18212
43
+ unaiverse-0.1.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
44
+ unaiverse-0.1.1.dist-info/top_level.txt,sha256=0rP09tH9hv17TDQs66OHbJaRSnADpZsDsODy6JVsTtw,10
45
+ unaiverse-0.1.1.dist-info/RECORD,,