Browse Source

also include hh:mm in min/max check datetime

Robin Herbots 7 years ago
parent
commit
7485b233ac
47 changed files with 317 additions and 283 deletions
  1. 1 1
      bower.json
  2. 1 1
      component.json
  3. 1 1
      composer.json
  4. 1 1
      dist/inputmask/bindings/inputmask.binding.js
  5. 1 1
      dist/inputmask/dependencyLibs/inputmask.dependencyLib.jqlite.js
  6. 1 1
      dist/inputmask/dependencyLibs/inputmask.dependencyLib.jquery.js
  7. 1 1
      dist/inputmask/dependencyLibs/inputmask.dependencyLib.js
  8. 1 1
      dist/inputmask/global/document.js
  9. 1 1
      dist/inputmask/global/window.js
  10. 14 5
      dist/inputmask/inputmask.date.extensions.js
  11. 1 1
      dist/inputmask/inputmask.extensions.js
  12. 1 1
      dist/inputmask/inputmask.js
  13. 1 1
      dist/inputmask/inputmask.numeric.extensions.js
  14. 1 1
      dist/inputmask/inputmask.phone.extensions.js
  15. 1 1
      dist/inputmask/jquery.inputmask.js
  16. 1 1
      dist/inputmask/phone-codes/phone-be.js
  17. 1 1
      dist/inputmask/phone-codes/phone-ca.js
  18. 1 1
      dist/inputmask/phone-codes/phone-hu.js
  19. 1 1
      dist/inputmask/phone-codes/phone-it.js
  20. 1 1
      dist/inputmask/phone-codes/phone-mx.js
  21. 1 1
      dist/inputmask/phone-codes/phone-nl.js
  22. 1 1
      dist/inputmask/phone-codes/phone-ru.js
  23. 1 1
      dist/inputmask/phone-codes/phone.js
  24. 14 5
      dist/jquery.inputmask.bundle.js
  25. 1 1
      dist/min/inputmask/bindings/inputmask.binding.min.js
  26. 1 1
      dist/min/inputmask/dependencyLibs/inputmask.dependencyLib.jqlite.min.js
  27. 1 1
      dist/min/inputmask/dependencyLibs/inputmask.dependencyLib.jquery.min.js
  28. 1 1
      dist/min/inputmask/dependencyLibs/inputmask.dependencyLib.min.js
  29. 1 1
      dist/min/inputmask/global/document.min.js
  30. 1 1
      dist/min/inputmask/global/window.min.js
  31. 2 2
      dist/min/inputmask/inputmask.date.extensions.min.js
  32. 1 1
      dist/min/inputmask/inputmask.extensions.min.js
  33. 1 1
      dist/min/inputmask/inputmask.min.js
  34. 1 1
      dist/min/inputmask/inputmask.numeric.extensions.min.js
  35. 1 1
      dist/min/inputmask/inputmask.phone.extensions.min.js
  36. 1 1
      dist/min/inputmask/jquery.inputmask.min.js
  37. 1 1
      dist/min/inputmask/phone-codes/phone-be.min.js
  38. 1 1
      dist/min/inputmask/phone-codes/phone-ca.min.js
  39. 1 1
      dist/min/inputmask/phone-codes/phone-hu.min.js
  40. 1 1
      dist/min/inputmask/phone-codes/phone-it.min.js
  41. 1 1
      dist/min/inputmask/phone-codes/phone-mx.min.js
  42. 1 1
      dist/min/inputmask/phone-codes/phone-nl.min.js
  43. 1 1
      dist/min/inputmask/phone-codes/phone-ru.min.js
  44. 1 1
      dist/min/inputmask/phone-codes/phone.min.js
  45. 2 2
      dist/min/jquery.inputmask.bundle.min.js
  46. 243 227
      js/inputmask.date.extensions.js
  47. 1 1
      package.json

+ 1 - 1
bower.json

@@ -1,6 +1,6 @@
 {
   "name": "inputmask",
-  "version": "4.0.0-beta.59",
+  "version": "4.0.0-beta.60",
   "main": [
 	  "./index.js",
     "./css/inputmask.css"

+ 1 - 1
component.json

@@ -2,7 +2,7 @@
 	"name": "inputmask",
 	"repository": "robinherbots/Inputmask",
 	"description": "Inputmask is a javascript library which creates an input mask.  Inputmask can run against vanilla javascript, jQuery and jqlite.",
-	"version": "4.0.0-beta.59",
+	"version": "4.0.0-beta.60",
 	"keywords": [
 		"jquery",
 		"plugins",

+ 1 - 1
composer.json

@@ -1,7 +1,7 @@
 {
   "name": "robinherbots/inputmask",
   "description": "Inputmask is a javascript library which creates an input mask.  Inputmask can run against vanilla javascript, jQuery and jqlite.",
-  "version": "4.0.0-beta.59",
+  "version": "4.0.0-beta.60",
   "type": "library",
   "keywords": ["jquery", "plugins", "input", "form", "inputmask", "mask"],
   "homepage": "http://robinherbots.github.io/Inputmask",

+ 1 - 1
dist/inputmask/bindings/inputmask.binding.js

@@ -3,7 +3,7 @@
 * https://github.com/RobinHerbots/Inputmask
 * Copyright (c) 2010 - 2018 Robin Herbots
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-* Version: 4.0.0-beta.59
+* Version: 4.0.0-beta.60
 */
 
 !function(factory) {

+ 1 - 1
dist/inputmask/dependencyLibs/inputmask.dependencyLib.jqlite.js

@@ -3,7 +3,7 @@
 * https://github.com/RobinHerbots/Inputmask
 * Copyright (c) 2010 - 2018 Robin Herbots
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-* Version: 4.0.0-beta.59
+* Version: 4.0.0-beta.60
 */
 
 !function(factory) {

+ 1 - 1
dist/inputmask/dependencyLibs/inputmask.dependencyLib.jquery.js

@@ -3,7 +3,7 @@
 * https://github.com/RobinHerbots/Inputmask
 * Copyright (c) 2010 - 2018 Robin Herbots
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-* Version: 4.0.0-beta.59
+* Version: 4.0.0-beta.60
 */
 
 !function(factory) {

+ 1 - 1
dist/inputmask/dependencyLibs/inputmask.dependencyLib.js

@@ -3,7 +3,7 @@
 * https://github.com/RobinHerbots/Inputmask
 * Copyright (c) 2010 - 2018 Robin Herbots
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-* Version: 4.0.0-beta.59
+* Version: 4.0.0-beta.60
 */
 
 !function(factory) {

+ 1 - 1
dist/inputmask/global/document.js

@@ -3,7 +3,7 @@
 * https://github.com/RobinHerbots/Inputmask
 * Copyright (c) 2010 - 2018 Robin Herbots
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-* Version: 4.0.0-beta.59
+* Version: 4.0.0-beta.60
 */
 
 "function" == typeof define && define.amd ? define(function() {

+ 1 - 1
dist/inputmask/global/window.js

@@ -3,7 +3,7 @@
 * https://github.com/RobinHerbots/Inputmask
 * Copyright (c) 2010 - 2018 Robin Herbots
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-* Version: 4.0.0-beta.59
+* Version: 4.0.0-beta.60
 */
 
 "function" == typeof define && define.amd ? define(function() {

+ 14 - 5
dist/inputmask/inputmask.date.extensions.js

@@ -3,7 +3,7 @@
 * https://github.com/RobinHerbots/Inputmask
 * Copyright (c) 2010 - 2018 Robin Herbots
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-* Version: 4.0.0-beta.59
+* Version: 4.0.0-beta.60
 */
 
 !function(factory) {
@@ -97,7 +97,7 @@
         return val;
     }
     function analyseMask(maskString, format, opts) {
-        var targetProp, match, dateOperation, dateObj = {
+        var targetProp, match, dateOperation, targetValidator, dateObj = {
             date: new Date(1, 0, 1)
         }, mask = maskString;
         function extendYear(year) {
@@ -108,15 +108,24 @@
             } else correctedyear = correctedyear.replace(/[^0-9]/g, "0");
             return correctedyear;
         }
+        function extendProperty(value) {
+            var correctedValue;
+            if (opts.min && opts.min[targetProp] || opts.max && opts.max[targetProp]) {
+                var min = opts.min && opts.min[targetProp] || opts.max[targetProp], max = opts.max && opts.max[targetProp] || opts.min[targetProp];
+                for (correctedValue = value.replace(/[^0-9]/g, ""), correctedValue += ("" !== correctedValue && 0 == max.indexOf(correctedValue) ? max : min).toString().substr(correctedValue.length); !new RegExp(targetValidator).test(correctedValue); ) correctedValue--;
+            } else correctedValue = value.replace(/[^0-9]/g, "0");
+            return correctedValue;
+        }
         function setValue(dateObj, value, opts) {
-            "year" === targetProp ? (dateObj[targetProp] = extendYear(value), dateObj["raw" + targetProp] = value) : dateObj[targetProp] = opts.min && value.match(/[^0-9]/) ? opts.min[targetProp] : value, 
+            "year" === targetProp ? (dateObj[targetProp] = extendYear(value), dateObj["raw" + targetProp] = value) : dateObj[targetProp] = extendProperty(value), 
             void 0 !== dateOperation && dateOperation.call(dateObj.date, "month" == targetProp ? parseInt(dateObj[targetProp]) - 1 : dateObj[targetProp]);
         }
         if ("string" == typeof mask) {
             for (;match = getTokenizer(opts).exec(format); ) {
                 var value = mask.slice(0, match[0].length);
-                formatCode.hasOwnProperty(match[0]) && (targetProp = formatCode[match[0]][2], dateOperation = formatCode[match[0]][1], 
-                setValue(dateObj, value, opts)), mask = mask.slice(value.length);
+                formatCode.hasOwnProperty(match[0]) && (targetValidator = formatCode[match[0]][0], 
+                targetProp = formatCode[match[0]][2], dateOperation = formatCode[match[0]][1], setValue(dateObj, value)), 
+                mask = mask.slice(value.length);
             }
             return dateObj;
         }

+ 1 - 1
dist/inputmask/inputmask.extensions.js

@@ -3,7 +3,7 @@
 * https://github.com/RobinHerbots/Inputmask
 * Copyright (c) 2010 - 2018 Robin Herbots
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-* Version: 4.0.0-beta.59
+* Version: 4.0.0-beta.60
 */
 
 !function(factory) {

+ 1 - 1
dist/inputmask/inputmask.js

@@ -3,7 +3,7 @@
 * https://github.com/RobinHerbots/Inputmask
 * Copyright (c) 2010 - 2018 Robin Herbots
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-* Version: 4.0.0-beta.59
+* Version: 4.0.0-beta.60
 */
 
 !function(factory) {

+ 1 - 1
dist/inputmask/inputmask.numeric.extensions.js

@@ -3,7 +3,7 @@
 * https://github.com/RobinHerbots/Inputmask
 * Copyright (c) 2010 - 2018 Robin Herbots
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-* Version: 4.0.0-beta.59
+* Version: 4.0.0-beta.60
 */
 
 !function(factory) {

+ 1 - 1
dist/inputmask/inputmask.phone.extensions.js

@@ -3,7 +3,7 @@
 * https://github.com/RobinHerbots/Inputmask
 * Copyright (c) 2010 - 2018 Robin Herbots
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-* Version: 4.0.0-beta.59
+* Version: 4.0.0-beta.60
 */
 
 !function(factory) {

+ 1 - 1
dist/inputmask/jquery.inputmask.js

@@ -3,7 +3,7 @@
 * https://github.com/RobinHerbots/Inputmask
 * Copyright (c) 2010 - 2018 Robin Herbots
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-* Version: 4.0.0-beta.59
+* Version: 4.0.0-beta.60
 */
 
 !function(factory) {

+ 1 - 1
dist/inputmask/phone-codes/phone-be.js

@@ -3,7 +3,7 @@
 * https://github.com/RobinHerbots/Inputmask
 * Copyright (c) 2010 - 2018 Robin Herbots
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-* Version: 4.0.0-beta.59
+* Version: 4.0.0-beta.60
 */
 
 !function(factory) {

+ 1 - 1
dist/inputmask/phone-codes/phone-ca.js

@@ -3,7 +3,7 @@
 * https://github.com/RobinHerbots/Inputmask
 * Copyright (c) 2010 - 2018 Robin Herbots
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-* Version: 4.0.0-beta.59
+* Version: 4.0.0-beta.60
 */
 
 !function(factory) {

+ 1 - 1
dist/inputmask/phone-codes/phone-hu.js

@@ -3,7 +3,7 @@
 * https://github.com/RobinHerbots/Inputmask
 * Copyright (c) 2010 - 2018 Robin Herbots
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-* Version: 4.0.0-beta.59
+* Version: 4.0.0-beta.60
 */
 
 !function(factory) {

+ 1 - 1
dist/inputmask/phone-codes/phone-it.js

@@ -3,7 +3,7 @@
 * https://github.com/RobinHerbots/Inputmask
 * Copyright (c) 2010 - 2018 Robin Herbots
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-* Version: 4.0.0-beta.59
+* Version: 4.0.0-beta.60
 */
 
 !function(factory) {

+ 1 - 1
dist/inputmask/phone-codes/phone-mx.js

@@ -3,7 +3,7 @@
 * https://github.com/RobinHerbots/Inputmask
 * Copyright (c) 2010 - 2018 Robin Herbots
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-* Version: 4.0.0-beta.59
+* Version: 4.0.0-beta.60
 */
 
 !function(factory) {

+ 1 - 1
dist/inputmask/phone-codes/phone-nl.js

@@ -3,7 +3,7 @@
 * https://github.com/RobinHerbots/Inputmask
 * Copyright (c) 2010 - 2018 Robin Herbots
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-* Version: 4.0.0-beta.59
+* Version: 4.0.0-beta.60
 */
 
 !function(factory) {

+ 1 - 1
dist/inputmask/phone-codes/phone-ru.js

@@ -3,7 +3,7 @@
 * https://github.com/RobinHerbots/Inputmask
 * Copyright (c) 2010 - 2018 Robin Herbots
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-* Version: 4.0.0-beta.59
+* Version: 4.0.0-beta.60
 */
 
 !function(factory) {

+ 1 - 1
dist/inputmask/phone-codes/phone.js

@@ -3,7 +3,7 @@
 * https://github.com/RobinHerbots/Inputmask
 * Copyright (c) 2010 - 2018 Robin Herbots
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-* Version: 4.0.0-beta.59
+* Version: 4.0.0-beta.60
 */
 
 !function(factory) {

+ 14 - 5
dist/jquery.inputmask.bundle.js

@@ -3,7 +3,7 @@
 * https://github.com/RobinHerbots/Inputmask
 * Copyright (c) 2010 - 2018 Robin Herbots
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-* Version: 4.0.0-beta.59
+* Version: 4.0.0-beta.60
 */
 
 !function(modules) {
@@ -1781,7 +1781,7 @@
             return val;
         }
         function analyseMask(maskString, format, opts) {
-            var targetProp, match, dateOperation, dateObj = {
+            var targetProp, match, dateOperation, targetValidator, dateObj = {
                 date: new Date(1, 0, 1)
             }, mask = maskString;
             function extendYear(year) {
@@ -1792,15 +1792,24 @@
                 } else correctedyear = correctedyear.replace(/[^0-9]/g, "0");
                 return correctedyear;
             }
+            function extendProperty(value) {
+                var correctedValue;
+                if (opts.min && opts.min[targetProp] || opts.max && opts.max[targetProp]) {
+                    var min = opts.min && opts.min[targetProp] || opts.max[targetProp], max = opts.max && opts.max[targetProp] || opts.min[targetProp];
+                    for (correctedValue = value.replace(/[^0-9]/g, ""), correctedValue += ("" !== correctedValue && 0 == max.indexOf(correctedValue) ? max : min).toString().substr(correctedValue.length); !new RegExp(targetValidator).test(correctedValue); ) correctedValue--;
+                } else correctedValue = value.replace(/[^0-9]/g, "0");
+                return correctedValue;
+            }
             function setValue(dateObj, value, opts) {
-                "year" === targetProp ? (dateObj[targetProp] = extendYear(value), dateObj["raw" + targetProp] = value) : dateObj[targetProp] = opts.min && value.match(/[^0-9]/) ? opts.min[targetProp] : value, 
+                "year" === targetProp ? (dateObj[targetProp] = extendYear(value), dateObj["raw" + targetProp] = value) : dateObj[targetProp] = extendProperty(value), 
                 void 0 !== dateOperation && dateOperation.call(dateObj.date, "month" == targetProp ? parseInt(dateObj[targetProp]) - 1 : dateObj[targetProp]);
             }
             if ("string" == typeof mask) {
                 for (;match = getTokenizer(opts).exec(format); ) {
                     var value = mask.slice(0, match[0].length);
-                    formatCode.hasOwnProperty(match[0]) && (targetProp = formatCode[match[0]][2], dateOperation = formatCode[match[0]][1], 
-                    setValue(dateObj, value, opts)), mask = mask.slice(value.length);
+                    formatCode.hasOwnProperty(match[0]) && (targetValidator = formatCode[match[0]][0], 
+                    targetProp = formatCode[match[0]][2], dateOperation = formatCode[match[0]][1], setValue(dateObj, value)), 
+                    mask = mask.slice(value.length);
                 }
                 return dateObj;
             }

File diff suppressed because it is too large
+ 1 - 1
dist/min/inputmask/bindings/inputmask.binding.min.js


File diff suppressed because it is too large
+ 1 - 1
dist/min/inputmask/dependencyLibs/inputmask.dependencyLib.jqlite.min.js


+ 1 - 1
dist/min/inputmask/dependencyLibs/inputmask.dependencyLib.jquery.min.js

@@ -3,7 +3,7 @@
 * https://github.com/RobinHerbots/Inputmask
 * Copyright (c) 2010 - 2018 Robin Herbots
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-* Version: 4.0.0-beta.59
+* Version: 4.0.0-beta.60
 */
 
 !function(e){"function"==typeof define&&define.amd?define(["jquery"],e):"object"==typeof exports?module.exports=e(require("jquery")):window.dependencyLib=e(jQuery)}(function(e){return e});

File diff suppressed because it is too large
+ 1 - 1
dist/min/inputmask/dependencyLibs/inputmask.dependencyLib.min.js


+ 1 - 1
dist/min/inputmask/global/document.min.js

@@ -3,7 +3,7 @@
 * https://github.com/RobinHerbots/Inputmask
 * Copyright (c) 2010 - 2018 Robin Herbots
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-* Version: 4.0.0-beta.59
+* Version: 4.0.0-beta.60
 */
 
 "function"==typeof define&&define.amd?define(function(){return document}):"object"==typeof exports&&(module.exports=document);

+ 1 - 1
dist/min/inputmask/global/window.min.js

@@ -3,7 +3,7 @@
 * https://github.com/RobinHerbots/Inputmask
 * Copyright (c) 2010 - 2018 Robin Herbots
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-* Version: 4.0.0-beta.59
+* Version: 4.0.0-beta.60
 */
 
 "function"==typeof define&&define.amd?define(function(){return window}):"object"==typeof exports&&(module.exports=window);

File diff suppressed because it is too large
+ 2 - 2
dist/min/inputmask/inputmask.date.extensions.min.js


File diff suppressed because it is too large
+ 1 - 1
dist/min/inputmask/inputmask.extensions.min.js


File diff suppressed because it is too large
+ 1 - 1
dist/min/inputmask/inputmask.min.js


File diff suppressed because it is too large
+ 1 - 1
dist/min/inputmask/inputmask.numeric.extensions.min.js


File diff suppressed because it is too large
+ 1 - 1
dist/min/inputmask/inputmask.phone.extensions.min.js


File diff suppressed because it is too large
+ 1 - 1
dist/min/inputmask/jquery.inputmask.min.js


File diff suppressed because it is too large
+ 1 - 1
dist/min/inputmask/phone-codes/phone-be.min.js


File diff suppressed because it is too large
+ 1 - 1
dist/min/inputmask/phone-codes/phone-ca.min.js


File diff suppressed because it is too large
+ 1 - 1
dist/min/inputmask/phone-codes/phone-hu.min.js


File diff suppressed because it is too large
+ 1 - 1
dist/min/inputmask/phone-codes/phone-it.min.js


File diff suppressed because it is too large
+ 1 - 1
dist/min/inputmask/phone-codes/phone-mx.min.js


File diff suppressed because it is too large
+ 1 - 1
dist/min/inputmask/phone-codes/phone-nl.min.js


File diff suppressed because it is too large
+ 1 - 1
dist/min/inputmask/phone-codes/phone-ru.min.js


File diff suppressed because it is too large
+ 1 - 1
dist/min/inputmask/phone-codes/phone.min.js


File diff suppressed because it is too large
+ 2 - 2
dist/min/jquery.inputmask.bundle.min.js


+ 243 - 227
js/inputmask.date.extensions.js

@@ -17,261 +17,277 @@
     }
 }
 (function ($, Inputmask) {
-    var //supported codes for formatting
-        //http://blog.stevenlevithan.com/archives/date-time-format
-        //https://docs.microsoft.com/en-us/dotnet/standard/base-types/custom-date-and-time-format-strings?view=netframework-4.7
-        formatCode = { //regex, valueSetter, type, displayformatter
-            d: ["[1-9]|[12][0-9]|3[01]", Date.prototype.setDate, "day", Date.prototype.getDate], //Day of the month as digits; no leading zero for single-digit days.
-            dd: ["0[1-9]|[12][0-9]|3[01]", Date.prototype.setDate, "day", function () {
-                return pad(Date.prototype.getDate.call(this), 2);
-            }], //Day of the month as digits; leading zero for single-digit days.
-            ddd: [""], //Day of the week as a three-letter abbreviation.
-            dddd: [""], //Day of the week as its full name.
-            m: ["[1-9]|1[012]", Date.prototype.setMonth, "month", function () {
-                return Date.prototype.getMonth.call(this) + 1;
-            }], //Month as digits; no leading zero for single-digit months.
-            mm: ["0[1-9]|1[012]", Date.prototype.setMonth, "month", function () {
-                return pad(Date.prototype.getMonth.call(this) + 1, 2);
-            }], //Month as digits; leading zero for single-digit months.
-            mmm: [""], //Month as a three-letter abbreviation.
-            mmmm: [""], //Month as its full name.
-            yy: ["[0-9]{2}", Date.prototype.setFullYear, "year", function () {
-                return pad(Date.prototype.getFullYear.call(this), 2);
-            }], //Year as last two digits; leading zero for years less than 10.
-            yyyy: ["[0-9]{4}", Date.prototype.setFullYear, "year", function () {
-                return pad(Date.prototype.getFullYear.call(this), 4);
-            }],
-            h: ["[1-9]|1[0-2]", Date.prototype.setHours, "hours", Date.prototype.getHours], //Hours; no leading zero for single-digit hours (12-hour clock).
-            hh: ["0[1-9]|1[0-2]", Date.prototype.setHours, "hours", function () {
-                return pad(Date.prototype.getHours.call(this), 2);
-            }], //Hours; leading zero for single-digit hours (12-hour clock).
-            hhh: ["[0-9]+", Date.prototype.setHours, "hours", Date.prototype.getHours], //Hours; no limit
-            H: ["1?[0-9]|2[0-3]", Date.prototype.setHours, "hours", Date.prototype.getHours], //Hours; no leading zero for single-digit hours (24-hour clock).
-            HH: ["[01][0-9]|2[0-3]", Date.prototype.setHours, "hours", function () {
-                return pad(Date.prototype.getHours.call(this), 2);
-            }], //Hours; leading zero for single-digit hours (24-hour clock).
-            HHH: ["[0-9]+", Date.prototype.setHours, "hours", Date.prototype.getHours], //Hours; no limit
-            M: ["[1-5]?[0-9]", Date.prototype.setMinutes, "minutes", Date.prototype.getMinutes], //Minutes; no leading zero for single-digit minutes. Uppercase M unlike CF timeFormat's m to avoid conflict with months.
-            MM: ["[0-5][0-9]", Date.prototype.setMinutes, "minutes", function () {
-                return pad(Date.prototype.getMinutes.call(this), 2);
-            }], //Minutes; leading zero for single-digit minutes. Uppercase MM unlike CF timeFormat's mm to avoid conflict with months.
-            s: ["[1-5]?[0-9]", Date.prototype.setSeconds, "seconds", Date.prototype.getSeconds], //Seconds; no leading zero for single-digit seconds.
-            ss: ["[0-5][0-9]", Date.prototype.setSeconds, "seconds", function () {
-                return pad(Date.prototype.getSeconds.call(this), 2);
-            }], //Seconds; leading zero for single-digit seconds.
-            l: ["[0-9]{3}", Date.prototype.setMilliseconds, "milliseconds", function () {
-                return pad(Date.prototype.getMilliseconds.call(this), 3);
-            }], //Milliseconds. 3 digits.
-            L: ["[0-9]{2}", Date.prototype.setMilliseconds, "milliseconds", function () {
-                return pad(Date.prototype.getMilliseconds.call(this), 2);
-            }], //Milliseconds. 2 digits.
-            t: ["[ap]"], //Lowercase, single-character time marker string: a or p.
-            tt: ["[ap]m"], //two-character time marker string: am or pm.
-            T: ["[AP]"], //single-character time marker string: A or P.
-            TT: ["[AP]M"], //two-character time marker string: AM or PM.
-            Z: [""], //US timezone abbreviation, e.g. EST or MDT. With non-US timezones or in the Opera browser, the GMT/UTC offset is returned, e.g. GMT-0500
-            o: [""], //GMT/UTC timezone offset, e.g. -0500 or +0230.
-            S: [""] //The date's ordinal suffix (st, nd, rd, or th).
-        },
-        formatAlias = {
-            isoDate: "yyyy-mm-dd", //2007-06-09
-            isoTime: "HH:MM:ss", //17:46:21
-            isoDateTime: "yyyy-mm-dd'T'HH:MM:ss", //2007-06-09T17:46:21
-            isoUtcDateTime: "UTC:yyyy-mm-dd'T'HH:MM:ss'Z'" //2007-06-09T22:46:21Z
-        };
+        var //supported codes for formatting
+            //http://blog.stevenlevithan.com/archives/date-time-format
+            //https://docs.microsoft.com/en-us/dotnet/standard/base-types/custom-date-and-time-format-strings?view=netframework-4.7
+            formatCode = { //regex, valueSetter, type, displayformatter
+                d: ["[1-9]|[12][0-9]|3[01]", Date.prototype.setDate, "day", Date.prototype.getDate], //Day of the month as digits; no leading zero for single-digit days.
+                dd: ["0[1-9]|[12][0-9]|3[01]", Date.prototype.setDate, "day", function () {
+                    return pad(Date.prototype.getDate.call(this), 2);
+                }], //Day of the month as digits; leading zero for single-digit days.
+                ddd: [""], //Day of the week as a three-letter abbreviation.
+                dddd: [""], //Day of the week as its full name.
+                m: ["[1-9]|1[012]", Date.prototype.setMonth, "month", function () {
+                    return Date.prototype.getMonth.call(this) + 1;
+                }], //Month as digits; no leading zero for single-digit months.
+                mm: ["0[1-9]|1[012]", Date.prototype.setMonth, "month", function () {
+                    return pad(Date.prototype.getMonth.call(this) + 1, 2);
+                }], //Month as digits; leading zero for single-digit months.
+                mmm: [""], //Month as a three-letter abbreviation.
+                mmmm: [""], //Month as its full name.
+                yy: ["[0-9]{2}", Date.prototype.setFullYear, "year", function () {
+                    return pad(Date.prototype.getFullYear.call(this), 2);
+                }], //Year as last two digits; leading zero for years less than 10.
+                yyyy: ["[0-9]{4}", Date.prototype.setFullYear, "year", function () {
+                    return pad(Date.prototype.getFullYear.call(this), 4);
+                }],
+                h: ["[1-9]|1[0-2]", Date.prototype.setHours, "hours", Date.prototype.getHours], //Hours; no leading zero for single-digit hours (12-hour clock).
+                hh: ["0[1-9]|1[0-2]", Date.prototype.setHours, "hours", function () {
+                    return pad(Date.prototype.getHours.call(this), 2);
+                }], //Hours; leading zero for single-digit hours (12-hour clock).
+                hhh: ["[0-9]+", Date.prototype.setHours, "hours", Date.prototype.getHours], //Hours; no limit
+                H: ["1?[0-9]|2[0-3]", Date.prototype.setHours, "hours", Date.prototype.getHours], //Hours; no leading zero for single-digit hours (24-hour clock).
+                HH: ["[01][0-9]|2[0-3]", Date.prototype.setHours, "hours", function () {
+                    return pad(Date.prototype.getHours.call(this), 2);
+                }], //Hours; leading zero for single-digit hours (24-hour clock).
+                HHH: ["[0-9]+", Date.prototype.setHours, "hours", Date.prototype.getHours], //Hours; no limit
+                M: ["[1-5]?[0-9]", Date.prototype.setMinutes, "minutes", Date.prototype.getMinutes], //Minutes; no leading zero for single-digit minutes. Uppercase M unlike CF timeFormat's m to avoid conflict with months.
+                MM: ["[0-5][0-9]", Date.prototype.setMinutes, "minutes", function () {
+                    return pad(Date.prototype.getMinutes.call(this), 2);
+                }], //Minutes; leading zero for single-digit minutes. Uppercase MM unlike CF timeFormat's mm to avoid conflict with months.
+                s: ["[1-5]?[0-9]", Date.prototype.setSeconds, "seconds", Date.prototype.getSeconds], //Seconds; no leading zero for single-digit seconds.
+                ss: ["[0-5][0-9]", Date.prototype.setSeconds, "seconds", function () {
+                    return pad(Date.prototype.getSeconds.call(this), 2);
+                }], //Seconds; leading zero for single-digit seconds.
+                l: ["[0-9]{3}", Date.prototype.setMilliseconds, "milliseconds", function () {
+                    return pad(Date.prototype.getMilliseconds.call(this), 3);
+                }], //Milliseconds. 3 digits.
+                L: ["[0-9]{2}", Date.prototype.setMilliseconds, "milliseconds", function () {
+                    return pad(Date.prototype.getMilliseconds.call(this), 2);
+                }], //Milliseconds. 2 digits.
+                t: ["[ap]"], //Lowercase, single-character time marker string: a or p.
+                tt: ["[ap]m"], //two-character time marker string: am or pm.
+                T: ["[AP]"], //single-character time marker string: A or P.
+                TT: ["[AP]M"], //two-character time marker string: AM or PM.
+                Z: [""], //US timezone abbreviation, e.g. EST or MDT. With non-US timezones or in the Opera browser, the GMT/UTC offset is returned, e.g. GMT-0500
+                o: [""], //GMT/UTC timezone offset, e.g. -0500 or +0230.
+                S: [""] //The date's ordinal suffix (st, nd, rd, or th).
+            },
+            formatAlias = {
+                isoDate: "yyyy-mm-dd", //2007-06-09
+                isoTime: "HH:MM:ss", //17:46:21
+                isoDateTime: "yyyy-mm-dd'T'HH:MM:ss", //2007-06-09T17:46:21
+                isoUtcDateTime: "UTC:yyyy-mm-dd'T'HH:MM:ss'Z'" //2007-06-09T22:46:21Z
+            };
 
-    function getTokenizer(opts) {
-        if (!opts.tokenizer) {
-            var tokens = [];
-            for (var ndx in formatCode) {
-                if (tokens.indexOf(ndx[0]) === -1)
-                    tokens.push(ndx[0]);
+        function getTokenizer(opts) {
+            if (!opts.tokenizer) {
+                var tokens = [];
+                for (var ndx in formatCode) {
+                    if (tokens.indexOf(ndx[0]) === -1)
+                        tokens.push(ndx[0]);
+                }
+                opts.tokenizer = "(" + tokens.join("+|") + ")+?|.";
+                opts.tokenizer = new RegExp(opts.tokenizer, "g");
             }
-            opts.tokenizer = "(" + tokens.join("+|") + ")+?|.";
-            opts.tokenizer = new RegExp(opts.tokenizer, "g");
+
+            return opts.tokenizer;
         }
 
-        return opts.tokenizer;
-    }
+        function isValidDate(dateParts, currentResult) {
+            return !isFinite(dateParts.day) || (dateParts.day == "29" && !isFinite(dateParts.rawyear)) || new Date(dateParts.date.getFullYear(), isFinite(dateParts.month) ? dateParts.month : dateParts.date.getMonth() + 1, 0).getDate() >= dateParts.day
+                ? currentResult
+                : false; //take corrective action if possible
+        }
 
-    function isValidDate(dateParts, currentResult) {
-        return !isFinite(dateParts.day) || (dateParts.day == "29" && !isFinite(dateParts.rawyear)) || new Date(dateParts.date.getFullYear(), isFinite(dateParts.month) ? dateParts.month : dateParts.date.getMonth() + 1, 0).getDate() >= dateParts.day
-            ? currentResult
-            : false; //take corrective action if possible
-    }
+        function isDateInRange(dateParts, opts) {
+            var result = true;
+            if (opts.min && opts.min.date.getTime() === opts.min.date.getTime()) {
+                result = opts.min.date.getTime() <= dateParts.date.getTime();
+            }
+            if (result && opts.max && opts.max.date.getTime() === opts.max.date.getTime()) {
+                result = opts.max.date.getTime() >= dateParts.date.getTime();
+            }
 
-    function isDateInRange(dateParts, opts) {
-        var result = true;
-        if (opts.min && opts.min.date.getTime() === opts.min.date.getTime()) {
-            result = opts.min.date.getTime() <= dateParts.date.getTime();
-        }
-        if (result && opts.max && opts.max.date.getTime() === opts.max.date.getTime()) {
-            result = opts.max.date.getTime() >= dateParts.date.getTime();
+            return result;
         }
 
-        return result;
-    }
-
-    //parse the given format and return a mask pattern
-    //when a dateObjValue is passed a datestring in the requested format is returned
-    function parse(format, dateObjValue, opts) {
-        //parse format to regex string
-        var mask = "", match;
-        while (match = getTokenizer(opts).exec(format)) {
-            if (dateObjValue === undefined) {
-                if (formatCode[match[0]]) {
-                    mask += "(" + formatCode[match[0]][0] + ")";
-                } else {
-                    switch (match[0]) {
-                        case "[":
-                            mask += "(";
-                            break;
-                        case "]":
-                            mask += ")?";
-                            break;
-                        default:
-                            mask += Inputmask.escapeRegex(match[0]);
+        //parse the given format and return a mask pattern
+        //when a dateObjValue is passed a datestring in the requested format is returned
+        function parse(format, dateObjValue, opts) {
+            //parse format to regex string
+            var mask = "", match;
+            while (match = getTokenizer(opts).exec(format)) {
+                if (dateObjValue === undefined) {
+                    if (formatCode[match[0]]) {
+                        mask += "(" + formatCode[match[0]][0] + ")";
+                    } else {
+                        switch (match[0]) {
+                            case "[":
+                                mask += "(";
+                                break;
+                            case "]":
+                                mask += ")?";
+                                break;
+                            default:
+                                mask += Inputmask.escapeRegex(match[0]);
+                        }
                     }
                 }
-            }
-            else {
-                if (formatCode[match[0]]) {
-                    var getFn = formatCode[match[0]][3];
-                    mask += getFn.call(dateObjValue.date);
+                else {
+                    if (formatCode[match[0]]) {
+                        var getFn = formatCode[match[0]][3];
+                        mask += getFn.call(dateObjValue.date);
+                    }
+                    else mask += match[0];
                 }
-                else mask += match[0];
             }
+            return mask;
         }
-        return mask;
-    }
 
-    //padding function
-    function pad(val, len) {
-        val = String(val);
-        len = len || 2;
-        while (val.length < len) val = "0" + val;
-        return val;
-    }
-
-    function analyseMask(maskString, format, opts) {
-        var dateObj = {"date": new Date(1, 0, 1)}, targetProp, mask = maskString, match, dateOperation;
-
-        function extendYear(year) {
-            var correctedyear = year.length === 4 ? year : new Date().getFullYear().toString().substr(0, 4 - year.length) + year;
-            if (opts.min && opts.min.year || opts.max && opts.max.year) {
-                var minyear = opts.min && opts.min.year || opts.max.year,
-                    maxyear = opts.max && opts.max.year || opts.min.year;
-                correctedyear = correctedyear.replace(/[^0-9]/g, "");
-                correctedyear += minyear == maxyear ?
-                    minyear.substr(correctedyear.length) :
-                    (correctedyear !== "" && maxyear.indexOf(correctedyear) == 0 ? parseInt(maxyear) - 1 : parseInt(minyear) + 1).toString().substr(correctedyear.length);
-            } else correctedyear = correctedyear.replace(/[^0-9]/g, "0");
-            return correctedyear;
+        //padding function
+        function pad(val, len) {
+            val = String(val);
+            len = len || 2;
+            while (val.length < len) val = "0" + val;
+            return val;
         }
 
-        function setValue(dateObj, value, opts) {
-            if (targetProp === "year") {
-                dateObj[targetProp] = extendYear(value);
-                dateObj["raw" + targetProp] = value;
+        function analyseMask(maskString, format, opts) {
+            var dateObj = {"date": new Date(1, 0, 1)}, targetProp, mask = maskString, match, dateOperation, targetValidator;
+
+            function extendYear(year) {
+                var correctedyear = year.length === 4 ? year : new Date().getFullYear().toString().substr(0, 4 - year.length) + year;
+                if (opts.min && opts.min.year || opts.max && opts.max.year) {
+                    var minyear = opts.min && opts.min.year || opts.max.year,
+                        maxyear = opts.max && opts.max.year || opts.min.year;
+                    correctedyear = correctedyear.replace(/[^0-9]/g, "");
+                    correctedyear += minyear == maxyear ?
+                        minyear.substr(correctedyear.length) :
+                        (correctedyear !== "" && maxyear.indexOf(correctedyear) == 0 ? parseInt(maxyear) - 1 : parseInt(minyear) + 1).toString().substr(correctedyear.length);
+                } else correctedyear = correctedyear.replace(/[^0-9]/g, "0");
+                return correctedyear;
             }
-            else dateObj[targetProp] = opts.min && value.match(/[^0-9]/) ? opts.min[targetProp] : value;
 
-            if (dateOperation !== undefined)
-                dateOperation.call(dateObj.date, targetProp == "month" ? parseInt(dateObj[targetProp]) - 1 : dateObj[targetProp]);
-        }
+            function extendProperty(value) {
+                var correctedValue;
+                if (opts.min && opts.min[targetProp] || opts.max && opts.max[targetProp]) {
+                    var min = opts.min && opts.min[targetProp] || opts.max[targetProp],
+                        max = opts.max && opts.max[targetProp] || opts.min[targetProp];
+                    correctedValue = value.replace(/[^0-9]/g, "");
+                    correctedValue += (correctedValue !== "" && max.indexOf(correctedValue) == 0 ? max : min).toString().substr(correctedValue.length);
+                    while (!(new RegExp(targetValidator)).test(correctedValue)) {
+                        correctedValue--;
+                    }
+                } else correctedValue = value.replace(/[^0-9]/g, "0");
+                return correctedValue;
+            }
 
-        if (typeof mask === "string") {
-            while (match = getTokenizer(opts).exec(format)) {
-                var value = mask.slice(0, match[0].length);
-                if (formatCode.hasOwnProperty(match[0])) {
-                    targetProp = formatCode[match[0]][2];
-                    dateOperation = formatCode[match[0]][1];
-                    setValue(dateObj, value, opts);
+            function setValue(dateObj, value, opts) {
+                if (targetProp === "year") {
+                    dateObj[targetProp] = extendYear(value);
+                    dateObj["raw" + targetProp] = value;
                 }
-                mask = mask.slice(value.length);
+                else dateObj[targetProp] = extendProperty(value);
+
+                if (dateOperation !== undefined)
+                    dateOperation.call(dateObj.date, targetProp == "month" ? parseInt(dateObj[targetProp]) - 1 : dateObj[targetProp]);
             }
 
-            return dateObj;
+            if (typeof mask === "string") {
+                while (match = getTokenizer(opts).exec(format)) {
+                    var value = mask.slice(0, match[0].length);
+                    if (formatCode.hasOwnProperty(match[0])) {
+                        targetValidator = formatCode[match[0]][0];
+                        targetProp = formatCode[match[0]][2];
+                        dateOperation = formatCode[match[0]][1];
+                        setValue(dateObj, value, opts);
+                    }
+                    mask = mask.slice(value.length);
+                }
+
+                return dateObj;
+            }
+            return undefined;
         }
-        return undefined;
-    }
 
-    Inputmask.extendAliases({
-        "datetime": {
-            mask: function (opts) {
-                //localize
-                formatCode.S = opts.i18n.ordinalSuffix.join("|");
+        Inputmask.extendAliases({
+            "datetime": {
+                mask: function (opts) {
+                    //localize
+                    formatCode.S = opts.i18n.ordinalSuffix.join("|");
 
-                opts.inputFormat = formatAlias[opts.inputFormat] || opts.inputFormat; //resolve possible formatAkias
-                opts.displayFormat = formatAlias[opts.displayFormat] || opts.displayFormat || opts.inputFormat; //resolve possible formatAkias
-                opts.outputFormat = formatAlias[opts.outputFormat] || opts.outputFormat || opts.inputFormat; //resolve possible formatAkias
-                opts.placeholder = opts.placeholder !== "" ? opts.placeholder : opts.inputFormat.replace(/[\[\]]/, "");
-                opts.min = analyseMask(opts.min, opts.inputFormat, opts);
-                opts.max = analyseMask(opts.max, opts.inputFormat, opts);
-                opts.regex = parse(opts.inputFormat, undefined, opts);
-                // console.log(opts.regex);
-                return null; //migrate to regex mask
-            },
-            placeholder: "", //set default as none (~ auto); when a custom placeholder is passed it will be used
-            inputFormat: "isoDateTime", //format used to input the date
-            displayFormat: undefined, //visual format when the input looses focus
-            outputFormat: undefined, //unmasking format
-            min: null, //needs to be in the same format as the inputfornat
-            max: null, //needs to be in the same format as the inputfornat,
-            // Internationalization strings
-            i18n: {
-                dayNames: [
-                    "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun",
-                    "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"
-                ],
-                monthNames: [
-                    "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
-                    "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
-                ],
-                ordinalSuffix: ["st", "nd", "rd", "th"]
-            },
-            postValidation: function (buffer, currentResult, opts) {
-                var result = currentResult, dateParts = analyseMask(buffer.join(""), opts.inputFormat, opts);
-                if (result && dateParts.date.getTime() === dateParts.date.getTime()) { //check for a valid date ~ an invalid date returns NaN which isn't equal
-                    result = isValidDate(dateParts, result);
-                    result = result && isDateInRange(dateParts, opts);
-                }
+                    opts.inputFormat = formatAlias[opts.inputFormat] || opts.inputFormat; //resolve possible formatAkias
+                    opts.displayFormat = formatAlias[opts.displayFormat] || opts.displayFormat || opts.inputFormat; //resolve possible formatAkias
+                    opts.outputFormat = formatAlias[opts.outputFormat] || opts.outputFormat || opts.inputFormat; //resolve possible formatAkias
+                    opts.placeholder = opts.placeholder !== "" ? opts.placeholder : opts.inputFormat.replace(/[\[\]]/, "");
+                    opts.min = analyseMask(opts.min, opts.inputFormat, opts);
+                    opts.max = analyseMask(opts.max, opts.inputFormat, opts);
+                    opts.regex = parse(opts.inputFormat, undefined, opts);
+                    // console.log(opts.regex);
+                    return null; //migrate to regex mask
+                },
+                placeholder: "", //set default as none (~ auto); when a custom placeholder is passed it will be used
+                inputFormat: "isoDateTime", //format used to input the date
+                displayFormat: undefined, //visual format when the input looses focus
+                outputFormat: undefined, //unmasking format
+                min: null, //needs to be in the same format as the inputfornat
+                max: null, //needs to be in the same format as the inputfornat,
+                // Internationalization strings
+                i18n: {
+                    dayNames: [
+                        "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun",
+                        "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"
+                    ],
+                    monthNames: [
+                        "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
+                        "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
+                    ],
+                    ordinalSuffix: ["st", "nd", "rd", "th"]
+                },
+                postValidation: function (buffer, currentResult, opts) {
+                    var result = currentResult, dateParts = analyseMask(buffer.join(""), opts.inputFormat, opts);
+                    if (result && dateParts.date.getTime() === dateParts.date.getTime()) { //check for a valid date ~ an invalid date returns NaN which isn't equal
+                        result = isValidDate(dateParts, result);
+                        result = result && isDateInRange(dateParts, opts);
+                    }
 
-                return result;
-            },
-            onKeyDown: function (e, buffer, caretPos, opts) {
-                var input = this;
-                if (e.ctrlKey && e.keyCode === Inputmask.keyCode.RIGHT) {
-                    var today = new Date(), match, date = "";
+                    return result;
+                },
+                onKeyDown: function (e, buffer, caretPos, opts) {
+                    var input = this;
+                    if (e.ctrlKey && e.keyCode === Inputmask.keyCode.RIGHT) {
+                        var today = new Date(), match, date = "";
 
-                    while (match = getTokenizer(opts).exec(opts.inputFormat)) {
-                        if (match[0].charAt(0) === "d") {
-                            date += pad(today.getDate(), match[0].length);
-                        } else if (match[0].charAt(0) === "m") {
-                            date += pad((today.getMonth() + 1), match[0].length);
-                        } else if (match[0] === "yyyy") {
-                            date += today.getFullYear().toString();
-                        } else if (match[0].charAt(0) === "y") {
-                            date += pad(today.getYear(), match[0].length);
+                        while (match = getTokenizer(opts).exec(opts.inputFormat)) {
+                            if (match[0].charAt(0) === "d") {
+                                date += pad(today.getDate(), match[0].length);
+                            } else if (match[0].charAt(0) === "m") {
+                                date += pad((today.getMonth() + 1), match[0].length);
+                            } else if (match[0] === "yyyy") {
+                                date += today.getFullYear().toString();
+                            } else if (match[0].charAt(0) === "y") {
+                                date += pad(today.getYear(), match[0].length);
+                            }
                         }
-                    }
 
-                    input.inputmask._valueSet(date);
-                    $(input).trigger("setvalue");
-                }
-            },
-            onUnMask: function (maskedValue, unmaskedValue, opts) {
-                return parse(opts.outputFormat, analyseMask(maskedValue, opts.inputFormat, opts), opts);
-            },
-            casing: function (elem, test, pos, validPositions) {
-                if (test.nativeDef.indexOf("[ap]") == 0) return elem.toLowerCase();
-                if (test.nativeDef.indexOf("[AP]") == 0) return elem.toUpperCase();
-                return elem;
-            },
-            insertMode: false
-        }
-    });
+                        input.inputmask._valueSet(date);
+                        $(input).trigger("setvalue");
+                    }
+                },
+                onUnMask: function (maskedValue, unmaskedValue, opts) {
+                    return parse(opts.outputFormat, analyseMask(maskedValue, opts.inputFormat, opts), opts);
+                },
+                casing: function (elem, test, pos, validPositions) {
+                    if (test.nativeDef.indexOf("[ap]") == 0) return elem.toLowerCase();
+                    if (test.nativeDef.indexOf("[AP]") == 0) return elem.toUpperCase();
+                    return elem;
+                },
+                insertMode: false
+            }
+        });
 
-    return Inputmask;
-}))
+        return Inputmask;
+    }
+))
 ;

+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
   "name": "inputmask",
-  "version": "4.0.0-beta.59",
+  "version": "4.0.0-beta.60",
   "description": "Inputmask is a javascript library which creates an input mask.  Inputmask can run against vanilla javascript, jQuery and jqlite.",
   "main": "index.js",
   "files": [