[Pkg-javascript-commits] [eonasdan-bootstrap-datetimepicker] 01/06: New upstream version 4.17.42

Mathias Behrle mbehrle at moszumanska.debian.org
Thu Sep 8 12:12:19 UTC 2016


This is an automated email from the git hooks/post-receive script.

mbehrle pushed a commit to branch master
in repository eonasdan-bootstrap-datetimepicker.

commit 5c2e7c00d02955d4393e373d8913c1cb67462185
Author: Mathias Behrle <mathiasb at m9s.biz>
Date:   Tue Sep 6 14:58:49 2016 +0200

    New upstream version 4.17.42
---
 .gitignore                                        |   2 +-
 .jscs.json                                        |   2 +-
 Gruntfile.js                                      |  99 ++--
 README.md                                         |  11 +-
 bower.json                                        |   5 +-
 build/css/bootstrap-datetimepicker-standalone.css |   7 +-
 build/css/bootstrap-datetimepicker.css            |  10 +-
 build/css/bootstrap-datetimepicker.min.css        |   2 +-
 build/js/bootstrap-datetimepicker.min.js          | 211 +++++++-
 component.json                                    |   4 +-
 composer.json                                     |   4 +-
 docs/ChangeLog.md                                 |  15 +
 docs/Events.md                                    |   3 +-
 docs/Functions.md                                 | 590 +---------------------
 docs/Options.md                                   | 534 ++++++++++++++++++--
 docs/index.md                                     |  54 +-
 docs/theme/android-chrome-144x144.png             | Bin 0 -> 40227 bytes
 docs/theme/android-chrome-192x192.png             | Bin 0 -> 68963 bytes
 docs/theme/android-chrome-36x36.png               | Bin 0 -> 3800 bytes
 docs/theme/android-chrome-48x48.png               | Bin 0 -> 5971 bytes
 docs/theme/android-chrome-72x72.png               | Bin 0 -> 11838 bytes
 docs/theme/android-chrome-96x96.png               | Bin 0 -> 19482 bytes
 docs/theme/apple-touch-icon-114x114.png           | Bin 0 -> 26475 bytes
 docs/theme/apple-touch-icon-120x120.png           | Bin 0 -> 29019 bytes
 docs/theme/apple-touch-icon-144x144.png           | Bin 0 -> 40227 bytes
 docs/theme/apple-touch-icon-152x152.png           | Bin 0 -> 44355 bytes
 docs/theme/apple-touch-icon-180x180.png           | Bin 0 -> 60935 bytes
 docs/theme/apple-touch-icon-57x57.png             | Bin 0 -> 7933 bytes
 docs/theme/apple-touch-icon-60x60.png             | Bin 0 -> 8684 bytes
 docs/theme/apple-touch-icon-72x72.png             | Bin 0 -> 11838 bytes
 docs/theme/apple-touch-icon-76x76.png             | Bin 0 -> 13014 bytes
 docs/theme/apple-touch-icon-precomposed.png       | Bin 0 -> 65745 bytes
 docs/theme/apple-touch-icon.png                   | Bin 0 -> 60935 bytes
 docs/theme/base.html                              |  74 +++
 docs/theme/browserconfig.xml                      |  12 +
 docs/theme/content.html                           |   9 +
 docs/theme/css/base.css                           | 107 ++++
 docs/theme/css/prettify-1.0.css                   |  28 +
 docs/theme/favicon-16x16.png                      | Bin 0 -> 1433 bytes
 docs/theme/favicon-32x32.png                      | Bin 0 -> 3187 bytes
 docs/theme/favicon-96x96.png                      | Bin 0 -> 19482 bytes
 docs/theme/favicon.ico                            | Bin 0 -> 12014 bytes
 docs/theme/js/base.js                             |  52 ++
 docs/theme/js/prettify-1.0.min.js                 |  28 +
 docs/theme/manifest.json                          |  41 ++
 docs/theme/mstile-144x144.png                     | Bin 0 -> 42796 bytes
 docs/theme/mstile-150x150.png                     | Bin 0 -> 36570 bytes
 docs/theme/mstile-310x150.png                     | Bin 0 -> 38916 bytes
 docs/theme/mstile-310x310.png                     | Bin 0 -> 144673 bytes
 docs/theme/mstile-70x70.png                       | Bin 0 -> 21052 bytes
 docs/theme/nav.html                               |  76 +++
 docs/theme/toc.html                               |  10 +
 mkdocs.yml                                        | 209 +++++++-
 package.json                                      |  84 +--
 src/js/bootstrap-datetimepicker.js                | 267 ++++++----
 src/less/_bootstrap-datetimepicker.less           |   2 +-
 src/sass/_bootstrap-datetimepicker.scss           |   5 +-
 test/publicApiSpec.js                             | 474 ++++++++++++++++-
 test/timezoneDataHelper.js                        |  11 +
 59 files changed, 2169 insertions(+), 873 deletions(-)

diff --git a/.gitignore b/.gitignore
index f118199..631b904 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,7 +4,7 @@ node_modules
 .vs
 obj
 bin
-site/
+site
 *.user
 *.csproj
 *.sln
diff --git a/.jscs.json b/.jscs.json
index 8af2b61..96ddb20 100644
--- a/.jscs.json
+++ b/.jscs.json
@@ -36,7 +36,7 @@
     "requireBlocksOnNewline": true,
     "disallowPaddingNewlinesInBlocks": true,
     "disallowEmptyBlocks": true,
-    "disallowSpacesInsideObjectBrackets": true,
+    "disallowSpacesInsideObjectBrackets": false,
     "disallowSpacesInsideArrayBrackets": true,
     "disallowSpacesInsideParentheses": true,
     "requireCommaBeforeLineBreak": true,
diff --git a/Gruntfile.js b/Gruntfile.js
index a13ab2b..61e577a 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -2,11 +2,10 @@ module.exports = function (grunt) {
     'use strict';
     grunt.initConfig({
         pkg: grunt.file.readJSON('package.json'),
-
-        uglify : {
+        uglify: {
             target: {
                 files: {
-                    'build/js/bootstrap-datetimepicker.min.js' : 'src/js/bootstrap-datetimepicker.js'
+                    'build/js/bootstrap-datetimepicker.min.js': 'src/js/bootstrap-datetimepicker.js'
                 }
             },
             options: {
@@ -21,41 +20,40 @@ module.exports = function (grunt) {
                 preserveComments: 'some'
             }
         },
-
         jshint: {
             all: [
                 'Gruntfile.js', 'src/js/*.js', 'test/*.js'
             ],
             options: {
-                'browser'  : true,
-                'node'     : true,
-                'jquery'   : true,
-                'boss'     : false,
-                'curly'    : true,
-                'debug'    : false,
-                'devel'    : false,
-                'eqeqeq'   : true,
-                'bitwise'  : true,
-                'eqnull'   : true,
-                'evil'     : false,
-                'forin'    : true,
-                'immed'    : false,
-                'laxbreak' : false,
-                'newcap'   : true,
-                'noarg'    : true,
-                'noempty'  : false,
-                'nonew'    : false,
-                'onevar'   : true,
-                'plusplus' : false,
-                'regexp'   : false,
-                'undef'    : true,
-                'sub'      : true,
-                'strict'   : true,
-                'unused'   : true,
-                'white'    : true,
-                'es3'      : true,
-                'camelcase' : true,
-                'quotmark' : 'single',
+                'browser': true,
+                'node': true,
+                'jquery': true,
+                'boss': false,
+                'curly': true,
+                'debug': false,
+                'devel': false,
+                'eqeqeq': true,
+                'bitwise': true,
+                'eqnull': true,
+                'evil': false,
+                'forin': true,
+                'immed': false,
+                'laxbreak': false,
+                'newcap': true,
+                'noarg': true,
+                'noempty': false,
+                'nonew': false,
+                'onevar': true,
+                'plusplus': false,
+                'regexp': false,
+                'undef': true,
+                'sub': true,
+                'strict': true,
+                'unused': true,
+                'white': true,
+                'es3': true,
+                'camelcase': true,
+                'quotmark': 'single',
                 'globals': {
                     'define': false,
                     'moment': false,
@@ -72,7 +70,6 @@ module.exports = function (grunt) {
                 }
             }
         },
-
         jscs: {
             all: [
                 'Gruntfile.js', 'src/js/*.js', 'test/*.js'
@@ -81,7 +78,6 @@ module.exports = function (grunt) {
                 config: '.jscs.json'
             }
         },
-
         less: {
             production: {
                 options: {
@@ -102,13 +98,25 @@ module.exports = function (grunt) {
                 }
             }
         },
-
+        env: {
+            paris: {
+                TZ: 'Europe/Paris' // sets env for phantomJS https://github.com/ariya/phantomjs/issues/10379#issuecomment-36058589
+            }
+        },
+        connect: {
+            server: {
+                options: {
+                    port: 8099
+                }
+            }
+        },
         jasmine: {
             customTemplate: {
                 src: 'src/js/*.js',
                 options: {
                     specs: 'test/*Spec.js',
                     helpers: 'test/*Helper.js',
+                    host: 'http://127.0.0.1:8099',
                     styles: [
                         'node_modules/bootstrap/dist/css/bootstrap.min.css',
                         'build/css/bootstrap-datetimepicker.min.css'
@@ -116,6 +124,7 @@ module.exports = function (grunt) {
                     vendor: [
                         'node_modules/jquery/dist/jquery.min.js',
                         'node_modules/moment/min/moment-with-locales.min.js',
+                        'node_modules/moment-timezone/moment-timezone.js',
                         'node_modules/bootstrap/dist/js/bootstrap.min.js'
                     ],
                     display: 'none',
@@ -123,7 +132,6 @@ module.exports = function (grunt) {
                 }
             }
         },
-
         nugetpack: {
             less: {
                 src: 'src/nuget/Bootstrap.v3.Datetimepicker.nuspec',
@@ -144,31 +152,26 @@ module.exports = function (grunt) {
 
     grunt.loadTasks('tasks');
 
+    grunt.loadNpmTasks('grunt-env');
+    grunt.loadNpmTasks('grunt-contrib-connect');
     grunt.loadNpmTasks('grunt-contrib-jasmine');
     grunt.loadNpmTasks('grunt-nuget');
 
-    // These plugins provide necessary tasks.
     require('load-grunt-tasks')(grunt);
-
-    // Default task.
-    grunt.registerTask('default', ['jshint', 'jscs', 'less', 'jasmine']);
-
-    // travis build task
+    grunt.registerTask('default', ['jshint', 'jscs', 'less', 'env:paris', 'connect', 'jasmine']);
     grunt.registerTask('build:travis', [
         // code style
         'jshint', 'jscs',
         // build
         'uglify', 'less',
         // tests
-        'jasmine'
+        'env:paris', 'connect', 'jasmine'
     ]);
 
     // Task to be run when building
-    grunt.registerTask('build', [
-        'jshint', 'jscs', 'uglify', 'less'
-    ]);
+    grunt.registerTask('build', ['jshint', 'jscs', 'uglify', 'less']);
 
-    grunt.registerTask('test', ['jshint', 'jscs', 'uglify', 'less', 'jasmine']);
+    grunt.registerTask('test', ['jshint', 'jscs', 'uglify', 'less', 'env:paris', 'connect', 'jasmine']);
 
     grunt.registerTask('docs', 'Generate docs', function () {
         grunt.util.spawn({
diff --git a/README.md b/README.md
index e63012c..357bf1e 100644
--- a/README.md
+++ b/README.md
@@ -1,11 +1,18 @@
 # Bootstrap 3 Date/Time Picker
-![GitHub version](https://badge.fury.io/gh/Eonasdan%2Fbootstrap-datetimepicker.png)   ![Travis](https://travis-ci.org/Eonasdan/bootstrap-datetimepicker.svg?branch=development)   [![Stories in Ready](https://badge.waffle.io/Eonasdan/bootstrap-datetimepicker.png?label=ready&title=Ready)](https://waffle.io/Eonasdan/bootstrap-datetimepicker)
+![GitHub version](https://badge.fury.io/gh/Eonasdan%2Fbootstrap-datetimepicker.png)   ![Travis](https://travis-ci.org/Eonasdan/bootstrap-datetimepicker.svg?branch=development)
 
 ![DateTimePicker](http://i.imgur.com/nfnvh5g.png)
 
 ## [View the manual and demos](http://eonasdan.github.io/bootstrap-datetimepicker/)
 
-# v4.17.37
+#Notice
+The issue tracker is now solely for bug reports.
+
+SO: http://stackoverflow.com/tags/eonasdan-datetimepicker
+
+New issues that are requests for "how do I.." will be closed and redirected to Stack Overflow.
+
+# v4.17.42
 
 Is the current stable release. The latest and greatest changes are available from the [development branch](https://github.com/Eonasdan/bootstrap-datetimepicker/tree/development)
 
diff --git a/bower.json b/bower.json
index 208176a..e8f47e7 100644
--- a/bower.json
+++ b/bower.json
@@ -1,14 +1,13 @@
 {
   "name": "eonasdan-bootstrap-datetimepicker",
-  "version": "4.17.37",
+  "version": "4.17.42",
   "main": [
     "build/css/bootstrap-datetimepicker.min.css",
     "build/js/bootstrap-datetimepicker.min.js"
   ],
   "dependencies": {
     "jquery": ">=1.8.3",
-    "moment": ">=2.9.0",
-    "moment-timezone": ">=0.4.0"
+    "moment": ">=2.10.5"
   },
   "homepage": "https://github.com/Eonasdan/bootstrap-datetimepicker",
   "authors": [
diff --git a/build/css/bootstrap-datetimepicker-standalone.css b/build/css/bootstrap-datetimepicker-standalone.css
index 49e3ea6..e2f9dbf 100644
--- a/build/css/bootstrap-datetimepicker-standalone.css
+++ b/build/css/bootstrap-datetimepicker-standalone.css
@@ -1,8 +1,3 @@
-/*!
- * Datetimepicker for Bootstrap 3
- * version : 4.17.37
- * https://github.com/Eonasdan/bootstrap-datetimepicker/
- */
 @font-face {
     font-family: 'Glyphicons Halflings';
     src: url('../fonts/glyphicons-halflings-regular.eot');
@@ -100,4 +95,4 @@
 .list-unstyled {
     padding-left: 0;
     list-style: none;
-}
\ No newline at end of file
+}
diff --git a/build/css/bootstrap-datetimepicker.css b/build/css/bootstrap-datetimepicker.css
index b8bf43b..33a05fa 100644
--- a/build/css/bootstrap-datetimepicker.css
+++ b/build/css/bootstrap-datetimepicker.css
@@ -1,6 +1,6 @@
 /*!
  * Datetimepicker for Bootstrap 3
- * version : 4.17.37
+ * version : 4.17.42
  * https://github.com/Eonasdan/bootstrap-datetimepicker/
  */
 .bootstrap-datetimepicker-widget {
@@ -35,7 +35,7 @@
 .bootstrap-datetimepicker-widget.dropdown-menu.bottom:before {
   border-left: 7px solid transparent;
   border-right: 7px solid transparent;
-  border-bottom: 7px solid #cccccc;
+  border-bottom: 7px solid #ccc;
   border-bottom-color: rgba(0, 0, 0, 0.2);
   top: -7px;
   left: 7px;
@@ -50,7 +50,7 @@
 .bootstrap-datetimepicker-widget.dropdown-menu.top:before {
   border-left: 7px solid transparent;
   border-right: 7px solid transparent;
-  border-top: 7px solid #cccccc;
+  border-top: 7px solid #ccc;
   border-top-color: rgba(0, 0, 0, 0.2);
   bottom: -7px;
   left: 6px;
@@ -310,7 +310,7 @@
 .bootstrap-datetimepicker-widget table td.active,
 .bootstrap-datetimepicker-widget table td.active:hover {
   background-color: #337ab7;
-  color: #ffffff;
+  color: #fff;
   text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
 }
 .bootstrap-datetimepicker-widget table td.active.today:before {
@@ -336,7 +336,7 @@
 }
 .bootstrap-datetimepicker-widget table td span.active {
   background-color: #337ab7;
-  color: #ffffff;
+  color: #fff;
   text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
 }
 .bootstrap-datetimepicker-widget table td span.old {
diff --git a/build/css/bootstrap-datetimepicker.min.css b/build/css/bootstrap-datetimepicker.min.css
index 63c2a3a..2ee13b0 100644
--- a/build/css/bootstrap-datetimepicker.min.css
+++ b/build/css/bootstrap-datetimepicker.min.css
@@ -1,5 +1,5 @@
 /*!
  * Datetimepicker for Bootstrap 3
- * version : 4.17.37
+ * version : 4.17.42
  * https://github.com/Eonasdan/bootstrap-datetimepicker/
  */.bootstrap-datetimepicker-widget{list-style:none}.bootstrap-datetimepicker-widget.dropdown-menu{margin:2px 0;padding:4px;width:19em}@media (min-width:768px){.bootstrap-datetimepicker-widget.dropdown-menu.timepicker-sbs{width:38em}}@media (min-width:992px){.bootstrap-datetimepicker-widget.dropdown-menu.timepicker-sbs{width:38em}}@media (min-width:1200px){.bootstrap-datetimepicker-widget.dropdown-menu.timepicker-sbs{width:38em}}.bootstrap-datetimepicker-widget.dropdown-menu:before,.boot [...]
\ No newline at end of file
diff --git a/build/js/bootstrap-datetimepicker.min.js b/build/js/bootstrap-datetimepicker.min.js
index db3d085..a953fe0 100644
--- a/build/js/bootstrap-datetimepicker.min.js
+++ b/build/js/bootstrap-datetimepicker.min.js
@@ -1,9 +1,214 @@
-/*! version : 4.17.37
+/*! version : 4.17.42
  =========================================================
  bootstrap-datetimejs
  https://github.com/Eonasdan/bootstrap-datetimepicker
  Copyright (c) 2015 Jonathan Peterson
  =========================================================
  */
-!function(a){"use strict";if("function"==typeof define&&define.amd)define(["jquery","moment"],a);else if("object"==typeof exports)a(require("jquery"),require("moment"));else{if("undefined"==typeof jQuery)throw"bootstrap-datetimepicker requires jQuery to be loaded first";if("undefined"==typeof moment)throw"bootstrap-datetimepicker requires Moment.js to be loaded first";a(jQuery,moment)}}(function(a,b){"use strict";if(!b)throw new Error("bootstrap-datetimepicker requires Moment.js to be lo [...]
-if("function"!=typeof a)throw new TypeError("parseInputDate() sholud be as function");return d.parseInputDate=a,l},l.disabledTimeIntervals=function(b){if(0===arguments.length)return d.disabledTimeIntervals?a.extend({},d.disabledTimeIntervals):d.disabledTimeIntervals;if(!b)return d.disabledTimeIntervals=!1,$(),l;if(!(b instanceof Array))throw new TypeError("disabledTimeIntervals() expects an array parameter");return d.disabledTimeIntervals=b,$(),l},l.disabledHours=function(b){if(0===argum [...]
\ No newline at end of file
+/*
+ The MIT License (MIT)
+
+ Copyright (c) 2015 Jonathan Peterson
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ */
+/*global define:false */
+/*global exports:false */
+/*global require:false */
+/*global jQuery:false */
+/*global moment:false */
+!function(a){"use strict";if("function"==typeof define&&define.amd)
+// AMD is used - Register as an anonymous module.
+define(["jquery","moment"],a);else if("object"==typeof exports)a(require("jquery"),require("moment"));else{
+// Neither AMD nor CommonJS used. Use global variables.
+if("undefined"==typeof jQuery)throw"bootstrap-datetimepicker requires jQuery to be loaded first";if("undefined"==typeof moment)throw"bootstrap-datetimepicker requires Moment.js to be loaded first";a(jQuery,moment)}}(function(a,b){"use strict";if(!b)throw new Error("bootstrap-datetimepicker requires Moment.js to be loaded first");var c=function(c,d){var e,f,g,h,i,j,k,l={},m=!0,n=!1,o=!1,p=0,q=[{clsName:"days",navFnc:"M",navStep:1},{clsName:"months",navFnc:"y",navStep:1},{clsName:"years",n [...]
+             *
+             * Private functions
+             *
+             ********************************************************************************/
+x=function(){return void 0!==b.tz&&void 0!==d.timeZone&&null!==d.timeZone&&""!==d.timeZone},y=function(a){var c;return c=void 0===a||null===a?b():x()?b.tz(a,j,d.useStrict,d.timeZone):b(a,j,d.useStrict),x()&&c.tz(d.timeZone),c},z=function(a){if("string"!=typeof a||a.length>1)throw new TypeError("isEnabled expects a single character string parameter");switch(a){case"y":return-1!==i.indexOf("Y");case"M":return-1!==i.indexOf("M");case"d":return-1!==i.toLowerCase().indexOf("d");case"h":case"H [...]
+// Top and bottom logic
+"auto"===g&&(g=f.top+1.5*o.height()>=a(window).height()+a(window).scrollTop()&&o.height()+c.outerHeight()<f.top?"top":"bottom"),
+// Left and right logic
+"auto"===h&&(h=b.width()<f.left+o.outerWidth()/2&&f.left+o.outerWidth()>a(window).width()?"right":"left"),"top"===g?o.addClass("top").removeClass("bottom"):o.addClass("bottom").removeClass("top"),"right"===h?o.addClass("pull-right"):o.removeClass("pull-right"),
+// find the first parent element that has a relative css positioning
+"relative"!==b.css("position")&&(b=b.parents().filter(function(){return"relative"===a(this).css("position")}).first()),0===b.length)throw new Error("datetimepicker component should be placed within a relative positioned container");o.css({top:"top"===g?"auto":e.top+c.outerHeight(),bottom:"top"===g?b.outerHeight()-(b===c?0:e.top):"auto",left:"left"===h?b===c?0:e.left:"auto",right:"left"===h?"auto":b.outerWidth()-c.outerWidth()-(b===c?0:e.left)})},J=function(a){"dp.change"===a.type&&(a.dat [...]
+0===b.weekday()&&(c=a("<tr>"),d.calendarWeeks&&c.append('<td class="cw">'+b.week()+"</td>"),k.push(c)),g="",b.isBefore(f,"M")&&(g+=" old"),b.isAfter(f,"M")&&(g+=" new"),b.isSame(e,"d")&&!m&&(g+=" active"),R(b,"d")||(g+=" disabled"),b.isSame(y(),"d")&&(g+=" today"),0!==b.day()&&6!==b.day()||(g+=" weekend"),c.append('<td data-action="selectDay" data-day="'+b.format("L")+'" class="day'+g+'">'+b.date()+"</td>"),b.add(1,"d");i.find("tbody").empty().append(k),T(),U(),V()}},X=function(){var b=o [...]
+// case of calling setValue(null or false)
+// case of calling setValue(null or false)
+//viewDate = date.clone(); // TODO this doesn't work right on first use
+return a?(a=a.clone().locale(d.locale),x()&&a.tz(d.timeZone),1!==d.stepping&&a.minutes(Math.round(a.minutes()/d.stepping)*d.stepping).seconds(0),void(R(a)?(e=a,g.val(e.format(i)),c.data("date",e.format(i)),m=!1,_(),J({type:"dp.change",date:e.clone(),oldDate:b})):(d.keepInvalid?J({type:"dp.change",date:a,oldDate:b}):g.val(m?"":e.format(i)),J({type:"dp.error",date:a,oldDate:b})))):(m=!0,g.val(""),c.data("date",""),J({type:"dp.change",date:!1,oldDate:b}),void _())},/**
+             * Hides the widget. Possibly will emit dp.hide
+             */
+ba=function(){var b=!1;
+// Ignore event if in the middle of a picker transition
+return o?(o.find(".collapse").each(function(){var c=a(this).data("collapse");return c&&c.transitioning?(b=!0,!1):!0}),b?l:(n&&n.hasClass("btn")&&n.toggleClass("active"),o.hide(),a(window).off("resize",I),o.off("click","[data-action]"),o.off("mousedown",!1),o.remove(),o=!1,J({type:"dp.hide",date:e.clone()}),g.blur(),k=0,f=e.clone(),l)):l},ca=function(){aa(null)},da=function(a){
+//inputDate.locale(options.locale);
+return void 0===d.parseInputDate?b.isMoment(a)||(a=y(a)):a=d.parseInputDate(a),a},/********************************************************************************
+             *
+             * Widget UI interaction functions
+             *
+             ********************************************************************************/
+ea={next:function(){var a=q[k].navFnc;f.add(q[k].navStep,a),W(),K(a)},previous:function(){var a=q[k].navFnc;f.subtract(q[k].navStep,a),W(),K(a)},pickerSwitch:function(){L(1)},selectMonth:function(b){var c=a(b.target).closest("tbody").find("span").index(a(b.target));f.month(c),k===p?(aa(e.clone().year(f.year()).month(f.month())),d.inline||ba()):(L(-1),W()),K("M")},selectYear:function(b){var c=parseInt(a(b.target).text(),10)||0;f.year(c),k===p?(aa(e.clone().year(f.year())),d.inline||ba()): [...]
+g.collapse("hide"),h.collapse("show")):(// otherwise just toggle in class on the two views
+g.removeClass("in"),h.addClass("in")),e.is("span")?e.toggleClass(d.icons.time+" "+d.icons.date):e.find("span").toggleClass(d.icons.time+" "+d.icons.date)}},showPicker:function(){o.find(".timepicker > div:not(.timepicker-picker)").hide(),o.find(".timepicker .timepicker-picker").show()},showHours:function(){o.find(".timepicker .timepicker-picker").hide(),o.find(".timepicker .timepicker-hours").show()},showMinutes:function(){o.find(".timepicker .timepicker-picker").hide(),o.find(".timepicke [...]
+             * Shows the widget. Possibly will emit dp.show and dp.change
+             */
+ga=function(){var b,c={year:function(a){return a.month(0).date(1).hours(0).seconds(0).minutes(0)},month:function(a){return a.date(1).hours(0).seconds(0).minutes(0)},day:function(a){return a.hours(0).seconds(0).minutes(0)},hour:function(a){return a.seconds(0).minutes(0)},minute:function(a){return a.seconds(0)}};// this handles clicks on the widget
+return g.prop("disabled")||!d.ignoreReadonly&&g.prop("readonly")||o?l:(void 0!==g.val()&&0!==g.val().trim().length?aa(da(g.val().trim())):m&&d.useCurrent&&(d.inline||g.is("input")&&0===g.val().trim().length)&&(b=y(),"string"==typeof d.useCurrent&&(b=c[d.useCurrent](b)),aa(b)),o=G(),M(),S(),o.find(".timepicker-hours").hide(),o.find(".timepicker-minutes").hide(),o.find(".timepicker-seconds").hide(),_(),L(),a(window).on("resize",I),o.on("click","[data-action]",fa),o.on("mousedown",!1),n&&n. [...]
+             * Shows or hides the widget
+             */
+ha=function(){return o?ba():ga()},ia=function(a){var b,c,e,f,g=null,h=[],i={},j=a.which,k="p";w[j]=k;for(b in w)w.hasOwnProperty(b)&&w[b]===k&&(h.push(b),parseInt(b,10)!==j&&(i[b]=!0));for(b in d.keyBinds)if(d.keyBinds.hasOwnProperty(b)&&"function"==typeof d.keyBinds[b]&&(e=b.split(" "),e.length===h.length&&v[j]===e[e.length-1])){for(f=!0,c=e.length-2;c>=0;c--)if(!(v[e[c]]in i)){f=!1;break}if(f){g=d.keyBinds[b];break}}g&&(g.call(l,o),a.stopPropagation(),a.preventDefault())},ja=function(a [...]
+// Store given enabledDates and disabledDates as keys.
+// This way we can check their existence in O(1) time instead of looping through whole array.
+// (for example: options.enabledDates['2014-02-27'] === true)
+var c={};return a.each(b,function(){var a=da(this);a.isValid()&&(c[a.format("YYYY-MM-DD")]=!0)}),Object.keys(c).length?c:!1},oa=function(b){
+// Store given enabledHours and disabledHours as keys.
+// This way we can check their existence in O(1) time instead of looping through whole array.
+// (for example: options.enabledHours['2014-02-27'] === true)
+var c={};return a.each(b,function(){c[this]=!0}),Object.keys(c).length?c:!1},pa=function(){var a=d.format||"L LT";i=a.replace(/(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,function(a){var b=e.localeData().longDateFormat(a)||a;return b.replace(/(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,function(a){//temp fix for #740
+return e.localeData().longDateFormat(a)||a})}),j=d.extraFormats?d.extraFormats.slice():[],j.indexOf(a)<0&&j.indexOf(i)<0&&j.push(i),h=i.toLowerCase().indexOf("a")<1&&i.replace(/\[.*?\]/g,"").indexOf("h")<1,z("y")&&(p=2),z("M")&&(p=1),z("d")&&(p=0),k=Math.max(p,k),m||aa(e)};
+// initializing element and component attributes
+if(/********************************************************************************
+         *
+         * Public API functions
+         * =====================
+         *
+         * Important: Do not expose direct references to private objects or the options
+         * object to the outer world. Always return a clone when returning values or make
+         * a clone when setting a private variable.
+         *
+         ********************************************************************************/
+l.destroy=function(){
+///<summary>Destroys the widget and removes all attached event listeners</summary>
+ba(),ma(),c.removeData("DateTimePicker"),c.removeData("date")},l.toggle=ha,l.show=ga,l.hide=ba,l.disable=function(){
+///<summary>Disables the input element, the component is attached to, by adding a disabled="true" attribute to it.
+///If the widget was visible before that call it is hidden. Possibly emits dp.hide</summary>
+return ba(),n&&n.hasClass("btn")&&n.addClass("disabled"),g.prop("disabled",!0),l},l.enable=function(){
+///<summary>Enables the input element, the component is attached to, by removing disabled attribute from it.</summary>
+return n&&n.hasClass("btn")&&n.removeClass("disabled"),g.prop("disabled",!1),l},l.ignoreReadonly=function(a){if(0===arguments.length)return d.ignoreReadonly;if("boolean"!=typeof a)throw new TypeError("ignoreReadonly () expects a boolean parameter");return d.ignoreReadonly=a,l},l.options=function(b){if(0===arguments.length)return a.extend(!0,{},d);if(!(b instanceof Object))throw new TypeError("options() options parameter should be an object");return a.extend(!0,d,b),a.each(d,function(a,b) [...]
+///<signature helpKeyword="$.fn.datetimepicker.date">
+///<summary>Returns the component's model current date, a moment object or null if not set.</summary>
+///<returns type="Moment">date.clone()</returns>
+///</signature>
+///<signature>
+///<summary>Sets the components model current moment to it. Passing a null value unsets the components model current moment. Parsing of the newDate parameter is made using moment library with the options.format and options.useStrict components configuration.</summary>
+///<param name="newDate" locid="$.fn.datetimepicker.date_p:newDate">Takes string, Date, moment, null parameter.</param>
+///</signature>
+if(0===arguments.length)return m?null:e.clone();if(!(null===a||"string"==typeof a||b.isMoment(a)||a instanceof Date))throw new TypeError("date() parameter must be one of [null, string, moment or Date]");return aa(null===a?null:da(a)),l},l.format=function(a){
+///<summary>test su</summary>
+///<param name="newFormat">info about para</param>
+///<returns type="string|boolean">returns foo</returns>
+if(0===arguments.length)return d.format;if("string"!=typeof a&&("boolean"!=typeof a||a!==!1))throw new TypeError("format() expects a string or boolean:false parameter "+a);return d.format=a,i&&pa(),l},l.timeZone=function(a){if(0===arguments.length)return d.timeZone;if("string"!=typeof a)throw new TypeError("newZone() expects a string parameter");return d.timeZone=a,l},l.dayViewHeaderFormat=function(a){if(0===arguments.length)return d.dayViewHeaderFormat;if("string"!=typeof a)throw new Ty [...]
+///<signature helpKeyword="$.fn.datetimepicker.disabledDates">
+///<summary>Returns an array with the currently set disabled dates on the component.</summary>
+///<returns type="array">options.disabledDates</returns>
+///</signature>
+///<signature>
+///<summary>Setting this takes precedence over options.minDate, options.maxDate configuration. Also calling this function removes the configuration of
+///options.enabledDates if such exist.</summary>
+///<param name="dates" locid="$.fn.datetimepicker.disabledDates_p:dates">Takes an [ string or Date or moment ] of values and allows the user to select only from those days.</param>
+///</signature>
+if(0===arguments.length)return d.disabledDates?a.extend({},d.disabledDates):d.disabledDates;if(!b)return d.disabledDates=!1,_(),l;if(!(b instanceof Array))throw new TypeError("disabledDates() expects an array parameter");return d.disabledDates=na(b),d.enabledDates=!1,_(),l},l.enabledDates=function(b){
+///<signature helpKeyword="$.fn.datetimepicker.enabledDates">
+///<summary>Returns an array with the currently set enabled dates on the component.</summary>
+///<returns type="array">options.enabledDates</returns>
+///</signature>
+///<signature>
+///<summary>Setting this takes precedence over options.minDate, options.maxDate configuration. Also calling this function removes the configuration of options.disabledDates if such exist.</summary>
+///<param name="dates" locid="$.fn.datetimepicker.enabledDates_p:dates">Takes an [ string or Date or moment ] of values and allows the user to select only from those days.</param>
+///</signature>
+if(0===arguments.length)return d.enabledDates?a.extend({},d.enabledDates):d.enabledDates;if(!b)return d.enabledDates=!1,_(),l;if(!(b instanceof Array))throw new TypeError("enabledDates() expects an array parameter");return d.enabledDates=na(b),d.disabledDates=!1,_(),l},l.daysOfWeekDisabled=function(a){if(0===arguments.length)return d.daysOfWeekDisabled.splice(0);if("boolean"==typeof a&&!a)return d.daysOfWeekDisabled=!1,_(),l;if(!(a instanceof Array))throw new TypeError("daysOfWeekDisable [...]
+///<signature helpKeyword="$.fn.datetimepicker.defaultDate">
+///<summary>Returns a moment with the options.defaultDate option configuration or false if not set</summary>
+///<returns type="Moment">date.clone()</returns>
+///</signature>
+///<signature>
+///<summary>Will set the picker's inital date. If a boolean:false value is passed the options.defaultDate parameter is cleared.</summary>
+///<param name="defaultDate" locid="$.fn.datetimepicker.defaultDate_p:defaultDate">Takes a string, Date, moment, boolean:false</param>
+///</signature>
+if(0===arguments.length)return d.defaultDate?d.defaultDate.clone():d.defaultDate;if(!a)return d.defaultDate=!1,l;"string"==typeof a&&(a="now"===a||"moment"===a?y():y(a));var b=da(a);if(!b.isValid())throw new TypeError("defaultDate() Could not parse date parameter: "+a);if(!R(b))throw new TypeError("defaultDate() date passed is invalid according to component setup validations");return d.defaultDate=b,(d.defaultDate&&d.inline||""===g.val().trim())&&aa(d.defaultDate),l},l.locale=function(a) [...]
+///<signature helpKeyword="$.fn.datetimepicker.disabledTimeIntervals">
+///<summary>Returns an array with the currently set disabled dates on the component.</summary>
+///<returns type="array">options.disabledTimeIntervals</returns>
+///</signature>
+///<signature>
+///<summary>Setting this takes precedence over options.minDate, options.maxDate configuration. Also calling this function removes the configuration of
+///options.enabledDates if such exist.</summary>
+///<param name="dates" locid="$.fn.datetimepicker.disabledTimeIntervals_p:dates">Takes an [ string or Date or moment ] of values and allows the user to select only from those days.</param>
+///</signature>
+if(0===arguments.length)return d.disabledTimeIntervals?a.extend({},d.disabledTimeIntervals):d.disabledTimeIntervals;if(!b)return d.disabledTimeIntervals=!1,_(),l;if(!(b instanceof Array))throw new TypeError("disabledTimeIntervals() expects an array parameter");return d.disabledTimeIntervals=b,_(),l},l.disabledHours=function(b){
+///<signature helpKeyword="$.fn.datetimepicker.disabledHours">
+///<summary>Returns an array with the currently set disabled hours on the component.</summary>
+///<returns type="array">options.disabledHours</returns>
+///</signature>
+///<signature>
+///<summary>Setting this takes precedence over options.minDate, options.maxDate configuration. Also calling this function removes the configuration of
+///options.enabledHours if such exist.</summary>
+///<param name="hours" locid="$.fn.datetimepicker.disabledHours_p:hours">Takes an [ int ] of values and disallows the user to select only from those hours.</param>
+///</signature>
+if(0===arguments.length)return d.disabledHours?a.extend({},d.disabledHours):d.disabledHours;if(!b)return d.disabledHours=!1,_(),l;if(!(b instanceof Array))throw new TypeError("disabledHours() expects an array parameter");if(d.disabledHours=oa(b),d.enabledHours=!1,d.useCurrent&&!d.keepInvalid){for(var c=0;!R(e,"h");){if(e.add(1,"h"),24===c)throw"Tried 24 times to find a valid date";c++}aa(e)}return _(),l},l.enabledHours=function(b){
+///<signature helpKeyword="$.fn.datetimepicker.enabledHours">
+///<summary>Returns an array with the currently set enabled hours on the component.</summary>
+///<returns type="array">options.enabledHours</returns>
+///</signature>
+///<signature>
+///<summary>Setting this takes precedence over options.minDate, options.maxDate configuration. Also calling this function removes the configuration of options.disabledHours if such exist.</summary>
+///<param name="hours" locid="$.fn.datetimepicker.enabledHours_p:hours">Takes an [ int ] of values and allows the user to select only from those hours.</param>
+///</signature>
+if(0===arguments.length)return d.enabledHours?a.extend({},d.enabledHours):d.enabledHours;if(!b)return d.enabledHours=!1,_(),l;if(!(b instanceof Array))throw new TypeError("enabledHours() expects an array parameter");if(d.enabledHours=oa(b),d.disabledHours=!1,d.useCurrent&&!d.keepInvalid){for(var c=0;!R(e,"h");){if(e.add(1,"h"),24===c)throw"Tried 24 times to find a valid date";c++}aa(e)}return _(),l},/**
+         * Returns the component's model current viewDate, a moment object or null if not set. Passing a null value unsets the components model current moment. Parsing of the newDate parameter is made using moment library with the options.format and options.useStrict components configuration.
+         * @param {Takes string, viewDate, moment, null parameter.} newDate
+         * @returns {viewDate.clone()}
+         */
+l.viewDate=function(a){if(0===arguments.length)return f.clone();if(!a)return f=e.clone(),l;if(!("string"==typeof a||b.isMoment(a)||a instanceof Date))throw new TypeError("viewDate() parameter must be one of [string, moment or Date]");return f=da(a),K(),l},c.is("input"))g=c;else if(g=c.find(d.datepickerInput),0===g.length)g=c.find("input");else if(!g.is("input"))throw new Error('CSS class "'+d.datepickerInput+'" cannot be applied to non input element');if(c.hasClass("input-group")&&(
+// in case there is more then one 'input-group-addon' Issue #48
+n=0===c.find(".datepickerbutton").length?c.find(".input-group-addon"):c.find(".datepickerbutton")),!d.inline&&!g.is("input"))throw new Error("Could not initialize DateTimePicker without an input element");
+// Set defaults for date here now instead of in var declaration
+return e=y(),f=e.clone(),a.extend(!0,d,H()),l.options(d),pa(),la(),g.prop("disabled")&&l.disable(),g.is("input")&&0!==g.val().trim().length?aa(da(g.val().trim())):d.defaultDate&&void 0===g.attr("placeholder")&&aa(d.defaultDate),d.inline&&ga(),l};/********************************************************************************
+     *
+     * jQuery plugin constructor and defaults object
+     *
+     ********************************************************************************/
+/**
+    * See (http://jquery.com/).
+    * @name jQuery
+    * @class
+    * See the jQuery Library  (http://jquery.com/) for full details.  This just
+    * documents the function and classes that are added to jQuery by this plug-in.
+    */
+/**
+     * See (http://jquery.com/)
+     * @name fn
+     * @class
+     * See the jQuery Library  (http://jquery.com/) for full details.  This just
+     * documents the function and classes that are added to jQuery by this plug-in.
+     * @memberOf jQuery
+     */
+/**
+     * Show comments
+     * @class datetimepicker
+     * @memberOf jQuery.fn
+     */
+a.fn.datetimepicker=function(b){b=b||{};var d,e=Array.prototype.slice.call(arguments,1),f=!0,g=["destroy","hide","show","toggle"];if("object"==typeof b)return this.each(function(){var d=a(this);d.data("DateTimePicker")||(b=a.extend(!0,{},a.fn.datetimepicker.defaults,b),d.data("DateTimePicker",c(d,b)))});if("string"==typeof b)return this.each(function(){var c=a(this),g=c.data("DateTimePicker");if(!g)throw new Error('bootstrap-datetimepicker("'+b+'") method was called on an element that is [...]
+//tab: function (widget) { //this break the flow of the form. disabling for now
+//    var toggle = widget.find('.picker-switch a[data-action="togglePicker"]');
+//    if(toggle.length > 0) toggle.click();
+//},
+"control space":function(a){a.find(".timepicker").is(":visible")&&a.find('.btn[data-action="togglePeriod"]').click()},t:function(){this.date(this.getMoment())},"delete":function(){this.clear()}},debug:!1,allowInputToggle:!1,disabledTimeIntervals:!1,disabledHours:!1,enabledHours:!1,viewDate:!1},"undefined"!=typeof module&&(module.exports=a.fn.datetimepicker)});
\ No newline at end of file
diff --git a/component.json b/component.json
index dfc00ee..ada02b7 100644
--- a/component.json
+++ b/component.json
@@ -1,9 +1,9 @@
 {
   "name": "bootstrap-datetimepicker",
-  "version": "4.17.37",
+  "version": "4.17.42",
   "main": ["build/css/bootstrap-datetimepicker.min.css","build/js/bootstrap-datetimepicker.min.js"],
   "dependencies": {
     "jquery" : ">=1.8.3",
-	"moment": ">=2.9.0"
+	"moment": ">=2.10.5"
   }
 }
diff --git a/composer.json b/composer.json
index c05f346..c50f2b1 100644
--- a/composer.json
+++ b/composer.json
@@ -1,7 +1,7 @@
 {
   "name": "eonasdan/bootstrap-datetimepicker",
   "type": "component",
-  "version": "4.17.37",
+  "version": "4.17.42",
   "description": "Date/time picker widget based on twitter bootstrap",
   "keywords": [
     "bootstrap",
@@ -12,7 +12,7 @@
   "require": {
     "robloach/component-installer": "*",
     "components/jquery": ">=1.9.1",
-    "moment/moment": ">=2.8"
+    "moment": ">=2.10.5"
   },
   "extra": {
     "component": {
diff --git a/docs/ChangeLog.md b/docs/ChangeLog.md
index 01ce0ed..9e20323 100644
--- a/docs/ChangeLog.md
+++ b/docs/ChangeLog.md
@@ -1,5 +1,20 @@
 # Version 4
 
+## 4.17.42
+
+### Bug Squashing
+
+* fixed moment dependencies to all be the same
+* defaulted `option.timeZone` to `''` instead of UTC. This way it will default to the local timezone if it's not set.
+* fixed #959
+* fixed #1311 internal `getMoment` function no longer sets `startOf('d')`
+* fixed #935
+
+### Other
+
+* moved some (will move the rest soon) inline docs to JSDoc now that ReSharper supports it.
+* moved getter/setter functions to options page instead. #1313
+
 ## 4.17.37
 
 ### New Features
diff --git a/docs/Events.md b/docs/Events.md
index 295240d..6ed53b1 100644
--- a/docs/Events.md
+++ b/docs/Events.md
@@ -37,7 +37,7 @@ Emitted from:
 
 ### dp.change
 
-Fired when the date is changed.
+Fired when the date is changed, including when changed to a non-date (e.g. When keepInvalid=true).
 
 Parameters:
 
@@ -68,6 +68,7 @@ Parameters:
 ```
 e = {
     date //the invalid date. Type: moment object (clone)
+    oldDate //previous date. Type: moment object (clone) or false in the event of a null
 }
 ```
 
diff --git a/docs/Functions.md b/docs/Functions.md
index 980874d..2e74097 100644
--- a/docs/Functions.md
+++ b/docs/Functions.md
@@ -63,530 +63,10 @@ Enables the input element, the component is attached to, by removing `disabled`
 
 ----------------------
 
-
-### date
-
-####date()
-
- Returns the component's model current date, a `moment` object or `null` if not set.
-
-####date([newDate])
-
- Takes `string, Date, moment, null` parameter and sets the components model current moment to it. Passing a `null` value unsets the components model current moment. Parsing of the newDate parameter is made using moment library with the `options.format` and `options.useStrict` components configuration.
-
-##### Throws
-
-* `TypeError` - in case the `newDate` cannot be parsed
-
-##### Emits
-
-* `dp.change` - In case `newDate` is different from current moment
-
-### en/disabledDates
-
-#### disabledDates()
-
-Returns an array with the currently set disabled dates on the component.
-
-#### disabledDates(dates)
-
-Takes an `[` `string` or `Date` or `moment` `]` of values and disallows the user to select those days. Setting this takes precedence over `options.minDate`, `options.maxDate` configuration. Also calling this function removes the configuration of options.enabledDates if such exist.
-
-**Note:** These values are matched with `Day` granularity.
-
-----------------------
-
-#### enabledDates()
-
-Returns an array with the currently set enabled dates on the component.
-
-
-#### enabledDates(dates)
-
-Takes an `[` `string` or `Date` or `moment` `]` of values and allows the user to select only from those days. Setting this takes precedence over `options.minDate`, `options.maxDate` configuration. Also calling this function removes the configuration of options.disabledDates if such exist.
-
-**Note:** These values are matched with `Day` granularity.
-
-----------------------
-
-### defaultDate
-
-#### defaultDate()
-
-Returns a `moment` with the `options.defaultDate` option configuration or `false` if not set
-
-#### defaultDate(defaultDate)
-
-Takes a `string, Date, moment, boolean:false`. Will set the picker's inital date. If a `boolean:false` value is passed the `options.defaultDate` parameter is cleared. 
-
-* `TypeError` - if the provided date pass validation, including `disabledDates`, `enabledDates`, `minDate`, `maxDate`, and `daysOfWeekDisabled`
-
-* `TypeError` - if the provided date cannot be parsed by momentjs
-
-----------------------
-
-### useCurrent
-
-#### useCurrent()
-
-Returns a `boolean` or `string` with the `options.useCurrent` option configuration
-
-#### useCurrent(boolean or string)
-
-Takes a `boolean` or `string`. If a `boolean` true is passed and the components model moment is not set (either through `setDate` or through a valid value on the input element the component is attached to) then the first time the user opens the datetimepicker widget the value is initialized to the current moment of the action. If a false `boolean` is passed then no initialization happens on the input element. You can select the granularity on the initialized moment by passing one of the  [...]
-
-If for example you pass `'day'` to the `setUseCurrent` function and the input field is empty the first time the user opens the datetimepicker widget the input text will be initialized to the current datetime with day granularity (ie if currentTime = `2014-08-10 13:32:33` the input value will be initialized to `2014-08-10 00:00:00`)
-
-**Note:** If the `options.defaultDate` is set or the input element the component is attached to has already a value that takes precedence and the functionality of `useCurrent` is not triggered!
-
-----------------------
-
-### min/maxDate
-
-#### minDate()
-
-Returns the currently set moment of the `options.minDate` or `false` if not set
-
-#### minDate(minDate)
-
-Takes a minDate `string, Date, moment, boolean:false` parameter and disallows the user to select a moment that is before that moment. If a `boolean:false` value is passed the `options.minDate` parameter is cleared and there is no restriction to the miminum moment the user can select. 
-
-**Note:** If the minDate parameter is after the currently selected moment the currently selected moment changes to minDate parameter
-
-##### Throws
-
-* `TypeError` - if minDate parameter cannot be parsed using the `options.format` and `options.useStrict` configuration settings
-
-* `TypeError` - if minDate parameter is after `options.maxDate`
-
-##### Emits
-
-* `dp.change` - if the new minDate is after currently selected moment (waiting for #472 to close in order to finalize this part)
-
-* `dp.error` - if the new minDate is after currently selected moment (waiting for #472 to close in order to finalize this part)
-
-----------------------
-
-#### maxDate()
-
-Returns the currently set moment of the `options.maxDate` or `false` if not set
-
-
-#### maxDate(maxDate)
-
-Takes a maxDate `string, Date, moment, boolean:false` parameter and disallows the user to select a moment that is after that moment. If a `boolean:false` value is passed `options.maxDate` is cleared and there is no restriction to the maximum moment the user can select.
-
-**Note:** If maxDate is before the currently selected moment the currently selected moment changes to maxDate
-
-##### Throws
-
-* `TypeError` - if maxDate parameter cannot be parsed using the `options.format` and `options.useStrict` configuration settings
-
-* `TypeError` - if maxDate parameter is before `options.minDate`
-
-##### Emits
-
-* `dp.change` - if the new maxDate is after currently selected moment  (waiting for #472 to close in order to finalize this part)
-
-* `dp.error` - if the new maxDate is after currently selected moment  (waiting for #472 to close in order to finalize this part)
-
-----------------------
-
-### daysOfWeekDisabled
-
-#### daysOfWeekDisabled()
-
-Returns an array with the `options.daysOfWeekDisabled` configuration setting of the component.
-
-#### daysOfWeekDisabled(daysOfWeek)
-
-Takes an `[` `Number`:`0` to `6` `]` and disallow the user to select weekdays that exist in this array. This has lower priority over the `options.minDate`, `options.maxDate`, `options.disabledDates` and `options.enabledDates` configuration settings.
-
-##### Emits
-
-* `dp.change` - if the currently selected moment falls in the values passed on the daysOfWeek parameter. (waiting for #472 to close in order to finalize this part)
-
-* `dp.error` - if the currently selected moment falls in the values passed on the daysOfWeek parameter. (waiting for #472 to close in order to finalize this part)
-
-----------------------
-
-### options
-
-####options()
-
-Returns the components current options object. Note that the changing the values of the returned object does not change the components actual configuration. Use `options(options)` to set the components options massively or the other methods for setting config options individually.
-
-
-#### options([options])
-
-Takes an object variable with option key:value properties and configures the component. Use this to update multiple options on the component.
-
-----------------------
-
-### format
-
-#### format()
-
-Returns the component's `options.format` `string`
-
-
-#### format(format)
-
-Takes a [moment.js](http://momentjs.com/docs/#/displaying/format/) format `string` and sets the components  `options.format`. This is used for displaying and also for parsing input strings either from the input element the component is attached to or the `date()` function.
-The parameter can also be a `boolean:false` in which case the format is set to the locale's `L LT`.
-
-**Note:** this is also used to determine if the TimePicker sub component will display the hours in 12 or 24 format. (if 'a' or 'h' exists in the passed `string` then a 12 hour mode is set)
-
-----------------------
-
-### extraFormats
-
-#### extraFormats()
-
-Returns a `boolean` or array with the `options.extraFormats` option configuration
-
-#### extraFormats(formats)
-
-Takes an array of valid input moment format options.  See PR #666
-
-----------------------
-
-### locale
-
-#### locale()
-
-Returns the currently set locale of the `options.locale`
-
-#### locale(newLocale)
-
-Takes a `string` of any valid [moment locale](https://github.com/moment/moment/tree/develop/locale) e.g. `de` for German.
-
-##### Throws
-
-* `TypeError` - if the locale is not loaded via a separate script or `moment-with-locales`
-
-----------------------
-
-### stepping
-
-#### stepping()
-
-Returns a `number` with the `options.stepping` option configuration
-
-
-#### stepping(number)
-
-Takes a `number`. This be the amount the up/down arrows move the minute value with a time picker.
-
-----------------------
-
-### sideBySide and collapse
-
-#### sideBySide()
-
-Returns a `boolean` of the `options.sideBySide`.
-
-
-#### sideBySide(sideBySide)
-
-Takes a `boolean`. If `sideBySide` is `true` and the time picker is used, both components will display side by side instead of collapsing.
-
-----------------------
-
-#### collapse()
-
-Returns a `boolean` with the `options.collapse` option configuration
-
-#### collapse(collapse)
-
-Takes a `boolean`. If set to `false` the picker will display similar to `sideBySide` except vertical.
-
-----------------------
-
-### icons
-
-#### icons()
-
-Returns an `Ojbect` of `options.icons` 
-
-#### icons(icons)
-
-Takes an `Ojbect` of `strings`.
-
-##### Throws
-
-* `TypeError` - if icons parameter is not an `Ojbect`
-
-----------------------
-
-### useStrict
-
-#### useStrict()
-
-Returns a `boolean` of the `options.useStrict`
-
-#### useStrict(useStrict)
-
-Takes a `boolean`. If `useStrict` is `true`, momentjs parsing rules will be stricter when determining if a date is valid or not.
-
-----------------------
-
-### widgetPositioning
-
-#### widgetPositioning()
-
-Returns the currently set `options.widgetPositioning` object containing two keys `horizontal` and `vertical`
-
-
-#### widgetPositioning(positioningObject)
-
-Takes an object parameter that can contain two keys `vertical` and `horizontal` each having a value of `'auto', 'top', 'bottom'` for `vertical` and `'auto', 'left', 'right'` for `horizontal` which defines where the dropdown with the widget will appear relative to the input element the component is attached to.
-
-`'auto'` is the default value for both `horizontal` and `vertical` keys and it tries to automatically place the dropdown in a position that is visible to the user. Usually you should not override those options unless you have a special need in your layout.
-
-----------------------
-
-### viewMode
-
-#### viewMode()
-
-Returns a `string` of the `options.viewMode`.
-
-#### viewMode(newViewMode)
-
-Takes a `string`. Valid values are `'days'`, `'months'`, `'years'` and `'decades'`
-
-##### Throws
-
-* `TypeError` - if `newViewMode` parameter is not an a `string` or if `newViewMode` is not a valid value
-
-----------------------
-
-### calendarWeeks
-
-#### calendarWeeks()
-
-Returns a `boolean` with the current `options.calendarWeeks` option configuration
-
-#### calendarWeeks(boolean)
-
-Takes a `boolean` variable to set if the week numbers will appear to the left on the days view
-
-----------------------
-
-### showClear
-
-#### showClear()
-
-Returns a `boolean` variable with the currently set `options.showClear` option.
-
-#### showClear(boolean)
-
-Takes a `boolean` variable to set if the clear date button will appear on the widget
-
-----------------------
-
-### showTodayButton
-
-#### showTodayButton()
-
-Returns a `boolean` variable with the currently set `options.showTodayButton` option.
-
-
-#### showTodayButton(boolean)
-
-Takes a `boolean` variable to set if the Today button will appear on the widget
-
-----------------------
-
-### toolbarplacement
-
-#### toolbarplacement()
-
-Returns a `string` variable with the currently set `options.toolbarplacement` option.
-
-#### toolbarplacement(string)
-
-Takes a `string` value. Valid values are `'default'`, `'top'` and `'bottom'`.
-
-Changes the placement of the toolbar where the today, clear, component switch icon are located.
-
-----------------------
-
-### dayViewHeaderFormat
-
-#### dayViewHeaderFormat()
-
-Returns a `string` variable with the currently set `options.dayViewHeaderFormat` option.
-
-#### dayViewHeaderFormat(string)
-
-Takes a `string` value.
-
-Used to customize the header of the day view.
-
-----------------------
-
-### keyBinds
-
-#### keyBinds()
-
-Returns a `string` variable with the currently set `options.keyBinds` option.
-
-#### keyBinds(object)
-
-Takes an `object` value.
-
-Allows for several keyBinding functions to be specified for ease of access or accessibility. See the options page for defaults.
-
-----------------------
-
 ### clear()
 
 Clears the datepicker by setting the value to `null`
 
-----------------------
-
-### inline
-
-#### inline()
-
-Returns a `boolean` variable with the currently set `options.inline` option.
-
-#### inline(boolean)
-
-Takes a `boolean` value.
-
-Used to customize the header of the day view.
-
-----------------------
-
-### ignoreReadonly
-
-#### ignoreReadonly()
-
-Returns a `boolean` variable with the currently set `options.ignoreReadonly` option.
-
-#### ignoreReadonly(boolean)
-
-Takes a `boolean` value.
-
-Set this to `true` to allow the picker to be used even if the input field is `readonly`. This will **not** bypass the `disabled` property
-
-----------------------
-
-### showClose
-
-#### showClose()
-
-Returns a `boolean` variable with the currently set `options.showClose` option.
-
-#### showClose(boolean)
-
-Takes a `boolean` value.
-
-If `true`, an icon will be displayed on the toolbar that will hide the picker
-
-----------------------
-
-### debug
-
-For the moment this function will only prevent the picker from calling `hide()` on `blur` so that the picker can be inspected.
-
-----------------------
-
-### keepInvalid
-
-<small>4.7.14</small>
-
-#### keepInvalid()
-
-Returns a `string` variable with the currently set `options.keepInvalid` option.
-
-#### keepInvalid(boolean)
-
-Takes a `boolean` value.
-
-If `true`, invalid dates will not be reverted to a previous selection or changed.
-
-----------------------
-
-### allowInputToggle
-
- <small>4.7.14</small>
-
-#### allowInputToggle()
-
-Returns a `boolean` variable with the currently set `options.allowInputToggle` option.
-
-#### allowInputToggle(boolean)
-
-Takes a `boolean` value.
-
-If `true`, the picker will show on textbox focus and icon click when used in a button group
-
-----------------------
-
-### focusOnShow
-
-<small>4.14.30</small> PR #884
-
-#### focusOnShow()
-
-Returns a `boolean` variable with the currently set `options.focusOnShow` option.
-
-#### focusOnShow(boolean)
-
-Takes a `boolean` value.
-
-If `false`, the textbox will not be given focus when the picker is shown
-
-
-----------------------
-
-### disabledTimeIntervals
-
-<small>4.14.30</small> Issue: #644
-
-#### disabledTimeIntervals()
-
-Returns an `array` variable with the currently set `options.disabledTimeIntervals` option.
-
-#### disabledTimeIntervals(array)
-
-Takes a `array` value.
-
-The array **must** be in the following format `[moment(),moment()]`
-
-For example:
-
-    disabledTimeIntervals: [[moment({ h: 0 }), moment({ h: 8 })], [moment({ h: 18 }), moment({ h: 24 })]]
-
-Will disable times between 12-8am and 6-12pm today
-
-----------------------
-
-### en/disabledHours
-
-<small>4.14.30</small> Issue: #851
-
-#### disabledHours()
-
-Returns an `array` variable with the currently set `options.en/disabledHours` option.
-
-#### disabledHours(boolean)
-
-Takes a `array` value.
-
-Must be in 24 hour format. Will allow or disallow hour selections (much like `disabledTimeIntervals`) but will affect all days.
-
-Like `en/disabledDates`, these options are mutually exclusive and will reset one of the options back to false.
-
-    disabledHours: [0, 1, 2, 3, 4, 5, 6, 7, 8, 18, 19, 20, 21, 22, 23, 24]
-    enabledHours: [9, 10, 11, 12, 13, 14, 15, 16]
-
-----------------------
-
 ### viewDate
 
 <small>4.14.30</small> Issue #872
@@ -599,72 +79,4 @@ Returns a `moment` variable with the currently set `options.viewDate` option.
 
 Takes a `string, moment or Date` value.
 
-This will change the `viewDate` without changing or setting the selected date.
-
-### parseInputDate
-<small>4.14.30</small> Issue #1095
-
-#### parseInputDate()
-
-Returns a `function` with the currently set `options.parseInputDate`
-
-#### parseInputDate(function)
-
-Takes a `function`
-
-Allows custom input formatting For example: the user can enter 'yesterday' or '30 days ago'.
-
-Example:
-
-```
-var parseRelativeDate = function(relativeDate) {
-
-    switch (relativeDate) {
-        case 'today':
-            return moment()
-        case 'yesterday':
-            return moment().subtract(1, 'day');
-        default:
-            return moment()
-                .subtract(Number(relativeDate.replace("days ago", "").trim()), 'days');
-    }
-}
-
-var parseInputDate = function(inputDate) {
-    var relativeDatePattern = /today|yesterday|[0-9]+\s+(days ago)/,
-        resultDate;
-
-    if (moment.isMoment(inputDate) || inputDate instanceof Date) {
-        resultDate = moment(inputDate);
-    } else {
-        var relativeDate = inputDate.match(relativeDatePattern),
-            parseDate = null;
-
-        if (relativeDate !== null) 
-          parseDate = this.parseRelativeDate(inputDate.match(relativeDatePattern)[0]);
-        else 
-          parseDate = moment();
-
-        resultDate = moment(parseDate, "YYYY-MM-DD");
-    }
-
-    return resultDate;
-}
-```
-
-----------------------
-
-### tooltips
-<small>4.14.30</small> 
-
-#### tooltips()
-
-Returns an `Ojbect` of `options.tooltips` 
-
-#### tooltips(tooltips)
-
-Takes an `Ojbect` of `strings`.
-
-##### Throws
-
-* `TypeError` - if tooltips parameter is not an `Ojbect`
\ No newline at end of file
+This will change the `viewDate` without changing or setting the selected date.
\ No newline at end of file
diff --git a/docs/Options.md b/docs/Options.md
index 993343c..182315b 100644
--- a/docs/Options.md
+++ b/docs/Options.md
@@ -1,13 +1,57 @@
 ## Options
 
+<div class="alert alert-info">
+    <strong>Note</strong>
+    All options are accessed via the <code>data</code> attribute e.g. <code>$('#datetimepicker').data("DateTimePicker").OPTION()</code>
+</div>
+
+### options()
+
+Returns the components current options object. Note that the changing the values of the returned object does not change the components actual configuration. Use `options(options)` to set the components options massively or the other methods for setting config options individually.
+
+
+### options([options])
+
+Takes an object variable with option key:value properties and configures the component. Use this to update multiple options on the component.
+
+----------------------
+
+### date
+
+ Returns the component's model current date, a `moment` object or `null` if not set.
+
+####date([newDate])
+
+ Takes `string, Date, moment, null` parameter and sets the components model current moment to it. Passing a `null` value unsets the components model current moment. Parsing of the newDate parameter is made using moment library with the `options.format` and `options.useStrict` components configuration.
+
+##### Throws
+
+* `TypeError` - in case the `newDate` cannot be parsed
+
+##### Emits
+
+* `dp.change` - In case `newDate` is different from current moment
+
+----------------------
+
 ### format
 
 	Default: false
 
 See [momentjs' docs](http://momentjs.com/docs/#/displaying/format/) for valid formats. Format also dictates what components are shown, e.g. `MM/dd/YYYY` will not display the time picker.
 
-----------------------
+#### format()
+
+Returns the component's `options.format` `string`
+
+#### format(format)
 
+Takes a [moment.js](http://momentjs.com/docs/#/displaying/format/) format `string` and sets the components  `options.format`. This is used for displaying and also for parsing input strings either from the input element the component is attached to or the `date()` function.
+The parameter can also be a `boolean:false` in which case the format is set to the locale's `L LT`.
+
+**Note:** this is also used to determine if the TimePicker sub component will display the hours in 12 or 24 format. (if 'a' or 'h' exists in the passed `string` then a 12 hour mode is set)
+
+----------------------
 
 ### dayViewHeaderFormat
 
@@ -17,8 +61,17 @@ Changes the heading of the datepicker when in "days" view.
 
 ![Datepicker Header](img/dpheader.png)
 
-----------------------
+#### dayViewHeaderFormat()
 
+Returns a `string` variable with the currently set `options.dayViewHeaderFormat` option.
+
+#### dayViewHeaderFormat(string)
+
+Takes a `string` value.
+
+Used to customize the header of the day view.
+
+----------------------
 
 ### extraFormats
 
@@ -26,6 +79,14 @@ Changes the heading of the datepicker when in "days" view.
 
 Allows for several input formats to be valid. See [this PR](https://github.com/Eonasdan/bootstrap-datetimepicker/pull/666).
 
+#### extraFormats()
+
+Returns a `boolean` or array with the `options.extraFormats` option configuration
+
+#### extraFormats(formats)
+
+Takes an array of valid input moment format options.
+
 ----------------------
 
 
@@ -35,38 +96,91 @@ Allows for several input formats to be valid. See [this PR](https://github.com/E
 
 Number of minutes the up/down arrow's will move the minutes value in the time picker
 
+#### stepping()
+
+Returns a `number` with the `options.stepping` option configuration
+
+
+#### stepping(number)
+
+Takes a `number`. This be the amount the up/down arrows move the minute value with a time picker.
+
 ----------------------
 
 
-### minDate
+### min/maxDate
 
 	Default: false
     Accepts: date, moment, string
 
-Prevents date/time selections before this date.
+Prevents date/time selections before this date. Will override `defaultDate` and `useCurrent` if either of these settings are the same day since both options are invalid according to the rules you've selected.
 
-#### `minDate` will override `defaultDate` and `useCurrent` if either of these settings are the same day since both options are invalid according to the rules you've selected.
+#### minDate()
 
-----------------------
+Returns the currently set moment of the `options.minDate` or `false` if not set
 
+#### minDate(minDate)
 
-### maxDate
+Takes a minDate `string, Date, moment, boolean:false` parameter and disallows the user to select a moment that is before that moment. If a `boolean:false` value is passed the `options.minDate` parameter is cleared and there is no restriction to the miminum moment the user can select. 
 
-	Default: false
-    Accepts: date, moment, string
+**Note:** If the minDate parameter is after the currently selected moment the currently selected moment changes to minDate parameter
+
+##### Throws
+
+* `TypeError` - if minDate parameter cannot be parsed using the `options.format` and `options.useStrict` configuration settings
+
+* `TypeError` - if minDate parameter is after `options.maxDate`
 
-Prevents date/time selections after this date.
+##### Emits
 
-#### `maxDate` will override `defaultDate` and `useCurrent` if either of these settings are the same day since both options are invalid according to the rules you've selected.
+* `dp.change` - if the new minDate is after currently selected moment (waiting for #472 to close in order to finalize this part)
+
+* `dp.error` - if the new minDate is after currently selected moment (waiting for #472 to close in order to finalize this part)
 
 ----------------------
 
+#### maxDate()
+
+Returns the currently set moment of the `options.maxDate` or `false` if not set
+
+
+#### maxDate(maxDate)
+
+Takes a maxDate `string, Date, moment, boolean:false` parameter and disallows the user to select a moment that is after that moment. If a `boolean:false` value is passed `options.maxDate` is cleared and there is no restriction to the maximum moment the user can select.
+
+**Note:** If maxDate is before the currently selected moment the currently selected moment changes to maxDate
+
+##### Throws
+
+* `TypeError` - if maxDate parameter cannot be parsed using the `options.format` and `options.useStrict` configuration settings
+
+* `TypeError` - if maxDate parameter is before `options.minDate`
+
+##### Emits
+
+* `dp.change` - if the new maxDate is after currently selected moment  (waiting for #472 to close in order to finalize this part)
+
+* `dp.error` - if the new maxDate is after currently selected moment  (waiting for #472 to close in order to finalize this part)
+
+----------------------
 
 ### useCurrent
 
 	Default: true
 
-On show, will set the picker to the current date/time
+On `show`, will set the picker to the current date/time.
+
+#### useCurrent()
+
+Returns a `boolean` or `string` with the `options.useCurrent` option configuration
+
+#### useCurrent(boolean or string)
+
+Takes a `boolean` or `string`. If a `boolean` true is passed and the components model moment is not set (either through `setDate` or through a valid value on the input element the component is attached to) then the first time the user opens the datetimepicker widget the value is initialized to the current moment of the action. If a false `boolean` is passed then no initialization happens on the input element. You can select the granularity on the initialized moment by passing one of the  [...]
+
+If for example you pass `'day'` to the `setUseCurrent` function and the input field is empty the first time the user opens the datetimepicker widget the input text will be initialized to the current datetime with day granularity (ie if currentTime = `2014-08-10 13:32:33` the input value will be initialized to `2014-08-10 00:00:00`)
+
+**Note:** If the `options.defaultDate` is set or the input element the component is attached to has already a value that takes precedence and the functionality of `useCurrent` is not triggered!
 
 ----------------------
 
@@ -77,6 +191,15 @@ On show, will set the picker to the current date/time
 
 Using a Bootstraps collapse to switch between date/time pickers.
 
+#### collapse()
+
+Returns a `boolean` of the `options.sideBySide`.
+
+
+#### collapse(collapse)
+
+Takes a `boolean`. If set to `false` the picker will display similar to `sideBySide` except vertical.
+
 ----------------------
 
 
@@ -89,6 +212,18 @@ See [momentjs](https://github.com/moment/moment/tree/develop/locale) for valid l
 
 You must include `moment-with-locales.js` or a local js file.
 
+#### locale()
+
+Returns the currently set locale of the `options.locale`
+
+#### locale(newLocale)
+
+Takes a `string` of any valid [moment locale](https://github.com/moment/moment/tree/develop/locale) e.g. `de` for German.
+
+##### Throws
+
+* `TypeError` - if the locale is not loaded via a separate script or `moment-with-locales`
+
 ----------------------
 
 
@@ -99,28 +234,49 @@ You must include `moment-with-locales.js` or a local js file.
 
 Sets the picker default date/time. Overrides `useCurrent`
 
-----------------------
+#### defaultDate()
 
+Returns a `moment` with the `options.defaultDate` option configuration or `false` if not set
 
-### disabledDates
+#### defaultDate(defaultDate)
 
-	Default: false
-    Accepts: array of [date, moment, string]
+Takes a `string, Date, moment, boolean:false`. Will set the picker's inital date. If a `boolean:false` value is passed the `options.defaultDate` parameter is cleared. 
 
-Disables selection of dates in the array, e.g. holidays
+* `TypeError` - if the provided date pass validation, including `disabledDates`, `enabledDates`, `minDate`, `maxDate`, and `daysOfWeekDisabled`
 
-----------------------
+* `TypeError` - if the provided date cannot be parsed by momentjs
 
+----------------------
 
-### enabledDates
+### en/disabledDates
 
 	Default: false
     Accepts: array of [date, moment, string]
 
-Disables selection of dates **NOT** in the array, e.g. holidays
+#### disabledDates()
+
+Returns an array with the currently set disabled dates on the component.
+
+#### disabledDates(dates)
+
+Takes an `[` `string` or `Date` or `moment` `]` of values and disallows the user to select those days. Setting this takes precedence over `options.minDate`, `options.maxDate` configuration. Also calling this function removes the configuration of options.enabledDates if such exist.
+
+**Note:** These values are matched with `Day` granularity.
 
 ----------------------
 
+#### enabledDates()
+
+Returns an array with the currently set enabled dates on the component.
+
+
+#### enabledDates(dates)
+
+Takes an `[` `string` or `Date` or `moment` `]` of values and allows the user to select only from those days. Setting this takes precedence over `options.minDate`, `options.maxDate` configuration. Also calling this function removes the configuration of options.disabledDates if such exist.
+
+**Note:** These values are matched with `Day` granularity.
+
+----------------------
 
 ### icons
 
@@ -139,11 +295,33 @@ Disables selection of dates **NOT** in the array, e.g. holidays
 
 Change the default icons for the pickers functions.
 
+#### icons()
+
+Returns an `Ojbect` of `options.icons` 
+
+#### icons(icons)
+
+Takes an `Ojbect` of `strings`.
+
+##### Throws
+
+* `TypeError` - if icons parameter is not an `Ojbect`
+
+----------------------
+
 ### useStrict
 
 	Default: false
 
-Defines if moment should use strict date parsing when considering a date to be valid
+Defines if moment should use strict date parsing when considering a date to be valid.
+
+#### useStrict()
+
+Returns a `boolean` of the `options.useStrict`
+
+#### useStrict(useStrict)
+
+Takes a `boolean`. If `useStrict` is `true`, momentjs parsing rules will be stricter when determining if a date is valid or not.
 
 ----------------------
 
@@ -156,6 +334,14 @@ Shows the picker side by side when using the time and date together.
 
 ![SideBySide](img/sideBySide.png)
 
+#### sideBySide()
+
+Returns a `boolean` of the `options.sideBySide`.
+
+#### sideBySide(sideBySide)
+
+Takes a `boolean`. If `sideBySide` is `true` and the time picker is used, both components will display side by side instead of collapsing.
+
 ----------------------
 
 
@@ -166,8 +352,21 @@ Shows the picker side by side when using the time and date together.
 
 Disables the section of days of the week, e.g. weekends.
 
-----------------------
+#### daysOfWeekDisabled()
+
+Returns an array with the `options.daysOfWeekDisabled` configuration setting of the component.
+
+#### daysOfWeekDisabled(daysOfWeek)
+
+Takes an `[` `Number`:`0` to `6` `]` and disallow the user to select weekdays that exist in this array. This has lower priority over the `options.minDate`, `options.maxDate`, `options.disabledDates` and `options.enabledDates` configuration settings.
+
+##### Emits
 
+* `dp.change` - if the currently selected moment falls in the values passed on the daysOfWeek parameter. (waiting for #472 to close in order to finalize this part)
+
+* `dp.error` - if the currently selected moment falls in the values passed on the daysOfWeek parameter. (waiting for #472 to close in order to finalize this part)
+
+----------------------
 
 ### calendarWeeks
 
@@ -177,8 +376,15 @@ Shows the week of the year to the left of first day of the week.
 
 ![calendarWeek](img/calendarWeeks.png)
 
-----------------------
+#### calendarWeeks()
 
+Returns a `boolean` with the current `options.calendarWeeks` option configuration
+
+#### calendarWeeks(boolean)
+
+Takes a `boolean` variable to set if the week numbers will appear to the left on the days view
+
+----------------------
 
 ### viewMode
 
@@ -187,10 +393,21 @@ Shows the week of the year to the left of first day of the week.
 
 The default view to display when the picker is shown.
 
-**Note**: To limit the picker to selecting, for instance the year and month, use `format: MM/YYYY`
+**Note**: To limit the picker to selecting, for instance the year and month, use `format: MM/YYYY`.
 
-----------------------
+#### viewMode()
+
+Returns a `string` of the `options.viewMode`.
+
+#### viewMode(newViewMode)
+
+Takes a `string`. Valid values are `'days'`, `'months'`, `'years'` and `'decades'`
 
+##### Throws
+
+* `TypeError` - if `newViewMode` parameter is not an a `string` or if `newViewMode` is not a valid value.
+
+----------------------
 
 ### toolbarPlacement
 
@@ -201,8 +418,17 @@ Changes the placement of the icon toolbar.
 
 ![toolbarPlacement](img/toolbarPlacement.png)
 
-----------------------
+#### toolbarplacement()
 
+Returns a `string` variable with the currently set `options.toolbarplacement` option.
+
+#### toolbarplacement(string)
+
+Takes a `string` value. Valid values are `'default'`, `'top'` and `'bottom'`.
+
+Changes the placement of the toolbar where the today, clear, component switch icon are located.
+
+----------------------
 
 ### showTodayButton
 
@@ -212,8 +438,15 @@ Show the "Today" button in the icon toolbar.
 
 Clicking the "Today" button will set the calendar view and set the date to `now`.
 
-----------------------
+#### showTodayButton()
+
+Returns a `boolean` variable with the currently set `options.showTodayButton` option.
+
+#### showTodayButton(boolean)
 
+Takes a `boolean` variable to set if the Today button will appear on the widget
+
+----------------------
 
 ### showClear
 
@@ -223,6 +456,14 @@ Show the "Clear" button in the icon toolbar.
 
 Clicking the "Clear" button will set the calendar to null.
 
+#### showClear()
+
+Returns a `boolean` variable with the currently set `options.showClear` option.
+
+#### showClear(boolean)
+
+Takes a `boolean` variable to set if the clear date button will appear on the widget
+
 ----------------------
 
 ### showClose
@@ -233,8 +474,17 @@ Show the "Close" button in the icon toolbar.
 
 Clicking the "Close" button will call `hide()`
 
-----------------------
+#### showClose()
+
+Returns a `boolean` variable with the currently set `options.showClose` option.
 
+#### showClose(boolean)
+
+Takes a `boolean` value.
+
+If `true`, an icon will be displayed on the toolbar that will hide the picker
+
+----------------------
 
 ### widgetPositioning
 
@@ -246,6 +496,18 @@ Clicking the "Close" button will call `hide()`
              horizontal: 'auto', 'left', 'right'
              vertical: 'auto', 'top', 'bottom'
 
+#### widgetPositioning()
+
+Returns the currently set `options.widgetPositioning` object containing two keys `horizontal` and `vertical`
+
+#### widgetPositioning(positioningObject)
+
+Takes an object parameter that can contain two keys `vertical` and `horizontal` each having a value of `'auto', 'top', 'bottom'` for `vertical` and `'auto', 'left', 'right'` for `horizontal` which defines where the dropdown with the widget will appear relative to the input element the component is attached to.
+
+`'auto'` is the default value for both `horizontal` and `vertical` keys and it tries to automatically place the dropdown in a position that is visible to the user. Usually you should not override those options unless you have a special need in your layout.
+
+----------------------
+
 ### widgetParent
 
 	Default: null
@@ -253,17 +515,31 @@ Clicking the "Close" button will call `hide()`
 
 On picker show, places the widget at the identifier (string) or jQuery object **if** the element has css `position: 'relative'`
 
-----------------------
+#### widgetParent()
 
+Returns a `$(element)` variable with the currently set `options.widgetParent` option.
+
+#### widgetParent(widgetParent)
+
+Takes a `string` or `$(element)` value.
+
+----------------------
 
 ### keepOpen
 
 	Default: false
 
-Will cause the date picker to stay open after selecting a date if no time components are being used.
+Will cause the date picker to stay open after selecting a date.
 
-----------------------
+#### keepOpen()
+
+Returns a `boolean` variable with the currently set `options.keepOpen` option.
+
+#### keepOpen(boolean)
+
+Takes a `boolean` value.
 
+----------------------
 
 ### inline
 
@@ -271,17 +547,35 @@ Will cause the date picker to stay open after selecting a date if no time compon
 
 Will display the picker inline without the need of a input field. This will also hide borders and shadows.
 
-----------------------
+#### inline()
+
+Returns a `boolean` variable with the currently set `options.inline` option.
+
+#### inline(boolean)
 
+Takes a `boolean` value.
+
+----------------------
 
 ### keepInvalid
 
+<small>4.7.14</small>
+
 	Default: false
 
 Will cause the date picker to **not** revert or overwrite invalid dates.
 
-----------------------
+#### keepInvalid()
+
+Returns a `string` variable with the currently set `options.keepInvalid` option.
+
+#### keepInvalid(boolean)
+
+Takes a `boolean` value.
 
+If `true`, invalid dates will not be reverted to a previous selection or changed.
+
+----------------------
 
 ### keyBinds
 
@@ -356,6 +650,16 @@ Will cause the date picker to **not** revert or overwrite invalid dates.
 
 Allows for custom events to fire on keyboard press.
 
+#### keyBinds()
+
+Returns a `string` variable with the currently set `options.keyBinds` option.
+
+#### keyBinds(object)
+
+Takes an `object` value.
+
+Allows for several keyBinding functions to be specified for ease of access or accessibility. See the options page for defaults.
+
 ----------------------
 
 
@@ -378,8 +682,17 @@ Will cause the date picker to stay open after a `blur` event.
 
 Allow date picker show event to fire even when the associated input element has the `readonly="readonly"`property.
 
-----------------------
+#### ignoreReadonly()
 
+Returns a `boolean` variable with the currently set `options.ignoreReadonly` option.
+
+#### ignoreReadonly(boolean)
+
+Takes a `boolean` value.
+
+Set this to `true` to allow the picker to be used even if the input field is `readonly`. This will **not** bypass the `disabled` property
+
+----------------------
 
 ### disabledTimeIntervals 
 
@@ -387,10 +700,25 @@ Allow date picker show event to fire even when the associated input element has
 
 	Default: false
 
-Disables time selection between the given `moments`
+Disables time selection between the given `moments`.
 
-----------------------
+#### disabledTimeIntervals()
+
+Returns an `array` variable with the currently set `options.disabledTimeIntervals` option.
+
+#### disabledTimeIntervals(array)
 
+Takes a `array` value.
+
+The array **must** be in the following format `[moment(),moment()]`
+
+For example:
+
+    disabledTimeIntervals: [[moment({ h: 0 }), moment({ h: 8 })], [moment({ h: 18 }), moment({ h: 24 })]]
+
+Will disable times between 12-8am and 6-12pm today
+
+----------------------
 
 ### allowInputToggle 
 
@@ -398,44 +726,62 @@ Disables time selection between the given `moments`
 
 	Default: false
 
+If `true`, the picker will show on textbox focus and icon click when used in a button group.
+
+#### allowInputToggle()
+
+Returns a `boolean` variable with the currently set `options.allowInputToggle` option.
+
+#### allowInputToggle(boolean)
+
+Takes a `boolean` value.
+
 If `true`, the picker will show on textbox focus and icon click when used in a button group
 
 ----------------------
 
-
 ### focusOnShow 
 
 <small>4.14.30</small>
 
 	Default: true
 
-If `false`, the textbox will not be given focus when the picker is shown
+If `false`, the textbox will not be given focus when the picker is shown.
 
-----------------------
+#### focusOnShow()
 
+Returns a `boolean` variable with the currently set `options.focusOnShow` option.
 
-### enabledHours 
+#### focusOnShow(boolean)
 
-<small>4.14.30</small>
+Takes a `boolean` value.
+
+If `false`, the textbox will not be given focus when the picker is shown
+
+----------------------
+### en/disabledHours
+
+<small>4.14.30</small> Issue: #851
 
 	Default: false
 
-Will allow or disallow hour selections (much like `disabledTimeIntervals`) but will affect all days
+#### disabledHours()
 
-----------------------
+Returns an `array` variable with the currently set `options.en/disabledHours` option.
 
+#### disabledHours(boolean)
 
-### disabledHours 
+Takes a `array` value.
 
-<small>4.14.30</small>
+Must be in 24 hour format. Will allow or disallow hour selections (much like `disabledTimeIntervals`) but will affect all days.
 
-	Default: false
+Like `en/disabledDates`, these options are mutually exclusive and will reset one of the options back to false.
 
-Will allow or disallow hour selections (much like `disabledTimeIntervals`) but will affect all days
+    disabledHours: [0, 1, 2, 3, 4, 5, 6, 7, 8, 18, 19, 20, 21, 22, 23, 24]
+    enabledHours: [9, 10, 11, 12, 13, 14, 15, 16]
 
 ----------------------
 
-
 ### viewDate 
 
 <small>4.14.30</small>
@@ -446,6 +792,59 @@ This will change the `viewDate` without changing or setting the selected date.
 
 ----------------------
 
+### parseInputDate
+
+<small>4.14.30</small> Issue #1095
+
+#### parseInputDate()
+
+Returns a `function` with the currently set `options.parseInputDate`
+
+#### parseInputDate(function)
+
+Takes a `function`
+
+Allows custom input formatting For example: the user can enter 'yesterday' or '30 days ago'.
+
+Example:
+
+```
+var parseRelativeDate = function(relativeDate) {
+
+    switch (relativeDate) {
+        case 'today':
+            return moment()
+        case 'yesterday':
+            return moment().subtract(1, 'day');
+        default:
+            return moment()
+                .subtract(Number(relativeDate.replace("days ago", "").trim()), 'days');
+    }
+}
+
+var parseInputDate = function(inputDate) {
+    var relativeDatePattern = /today|yesterday|[0-9]+\s+(days ago)/,
+        resultDate;
+
+    if (moment.isMoment(inputDate) || inputDate instanceof Date) {
+        resultDate = moment(inputDate);
+    } else {
+        var relativeDate = inputDate.match(relativeDatePattern),
+            parseDate = null;
+
+        if (relativeDate !== null) 
+          parseDate = this.parseRelativeDate(inputDate.match(relativeDatePattern)[0]);
+        else 
+          parseDate = moment();
+
+        resultDate = moment(parseDate, "YYYY-MM-DD");
+    }
+
+    return resultDate;
+}
+```
+
+----------------------
 
 ### tooltips 
 
@@ -470,4 +869,41 @@ tooltips: {
 }
 ```
 
-This will change the `tooltips` over each icon to a custom string
+This will change the `tooltips` over each icon to a custom string.
+
+#### tooltips()
+
+Returns an `Ojbect` of `options.tooltips` 
+
+#### tooltips(tooltips)
+
+Takes an `Ojbect` of `strings`.
+
+##### Throws
+
+* `TypeError` - if tooltips parameter is not an `Ojbect`
+
+----------------------
+
+
+### timeZone 
+
+<small>4.17.37</small>
+
+```
+timeZone: ''
+```
+
+Allows the setting of the Time Zone. You must include [`moment-timezone.js`](http://momentjs.com/timezone/) and `moment-timzone` data. See moment timezone documentation for usage.
+
+#### timeZone()
+
+Returns an `string` of `options.timeZone` 
+
+#### timeZone(timeZone)
+
+Takes an `string` of a valid timezone.
+
+##### Throws
+
+* `TypeError` - if tooltips parameter is not an `string`
\ No newline at end of file
diff --git a/docs/index.md b/docs/index.md
index d60df0b..ac35290 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -105,7 +105,7 @@
 
 ----------------------
 
-### Custom Formats
+### Time Only
 
 <div class="container">
     <div class="row">
@@ -157,6 +157,58 @@
 
 ----------------------
 
+### Date Only
+
+<div class="container">
+    <div class="row">
+        <div class='col-sm-6'>
+            <div class="form-group">
+                <div class='input-group date' id='datetimepicker3'>
+                    <input type='text' class="form-control" />
+                    <span class="input-group-addon">
+                        <span class="glyphicon glyphicon-time"></span>
+                    </span>
+                </div>
+            </div>
+        </div>
+        <script type="text/javascript">
+            $(function () {
+                $('#datetimepicker3').datetimepicker({
+                    format: 'L'
+                });
+            });
+        </script>
+    </div>
+</div>
+
+#### Code
+
+```
+<div class="container">
+    <div class="row">
+        <div class='col-sm-6'>
+            <div class="form-group">
+                <div class='input-group date' id='datetimepicker3'>
+                    <input type='text' class="form-control" />
+                    <span class="input-group-addon">
+                        <span class="glyphicon glyphicon-time"></span>
+                    </span>
+                </div>
+            </div>
+        </div>
+        <script type="text/javascript">
+            $(function () {
+                $('#datetimepicker3').datetimepicker({
+                    format: 'LT'
+                });
+            });
+        </script>
+    </div>
+</div>
+```
+
+----------------------
+
 ### No Icon (input field only):
 
 <div class="container">
diff --git a/docs/theme/android-chrome-144x144.png b/docs/theme/android-chrome-144x144.png
new file mode 100644
index 0000000..0c40e34
Binary files /dev/null and b/docs/theme/android-chrome-144x144.png differ
diff --git a/docs/theme/android-chrome-192x192.png b/docs/theme/android-chrome-192x192.png
new file mode 100644
index 0000000..8ec2a4b
Binary files /dev/null and b/docs/theme/android-chrome-192x192.png differ
diff --git a/docs/theme/android-chrome-36x36.png b/docs/theme/android-chrome-36x36.png
new file mode 100644
index 0000000..2b202e9
Binary files /dev/null and b/docs/theme/android-chrome-36x36.png differ
diff --git a/docs/theme/android-chrome-48x48.png b/docs/theme/android-chrome-48x48.png
new file mode 100644
index 0000000..517e151
Binary files /dev/null and b/docs/theme/android-chrome-48x48.png differ
diff --git a/docs/theme/android-chrome-72x72.png b/docs/theme/android-chrome-72x72.png
new file mode 100644
index 0000000..8bcbe34
Binary files /dev/null and b/docs/theme/android-chrome-72x72.png differ
diff --git a/docs/theme/android-chrome-96x96.png b/docs/theme/android-chrome-96x96.png
new file mode 100644
index 0000000..7b1fafe
Binary files /dev/null and b/docs/theme/android-chrome-96x96.png differ
diff --git a/docs/theme/apple-touch-icon-114x114.png b/docs/theme/apple-touch-icon-114x114.png
new file mode 100644
index 0000000..f31b055
Binary files /dev/null and b/docs/theme/apple-touch-icon-114x114.png differ
diff --git a/docs/theme/apple-touch-icon-120x120.png b/docs/theme/apple-touch-icon-120x120.png
new file mode 100644
index 0000000..df87985
Binary files /dev/null and b/docs/theme/apple-touch-icon-120x120.png differ
diff --git a/docs/theme/apple-touch-icon-144x144.png b/docs/theme/apple-touch-icon-144x144.png
new file mode 100644
index 0000000..0c40e34
Binary files /dev/null and b/docs/theme/apple-touch-icon-144x144.png differ
diff --git a/docs/theme/apple-touch-icon-152x152.png b/docs/theme/apple-touch-icon-152x152.png
new file mode 100644
index 0000000..49db777
Binary files /dev/null and b/docs/theme/apple-touch-icon-152x152.png differ
diff --git a/docs/theme/apple-touch-icon-180x180.png b/docs/theme/apple-touch-icon-180x180.png
new file mode 100644
index 0000000..b5bad58
Binary files /dev/null and b/docs/theme/apple-touch-icon-180x180.png differ
diff --git a/docs/theme/apple-touch-icon-57x57.png b/docs/theme/apple-touch-icon-57x57.png
new file mode 100644
index 0000000..d3b682c
Binary files /dev/null and b/docs/theme/apple-touch-icon-57x57.png differ
diff --git a/docs/theme/apple-touch-icon-60x60.png b/docs/theme/apple-touch-icon-60x60.png
new file mode 100644
index 0000000..1575223
Binary files /dev/null and b/docs/theme/apple-touch-icon-60x60.png differ
diff --git a/docs/theme/apple-touch-icon-72x72.png b/docs/theme/apple-touch-icon-72x72.png
new file mode 100644
index 0000000..8bcbe34
Binary files /dev/null and b/docs/theme/apple-touch-icon-72x72.png differ
diff --git a/docs/theme/apple-touch-icon-76x76.png b/docs/theme/apple-touch-icon-76x76.png
new file mode 100644
index 0000000..89d384c
Binary files /dev/null and b/docs/theme/apple-touch-icon-76x76.png differ
diff --git a/docs/theme/apple-touch-icon-precomposed.png b/docs/theme/apple-touch-icon-precomposed.png
new file mode 100644
index 0000000..cc11749
Binary files /dev/null and b/docs/theme/apple-touch-icon-precomposed.png differ
diff --git a/docs/theme/apple-touch-icon.png b/docs/theme/apple-touch-icon.png
new file mode 100644
index 0000000..b5bad58
Binary files /dev/null and b/docs/theme/apple-touch-icon.png differ
diff --git a/docs/theme/base.html b/docs/theme/base.html
new file mode 100644
index 0000000..9f932f9
--- /dev/null
+++ b/docs/theme/base.html
@@ -0,0 +1,74 @@
+<!DOCTYPE html>
+<html lang="en">
+    <head>
+        <meta charset="utf-8">
+        <meta http-equiv="X-UA-Compatible" content="IE=edge">
+        <meta name="viewport" content="width=device-width, initial-scale=1.0">
+        {% if page_description %}<meta name="description" content="{{ page_description }}">{% endif %}
+        {% if site_author %}<meta name="author" content="{{ site_author }}">{% endif %}
+        {% if canonical_url %}<link rel="canonical" href="{{ canonical_url }}">{% endif %}
+        <link rel="apple-touch-icon" sizes="57x57" href="/apple-touch-icon-57x57.png">
+		<link rel="apple-touch-icon" sizes="114x114" href="/apple-touch-icon-114x114.png">
+		<link rel="apple-touch-icon" sizes="72x72" href="/apple-touch-icon-72x72.png">
+		<link rel="apple-touch-icon" sizes="144x144" href="/apple-touch-icon-144x144.png">
+		<link rel="apple-touch-icon" sizes="60x60" href="/apple-touch-icon-60x60.png">
+		<link rel="apple-touch-icon" sizes="120x120" href="/apple-touch-icon-120x120.png">
+		<link rel="apple-touch-icon" sizes="76x76" href="/apple-touch-icon-76x76.png">
+		<link rel="apple-touch-icon" sizes="152x152" href="/apple-touch-icon-152x152.png">
+		<link rel="icon" type="image/png" href="/favicon-196x196.png" sizes="196x196">
+		<link rel="icon" type="image/png" href="/favicon-160x160.png" sizes="160x160">
+		<link rel="icon" type="image/png" href="/favicon-96x96.png" sizes="96x96">
+		<link rel="icon" type="image/png" href="/favicon-16x16.png" sizes="16x16">
+		<link rel="icon" type="image/png" href="/favicon-32x32.png" sizes="32x32">
+		<meta name="msapplication-TileColor" content="#2b5797">
+		<meta name="msapplication-TileImage" content="/mstile-144x144.png">
+
+        <title>{{ page_title }}</title>
+
+        <link rel="stylesheet" type="text/css" media="screen" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" />
+        <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">
+        <link href="{{ base_url }}/css/prettify-1.0.css" rel="stylesheet">
+        <link href="{{ base_url }}/css/base.css" rel="stylesheet">
+        {%- for path in extra_css %}
+        <link href="{{ path }}" rel="stylesheet">
+        {%- endfor %}
+
+        <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
+        <!--[if lt IE 9]>
+            <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
+            <script src="https://oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script>
+        <![endif]-->
+		<script type="text/javascript" src="//code.jquery.com/jquery-2.1.1.min.js"></script>
+		<script type="text/javascript" src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/js/bootstrap.min.js"></script>
+		{%- for path in extra_javascript %}
+			<script src="{{ path }}"></script>
+        {%- endfor %}
+    </head>
+
+    <body>
+
+        {% include "nav.html" %}
+
+        <div class="container">
+			<div class="row">
+				<div class="col-md-3">{% include "toc.html" %}</div>
+				<div class="col-md-9" role="main">{% include "content.html" %}</div>
+			</div>
+        </div>
+
+        {% if include_search %}{% include "search.html" %}{% endif %}
+
+        <script src="{{ base_url }}/js/prettify-1.0.min.js"></script>
+        <script src="{{ base_url }}/js/base.js"></script>
+		<script>
+		if (top != self) { top.location.replace(self.location.href); }
+		(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
+		(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
+		m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
+		})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
+
+		ga('create', 'UA-47462200-1', 'eonasdan.github.io');
+		ga('send', 'pageview');
+		</script>
+    </body>
+</html>
diff --git a/docs/theme/browserconfig.xml b/docs/theme/browserconfig.xml
new file mode 100644
index 0000000..fe44cae
--- /dev/null
+++ b/docs/theme/browserconfig.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<browserconfig>
+  <msapplication>
+    <tile>
+      <square70x70logo src="/mstile-70x70.png"/>
+      <square150x150logo src="/mstile-150x150.png"/>
+      <square310x310logo src="/mstile-310x310.png"/>
+      <wide310x150logo src="/mstile-310x150.png"/>
+      <TileColor>#da532c</TileColor>
+    </tile>
+  </msapplication>
+</browserconfig>
diff --git a/docs/theme/content.html b/docs/theme/content.html
new file mode 100644
index 0000000..a372658
--- /dev/null
+++ b/docs/theme/content.html
@@ -0,0 +1,9 @@
+{% if meta.source %}
+<div class="source-links">
+{% for filename in meta.source %}
+    <span class="label label-primary">{{ filename }}</span>
+{% endfor %}
+</div>
+{% endif %}
+
+{{ content }}
diff --git a/docs/theme/css/base.css b/docs/theme/css/base.css
new file mode 100644
index 0000000..7c063eb
--- /dev/null
+++ b/docs/theme/css/base.css
@@ -0,0 +1,107 @@
+body {
+    padding-top: 70px;
+}
+
+ul.nav li.main {
+    font-weight: bold;
+}
+
+div.col-md-3 {
+    padding-left: 0;
+}
+
+div.source-links {
+    float: right;
+}
+
+/*
+ * Side navigation
+ *
+ * Scrollspy and affixed enhanced navigation to highlight sections and secondary
+ * sections of docs content.
+ */
+
+/* By default it's not affixed in mobile views, so undo that */
+.bs-sidebar {
+  overflow-y: scroll;
+  max-height: 86%;
+  overflow-x: hidden;
+}
+
+.bs-sidebar.affix {
+    position: static;
+}
+
+.bs-sidebar.well {
+    padding: 0;
+}
+
+/* First level of nav */
+.bs-sidenav {
+    margin-top: 30px;
+    margin-bottom: 30px;
+    padding-top:    10px;
+    padding-bottom: 10px;
+    border-radius: 5px;
+}
+
+/* All levels of nav */
+.bs-sidebar .nav > li > a {
+    display: block;
+    padding: 5px 20px;
+}
+.bs-sidebar .nav > li > a:hover,
+.bs-sidebar .nav > li > a:focus {
+    text-decoration: none;
+    border-right: 1px solid;
+}
+.bs-sidebar .nav > .active > a,
+.bs-sidebar .nav > .active:hover > a,
+.bs-sidebar .nav > .active:focus > a {
+    font-weight: bold;
+    background-color: transparent;
+    border-right: 1px solid;
+}
+
+/* Nav: second level (shown on .active) */
+.bs-sidebar .nav .nav {
+    display: none; /* Hide by default, but at >768px, show it */
+    margin-bottom: 8px;
+}
+.bs-sidebar .nav .nav > li > a {
+    padding-top:    3px;
+    padding-bottom: 3px;
+    padding-left: 30px;
+    font-size: 90%;
+}
+
+/* Show and affix the side nav when space allows it */
+ at media (min-width: 992px) {
+    .bs-sidebar .nav > .active > ul {
+        display: block;
+    }
+    /* Widen the fixed sidebar */
+    .bs-sidebar.affix,
+    .bs-sidebar.affix-bottom {
+        width: 213px;
+    }
+    .bs-sidebar.affix {
+        position: fixed; /* Undo the static from mobile first approach */
+        top: 80px;
+    }
+    .bs-sidebar.affix-bottom {
+        position: absolute; /* Undo the static from mobile first approach */
+    }
+    .bs-sidebar.affix-bottom .bs-sidenav,
+    .bs-sidebar.affix .bs-sidenav {
+        margin-top: 0;
+        margin-bottom: 0;
+    }
+}
+ at media (min-width: 1200px) {
+    /* Widen the fixed sidebar again */
+    .bs-sidebar.affix-bottom,
+    .bs-sidebar.affix {
+        width: 263px;
+    }
+}
\ No newline at end of file
diff --git a/docs/theme/css/prettify-1.0.css b/docs/theme/css/prettify-1.0.css
new file mode 100644
index 0000000..e0df245
--- /dev/null
+++ b/docs/theme/css/prettify-1.0.css
@@ -0,0 +1,28 @@
+.com { color: #93a1a1; }
+.lit { color: #195f91; }
+.pun, .opn, .clo { color: #93a1a1; }
+.fun { color: #dc322f; }
+.str, .atv { color: #D14; }
+.kwd, .prettyprint .tag { color: #1e347b; }
+.typ, .atn, .dec, .var { color: teal; }
+.pln { color: #48484c; }
+
+.prettyprint {
+    padding: 8px;
+}
+.prettyprint.linenums {
+  -webkit-box-shadow: inset 40px 0 0 #fbfbfc, inset 41px 0 0 #ececf0;
+     -moz-box-shadow: inset 40px 0 0 #fbfbfc, inset 41px 0 0 #ececf0;
+          box-shadow: inset 40px 0 0 #fbfbfc, inset 41px 0 0 #ececf0;
+}
+
+/* Specify class=linenums on a pre to get line numbering */
+ol.linenums {
+  margin: 0 0 0 33px; /* IE indents via margin-left */
+}
+ol.linenums li {
+  padding-left: 12px;
+  color: #bebec5;
+  line-height: 20px;
+  text-shadow: 0 1px 0 #fff;
+}
diff --git a/docs/theme/favicon-16x16.png b/docs/theme/favicon-16x16.png
new file mode 100644
index 0000000..b8a87bb
Binary files /dev/null and b/docs/theme/favicon-16x16.png differ
diff --git a/docs/theme/favicon-32x32.png b/docs/theme/favicon-32x32.png
new file mode 100644
index 0000000..88eff99
Binary files /dev/null and b/docs/theme/favicon-32x32.png differ
diff --git a/docs/theme/favicon-96x96.png b/docs/theme/favicon-96x96.png
new file mode 100644
index 0000000..7b1fafe
Binary files /dev/null and b/docs/theme/favicon-96x96.png differ
diff --git a/docs/theme/favicon.ico b/docs/theme/favicon.ico
new file mode 100644
index 0000000..b8e6d01
Binary files /dev/null and b/docs/theme/favicon.ico differ
diff --git a/docs/theme/js/base.js b/docs/theme/js/base.js
new file mode 100644
index 0000000..c99cce7
--- /dev/null
+++ b/docs/theme/js/base.js
@@ -0,0 +1,52 @@
+
+/* Prettyify */
+$( document ).ready(function() {
+    prettyPrint();
+});
+
+
+/* Scrollspy */
+var navHeight = $('.navbar').outerHeight(true) + 10
+
+$('body').scrollspy({
+    target: '.bs-sidebar',
+    offset: navHeight
+})
+
+
+/* Prevent disabled links from causing a page reload */
+$("li.disabled a").click(function() {
+    event.preventDefault();
+});
+
+
+/* Adjust the scroll height of anchors to compensate for the fixed navbar */
+window.disableShift = false;
+var shiftWindow = function() {
+    if (window.disableShift) {
+        window.disableShift = false;
+    } else {
+        /* If we're at the bottom of the page, don't erronously scroll up */
+        var scrolledToBottomOfPage = (
+            (window.innerHeight + window.scrollY) >= document.body.offsetHeight
+        );
+        if (!scrolledToBottomOfPage) {
+            scrollBy(0, -60);
+        };
+    };
+};
+if (location.hash) {shiftWindow();}
+window.addEventListener("hashchange", shiftWindow);
+
+
+/* Deal with clicks on nav links that do not change the current anchor link. */
+$("ul.nav a" ).click(function() {
+    var href = this.href;
+    var suffix = location.hash;
+    var matchesCurrentHash = (href.indexOf(suffix, href.length - suffix.length) !== -1);
+    if (location.hash && matchesCurrentHash) {
+        /* Force a single 'hashchange' event to occur after the click event */
+        window.disableShift = true;
+        location.hash='';
+    };
+});
diff --git a/docs/theme/js/prettify-1.0.min.js b/docs/theme/js/prettify-1.0.min.js
new file mode 100644
index 0000000..eef5ad7
--- /dev/null
+++ b/docs/theme/js/prettify-1.0.min.js
@@ -0,0 +1,28 @@
+var q=null;window.PR_SHOULD_USE_CONTINUATION=!0;
+(function(){function L(a){function m(a){var f=a.charCodeAt(0);if(f!==92)return f;var b=a.charAt(1);return(f=r[b])?f:"0"<=b&&b<="7"?parseInt(a.substring(1),8):b==="u"||b==="x"?parseInt(a.substring(2),16):a.charCodeAt(1)}function e(a){if(a<32)return(a<16?"\\x0":"\\x")+a.toString(16);a=String.fromCharCode(a);if(a==="\\"||a==="-"||a==="["||a==="]")a="\\"+a;return a}function h(a){for(var f=a.substring(1,a.length-1).match(/\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\[0-3][0-7]{0,2}|\\[0-7]{1,2}|\\[\S\ [...]
+[],b=[],o=f[0]==="^",c=o?1:0,i=f.length;c<i;++c){var j=f[c];if(/\\[bdsw]/i.test(j))a.push(j);else{var j=m(j),d;c+2<i&&"-"===f[c+1]?(d=m(f[c+2]),c+=2):d=j;b.push([j,d]);d<65||j>122||(d<65||j>90||b.push([Math.max(65,j)|32,Math.min(d,90)|32]),d<97||j>122||b.push([Math.max(97,j)&-33,Math.min(d,122)&-33]))}}b.sort(function(a,f){return a[0]-f[0]||f[1]-a[1]});f=[];j=[NaN,NaN];for(c=0;c<b.length;++c)i=b[c],i[0]<=j[1]+1?j[1]=Math.max(j[1],i[1]):f.push(j=i);b=["["];o&&b.push("^");b.push.apply(b,a) [...]
+f.length;++c)i=f[c],b.push(e(i[0])),i[1]>i[0]&&(i[1]+1>i[0]&&b.push("-"),b.push(e(i[1])));b.push("]");return b.join("")}function y(a){for(var f=a.source.match(/\[(?:[^\\\]]|\\[\S\s])*]|\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\\d+|\\[^\dux]|\(\?[!:=]|[()^]|[^()[\\^]+/g),b=f.length,d=[],c=0,i=0;c<b;++c){var j=f[c];j==="("?++i:"\\"===j.charAt(0)&&(j=+j.substring(1))&&j<=i&&(d[j]=-1)}for(c=1;c<d.length;++c)-1===d[c]&&(d[c]=++t);for(i=c=0;c<b;++c)j=f[c],j==="("?(++i,d[i]===void 0&&(f[c]="(?:")):"\ [...]
+(j=+j.substring(1))&&j<=i&&(f[c]="\\"+d[i]);for(i=c=0;c<b;++c)"^"===f[c]&&"^"!==f[c+1]&&(f[c]="");if(a.ignoreCase&&s)for(c=0;c<b;++c)j=f[c],a=j.charAt(0),j.length>=2&&a==="["?f[c]=h(j):a!=="\\"&&(f[c]=j.replace(/[A-Za-z]/g,function(a){a=a.charCodeAt(0);return"["+String.fromCharCode(a&-33,a|32)+"]"}));return f.join("")}for(var t=0,s=!1,l=!1,p=0,d=a.length;p<d;++p){var g=a[p];if(g.ignoreCase)l=!0;else if(/[a-z]/i.test(g.source.replace(/\\u[\da-f]{4}|\\x[\da-f]{2}|\\[^UXux]/gi,""))){s=!0;l= [...]
+{b:8,t:9,n:10,v:11,f:12,r:13},n=[],p=0,d=a.length;p<d;++p){g=a[p];if(g.global||g.multiline)throw Error(""+g);n.push("(?:"+y(g)+")")}return RegExp(n.join("|"),l?"gi":"g")}function M(a){function m(a){switch(a.nodeType){case 1:if(e.test(a.className))break;for(var g=a.firstChild;g;g=g.nextSibling)m(g);g=a.nodeName;if("BR"===g||"LI"===g)h[s]="\n",t[s<<1]=y++,t[s++<<1|1]=a;break;case 3:case 4:g=a.nodeValue,g.length&&(g=p?g.replace(/\r\n?/g,"\n"):g.replace(/[\t\n\r ]+/g," "),h[s]=g,t[s<<1]=y,y+ [...]
+t[s++<<1|1]=a)}}var e=/(?:^|\s)nocode(?:\s|$)/,h=[],y=0,t=[],s=0,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=document.defaultView.getComputedStyle(a,q).getPropertyValue("white-space"));var p=l&&"pre"===l.substring(0,3);m(a);return{a:h.join("").replace(/\n$/,""),c:t}}function B(a,m,e,h){m&&(a={a:m,d:a},e(a),h.push.apply(h,a.e))}function x(a,m){function e(a){for(var l=a.d,p=[l,"pln"],d=0,g=a.a.match(y)||[],r={},n=0,z=g.length;n<z;++n){var f=g[n],b=r[f],o=void 0 [...]
+"string")c=!1;else{var i=h[f.charAt(0)];if(i)o=f.match(i[1]),b=i[0];else{for(c=0;c<t;++c)if(i=m[c],o=f.match(i[1])){b=i[0];break}o||(b="pln")}if((c=b.length>=5&&"lang-"===b.substring(0,5))&&!(o&&typeof o[1]==="string"))c=!1,b="src";c||(r[f]=b)}i=d;d+=f.length;if(c){c=o[1];var j=f.indexOf(c),k=j+c.length;o[2]&&(k=f.length-o[2].length,j=k-c.length);b=b.substring(5);B(l+i,f.substring(0,j),e,p);B(l+i+j,c,C(b,c),p);B(l+i+k,f.substring(k),e,p)}else p.push(l+i,b)}a.e=p}var h={},y;(function(){fo [...]
+l=[],p={},d=0,g=e.length;d<g;++d){var r=e[d],n=r[3];if(n)for(var k=n.length;--k>=0;)h[n.charAt(k)]=r;r=r[1];n=""+r;p.hasOwnProperty(n)||(l.push(r),p[n]=q)}l.push(/[\S\s]/);y=L(l)})();var t=m.length;return e}function u(a){var m=[],e=[];a.tripleQuotedStrings?m.push(["str",/^(?:'''(?:[^'\\]|\\[\S\s]|''?(?=[^']))*(?:'''|$)|"""(?:[^"\\]|\\[\S\s]|""?(?=[^"]))*(?:"""|$)|'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$))/,q,"'\""]):a.multiLineStrings?m.push(["str",/^(?:'(?:[^'\\]|\\[\S\s [...]
+q,"'\"`"]):m.push(["str",/^(?:'(?:[^\n\r'\\]|\\.)*(?:'|$)|"(?:[^\n\r"\\]|\\.)*(?:"|$))/,q,"\"'"]);a.verbatimStrings&&e.push(["str",/^@"(?:[^"]|"")*(?:"|$)/,q]);var h=a.hashComments;h&&(a.cStyleComments?(h>1?m.push(["com",/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,q,"#"]):m.push(["com",/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\n\r]*)/,q,"#"]),e.push(["str",/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,q])):m.push(["com [...]
+q,"#"]));a.cStyleComments&&(e.push(["com",/^\/\/[^\n\r]*/,q]),e.push(["com",/^\/\*[\S\s]*?(?:\*\/|$)/,q]));a.regexLiterals&&e.push(["lang-regex",/^(?:^^\.?|[!+-]|!=|!==|#|%|%=|&|&&|&&=|&=|\(|\*|\*=|\+=|,|-=|->|\/|\/=|:|::|;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|[?@[^]|\^=|\^\^|\^\^=|{|\||\|=|\|\||\|\|=|~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\s*(\/(?=[^*/])(?:[^/[\\]|\\[\S\s]|\[(?:[^\\\]]|\\[\S\s])*(?:]|$))+\/)/]);(h=a.types)&&e.push(["typ",h]) [...]
+"");a.length&&e.push(["kwd",RegExp("^(?:"+a.replace(/[\s,]+/g,"|")+")\\b"),q]);m.push(["pln",/^\s+/,q," \r\n\t\xa0"]);e.push(["lit",/^@[$_a-z][\w$@]*/i,q],["typ",/^(?:[@_]?[A-Z]+[a-z][\w$@]*|\w+_t\b)/,q],["pln",/^[$_a-z][\w$@]*/i,q],["lit",/^(?:0x[\da-f]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+-]?\d+)?)[a-z]*/i,q,"0123456789"],["pln",/^\\[\S\s]?/,q],["pun",/^.[^\s\w"-$'./@\\`]*/,q]);return x(m,e)}function D(a,m){function e(a){switch(a.nodeType){case 1:if(k.test(a.className))break;if("B [...]
+a.parentNode&&a.parentNode.removeChild(a);else for(a=a.firstChild;a;a=a.nextSibling)e(a);break;case 3:case 4:if(p){var b=a.nodeValue,d=b.match(t);if(d){var c=b.substring(0,d.index);a.nodeValue=c;(b=b.substring(d.index+d[0].length))&&a.parentNode.insertBefore(s.createTextNode(b),a.nextSibling);h(a);c||a.parentNode.removeChild(a)}}}}function h(a){function b(a,d){var e=d?a.cloneNode(!1):a,f=a.parentNode;if(f){var f=b(f,1),g=a.nextSibling;f.appendChild(e);for(var h=g;h;h=g)g=h.nextSibling,f. [...]
+for(;!a.nextSibling;)if(a=a.parentNode,!a)return;for(var a=b(a.nextSibling,0),e;(e=a.parentNode)&&e.nodeType===1;)a=e;d.push(a)}var k=/(?:^|\s)nocode(?:\s|$)/,t=/\r\n?|\n/,s=a.ownerDocument,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=s.defaultView.getComputedStyle(a,q).getPropertyValue("white-space"));var p=l&&"pre"===l.substring(0,3);for(l=s.createElement("LI");a.firstChild;)l.appendChild(a.firstChild);for(var d=[l],g=0;g<d.length;++g)e(d[g]);m===(m|0)&&d[0] [...]
+m);var r=s.createElement("OL");r.className="linenums";for(var n=Math.max(0,m-1|0)||0,g=0,z=d.length;g<z;++g)l=d[g],l.className="L"+(g+n)%10,l.firstChild||l.appendChild(s.createTextNode("\xa0")),r.appendChild(l);a.appendChild(r)}function k(a,m){for(var e=m.length;--e>=0;){var h=m[e];A.hasOwnProperty(h)?window.console&&console.warn("cannot override language handler %s",h):A[h]=a}}function C(a,m){if(!a||!A.hasOwnProperty(a))a=/^\s*</.test(m)?"default-markup":"default-code";return A[a]}funct [...]
+a.g;try{var e=M(a.h),h=e.a;a.a=h;a.c=e.c;a.d=0;C(m,h)(a);var k=/\bMSIE\b/.test(navigator.userAgent),m=/\n/g,t=a.a,s=t.length,e=0,l=a.c,p=l.length,h=0,d=a.e,g=d.length,a=0;d[g]=s;var r,n;for(n=r=0;n<g;)d[n]!==d[n+2]?(d[r++]=d[n++],d[r++]=d[n++]):n+=2;g=r;for(n=r=0;n<g;){for(var z=d[n],f=d[n+1],b=n+2;b+2<=g&&d[b+1]===f;)b+=2;d[r++]=z;d[r++]=f;n=b}for(d.length=r;h<p;){var o=l[h+2]||s,c=d[a+2]||s,b=Math.min(o,c),i=l[h+1],j;if(i.nodeType!==1&&(j=t.substring(e,b))){k&&(j=j.replace(m,"\r"));i.n [...]
+j;var u=i.ownerDocument,v=u.createElement("SPAN");v.className=d[a+1];var x=i.parentNode;x.replaceChild(v,i);v.appendChild(i);e<o&&(l[h+1]=i=u.createTextNode(t.substring(b,o)),x.insertBefore(i,v.nextSibling))}e=b;e>=o&&(h+=2);e>=c&&(a+=2)}}catch(w){"console"in window&&console.log(w&&w.stack?w.stack:w)}}var v=["break,continue,do,else,for,if,return,while"],w=[[v,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,uni [...]
+"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"],F=[w,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"],G=[w,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,thro [...]
+H=[G,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"],w=[w,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"],I=[v,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield [...]
+J=[v,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"],v=[v,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"],K=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/,N=/\S/,O=u({keywords:[F,H,w,"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,pac [...]
+I,J,v],hashComments:!0,cStyleComments:!0,multiLineStrings:!0,regexLiterals:!0}),A={};k(O,["default-code"]);k(x([],[["pln",/^[^<?]+/],["dec",/^<!\w[^>]*(?:>|$)/],["com",/^<\!--[\S\s]*?(?:--\>|$)/],["lang-",/^<\?([\S\s]+?)(?:\?>|$)/],["lang-",/^<%([\S\s]+?)(?:%>|$)/],["pun",/^(?:<[%?]|[%?]>)/],["lang-",/^<xmp\b[^>]*>([\S\s]+?)<\/xmp\b[^>]*>/i],["lang-js",/^<script\b[^>]*>([\S\s]*?)(<\/script\b[^>]*>)/i],["lang-css",/^<style\b[^>]*>([\S\s]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z] [...]
+["default-markup","htm","html","mxml","xhtml","xml","xsl"]);k(x([["pln",/^\s+/,q," \t\r\n"],["atv",/^(?:"[^"]*"?|'[^']*'?)/,q,"\"'"]],[["tag",/^^<\/?[a-z](?:[\w-.:]*\w)?|\/?>$/i],["atn",/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^\s"'>]*(?:[^\s"'/>]|\/(?=\s)))/],["pun",/^[/<->]+/],["lang-js",/^on\w+\s*=\s*"([^"]+)"/i],["lang-js",/^on\w+\s*=\s*'([^']+)'/i],["lang-js",/^on\w+\s*=\s*([^\s"'>]+)/i],["lang-css",/^style\s*=\s*"([^"]+)"/i],["lang-css",/^style\s*=\s*'([^']+ [...]
+/^style\s*=\s*([^\s"'>]+)/i]]),["in.tag"]);k(x([],[["atv",/^[\S\s]+/]]),["uq.val"]);k(u({keywords:F,hashComments:!0,cStyleComments:!0,types:K}),["c","cc","cpp","cxx","cyc","m"]);k(u({keywords:"null,true,false"}),["json"]);k(u({keywords:H,hashComments:!0,cStyleComments:!0,verbatimStrings:!0,types:K}),["cs"]);k(u({keywords:G,cStyleComments:!0}),["java"]);k(u({keywords:v,hashComments:!0,multiLineStrings:!0}),["bsh","csh","sh"]);k(u({keywords:I,hashComments:!0,multiLineStrings:!0,tripleQuote [...]
+["cv","py"]);k(u({keywords:"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["perl","pl","pm"]);k(u({keywords:J,hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["rb"]);k(u({keywords:w,cStyleComments:!0,regexLiterals:!0}),["js"]);k(u({keywords:"all,and,by,catch,class,else,extends,false,finally,for,if,i [...]
+hashComments:3,cStyleComments:!0,multilineStrings:!0,tripleQuotedStrings:!0,regexLiterals:!0}),["coffee"]);k(x([],[["str",/^[\S\s]+/]]),["regex"]);window.prettyPrintOne=function(a,m,e){var h=document.createElement("PRE");h.innerHTML=a;e&&D(h,e);E({g:m,i:e,h:h});return h.innerHTML};window.prettyPrint=function(a){function m(){for(var e=window.PR_SHOULD_USE_CONTINUATION?l.now()+250:Infinity;p<h.length&&l.now()<e;p++){var n=h[p],k=n.className;if(k.indexOf("prettyprint")>=0){var k=k.match(g), [...]
+!k){b=n;for(var o=void 0,c=b.firstChild;c;c=c.nextSibling)var i=c.nodeType,o=i===1?o?b:c:i===3?N.test(c.nodeValue)?b:o:o;b=(f=o===b?void 0:o)&&"CODE"===f.tagName}b&&(k=f.className.match(g));k&&(k=k[1]);b=!1;for(o=n.parentNode;o;o=o.parentNode)if((o.tagName==="pre"||o.tagName==="code"||o.tagName==="xmp")&&o.className&&o.className.indexOf("prettyprint")>=0){b=!0;break}b||((b=(b=n.className.match(/\blinenums\b(?::(\d+))?/))?b[1]&&b[1].length?+b[1]:!0:!1)&&D(n,b),d={g:k,h:n,i:b},E(d))}}p<h.l [...]
+250):a&&a()}for(var e=[document.getElementsByTagName("pre"),document.getElementsByTagName("code"),document.getElementsByTagName("xmp")],h=[],k=0;k<e.length;++k)for(var t=0,s=e[k].length;t<s;++t)h.push(e[k][t]);var e=q,l=Date;l.now||(l={now:function(){return+new Date}});var p=0,d,g=/\blang(?:uage)?-([\w.]+)(?!\S)/;m()};window.PR={createSimpleLexer:x,registerLangHandler:k,sourceDecorator:u,PR_ATTRIB_NAME:"atn",PR_ATTRIB_VALUE:"atv",PR_COMMENT:"com",PR_DECLARATION:"dec",PR_KEYWORD:"kwd",PR_ [...]
+PR_NOCODE:"nocode",PR_PLAIN:"pln",PR_PUNCTUATION:"pun",PR_SOURCE:"src",PR_STRING:"str",PR_TAG:"tag",PR_TYPE:"typ"}})();
diff --git a/docs/theme/manifest.json b/docs/theme/manifest.json
new file mode 100644
index 0000000..73c8255
--- /dev/null
+++ b/docs/theme/manifest.json
@@ -0,0 +1,41 @@
+{
+	"name": "Eonasdan.com",
+	"icons": [
+		{
+			"src": "\/android-chrome-36x36.png",
+			"sizes": "36x36",
+			"type": "image\/png",
+			"density": "0.75"
+		},
+		{
+			"src": "\/android-chrome-48x48.png",
+			"sizes": "48x48",
+			"type": "image\/png",
+			"density": "1.0"
+		},
+		{
+			"src": "\/android-chrome-72x72.png",
+			"sizes": "72x72",
+			"type": "image\/png",
+			"density": "1.5"
+		},
+		{
+			"src": "\/android-chrome-96x96.png",
+			"sizes": "96x96",
+			"type": "image\/png",
+			"density": "2.0"
+		},
+		{
+			"src": "\/android-chrome-144x144.png",
+			"sizes": "144x144",
+			"type": "image\/png",
+			"density": "3.0"
+		},
+		{
+			"src": "\/android-chrome-192x192.png",
+			"sizes": "192x192",
+			"type": "image\/png",
+			"density": "4.0"
+		}
+	]
+}
diff --git a/docs/theme/mstile-144x144.png b/docs/theme/mstile-144x144.png
new file mode 100644
index 0000000..20647d7
Binary files /dev/null and b/docs/theme/mstile-144x144.png differ
diff --git a/docs/theme/mstile-150x150.png b/docs/theme/mstile-150x150.png
new file mode 100644
index 0000000..b728b98
Binary files /dev/null and b/docs/theme/mstile-150x150.png differ
diff --git a/docs/theme/mstile-310x150.png b/docs/theme/mstile-310x150.png
new file mode 100644
index 0000000..b8bf492
Binary files /dev/null and b/docs/theme/mstile-310x150.png differ
diff --git a/docs/theme/mstile-310x310.png b/docs/theme/mstile-310x310.png
new file mode 100644
index 0000000..649ffa1
Binary files /dev/null and b/docs/theme/mstile-310x310.png differ
diff --git a/docs/theme/mstile-70x70.png b/docs/theme/mstile-70x70.png
new file mode 100644
index 0000000..d76ae36
Binary files /dev/null and b/docs/theme/mstile-70x70.png differ
diff --git a/docs/theme/nav.html b/docs/theme/nav.html
new file mode 100644
index 0000000..0c5c26b
--- /dev/null
+++ b/docs/theme/nav.html
@@ -0,0 +1,76 @@
+<div class="navbar navbar-default navbar-fixed-top" role="navigation">
+    <div class="container">
+
+        <!-- Collapsed navigation -->
+        <div class="navbar-header">
+            <!-- Expander button -->
+            <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
+                <span class="sr-only">Toggle navigation</span>
+                <span class="icon-bar"></span>
+                <span class="icon-bar"></span>
+                <span class="icon-bar"></span>
+            </button>
+
+            <!-- Main title -->
+            <a class="navbar-brand" href="{{ homepage_url }}">{{ site_name }}</a>
+        </div>
+
+        <!-- Expanded navigation -->
+        <div class="navbar-collapse collapse">
+            <!-- Main navigation -->
+            <ul class="nav navbar-nav">
+            {% for nav_item in nav %}
+            {% if nav_item.children %}
+                <li class="dropdown{% if nav_item.active %} active{% endif %}">
+                    <a href="#" class="dropdown-toggle" data-toggle="dropdown">{{ nav_item.title }} <b class="caret"></b></a>
+                    <ul class="dropdown-menu">
+                    {% for nav_item in nav_item.children %}
+                        <li {% if nav_item.active %}class="active"{% endif %}>
+                            <a href="{{ nav_item.url }}">{{ nav_item.title }}</a>
+                        </li>
+                    {% endfor %}
+                    </ul>
+                </li>
+            {% else %}
+                <li {% if nav_item.active %}class="active"{% endif %}>
+                    <a href="{{ nav_item.url }}">{{ nav_item.title }}</a>
+                </li>
+            {% endif %}
+            {% endfor %}
+            </ul>
+
+            <!-- Search, Navigation and Repo links -->
+            <ul class="nav navbar-nav navbar-right">
+                {% if include_search %}
+                <li>
+                    <a href="#searchModal" data-toggle="modal"><i class="fa fa-search"></i> Search</a>
+                </li>
+                {% endif %}
+				{% if false %}
+                <li {% if not previous_page %}class="disabled"{% endif %}>
+                    <a rel="next" {% if previous_page %}href="{{ previous_page.url }}"{% endif %}>
+                        <i class="fa fa-arrow-left"></i> Previous
+                    </a>
+                </li>
+                <li {% if not next_page %}class="disabled"{% endif %}>
+                    <a rel="prev" {% if next_page %}href="{{ next_page.url }}"{% endif %}>
+                        Next <i class="fa fa-arrow-right"></i>
+                    </a>
+                </li>
+				{% endif %}
+                {% if repo_url %}
+                <li>
+                    <a href="{{ repo_url }}">
+                        {% if repo_name == 'GitHub' %}
+                            <i class="fa fa-github"></i>
+                        {% elif repo_name == 'Bitbucket' %}
+                            <i class="fa fa-bitbucket"></i>
+                        {% endif %}
+                        {{ repo_name }}
+                    </a>
+                </li>
+                {% endif %}
+            </ul>
+        </div>
+    </div>
+</div>
diff --git a/docs/theme/toc.html b/docs/theme/toc.html
new file mode 100644
index 0000000..bb8fdcd
--- /dev/null
+++ b/docs/theme/toc.html
@@ -0,0 +1,10 @@
+<div class="bs-sidebar hidden-print affix well" role="complementary">
+    <ul class="nav bs-sidenav">
+    {% for toc_item in toc %}
+        <li class="main {% if toc_item.active %}active{% endif %}"><a href="{{ toc_item.url }}">{{ toc_item.title }}</a></li>
+        {% for toc_item in toc_item.children %}
+            <li><a href="{{ toc_item.url }}">{{ toc_item.title }}</a></li>
+        {% endfor %}
+    {% endfor %}
+    </ul>
+</div>
diff --git a/mkdocs.yml b/mkdocs.yml
index 5df9623..b83c6b8 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -1,17 +1,202 @@
 site_name: Bootstrap 3 Datepicker
-theme: bootstrap
+theme_dir: docs/theme
 extra_javascript: ['//cdnjs.cloudflare.com/ajax/libs/moment.js/2.9.0/moment-with-locales.js','//cdn.rawgit.com/Eonasdan/bootstrap-datetimepicker/e8bddc60e73c1ec2475f827be36e1957af72e2ea/src/js/bootstrap-datetimepicker.js']
 extra_css: ['//cdn.rawgit.com/Eonasdan/bootstrap-datetimepicker/e8bddc60e73c1ec2475f827be36e1957af72e2ea/build/css/bootstrap-datetimepicker.css']
 repo_url: https://github.com/Eonasdan/bootstrap-datetimepicker
 pages:
-- ['index.md', 'Usage']
-- ['Installing.md', 'Installing']
-- ['Functions.md', 'Functions']
-- ['Options.md', 'Options']
-- ['Events.md', 'Events']
-- ['Changelog.md', 'Change Log']
-- ['ContributorsGuide.md', 'Dev Guide']
-- ['Extras.md', 'Extras']
-- ['FAQ.md', 'FAQs']
-- ['Version 4 Changelog.md', '']
-- ['Version 4 Contributors guide.md', '']
\ No newline at end of file
+- Usage: 'index.md'
+- Installing: 'Installing.md'
+- Functions: 'Functions.md'
+- Options: 'Options.md'
+- Events: 'Events.md'
+- Change Log: 'Changelog.md'
+- Dev Guide: 'ContributorsGuide.md'
+- Extras: 'Extras.md'
+- FAQs: 'FAQ.md'
+- Issues:
+    - Issues: 'Issues/Index.md'
+    - 1014: 'Issues/1014.md'
+    - 1041: 'Issues/1041.md'
+    - 1045: 'Issues/1045.md'
+    - 1058: 'Issues/1058.md'
+    - 1059: 'Issues/1059.md'
+    - 1065: 'Issues/1065.md'
+    - 1073: 'Issues/1073.md'
+    - 1097: 'Issues/1097.md'
+    - 1126: 'Issues/1126.md'
+    - 1130: 'Issues/1130.md'
+    - 1132: 'Issues/1132.md'
+    - 1144: 'Issues/1144.md'
+    - 1154: 'Issues/1154.md'
+    - 1158: 'Issues/1158.md'
+    - 1170: 'Issues/1170.md'
+    - 1171: 'Issues/1171.md'
+    - 1173: 'Issues/1173.md'
+    - 1177: 'Issues/1177.md'
+    - 1180: 'Issues/1180.md'
+    - 1181: 'Issues/1181.md'
+    - 1185: 'Issues/1185.md'
+    - 1186: 'Issues/1186.md'
+    - 1189: 'Issues/1189.md'
+    - 1191: 'Issues/1191.md'
+    - 1195: 'Issues/1195.md'
+    - 1199: 'Issues/1199.md'
+    - 1211: 'Issues/1211.md'
+    - 1219: 'Issues/1219.md'
+    - 1224: 'Issues/1224.md'
+    - 1236: 'Issues/1236.md'
+    - 1238: 'Issues/1238.md'
+    - 1246: 'Issues/1246.md'
+    - 1247: 'Issues/1247.md'
+    - 1249: 'Issues/1249.md'
+    - 1250: 'Issues/1250.md'
+    - 1251: 'Issues/1251.md'
+    - 1257: 'Issues/1257.md'
+    - 1267: 'Issues/1267.md'
+    - 1270: 'Issues/1270.md'
+    - 1273: 'Issues/1273.md'
+    - 1276: 'Issues/1276.md'
+    - 1277: 'Issues/1277.md'
+    - 1278: 'Issues/1278.md'
+    - 1279: 'Issues/1279.md'
+    - 1285: 'Issues/1285.md'
+    - 1289: 'Issues/1289.md'
+    - 1290: 'Issues/1290.md'
+    - 1291: 'Issues/1291.md'
+    - 1294: 'Issues/1294.md'
+    - 1295: 'Issues/1295.md'
+    - 1297: 'Issues/1297.md'
+    - 1299: 'Issues/1299.md'
+    - 1300: 'Issues/1300.md'
+    - 1302: 'Issues/1302.md'
+    - 1303: 'Issues/1303.md'
+    - 1304: 'Issues/1304.md'
+    - 1307: 'Issues/1307.md'
+    - 1311: 'Issues/1311.md'
+    - 1313: 'Issues/1313.md'
+    - 1314: 'Issues/1314.md'
+    - 1318: 'Issues/1318.md'
+    - 1323: 'Issues/1323.md'
+    - 1324: 'Issues/1324.md'
+    - 1326: 'Issues/1326.md'
+    - 1328: 'Issues/1328.md'
+    - 1334: 'Issues/1334.md'
+    - 1337: 'Issues/1337.md'
+    - 1338: 'Issues/1338.md'
+    - 1339: 'Issues/1339.md'
+    - 1340: 'Issues/1340.md'
+    - 1341: 'Issues/1341.md'
+    - 1343: 'Issues/1343.md'
+    - 1344: 'Issues/1344.md'
+    - 1345: 'Issues/1345.md'
+    - 1346: 'Issues/1346.md'
+    - 1347: 'Issues/1347.md'
+    - 1349: 'Issues/1349.md'
+    - 1351: 'Issues/1351.md'
+    - 1353: 'Issues/1353.md'
+    - 1354: 'Issues/1354.md'
+    - 1355: 'Issues/1355.md'
+    - 1356: 'Issues/1356.md'
+    - 1357: 'Issues/1357.md'
+    - 1358: 'Issues/1358.md'
+    - 1359: 'Issues/1359.md'
+    - 1360: 'Issues/1360.md'
+    - 1361: 'Issues/1361.md'
+    - 1363: 'Issues/1363.md'
+    - 1364: 'Issues/1364.md'
+    - 1366: 'Issues/1366.md'
+    - 1368: 'Issues/1368.md'
+    - 1369: 'Issues/1369.md'
+    - 1371: 'Issues/1371.md'
+    - 1372: 'Issues/1372.md'
+    - 1374: 'Issues/1374.md'
+    - 1377: 'Issues/1377.md'
+    - 1379: 'Issues/1379.md'
+    - 1380: 'Issues/1380.md'
+    - 1383: 'Issues/1383.md'
+    - 1384: 'Issues/1384.md'
+    - 1386: 'Issues/1386.md'
+    - 1387: 'Issues/1387.md'
+    - 1395: 'Issues/1395.md'
+    - 1405: 'Issues/1405.md'
+    - 1408: 'Issues/1408.md'
+    - 1412: 'Issues/1412.md'
+    - 1413: 'Issues/1413.md'
+    - 1417: 'Issues/1417.md'
+    - 1422: 'Issues/1422.md'
+    - 1423: 'Issues/1423.md'
+    - 1426: 'Issues/1426.md'
+    - 1427: 'Issues/1427.md'
+    - 1428: 'Issues/1428.md'
+    - 1429: 'Issues/1429.md'
+    - 1430: 'Issues/1430.md'
+    - 1432: 'Issues/1432.md'
+    - 1433: 'Issues/1433.md'
+    - 1436: 'Issues/1436.md'
+    - 1438: 'Issues/1438.md'
+    - 1439: 'Issues/1439.md'
+    - 1441: 'Issues/1441.md'
+    - 1443: 'Issues/1443.md'
+    - 1444: 'Issues/1444.md'
+    - 1445: 'Issues/1445.md'
+    - 1446: 'Issues/1446.md'
+    - 1448: 'Issues/1448.md'
+    - 1449: 'Issues/1449.md'
+    - 1453: 'Issues/1453.md'
+    - 1454: 'Issues/1454.md'
+    - 1457: 'Issues/1457.md'
+    - 1459: 'Issues/1459.md'
+    - 1461: 'Issues/1461.md'
+    - 1462: 'Issues/1462.md'
+    - 1463: 'Issues/1463.md'
+    - 1465: 'Issues/1465.md'
+    - 1466: 'Issues/1466.md'
+    - 1469: 'Issues/1469.md'
+    - 1471: 'Issues/1471.md'
+    - 1474: 'Issues/1474.md'
+    - 1475: 'Issues/1475.md'
+    - 1477: 'Issues/1477.md'
+    - 1478: 'Issues/1478.md'
+    - 1479: 'Issues/1479.md'
+    - 1480: 'Issues/1480.md'
+    - 1483: 'Issues/1483.md'
+    - 1484: 'Issues/1484.md'
+    - 1485: 'Issues/1485.md'
+    - 1486: 'Issues/1486.md'
+    - 1489: 'Issues/1489.md'
+    - 1490: 'Issues/1490.md'
+    - 1491: 'Issues/1491.md'
+    - 1493: 'Issues/1493.md'
+    - 1494: 'Issues/1494.md'
+    - 1496: 'Issues/1496.md'
+    - 1498: 'Issues/1498.md'
+    - 1499: 'Issues/1499.md'
+    - 1505: 'Issues/1505.md'
+    - 1506: 'Issues/1506.md'
+    - 1507: 'Issues/1507.md'
+    - 1511: 'Issues/1511.md'
+    - 1512: 'Issues/1512.md'
+    - 1513: 'Issues/1513.md'
+    - 1514: 'Issues/1514.md'
+    - 1515: 'Issues/1515.md'
+    - 1516: 'Issues/1516.md'
+    - 1519: 'Issues/1519.md'
+    - 1520: 'Issues/1520.md'
+    - 1521: 'Issues/1521.md'
+    - 1522: 'Issues/1522.md'
+    - 1523: 'Issues/1523.md'
+    - 1524: 'Issues/1524.md'
+    - 1526: 'Issues/1526.md'
+    - 1527: 'Issues/1527.md'
+    - 1529: 'Issues/1529.md'
+    - 766: 'Issues/766.md'
+    - 790: 'Issues/790.md'
+    - 935: 'Issues/935.md'
+    - 943: 'Issues/943.md'
+    - 950: 'Issues/950.md'
+    - 957: 'Issues/957.md'
+    - 959: 'Issues/959.md'
+    - 982: 'Issues/982.md'
+    - 985: 'Issues/985.md'
+    - 993: 'Issues/993.md'
+    - 995: 'Issues/995.md'
diff --git a/package.json b/package.json
index 01f82d1..8637390 100644
--- a/package.json
+++ b/package.json
@@ -1,43 +1,45 @@
 {
-    "author": {
-        "name": "Jonathan Peterson"
-    },
-    "bugs": {
-        "url": "https://github.com/eonasdan/bootstrap-datetimepicker/issues"
-    },
-    "dependencies": {
-        "moment": "~2.8",
-        "moment-timezone" : "~0.4",
-        "bootstrap": "^3.3",
-        "jquery": ">=1.8.3 <2.2.0"
-    },
-    "description": "A date/time picker component designed to work with Bootstrap 3 and Momentjs. For usage, installation and demos see Project Site on GitHub",
-    "devDependencies": {
-        "grunt": "latest",
-        "grunt-contrib-jasmine": "^0.7.0",
-        "grunt-contrib-jshint": "latest",
-        "grunt-contrib-less": "latest",
-        "grunt-contrib-uglify": "latest",
-        "grunt-jscs": "latest",
-        "grunt-string-replace": "latest",
-        "load-grunt-tasks": "latest",
-        "grunt-nuget": "^0.1.4"
-    },
-    "homepage": "http://eonasdan.github.io/bootstrap-datetimepicker/",
-    "keywords": [
-        "twitter-bootstrap",
-        "bootstrap",
-        "datepicker",
-        "datetimepicker",
-        "timepicker",
-        "moment"
-    ],
-    "license": "MIT",
-    "main": "src/js/bootstrap-datetimepicker.js",
-    "name": "eonasdan-bootstrap-datetimepicker",
-    "repository": {
-        "type": "git",
-        "url": "https://github.com/eonasdan/bootstrap-datetimepicker.git"
-    },
-    "version": "4.17.37"
+  "author": {
+    "name": "Jonathan Peterson"
+  },
+  "bugs": {
+    "url": "https://github.com/eonasdan/bootstrap-datetimepicker/issues"
+  },
+  "dependencies": {
+    "bootstrap": "^3.3",
+    "jquery": "^1.8.3 || ^2.0",
+    "moment": "^2.10",
+    "moment-timezone": "^0.4.0"
+  },
+  "description": "A date/time picker component designed to work with Bootstrap 3 and Momentjs. For usage, installation and demos see Project Site on GitHub",
+  "devDependencies": {
+    "grunt": "latest",
+    "grunt-contrib-connect": "^1.0.1",
+    "grunt-contrib-jasmine": "^1.0.3",
+    "grunt-contrib-jshint": "latest",
+    "grunt-contrib-less": "latest",
+    "grunt-contrib-uglify": "latest",
+    "grunt-env": "^0.4.4",
+    "grunt-jscs": "latest",
+    "grunt-nuget": "^0.1.5",
+    "grunt-string-replace": "latest",
+    "load-grunt-tasks": "latest"
+  },
+  "homepage": "http://eonasdan.github.io/bootstrap-datetimepicker/",
+  "keywords": [
+    "twitter-bootstrap",
+    "bootstrap",
+    "datepicker",
+    "datetimepicker",
+    "timepicker",
+    "moment"
+  ],
+  "license": "MIT",
+  "main": "src/js/bootstrap-datetimepicker.js",
+  "name": "eonasdan-bootstrap-datetimepicker",
+  "repository": {
+    "type": "git",
+    "url": "https://github.com/eonasdan/bootstrap-datetimepicker.git"
+  },
+  "version": "4.17.42"
 }
diff --git a/src/js/bootstrap-datetimepicker.js b/src/js/bootstrap-datetimepicker.js
index 31e4e6a..5d2cc71 100644
--- a/src/js/bootstrap-datetimepicker.js
+++ b/src/js/bootstrap-datetimepicker.js
@@ -1,4 +1,4 @@
-/*! version : 4.17.37
+/*! version : 4.17.42
  =========================================================
  bootstrap-datetimejs
  https://github.com/Eonasdan/bootstrap-datetimepicker
@@ -39,7 +39,7 @@
         // AMD is used - Register as an anonymous module.
         define(['jquery', 'moment'], factory);
     } else if (typeof exports === 'object') {
-        factory(require('jquery'), require('moment'));
+        module.exports = factory(require('jquery'), require('moment'));
     } else {
         // Neither AMD nor CommonJS used. Use global variables.
         if (typeof jQuery === 'undefined') {
@@ -132,40 +132,30 @@
              * Private functions
              *
              ********************************************************************************/
+
+            hasTimeZone = function () {
+                return moment.tz !== undefined && options.timeZone !== undefined && options.timeZone !== null && options.timeZone !== '';
+            },
+
             getMoment = function (d) {
-                var tzEnabled = false,
-                    returnMoment,
-                    currentZoneOffset,
-                    incomingZoneOffset,
-                    timeZoneIndicator,
-                    dateWithTimeZoneInfo;
+                var returnMoment;
 
-                if (moment.tz !== undefined && options.timeZone !== undefined && options.timeZone !== null && options.timeZone !== '') {
-                    tzEnabled = true;
-                }
                 if (d === undefined || d === null) {
-                    if (tzEnabled) {
-                        returnMoment = moment().tz(options.timeZone).startOf('d');
-                    } else {
-                        returnMoment = moment().startOf('d');
-                    }
+                    returnMoment = moment(); //TODO should this use format? and locale?
+                } else if (hasTimeZone()) { // There is a string to parse and a default time zone
+                    // parse with the tz function which takes a default time zone if it is not in the format string
+                    returnMoment = moment.tz(d, parseFormats, options.useStrict, options.timeZone);
                 } else {
-                    if (tzEnabled) {
-                        currentZoneOffset = moment().tz(options.timeZone).utcOffset();
-                        incomingZoneOffset = moment(d, parseFormats, options.useStrict).utcOffset();
-                        if (incomingZoneOffset !== currentZoneOffset) {
-                            timeZoneIndicator = moment().tz(options.timeZone).format('Z');
-                            dateWithTimeZoneInfo = moment(d, parseFormats, options.useStrict).format('YYYY-MM-DD[T]HH:mm:ss') + timeZoneIndicator;
-                            returnMoment = moment(dateWithTimeZoneInfo, parseFormats, options.useStrict).tz(options.timeZone);
-                        } else {
-                            returnMoment = moment(d, parseFormats, options.useStrict).tz(options.timeZone);
-                        }
-                    } else {
-                        returnMoment = moment(d, parseFormats, options.useStrict);
-                    }
+                    returnMoment = moment(d, parseFormats, options.useStrict);
                 }
+
+                if (hasTimeZone()) {
+                    returnMoment.tz(options.timeZone);
+                }
+
                 return returnMoment;
             },
+
             isEnabled = function (granularity) {
                 if (typeof granularity !== 'string' || granularity.length > 1) {
                     throw new TypeError('isEnabled expects a single character string parameter');
@@ -188,6 +178,7 @@
                         return false;
                 }
             },
+
             hasTime = function () {
                 return (isEnabled('h') || isEnabled('m') || isEnabled('s'));
             },
@@ -243,13 +234,11 @@
 
                 if (isEnabled('h')) {
                     topRow.append($('<td>')
-                        .append($('<a>').attr({href: '#', tabindex: '-1', 'title': options.tooltips.incrementHour}).addClass('btn').attr('data-action', 'incrementHours')
-                            .append($('<span>').addClass(options.icons.up))));
+                        .append($('<a>').attr({ href: '#', tabindex: '-1', 'title': options.tooltips.incrementHour }).addClass('btn').attr('data-action', 'incrementHours').append($('<span>').addClass(options.icons.up))));
                     middleRow.append($('<td>')
-                        .append($('<span>').addClass('timepicker-hour').attr({'data-time-component':'hours', 'title': options.tooltips.pickHour}).attr('data-action', 'showHours')));
+                        .append($('<span>').addClass('timepicker-hour').attr({ 'data-time-component': 'hours', 'title': options.tooltips.pickHour }).attr('data-action', 'showHours')));
                     bottomRow.append($('<td>')
-                        .append($('<a>').attr({href: '#', tabindex: '-1', 'title': options.tooltips.decrementHour}).addClass('btn').attr('data-action', 'decrementHours')
-                            .append($('<span>').addClass(options.icons.down))));
+                        .append($('<a>').attr({ href: '#', tabindex: '-1', 'title': options.tooltips.decrementHour }).addClass('btn').attr('data-action', 'decrementHours').append($('<span>').addClass(options.icons.down))));
                 }
                 if (isEnabled('m')) {
                     if (isEnabled('h')) {
@@ -258,12 +247,12 @@
                         bottomRow.append($('<td>').addClass('separator'));
                     }
                     topRow.append($('<td>')
-                        .append($('<a>').attr({href: '#', tabindex: '-1', 'title': options.tooltips.incrementMinute}).addClass('btn').attr('data-action', 'incrementMinutes')
+                        .append($('<a>').attr({ href: '#', tabindex: '-1', 'title': options.tooltips.incrementMinute }).addClass('btn').attr('data-action', 'incrementMinutes')
                             .append($('<span>').addClass(options.icons.up))));
                     middleRow.append($('<td>')
-                        .append($('<span>').addClass('timepicker-minute').attr({'data-time-component': 'minutes', 'title': options.tooltips.pickMinute}).attr('data-action', 'showMinutes')));
+                        .append($('<span>').addClass('timepicker-minute').attr({ 'data-time-component': 'minutes', 'title': options.tooltips.pickMinute }).attr('data-action', 'showMinutes')));
                     bottomRow.append($('<td>')
-                        .append($('<a>').attr({href: '#', tabindex: '-1', 'title': options.tooltips.decrementMinute}).addClass('btn').attr('data-action', 'decrementMinutes')
+                        .append($('<a>').attr({ href: '#', tabindex: '-1', 'title': options.tooltips.decrementMinute }).addClass('btn').attr('data-action', 'decrementMinutes')
                             .append($('<span>').addClass(options.icons.down))));
                 }
                 if (isEnabled('s')) {
@@ -273,19 +262,19 @@
                         bottomRow.append($('<td>').addClass('separator'));
                     }
                     topRow.append($('<td>')
-                        .append($('<a>').attr({href: '#', tabindex: '-1', 'title': options.tooltips.incrementSecond}).addClass('btn').attr('data-action', 'incrementSeconds')
+                        .append($('<a>').attr({ href: '#', tabindex: '-1', 'title': options.tooltips.incrementSecond }).addClass('btn').attr('data-action', 'incrementSeconds')
                             .append($('<span>').addClass(options.icons.up))));
                     middleRow.append($('<td>')
-                        .append($('<span>').addClass('timepicker-second').attr({'data-time-component': 'seconds', 'title': options.tooltips.pickSecond}).attr('data-action', 'showSeconds')));
+                        .append($('<span>').addClass('timepicker-second').attr({ 'data-time-component': 'seconds', 'title': options.tooltips.pickSecond }).attr('data-action', 'showSeconds')));
                     bottomRow.append($('<td>')
-                        .append($('<a>').attr({href: '#', tabindex: '-1', 'title': options.tooltips.decrementSecond}).addClass('btn').attr('data-action', 'decrementSeconds')
+                        .append($('<a>').attr({ href: '#', tabindex: '-1', 'title': options.tooltips.decrementSecond }).addClass('btn').attr('data-action', 'decrementSeconds')
                             .append($('<span>').addClass(options.icons.down))));
                 }
 
                 if (!use24Hours) {
                     topRow.append($('<td>').addClass('separator'));
                     middleRow.append($('<td>')
-                        .append($('<button>').addClass('btn btn-primary').attr({'data-action': 'togglePeriod', tabindex: '-1', 'title': options.tooltips.togglePeriod})));
+                        .append($('<button>').addClass('btn btn-primary').attr({ 'data-action': 'togglePeriod', tabindex: '-1', 'title': options.tooltips.togglePeriod })));
                     bottomRow.append($('<td>').addClass('separator'));
                 }
 
@@ -319,16 +308,16 @@
             getToolbar = function () {
                 var row = [];
                 if (options.showTodayButton) {
-                    row.push($('<td>').append($('<a>').attr({'data-action':'today', 'title': options.tooltips.today}).append($('<span>').addClass(options.icons.today))));
+                    row.push($('<td>').append($('<a>').attr({ 'data-action': 'today', 'title': options.tooltips.today }).append($('<span>').addClass(options.icons.today))));
                 }
                 if (!options.sideBySide && hasDate() && hasTime()) {
-                    row.push($('<td>').append($('<a>').attr({'data-action':'togglePicker', 'title': options.tooltips.selectTime}).append($('<span>').addClass(options.icons.time))));
+                    row.push($('<td>').append($('<a>').attr({ 'data-action': 'togglePicker', 'title': options.tooltips.selectTime }).append($('<span>').addClass(options.icons.time))));
                 }
                 if (options.showClear) {
-                    row.push($('<td>').append($('<a>').attr({'data-action':'clear', 'title': options.tooltips.clear}).append($('<span>').addClass(options.icons.clear))));
+                    row.push($('<td>').append($('<a>').attr({ 'data-action': 'clear', 'title': options.tooltips.clear }).append($('<span>').addClass(options.icons.clear))));
                 }
                 if (options.showClose) {
-                    row.push($('<td>').append($('<a>').attr({'data-action':'close', 'title': options.tooltips.close}).append($('<span>').addClass(options.icons.close))));
+                    row.push($('<td>').append($('<a>').attr({ 'data-action': 'close', 'title': options.tooltips.close }).append($('<span>').addClass(options.icons.close))));
                 }
                 return $('<table>').addClass('table-condensed').append($('<tbody>').append($('<tr>').append(row)));
             },
@@ -472,7 +461,7 @@
 
                 widget.css({
                     top: vertical === 'top' ? 'auto' : position.top + element.outerHeight(),
-                    bottom: vertical === 'top' ? position.top + element.outerHeight() : 'auto',
+                    bottom: vertical === 'top' ? parent.outerHeight() - (parent === element ? 0 : position.top) : 'auto',
                     left: horizontal === 'left' ? (parent === element ? 0 : position.left) : 'auto',
                     right: horizontal === 'left' ? 'auto' : parent.outerWidth() - element.outerWidth() - (parent === element ? 0 : position.left)
                 });
@@ -654,9 +643,12 @@
             updateDecades = function () {
                 var decadesView = widget.find('.datepicker-decades'),
                     decadesViewHeader = decadesView.find('th'),
-                    startDecade = moment({y: viewDate.year() - (viewDate.year() % 100) - 1}),
+                    startDecade = moment({ y: viewDate.year() - (viewDate.year() % 100) - 1 }),
                     endDecade = startDecade.clone().add(100, 'y'),
                     startedAt = startDecade.clone(),
+                    minDateDecade = false,
+                    maxDateDecade = false,
+                    endDecadeYear,
                     html = '';
 
                 decadesViewHeader.eq(0).find('span').attr('title', options.tooltips.prevCentury);
@@ -664,19 +656,22 @@
 
                 decadesView.find('.disabled').removeClass('disabled');
 
-                if (startDecade.isSame(moment({y: 1900})) || (options.minDate && options.minDate.isAfter(startDecade, 'y'))) {
+                if (startDecade.isSame(moment({ y: 1900 })) || (options.minDate && options.minDate.isAfter(startDecade, 'y'))) {
                     decadesViewHeader.eq(0).addClass('disabled');
                 }
 
                 decadesViewHeader.eq(1).text(startDecade.year() + '-' + endDecade.year());
 
-                if (startDecade.isSame(moment({y: 2000})) || (options.maxDate && options.maxDate.isBefore(endDecade, 'y'))) {
+                if (startDecade.isSame(moment({ y: 2000 })) || (options.maxDate && options.maxDate.isBefore(endDecade, 'y'))) {
                     decadesViewHeader.eq(2).addClass('disabled');
                 }
 
                 while (!startDecade.isAfter(endDecade, 'y')) {
-                    html += '<span data-action="selectDecade" class="decade' + (startDecade.isSame(date, 'y') ? ' active' : '') +
-                        (!isValid(startDecade, 'y') ? ' disabled' : '') + '" data-selection="' + (startDecade.year() + 6) + '">' + (startDecade.year() + 1) + ' - ' + (startDecade.year() + 12) + '</span>';
+                    endDecadeYear = startDecade.year() + 12;
+                    minDateDecade = options.minDate && options.minDate.isAfter(startDecade, 'y') && options.minDate.year() <= endDecadeYear;
+                    maxDateDecade = options.maxDate && options.maxDate.isAfter(startDecade, 'y') && options.maxDate.year() <= endDecadeYear;
+                    html += '<span data-action="selectDecade" class="decade' + (date.isAfter(startDecade) && date.year() <= endDecadeYear ? ' active' : '') +
+                        (!isValid(startDecade, 'y') && !minDateDecade && !maxDateDecade ? ' disabled' : '') + '" data-selection="' + (startDecade.year() + 6) + '">' + (startDecade.year() + 1) + ' - ' + (startDecade.year() + 12) + '</span>';
                     startDecade.add(12, 'y');
                 }
                 html += '<span></span><span></span><span></span>'; //push the dangling block over, at least this way it's even
@@ -861,13 +856,17 @@
 
                 targetMoment = targetMoment.clone().locale(options.locale);
 
+                if (hasTimeZone()) {
+                    targetMoment.tz(options.timeZone);
+                }
+
                 if (options.stepping !== 1) {
-                    targetMoment.minutes((Math.round(targetMoment.minutes() / options.stepping) * options.stepping) % 60).seconds(0);
+                    targetMoment.minutes((Math.round(targetMoment.minutes() / options.stepping) * options.stepping)).seconds(0);
                 }
 
                 if (isValid(targetMoment)) {
                     date = targetMoment;
-                    viewDate = date.clone();
+                    //viewDate = date.clone(); // TODO this doesn't work right on first use
                     input.val(date.format(actualFormat));
                     element.data('date', date.format(actualFormat));
                     unset = false;
@@ -880,16 +879,25 @@
                 } else {
                     if (!options.keepInvalid) {
                         input.val(unset ? '' : date.format(actualFormat));
+                    } else {
+                        notifyEvent({
+                            type: 'dp.change',
+                            date: targetMoment,
+                            oldDate: oldDate
+                        });
                     }
                     notifyEvent({
                         type: 'dp.error',
-                        date: targetMoment
+                        date: targetMoment,
+                        oldDate: oldDate
                     });
                 }
             },
 
+            /**
+             * Hides the widget. Possibly will emit dp.hide
+             */
             hide = function () {
-                ///<summary>Hides the widget. Possibly will emit dp.hide</summary>
                 var transitioning = false;
                 if (!widget) {
                     return picker;
@@ -925,6 +933,9 @@
 
                 input.blur();
 
+                currentViewMode = 0;
+                viewDate = date.clone();
+
                 return picker;
             },
 
@@ -932,6 +943,18 @@
                 setValue(null);
             },
 
+            parseInputDate = function (inputDate) {
+                if (options.parseInputDate === undefined) {
+                    if (!moment.isMoment(inputDate)) {
+                        inputDate = getMoment(inputDate);
+                    }
+                } else {
+                    inputDate = options.parseInputDate(inputDate);
+                }
+                //inputDate.locale(options.locale);
+                return inputDate;
+            },
+
             /********************************************************************************
              *
              * Widget UI interaction functions
@@ -1161,8 +1184,10 @@
                 return false;
             },
 
+            /**
+             * Shows the widget. Possibly will emit dp.show and dp.change
+             */
             show = function () {
-                ///<summary>Shows the widget. Possibly will emit dp.show and dp.change</summary>
                 var currentMoment,
                     useCurrentGranularity = {
                         'year': function (m) {
@@ -1187,14 +1212,13 @@
                 }
                 if (input.val() !== undefined && input.val().trim().length !== 0) {
                     setValue(parseInputDate(input.val().trim()));
-                } else if (options.useCurrent && unset && ((input.is('input') && input.val().trim().length === 0) || options.inline)) {
+                } else if (unset && options.useCurrent && (options.inline || (input.is('input') && input.val().trim().length === 0))) {
                     currentMoment = getMoment();
                     if (typeof options.useCurrent === 'string') {
                         currentMoment = useCurrentGranularity[options.useCurrent](currentMoment);
                     }
                     setValue(currentMoment);
                 }
-
                 widget = getTemplate();
 
                 fillDow();
@@ -1214,9 +1238,8 @@
                 if (component && component.hasClass('btn')) {
                     component.toggleClass('active');
                 }
-                widget.show();
                 place();
-
+                widget.show();
                 if (options.focusOnShow && !input.is(':focus')) {
                     input.focus();
                 }
@@ -1227,25 +1250,13 @@
                 return picker;
             },
 
+            /**
+             * Shows or hides the widget
+             */
             toggle = function () {
-                /// <summary>Shows or hides the widget</summary>
                 return (widget ? hide() : show());
             },
 
-            parseInputDate = function (inputDate) {
-                if (options.parseInputDate === undefined) {
-                    if (moment.isMoment(inputDate) || inputDate instanceof Date) {
-                        inputDate = moment(inputDate);
-                    } else {
-                        inputDate = getMoment(inputDate);
-                    }
-                } else {
-                    inputDate = options.parseInputDate(inputDate);
-                }
-                inputDate.locale(options.locale);
-                return inputDate;
-            },
-
             keydown = function (e) {
                 var handler = null,
                     index,
@@ -1513,7 +1524,7 @@
             }
 
             if ((typeof newFormat !== 'string') && ((typeof newFormat !== 'boolean') || (newFormat !== false))) {
-                throw new TypeError('format() expects a sting or boolean:false parameter ' + newFormat);
+                throw new TypeError('format() expects a string or boolean:false parameter ' + newFormat);
             }
 
             options.format = newFormat;
@@ -1528,6 +1539,10 @@
                 return options.timeZone;
             }
 
+            if (typeof newZone !== 'string') {
+                throw new TypeError('newZone() expects a string parameter');
+            }
+
             options.timeZone = newZone;
 
             return picker;
@@ -1645,8 +1660,8 @@
                 var tries = 0;
                 while (!isValid(date, 'd')) {
                     date.add(1, 'd');
-                    if (tries === 7) {
-                        throw 'Tried 7 times to find a valid date';
+                    if (tries === 31) {
+                        throw 'Tried 31 times to find a valid date';
                     }
                     tries++;
                 }
@@ -1748,6 +1763,8 @@
             if (typeof defaultDate === 'string') {
                 if (defaultDate === 'now' || defaultDate === 'moment') {
                     defaultDate = getMoment();
+                } else {
+                    defaultDate = getMoment(defaultDate);
                 }
             }
 
@@ -2084,6 +2101,10 @@
         };
 
         picker.keyBinds = function (keyBinds) {
+            if (arguments.length === 0) {
+                return options.keyBinds;
+            }
+
             options.keyBinds = keyBinds;
             return picker;
         };
@@ -2269,16 +2290,12 @@
             update();
             return picker;
         };
-
+        /**
+         * Returns the component's model current viewDate, a moment object or null if not set. Passing a null value unsets the components model current moment. Parsing of the newDate parameter is made using moment library with the options.format and options.useStrict components configuration.
+         * @param {Takes string, viewDate, moment, null parameter.} newDate
+         * @returns {viewDate.clone()}
+         */
         picker.viewDate = function (newDate) {
-            ///<signature helpKeyword="$.fn.datetimepicker.viewDate">
-            ///<summary>Returns the component's model current viewDate, a moment object or null if not set.</summary>
-            ///<returns type="Moment">viewDate.clone()</returns>
-            ///</signature>
-            ///<signature>
-            ///<summary>Sets the components model current moment to it. Passing a null value unsets the components model current moment. Parsing of the newDate parameter is made using moment library with the options.format and options.useStrict components configuration.</summary>
-            ///<param name="newDate" locid="$.fn.datetimepicker.date_p:newDate">Takes string, viewDate, moment, null parameter.</param>
-            ///</signature>
             if (arguments.length === 0) {
                 return viewDate.clone();
             }
@@ -2302,7 +2319,7 @@
             input = element;
         } else {
             input = element.find(options.datepickerInput);
-            if (input.size() === 0) {
+            if (input.length === 0) {
                 input = element.find('input');
             } else if (!input.is('input')) {
                 throw new Error('CSS class "' + options.datepickerInput + '" cannot be applied to non input element');
@@ -2311,7 +2328,7 @@
 
         if (element.hasClass('input-group')) {
             // in case there is more then one 'input-group-addon' Issue #48
-            if (element.find('.datepickerbutton').size() === 0) {
+            if (element.find('.datepickerbutton').length === 0) {
                 component = element.find('.input-group-addon');
             } else {
                 component = element.find('.datepickerbutton');
@@ -2355,19 +2372,67 @@
      *
      ********************************************************************************/
 
+    /**
+    * See (http://jquery.com/).
+    * @name jQuery
+    * @class
+    * See the jQuery Library  (http://jquery.com/) for full details.  This just
+    * documents the function and classes that are added to jQuery by this plug-in.
+    */
+    /**
+     * See (http://jquery.com/)
+     * @name fn
+     * @class
+     * See the jQuery Library  (http://jquery.com/) for full details.  This just
+     * documents the function and classes that are added to jQuery by this plug-in.
+     * @memberOf jQuery
+     */
+    /**
+     * Show comments
+     * @class datetimepicker
+     * @memberOf jQuery.fn
+     */
     $.fn.datetimepicker = function (options) {
-        return this.each(function () {
-            var $this = $(this);
-            if (!$this.data('DateTimePicker')) {
-                // create a private copy of the defaults object
-                options = $.extend(true, {}, $.fn.datetimepicker.defaults, options);
-                $this.data('DateTimePicker', dateTimePicker($this, options));
-            }
-        });
+        options = options || {};
+
+        var args = Array.prototype.slice.call(arguments, 1),
+            isInstance = true,
+            thisMethods = ['destroy', 'hide', 'show', 'toggle'],
+            returnValue;
+
+        if (typeof options === 'object') {
+            return this.each(function () {
+                var $this = $(this);
+                if (!$this.data('DateTimePicker')) {
+                    // create a private copy of the defaults object
+                    options = $.extend(true, {}, $.fn.datetimepicker.defaults, options);
+                    $this.data('DateTimePicker', dateTimePicker($this, options));
+                }
+            });
+        } else if (typeof options === 'string') {
+            this.each(function () {
+                var $this = $(this),
+                    instance = $this.data('DateTimePicker');
+                if (!instance) {
+                    throw new Error('bootstrap-datetimepicker("' + options + '") method was called on an element that is not using DateTimePicker');
+                }
+
+                returnValue = instance[options].apply(instance, args);
+                isInstance = returnValue === instance;
+            });
+
+            if (isInstance || $.inArray(options, thisMethods) > -1) {
+                return this;
+            }
+
+            return returnValue;
+        }
+
+        throw new TypeError('Invalid arguments for DateTimePicker: ' + options);
     };
 
     $.fn.datetimepicker.defaults = {
-        timeZone: 'Etc/UTC',
+        timeZone: '',
         format: false,
         dayViewHeaderFormat: 'MMMM YYYY',
         extraFormats: false,
@@ -2531,6 +2596,9 @@
             //    if(toggle.length > 0) toggle.click();
             //},
             'control space': function (widget) {
+                if (!widget) {
+                    return;
+                }
                 if (widget.find('.timepicker').is(':visible')) {
                     widget.find('.btn[data-action="togglePeriod"]').click();
                 }
@@ -2549,4 +2617,7 @@
         enabledHours: false,
         viewDate: false
     };
+    if (typeof module !== 'undefined') {
+        module.exports = $.fn.datetimepicker;
+    }
 }));
diff --git a/src/less/_bootstrap-datetimepicker.less b/src/less/_bootstrap-datetimepicker.less
index 5beb293..a92cd37 100644
--- a/src/less/_bootstrap-datetimepicker.less
+++ b/src/less/_bootstrap-datetimepicker.less
@@ -1,6 +1,6 @@
 /*!
  * Datetimepicker for Bootstrap 3
- * version : 4.17.37
+ * version : 4.17.42
  * https://github.com/Eonasdan/bootstrap-datetimepicker/
  */
 @bs-datetimepicker-timepicker-font-size: 1.2em;
diff --git a/src/sass/_bootstrap-datetimepicker.scss b/src/sass/_bootstrap-datetimepicker.scss
index 06489be..c9f26e4 100644
--- a/src/sass/_bootstrap-datetimepicker.scss
+++ b/src/sass/_bootstrap-datetimepicker.scss
@@ -268,7 +268,8 @@ $bs-datetimepicker-text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25) !default;
                 &:before {
                     content: '';
                     display: inline-block;
-                    border: 0 0 7px 7px solid transparent;
+                    border: solid transparent;
+ +                  border-width: 0 0 7px 7px;
                     border-bottom-color: $bs-datetimepicker-active-bg;
                     border-top-color: $bs-datetimepicker-secondary-border-color-rgba;
                     position: absolute;
@@ -340,4 +341,4 @@ $bs-datetimepicker-text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25) !default;
     & .input-group-addon {
         cursor: pointer;
     }
-}
\ No newline at end of file
+}
diff --git a/test/publicApiSpec.js b/test/publicApiSpec.js
index 7812cb8..30573d1 100644
--- a/test/publicApiSpec.js
+++ b/test/publicApiSpec.js
@@ -8,14 +8,40 @@ describe('Plugin initialization and component basic construction', function () {
     });
 
     it('creates the component with default options on an input element', function () {
-        var dtp = $('<input>');
-        $(document).find('body').append(dtp);
+        var dtpElement = $('<input>'),
+            dtp;
+        $(document).find('body').append(dtpElement);
 
         expect(function () {
-            dtp = dtp.datetimepicker();
+            expect(dtpElement.datetimepicker()).toBe(dtpElement);
         }).not.toThrow();
 
+        dtp = dtpElement.data('DateTimePicker');
+        expect(dtpElement).not.toBe(null);
+    });
+
+    it('creates the component with default options merged with those provided on an input element', function () {
+        var options = {locale: 'fr'},
+            dtpElement = $('<input>'),
+            dtp;
+        $(document).find('body').append(dtpElement);
+
+        expect(function () {
+            expect(dtpElement.datetimepicker(options)).toBe(dtpElement);
+        }).not.toThrow();
+
+        dtp = dtpElement.data('DateTimePicker');
         expect(dtp).not.toBe(null);
+        expect(dtp.options()).toEqual($.extend(true, {}, dtpElement.datetimepicker.defaults, options));
+    });
+
+    it('does not accept non-object or string types', function () {
+        var dtpElement = $('<input>');
+        $(document).find('body').append(dtpElement);
+
+        expect(function () {
+            dtpElement.datetimepicker(true);
+        }).toThrow();
     });
 
     xit('calls destroy when Element that the component is attached is removed', function () {
@@ -69,6 +95,14 @@ describe('Public API method tests', function () {
         });
     });
 
+    describe('unknown functions', function () {
+        it('are not allowed', function () {
+            expect(function () {
+                dtpElement.datetimepicker('abcdef');
+            }).toThrow();
+        });
+    });
+
     describe('date() function', function () {
         describe('typechecking', function () {
             it('accepts a null', function () {
@@ -131,6 +165,18 @@ describe('Public API method tests', function () {
                 expect(dtp.date().isSame(timestamp)).toBe(true);
             });
         });
+
+        describe('access', function () {
+            it('gets date', function () {
+                expect(dtpElement.datetimepicker('date')).toBe(null);
+            });
+
+            it('sets date', function () {
+                var timestamp = moment();
+                expect(dtpElement.datetimepicker('date', timestamp)).toBe(dtpElement);
+                expect(dtpElement.datetimepicker('date').isSame(timestamp)).toBe(true);
+            });
+        });
     });
 
     describe('format() function', function () {
@@ -172,8 +218,21 @@ describe('Public API method tests', function () {
             });
 
             it('sets the format correctly', function () {
-                dtp.format('YYYY-MM-DD');
-                expect(dtp.format()).toBe('YYYY-MM-DD');
+                var format = 'YYYY-MM-DD';
+                dtp.format(format);
+                expect(dtp.format()).toBe(format);
+            });
+        });
+
+        describe('access', function () {
+            it('gets format', function () {
+                expect(dtpElement.datetimepicker('format')).toBe(false);
+            });
+
+            it('sets format', function () {
+                var format = 'YYYY-MM-DD';
+                expect(dtpElement.datetimepicker('format', format)).toBe(dtpElement);
+                expect(dtpElement.datetimepicker('format')).toBe(format);
             });
         });
     });
@@ -184,6 +243,12 @@ describe('Public API method tests', function () {
                 expect(dtp.destroy).toBeDefined();
             });
         });
+
+        describe('access', function () {
+            it('returns jQuery object', function () {
+                expect(dtpElement.datetimepicker('destroy')).toBe(dtpElement);
+            });
+        });
     });
 
     describe('toggle() function', function () {
@@ -196,6 +261,12 @@ describe('Public API method tests', function () {
         // describe('functionality', function () {
         //     it('')
         // });
+
+        describe('access', function () {
+            it('returns jQuery object', function () {
+                expect(dtpElement.datetimepicker('toggle')).toBe(dtpElement);
+            });
+        });
     });
 
     describe('show() function', function () {
@@ -224,6 +295,12 @@ describe('Public API method tests', function () {
                 expect($(document).find('body').find('.bootstrap-datetimepicker-widget').length).toEqual(1);
             });
         });
+
+        describe('access', function () {
+            it('returns jQuery object', function () {
+                expect(dtpElement.datetimepicker('show')).toBe(dtpElement);
+            });
+        });
     });
 
     describe('hide() function', function () {
@@ -251,6 +328,12 @@ describe('Public API method tests', function () {
                 expect($(document).find('body').find('.bootstrap-datetimepicker-widget').length).toEqual(0);
             });
         });
+
+        describe('access', function () {
+            it('returns jQuery object', function () {
+                expect(dtpElement.datetimepicker('hide')).toBe(dtpElement);
+            });
+        });
     });
 
     describe('disable() function', function () {
@@ -259,6 +342,12 @@ describe('Public API method tests', function () {
                 expect(dtp.disable).toBeDefined();
             });
         });
+
+        describe('access', function () {
+            it('returns jQuery object', function () {
+                expect(dtpElement.datetimepicker('disable')).toBe(dtpElement);
+            });
+        });
     });
 
     describe('enable() function', function () {
@@ -267,6 +356,12 @@ describe('Public API method tests', function () {
                 expect(dtp.enable).toBeDefined();
             });
         });
+
+        describe('access', function () {
+            it('returns jQuery object', function () {
+                expect(dtpElement.datetimepicker('enable')).toBe(dtpElement);
+            });
+        });
     });
 
     describe('options() function', function () {
@@ -275,6 +370,18 @@ describe('Public API method tests', function () {
                 expect(dtp.options).toBeDefined();
             });
         });
+
+        describe('access', function () {
+            it('gets options', function () {
+                expect(dtpElement.datetimepicker('options')).toEqual(dtpElement.datetimepicker.defaults);
+            });
+
+            it('sets options', function () {
+                var options = {locale: 'fr'};
+                expect(dtpElement.datetimepicker('options', options)).toBe(dtpElement);
+                expect(dtpElement.datetimepicker('options')).toEqual($.extend(true, {}, dtpElement.datetimepicker.defaults, options));
+            });
+        });
     });
 
     describe('disabledDates() function', function () {
@@ -283,6 +390,18 @@ describe('Public API method tests', function () {
                 expect(dtp.disabledDates).toBeDefined();
             });
         });
+
+        describe('access', function () {
+            it('gets disabled dates', function () {
+                expect(dtpElement.datetimepicker('disabledDates')).toBe(false);
+            });
+
+            it('sets disabled dates', function () {
+                var timestamps = [moment()];
+                expect(dtpElement.datetimepicker('disabledDates', timestamps)).toBe(dtpElement);
+                expect(dtpElement.datetimepicker('disabledDates')).not.toBe(false);
+            });
+        });
     });
 
     describe('enabledDates() function', function () {
@@ -291,6 +410,18 @@ describe('Public API method tests', function () {
                 expect(dtp.enabledDates).toBeDefined();
             });
         });
+
+        describe('access', function () {
+            it('gets enabled dates', function () {
+                expect(dtpElement.datetimepicker('enabledDates')).toBe(false);
+            });
+
+            it('sets enabled dates', function () {
+                var timestamps = [moment()];
+                expect(dtpElement.datetimepicker('enabledDates', timestamps)).toBe(dtpElement);
+                expect(dtpElement.datetimepicker('enabledDates')).not.toBe(false);
+            });
+        });
     });
 
     describe('daysOfWeekDisabled() function', function () {
@@ -299,6 +430,18 @@ describe('Public API method tests', function () {
                 expect(dtp.daysOfWeekDisabled).toBeDefined();
             });
         });
+
+        describe('access', function () {
+            xit('gets days of week disabled', function () {
+                expect(dtpElement.datetimepicker('daysOfWeekDisabled')).toEqual([]);
+            });
+
+            it('sets days of week disabled', function () {
+                var daysOfWeek = [0];
+                expect(dtpElement.datetimepicker('daysOfWeekDisabled', daysOfWeek)).toBe(dtpElement);
+                expect(dtpElement.datetimepicker('daysOfWeekDisabled')).toEqual(daysOfWeek);
+            });
+        });
     });
 
     describe('maxDate() function', function () {
@@ -307,6 +450,18 @@ describe('Public API method tests', function () {
                 expect(dtp.maxDate).toBeDefined();
             });
         });
+
+        describe('access', function () {
+            it('gets max date', function () {
+                expect(dtpElement.datetimepicker('maxDate')).toBe(false);
+            });
+
+            it('sets max date', function () {
+                var timestamp = moment();
+                expect(dtpElement.datetimepicker('maxDate', timestamp)).toBe(dtpElement);
+                expect(dtpElement.datetimepicker('maxDate').isSame(timestamp)).toBe(true);
+            });
+        });
     });
 
     describe('minDate() function', function () {
@@ -315,6 +470,18 @@ describe('Public API method tests', function () {
                 expect(dtp.minDate).toBeDefined();
             });
         });
+
+        describe('access', function () {
+            it('gets min date', function () {
+                expect(dtpElement.datetimepicker('minDate')).toBe(false);
+            });
+
+            it('sets min date', function () {
+                var timestamp = moment();
+                expect(dtpElement.datetimepicker('minDate', timestamp)).toBe(dtpElement);
+                expect(dtpElement.datetimepicker('minDate').isSame(timestamp)).toBe(true);
+            });
+        });
     });
 
     describe('defaultDate() function', function () {
@@ -348,6 +515,18 @@ describe('Public API method tests', function () {
                 expect(dtp.date().isSame(timestamp)).toBe(true);
             });
         });
+
+        describe('access', function () {
+            it('gets default date', function () {
+                expect(dtpElement.datetimepicker('defaultDate')).toBe(false);
+            });
+
+            it('sets default date', function () {
+                var timestamp = moment();
+                expect(dtpElement.datetimepicker('defaultDate', timestamp)).toBe(dtpElement);
+                expect(dtpElement.datetimepicker('defaultDate').isSame(timestamp)).toBe(true);
+            });
+        });
     });
 
     describe('locale() function', function () {
@@ -364,6 +543,18 @@ describe('Public API method tests', function () {
                 expect(moment.locale()).toBe('en');
             });
         });
+
+        describe('access', function () {
+            it('gets locale', function () {
+                expect(dtpElement.datetimepicker('locale')).toBe(moment.locale());
+            });
+
+            it('sets locale', function () {
+                var locale = 'fr';
+                expect(dtpElement.datetimepicker('locale', locale)).toBe(dtpElement);
+                expect(dtpElement.datetimepicker('locale')).toBe(locale);
+            });
+        });
     });
 
     describe('useCurrent() function', function () {
@@ -404,6 +595,18 @@ describe('Public API method tests', function () {
                 expect(dpChangeSpy).toHaveBeenCalled();
             });
         });
+
+        describe('access', function () {
+            it('gets use current', function () {
+                expect(dtpElement.datetimepicker('useCurrent')).toBe(true);
+            });
+
+            it('sets use current', function () {
+                var useCurrent = false;
+                expect(dtpElement.datetimepicker('useCurrent', useCurrent)).toBe(dtpElement);
+                expect(dtpElement.datetimepicker('useCurrent')).toBe(useCurrent);
+            });
+        });
     });
 
     describe('ignoreReadonly() function', function () {
@@ -412,6 +615,18 @@ describe('Public API method tests', function () {
                 expect(dtp.ignoreReadonly).toBeDefined();
             });
         });
+
+        describe('access', function () {
+            it('gets ignore readonly', function () {
+                expect(dtpElement.datetimepicker('ignoreReadonly')).toBe(false);
+            });
+
+            it('sets ignore readonly', function () {
+                var ignoreReadonly = true;
+                expect(dtpElement.datetimepicker('ignoreReadonly', ignoreReadonly)).toBe(dtpElement);
+                expect(dtpElement.datetimepicker('ignoreReadonly')).toBe(ignoreReadonly);
+            });
+        });
     });
 
     describe('stepping() function', function () {
@@ -420,6 +635,18 @@ describe('Public API method tests', function () {
                 expect(dtp.stepping).toBeDefined();
             });
         });
+
+        describe('access', function () {
+            it('gets stepping', function () {
+                expect(dtpElement.datetimepicker('stepping')).toBe(1);
+            });
+
+            it('sets stepping', function () {
+                var stepping = 2;
+                expect(dtpElement.datetimepicker('stepping', stepping)).toBe(dtpElement);
+                expect(dtpElement.datetimepicker('stepping')).toBe(stepping);
+            });
+        });
     });
 
     describe('collapse() function', function () {
@@ -428,6 +655,18 @@ describe('Public API method tests', function () {
                 expect(dtp.collapse).toBeDefined();
             });
         });
+
+        describe('access', function () {
+            it('gets collapse', function () {
+                expect(dtpElement.datetimepicker('collapse')).toBe(true);
+            });
+
+            it('sets collapse', function () {
+                var collapse = false;
+                expect(dtpElement.datetimepicker('collapse', collapse)).toBe(dtpElement);
+                expect(dtpElement.datetimepicker('collapse')).toBe(collapse);
+            });
+        });
     });
 
     describe('icons() function', function () {
@@ -436,6 +675,18 @@ describe('Public API method tests', function () {
                 expect(dtp.icons).toBeDefined();
             });
         });
+
+        describe('access', function () {
+            it('gets icons', function () {
+                expect(dtpElement.datetimepicker('icons')).toEqual(dtpElement.datetimepicker.defaults.icons);
+            });
+
+            it('sets icons', function () {
+                var icons = {time: 'fa fa-time'};
+                expect(dtpElement.datetimepicker('icons', icons)).toBe(dtpElement);
+                expect(dtpElement.datetimepicker('icons')).toEqual($.extend(true, {}, dtpElement.datetimepicker.defaults.icons, icons));
+            });
+        });
     });
 
     describe('useStrict() function', function () {
@@ -444,6 +695,18 @@ describe('Public API method tests', function () {
                 expect(dtp.useStrict).toBeDefined();
             });
         });
+
+        describe('access', function () {
+            it('gets use strict', function () {
+                expect(dtpElement.datetimepicker('useStrict')).toBe(false);
+            });
+
+            it('sets use strict', function () {
+                var useStrict = true;
+                expect(dtpElement.datetimepicker('useStrict', useStrict)).toBe(dtpElement);
+                expect(dtpElement.datetimepicker('useStrict')).toBe(useStrict);
+            });
+        });
     });
 
     describe('sideBySide() function', function () {
@@ -452,6 +715,18 @@ describe('Public API method tests', function () {
                 expect(dtp.sideBySide).toBeDefined();
             });
         });
+
+        describe('access', function () {
+            it('gets side-by-side', function () {
+                expect(dtpElement.datetimepicker('sideBySide')).toBe(false);
+            });
+
+            it('sets side-by-side', function () {
+                var sideBySide = true;
+                expect(dtpElement.datetimepicker('sideBySide', sideBySide)).toBe(dtpElement);
+                expect(dtpElement.datetimepicker('sideBySide')).toBe(sideBySide);
+            });
+        });
     });
 
     describe('viewMode() function', function () {
@@ -460,6 +735,18 @@ describe('Public API method tests', function () {
                 expect(dtp.viewMode).toBeDefined();
             });
         });
+
+        describe('access', function () {
+            it('gets view mode', function () {
+                expect(dtpElement.datetimepicker('viewMode')).toBe('days');
+            });
+
+            it('sets view mode', function () {
+                var viewMode = 'years';
+                expect(dtpElement.datetimepicker('viewMode', viewMode)).toBe(dtpElement);
+                expect(dtpElement.datetimepicker('viewMode')).toBe(viewMode);
+            });
+        });
     });
 
     describe('widgetPositioning() function', function () {
@@ -468,6 +755,18 @@ describe('Public API method tests', function () {
                 expect(dtp.widgetPositioning).toBeDefined();
             });
         });
+
+        describe('access', function () {
+            it('gets widget positioning', function () {
+                expect(dtpElement.datetimepicker('widgetPositioning')).toEqual(dtpElement.datetimepicker.defaults.widgetPositioning);
+            });
+
+            it('sets widget positioning', function () {
+                var widgetPositioning = {horizontal: 'left'};
+                expect(dtpElement.datetimepicker('widgetPositioning', widgetPositioning)).toBe(dtpElement);
+                expect(dtpElement.datetimepicker('widgetPositioning')).toEqual($.extend(true, {}, dtpElement.datetimepicker.defaults.widgetPositioning, widgetPositioning));
+            });
+        });
     });
 
     describe('calendarWeeks() function', function () {
@@ -476,6 +775,18 @@ describe('Public API method tests', function () {
                 expect(dtp.calendarWeeks).toBeDefined();
             });
         });
+
+        describe('access', function () {
+            it('gets calendar weeks', function () {
+                expect(dtpElement.datetimepicker('calendarWeeks')).toBe(false);
+            });
+
+            it('sets calendar weeks', function () {
+                var calendarWeeks = true;
+                expect(dtpElement.datetimepicker('calendarWeeks', calendarWeeks)).toBe(dtpElement);
+                expect(dtpElement.datetimepicker('calendarWeeks')).toBe(calendarWeeks);
+            });
+        });
     });
 
     describe('showTodayButton() function', function () {
@@ -484,6 +795,18 @@ describe('Public API method tests', function () {
                 expect(dtp.showTodayButton).toBeDefined();
             });
         });
+
+        describe('access', function () {
+            it('gets show today button', function () {
+                expect(dtpElement.datetimepicker('showTodayButton')).toBe(false);
+            });
+
+            it('sets show today button', function () {
+                var showTodayButton = true;
+                expect(dtpElement.datetimepicker('showTodayButton', showTodayButton)).toBe(dtpElement);
+                expect(dtpElement.datetimepicker('showTodayButton')).toBe(showTodayButton);
+            });
+        });
     });
 
     describe('showClear() function', function () {
@@ -492,6 +815,18 @@ describe('Public API method tests', function () {
                 expect(dtp.showClear).toBeDefined();
             });
         });
+
+        describe('access', function () {
+            it('gets show clear', function () {
+                expect(dtpElement.datetimepicker('showClear')).toBe(false);
+            });
+
+            it('sets show clear', function () {
+                var showClear = true;
+                expect(dtpElement.datetimepicker('showClear', showClear)).toBe(dtpElement);
+                expect(dtpElement.datetimepicker('showClear')).toBe(showClear);
+            });
+        });
     });
 
     describe('dayViewHeaderFormat() function', function () {
@@ -537,6 +872,18 @@ describe('Public API method tests', function () {
                 expect(dtp.dayViewHeaderFormat()).toBe('MM YY');
             });
         });
+
+        describe('access', function () {
+            it('gets day view header format', function () {
+                expect(dtpElement.datetimepicker('dayViewHeaderFormat')).toBe('MMMM YYYY');
+            });
+
+            it('sets day view header format', function () {
+                var dayViewHeaderFormat = 'MM YY';
+                expect(dtpElement.datetimepicker('dayViewHeaderFormat', dayViewHeaderFormat)).toBe(dtpElement);
+                expect(dtpElement.datetimepicker('dayViewHeaderFormat')).toBe(dayViewHeaderFormat);
+            });
+        });
     });
 
     describe('extraFormats() function', function () {
@@ -582,6 +929,18 @@ describe('Public API method tests', function () {
                 expect(dtp.extraFormats()[0]).toBe('YYYY-MM-DD');
             });
         });
+
+        describe('access', function () {
+            it('gets extra formats', function () {
+                expect(dtpElement.datetimepicker('extraFormats')).toBe(false);
+            });
+
+            it('sets extra formats', function () {
+                var extraFormats = ['YYYY-MM-DD'];
+                expect(dtpElement.datetimepicker('extraFormats', extraFormats)).toBe(dtpElement);
+                expect(dtpElement.datetimepicker('extraFormats')).toEqual(extraFormats);
+            });
+        });
     });
 
     describe('toolbarPlacement() function', function () {
@@ -618,6 +977,18 @@ describe('Public API method tests', function () {
                 }).toThrow();
             });
         });
+
+        describe('access', function () {
+            it('gets toolbar placement', function () {
+                expect(dtpElement.datetimepicker('toolbarPlacement')).toBe('default');
+            });
+
+            it('sets toolbar placement', function () {
+                var toolbarPlacement = 'top';
+                expect(dtpElement.datetimepicker('toolbarPlacement', toolbarPlacement)).toBe(dtpElement);
+                expect(dtpElement.datetimepicker('toolbarPlacement')).toBe(toolbarPlacement);
+            });
+        });
     });
 
     describe('widgetParent() function', function () {
@@ -664,6 +1035,17 @@ describe('Public API method tests', function () {
                 }).toThrow();
             });
         });
+
+        describe('access', function () {
+            it('gets widget parent', function () {
+                expect(dtpElement.datetimepicker('widgetParent')).toBe(null);
+            });
+
+            it('sets widget parent', function () {
+                expect(dtpElement.datetimepicker('widgetParent', 'testDiv')).toBe(dtpElement);
+                expect(dtpElement.datetimepicker('widgetParent')).not.toBe(null);
+            });
+        });
     });
 
     describe('keepOpen() function', function () {
@@ -672,6 +1054,18 @@ describe('Public API method tests', function () {
                 expect(dtp.keepOpen).toBeDefined();
             });
         });
+
+        describe('access', function () {
+            it('gets keep open', function () {
+                expect(dtpElement.datetimepicker('keepOpen')).toBe(false);
+            });
+
+            it('sets keep open', function () {
+                var keepOpen = true;
+                expect(dtpElement.datetimepicker('keepOpen', keepOpen)).toBe(dtpElement);
+                expect(dtpElement.datetimepicker('keepOpen')).toBe(keepOpen);
+            });
+        });
     });
 
     describe('inline() function', function () {
@@ -680,6 +1074,18 @@ describe('Public API method tests', function () {
                 expect(dtp.inline).toBeDefined();
             });
         });
+
+        describe('access', function () {
+            it('gets inline', function () {
+                expect(dtpElement.datetimepicker('inline')).toBe(false);
+            });
+
+            it('sets inline', function () {
+                var inline = true;
+                expect(dtpElement.datetimepicker('inline', inline)).toBe(dtpElement);
+                expect(dtpElement.datetimepicker('inline')).toBe(inline);
+            });
+        });
     });
 
     describe('clear() function', function () {
@@ -688,6 +1094,12 @@ describe('Public API method tests', function () {
                 expect(dtp.clear).toBeDefined();
             });
         });
+
+        describe('access', function () {
+            it('returns jQuery object', function () {
+                expect(dtpElement.datetimepicker('clear')).toBe(dtpElement);
+            });
+        });
     });
 
     describe('keyBinds() function', function () {
@@ -696,6 +1108,18 @@ describe('Public API method tests', function () {
                 expect(dtp.keyBinds).toBeDefined();
             });
         });
+
+        describe('access', function () {
+            it('gets key binds', function () {
+                expect(dtpElement.datetimepicker('keyBinds')).toEqual(dtpElement.datetimepicker.defaults.keyBinds);
+            });
+
+            it('sets key binds', function () {
+                var keyBinds = {up: function () {}};
+                expect(dtpElement.datetimepicker('keyBinds', keyBinds)).toBe(dtpElement);
+                expect(dtpElement.datetimepicker('keyBinds')).toEqual(keyBinds);
+            });
+        });
     });
 
     describe('parseInputDate() function', function () {
@@ -704,5 +1128,45 @@ describe('Public API method tests', function () {
                 expect(dtp.parseInputDate).toBeDefined();
             });
         });
+
+        describe('access', function () {
+            it('gets parse input date', function () {
+                expect(dtpElement.datetimepicker('parseInputDate')).toBe(undefined);
+            });
+
+            it('sets parse input date', function () {
+                var parseInputDate = function () {};
+                expect(dtpElement.datetimepicker('parseInputDate', parseInputDate)).toBe(dtpElement);
+                expect(dtpElement.datetimepicker('parseInputDate')).toBe(parseInputDate);
+            });
+        });
+    });
+
+    describe('Time zone tests', function () {
+        function makeFormatTest (format, displayTimeZone) {
+            it('should not change the value that was set when using format ' + format, function () { // #1326
+                var oldFormat = dtp.format(),
+                    oldTimeZone = dtp.timeZone(),
+                    now = moment().startOf('second');
+
+                dtp.timeZone(displayTimeZone);
+                dtp.format(format);
+
+                dtp.date(now);
+                dpChangeSpy.calls.reset();
+                dtp.show();
+                dtp.hide();
+                expect(dpChangeSpy).not.toHaveBeenCalled();
+                expect(dtp.date().format()).toEqual(now.tz(displayTimeZone).format());
+
+                dtp.format(oldFormat);
+                dtp.timeZone(oldTimeZone);
+            });
+        }
+
+        makeFormatTest('YYYY-MM-DD HH:mm:ss Z', 'UTC');
+        makeFormatTest('YYYY-MM-DD HH:mm:ss', 'UTC');
+        makeFormatTest('YYYY-MM-DD HH:mm:ss Z', 'America/New_York');
+        makeFormatTest('YYYY-MM-DD HH:mm:ss', 'America/New_York');
     });
 });
diff --git a/test/timezoneDataHelper.js b/test/timezoneDataHelper.js
new file mode 100644
index 0000000..f25d237
--- /dev/null
+++ b/test/timezoneDataHelper.js
@@ -0,0 +1,11 @@
+(function () {
+    'use strict';
+    $.ajax('node_modules/moment-timezone/data/packed/latest.json', {
+        success: function (data) {
+            moment.tz.load(data);
+        },
+        method: 'GET',
+        dataType: 'json',
+        async: false
+    });
+}());

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/eonasdan-bootstrap-datetimepicker.git



More information about the Pkg-javascript-commits mailing list