You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@jena.apache.org by aj...@apache.org on 2017/10/07 16:14:05 UTC
Why RDF/XML? Was: loading many small rdf/xml files
Simply because it is both XML and RDF.
There is an enormous installed base of expertise and tooling for XML. It's often worth taking advantage of, even if it
is technically unperformant on a case-by-case basis. If you have to process RDF and you already know a great deal about
XML and use languages like XSLT or XQuery, reusing them for RDF is very attractive.
Historically, there was an idea of a unified layered architecture to the semantic web activity. I think this Wikipedia
page: https://en.wikipedia.org/wiki/Semantic_Web_Stack is old enough to portray that idea. I'm not sure anyone now would
be willing to argue that XML sits under RDF as a syntax layer. (Think about the evolution of JSON and JSON-LD, not shown
at all on that picture.)
ajs6f
Andrew U. Frank wrote on 10/7/17 12:06 PM:
> thank you - your link indicates why the solution with calling s-put for each individual file is so slow.
>
> practically - i will just wait the 10 hours and then extract the triples from the store.
>
> can you understand, why somebody would select this format? what is the advantage?
>
> andrew
>
>
>
> On 10/07/2017 10:52 AM, zPlus wrote:
>> Hello Andrew,
>>
>> if I understand this correctly, I think I stumbled on the same problem
>> before. Concatenating XML files will not work indeed. My solution was
>> to convert all XML files to N-Triples, then concatenate all those
>> triples into a single file, and finally load only this file.
>> Ultimately, what I ended up with is this loop [1]. The idea is to call
>> RIOT with a list of files as input, instead of calling RIOT on every
>> file.
>>
>> I hope this helps.
>>
>> ----
>> [1] https://notabug.org/metadb/pipeline/src/master/build.sh#L54
>>
>> ----- Original Message -----
>> From: users@jena.apache.org
>> To:"users@jena.apache.org" <us...@jena.apache.org>
>> Cc:
>> Sent:Sat, 7 Oct 2017 10:17:18 -0400
>> Subject:loading many small rdf/xml files
>>
>> i have to load the Gutenberg projects catalog in rdf/xml format. this
>> is
>> a collection of about 50,000 files, each containing a single record
>> as
>> attached.
>>
>> if i try to concatenate these files into a single one the result is
>> not
>> legal rdf/xml - there are xml doc headers:
>>
>> <rdf:RDF xml:base="http://www.gutenberg.org/">
>>
>> and similar, which can only occur once per file.
>>
>> i found a way to load each file individually with s-put and a loop,
>> but
>> this runs extremely slowly - it is alrady running for more than 10
>> hours; each file takes half a second to load (fuseki running as
>> localhost).
>>
>> i am sure there is a better way?
>>
>> thank you for the help!
>>
>> andrew
>>
>> --
>> em.o.Univ.Prof. Dr. sc.techn. Dr. h.c. Andrew U. Frank
>> +43 1 58801 12710 direct
>> Geoinformation, TU Wien +43 1 58801 12700 office
>> Gusshausstr. 27-29 +43 1 55801 12799 fax
>> 1040 Wien Austria +43 676 419 25 72 mobil
>>
>>
>>
>
Re: Why RDF/XML? Was: loading many small rdf/xml files
Posted by Martynas Jusevičius <ma...@atomgraph.com>.
I know that. We are using keys extensively (mostly to lookup blank nodes).
Still, XSLT processing model is based on XML trees, and not RDF graphs.
It also depends on the output format you want to produce. In our case it is
XHTML which renders the resources and properties (and not triples), so it
corresponds to RDF/XML nesting.
Therefore it's more natural (in our case at least) to be able to simply
invoke
<xsl:apply-templates/>
rather than
<xsl:apply-templates select="key('triples-by-subject-and-predicate',
concat($my-subject, ' ', $my-predicate))"/>
On Wed, Oct 11, 2017 at 12:10 PM, Conal Tuohy <co...@gmail.com> wrote:
> On 11 October 2017 at 19:30, Martynas Jusevičius <ma...@atomgraph.com>
> wrote:
>
> > TriX is not particularly well-suited for XSLT processing as it's a raw
> list
> > of statements. A nested resource/property structure like in RDF/XML is a
> > more natural fit for the parent/child traversal that XSLT does best.
> >
>
> In XSLT you're not restricted to traversing from parent to child elements.
> The "child" axis is only one of several XPath axes. There's also a very
> common programming pattern in XSLT for traversing cross-references (such as
> IDREF and internal URI references), by using an xsl:key to generate an
> index, and then looking up elements using the key() function. This allows
> you to look up triples by subject, or subject-and-predicate, etc:
>
> <xsl:apply-templates select="key('triples-by-subject-and-predicate',
> concat($my-subject, ' ', $my-predicate))"/>
>
> The value of TriX for graph processing in XSLT is precisely *because* it is
> just a list of statements. That is what makes it easy to process RDF *as a
> graph* in XSLT. Whereas if your dataset is encoded in RDF/XML, it's
> enormously difficult to process *as a graph*.
>
> --
> Conal Tuohy
> http://conaltuohy.com/
> @conal_tuohy
> +61-466-324297
>
Re: Why RDF/XML? Was: loading many small rdf/xml files
Posted by Conal Tuohy <co...@gmail.com>.
On 11 October 2017 at 19:30, Martynas Jusevičius <ma...@atomgraph.com>
wrote:
> TriX is not particularly well-suited for XSLT processing as it's a raw list
> of statements. A nested resource/property structure like in RDF/XML is a
> more natural fit for the parent/child traversal that XSLT does best.
>
In XSLT you're not restricted to traversing from parent to child elements.
The "child" axis is only one of several XPath axes. There's also a very
common programming pattern in XSLT for traversing cross-references (such as
IDREF and internal URI references), by using an xsl:key to generate an
index, and then looking up elements using the key() function. This allows
you to look up triples by subject, or subject-and-predicate, etc:
<xsl:apply-templates select="key('triples-by-subject-and-predicate',
concat($my-subject, ' ', $my-predicate))"/>
The value of TriX for graph processing in XSLT is precisely *because* it is
just a list of statements. That is what makes it easy to process RDF *as a
graph* in XSLT. Whereas if your dataset is encoded in RDF/XML, it's
enormously difficult to process *as a graph*.
--
Conal Tuohy
http://conaltuohy.com/
@conal_tuohy
+61-466-324297
Re: Why RDF/XML? Was: loading many small rdf/xml files
Posted by Martynas Jusevičius <ma...@atomgraph.com>.
TriX is not particularly well-suited for XSLT processing as it's a raw list
of statements. A nested resource/property structure like in RDF/XML is a
more natural fit for the parent/child traversal that XSLT does best.
On Wed, Oct 11, 2017 at 11:24 AM, Conal Tuohy <co...@gmail.com> wrote:
> On 11 October 2017 at 18:53, Martynas Jusevičius <ma...@atomgraph.com>
> wrote:
>
> > I wouldn't be so categorical :) We generate all the UI layouts straight
> > from RDF/XML using XSLT 2.0:
> > https://github.com/AtomGraph/Web-Client/blob/master/src/
> > main/webapp/static/com/atomgraph/client/xsl/bootstrap/2.3.2/layout.xsl
> >
> > The prerequisite is that RDF/XML structure is predictable like Jena's
> > output, not any RDF/XML that is possible in the wild.
>
>
> I agree; it's only convenient to process RDF/XML with XSLT when it is known
> to have some particular structure. And unfortunately, in general, RDF/XML
> can't be relied on to have any particular structure, because RDF/XML is a
> very complicated formats which provides many different ways to encode the
> same triples.
>
> For people who wish to process RDF using XSLT, XQuery, or similar
> languages, a simpler solution is to use an XML based format with a
> completely regular structure: TriX <TriX
> https://en.wikipedia.org/wiki/TriX_(serialization_format)>.
>
> TriX is supported by Jena and Fuseki; you can obtain a TriX representation
> using HTTP content negotiation in Fuseki, by sending an "Accept" header
> with the value "application/trix+xml".
> <https://www.w3.org/community/rax/wiki/Draft_Material#RDF.
> 2FXML_.22plain.22_profile_suitable_for_XSLT_transformations>
>
>
> On Wed, Oct 11, 2017 at 9:16 AM, Olivier Rossel <ol...@gmail.com>
> wrote:
>
> > I don't see any practical usage of managing RDF data via its XML
> > serialization through XML tools.
> > In my town, a huge project tried to store graph data in a XML
> > database. And querying all that with XQuery.
> > It was probably the most expensive failure I have seen in my career.
> > (performances were awful).
> >
> > I think it is and always has been a HUGE error to maintain this
> > ambiguity that RDF/XML is XML. No no and no, it is RDF.
> > May be you can generate RDF/XML via XML tools. Sure.
> > But consuming RDF/XML with XML tools is a BAD idea.
>
>
> --
> Conal Tuohy
> http://conaltuohy.com/
> @conal_tuohy
> +61-466-324297
>
Re: Why RDF/XML? Was: loading many small rdf/xml files
Posted by Conal Tuohy <co...@gmail.com>.
On 11 October 2017 at 18:53, Martynas Jusevičius <ma...@atomgraph.com>
wrote:
> I wouldn't be so categorical :) We generate all the UI layouts straight
> from RDF/XML using XSLT 2.0:
> https://github.com/AtomGraph/Web-Client/blob/master/src/
> main/webapp/static/com/atomgraph/client/xsl/bootstrap/2.3.2/layout.xsl
>
> The prerequisite is that RDF/XML structure is predictable like Jena's
> output, not any RDF/XML that is possible in the wild.
I agree; it's only convenient to process RDF/XML with XSLT when it is known
to have some particular structure. And unfortunately, in general, RDF/XML
can't be relied on to have any particular structure, because RDF/XML is a
very complicated formats which provides many different ways to encode the
same triples.
For people who wish to process RDF using XSLT, XQuery, or similar
languages, a simpler solution is to use an XML based format with a
completely regular structure: TriX <TriX
https://en.wikipedia.org/wiki/TriX_(serialization_format)>.
TriX is supported by Jena and Fuseki; you can obtain a TriX representation
using HTTP content negotiation in Fuseki, by sending an "Accept" header
with the value "application/trix+xml".
<https://www.w3.org/community/rax/wiki/Draft_Material#RDF.2FXML_.22plain.22_profile_suitable_for_XSLT_transformations>
On Wed, Oct 11, 2017 at 9:16 AM, Olivier Rossel <ol...@gmail.com>
wrote:
> I don't see any practical usage of managing RDF data via its XML
> serialization through XML tools.
> In my town, a huge project tried to store graph data in a XML
> database. And querying all that with XQuery.
> It was probably the most expensive failure I have seen in my career.
> (performances were awful).
>
> I think it is and always has been a HUGE error to maintain this
> ambiguity that RDF/XML is XML. No no and no, it is RDF.
> May be you can generate RDF/XML via XML tools. Sure.
> But consuming RDF/XML with XML tools is a BAD idea.
--
Conal Tuohy
http://conaltuohy.com/
@conal_tuohy
+61-466-324297
Re: Why RDF/XML? Was: loading many small rdf/xml files
Posted by Martynas Jusevičius <ma...@atomgraph.com>.
I wouldn't be so categorical :) We generate all the UI layouts straight
from RDF/XML using XSLT 2.0:
https://github.com/AtomGraph/Web-Client/blob/master/src/main/webapp/static/com/atomgraph/client/xsl/bootstrap/2.3.2/layout.xsl
The prerequisite is that RDF/XML structure is predictable like Jena's
output, not any RDF/XML that is possible in the wild. We have actually
proposed to standardise this in some form:
https://www.w3.org/community/rax/wiki/Draft_Material#RDF.2FXML_.22plain.22_profile_suitable_for_XSLT_transformations
On Wed, Oct 11, 2017 at 9:16 AM, Olivier Rossel <ol...@gmail.com>
wrote:
> I don't see any practical usage of managing RDF data via its XML
> serialization through XML tools.
> In my town, a huge project tried to store graph data in a XML
> database. And querying all that with XQuery.
> It was probably the most expensive failure I have seen in my career.
> (performances were awful).
>
> I think it is and always has been a HUGE error to maintain this
> ambiguity that RDF/XML is XML. No no and no, it is RDF.
> May be you can generate RDF/XML via XML tools. Sure.
> But consuming RDF/XML with XML tools is a BAD idea.
>
>
>
> On Sat, Oct 7, 2017 at 6:14 PM, <aj...@apache.org> wrote:
> > Simply because it is both XML and RDF.
> >
> > There is an enormous installed base of expertise and tooling for XML.
> It's
> > often worth taking advantage of, even if it is technically unperformant
> on a
> > case-by-case basis. If you have to process RDF and you already know a
> great
> > deal about XML and use languages like XSLT or XQuery, reusing them for
> RDF
> > is very attractive.
> >
> > Historically, there was an idea of a unified layered architecture to the
> > semantic web activity. I think this Wikipedia page:
> > https://en.wikipedia.org/wiki/Semantic_Web_Stack is old enough to
> portray
> > that idea. I'm not sure anyone now would be willing to argue that XML
> sits
> > under RDF as a syntax layer. (Think about the evolution of JSON and
> JSON-LD,
> > not shown at all on that picture.)
> >
> >
> > ajs6f
> >
> > Andrew U. Frank wrote on 10/7/17 12:06 PM:
> >>
> >> thank you - your link indicates why the solution with calling s-put for
> >> each individual file is so slow.
> >>
> >> practically - i will just wait the 10 hours and then extract the triples
> >> from the store.
> >>
> >> can you understand, why somebody would select this format? what is the
> >> advantage?
> >>
> >> andrew
> >>
> >>
> >>
> >> On 10/07/2017 10:52 AM, zPlus wrote:
> >>>
> >>> Hello Andrew,
> >>>
> >>> if I understand this correctly, I think I stumbled on the same problem
> >>> before. Concatenating XML files will not work indeed. My solution was
> >>> to convert all XML files to N-Triples, then concatenate all those
> >>> triples into a single file, and finally load only this file.
> >>> Ultimately, what I ended up with is this loop [1]. The idea is to call
> >>> RIOT with a list of files as input, instead of calling RIOT on every
> >>> file.
> >>>
> >>> I hope this helps.
> >>>
> >>> ----
> >>> [1] https://notabug.org/metadb/pipeline/src/master/build.sh#L54
> >>>
> >>> ----- Original Message -----
> >>> From: users@jena.apache.org
> >>> To:"users@jena.apache.org" <us...@jena.apache.org>
> >>> Cc:
> >>> Sent:Sat, 7 Oct 2017 10:17:18 -0400
> >>> Subject:loading many small rdf/xml files
> >>>
> >>> i have to load the Gutenberg projects catalog in rdf/xml format. this
> >>> is
> >>> a collection of about 50,000 files, each containing a single record
> >>> as
> >>> attached.
> >>>
> >>> if i try to concatenate these files into a single one the result is
> >>> not
> >>> legal rdf/xml - there are xml doc headers:
> >>>
> >>> <rdf:RDF xml:base="http://www.gutenberg.org/">
> >>>
> >>> and similar, which can only occur once per file.
> >>>
> >>> i found a way to load each file individually with s-put and a loop,
> >>> but
> >>> this runs extremely slowly - it is alrady running for more than 10
> >>> hours; each file takes half a second to load (fuseki running as
> >>> localhost).
> >>>
> >>> i am sure there is a better way?
> >>>
> >>> thank you for the help!
> >>>
> >>> andrew
> >>>
> >>> --
> >>> em.o.Univ.Prof. Dr. sc.techn. Dr. h.c. Andrew U. Frank
> >>> +43 1 58801 12710 direct
> >>> Geoinformation, TU Wien +43 1 58801 12700 office
> >>> Gusshausstr. 27-29 +43 1 55801 12799 fax
> >>> 1040 Wien Austria +43 676 419 25 72 mobil
> >>>
> >>>
> >>>
> >>
> >
>
RE: Why RDF/XML? Was: loading many small rdf/xml files
Posted by "John A. Fereira" <ja...@cornell.edu>.
I am the maintainer of a project called VIVO-Harvester (https://github.com/vivo-project/VIVO-Harvester). VIVO is a semantic web application that includes it's own ontology, primarily for modeling people, organizations, scholarly research and other attributes related to an academic environment. The VIVO Harvester is a suite of tools for taking structured data, mapping it to the ontology and loading the RDF into a triple store.
The project includes several "fetcher" tools that can read data from several formats (JSON, a SQL database, a CSV file, Excel spreadsheet, or simple XML either from a flat file or a web service). The output of the fetcher tools is a "faux" RDF file that uses a temporary namespace and a flat structure. XSLT transforms are used to map that RDF to the real ontology used by the VIVO application (there is no reason why it can't be used for other ontologies). The project might provide some ideas for non-VIVO projects as well. I'd suggest looking at the develop branch.
For the mapping to an ontology piece something like D2RQ is an option if you're data is in a relational database. I'd also suggest taking a look at a project called Karma (http://usc-isi-i2.github.io/karma/). It also can read data in multiple formats and provides a GUI for mapping data into RDF.
-----Original Message-----
From: Olivier Rossel [mailto:olivier.rossel@gmail.com]
Sent: Wednesday, October 11, 2017 3:16 AM
To: users@jena.apache.org; ajs6f@apache.org
Subject: Re: Why RDF/XML? Was: loading many small rdf/xml files
I don't see any practical usage of managing RDF data via its XML serialization through XML tools.
In my town, a huge project tried to store graph data in a XML database. And querying all that with XQuery.
It was probably the most expensive failure I have seen in my career.
(performances were awful).
I think it is and always has been a HUGE error to maintain this ambiguity that RDF/XML is XML. No no and no, it is RDF.
May be you can generate RDF/XML via XML tools. Sure.
But consuming RDF/XML with XML tools is a BAD idea.
On Sat, Oct 7, 2017 at 6:14 PM, <aj...@apache.org> wrote:
> Simply because it is both XML and RDF.
>
> There is an enormous installed base of expertise and tooling for XML.
> It's often worth taking advantage of, even if it is technically
> unperformant on a case-by-case basis. If you have to process RDF and
> you already know a great deal about XML and use languages like XSLT or
> XQuery, reusing them for RDF is very attractive.
>
> Historically, there was an idea of a unified layered architecture to
> the semantic web activity. I think this Wikipedia page:
> https://en.wikipedia.org/wiki/Semantic_Web_Stack is old enough to
> portray that idea. I'm not sure anyone now would be willing to argue
> that XML sits under RDF as a syntax layer. (Think about the evolution
> of JSON and JSON-LD, not shown at all on that picture.)
>
>
> ajs6f
>
> Andrew U. Frank wrote on 10/7/17 12:06 PM:
>>
>> thank you - your link indicates why the solution with calling s-put
>> for each individual file is so slow.
>>
>> practically - i will just wait the 10 hours and then extract the
>> triples from the store.
>>
>> can you understand, why somebody would select this format? what is
>> the advantage?
>>
>> andrew
>>
>>
>>
>> On 10/07/2017 10:52 AM, zPlus wrote:
>>>
>>> Hello Andrew,
>>>
>>> if I understand this correctly, I think I stumbled on the same
>>> problem before. Concatenating XML files will not work indeed. My
>>> solution was to convert all XML files to N-Triples, then concatenate
>>> all those triples into a single file, and finally load only this file.
>>> Ultimately, what I ended up with is this loop [1]. The idea is to
>>> call RIOT with a list of files as input, instead of calling RIOT on
>>> every file.
>>>
>>> I hope this helps.
>>>
>>> ----
>>> [1] https://notabug.org/metadb/pipeline/src/master/build.sh#L54
>>>
>>> ----- Original Message -----
>>> From: users@jena.apache.org
>>> To:"users@jena.apache.org" <us...@jena.apache.org>
>>> Cc:
>>> Sent:Sat, 7 Oct 2017 10:17:18 -0400
>>> Subject:loading many small rdf/xml files
>>>
>>> i have to load the Gutenberg projects catalog in rdf/xml format.
>>> this is
>>> a collection of about 50,000 files, each containing a single
>>> record as
>>> attached.
>>>
>>> if i try to concatenate these files into a single one the result
>>> is not
>>> legal rdf/xml - there are xml doc headers:
>>>
>>> <rdf:RDF xml:base="http://www.gutenberg.org/">
>>>
>>> and similar, which can only occur once per file.
>>>
>>> i found a way to load each file individually with s-put and a
>>> loop, but
>>> this runs extremely slowly - it is alrady running for more than 10
>>> hours; each file takes half a second to load (fuseki running as
>>> localhost).
>>>
>>> i am sure there is a better way?
>>>
>>> thank you for the help!
>>>
>>> andrew
>>>
>>> --
>>> em.o.Univ.Prof. Dr. sc.techn. Dr. h.c. Andrew U. Frank
>>> +43 1 58801 12710 direct
>>> Geoinformation, TU Wien +43 1 58801 12700 office
>>> Gusshausstr. 27-29 +43 1 55801 12799 fax
>>> 1040 Wien Austria +43 676 419 25 72 mobil
>>>
>>>
>>>
>>
>
Re: Why RDF/XML? Was: loading many small rdf/xml files
Posted by Olivier Rossel <ol...@gmail.com>.
I don't see any practical usage of managing RDF data via its XML
serialization through XML tools.
In my town, a huge project tried to store graph data in a XML
database. And querying all that with XQuery.
It was probably the most expensive failure I have seen in my career.
(performances were awful).
I think it is and always has been a HUGE error to maintain this
ambiguity that RDF/XML is XML. No no and no, it is RDF.
May be you can generate RDF/XML via XML tools. Sure.
But consuming RDF/XML with XML tools is a BAD idea.
On Sat, Oct 7, 2017 at 6:14 PM, <aj...@apache.org> wrote:
> Simply because it is both XML and RDF.
>
> There is an enormous installed base of expertise and tooling for XML. It's
> often worth taking advantage of, even if it is technically unperformant on a
> case-by-case basis. If you have to process RDF and you already know a great
> deal about XML and use languages like XSLT or XQuery, reusing them for RDF
> is very attractive.
>
> Historically, there was an idea of a unified layered architecture to the
> semantic web activity. I think this Wikipedia page:
> https://en.wikipedia.org/wiki/Semantic_Web_Stack is old enough to portray
> that idea. I'm not sure anyone now would be willing to argue that XML sits
> under RDF as a syntax layer. (Think about the evolution of JSON and JSON-LD,
> not shown at all on that picture.)
>
>
> ajs6f
>
> Andrew U. Frank wrote on 10/7/17 12:06 PM:
>>
>> thank you - your link indicates why the solution with calling s-put for
>> each individual file is so slow.
>>
>> practically - i will just wait the 10 hours and then extract the triples
>> from the store.
>>
>> can you understand, why somebody would select this format? what is the
>> advantage?
>>
>> andrew
>>
>>
>>
>> On 10/07/2017 10:52 AM, zPlus wrote:
>>>
>>> Hello Andrew,
>>>
>>> if I understand this correctly, I think I stumbled on the same problem
>>> before. Concatenating XML files will not work indeed. My solution was
>>> to convert all XML files to N-Triples, then concatenate all those
>>> triples into a single file, and finally load only this file.
>>> Ultimately, what I ended up with is this loop [1]. The idea is to call
>>> RIOT with a list of files as input, instead of calling RIOT on every
>>> file.
>>>
>>> I hope this helps.
>>>
>>> ----
>>> [1] https://notabug.org/metadb/pipeline/src/master/build.sh#L54
>>>
>>> ----- Original Message -----
>>> From: users@jena.apache.org
>>> To:"users@jena.apache.org" <us...@jena.apache.org>
>>> Cc:
>>> Sent:Sat, 7 Oct 2017 10:17:18 -0400
>>> Subject:loading many small rdf/xml files
>>>
>>> i have to load the Gutenberg projects catalog in rdf/xml format. this
>>> is
>>> a collection of about 50,000 files, each containing a single record
>>> as
>>> attached.
>>>
>>> if i try to concatenate these files into a single one the result is
>>> not
>>> legal rdf/xml - there are xml doc headers:
>>>
>>> <rdf:RDF xml:base="http://www.gutenberg.org/">
>>>
>>> and similar, which can only occur once per file.
>>>
>>> i found a way to load each file individually with s-put and a loop,
>>> but
>>> this runs extremely slowly - it is alrady running for more than 10
>>> hours; each file takes half a second to load (fuseki running as
>>> localhost).
>>>
>>> i am sure there is a better way?
>>>
>>> thank you for the help!
>>>
>>> andrew
>>>
>>> --
>>> em.o.Univ.Prof. Dr. sc.techn. Dr. h.c. Andrew U. Frank
>>> +43 1 58801 12710 direct
>>> Geoinformation, TU Wien +43 1 58801 12700 office
>>> Gusshausstr. 27-29 +43 1 55801 12799 fax
>>> 1040 Wien Austria +43 676 419 25 72 mobil
>>>
>>>
>>>
>>
>