pyerualjetwork 4.5.2b0__py3-none-any.whl → 4.6b0__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.
@@ -19,11 +19,11 @@ import math
19
19
 
20
20
 
21
21
  ### LIBRARY IMPORTS ###
22
- from .data_operations_cuda import normalization, non_neg_normalization
22
+ from .data_operations_cuda import normalization, non_neg_normalization, split_nested_arrays, reconstruct_nested_arrays
23
23
  from .ui import loading_bars, initialize_loading_bar
24
24
  from .activation_functions_cuda import apply_activation, all_activations
25
25
 
26
- def define_genomes(input_shape, output_shape, population_size, dtype=cp.float32):
26
+ def define_genomes(input_shape, output_shape, population_size, hidden=0, neurons=None, activation_functions=None, dtype=cp.float32):
27
27
  """
28
28
  Initializes a population of genomes, where each genome is represented by a set of weights
29
29
  and an associated activation function. Each genome is created with random weights and activation
@@ -36,6 +36,12 @@ def define_genomes(input_shape, output_shape, population_size, dtype=cp.float32)
36
36
  output_shape (int): The number of output features for the neural network.
37
37
 
38
38
  population_size (int): The number of genomes (individuals) in the population.
39
+
40
+ hidden (int, optional): If you dont want train PLAN model this parameter represents a hidden layer count for MLP model. Default: 0 (PLAN)
41
+
42
+ neurons (list[int], optional): If you dont want train PLAN model this parameter represents neuron count of each hidden layer for MLP. Default: None (PLAN)
43
+
44
+ activation_functions (list[str], optional): If you dont want train PLAN model this parameter represents activation function of each hidden layer for MLP. Default: None (PLAN) NOTE: THIS EFFECTS HIDDEN LAYERS OUTPUT. NOT OUTPUT LAYER!
39
45
 
40
46
  dtype (cupy.dtype): Data type for the arrays. np.float32 by default. Example: cp.float64 or cp.float16.
41
47
 
@@ -51,25 +57,57 @@ def define_genomes(input_shape, output_shape, population_size, dtype=cp.float32)
51
57
  The weights for each genome are then modified by applying the corresponding activation function
52
58
  and normalized using the `normalization()` function. (Max abs normalization.)
53
59
  """
54
- population_weights = [0] * population_size
55
- population_activations = [0] * population_size
60
+ if hidden > 0:
61
+ population_weights = [[0] * (hidden + 1) for _ in range(population_size)]
62
+ population_activations = [[0] * (hidden) for _ in range(population_size)]
63
+
64
+ if len(neurons) != hidden:
65
+ raise ValueError('hidden parameter and neurons list length must be equal.')
66
+
56
67
 
57
- except_this = ['spiral', 'circular']
58
- activations = [item for item in all_activations() if item not in except_this] # SPIRAL AND CIRCULAR ACTIVATION DISCARDED
68
+ for i in range(len(population_weights)):
69
+
70
+ for l in range(hidden + 1):
71
+
72
+ if l == 0:
73
+ population_weights[i][l] = cp.random.uniform(-1, 1, (neurons[l], input_shape)).astype(dtype)
74
+
75
+ elif l == hidden:
76
+ population_weights[i][l] = cp.random.uniform(-1, 1, (output_shape, neurons[l-1])).astype(dtype)
77
+
78
+ else:
79
+ population_weights[i][l] = cp.random.uniform(-1, 1, (neurons[l], neurons[l-1])).astype(dtype)
80
+
81
+ if l != hidden:
82
+ population_activations[i][l] = activation_functions[l]
83
+
84
+ # ACTIVATIONS APPLYING IN WEIGHTS SPECIFIC OUTPUT CONNECTIONS (MORE PLAN LIKE FEATURES(FOR NON-LINEARITY)):
85
+
86
+ for j in range(population_weights[i][l].shape[0]):
87
+
88
+ population_weights[i][l][j,:] = apply_activation(population_weights[i][l][j,:], population_activations[i])
89
+ population_weights[i][l][j,:] = normalization(population_weights[i][l][j,:], dtype=dtype)
90
+
91
+ else:
92
+ population_weights = [0] * population_size
93
+ population_activations = [0] * population_size
94
+
95
+ except_this = ['spiral', 'circular']
96
+ activations = [item for item in all_activations() if item not in except_this] # SPIRAL AND CIRCULAR ACTIVATION DISCARDED
59
97
 
60
- for i in range(len(population_weights)):
98
+ for i in range(len(population_weights)):
61
99
 
62
- population_weights[i] = cp.random.uniform(-1, 1, (output_shape, input_shape)).astype(dtype, copy=False)
63
- population_activations[i] = activations[int(random.uniform(0, len(activations)-1))]
100
+ population_weights[i] = cp.random.uniform(-1, 1, (output_shape, input_shape)).astype(dtype, copy=False)
101
+ population_activations[i] = activations[int(random.uniform(0, len(activations)-1))]
64
102
 
65
- # ACTIVATIONS APPLYING IN WEIGHTS SPECIFIC OUTPUT CONNECTIONS (MORE PLAN LIKE FEATURES(FOR NON-LINEARITY)):
103
+ # ACTIVATIONS APPLYING IN WEIGHTS SPECIFIC OUTPUT CONNECTIONS (MORE PLAN LIKE FEATURES(FOR NON-LINEARITY)):
66
104
 
67
- for j in range(population_weights[i].shape[0]):
105
+ for j in range(population_weights[i].shape[0]):
68
106
 
69
- population_weights[i][j,:] = apply_activation(population_weights[i][j,:], population_activations[i])
70
- population_weights[i][j,:] = normalization(population_weights[i][j,:], dtype=dtype)
107
+ population_weights[i][j,:] = apply_activation(population_weights[i][j,:], population_activations[i])
108
+ population_weights[i][j,:] = normalization(population_weights[i][j,:], dtype=dtype)
71
109
 
72
- return cp.array(population_weights, dtype=dtype), population_activations
110
+ return population_weights, population_activations
73
111
 
74
112
 
75
113
  def evolver(weights,
@@ -90,11 +128,12 @@ def evolver(weights,
90
128
  activation_mutate_change_prob=0.5,
91
129
  activation_selection_add_prob=0.5,
92
130
  activation_selection_change_prob=0.5,
93
- activation_selection_threshold=2,
131
+ activation_selection_threshold=20,
94
132
  activation_mutate_prob=1,
95
- activation_mutate_threshold=2,
133
+ activation_mutate_threshold=20,
96
134
  weight_mutate_threshold=16,
97
- weight_mutate_prob=1,
135
+ weight_mutate_prob=1,
136
+ is_mlp=False,
98
137
  dtype=cp.float32):
99
138
  """
100
139
  Applies the evolving process of a population of genomes using selection, crossover, mutation, and activation function potentiation.
@@ -107,8 +146,8 @@ def evolver(weights,
107
146
  weights (cupy.ndarray): Array of weights for each genome.
108
147
  (first returned value of define_genomes function)
109
148
 
110
- activation_potentiations (list): A list of activation functions for each genome.
111
- (second returned value of define_genomes function)
149
+ activation_potentiations (list[str]): A list of activation functions for each genome.
150
+ (second returned value of define_genomes function) NOTE!: 'activation potentiations' for PLAN 'activation functions' for MLP.
112
151
 
113
152
  what_gen (int): The current generation number, used for informational purposes or logging.
114
153
 
@@ -177,9 +216,11 @@ def evolver(weights,
177
216
  activation_selection_change_prob (float, optional): The probability of changing an activation function in the genome for crossover.
178
217
  Must be in the range [0, 1]. Default is 0.5.
179
218
 
180
- activation_mutate_threshold (int): Determines max how much activation mutaiton operation applying. (Function automaticly determines to min) Default: 2
219
+ activation_mutate_threshold (int): Determines max how much activation mutaiton operation applying. (Function automaticly determines to min) Default: 20
181
220
 
182
- activation_selection_threshold (int, optional): Determines max how much activaton transferable to child from undominant parent. (Function automaticly determines to min) Default: 2
221
+ activation_selection_threshold (int, optional): Determines max how much activaton transferable to child from undominant parent. (Function automaticly determines to min) Default: 20
222
+
223
+ is_mlp (bool, optional): Evolve PLAN model or MLP model ? Default: False (PLAN)
183
224
 
184
225
  dtype (cupy.dtype): Data type for the arrays. Default: cp.float32.
185
226
  Example: cp.float64 or cp.float16 [fp32 for balanced devices, fp64 for strong devices, fp16 for weak devices: not recommended!].
@@ -218,7 +259,7 @@ def evolver(weights,
218
259
 
219
260
  Example:
220
261
  ```python
221
- weights, activation_potentiations = planeat.evolver(weights, activation_potentiations, 1, fitness, show_info=True, strategy='normal_selective', policy='aggressive')
262
+ weights, activation_potentiations = planeat_cuda.evolver(weights, activation_potentiations, 1, fitness, show_info=True, strategy='normal_selective', policy='aggressive')
222
263
  ```
223
264
 
224
265
  - The function returns the updated weights and activations after processing based on the chosen strategy, policy, and mutation parameters.
@@ -267,6 +308,34 @@ def evolver(weights,
267
308
 
268
309
  if weight_evolve is False: origin_weights = cp.copy(weights)
269
310
 
311
+ if is_mlp: ### IF EACH GENOME HAVE MORE THEN 1 WEIGHT MATRIX IT IS NOT PLAN MODEL. IT IS MLP MODEL.
312
+
313
+ activations = activation_potentiations.copy()
314
+
315
+ return mlp_evolver(weights,
316
+ activations,
317
+ what_gen,
318
+ dtype,
319
+ fitness,
320
+ policy,
321
+ bad_genomes_selection_prob,
322
+ bar_status,
323
+ strategy,
324
+ bad_genomes_mutation_prob,
325
+ fitness_bias,
326
+ cross_over_mode,
327
+ activation_mutate_change_prob,
328
+ activation_selection_change_prob,
329
+ activation_selection_threshold,
330
+ activation_mutate_prob,
331
+ activation_mutate_threshold,
332
+ weight_mutate_threshold,
333
+ show_info,
334
+ weight_mutate_prob,
335
+ )
336
+
337
+ if isinstance(weights, list): weights = cp.array(weights, dtype=dtype)
338
+
270
339
  ### FITNESS LIST IS SORTED IN ASCENDING ORDER, AND THE WEIGHT AND ACTIVATIONS OF EACH GENOME ARE SORTED ACCORDING TO THIS ORDER:
271
340
 
272
341
  sort_indices = cp.argsort(fitness)
@@ -408,14 +477,14 @@ def evolver(weights,
408
477
  return weights, activation_potentiations
409
478
 
410
479
 
411
- def evaluate(x_population, weights, activation_potentiations):
480
+ def evaluate(Input, weights, activation_potentiations, is_mlp=False):
412
481
  """
413
482
  Evaluates the performance of a population of genomes, applying different activation functions
414
483
  and weights depending on whether reinforcement learning mode is enabled or not.
415
484
 
416
485
  Args:
417
- x_population (list or cupy.ndarray): A list or 2D numpy or cupy array where each element represents
418
- a genome (A list of input features for each genome, or a single set of input features for one genome (only in rl_mode)).
486
+ Input (list or cupy.ndarray): A list or 2D numpy or cupy array where each element represents
487
+ a genome (A list of input features for each genome, or a single set of input features for one genome).
419
488
 
420
489
  weights (list or cupy.ndarray): A list or 2D numpy array of weights corresponding to each genome
421
490
  in `x_population`. This determines the strength of connections.
@@ -423,17 +492,19 @@ def evaluate(x_population, weights, activation_potentiations):
423
492
  activation_potentiations (list or str): A list where each entry represents an activation function
424
493
  or a potentiation strategy applied to each genome. If only one
425
494
  activation function is used, this can be a single string.
495
+ is_mlp (bool, optional): Evaluate PLAN model or MLP model ? Default: False (PLAN)
496
+
426
497
  Returns:
427
498
  list: A list of outputs corresponding to each genome in the population after applying the respective
428
499
  activation function and weights.
429
500
 
430
501
  Example:
431
502
  ```python
432
- outputs = evaluate(x_population, weights, activation_potentiations)
503
+ outputs = evaluate(Input, weights, activation_potentiations)
433
504
  ```
434
505
 
435
506
  - The function returns a list of outputs after processing the population, where each element corresponds to
436
- the output for each genome in `x_population`.
507
+ the output for each genome in population.
437
508
  """
438
509
  ### THE OUTPUTS ARE RETURNED WHERE EACH GENOME'S OUTPUT MATCHES ITS INDEX:
439
510
 
@@ -442,11 +513,80 @@ def evaluate(x_population, weights, activation_potentiations):
442
513
  else:
443
514
  activation_potentiations = [item if isinstance(item, list) else [item] for item in activation_potentiations]
444
515
 
445
- x_population = apply_activation(x_population, activation_potentiations)
446
- result = x_population @ weights.T
516
+ if is_mlp:
517
+
518
+ layer = Input
519
+ for i in range(len(weights)):
520
+ if i != len(weights) - 1: layer = apply_activation(layer, activation_potentiations[i])
521
+ layer = layer @ weights[i].T
522
+
523
+ return layer
524
+
525
+ else:
447
526
 
448
- return result
527
+ Input = apply_activation(Input, activation_potentiations)
528
+ result = Input @ weights.T
529
+
530
+ return result
531
+
532
+ def mlp_evolver(weights,
533
+ activations,
534
+ generation,
535
+ dtype,
536
+ fitness,
537
+ policy,
538
+ bad_genomes_selection_prob,
539
+ bar_status,
540
+ strategy,
541
+ bad_genomes_mutation_prob,
542
+ fitness_bias,
543
+ cross_over_mode,
544
+ activation_mutate_change_prob,
545
+ activation_selection_change_prob,
546
+ activation_selection_threshold,
547
+ activation_mutate_prob,
548
+ activation_mutate_threshold,
549
+ weight_mutate_threshold,
550
+ show_info,
551
+ weight_mutate_prob,
552
+ ):
553
+
554
+ weights = split_nested_arrays(weights)
449
555
 
556
+ for layer in range(len(weights)):
557
+ if show_info == True:
558
+ if layer == len(weights) - 1:
559
+ show = True
560
+ else:
561
+ show = False
562
+ else:
563
+ show = False
564
+
565
+ weights[layer], activations = evolver(weights[layer], activations,
566
+ fitness=fitness,
567
+ what_gen=generation,
568
+ show_info=show,
569
+ policy=policy,
570
+ bad_genomes_selection_prob=bad_genomes_selection_prob,
571
+ bar_status=bar_status,
572
+ strategy=strategy,
573
+ bad_genomes_mutation_prob=bad_genomes_mutation_prob,
574
+ fitness_bias=fitness_bias,
575
+ cross_over_mode=cross_over_mode,
576
+ activation_mutate_add_prob=0,
577
+ activation_mutate_delete_prob=0,
578
+ activation_mutate_change_prob=activation_mutate_change_prob,
579
+ activation_selection_add_prob=0,
580
+ activation_selection_change_prob=activation_selection_change_prob,
581
+ activation_selection_threshold=activation_selection_threshold,
582
+ activation_mutate_prob=activation_mutate_prob,
583
+ activation_mutate_threshold=activation_mutate_threshold,
584
+ weight_mutate_threshold=weight_mutate_threshold,
585
+ weight_mutate_prob=weight_mutate_prob,
586
+ dtype=dtype
587
+ )
588
+
589
+ return reconstruct_nested_arrays(weights), activations
450
590
 
451
591
  def cross_over(first_parent_W,
452
592
  second_parent_W,
@@ -603,7 +743,7 @@ def cross_over(first_parent_W,
603
743
 
604
744
  while True:
605
745
 
606
- random_index = int(random.uniform(0, len(undominant_parent_act)-1))
746
+ random_index = int(random.uniform(0, len(undominant_parent_act)))
607
747
  random_undominant_activation = undominant_parent_act[random_index]
608
748
 
609
749
  child_act.append(random_undominant_activation)
@@ -625,8 +765,8 @@ def cross_over(first_parent_W,
625
765
 
626
766
  while True:
627
767
 
628
- random_index_undominant = int(random.uniform(0, len(undominant_parent_act)-1))
629
- random_index_dominant = int(random.uniform(0, len(dominant_parent_act)-1))
768
+ random_index_undominant = int(random.uniform(0, len(undominant_parent_act)))
769
+ random_index_dominant = int(random.uniform(0, len(dominant_parent_act)))
630
770
  random_undominant_activation = undominant_parent_act[random_index_undominant]
631
771
 
632
772
  child_act[random_index_dominant] = random_undominant_activation
@@ -749,7 +889,7 @@ def mutation(weight,
749
889
 
750
890
  if potential_activation_delete_prob > activation_delete_prob and len(activations) > 1:
751
891
 
752
- random_index = random.randint(0, len(activations) - 1)
892
+ random_index = random.randint(0, len(activations))
753
893
  activations.pop(random_index)
754
894
 
755
895
 
@@ -757,7 +897,7 @@ def mutation(weight,
757
897
 
758
898
  try:
759
899
 
760
- random_index_all_act = int(random.uniform(0, len(all_acts)-1))
900
+ random_index_all_act = int(random.uniform(0, len(all_acts)))
761
901
  activations.append(all_acts[random_index_all_act])
762
902
 
763
903
  except:
@@ -766,12 +906,12 @@ def mutation(weight,
766
906
  activations = []
767
907
 
768
908
  activations.append(activation)
769
- activations.append(all_acts[int(random.uniform(0, len(all_acts)-1))])
909
+ activations.append(all_acts[int(random.uniform(0, len(all_acts)))])
770
910
 
771
911
  if potential_activation_change_prob > activation_change_prob:
772
912
 
773
- random_index_all_act = int(random.uniform(0, len(all_acts)-1))
774
- random_index_genom_act = int(random.uniform(0, len(activations)-1))
913
+ random_index_all_act = int(random.uniform(0, len(all_acts)))
914
+ random_index_genom_act = int(random.uniform(0, len(activations)))
775
915
 
776
916
  activations[random_index_genom_act] = all_acts[random_index_all_act]
777
917
 
@@ -786,7 +926,7 @@ def mutation(weight,
786
926
  def second_parent_selection(good_weights, bad_weights, good_activations, bad_activations, bad_genomes_selection_prob):
787
927
 
788
928
  selection_prob = random.uniform(0, 1)
789
- random_index = int(random.uniform(0, len(good_weights) - 1))
929
+ random_index = int(random.uniform(0, len(good_weights)))
790
930
 
791
931
  if selection_prob > bad_genomes_selection_prob:
792
932
  second_selected_W = good_weights[random_index]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pyerualjetwork
3
- Version: 4.5.2b0
3
+ Version: 4.6b0
4
4
  Summary: PyerualJetwork is a machine learning library supported with GPU(CUDA) acceleration written in Python for professionals and researchers including with PLAN algorithm, PLANEAT algorithm (genetic optimization). Also includes data pre-process and memory manegament
5
5
  Author: Hasan Can Beydili
6
6
  Author-email: tchasancan@gmail.com
@@ -1,8 +1,8 @@
1
- pyerualjetwork/__init__.py,sha256=4sn4PeP5OH6s4k1M-rZDt1RlahliTEVJ-5Bg3wyGIk0,1281
1
+ pyerualjetwork/__init__.py,sha256=KLgnJmN6LoSApf-e8QKuNBxyBM3QqRZOSsUEVy5jL58,1279
2
2
  pyerualjetwork/activation_functions.py,sha256=Ms0AGBqkJuCA42ht64MSQnO54Td_1eDGquedpoBDVbc,7642
3
3
  pyerualjetwork/activation_functions_cuda.py,sha256=5y1Ti3GDfDteQDCUmODwe7tAyDAUlDTKmIikChQ8d6g,7772
4
- pyerualjetwork/data_operations.py,sha256=Y_RdxkjLEszFgeo4VDWIX1keF2syP-88KesLXA5sRyY,15280
5
- pyerualjetwork/data_operations_cuda.py,sha256=9tyD3Bbv5__stuUampgh3_GbMhb_kmTTJmZi7BJsvuA,17381
4
+ pyerualjetwork/data_operations.py,sha256=TxfpwHWUpJ2E7IVF2uSmigrwpVL_JxrvGPOrMg2lNuI,15981
5
+ pyerualjetwork/data_operations_cuda.py,sha256=5e8EO-XRplSmmXcZJxxEISdxO3297ShsAKHswTh3kGQ,18084
6
6
  pyerualjetwork/fitness_functions.py,sha256=urRdeMvUhNgWxD4ZGHCRdQlIf9cTWYMvF3_aVBojRqY,1235
7
7
  pyerualjetwork/help.py,sha256=nQ_YbYA2RtuafhuvkreNpX0WWL1I_nzlelwCtvei0_Y,775
8
8
  pyerualjetwork/loss_functions.py,sha256=6PyBI232SQRGuFnG3LDGvnv_PUdWzT2_2mUODJiejGI,618
@@ -10,16 +10,16 @@ pyerualjetwork/loss_functions_cuda.py,sha256=C93IZJcrOpT6HMK9x1O4AHJWXYTkN5WZiqd
10
10
  pyerualjetwork/memory_operations.py,sha256=0yCOHcgiNyF4ccMcRlL1Q9F_byG4nzjhmkbpXE_yU6E,13401
11
11
  pyerualjetwork/metrics.py,sha256=q7MkhnZDRbCjFBDDfUgrl8lBYnUT_1ro1LxeBq105pI,6077
12
12
  pyerualjetwork/metrics_cuda.py,sha256=73h9GC7XwmnFCVzFEEiPQfF8CwHIz2wsCbxpZrJtYgw,5061
13
- pyerualjetwork/model_operations.py,sha256=BLRL_5s_KSs8iCiLsEwWvhRcGiWCP_TD9lsjYWM7Zek,12746
14
- pyerualjetwork/model_operations_cuda.py,sha256=b3Bkobbrhq28AmYZ0vGxf2Hf8V2LPvoiM0xaPAApqec,13254
13
+ pyerualjetwork/model_operations.py,sha256=aARz97TFaVX5lkdKSV-4cp3OT0KSiRUYO7ktpfCmr44,14854
14
+ pyerualjetwork/model_operations_cuda.py,sha256=ZpnqaJYNb8Wyc5htEY0qXcZA4N9LLPDiHEBjrIqvGCI,15745
15
15
  pyerualjetwork/plan.py,sha256=UyIvPmvHCHwczlc9KHolE4y6CPEeBfhnRN5yznSbnoM,23028
16
16
  pyerualjetwork/plan_cuda.py,sha256=iteqgv7x9Z2Pj4vGOZs6HXS3r0bNaF_smr7ZXaOdRnw,23990
17
- pyerualjetwork/planeat.py,sha256=_dnGRVBzdRUgvVCnHZ721tdXYV9PSvCz-aUnj--5VpU,38697
18
- pyerualjetwork/planeat_cuda.py,sha256=CXBF4vsTZ-fE-3W8Zc6Zxe_oKuyJS02FaHsOzSwzLV8,38731
17
+ pyerualjetwork/planeat.py,sha256=RjTB2GN1Dp6Qbm6w5iDCEIR056KzQc4vyJ06Gce0iWQ,45193
18
+ pyerualjetwork/planeat_cuda.py,sha256=cIkrjT9rjeyKhcrv3x_YXYqr2yeKe8yC1VblFqULg88,45241
19
19
  pyerualjetwork/ui.py,sha256=JBTFYz5R24XwNKhA3GSW-oYAoiIBxAE3kFGXkvm5gqw,656
20
20
  pyerualjetwork/visualizations.py,sha256=utnX9zQhzmtvBJLOLNGm2jecVVk4zHXABQdjb0XzJac,28352
21
21
  pyerualjetwork/visualizations_cuda.py,sha256=gnoaaazZ-nc9E1ImqXrZBRgQ4Rnpi2qh2yGJ2eLKMlE,28807
22
- pyerualjetwork-4.5.2b0.dist-info/METADATA,sha256=NR5_4DsomrEJETWRlfpcIDaAJtlipTDe4rhI-DZ4h4o,7507
23
- pyerualjetwork-4.5.2b0.dist-info/WHEEL,sha256=2wepM1nk4DS4eFpYrW1TTqPcoGNfHhhO_i5m4cOimbo,92
24
- pyerualjetwork-4.5.2b0.dist-info/top_level.txt,sha256=BRyt62U_r3ZmJpj-wXNOoA345Bzamrj6RbaWsyW4tRg,15
25
- pyerualjetwork-4.5.2b0.dist-info/RECORD,,
22
+ pyerualjetwork-4.6b0.dist-info/METADATA,sha256=xS9cCvZpXLGKrVHK0VSQP49HnPKeN5PoyDSscUXzDDo,7505
23
+ pyerualjetwork-4.6b0.dist-info/WHEEL,sha256=2wepM1nk4DS4eFpYrW1TTqPcoGNfHhhO_i5m4cOimbo,92
24
+ pyerualjetwork-4.6b0.dist-info/top_level.txt,sha256=BRyt62U_r3ZmJpj-wXNOoA345Bzamrj6RbaWsyW4tRg,15
25
+ pyerualjetwork-4.6b0.dist-info/RECORD,,