         when 'class'  then 'js-snap-tips'
         else 'hlf.tip.snap'
 
-    # SnapTip Options
-    # ---------------
-    #- NOTE: The plugin instance gets extended with the options.
     defaults: do (pre = 'js-snap-tip-') ->
-      # These options extend the tip options.
       $.extend (deep = yes), {}, hlf.tip.defaults,
-        # NOTE: For each snapping option, the plugin adds its class to the tip
-        # if the option is on.
-        # 
-        # - `snap.toXAxis` is the switch for snapping along x-axis and only
-        #   following along y-axis. Off by default.
-        # - `snap.toYAxis` is the switch for snapping along y-axis and only
-        #   following along x-axis. Off by default.
-        # - `snap.toTrigger` is the switch for snapping to trigger built on
-        #   axis-snapping. On by default.
         snap:
           toTrigger: on
           toXAxis: off

          classNames.tip = 'js-tip js-snap-tip'
          classNames

  # §

  # Tip Implementation
  # ------------------
  # Read on to learn about implementation details.
  class Tip

    # ƒ `constructor` keeps `$triggers` and `$context` as properties. `options`
    # is further normalized.
    constructor: (@$triggers, options, @$context) ->
      for own name, animation of options.animations when name isnt 'base'
        _.defaults animation, options.animations.base

    # ƒ `init` offloads non-trivial setup to other subroutines.
    init: ->
      _.bindAll @, '_onTriggerMouseMove', '_setBounds'
      # - Initialize tip element.
      @_setTip $ '<div>'
      # - Infer `doStem` and `doFollow` flags from respective `classNames` entries.
      @doStem = @classNames.stem isnt ''
      @doFollow = @classNames.follow isnt ''
      # - Initialize state, which is either: `awake`, `asleep`, `waking`,
      # `sleeping`; respectively show, hide.
      @_setState 'asleep'
      # - The tip should remain visible and `awake` as long as there is a high
      # enough frequency of relevant mouse activity. In addition to using
      # `hoverIntent`, this is achieved with a simple base implementation around
      # timers `_sleepCountdown` and `_wakeCountdown` and an extra reference to
      # `_$currentTrigger`.
      @_wakeCountdown = null
      @_sleepCountdown = null
      @_$currentTrigger = null
      # - Initialize tip. Note the initial render.
      @_render()
      @_bind()
      # - Initialize context.
      @_bindContext()
      # - Initialize triggers. Note the initial processing.
      @_processTriggers()
      @_bindTriggers()

    # ### Accessors

    # ƒ `_defaultHtml` provides a basic html structure for tip content. It can be
    # customized via the `tipTemplate` external option, or by subclasses using
    # the `htmlOnRender` hook.
    _defaultHtml: ->

# axis. For example, snapping to the x-axis will only allow the tip to shift
# along the y-axis. The x will remain constant.

# __UMD__
# - When AMD, register the attacher as an anonymous module.
# - When Node or Browserify, set module exports to the attach result.
# - When browser globals (root is window), Just run the attach function.
((root, attach) ->
  if typeof define is 'function' and define.amd?
    define [
      'jquery'
      'underscore'
      'hlf/jquery.extension.hlf.core'
      'hlf/jquery.extension.hlf.event'
    ], attach
  else if typeof module is 'object' && module.exports?
    module.exports = attach(
      require 'jquery',
      require 'underscore',
      require 'hlf/jquery.extension.hlf.core',
      require 'hlf/jquery.extension.hlf.event'
    )
  else
    attach jQuery, _, jQuery.hlf
  return
)(@, ($, _, hlf) ->

  #- Cache common references internally.
  _requestAnimationFrame = window.requireAnimationFrame or
    window.Modernizr?.prefixed 'requestAnimationFrame', window

  # Namespace
  # ---------

  # It takes some more boilerplate to write the plugins. Any of this additional
  # support API is put into a plugin specific namespace under `$.hlf`, which in
  # this case is __$.hlf.tip__.
  #
  # - __debug__ toggles debug logging for all instances of a plugin.
  # - __toString__ helps to namespace when extending any jQuery API.
  #
  # The plugin's __defaults__ are available as reference. Also note that _the
  # plugin instance gets extended with the options_.
  #
  # - __$viewport__ is the element in which the tip must fit. It is _not_ the
  #   context element, which stores the tip instance and by convention contains
  #   the triggers.
  #
  # - __autoDirection__ automatically changes the direction to better fit the
  #   tip inside the viewport.
  #
  # - __cursorHeight__ is the browser's cursor height. We need to know this to
  #   properly offset the tip to avoid cases of cursor-tip-stem overlap.
  #
  # - __defaultDirection__ is used as a tie-breaker when selecting the best
  #   direction. Note that the direction data structure must be an array of
  #   `components`, and conventionally with top/bottom first.
  #
  # - __fireEvents__ can allow events __show.hlf.tip__ and __shown.hlf.tip__,
  #   __hide.hlf.tip__ and __hidden.hlf.tip__ to be triggered from the trigger
  #   elements. This is off by default to improve performance.
  #
  # - __tipTemplate__ should return interpolated html when given the additional
  #   container class list. Its context is the plugin instance.
  #
  # - __triggerContent__ can be the name of the trigger element's attribute or a
  #   function that provides custom content when given the trigger element.
  #
  # - NOTE: For these tip plugins, the majority of presentation state logic is
  #   in the plugin stylesheet. We update the presentation state by using
  #   namespaced __classNames__ generated in a closure.
  # 
  #   - __classNames.stem__ - Empty string to remove the stem.
  #   - __classNames.follow__ - Empty string to disable cursor following.
  #
  # - __animator__ by default uses the stock jQuery animation system. If you
  #   want a more performant system, like GreenSock or Velocity, set it here.
  #   See the visual tests for an example.
  #
  # - __animations__ are very configurable. Individual animations can be
  #   customized and will default to the base animation settings as needed.
  #
  # - __followUsingTransform__ will automatically check CSS transforms support
  #   via Modernizr. So you'll need to use Modernizr or manually enable this
  #   option to use the more performant transforms.
  #
  hlf.tip =
    debug: off
    toString: _.memoize (context) ->
      switch context
        when 'event'  then '.hlf.tip'
        when 'data'   then 'hlf-tip'
        when 'class'  then 'js-tips'
        else 'hlf.tip'

    defaults: do (pre = 'js-tip-') ->

      $viewport: $ 'body'
      autoDirection: on
      cursorHeight: 12
      defaultDirection: ['bottom', 'right']
      fireEvents: on
      tipTemplate: (containerClass) ->
        stemHtml = "<div class='#{@classNames.stem}'></div>" if @doStem is on
        """
