diff --git a/DESCRIPTION b/DESCRIPTION
index ba72bbf..c3d997e 100644
--- a/DESCRIPTION
+++ b/DESCRIPTION
@@ -37,7 +37,6 @@
     xml2 (>= 1.1.1),
     rvest,
     rmarkdown (>= 1.6.0),
-    readr,
     scales, 
     viridisLite,
     stats,
@@ -52,8 +51,7 @@
     testthat,
     magick,
     formattable,
-    dplyr,
-    sparkline
+    dplyr
 VignetteBuilder: knitr
 Encoding: UTF-8
 RoxygenNote: 7.1.1
diff --git a/NAMESPACE b/NAMESPACE
index 4dafc68..59c7f51 100644
--- a/NAMESPACE
+++ b/NAMESPACE
@@ -59,8 +59,6 @@
 importFrom(knitr,knit_meta_add)
 importFrom(knitr,knit_print)
 importFrom(magrittr,"%>%")
-importFrom(readr,read_file)
-importFrom(readr,read_lines)
 importFrom(rmarkdown,html_dependency_bootstrap)
 importFrom(rmarkdown,html_dependency_jquery)
 importFrom(rmarkdown,latex_dependency)
diff --git a/R/kableExtra-package.R b/R/kableExtra-package.R
index c01f058..35617e1 100644
--- a/R/kableExtra-package.R
+++ b/R/kableExtra-package.R
@@ -66,7 +66,6 @@
 #' html_dependency_jquery pandoc_self_contained_html
 #' @importFrom magrittr %>%
 #' @importFrom utils read.csv head capture.output
-#' @importFrom readr read_lines read_file
 #' @importFrom scales rescale
 #' @importFrom viridisLite viridis
 #' @importFrom stats ave
diff --git a/R/kable_styling.R b/R/kable_styling.R
index 9be4bcc..10dfb4f 100644
--- a/R/kable_styling.R
+++ b/R/kable_styling.R
@@ -438,7 +438,7 @@
 styling_latex_repeat_header <- function(x, table_info, repeat_header_text,
                                         repeat_header_method,
                                         repeat_header_continued) {
-  x <- read_lines(x)
+  x <- str_split(x, "\n")[[1]]
   if (table_info$booktabs) {
     header_rows_start <- which(x == "\\toprule")[1]
     if (is.null(table_info$colnames)) {
diff --git a/docs/awesome_table_in_html.Rmd b/docs/awesome_table_in_html.Rmd
index 7ae49b6..9b1eea9 100644
--- a/docs/awesome_table_in_html.Rmd
+++ b/docs/awesome_table_in_html.Rmd
@@ -536,14 +536,15 @@
 ```
 
 ## 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/)
+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. For a working example, see: [Chinese names in US babynames](https://cranky-chandrasekhar-cfefcd.netlify.app/)
 
-```{r}
+```{r, eval=FALSE}
+# Not evaluated
 library(sparkline)
 sparkline(0)
 ```
 
-```{r}
+```{r,eval=FALSE}
 spk_dt <- data.frame(
   var = c("mpg", "wt"),
   sparkline = c(spk_chr(mtcars$mpg), spk_chr(mtcars$wt))
diff --git a/docs/awesome_table_in_html.html b/docs/awesome_table_in_html.html
index 5f28af0..40f4a07 100644
--- a/docs/awesome_table_in_html.html
+++ b/docs/awesome_table_in_html.html
@@ -1489,4578 +1489,6 @@
 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">
@@ -11032,7 +6460,7 @@
 2
 </td>
 <td style="text-align:center;">
-1
+0
 </td>
 </tr>
 <tr>
@@ -11072,7 +6500,7 @@
 7
 </td>
 <td style="text-align:center;">
-0
+1
 </td>
 </tr>
 <tr>
@@ -11091,7 +6519,7 @@
 9
 </td>
 <td style="text-align:center;">
-0
+1
 </td>
 </tr>
 <tr>
@@ -11113,7 +6541,7 @@
 11
 </td>
 <td style="text-align:center;">
-0
+1
 </td>
 </tr>
 <tr>
@@ -16438,11 +11866,10 @@
 </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)
+<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. For a working example, see: <a href="https://cranky-chandrasekhar-cfefcd.netlify.app/">Chinese names in US babynames</a></p>
+<pre class="r"><code># Not evaluated
+library(sparkline)
 sparkline(0)</code></pre>
-<span id="htmlwidget-fe2aeadaaa92a48c86ee" class="sparkline html-widget"></span>
-<script type="application/json" data-for="htmlwidget-fe2aeadaaa92a48c86ee">{"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))
@@ -16450,38 +11877,6 @@
 
 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-fdddfe62cb83547210eb" class="sparkline html-widget"></span>
-<script type="application/json" data-for="htmlwidget-fdddfe62cb83547210eb">{"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-da7e098e9f570e71333f" class="sparkline html-widget"></span>
-<script type="application/json" data-for="htmlwidget-da7e098e9f570e71333f">{"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">
diff --git a/inst/NEWS.md b/inst/NEWS.md
index 0ee80d9..b3d9fb2 100644
--- a/inst/NEWS.md
+++ b/inst/NEWS.md
@@ -46,7 +46,7 @@
 * Added `monospace`, `underline`, `strikeout`, `color` and `background` to 
 `pack_rows()`. (#412)
 
-
+* Added documentation for how to use `sparkline`.
 
 
 # Bug Fix
@@ -79,7 +79,11 @@
 * Fixed the `include_empty` option in `add_header_above`. (#367, #393, thanks 
 @trianglegirl)
 
+* Fixed a bug with `pack_rows` when escape is `F`. (#396)
 
+* Fixed a bug with `collapse_rows` when used together with `pack_rows`. (#430)
+
+* Fixed a bug with `pack_rows` when longtable is enabled. (#410)
 
 
  
diff --git a/man/group_rows.Rd b/man/group_rows.Rd
index 1bcb78a..30c5a4b 100644
--- a/man/group_rows.Rd
+++ b/man/group_rows.Rd
@@ -108,8 +108,9 @@
 \item{indent}{A T/F value to control whether list items are indented.}
 
 \item{monospace}{T/F value to control whether the text of the
-selected column need to be monospaced (verbatim)
-#' @param underline T/F value to control whether the text of the
+selected column need to be monospaced (verbatim)}
+
+\item{underline}{T/F value to control whether the text of the
 selected row need to be underlined}
 
 \item{strikeout}{T/F value to control whether the text of the
