Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Ahmad Reza Cheraghi
swarm-sim
Commits
b3028f02
Commit
b3028f02
authored
Apr 12, 2019
by
Ahmad Reza
Browse files
some code cleaning based on the results of sonarqube
parent
26633e17
Changes
11
Expand all
Hide whitespace changes
Inline
Side-by-side
config.ini
View file @
b3028f02
...
...
@@ -43,8 +43,8 @@ tile_mm_size = 2
##Examples##
##Moving
scenario
=
lonely_particle
.py
solution
=
random_walk
.py
scenario
=
lonely_particle
solution
=
random_walk
#solution = round_walk.py
## Creating and Deleting
...
...
lib/gnuplot_generator.py
View file @
b3028f02
...
...
@@ -12,7 +12,6 @@ def generate_gnuplot(directory):
plot
.
stdin
.
write
(
'set xlabel "Rounds"
\n
'
)
for
bla
in
data
.
columns
:
if
i
>=
5
:
# bla="Location"
plot
.
stdin
.
write
(
'set ylabel "%s"
\n
'
%
(
bla
))
plot
.
stdin
.
write
(
"set output '"
+
directory
+
"/rounds_%s.png'
\n
"
%
(
bla
))
plot
.
stdin
.
write
(
"set term png giant size 800,600 font 'Helvetica,20'
\n
"
)
...
...
@@ -32,7 +31,6 @@ def generate_gnuplot(directory):
plot
.
stdin
.
write
(
'set xlabel "Particle"
\n
'
)
for
bla
in
data
.
columns
:
if
i
>=
3
:
# bla="Location"
plot
.
stdin
.
write
(
'set ylabel "%s"
\n
'
%
(
bla
))
plot
.
stdin
.
write
(
"set term png giant size 800,600 font 'Helvetica,20'
\n
"
)
plot
.
stdin
.
write
(
"set output '"
+
directory
+
"/particle_%s.png'
\n
"
%
(
bla
))
...
...
lib/matter.py
View file @
b3028f02
...
...
@@ -119,13 +119,6 @@ class Matter():
if
(
self
.
mm_limit
==
True
and
len
(
self
.
_memory
)
<
self
.
mm_size
)
or
not
self
.
mm_limit
:
self
.
_memory
[
key
]
=
data
self
.
sim
.
csv_round_writer
.
update_metrics
(
memory_write
=
1
)
# if self.memory_delay == True:
# self._tmp_memory[key] = data
# print("Wrote data at ", self.sim.sim.get_actual_round())
# self.memory_buffer[self.sim.sim.get_actual_round()+self.memory_delay_time] = self._tmp_memory.copy()
# self._tmp_memory.clear()
# else:
# self._memory[key] = data
return
True
else
:
return
False
...
...
lib/particle.py
View file @
b3028f02
This diff is collapsed.
Click to expand it.
lib/sim.py
View file @
b3028f02
...
...
@@ -40,10 +40,7 @@ blue = 5
class
Sim
:
def
__init__
(
self
,
seed
=
1
,
max_round
=
10
,
solution
=
"None"
,
size_x
=
0
,
size_y
=
0
,
scenario_name
=
None
,
max_particles
=
50
,
mm_limitation
=
False
,
particle_mm_size
=
0
,
tile_mm_size
=
0
,
location_mm_size
=
0
,
dir
=
""
,
random_order
=
False
,
visualization
=
False
,
border
=
0
,
window_size_x
=
600
,
window_size_y
=
800
):
def
__init__
(
self
,
config_data
):
"""
Initializing the sim constructor
:param seed: seed number for new random numbers
...
...
@@ -56,14 +53,14 @@ class Sim:
:param seed: the seed number it is only used here for the csv file
:param max_particles: the maximal number of particles that are allowed to be or created in this sim
"""
random
.
seed
(
seed
)
self
.
__max_round
=
max_round
random
.
seed
(
config_data
.
seedvalue
)
self
.
__max_round
=
config_data
.
max_round
self
.
__round_counter
=
1
self
.
__seed
=
seed
self
.
__solution
=
solution
self
.
solution_mod
=
importlib
.
import_module
(
'solution.'
+
solution
)
self
.
__seed
=
config_data
.
seedvalue
self
.
__solution
=
config_data
.
solution
self
.
solution_mod
=
importlib
.
import_module
(
'solution.'
+
config_data
.
solution
)
self
.
__end
=
False
self
.
mm_limitation
=
mm_limitation
self
.
mm_limitation
=
config_data
.
mm_limitation
self
.
init_particles
=
[]
self
.
particle_num
=
0
self
.
particles
=
[]
...
...
@@ -71,7 +68,7 @@ class Sim:
self
.
particle_rm
=
[]
self
.
particle_map_coords
=
{}
self
.
particle_map_id
=
{}
self
.
particle_mm_size
=
particle_mm_size
self
.
particle_mm_size
=
config_data
.
particle_mm_size
self
.
__particle_deleted
=
False
self
.
tiles_num
=
0
self
.
tiles
=
[]
...
...
@@ -81,32 +78,33 @@ class Sim:
self
.
tile_map_id
=
{}
self
.
__tile_deleted
=
False
self
.
new_tile_flag
=
False
self
.
tile_mm_size
=
tile_mm_size
self
.
tile_mm_size
=
config_data
.
tile_mm_size
self
.
locations_num
=
0
self
.
locations
=
[]
self
.
locations_created
=
[]
self
.
location_map_coords
=
{}
self
.
location_map_id
=
{}
self
.
locations_rm
=
[]
self
.
location_mm_size
=
location_mm_size
self
.
location_mm_size
=
config_data
.
location_mm_size
self
.
__location_deleted
=
False
self
.
new_tile
=
None
self
.
__size_x
=
size_x
self
.
__size_y
=
size_y
self
.
max_particles
=
max_particles
self
.
directory
=
dir
self
.
visualization
=
visualization
self
.
window_size_x
=
window_size_x
self
.
window_size_y
=
window_size_y
self
.
border
=
border
self
.
csv_round_writer
=
csv_generator
.
CsvRoundData
(
self
,
solution
=
solution
.
rsplit
(
'.'
,
1
)[
0
],
seed
=
seed
,
self
.
__size_x
=
config_data
.
size_x
self
.
__size_y
=
config_data
.
size_y
self
.
max_particles
=
config_data
.
max_particles
self
.
directory
=
config_data
.
dir_name
self
.
visualization
=
config_data
.
visualization
self
.
window_size_x
=
config_data
.
window_size_x
self
.
window_size_y
=
config_data
.
window_size_y
self
.
border
=
config_data
.
border
self
.
csv_round_writer
=
csv_generator
.
CsvRoundData
(
self
,
scenario
=
config_data
.
scenario
,
solution
=
self
.
solution_mod
,
seed
=
config_data
.
seedvalue
,
tiles_num
=
0
,
particle_num
=
0
,
steps
=
0
,
directory
=
dir
)
steps
=
0
,
directory
=
self
.
directory
)
mod
=
importlib
.
import_module
(
'scenario.'
+
scenario_name
.
rsplit
(
'.'
,
1
)[
0
]
)
mod
=
importlib
.
import_module
(
'scenario.'
+
config_data
.
scenario
)
mod
.
scenario
(
self
)
if
random_order
:
if
config_data
.
random_order
:
random
.
shuffle
(
self
.
particles
)
...
...
@@ -127,10 +125,10 @@ class Sim:
#creating gnu plots
self
.
csv_round_writer
.
aggregate_metrics
()
particle
File
=
csv_generator
.
CsvParticleFile
(
self
.
directory
)
particle
_csv
=
csv_generator
.
CsvParticleFile
(
self
.
directory
)
for
particle
in
self
.
init_particles
:
particle
File
.
write_particle
(
particle
)
particle
File
.
csv_file
.
close
()
particle
_csv
.
write_particle
(
particle
)
particle
_csv
.
csv_file
.
close
()
generate_gnuplot
(
self
.
directory
)
return
...
...
@@ -420,7 +418,6 @@ class Sim:
if
coords
in
self
.
particle_map_coords
:
self
.
particles
.
remove
(
self
.
particle_map_coords
[
coords
])
self
.
particle_rm
.
append
(
self
.
particle_map_coords
[
coords
])
# del self.tile_map_coords[rm_tile.coords]
try
:
# cher: added so the program does not crashed if it does not find any entries in the map
del
self
.
particle_map_id
[
self
.
particle_map_coords
[
coords
].
get_id
()]
except
KeyError
:
...
...
@@ -506,7 +503,6 @@ class Sim:
self
.
tiles
.
remove
(
rm_tile
)
self
.
tiles_rm
.
append
(
rm_tile
)
logging
.
info
(
"Deleted tile with tile id %s on %s"
,
str
(
rm_tile
.
get_id
()),
str
(
rm_tile
.
coords
)
)
# del self.tile_map_coords[rm_tile.coords]
try
:
# cher: added so the program does not crashed if it does not find any entries in the map
del
self
.
tile_map_id
[
rm_tile
.
get_id
()]
except
KeyError
:
...
...
@@ -532,7 +528,6 @@ class Sim:
if
coords
in
self
.
tile_map_coords
:
self
.
tiles
.
remove
(
self
.
tile_map_coords
[
coords
])
self
.
tiles_rm
.
append
(
self
.
tile_map_coords
[
coords
])
# del self.tile_map_coords[rm_tile.coords]
try
:
# cher: added so the program does not crashed if it does not find any entries in the map
del
self
.
tile_map_id
[
self
.
tile_map_coords
[
coords
].
get_id
()]
except
KeyError
:
...
...
lib/vis.py
View file @
b3028f02
...
...
@@ -315,7 +315,7 @@ class VisWindow(pyglet.window.Window):
tile_alpha
=
1
else
:
texLeft
=
7
/
8
texRight
=
8
/
8
texRight
=
1
# 8/
8
texBottom
=
4
/
8
texTop
=
5
/
8
tile_alpha
=
0.5
...
...
@@ -407,7 +407,7 @@ class VisWindow(pyglet.window.Window):
self
.
location_vertex_list
.
vertices
[
8
*
i
:
8
*
i
+
8
]
=
[
x
-
weird
,
y
-
weird
,
x
+
weird
,
y
-
weird
,
x
+
weird
,
y
+
weird
,
x
-
weird
,
y
+
weird
]
texLeft
=
7
/
8
texRight
=
8
/
8
texRight
=
1
#
8/8
texBottom
=
0
/
8
texTop
=
1
/
8
...
...
multiple.py
View file @
b3028f02
...
...
@@ -6,19 +6,13 @@ import configparser
def
main
(
argv
):
max_round
=
2000
seedvalue
=
1
0
seedvalue
=
1
config
=
configparser
.
ConfigParser
(
allow_no_value
=
True
)
config
.
read
(
"config.ini"
)
try
:
scenario_file
=
config
.
get
(
"File"
,
"scenario"
)
except
(
configparser
.
NoOptionError
)
as
noe
:
scenario_file
=
"init_scenario.py"
scenario
=
config
.
get
(
"File"
,
"scenario"
)
try
:
solution_file
=
config
.
get
(
"File"
,
"solution"
)
except
(
configparser
.
NoOptionError
)
as
noe
:
solution_file
=
"solution.py"
nTime
=
datetime
.
now
().
strftime
(
'%Y-%m-%d_%H:%M:%S'
)[:
-
1
]
solution
=
config
.
get
(
"File"
,
"solution"
)
local_time
=
datetime
.
now
().
strftime
(
'%Y-%m-%d_%H:%M:%S'
)[:
-
1
]
try
:
opts
,
args
=
getopt
.
getopt
(
argv
,
"hs:w:r:n:v:"
,
[
"scenaro="
,
"solution="
])
except
getopt
.
GetoptError
:
...
...
@@ -29,30 +23,32 @@ def main(argv):
print
(
'multiple.py -r <randomeSeed> -w <scenario> -s <solution> -n <maxRounds>'
)
sys
.
exit
()
elif
opt
in
(
"-s"
,
"--solution"
):
solution
_file
=
arg
solution
=
arg
elif
opt
in
(
"-w"
,
"--scenario"
):
s
im_file
=
arg
s
cenario
=
arg
elif
opt
in
(
"-r"
,
"--seed"
):
seedvalue
=
int
(
arg
)
elif
opt
in
(
"-n"
,
"--maxrounds"
):
max_round
=
int
(
arg
)
round
=
1
dir
=
"./outputs/mulitple/"
+
str
(
nTime
)
+
"_"
+
scenario_file
.
rsplit
(
'.'
,
1
)[
0
]
+
"_"
+
\
solution_file
.
rsplit
(
'.'
,
1
)[
0
]
dir
=
"./outputs/mulitple/"
+
str
(
local_time
)
+
\
"_"
+
scenario
+
"_"
+
\
solution
if
not
os
.
path
.
exists
(
dir
):
os
.
makedirs
(
dir
)
out
=
open
(
dir
+
"/multiprocess.txt"
,
"w"
)
child_processes
=
[]
for
seed
in
range
(
1
,
seedvalue
+
1
):
process
=
"python3.6"
,
"run.py"
,
"-n"
+
str
(
max_round
),
"-m 1"
,
"-d"
+
str
(
nTime
),
\
"-r"
+
str
(
seed
),
"-v"
+
str
(
0
)
p
=
subprocess
.
Popen
(
process
,
stdout
=
out
,
stderr
=
out
)
process
=
"python3.6"
,
"run.py"
,
"-w"
+
scenario
,
"-s"
+
solution
\
,
"-n"
+
str
(
max_round
),
"-m 1"
,
"-d"
+
str
(
local_time
),
\
"-r"
+
str
(
seed
),
"-v"
+
str
(
0
)
p
=
subprocess
.
call
(
process
,
stdout
=
out
,
stderr
=
out
)
print
(
"Round Nr. "
,
round
,
"finished"
)
child_processes
.
append
(
p
)
round
+=
1
for
cp
in
child_processes
:
cp
.
wait
()
#
#
for cp in child_processes:
#
cp.wait()
fout
=
open
(
dir
+
"/all_aggregates.csv"
,
"w+"
)
...
...
run.py
View file @
b3028f02
...
...
@@ -10,40 +10,44 @@ from datetime import datetime
from
lib
import
sim
def
swarm_sim
(
argv
):
class
ConfigData
():
def
__init__
(
self
,
config
):
self
.
seedvalue
=
config
.
getint
(
"Simulator"
,
"seedvalue"
)
self
.
max_round
=
config
.
getint
(
"Simulator"
,
"max_round"
)
self
.
random_order
=
config
.
getboolean
(
"Simulator"
,
"random_order"
)
self
.
visualization
=
config
.
getint
(
"Simulator"
,
"visualization"
)
try
:
self
.
scenario
=
config
.
get
(
"File"
,
"scenario"
)
except
(
configparser
.
NoOptionError
)
as
noe
:
self
.
scenario
=
"init_scenario.py"
try
:
self
.
solution
=
config
.
get
(
"File"
,
"solution"
)
except
(
configparser
.
NoOptionError
)
as
noe
:
self
.
solution
=
"solution.py"
self
.
size_x
=
config
.
getint
(
"Simulator"
,
"size_x"
)
self
.
size_y
=
config
.
getint
(
"Simulator"
,
"size_y"
)
self
.
window_size_x
=
config
.
getint
(
"Simulator"
,
"window_size_x"
)
self
.
window_size_y
=
config
.
getint
(
"Simulator"
,
"window_size_y"
)
self
.
border
=
config
.
getint
(
"Simulator"
,
"border"
)
self
.
max_particles
=
config
.
getint
(
"Simulator"
,
"max_particles"
)
self
.
mm_limitation
=
config
.
getboolean
(
"Matter"
,
"mm_limitation"
)
self
.
particle_mm_size
=
config
.
getint
(
"Matter"
,
"particle_mm_size"
)
self
.
tile_mm_size
=
config
.
getint
(
"Matter"
,
"tile_mm_size"
)
self
.
location_mm_size
=
config
.
getint
(
"Matter"
,
"location_mm_size"
)
self
.
dir_name
=
None
def
swarm_sim
(
argv
):
"""In the main function first the config is getting parsed and than
the simulator and the sim object is created. Afterwards the run method of the simulator
is called in which the simlator is going to start to run"""
config
=
configparser
.
ConfigParser
(
allow_no_value
=
True
)
config
.
read
(
"config.ini"
)
seedvalue
=
config
.
getint
(
"Simulator"
,
"seedvalue"
)
max_round
=
config
.
getint
(
"Simulator"
,
"max_round"
)
random_order
=
config
.
getboolean
(
"Simulator"
,
"random_order"
)
visualization
=
config
.
getint
(
"Simulator"
,
"visualization"
)
try
:
scenario_file
=
config
.
get
(
"File"
,
"scenario"
)
except
(
configparser
.
NoOptionError
)
as
noe
:
scenario_file
=
"init_scenario.py"
try
:
solution_file
=
config
.
get
(
"File"
,
"solution"
)
except
(
configparser
.
NoOptionError
)
as
noe
:
solution_file
=
"solution.py"
size_x
=
config
.
getint
(
"Simulator"
,
"size_x"
)
size_y
=
config
.
getint
(
"Simulator"
,
"size_y"
)
window_size_x
=
config
.
getint
(
"Simulator"
,
"window_size_x"
)
window_size_y
=
config
.
getint
(
"Simulator"
,
"window_size_y"
)
border
=
config
.
getint
(
"Simulator"
,
"border"
)
max_particles
=
config
.
getint
(
"Simulator"
,
"max_particles"
)
mm_limitation
=
config
.
getboolean
(
"Matter"
,
"mm_limitation"
)
mm_particle
=
config
.
getint
(
"Matter"
,
"particle_mm_size"
)
mm_tile
=
config
.
getint
(
"Matter"
,
"tile_mm_size"
)
mm_location
=
config
.
getint
(
"Matter"
,
"location_mm_size"
)
# tile_color_map = config.getboolean("Matter", "tile_color_map")
config_data
=
ConfigData
(
config
)
multiple_sim
=
0
local_time
=
datetime
.
now
().
strftime
(
'%Y-%m-%d_%H:%M:%S'
)[:
-
1
]
try
:
opts
,
args
=
getopt
.
getopt
(
argv
,
"hs:w:r:n:m:d:v:"
,
[
"solution="
,
"scenario="
])
except
getopt
.
GetoptError
:
...
...
@@ -54,49 +58,42 @@ def swarm_sim(argv):
print
(
'run.py -r <randomeSeed> -w <scenario> -s <solution> -n <maxRounds>'
)
sys
.
exit
()
elif
opt
in
(
"-s"
,
"--solution"
):
solution
_file
=
arg
config_data
.
solution
=
arg
elif
opt
in
(
"-w"
,
"--scenario"
):
scenario
_file
=
arg
config_data
.
scenario
=
arg
elif
opt
in
(
"-r"
,
"--seed"
):
seedvalue
=
int
(
arg
)
config_data
.
seedvalue
=
int
(
arg
)
elif
opt
in
(
"-n"
,
"--maxrounds"
):
max_round
=
int
(
arg
)
config_data
.
max_round
=
int
(
arg
)
elif
opt
in
(
"-m"
):
multiple_sim
=
int
(
arg
)
elif
opt
in
(
"-v"
):
visualization
=
int
(
arg
)
config_data
.
visualization
=
int
(
arg
)
elif
opt
in
(
"-d"
):
act_date
=
arg
local_time
=
str
(
arg
)
#logging.basicConfig(filename='myapp.log', filemode='w', level=logging.INFO, format='%(asctime)s %(message)s')
logging
.
basicConfig
(
filename
=
'system.log'
,
filemode
=
'w'
,
level
=
logging
.
INFO
,
format
=
'%(message)s'
)
nTime
=
datetime
.
now
().
strftime
(
'%Y-%m-%d_%H-%M-%S-%f'
)[:
-
1
]
dir_name
=
nTime
+
"_"
+
scenario_file
.
rsplit
(
'.'
,
1
)[
0
]
+
"_"
+
solution_file
.
rsplit
(
'.'
,
1
)[
0
]
+
"_"
+
\
str
(
seedvalue
)
if
multiple_sim
==
1
:
directory
=
"./outputs/mulitple/"
+
act_date
+
"_"
+
scenario_file
.
rsplit
(
'.'
,
1
)[
0
]
+
\
"_"
+
solution_file
.
rsplit
(
'.'
,
1
)[
0
]
+
"/"
+
str
(
seedvalue
)
else
:
directory
=
"./outputs/"
+
dir_name
if
not
os
.
path
.
exists
(
directory
):
os
.
makedirs
(
directory
)
config_data
.
dir_name
=
local_time
+
"_"
+
config_data
.
scenario
.
rsplit
(
'.'
,
1
)[
0
]
+
\
"_"
+
config_data
.
solution
.
rsplit
(
'.'
,
1
)[
0
]
+
"/"
+
\
str
(
config_data
.
seedvalue
)
config_data
.
dir_name
=
"./outputs/mulitple/"
+
config_data
.
dir_name
else
:
config_data
.
dir_name
=
local_time
+
"_"
+
config_data
.
scenario
.
rsplit
(
'.'
,
1
)[
0
]
+
\
"_"
+
config_data
.
solution
.
rsplit
(
'.'
,
1
)[
0
]
+
"_"
+
\
str
(
config_data
.
seedvalue
)
config_data
.
dir_name
=
"./outputs/"
+
config_data
.
dir_name
if
not
os
.
path
.
exists
(
config_data
.
dir_name
):
os
.
makedirs
(
config_data
.
dir_name
)
logging
.
info
(
'Started'
)
simulator
=
sim
.
Sim
(
seed
=
seedvalue
,
max_round
=
max_round
,
solution
=
solution_file
.
rsplit
(
'.'
,
1
)[
0
],
size_x
=
size_x
,
size_y
=
size_y
,
scenario_name
=
scenario_file
,
max_particles
=
max_particles
,
mm_limitation
=
mm_limitation
,
particle_mm_size
=
mm_particle
,
tile_mm_size
=
mm_tile
,
location_mm_size
=
mm_location
,
dir
=
directory
,
random_order
=
random_order
,
visualization
=
visualization
,
border
=
border
,
window_size_x
=
window_size_x
,
window_size_y
=
window_size_y
,)
simulator
=
sim
.
Sim
(
config_data
)
simulator
.
run
()
logging
.
info
(
'Finished'
)
...
...
scenario/lonely_particle.py
View file @
b3028f02
def
scenario
(
sim
):
sim
.
add_particle
(
0
,
0
)
#sim.add_tile(0, 0)
# sim.add_tile(-1, 0)
# sim.add_tile(-1.5, 1)
# sim.add_tile(-0.5, 1)
solution/read_write.py
View file @
b3028f02
...
...
@@ -36,7 +36,6 @@ def read_write( sim):
sim
.
get_particle_list
()[
0
].
write_to_with
(
sim
.
get_particle_list
()[
1
],
"particle4"
,
"test6"
)
loc_data
=
sim
.
get_particle_list
()[
0
].
read_from_with
(
sim
.
locations
[
0
],
"location"
)
tile_data
=
sim
.
get_particle_list
()[
0
].
read_from_with
(
sim
.
tiles
[
0
],
"tile"
)
#part_data = sim.get_particle_list()[0].read_from_with(sim.get_particle_list()[1], "particle")
if
loc_data
!=
0
:
print
(
loc_data
)
if
tile_data
!=
0
:
...
...
system.log
View file @
b3028f02
Started
Created particle at (0, 0)
particle 004c01aa-9ff8-46d3-ac8e-3fa32f051d44 successfully moved to 3
particle 004c01aa-9ff8-46d3-ac8e-3fa32f051d44 successfully moved to 2
particle 004c01aa-9ff8-46d3-ac8e-3fa32f051d44 successfully moved to 5
particle 004c01aa-9ff8-46d3-ac8e-3fa32f051d44 successfully moved to 4
particle 004c01aa-9ff8-46d3-ac8e-3fa32f051d44 successfully moved to 5
particle 004c01aa-9ff8-46d3-ac8e-3fa32f051d44 successfully moved to 2
particle 004c01aa-9ff8-46d3-ac8e-3fa32f051d44 successfully moved to 1
particle 004c01aa-9ff8-46d3-ac8e-3fa32f051d44 successfully moved to 3
particle 004c01aa-9ff8-46d3-ac8e-3fa32f051d44 successfully moved to 0
particle 004c01aa-9ff8-46d3-ac8e-3fa32f051d44 successfully moved to 2
particle 004c01aa-9ff8-46d3-ac8e-3fa32f051d44 successfully moved to 3
particle 004c01aa-9ff8-46d3-ac8e-3fa32f051d44 successfully moved to 2
particle f25d2af6-c038-4835-89ff-10590203b91d successfully moved to 3
particle f25d2af6-c038-4835-89ff-10590203b91d successfully moved to 2
particle f25d2af6-c038-4835-89ff-10590203b91d successfully moved to 5
particle f25d2af6-c038-4835-89ff-10590203b91d successfully moved to 4
particle f25d2af6-c038-4835-89ff-10590203b91d successfully moved to 5
particle f25d2af6-c038-4835-89ff-10590203b91d successfully moved to 2
particle f25d2af6-c038-4835-89ff-10590203b91d successfully moved to 1
particle f25d2af6-c038-4835-89ff-10590203b91d successfully moved to 3
particle f25d2af6-c038-4835-89ff-10590203b91d successfully moved to 0
particle f25d2af6-c038-4835-89ff-10590203b91d successfully moved to 2
particle f25d2af6-c038-4835-89ff-10590203b91d successfully moved to 3
particle f25d2af6-c038-4835-89ff-10590203b91d successfully moved to 2
particle f25d2af6-c038-4835-89ff-10590203b91d successfully moved to 5
particle f25d2af6-c038-4835-89ff-10590203b91d successfully moved to 3
particle f25d2af6-c038-4835-89ff-10590203b91d successfully moved to 5
Finished
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment