aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/doxy-style.css2
-rw-r--r--doc/style.css57
-rw-r--r--ext/atom.lv2/atom.ttl1
-rw-r--r--ext/contexts.lv2/contexts.ttl4
-rw-r--r--ext/cv-port.lv2/cv-port.ttl1
-rw-r--r--ext/data-access.lv2/data-access.ttl1
-rw-r--r--ext/event.lv2/event.ttl1
-rw-r--r--ext/files.lv2/files.ttl1
-rw-r--r--ext/host-info.lv2/host-info.ttl1
-rw-r--r--ext/instance-access.lv2/instance-access.ttl1
-rw-r--r--ext/midi.lv2/midi.ttl2
-rw-r--r--ext/osc.lv2/osc.ttl19
-rw-r--r--ext/parameter.lv2/parameter.ttl1
-rw-r--r--ext/port-groups.lv2/port-groups.ttl1
-rw-r--r--ext/presets.lv2/presets.ttl1
-rw-r--r--ext/reference.lv2/reference.ttl1
-rw-r--r--ext/resize-port.lv2/resize-port.ttl1
-rw-r--r--ext/state.lv2/state.ttl1
-rw-r--r--ext/time.lv2/time.ttl1
-rw-r--r--ext/ui-resize.lv2/ui-resize.ttl1
-rw-r--r--ext/uri-map.lv2/uri-map.ttl1
-rw-r--r--ext/uri-unmap.lv2/uri-unmap.ttl1
-rw-r--r--ext/urid.lv2/urid.ttl1
-rwxr-xr-xgendoc.py70
-rw-r--r--lv2specgen/template.html24
25 files changed, 111 insertions, 85 deletions
diff --git a/doc/doxy-style.css b/doc/doxy-style.css
index 213d7ed..aedd40d 100644
--- a/doc/doxy-style.css
+++ b/doc/doxy-style.css
@@ -393,6 +393,8 @@ table.memberdecls {
.paramname {
color: #602020;
white-space: nowrap;
+ vertical-align: text-top;
+ padding-right: 1em;
}
.paramname em {
diff --git a/doc/style.css b/doc/style.css
index d7d075f..6d6e090 100644
--- a/doc/style.css
+++ b/doc/style.css
@@ -70,7 +70,7 @@ h6 {
#title {
font-size: 200%;
font-weight: 700;
- margin: .25ex 0 .5ex;
+ margin: .25ex 0 .5ex 0;
padding: 0;
}
#logo {
@@ -395,12 +395,6 @@ ul, ol {
margin: 0;
padding: 0;
}
-.restriction {
- margin: 0;
- padding: 0;
- border-spacing: 0;
- vertical-align: text-top;
-}
.description {
margin-bottom: 0.75em;
}
@@ -413,24 +407,22 @@ ul, ol {
.blankterm {
padding-right: .5em;
}
-.terminfo {
- border-spacing: 0 0.5ex;
+.terminfo, .restriction {
+ border-spacing: 0.5ex 0.5ex;
+ border-collapse: collapse;
+ border-style: hidden;
}
.restriction {
- border-spacing: 0;
-}
-.terminfo th, .restriction th {
margin: 0;
padding: 0;
- padding-right: 1ex;
- border-top: dotted 1px #F0F0F0;
- background-color: #F8F8F8;
+ border-spacing: 0;
+ vertical-align: text-top;
}
-.terminfo td, .restriction td {
- margin: 0;
- padding: 0;
- border-top: dotted 1px #F0F0F0;
- background-color: #F8F8F8;
+.terminfo th, .terminfo td {
+ border: solid 1px #f3f3f3;
+}
+.terminfo th, .restriction th {
+ padding: 0 1ex 0 0;
}
.specterm {
background-color: #fbfbfb;
@@ -446,7 +438,7 @@ ul, ol {
margin: 0;
}
.spectermbody {
- padding: 0 1ex 1ex 1ex;
+ padding: 1ex 1ex 1ex 1ex;
}
dl {
margin: 0;
@@ -476,25 +468,22 @@ div.head table {
margin-top: 2em;
}
table {
- margin: 0;
- padding: 0;
- border-width: 0;
+ border-collapse: collapse;
+ border-style: hidden;
+ margin: 0;
}
th {
- vertical-align: text-top;
+ vertical-align: text-top;
}
-td {
- margin: 0;
- padding: 0 2ex 0 0;
+td, th {
+ border: 1px solid #eee;
+ padding: 0.3ex 1em 0.3ex 1em;
}
#meta {
- border-bottom: 1px solid #c4cfe5;
- font-size: small;
- margin: 0 0 2ex;
- padding: 1ex 0 1ex 2ex;
+ margin-left: 0.5ex;
}
-.metahead {
- padding-right: 1ex;
+#meta tr td, #meta tr th {
+ padding-left: 0;
}
pre {
margin: 1em 1em 1em 4em;
diff --git a/ext/atom.lv2/atom.ttl b/ext/atom.lv2/atom.ttl
index 0cc5abf..e411c63 100644
--- a/ext/atom.lv2/atom.ttl
+++ b/ext/atom.lv2/atom.ttl
@@ -24,6 +24,7 @@
<http://lv2plug.in/ns/ext/atom>
a lv2:Specification ;
doap:name "LV2 Atom" ;
+ doap:shortdesc "A generic value container and several data types." ;
doap:release [
doap:revision "0.1" ;
doap:created "2011-04-05"
diff --git a/ext/contexts.lv2/contexts.ttl b/ext/contexts.lv2/contexts.ttl
index 3fb4358..b04ab97 100644
--- a/ext/contexts.lv2/contexts.ttl
+++ b/ext/contexts.lv2/contexts.ttl
@@ -32,9 +32,9 @@
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
<http://lv2plug.in/ns/ext/contexts>
- a lv2:Specification ;
- a lv2:Feature ;
+ a lv2:Specification , lv2:Feature ;
doap:name "LV2 Contexts" ;
+ doap:shortdesc "Support for plugins with several execution contexts." ;
lv2:documentation """
<p>An extension for LV2 plugins which have several execution contexts.</p>
diff --git a/ext/cv-port.lv2/cv-port.ttl b/ext/cv-port.lv2/cv-port.ttl
index 9c08b57..d751692 100644
--- a/ext/cv-port.lv2/cv-port.ttl
+++ b/ext/cv-port.lv2/cv-port.ttl
@@ -24,6 +24,7 @@
a lv2:Specification ;
doap:license <http://opensource.org/licenses/isc-license> ;
doap:name "LV2 CV Port" ;
+ doap:shortdesc "Control Voltage ports for LV2 plugins." ;
doap:maintainer [
a foaf:Person ;
foaf:name "David Robillard" ;
diff --git a/ext/data-access.lv2/data-access.ttl b/ext/data-access.lv2/data-access.ttl
index 2d33b77..a83da2e 100644
--- a/ext/data-access.lv2/data-access.ttl
+++ b/ext/data-access.lv2/data-access.ttl
@@ -25,6 +25,7 @@
a lv2:Specification ;
doap:license <http://opensource.org/licenses/isc-license> ;
doap:name "LV2 Data Access" ;
+ doap:shortdesc "Provides access to LV2_Descriptor::extension_data." ;
doap:release [
doap:revision "1.2" ;
doap:created "2011-05-26"
diff --git a/ext/event.lv2/event.ttl b/ext/event.lv2/event.ttl
index 6f9bce3..064e3eb 100644
--- a/ext/event.lv2/event.ttl
+++ b/ext/event.lv2/event.ttl
@@ -25,6 +25,7 @@
a lv2:Specification ;
doap:license <http://opensource.org/licenses/isc-license> ;
doap:name "LV2 Event" ;
+ doap:shortdesc "A port-based real-time generic event interface." ;
rdfs:seeAlso <event-helpers.h> ;
doap:release [
doap:revision "1.2" ;
diff --git a/ext/files.lv2/files.ttl b/ext/files.lv2/files.ttl
index dc51ede..84bac64 100644
--- a/ext/files.lv2/files.ttl
+++ b/ext/files.lv2/files.ttl
@@ -25,6 +25,7 @@
<http://lv2plug.in/ns/ext/files>
a lv2:Specification ;
doap:name "LV2 Files" ;
+ doap:shortdesc "A standard for referring to files in plugin state." ;
doap:license <http://opensource.org/licenses/isc-license> ;
doap:release [
doap:revision "0.2" ;
diff --git a/ext/host-info.lv2/host-info.ttl b/ext/host-info.lv2/host-info.ttl
index 38bdd2d..127f4cc 100644
--- a/ext/host-info.lv2/host-info.ttl
+++ b/ext/host-info.lv2/host-info.ttl
@@ -33,6 +33,7 @@
<http://lv2plug.in/ns/ext/host-info> a lv2:Specification ;
doap:license <http://usefulinc.com/doap/licenses/mit> ;
doap:name "LV2 Host Info" ;
+ doap:shortdesc "A format for describing LV2 hosts." ;
doap:maintainer [
a foaf:Person ;
foaf:name "David Robillard" ;
diff --git a/ext/instance-access.lv2/instance-access.ttl b/ext/instance-access.lv2/instance-access.ttl
index 23a543b..5e1b9f8 100644
--- a/ext/instance-access.lv2/instance-access.ttl
+++ b/ext/instance-access.lv2/instance-access.ttl
@@ -25,6 +25,7 @@
a lv2:Specification ;
doap:license <http://opensource.org/licenses/isc-license> ;
doap:name "LV2 Instance Access" ;
+ doap:shortdesc "Provides access to the LV2_Handle of a plugin." ;
doap:release [
doap:revision "1.2" ;
doap:created "2011-05-26"
diff --git a/ext/midi.lv2/midi.ttl b/ext/midi.lv2/midi.ttl
index b08ced5..9621aa8 100644
--- a/ext/midi.lv2/midi.ttl
+++ b/ext/midi.lv2/midi.ttl
@@ -25,7 +25,7 @@
a lv2:Specification ;
doap:license <http://opensource.org/licenses/isc-license> ;
doap:name "LV2 MIDI Events" ;
- rdfs:comment "Defines an LV2 event type for standard raw MIDI" ;
+ doap:shortdesc "A data type for raw MIDI." ;
doap:release [
doap:revision "1.2" ;
doap:created "2011-05-21"
diff --git a/ext/osc.lv2/osc.ttl b/ext/osc.lv2/osc.ttl
index 6d84772..c83a69d 100644
--- a/ext/osc.lv2/osc.ttl
+++ b/ext/osc.lv2/osc.ttl
@@ -30,27 +30,10 @@
<http://lv2plug.in/ns/ext/osc> a lv2:Specification ;
doap:license <http://usefulinc.com/doap/licenses/mit> ;
doap:name "LV2 OSC Events" ;
- rdfs:comment "Defines an LV2 event type for standard raw OSC" ;
+ doap:shortdesc "A data type for raw OSC." ;
doap:maintainer [
a foaf:Person ;
foaf:name "David Robillard" ;
foaf:homepage <http://drobilla.net/> ;
rdfs:seeAlso <http://drobilla.net/drobilla.xrdf>
] .
-
-
-#######################
-## Plugin Properties ##
-#######################
-
-osc:interfacePort a rdf:Property ;
- rdfs:domain lv2:Plugin ;
- rdfs:range lv2:Port ;
- rdfs:label "Has a main OSC control port" ;
- rdfs:comment """
-Specifies a port that can be used as the OSC interface for the plugin as a
-whole. For example, if a host is providing an OSC interface to a plugin at
-/some/osc/path/someplugin and a message /some/osc/path/someplugin/foo is
-received, the message /foo should be sent to this port.
-""" .
-
diff --git a/ext/parameter.lv2/parameter.ttl b/ext/parameter.lv2/parameter.ttl
index c489c6f..f136ad9 100644
--- a/ext/parameter.lv2/parameter.ttl
+++ b/ext/parameter.lv2/parameter.ttl
@@ -31,6 +31,7 @@
<http://lv2plug.in/ns/ext/parameter>
a lv2:Specification ;
doap:name "LV2 Parameter" ;
+ doap:shortdesc "Dynamic message-controlled LV2 plugin parameters." ;
doap:maintainer [
a foaf:Person ;
foaf:name "David Robillard" ;
diff --git a/ext/port-groups.lv2/port-groups.ttl b/ext/port-groups.lv2/port-groups.ttl
index e0512db..b584a25 100644
--- a/ext/port-groups.lv2/port-groups.ttl
+++ b/ext/port-groups.lv2/port-groups.ttl
@@ -34,6 +34,7 @@
<http://lv2plug.in/ns/ext/port-groups> a lv2:Specification ;
doap:license <http://usefulinc.com/doap/licenses/mit> ;
doap:name "LV2 Port Groups" ;
+ doap:shortdesc "Multi-channel groups of LV2 ports." ;
rdfs:comment "Defines semantic groupings of LV2 ports" ;
doap:maintainer [
a foaf:Person ;
diff --git a/ext/presets.lv2/presets.ttl b/ext/presets.lv2/presets.ttl
index c20cb2d..165fc57 100644
--- a/ext/presets.lv2/presets.ttl
+++ b/ext/presets.lv2/presets.ttl
@@ -32,6 +32,7 @@
<http://lv2plug.in/ns/ext/presets> a lv2:Specification ;
doap:license <http://usefulinc.com/doap/licenses/mit> ;
doap:name "LV2 Presets" ;
+ doap:shortdesc "Presets for LV2 plugins. " ;
doap:release [
doap:revision "2.1" ;
doap:created "2010-10-29"
diff --git a/ext/reference.lv2/reference.ttl b/ext/reference.lv2/reference.ttl
index e928e06..fae31d3 100644
--- a/ext/reference.lv2/reference.ttl
+++ b/ext/reference.lv2/reference.ttl
@@ -24,6 +24,7 @@
<http://lv2plug.in/ns/ext/reference>
a lv2:Specification ;
doap:name "LV2 Reference" ;
+ doap:shortdesc "A reference data type for using non-POD data." ;
doap:release [
doap:revision "0.1" ;
doap:created "2011-07-22"
diff --git a/ext/resize-port.lv2/resize-port.ttl b/ext/resize-port.lv2/resize-port.ttl
index 38f6201..baa1f7f 100644
--- a/ext/resize-port.lv2/resize-port.ttl
+++ b/ext/resize-port.lv2/resize-port.ttl
@@ -35,6 +35,7 @@
a lv2:Specification ;
a lv2:Feature ;
doap:name "LV2 Resize Port Extension" ;
+ doap:shortdesc "Dynamically sized LV2 port buffers." ;
lv2:documentation """
<p>An extension that allows LV2 plugins to request a resize of an output port.</p>
diff --git a/ext/state.lv2/state.ttl b/ext/state.lv2/state.ttl
index ed132be..328dcc9 100644
--- a/ext/state.lv2/state.ttl
+++ b/ext/state.lv2/state.ttl
@@ -24,6 +24,7 @@
<http://lv2plug.in/ns/ext/state>
a lv2:Specification ;
doap:name "LV2 State" ;
+ doap:shortdesc "An interface for LV2 plugins to save and restore state." ;
doap:license <http://opensource.org/licenses/isc-license> ;
doap:release [
doap:revision "0.2" ;
diff --git a/ext/time.lv2/time.ttl b/ext/time.lv2/time.ttl
index b99c8d9..bf57402 100644
--- a/ext/time.lv2/time.ttl
+++ b/ext/time.lv2/time.ttl
@@ -24,6 +24,7 @@
<http://lv2plug.in/ns/ext/time>
a lv2:Specification ;
doap:name "LV2 Time" ;
+ doap:shortdesc "A data type for transport speed and position." ;
doap:maintainer [
a foaf:Person ;
foaf:name "David Robillard" ;
diff --git a/ext/ui-resize.lv2/ui-resize.ttl b/ext/ui-resize.lv2/ui-resize.ttl
index 83c4206..5e2a5a8 100644
--- a/ext/ui-resize.lv2/ui-resize.ttl
+++ b/ext/ui-resize.lv2/ui-resize.ttl
@@ -24,6 +24,7 @@
<http://lv2plug.in/ns/ext/ui-resize>
a lv2:Specification ;
doap:name "LV2 UI Resize Extension" ;
+ doap:shortdesc "A feature for self-resizing plugin UIs." ;
doap:license <http://opensource.org/licenses/isc-license> ;
lv2:documentation """
<p>An extension that allows LV2 plugin UIs to notify the host about size
diff --git a/ext/uri-map.lv2/uri-map.ttl b/ext/uri-map.lv2/uri-map.ttl
index e5dce43..d7ec97b 100644
--- a/ext/uri-map.lv2/uri-map.ttl
+++ b/ext/uri-map.lv2/uri-map.ttl
@@ -25,6 +25,7 @@
a lv2:Specification , lv2:Feature ;
doap:license <http://opensource.org/licenses/isc-license> ;
doap:name "LV2 URI Map" ;
+ doap:shortdesc "A feature for mapping URIs to integers." ;
doap:release [
doap:revision "1.2" ;
doap:created "2011-05-26"
diff --git a/ext/uri-unmap.lv2/uri-unmap.ttl b/ext/uri-unmap.lv2/uri-unmap.ttl
index 6efab1f..a55de8a 100644
--- a/ext/uri-unmap.lv2/uri-unmap.ttl
+++ b/ext/uri-unmap.lv2/uri-unmap.ttl
@@ -30,6 +30,7 @@
<http://lv2plug.in/ns/ext/uri-unmap> a lv2:Specification , lv2:Feature ;
doap:license <http://usefulinc.com/doap/licenses/mit> ;
doap:name "LV2 URI Unmap" ;
+ doap:shortdesc "A feature for unmapping URIs from integers." ;
doap:maintainer [
a foaf:Person ;
foaf:name "David Robillard" ;
diff --git a/ext/urid.lv2/urid.ttl b/ext/urid.lv2/urid.ttl
index f32ed99..fdc4871 100644
--- a/ext/urid.lv2/urid.ttl
+++ b/ext/urid.lv2/urid.ttl
@@ -24,6 +24,7 @@
a lv2:Specification ;
doap:license <http://opensource.org/licenses/isc-license> ;
doap:name "LV2 URID" ;
+ doap:shortdesc "Features for mapping URIs to and from integers." ;
doap:release [
doap:revision "0.1" ;
doap:created "2011-07-20"
diff --git a/gendoc.py b/gendoc.py
index 353176d..b6279f5 100755
--- a/gendoc.py
+++ b/gendoc.py
@@ -28,8 +28,9 @@ SPECGENDIR = './specgen'
STYLEURI = os.path.join('aux', 'style.css')
TAGFILE = './doclinks'
-rdf = rdflib.Namespace('http://www.w3.org/1999/02/22-rdf-syntax-ns#')
-lv2 = rdflib.Namespace('http://lv2plug.in/ns/lv2core#')
+doap = rdflib.Namespace('http://usefulinc.com/ns/doap#')
+lv2 = rdflib.Namespace('http://lv2plug.in/ns/lv2core#')
+rdf = rdflib.Namespace('http://www.w3.org/1999/02/22-rdf-syntax-ns#')
devnull = open(os.devnull, 'w')
@@ -44,12 +45,10 @@ subprocess.call('doxygen', stdout=devnull)
# Return the content of the first child node with a certain tag name
def getChildText(elt, tagname):
elements = elt.getElementsByTagName(tagname)
- text = ''
for e in elements:
if e.parentNode == elt:
- text = e.firstChild.nodeValue
- return text
- return text
+ return e.firstChild.nodeValue
+ return ''
tagdoc = xml.dom.minidom.parse('c_tags')
root = tagdoc.documentElement
@@ -114,13 +113,14 @@ for dir in ['ext', 'extensions']:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="application/xhtml+xml;charset=utf-8" />
-<title>LV2 Extensions</title>
+<title>LV2 Extension Index</title>
<link rel="stylesheet" type="text/css" href="../../""" + STYLEURI + """\" />
</head>
<body>
-<div id="titleheader"><h1 id="title">LV2 Extensions</h1></div>
+<div id="titleheader"><h1 id="title">LV2 Extension Index</h1></div>
<div class="content">
-<h2>""" + URIPREFIX + dir + "/</h2><ul>\n"
+<table summary="An index of LV2 extensions">
+<tr><th>Name</th><th>Description</th><th>Version</th><th>Date</th></tr>\n"""
extensions = []
@@ -128,9 +128,14 @@ for dir in ['ext', 'extensions']:
b = bundle.replace('.lv2', '')
b = b[b.find('/') + 1:]
- model = rdflib.ConjunctiveGraph()
- model.parse('%s/manifest.ttl' % bundle, format='n3')
- model.parse('%s/%s.ttl' % (bundle, b), format='n3')
+ try:
+ model = rdflib.ConjunctiveGraph()
+ model.parse('%s/manifest.ttl' % bundle, format='n3')
+ model.parse('%s/%s.ttl' % (bundle, b), format='n3')
+ except:
+ e = sys.exc_info()[1]
+ print('error parsing %s: %s' % (bundle, str(e)))
+ continue
# Get extension URI
ext_node = model.value(None, rdf.type, lv2.Specification)
@@ -149,6 +154,21 @@ for dir in ['ext', 'extensions']:
print "warning: %s: failed to find version for %s" % (bundle, ext)
pass
+ # Get date
+ date = None
+ for r in model.triples([ext_node, doap.release, None]):
+ revision = model.value(r[2], doap.revision, None)
+ if revision != ("%d.%d" % (minor, micro)):
+ print("warning: %s: doap:revision %s != %d.%d" % (
+ bundle, revision, minor, micro))
+ continue
+
+ date = model.value(r[2], doap.created, None)
+ break
+
+ # Get short description
+ shortdesc = model.value(ext_node, doap.shortdesc, None)
+
specgendir = '../../../lv2specgen/'
if (os.access(outdir + '/%s.lv2/%s.ttl' % (b, b), os.R_OK)):
oldcwd = os.getcwd()
@@ -164,11 +184,27 @@ for dir in ['ext', 'extensions']:
instances=True))
os.chdir(oldcwd)
- li = '<li>'
+ # Name
+ li = '<tr><td><a rel="rdfs:seeAlso" href="%s">%s</a></td>' % (b, b)
+
+ # Description
+ if shortdesc:
+ li += '<td>' + str(shortdesc) + '</td>'
+ else:
+ li += '<td></td>'
+
+ # Version
+ version_str = '%s.%s' % (minor, micro)
if minor == 0 or (micro % 2 != 0):
- li += '<span style="color: red;">Experimental: </span>'
- li += '<a rel="rdfs:seeAlso" href="%s">%s</a>' % (b, b)
- li += '</li>'
+ li += '<td><span style="color: red">' + version_str + ' dev</span></td>'
+ else:
+ li += '<td>' + version_str + '</td>'
+
+ # Date
+ if date:
+ li += '<td>' + str(date) + '</td>'
+
+ li += '</tr>'
extensions.append(li)
@@ -181,7 +217,7 @@ for dir in ['ext', 'extensions']:
for i in extensions:
index_html += i + '\n'
- index_html += '</ul>\n</div>\n'
+ index_html += '</table>\n</div>\n'
index_html += '<div id="footer">'
index_html += '<span class="footer-text">Generated on '
diff --git a/lv2specgen/template.html b/lv2specgen/template.html
index df49f17..d1a91ef 100644
--- a/lv2specgen/template.html
+++ b/lv2specgen/template.html
@@ -19,19 +19,17 @@
<!-- HEADER -->
<div id="titleheader">
<h1 id="title">@NAME@</h1>
- <div class="meta">
- <table>
- <tr><th class="metahead">URI</th><td><a href="@URI@">@URI@</a></td></tr>
- <tr><th class="metahead">Version</th><td>@REVISION@</td></tr>
- <tr><th class="metahead">Prefixes</th><td>@PREFIXES@</td></tr>
- <tr><th class="metahead">Discuss</th><td>
- <a href="mailto:@MAIL@">@MAIL@</a>
- (<a href="http://lists.lv2plug.in/listinfo.cgi/devel-lv2plug.in">subscribe</a>)
- </td></tr>
- @AUTHORS@
- @FILES@
- </table>
- </div>
+ <table id="meta">
+ <tr><th>URI</th><td><a href="@URI@">@URI@</a></td></tr>
+ <tr><th>Version</th><td>@REVISION@</td></tr>
+ <tr><th>Prefixes</th><td>@PREFIXES@</td></tr>
+ <tr><th>Discuss</th><td>
+ <a href="mailto:@MAIL@">@MAIL@</a>
+ (<a href="http://lists.lv2plug.in/listinfo.cgi/devel-lv2plug.in">subscribe</a>)
+ </td></tr>
+ @AUTHORS@
+ @FILES@
+ </table>
</div>
<!-- DESCRIPTION -->