
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License.
-->

{% if page.toc %}
  {% assign p = page.toc %}
{% else %}
  {% assign p = 'toc.json' %}
{% endif %}
{% capture toc_string %}{% readj p %}{% endcapture %}
{% jsonball toc from var toc_string %}

{% capture pagesiteurl %}{{ site.url }}{{ page.url }}{% endcapture %}

{% for x in toc %}
    {% if pagesiteurl == x.file %}
        {% capture l1name %}{{ x.title }}{% endcapture %}
        {% capture l1link %}{{ x.file }}{% endcapture %}
    {% endif %}
    {% if x.children %}{% for x2 in x.children %}
        {% if pagesiteurl == x2.file %}
            {% capture l1name %}{{ x.title }}{% endcapture %}
            {% capture l1link %}{{ x.file }}{% endcapture %}
            {% capture l2name %}{{ x2.title }}{% endcapture %}
            {% capture l2link %}{{ x2.file }}{% endcapture %}
        {% endif %}
        {% if x2.children %}{% for x3 in x2.children %}
            {% if pagesiteurl == x3.file %}
                {% capture l1name %}{{ x.title }}{% endcapture %}
                {% capture l1link %}{{ x.file }}{% endcapture %}
                {% capture l2name %}{{ x2.title }}{% endcapture %}
                {% capture l2link %}{{ x2.file }}{% endcapture %}
                {% capture l3name %}{{ x3.title }}{% endcapture %}
                {% capture l3link %}{{ x3.file }}{% endcapture %}
            {% endif %}
        {% endfor %}{% endif %}
    {% endfor %}{% endif %}
{% endfor %}

{% if l1name %}{% else %}
    {% capture l1name %}Home{% endcapture %}
    {% capture l1link %}{{ site.url }}{% endcapture %}
    {% capture l2name %}{{ page.title }}{% endcapture %}
    {% capture l2link %}{{ pagesiteurl }}{% endcapture %}
{% endif %}
            
<p id="breadcrumb">
    <a href="{{l1link}}">{{ l1name }}</a>
    {% if l2name %}
        &raquo; <a href="{{l2link}}">{{l2name}}</a>
        {% if l3name %}
            &raquo; <a href="{{l3link}}">{{l3name}}</a>
        {% endif %}
    {% endif %}
</p>
