   [min_top, max_top] = recurse $el, Infinity, 0
 
   [max_top - min_top, min_top]
-
-
-
-

  #
  # Different constraints may need to be introduced to accommodate different
  # sticky component configurations.   
  calculateYPositions : (stuck) -> 
    debug = true

    solver = new c.SimplexSolver()    

    y_pos = {}

    viewport_height = Math.max(document.documentElement.clientHeight, window.innerHeight || 0)

    scrolling_down = scroller.viewport_top > scroller.last_viewport_top

    y_stack = 0

    for [k,v], i in stuck
      console.log "**#{k} constraints**" if debug
      y_pos[k] = new c.Variable

      sticky = fetch k

      # If we've already been moving, we should be bounded by the amount scrolled. 
      # |y(t) - y(t-1)| <= |v(t) - v(t-1)|
      if sticky.y?
        scroll_distance = Math.abs(scroller.viewport_top - scroller.last_viewport_top)

        console.log "\tBounded: |#{k} - #{sticky.y}| <= |#{scroller.viewport_top} - #{scroller.last_viewport_top}|, strong" if debug
        solver.addConstraint new c.Inequality \
          y_pos[k], \
          c.LEQ,

        c.GEQ, \
        scroller.viewport_top - v.jut + y_stack, \
        if scrolling_down then c.Strength.weak else c.Strength.medium
      y_stack += v.height

      # BOTTOM OF COMPONENT ABOVE VIEWPORT BOTTOM
      # Try to keep the bottom above the viewport, especially when scrolling down
      console.log "\tBottom Above viewport bottom: #{k} + #{v.$el.height() + v.jut} <= #{scroller.viewport_top} + #{viewport_height}, #{if scrolling_down then 'weak' else 'medium'}" if debug
      solver.addConstraint new c.Inequality \
