<!--
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.
-->
{{! Common header template with navbar which starts a container div for content (closed by
common-footer.tmpl) }}
<!DOCTYPE html>
<html>
  <head><title>Apache Impala</title>
    <script src='{{ __common__.host-url }}/www/jquery/jquery-3.4.1.min.js'></script>
    <script src='{{ __common__.host-url }}/www/bootstrap/js/bootstrap-4.3.1.min.js'></script>
    <script src='{{ __common__.host-url }}/www/scripts/util.js'></script>
    <link rel="stylesheet" type="text/css" href="{{ __common__.host-url }}/www/datatables-1.10.18.min.css"/>
    <script type="text/javascript" src="{{ __common__.host-url }}/www/datatables-1.10.18.min.js"></script>
    <link href='{{ __common__.host-url }}/www/bootstrap/css/bootstrap-4.3.1.min.css' rel='stylesheet' media='screen'>
    <style>
      @media (min-width: 1300px) {
        #nav-options {
            width: 1280px;
        }
      }

      body {
        font-size: 14px;
      }

      pre {
        padding: 10px;
        font-size: 12px;
        border: 1px solid #ccc;
      }

      /* Avoid unsightly padding around code element */
      pre.code {
        padding: 0;
      }
    </style>
  </head>
  <body>
    <header class="navbar navbar-default navbar-expand bg-light navbar-static-top" id="top" role="banner">
      <div id="nav-options" class="container">
        <div class="navbar-header">
          <a class='navbar-brand' href='{{ __common__.host-url }}/' id='root-link'>{{ __common__.process-name }}</a>
        </div>
        <nav class="collapse navbar-collapse bs-navbar-collapse" role="navigation">
          <ul class="nav navbar-nav">
            {{#__common__.navbar}}
            <li class="navbar-item"><a class="nav-link" href="{{ __common__.host-url }}{{link}}">{{title}}</a></li>
            {{/__common__.navbar}}
          </ul>
        </nav>
      </div>
    </header>
<div class='container-fluid' style='width:80%'>
{{#error}}
<div class="alert alert-danger">
  <strong>Error:</strong>
  {{.}}
</div>
{{/error}}
<script>
// For Apache Knox compatibility, all urls that are accessed by javascript should have
// their path wrapped with this.
function make_url(path) {
  var root_link = document.getElementById('root-link');
  var s  = root_link.href.split("?");
  url = s[0] + path;
  if (s.length > 1) {
    if (path.includes("?")) {
      url += "&"
    } else {
      url += "?";
    }
    url += s[1];
  }
  return url;
}
</script>