Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
OpenDAS
Torchaudio
Commits
d416a49b
Unverified
Commit
d416a49b
authored
Oct 29, 2022
by
moto
Committed by
GitHub
Oct 28, 2022
Browse files
Cherry-pick #2767 to release/0.13 (#2805)
parent
bc8640b4
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
319 additions
and
79 deletions
+319
-79
docs/source/_static/css/custom.css
docs/source/_static/css/custom.css
+9
-0
docs/source/_templates/layout.html
docs/source/_templates/layout.html
+1
-1
docs/source/conf.py
docs/source/conf.py
+4
-1
docs/source/custom_directives.py
docs/source/custom_directives.py
+100
-0
docs/source/feature_classifications.rst
docs/source/feature_classifications.rst
+20
-0
docs/source/index.rst
docs/source/index.rst
+185
-56
docs/source/tutorials.io.rst
docs/source/tutorials.io.rst
+0
-21
No files found.
docs/source/_static/css/custom.css
View file @
d416a49b
...
...
@@ -26,3 +26,12 @@ article.pytorch-article .sphx-glr-thumbnails .sphx-glr-thumbcontainer {
article
.pytorch-article
div
.section
div
.wy-table-responsive
tbody
td
{
width
:
50%
;
}
/* For customcarditem*/
article
.pytorch-article
div
.tutorials-card
div
.card-body
code
{
color
:
#d14
;
padding
:
2px
4px
;
border-radius
:
6px
;
border-top
:
none
;
border-bottom
:
none
;
background-color
:
#AFB8C133
;
}
docs/source/_templates/layout.html
View file @
d416a49b
...
...
@@ -55,7 +55,7 @@
{%- block footer %}
<script
type=
"text/javascript"
>
var
collapsedSections
=
[]
var
collapsedSections
=
[
'
API Tutorials
'
,
'
Pipeline Tutorials
'
]
</script>
{{ super() }}
<script
type=
"text/javascript"
>
...
...
docs/source/conf.py
View file @
d416a49b
...
...
@@ -347,7 +347,7 @@ def setup(app):
app
.
connect
(
"autodoc-process-docstring"
,
inject_minigalleries
)
from
custom_directives
import
SupportedDevices
,
SupportedProperties
from
custom_directives
import
CustomCardEnd
,
CustomCardItem
,
CustomCardStart
,
SupportedDevices
,
SupportedProperties
# Register custom directives
...
...
@@ -355,3 +355,6 @@ from docutils.parsers import rst
rst
.
directives
.
register_directive
(
"devices"
,
SupportedDevices
)
rst
.
directives
.
register_directive
(
"properties"
,
SupportedProperties
)
rst
.
directives
.
register_directive
(
"customcardstart"
,
CustomCardStart
)
rst
.
directives
.
register_directive
(
"customcarditem"
,
CustomCardItem
)
rst
.
directives
.
register_directive
(
"customcardend"
,
CustomCardEnd
)
docs/source/custom_directives.py
View file @
d416a49b
...
...
@@ -6,7 +6,9 @@ from urllib.parse import quote, urlencode
import
requests
from
docutils
import
nodes
from
docutils.parsers.rst
import
Directive
,
directives
from
docutils.parsers.rst.directives.images
import
Image
from
docutils.statemachine
import
StringList
from
sphinx.util.docutils
import
SphinxDirective
...
...
@@ -125,3 +127,101 @@ class SupportedProperties(BaseShield):
"style"
:
"flat-square"
,
}
return
super
().
run
(
params
,
alt
,
"properties"
)
_CARDLIST_START
=
"""
.. raw:: html
<div id="tutorial-cards-container">
<nav class="navbar navbar-expand-lg navbar-light tutorials-nav col-12">
<div class="tutorial-tags-container">
<div id="dropdown-filter-tags">
<div class="tutorial-filter-menu">
<div class="tutorial-filter filter-btn all-tag-selected" data-tag="all">All</div>
</div>
</div>
</div>
</nav>
<hr class="tutorials-hr">
<div class="row">
<div id="tutorial-cards">
<div class="list">
"""
_CARD_TEMPLATE
=
"""
.. raw:: html
<div class="col-md-12 tutorials-card-container" data-tags={tags}>
<div class="card tutorials-card">
<a href="{link}">
<div class="card-body">
<div class="card-title-container">
<h4>{header}</h4>
</div>
<p>Topics: <span class="tags">{tags}</span></p>
<p class="card-summary">{card_description}</p>
<div class="tutorials-image">{image}</div>
</div>
</a>
</div>
</div>
"""
_CARDLIST_END
=
"""
.. raw:: html
</div>
<div class="pagination d-flex justify-content-center"></div>
</div>
</div>
</div>
"""
class
CustomCardStart
(
Directive
):
def
run
(
self
):
para
=
nodes
.
paragraph
()
self
.
state
.
nested_parse
(
StringList
(
_CARDLIST_START
.
split
(
"
\n
"
)),
self
.
content_offset
,
para
)
return
[
para
]
class
CustomCardItem
(
Directive
):
option_spec
=
{
"header"
:
directives
.
unchanged
,
"image"
:
directives
.
unchanged
,
"link"
:
directives
.
unchanged
,
"card_description"
:
directives
.
unchanged
,
"tags"
:
directives
.
unchanged
,
}
def
run
(
self
):
for
key
in
[
"header"
,
"card_description"
,
"link"
]:
if
key
not
in
self
.
options
:
raise
ValueError
(
f
"Key: `
{
key
}
` is missing"
)
header
=
self
.
options
[
"header"
]
link
=
self
.
options
[
"link"
]
card_description
=
self
.
options
[
"card_description"
]
tags
=
self
.
options
.
get
(
"tags"
,
""
)
if
"image"
in
self
.
options
:
image
=
"<img src='"
+
self
.
options
[
"image"
]
+
"'>"
else
:
image
=
"_static/img/thumbnails/default.png"
card_rst
=
_CARD_TEMPLATE
.
format
(
header
=
header
,
image
=
image
,
link
=
link
,
card_description
=
card_description
,
tags
=
tags
)
card_list
=
StringList
(
card_rst
.
split
(
"
\n
"
))
card
=
nodes
.
paragraph
()
self
.
state
.
nested_parse
(
card_list
,
self
.
content_offset
,
card
)
return
[
card
]
class
CustomCardEnd
(
Directive
):
def
run
(
self
):
para
=
nodes
.
paragraph
()
self
.
state
.
nested_parse
(
StringList
(
_CARDLIST_END
.
split
(
"
\n
"
)),
self
.
content_offset
,
para
)
return
[
para
]
docs/source/feature_classifications.rst
0 → 100644
View file @
d416a49b
Feature Classifications
=======================
Features described in this documentation are classified by release status:
*Stable:* These features will be maintained long-term and there should generally
be no major performance limitations or gaps in documentation.
We also expect to maintain backwards compatibility (although
breaking changes can happen and notice will be given one release ahead
of time).
*Beta:* Features are tagged as Beta because the API may change based on
user feedback, because the performance needs to improve, or because
coverage across operators is not yet complete. For Beta features, we are
committing to seeing the feature through to the Stable classification.
We are not, however, committing to backwards compatibility.
*Prototype:* These features are typically not available as part of
binary distributions like PyPI or Conda, except sometimes behind run-time
flags, and are at an early stage for feedback and testing.
docs/source/index.rst
View file @
d416a49b
...
...
@@ -5,39 +5,57 @@ Torchaudio is a library for audio and signal processing with PyTorch.
It
provides
I
/
O
,
signal
and
data
processing
functions
,
datasets
,
model
implementations
and
application
components
.
Features
described
in
this
documentation
are
classified
by
release
status
:
*
Stable
:*
These
features
will
be
maintained
long
-
term
and
there
should
generally
be
no
major
performance
limitations
or
gaps
in
documentation
.
We
also
expect
to
maintain
backwards
compatibility
(
although
breaking
changes
can
happen
and
notice
will
be
given
one
release
ahead
of
time
).
*
Beta
:*
Features
are
tagged
as
Beta
because
the
API
may
change
based
on
user
feedback
,
because
the
performance
needs
to
improve
,
or
because
coverage
across
operators
is
not
yet
complete
.
For
Beta
features
,
we
are
committing
to
seeing
the
feature
through
to
the
Stable
classification
.
We
are
not
,
however
,
committing
to
backwards
compatibility
.
*
Prototype
:*
These
features
are
typically
not
available
as
part
of
binary
distributions
like
PyPI
or
Conda
,
except
sometimes
behind
run
-
time
flags
,
and
are
at
an
early
stage
for
feedback
and
testing
.
..
Generate
Table
Of
Contents
(
left
navigation
bar
)
NOTE
:
If
you
are
adding
tutorials
,
add
entries
to
toctree
and
customcarditem
below
..
toctree
::
:
maxdepth
:
1
:
hidden
:
:
caption
:
Torchaudio
Documentation
:
hidden
:
Index
<
self
>
supported_features
feature_classifications
references
API
References
--------------
..
toctree
::
:
maxdepth
:
1
:
caption
:
API
Tutorials
:
hidden
:
tutorials
/
audio_io_tutorial
tutorials
/
streamreader_basic_tutorial
tutorials
/
streamreader_advanced_tutorial
tutorials
/
streamwriter_basic_tutorial
tutorials
/
streamwriter_advanced
hw_acceleration_tutorial
tutorials
/
audio_resampling_tutorial
tutorials
/
audio_data_augmentation_tutorial
tutorials
/
audio_feature_extractions_tutorial
tutorials
/
audio_feature_augmentation_tutorial
tutorials
/
audio_datasets_tutorial
..
toctree
::
:
maxdepth
:
1
:
caption
:
Pipeline
Tutorials
:
hidden
:
tutorials
/
speech_recognition_pipeline_tutorial
tutorials
/
asr_inference_with_ctc_decoder_tutorial
tutorials
/
online_asr_tutorial
tutorials
/
device_asr
tutorials
/
forced_alignment_tutorial
tutorials
/
tacotron2_pipeline_tutorial
tutorials
/
mvdr_tutorial
tutorials
/
hybrid_demucs_tutorial
..
toctree
::
:
maxdepth
:
1
:
caption
:
API
Reference
:
hidden
:
torchaudio
io
...
...
@@ -53,35 +71,159 @@ API References
kaldi_io
utils
Getting
Started
---------------
..
toctree
::
:
maxdepth
:
1
:
caption
:
Getting
Started
:
caption
:
PyTorch
Libraries
:
hidden
:
tutorials
.
io
tutorials
/
audio_resampling_tutorial
tutorials
/
audio_data_augmentation_tutorial
tutorials
/
audio_feature_extractions_tutorial
tutorials
/
audio_feature_augmentation_tutorial
tutorials
/
audio_datasets_tutorial
PyTorch
<
https
://
pytorch
.
org
/
docs
>
torchaudio
<
https
://
pytorch
.
org
/
audio
>
torchtext
<
https
://
pytorch
.
org
/
text
>
torchvision
<
https
://
pytorch
.
org
/
vision
>
TorchElastic
<
https
://
pytorch
.
org
/
elastic
/>
TorchServe
<
https
://
pytorch
.
org
/
serve
>
PyTorch
on
XLA
Devices
<
http
://
pytorch
.
org
/
xla
/>
Advanced
Usage
s
---------
------
Tutorial
s
---------
..
toctree
::
:
maxdepth
:
1
:
caption
:
Advanced
Usages
..
customcardstart
::
..
customcarditem
::
:
header
:
Loading
waveform
Tensors
from
files
and
saving
them
:
card_description
:
Learn
how
to
query
/
load
audio
files
and
save
waveform
tensors
to
files
,
using
<
code
>
torchaudio
.
info
</
code
>,
<
code
>
torchaudio
.
load
</
code
>
and
<
code
>
torchaudio
.
save
</
code
>
functions
.
:
image
:
https
://
download
.
pytorch
.
org
/
torchaudio
/
tutorial
-
assets
/
thumbnails
/
audio_io_tutorial
.
png
:
link
:
tutorials
/
audio_io_tutorial
.
html
:
tags
:
I
/
O
..
customcarditem
::
:
header
:
Streaming
media
decoding
with
StreamReader
:
card_description
:
Learn
how
to
load
audio
/
video
to
Tensors
using
<
code
>
torchaudio
.
io
.
StreamReader
</
code
>
class
.
:
image
:
https
://
download
.
pytorch
.
org
/
torchaudio
/
tutorial
-
assets
/
thumbnails
/
streamreader_basic_tutorial
.
png
:
link
:
tutorials
/
streamreader_basic_tutorial
.
html
:
tags
:
I
/
O
,
StreamReader
..
customcarditem
::
:
header
:
Device
input
,
synthetic
audio
/
video
,
and
filtering
with
StreamReader
:
card_description
:
Learn
how
to
load
media
from
hardware
devices
,
generate
synthetic
audio
/
video
,
and
apply
filters
to
them
with
<
code
>
torchaudio
.
io
.
StreamReader
</
code
>.
:
image
:
https
://
download
.
pytorch
.
org
/
torchaudio
/
tutorial
-
assets
/
thumbnails
/
streamreader_advanced_tutorial
.
gif
:
link
:
tutorials
/
streamreader_advanced_tutorial
.
html
:
tags
:
I
/
O
,
StreamReader
..
customcarditem
::
:
header
:
Streaming
media
encoding
with
StreamWriter
:
card_description
:
Learn
how
to
save
audio
/
video
with
<
code
>
torchaudio
.
io
.
StreamWriter
</
code
>.
:
image
:
https
://
download
.
pytorch
.
org
/
torchaudio
/
tutorial
-
assets
/
thumbnails
/
streamwriter_basic_tutorial
.
gif
:
link
:
tutorials
/
streamwriter_basic_tutorial
.
html
:
tags
:
I
/
O
,
StreamWriter
..
customcarditem
::
:
header
:
Playing
media
with
StreamWriter
:
card_description
:
Learn
how
to
play
audio
/
video
with
<
code
>
torchaudio
.
io
.
StreamWriter
</
code
>.
:
image
:
https
://
download
.
pytorch
.
org
/
torchaudio
/
tutorial
-
assets
/
thumbnails
/
streamwriter_advanced
.
gif
:
link
:
tutorials
/
streamwriter_advanced
.
html
:
tags
:
I
/
O
,
StreamWriter
..
customcarditem
::
:
header
:
Hardware
accelerated
video
I
/
O
with
NVDEC
/
NVENC
:
card_description
:
Learn
how
to
setup
and
use
HW
accelerated
video
I
/
O
.
:
image
:
https
://
download
.
pytorch
.
org
/
torchaudio
/
tutorial
-
assets
/
thumbnails
/
hw_acceleration_tutorial
.
png
:
link
:
hw_acceleration_tutorial
.
html
:
tags
:
I
/
O
,
StreamReader
,
StreamWriter
..
customcarditem
::
:
header
:
Audio
resampling
with
bandlimited
sinc
interpolation
:
card_description
:
Learn
how
to
resample
audio
tensor
with
<
code
>
torchaudio
.
functional
.
resample
</
code
>
and
<
code
>
torchaudio
.
transforms
.
Resample
</
code
>.
:
image
:
https
://
download
.
pytorch
.
org
/
torchaudio
/
tutorial
-
assets
/
thumbnails
/
audio_resampling_tutorial
.
png
:
link
:
tutorials
/
audio_resampling_tutorial
.
html
:
tags
:
Preprocessing
..
customcarditem
::
:
header
:
Audio
data
augmentation
:
card_description
:
Learn
how
to
use
<
code
>
torchaudio
.
functional
</
code
>
and
<
code
>
torchaudio
.
transforms
</
code
>
modules
to
perform
data
augmentation
.
:
image
:
https
://
download
.
pytorch
.
org
/
torchaudio
/
tutorial
-
assets
/
thumbnails
/
audio_data_augmentation_tutorial
.
png
:
link
:
tutorials
/
audio_data_augmentation_tutorial
.
html
:
tags
:
Preprocessing
..
customcarditem
::
:
header
:
Audio
feature
extraction
:
card_description
:
Learn
how
to
use
<
code
>
torchaudio
.
functional
</
code
>
and
<
code
>
torchaudio
.
transforms
</
code
>
modules
to
extract
features
from
waveform
.
:
image
:
https
://
download
.
pytorch
.
org
/
torchaudio
/
tutorial
-
assets
/
thumbnails
/
audio_feature_extractions_tutorial
.
png
:
link
:
tutorials
/
audio_feature_extractions_tutorial
.
html
:
tags
:
Preprocessing
..
customcarditem
::
:
header
:
Audio
feature
augmentation
:
card_description
:
Learn
how
to
use
<
code
>
torchaudio
.
functional
</
code
>
and
<
code
>
torchaudio
.
transforms
</
code
>
modules
to
perform
feature
augmentation
.
:
image
:
https
://
download
.
pytorch
.
org
/
torchaudio
/
tutorial
-
assets
/
thumbnails
/
audio_feature_augmentation_tutorial
.
png
:
link
:
tutorials
/
audio_feature_augmentation_tutorial
.
html
:
tags
:
Preprocessing
..
customcarditem
::
:
header
:
Audio
dataset
:
card_description
:
Learn
how
to
use
<
code
>
torchaudio
.
datasets
</
code
>
module
.
:
image
:
https
://
download
.
pytorch
.
org
/
torchaudio
/
tutorial
-
assets
/
thumbnails
/
audio_datasets_tutorial
.
png
:
link
:
tutorials
/
audio_datasets_tutorial
.
html
:
tags
:
Dataset
..
customcarditem
::
:
header
:
AM
inference
with
Wav2Vec2
:
card_description
:
Learn
how
to
perform
acoustic
model
inference
with
Wav2Vec2
(<
code
>
torchaudio
.
pipelines
.
Wav2Vec2ASRBundle
</
code
>).
:
image
:
https
://
download
.
pytorch
.
org
/
torchaudio
/
tutorial
-
assets
/
thumbnails
/
speech_recognition_pipeline_tutorial
.
png
:
link
:
tutorials
/
speech_recognition_pipeline_tutorial
.
html
:
tags
:
ASR
,
wav2vec2
..
customcarditem
::
:
header
:
LM
inference
with
CTC
Beam
Seach
Decoder
:
card_description
:
Learn
how
to
perform
ASR
beam
search
decoding
with
lexicon
and
language
model
,
using
<
code
>
torchaudio
.
models
.
decoder
.
ctc_decoder
</
code
>.
:
image
:
https
://
download
.
pytorch
.
org
/
torchaudio
/
tutorial
-
assets
/
thumbnails
/
asr_inference_with_ctc_decoder_tutorial
.
png
:
link
:
tutorials
/
asr_inference_with_ctc_decoder_tutorial
.
html
:
tags
:
Pipelines
,
ASR
,
wav2vec2
,
CTC
-
Decoder
..
customcarditem
::
:
header
:
Online
ASR
with
Emformer
RNN
-
T
:
card_description
:
Learn
how
to
perform
online
ASR
with
Emformer
RNN
-
T
(<
code
>
torchaudio
.
pipelines
.
RNNTBundle
</
code
>)
and
<
code
>
torchaudio
.
io
.
StreamReader
</
code
>.
:
image
:
https
://
download
.
pytorch
.
org
/
torchaudio
/
tutorial
-
assets
/
thumbnails
/
online_asr_tutorial
.
gif
:
link
:
tutorials
/
online_asr_tutorial
.
html
:
tags
:
Pipelines
,
ASR
,
RNNT
,
StreamReader
..
customcarditem
::
:
header
:
Real
-
time
microphone
ASR
with
Emformer
RNN
-
T
:
card_description
:
Learn
how
to
transcribe
speech
fomr
microphone
with
Emformer
RNN
-
T
(<
code
>
torchaudio
.
pipelines
.
RNNTBundle
</
code
>)
and
<
code
>
torchaudio
.
io
.
StreamReader
</
code
>.
:
image
:
https
://
download
.
pytorch
.
org
/
torchaudio
/
tutorial
-
assets
/
thumbnails
/
device_asr
.
png
:
link
:
tutorials
/
device_asr
.
html
:
tags
:
Pipelines
,
ASR
,
RNNT
,
StreamReader
..
customcarditem
::
:
header
:
Forced
Alignment
with
Wav2Vec2
:
card_description
:
Learn
how
to
align
text
to
speech
with
Wav2Vec
2
(<
code
>
torchaudio
.
pipelines
.
Wav2Vec2ASRBundle
</
code
>).
:
image
:
https
://
download
.
pytorch
.
org
/
torchaudio
/
tutorial
-
assets
/
thumbnails
/
forced_alignment_tutorial
.
png
:
link
:
tutorials
/
forced_alignment_tutorial
.
html
:
tags
:
Pipelines
,
Forced
-
Alignment
,
wav2vec2
..
customcarditem
::
:
header
:
Text
-
to
-
Speech
with
Tacotron2
:
card_description
:
Learn
how
to
generate
speech
from
text
with
Tacotron2
(<
code
>
torchaudio
.
pipelines
.
Tacotron2TTSBundle
</
code
>).
:
image
:
https
://
download
.
pytorch
.
org
/
torchaudio
/
tutorial
-
assets
/
thumbnails
/
tacotron2_pipeline_tutorial
.
png
:
link
:
tutorials
/
tacotron2_pipeline_tutorial
.
html
:
tags
:
Pipelines
,
TTS
-(
Text
-
to
-
Speech
)
..
customcarditem
::
:
header
:
Speech
Enhancement
with
MVDR
Beamforming
:
card_description
:
Learn
how
to
improve
speech
quality
with
MVDR
Beamforming
.
:
image
:
https
://
download
.
pytorch
.
org
/
torchaudio
/
tutorial
-
assets
/
thumbnails
/
mvdr_tutorial
.
png
:
link
:
tutorials
/
mvdr_tutorial
.
html
:
tags
:
Pipelines
,
Speech
-
Enhancement
..
customcarditem
::
:
header
:
Music
Source
Separation
with
Hybrid
Demucs
:
card_description
:
Learn
how
to
perform
music
source
separation
with
pre
-
trained
Hybrid
Demucs
(<
code
>
torchaudio
.
pipelines
.
SourceSeparationBundle
</
code
>).
:
image
:
https
://
download
.
pytorch
.
org
/
torchaudio
/
tutorial
-
assets
/
thumbnails
/
hybrid_demucs_tutorial
.
png
:
link
:
tutorials
/
hybrid_demucs_tutorial
.
html
:
tags
:
Pipelines
,
Source
-
Separation
..
customcardend
::
tutorials
/
speech_recognition_pipeline_tutorial
tutorials
/
online_asr_tutorial
tutorials
/
device_asr
tutorials
/
forced_alignment_tutorial
tutorials
/
tacotron2_pipeline_tutorial
tutorials
/
mvdr_tutorial
tutorials
/
asr_inference_with_ctc_decoder_tutorial
tutorials
/
hybrid_demucs_tutorial
Citing
torchaudio
-----------------
...
...
@@ -112,16 +254,3 @@ In BibTeX format:
journal
={
arXiv
preprint
arXiv
:
2110.15018
},
year
={
2021
}
}
..
toctree
::
:
maxdepth
:
1
:
caption
:
PyTorch
Libraries
:
hidden
:
PyTorch
<
https
://
pytorch
.
org
/
docs
>
torchaudio
<
https
://
pytorch
.
org
/
audio
>
torchtext
<
https
://
pytorch
.
org
/
text
>
torchvision
<
https
://
pytorch
.
org
/
vision
>
TorchElastic
<
https
://
pytorch
.
org
/
elastic
/>
TorchServe
<
https
://
pytorch
.
org
/
serve
>
PyTorch
on
XLA
Devices
<
http
://
pytorch
.
org
/
xla
/>
docs/source/tutorials.io.rst
deleted
100644 → 0
View file @
bc8640b4
Media IO
========
TorchAudio project has started as a simple audio IO library for PyTorch, which are
:py:func:`torchaudio.info`, :py:func:`torchaudio.load` and :py:func:`torchaudio.save`.
In recent releases, more powerful IO features were added in :py:mod:`torchaudio.io`.
These features are based on FFmpeg libraries, thus cross-platform and can handle
wide variety of media formats, including audio and video, coming from many different source.
.. toctree::
:maxdepth: 1
:caption: Media IO Tutorials
tutorials/audio_io_tutorial
tutorials/streamreader_basic_tutorial
tutorials/streamreader_advanced_tutorial
tutorials/streamwriter_basic_tutorial
tutorials/streamwriter_advanced
hw_acceleration_tutorial
Write
Preview
Markdown
is supported
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