►
From YouTube: ROS 2 Security Working Group (2020-09-08)
Description
Meeting notes: https://wiki.ros.org/ROS2/WorkingGroups/Security
A
Just
one
administrative
note:
before
we
start
joe
mcmanus
is
a
long
journey.
A
Oh
you
got
it
okay,
so
joe
mcmanus
is
no
longer
with
canonical
so
I'll,
be
leading
the
working
group
with
kyle,
so
we'll
just
continue
moving
that
along.
A
So
with
that,
I
think
we'll
we'll
just
dig
right
in
and
mikhail,
if
you're
good,
with
just
giving
us
an
overview
of
how
system
tests
work.
I
know
we've
had
a
lot
of
interest
in
that.
C
B
Can
you
guys
see
my
screen
now?
Yep
perfect,
all
right?
That's
awesome,
yeah,
so
on
on
a
note
related
to
that,
but
maybe
we
like
discuss
and
make
a
decision
and
decision
later.
B
Originally
all
the
test
security
stuff
was
part
of
this
big
package
that
was
test
communication
used
for
testing
all
the
various
configuration
of
communication
in
ras2
and
test
security
has
been
pulled
out
as
a
separate
package,
but
keeping
like
most
of
the
structure
of
the
original
package,
and
I
think
basically,
this
working
group
are
the
only
people
like
impacted
by
these
tests
and
like
following
up
on
them.
B
So
maybe
we'll
see,
but
maybe
it
would
make
sense
to
move
that
closer
to
srs2
or
to
a
repository
where
the
working
group
can
act
on
it
more
easily
and
watch
it
more
closely
than
a
repo.
That's
watched
mostly
by
the
roster
team.
B
Yeah,
mostly
yeah,
because
it's
it's
based
on
that,
we
can
have
a
look
quickly,
but
so
one
thing
that
we
could
change
among
the
many
other
things
that
could
change
is
the
fact
that
this
is
right
now,
testing
c,
plus
plus
nodes,
which
is
not
that
big
of
an
issue.
But
so
we
have
like
a
set
of
dependencies
on
rcmcbp,
etc.
B
D
C
D
To
give
an
overview
to
folks
who,
who
are
probably
I
mean-
I
I'm
not
going
to
pretend
to
be
super
familiar
with
this?
This
is
the
whole
reason
mikhail
is
is
presenting
this,
but
correct
me
if
I'm
wrong
mikhail,
but
but
these
these
are
essentially
integration
level
tests
right.
So
we
have.
We
have
individual
security
tests
that
are
more
the
unit
level
in
the
sros
2
utilities
repo,
but
these
are
the
things
that
actually
make
sure
that
security
features
work
across
across
dds
vendors
and
actually
actually
runs
nodes
and
tests
to
communications.
Yes,.
B
That's
exactly
right,
so
the
the
system
test,
repo
in
ros2
is
for
all
the
integration,
level,
testing
and
and
so
yeah.
The
test
security
is
basically
spawning
nodes
in
different
processes
and
making
them
talk
with
security
and
making
sure
that
messages
are
coming
across
and
messages
that
shouldn't
come
across.
Don't
and
that
kind
of
thing.
B
So
we
are
basically
like,
let's
say
two
main
types
of
tests
there.
One
which
is
mostly
captured
in
this
file
is
making
sure
that
configurations
that
should
not
work
do
not
work.
B
B
So
the
main
things
we're
testing
here
is
invalid,
keystores,
with
a
set
of
configs.
So
basically
we
say:
okay
like
here,
are
the
things
you're
gonna
pass
as
the
key
stoppers
and,
and
so
we
have
like
some
of
them
that
are
like
okay.
This
is
going
to
be
the
keystone
path.
This
is
your
security
or
not.
This
is
a
security
strategy.
B
And
so
this
is
mostly
to
test
all
the
cases
that
should
not
work,
so
we're
basically
expecting
nodes
to
not
work
with
those,
and
then
we
have
a
bunch
of
tests
that
try
like
a
more
multiple
node
level
kind
of
thing.
So
we
basically
have
a
test,
secure,
publisher
and
a
secure
subscriber,
and
these
basically
just
spawn
a
regular
node
and
so
on.
The
publisher
side
try
to
like
reset
all
the
environment
variable
and
we
try
to
publish.
B
We
have
some
configuration
here
on
being
able
to
test
a
variety
of
messages.
The
main
goal
of
this
and
test
communication
was
to
be
able
to
test
all
the
messages
in
text
messages
and
this
package
test
messages
is
supposed
to
be
covering
every
possible
configuration
of
ros
msg
files.
So
it's
using
every
kind
of
primitive,
every
kind
of
nesting,
multiple
nesting,
these
kind
of
things
nice.
B
Currently
we
test
only
a
very
small
subset
of
that,
mostly
because
it
takes
a
long
time,
and
so
we
cannot
really
afford
to
run
all
these
because
it
will
take
forever
and
and
so
yeah.
Here
it's
always
the
same
configuration
we
basically
give
it
the
enclave
we
want,
which
is
basically
the
same
by
default,
and
then
what?
What
is
the
name
of
the
node?
What
is
the
name
of
the
topic?
And
we
just
try
to
publish.
B
On
the
subscriber
side,
it's
more
of
the
same
thing.
We
basically
expect
a
set
of
messages
to
be
received,
so
we
subscribe
to
the
topic
we
trigger,
like
we
get
this
callback
instantiated.
That
just
gives
us
the
messages
that
are
received
and
we
make
sure
that
basically,
we
receive
all
the
message
received
are
part
of
the
expected
set
and
and
so
that
we
don't
receive
any
unexpected
message.
B
B
So
all
these
are
like
fixtures,
which
is
just
like
okay.
I
expect
all
these
messages
when
I
subscribe
to
an
empty
topic.
I
expect
all
these
messages
when
I
subscribe
to
basic
types-
and
that's
basically
it
where
it
gets
a
bit
trickier,
is
that
we
want
to
be
able
to
test
this
with
all
rmw
implementations
and,
ideally
with
all
client
libraries
and
so
to
generate
those
tests.
We
have.
B
Where
it
gets
messy
and
that's
where
I
think
I
didn't
have
time,
I
was
hoping
to
do
it
before
this
meeting,
because
the
current
state
of
test
security
is
testing
only
c
plus
plus
nodes
and
we're
not
doing
cross
vendor
testing
which,
mostly
because
up
until,
like
recently
I
haven't
tried
recently
but
up
until
a
year
ago,
various
dds
vendors
were
not
able
to
speak
to
each
other
with
security
enabled.
C
So,
michael,
you
know
there
is
an
internal
probability
test
at
the
point
for
security
right.
B
Yeah
yeah,
so
actually
I
mean
refinism
the
color
as
well
like,
even
if
the
interoperability
tests
were
passing
so
far,
we
weren't
able
to
get
like
this
lost
level
testing
to
pass,
and
I
think
the
reasons
are
varied
over
time.
There
may
still
be
an
issue
open
and
roughing.
Like
you,
you
looked
into
that.
B
Like
I
mean
I
guess
it
was
two
years
ago,
but
up
until
a
year
ago
we
couldn't
get
it
working
between
rti
connects
and
fast
rtps,
which
were
the
only
two
that
were
supported
like
they
were
supporting
security
and
supported
by
ras2
and
recently.
I
think
something
that
may
also
be
an
issue.
If
I
remember
correctly,
we
had
an
issue
with
recent
open
ssl
in
first
rtps
and
the
fix
for
that
has
been
for
first
rtps
to
change
the
key
exchange
mechanism.
B
Yeah
and
like,
if
you
give
me
a
chance
like
I,
I
didn't
look
at
that
for
a
long
time
so
like
I
want
to
be
sure
that
I'm
giving
you
correct
information
but
but
yeah.
So
I
I
guess
I
can
check
and
maybe
I
think,
with
raffin
as
well.
That
has
been
looking
into
that
to
make
sure
that,
like
what
are
the
issues
we're
facing
today,
not
to
point
you
to
all
the
issues
that
may
have
irrelevant
error
messages
and
I'll
get
back
to
you.
D
B
No,
so
the
logic,
basically
the
logic,
I
wrote
the
project
for
test
communication
that
was
not
using
security
and
so
and
then
all
that
cma
logic
has
been
copied
over
to
test
security.
Okay,
do
the
test
security,
repo,
like
package,
and
so
so
there
is
a
cmake
infrastructure
to
be
able
to
generate
cross
vendor
tests,
but
we've
never
done
it
for
security
because
empirically
we
couldn't
get
it
to
work.
So
we
never
enabled
it
yeah.
D
B
B
Yeah,
so
I
did.
I
didn't
look
at
those
recently,
but
I
remember
that's
what
we
were
basing
on
originally
when
we're
testing
with
ruffin
but
yeah.
So
I
don't
remember
why
we
couldn't
get
it
to
work
for
us
too,
and
that's
part
of
why
I
don't
want
to
tell
you
it's
because
of
that,
because
I
I
may
give
you
false
information.
C
Another
thing
is:
isn't
it
that
some
rmw
implementations
have
slightly
different
mappings,
or
was
that
ever
I
remember
like
rti.
C
B
B
Yeah,
I
think,
I'm
not
sure
that's
the
case
anymore,
but
it
it
was
indeed
the
case
where,
like
rti,
was
implementing
dds
remote
protocol
like
rpcs
and
and
so
that's
what
was
used
for
services,
and
it
was
not
the
case
for
openspace
and
faster
tps
at
the
time.
So,
basically,
the
rmw
layer
was
implementing
above
topics
the
logic
for
services,
but
for
as
far
as
individual
topics
are
concerned,
it
shouldn't
be
impacting.
C
Cross
vendors
testing
of
like
non-security
so
like
you
had
two
tests,
one's
the
security
ones,
that's
non-security
and
you
get
your
full
matrix
and
you
can
see
like
these.
Two
vendors
work,
fine
without
security.
So
then
you
can
narrow
down
your
focus
on
why
it's
not
working
with
security,
but
certainly
we
could
you
know
we
could
still
rust.
The
raw
security
working
group
could
probably
help
take
over
the
security.
B
C
In
terms
of
just
testing
sros
with
security,
yes
on
that
signal,.
B
I
guess
that's
like
that
was
the
original
like
thing
like
the
test
security
were,
I
think,
if
I
remember
probably
like
part
of
test
communications
to
begin
with,
but
because
security
needed
so
much
boilerplate
around
like
setting
more
environment,
variables
and
stuff
like
that
and
the
fact
that
it
was
not
the
same
people
looking
at
these
tests,
I
think
at
the
time
it
was
decided
to
put
it
in
another
package
so
right
now
it
leaves
close
in
a
sense
that
I
can
see
the
same
repo.
But
it's
not
in
the
same
package.
B
So
it's
just
like
my
only
concern
is
that,
like
I'm,
I'm
not
looking
at
the
ci
jobs
on
a
daily
basis,
the
the
official
rus
2,
ci
jobs,
and
so
I
don't
get
notified,
or
I
don't
know
when
these
security
tests
start
failing,
which
is
still
the
case
with
the
current
system,
even
if
it's
in
another
package,
but
now
that
we
actually
added
that
to
the
extras
2
ci,
which
is
basically
building
express,
2
and
building
that
package.
On
top.
B
Yep
there
is
that
too,
and
so
yeah
now
the
really
nasty
part
of
this
is
that's
crazy,
make
logic
and,
as
you
can
see
like
some
of
it
is
commented
because
it's
actually
able
to
do
a
lot
more
than
what
it's
currently
doing,
but
basically
how
it's
working
right.
Now,
it's
it's
looking
for
what
are
all
the
messages
located
in
text
messages
and
building
a
list
of
all
the
messages
for
the
services
and
based
on
that
it
can
then
do
some
magic.
B
So
we
have
like
a
couple
sets
of
magic
here
we
have
so
the
c
security
test.
So
this
is
the
first
file
I
showed,
which
has
like
multiple
configuration
testing
configuration
of
nodes
that
should
not
be
able
to
start
properly
and
so,
and
so
this
is
basically
a
function
that
is
being
code
for
each
rmw
implementation,
generating
tests
and
then
running
them
all.
B
And
so
how
it
works
in
general
is
that
we
have
we
find
ros
2.
We
find
s
plus
2.,
based
on
that
we
use
estrous
2
to
generate
all
the
security
artifacts,
we're
going
to
use
for
testing
and
and
then
once
we
created
all
that,
and
here
we
do
a
bit
of
a
hack.
So
it's
basically
we're
constructing
invalid
pistols.
B
So
here
we're
just
removing
a
file
from
one
of
the
enclaves
to
make
the
test
fail
and
here
we're
copying
an
invalid
certificate
into
the
valid
certificate
that
was
generated,
and
so
these
are
just
conditions
to
make
the
test
fail
and-
and
then
all
the
logic
actually
happens
here.
So
there
is
this
cmak
macro
provided
by
ras2,
which
is
just
call
that
macro
for
hrmw
implementation,
and
so,
if
you
go
to
the
target
macro,
what
this
does
is.
First,
it's
looking
and
setting
up
environment
variables
to
be
able
to
like
use
the
right
open,
ssl.
B
The
main
reason
is
that
ros2
is
using
a
pretty
old
version
of
connext
that
doesn't
have
support
for
openssl
111,
and
so
we
need
to
use
one
zero.
Two
and
here
this
is
a
logic,
and
so
this
is
where
we
right
now
say:
okay,
which
implementation
should
be
tested,
like
which
ones
are
supporting
security,
and
we
have
we
call
these
two
macros,
so
the
one
that
generates
all
the
c
security
tests.
So
this
is
the
one
I
showed
earlier
and
then
the
bulk
of
the
work
is
being
done
in
the
security
test
macro.
B
And
so
what
the
security
test
macro
does
it's
basically
defining,
so
we
have
we
receive
which
rmw
implementation
is
being
used
so
right
now
we
kind
of
like
hacked
that
so
that's
where
we
disabled
the
cross
vendor
testing,
which
is
basically
right.
Now
we
use
for
the
publisher
and
the
subscribers
the
same
rmw
implementation.
When
usually,
we
would
do
every
cell
of
the
matrix
and
the
same
thing
for
the
client
library
right
now.
We
just
set
it
to
rclcpp.
B
B
B
Yeah
yeah
the
sequence
of
same
lengths,
and
they
need
to
have
matching
lengths
and
and
so
yeah.
The
first
test
would
be
security,
enable
falls
for
both
security
strategy
and
force
for
both,
but
it
should
be
ignored
because
we
don't
use
security.
B
Then
we
have
a
test
suite
for
testing
actual
secure
communication,
so
here
we
say
we
want
to
use
security,
so
security
enable
is
set
to
true
for
all
tests,
and
then
we
test
the
different.
So
we
know
that
here
we're
going
to
be
using
a
valid
key
store,
so
we're
going
to
be
able
to
find
the
security
artifacts
for
every
publisher
and
subscriber
created,
so
they
will
all
instantiate
the
security
plugins
and
and
then
like
we
just
play
around
with
a
strategy
which
is
basically
if
you
can
find
the
security
artifacts.
B
If
you
use
enforce
it's
gonna
work,
because
what
enforce
does
is
like
if
there
is
a
security
artifact,
we
use
them.
If
there
is
not,
we
the
node
cannot
be
created
and
permissive
allows
you
to
have
some
missing
artifacts
and
create
non-secure
nodes.
But
here
we're
gonna,
we're
not
gonna
have
any
missing
artifacts.
So
all
these
should
end
up
with
a
publisher
and
a
subscriber
talking
with
security
over
a
secure
topic.
B
So
this
is
basically
a
set
of
tests
where,
like
one
node
is
using
security,
the
other
one
is
not,
and
so
they
should
not
connect,
and
so
how
it's
done
in
the
code
is
that
we
basically
put
a
timeout
and
we
make
sure
that
we
don't
connect
and
don't
receive
any
message
during
that
time,
and
so
these
are
basically
the
parameters
used
for
the
various
test,
suites
and
so
then,
for
each
of
these
parameters,
we're
going
to
generate
n
files,
and
so
in
this
case,
what
we're
going
to
do
is
that
we
say
that
we're
going
to
test
only
this
subset
of
a
file.
B
D
C
In
what
sense
does
the
message
type
have
ramifications
on
the
success
or
failure
of
the
security.
B
So
it
really
depends
like
you
would
expect
that
if
they
all
passed
test
communication,
it
should
be
fine.
We
had
issues
in
the
past
where,
like,
depending
on
the
order
of
the
fields
and
if
something
weren't
bounded
followed
by
bounded
messages
like
is,
is
the
padding
gonna
match?
Is
the
length
gonna
be
good?
Is
the
fragmentation
like?
Is
fragmentation?
Gonna
occur,
but.
B
Yeah,
so
so
that's
part
of
the
thing
like
you
would
expect
that,
like
if
the
old
past
test
communication,
which
is
the
one
testing
like
just
like
communication
between
those
regardless
of
security,
this
should
pass
here
as
well,
but
to
be
fair,
like
we,
we
always
like
I've
been
finding
corner
cases
in
like
random,
failing
failing
tests
in
the
past,
so
I
think
there
may
still
be
value,
but
for
the
last
three
years
or
maybe
more,
only
these
two
types
have
been
tested.
B
So-
and
I
guess
in
this
case,
like
the
empty
type,
is
not
a
very
useful
one,
because
you
basically
just
ensure
that
you
receive
messages,
but
you
don't
ensure
the
integrity
of
the
data
you
receive,
but
we
could
test
only
one
type,
which
is
something
that
has
a
lot
of
data
that
we
will
need
to
match
on
the
other
side,
just
to
make
sure
that
everything
is
working.
Fine,
encryption,
decryption
like
you
get
you
get
the
right
thing
on
the
other
end.
B
Okay,
but
yeah
so
to
to
be
fair.
Like
I
don't
I
I
don't
know
if
we
need
to
test
more
of
those
and
if
like
in
what
cases,
one
message
would
pass
and
others
would
fail.
D
D
B
For
sure
and-
and
I
think
that's
part
of
why
even
on
the
test
communication
side
of
things
like
only
very
few
messages
are
being
tested
because
at
the
beginning
it
was
also
a
way
to
ensure
that
both
the
message-
generators
on
the
ros
side
and
the
serialization
on
the
various
dds
vendor
sides
were
in
agreement
at
the
roster
level.
B
But
now
that's
been
more
or
less
like
all
all
the
corner
cases
have
been
like
fixed,
either
in
rs2
or
in
the
various
dds
vendors.
So
there
is
no
really
not
really
a
need
for
that
anymore,
except
if
you
get
a
brand
new
dds
implementation
that
has
a
brand
new
rust
to
implementation
across
the
middleware
implementation.
B
And
then
you
may
find
some
of
these
corner
cases,
yeah
that
makes
sense,
yeah
and
then
basically,
what
this
does
so
cmake
doesn't
have
for
loops.
So
we
just
while
for
like,
we
do
a
while
look
for
a
given
number
of
time,
and-
and
so
here
what
we
do
is
like.
We
get
the
fixture
from
the
list,
the
sequences
above
and
then
we
configure
a
test
file
with
this
information.
B
Well,
actually
like
originally,
I
I
I
wrote
those
I
mean
these
are
like
launch
files,
so
it's
harder
to
write
them
in
c,
but
yeah
and
you
you
don't
want
to,
but
but
yeah.
Basically,
what.
C
B
Does
is
like
it's
also?
No
actually
now
it's
using
launch
testing
directly.
Okay!
So
basically
your
that's
the
same
thing.
You
basically
generate
launch
flights,
so
you
generate
a
test
description.
You
just
say
which
executable
to
use
any
extra
argument
you
want
to
give
which
message
type.
What
is
which
is
an
argument
that
the
c
plus
plus
executable
take
should
the
subscriber
timeout
or
not,
etc,
and
then
so,
as
you
can
see,
we
don't
do
python
testing
here
either
and
we
just
we
just
keep.
B
So
we
extract
all
these
from
the
fixtures
we
put
them
in
the
environment
of
the
publisher
and
the
subscriber,
and
then
we
just
say
add
an
action
ready
to
test
and
launch
this.
That's
basically
all
it
does.
Then
that's
like
just
launch
boilerplate
that
ensures
that
the
tests
are
like
properly
exiting
and
and
this
kind
of
thing,
but
on
our
side,
all
we're
interested
in
is
that,
like
these
tests
that
have
their
logic
inside
the
c
plus
plus
are
launched,
and
so
this
is
just
generating
launch
lines.
B
B
Yeah,
that's
that's
kind
of
like
my
feeling
as
well,
especially
because,
like
I,
I
don't
see
either
a
good
reason.
For
I
mean
the
only
thing
cma
gives
us
is
the
ability
to
generate
stuff
and
the
fact
that
we
already
have
like
testing
macros
that
give
you
like
code
for
hrmw
implementation.
B
But
then,
on
the
other,
on
the
other
side,
like
you,
could
I
mean
if
you
were
willing
to
spawn
a
python
interpreter
for
registering
and
running
your
tests?
You
could
do
a
very
similar
thing
by
just
asking
rclp,
which
are
the
rmw
implementations
available
and
then
like
loop
over
those
to
generate
your
tests.
B
D
I
mean
so
yeah
if
the
tests
are
already
in
python.
That
seems
like
something
you
could
do
from
the
test
itself
and
then
make
it
like
I
mean
you're,
that's
essentially
what
you're
doing
right
is
you're
doing
like
a
data-driven
test
generation
thing.
You
can
do
that
in
pi
tests
too.
B
Yeah,
so
that's
part
of
the
thing
and
then
the
other
thing
is
that,
like
right
now,
the
like
the
executables
are
c
plus
plus,
but
there
is
nothing
preventing
us
from
making
a
python
version
and
at
this
point,
except
some
c
mac
magic
that
I
think
we
could
still
do
in
python,
which
is
just
like
invoking
some
commands,
like
some
homebrew
commands,
to
find
where
opposite
open
ssl
is
located
this
kind
of
stuff.
D
Well,
what
would
it
I
have
not
tried
this
in
in
ross
2.
so
like
in
ross
one?
You
always
had
that
c.
Make
lists
right,
regardless
of
what
language
you
were
using
in
ross
2.
Well,
what
that?
What
that
meant
then
was
that
it
was.
It
was
pretty
easy
to
sort
of
you
could
kind
of
ship,
a
node
that
used
both
ross
or
the
usability
plus
plus
and
python.
What
does
that
look
like
in
ross2.
B
B
B
Otherwise
it
goes
there
on
your
path,
but
ross
run,
won't
find
it
and
whatever,
and
so
one
of
the
things
that
would
be
like
that
was
an
advantage
of
plus
two
is
to
be
able
to
say:
hey,
let's
have
pure
python
packages,
but
if
you
want
to
generate
messages,
if
you
want
to
do
like
anything
that
is,
I
meant,
like
all
the
cool
stuff
that
amen
gives
you.
You
cannot
do
it
without
simic,
so
you
cannot
have
the
same
problem.
B
B
Well,
honestly,
like
you
would
basically
what
you
would
do
is
that
you
would
take
this
symmach
list.
Did
it
98
of
it
keep
the
part
that
builds
the
c
plus
plus
exchange
tables,
and
then
you
would
like
you
can
register
pi
test
tests
with
almond.
B
Like
I
don't
know,
I'm
in
test
or
something
like
that,
like
you
can,
just
do
add,
add
pie
test
so
like
adam
and
spy
test,
or
something
like
that,
so
you
can
register
your
test
so
that
it
would
be
run
that
way,
and
so
the
only
part
you
would
be
needing
between
generating
the
binaries,
the
c
binaries
and
registering
your
test
would
be
generating
your
test.
If
you
want
to
do
it,
data
driven
and
that
part
could
be.
A
So
we've
run
beyond
our
meeting
time
and
it's
a
great
discussion,
I'm
glad
we
actually
captured
it
all.
So
we
have
it
for
later
as
well.
I
think
it
sounded
like.
B
A
Some
potential
to
do
some
more
work
with
the
test
routines
and
I
I
think
michelle
kind
of
you
pointed
out
a
lot
of
opportunities
there.
So
maybe
that
would
be
something
that
we
should
pick
up
either
on
matrix
or
at
our
next
meeting.
D
D
B
Yeah
but
yeah,
so
I'm
very
sorry
for
running
over.
I
didn't
look
at
the
clock,
I'm
more
than
happy
to
follow
up
on
matrix
and
and
we
can
decide
like
discuss
both
if
we
want
to
bring
that
closer
to
estrus
2,
to
have
a
bit
more
control
over
it
and
and
what
tasks
we
can
like
split
out
of
this
discussion.
B
A
B
A
That's
great
yeah:
if
there's
anything
else,
anybody
we
didn't
get
a
chance
to
talk
to
just
drop
them
in
the
agenda
and
then
I'll
piss
them
up
and
kyle.
I
guess
we'll
push
off
the
s
for
us
to
api
update
until
our
next
meeting.
That
sounds
good,
no
problem,
all
right!
Thanks
everybody
for
joining
appreciate
your
time
thanks.
Everybody.