diff --git a/docs/awesome_table_in_html.Rmd b/docs/awesome_table_in_html.Rmd
index 43f6f1d..e7571b5 100644
--- a/docs/awesome_table_in_html.Rmd
+++ b/docs/awesome_table_in_html.Rmd
@@ -533,6 +533,26 @@
   save_kable(file = "table1.html", self_contained = T)
 ```
 
+## Use it with sparkline
+Well, this is not a feature but rather a documentation of how to use the `sparkline` package together with this package. The easiest way is sort of a hack. You can call `sparkline::sparkline(0)` somewhere on your document where no one would mind so its dependencies could be loaded without any hurdles. Then you use `sparkline::spk_chr()` to generate the text. Here is another example: [Chinese names in US babynames](https://cranky-chandrasekhar-cfefcd.netlify.app/)
+
+```{r}
+library(sparkline)
+sparkline(0)
+```
+
+```{r}
+spk_dt <- data.frame(
+  var = c("mpg", "wt"),
+  sparkline = c(spk_chr(mtcars$mpg), spk_chr(mtcars$wt))
+)
+
+kbl(spk_dt, escape = F) %>%
+  kable_paper(full_width = F)
+```
+
+
+
 # From other packages
 Since the structure of `kable` is relatively simple, it shouldn't be too difficult to convert HTML or LaTeX tables generated by other packages to a `kable` object and then use `kableExtra` to modify the outputs. If you are a package author, feel free to reach out to me and we can collaborate. 
 
diff --git a/docs/awesome_table_in_html.html b/docs/awesome_table_in_html.html
index 1a7cb46..f5ed744 100644
--- a/docs/awesome_table_in_html.html
+++ b/docs/awesome_table_in_html.html
@@ -1489,6 +1489,4578 @@
 border: 0;
 }
 </style>
+<script>(function() {
+  // If window.HTMLWidgets is already defined, then use it; otherwise create a
+  // new object. This allows preceding code to set options that affect the
+  // initialization process (though none currently exist).
+  window.HTMLWidgets = window.HTMLWidgets || {};
+
+  // See if we're running in a viewer pane. If not, we're in a web browser.
+  var viewerMode = window.HTMLWidgets.viewerMode =
+      /\bviewer_pane=1\b/.test(window.location);
+
+  // See if we're running in Shiny mode. If not, it's a static document.
+  // Note that static widgets can appear in both Shiny and static modes, but
+  // obviously, Shiny widgets can only appear in Shiny apps/documents.
+  var shinyMode = window.HTMLWidgets.shinyMode =
+      typeof(window.Shiny) !== "undefined" && !!window.Shiny.outputBindings;
+
+  // We can't count on jQuery being available, so we implement our own
+  // version if necessary.
+  function querySelectorAll(scope, selector) {
+    if (typeof(jQuery) !== "undefined" && scope instanceof jQuery) {
+      return scope.find(selector);
+    }
+    if (scope.querySelectorAll) {
+      return scope.querySelectorAll(selector);
+    }
+  }
+
+  function asArray(value) {
+    if (value === null)
+      return [];
+    if ($.isArray(value))
+      return value;
+    return [value];
+  }
+
+  // Implement jQuery's extend
+  function extend(target /*, ... */) {
+    if (arguments.length == 1) {
+      return target;
+    }
+    for (var i = 1; i < arguments.length; i++) {
+      var source = arguments[i];
+      for (var prop in source) {
+        if (source.hasOwnProperty(prop)) {
+          target[prop] = source[prop];
+        }
+      }
+    }
+    return target;
+  }
+
+  // IE8 doesn't support Array.forEach.
+  function forEach(values, callback, thisArg) {
+    if (values.forEach) {
+      values.forEach(callback, thisArg);
+    } else {
+      for (var i = 0; i < values.length; i++) {
+        callback.call(thisArg, values[i], i, values);
+      }
+    }
+  }
+
+  // Replaces the specified method with the return value of funcSource.
+  //
+  // Note that funcSource should not BE the new method, it should be a function
+  // that RETURNS the new method. funcSource receives a single argument that is
+  // the overridden method, it can be called from the new method. The overridden
+  // method can be called like a regular function, it has the target permanently
+  // bound to it so "this" will work correctly.
+  function overrideMethod(target, methodName, funcSource) {
+    var superFunc = target[methodName] || function() {};
+    var superFuncBound = function() {
+      return superFunc.apply(target, arguments);
+    };
+    target[methodName] = funcSource(superFuncBound);
+  }
+
+  // Add a method to delegator that, when invoked, calls
+  // delegatee.methodName. If there is no such method on
+  // the delegatee, but there was one on delegator before
+  // delegateMethod was called, then the original version
+  // is invoked instead.
+  // For example:
+  //
+  // var a = {
+  //   method1: function() { console.log('a1'); }
+  //   method2: function() { console.log('a2'); }
+  // };
+  // var b = {
+  //   method1: function() { console.log('b1'); }
+  // };
+  // delegateMethod(a, b, "method1");
+  // delegateMethod(a, b, "method2");
+  // a.method1();
+  // a.method2();
+  //
+  // The output would be "b1", "a2".
+  function delegateMethod(delegator, delegatee, methodName) {
+    var inherited = delegator[methodName];
+    delegator[methodName] = function() {
+      var target = delegatee;
+      var method = delegatee[methodName];
+
+      // The method doesn't exist on the delegatee. Instead,
+      // call the method on the delegator, if it exists.
+      if (!method) {
+        target = delegator;
+        method = inherited;
+      }
+
+      if (method) {
+        return method.apply(target, arguments);
+      }
+    };
+  }
+
+  // Implement a vague facsimilie of jQuery's data method
+  function elementData(el, name, value) {
+    if (arguments.length == 2) {
+      return el["htmlwidget_data_" + name];
+    } else if (arguments.length == 3) {
+      el["htmlwidget_data_" + name] = value;
+      return el;
+    } else {
+      throw new Error("Wrong number of arguments for elementData: " +
+        arguments.length);
+    }
+  }
+
+  // http://stackoverflow.com/questions/3446170/escape-string-for-use-in-javascript-regex
+  function escapeRegExp(str) {
+    return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
+  }
+
+  function hasClass(el, className) {
+    var re = new RegExp("\\b" + escapeRegExp(className) + "\\b");
+    return re.test(el.className);
+  }
+
+  // elements - array (or array-like object) of HTML elements
+  // className - class name to test for
+  // include - if true, only return elements with given className;
+  //   if false, only return elements *without* given className
+  function filterByClass(elements, className, include) {
+    var results = [];
+    for (var i = 0; i < elements.length; i++) {
+      if (hasClass(elements[i], className) == include)
+        results.push(elements[i]);
+    }
+    return results;
+  }
+
+  function on(obj, eventName, func) {
+    if (obj.addEventListener) {
+      obj.addEventListener(eventName, func, false);
+    } else if (obj.attachEvent) {
+      obj.attachEvent(eventName, func);
+    }
+  }
+
+  function off(obj, eventName, func) {
+    if (obj.removeEventListener)
+      obj.removeEventListener(eventName, func, false);
+    else if (obj.detachEvent) {
+      obj.detachEvent(eventName, func);
+    }
+  }
+
+  // Translate array of values to top/right/bottom/left, as usual with
+  // the "padding" CSS property
+  // https://developer.mozilla.org/en-US/docs/Web/CSS/padding
+  function unpackPadding(value) {
+    if (typeof(value) === "number")
+      value = [value];
+    if (value.length === 1) {
+      return {top: value[0], right: value[0], bottom: value[0], left: value[0]};
+    }
+    if (value.length === 2) {
+      return {top: value[0], right: value[1], bottom: value[0], left: value[1]};
+    }
+    if (value.length === 3) {
+      return {top: value[0], right: value[1], bottom: value[2], left: value[1]};
+    }
+    if (value.length === 4) {
+      return {top: value[0], right: value[1], bottom: value[2], left: value[3]};
+    }
+  }
+
+  // Convert an unpacked padding object to a CSS value
+  function paddingToCss(paddingObj) {
+    return paddingObj.top + "px " + paddingObj.right + "px " + paddingObj.bottom + "px " + paddingObj.left + "px";
+  }
+
+  // Makes a number suitable for CSS
+  function px(x) {
+    if (typeof(x) === "number")
+      return x + "px";
+    else
+      return x;
+  }
+
+  // Retrieves runtime widget sizing information for an element.
+  // The return value is either null, or an object with fill, padding,
+  // defaultWidth, defaultHeight fields.
+  function sizingPolicy(el) {
+    var sizingEl = document.querySelector("script[data-for='" + el.id + "'][type='application/htmlwidget-sizing']");
+    if (!sizingEl)
+      return null;
+    var sp = JSON.parse(sizingEl.textContent || sizingEl.text || "{}");
+    if (viewerMode) {
+      return sp.viewer;
+    } else {
+      return sp.browser;
+    }
+  }
+
+  // @param tasks Array of strings (or falsy value, in which case no-op).
+  //   Each element must be a valid JavaScript expression that yields a
+  //   function. Or, can be an array of objects with "code" and "data"
+  //   properties; in this case, the "code" property should be a string
+  //   of JS that's an expr that yields a function, and "data" should be
+  //   an object that will be added as an additional argument when that
+  //   function is called.
+  // @param target The object that will be "this" for each function
+  //   execution.
+  // @param args Array of arguments to be passed to the functions. (The
+  //   same arguments will be passed to all functions.)
+  function evalAndRun(tasks, target, args) {
+    if (tasks) {
+      forEach(tasks, function(task) {
+        var theseArgs = args;
+        if (typeof(task) === "object") {
+          theseArgs = theseArgs.concat([task.data]);
+          task = task.code;
+        }
+        var taskFunc = tryEval(task);
+        if (typeof(taskFunc) !== "function") {
+          throw new Error("Task must be a function! Source:\n" + task);
+        }
+        taskFunc.apply(target, theseArgs);
+      });
+    }
+  }
+
+  // Attempt eval() both with and without enclosing in parentheses.
+  // Note that enclosing coerces a function declaration into
+  // an expression that eval() can parse
+  // (otherwise, a SyntaxError is thrown)
+  function tryEval(code) {
+    var result = null;
+    try {
+      result = eval(code);
+    } catch(error) {
+      if (!error instanceof SyntaxError) {
+        throw error;
+      }
+      try {
+        result = eval("(" + code + ")");
+      } catch(e) {
+        if (e instanceof SyntaxError) {
+          throw error;
+        } else {
+          throw e;
+        }
+      }
+    }
+    return result;
+  }
+
+  function initSizing(el) {
+    var sizing = sizingPolicy(el);
+    if (!sizing)
+      return;
+
+    var cel = document.getElementById("htmlwidget_container");
+    if (!cel)
+      return;
+
+    if (typeof(sizing.padding) !== "undefined") {
+      document.body.style.margin = "0";
+      document.body.style.padding = paddingToCss(unpackPadding(sizing.padding));
+    }
+
+    if (sizing.fill) {
+      document.body.style.overflow = "hidden";
+      document.body.style.width = "100%";
+      document.body.style.height = "100%";
+      document.documentElement.style.width = "100%";
+      document.documentElement.style.height = "100%";
+      if (cel) {
+        cel.style.position = "absolute";
+        var pad = unpackPadding(sizing.padding);
+        cel.style.top = pad.top + "px";
+        cel.style.right = pad.right + "px";
+        cel.style.bottom = pad.bottom + "px";
+        cel.style.left = pad.left + "px";
+        el.style.width = "100%";
+        el.style.height = "100%";
+      }
+
+      return {
+        getWidth: function() { return cel.offsetWidth; },
+        getHeight: function() { return cel.offsetHeight; }
+      };
+
+    } else {
+      el.style.width = px(sizing.width);
+      el.style.height = px(sizing.height);
+
+      return {
+        getWidth: function() { return el.offsetWidth; },
+        getHeight: function() { return el.offsetHeight; }
+      };
+    }
+  }
+
+  // Default implementations for methods
+  var defaults = {
+    find: function(scope) {
+      return querySelectorAll(scope, "." + this.name);
+    },
+    renderError: function(el, err) {
+      var $el = $(el);
+
+      this.clearError(el);
+
+      // Add all these error classes, as Shiny does
+      var errClass = "shiny-output-error";
+      if (err.type !== null) {
+        // use the classes of the error condition as CSS class names
+        errClass = errClass + " " + $.map(asArray(err.type), function(type) {
+          return errClass + "-" + type;
+        }).join(" ");
+      }
+      errClass = errClass + " htmlwidgets-error";
+
+      // Is el inline or block? If inline or inline-block, just display:none it
+      // and add an inline error.
+      var display = $el.css("display");
+      $el.data("restore-display-mode", display);
+
+      if (display === "inline" || display === "inline-block") {
+        $el.hide();
+        if (err.message !== "") {
+          var errorSpan = $("<span>").addClass(errClass);
+          errorSpan.text(err.message);
+          $el.after(errorSpan);
+        }
+      } else if (display === "block") {
+        // If block, add an error just after the el, set visibility:none on the
+        // el, and position the error to be on top of the el.
+        // Mark it with a unique ID and CSS class so we can remove it later.
+        $el.css("visibility", "hidden");
+        if (err.message !== "") {
+          var errorDiv = $("<div>").addClass(errClass).css("position", "absolute")
+            .css("top", el.offsetTop)
+            .css("left", el.offsetLeft)
+            // setting width can push out the page size, forcing otherwise
+            // unnecessary scrollbars to appear and making it impossible for
+            // the element to shrink; so use max-width instead
+            .css("maxWidth", el.offsetWidth)
+            .css("height", el.offsetHeight);
+          errorDiv.text(err.message);
+          $el.after(errorDiv);
+
+          // Really dumb way to keep the size/position of the error in sync with
+          // the parent element as the window is resized or whatever.
+          var intId = setInterval(function() {
+            if (!errorDiv[0].parentElement) {
+              clearInterval(intId);
+              return;
+            }
+            errorDiv
+              .css("top", el.offsetTop)
+              .css("left", el.offsetLeft)
+              .css("maxWidth", el.offsetWidth)
+              .css("height", el.offsetHeight);
+          }, 500);
+        }
+      }
+    },
+    clearError: function(el) {
+      var $el = $(el);
+      var display = $el.data("restore-display-mode");
+      $el.data("restore-display-mode", null);
+
+      if (display === "inline" || display === "inline-block") {
+        if (display)
+          $el.css("display", display);
+        $(el.nextSibling).filter(".htmlwidgets-error").remove();
+      } else if (display === "block"){
+        $el.css("visibility", "inherit");
+        $(el.nextSibling).filter(".htmlwidgets-error").remove();
+      }
+    },
+    sizing: {}
+  };
+
+  // Called by widget bindings to register a new type of widget. The definition
+  // object can contain the following properties:
+  // - name (required) - A string indicating the binding name, which will be
+  //   used by default as the CSS classname to look for.
+  // - initialize (optional) - A function(el) that will be called once per
+  //   widget element; if a value is returned, it will be passed as the third
+  //   value to renderValue.
+  // - renderValue (required) - A function(el, data, initValue) that will be
+  //   called with data. Static contexts will cause this to be called once per
+  //   element; Shiny apps will cause this to be called multiple times per
+  //   element, as the data changes.
+  window.HTMLWidgets.widget = function(definition) {
+    if (!definition.name) {
+      throw new Error("Widget must have a name");
+    }
+    if (!definition.type) {
+      throw new Error("Widget must have a type");
+    }
+    // Currently we only support output widgets
+    if (definition.type !== "output") {
+      throw new Error("Unrecognized widget type '" + definition.type + "'");
+    }
+    // TODO: Verify that .name is a valid CSS classname
+
+    // Support new-style instance-bound definitions. Old-style class-bound
+    // definitions have one widget "object" per widget per type/class of
+    // widget; the renderValue and resize methods on such widget objects
+    // take el and instance arguments, because the widget object can't
+    // store them. New-style instance-bound definitions have one widget
+    // object per widget instance; the definition that's passed in doesn't
+    // provide renderValue or resize methods at all, just the single method
+    //   factory(el, width, height)
+    // which returns an object that has renderValue(x) and resize(w, h).
+    // This enables a far more natural programming style for the widget
+    // author, who can store per-instance state using either OO-style
+    // instance fields or functional-style closure variables (I guess this
+    // is in contrast to what can only be called C-style pseudo-OO which is
+    // what we required before).
+    if (definition.factory) {
+      definition = createLegacyDefinitionAdapter(definition);
+    }
+
+    if (!definition.renderValue) {
+      throw new Error("Widget must have a renderValue function");
+    }
+
+    // For static rendering (non-Shiny), use a simple widget registration
+    // scheme. We also use this scheme for Shiny apps/documents that also
+    // contain static widgets.
+    window.HTMLWidgets.widgets = window.HTMLWidgets.widgets || [];
+    // Merge defaults into the definition; don't mutate the original definition.
+    var staticBinding = extend({}, defaults, definition);
+    overrideMethod(staticBinding, "find", function(superfunc) {
+      return function(scope) {
+        var results = superfunc(scope);
+        // Filter out Shiny outputs, we only want the static kind
+        return filterByClass(results, "html-widget-output", false);
+      };
+    });
+    window.HTMLWidgets.widgets.push(staticBinding);
+
+    if (shinyMode) {
+      // Shiny is running. Register the definition with an output binding.
+      // The definition itself will not be the output binding, instead
+      // we will make an output binding object that delegates to the
+      // definition. This is because we foolishly used the same method
+      // name (renderValue) for htmlwidgets definition and Shiny bindings
+      // but they actually have quite different semantics (the Shiny
+      // bindings receive data that includes lots of metadata that it
+      // strips off before calling htmlwidgets renderValue). We can't
+      // just ignore the difference because in some widgets it's helpful
+      // to call this.renderValue() from inside of resize(), and if
+      // we're not delegating, then that call will go to the Shiny
+      // version instead of the htmlwidgets version.
+
+      // Merge defaults with definition, without mutating either.
+      var bindingDef = extend({}, defaults, definition);
+
+      // This object will be our actual Shiny binding.
+      var shinyBinding = new Shiny.OutputBinding();
+
+      // With a few exceptions, we'll want to simply use the bindingDef's
+      // version of methods if they are available, otherwise fall back to
+      // Shiny's defaults. NOTE: If Shiny's output bindings gain additional
+      // methods in the future, and we want them to be overrideable by
+      // HTMLWidget binding definitions, then we'll need to add them to this
+      // list.
+      delegateMethod(shinyBinding, bindingDef, "getId");
+      delegateMethod(shinyBinding, bindingDef, "onValueChange");
+      delegateMethod(shinyBinding, bindingDef, "onValueError");
+      delegateMethod(shinyBinding, bindingDef, "renderError");
+      delegateMethod(shinyBinding, bindingDef, "clearError");
+      delegateMethod(shinyBinding, bindingDef, "showProgress");
+
+      // The find, renderValue, and resize are handled differently, because we
+      // want to actually decorate the behavior of the bindingDef methods.
+
+      shinyBinding.find = function(scope) {
+        var results = bindingDef.find(scope);
+
+        // Only return elements that are Shiny outputs, not static ones
+        var dynamicResults = results.filter(".html-widget-output");
+
+        // It's possible that whatever caused Shiny to think there might be
+        // new dynamic outputs, also caused there to be new static outputs.
+        // Since there might be lots of different htmlwidgets bindings, we
+        // schedule execution for later--no need to staticRender multiple
+        // times.
+        if (results.length !== dynamicResults.length)
+          scheduleStaticRender();
+
+        return dynamicResults;
+      };
+
+      // Wrap renderValue to handle initialization, which unfortunately isn't
+      // supported natively by Shiny at the time of this writing.
+
+      shinyBinding.renderValue = function(el, data) {
+        Shiny.renderDependencies(data.deps);
+        // Resolve strings marked as javascript literals to objects
+        if (!(data.evals instanceof Array)) data.evals = [data.evals];
+        for (var i = 0; data.evals && i < data.evals.length; i++) {
+          window.HTMLWidgets.evaluateStringMember(data.x, data.evals[i]);
+        }
+        if (!bindingDef.renderOnNullValue) {
+          if (data.x === null) {
+            el.style.visibility = "hidden";
+            return;
+          } else {
+            el.style.visibility = "inherit";
+          }
+        }
+        if (!elementData(el, "initialized")) {
+          initSizing(el);
+
+          elementData(el, "initialized", true);
+          if (bindingDef.initialize) {
+            var result = bindingDef.initialize(el, el.offsetWidth,
+              el.offsetHeight);
+            elementData(el, "init_result", result);
+          }
+        }
+        bindingDef.renderValue(el, data.x, elementData(el, "init_result"));
+        evalAndRun(data.jsHooks.render, elementData(el, "init_result"), [el, data.x]);
+      };
+
+      // Only override resize if bindingDef implements it
+      if (bindingDef.resize) {
+        shinyBinding.resize = function(el, width, height) {
+          // Shiny can call resize before initialize/renderValue have been
+          // called, which doesn't make sense for widgets.
+          if (elementData(el, "initialized")) {
+            bindingDef.resize(el, width, height, elementData(el, "init_result"));
+          }
+        };
+      }
+
+      Shiny.outputBindings.register(shinyBinding, bindingDef.name);
+    }
+  };
+
+  var scheduleStaticRenderTimerId = null;
+  function scheduleStaticRender() {
+    if (!scheduleStaticRenderTimerId) {
+      scheduleStaticRenderTimerId = setTimeout(function() {
+        scheduleStaticRenderTimerId = null;
+        window.HTMLWidgets.staticRender();
+      }, 1);
+    }
+  }
+
+  // Render static widgets after the document finishes loading
+  // Statically render all elements that are of this widget's class
+  window.HTMLWidgets.staticRender = function() {
+    var bindings = window.HTMLWidgets.widgets || [];
+    forEach(bindings, function(binding) {
+      var matches = binding.find(document.documentElement);
+      forEach(matches, function(el) {
+        var sizeObj = initSizing(el, binding);
+
+        if (hasClass(el, "html-widget-static-bound"))
+          return;
+        el.className = el.className + " html-widget-static-bound";
+
+        var initResult;
+        if (binding.initialize) {
+          initResult = binding.initialize(el,
+            sizeObj ? sizeObj.getWidth() : el.offsetWidth,
+            sizeObj ? sizeObj.getHeight() : el.offsetHeight
+          );
+          elementData(el, "init_result", initResult);
+        }
+
+        if (binding.resize) {
+          var lastSize = {
+            w: sizeObj ? sizeObj.getWidth() : el.offsetWidth,
+            h: sizeObj ? sizeObj.getHeight() : el.offsetHeight
+          };
+          var resizeHandler = function(e) {
+            var size = {
+              w: sizeObj ? sizeObj.getWidth() : el.offsetWidth,
+              h: sizeObj ? sizeObj.getHeight() : el.offsetHeight
+            };
+            if (size.w === 0 && size.h === 0)
+              return;
+            if (size.w === lastSize.w && size.h === lastSize.h)
+              return;
+            lastSize = size;
+            binding.resize(el, size.w, size.h, initResult);
+          };
+
+          on(window, "resize", resizeHandler);
+
+          // This is needed for cases where we're running in a Shiny
+          // app, but the widget itself is not a Shiny output, but
+          // rather a simple static widget. One example of this is
+          // an rmarkdown document that has runtime:shiny and widget
+          // that isn't in a render function. Shiny only knows to
+          // call resize handlers for Shiny outputs, not for static
+          // widgets, so we do it ourselves.
+          if (window.jQuery) {
+            window.jQuery(document).on(
+              "shown.htmlwidgets shown.bs.tab.htmlwidgets shown.bs.collapse.htmlwidgets",
+              resizeHandler
+            );
+            window.jQuery(document).on(
+              "hidden.htmlwidgets hidden.bs.tab.htmlwidgets hidden.bs.collapse.htmlwidgets",
+              resizeHandler
+            );
+          }
+
+          // This is needed for the specific case of ioslides, which
+          // flips slides between display:none and display:block.
+          // Ideally we would not have to have ioslide-specific code
+          // here, but rather have ioslides raise a generic event,
+          // but the rmarkdown package just went to CRAN so the
+          // window to getting that fixed may be long.
+          if (window.addEventListener) {
+            // It's OK to limit this to window.addEventListener
+            // browsers because ioslides itself only supports
+            // such browsers.
+            on(document, "slideenter", resizeHandler);
+            on(document, "slideleave", resizeHandler);
+          }
+        }
+
+        var scriptData = document.querySelector("script[data-for='" + el.id + "'][type='application/json']");
+        if (scriptData) {
+          var data = JSON.parse(scriptData.textContent || scriptData.text);
+          // Resolve strings marked as javascript literals to objects
+          if (!(data.evals instanceof Array)) data.evals = [data.evals];
+          for (var k = 0; data.evals && k < data.evals.length; k++) {
+            window.HTMLWidgets.evaluateStringMember(data.x, data.evals[k]);
+          }
+          binding.renderValue(el, data.x, initResult);
+          evalAndRun(data.jsHooks.render, initResult, [el, data.x]);
+        }
+      });
+    });
+
+    invokePostRenderHandlers();
+  }
+
+
+  function has_jQuery3() {
+    if (!window.jQuery) {
+      return false;
+    }
+    var $version = window.jQuery.fn.jquery;
+    var $major_version = parseInt($version.split(".")[0]);
+    return $major_version >= 3;
+  }
+
+  /*
+  / Shiny 1.4 bumped jQuery from 1.x to 3.x which means jQuery's
+  / on-ready handler (i.e., $(fn)) is now asyncronous (i.e., it now
+  / really means $(setTimeout(fn)).
+  / https://jquery.com/upgrade-guide/3.0/#breaking-change-document-ready-handlers-are-now-asynchronous
+  /
+  / Since Shiny uses $() to schedule initShiny, shiny>=1.4 calls initShiny
+  / one tick later than it did before, which means staticRender() is
+  / called renderValue() earlier than (advanced) widget authors might be expecting.
+  / https://github.com/rstudio/shiny/issues/2630
+  /
+  / For a concrete example, leaflet has some methods (e.g., updateBounds)
+  / which reference Shiny methods registered in initShiny (e.g., setInputValue).
+  / Since leaflet is privy to this life-cycle, it knows to use setTimeout() to
+  / delay execution of those methods (until Shiny methods are ready)
+  / https://github.com/rstudio/leaflet/blob/18ec981/javascript/src/index.js#L266-L268
+  /
+  / Ideally widget authors wouldn't need to use this setTimeout() hack that
+  / leaflet uses to call Shiny methods on a staticRender(). In the long run,
+  / the logic initShiny should be broken up so that method registration happens
+  / right away, but binding happens later.
+  */
+  function maybeStaticRenderLater() {
+    if (shinyMode && has_jQuery3()) {
+      window.jQuery(window.HTMLWidgets.staticRender);
+    } else {
+      window.HTMLWidgets.staticRender();
+    }
+  }
+
+  if (document.addEventListener) {
+    document.addEventListener("DOMContentLoaded", function() {
+      document.removeEventListener("DOMContentLoaded", arguments.callee, false);
+      maybeStaticRenderLater();
+    }, false);
+  } else if (document.attachEvent) {
+    document.attachEvent("onreadystatechange", function() {
+      if (document.readyState === "complete") {
+        document.detachEvent("onreadystatechange", arguments.callee);
+        maybeStaticRenderLater();
+      }
+    });
+  }
+
+
+  window.HTMLWidgets.getAttachmentUrl = function(depname, key) {
+    // If no key, default to the first item
+    if (typeof(key) === "undefined")
+      key = 1;
+
+    var link = document.getElementById(depname + "-" + key + "-attachment");
+    if (!link) {
+      throw new Error("Attachment " + depname + "/" + key + " not found in document");
+    }
+    return link.getAttribute("href");
+  };
+
+  window.HTMLWidgets.dataframeToD3 = function(df) {
+    var names = [];
+    var length;
+    for (var name in df) {
+        if (df.hasOwnProperty(name))
+            names.push(name);
+        if (typeof(df[name]) !== "object" || typeof(df[name].length) === "undefined") {
+            throw new Error("All fields must be arrays");
+        } else if (typeof(length) !== "undefined" && length !== df[name].length) {
+            throw new Error("All fields must be arrays of the same length");
+        }
+        length = df[name].length;
+    }
+    var results = [];
+    var item;
+    for (var row = 0; row < length; row++) {
+        item = {};
+        for (var col = 0; col < names.length; col++) {
+            item[names[col]] = df[names[col]][row];
+        }
+        results.push(item);
+    }
+    return results;
+  };
+
+  window.HTMLWidgets.transposeArray2D = function(array) {
+      if (array.length === 0) return array;
+      var newArray = array[0].map(function(col, i) {
+          return array.map(function(row) {
+              return row[i]
+          })
+      });
+      return newArray;
+  };
+  // Split value at splitChar, but allow splitChar to be escaped
+  // using escapeChar. Any other characters escaped by escapeChar
+  // will be included as usual (including escapeChar itself).
+  function splitWithEscape(value, splitChar, escapeChar) {
+    var results = [];
+    var escapeMode = false;
+    var currentResult = "";
+    for (var pos = 0; pos < value.length; pos++) {
+      if (!escapeMode) {
+        if (value[pos] === splitChar) {
+          results.push(currentResult);
+          currentResult = "";
+        } else if (value[pos] === escapeChar) {
+          escapeMode = true;
+        } else {
+          currentResult += value[pos];
+        }
+      } else {
+        currentResult += value[pos];
+        escapeMode = false;
+      }
+    }
+    if (currentResult !== "") {
+      results.push(currentResult);
+    }
+    return results;
+  }
+  // Function authored by Yihui/JJ Allaire
+  window.HTMLWidgets.evaluateStringMember = function(o, member) {
+    var parts = splitWithEscape(member, '.', '\\');
+    for (var i = 0, l = parts.length; i < l; i++) {
+      var part = parts[i];
+      // part may be a character or 'numeric' member name
+      if (o !== null && typeof o === "object" && part in o) {
+        if (i == (l - 1)) { // if we are at the end of the line then evalulate
+          if (typeof o[part] === "string")
+            o[part] = tryEval(o[part]);
+        } else { // otherwise continue to next embedded object
+          o = o[part];
+        }
+      }
+    }
+  };
+
+  // Retrieve the HTMLWidget instance (i.e. the return value of an
+  // HTMLWidget binding's initialize() or factory() function)
+  // associated with an element, or null if none.
+  window.HTMLWidgets.getInstance = function(el) {
+    return elementData(el, "init_result");
+  };
+
+  // Finds the first element in the scope that matches the selector,
+  // and returns the HTMLWidget instance (i.e. the return value of
+  // an HTMLWidget binding's initialize() or factory() function)
+  // associated with that element, if any. If no element matches the
+  // selector, or the first matching element has no HTMLWidget
+  // instance associated with it, then null is returned.
+  //
+  // The scope argument is optional, and defaults to window.document.
+  window.HTMLWidgets.find = function(scope, selector) {
+    if (arguments.length == 1) {
+      selector = scope;
+      scope = document;
+    }
+
+    var el = scope.querySelector(selector);
+    if (el === null) {
+      return null;
+    } else {
+      return window.HTMLWidgets.getInstance(el);
+    }
+  };
+
+  // Finds all elements in the scope that match the selector, and
+  // returns the HTMLWidget instances (i.e. the return values of
+  // an HTMLWidget binding's initialize() or factory() function)
+  // associated with the elements, in an array. If elements that
+  // match the selector don't have an associated HTMLWidget
+  // instance, the returned array will contain nulls.
+  //
+  // The scope argument is optional, and defaults to window.document.
+  window.HTMLWidgets.findAll = function(scope, selector) {
+    if (arguments.length == 1) {
+      selector = scope;
+      scope = document;
+    }
+
+    var nodes = scope.querySelectorAll(selector);
+    var results = [];
+    for (var i = 0; i < nodes.length; i++) {
+      results.push(window.HTMLWidgets.getInstance(nodes[i]));
+    }
+    return results;
+  };
+
+  var postRenderHandlers = [];
+  function invokePostRenderHandlers() {
+    while (postRenderHandlers.length) {
+      var handler = postRenderHandlers.shift();
+      if (handler) {
+        handler();
+      }
+    }
+  }
+
+  // Register the given callback function to be invoked after the
+  // next time static widgets are rendered.
+  window.HTMLWidgets.addPostRenderHandler = function(callback) {
+    postRenderHandlers.push(callback);
+  };
+
+  // Takes a new-style instance-bound definition, and returns an
+  // old-style class-bound definition. This saves us from having
+  // to rewrite all the logic in this file to accomodate both
+  // types of definitions.
+  function createLegacyDefinitionAdapter(defn) {
+    var result = {
+      name: defn.name,
+      type: defn.type,
+      initialize: function(el, width, height) {
+        return defn.factory(el, width, height);
+      },
+      renderValue: function(el, x, instance) {
+        return instance.renderValue(x);
+      },
+      resize: function(el, width, height, instance) {
+        return instance.resize(width, height);
+      }
+    };
+
+    if (defn.find)
+      result.find = defn.find;
+    if (defn.renderError)
+      result.renderError = defn.renderError;
+    if (defn.clearError)
+      result.clearError = defn.clearError;
+
+    return result;
+  }
+})();
+
+</script>
+<style type="text/css">.jqstooltip {-webkit-box-sizing: content-box;-moz-box-sizing: content-box;box-sizing: content-box;}</style>
+<script>/**
+*
+* jquery.sparkline.js
+*
+* v@VERSION@
+* (c) Splunk, Inc
+* Contact: Gareth Watts (gareth@splunk.com)
+* http://omnipotent.net/jquery.sparkline/
+*
+* Generates inline sparkline charts from data supplied either to the method
+* or inline in HTML
+*
+* Compatible with Internet Explorer 6.0+ and modern browsers equipped with the canvas tag
+* (Firefox 2.0+, Safari, Opera, etc)
+*
+* License: New BSD License
+*
+* Copyright (c) 2012, Splunk Inc.
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification,
+* are permitted provided that the following conditions are met:
+*
+*     * Redistributions of source code must retain the above copyright notice,
+*       this list of conditions and the following disclaimer.
+*     * Redistributions in binary form must reproduce the above copyright notice,
+*       this list of conditions and the following disclaimer in the documentation
+*       and/or other materials provided with the distribution.
+*     * Neither the name of Splunk Inc nor the names of its contributors may
+*       be used to endorse or promote products derived from this software without
+*       specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+* SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*
+* Usage:
+*  $(selector).sparkline(values, options)
+*
+* If values is undefined or set to 'html' then the data values are read from the specified tag:
+*   <p>Sparkline: <span class="sparkline">1,4,6,6,8,5,3,5</span></p>
+*   $('.sparkline').sparkline();
+* There must be no spaces in the enclosed data set
+*
+* Otherwise values must be an array of numbers or null values
+*    <p>Sparkline: <span id="sparkline1">This text replaced if the browser is compatible</span></p>
+*    $('#sparkline1').sparkline([1,4,6,6,8,5,3,5])
+*    $('#sparkline2').sparkline([1,4,6,null,null,5,3,5])
+*
+* Values can also be specified in an HTML comment, or as a values attribute:
+*    <p>Sparkline: <span class="sparkline"><!--1,4,6,6,8,5,3,5 --></span></p>
+*    <p>Sparkline: <span class="sparkline" values="1,4,6,6,8,5,3,5"></span></p>
+*    $('.sparkline').sparkline();
+*
+* For line charts, x values can also be specified:
+*   <p>Sparkline: <span class="sparkline">1:1,2.7:4,3.4:6,5:6,6:8,8.7:5,9:3,10:5</span></p>
+*    $('#sparkline1').sparkline([ [1,1], [2.7,4], [3.4,6], [5,6], [6,8], [8.7,5], [9,3], [10,5] ])
+*
+* By default, options should be passed in as the second argument to the sparkline function:
+*   $('.sparkline').sparkline([1,2,3,4], {type: 'bar'})
+*
+* Options can also be set by passing them on the tag itself.  This feature is disabled by default though
+* as there's a slight performance overhead:
+*   $('.sparkline').sparkline([1,2,3,4], {enableTagOptions: true})
+*   <p>Sparkline: <span class="sparkline" sparkType="bar" sparkBarColor="red">loading</span></p>
+* Prefix all options supplied as tag attribute with "spark" (configurable by setting tagOptionsPrefix)
+*
+* Supported options:
+*   lineColor - Color of the line used for the chart
+*   fillColor - Color used to fill in the chart - Set to '' or false for a transparent chart
+*   width - Width of the chart - Defaults to 3 times the number of values in pixels
+*   height - Height of the chart - Defaults to the height of the containing element
+*   chartRangeMin - Specify the minimum value to use for the Y range of the chart - Defaults to the minimum value supplied
+*   chartRangeMax - Specify the maximum value to use for the Y range of the chart - Defaults to the maximum value supplied
+*   chartRangeClip - Clip out of range values to the max/min specified by chartRangeMin and chartRangeMax
+*   chartRangeMinX - Specify the minimum value to use for the X range of the chart - Defaults to the minimum value supplied
+*   chartRangeMaxX - Specify the maximum value to use for the X range of the chart - Defaults to the maximum value supplied
+*   composite - If true then don't erase any existing chart attached to the tag, but draw
+*           another chart over the top - Note that width and height are ignored if an
+*           existing chart is detected.
+*   tagValuesAttribute - Name of tag attribute to check for data values - Defaults to 'values'
+*   enableTagOptions - Whether to check tags for sparkline options
+*   tagOptionsPrefix - Prefix used for options supplied as tag attributes - Defaults to 'spark'
+*   disableHiddenCheck - If set to true, then the plugin will assume that charts will never be drawn into a
+*           hidden dom element, avoiding a browser reflow
+*   disableInteraction - If set to true then all mouseover/click interaction behaviour will be disabled,
+*       making the plugin perform much like it did in 1.x
+*   disableTooltips - If set to true then tooltips will be disabled - Defaults to false (tooltips enabled)
+*   disableHighlight - If set to true then highlighting of selected chart elements on mouseover will be disabled
+*           defaults to false (highlights enabled)
+*   highlightLighten - Factor to lighten/darken highlighted chart values by - Defaults to 1.4 for a 40% increase
+*   tooltipContainer - Specify which DOM element the tooltip should be rendered into - defaults to document.body
+*   tooltipClassname - Optional CSS classname to apply to tooltips - If not specified then a default style will be applied
+*   tooltipOffsetX - How many pixels away from the mouse pointer to render the tooltip on the X axis
+*   tooltipOffsetY - How many pixels away from the mouse pointer to render the tooltip on the r axis
+*   tooltipFormatter  - Optional callback that allows you to override the HTML displayed in the tooltip
+*           callback is given arguments of (sparkline, options, fields)
+*   tooltipChartTitle - If specified then the tooltip uses the string specified by this setting as a title
+*   tooltipFormat - A format string or SPFormat object  (or an array thereof for multiple entries)
+*           to control the format of the tooltip
+*   tooltipPrefix - A string to prepend to each field displayed in a tooltip
+*   tooltipSuffix - A string to append to each field displayed in a tooltip
+*   tooltipPrefixBinLabels - An array of Bin Labels for each offset value to add as the start
+*                            of the tooltip prefix.  Example:
+*        var giants_game_results = [1,-1,1,-1,-1,-1,1,1,1,-1,1,-1,-1,1,1,1,1,1,1,1],
+*            giants_game_dates  = ["9/30", "10/1", "10/2", "10/3", "10/6", "10/7", "10/9", "10/10", "10/11", "10/14", "10/15",
+*                                  "10/17", "10/18", "10/19", "10/21", "10/22", "10/24", "10/25", "10/27", "10/28"];
+*        $('#giants').sparkline(giants_results, {type: 'tristate', tooltipPrefixBinLabels: giants_dates, tooltipPrefix: ' - '};
+*   tooltipSuffixBinLabels - An array of Bin Labels for each offset value to add as the end
+*                            of the tooltip suffix.
+*   tooltipSkipNull - If true then null values will not have a tooltip displayed (defaults to true)
+*   tooltipValueLookups - An object or range map to map field values to tooltip strings
+*                         (eg. to map -1 to "Lost", 0 to "Draw", and 1 to "Win")
+*   toolTipPosition - Display tooltip to the 'left' or 'right' of the mouse - Defaults to "right"
+*   numberFormatter - Optional callback for formatting numbers in tooltips
+*   numberDigitGroupSep - Character to use for group separator in numbers "1,234" - Defaults to ","
+*   numberDecimalMark - Character to use for the decimal point when formatting numbers - Defaults to "."
+*   numberDigitGroupCount - Number of digits between group separator - Defaults to 3
+*
+* There are 8 types of sparkline, selected by supplying a "type" option of 'line' (default),
+* 'bar', 'tristate', 'bullet', 'discrete', 'pie', 'box' or 'stack'
+*    line - Line chart.  Options:
+*       spotColor - Set to '' to not end each line in a circular spot
+*       minSpotColor - If set, color of spot at minimum value
+*       maxSpotColor - If set, color of spot at maximum value
+*       spotRadius - Radius in pixels
+*       lineWidth - Width of line in pixels
+*       normalRangeMin
+*       normalRangeMax - If set draws a filled horizontal bar between these two values marking the "normal"
+*                        or expected range of values
+*       normalRangeColor - Color to use for the above bar
+*       drawNormalOnTop - Draw the normal range above the chart fill color if true
+*       defaultPixelsPerValue - Defaults to 3 pixels of width for each value in the chart
+*       highlightSpotColor - The color to use for drawing a highlight spot on mouseover - Set to null to disable
+*       highlightLineColor - The color to use for drawing a highlight line on mouseover - Set to null to disable
+*       valueSpots - Specify which points to draw spots on, and in which color.  Accepts a range map
+*
+*   bar - Bar chart.  Options:
+*       barColor - Color of bars for positive values
+*       negBarColor - Color of bars for negative values
+*       zeroColor - Color of bars with zero values
+*       nullColor - Color of bars with null values - Defaults to omitting the bar entirely
+*       barWidth - Width of bars in pixels
+*       colorMap - Optional mapping of values to colors to override the *BarColor values above
+*                  can be an Array of values to control the color of individual bars or a range map
+*                  to specify colors for individual ranges of values
+*       barSpacing - Gap between bars in pixels
+*       zeroAxis - Centers the y-axis around zero if true
+*
+*   tristate - Charts values of win (>0), lose (<0) or draw (=0)
+*       posBarColor - Color of win values
+*       negBarColor - Color of lose values
+*       zeroBarColor - Color of draw values
+*       barWidth - Width of bars in pixels
+*       barSpacing - Gap between bars in pixels
+*       colorMap - Optional mapping of values to colors to override the *BarColor values above
+*                  can be an Array of values to control the color of individual bars or a range map
+*                  to specify colors for individual ranges of values
+*
+*   discrete - Options:
+*       lineHeight - Height of each line in pixels - Defaults to 30% of the graph height
+*       thesholdValue - Values less than this value will be drawn using thresholdColor instead of lineColor
+*       thresholdColor
+*
+*   bullet - Values for bullet graphs msut be in the order: target, performance, range1, range2, range3, ...
+*       options:
+*       targetColor - The color of the vertical target marker
+*       targetWidth - The width of the target marker in pixels
+*       performanceColor - The color of the performance measure horizontal bar
+*       rangeColors - Colors to use for each qualitative range background color
+*
+*   pie - Pie chart. Options:
+*       sliceColors - An array of colors to use for pie slices
+*       offset - Angle in degrees to offset the first slice - Try -90 or +90
+*       borderWidth - Width of border to draw around the pie chart, in pixels - Defaults to 0 (no border)
+*       borderColor - Color to use for the pie chart border - Defaults to #000
+*   stack - Horizontal stack chart. Options:
+*       sliceColors - An array of colors to use for pie slices
+*
+*   box - Box plot. Options:
+*       raw - Set to true to supply pre-computed plot points as values
+*             values should be: low_outlier, low_whisker, q1, median, q3, high_whisker, high_outlier
+*             When set to false you can supply any number of values and the box plot will
+*             be computed for you.  Default is false.
+*       showOutliers - Set to true (default) to display outliers as circles
+*       outlierIQR - Interquartile range used to determine outliers.  Default 1.5
+*       boxLineColor - Outline color of the box
+*       boxFillColor - Fill color for the box
+*       whiskerColor - Line color used for whiskers
+*       outlierLineColor - Outline color of outlier circles
+*       outlierFillColor - Fill color of the outlier circles
+*       spotRadius - Radius of outlier circles
+*       medianColor - Line color of the median line
+*       target - Draw a target cross hair at the supplied value (default undefined)
+*
+*
+*
+*   Examples:
+*   $('#sparkline1').sparkline(myvalues, { lineColor: '#f00', fillColor: false });
+*   $('.barsparks').sparkline('html', { type:'bar', height:'40px', barWidth:5 });
+*   $('#tristate').sparkline([1,1,-1,1,0,0,-1], { type:'tristate' }):
+*   $('#discrete').sparkline([1,3,4,5,5,3,4,5], { type:'discrete' });
+*   $('#bullet').sparkline([10,12,12,9,7], { type:'bullet' });
+*   $('#pie').sparkline([1,1,2], { type:'pie' });
+*/
+
+/*jslint regexp: true, browser: true, jquery: true, white: true, nomen: false, plusplus: false, maxerr: 500, indent: 4 */
+
+(function(document, Math, undefined) { // performance/minified-size optimization
+(function(factory) {
+    if(typeof define === 'function' && define.amd) {
+        define('jquery.sparkline', ['jquery'], factory);
+    } else if (jQuery && !jQuery.fn.sparkline) {
+        factory(jQuery);
+    }
+}
+(function($) {
+    'use strict';
+
+    // CUSTOM MOD: median var added
+    var UNSET_OPTION = {},
+        getDefaults, createClass, SPFormat, clipval, median, quartile, normalizeValue, normalizeValues,
+        remove, isNumber, all, sum, addCSS, ensureArray, formatNumber, RangeMap,
+        MouseHandler, Tooltip, barHighlightMixin,
+        line, bar, tristate, discrete, bullet, pie, stack, box, timeline, defaultStyles, initStyles,
+        VShape, VCanvas_base, VCanvas_canvas, VCanvas_vml, pending, shapeCount = 0;
+
+
+    /**
+     * Default configuration settings
+     */
+    getDefaults = function () {
+        return {
+            // Settings common to most/all chart types
+            common: {
+                type: 'line',
+                lineColor: '#00f',
+                fillColor: '#cdf',
+                defaultPixelsPerValue: 3,
+                width: 'auto',
+                height: 'auto',
+                composite: false,
+                tagValuesAttribute: 'values',
+                tagOptionsPrefix: 'spark',
+                enableTagOptions: false,
+                enableHighlight: true,
+                highlightLighten: 1.4,
+                tooltipSkipNull: true,
+                tooltipPrefix: '',
+                tooltipSuffix: '',
+                disableHiddenCheck: false,
+                numberFormatter: false,
+                numberDigitGroupCount: 3,
+                numberDigitGroupSep: ',',
+                numberDecimalMark: '.',
+                disableTooltips: false,
+                disableInteraction: false
+            },
+            // Defaults for line charts
+            line: {
+                spotColor: '#f80',
+                highlightSpotColor: '#5f5',
+                highlightLineColor: '#f22',
+                refLineColor: '#f22',
+                // refLineX: null,
+                // refLineY: null,
+                spotRadius: 1.5,
+                minSpotColor: '#f80',
+                maxSpotColor: '#f80',
+                lineWidth: 1,
+                normalRangeMin: undefined,
+                normalRangeMax: undefined,
+                normalRangeColor: '#ccc',
+                drawNormalOnTop: false,
+                chartRangeMin: undefined,
+                chartRangeMax: undefined,
+                chartRangeMinX: undefined,
+                chartRangeMaxX: undefined,
+                tooltipFormat: new SPFormat('<span style="color: {{color}}">&#9679;</span> {{prefix}}{{y}}{{suffix}}')
+            },
+            // Defaults for bar charts
+            bar: {
+                barColor: '#3366cc',
+                negBarColor: '#f44',
+                stackedBarColor: ['#3366cc', '#dc3912', '#ff9900', '#109618', '#66aa00',
+                    '#dd4477', '#0099c6', '#990099'],
+                zeroColor: undefined,
+                nullColor: undefined,
+                zeroAxis: true,
+                barWidth: 4,
+                barSpacing: 1,
+                chartRangeMax: undefined,
+                chartRangeMin: undefined,
+                chartRangeClip: false,
+                colorMap: undefined,
+                tooltipFormat: new SPFormat('<span style="color: {{color}}">&#9679;</span> {{prefix}}{{value}}{{suffix}}')
+            },
+            // Defaults for timeline charts
+            timeline: {
+                width: 120,
+                height: 3,
+                lineColor: '#6792c6',
+                fillColor: '#bad7fb',
+                orientation: 'horizontal', // or 'vertical'
+                // number of minutes to modulate time markers from begin option
+                timeMarkInterval: 0,
+                // minimum date/time to show in timeline
+                begin: new Date(2000, 1, 1, 0, 0),
+                // maximum date/time to show in timeline
+                finish: new Date(2000, 1, 1, 23, 59),
+                // allow user to provide their own date parsing abilities
+                // data must provide begin, finish, title and color hash object
+                init: function (data) { return {begin: new Date(data.begin), finish: new Date(data.finish), title: data.title, color: data.color}; },
+                tooltipFormat: new SPFormat('<span style="color: {{color}}">&#9679;</span> {{title}}: {{begin}} / {{finish}}')
+            },
+            // Defaults for tristate charts
+            tristate: {
+                barWidth: 4,
+                barSpacing: 1,
+                posBarColor: '#6f6',
+                negBarColor: '#f44',
+                zeroBarColor: '#999',
+                colorMap: {},
+                tooltipFormat: new SPFormat('<span style="color: {{color}}">&#9679;</span> {{prefix}}{{value:map}}{{suffix}}'),
+                tooltipValueLookups: { map: { '-1': 'Loss', '0': 'Draw', '1': 'Win' } }
+            },
+            // Defaults for discrete charts
+            discrete: {
+                lineHeight: 'auto',
+                thresholdColor: undefined,
+                thresholdValue: 0,
+                chartRangeMax: undefined,
+                chartRangeMin: undefined,
+                chartRangeClip: false,
+                tooltipFormat: new SPFormat('{{prefix}}{{value}}{{suffix}}')
+            },
+            // Defaults for bullet charts
+            bullet: {
+                targetColor: '#f33',
+                targetWidth: 3, // width of the target bar in pixels
+                performanceColor: '#33f',
+                rangeColors: ['#d3dafe', '#a8b6ff', '#7f94ff'],
+                base: undefined, // set this to a number to change the base start number
+                tooltipFormat: new SPFormat('{{fieldkey:fields}} - {{value}}'),
+                tooltipValueLookups: { fields: {r: 'Range', p: 'Performance', t: 'Target'} }
+            },
+            // Defaults for pie charts
+            pie: {
+                offset: 0,
+                sliceColors: ['#3366cc', '#dc3912', '#ff9900', '#109618', '#66aa00',
+                    '#dd4477', '#0099c6', '#990099'],
+                borderWidth: 0,
+                borderColor: '#000',
+                tooltipFormat: new SPFormat('<span style="color: {{color}}">&#9679;</span> {{prefix}}{{value}} ({{percent.1}}%){{suffix}}')
+            },
+            // Defaults for stack charts
+            stack: {
+                offset: 0,
+                sliceColors: ['#3366cc', '#dc3912', '#ff9900', '#109618', '#66aa00',
+                    '#dd4477', '#0099c6', '#990099'],
+                borderWidth: 0,
+                borderColor: '#000',
+                tooltipFormat: new SPFormat('<span style="color: {{color}}">&#9679;</span> {{value}} ({{percent.1}}%)')
+            },
+            // Defaults for box plots
+            box: {
+                raw: false,
+                boxLineColor: '#000',
+                boxFillColor: '#cdf',
+                whiskerColor: '#000',
+                outlierLineColor: '#333',
+                outlierFillColor: '#fff',
+                medianColor: '#f00',
+                showOutliers: true,
+                outlierIQR: 1.5,
+                spotRadius: 1.5,
+                target: undefined,
+                targetColor: '#4a2',
+                chartRangeMax: undefined,
+                chartRangeMin: undefined,
+                tooltipFormat: new SPFormat('{{field:fields}}: {{value}}'),
+                tooltipFormatFieldlistKey: 'field',
+                tooltipValueLookups: { fields: { lq: 'Lower Quartile', med: 'Median',
+                    uq: 'Upper Quartile', lo: 'Left Outlier', ro: 'Right Outlier',
+                    lw: 'Left Whisker', rw: 'Right Whisker'} }
+            }
+        };
+    };
+
+    // Bootstrap adds box-sizing that messes with alignment in the tooltip.
+    var box_sizing = '-webkit-box-sizing: content-box !important;' +
+          '-moz-box-sizing: content-box !important;' +
+          'box-sizing: content-box !important;';
+
+    // You can have tooltips use a css class other than jqstooltip by specifying tooltipClassname
+    defaultStyles = '.jqstooltip { ' +
+            'position: absolute;' +
+            'left: 0px;' +
+            'top: 0px;' +
+            'visibility: hidden;' +
+            'background: rgb(0, 0, 0) transparent;' +
+            'background-color: rgba(0,0,0,0.6);' +
+            'filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#99000000, endColorstr=#99000000);' +
+            '-ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#99000000, endColorstr=#99000000)";' +
+            'color: white;' +
+            'font: 10px arial, san serif;' +
+            'text-align: left;' +
+            'white-space: nowrap;' +
+            'padding: 5px;' +
+            'border: 1px solid white;' +
+            'z-index: 10000;' +
+            box_sizing +
+            '}' +
+            '.jqsfield { ' +
+            'color: white;' +
+            'font: 10px arial, san serif;' +
+            'text-align: left;' +
+            '}' +
+            '.jqstooltip:before, .jqstooltip:after { ' +
+            box_sizing +
+            '}';
+
+    /**
+     * Utilities
+     */
+
+    createClass = function (/* [baseclass, [mixin, ...]], definition */) {
+        var Class, args;
+        Class = function () {
+            this.init.apply(this, arguments);
+        };
+        if (arguments.length > 1) {
+            if (arguments[0]) {
+                Class.prototype = $.extend(new arguments[0](), arguments[arguments.length - 1]);
+                Class._super = arguments[0].prototype;
+            } else {
+                Class.prototype = arguments[arguments.length - 1];
+            }
+            if (arguments.length > 2) {
+                args = Array.prototype.slice.call(arguments, 1, -1);
+                args.unshift(Class.prototype);
+                $.extend.apply($, args);
+            }
+        } else {
+            Class.prototype = arguments[0];
+        }
+        Class.prototype.cls = Class;
+        return Class;
+    };
+
+    /**
+     * Wraps a format string for tooltips
+     * {{x}}
+     * {{x.2}
+     * {{x:months}}
+     */
+    $.SPFormatClass = SPFormat = createClass({
+        fre: /\{\{([\w.]+?)(:(.+?))?\}\}/g,
+        precre: /(\w+)\.(\d+)/,
+
+        init: function (format, fclass) {
+            this.format = format;
+            this.fclass = fclass;
+        },
+
+        render: function (fieldset, lookups, options) {
+            var self = this,
+                fields = fieldset,
+                match, token, lookupkey, fieldvalue, prec;
+
+            return this.format.replace(this.fre, function () {
+                var lookup;
+                token = arguments[1];
+                lookupkey = arguments[3];
+                match = self.precre.exec(token);
+                if (match) {
+                    prec = match[2];
+                    token = match[1];
+                } else {
+                    prec = false;
+                }
+                fieldvalue = fields[token];
+                if (fieldvalue === undefined) {
+                    return '';
+                }
+                if (lookupkey && lookups && lookups[lookupkey]) {
+                    lookup = lookups[lookupkey];
+                    if (lookup.get) { // RangeMap
+                        return lookups[lookupkey].get(fieldvalue) || fieldvalue;
+                    } else {
+                        return lookups[lookupkey][fieldvalue] || fieldvalue;
+                    }
+                }
+                if (isNumber(fieldvalue)) {
+                    if (options.get('numberFormatter')) {
+                        fieldvalue = options.get('numberFormatter')(fieldvalue);
+                    } else {
+                        fieldvalue = formatNumber(fieldvalue, prec,
+                            options.get('numberDigitGroupCount'),
+                            options.get('numberDigitGroupSep'),
+                            options.get('numberDecimalMark'));
+                    }
+                }
+                return fieldvalue;
+            });
+        }
+    });
+
+    // convenience method to avoid needing the new operator
+    $.spformat = function (format, fclass) {
+        return new SPFormat(format, fclass);
+    };
+
+    clipval = function (val, min, max) {
+        if (val < min) {
+            return min;
+        }
+        if (val > max) {
+            return max;
+        }
+        return val;
+    };
+
+    // CUSTOM MOD: completely new median function
+    median = function (values) {
+        var ret, idx;
+        if (0 === values.length % 2) {
+            var v1, v2;
+            idx = values.length / 2;
+            v1 = values[idx - 1];
+            v2 = values[idx];
+            ret = (v1 + v2) / 2;
+        }
+        else {
+            idx = parseInt(values.length / 2);
+            ret = values[idx];
+        }
+
+        return { 
+            m: ret, 
+            idx: idx 
+        };
+    };
+
+    // CUSTOM MOD: completely rewritten quartile function
+    quartile = function (values, q) {
+        var ret, m, med;
+        m = median(values);
+
+        if (q === 2) {
+            ret = m.m;
+        }
+        else {
+            var arr = [];
+            med = m.m;
+
+            if (med != null) {                                                              // jshint ignore:line
+                var i = 0;
+                if (q === 1) {
+                    while (i < m.idx) {
+                      arr[i] = values[i];
+                      i++;
+                    }
+                    if (!arr.length)
+                      arr = [ values[0] ];
+                }
+                else if (q === 3) {
+                    var j = values.length - 1;
+                    while (j > m.idx) {
+                        arr[i] = values[j];
+                        i++;
+                        j--;
+                    }
+                    if (!arr.length)
+                      arr = [ values[values.length - 1] ];
+                }
+            }
+            m = median(arr);
+            ret = m.m;
+        }
+        return ret;
+    };
+
+    normalizeValue = function (val) {
+        var nf;
+        switch (val) {
+        case 'undefined':
+            val = undefined;
+            break;
+        case 'null':
+            val = null;
+            break;
+        case 'true':
+            val = true;
+            break;
+        case 'false':
+            val = false;
+            break;
+        default:
+            nf = parseFloat(val);
+            if (val == nf) {
+                val = nf;
+            }
+        }
+        return val;
+    };
+
+    normalizeValues = function (vals) {
+        var i, result = [];
+        for (i = vals.length; i--;) {
+            result[i] = normalizeValue(vals[i]);
+        }
+        return result;
+    };
+
+    remove = function (vals, filter) {
+        var i, vl, result = [];
+        for (i = 0, vl = vals.length; i < vl; i++) {
+            if (vals[i] !== filter) {
+                result.push(vals[i]);
+            }
+        }
+        return result;
+    };
+
+    isNumber = function (num) {
+        return !isNaN(parseFloat(num)) && isFinite(num);
+    };
+
+    formatNumber = function (num, prec, groupsize, groupsep, decsep) {
+        var p, i;
+        num = (prec === false ? parseFloat(num).toString() : num.toFixed(prec)).split('');
+        p = (p = $.inArray('.', num)) < 0 ? num.length : p;
+        if (p < num.length) {
+            num[p] = decsep;
+        }
+        for (i = p - groupsize; i > 0; i -= groupsize) {
+            num.splice(i, 0, groupsep);
+        }
+        return num.join('');
+    };
+
+    // determine if all values of an array match a value
+    // returns true if the array is empty
+    all = function (val, arr, ignoreNull) {
+        var i;
+        for (i = arr.length; i--; ) {
+            if (ignoreNull && arr[i] === null) continue;
+            if (arr[i] !== val) {
+                return false;
+            }
+        }
+        return true;
+    };
+
+    // sums the numeric values in an array, ignoring other values
+    sum = function (vals) {
+        var total = 0, i;
+        for (i = vals.length; i--;) {
+            total += typeof vals[i] === 'number' ? vals[i] : 0;
+        }
+        return total;
+    };
+
+    ensureArray = function (val) {
+        return $.isArray(val) ? val : [val];
+    };
+
+    // http://paulirish.com/2008/bookmarklet-inject-new-css-rules/
+    addCSS = function (css) {
+        var tag, iefail;
+        if (document.createStyleSheet) {
+            try {
+                document.createStyleSheet().cssText = css;
+                return;
+            } catch (e) {
+                // IE <= 9 maxes out at 31 stylesheets; inject into page instead.
+                iefail = true;
+            }
+        }
+        tag = document.createElement('style');
+        tag.type = 'text/css';
+        document.getElementsByTagName('head')[0].appendChild(tag);
+        if (iefail) {
+            document.styleSheets[document.styleSheets.length - 1].cssText = css;
+        } else {
+            tag[(typeof document.body.style.WebkitAppearance == 'string') /* webkit only */ ? 'innerText' : 'innerHTML'] = css;
+        }
+    };
+
+
+    // Provide a cross-browser interface to a few simple drawing primitives
+    $.fn.simpledraw = function (width, height, useExisting, interact) {
+        var target, mhandler;
+        if (useExisting && (target = this.data('_jqs_vcanvas'))) {
+            return target;
+        }
+
+        if ($.fn.sparkline.canvas === false) {
+            // We've already determined that neither Canvas nor VML are available
+            return false;
+        } else if ($.fn.sparkline.canvas === undefined) {
+            // No function defined yet -- need to see if we support Canvas or VML
+            var el = document.createElement('canvas');
+            if (!!(el.getContext && el.getContext('2d'))) {
+                // Canvas is available
+                $.fn.sparkline.canvas = function(width, height, target, interact) {
+                    return new VCanvas_canvas(width, height, target, interact);
+                };
+            } else if (document.namespaces && !document.namespaces.v) {
+                // VML is available
+                document.namespaces.add('v', 'urn:schemas-microsoft-com:vml', '#default#VML');
+                $.fn.sparkline.canvas = function(width, height, target, interact) {
+                    return new VCanvas_vml(width, height, target);
+                };
+            } else {
+                // Neither Canvas nor VML are available
+                $.fn.sparkline.canvas = false;
+                return false;
+            }
+        }
+
+        if (width === undefined) {
+            width = $(this).innerWidth();
+        }
+        if (height === undefined) {
+            height = $(this).innerHeight();
+        }
+
+        target = $.fn.sparkline.canvas(width, height, this, interact);
+
+        mhandler = $(this).data('_jqs_mhandler');
+        if (mhandler) {
+            mhandler.registerCanvas(target);
+        }
+        return target;
+    };
+
+    $.fn.cleardraw = function () {
+        var target = this.data('_jqs_vcanvas');
+        if (target) {
+            target.reset();
+        }
+    };
+
+
+    $.RangeMapClass = RangeMap = createClass({
+        init: function (map) {
+            var key, range, rangelist = [];
+            for (key in map) {
+                if (map.hasOwnProperty(key) && typeof key === 'string' && key.indexOf(':') > -1) {
+                    range = key.split(':');
+                    range[0] = range[0].length === 0 ? -Infinity : parseFloat(range[0]);
+                    range[1] = range[1].length === 0 ? Infinity : parseFloat(range[1]);
+                    range[2] = map[key];
+                    rangelist.push(range);
+                }
+            }
+            this.map = map;
+            this.rangelist = rangelist || false;
+        },
+
+        get: function (value) {
+            var rangelist = this.rangelist,
+                i, range, result;
+            if ((result = this.map[value]) !== undefined) {
+                return result;
+            }
+            if (rangelist) {
+                for (i = rangelist.length; i--;) {
+                    range = rangelist[i];
+                    if (range[0] <= value && range[1] >= value) {
+                        return range[2];
+                    }
+                }
+            }
+            return undefined;
+        }
+    });
+
+    // Convenience function
+    $.range_map = function(map) {
+        return new RangeMap(map);
+    };
+
+
+    MouseHandler = createClass({
+        init: function (el, options) {
+            var $el = $(el);
+            this.$el = $el;
+            this.options = options;
+            this.currentPageX = 0;
+            this.currentPageY = 0;
+            this.el = el;
+            this.splist = [];
+            this.tooltip = null;
+            this.over = false;
+            this.displayTooltips = !options.get('disableTooltips');
+            this.highlightEnabled = !options.get('disableHighlight');
+        },
+
+        registerSparkline: function (sp) {
+            this.splist.push(sp);
+            if (this.over) {
+                this.updateDisplay();
+            }
+        },
+
+        registerCanvas: function (canvas) {
+            var $canvas = $(canvas.canvas);
+            this.canvas = canvas;
+            this.$canvas = $canvas;
+            $canvas.mouseenter($.proxy(this.mouseenter, this));
+            $canvas.mouseleave($.proxy(this.mouseleave, this));
+            $canvas.click($.proxy(this.mouseclick, this));
+        },
+
+        reset: function (removeTooltip) {
+            this.splist = [];
+            if (this.tooltip && removeTooltip) {
+                this.tooltip.remove();
+                this.tooltip = undefined;
+            }
+        },
+
+        mouseclick: function (e) {
+            var clickEvent = $.Event('sparklineClick');
+            clickEvent.originalEvent = e;
+            clickEvent.sparklines = this.splist;
+            this.$el.trigger(clickEvent);
+        },
+
+        mouseenter: function (e) {
+            $(document.body).unbind('mousemove.jqs');
+            $(document.body).bind('mousemove.jqs', $.proxy(this.mousemove, this));
+            this.over = true;
+            this.currentPageX = e.pageX;
+            this.currentPageY = e.pageY;
+            this.currentEl = e.target;
+            if (!this.tooltip && this.displayTooltips) {
+                this.tooltip = new Tooltip(this.options);
+                this.tooltip.updatePosition(e.pageX, e.pageY);
+            }
+            this.updateDisplay();
+        },
+
+        mouseleave: function () {
+            $(document.body).unbind('mousemove.jqs');
+            var splist = this.splist,
+                 spcount = splist.length,
+                 needsRefresh = false,
+                 sp, i;
+            this.over = false;
+            this.currentEl = null;
+
+            if (this.tooltip) {
+                this.tooltip.remove();
+                this.tooltip = null;
+            }
+
+            for (i = 0; i < spcount; i++) {
+                sp = splist[i];
+                if (sp.clearRegionHighlight()) {
+                    needsRefresh = true;
+                }
+            }
+
+            if (needsRefresh) {
+                this.canvas.render();
+            }
+        },
+
+        mousemove: function (e) {
+            this.currentPageX = e.pageX;
+            this.currentPageY = e.pageY;
+            this.currentEl = e.target;
+            if (this.tooltip) {
+                this.tooltip.updatePosition(e.pageX, e.pageY);
+            }
+            this.updateDisplay();
+        },
+
+        updateDisplay: function () {
+            var splist = this.splist,
+                 spcount = splist.length,
+                 needsRefresh = false,
+                 offset = this.$canvas.offset(),
+                 localX = Math.round(this.currentPageX - offset.left),
+                 localY = Math.round(this.currentPageY - offset.top),
+                 tooltiphtml, sp, i, result, changeEvent;
+            // localX/localY fix issue #50 with Google Chrome
+            // and subpixel rendering
+
+            if (!this.over) {
+                return;
+            }
+            for (i = 0; i < spcount; i++) {
+                sp = splist[i];
+                result = sp.setRegionHighlight(this.currentEl, localX, localY);
+                if (result) {
+                    needsRefresh = true;
+                }
+            }
+            if (needsRefresh) {
+                changeEvent = $.Event('sparklineRegionChange');
+                changeEvent.sparklines = this.splist;
+                this.$el.trigger(changeEvent);
+                if (this.tooltip) {
+                    tooltiphtml = '';
+                    for (i = 0; i < spcount; i++) {
+                        sp = splist[i];
+                        tooltiphtml += sp.getCurrentRegionTooltip();
+                    }
+                    this.tooltip.setContent(tooltiphtml);
+                }
+                if (!this.disableHighlight) {
+                    this.canvas.render();
+                }
+            }
+            if (result === null) {
+                this.mouseleave();
+            }
+        }
+    });
+
+
+    Tooltip = createClass({
+        sizeStyle: 'position: static !important;' +
+            'display: block !important;' +
+            'visibility: hidden !important;' +
+            'float: left !important;',
+
+        init: function (options) {
+            var tooltipClassname = options.get('tooltipClassname', 'jqstooltip'),
+                sizetipStyle = this.sizeStyle,
+                offset;
+            this.container = options.get('tooltipContainer') || document.body;
+            this.tooltipOffsetX = options.get('tooltipOffsetX', 10);
+            this.tooltipOffsetY = options.get('tooltipOffsetY', 12);
+            this.displayOnLeft  = options.get('toolTipPosition') === 'left';
+            // remove any previous lingering tooltip
+            $('#jqssizetip').remove();
+            $('#jqstooltip').remove();
+            this.sizetip = $('<div/>', {
+                id: 'jqssizetip',
+                style: sizetipStyle,
+                'class': tooltipClassname
+            });
+            this.tooltip = $('<div/>', {
+                id: 'jqstooltip',
+                'class': tooltipClassname
+            }).appendTo(this.container);
+            // account for the container's location
+            offset = this.tooltip.offset();
+            this.offsetLeft = offset.left;
+            this.offsetTop = offset.top;
+            this.hidden = true;
+            $(window).unbind('resize.jqs scroll.jqs');
+            $(window).bind('resize.jqs scroll.jqs', $.proxy(this.updateWindowDims, this));
+            this.updateWindowDims();
+        },
+
+        updateWindowDims: function () {
+            this.scrollTop = $(window).scrollTop();
+            this.scrollLeft = $(window).scrollLeft();
+            this.scrollRight = this.scrollLeft + $(window).width();
+            this.updatePosition();
+        },
+
+        getSize: function (content) {
+            this.sizetip.html(content).appendTo(this.container);
+            var lpadding = parseInt(this.sizetip.css('padding-left'), 10);
+            var rpadding = parseInt(this.sizetip.css('padding-right'), 10);
+            this.padding = lpadding + rpadding + 1;
+            this.width = this.sizetip.width() + 1;
+            this.height = this.sizetip.height();
+            this.sizetip.remove();
+        },
+
+        setContent: function (content) {
+            if (!content) {
+                this.tooltip.css('visibility', 'hidden');
+                this.hidden = true;
+                return;
+            }
+            this.getSize(content);
+            this.tooltip.html(content)
+                .css({
+                    'width': this.width,
+                    'height': this.height,
+                    'visibility': 'visible'
+                });
+            if (this.hidden) {
+                this.hidden = false;
+                this.updatePosition();
+            }
+        },
+
+        updatePosition: function (x, y) {
+            if (x === undefined) {
+                if (this.mousex === undefined) {
+                    return;
+                }
+                x = this.mousex - this.offsetLeft;
+                y = this.mousey - this.offsetTop;
+
+            } else {
+                this.mousex = x = x - this.offsetLeft;
+                this.mousey = y = y - this.offsetTop;
+            }
+            if (!this.height || !this.width || this.hidden) {
+                return;
+            }
+
+            y -= this.height + this.tooltipOffsetY;
+            if (y < this.scrollTop) {
+                y = this.scrollTop;
+            }
+
+            if (this.displayOnLeft) {
+                x -= this.tooltipOffsetX + this.width + this.padding;
+            } else {
+                x += this.tooltipOffsetX;
+            }
+            if (x < this.scrollLeft) {
+                x = this.scrollLeft;
+            } else if (x + this.width > this.scrollRight) {
+                x = this.scrollRight - this.width;
+            }
+
+            this.tooltip.css({
+                'left': x,
+                'top': y
+            });
+        },
+
+        remove: function () {
+            this.tooltip.remove();
+            this.sizetip.remove();
+            this.sizetip = this.tooltip = undefined;
+            $(window).unbind('resize.jqs scroll.jqs');
+        }
+    });
+
+
+    initStyles = function() {
+        addCSS(defaultStyles);
+    };
+
+    $(initStyles);
+
+    pending = [];
+    $.fn.sparkline = function (userValues, userOptions) {
+        return this.each(function () {
+            var options = new $.fn.sparkline.options(this, userOptions),
+                 $this = $(this),
+                 render, i;
+            render = function () {
+                var values, width, height, tmp, mhandler, sp, vals;
+                if (userValues === 'html' || userValues === undefined) {
+                    vals = this.getAttribute(options.get('tagValuesAttribute'));
+                    if (vals === undefined || vals === null) {
+                        vals = $this.html();
+                    }
+                    values = vals.replace(/(^\s*<!--)|(-->\s*$)|\s+/g, '').split(',');
+                } else {
+                    values = userValues;
+                }
+
+                width = options.get('width') === 'auto' ? values.length * options.get('defaultPixelsPerValue') : options.get('width');
+                if (options.get('height') === 'auto') {
+                    if (!options.get('composite') || !$.data(this, '_jqs_vcanvas')) {
+                        // must be a better way to get the line height
+                        tmp = document.createElement('span');
+                        tmp.innerHTML = 'a';
+                        $this.html(tmp);
+                        height = $(tmp).innerHeight() || $(tmp).height();
+                        $(tmp).remove();
+                        tmp = null;
+                    }
+                } else {
+                    height = options.get('height');
+                }
+
+                if (!options.get('disableInteraction')) {
+                    mhandler = $.data(this, '_jqs_mhandler');
+                    if (!mhandler) {
+                        mhandler = new MouseHandler(this, options);
+                        $.data(this, '_jqs_mhandler', mhandler);
+                    } else if (!options.get('composite')) {
+                        mhandler.reset();
+                    }
+                } else {
+                    mhandler = false;
+                }
+
+                if (options.get('composite') && !$.data(this, '_jqs_vcanvas')) {
+                    if (!$.data(this, '_jqs_errnotify')) {
+                        alert('Attempted to attach a composite sparkline to an element with no existing sparkline');
+                        $.data(this, '_jqs_errnotify', true);
+                    }
+                    return;
+                }
+
+                sp = new $.fn.sparkline[options.get('type')](this, values, options, width, height);
+
+                sp.render();
+
+                if (mhandler) {
+                    mhandler.registerSparkline(sp);
+                }
+            };
+            if (($(this).html() && !options.get('disableHiddenCheck') && $(this).is(':hidden')) || !$(this).parents('body').length) {
+                if (!options.get('composite') && $.data(this, '_jqs_pending')) {
+                    // remove any existing references to the element
+                    for (i = pending.length; i; i--) {
+                        if (pending[i - 1][0] == this) {
+                            pending.splice(i - 1, 1);
+                        }
+                    }
+                }
+                pending.push([this, render]);
+                $.data(this, '_jqs_pending', true);
+            } else {
+                render.call(this);
+            }
+        });
+    };
+
+    $.fn.sparkline.defaults = getDefaults();
+
+
+    $.sparkline_display_visible = function () {
+        var el, i, pl;
+        var done = [];
+        for (i = 0, pl = pending.length; i < pl; i++) {
+            el = pending[i][0];
+            if ($(el).is(':visible') && !$(el).parents().is(':hidden')) {
+                pending[i][1].call(el);
+                $.data(pending[i][0], '_jqs_pending', false);
+                done.push(i);
+            } else if (!$(el).closest('html').length && !$.data(el, '_jqs_pending')) {
+                // element has been inserted and removed from the DOM
+                // If it was not yet inserted into the dom then the .data request
+                // will return true.
+                // removing from the dom causes the data to be removed.
+                $.data(pending[i][0], '_jqs_pending', false);
+                done.push(i);
+            }
+        }
+        for (i = done.length; i; i--) {
+            pending.splice(done[i - 1], 1);
+        }
+    };
+
+
+    /**
+     * User option handler
+     */
+    $.fn.sparkline.options = createClass({
+        init: function (tag, userOptions) {
+            var extendedOptions, defaults, base, tagOptionType;
+            this.userOptions = userOptions = userOptions || {};
+            this.tag = tag;
+            this.tagValCache = {};
+            defaults = $.fn.sparkline.defaults;
+            base = defaults.common;
+            this.tagOptionsPrefix = userOptions.enableTagOptions && (userOptions.tagOptionsPrefix || base.tagOptionsPrefix);
+
+            tagOptionType = this.getTagSetting('type');
+            if (tagOptionType === UNSET_OPTION) {
+                extendedOptions = defaults[userOptions.type || base.type];
+            } else {
+                extendedOptions = defaults[tagOptionType];
+            }
+            this.mergedOptions = $.extend({}, base, extendedOptions, userOptions);
+        },
+
+
+        getTagSetting: function (key) {
+            var prefix = this.tagOptionsPrefix,
+                val, i, pairs, keyval;
+            if (prefix === false || prefix === undefined) {
+                return UNSET_OPTION;
+            }
+            if (this.tagValCache.hasOwnProperty(key)) {
+                val = this.tagValCache.key;
+            } else {
+                val = this.tag.getAttribute(prefix + key);
+                if (val === undefined || val === null) {
+                    val = UNSET_OPTION;
+                } else if (val.substr(0, 1) === '[') {
+                    val = val.substr(1, val.length - 2).split(',');
+                    for (i = val.length; i--;) {
+                        val[i] = normalizeValue(val[i].replace(/(^\s*)|(\s*$)/g, ''));
+                    }
+                } else if (val.substr(0, 1) === '{') {
+                    pairs = val.substr(1, val.length - 2).split(',');
+                    val = {};
+                    for (i = pairs.length; i--;) {
+                        keyval = pairs[i].split(':', 2);
+                        val[keyval[0].replace(/(^\s*)|(\s*$)/g, '')] = normalizeValue(keyval[1].replace(/(^\s*)|(\s*$)/g, ''));
+                    }
+                } else {
+                    val = normalizeValue(val);
+                }
+                this.tagValCache.key = val;
+            }
+            return val;
+        },
+
+        get: function (key, defaultval) {
+            var tagOption = this.getTagSetting(key),
+                result;
+            if (tagOption !== UNSET_OPTION) {
+                return tagOption;
+            }
+            return (result = this.mergedOptions[key]) === undefined ? defaultval : result;
+        }
+    });
+
+
+    $.fn.sparkline._base = createClass({
+        disabled: false,
+
+        init: function (el, values, options, width, height) {
+            this.el = el;
+            this.$el = $(el);
+            this.values = values;
+            this.options = options;
+            this.width = width;
+            this.height = height;
+            this.currentRegion = undefined;
+        },
+
+        /**
+         * Setup the canvas
+         */
+        initTarget: function () {
+            var interactive = !this.options.get('disableInteraction');
+            if (!(this.target = this.$el.simpledraw(this.width, this.height, this.options.get('composite'), interactive))) {
+                this.disabled = true;
+            } else {
+                this.canvasWidth = this.target.pixelWidth;
+                this.canvasHeight = this.target.pixelHeight;
+            }
+        },
+
+        /**
+         * Setup colorMap from options
+         */
+        initColorMap: function() {
+            var colorMap = this.options.get('colorMap');
+            if ($.isFunction(colorMap)) {
+                this.colorMapFunction = colorMap;
+            } else if ($.isArray(colorMap)) {
+                this.colorMapFunction = function(sparkline, options, index, value) {
+                    if (index < colorMap.length) {
+                        return colorMap[index];
+                    }
+                    // else undefined
+                };
+            } else if (colorMap) {
+                if (colorMap.get === undefined) {
+                    colorMap = new RangeMap(colorMap); 
+                }
+                this.colorMapFunction = function(sparkline, options, index, value) {
+                    return colorMap.get(value);
+                };
+            }
+        },
+
+        /**
+         * Actually render the chart to the canvas
+         */
+        render: function () {
+            if (this.disabled) {
+                this.el.innerHTML = '';
+                return false;
+            }
+            return true;
+        },
+
+        /**
+         * Return a region id for a given x/y co-ordinate
+         */
+        getRegion: function (x, y) {
+        },
+
+        /**
+         * Highlight an item based on the moused-over x,y co-ordinate
+         */
+        setRegionHighlight: function (el, x, y) {
+            var currentRegion = this.currentRegion,
+                highlightEnabled = !this.options.get('disableHighlight'),
+                newRegion;
+            // CUSTOM MOD: proper hover detection considering padding as well
+            var cW = $('canvas',this.el).width() + parseInt($('canvas',this.el).css('padding-left')) + parseInt($('canvas',this.el).css('padding-right'))
+            // if (x > this.canvasWidth || y > this.canvasHeight || x < 0 || y < 0) {
+            if (x > cW || y > this.canvasHeight || x < 0 || y < 0) {
+                return null;
+            }
+            newRegion = this.getRegion(el, x, y);
+            if (currentRegion !== newRegion) {
+                if (currentRegion !== undefined && highlightEnabled) {
+                    this.removeHighlight();
+                }
+                this.currentRegion = newRegion;
+                if (newRegion !== undefined && highlightEnabled) {
+                    this.renderHighlight();
+                }
+                return true;
+            }
+            return false;
+        },
+
+        /**
+         * Reset any currently highlighted item
+         */
+        clearRegionHighlight: function () {
+            if (this.currentRegion !== undefined) {
+                this.removeHighlight();
+                this.currentRegion = undefined;
+                return true;
+            }
+            return false;
+        },
+
+        renderHighlight: function () {
+            this.changeHighlight(true);
+        },
+
+        removeHighlight: function () {
+            this.changeHighlight(false);
+        },
+
+        changeHighlight: function (highlight)  {},
+
+        /**
+         * Fetch the HTML to display as a tooltip
+         */
+        getCurrentRegionTooltip: function () {
+            var options = this.options,
+                header = '',
+                entries = [],
+                fields, formats, formatlen, fclass, text, i,
+                showFields, showFieldsKey, newFields, fv,
+                formatter, format, fieldlen, j,
+                label_prefix, label_suffix;
+            if (this.currentRegion === undefined) {
+                return '';
+            }
+            fields = this.getCurrentRegionFields();
+            formatter = options.get('tooltipFormatter');
+            if (formatter) {
+                return formatter(this, options, fields);
+            }
+            if (options.get('tooltipChartTitle')) {
+                header += '<div class="jqs jqstitle">' + options.get('tooltipChartTitle') + '</div>\n';
+            }
+            formats = this.options.get('tooltipFormat');
+            if (!formats) {
+                return '';
+            }
+            if (!$.isArray(formats)) {
+                formats = [formats];
+            }
+            if (!$.isArray(fields)) {
+                fields = [fields];
+            }
+            showFields = this.options.get('tooltipFormatFieldlist');
+            showFieldsKey = this.options.get('tooltipFormatFieldlistKey');
+            if (showFields && showFieldsKey) {
+                // user-selected ordering of fields
+                newFields = [];
+                for (i = fields.length; i--;) {
+                    fv = fields[i][showFieldsKey];
+                    if ((j = $.inArray(fv, showFields)) != -1) {
+                        newFields[j] = fields[i];
+                    }
+                }
+                fields = newFields;
+            }
+            formatlen = formats.length;
+            fieldlen = fields.length;
+            for (i = 0; i < formatlen; i++) {
+                format = formats[i];
+                if (typeof format === 'string') {
+                    format = new SPFormat(format);
+                }
+                fclass = format.fclass || 'jqsfield';
+
+                for (j = 0; j < fieldlen; j++) {
+                    if (!fields[j].isNull || !options.get('tooltipSkipNull')) {
+                        label_prefix = '';
+                        label_suffix = '';
+                        if (options.get('tooltipPrefixBinLabels')
+                            && (options.get('tooltipPrefixBinLabels').length > fields[j].offset)) {
+                            label_prefix = options.get('tooltipPrefixBinLabels')[fields[j].offset];
+                        }
+                        if (options.get('tooltipSuffixBinLabels')
+                            && (options.get('tooltipSuffixBinLabels').length > fields[j].offset)) {
+                            label_suffix = options.get('tooltipSuffixBinLabels')[fields[j].offset];
+                        }
+                        $.extend(fields[j], {
+                            prefix: label_prefix + options.get('tooltipPrefix'),
+                            suffix: options.get('tooltipSuffix') + label_suffix
+                        });
+
+                        text = format.render(fields[j], options.get('tooltipValueLookups'), options);
+                        entries.push('<div class="' + fclass + '">' + text + '</div>');
+                    }
+                }
+            }
+            if (entries.length) {
+                return header + entries.join('\n');
+            }
+            return '';
+        },
+
+        getCurrentRegionFields: function () {},
+
+        calcHighlightColor: function (color, options) {
+            var highlightColor = options.get('highlightColor'),
+                lighten = options.get('highlightLighten'),
+                parse, mult, rgbnew, i;
+            if (highlightColor) {
+                return highlightColor;
+            }
+            if (lighten) {
+                // extract RGB values
+                parse = /^#([0-9a-f])([0-9a-f])([0-9a-f])$/i.exec(color) || /^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i.exec(color);
+                if (parse) {
+                    rgbnew = [];
+                    mult = color.length === 4 ? 16 : 1;
+                    for (i = 0; i < 3; i++) {
+                        rgbnew[i] = clipval(Math.round(parseInt(parse[i + 1], 16) * mult * lighten), 0, 255);
+                    }
+                    return 'rgb(' + rgbnew.join(',') + ')';
+                }
+
+            }
+            return color;
+        }
+
+    });
+
+    barHighlightMixin = {
+        changeHighlight: function (highlight) {
+            var currentRegion = this.currentRegion,
+                target = this.target,
+                shapeids = this.regionShapes[currentRegion],
+                newShapes;
+            // will be null if the region value was null
+            if (shapeids >= 0) {
+                newShapes = this.renderRegion(currentRegion, highlight);
+                if ($.isArray(newShapes) || $.isArray(shapeids)) {
+                    target.replaceWithShapes(shapeids, newShapes);
+                    this.regionShapes[currentRegion] = $.map(newShapes, function (newShape) {
+                        return newShape.id;
+                    });
+                } else {
+                    target.replaceWithShape(shapeids, newShapes);
+                    this.regionShapes[currentRegion] = newShapes.id;
+                }
+            }
+        },
+
+        render: function () {
+            var values = this.values,
+                target = this.target,
+                regionShapes = this.regionShapes,
+                shapes, ids, i, j;
+
+            if (!this.cls._super.render.call(this)) {
+                return;
+            }
+            for (i = values.length; i--;) {
+                shapes = this.renderRegion(i);
+                if (shapes) {
+                    if ($.isArray(shapes)) {
+                        ids = [];
+                        for (j = shapes.length; j--;) {
+                            shapes[j].append();
+                            ids.push(shapes[j].id);
+                        }
+                        regionShapes[i] = ids;
+                    } else {
+                        shapes.append();
+                        regionShapes[i] = shapes.id; // store just the shapeid
+                    }
+                } else {
+                    // null value
+                    regionShapes[i] = null;
+                }
+            }
+            target.render();
+        }
+    };
+
+
+    /**
+     * Line charts
+     */
+    $.fn.sparkline.line = line = createClass($.fn.sparkline._base, {
+        type: 'line',
+
+        init: function (el, values, options, width, height) {
+            line._super.init.call(this, el, values, options, width, height);
+            this.vertices = [];
+            this.regionMap = [];
+            this.xvalues = [];
+            this.yvalues = [];
+            this.yminmax = [];
+            this.hightlightSpotId = null;
+            this.lastShapeId = null;
+            this.initTarget();
+        },
+
+        getRegion: function (el, x, y) {
+            var i,
+                regionMap = this.regionMap; // maps regions to value positions
+            for (i = regionMap.length; i--;) {
+                if (regionMap[i] !== null && x * this.target.ratio >= regionMap[i][0] && x * this.target.ratio <= regionMap[i][1]) {
+                    return regionMap[i][2];
+                }
+            }
+            return undefined;
+        },
+
+        getCurrentRegionFields: function () {
+            var currentRegion = this.currentRegion;
+            return {
+                isNull: this.yvalues[currentRegion] === null,
+                x: this.xvalues[currentRegion],
+                y: this.yvalues[currentRegion],
+                color: this.options.get('lineColor'),
+                fillColor: this.options.get('fillColor'),
+                offset: currentRegion
+            };
+        },
+
+        renderHighlight: function () {
+            var currentRegion = this.currentRegion,
+                target = this.target,
+                vertex = this.vertices[currentRegion],
+                options = this.options,
+                spotRadius = options.get('spotRadius'),
+                highlightSpotColor = options.get('highlightSpotColor'),
+                highlightLineColor = options.get('highlightLineColor'),
+                highlightSpot, highlightLine;
+
+            if (!vertex) {
+                return;
+            }
+            if (spotRadius && highlightSpotColor) {
+                highlightSpot = target.drawCircle(vertex[0], vertex[1],
+                    spotRadius, undefined, highlightSpotColor);
+                this.highlightSpotId = highlightSpot.id;
+                target.insertAfterShape(this.lastShapeId, highlightSpot);
+            }
+            if (highlightLineColor) {
+                highlightLine = target.drawLine(vertex[0], this.canvasTop, vertex[0],
+                    this.canvasTop + this.canvasHeight, highlightLineColor);
+                this.highlightLineId = highlightLine.id;
+                target.insertAfterShape(this.lastShapeId, highlightLine);
+            }
+        },
+
+        removeHighlight: function () {
+            var target = this.target;
+            if (this.highlightSpotId) {
+                target.removeShapeId(this.highlightSpotId);
+                this.highlightSpotId = null;
+            }
+            if (this.highlightLineId) {
+                target.removeShapeId(this.highlightLineId);
+                this.highlightLineId = null;
+            }
+        },
+
+        scanValues: function () {
+            var values = this.values,
+                valcount = values.length,
+                xvalues = this.xvalues,
+                yvalues = this.yvalues,
+                yminmax = this.yminmax,
+                i, val, isStr, isArray, sp;
+            for (i = 0; i < valcount; i++) {
+                val = values[i];
+                isStr = typeof(values[i]) === 'string';
+                isArray = typeof(values[i]) === 'object' && values[i] instanceof Array;
+                sp = isStr && values[i].split(':');
+                if (isStr && sp.length === 2) { // x:y
+                    xvalues.push(Number(sp[0]));
+                    yvalues.push(Number(sp[1]));
+                    yminmax.push(Number(sp[1]));
+                } else if (isArray) {
+                    xvalues.push(val[0]);
+                    yvalues.push(val[1]);
+                    yminmax.push(val[1]);
+                } else {
+                    xvalues.push(i);
+                    if (values[i] === null || values[i] === 'null') {
+                        yvalues.push(null);
+                    } else {
+                        yvalues.push(Number(val));
+                        yminmax.push(Number(val));
+                    }
+                }
+            }
+            if (this.options.get('xvalues')) {
+                xvalues = this.options.get('xvalues');
+            }
+
+            this.maxy = this.maxyorg = Math.max.apply(Math, yminmax);
+            this.miny = this.minyorg = Math.min.apply(Math, yminmax);
+
+            this.maxx = Math.max.apply(Math, xvalues);
+            this.minx = Math.min.apply(Math, xvalues);
+
+            this.xvalues = xvalues;
+            this.yvalues = yvalues;
+            this.yminmax = yminmax;
+        },
+
+        processRangeOptions: function () {
+            var options = this.options,
+                normalRangeMin = options.get('normalRangeMin'),
+                normalRangeMax = options.get('normalRangeMax');
+
+            if (normalRangeMin !== undefined) {
+                if (normalRangeMin < this.miny) {
+                    this.miny = normalRangeMin;
+                }
+                if (normalRangeMax > this.maxy) {
+                    this.maxy = normalRangeMax;
+                }
+            }
+            if (options.get('chartRangeMin') !== undefined && (options.get('chartRangeClip') || options.get('chartRangeMin') < this.miny)) {
+                this.miny = options.get('chartRangeMin');
+            }
+            if (options.get('chartRangeMax') !== undefined && (options.get('chartRangeClip') || options.get('chartRangeMax') > this.maxy)) {
+                this.maxy = options.get('chartRangeMax');
+            }
+            if (options.get('chartRangeMinX') !== undefined && (options.get('chartRangeClipX') || options.get('chartRangeMinX') < this.minx)) {
+                this.minx = options.get('chartRangeMinX');
+            }
+            if (options.get('chartRangeMaxX') !== undefined && (options.get('chartRangeClipX') || options.get('chartRangeMaxX') > this.maxx)) {
+                this.maxx = options.get('chartRangeMaxX');
+            }
+
+        },
+
+        drawNormalRange: function (canvasLeft, canvasTop, canvasHeight, canvasWidth, rangey) {
+            var normalRangeMin = this.options.get('normalRangeMin'),
+                normalRangeMax = this.options.get('normalRangeMax'),
+                ytop = canvasTop + Math.round(canvasHeight - (canvasHeight * ((normalRangeMax - this.miny) / rangey))),
+                height = Math.round((canvasHeight * (normalRangeMax - normalRangeMin)) / rangey);
+            this.target.drawRect(canvasLeft, ytop, canvasWidth, height, undefined, this.options.get('normalRangeColor')).append();
+        },
+
+        render: function () {
+            var options = this.options,
+                target = this.target,
+                canvasWidth = this.canvasWidth,
+                canvasHeight = this.canvasHeight,
+                vertices = this.vertices,
+                spotRadius = options.get('spotRadius'),
+                regionMap = this.regionMap,
+                rangex, rangey, yvallast,
+                canvasTop, canvasLeft,
+                vertex, path, paths, x, y, xnext, xpos, xposnext,
+                last, next, yvalcount, lineShapes, fillShapes, plen,
+                valueSpots, hlSpotsEnabled, color, xvalues, yvalues, i;
+
+            if (!line._super.render.call(this)) {
+                return;
+            }
+
+            this.scanValues();
+            this.processRangeOptions();
+
+            xvalues = this.xvalues;
+            yvalues = this.yvalues;
+
+            if (!this.yminmax.length || this.yvalues.length < 2) {
+                // empty or all null valuess
+                return;
+            }
+
+            canvasTop = canvasLeft = 0;
+
+            rangex = this.maxx - this.minx === 0 ? 1 : this.maxx - this.minx;
+            rangey = this.maxy - this.miny === 0 ? 1 : this.maxy - this.miny;
+            yvallast = this.yvalues.length - 1;
+
+            if (spotRadius && (canvasWidth < (spotRadius * 4) || canvasHeight < (spotRadius * 4))) {
+                spotRadius = 0;
+            }
+            if (spotRadius) {
+                // adjust the canvas size as required so that spots will fit
+                hlSpotsEnabled = options.get('highlightSpotColor') &&  !options.get('disableInteraction');
+                if (hlSpotsEnabled || options.get('minSpotColor') || (options.get('spotColor') && yvalues[yvallast] === this.miny)) {
+                    canvasHeight -= Math.ceil(spotRadius);
+                }
+                if (hlSpotsEnabled || options.get('maxSpotColor') || (options.get('spotColor') && yvalues[yvallast] === this.maxy)) {
+                    canvasHeight -= Math.ceil(spotRadius);
+                    canvasTop += Math.ceil(spotRadius);
+                }
+                if (hlSpotsEnabled ||
+                     ((options.get('minSpotColor') || options.get('maxSpotColor')) && (yvalues[0] === this.miny || yvalues[0] === this.maxy))) {
+                    canvasLeft += Math.ceil(spotRadius);
+                    canvasWidth -= Math.ceil(spotRadius);
+                }
+                if (hlSpotsEnabled || options.get('spotColor') ||
+                    (options.get('minSpotColor') || options.get('maxSpotColor') &&
+                        (yvalues[yvallast] === this.miny || yvalues[yvallast] === this.maxy))) {
+                    canvasWidth -= Math.ceil(spotRadius);
+                }
+            }
+
+
+            canvasHeight--;
+
+            if (options.get('normalRangeMin') !== undefined && !options.get('drawNormalOnTop')) {
+                this.drawNormalRange(canvasLeft, canvasTop, canvasHeight, canvasWidth, rangey);
+            }
+
+            path = [];
+            paths = [path];
+            last = next = null;
+            yvalcount = yvalues.length;
+            for (i = 0; i < yvalcount; i++) {
+                x = xvalues[i];
+                xnext = xvalues[i + 1];
+                y = yvalues[i];
+                xpos = canvasLeft + Math.round((x - this.minx) * (canvasWidth / rangex));
+                xposnext = i < yvalcount - 1 ? canvasLeft + Math.round((xnext - this.minx) * (canvasWidth / rangex)) : canvasWidth;
+                next = xpos + ((xposnext - xpos) / 2);
+                regionMap[i] = [last || 0, next, i];
+                last = next;
+                if (y === null) {
+                    if (i) {
+                        if (yvalues[i - 1] !== null) {
+                            path = [];
+                            paths.push(path);
+                        }
+                        vertices.push(null);
+                    }
+                } else {
+                    if (y < this.miny) {
+                        y = this.miny;
+                    }
+                    if (y > this.maxy) {
+                        y = this.maxy;
+                    }
+                    if (!path.length) {
+                        // previous value was null
+                        path.push([xpos, canvasTop + canvasHeight]);
+                    }
+                    vertex = [xpos, canvasTop + Math.round(canvasHeight - (canvasHeight * ((y - this.miny) / rangey)))];
+                    path.push(vertex);
+                    vertices.push(vertex);
+                }
+            }
+
+            lineShapes = [];
+            fillShapes = [];
+            plen = paths.length;
+            for (i = 0; i < plen; i++) {
+                path = paths[i];
+                if (path.length) {
+                    if (options.get('fillColor')) {
+                        path.push([path[path.length - 1][0], (canvasTop + canvasHeight)]);
+                        fillShapes.push(path.slice(0));
+                        path.pop();
+                    }
+                    // if there's only a single point in this path, then we want to display it
+                    // as a vertical line which means we keep path[0]  as is
+                    if (path.length > 2) {
+                        // else we want the first value
+                        path[0] = [path[0][0], path[1][1]];
+                    }
+                    lineShapes.push(path);
+                }
+            }
+
+            // draw the fill first, then optionally the normal range, then the line on top of that
+            plen = fillShapes.length;
+            for (i = 0; i < plen; i++) {
+                target.drawShape(fillShapes[i],
+                    options.get('fillColor'), options.get('fillColor')).append();
+            }
+
+            if (options.get('normalRangeMin') !== undefined && options.get('drawNormalOnTop')) {
+                this.drawNormalRange(canvasLeft, canvasTop, canvasHeight, canvasWidth, rangey);
+            }
+
+            plen = lineShapes.length;
+            for (i = 0; i < plen; i++) {
+                target.drawShape(lineShapes[i], options.get('lineColor'), undefined,
+                    options.get('lineWidth')).append();
+            }
+
+            if (spotRadius && options.get('valueSpots')) {
+                valueSpots = options.get('valueSpots');
+                if (valueSpots.get === undefined) {
+                    valueSpots = new RangeMap(valueSpots);
+                }
+                for (i = 0; i < yvalcount; i++) {
+                    color = valueSpots.get(yvalues[i]);
+                    if (color) {
+                        target.drawCircle(canvasLeft + Math.round((xvalues[i] - this.minx) * (canvasWidth / rangex)),
+                            canvasTop + Math.round(canvasHeight - (canvasHeight * ((yvalues[i] - this.miny) / rangey))),
+                            spotRadius, undefined,
+                            color).append();
+                    }
+                }
+
+            }
+            if (spotRadius && options.get('spotColor') && yvalues[yvallast] !== null) {
+                target.drawCircle(canvasLeft + Math.round((xvalues[xvalues.length - 1] - this.minx) * (canvasWidth / rangex)),
+                    canvasTop + Math.round(canvasHeight - (canvasHeight * ((yvalues[yvallast] - this.miny) / rangey))),
+                    spotRadius, undefined,
+                    options.get('spotColor')).append();
+            }
+            if (this.maxy !== this.minyorg) {
+                if (spotRadius && options.get('minSpotColor')) {
+                    x = xvalues[$.inArray(this.minyorg, yvalues)];
+                    target.drawCircle(canvasLeft + Math.round((x - this.minx) * (canvasWidth / rangex)),
+                        canvasTop + Math.round(canvasHeight - (canvasHeight * ((this.minyorg - this.miny) / rangey))),
+                        spotRadius, undefined,
+                        options.get('minSpotColor')).append();
+                }
+                if (spotRadius && options.get('maxSpotColor')) {
+                    x = xvalues[$.inArray(this.maxyorg, yvalues)];
+                    target.drawCircle(canvasLeft + Math.round((x - this.minx) * (canvasWidth / rangex)),
+                        canvasTop + Math.round(canvasHeight - (canvasHeight * ((this.maxyorg - this.miny) / rangey))),
+                        spotRadius, undefined,
+                        options.get('maxSpotColor')).append();
+                }
+            }
+
+            // explicitly compare the refLineX/Y option values with 'null' as numeric zero(0) should plot a ref-line at zero!
+            if (options.get('refLineX') != null) {                                          // jshint ignore:line
+                y = Math.round(this.canvasHeight - (options.get('refLineX') - this.miny) * (this.canvasHeight/rangey));
+                target.drawLine(0, y, this.canvasWidth, y, options.get('refLineColor')).append();
+            }
+
+            if (options.get('refLineY') != null) {                                          // jshint ignore:line
+                x = Math.round((options.get('refLineY') - this.minx) * (this.canvasWidth/rangex));
+                target.drawLine(x, this.canvasHeight, x, 0, options.get('refLineColor')).append();
+            }
+
+            this.lastShapeId = target.getLastShapeId();
+            this.canvasTop = canvasTop;
+            target.render();
+        }
+    });
+
+
+    /**
+     * Bar charts
+     */
+    $.fn.sparkline.bar = bar = createClass($.fn.sparkline._base, barHighlightMixin, {
+        type: 'bar',
+
+        init: function (el, values, options, width, height) {
+            var barWidth = parseInt(options.get('barWidth'), 10),
+                barSpacing = parseInt(options.get('barSpacing'), 10),
+                chartRangeMin = options.get('chartRangeMin'),
+                chartRangeMax = options.get('chartRangeMax'),
+                chartRangeClip = options.get('chartRangeClip'),
+                stackMin = Infinity,
+                stackMax = -Infinity,
+                isStackString, groupMin, groupMax, stackRanges, stackRangesNeg, stackTotals, actualMin, actualMax,
+                numValues, i, vlen, range, zeroAxis, xaxisOffset, min, max, clipMin, clipMax,
+                stacked, vlist, j, slen, svals, val, yoffset, yMaxCalc, canvasHeightEf;
+            bar._super.init.call(this, el, values, options, width, height);
+
+            // scan values to determine whether to stack bars
+            for (i = 0, vlen = values.length; i < vlen; i++) {
+                val = values[i];
+                isStackString = typeof(val) === 'string' && val.indexOf(':') > -1;
+                if (isStackString || $.isArray(val)) {
+                    stacked = true;
+                    if (isStackString) {
+                        val = values[i] = normalizeValues(val.split(':'));
+                    }
+                    val = remove(val, null); // min/max will treat null as zero
+                    groupMin = Math.min.apply(Math, val);
+                    groupMax = Math.max.apply(Math, val);
+                    if (groupMin < stackMin) {
+                        stackMin = groupMin;
+                    }
+                    if (groupMax > stackMax) {
+                        stackMax = groupMax;
+                    }
+                }
+            }
+
+            this.initTarget();
+
+            this.stacked = stacked;
+            this.regionShapes = {};
+            this.barWidth = barWidth * this.target.devicePixelRatio;
+            this.barSpacing = barSpacing * this.target.devicePixelRatio;
+            this.totalBarWidth = (barWidth + barSpacing) * this.target.devicePixelRatio;
+            var rawWidth = (values.length * barWidth * this.target.devicePixelRatio) + ((values.length - 1) * barSpacing * this.target.devicePixelRatio);
+            this.xScale = Math.min(1, rawWidth ? width * this.target.devicePixelRatio / rawWidth : 1);
+            this.width = rawWidth * this.xScale;
+
+            if (chartRangeClip) {
+                clipMin = chartRangeMin === undefined ? -Infinity : chartRangeMin;
+                clipMax = chartRangeMax === undefined ? Infinity : chartRangeMax;
+            }
+			if (stacked) {
+				actualMin = chartRangeMin === undefined ? stackMin : Math.min(stackMin, chartRangeMin);
+				actualMax = chartRangeMax === undefined ? stackMax : Math.max(stackMax, chartRangeMax);
+			}
+
+            numValues = [];
+            stackRanges = stacked ? [] : numValues;
+            stackTotals = [];
+            stackRangesNeg = [];
+            for (i = 0, vlen = values.length; i < vlen; i++) {
+                if (stacked) {
+                    vlist = values[i];
+                    values[i] = svals = [];
+                    stackTotals[i] = 0;
+                    stackRanges[i] = stackRangesNeg[i] = 0;
+                    for (j = 0, slen = vlist.length; j < slen; j++) {
+                        val = svals[j] = chartRangeClip ? clipval(vlist[j], clipMin, clipMax) : vlist[j];
+                        if (val !== null) {
+                            if (val > 0) {
+                                stackTotals[i] += val;
+                            }
+                            if (stackMin < 0 && stackMax > 0) {
+                                if (val < 0) {
+                                    stackRangesNeg[i] += Math.abs(val);
+                                } else {
+                                    stackRanges[i] += val;
+                                }
+                            } else {
+                                stackRanges[i] += Math.abs(val - (val < 0 ? actualMax : actualMin));
+                            }
+                            numValues.push(val);
+                        }
+                    }
+                } else {
+                    val = chartRangeClip ? clipval(values[i], clipMin, clipMax) : values[i];
+                    val = values[i] = normalizeValue(val);
+                    if (val !== null) {
+                        numValues.push(val);
+                    }
+                }
+            }
+            this.max = max = Math.max.apply(Math, numValues);
+            this.min = min = Math.min.apply(Math, numValues);
+            this.stackMax = stackMax = stacked ? Math.max.apply(Math, stackTotals) : max;
+            this.stackMin = stackMin = stacked ? Math.min.apply(Math, numValues) : min;
+
+            if (chartRangeMin !== undefined && (chartRangeClip || chartRangeMin < min)) {
+                min = chartRangeMin;
+            }
+            if (chartRangeMax !== undefined && (chartRangeClip || chartRangeMax > max)) {
+                max = chartRangeMax;
+            }
+
+            this.zeroAxis = zeroAxis = options.get('zeroAxis', true);
+            if (min <= 0 && max >= 0 && zeroAxis) {
+                xaxisOffset = 0;
+            } else if (zeroAxis === false) {
+                xaxisOffset = min;
+            } else if (min > 0) {
+                xaxisOffset = min;
+            } else {
+                xaxisOffset = max;
+            }
+            this.xaxisOffset = xaxisOffset;
+
+            range = stacked ? (Math.max.apply(Math, stackRanges) + Math.max.apply(Math, stackRangesNeg)) : max - min;
+
+            // as we plot zero/min values a single pixel line, we add a pixel to all other
+            // values - Reduce the effective canvas size to suit
+            this.canvasHeightEf = (zeroAxis && min < 0) ? this.canvasHeight - 2 : this.canvasHeight - 1;
+
+            if (min < xaxisOffset) {
+                yMaxCalc = (stacked && max >= 0) ? stackMax : max;
+                yoffset = (yMaxCalc - xaxisOffset) / range * this.canvasHeight;
+                if (yoffset !== Math.ceil(yoffset)) {
+                    this.canvasHeightEf -= 2;
+                    yoffset = Math.ceil(yoffset);
+                }
+            } else {
+                yoffset = this.canvasHeight;
+            }
+            this.yoffset = yoffset;
+
+            this.initColorMap();
+            this.range = range;
+        },
+
+        getRegion: function (el, x, y) {
+            x /= this.xScale;
+            var result = Math.floor(x * this.target.ratio / this.totalBarWidth);
+            return (result < 0 || result >= this.values.length) ? undefined : result;
+        },
+
+        getCurrentRegionFields: function () {
+            var currentRegion = this.currentRegion,
+                values = ensureArray(this.values[currentRegion]),
+                result = [],
+                value, i;
+            for (i = values.length; i--;) {
+                value = values[i];
+                result.push({
+                    isNull: value === null,
+                    value: value,
+                    color: this.calcColor(i, value, currentRegion),
+                    offset: currentRegion
+                });
+            }
+            return result;
+        },
+
+        calcColor: function (stacknum, value, valuenum) {
+            var colorMapFunction = this.colorMapFunction,
+                options = this.options,
+                color, newColor;
+
+            if (colorMapFunction && (newColor = colorMapFunction(this, options, valuenum, value))) {
+                color = newColor;
+            }
+            else {
+                if (this.stacked) {
+                    color = options.get('stackedBarColor');
+                } else {
+                    color = (value < 0) ? options.get('negBarColor') : options.get('barColor');
+                }
+                if (value === 0 && options.get('zeroColor') !== undefined) {
+                    color = options.get('zeroColor');
+                }
+            }
+            return $.isArray(color) ? color[stacknum % color.length] : color;
+        },
+
+        /**
+         * Render bar(s) for a region
+         */
+        renderRegion: function (valuenum, highlight) {
+            var vals = this.values[valuenum],
+                options = this.options,
+                xaxisOffset = this.xaxisOffset,
+                result = [],
+                range = this.range,
+                stacked = this.stacked,
+                target = this.target,
+                x = valuenum * this.totalBarWidth,
+                canvasHeightEf = this.canvasHeightEf,
+                yoffset = this.yoffset,
+                y, height, color, isNull, yoffsetNeg, i, valcount, val, minPlotted, allMin;
+
+            vals = $.isArray(vals) ? vals : [vals];
+            valcount = vals.length;
+            val = vals[0];
+            isNull = all(null, vals);
+            allMin = all(xaxisOffset, vals, true);
+
+            if (isNull) {
+                if (options.get('nullColor')) {
+                    color = highlight ? options.get('nullColor') : this.calcHighlightColor(options.get('nullColor'), options);
+                    y = (yoffset > 0) ? yoffset - 1 : yoffset;
+                    return target.drawRect(x, y, this.barWidth - 1, 0, color, color);
+                } else {
+                    return undefined;
+                }
+            }
+            yoffsetNeg = yoffset;
+            for (i = 0; i < valcount; i++) {
+                val = vals[i];
+
+                if (stacked && val === xaxisOffset) {
+                    if (!allMin || minPlotted) {
+                        continue;
+                    }
+                    minPlotted = true;
+                }
+
+                if (range > 0) {
+                    height = Math.floor(canvasHeightEf * ((Math.abs(val - xaxisOffset) / range))) + 1;
+                } else {
+                    height = 1;
+                }
+                if (val < xaxisOffset || (val === xaxisOffset && yoffset === 0)) {
+                    y = yoffsetNeg;
+                    yoffsetNeg += height;
+                } else {
+                    y = yoffset - height;
+                    yoffset -= height;
+                }
+                color = this.calcColor(i, val, valuenum);
+                if (highlight) {
+                    color = this.calcHighlightColor(color, options);
+                }
+                result.push(target.drawRect(x * this.xScale, y, (this.barWidth - 1) * this.xScale, height - 1, color, color));
+            }
+            if (result.length === 1) {
+                return result[0];
+            }
+            return result;
+        }
+    });
+
+
+    /**
+     * Stack charts
+     */
+    $.fn.sparkline.stack = stack = createClass($.fn.sparkline._base, {
+        type: 'stack',
+
+        init: function (el, values, options, width, height) {
+            var total = 0, i;
+
+            stack._super.init.call(this, el, values, options, width, height);
+
+            this.shapes = {}; // map shape ids to value offsets
+            this.valueShapes = {}; // maps value offsets to shape ids
+            this.values = values = $.map(values, Number);
+
+            this.initTarget();
+
+            if (options.get('width') === 'auto') {
+                this.width = this.height;
+            }
+
+            if (values.length > 0) {
+                for (i = values.length; i--;) {
+                    total += values[i];
+                }
+            }
+            this.total = total;
+
+            this.height = this.canvasHeight * this.target.devicePixelRatio;
+            this.width = this.canvasWidth * this.target.devicePixelRatio;
+        },
+
+        getRegion: function (el, x, y) {
+            var shapeid = this.target.getShapeAt(el, x * this.target.ratio, y * this.target.ratio);
+            return (shapeid !== undefined && this.shapes[shapeid] !== undefined) ? this.shapes[shapeid] : undefined;
+        },
+
+        getCurrentRegionFields: function () {
+            var currentRegion = this.currentRegion;
+            return {
+                isNull: this.values[currentRegion] === undefined,
+                value: this.values[currentRegion],
+                percent: this.values[currentRegion] / this.total * 100,
+                color: this.options.get('sliceColors')[currentRegion % this.options.get('sliceColors').length],
+                offset: currentRegion
+            };
+        },
+
+        changeHighlight: function (highlight) {
+            var currentRegion = this.currentRegion,
+                 newslice = this.renderSlice(currentRegion, highlight),
+                 shapeid = this.valueShapes[currentRegion];
+            delete this.shapes[shapeid];
+            this.target.replaceWithShape(shapeid, newslice);
+            this.valueShapes[currentRegion] = newslice.id;
+            this.shapes[newslice.id] = currentRegion;
+        },
+
+        renderSlice: function (valuenum, highlight) {
+            var target = this.target,
+                options = this.options,
+                height = this.height,
+                width = this.width,
+                values = this.values,
+                total = this.total,
+                start = 0,
+                end = 0,
+                i, vlen, color;
+
+            vlen = values.length;
+            for (i = 0; i < vlen; i++) {
+                start = end;
+                var sliceWidth = Math.round(values[i] * width / total);
+                if (valuenum === i) {
+                    color = options.get('sliceColors')[i % options.get('sliceColors').length];
+                    if (highlight) {
+                        color = this.calcHighlightColor(color, options);
+                    }
+                    return target.drawRect(start, 0, sliceWidth, height, undefined, color);
+                }
+                end += sliceWidth;
+            }
+        },
+
+        render: function () {
+            var target = this.target,
+                values = this.values,
+                options = this.options,
+                borderWidth = options.get('borderWidth'),
+                shape, i;
+
+            if (!stack._super.render.call(this)) {
+                return;
+            }
+            for (i = 0; i < values.length; i++) {
+                if (values[i]) { // don't render zero values
+                    shape = this.renderSlice(i).append();
+                    this.valueShapes[i] = shape.id; // store just the shapeid
+                    this.shapes[shape.id] = i;
+                }
+            }
+            target.render();
+        }
+    });
+
+    /**
+     * Tristate charts
+     */
+    $.fn.sparkline.tristate = tristate = createClass($.fn.sparkline._base, barHighlightMixin, {
+        type: 'tristate',
+
+        init: function (el, values, options, width, height) {
+            var barWidth = parseInt(options.get('barWidth'), 10),
+                barSpacing = parseInt(options.get('barSpacing'), 10);
+            tristate._super.init.call(this, el, values, options, width, height);
+
+            this.initTarget();
+
+            this.regionShapes = {};
+            this.barWidth = barWidth * this.target.devicePixelRatio;
+            this.barSpacing = barSpacing * this.target.devicePixelRatio;
+            this.totalBarWidth = (barWidth + barSpacing) * this.target.devicePixelRatio;
+            this.values = $.map(values, Number);
+            var rawWidth = (values.length * barWidth * this.target.devicePixelRatio) + ((values.length - 1) * barSpacing * this.target.devicePixelRatio);
+            this.xScale = Math.min(1, rawWidth ? width * this.target.devicePixelRatio / rawWidth : 1);
+            this.width = rawWidth * this.xScale; 
+
+            this.initColorMap();
+        },
+
+        getRegion: function (el, x, y) {
+            x /= this.xScale;
+            var result = Math.floor(x * this.target.ratio / this.totalBarWidth);
+            return (result < 0 || result >= this.values.length) ? undefined : result;
+        },
+
+        getCurrentRegionFields: function () {
+            var currentRegion = this.currentRegion;
+            return {
+                isNull: this.values[currentRegion] === undefined,
+                value: this.values[currentRegion],
+                color: this.calcColor(this.values[currentRegion], currentRegion),
+                offset: currentRegion
+            };
+        },
+
+        calcColor: function (value, valuenum) {
+            var options = this.options,
+                colorMapFunction = this.colorMapFunction,
+                color, newColor;
+
+            if (colorMapFunction && (newColor = colorMapFunction(this, options, valuenum, value))) {
+                color = newColor;
+            } else if (value < 0) {
+                color = options.get('negBarColor');
+            } else if (value > 0) {
+                color = options.get('posBarColor');
+            } else {
+                color = options.get('zeroBarColor');
+            }
+            return color;
+        },
+
+        renderRegion: function (valuenum, highlight) {
+            var values = this.values,
+                options = this.options,
+                target = this.target,
+                canvasHeight, height, halfHeight,
+                x, y, color;
+
+            canvasHeight = target.pixelHeight;
+            halfHeight = Math.round(canvasHeight / 2);
+
+            x = valuenum * this.totalBarWidth;
+            if (values[valuenum] < 0) {
+                y = halfHeight;
+                height = halfHeight - 1;
+            } else if (values[valuenum] > 0) {
+                y = 0;
+                height = halfHeight - 1;
+            } else {
+                y = halfHeight - 1;
+                height = 2;
+            }
+            color = this.calcColor(values[valuenum], valuenum);
+            if (color === null) {
+                return;
+            }
+            if (highlight) {
+                color = this.calcHighlightColor(color, options);
+            }
+            return target.drawRect(x * this.xScale, y, (this.barWidth - 1) * this.xScale, height - 1, color, color);
+        }
+    });
+
+
+    /**
+     * Discrete charts
+     */
+    $.fn.sparkline.discrete = discrete = createClass($.fn.sparkline._base, barHighlightMixin, {
+        type: 'discrete',
+
+        init: function (el, values, options, width, height) {
+            discrete._super.init.call(this, el, values, options, width, height);
+
+            this.initTarget();
+
+            this.regionShapes = {};
+            this.values = values = $.map(values, Number);
+            this.min = Math.min.apply(Math, values);
+            this.max = Math.max.apply(Math, values);
+            this.range = this.max - this.min;
+            width = options.get('width') === 'auto' ? values.length * 2 * this.target.devicePixelRatio : this.width;
+            //adjust width for pixel ratio
+            width = width * this.target.devicePixelRatio;
+            this.width = width;
+            this.interval = Math.floor(width / values.length);
+            this.itemWidth = width / values.length;
+            if (options.get('chartRangeMin') !== undefined && (options.get('chartRangeClip') || options.get('chartRangeMin') < this.min)) {
+                this.min = options.get('chartRangeMin');
+            }
+            if (options.get('chartRangeMax') !== undefined && (options.get('chartRangeClip') || options.get('chartRangeMax') > this.max)) {
+                this.max = options.get('chartRangeMax');
+            }
+
+            if (this.target) {
+                this.lineHeight = options.get('lineHeight') === 'auto' ? Math.round(this.canvasHeight * 0.3) : options.get('lineHeight');
+            }
+        },
+
+        getRegion: function (el, x, y) {
+            return Math.floor(x * this.target.ratio / this.itemWidth);
+        },
+
+        getCurrentRegionFields: function () {
+            var currentRegion = this.currentRegion;
+            return {
+                isNull: this.values[currentRegion] === undefined,
+                value: this.values[currentRegion],
+                offset: currentRegion
+            };
+        },
+
+        renderRegion: function (valuenum, highlight) {
+            var values = this.values,
+                options = this.options,
+                min = this.min,
+                max = this.max,
+                range = this.range,
+                interval = this.interval,
+                target = this.target,
+                canvasHeight = this.canvasHeight,
+                lineHeight = this.lineHeight,
+                pheight = canvasHeight - lineHeight,
+                ytop, val, color, x;
+
+            val = clipval(values[valuenum], min, max);
+            x = valuenum * interval;
+            ytop = Math.round(pheight - pheight * ((val - min) / range));
+            color = (options.get('thresholdColor') && val < options.get('thresholdValue')) ? options.get('thresholdColor') : options.get('lineColor');
+            if (highlight) {
+                color = this.calcHighlightColor(color, options);
+            }
+            return target.drawLine(x, ytop, x, ytop + lineHeight, color);
+        }
+    });
+
+
+    /**
+     * Bullet charts
+     */
+    $.fn.sparkline.bullet = bullet = createClass($.fn.sparkline._base, {
+        type: 'bullet',
+
+        init: function (el, values, options, width, height) {
+            var min, max, vals;
+            bullet._super.init.call(this, el, values, options, width, height);
+
+            // values: target, performance, range1, range2, range3
+            this.values = values = normalizeValues(values);
+            // target or performance could be null
+            vals = values.slice();
+            vals[0] = vals[0] === null ? vals[2] : vals[0];
+            vals[1] = values[1] === null ? vals[2] : vals[1];
+            min = Math.min.apply(Math, values);
+            max = Math.max.apply(Math, values);
+            if (options.get('base') === undefined) {
+                min = min < 0 ? min : 0;
+            } else {
+                min = options.get('base');
+            }
+            this.min = min;
+            this.max = max;
+            this.range = max - min;
+			
+			// GRADIENT
+			var colors = options.get('rangeColors');
+			if (options.get('gradient') && colors.length > 1) {
+				var rainbow = new Rainbow();
+				rainbow.setSpectrumByArray(colors);
+				rainbow.setNumberRange(0, this.values.length);
+				
+				for (var i = 0; i < this.values.length; i++) {
+					colors[i] = rainbow.colorAt(i);
+				}
+			}
+			
+			this.rangeColors = colors;
+            this.shapes = {};
+            this.valueShapes = {};
+            this.regiondata = {};
+            this.width = width = options.get('width') === 'auto' ? '4.0em' : width;
+            this.target = this.$el.simpledraw(width, height, options.get('composite'));
+            if (!values.length) {
+                this.disabled = true;
+            }
+            this.initTarget();
+        },
+
+        getRegion: function (el, x, y) {
+            var shapeid = this.target.getShapeAt(el, x * this.target.ratio, y * this.target.ratio);
+            return (shapeid !== undefined && this.shapes[shapeid] !== undefined) ? this.shapes[shapeid] : undefined;
+        },
+
+        getCurrentRegionFields: function () {
+            var currentRegion = this.currentRegion;
+            return {
+                fieldkey: currentRegion.substr(0, 1),
+                value: this.values[currentRegion.substr(1)],
+                region: currentRegion
+            };
+        },
+
+        changeHighlight: function (highlight) {
+            var currentRegion = this.currentRegion,
+                shapeid = this.valueShapes[currentRegion],
+                shape;
+            delete this.shapes[shapeid];
+            switch (currentRegion.substr(0, 1)) {
+                case 'r':
+                    shape = this.renderRange(currentRegion.substr(1), highlight);
+                    break;
+                case 'p':
+                    shape = this.renderPerformance(highlight);
+                    break;
+                case 't':
+                    shape = this.renderTarget(highlight);
+                    break;
+            }
+            this.valueShapes[currentRegion] = shape.id;
+            this.shapes[shape.id] = currentRegion;
+            this.target.replaceWithShape(shapeid, shape);
+        },
+
+        renderRange: function (rn, highlight) {
+            var rangeval = this.values[rn],
+                rangewidth = Math.round(this.canvasWidth * ((rangeval - this.min) / this.range)),
+                color = this.rangeColors[rn - 2];
+            if (highlight) {
+                color = this.calcHighlightColor(color, this.options);
+            }
+            return this.target.drawRect(0, 0, rangewidth - 1, this.canvasHeight - 1, color, color);
+        },
+
+        renderPerformance: function (highlight) {
+            var perfval = this.values[1],
+                perfwidth = Math.round(this.canvasWidth * ((perfval - this.min) / this.range)),
+                color = this.options.get('performanceColor');
+            if (highlight) {
+                color = this.calcHighlightColor(color, this.options);
+            }
+            return this.target.drawRect(0, Math.round(this.canvasHeight * 0.3), perfwidth - 1,
+                Math.round(this.canvasHeight * 0.4) - 1, color, color);
+        },
+
+        renderTarget: function (highlight) {
+            var targetval = this.values[0],
+                x = Math.round(this.canvasWidth * ((targetval - this.min) / this.range) - (this.options.get('targetWidth') / 2)),
+                targettop = Math.round(this.canvasHeight * 0.10),
+                targetheight = this.canvasHeight - (targettop * 2),
+                color = this.options.get('targetColor');
+            if (highlight) {
+                color = this.calcHighlightColor(color, this.options);
+            }
+            return this.target.drawRect(x, targettop, this.options.get('targetWidth') - 1, targetheight - 1, color, color);
+        },
+
+        render: function () {
+            var vlen = this.values.length,
+                target = this.target,
+                i, shape;
+            if (!bullet._super.render.call(this)) {
+                return;
+            }
+            for (i = 2; i < vlen; i++) {
+                shape = this.renderRange(i).append();
+                this.shapes[shape.id] = 'r' + i;
+                this.valueShapes['r' + i] = shape.id;
+            }
+            if (this.values[1] !== null) {
+                shape = this.renderPerformance().append();
+                this.shapes[shape.id] = 'p1';
+                this.valueShapes.p1 = shape.id;
+            }
+            if (this.values[0] !== null) {
+                shape = this.renderTarget().append();
+                this.shapes[shape.id] = 't0';
+                this.valueShapes.t0 = shape.id;
+            }
+            target.render();
+        }
+    });
+
+
+    /**
+     * Pie charts
+     */
+    $.fn.sparkline.pie = pie = createClass($.fn.sparkline._base, {
+        type: 'pie',
+
+        init: function (el, values, options, width, height) {
+            var total = 0, i;
+
+            pie._super.init.call(this, el, values, options, width, height);
+
+            this.shapes = {}; // map shape ids to value offsets
+            this.valueShapes = {}; // maps value offsets to shape ids
+            this.values = values = $.map(values, Number);
+
+            if (options.get('width') === 'auto') {
+                this.width = this.height;
+            }
+
+            if (values.length > 0) {
+                for (i = values.length; i--;) {
+                    total += values[i];
+                }
+            }
+            this.total = total;
+            this.initTarget();
+            this.radius = Math.floor(Math.min(this.canvasWidth, this.canvasHeight) / 2);
+        },
+
+        getRegion: function (el, x, y) {
+            var shapeid = this.target.getShapeAt(el, x * this.target.ratio, y * this.target.ratio);
+            return (shapeid !== undefined && this.shapes[shapeid] !== undefined) ? this.shapes[shapeid] : undefined;
+        },
+
+        getCurrentRegionFields: function () {
+            var currentRegion = this.currentRegion;
+            return {
+                isNull: this.values[currentRegion] === undefined,
+                value: this.values[currentRegion],
+                percent: this.values[currentRegion] / this.total * 100,
+                color: this.options.get('sliceColors')[currentRegion % this.options.get('sliceColors').length],
+                offset: currentRegion
+            };
+        },
+
+        changeHighlight: function (highlight) {
+            var currentRegion = this.currentRegion,
+                 newslice = this.renderSlice(currentRegion, highlight),
+                 shapeid = this.valueShapes[currentRegion];
+            delete this.shapes[shapeid];
+            this.target.replaceWithShape(shapeid, newslice);
+            this.valueShapes[currentRegion] = newslice.id;
+            this.shapes[newslice.id] = currentRegion;
+        },
+
+        renderSlice: function (valuenum, highlight) {
+            var target = this.target,
+                options = this.options,
+                radius = this.radius,
+                borderWidth = options.get('borderWidth'),
+                offset = options.get('offset'),
+                circle = 2 * Math.PI,
+                values = this.values,
+                total = this.total,
+                next = offset ? (2*Math.PI)*(offset/360) : 0,
+                start, end, i, vlen, color;
+
+            vlen = values.length;
+            for (i = 0; i < vlen; i++) {
+                start = next;
+                end = next;
+                if (total > 0) {  // avoid divide by zero
+                    end = next + (circle * (values[i] / total));
+                }
+                if (valuenum === i) {
+                    color = options.get('sliceColors')[i % options.get('sliceColors').length];
+                    if (highlight) {
+                        color = this.calcHighlightColor(color, options);
+                    }
+
+                    return target.drawPieSlice(radius, radius, radius - borderWidth, start, end, undefined, color);
+                }
+                next = end;
+            }
+        },
+
+        render: function () {
+            var target = this.target,
+                values = this.values,
+                options = this.options,
+                radius = this.radius,
+                borderWidth = options.get('borderWidth'),
+                shape, i;
+
+            if (!pie._super.render.call(this)) {
+                return;
+            }
+            if (borderWidth) {
+                target.drawCircle(radius, radius, Math.floor(radius - (borderWidth / 2)),
+                    options.get('borderColor'), undefined, borderWidth).append();
+            }
+            for (i = values.length; i--;) {
+                if (values[i]) { // don't render zero values
+                    shape = this.renderSlice(i).append();
+                    this.valueShapes[i] = shape.id; // store just the shapeid
+                    this.shapes[shape.id] = i;
+                }
+            }
+            target.render();
+        }
+    });
+
+
+    /**
+     * Box plots
+     */
+    $.fn.sparkline.box = box = createClass($.fn.sparkline._base, {
+        type: 'box',
+
+        init: function (el, values, options, width, height) {
+            box._super.init.call(this, el, values, options, width, height);
+            this.values = $.map(values, Number);
+            this.width = options.get('width') === 'auto' ? '4.0em' : width;
+            this.initTarget();
+            if (!this.values.length) {
+                this.disabled = 1;
+            }
+        },
+
+        /**
+         * Simulate a single region
+         */
+        getRegion: function () {
+            return 1;
+        },
+
+        getCurrentRegionFields: function () {
+            var result = [
+                { field: 'lq', value: this.quartiles[0] },
+                { field: 'med', value: this.quartiles[1] },
+                { field: 'uq', value: this.quartiles[2] }
+            ];
+            if (this.loutlier !== undefined) {
+                result.push({ field: 'lo', value: this.loutlier});
+            }
+            if (this.routlier !== undefined) {
+                result.push({ field: 'ro', value: this.routlier});
+            }
+            if (this.lwhisker !== undefined) {
+                result.push({ field: 'lw', value: this.lwhisker});
+            }
+            if (this.rwhisker !== undefined) {
+                result.push({ field: 'rw', value: this.rwhisker});
+            }
+            return result;
+        },
+
+        render: function () {
+            var target = this.target,
+                values = this.values,
+                vlen = values.length,
+                options = this.options,
+                canvasWidth = this.canvasWidth,
+                canvasHeight = this.canvasHeight,
+                minValue = options.get('chartRangeMin') === undefined ? Math.min.apply(Math, values) : options.get('chartRangeMin'),
+                maxValue = options.get('chartRangeMax') === undefined ? Math.max.apply(Math, values) : options.get('chartRangeMax'),
+                canvasLeft = 0,
+                lwhisker, loutlier, iqr, q1, q2, q3, rwhisker, routlier, i,
+                size, unitSize, unitOffset;
+
+            if (!box._super.render.call(this)) {
+                return;
+            }
+
+            if (options.get('raw')) {
+                if (options.get('showOutliers') && values.length > 5) {
+                    loutlier = values[0];
+                    lwhisker = values[1];
+                    q1 = values[2];
+                    q2 = values[3];
+                    q3 = values[4];
+                    rwhisker = values[5];
+                    routlier = values[6];
+                } else {
+                    lwhisker = values[0];
+                    q1 = values[1];
+                    q2 = values[2];
+                    q3 = values[3];
+                    rwhisker = values[4];
+                }
+            } else {
+                values.sort(function (a, b) { return a - b; });
+                q1 = quartile(values, 1);
+                q2 = quartile(values, 2);
+                q3 = quartile(values, 3);
+                iqr = q3 - q1;
+                if (options.get('showOutliers')) {
+                    lwhisker = rwhisker = undefined;
+                    for (i = 0; i < vlen; i++) {
+                        if (lwhisker === undefined && values[i] > q1 - (iqr * options.get('outlierIQR'))) {
+                            lwhisker = values[i];
+                        }
+                        if (values[i] < q3 + (iqr * options.get('outlierIQR'))) {
+                            rwhisker = values[i];
+                        }
+                    }
+                    loutlier = values[0];
+                    routlier = values[vlen - 1];
+                } else {
+                    lwhisker = values[0];
+                    rwhisker = values[vlen - 1];
+                }
+            }
+            this.quartiles = [q1, q2, q3];
+            this.lwhisker = lwhisker;
+            this.rwhisker = rwhisker;
+            this.loutlier = loutlier;
+            this.routlier = routlier;
+
+            // Non-zero unit offset can throw off the plotting if it is not
+            // required to avoid a division by zero.
+            unitOffset = 0.0;
+            if ( ( maxValue - minValue ) == 0.0 ) { unitOffset = 1.0; }
+
+            unitSize = canvasWidth / (maxValue - minValue + unitOffset );
+            if (options.get('showOutliers')) {
+                canvasLeft = Math.ceil(options.get('spotRadius'));
+                canvasWidth -= 2 * Math.ceil(options.get('spotRadius'));
+                unitSize = canvasWidth / (maxValue - minValue + unitOffset);
+                if (loutlier < lwhisker) {
+                    target.drawCircle((loutlier - minValue) * unitSize + canvasLeft,
+                        canvasHeight / 2,
+                        options.get('spotRadius'),
+                        options.get('outlierLineColor'),
+                        options.get('outlierFillColor')).append();
+                }
+                if (routlier > rwhisker) {
+                    target.drawCircle((routlier - minValue) * unitSize + canvasLeft,
+                        canvasHeight / 2,
+                        options.get('spotRadius'),
+                        options.get('outlierLineColor'),
+                        options.get('outlierFillColor')).append();
+                }
+            }
+
+            // box
+            target.drawRect(
+                Math.round((q1 - minValue) * unitSize + canvasLeft),
+                Math.round(canvasHeight * 0.1),
+                Math.round((q3 - q1) * unitSize),
+                Math.round(canvasHeight * 0.8),
+                options.get('boxLineColor'),
+                options.get('boxFillColor'),
+                // CUSTOM MOD: line width & corner radius
+                options.get('lineWidth'),
+                options.get('cornerRadius')).append();
+            // left whisker
+            // CUSTOM MOD: strikethrough option
+            var rightEnd = q1 - minValue;
+            if (options.get('strikeThrough'))
+              rightEnd = rwhisker - minValue;
+
+            target.drawLine(
+                Math.round((lwhisker - minValue) * unitSize + canvasLeft),
+                Math.round(canvasHeight / 2),
+                Math.round(rightEnd * unitSize + canvasLeft),
+                Math.round(canvasHeight / 2),
+                // CUSTOM MOD: line width added
+                options.get('lineColor'),
+                options.get('lineWidth')).append();
+            target.drawLine(
+                Math.round((lwhisker - minValue) * unitSize + canvasLeft),
+                Math.round(canvasHeight / 4),
+                Math.round((lwhisker - minValue) * unitSize + canvasLeft),
+                Math.round(canvasHeight - canvasHeight / 4),
+                options.get('whiskerColor'),
+                // CUSTOM MOD: line width added
+                options.get('lineWidth')).append();
+            // right whisker
+            // CUSTOM MOD: strikethrough option
+            if (!options.get('strikeThrough'))
+            {
+              target.drawLine(Math.round((rwhisker - minValue) * unitSize + canvasLeft),
+                  Math.round(canvasHeight / 2),
+                  Math.round((q3 - minValue) * unitSize + canvasLeft),
+                  Math.round(canvasHeight / 2),
+                  options.get('lineColor'),
+                  // CUSTOM MOD: line width added
+                  options.get('lineWidth')).append();
+            }
+            target.drawLine(
+                Math.round((rwhisker - minValue) * unitSize + canvasLeft),
+                Math.round(canvasHeight / 4),
+                Math.round((rwhisker - minValue) * unitSize + canvasLeft),
+                Math.round(canvasHeight - canvasHeight / 4),
+                options.get('whiskerColor'),
+                // CUSTOM MOD: line width added
+                options.get('lineWidth')).append();
+
+            // median line
+            target.drawLine(
+                Math.round((q2 - minValue) * unitSize + canvasLeft),
+                Math.round(canvasHeight * 0.1),
+                Math.round((q2 - minValue) * unitSize + canvasLeft),
+                Math.round(canvasHeight * 0.9),
+                // CUSTOM MOD: medianwidth option
+                options.get('medianColor'),
+                options.get('medianWidth')).append();
+            if (typeof options.get('target') == 'number') {
+                size = Math.ceil(options.get('spotRadius'));
+                // CUSTOM MOD: circle representation of median
+                var targetVal = options.get('target');
+                var targetObj = options.get('targetObj')
+                if (!targetObj || targetObj == 'crosshair') {
+                    target.drawLine(
+                        Math.round((targetVal - minValue) * unitSize + canvasLeft),
+                        Math.round((canvasHeight / 2) - size),
+                        Math.round((targetVal - minValue) * unitSize + canvasLeft),
+                        Math.round((canvasHeight / 2) + size),
+                        options.get('targetColor')).append();
+                    target.drawLine(
+                        Math.round((targetVal - minValue) * unitSize + canvasLeft - size),
+                        Math.round(canvasHeight / 2),
+                        Math.round((targetVal - minValue) * unitSize + canvasLeft + size),
+                        Math.round(canvasHeight / 2),
+                        options.get('targetColor')).append();
+                }
+                else if (targetObj == 'circle')
+                {
+                    target.drawCircle(
+                        (targetVal - minValue) * unitSize + canvasLeft,
+                        canvasHeight / 2,
+                        options.get('spotRadius'),
+                        options.get('targetColor'),
+                        options.get('targetColor')).append();
+                }
+            }
+            target.render();
+        }
+    });
+
+
+  /*jslint nomen: true, plusplus: true, todo: true, white: true, browser: true *//**
+     * Timeline sparkline chart
+     * Given a list of events with begin/finish times, graph them vertically or horizontally by event type.
+     * let events = [
+     *  {begin:date(11a), finish:date(12a), color:'red'},
+     *  {begin:date(12a), finish:date(1p), color:'green'},
+     *  {begin:date(1p), finish:date(6p), color:'blue'}
+     * ]
+     * let 1 pixel = 1 minute
+     * let 8 am be the sparkline begin
+     * let 8 pm be the sparkline finish 
+     * let 720 pixels be the total visible duration
+     * then graph 
+     *  |white for 300 pixels||red for 60 pixels||green for 60 pixels||blue for 300 pixels||white for 120 pixels|
+     */
+;(function ($) {
+
+    "use strict";
+
+    $.fn.sparkline.timeline = timeline = createClass($.fn.sparkline._base, barHighlightMixin, {
+
+        type: 'timeline',
+
+        init: function (el, values, options, width, height) {
+            // expect a Date or the Number of milliseconds since the epoc
+            function minutes(date) {
+                return date / (60 * 1000);
+            }
+            // force positive number otherwise 0
+            function forcePositiveNumber(val) {
+                val = Math.abs(val);
+                return isNaN(val) ? 0 : val;
+            }
+            var i, data, segment, beginMinutes, finishMinutes, durationMinutes, 
+                pixelsPerMinute, userInitHandler, timeMarkPixels, isVerticalOrientation, 
+                timeMarkInterval, timeMarkOffset, timeMark, tick, tickSize;
+            timeline._super.init.call(this, el, values, options, width, height);
+            // required by barHighlightMixin
+            this.regionShapes = {};
+            // sets canvas height/width
+            this.initTarget();
+            // holds each timeline entry with x,y,w,h,lc,fc,rd values
+            this.segments = [];
+            // holds time markers entry with x1,y1,x2,y2,lc,w values
+            this.timemarks = [];
+            // paints a 1px line showing full length of timeline
+            timeMarkInterval = forcePositiveNumber(options.mergedOptions.timeMarkInterval);
+            // orient the sparkline direction, the default is horizontal
+            isVerticalOrientation = 'vertical' === options.mergedOptions.orientation;
+            // allow user to manipulate the data before segment is built
+            userInitHandler = $.isFunction(options.mergedOptions.init) ? options.mergedOptions.init : function (d) { return d; };
+            function offset(date, baseline) {
+                return Math.ceil(pixelsPerMinute * (minutes(date) - baseline));
+            }
+            // segments that fall outside of begin/finish will be clipped
+            beginMinutes = minutes(options.mergedOptions.begin);
+            finishMinutes = minutes(options.mergedOptions.finish);
+            durationMinutes = (finishMinutes - beginMinutes);
+            if (isVerticalOrientation) {
+                pixelsPerMinute = (this.canvasHeight - 1) / durationMinutes;
+            } else {
+                pixelsPerMinute = (this.canvasWidth - 1) / durationMinutes;
+            }
+            if (timeMarkInterval > 0) {
+                timeMarkPixels = timeMarkInterval * pixelsPerMinute;
+                // add tick marks based on timeMarkInterval
+                for (i = 0; i < ((durationMinutes * pixelsPerMinute) / timeMarkPixels) + 1; i++) {
+                    tick = {x1: 0, y1: 0, x2: 0, y2: 0, lc:'#ff0011', w: 1};
+                    timeMark = Math.round(i * timeMarkPixels);
+                    tickSize = Math.ceil(timeMark / pixelsPerMinute) % 60 === 0 ? 3 : 1;
+                    if (isVerticalOrientation) {
+                        tick.x2 = tickSize;
+                        tick.y1 = tick.y2 = timeMark;
+                    } else {
+                        tick.y2 = tickSize;
+                        tick.x1 = tick.x2 = timeMark;
+                    }
+                    this.timemarks.push(tick);
+                }
+                // add last tick mark and timeline
+                if (isVerticalOrientation) {
+                    this.timemarks.push({x1:0, y1:0, x2:0, y2:this.canvasHeight, lc:'#eee', w:1});
+                } else {
+                    this.timemarks.push({x1:0, y1:0, x2:this.canvasWidth, y2:0, lc:'#eee', w:1});
+                }
+            }
+            // build each segment for rendering
+            timeMarkOffset = (timeMarkInterval > 0) ? 1 : 0;
+            for (i = 0; i < values.length; i++) {
+                // TODO: determine why values has bogus length value in IE8
+                if (values[i]) {
+                    data = userInitHandler(values[i], i);
+                    if (data) {
+                        // the minus 2 is to prevent clipping the segment
+                        segment = {
+                            x: timeMarkOffset, 
+                            y: timeMarkOffset, 
+                            w: width - (timeMarkOffset + 1), 
+                            h: height - (timeMarkOffset + 1), 
+                            data: data
+                        };
+                        // TODO: adjust shape size for overlapping regions
+                        if (isVerticalOrientation) {
+                            segment.y = offset(data.begin, beginMinutes);
+                            segment.h = offset(data.finish, minutes(data.begin));
+                        } else {
+                            segment.x = offset(data.begin, beginMinutes);
+                            segment.w = offset(data.finish, minutes(data.begin));
+                        }
+                        segment.fc = data.color || options.mergedOptions.fillColor;
+                        segment.lc = data.lineColor || options.mergedOptions.lineColor;
+                        this.segments.push(segment);
+                    }
+                }
+            }
+
+            // sort the segments so all segments are visible in timeline
+            this.segments = this.segments.sort(function compare(a,b) {
+                var ab, af, bb, bf;
+                ab = Number(a.data.begin);
+                bb = Number(b.data.begin);
+                af = Number(a.data.finish);
+                bf = Number(b.data.finish);
+                // reverse order sort
+                return (bb-ab) + (bf-af);
+            });
+        },
+
+        /** return mouse coordinates on timeline */
+        getRegion: function (el, x, y) {
+            return {el: el, x: x, y: y};
+        },
+
+        /** return data used to display tooltip for the current region(s) */
+        getCurrentRegionFields: function () {
+            var i, el, x, y, segment, regions = [], left, right, top, bottom;
+            el = this.currentRegion.el;
+            x = this.currentRegion.x;
+            y = this.currentRegion.y;
+            for (i = 0; i < this.segments.length; i++) {
+                segment = this.segments[i];
+                if (segment) {
+                    left = segment.x;
+                    right = left + segment.w;
+                    top = segment.y;
+                    bottom = top + segment.h;
+                    if (x > left && x < right && y > top && y < bottom) {
+                        regions.push(segment.data);
+                    }
+                }
+            }
+            return regions;
+        },
+
+        /** render timeline segment and tickmarks */
+        renderRegion: function (valuenum, highlight) {
+            var i, tick, segment, result = [], target = this.target;
+            if (valuenum === 0) {
+                for (i = 0; i < this.timemarks.length; i++) {
+                    tick = this.timemarks[i];
+                    result.push(target.drawLine(tick.x1, tick.y1, tick.x2, tick.y2, tick.lc, tick.w));
+                }
+            }
+            segment = this.segments[valuenum];
+            if (segment) {
+                result.push(target.drawRect(segment.x, segment.y, segment.w, segment.h, segment.lc, segment.fc));
+            }
+            return result;
+        }
+    });
+}(jQuery));
+
+
+    // Setup a very simple "virtual canvas" to make drawing the few shapes we need easier
+    // This is accessible as $(foo).simpledraw()
+
+    VShape = createClass({
+        init: function (target, id, type, args) {
+            this.target = target;
+            this.id = id;
+            this.type = type;
+            this.args = args;
+        },
+        append: function () {
+            this.target.appendShape(this);
+            return this;
+        }
+    });
+
+    VCanvas_base = createClass({
+        _pxregex: /(\d+)(px)?\s*$/i,
+
+        init: function (width, height, target) {
+            if (!width) {
+                return;
+            }
+            this.width = width;
+            this.height = height;
+            this.target = target;
+            this.lastShapeId = null;
+            if (target[0]) {
+                target = target[0];
+            }
+            $.data(target, '_jqs_vcanvas', this);
+        },
+
+        drawLine: function (x1, y1, x2, y2, lineColor, lineWidth) {
+            // CUSTOM MOD: line width added
+            return this.drawShape([[x1, y1], [x2, y2]], lineColor, null, lineWidth);
+        },
+
+        drawShape: function (path, lineColor, fillColor, lineWidth) {
+            return this._genShape('Shape', [path, lineColor, fillColor, lineWidth]);
+        },
+
+        drawCircle: function (x, y, radius, lineColor, fillColor, lineWidth) {
+            return this._genShape('Circle', [x, y, radius, lineColor, fillColor, lineWidth]);
+        },
+
+        drawPieSlice: function (x, y, radius, startAngle, endAngle, lineColor, fillColor) {
+            return this._genShape('PieSlice', [x, y, radius, startAngle, endAngle, lineColor, fillColor]);
+        },
+
+        // CUSTOM MOD: line width / radius added
+        drawRect: function (x, y, width, height, lineColor, fillColor, lineWidth, radius) {
+            return this._genShape('Rect', [x, y, width, height, lineColor, fillColor, lineWidth, radius]);
+        },
+
+        getElement: function () {
+            return this.canvas;
+        },
+
+        /**
+         * Return the most recently inserted shape id
+         */
+        getLastShapeId: function () {
+            return this.lastShapeId;
+        },
+
+        /**
+         * Clear and reset the canvas
+         */
+        reset: function () {
+            alert('reset not implemented');
+        },
+
+        _insert: function (el, target) {
+            $(target).html(el);
+        },
+
+        /**
+         * Calculate the pixel dimensions of the canvas
+         */
+        _calculatePixelDims: function (width, height, canvas) {
+            // XXX This should probably be a configurable option
+            var match;
+            match = this._pxregex.exec(height);
+            if (match) {
+                this.pixelHeight = match[1];
+            } else {
+                this.pixelHeight = $(canvas).height();
+            }
+            match = this._pxregex.exec(width);
+            if (match) {
+                this.pixelWidth = match[1];
+            } else {
+                this.pixelWidth = $(canvas).width();
+            }
+            var ratio = window.hasOwnProperty('devicePixelRatio') ? window.devicePixelRatio : 1;
+            this.pixelWidth *= ratio;
+            this.pixelHeight *= ratio;
+        },
+
+        /**
+         * Generate a shape object and id for later rendering
+         */
+        _genShape: function (shapetype, shapeargs) {
+            var id = shapeCount++;
+            shapeargs.unshift(id);
+            return new VShape(this, id, shapetype, shapeargs);
+        },
+
+        /**
+         * Add a shape to the end of the render queue
+         */
+        appendShape: function (shape) {
+            alert('appendShape not implemented');
+        },
+
+        /**
+         * Replace one shape with another
+         */
+        replaceWithShape: function (shapeid, shape) {
+            alert('replaceWithShape not implemented');
+        },
+
+        /**
+         * Insert one shape after another in the render queue
+         */
+        insertAfterShape: function (shapeid, shape) {
+            alert('insertAfterShape not implemented');
+        },
+
+        /**
+         * Remove a shape from the queue
+         */
+        removeShapeId: function (shapeid) {
+            alert('removeShapeId not implemented');
+        },
+
+        /**
+         * Find a shape at the specified x/y co-ordinates
+         */
+        getShapeAt: function (el, x, y) {
+            alert('getShapeAt not implemented');
+        },
+
+        /**
+         * Render all queued shapes onto the canvas
+         */
+        render: function () {
+            alert('render not implemented');
+        }
+    });
+
+
+    VCanvas_canvas = createClass(VCanvas_base, {
+        init: function (width, height, target, interact) {
+            VCanvas_canvas._super.init.call(this, width, height, target);
+            this.canvas = document.createElement('canvas');
+            if (target[0]) {
+                target = target[0];
+            }
+            this.context = this.canvas.getContext('2d');
+
+            var devicePixelRatio = window.devicePixelRatio || 1,
+                backingStoreRatio = this.context.webkitBackingStorePixelRatio || this.context.mozBackingStorePixelRatio || this.context.msBackingStorePixelRatio || this.context.oBackingStorePixelRatio || this.context.backingStorePixelRatio || 1,
+                ratio = devicePixelRatio / backingStoreRatio;
+
+            $.data(target, '_jqs_vcanvas', this);
+            $(this.canvas).css({ display: 'inline-block', width: width, height: height, verticalAlign: 'top' });
+            this._insert(this.canvas, target);
+            this._calculatePixelDims(width, height, this.canvas);
+            this.canvas.width = this.pixelWidth * ratio;
+            this.canvas.height = this.pixelHeight * ratio;
+            this.context.scale(ratio, ratio);
+            this.interact = interact;
+            this.shapes = {};
+            this.shapeseq = [];
+            this.currentTargetShapeId = undefined;
+            //$(this.canvas).css({width: this.pixelWidth, height: this.pixelHeight});
+            //if transform applied to parent then need to adjust for that
+            this.devicePixelRatio = ratio;
+            this.ratio = this.pixelWidth / this.canvas.getBoundingClientRect().width;
+        },
+
+        _getContext: function (lineColor, fillColor, lineWidth) {
+            var context = this.canvas.getContext('2d');
+            if (lineColor !== undefined) {
+                context.strokeStyle = lineColor;
+            }
+            context.lineWidth = lineWidth === undefined ? 1 : lineWidth;
+            if (fillColor !== undefined) {
+                context.fillStyle = fillColor;
+            }
+            return context;
+        },
+
+        reset: function () {
+            var context = this._getContext();
+            context.clearRect(0, 0, this.pixelWidth, this.pixelHeight);
+            this.shapes = {};
+            this.shapeseq = [];
+            this.currentTargetShapeId = undefined;
+        },
+
+        // CUSTOM MOD: radius added
+        _drawShape: function (shapeid, path, lineColor, fillColor, lineWidth, radius) {
+            var context = this._getContext(lineColor, fillColor, lineWidth),
+                i, plen, done = false;
+            if (!radius)
+              radius = 0;
+            context.beginPath();
+            // CUSTOM MOD: corner radius drawing added for rectangles
+            if (path.length === 5) {
+                if ((path[1][0] - path[0][0]) < radius)
+                    radius = 0;
+                // this is a rectangle
+                if (radius > 0) {
+                    context.moveTo(path[0][0] + radius + 0.5, path[0][1] + 0.5);
+
+                    context.lineTo(path[1][0] - radius + 0.5, path[1][1] + 0.5);
+                    context.quadraticCurveTo(path[1][0] - radius + 0.5, path[1][1] + 0.5, path[1][0] + 0.5, path[1][1] + radius + 0.5);
+
+                    context.lineTo(path[2][0] + 0.5, path[2][1] - radius + 0.5);
+                    context.quadraticCurveTo(path[2][0] + 0.5, path[2][1] - radius + 0.5, path[2][0] - radius + 0.5, path[2][1] + 0.5);
+
+                    context.lineTo(path[3][0] + radius + 0.5, path[3][1] + 0.5);
+                    context.quadraticCurveTo(path[3][0] + radius + 0.5, path[3][1] + 0.5, path[3][0] + 0.5, path[3][1] - radius + 0.5);
+
+                    context.lineTo(path[4][0] + 0.5, path[4][1] + radius + 0.5);
+                    context.quadraticCurveTo(path[4][0] + 0.5, path[4][1] + radius + 0.5, path[4][0] + radius + 0.5, path[4][1] + 0.5);
+
+                    done = true;
+                }
+            } 
+            if (!done) {
+              context.moveTo(path[0][0] + 0.5, path[0][1] + 0.5);
+              for (i = 1, plen = path.length; i < plen; i++) {
+                  context.lineTo(path[i][0] + 0.5, path[i][1] + 0.5); // the 0.5 offset gives us crisp pixel-width lines
+              }
+            }
+
+            if (lineColor !== undefined) {
+                context.stroke();
+            }
+            if (fillColor !== undefined) {
+                context.fill();
+            }
+            if (this.targetX !== undefined && this.targetY !== undefined &&
+                context.isPointInPath(this.targetX, this.targetY)) {
+                this.currentTargetShapeId = shapeid;
+            }
+        },
+
+        _drawCircle: function (shapeid, x, y, radius, lineColor, fillColor, lineWidth) {
+            var context = this._getContext(lineColor, fillColor, lineWidth);
+            context.beginPath();
+            context.arc(x, y, radius, 0, 2 * Math.PI, false);
+            if (this.targetX !== undefined && this.targetY !== undefined &&
+                context.isPointInPath(this.targetX, this.targetY)) {
+                this.currentTargetShapeId = shapeid;
+            }
+            if (lineColor !== undefined) {
+                context.stroke();
+            }
+            if (fillColor !== undefined) {
+                context.fill();
+            }
+        },
+
+        _drawPieSlice: function (shapeid, x, y, radius, startAngle, endAngle, lineColor, fillColor) {
+            var context = this._getContext(lineColor, fillColor);
+            context.beginPath();
+            context.moveTo(x, y);
+            context.arc(x, y, radius, startAngle, endAngle, false);
+            context.lineTo(x, y);
+            context.closePath();
+            if (lineColor !== undefined) {
+                context.stroke();
+            }
+            if (fillColor) {
+                context.fill();
+            }
+            if (this.targetX !== undefined && this.targetY !== undefined &&
+                context.isPointInPath(this.targetX, this.targetY)) {
+                this.currentTargetShapeId = shapeid;
+            }
+        },
+
+        // CUSTOM MOD: radius added
+        _drawRect: function (shapeid, x, y, width, height, lineColor, fillColor, lineWidth, radius) {
+            return this._drawShape(shapeid, [[x, y], [x + width, y], [x + width, y + height], [x, y + height], [x, y]], lineColor, fillColor, null, radius);
+        },
+
+        appendShape: function (shape) {
+            this.shapes[shape.id] = shape;
+            this.shapeseq.push(shape.id);
+            this.lastShapeId = shape.id;
+            return shape.id;
+        },
+
+        replaceWithShape: function (shapeid, shape) {
+            var shapeseq = this.shapeseq,
+                i;
+            this.shapes[shape.id] = shape;
+            for (i = shapeseq.length; i--;) {
+                if (shapeseq[i] == shapeid) {
+                    shapeseq[i] = shape.id;
+                }
+            }
+            delete this.shapes[shapeid];
+        },
+
+        replaceWithShapes: function (shapeids, shapes) {
+            var shapeseq = this.shapeseq,
+                shapemap = {},
+                sid, i, first;
+
+            for (i = shapeids.length; i--;) {
+                shapemap[shapeids[i]] = true;
+            }
+            for (i = shapeseq.length; i--;) {
+                sid = shapeseq[i];
+                if (shapemap[sid]) {
+                    shapeseq.splice(i, 1);
+                    delete this.shapes[sid];
+                    first = i;
+                }
+            }
+            for (i = shapes.length; i--;) {
+                shapeseq.splice(first, 0, shapes[i].id);
+                this.shapes[shapes[i].id] = shapes[i];
+            }
+
+        },
+
+        insertAfterShape: function (shapeid, shape) {
+            var shapeseq = this.shapeseq,
+                i;
+            for (i = shapeseq.length; i--;) {
+                if (shapeseq[i] === shapeid) {
+                    shapeseq.splice(i + 1, 0, shape.id);
+                    this.shapes[shape.id] = shape;
+                    return;
+                }
+            }
+        },
+
+        removeShapeId: function (shapeid) {
+            var shapeseq = this.shapeseq,
+                i;
+            for (i = shapeseq.length; i--;) {
+                if (shapeseq[i] === shapeid) {
+                    shapeseq.splice(i, 1);
+                    break;
+                }
+            }
+            delete this.shapes[shapeid];
+        },
+
+        getShapeAt: function (el, x, y) {
+            this.targetX = x * window.devicePixelRatio;
+            this.targetY = y * window.devicePixelRatio;
+            this.render();
+            return this.currentTargetShapeId;
+        },
+
+        render: function () {
+            var shapeseq = this.shapeseq,
+                shapes = this.shapes,
+                shapeCount = shapeseq.length,
+                context = this._getContext(),
+                shapeid, shape, i;
+            context.clearRect(0, 0, this.pixelWidth, this.pixelHeight);
+            for (i = 0; i < shapeCount; i++) {
+                shapeid = shapeseq[i];
+                shape = shapes[shapeid];
+                this['_draw' + shape.type].apply(this, shape.args);
+            }
+            if (!this.interact) {
+                // not interactive so no need to keep the shapes array
+                this.shapes = {};
+                this.shapeseq = [];
+            }
+        }
+    });
+
+
+    VCanvas_vml = createClass(VCanvas_base, {
+        init: function (width, height, target) {
+            var groupel;
+            VCanvas_vml._super.init.call(this, width, height, target);
+            if (target[0]) {
+                target = target[0];
+            }
+            $.data(target, '_jqs_vcanvas', this);
+            this.canvas = document.createElement('span');
+            $(this.canvas).css({ display: 'inline-block', position: 'relative', overflow: 'hidden', width: width, height: height, margin: '0px', padding: '0px', verticalAlign: 'top'});
+            this._insert(this.canvas, target);
+            this._calculatePixelDims(width, height, this.canvas);
+            this.canvas.width = this.pixelWidth;
+            this.canvas.height = this.pixelHeight;
+            groupel = '<v:group coordorigin="0 0" coordsize="' + this.pixelWidth + ' ' + this.pixelHeight + '"' +
+                    ' style="position:absolute;top:0;left:0;width:' + this.pixelWidth + 'px;height=' + this.pixelHeight + 'px;"></v:group>';
+            this.canvas.insertAdjacentHTML('beforeEnd', groupel);
+            this.group = $(this.canvas).children()[0];
+            this.rendered = false;
+            this.prerender = '';
+        },
+
+        _drawShape: function (shapeid, path, lineColor, fillColor, lineWidth, radius) {
+            var vpath = [],
+                initial, stroke, fill, closed, vel, plen, i;
+            for (i = 0, plen = path.length; i < plen; i++) {
+                vpath[i] = '' + (path[i][0]) + ',' + (path[i][1]);
+            }
+            initial = vpath.splice(0, 1);
+            lineWidth = lineWidth === undefined ? 1 : lineWidth;
+            stroke = lineColor === undefined ? ' stroked="false" ' : ' strokeWeight="' + lineWidth + 'px" strokeColor="' + lineColor + '" ';
+            fill = fillColor === undefined ? ' filled="false"' : ' fillColor="' + fillColor + '" filled="true" ';
+            closed = vpath[0] === vpath[vpath.length - 1] ? 'x ' : '';
+            vel = '<v:shape coordorigin="0 0" coordsize="' + this.pixelWidth + ' ' + this.pixelHeight + '" ' +
+                 ' id="jqsshape' + shapeid + '" ' +
+                 stroke +
+                 fill +
+                ' style="position:absolute;left:0px;top:0px;height:' + this.pixelHeight + 'px;width:' + this.pixelWidth + 'px;padding:0px;margin:0px;" ' +
+                ' path="m ' + initial + ' l ' + vpath.join(', ') + ' ' + closed + 'e">' +
+                ' </v:shape>';
+            return vel;
+        },
+
+        _drawCircle: function (shapeid, x, y, radius, lineColor, fillColor, lineWidth) {
+            var stroke, fill, vel;
+            x -= radius;
+            y -= radius;
+            stroke = lineColor === undefined ? ' stroked="false" ' : ' strokeWeight="' + lineWidth + 'px" strokeColor="' + lineColor + '" ';
+            fill = fillColor === undefined ? ' filled="false"' : ' fillColor="' + fillColor + '" filled="true" ';
+            vel = '<v:oval ' +
+                 ' id="jqsshape' + shapeid + '" ' +
+                stroke +
+                fill +
+                ' style="position:absolute;top:' + y + 'px; left:' + x + 'px; width:' + (radius * 2) + 'px; height:' + (radius * 2) + 'px"></v:oval>';
+            return vel;
+
+        },
+
+        _drawPieSlice: function (shapeid, x, y, radius, startAngle, endAngle, lineColor, fillColor) {
+            var vpath, startx, starty, endx, endy, stroke, fill, vel;
+            if (startAngle === endAngle) {
+                return '';  // VML seems to have problem when start angle equals end angle.
+            }
+            if ((endAngle - startAngle) === (2 * Math.PI)) {
+                startAngle = 0.0;  // VML seems to have a problem when drawing a full circle that doesn't start 0
+                endAngle = (2 * Math.PI);
+            }
+
+            startx = x + Math.round(Math.cos(startAngle) * radius);
+            starty = y + Math.round(Math.sin(startAngle) * radius);
+            endx = x + Math.round(Math.cos(endAngle) * radius);
+            endy = y + Math.round(Math.sin(endAngle) * radius);
+
+            if (startx === endx && starty === endy) {
+                if ((endAngle - startAngle) < Math.PI) {
+                    // Prevent very small slices from being mistaken as a whole pie
+                    return '';
+                }
+                // essentially going to be the entire circle, so ignore startAngle
+                startx = endx = x + radius;
+                starty = endy = y;
+            }
+
+            if (startx === endx && starty === endy && (endAngle - startAngle) < Math.PI) {
+                return '';
+            }
+
+            vpath = [x - radius, y - radius, x + radius, y + radius, startx, starty, endx, endy];
+            stroke = lineColor === undefined ? ' stroked="false" ' : ' strokeWeight="1px" strokeColor="' + lineColor + '" ';
+            fill = fillColor === undefined ? ' filled="false"' : ' fillColor="' + fillColor + '" filled="true" ';
+            vel = '<v:shape coordorigin="0 0" coordsize="' + this.pixelWidth + ' ' + this.pixelHeight + '" ' +
+                 ' id="jqsshape' + shapeid + '" ' +
+                 stroke +
+                 fill +
+                ' style="position:absolute;left:0px;top:0px;height:' + this.pixelHeight + 'px;width:' + this.pixelWidth + 'px;padding:0px;margin:0px;" ' +
+                ' path="m ' + x + ',' + y + ' wa ' + vpath.join(', ') + ' x e">' +
+                ' </v:shape>';
+            return vel;
+        },
+
+        _drawRect: function (shapeid, x, y, width, height, lineColor, fillColor, lineWidth, radius) {
+            return this._drawShape(shapeid, [[x, y], [x, y + height], [x + width, y + height], [x + width, y], [x, y]], lineColor, fillColor, lineWidth, radius);
+        },
+
+        reset: function () {
+            this.group.innerHTML = '';
+        },
+
+        appendShape: function (shape) {
+            var vel = this['_draw' + shape.type].apply(this, shape.args);
+            if (this.rendered) {
+                this.group.insertAdjacentHTML('beforeEnd', vel);
+            } else {
+                this.prerender += vel;
+            }
+            this.lastShapeId = shape.id;
+            return shape.id;
+        },
+
+        replaceWithShape: function (shapeid, shape) {
+            var existing = $('#jqsshape' + shapeid),
+                vel = this['_draw' + shape.type].apply(this, shape.args);
+            existing[0].outerHTML = vel;
+        },
+
+        replaceWithShapes: function (shapeids, shapes) {
+            // replace the first shapeid with all the new shapes then toast the remaining old shapes
+            var existing = $('#jqsshape' + shapeids[0]),
+                replace = '',
+                slen = shapes.length,
+                i;
+            for (i = 0; i < slen; i++) {
+                replace += this['_draw' + shapes[i].type].apply(this, shapes[i].args);
+            }
+            existing[0].outerHTML = replace;
+            for (i = 1; i < shapeids.length; i++) {
+                $('#jqsshape' + shapeids[i]).remove();
+            }
+        },
+
+        insertAfterShape: function (shapeid, shape) {
+            var existing = $('#jqsshape' + shapeid),
+                 vel = this['_draw' + shape.type].apply(this, shape.args);
+            existing[0].insertAdjacentHTML('afterEnd', vel);
+        },
+
+        removeShapeId: function (shapeid) {
+            var existing = $('#jqsshape' + shapeid);
+            this.group.removeChild(existing[0]);
+        },
+
+        getShapeAt: function (el, x, y) {
+            var shapeid = el.id.substr(8);
+            return shapeid;
+        },
+
+        render: function () {
+            if (!this.rendered) {
+                // batch the intial render into a single repaint
+                this.group.innerHTML = this.prerender;
+                this.rendered = true;
+            }
+        }
+    });
+
+
+}));
+
+}(document, Math));
+</script>
+<script>HTMLWidgets.widget({
+  name: "sparkline",
+  type: "output",
+  factory: function(el, width, height) {
+    
+    var instance = {};
+    
+    return {
+
+      renderValue: function(data) {
+        
+        $(el).empty();
+
+        // if renderTag provided then we will do three things
+        //   1.  set height and width to 0 and display none
+        //   2.  set our el to the render tag if available
+        //   3.  set height and width options to null
+        if(data.renderSelector && $(data.renderSelector).length){
+          $(el).css({
+            'height': '0',
+            'width': '0',
+            'display': 'none'
+          });
+          el = data.renderSelector;
+          // set height and width to null
+          //   this might be confusing and need to be reverted
+          data.options.height = null;
+          data.options.width = null;
+        }
+        $(el).sparkline(data.values, data.options);
+        
+        // experimental addComposite function in R
+        //   will add composites to data.composites
+        if(data.composites) {
+          if(!Array.isArray(data.composites)) {
+            data.composites = [data.composites];
+          }
+          data.composites.map( function(spk) {
+            $(el).sparkline(spk.values,spk.options);
+          });
+        }
+        
+        instance.data = data;
+      },
+
+      resize: function(width, height) {
+
+        // not sure what to do in the event of resize
+        //  I think nothing for now
+        //  but will need to get a feel for use cases
+        //  where this is important such as slides, flexdashboard, tabset
+        this.renderValue(instance.data);
+
+      }
+
+    };
+  }  
+});
+</script>
 
 <style type="text/css">code{white-space: pre;}</style>
 <style type="text/css">
@@ -1909,7 +6481,7 @@
 </div>
 <div id="bootstrap-theme" class="section level2">
 <h2>Bootstrap theme</h2>
-<p>When used on a HTML table, <code>kable_styling()</code> will automatically apply twitter bootstrap theme to the table. Now it should looks the same as the original pandoc output (the one when you don’t specify <code>format</code> in <code>kbl()</code>) but this time, you are controlling it.</p>
+<p>When used on a HTML table, <code>kable_styling()</code> will automatically apply twitter bootstrap theme to the table. Now it should looks the same as the original pandoc output (the one when you don’t specify <code>format</code> in <code>kable()</code>) but this time, you are controlling it.</p>
 <pre class="r"><code>dt %&gt;%
   kbl() %&gt;%
   kable_styling()</code></pre>
@@ -6451,7 +11023,7 @@
 1
 </td>
 <td style="text-align:center;">
-0
+1
 </td>
 </tr>
 <tr>
@@ -6459,7 +11031,7 @@
 2
 </td>
 <td style="text-align:center;">
-1
+0
 </td>
 </tr>
 <tr>
@@ -6467,7 +11039,7 @@
 3
 </td>
 <td style="text-align:center;">
-1
+0
 </td>
 </tr>
 <tr>
@@ -6510,7 +11082,7 @@
 8
 </td>
 <td style="text-align:center;">
-0
+1
 </td>
 </tr>
 <tr>
@@ -6526,7 +11098,7 @@
 10
 </td>
 <td style="text-align:center;">
-1
+0
 </td>
 </tr>
 <tr>
@@ -6548,7 +11120,7 @@
 12
 </td>
 <td style="text-align:center;">
-0
+1
 </td>
 </tr>
 <tr>
@@ -6559,7 +11131,7 @@
 13
 </td>
 <td style="text-align:center;">
-0
+1
 </td>
 </tr>
 <tr>
@@ -6567,7 +11139,7 @@
 14
 </td>
 <td style="text-align:center;">
-1
+0
 </td>
 </tr>
 <tr>
@@ -11863,6 +16435,53 @@
   kable_styling() %&gt;%
   save_kable(file = &quot;table1.html&quot;, self_contained = T)</code></pre>
 </div>
+<div id="use-it-with-sparkline" class="section level2">
+<h2>Use it with sparkline</h2>
+<p>Well, this is not a feature but rather a documentation of how to use the <code>sparkline</code> package together with this package. The easiest way is sort of a hack. You can call <code>sparkline::sparkline(0)</code> somewhere on your document where no one would mind so its dependencies could be loaded without any hurdles. Then you use <code>sparkline::spk_chr()</code> to generate the text. Here is another example: <a href="https://cranky-chandrasekhar-cfefcd.netlify.app/">Chinese names in US babynames</a></p>
+<pre class="r"><code>library(sparkline)
+sparkline(0)</code></pre>
+<span id="htmlwidget-749226e66b9fa596d145" class="sparkline html-widget"></span>
+<script type="application/json" data-for="htmlwidget-749226e66b9fa596d145">{"x":{"values":0,"options":{"height":20,"width":60},"width":60,"height":20},"evals":[],"jsHooks":[]}</script>
+<pre class="r"><code>spk_dt &lt;- data.frame(
+  var = c(&quot;mpg&quot;, &quot;wt&quot;),
+  sparkline = c(spk_chr(mtcars$mpg), spk_chr(mtcars$wt))
+)
+
+kbl(spk_dt, escape = F) %&gt;%
+  kable_paper(full_width = F)</code></pre>
+<table class=" lightable-paper" style="font-family: &quot;Arial Narrow&quot;, arial, helvetica, sans-serif; width: auto !important; margin-left: auto; margin-right: auto;">
+<thead>
+<tr>
+<th style="text-align:left;">
+var
+</th>
+<th style="text-align:left;">
+sparkline
+</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td style="text-align:left;">
+mpg
+</td>
+<td style="text-align:left;">
+<span id="htmlwidget-01f5d4d060b2fac4517e" class="sparkline html-widget"></span>
+<script type="application/json" data-for="htmlwidget-01f5d4d060b2fac4517e">{"x":{"values":[21,21,22.8,21.4,18.7,18.1,14.3,24.4,22.8,19.2,17.8,16.4,17.3,15.2,10.4,10.4,14.7,32.4,30.4,33.9,21.5,15.5,15.2,13.3,19.2,27.3,26,30.4,15.8,19.7,15,21.4],"options":{"height":20,"width":60},"width":60,"height":20},"evals":[],"jsHooks":[]}</script>
+</td>
+</tr>
+<tr>
+<td style="text-align:left;">
+wt
+</td>
+<td style="text-align:left;">
+<span id="htmlwidget-78061f9e6c3128c1d82d" class="sparkline html-widget"></span>
+<script type="application/json" data-for="htmlwidget-78061f9e6c3128c1d82d">{"x":{"values":[2.62,2.875,2.32,3.215,3.44,3.46,3.57,3.19,3.15,3.44,3.44,4.07,3.73,3.78,5.25,5.424,5.345,2.2,1.615,1.835,2.465,3.52,3.435,3.84,3.845,1.935,2.14,1.513,3.17,2.77,3.57,2.78],"options":{"height":20,"width":60},"width":60,"height":20},"evals":[],"jsHooks":[]}</script>
+</td>
+</tr>
+</tbody>
+</table>
+</div>
 </div>
 <div id="from-other-packages" class="section level1">
 <h1>From other packages</h1>
