content: """
  GUI progressbar decorator for iterators.
  Includes a default (x)range iterator printing to stderr.
  
  Usage:
    >>> from tqdm_gui import tgrange[, tqdm_gui]
    >>> for i in tgrange(10): #same as: for i in tqdm_gui(xrange(10))
    ...     ...
  """
  # future division is important to divide integers and get as
  # a result precise floating numbers (instead of truncated int)
  from __future__ import division, absolute_import
  # import compatibility functions and utilities
  # import sys
  from time import time
  from ._utils import _range
  # to inherit from the tqdm class
  from ._tqdm import tqdm, TqdmExperimentalWarning
  from warnings import warn
  
  
  __author__ = {"github.com/": ["casperdcl", "lrq3000"]}
  __all__ = ['tqdm_gui', 'tgrange']
  
  
  class tqdm_gui(tqdm):  # pragma: no cover
      """
      Experimental GUI version of tqdm!
      """
  
      # TODO: @classmethod: write() on GUI?
  
      def __init__(self, *args, **kwargs):
          import matplotlib as mpl
          import matplotlib.pyplot as plt
          from collections import deque
          kwargs['gui'] = True
  
          super(tqdm_gui, self).__init__(*args, **kwargs)
  
          # Initialize the GUI display
          if self.disable or not kwargs['gui']:
              return
  
          warn('GUI is experimental/alpha', TqdmExperimentalWarning)
          self.mpl = mpl
          self.plt = plt
          self.sp = None
  
          # Remember if external environment uses toolbars
          self.toolbar = self.mpl.rcParams['toolbar']
          self.mpl.rcParams['toolbar'] = 'None'
  
          self.mininterval = max(self.mininterval, 0.5)
          self.fig, ax = plt.subplots(figsize=(9, 2.2))
          # self.fig.subplots_adjust(bottom=0.2)
          if self.total:
              self.xdata = []
              self.ydata = []
              self.zdata = []
          else:
              self.xdata = deque([])
              self.ydata = deque([])
              self.zdata = deque([])
          self.line1, = ax.plot(self.xdata, self.ydata, color='b')
          self.line2, = ax.plot(self.xdata, self.zdata, color='k')
          ax.set_ylim(0, 0.001)
          if self.total:
              ax.set_xlim(0, 100)
              ax.set_xlabel('percent')
              self.fig.legend((self.line1, self.line2), ('cur', 'est'),
                              loc='center right')
              # progressbar
              self.hspan = plt.axhspan(0, 0.001,
                                       xmin=0, xmax=0, color='g')
          else:
              # ax.set_xlim(-60, 0)
              ax.set_xlim(0, 60)
              ax.invert_xaxis()
              ax.set_xlabel('seconds')
              ax.legend(('cur', 'est'), loc='lower left')
          ax.grid()
          # ax.set_xlabel('seconds')
          ax.set_ylabel((self.unit if self.unit else 'it') + '/s')
          if self.unit_scale:
              plt.ticklabel_format(style='sci', axis='y',
                                   scilimits=(0, 0))
              ax.yaxis.get_offset_text().set_x(-0.15)
  
          # Remember if external environment is interactive
          self.wasion = plt.isinteractive()
          plt.ion()
          self.ax = ax
  
      def __iter__(self):
          # TODO: somehow allow the following:
          # if not self.gui:
          #   return super(tqdm_gui, self).__iter__()
          iterable = self.iterable
          if self.disable:
              for obj in iterable:
                  yield obj
              return
  
          # ncols = self.ncols
          mininterval = self.mininterval
          maxinterval = self.maxinterval
          miniters = self.miniters
          dynamic_miniters = self.dynamic_miniters
          unit = self.unit
          unit_scale = self.unit_scale
          ascii = self.ascii
          start_t = self.start_t
          last_print_t = self.last_print_t
          last_print_n = self.last_print_n
          n = self.n
          # dynamic_ncols = self.dynamic_ncols
          smoothing = self.smoothing
          avg_time = self.avg_time
          bar_format = self.bar_format
  
          plt = self.plt
          ax = self.ax
          xdata = self.xdata
          ydata = self.ydata
          zdata = self.zdata
          line1 = self.line1
          line2 = self.line2
  
          for obj in iterable:
              yield obj
              # Update and print the progressbar.
              # Note: does not call self.update(1) for speed optimisation.
              n += 1
              delta_it = n - last_print_n
              # check the counter first (avoid calls to time())
              if delta_it >= miniters:
                  cur_t = time()
                  delta_t = cur_t - last_print_t
                  if delta_t >= mininterval:
                      elapsed = cur_t - start_t
                      # EMA (not just overall average)
                      if smoothing and delta_t:
                          avg_time = delta_t / delta_it \
                              if avg_time is None \
                              else smoothing * delta_t / delta_it + \
                              (1 - smoothing) * avg_time
  
                      # Inline due to multiple calls
                      total = self.total
                      # instantaneous rate
                      y = delta_it / delta_t
                      # overall rate
                      z = n / elapsed
                      # update line data
                      xdata.append(n * 100.0 / total if total else cur_t)
                      ydata.append(y)
                      zdata.append(z)
  
                      # Discard old values
                      # xmin, xmax = ax.get_xlim()
                      # if (not total) and elapsed > xmin * 1.1:
                      if (not total) and elapsed > 66:
                          xdata.popleft()
                          ydata.popleft()
                          zdata.popleft()
  
                      ymin, ymax = ax.get_ylim()
                      if y > ymax or z > ymax:
                          ymax = 1.1 * y
                          ax.set_ylim(ymin, ymax)
                          ax.figure.canvas.draw()
  
                      if total:
                          line1.set_data(xdata, ydata)
                          line2.set_data(xdata, zdata)
                          try:
                              poly_lims = self.hspan.get_xy()
                          except AttributeError:
                              self.hspan = plt.axhspan(0, 0.001, xmin=0,
                                                       xmax=0, color='g')
                              poly_lims = self.hspan.get_xy()
                          poly_lims[0, 1] = ymin
                          poly_lims[1, 1] = ymax
                          poly_lims[2] = [n / total, ymax]
                          poly_lims[3] = [poly_lims[2, 0], ymin]
                          if len(poly_lims) > 4:
                              poly_lims[4, 1] = ymin
                          self.hspan.set_xy(poly_lims)
                      else:
                          t_ago = [cur_t - i for i in xdata]
                          line1.set_data(t_ago, ydata)
                          line2.set_data(t_ago, zdata)
  
                      ax.set_title(self.format_meter(
                          n, total, elapsed, 0,
                          self.desc, ascii, unit, unit_scale,
                          1 / avg_time if avg_time else None, bar_format),
                          fontname="DejaVu Sans Mono", fontsize=11)
                      plt.pause(1e-9)
  
                      # If no `miniters` was specified, adjust automatically
                      # to the maximum iteration rate seen so far.
                      if dynamic_miniters:
                          if maxinterval and delta_t > maxinterval:
                              # Set miniters to correspond to maxinterval
                              miniters = delta_it * maxinterval / delta_t
                          elif mininterval and delta_t:
                              # EMA-weight miniters to converge
                              # towards the timeframe of mininterval
                              miniters = smoothing * delta_it * mininterval \
                                  / delta_t + (1 - smoothing) * miniters
                          else:
                              miniters = smoothing * delta_it + \
                                  (1 - smoothing) * miniters
  
                      # Store old values for next call
                      last_print_n = n
                      last_print_t = cur_t
  
          # Closing the progress bar.
          # Update some internal variables for close().
          self.last_print_n = last_print_n
          self.n = n
          self.close()
  
      def update(self, n=1):
          # if not self.gui:
          #   return super(tqdm_gui, self).close()
          if self.disable:
              return
  
          if n < 0:
              n = 1
          self.n += n
  
          delta_it = self.n - self.last_print_n  # should be n?
          if delta_it >= self.miniters:
              # We check the counter first, to reduce the overhead of time()
              cur_t = time()
              delta_t = cur_t - self.last_print_t
              if delta_t >= self.mininterval:
                  elapsed = cur_t - self.start_t
                  # EMA (not just overall average)
                  if self.smoothing and delta_t:
                      self.avg_time = delta_t / delta_it \
                          if self.avg_time is None \
                          else self.smoothing * delta_t / delta_it + \
                          (1 - self.smoothing) * self.avg_time
  
                  # Inline due to multiple calls
                  total = self.total
                  ax = self.ax
  
                  # instantaneous rate
                  y = delta_it / delta_t
                  # smoothed rate
                  z = self.n / elapsed
                  # update line data
                  self.xdata.append(self.n * 100.0 / total
                                    if total else cur_t)
                  self.ydata.append(y)
                  self.zdata.append(z)
  
                  # Discard old values
                  if (not total) and elapsed > 66:
                      self.xdata.popleft()
                      self.ydata.popleft()
                      self.zdata.popleft()
  
                  ymin, ymax = ax.get_ylim()
                  if y > ymax or z > ymax:
                      ymax = 1.1 * y
                      ax.set_ylim(ymin, ymax)
                      ax.figure.canvas.draw()
  
                  if total:
                      self.line1.set_data(self.xdata, self.ydata)
                      self.line2.set_data(self.xdata, self.zdata)
                      try:
                          poly_lims = self.hspan.get_xy()
                      except AttributeError:
                          self.hspan = self.plt.axhspan(0, 0.001, xmin=0,
                                                        xmax=0, color='g')
                          poly_lims = self.hspan.get_xy()
                      poly_lims[0, 1] = ymin
                      poly_lims[1, 1] = ymax
                      poly_lims[2] = [self.n / total, ymax]
                      poly_lims[3] = [poly_lims[2, 0], ymin]
                      if len(poly_lims) > 4:
                          poly_lims[4, 1] = ymin
                      self.hspan.set_xy(poly_lims)
                  else:
                      t_ago = [cur_t - i for i in self.xdata]
                      self.line1.set_data(t_ago, self.ydata)
                      self.line2.set_data(t_ago, self.zdata)
  
                  ax.set_title(self.format_meter(
                      self.n, total, elapsed, 0,
                      self.desc, self.ascii, self.unit, self.unit_scale,
                      1 / self.avg_time if self.avg_time else None,
                      self.bar_format),
                      fontname="DejaVu Sans Mono", fontsize=11)
                  self.plt.pause(1e-9)
  
                  # If no `miniters` was specified, adjust automatically to the
                  # maximum iteration rate seen so far.
                  # e.g.: After running `tqdm.update(5)`, subsequent
                  # calls to `tqdm.update()` will only cause an update after
                  # at least 5 more iterations.
                  if self.dynamic_miniters:
                      if self.maxinterval and delta_t > self.maxinterval:
                          self.miniters = self.miniters * self.maxinterval \
                              / delta_t
                      elif self.mininterval and delta_t:
                          self.miniters = self.smoothing * delta_it \
                              * self.mininterval / delta_t + \
                              (1 - self.smoothing) * self.miniters
                      else:
                          self.miniters = self.smoothing * delta_it + \
                              (1 - self.smoothing) * self.miniters
  
                  # Store old values for next call
                  self.last_print_n = self.n
                  self.last_print_t = cur_t
  
      def close(self):
          # if not self.gui:
          #   return super(tqdm_gui, self).close()
          if self.disable:
              return
  
          self.disable = True
  
          self._instances.remove(self)
  
          # Restore toolbars
          self.mpl.rcParams['toolbar'] = self.toolbar
          # Return to non-interactive mode
          if not self.wasion:
              self.plt.ioff()
          if not self.leave:
              self.plt.close(self.fig)
  
  
  def tgrange(*args, **kwargs):
      """
      A shortcut for tqdm_gui(xrange(*args), **kwargs).
      On Python3+ range is used instead of xrange.
      """
      return tqdm_gui(_range(*args), **kwargs)
  