{% extends "classic_base.html" %}

{% block topbar_buttons %}
<div class="dropdown" id="threadsDropdown" hidden>
  <button class="btn btn-outline-light dropdown-toggle mr-3" type="button" id="threadsDropdownButton" data-toggle="dropdown"
          aria-haspopup="true" aria-expanded="false" data-toggle-second="tooltip" data-placement="right"
          title="Display only the selected thread">
    Filter Thread
  </button>
  <div class="dropdown-menu" aria-labelledby="threadsDropdownButton" id="threadsDropdownList">
    <a class="dropdown-item" data-thread="-0x1" id="resetThreadFilterItem">Reset</a>
  </div>
</div>
<div class="form-check mr-3">
  <input class="form-check-input" type="checkbox" data-toggle="tooltip" id="hideUninteresting"
          title="Hide CPython eval frames and Memray-related frames" checked>
    <label class="form-check-label text-white bg-dark">Hide Irrelevant Frames</label>
</div>
<div class="form-check mr-3">
  <input class="form-check-input" type="checkbox" data-toggle="tooltip" id="hideImportSystem"
          title="Hide frames related to the Python import system" >
    <label class="form-check-label text-white bg-dark">Hide Import System Frames</label>
</div>
<div class="btn-group btn-group-toggle mr-3" data-toggle="buttons">
  <label class="btn btn-outline-light shadow-none" data-container="body" data-toggle="tooltip" title="Enable flame graph mode: functions above their callers with the root at the bottom">
    <input type="radio" name="flames/icicles" id="flames" autocomplete="off">
    <div class="flamegraph-icon flipped">
      <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" stroke-width="1" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
        <path d="M 1 1 h 22 Z M 11 6 h 10 Z M 1 6 h 7 Z M 11 11 h 7 Z M 1 11 h 4 Z M 11 16 h 4 Z M 1 16 h 2 Z M 11 21 h 2 Z"/>
      </svg>
    </div>
    &nbsp;
    Flames
  </label>
  <label class="btn btn-outline-light active shadow-none" data-container="body" data-toggle="tooltip" title="Enable icicle graph mode: functions below their callers with the root at the top">
    <input type="radio" name="flames/icicles" id="icicles" autocomplete="off" checked/>
    Icicles
    &nbsp;
    <div class="flamegraph-icon">
      <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" stroke-width="1" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
        <path d="M 1 1 h 22 Z M 11 6 h 10 Z M 1 6 h 7 Z M 11 11 h 7 Z M 1 11 h 4 Z M 11 16 h 4 Z M 1 16 h 2 Z M 11 21 h 2 Z"/>
      </svg>
    </div>
  </label>
</div>
<button id="resetZoomButton" class="btn btn-outline-light mr-3">Reset Zoom</button>
{% endblock %}

{% block content %}
<div class="chart-container">
  <div id="chart"></div>
</div>
{% endblock %}

{% block help %}
{% if show_memory_leaks %}
<p>
  The flame graph displays stack frames at allocation, for memory that was leaked during the tracking period (i.e. allocated and not deallocated).
</p>
<div class="alert alert-warning" role="alert">
  Note that the Python allocator doesn't necessarily release memory to the system when Python objects are deallocated and these can still appear as "leaks". If you want to exclude these, you can run your application with the `PYTHONMALLOC=malloc` environment variable set.
</div>
{% else %}
<p>
  The flame graph displays a snapshot of memory used across stack frames at the time <b>when the memory usage was at its peak</b>.
</p>
{% endif %}
{% block slider_help %}
{% endblock %}
<p>
  The vertical ordering of the stack frames corresponds to the order of function calls, from parent to children.
  The horizontal ordering does not represent the passage of time in the application: they simply represent child frames in arbitrary order.
</p>
<p>
  On the flame graph, each bar represents a stack frame and shows the code which triggered the memory allocation.
  Hovering over the frame you can also see the overall memory allocated in the given frame and its children and the number of times allocations have occurred.
</p>
<p>
  The <b>Show/Hide Irrelevant Frames</b> button can be used to reveal and hide frames which contain allocations in code which might not be
  relevant for the application. These include frames in the CPython eval loop as well as frames introduced by memray during the analysis.
</p>
<p>
  You can find more information in the <a target="_blank"  href="https://bloomberg.github.io/memray/flamegraph.html">documentation</a>.
</p>
{% endblock %}

{% block styles %}
{{ super() }}
<style>{% include "assets/flamegraph.css" %}</style>
{% endblock %}

{% block scripts %}
{{ super() }}
<script src="https://d3js.org/d3.v4.min.js" charset="utf-8"></script>
<script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/d3-tip@0.9.1/dist/index.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/d3-flame-graph@4.0.6/dist/d3-flamegraph.min.js"></script>

{% block flamegraph_script %}
<script type="text/javascript">
  {{ include_file("assets/flamegraph.js") }}
</script>
{% endblock %}

{% endblock %}
