
<!--
   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.
-->

<project xmlns="http://maven.apache.org/DECORATION/1.3.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/DECORATION/1.3.0 http://maven.apache.org/xsd/decoration-1.3.0.xsd"
         name="Apache Tez">
  <skin>
    <groupId>org.apache.maven.skins</groupId>
    <artifactId>maven-fluido-skin</artifactId>
    <version>1.3.0</version>
  </skin>
  <custom>
    <fluidoSkin>
      <topBarEnabled>true</topBarEnabled>
      <sideBarEnabled>true</sideBarEnabled>
      <leftColumnClass>span2</leftColumnClass>
      <bodyColumnClass>span10</bodyColumnClass>
      <twitter>
        <user>ApacheTez</user>
        <showUser>true</showUser>
      </twitter>
    </fluidoSkin>
  </custom>

  <bannerLeft>
    <name>Apache Tez</name>
    <src>./images/ApacheTezLogo_lowres.png</src>
    <width>25%</width>
    <height>25%</height>
    <href>http://tez.apache.org/</href>
  </bannerLeft>

  <bannerRight>
    <name>Apache Software Foundation</name>
    <src>http://www.apache.org/images/asf_logo.gif</src>
    <href>http://www.apache.org/</href>
  </bannerRight>

  <publishDate position="right"/>
  <version position="none"/>

  <body>
    <head>
       <!-- Start of Google analytics 
       <script type="text/javascript">
         var _gaq = _gaq || [];
         _gaq.push(['_setAccount', '']);
         _gaq.push(['_trackPageview']);

         (function() {
            var ga = document.createElement('script'); 
            ga.type = 'text/javascript'; ga.async = true;
            ga.src = ('https:' == document.location.protocol ? 
                      'https://ssl' : 'http://www') + 
                     '.google-analytics.com/ga.js';
            var s = document.getElementsByTagName('script')[0]; 
            s.parentNode.insertBefore(ga, s);
          })();
       </script>
       End of Google analytics -->
       <style>
           .well.sidebar-nav {
             background-color: #fff;
           }
           a.externalLink[href^=http] {
             background-image: none;
             padding-right: 0;
           }
           body.topBarEnabled {
             padding-top: 40px;
           }
           #leftColumn .nav-list .active a {
             background-color: #a0a0a0;
           }
           .nav-list .active a:hover {
             background-color: #a0a0a0;
           }
       </style>
    </head>

    <breadcrumbs>
      <item name="Apache TEZ&#174;" href="http://tez.apache.org/"/>
    </breadcrumbs>

    <menu name="Getting Started">
      <item name="Overview" href="index.html"/>
      <item name="Talks and Meetup Recordings" href="talks.html"/>
      <item name="Project License" href="http://www.apache.org/licenses/LICENSE-2.0.txt"/>
    </menu>

    <menu name="Documentation">
      <item name="Install Guide" href="install.html"/>
      <item name="Local Mode" href="localmode.html"/>
      <item name="Tez UI" href="tez-ui.html"/>
      <item name="Tez Shuffle Handler" href="shuffle-handler.html"/>
      <item name="User Guides" href="user_guides.html"/>
    </menu>

    <menu name="Community">
      <item name="Mailing Lists" href="mail-lists.html"/>
      <item name="Issue Tracking" href="issue-tracking.html"/>
      <item name="Project Team" href="team-list.html"/>
      <item name="Project By-Laws" href="by-laws.html"/>
      <item name="User Meetup Group" href="http://www.meetup.com/Apache-Tez-User-Group"/>
      <item name="Tez Wiki" href="https://cwiki.apache.org/confluence/display/TEZ"/>
    </menu>

    <menu name="Download Apache TEZ&#174; Releases">
      <item name="0.4.1-incubating" href="http://archive.apache.org/dist/incubator/tez/tez-0.4.1-incubating/"/>
      <item name="0.5.4" href="./releases/apache-tez-0-5-4.html"/>
      <item name="0.6.2" href="./releases/apache-tez-0-6-2.html"/>
      <item name="0.7.1" href="./releases/apache-tez-0-7-1.html"/>
      <item name="0.8.5" href="./releases/apache-tez-0-8-5.html"/>
      <item name="0.9.0" href="./releases/apache-tez-0-9-0.html"/>
      <item name="0.9.1" href="./releases/apache-tez-0-9-1.html"/>
      <item name="0.9.2" href="./releases/apache-tez-0-9-2.html"/>
      <item name="0.10.0" href="./releases/apache-tez-0-10.0.html"/>
      <item name="All Releases" href="./releases/index.html"/>
    </menu>

    <menu name="Contribute">
      <item name="JIRA" href="https://issues.apache.org/jira/browse/TEZ" />
      <item name="Git (Read/Write)" href="https://gitbox.apache.org/repos/asf/tez.git" alt="Use git clone https://gitbox.apache.org/repos/asf/tez.git" />
      <item name="Git (Read-only)" href="git://git.apache.org/tez.git" alt="Use git clone git://git.apache.org/tez.git" />
      <item name="How to Contribute" href="https://cwiki.apache.org/confluence/display/TEZ/How+to+Contribute+to+Tez" alt="Detailed guide on how to contribute to Tez" />
    </menu>

    <menu name="ASF">
      <item name="License" href="http://www.apache.org/licenses/" />
      <item name="Donate" href="http://www.apache.org/foundation/sponsorship.html" />
      <item name="Thanks" href="http://www.apache.org/foundation/thanks.html" />
      <item name="Security" href="http://www.apache.org/security/" />
    </menu>

    <footer>
      <div class="row span12">
        Apache Tez, Apache, the Apache feather logo, and the Apache Tez project logos are trademarks of The Apache Software Foundation.
        All other marks mentioned may be trademarks or registered trademarks of their respective owners.
      </div>
      <br/>
      <div class="row span12">
        <a href="privacy-policy.html">Privacy Policy</a>
      </div>
    </footer>

  </body>
</project>
