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

<head>
<link rel="shortcut icon" href="{{ static_url('img/logo54x54.png') }}" type="image/x-icon" >
<link href="{{ static_url('css/bootstrap.css') }}" rel="stylesheet">
<style type="text/css">
div.tight
{
  height:85%;
  overflow:auto;
}
</style>
<title>Path browser for {{path}}</title>

</head>

<body>
  <div class="container">
  <div class="span6">
    <strong> Path </strong> {{path}}
  </div>

  <div class="span12 tight">
    <pre>
{% for fn in sorted(filestats.keys()) %} {% if not filestats[fn]["is_dir"] %}
  {{ filestats[fn]["formatted_stat"] }} <a href='{{baseUrl}}/topologies/{{cluster}}/{{environ}}/{{topology}}/{{container}}/file?path={{filestats[fn]["path"]}}'>{{ fn }}</a> <a href='/topologies/{{cluster}}/{{environ}}/{{topology}}/{{container}}/filedownload?path={{filestats[fn]["path"]}}'><font size=1>dl</font></a> {% else %}
  {{ filestats[fn]["formatted_stat"] }} <a href='{{baseUrl}}/topologies/filestats/{{cluster}}/{{environ}}/{{topology}}/{{container}}?path={{filestats[fn]["path"]}}'>{{ fn }}</a> {% end %} {% end %}
    </pre>
  </div>
  </div>
</body>

</html>
