blob: 786607bc74cca7db0cf90e6b0d6e8c5310cabbb5 [file] [log] [blame]
<!DOCTYPE html>
<html lang="en">
<head>
<title>Apache Jena - Fuseki Data Service Configuration Syntax</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="/css/bootstrap.min.css" rel="stylesheet" media="screen">
<link href="/css/bootstrap-extension.css" rel="stylesheet" type="text/css">
<link href="/css/jena.css" rel="stylesheet" type="text/css">
<link rel="shortcut icon" href="/images/favicon.ico" />
<script src="https://code.jquery.com/jquery-2.2.4.min.js"
integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44="
crossorigin="anonymous"></script>
<script src="/js/jena-navigation.js" type="text/javascript"></script>
<script src="/js/bootstrap.min.js" type="text/javascript"></script>
<script src="/js/improve.js" type="text/javascript"></script>
</head>
<body>
<nav class="navbar navbar-default" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-ex1-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/index.html">
<img class="logo-menu" src="/images/jena-logo/jena-logo-notext-small.png" alt="jena logo">Apache Jena</a>
</div>
<div class="collapse navbar-collapse navbar-ex1-collapse">
<ul class="nav navbar-nav">
<li id="homepage"><a href="/index.html"><span class="glyphicon glyphicon-home"></span> Home</a></li>
<li id="download"><a href="/download/index.cgi"><span class="glyphicon glyphicon-download-alt"></span> Download</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown"><span class="glyphicon glyphicon-book"></span> Learn <b class="caret"></b></a>
<ul class="dropdown-menu">
<li class="dropdown-header">Tutorials</li>
<li><a href="/tutorials/index.html">Overview</a></li>
<li><a href="/documentation/fuseki2/index.html">Fuseki Triplestore</a></li>
<li><a href="/documentation/notes/index.html">How-To's</a></li>
<li><a href="/documentation/query/manipulating_sparql_using_arq.html">Manipulating SPARQL using ARQ</a></li>
<li><a href="/tutorials/rdf_api.html">RDF core API tutorial</a></li>
<li><a href="/tutorials/sparql.html">SPARQL tutorial</a></li>
<li><a href="/tutorials/using_jena_with_eclipse.html">Using Jena with Eclipse</a></li>
<li class="divider"></li>
<li class="dropdown-header">References</li>
<li><a href="/documentation/index.html">Overview</a></li>
<li><a href="/documentation/query/index.html">ARQ (SPARQL)</a></li>
<li><a href="/documentation/assembler/index.html">Assembler</a></li>
<li><a href="/documentation/tools/index.html">Command-line tools</a></li>
<li><a href="/documentation/rdfs/">Data with RDFS Inferencing</a></li>
<li><a href="/documentation/geosparql/index.html">GeoSPARQL</a></li>
<li><a href="/documentation/inference/index.html">Inference API</a></li>
<li><a href="/documentation/javadoc.html">Javadoc</a></li>
<li><a href="/documentation/ontology/">Ontology API</a></li>
<li><a href="/documentation/permissions/index.html">Permissions</a></li>
<li><a href="/documentation/extras/querybuilder/index.html">Query Builder</a></li>
<li><a href="/documentation/rdf/index.html">RDF API</a></li>
<li><a href="/documentation/rdfconnection/">RDF Connection - SPARQL API</a></li>
<li><a href="/documentation/io/">RDF I/O</a></li>
<li><a href="/documentation/rdfstar/index.html">RDF-star</a></li>
<li><a href="/documentation/shacl/index.html">SHACL</a></li>
<li><a href="/documentation/shex/index.html">ShEx</a></li>
<li><a href="/documentation/jdbc/index.html">SPARQL over JDBC</a></li>
<li><a href="/documentation/tdb/index.html">TDB</a></li>
<li><a href="/documentation/tdb2/index.html">TDB2</a></li>
<li><a href="/documentation/query/text-query.html">Text Search</a></li>
</ul>
</li>
<li class="drop down">
<a href="#" class="dropdown-toggle" data-toggle="dropdown"><span class="glyphicon glyphicon-book"></span> Javadoc <b class="caret"></b></a>
<ul class="dropdown-menu">
<li><a href="/documentation/javadoc.html">All Javadoc</a></li>
<li><a href="/documentation/javadoc/arq/">ARQ</a></li>
<li><a href="/documentation/javadoc_elephas.html">Elephas</a></li>
<li><a href="/documentation/javadoc/fuseki2/">Fuseki</a></li>
<li><a href="/documentation/javadoc/geosparql/">GeoSPARQL</a></li>
<li><a href="/documentation/javadoc/jdbc/">JDBC</a></li>
<li><a href="/documentation/javadoc/jena/">Jena Core</a></li>
<li><a href="/documentation/javadoc/permissions/">Permissions</a></li>
<li><a href="/documentation/javadoc/extras/querybuilder/">Query Builder</a></li>
<li><a href="/documentation/javadoc/shacl/">SHACL</a></li>
<li><a href="/documentation/javadoc/tdb/">TDB</a></li>
<li><a href="/documentation/javadoc/text/">Text Search</a></li>
</ul>
</li>
<li id="ask"><a href="/help_and_support/index.html"><span class="glyphicon glyphicon-question-sign"></span> Ask</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown"><span class="glyphicon glyphicon-bullhorn"></span> Get involved <b class="caret"></b></a>
<ul class="dropdown-menu">
<li><a href="/getting_involved/index.html">Contribute</a></li>
<li><a href="/help_and_support/bugs_and_suggestions.html">Report a bug</a></li>
<li class="divider"></li>
<li class="dropdown-header">Project</li>
<li><a href="/about_jena/about.html">About Jena</a></li>
<li><a href="/about_jena/architecture.html">Architecture</a></li>
<li><a href="/about_jena/citing.html">Citing</a></li>
<li><a href="/about_jena/team.html">Project team</a></li>
<li><a href="/about_jena/contributions.html">Related projects</a></li>
<li><a href="/about_jena/roadmap.html">Roadmap</a></li>
<li class="divider"></li>
<li class="dropdown-header">ASF</li>
<li><a href="http://www.apache.org/">Apache Software Foundation</a></li>
<li><a href="http://www.apache.org/foundation/sponsorship.html">Become a Sponsor</a></li>
<li><a href="http://www.apache.org/licenses/LICENSE-2.0">License</a></li>
<li><a href="http://www.apache.org/security/">Security</a></li>
<li><a href="http://www.apache.org/foundation/thanks.html">Thanks</a></li>
</ul>
</li>
<li id="edit"><a href="https://github.com/apache/jena-site/edit/main/source/documentation/fuseki2/fuseki-config-endpoint.md" title="Edit this page on GitHub"><span class="glyphicon glyphicon-pencil"></span> Edit this page</a></li>
</ul>
</div>
</div>
</nav>
<div class="container">
<div class="row">
<div class="col-md-12">
<div id="breadcrumbs">
<ol class="breadcrumb">
<li><a href='/documentation'>DOCUMENTATION</a></li>
<li><a href='/documentation/fuseki2'>FUSEKI2</a></li>
<li class="active">FUSEKI CONFIG ENDPOINT</li>
</ol>
</div>
<h1 class="title">Fuseki Data Service Configuration Syntax</h1>
<p>A data service provides a number of operations on a dataset. These can be
explicitly named endpoints or operations at the URL of the dataset. New
operations can be configured in; these typically have their own named endpoints.</p>
<h2 id="syntax">Syntax</h2>
<p>Here is an example of a server configuration that provides one operation, SPARQL
query, and then only on the dataset URL.</p>
<pre><code>PREFIX : &lt;#&gt;
PREFIX fuseki: &lt;http://jena.apache.org/fuseki#&gt;
PREFIX rdf: &lt;http://www.w3.org/1999/02/22-rdf-syntax-ns#&gt;
[] rdf:type fuseki:Server .
&lt;#service&gt; rdf:type fuseki:Service ;
fuseki:name &quot;dataset&quot; ;
fuseki:endpoint [ fuseki:operation fuseki:query ] ;
fuseki:dataset &lt;#dataset&gt; .
## In memory transactional dataset initially loaded
## with the contents of file &quot;data.trig&quot;
&lt;#dataset&gt; rdf:type ja:MemoryDataset;
ja:data &quot;data.trig&quot; .
</code></pre>
<p>This is invoked with a URL of the form
<tt>http://<i>host:port</i>/dataset?query=...</tt>
which is a SPARQL query request sent to the dataset URL.</p>
<p>The property <code>fuseki:endpoint</code> describes the operation available. No name is
given so the operation is available at the URL of the dataset.</p>
<p><code>fuseki:dataset</code> names the dataset to be used with this data service.</p>
<p>In this second example:</p>
<pre><code>&lt;#service&gt; rdf:type fuseki:Service ;
fuseki:name &quot;dataset&quot; ;
fuseki:endpoint [
fuseki:operation fuseki:query ;
fuseki:name &quot;sparql&quot;;
];
fuseki:dataset &lt;#dataset&gt; .
</code></pre>
<p>the endpoint has a name. The URL to invoke the operation is now:</p>
<p><tt>http://<i>host:port</i>/dataset/sparql?query=...</tt></p>
<p>and is similar to older form:</p>
<pre><code>&lt;#service&gt; rdf:type fuseki:Service ;
fuseki:name &quot;dataset&quot; ;
fuseki:serviceQuery &quot;sparql&quot; ;
fuseki:dataset &lt;#dataset&gt; .
</code></pre>
<p>Operations on the dataset URL have the name <code>&quot;&quot;</code> (the empty string) and this is
the default. The first example is the same as:</p>
<pre><code>&lt;#service&gt; rdf:type fuseki:Service ;
fuseki:name &quot;dataset&quot; ;
fuseki:endpoint [
fuseki:operation fuseki:query ;
fuseki:name &quot;&quot; ;
] ;
fuseki:dataset &lt;#dataset&gt; .
</code></pre>
<h3 id="original-configuration-syntax">Original Configuration Syntax</h3>
<p>The syntax described on this page was introduced in Apache Jena 3.13.0.</p>
<p>The <a href="fuseki-old-config-endpoint.html">previous syntax</a> is still valid.</p>
<p>The new syntax enables more configuration options and gives more control of server functionality:</p>
<ul>
<li>setting the context on a per-endpoint basis</li>
<li>having multiple operations at the service access point, switching based on
operation type</li>
<li>a more general structure for adding custom services</li>
<li>adding custom extensions to a Fuseki server</li>
</ul>
<h2 id="operations">Operations</h2>
<p>The following operations are provided:</p>
<table>
<thead>
<tr>
<th>URI</th>
<th>Operation</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>fuseki:query</code></td>
<td>SPARQL 1.1 Query with ARQ extensions</td>
</tr>
<tr>
<td><code>fuseki:update</code></td>
<td>SPARQL 1.1 Update with ARQ extensions</td>
</tr>
<tr>
<td><code>fuseki:gsp-r</code></td>
<td>SPARQL Graph Store Protocol and Quad extensions (read only)</td>
</tr>
<tr>
<td><code>fuseki:gsp-rw</code></td>
<td>SPARQL Graph Store Protocol and Quad extensions</td>
</tr>
<tr>
<td><code>fuseki:upload</code></td>
<td>HTML form file upload</td>
</tr>
<tr>
<td><code>fuseki:no-op</code></td>
<td>An operation that causes a 400 or 404 error</td>
</tr>
</tbody>
</table>
<p>Custom extensions can be added (see <a href="fuseki-main.html#build">Programmatic configuration</a> of the Fuseki server). To be able to uniquely identify the operation, these are usually</p>
<pre><code> fuseki:endpoint [
fuseki:operation fuseki:shacl ;
fuseki:name &quot;shacl&quot; ;
] ;
</code></pre>
<p>See the section <a href="/documentation/shacl/#integration-with-apache-jena-fuseki">&ldquo;Integration with Apache Jena Fuseki&rdquo;</a> for details of the SHACL support. While this operation is part of the standard Fuseki distribution, this operation is added during system initialization, using the custom operation support.</p>
<h3 id="command-line-equivalents">Command Line Equivalents</h3>
<p>The standard set of service installed by running the server from the command line
without a configuration file is for a read-only:</p>
<pre><code>&lt;#service1&gt; rdf:type fuseki:Service ;
fuseki:name &quot;dataset&quot; ;
fuseki:endpoint [ fuseki:operation fuseki:query ; ];
fuseki:endpoint [ fuseki:operation fuseki:query ; fuseki:name &quot;sparql&quot; ];
fuseki:endpoint [ fuseki:operation fuseki:query ; fuseki:name &quot;query&quot; ];
fuseki:endpoint [ fuseki:operation fuseki:gsp-r ; ];
fuseki:endpoint [ fuseki:operation fuseki:gsp-r ; fuseki:name &quot;get&quot; ];
fuseki:dataset ...
</code></pre>
<p>which supports requests such as:</p>
<pre><code>http://&lt;i&gt;host:port&lt;/i&gt;/dataset?query=...
http://&lt;i&gt;host:port&lt;/i&gt;/dataset/sparql?query=...
http://&lt;i&gt;host:port&lt;/i&gt;/dataset?default
http://&lt;i&gt;host:port&lt;/i&gt;/dataset/get?default
</code></pre>
<p>and for an updatable dataset (command line <code>--mem</code> for an in-memory dataset;
or with TDB storage, with <code>--update</code>):</p>
<pre><code>&lt;#service1&gt; rdf:type fuseki:Service ;
fuseki:name &quot;dataset&quot; ;
fuseki:endpoint [ fuseki:operation fuseki:query ;];
fuseki:endpoint [ fuseki:operation fuseki:query ; fuseki:name &quot;sparql&quot; ];
fuseki:endpoint [ fuseki:operation fuseki:query ; fuseki:name &quot;query&quot; ];
fuseki:endpoint [ fuseki:operation fuseki:update ; ];
fuseki:endpoint [ fuseki:operation fuseki:update ; fuseki:name &quot;update&quot; ];
fuseki:endpoint [ fuseki:operation fuseki:gsp-r ; fuseki:name &quot;get&quot; ];
fuseki:endpoint [ fuseki:operation fuseki:gsp-rw ; ] ;
fuseki:endpoint [ fuseki:operation fuseki:gsp-rw ; fuseki:name &quot;data&quot; ];
fuseki:endpoint [ fuseki:operation fuseki:upload ; fuseki:name &quot;upload&quot; ]
fuseki:dataset ...
</code></pre>
<p>which adds requests that can change the data.</p>
<p>New operations can be added by programmatic setup in <a href="/documentation/fuseki2/fuseki-main">Fuseki Main</a>.</p>
<h2 id="dispatch">Dispatch</h2>
<p>&ldquo;Dispatch&rdquo; is the process of routing a HTTP request to a specific operation
processor implementation to handle the request.</p>
<p>Dispatch to named endpoint usually happens from the name alone, when there is a
unique name for an endpoint. If, however, two endpoints give the same
<code>fuseki:name</code>, or if operations are defined for the dataset itself, then
dispatch is based on a second step of determining the operation type by
inspecting the request. Each of the SPARQL operations has a unique signature.</p>
<p>A query is either a GET with query string including &ldquo;?query=&rdquo;, or a POST with a
content type of the body &ldquo;application/sparql-query&rdquo;, or an HTML form with a field
&ldquo;query=&rdquo;</p>
<p>An update is a POST where the body is &ldquo;application/sparql-update&rdquo; or an HTML
form with field &ldquo;update=&rdquo;.</p>
<p>A GSP operation has <code>?default</code> or <code>?graph=</code>.</p>
<p>Quads operations have no query string and a have a <code>Content-Type</code> for a data in
a RDF triples or quads syntax.</p>
<p>So, for example &ldquo;GET /dataset&rdquo; is a request to get all the triples and quads in the
dataset. The syntax for the response is determined by content negotiation,
defaulting to <code>text/trig</code>.</p>
<p>Custom services usually use a named endpoint. Custom operations
can specific a content type that they handle, which must be unique for the
operation. They can not provide a query string signature for dispatch.</p>
<h2 id="common-cases">Common Cases</h2>
<p>This section describes a few deployment patterns:</p>
<h4 id="case-1-read-only-dataset">Case 1: Read-only Dataset</h4>
<p>The 2 SPARQL standard operations for a read-only dataset:</p>
<pre><code>&lt;#service&gt; rdf:type fuseki:Service ;
fuseki:name &quot;ds-read-only&quot; ;
## fuseki:name &quot;&quot; is optional.
fuseki:endpoint [ fuseki:operation fuseki:query; ] ;
fuseki:endpoint [ fuseki:operation fuseki:gsp-r; ] ;
fuseki:dataset &lt;#dataset&gt; .
</code></pre>
<p>This is good for publishing data.</p>
<h4 id="case-2-dataset-level-operation">Case 2: Dataset level operation.</h4>
<p>The 3 SPARQL standard operations for a read-write dataset, request are sent to <tt>http://<i>host:port</i>/dataset</tt>. There are no named endpoint services.</p>
<pre><code>&lt;#service&gt; rdf:type fuseki:Service ;
fuseki:name &quot;ds-rw&quot; ;
## fuseki:name &quot;&quot; is optional.
fuseki:endpoint [ fuseki:operation fuseki:query; ] ;
fuseki:endpoint [ fuseki:operation fuseki:update;] ;
fuseki:endpoint [ fuseki:operation fuseki:gsp-rw; ] ;
fuseki:dataset &lt;#dataset&gt; .
</code></pre>
<h4 id="case-3-named-endpoints">Case 3: Named endpoints</h4>
<pre><code>&lt;#service1&gt; rdf:type fuseki:Service ;
fuseki:name &quot;ds-named&quot; ;
fuseki:endpoint [ fuseki:operation fuseki:query; fuseki:name &quot;sparql&quot; ] ;
fuseki:endpoint [ fuseki:operation fuseki:query; fuseki:name &quot;query&quot; ] ;
fuseki:endpoint [ fuseki:operation fuseki:update; fuseki:name &quot;update&quot; ] ;
fuseki:endpoint [ fuseki:operation fuseki:upload; fuseki:name &quot;upload&quot; ] ;
fuseki:endpoint [ fuseki:operation fuseki:gsp_r; fuseki:name &quot;get&quot; ] ;
fuseki:endpoint [ fuseki:operation fuseki:gsp_rw; fuseki:name &quot;data&quot; ] ;
fuseki:dataset &lt;#dataset&gt; .
</code></pre>
<p>The operation on this dataset can only be accessed as &ldquo;/ds-named/sparql&rdquo;,
&ldquo;/ds-named/update&rdquo; etc, not as &ldquo;/ds-named&rdquo;.</p>
<h4 id="case-4-named-endpoints-with-query-of-the-dataset">Case 4: Named endpoints with query of the dataset.</h4>
<pre><code>&lt;#service1&gt; rdf:type fuseki:Service ;
fuseki:name &quot;ds&quot; ;
fuseki:endpoint [ fuseki:operation fuseki:query ] ;
fuseki:endpoint [ fuseki:operation fuseki:query; fuseki:name &quot;sparql&quot; ] ;
fuseki:endpoint [ fuseki:operation fuseki:query; fuseki:name &quot;query&quot; ] ;
fuseki:endpoint [ fuseki:operation fuseki:update; fuseki:name &quot;update&quot; ] ;
fuseki:endpoint [ fuseki:operation fuseki:upload; fuseki:name &quot;upload&quot; ] ;
fuseki:endpoint [ fuseki:operation fuseki:gsp_r; fuseki:name &quot;get&quot; ] ;
fuseki:endpoint [ fuseki:operation fuseki:gsp_rw; fuseki:name &quot;data&quot; ] ;
fuseki:dataset &lt;#dataset&gt; .
</code></pre>
<p>The operations on this dataset are accessed as &ldquo;/ds/sparql&rdquo;,
&ldquo;/ds/update&rdquo; etc. In addition, &ldquo;/ds?query=&rdquo; provided SPARQL query.</p>
<h2 id="quad-extensions">Quad extensions</h2>
<p>The GSP (SPARQL Graph Store Protocol) operations provide the HTTP operations of
GET, POST, PUT and DELETE for specific graphs in the RDF dataset. The SPARQL GSP
standard includes identifying the target graph with <code>?default</code> or <code>?graph=...uri...</code> and
the request or response is one of the RDF triple syntaxes (Turtle, N-Triples,
JSON-LD, RDF/XML) as well as older proposals (TriX and RDF/JSON).</p>
<p>Apache Jena Fuseki also provides quad operations for HTTP methods
GET, POST, PUT (not DELETE, that would be the dataset itself),
and the request or response is one of the syntaxes for datasets
(TriG, N-Quads, JSON-LD, TriX).</p>
<p>Fuseki also provides [/documentation/io/rdf-binary.html](RDF Binary) for triples and quads.</p>
<p>The quads extension applies when there is no <code>?default</code> or <code>?graph</code>.
<code>GET</code> fetches the dataset in quads format, and <code>PUT</code> and <code>POST</code> take quads format data (N-Quads and Trig).</p>
<h2 id="context">Context</h2>
<p>Each operation execution is given a &ldquo;context&rdquo; - a set of name-value pairs.
Internally, this is used for system registries, for the fixed &ldquo;current time&rdquo; for
an operation. The context is the merge of the server&rsquo;s context, any additional
settings on the dataset and any settings for the endpoint. The merge is performed
in that order - server then dataset then endpoint.</p>
<p>Uses for the context setting include query timeouts and making default query pattern
matching apply to the union of named graphs, not the default graph.</p>
<p>In this example (prefix <code>tdb2:</code> is for URI <code>&lt;http://jena.apache.org/2016/tdb#&gt;</code>):</p>
<pre><code>&lt;#servicetdb&gt; rdf:type fuseki:Service ;
fuseki:name &quot;ds-tdb&quot; ;
fuseki:endpoint [
fuseki:operation fuseki:query ;
fuseki:name &quot;sparql-union&quot; ;
ja:context [ ja:cxtName &quot;tdb:unionDefaultGraph&quot; ; ja:cxtValue true ] ;
] ;
fuseki:endpoint [ fuseki:operation fuseki:query; ] ;
fuseki:endpoint [ fuseki:operation fuseki:update; ] ;
fuseki:dataset &lt;#tdbDataset&gt; .
&lt;#tdbDataset&gt; rdf:type tdb2:DatasetTDB ;
ja:context [ ja:cxtName &quot;arq:queryTimeout&quot; ; ja:cxtValue &quot;10000,30000&quot; ] ;
tdb2:location &quot;DATA&quot; .
</code></pre>
<p>&ldquo;/ds-tdb&rdquo; is a <a href="/documentation/tdb2/">TDB2 database</a> with endpoints for SPARQL
query and update on the dataset URL. In addition, it has a named service
&ldquo;/ds-tdb/sparql-union&rdquo; where the query works with the union of named graphs as
the default graph.</p>
<p>Query timeout is set for any use of the dataset with first result in 10
seconds, and complete results in 30 seconds.</p>
<h2 id="security">Security</h2>
<p>The page <a href="./fuseki-data-access-control.html">Data Access Control for Fuseki</a>
covers the</p>
<p>For endpoints, the permitted users are part of the endpoint description.</p>
<pre><code>fuseki:endpoint [
fuseki:operation fuseki:query;
fuseki:name &quot;sparql&quot; ;
fuseki:allowedUsers &quot;user1&quot;, &quot;user2&quot;
] ;
</code></pre>
</div>
</div>
</div>
<footer class="footer">
<div class="container" style="font-size:80%" >
<p>
Copyright &copy; 2011&ndash;2022 The Apache Software Foundation, Licensed under the
<a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.
</p>
<p>
Apache Jena, Jena, the Apache Jena project logo, Apache and the Apache feather logos are trademarks of
The Apache Software Foundation.
<br/>
<a href="https://privacy.apache.org/policies/privacy-policy-public.html"
>Apache Software Foundation Privacy Policy</a>.
</p>
</div>
</footer>
<script type="text/javascript">
var link = $('a[href="' + this.location.pathname + '"]');
if (link != undefined)
link.parents('li,ul').addClass('active');
</script>
</body>
</html>