blob: 0c7d66fb9d62b8aab7fd613b307ac25c37e887cb [file] [log] [blame]
Yingyi Bu08953b22016-03-25 15:23:26 -07001<!DOCTYPE html>
2<!--
3 | Generated by Apache Maven Doxia at 2016-03-25
4 | Rendered using Apache Maven Fluido Skin 1.3.0
5-->
6<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
7 <head>
8 <meta charset="UTF-8" />
9 <meta name="viewport" content="width=device-width, initial-scale=1.0" />
10 <meta name="Date-Revision-yyyymmdd" content="20160325" />
11 <meta http-equiv="Content-Language" content="en" />
12 <title>AsterixDB &#x2013; AsterixDB Temporal Functions: Allens Relations</title>
13 <link rel="stylesheet" href="../css/apache-maven-fluido-1.3.0.min.css" />
14 <link rel="stylesheet" href="../css/site.css" />
15 <link rel="stylesheet" href="../css/print.css" media="print" />
16
17
18 <script type="text/javascript" src="../js/apache-maven-fluido-1.3.0.min.js"></script>
19
20
21
22<script>(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
23 (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
24 m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
25 })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
26
27 ga('create', 'UA-41536543-1', 'uci.edu');
28 ga('send', 'pageview');</script>
29
30 </head>
31 <body class="topBarDisabled">
32
33
34
35
36 <div class="container-fluid">
37 <div id="banner">
38 <div class="pull-left">
39 <a href="http://asterixdb.apache.org/" id="bannerLeft">
40 <img src="../images/asterixlogo.png" alt="AsterixDB"/>
41 </a>
42 </div>
43 <div class="pull-right"> </div>
44 <div class="clear"><hr/></div>
45 </div>
46
47 <div id="breadcrumbs">
48 <ul class="breadcrumb">
49
50
51 <li id="publishDate">Last Published: 2016-03-25</li>
52
53
54
55 <li id="projectVersion" class="pull-right">Version: 0.8.8-incubating</li>
56
57 <li class="divider pull-right">|</li>
58
59 <li class="pull-right"> <a href="../index.html" title="Documentation Home">
60 Documentation Home</a>
61 </li>
62
63 </ul>
64 </div>
65
66
67 <div class="row-fluid">
68 <div id="leftColumn" class="span3">
69 <div class="well sidebar-nav">
70
71
72 <ul class="nav nav-list">
73 <li class="nav-header">Documentation</li>
74
75 <li>
76
77 <a href="../install.html" title="Installing and Managing AsterixDB using Managix">
78 <i class="none"></i>
79 Installing and Managing AsterixDB using Managix</a>
80 </li>
81
82 <li>
83
84 <a href="../yarn.html" title="Deploying AsterixDB using YARN">
85 <i class="none"></i>
86 Deploying AsterixDB using YARN</a>
87 </li>
88
89 <li>
90
91 <a href="../aql/primer.html" title="AsterixDB 101: An ADM and AQL Primer">
92 <i class="none"></i>
93 AsterixDB 101: An ADM and AQL Primer</a>
94 </li>
95
96 <li>
97
98 <a href="../aql/primer-sql-like.html" title="AsterixDB 101: An ADM and AQL Primer (For SQL Fans)">
99 <i class="none"></i>
100 AsterixDB 101: An ADM and AQL Primer (For SQL Fans)</a>
101 </li>
102
103 <li>
104
Yingyi Bu08953b22016-03-25 15:23:26 -0700105 <a href="../aql/datamodel.html" title="Asterix Data Model (ADM)">
106 <i class="none"></i>
107 Asterix Data Model (ADM)</a>
108 </li>
109
110 <li>
111
112 <a href="../aql/manual.html" title="Asterix Query Language (AQL)">
113 <i class="none"></i>
114 Asterix Query Language (AQL)</a>
115 </li>
116
117 <li>
118
119 <a href="../aql/functions.html" title="AQL Functions">
120 <i class="none"></i>
121 AQL Functions</a>
122 </li>
123
124 <li class="active">
125
126 <a href="#"><i class="none"></i>AQL Allen's Relations Functions</a>
127 </li>
128
129 <li>
130
131 <a href="../aql/similarity.html" title="AQL Support of Similarity Queries">
132 <i class="none"></i>
133 AQL Support of Similarity Queries</a>
134 </li>
135
136 <li>
137
138 <a href="../aql/externaldata.html" title="Accessing External Data">
139 <i class="none"></i>
140 Accessing External Data</a>
141 </li>
142
143 <li>
144
145 <a href="../feeds/tutorial.html" title="Support for Data Ingestion in AsterixDB">
146 <i class="none"></i>
147 Support for Data Ingestion in AsterixDB</a>
148 </li>
149
150 <li>
151
152 <a href="../udf.html" title="Support for User Defined Functions in AsterixDB">
153 <i class="none"></i>
154 Support for User Defined Functions in AsterixDB</a>
155 </li>
156
157 <li>
158
159 <a href="../aql/filters.html" title="Filter-Based LSM Index Acceleration">
160 <i class="none"></i>
161 Filter-Based LSM Index Acceleration</a>
162 </li>
163
164 <li>
165
166 <a href="../api.html" title="HTTP API to AsterixDB">
167 <i class="none"></i>
168 HTTP API to AsterixDB</a>
169 </li>
170 </ul>
171
172
173
174 <hr class="divider" />
175
176 <div id="poweredBy">
177 <div class="clear"></div>
178 <div class="clear"></div>
179 <div class="clear"></div>
180 <a href="https://code.google.com/p/hyracks/" title="Hyracks" class="builtBy">
181 <img class="builtBy" alt="Hyracks" src="../images/hyrax_ts.png" />
182 </a>
183 </div>
184 </div>
185 </div>
186
187
188 <div id="bodyColumn" class="span9" >
189
190 <!-- ! Licensed to the Apache Software Foundation (ASF) under one
191 ! or more contributor license agreements. See the NOTICE file
192 ! distributed with this work for additional information
193 ! regarding copyright ownership. The ASF licenses this file
194 ! to you under the Apache License, Version 2.0 (the
195 ! "License"); you may not use this file except in compliance
196 ! with the License. You may obtain a copy of the License at
197 !
198 ! http://www.apache.org/licenses/LICENSE-2.0
199 !
200 ! Unless required by applicable law or agreed to in writing,
201 ! software distributed under the License is distributed on an
202 ! "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
203 ! KIND, either express or implied. See the License for the
204 ! specific language governing permissions and limitations
205 ! under the License.
206 ! --><h1>AsterixDB Temporal Functions: Allen&#x2019;s Relations</h1>
207<div class="section">
208<h2><a name="Table_of_Contents"></a><a name="toc" id="toc">Table of Contents</a></h2>
209
210<ul>
211
212<li><a href="#AboutAllensRelations">About Allen&#x2019;s Relations</a></li>
213
214<li><a href="#AllensRelatonsFunctions">Allen&#x2019;s Relations Functions</a></li>
215</ul></div>
216<div class="section">
217<h2><a name="About_Allens_Relations_Back_to_TOC"></a><a name="AboutAllensRelations" id="AboutAllensRelations">About Allen&#x2019;s Relations</a> <font size="4"><a href="#toc">[Back to TOC]</a></font></h2>
218<p>AsterixDB supports Allen&#x2019;s relations over interval types. Allen&#x2019;s relations are also called Allen&#x2019;s interval algebra. There are totally 13 base relations described by this algebra, and all of them are supported in AsterixDB (note that <tt>interval-equals</tt> is supported by the <tt>=</tt> comparison symbol so there is no extra function for it). </p>
219<p>A detailed description of Allen&#x2019;s relations can be found from its <a class="externalLink" href="http://en.wikipedia.org/wiki/Allen&apos;s_interval_algebra">wikipedia entry</a>. </p></div>
220<div class="section">
221<h2><a name="Allens_Relations_Functions_Back_to_TOC"></a><a name="AllensRelatonsFunctions" id="AllensRelatonsFunctions">Allen&#x2019;s Relations Functions</a> <font size="4"><a href="#toc">[Back to TOC]</a></font></h2>
222<div class="section">
223<h3><a name="interval-before_interval-after"></a>interval-before, interval-after</h3>
224
225<ul>
226
227<li>
228<p>Syntax:</p>
229
230<div class="source">
231<div class="source">
232<pre>interval-before(interval1, interval2)
233interval-after(interval1, interval2)
234</pre></div></div></li>
235
236<li>
237<p>These two functions check whether an interval happens before/after another interval. </p></li>
238
239<li>Arguments:
240
241<ul>
242
243<li><tt>interval1</tt>, <tt>interval2</tt>: two intervals to be compared</li>
244 </ul></li>
245
246<li>
247<p>Return Value:</p>
248<p>A <tt>boolean</tt> value. Specifically, <tt>interval-before(interval1, interval2)</tt> is true if and only if <tt>interval1.end &lt; interval2.start</tt>, and <tt>interval-after(interval1, interval2)</tt> is true if and only if <tt>interval1.start &gt; interval2.end</tt>. If any of the two inputs is <tt>null</tt>, <tt>null</tt> is returned.</p></li>
249
250<li>
251<p>Examples:</p>
252
253<div class="source">
254<div class="source">
255<pre>let $itv1 := interval-from-date(&quot;2000-01-01&quot;, &quot;2005-01-01&quot;)
256let $itv2 := interval-from-date(&quot;2005-05-01&quot;, &quot;2012-09-09&quot;)
257return {&quot;interval-before&quot;: interval-before($itv1, $itv2), &quot;interval-after&quot;: interval-after($itv2, $itv1)}
258</pre></div></div></li>
259
260<li>
261<p>The expected result is:</p>
262
263<div class="source">
264<div class="source">
265<pre>{ &quot;interval-before&quot;: true, &quot;interval-after&quot;: true }
266</pre></div></div></li>
267</ul></div>
268<div class="section">
269<h3><a name="interval-covers_interval-covered-by"></a>interval-covers, interval-covered-by</h3>
270
271<ul>
272
273<li>
274<p>Syntax:</p>
275
276<div class="source">
277<div class="source">
278<pre>interval-covers(interval1, interval2)
279interval-covered-by(interval1, interval2)
280</pre></div></div></li>
281
282<li>
283<p>These two functions check whether one interval covers the other interval.</p></li>
284
285<li>Arguments:
286
287<ul>
288
289<li><tt>interval1</tt>, <tt>interval2</tt>: two intervals to be compared</li>
290 </ul></li>
291
292<li>
293<p>Return Value:</p>
294<p>A <tt>boolean</tt> value. Specifically, <tt>interval-covers(interval1, interval2)</tt> is true if and only if</p>
295
296<div class="source">
297<div class="source">
298<pre>interval1.start &lt;= interval2.start
299AND interval1.end &gt;= interval2.end
300</pre></div></div>
301<p><tt>interval-covered-by(interval1, interval2)</tt> is true if and only if</p>
302
303<div class="source">
304<div class="source">
305<pre>interval2.start &lt;= interval1.start
306AND interval2.end &gt;= interval1.end
307</pre></div></div>
308<p>For both functions, if any of the two inputs is <tt>null</tt>, <tt>null</tt> is returned.</p></li>
309
310<li>
311<p>Examples:</p>
312
313<div class="source">
314<div class="source">
315<pre>let $itv1 := interval-from-date(&quot;2000-01-01&quot;, &quot;2005-01-01&quot;)
316let $itv2 := interval-from-date(&quot;2000-03-01&quot;, &quot;2004-09-09&quot;)
317let $itv3 := interval-from-date(&quot;2006-08-01&quot;, &quot;2007-03-01&quot;)
318let $itv4 := interval-from-date(&quot;2004-09-10&quot;, &quot;2012-08-01&quot;)
319return {&quot;interval-covers&quot;: interval-covers($itv1, $itv2), &quot;interval-covered-by&quot;: interval-covered-by($itv3, $itv4)}
320</pre></div></div></li>
321
322<li>
323<p>The expected result is:</p>
324
325<div class="source">
326<div class="source">
327<pre>{ &quot;interval-covers&quot;: true, &quot;interval-covered-by&quot;: true }
328</pre></div></div></li>
329</ul></div>
330<div class="section">
331<h3><a name="interval-overlaps_interval-overlapped-by"></a>interval-overlaps, interval-overlapped-by</h3>
332
333<ul>
334
335<li>
336<p>Syntax:</p>
337
338<div class="source">
339<div class="source">
340<pre>interval-overlaps(interval1, interval2)
341interval-overlapped-by(interval1, interval2)
342</pre></div></div></li>
343
344<li>
345<p>These functions check whether two intervals overlap with each other.</p></li>
346
347<li>Arguments:
348
349<ul>
350
351<li><tt>interval1</tt>, <tt>interval2</tt>: two intervals to be compared</li>
352 </ul></li>
353
354<li>
355<p>Return Value:</p>
356<p>A <tt>boolean</tt> value. Specifically, <tt>interval-overlaps(interval1, interval2)</tt> is true if and only if</p>
357
358<div class="source">
359<div class="source">
360<pre>interval1.start &lt; interval2.start
361AND interval2.end &gt; interval1.end
362AND interval1.end &gt; interval2.start
363</pre></div></div>
364<p><tt>interval-overlapped-by(interval1, interval2)</tt> is true if and only if</p>
365
366<div class="source">
367<div class="source">
368<pre>interval2.start &lt; interval1.start
369AND interval1.end &gt; interval2.end
370AND interval2.end &gt; interval1.start
371</pre></div></div>
372<p>For all these functions, if any of the two inputs is <tt>null</tt>, <tt>null</tt> is returned.</p>
373<p>Note that <tt>interval-overlaps</tt> and <tt>interval-overlapped-by</tt> are following the Allen&#x2019;s relations on the definition of overlap.</p></li>
374
375<li>
376<p>Examples:</p>
377
378<div class="source">
379<div class="source">
380<pre>let $itv1 := interval-from-date(&quot;2000-01-01&quot;, &quot;2005-01-01&quot;)
381let $itv2 := interval-from-date(&quot;2004-05-01&quot;, &quot;2012-09-09&quot;)
382let $itv3 := interval-from-date(&quot;2006-08-01&quot;, &quot;2007-03-01&quot;)
383let $itv4 := interval-from-date(&quot;2004-09-10&quot;, &quot;2006-12-31&quot;)
384return {&quot;overlaps&quot;: interval-overlaps($itv1, $itv2),
385 &quot;overlapped-by&quot;: interval-overlapped-by($itv3, $itv4)}
386</pre></div></div></li>
387
388<li>
389<p>The expected result is:</p>
390
391<div class="source">
392<div class="source">
393<pre>{ &quot;overlaps&quot;: true, &quot;overlapped-by&quot;: true }
394</pre></div></div></li>
395</ul></div>
396<div class="section">
397<h3><a name="interval-overlapping"></a>interval-overlapping</h3>
398<p>Note that <tt>interval-overlapping</tt> is not an Allen&#x2019;s Relation, but syntactic sugar we added for the case that the intersect of two intervals is not empty. Basically this function returns true if any of these functions return true: <tt>interval-overlaps</tt>, <tt>interval-overlapped-by</tt>, <tt>interval-covers</tt>, or <tt>interval-covered-by</tt>.</p>
399
400<ul>
401
402<li>
403<p>Syntax:</p>
404
405<div class="source">
406<div class="source">
407<pre>interval-overlapping(interval1, interval2)
408</pre></div></div></li>
409
410<li>
411<p>This functions check whether two intervals share any points with each other. </p></li>
412
413<li>Arguments:
414
415<ul>
416
417<li><tt>interval1</tt>, <tt>interval2</tt>: two intervals to be compared</li>
418 </ul></li>
419
420<li>
421<p>Return Value:</p>
422<p>A <tt>boolean</tt> value. Specifically, <tt>interval-overlapping(interval1, interval2)</tt> is true if</p>
423
424<div class="source">
425<div class="source">
426<pre>(interval2.start &gt;= interval1.start
427AND interval2.start &lt; interval1.end)
428OR
429(interval2.end &gt; interval1.start
430AND interval2.end &lt;= interval1.end)
431</pre></div></div>
432<p>If any of the two inputs is <tt>null</tt>, <tt>null</tt> is returned.</p></li>
433
434<li>
435<p>Examples:</p>
436
437<div class="source">
438<div class="source">
439<pre>let $itv1 := interval-from-date(&quot;2000-01-01&quot;, &quot;2005-01-01&quot;)
440let $itv2 := interval-from-date(&quot;2004-05-01&quot;, &quot;2012-09-09&quot;)
441let $itv3 := interval-from-date(&quot;2006-08-01&quot;, &quot;2007-03-01&quot;)
442let $itv4 := interval-from-date(&quot;2004-09-10&quot;, &quot;2006-12-31&quot;)
443return {&quot;overlapping1&quot;: interval-overlapping($itv1, $itv2),
444 &quot;overlapping2&quot;: interval-overlapping($itv3, $itv4)}
445</pre></div></div></li>
446
447<li>
448<p>The expected result is:</p>
449
450<div class="source">
451<div class="source">
452<pre>{ &quot;overlapping1&quot;: true, &quot;overlapping2&quot;: true }
453</pre></div></div></li>
454</ul></div>
455<div class="section">
456<h3><a name="interval-meets_interval-met-by"></a>interval-meets, interval-met-by</h3>
457
458<ul>
459
460<li>
461<p>Syntax:</p>
462
463<div class="source">
464<div class="source">
465<pre>interval-meets(interval1, interval2)
466interval-met-by(interval1, interval2)
467</pre></div></div></li>
468
469<li>
470<p>These two functions check whether an interval meets with another interval. </p></li>
471
472<li>Arguments:
473
474<ul>
475
476<li><tt>interval1</tt>, <tt>interval2</tt>: two intervals to be compared</li>
477 </ul></li>
478
479<li>
480<p>Return Value:</p>
481<p>A <tt>boolean</tt> value. Specifically, <tt>interval-meets(interval1, interval2)</tt> is true if and only if <tt>interval1.end = interval2.start</tt>, and <tt>interval-met-by(interval1, interval2)</tt> is true if and only if <tt>interval1.start = interval2.end</tt>. If any of the two inputs is <tt>null</tt>, <tt>null</tt> is returned.</p></li>
482
483<li>
484<p>Examples:</p>
485
486<div class="source">
487<div class="source">
488<pre>let $itv1 := interval-from-date(&quot;2000-01-01&quot;, &quot;2005-01-01&quot;)
489let $itv2 := interval-from-date(&quot;2005-01-01&quot;, &quot;2012-09-09&quot;)
490let $itv3 := interval-from-date(&quot;2006-08-01&quot;, &quot;2007-03-01&quot;)
491let $itv4 := interval-from-date(&quot;2004-09-10&quot;, &quot;2006-08-01&quot;)
492return {&quot;meets&quot;: interval-meets($itv1, $itv2), &quot;metby&quot;: interval-met-by($itv3, $itv4)}
493</pre></div></div></li>
494
495<li>
496<p>The expected result is:</p>
497
498<div class="source">
499<div class="source">
500<pre>{ &quot;meets&quot;: true, &quot;metby&quot;: true }
501</pre></div></div></li>
502</ul></div>
503<div class="section">
504<h3><a name="interval-starts_interval-started-by"></a>interval-starts, interval-started-by</h3>
505
506<ul>
507
508<li>
509<p>Syntax:</p>
510
511<div class="source">
512<div class="source">
513<pre>interval-starts(interval1, interval2)
514interval-started-by(interval1, interval2)
515</pre></div></div></li>
516
517<li>
518<p>These two functions check whether one interval starts with the other interval.</p></li>
519
520<li>Arguments:
521
522<ul>
523
524<li><tt>interval1</tt>, <tt>interval2</tt>: two intervals to be compared</li>
525 </ul></li>
526
527<li>
528<p>Return Value:</p>
529<p>A <tt>boolean</tt> value. Specifically, <tt>interval-starts(interval1, interval2)</tt> returns true if and only if</p>
530
531<div class="source">
532<div class="source">
533<pre>interval1.start = interval2.start
534AND interval1.end &lt;= interval2.end
535</pre></div></div>
536<p><tt>interval-started-by(interval1, interval2)</tt> returns true if and only if</p>
537
538<div class="source">
539<div class="source">
540<pre>interval1.start = interval2.start
541AND interval2.end &lt;= interval1.end
542</pre></div></div>
543<p>For both functions, if any of the two inputs is <tt>null</tt>, <tt>null</tt> is returned.</p></li>
544
545<li>
546<p>Examples:</p>
547
548<div class="source">
549<div class="source">
550<pre>let $itv1 := interval-from-date(&quot;2000-01-01&quot;, &quot;2005-01-01&quot;)
551let $itv2 := interval-from-date(&quot;2000-01-01&quot;, &quot;2012-09-09&quot;)
552let $itv3 := interval-from-date(&quot;2006-08-01&quot;, &quot;2007-03-01&quot;)
553let $itv4 := interval-from-date(&quot;2006-08-01&quot;, &quot;2006-08-01&quot;)
554return {&quot;interval-starts&quot;: interval-starts($itv1, $itv2), &quot;interval-started-by&quot;: interval-started-by($itv3, $itv4)}
555</pre></div></div></li>
556
557<li>
558<p>The expected result is:</p>
559
560<div class="source">
561<div class="source">
562<pre>{ &quot;interval-starts&quot;: true, &quot;interval-started-by&quot;: true }
563</pre></div></div></li>
564</ul></div>
565<div class="section">
566<h3><a name="interval-ends_interval-ended-by"></a>interval-ends, interval-ended-by</h3>
567
568<ul>
569
570<li>
571<p>Syntax:</p>
572
573<div class="source">
574<div class="source">
575<pre>interval-ends(interval1, interval2)
576interval-ended-by(interval1, interval2)
577</pre></div></div></li>
578
579<li>
580<p>These two functions check whether one interval ends with the other interval.</p></li>
581
582<li>Arguments:
583
584<ul>
585
586<li><tt>interval1</tt>, <tt>interval2</tt>: two intervals to be compared</li>
587 </ul></li>
588
589<li>
590<p>Return Value:</p>
591<p>A <tt>boolean</tt> value. Specifically, <tt>interval-ends(interval1, interval2)</tt> returns true if and only if</p>
592
593<div class="source">
594<div class="source">
595<pre>interval1.end = interval2.end
596AND interval1.start &gt;= interval2.start
597</pre></div></div>
598<p><tt>interval-ended-by(interval1, interval2)</tt> returns true if and only if</p>
599
600<div class="source">
601<div class="source">
602<pre>interval2.end = interval1.end
603AND interval2.start &gt;= interval1.start
604</pre></div></div>
605<p>For both functions, if any of the two inputs is <tt>null</tt>, <tt>null</tt> is returned.</p></li>
606
607<li>
608<p>Examples:</p>
609
610<div class="source">
611<div class="source">
612<pre>let $itv1 := interval-from-date(&quot;2000-01-01&quot;, &quot;2005-01-01&quot;)
613let $itv2 := interval-from-date(&quot;1998-01-01&quot;, &quot;2005-01-01&quot;)
614let $itv3 := interval-from-date(&quot;2006-08-01&quot;, &quot;2007-03-01&quot;)
615let $itv4 := interval-from-date(&quot;2006-09-10&quot;, &quot;2007-03-01&quot;)
616return {&quot;interval-ends&quot;: interval-ends($itv1, $itv2), &quot;interval-ended-by&quot;: interval-ended-by($itv3, $itv4) }
617</pre></div></div></li>
618
619<li>
620<p>The expected result is:</p>
621
622<div class="source">
623<div class="source">
624<pre>{ &quot;interval-ends&quot;: true, &quot;interval-ended-by&quot;: true }
625</pre></div></div></li>
626</ul></div></div>
627 </div>
628 </div>
629 </div>
630
631 <hr/>
632
633 <footer>
634 <div class="container-fluid">
635 <div class="row span12">Copyright &copy; 2016
636 <a href="http://www.apache.org/">The Apache Software Foundation</a>.
637 All Rights Reserved.
638
639 </div>
640
641 <?xml version="1.0" encoding="UTF-8"?>
642<div class="row-fluid">Apache AsterixDB, AsterixDB, Apache, the Apache
643 feather logo, and the Apache AsterixDB project logo are either
644 registered trademarks or trademarks of The Apache Software
645 Foundation in the United States and other countries.
646 All other marks mentioned may be trademarks or registered
647 trademarks of their respective owners.</div>
648
649
650 </div>
651 </footer>
652 </body>
653</html>