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