diff --git a/.travis.yml b/.travis.yml index fbded7c..4c30482 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,6 +22,7 @@ deploy: repo: shopnilsazal/validus tags: true env: +- TOXENV=py36 - TOXENV=py35 - TOXENV=py34 - TOXENV=py33 diff --git a/HISTORY.rst b/HISTORY.rst index 83158f7..75a6dee 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -2,6 +2,12 @@ History ======= +0.2.0 (2017-12-15) +------------------ + +* Added some more functions. +* Refactored for improved performance. + 0.1.0 (2017-06-07) ------------------ diff --git a/README.rst b/README.rst index f180f49..e3dd87f 100644 --- a/README.rst +++ b/README.rst @@ -10,7 +10,7 @@ Validus :target: https://travis-ci.org/shopnilsazal/validus -A dead simple Python data validation library. +A dead simple Python string validation library. Requirements @@ -45,11 +45,13 @@ List of Functions isascii() isprintascii() + isnonempty() isbase64() isemail() ishexadecimal() isint() isfloat() + ispositive() isslug() isuuid() isuuid3() @@ -90,6 +92,8 @@ List of Functions isisbn10() isisbn13() isimei() + ismimetype() + isisrc() diff --git a/docs/.buildinfo b/docs/.buildinfo index 4ca426f..80e559e 100644 --- a/docs/.buildinfo +++ b/docs/.buildinfo @@ -1,4 +1,4 @@ # Sphinx build info version 1 # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. -config: d0213160df0bf744dd6a6203cfb914b0 +config: e7441bff21ce101b07f8cb138af3427c tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/docs/.doctrees/authors.doctree b/docs/.doctrees/authors.doctree index 2519e01..15a6fcd 100644 Binary files a/docs/.doctrees/authors.doctree and b/docs/.doctrees/authors.doctree differ diff --git a/docs/.doctrees/contributing.doctree b/docs/.doctrees/contributing.doctree index 93a16a8..5c5a542 100644 Binary files a/docs/.doctrees/contributing.doctree and b/docs/.doctrees/contributing.doctree differ diff --git a/docs/.doctrees/environment.pickle b/docs/.doctrees/environment.pickle index f6e0d07..1ded56b 100644 Binary files a/docs/.doctrees/environment.pickle and b/docs/.doctrees/environment.pickle differ diff --git a/docs/.doctrees/history.doctree b/docs/.doctrees/history.doctree index e6bac56..f95fe15 100644 Binary files a/docs/.doctrees/history.doctree and b/docs/.doctrees/history.doctree differ diff --git a/docs/.doctrees/index.doctree b/docs/.doctrees/index.doctree index 6c42a7e..6408e70 100644 Binary files a/docs/.doctrees/index.doctree and b/docs/.doctrees/index.doctree differ diff --git a/docs/.doctrees/installation.doctree b/docs/.doctrees/installation.doctree index f71b063..880a35a 100644 Binary files a/docs/.doctrees/installation.doctree and b/docs/.doctrees/installation.doctree differ diff --git a/docs/.doctrees/readme.doctree b/docs/.doctrees/readme.doctree index d77fb59..8861c34 100644 Binary files a/docs/.doctrees/readme.doctree and b/docs/.doctrees/readme.doctree differ diff --git a/docs/.doctrees/usage.doctree b/docs/.doctrees/usage.doctree index 8c583d1..7ba38e2 100644 Binary files a/docs/.doctrees/usage.doctree and b/docs/.doctrees/usage.doctree differ diff --git a/docs/_downloads/game1.py b/docs/_downloads/game1.py deleted file mode 100644 index 9b80d46..0000000 --- a/docs/_downloads/game1.py +++ /dev/null @@ -1,35 +0,0 @@ -# attrs-style automatic setting of members with validation -from validus.contract import ValidusBase -import sys -sys.tracebacklimit=None # Convenience - -class Player(ValidusBase): - name: nonempty_ascii - x: integer - y: integer - - def left(self,dx: positive_integer): - self.x -= dx - - def right(self,dx: positive_integer): - self.x += dx - - -if __name__ == "__main__": - # Show failure - #name=''; x=0; y=0 - #print(f"Instantiating class with name={name}, x={x}, y={y}") - #g=Player(name,x,y) - - # Show success - name='Guido'; x=0; y=0 - print(f"Instantiating class with name={name}, x={x}, y={y}") - g=Player(name,x,y) - dx=1 - print(f"Move to the left with dx={dx}") - g.left(dx) - - # Show failure - dx=-1 - print(f"Move to the left with dx={dx}") - g.left(dx) diff --git a/docs/_downloads/game2.py b/docs/_downloads/game2.py deleted file mode 100644 index 9e02589..0000000 --- a/docs/_downloads/game2.py +++ /dev/null @@ -1,33 +0,0 @@ -from validus.contract import ValidusBase -from validus.contract import set_validated_contracts -set_validated_contracts(__name__) -import sys -sys.tracebacklimit=None # Convenience - -dx: positive_integer - -class Player(ValidusBase): - name: nonempty_ascii - x: integer - y: integer - - def left(self,dx): - self.x -= dx - - def right(self,dx): - self.x += dx - - -if __name__ == "__main__": - # Show that it works - name='Guido'; x=0; y=0 - print(f"Instantiating class with name={name}, x={x}, y={y}") - g=Player(name,x,y) - dx=1 - print(f"Move to the left with dx={dx}") - g.left(dx) - - # Show that it is broken - dx=-1 - print(f"Move to the left with dx={dx}") - g.left(dx) diff --git a/docs/_downloads/gcd0.py b/docs/_downloads/gcd0.py deleted file mode 100644 index 681c843..0000000 --- a/docs/_downloads/gcd0.py +++ /dev/null @@ -1,26 +0,0 @@ -# Method 0: Traditional method -import validus -import sys -sys.tracebacklimit=None # Convenience - -def gcd(a,b): - """ - Compute greatest common denominator - """ - assert validus.isint(str(a)) and validus.ispositive(str(a)), 'gcd requires a positive number for a' - assert validus.isint(str(b)) and validus.ispositive(str(b)), 'gcd requires a positive number for b' - - while b: - a, b = b, a % b - return a - -if __name__ == "__main__": - # Show that it works - a=27; b=36 - print(f"The greatest common denominator of {a} and {b} is:") - print(gcd(a,b)) - - # Show that it is broken - a=2.7; b=3.6 - print(f"The greatest common denominator of {a} and {b} is:") - print(gcd(a,b)) diff --git a/docs/_downloads/gcd1.py b/docs/_downloads/gcd1.py deleted file mode 100644 index b910a5c..0000000 --- a/docs/_downloads/gcd1.py +++ /dev/null @@ -1,25 +0,0 @@ -# Method using type annotations and decorators -from validus.contract import set_validated_contracts -set_validated_contracts(__name__) -import sys -sys.tracebacklimit=None # Convenience - -@checked -def gcd(a:positive_integer,b:positive_integer): - """ - Compute greatest common denominator - """ - while b: - a, b = b, a % b - return a - -if __name__ == "__main__": - # Show that it works - a=27; b=36 - print(f"The greatest common denominator of {a} and {b} is:") - print(gcd(a,b)) - - # Show that it is broken - a=2.7; b=3.6 - print(f"The greatest common denominator of {a} and {b} is:") - print(gcd(a,b)) diff --git a/docs/_modules/index.html b/docs/_modules/index.html index 2c39542..bd153fb 100644 --- a/docs/_modules/index.html +++ b/docs/_modules/index.html @@ -1,23 +1,21 @@ + - - - Overview: module code — validus 0.1.0 documentation - + Overview: module code — validus 0.2.0 documentation - @@ -25,7 +23,6 @@ - @@ -33,7 +30,7 @@ - +
@@ -63,9 +60,10 @@

validus

Navigation

diff --git a/docs/_modules/validus/isbn.html b/docs/_modules/validus/isbn.html index 93ace60..a53aa29 100644 --- a/docs/_modules/validus/isbn.html +++ b/docs/_modules/validus/isbn.html @@ -1,23 +1,21 @@ + - - - validus.isbn — validus 0.1.0 documentation - + validus.isbn — validus 0.2.0 documentation - @@ -25,8 +23,6 @@ - - @@ -34,7 +30,7 @@ - +
@@ -47,12 +43,6 @@

Source code for validus.isbn

 import re
 
 
-isbn_patterns = {
-    'isbn10': r"^(?:[0-9]{9}X|[0-9]{10})$",
-    'isbn13': r"^(?:[0-9]{13})$",
-}
-
-
 @validate_str
 def sanitize_isbn(isbn):
     sanitized = re.sub(r'[\s-]+', '', isbn)
@@ -93,10 +83,12 @@ 

Source code for validus.isbn

     :param isbn: ISBN string to validate
     :param version: Optional ISBN version (10 or 13)
     """
+    isbn10_pattern = re.compile(r"^(?:[0-9]{9}X|[0-9]{10})$")
+    isbn13_pattern = re.compile(r"^(?:[0-9]{13})$")
     sanitized = sanitize_isbn(isbn)
 
     if version == 10:
-        if not re.match(isbn_patterns['isbn10'], sanitized):
+        if not isbn10_pattern.match(sanitized):
             return False
         checksum = get_isbn_10_checksum(isbn)
         if checksum % 11 == 0:
@@ -104,7 +96,7 @@ 

Source code for validus.isbn

         return False
 
     elif version == 13:
-        if not re.match(isbn_patterns['isbn13'], sanitized):
+        if not isbn13_pattern.match(sanitized):
             return False
         checksum = get_isbn_13_checksum(isbn)
         if int(sanitized[12]) - ((10 - (checksum % 10)) % 10) == 0:
@@ -167,9 +159,10 @@ 

validus

Navigation

diff --git a/docs/_modules/validus/phones.html b/docs/_modules/validus/phones.html index d7c389a..5d4dd51 100644 --- a/docs/_modules/validus/phones.html +++ b/docs/_modules/validus/phones.html @@ -1,23 +1,21 @@ + - - - validus.phones — validus 0.1.0 documentation - + validus.phones — validus 0.2.0 documentation - @@ -25,8 +23,6 @@ - - @@ -34,7 +30,7 @@ - +
@@ -46,55 +42,9 @@

Source code for validus.phones

 from .utils import validate_str
 import re
 
-phones = {
-    'ar-DZ': r'^(\+?213|0)(5|6|7)\d{8}$',
-    'ar-SY': r'^(!?(\+?963)|0)?9\d{8}$',
-    'ar-SA': r'^(!?(\+?966)|0)?5\d{8}$',
-    'en-US': r'^(\+?1)?[2-9]\d{2}[2-9](?!11)\d{6}$',
-    'cs-CZ': r'^(\+?420)? ?[1-9][0-9]{2} ?[0-9]{3} ?[0-9]{3}$',
-    'de-DE': r'^(\+?49[ \.\-])?([\(]{1}[0-9]{1,6}[\)])?([0-9 \.\-\']{3,20})((x|ext|extension)[ ]?[0-9]{1,4})?$',
-    'da-DK': r'^(\+?45)?(\d{8})$',
-    'el-GR': r'^(\+?30)?(69\d{8})$',
-    'en-AU': r'^(\+?61|0)4\d{8}$',
-    'en-GB': r'^(\+?44|0)7\d{9}$',
-    'en-HK': r'^(\+?852\-?)?[569]\d{3}\-?\d{4}$',
-    'en-IN': r'^(\+?91|0)?[789]\d{9}$',
-    'en-NG': r'^(\+?234|0)?[789]\d{9}$',
-    'en-NZ': r'^(\+?64|0)2\d{7,9}$',
-    'en-ZA': r'^(\+?27|0)\d{9}$',
-    'en-ZM': r'^(\+?26)?09[567]\d{7}$',
-    'es-ES': r'^(\+?34)?(6\d{1}|7[1234])\d{7}$',
-    'fi-FI': r'^(\+?358|0)\s?(4(0|1|2|4|5)?|50)\s?(\d\s?){4,8}\d$',
-    'fr-FR': r'^(\+?33|0)[67]\d{8}$',
-    'he-IL': r'^(\+972|0)([23489]|5[0248]|77)[1-9]\d{6}',
-    'hu-HU': r'^(\+?36)(20|30|70)\d{7}$',
-    'id-ID': r'^(\+?62|0[1-9])[\s|\d]+$',
-    'it-IT': r'^(\+?39)?\s?3\d{2} ?\d{6,7}$',
-    'ja-JP': r'^(\+?81|0)\d{1,4}[ \-]?\d{1,4}[ \-]?\d{4}$',
-    'ms-MY': r'^(\+?6?01){1}(([145]{1}(\-|\s)?\d{7,8})|([236789]{1}(\s|\-)?\d{7}))$',
-    'nb-NO': r'^(\+?47)?[49]\d{7}$',
-    'nl-BE': r'^(\+?32|0)4?\d{8}$',
-    'nn-NO': r'^(\+?47)?[49]\d{7}$',
-    'pl-PL': r'^(\+?48)? ?[5-8]\d ?\d{3} ?\d{2} ?\d{2}$',
-    'pt-BR': r'^(\+?55|0)\-?[1-9]{2}\-?[2-9]{1}\d{3,4}\-?\d{4}$',
-    'pt-PT': r'^(\+?351)?9[1236]\d{7}$',
-    'ro-RO': r'^(\+?4?0)\s?7\d{2}(\'|\s|\.|\-)?\d{3}(\s|\.|\-)?\d{3}$',
-    'en-PK': r'^((\+92)|(0092))-{0,1}\d{3}-{0,1}\d{7}$|^\d{11}$|^\d{4}-\d{7}$',
-    'ru-RU': r'^(\+?7|8)?9\d{9}$',
-    'sr-RS': r'^(\+3816|06)[- \d]{5,9}$',
-    'tr-TR': r'^(\+?90|0)?5\d{9}$',
-    'vi-VN': r'^(\+?84|0)?((1(2([0-9])|6([2-9])|88|99))|(9((?!5)[0-9])))([0-9]{7})$',
-    'zh-CN': r'^(\+?0?86\-?)?1[345789]\d{9}$',
-    'zh-TW': r'^(\+?886\-?|0)?9\d{8}$'
-}
-
-phones['en-CA'] = phones['en-US']
-phones['fr-BE'] = phones['nl-BE']
-phones['zh-HK'] = phones['en-HK']
-
-
-@validate_str
-
[docs]def isphone(value, locale='en-US'): + +
[docs]@validate_str +def isphone(value, locale='en-US'): """ Return whether or not given value is valid mobile number according to given locale. Default locale is 'en-US'. If the value is valid mobile number, this function returns ``True``, otherwise ``False``. @@ -102,7 +52,7 @@

Source code for validus.phones

     ``el-GR``, ``en-AU``, ``en-GB``, ``en-HK``, ``zh-HK``, ``en-IN``, ``en-NG``, ``en-NZ``, ``en-ZA``, ``en-ZM``
     ``es-ES``, ``fi-FI``, ``fr-FR``, ``he-IL``, ``hu-HU``, ``id-ID``, ``it-IT``, ``ja-JP``, ``ms-MY``, ``nb-NO``
     ``nl-BE``, ``fr-BE``, ``nn-NO``, ``pl-PL``, ``pt-BR``, ``pt-PT``, ``ro-RO``, ``en-PK``, ``ru-RU``, ``sr-RS``
-    ``tr-TR``, ``vi-VN``, ``zh-CN``, ``zh-TW``
+    ``tr-TR``, ``vi-VN``, ``zh-CN``, ``zh-TW``, ``bn-BD``
 
     Examples::
 
@@ -115,10 +65,60 @@ 

Source code for validus.phones

     :param value: string to validate mobile number
     :param locale: locale of mobile number to validate
     """
+
+    phones = {
+        'ar-DZ': r'^(\+?213|0)(5|6|7)\d{8}$',
+        'ar-SY': r'^(!?(\+?963)|0)?9\d{8}$',
+        'ar-SA': r'^(!?(\+?966)|0)?5\d{8}$',
+        'bn-BD': r'^(\+?88)?(01[56789]\d{2}(\s|\-)?\d{6})$',
+        'en-US': r'^(\+?1)?[2-9]\d{2}[2-9](?!11)\d{6}$',
+        'cs-CZ': r'^(\+?420)? ?[1-9][0-9]{2} ?[0-9]{3} ?[0-9]{3}$',
+        'de-DE': r'^(\+?49[ \.\-])?([\(]{1}[0-9]{1,6}[\)])?([0-9 \.\-\']{3,20})((x|ext|extension)[ ]?[0-9]{1,4})?$',
+        'da-DK': r'^(\+?45)?(\d{8})$',
+        'el-GR': r'^(\+?30)?(69\d{8})$',
+        'en-AU': r'^(\+?61|0)4\d{8}$',
+        'en-GB': r'^(\+?44|0)7\d{9}$',
+        'en-HK': r'^(\+?852\-?)?[569]\d{3}\-?\d{4}$',
+        'en-IN': r'^(\+?91|0)?[789]\d{9}$',
+        'en-NG': r'^(\+?234|0)?[789]\d{9}$',
+        'en-NZ': r'^(\+?64|0)2\d{7,9}$',
+        'en-ZA': r'^(\+?27|0)\d{9}$',
+        'en-ZM': r'^(\+?26)?09[567]\d{7}$',
+        'es-ES': r'^(\+?34)?(6\d{1}|7[1234])\d{7}$',
+        'fi-FI': r'^(\+?358|0)\s?(4(0|1|2|4|5)?|50)\s?(\d\s?){4,8}\d$',
+        'fr-FR': r'^(\+?33|0)[67]\d{8}$',
+        'he-IL': r'^(\+972|0)([23489]|5[0248]|77)[1-9]\d{6}',
+        'hu-HU': r'^(\+?36)(20|30|70)\d{7}$',
+        'id-ID': r'^(\+?62|0[1-9])[\s|\d]+$',
+        'it-IT': r'^(\+?39)?\s?3\d{2} ?\d{6,7}$',
+        'ja-JP': r'^(\+?81|0)\d{1,4}[ \-]?\d{1,4}[ \-]?\d{4}$',
+        'ms-MY': r'^(\+?6?01){1}(([145]{1}(\-|\s)?\d{7,8})|([236789]{1}(\s|\-)?\d{7}))$',
+        'nb-NO': r'^(\+?47)?[49]\d{7}$',
+        'nl-BE': r'^(\+?32|0)4?\d{8}$',
+        'nn-NO': r'^(\+?47)?[49]\d{7}$',
+        'pl-PL': r'^(\+?48)? ?[5-8]\d ?\d{3} ?\d{2} ?\d{2}$',
+        'pt-BR': r'^(\+?55|0)\-?[1-9]{2}\-?[2-9]{1}\d{3,4}\-?\d{4}$',
+        'pt-PT': r'^(\+?351)?9[1236]\d{7}$',
+        'ro-RO': r'^(\+?4?0)\s?7\d{2}(\'|\s|\.|\-)?\d{3}(\s|\.|\-)?\d{3}$',
+        'en-PK': r'^((\+92)|(0092))-{0,1}\d{3}-{0,1}\d{7}$|^\d{11}$|^\d{4}-\d{7}$',
+        'ru-RU': r'^(\+?7|8)?9\d{9}$',
+        'sr-RS': r'^(\+3816|06)[- \d]{5,9}$',
+        'tr-TR': r'^(\+?90|0)?5\d{9}$',
+        'vi-VN': r'^(\+?84|0)?((1(2([0-9])|6([2-9])|88|99))|(9((?!5)[0-9])))([0-9]{7})$',
+        'zh-CN': r'^(\+?0?86\-?)?1[345789]\d{9}$',
+        'zh-TW': r'^(\+?886\-?|0)?9\d{8}$'
+    }
+
+    phones['en-CA'] = phones['en-US']
+    phones['fr-BE'] = phones['nl-BE']
+    phones['zh-HK'] = phones['en-HK']
+
     loc = phones.get(locale)
     if loc is None:
         raise ValueError('Please provide a supported locale.')
-    return bool(re.match(loc, value))
+ else: + loc_pattern = re.compile(loc) + return bool(loc_pattern.match(value))
@@ -138,9 +138,10 @@

validus

Navigation

diff --git a/docs/_modules/validus/validators.html b/docs/_modules/validus/validators.html index ae233af..f7aaac3 100644 --- a/docs/_modules/validus/validators.html +++ b/docs/_modules/validus/validators.html @@ -1,23 +1,21 @@ + - - - validus.validators — validus 0.1.0 documentation - + validus.validators — validus 0.2.0 documentation - @@ -25,8 +23,6 @@ - - @@ -34,7 +30,7 @@ - +
@@ -51,45 +47,27 @@

Source code for validus.validators

 import json
 import time
 
-patterns = {
-    'ascii': r"^[\x00-\x7F]+$",
-    'base64': r"^(?:[A-Za-z0-9+\/]{4})*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=|[A-Za-z0-9+\/]{4})$",
-    'email': r"""^(((([a-zA-Z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-zA-Z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-zA-Z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-zA-Z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-zA-Z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-zA-Z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-zA-Z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-zA-Z]|\d|-|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-zA-Z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$""",
-    'credit_card': r"^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\d{3})\d{11})$",
-    'float': r"^(?:[-+]?(?:[0-9]+))?(?:\.[0-9]*)?(?:[eE][\+\-]?(?:[0-9]+))?$",
-    'int': r"^(?:[-+]?(?:0|[1-9][0-9]*))$",
-    'iso8601': r'^([\+-]?\d{4}(?!\d{2}\b))((-?)((0[1-9]|1[0-2])(\3([12]\d|0[1-9]|3[01]))?|W([0-4]\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6])))([T\s]((([01]\d|2[0-3])((:?)[0-5]\d)?|24:?00)([\.,]\d+(?!:))?)?(\17[0-5]\d([\.,]\d+)?)?([zZ]|([\+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?)?$',
-    'iban': r'^[A-Z]{2}[0-9]{2}[A-Z0-9]{11,30}$',
-    'isin': r'^[A-Z]{2}[0-9A-Z]{9}[0-9]$',
-    'uuid3': r"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-3[0-9a-fA-F]{3}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$",
-    'uuid4': r"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$",
-    'uuid5': r"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-5[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$",
-    'uuid': r"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$",
-    'md5': r'^[a-fA-F0-9]{32}$',
-    'mac': r'^([0-9a-fA-F][0-9a-fA-F]:){5}([0-9a-fA-F][0-9a-fA-F])$',
-    'printable_ascii': r"^[\x20-\x7E]+$",
-    'multi_byte': r"[^\x00-\x7F]",
-    'full_width': r"[^\u0020-\u007E\uFF61-\uFF9F\uFFA0-\uFFDC\uFFE8-\uFFEE0-9a-zA-Z]",
-    'half_width': r"[\u0020-\u007E\uFF61-\uFF9F\uFFA0-\uFFDC\uFFE8-\uFFEE0-9a-zA-Z]",
-    'hexadecimal': r"^[0-9a-fA-F]+$",
-    'hex_color': r"^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$",
-    'rgb_color': r"^rgb\(\s*(0|[1-9]\d?|1\d\d?|2[0-4]\d|25[0-5])\s*,\s*(0|[1-9]\d?|1\d\d?|2[0-4]\d|25[0-5])\s*,\s*(0|[1-9]\d?|1\d\d?|2[0-4]\d|25[0-5])\s*\)$",
-    'data_uri': r"\s*data:([a-zA-Z]+\/[a-zA-Z0-9\-\+]+(;[a-zA-Z\-]+=[a-zA-Z0-9\-]+)?)?(;base64)?,[a-zA-Z0-9!\$&',\(\)\*\+,;=\-\._~:@\/\?%\s]*\s*$",
-    'latitude': r'^[-+]?([1-8]?\d(\.\d+)?|90(\.0+)?)$',
-    'longitude': r'^[-+]?(180(\.0+)?|((1[0-7]\d)|([1-9]?\d))(\.\d+)?)$',
-    'dns': r'^([a-zA-Z0-9_]{1}[a-zA-Z0-9_-]{0,62}){1}(\.[a-zA-Z0-9_]{1}[a-zA-Z0-9_-]{0,62})*[\._]?$',
-    'url': r'^((ftp|tcp|irc|udp|wss?|https?):\/\/)?(\S+(:\S*)?@)?((([1-9]\d?|1\d\d|2[01]\d|22[0-3])(\.(1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.([0-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(\[(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\])|(([a-zA-Z0-9]([a-zA-Z0-9-_]+)?[a-zA-Z0-9]([-\.][a-zA-Z0-9]+)*)|(((www\.)|([a-zA-Z0-9]([-\.][-\._a-zA-Z0-9]+)*))?))?(([a-zA-Z\u00a1-\uffff0-9]+-?-?)*[a-zA-Z\u00a1-\uffff0-9]+)(?:\.([a-zA-Z\u00a1-\uffff]{1,}))?))\.?(:(\d{1,5}))?((\/|\?|#)[^\s]*)?$',
-    'ssn': r'^\d{3}[- ]?\d{2}[- ]?\d{4}$',
-    'slug': r'^[-a-zA-Z0-9_]+$',
-    'semver': r'^v?(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)(-(0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(\.(0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*)?(\+[0-9a-zA-Z-]+(\.[0-9a-zA-Z-]+)*)?$',
-    'win_path': r'^[a-zA-Z]:\\(?:[^\\/:*?"<>|\r\n]+\\)*[^\\/:*?"<>|\r\n]*$',
-    'unix_path': r'^(/[^/\x00]*)+/?$'
-
-}
-
-
-@validate_str
-
[docs]def isascii(value): + +
[docs]@validate_str +def isnonempty(value): + """ + Return whether the value is not empty + + Examples:: + + >>> isnonempty('a') + True + + >>> isnonempty('') + False + + :param value: string to validate whether value is not empty + """ + return True if len(value) > 0 else False
+ + +
[docs]@validate_str +def isascii(value): """ Return whether or not given value contains ASCII chars only. Empty string is valid. If the value contains ASCII chars only, this function returns ``True``, otherwise ``False``. @@ -104,11 +82,12 @@

Source code for validus.validators

 
     :param value: string to validate ASCII chars
     """
-    return value == '' or bool(re.match(patterns['ascii'], value))
+ ascii_pattern = re.compile(r"^[\x00-\x7F]+$") + return value == '' or bool(ascii_pattern.match(value))
-@validate_str -
[docs]def isprintascii(value): +
[docs]@validate_str +def isprintascii(value): """ Return whether or not given value contains printable ASCII chars only. Empty string is valid. If the value contains printable ASCII chars only, this function returns ``True``, otherwise ``False``. @@ -123,11 +102,12 @@

Source code for validus.validators

 
     :param value: string to validate printable ASCII chars
     """
-    return value == '' or bool(re.match(patterns['printable_ascii'], value))
+ print_ascii = re.compile(r"^[\x20-\x7E]+$") + return value == '' or bool(print_ascii.match(value))
-@validate_str -
[docs]def isbase64(value): +
[docs]@validate_str +def isbase64(value): """ Return whether or not given value is base64 encoded. If the value is base64 encoded, this function returns ``True``, otherwise ``False``. @@ -142,11 +122,12 @@

Source code for validus.validators

 
     :param value: string to validate base64 encoding
     """
-    return bool(re.match(patterns['base64'], value))
+ base64 = re.compile(r"^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{4})$") + return bool(base64.match(value))
-@validate_str -
[docs]def isemail(value): +
[docs]@validate_str +def isemail(value): """ Return whether or not given value is an email. If the value is an email, this function returns ``True``, otherwise ``False``. @@ -161,11 +142,12 @@

Source code for validus.validators

 
     :param value: string to validate email
     """
-    return bool(re.match(patterns['email'], value))
+ email = re.compile(r"""^(((([a-zA-Z]|\d|[!#$%&'*+\-/=?^_`{|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-zA-Z]|\d|[!#$%&'*+\-/=?^_`{|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-zA-Z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-zA-Z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-zA-Z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-zA-Z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-zA-Z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-zA-Z]|\d|-|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-zA-Z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$""") + return bool(email.match(value))
-@validate_str -
[docs]def ishexadecimal(value): +
[docs]@validate_str +def ishexadecimal(value): """ Return whether or not given value is a hexadecimal number. If the value is a hexadecimal number, this function returns ``True``, otherwise ``False``. @@ -180,11 +162,12 @@

Source code for validus.validators

 
     :param value: string to validate hexadecimal number
     """
-    return bool(re.match(patterns['hexadecimal'], value))
+ hexa_decimal = re.compile(r"^[0-9a-fA-F]+$") + return bool(hexa_decimal.match(value))
-@validate_str -
[docs]def ishexcolor(value): +
[docs]@validate_str +def ishexcolor(value): """ Return whether or not given value is a hexadecimal color. If the value is a hexadecimal color, this function returns ``True``, otherwise ``False``. @@ -199,11 +182,12 @@

Source code for validus.validators

 
     :param value: string to validate hexadecimal color
     """
-    return bool(re.match(patterns['hex_color'], value))
+ pattern = re.compile(r"^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$") + return bool(pattern.match(value))
-@validate_str -
[docs]def isrgbcolor(value): +
[docs]@validate_str +def isrgbcolor(value): """ Return whether or not given value is a rgb color. If the value is a rgb color, this function returns ``True``, otherwise ``False``. @@ -218,11 +202,12 @@

Source code for validus.validators

 
     :param value: string to validate rgb color
     """
-    return bool(re.match(patterns['rgb_color'], value))
+ rgb = re.compile(r"^rgb\(\s*(0|[1-9]\d?|1\d\d?|2[0-4]\d|25[0-5])\s*,\s*(0|[1-9]\d?|1\d\d?|2[0-4]\d|25[0-5])\s*,\s*(0|[1-9]\d?|1\d\d?|2[0-4]\d|25[0-5])\s*\)$") + return bool(rgb.match(value))
-@validate_str -
[docs]def isint(value): +
[docs]@validate_str +def isint(value): """ Return whether or not given value is an integer. If the value is an integer, this function returns ``True``, otherwise ``False``. @@ -237,13 +222,21 @@

Source code for validus.validators

 
     :param value: string to validate integer
     """
-    return value != '' and bool(re.match(patterns['int'], value))
+ integer = re.compile(r"^(?:[-+]?(?:0|[1-9][0-9]*))$") + return value != '' and bool(integer.match(value))
-@validate_str -
[docs]def isfloat(value): +
[docs]@validate_str +def isfloat(value): """ Return whether or not given value is a float. + This does not give the same answer as:: + + isinstance(num_value,float) + + Because isfloat('1') returns true. More strict typing requirements may want + to use is_instance. + If the value is a float, this function returns ``True``, otherwise ``False``. Examples:: @@ -256,11 +249,38 @@

Source code for validus.validators

 
     :param value: string to validate float
     """
-    return value != '' and bool(re.match(patterns['float'], value))
+ floating = re.compile(r"^(?:[-+]?(?:[0-9]+))?(?:\.[0-9]*)?(?:[eE][+\-]?(?:[0-9]+))?$") + return value != '' and bool(floating.match(value))
+ + +
[docs]@validate_str +def ispositive(value): + """ + Return whether a number is positive or not + + Examples:: + + >>> ispositive('1') + True + + >>> ispositive('1.') + True + + >>> ispositive('-1.') + False + + >>> ispositive('a') + False + + :param value: string to validate number + """ + if not isfloat(value): + return False + return float(value) > 0
-@validate_str -
[docs]def isslug(value): +
[docs]@validate_str +def isslug(value): """ Validate whether or not given value is valid slug. Valid slug can contain only alphanumeric characters, hyphens and @@ -276,11 +296,12 @@

Source code for validus.validators

 
     :param value: value to validate
     """
-    return bool(re.match(patterns['slug'], value))
+ slug = re.compile(r'^[-a-zA-Z0-9_]+$') + return bool(slug.match(value))
-@validate_str -
[docs]def isuuid(value): +
[docs]@validate_str +def isuuid(value): """ Return whether or not given value is a UUID (version 3, 4 or 5). If the value is a UUID (version 3, 4 or 5), this function returns ``True``, otherwise ``False``. @@ -295,11 +316,12 @@

Source code for validus.validators

 
     :param value: string to validate UUID (version 3, 4 or 5)
     """
-    return bool(re.match(patterns['uuid'], value))
+ uuid = re.compile(r"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$") + return bool(uuid.match(value))
-@validate_str -
[docs]def isuuid3(value): +
[docs]@validate_str +def isuuid3(value): """ Return whether or not given value is a UUID version 3. If the value is a UUID version 3, this function returns ``True``, otherwise ``False``. @@ -314,11 +336,12 @@

Source code for validus.validators

 
     :param value: string to validate UUID version 3
     """
-    return bool(re.match(patterns['uuid3'], value))
+ uuid3 = re.compile(r"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-3[0-9a-fA-F]{3}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$") + return bool(uuid3.match(value))
-@validate_str -
[docs]def isuuid4(value): +
[docs]@validate_str +def isuuid4(value): """ Return whether or not given value is a UUID version 4. If the value is a UUID version 4, this function returns ``True``, otherwise ``False``. @@ -333,11 +356,12 @@

Source code for validus.validators

 
     :param value: string to validate UUID version 4
     """
-    return bool(re.match(patterns['uuid4'], value))
+ uuid4 = re.compile(r"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$") + return bool(uuid4.match(value))
-@validate_str -
[docs]def isuuid5(value): +
[docs]@validate_str +def isuuid5(value): """ Return whether or not given value is a UUID version 5. If the value is a UUID version 5, this function returns ``True``, otherwise ``False``. @@ -352,11 +376,12 @@

Source code for validus.validators

 
     :param value: string to validate UUID version 5
     """
-    return bool(re.match(patterns['uuid5'], value))
+ uuid5 = re.compile(r"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-5[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$") + return bool(uuid5.match(value))
-@validate_str -
[docs]def isfullwidth(value): +
[docs]@validate_str +def isfullwidth(value): """ Return whether or not given value contains any full-width chars. If the value contains any full-width chars, this function returns ``True``, otherwise ``False``. @@ -371,11 +396,12 @@

Source code for validus.validators

 
     :param value: string to validate full-width chars
     """
-    return bool(re.match(patterns['full_width'], value))
+ full = re.compile(r"[^\u0020-\u007E\uFF61-\uFF9F\uFFA0-\uFFDC\uFFE8-\uFFEE0-9a-zA-Z]") + return bool(full.match(value))
-@validate_str -
[docs]def ishalfwidth(value): +
[docs]@validate_str +def ishalfwidth(value): """ Return whether or not given value contains any half-width chars. If the value contains any half-width chars, this function returns ``True``, otherwise ``False``. @@ -390,11 +416,12 @@

Source code for validus.validators

 
     :param value: string to validate half-width chars
     """
-    return bool(re.match(patterns['half_width'], value))
+ half = re.compile(r"[\u0020-\u007E\uFF61-\uFF9F\uFFA0-\uFFDC\uFFE8-\uFFEE0-9a-zA-Z]") + return bool(half.match(value))
-@validate_str -
[docs]def islatitude(value): +
[docs]@validate_str +def islatitude(value): """ Return whether or not given value is valid latitude. If the value is valid latitude, this function returns ``True``, otherwise ``False``. @@ -409,11 +436,12 @@

Source code for validus.validators

 
     :param value: string to validate latitude
     """
-    return bool(re.match(patterns['latitude'], value))
+ lat = re.compile(r'^[-+]?([1-8]?\d(\.\d+)?|90(\.0+)?)$') + return bool(lat.match(value))
-@validate_str -
[docs]def islongitude(value): +
[docs]@validate_str +def islongitude(value): """ Return whether or not given value is valid longitude. If the value is valid longitude, this function returns ``True``, otherwise ``False``. @@ -428,11 +456,12 @@

Source code for validus.validators

 
     :param value: string to validate longitude
     """
-    return bool(re.match(patterns['longitude'], value))
+ long = re.compile(r'^[-+]?(180(\.0+)?|((1[0-7]\d)|([1-9]?\d))(\.\d+)?)$') + return bool(long.match(value))
-@validate_str -
[docs]def ismac(value): +
[docs]@validate_str +def ismac(value): """ Return whether or not given value is valid MAC address. If the value is valid MAC address, this function returns ``True``, otherwise ``False``. @@ -447,11 +476,12 @@

Source code for validus.validators

 
     :param value: string to validate MAC address
     """
-    return bool(re.match(patterns['mac'], value))
+ mac = re.compile(r'^([0-9a-fA-F][0-9a-fA-F]:){5}([0-9a-fA-F][0-9a-fA-F])$') + return bool(mac.match(value))
-@validate_str -
[docs]def ismd5(value): +
[docs]@validate_str +def ismd5(value): """ Return whether or not given value is MD5 encoded. If the value is MD5 encoded, this function returns ``True``, otherwise ``False``. @@ -466,11 +496,72 @@

Source code for validus.validators

 
     :param value: string to validate MD5 encoding
     """
-    return bool(re.match(patterns['md5'], value))
+ md5 = re.compile(r'^[a-fA-F0-9]{32}$') + return bool(md5.match(value))
+ + +
[docs]@validate_str +def issha1(value): + """ + Return whether or not given value is SHA1 encoded. + If the value is SHA1 encoded, this function returns ``True``, otherwise ``False``. + + Examples:: + + >>> issha1('1bc6b8a58b484bdb6aa5264dc554934e3e46c405') + True + + >>> issha1('ZKYT059dbf1c356032a7b1a1d4c2f719e5a14c1') + False + + :param value: string to validate SHA1 encoding + """ + sha1 = re.compile(r'^[a-fA-F0-9]{40}$') + return bool(sha1.match(value))
+ + +
[docs]@validate_str +def issha256(value): + """ + Return whether or not given value is SHA256 encoded. + If the value is SHA256 encoded, this function returns ``True``, otherwise ``False``. + + Examples:: + + >>> issha256('fd04c4a99b6b1f118452da33dfe9523ec164f5fecde4502b69f1ed3f24a29ff6') + True + + >>> issha256('KLO4545ID55545789Hg545235F4525576adca7676cd7dca7976676e6789dcaee') + False + + :param value: string to validate SHA256 encoding + """ + sha256 = re.compile(r'^[a-fA-F0-9]{64}$') + return bool(sha256.match(value))
+ + +
[docs]@validate_str +def issha512(value): + """ + Return whether or not given value is SHA512 encoded. + If the value is SHA512 encoded, this function returns ``True``, otherwise ``False``. + + Examples:: + + >>> issha512('0b696861da778f6bd0d899ad9a581f4b9b1eb8286eaba266d2f2e2767539055bf8eb59e8884839a268141aba1ef078ce67cf94d421bd1195a3c0e817f5f7b286') + True + + >>> issha512('KLO4545ID55545789Hg545235F45255452Hgf76DJF56HgKJfg3456356356346534534653456sghey45656jhgjfgghdfhgdfhdfhdfhdfhghhq94375dj93458w34') + False + + :param value: string to validate SHA512 encoding + """ + sha512 = re.compile(r'^[a-fA-F0-9]{128}$') + return bool(sha512.match(value))
-@validate_str -
[docs]def ismongoid(value): +
[docs]@validate_str +def ismongoid(value): """ Return whether or not given value is a valid hex-encoded representation of a MongoDB ObjectId. If the value is a MongoDB ObjectId, this function returns ``True``, otherwise ``False``. @@ -488,8 +579,8 @@

Source code for validus.validators

     return ishexadecimal(value) and len(value) == 24
-@validate_str -
[docs]def isiso8601(value): +
[docs]@validate_str +def isiso8601(value): """ Return whether or not given value is ISO 8601 date. If the value is ISO 8601 date, this function returns ``True``, otherwise ``False``. @@ -504,11 +595,12 @@

Source code for validus.validators

 
     :param value: string to validate ISO 8601 date
     """
-    return bool(re.match(patterns['iso8601'], value))
+ iso8601 = re.compile(r'^([+-]?\d{4}(?!\d{2}\b))((-?)((0[1-9]|1[0-2])(\3([12]\d|0[1-9]|3[01]))?|W([0-4]\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6])))([T\s]((([01]\d|2[0-3])((:?)[0-5]\d)?|24:?00)([.,]\d+(?!:))?)?(\17[0-5]\d([.,]\d+)?)?([zZ]|([+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?)?$') + return bool(iso8601.match(value))
-@validate_str -
[docs]def isipv4(value): +
[docs]@validate_str +def isipv4(value): """ Return whether or not given value is an IP version 4. If the value is an IP version 4, this function returns ``True``, otherwise ``False``. @@ -530,8 +622,8 @@

Source code for validus.validators

     return ip_addr.version == 4
-@validate_str -
[docs]def isipv6(value): +
[docs]@validate_str +def isipv6(value): """ Return whether or not given value is an IP version 6. If the value is an IP version 6, this function returns ``True``, otherwise ``False``. @@ -553,8 +645,8 @@

Source code for validus.validators

     return ip_addr.version == 6
-@validate_str -
[docs]def isip(value): +
[docs]@validate_str +def isip(value): """ Return whether or not given value is an IP version 4 or 6. If the value is an IP version 4 or 6, this function returns ``True``, otherwise ``False``. @@ -572,8 +664,8 @@

Source code for validus.validators

     return isipv4(value) or isipv6(value)
-@validate_str -
[docs]def isport(value): +
[docs]@validate_str +def isport(value): """ Return whether or not given value represents a valid port. If the value represents a valid port, this function returns ``True``, otherwise ``False``. @@ -598,8 +690,8 @@

Source code for validus.validators

         return False
-@validate_str -
[docs]def isdns(value): +
[docs]@validate_str +def isdns(value): """ Return whether or not given value represents a valid DNS name. If the value represents a valid DNS name, this function returns ``True``, otherwise ``False``. @@ -614,13 +706,14 @@

Source code for validus.validators

 
     :param value: string to validate DNS name
     """
+    dns = re.compile(r'^([a-zA-Z0-9_][a-zA-Z0-9_-]{0,62})(\.[a-zA-Z0-9_][a-zA-Z0-9_-]{0,62})*[._]?$')
     if value == '' or len(value.replace('.', '')) > 255:
         return False
-    return (not isip(value)) and bool(re.match(patterns['dns'], value))
+ return (not isip(value)) and bool(dns.match(value))
-@validate_str -
[docs]def isssn(value): +
[docs]@validate_str +def isssn(value): """ Return whether or not given value is a U.S. Social Security Number. If the value is a U.S. Social Security Number, this function returns ``True``, otherwise ``False``. @@ -635,13 +728,14 @@

Source code for validus.validators

 
     :param value: string to validate U.S. Social Security Number
     """
+    ssn = re.compile(r'^\d{3}[- ]?\d{2}[- ]?\d{4}$')
     if value == '' or len(value) != 11:
         return False
-    return bool(re.match(patterns['ssn'], value))
+ return bool(ssn.match(value))
-@validate_str -
[docs]def issemver(value): +
[docs]@validate_str +def issemver(value): """ Return whether or not given value is valid semantic version. If the value is valid semantic version, this function returns ``True``, otherwise ``False``. @@ -656,11 +750,12 @@

Source code for validus.validators

 
     :param value: string to validate semantic version
     """
-    return bool(re.match(patterns['semver'], value))
+ semver = re.compile(r'^v?(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)(-(0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(\.(0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*)?(\+[0-9a-zA-Z-]+(\.[0-9a-zA-Z-]+)*)?$') + return bool(semver.match(value))
-@validate_str -
[docs]def isbytelen(value, minimum, maximum): +
[docs]@validate_str +def isbytelen(value, minimum, maximum): """ Return whether or not given value's length (in bytes) falls in a range. If the value's length (in bytes) falls in a range, this function returns ``True``, otherwise ``False``. @@ -680,8 +775,8 @@

Source code for validus.validators

     return minimum <= len(value) <= maximum
-@validate_str -
[docs]def ismultibyte(value): +
[docs]@validate_str +def ismultibyte(value): """ Return whether or not given value contains one or more multibyte chars. If the value contains one or more multibyte chars, this function returns ``True``, otherwise ``False``. @@ -696,11 +791,12 @@

Source code for validus.validators

 
     :param value: string to validate one or more multibyte chars
     """
-    return bool(re.match(patterns['multi_byte'], value))
+ multi_byte = re.compile(r"[^\x00-\x7F]") + return bool(multi_byte.match(value))
-@validate_str -
[docs]def isfilepath(value): +
[docs]@validate_str +def isfilepath(value): """ Return whether or not given value is Win or Unix file path and returns it's type. If the value is Win or Unix file path, this function returns ``True, Type``, otherwise ``False, Type``. @@ -718,19 +814,21 @@

Source code for validus.validators

 
     :param value: string to validate file path
     """
-    if re.match(patterns['win_path'], value):
+    win_path = re.compile(r'^[a-zA-Z]:\\(?:[^\\/:*?"<>|\r\n]+\\)*[^\\/:*?"<>|\r\n]*$')
+    nix_path = re.compile(r'^(/[^/\x00]*)+/?$')
+    if win_path.match(value):
         # check windows path limit see:
         # http://msdn.microsoft.com/en-us/library/aa365247(VS.85).aspx#maxpath
         if len(value[3:]) > 32767:
             return False, 'Win'
         return True, 'Win'
-    elif re.match(patterns['unix_path'], value):
+    elif nix_path.match(value):
         return True, 'Unix'
     return False, 'Unknown'
-@validate_str -
[docs]def isdatauri(value): +
[docs]@validate_str +def isdatauri(value): """ Return whether or not given value is base64 encoded data URI such as an image. If the value is base64 encoded data URI, this function returns ``True``, otherwise ``False``. @@ -745,11 +843,12 @@

Source code for validus.validators

 
     :param value: string to validate base64 encoded data URI
     """
-    return bool(re.match(patterns['data_uri'], value))
+ data_uri = re.compile(r"\s*data:([a-zA-Z]+/[a-zA-Z0-9\-+]+(;[a-zA-Z\-]+=[a-zA-Z0-9\-]+)?)?(;base64)?,[a-zA-Z0-9!$&',()*+,;=\-._~:@/?%\s]*\s*$") + return bool(data_uri.match(value))
-@validate_str -
[docs]def isjson(value): +
[docs]@validate_str +def isjson(value): """ Return whether or not given value is valid JSON. If the value is valid JSON, this function returns ``True``, otherwise ``False``. @@ -771,8 +870,8 @@

Source code for validus.validators

     return True
-@validate_str -
[docs]def istime(value, fmt): +
[docs]@validate_str +def istime(value, fmt): """ Return whether or not given value is valid time according to given format. If the value is valid time, this function returns ``True``, otherwise ``False``. @@ -795,8 +894,8 @@

Source code for validus.validators

     return True
-@validate_str -
[docs]def isurl(value): +
[docs]@validate_str +def isurl(value): """ Return whether or not given value is an URL. If the value is an URL, this function returns ``True``, otherwise ``False``. @@ -811,13 +910,14 @@

Source code for validus.validators

 
     :param value: string to validate URL
     """
+    url = re.compile(r'^((ftp|tcp|irc|udp|wss?|https?)://)?(\S+(:\S*)?@)?((([1-9]\d?|1\d\d|2[01]\d|22[0-3])(\.(1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.([0-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(\[(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]+|::(ffff(:0{1,4})?:)?((25[0-5]|(2[0-4]|1?[0-9])?[0-9])\.){3}(25[0-5]|(2[0-4]|1?[0-9])?[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1?[0-9])?[0-9])\.){3}(25[0-5]|(2[0-4]|1?[0-9])?[0-9]))\])|(([a-zA-Z0-9]([a-zA-Z0-9-_]+)?[a-zA-Z0-9]([-.][a-zA-Z0-9]+)*)|(((www\.)|([a-zA-Z0-9]([-.][-._a-zA-Z0-9]+)*))?))?(([a-zA-Z\u00a1-\uffff0-9]+-?-?)*[a-zA-Z\u00a1-\uffff0-9]+)(?:\.([a-zA-Z\u00a1-\uffff]+))?))\.?(:(\d{1,5}))?((/|\?|#)[^\s]*)?$')
     if value == '' or len(value) >= 2083 or len(value) <= 3:
         return False
-    return bool(re.match(patterns['url'], value))
+ return bool(url.match(value))
-@validate_str -
[docs]def iscrcard(value): +
[docs]@validate_str +def iscrcard(value): """ Return whether or not given value is a credit card. If the value is a credit card, this function returns ``True``, otherwise ``False``. @@ -832,10 +932,10 @@

Source code for validus.validators

 
     :param value: string to validate credit card
     """
+    pattern = re.compile(r"^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\d{3})\d{11})$")
     sanitized = re.sub(r'[^0-9]+', '', value)
-    if not re.match(patterns['credit_card'], sanitized):
+    if not pattern.match(sanitized):
         return False
-
     summation = 0
     should_double = False
     for i in reversed(range(len(sanitized))):
@@ -854,8 +954,8 @@ 

Source code for validus.validators

     return False
-@validate_str -
[docs]def isisin(value): +
[docs]@validate_str +def isisin(value): """ Return whether or not given value is valid International Securities Identification Number. If the value is a valid ISIN, this function returns ``True``, otherwise ``False``. @@ -870,7 +970,8 @@

Source code for validus.validators

 
     :param value: string to validate ISIN
     """
-    if not re.match(patterns['isin'], value):
+    pattern = re.compile(r'^[A-Z]{2}[0-9A-Z]{9}[0-9]$')
+    if not pattern.match(value):
         return False
 
     checksum_str = re.sub(r'[A-Z]', lambda ch: str(int(ch.group(0), 36)), value)
@@ -891,8 +992,8 @@ 

Source code for validus.validators

     return int(value[-1]) == (10000 - summation) % 10
-@validate_str -
[docs]def isiban(value): +
[docs]@validate_str +def isiban(value): """ Return whether or not given value is a valid IBAN code. If the value is a valid IBAN, this function returns ``True``, otherwise ``False``. @@ -907,13 +1008,94 @@

Source code for validus.validators

 
     :param value: string to validate IBAN code
     """
+    pattern = re.compile(r'^[A-Z]{2}[0-9]{2}[A-Z0-9]{11,30}$')
     cleaned_value = value.replace(' ', '').replace('\t', '')
     iban = cleaned_value[4:] + cleaned_value[:4]
-    if not re.match(patterns['iban'], cleaned_value):
+    if not pattern.match(cleaned_value):
         return False
     digits = int(''.join(str(int(ch, 36)) for ch in iban))  # BASE 36: 0..9,A..Z -> 0..35
     return digits % 97 == 1
+ +
[docs]@validate_str +def isimei(value): + """ + Return whether or not given value is an imei. + If the value is an imei, this function returns ``True``, otherwise ``False``. + + Examples:: + + >>> isimei('565464561111118') + True + + >>> isimei('123456789012341') + False + + :param value: string to validate imei + """ + pattern = re.compile(r'^[0-9]{15}$') + sanitized = re.sub(r'[ -]', '', value) + if not pattern.match(sanitized): + return False + + should_double = True + total_sum = 0 + for digit in reversed(sanitized[:-1]): + digit_int = int(digit) + if should_double: + digit_int = digit_int * 2 + + if digit_int >= 10: + total_sum += (digit_int - 9) + else: + total_sum += digit_int + should_double = not should_double + if str(10 - (total_sum % 10))[-1] == sanitized[-1]: + return True + else: + return False
+ + +
[docs]@validate_str +def ismimetype(value): + """ + Checks if the provided string matches to a correct Media type format (MIME type) + If the value is a valid MIME Type, this function returns ``True``, otherwise ``False``. + + Examples:: + + >>> ismimetype('application/xhtml+xml') + True + + >>> ismimetype('application/json/text') + False + + :param value: string to validate MIME Type + """ + simple = re.compile(r'^(application|audio|font|image|message|model|multipart|text|video)/[a-zA-Z0-9.\-+]{1,100}$', re.IGNORECASE) + text = re.compile(r'^text/[a-zA-Z0-9.\-+]{1,100};\s?charset=("[a-zA-Z0-9.\-+\s]{0,70}"|[a-zA-Z0-9.\-+]{0,70})(\s?\([a-zA-Z0-9.\-+\s]{1,20}\))?$', re.IGNORECASE) + multipart = re.compile(r'^multipart/[a-zA-Z0-9.\-+]{1,100}(;\s?(boundary|charset)=("[a-zA-Z0-9.\-+\s]{0,70}"|[a-zA-Z0-9.\-+]{0,70})(\s?\([a-zA-Z0-9.\-+\s]{1,20}\))?){0,2}$', re.IGNORECASE) + return bool(simple.match(value) or text.match(value) or multipart.match(value))
+ + +
[docs]@validate_str +def isisrc(value): + """ + Checks if the provided string is valid ISRC(International Standard Recording Code) + If the value is a valid ISRC, this function returns ``True``, otherwise ``False``. + + Examples:: + + >>> isisrc('USAT29900609') + True + + >>> isisrc('USAT2990060') + False + + :param value: string to validate MIME Type + """ + isrc = re.compile(r'^[A-Z]{2}[0-9A-Z]{3}\d{2}\d{5}$') + return bool(isrc.match(value))
@@ -932,9 +1114,10 @@

validus

Navigation

diff --git a/docs/_sources/authors.txt b/docs/_sources/authors.rst.txt similarity index 100% rename from docs/_sources/authors.txt rename to docs/_sources/authors.rst.txt diff --git a/docs/_sources/contributing.txt b/docs/_sources/contributing.rst.txt similarity index 100% rename from docs/_sources/contributing.txt rename to docs/_sources/contributing.rst.txt diff --git a/docs/_sources/history.txt b/docs/_sources/history.rst.txt similarity index 100% rename from docs/_sources/history.txt rename to docs/_sources/history.rst.txt diff --git a/docs/_sources/index.txt b/docs/_sources/index.rst.txt similarity index 94% rename from docs/_sources/index.txt rename to docs/_sources/index.rst.txt index 52220ca..2f4e130 100644 --- a/docs/_sources/index.txt +++ b/docs/_sources/index.rst.txt @@ -9,6 +9,7 @@ Contents: readme installation usage + contract_usage contributing authors history diff --git a/docs/_sources/installation.txt b/docs/_sources/installation.rst.txt similarity index 100% rename from docs/_sources/installation.txt rename to docs/_sources/installation.rst.txt diff --git a/docs/_sources/readme.txt b/docs/_sources/readme.rst.txt similarity index 100% rename from docs/_sources/readme.txt rename to docs/_sources/readme.rst.txt diff --git a/docs/_sources/usage.txt b/docs/_sources/usage.rst.txt similarity index 74% rename from docs/_sources/usage.txt rename to docs/_sources/usage.rst.txt index 0e68d43..97a24ba 100644 --- a/docs/_sources/usage.txt +++ b/docs/_sources/usage.rst.txt @@ -10,7 +10,7 @@ validate and possibly some additional key-value arguments. Each function returns ``True`` when validation succeeds and ``False`` when validation fails. Basic Usage ------------ +=========== >>> import validus >>> validus.isemail('me@mine.com') @@ -18,9 +18,12 @@ Basic Usage >>> validus.isemail('@invalid.com') False +=================== +Available Functions +=================== isascii -------- +======= .. module:: validus @@ -28,15 +31,23 @@ isascii isprintascii ------------- +============ .. module:: validus .. autofunction:: isprintascii +isnonempty +========== + +.. module:: validus + +.. autofunction:: isnonempty + + isbase64 --------- +======== .. module:: validus @@ -44,7 +55,7 @@ isbase64 isemail -------- +======= .. module:: validus @@ -52,7 +63,7 @@ isemail ishexadecimal -------------- +============= .. module:: validus @@ -60,7 +71,7 @@ ishexadecimal ishexcolor ----------- +========== .. module:: validus @@ -68,7 +79,7 @@ ishexcolor isrgbcolor ----------- +========== .. module:: validus @@ -76,7 +87,7 @@ isrgbcolor isint ------ +===== .. module:: validus @@ -84,7 +95,7 @@ isint isfloat -------- +======= .. module:: validus @@ -92,7 +103,7 @@ isfloat isslug ------- +====== .. module:: validus @@ -100,7 +111,7 @@ isslug isuuid ------- +====== .. module:: validus @@ -108,7 +119,7 @@ isuuid isuuid3 -------- +======= .. module:: validus @@ -116,7 +127,7 @@ isuuid3 isuuid4 -------- +======= .. module:: validus @@ -124,7 +135,7 @@ isuuid4 isuuid5 -------- +======= .. module:: validus @@ -132,7 +143,7 @@ isuuid5 isfullwidth ------------ +=========== .. module:: validus @@ -140,7 +151,7 @@ isfullwidth ishalfwidth ------------ +=========== .. module:: validus @@ -148,7 +159,7 @@ ishalfwidth islatitude ----------- +========== .. module:: validus @@ -156,7 +167,7 @@ islatitude islongitude ------------ +=========== .. module:: validus @@ -164,7 +175,7 @@ islongitude ismac ------ +===== .. module:: validus @@ -172,7 +183,7 @@ ismac ismd5 ------ +===== .. module:: validus @@ -180,7 +191,7 @@ ismd5 ismongoid ---------- +========= .. module:: validus @@ -188,7 +199,7 @@ ismongoid isiso8601 ---------- +========= .. module:: validus @@ -196,7 +207,7 @@ isiso8601 isipv4 ------- +====== .. module:: validus @@ -204,7 +215,7 @@ isipv4 isipv6 ------- +====== .. module:: validus @@ -212,7 +223,7 @@ isipv6 isip ----- +==== .. module:: validus @@ -220,7 +231,7 @@ isip isport ------- +====== .. module:: validus @@ -228,7 +239,7 @@ isport isdns ------ +===== .. module:: validus @@ -236,7 +247,7 @@ isdns isssn ------ +===== .. module:: validus @@ -244,7 +255,7 @@ isssn issemver --------- +======== .. module:: validus @@ -252,7 +263,7 @@ issemver isbytelen ---------- +========= .. module:: validus @@ -260,7 +271,7 @@ isbytelen ismultibyte ------------ +=========== .. module:: validus @@ -268,7 +279,7 @@ ismultibyte isfilepath ----------- +========== .. module:: validus @@ -276,7 +287,7 @@ isfilepath isdatauri ---------- +========= .. module:: validus @@ -284,7 +295,7 @@ isdatauri isjson ------- +====== .. module:: validus @@ -292,7 +303,7 @@ isjson istime ------- +====== .. module:: validus @@ -300,7 +311,7 @@ istime isurl ------ +===== .. module:: validus @@ -308,7 +319,7 @@ isurl iscrcard --------- +======== .. module:: validus @@ -316,7 +327,7 @@ iscrcard isisin ------- +====== .. module:: validus @@ -324,7 +335,7 @@ isisin isiban ------- +====== .. module:: validus @@ -332,7 +343,7 @@ isiban isphone -------- +======= .. module:: validus @@ -340,7 +351,7 @@ isphone isisbn ------- +====== .. module:: validus @@ -348,7 +359,7 @@ isisbn isisbn10 --------- +======== .. module:: validus @@ -356,9 +367,65 @@ isisbn10 isisbn13 --------- +======== .. module:: validus .. autofunction:: isisbn13 + +ispositive +========== + +.. module:: validus + +.. autofunction:: ispositive + + +isimei +====== + +.. module:: validus + +.. autofunction:: isimei + + +issha1 +====== + +.. module:: validus + +.. autofunction:: issha1 + + +issha256 +======== + +.. module:: validus + +.. autofunction:: issha256 + + +issha512 +======== + +.. module:: validus + +.. autofunction:: issha512 + + +ismimetype +========== + +.. module:: validus + +.. autofunction:: ismimetype + + +isisrc +====== + +.. module:: validus + +.. autofunction:: isisrc + diff --git a/docs/_static/basic.css b/docs/_static/basic.css index 0b79414..6df76b0 100644 --- a/docs/_static/basic.css +++ b/docs/_static/basic.css @@ -4,7 +4,7 @@ * * Sphinx stylesheet -- basic theme. * - * :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS. + * :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ @@ -122,6 +122,8 @@ ul.keywordmatches li.goodmatch a { table.contentstable { width: 90%; + margin-left: auto; + margin-right: auto; } table.contentstable p.biglink { @@ -149,9 +151,14 @@ table.indextable td { vertical-align: top; } -table.indextable dl, table.indextable dd { +table.indextable ul { margin-top: 0; margin-bottom: 0; + list-style-type: none; +} + +table.indextable > tbody > tr > td > ul { + padding-left: 0em; } table.indextable tr.pcap { @@ -183,6 +190,13 @@ div.genindex-jumpbox { padding: 0.4em; } +/* -- domain module index --------------------------------------------------- */ + +table.modindextable td { + padding: 2px; + border-collapse: collapse; +} + /* -- general body styles --------------------------------------------------- */ div.body p, div.body dd, div.body li, div.body blockquote { @@ -217,10 +231,6 @@ div.body td { text-align: left; } -.field-list ul { - padding-left: 1em; -} - .first { margin-top: 0 !important; } @@ -337,10 +347,6 @@ table.docutils td, table.docutils th { border-bottom: 1px solid #aaa; } -table.field-list td, table.field-list th { - border: 0 !important; -} - table.footnote td, table.footnote th { border: 0 !important; } @@ -377,6 +383,27 @@ div.figure p.caption span.caption-number { div.figure p.caption span.caption-text { } +/* -- field list styles ----------------------------------------------------- */ + +table.field-list td, table.field-list th { + border: 0 !important; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} /* -- other body styles ----------------------------------------------------- */ @@ -427,15 +454,6 @@ dl.glossary dt { font-size: 1.1em; } -.field-list ul { - margin: 0; - padding-left: 1em; -} - -.field-list p { - margin: 0; -} - .optional { font-size: 1.3em; } @@ -592,6 +610,16 @@ span.eqno { float: right; } +span.eqno a.headerlink { + position: relative; + left: 0px; + z-index: 1; +} + +div.math:hover a.headerlink { + visibility: visible; +} + /* -- printout stylesheet --------------------------------------------------- */ @media print { diff --git a/docs/_static/comment-bright.png b/docs/_static/comment-bright.png index 551517b..15e27ed 100644 Binary files a/docs/_static/comment-bright.png and b/docs/_static/comment-bright.png differ diff --git a/docs/_static/comment-close.png b/docs/_static/comment-close.png index 09b54be..4d91bcf 100644 Binary files a/docs/_static/comment-close.png and b/docs/_static/comment-close.png differ diff --git a/docs/_static/comment.png b/docs/_static/comment.png index 92feb52..dfbc0cb 100644 Binary files a/docs/_static/comment.png and b/docs/_static/comment.png differ diff --git a/docs/_static/doctools.js b/docs/_static/doctools.js index 8163495..5654977 100644 --- a/docs/_static/doctools.js +++ b/docs/_static/doctools.js @@ -4,7 +4,7 @@ * * Sphinx JavaScript utilities for all documentation. * - * :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS. + * :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ diff --git a/docs/_static/down-pressed.png b/docs/_static/down-pressed.png index 7c30d00..5756c8c 100644 Binary files a/docs/_static/down-pressed.png and b/docs/_static/down-pressed.png differ diff --git a/docs/_static/down.png b/docs/_static/down.png index f48098a..1b3bdad 100644 Binary files a/docs/_static/down.png and b/docs/_static/down.png differ diff --git a/docs/_static/file.png b/docs/_static/file.png index 254c60b..a858a41 100644 Binary files a/docs/_static/file.png and b/docs/_static/file.png differ diff --git a/docs/_static/jquery-1.11.1.js b/docs/_static/jquery-3.1.0.js similarity index 53% rename from docs/_static/jquery-1.11.1.js rename to docs/_static/jquery-3.1.0.js index d4b67f7..f2fc274 100644 --- a/docs/_static/jquery-1.11.1.js +++ b/docs/_static/jquery-3.1.0.js @@ -1,27 +1,30 @@ +/*eslint-disable no-unused-vars*/ /*! - * jQuery JavaScript Library v1.11.1 - * http://jquery.com/ + * jQuery JavaScript Library v3.1.0 + * https://jquery.com/ * * Includes Sizzle.js - * http://sizzlejs.com/ + * https://sizzlejs.com/ * - * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors + * Copyright jQuery Foundation and other contributors * Released under the MIT license - * http://jquery.org/license + * https://jquery.org/license * - * Date: 2014-05-01T17:42Z + * Date: 2016-07-07T21:44Z */ +( function( global, factory ) { -(function( global, factory ) { + "use strict"; if ( typeof module === "object" && typeof module.exports === "object" ) { - // For CommonJS and CommonJS-like environments where a proper window is present, - // execute the factory and get jQuery - // For environments that do not inherently posses a window with a document - // (such as Node.js), expose a jQuery-making factory as module.exports - // This accentuates the need for the creation of a real window + + // For CommonJS and CommonJS-like environments where a proper `window` + // is present, execute the factory and get jQuery. + // For environments that do not have a `window` with a `document` + // (such as Node.js), expose a factory as module.exports. + // This accentuates the need for the creation of a real `window`. // e.g. var jQuery = require("jquery")(window); - // See ticket #14549 for more info + // See ticket #14549 for more info. module.exports = global.document ? factory( global, true ) : function( w ) { @@ -35,23 +38,27 @@ } // Pass this if window is not defined yet -}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) { +} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) { -// Can't do this because several apps including ASP.NET trace -// the stack via arguments.caller.callee and Firefox dies if -// you try to trace through "use strict" call chains. (#13335) -// Support: Firefox 18+ -// +// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1 +// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode +// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common +// enough that all such attempts are guarded in a try block. +"use strict"; + +var arr = []; -var deletedIds = []; +var document = window.document; -var slice = deletedIds.slice; +var getProto = Object.getPrototypeOf; -var concat = deletedIds.concat; +var slice = arr.slice; -var push = deletedIds.push; +var concat = arr.concat; -var indexOf = deletedIds.indexOf; +var push = arr.push; + +var indexOf = arr.indexOf; var class2type = {}; @@ -59,27 +66,46 @@ var toString = class2type.toString; var hasOwn = class2type.hasOwnProperty; +var fnToString = hasOwn.toString; + +var ObjectFunctionString = fnToString.call( Object ); + var support = {}; + function DOMEval( code, doc ) { + doc = doc || document; + + var script = doc.createElement( "script" ); + + script.text = code; + doc.head.appendChild( script ).parentNode.removeChild( script ); + } +/* global Symbol */ +// Defining this global in .eslintrc would create a danger of using the global +// unguarded in another place, it seems safer to define global only for this module + + + var - version = "1.11.1", + version = "3.1.0", // Define a local copy of jQuery jQuery = function( selector, context ) { + // The jQuery object is actually just the init constructor 'enhanced' // Need init if jQuery is called (just allow error to be thrown if not included) return new jQuery.fn.init( selector, context ); }, - // Support: Android<4.1, IE<9 + // Support: Android <=4.0 only // Make sure we trim BOM and NBSP rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, // Matches dashed string for camelizing rmsPrefix = /^-ms-/, - rdashAlpha = /-([\da-z])/gi, + rdashAlpha = /-([a-z])/g, // Used by jQuery.camelCase as callback to replace() fcamelCase = function( all, letter ) { @@ -87,14 +113,12 @@ var }; jQuery.fn = jQuery.prototype = { + // The current version of jQuery being used jquery: version, constructor: jQuery, - // Start with an empty selector - selector: "", - // The default length of a jQuery object is 0 length: 0, @@ -123,23 +147,20 @@ jQuery.fn = jQuery.prototype = { // Add the old object onto the stack (as a reference) ret.prevObject = this; - ret.context = this.context; // Return the newly-formed element set return ret; }, // Execute a callback for every element in the matched set. - // (You can seed the arguments with an array of args, but this is - // only used internally.) - each: function( callback, args ) { - return jQuery.each( this, callback, args ); + each: function( callback ) { + return jQuery.each( this, callback ); }, map: function( callback ) { - return this.pushStack( jQuery.map(this, function( elem, i ) { + return this.pushStack( jQuery.map( this, function( elem, i ) { return callback.call( elem, i, elem ); - })); + } ) ); }, slice: function() { @@ -157,23 +178,23 @@ jQuery.fn = jQuery.prototype = { eq: function( i ) { var len = this.length, j = +i + ( i < 0 ? len : 0 ); - return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] ); + return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); }, end: function() { - return this.prevObject || this.constructor(null); + return this.prevObject || this.constructor(); }, // For internal use only. // Behaves like an Array's method, not like a jQuery method. push: push, - sort: deletedIds.sort, - splice: deletedIds.splice + sort: arr.sort, + splice: arr.splice }; jQuery.extend = jQuery.fn.extend = function() { - var src, copyIsArray, copy, name, options, clone, - target = arguments[0] || {}, + var options, name, src, copy, copyIsArray, clone, + target = arguments[ 0 ] || {}, i = 1, length = arguments.length, deep = false; @@ -182,25 +203,27 @@ jQuery.extend = jQuery.fn.extend = function() { if ( typeof target === "boolean" ) { deep = target; - // skip the boolean and the target + // Skip the boolean and the target target = arguments[ i ] || {}; i++; } // Handle case when target is a string or something (possible in deep copy) - if ( typeof target !== "object" && !jQuery.isFunction(target) ) { + if ( typeof target !== "object" && !jQuery.isFunction( target ) ) { target = {}; } - // extend jQuery itself if only one argument is passed + // Extend jQuery itself if only one argument is passed if ( i === length ) { target = this; i--; } for ( ; i < length; i++ ) { + // Only deal with non-null/undefined values - if ( (options = arguments[ i ]) != null ) { + if ( ( options = arguments[ i ] ) != null ) { + // Extend the base object for ( name in options ) { src = target[ name ]; @@ -212,13 +235,15 @@ jQuery.extend = jQuery.fn.extend = function() { } // Recurse if we're merging plain objects or arrays - if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { + if ( deep && copy && ( jQuery.isPlainObject( copy ) || + ( copyIsArray = jQuery.isArray( copy ) ) ) ) { + if ( copyIsArray ) { copyIsArray = false; - clone = src && jQuery.isArray(src) ? src : []; + clone = src && jQuery.isArray( src ) ? src : []; } else { - clone = src && jQuery.isPlainObject(src) ? src : {}; + clone = src && jQuery.isPlainObject( src ) ? src : {}; } // Never move original objects, clone them @@ -236,7 +261,8 @@ jQuery.extend = jQuery.fn.extend = function() { return target; }; -jQuery.extend({ +jQuery.extend( { + // Unique for each copy of jQuery on the page expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), @@ -249,98 +275,81 @@ jQuery.extend({ noop: function() {}, - // See test/unit/core.js for details concerning isFunction. - // Since version 1.3, DOM methods and functions like alert - // aren't supported. They return false on IE (#2968). isFunction: function( obj ) { - return jQuery.type(obj) === "function"; + return jQuery.type( obj ) === "function"; }, - isArray: Array.isArray || function( obj ) { - return jQuery.type(obj) === "array"; - }, + isArray: Array.isArray, isWindow: function( obj ) { - /* jshint eqeqeq: false */ - return obj != null && obj == obj.window; + return obj != null && obj === obj.window; }, isNumeric: function( obj ) { - // parseFloat NaNs numeric-cast false positives (null|true|false|"") - // ...but misinterprets leading-number strings, particularly hex literals ("0x...") - // subtraction forces infinities to NaN - return !jQuery.isArray( obj ) && obj - parseFloat( obj ) >= 0; - }, - isEmptyObject: function( obj ) { - var name; - for ( name in obj ) { - return false; - } - return true; + // As of jQuery 3.0, isNumeric is limited to + // strings and numbers (primitives or objects) + // that can be coerced to finite numbers (gh-2662) + var type = jQuery.type( obj ); + return ( type === "number" || type === "string" ) && + + // parseFloat NaNs numeric-cast false positives ("") + // ...but misinterprets leading-number strings, particularly hex literals ("0x...") + // subtraction forces infinities to NaN + !isNaN( obj - parseFloat( obj ) ); }, isPlainObject: function( obj ) { - var key; + var proto, Ctor; - // Must be an Object. - // Because of IE, we also have to check the presence of the constructor property. - // Make sure that DOM nodes and window objects don't pass through, as well - if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { + // Detect obvious negatives + // Use toString instead of jQuery.type to catch host objects + if ( !obj || toString.call( obj ) !== "[object Object]" ) { return false; } - try { - // Not own constructor property must be Object - if ( obj.constructor && - !hasOwn.call(obj, "constructor") && - !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { - return false; - } - } catch ( e ) { - // IE8,9 Will throw exceptions on certain host objects #9897 - return false; - } + proto = getProto( obj ); - // Support: IE<9 - // Handle iteration over inherited properties before own properties. - if ( support.ownLast ) { - for ( key in obj ) { - return hasOwn.call( obj, key ); - } + // Objects with no prototype (e.g., `Object.create( null )`) are plain + if ( !proto ) { + return true; } - // Own properties are enumerated firstly, so to speed up, - // if last one is own, then all properties are own. - for ( key in obj ) {} + // Objects with prototype are plain iff they were constructed by a global Object function + Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor; + return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString; + }, + + isEmptyObject: function( obj ) { + + /* eslint-disable no-unused-vars */ + // See https://github.com/eslint/eslint/issues/6125 + var name; - return key === undefined || hasOwn.call( obj, key ); + for ( name in obj ) { + return false; + } + return true; }, type: function( obj ) { if ( obj == null ) { return obj + ""; } + + // Support: Android <=2.3 only (functionish RegExp) return typeof obj === "object" || typeof obj === "function" ? - class2type[ toString.call(obj) ] || "object" : + class2type[ toString.call( obj ) ] || "object" : typeof obj; }, // Evaluates a script in a global context - // Workarounds based on findings by Jim Driscoll - // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context - globalEval: function( data ) { - if ( data && jQuery.trim( data ) ) { - // We use execScript on Internet Explorer - // We use an anonymous function so that context is window - // rather than jQuery in Firefox - ( window.execScript || function( data ) { - window[ "eval" ].call( window, data ); - } )( data ); - } + globalEval: function( code ) { + DOMEval( code ); }, // Convert dashed to camelCase; used by the css and data modules + // Support: IE <=9 - 11, Edge 12 - 13 // Microsoft forgot to hump their vendor prefix (#9572) camelCase: function( string ) { return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); @@ -350,49 +359,20 @@ jQuery.extend({ return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); }, - // args is for internal usage only - each: function( obj, callback, args ) { - var value, - i = 0, - length = obj.length, - isArray = isArraylike( obj ); - - if ( args ) { - if ( isArray ) { - for ( ; i < length; i++ ) { - value = callback.apply( obj[ i ], args ); - - if ( value === false ) { - break; - } - } - } else { - for ( i in obj ) { - value = callback.apply( obj[ i ], args ); + each: function( obj, callback ) { + var length, i = 0; - if ( value === false ) { - break; - } + if ( isArrayLike( obj ) ) { + length = obj.length; + for ( ; i < length; i++ ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; } } - - // A special, fast, case for the most common use of each } else { - if ( isArray ) { - for ( ; i < length; i++ ) { - value = callback.call( obj[ i ], i, obj[ i ] ); - - if ( value === false ) { - break; - } - } - } else { - for ( i in obj ) { - value = callback.call( obj[ i ], i, obj[ i ] ); - - if ( value === false ) { - break; - } + for ( i in obj ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; } } } @@ -400,7 +380,7 @@ jQuery.extend({ return obj; }, - // Support: Android<4.1, IE<9 + // Support: Android <=4.0 only trim: function( text ) { return text == null ? "" : @@ -412,7 +392,7 @@ jQuery.extend({ var ret = results || []; if ( arr != null ) { - if ( isArraylike( Object(arr) ) ) { + if ( isArrayLike( Object( arr ) ) ) { jQuery.merge( ret, typeof arr === "string" ? [ arr ] : arr @@ -426,42 +406,18 @@ jQuery.extend({ }, inArray: function( elem, arr, i ) { - var len; - - if ( arr ) { - if ( indexOf ) { - return indexOf.call( arr, elem, i ); - } - - len = arr.length; - i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0; - - for ( ; i < len; i++ ) { - // Skip accessing in sparse arrays - if ( i in arr && arr[ i ] === elem ) { - return i; - } - } - } - - return -1; + return arr == null ? -1 : indexOf.call( arr, elem, i ); }, + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit merge: function( first, second ) { var len = +second.length, j = 0, i = first.length; - while ( j < len ) { - first[ i++ ] = second[ j++ ]; - } - - // Support: IE<9 - // Workaround casting of .length to NaN on otherwise arraylike objects (e.g., NodeLists) - if ( len !== len ) { - while ( second[j] !== undefined ) { - first[ i++ ] = second[ j++ ]; - } + for ( ; j < len; j++ ) { + first[ i++ ] = second[ j ]; } first.length = i; @@ -490,14 +446,13 @@ jQuery.extend({ // arg is for internal usage only map: function( elems, callback, arg ) { - var value, + var length, value, i = 0, - length = elems.length, - isArray = isArraylike( elems ), ret = []; // Go through the array, translating each of the items to their new values - if ( isArray ) { + if ( isArrayLike( elems ) ) { + length = elems.length; for ( ; i < length; i++ ) { value = callback( elems[ i ], i, arg ); @@ -527,7 +482,7 @@ jQuery.extend({ // Bind a function to a context, optionally partially applying any // arguments. proxy: function( fn, context ) { - var args, proxy, tmp; + var tmp, args, proxy; if ( typeof context === "string" ) { tmp = fn[ context ]; @@ -553,45 +508,49 @@ jQuery.extend({ return proxy; }, - now: function() { - return +( new Date() ); - }, + now: Date.now, // jQuery.support is not used in Core but other projects attach their // properties to it so it needs to exist. support: support -}); +} ); + +if ( typeof Symbol === "function" ) { + jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ]; +} // Populate the class2type map -jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) { +jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), +function( i, name ) { class2type[ "[object " + name + "]" ] = name.toLowerCase(); -}); +} ); + +function isArrayLike( obj ) { -function isArraylike( obj ) { - var length = obj.length, + // Support: real iOS 8.2 only (not reproducible in simulator) + // `in` check used to prevent JIT error (gh-2145) + // hasOwn isn't used here due to false negatives + // regarding Nodelist length in IE + var length = !!obj && "length" in obj && obj.length, type = jQuery.type( obj ); if ( type === "function" || jQuery.isWindow( obj ) ) { return false; } - if ( obj.nodeType === 1 && length ) { - return true; - } - return type === "array" || length === 0 || typeof length === "number" && length > 0 && ( length - 1 ) in obj; } var Sizzle = /*! - * Sizzle CSS Selector Engine v1.10.19 - * http://sizzlejs.com/ + * Sizzle CSS Selector Engine v2.3.0 + * https://sizzlejs.com/ * - * Copyright 2013 jQuery Foundation, Inc. and other contributors + * Copyright jQuery Foundation and other contributors * Released under the MIT license * http://jquery.org/license * - * Date: 2014-04-18 + * Date: 2016-01-04 */ (function( window ) { @@ -618,7 +577,7 @@ var i, contains, // Instance-specific data - expando = "sizzle" + -(new Date()), + expando = "sizzle" + 1 * new Date(), preferredDoc = window.document, dirruns = 0, done = 0, @@ -632,10 +591,6 @@ var i, return 0; }, - // General-purpose constants - strundefined = typeof undefined, - MAX_NEGATIVE = 1 << 31, - // Instance methods hasOwn = ({}).hasOwnProperty, arr = [], @@ -643,12 +598,13 @@ var i, push_native = arr.push, push = arr.push, slice = arr.slice, - // Use a stripped-down indexOf if we can't use a native one - indexOf = arr.indexOf || function( elem ) { + // Use a stripped-down indexOf as it's faster than native + // https://jsperf.com/thor-indexof-vs-for/5 + indexOf = function( list, elem ) { var i = 0, - len = this.length; + len = list.length; for ( ; i < len; i++ ) { - if ( this[i] === elem ) { + if ( list[i] === elem ) { return i; } } @@ -659,25 +615,21 @@ var i, // Regular expressions - // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace + // http://www.w3.org/TR/css3-selectors/#whitespace whitespace = "[\\x20\\t\\r\\n\\f]", - // http://www.w3.org/TR/css3-syntax/#characters - characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+", - // Loosely modeled on CSS identifier characters - // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors - // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier - identifier = characterEncoding.replace( "w", "w#" ), + // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier + identifier = "(?:\\\\.|[\\w-]|[^\0-\\xa0])+", // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors - attributes = "\\[" + whitespace + "*(" + characterEncoding + ")(?:" + whitespace + + attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + // Operator (capture 2) "*([*^$|!~]?=)" + whitespace + // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + "*\\]", - pseudos = ":(" + characterEncoding + ")(?:\\((" + + pseudos = ":(" + identifier + ")(?:\\((" + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: // 1. quoted (capture 3; capture 4 or capture 5) "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + @@ -688,6 +640,7 @@ var i, ")\\)|)", // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rwhitespace = new RegExp( whitespace + "+", "g" ), rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), @@ -699,9 +652,9 @@ var i, ridentifier = new RegExp( "^" + identifier + "$" ), matchExpr = { - "ID": new RegExp( "^#(" + characterEncoding + ")" ), - "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ), - "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ), + "ID": new RegExp( "^#(" + identifier + ")" ), + "CLASS": new RegExp( "^\\.(" + identifier + ")" ), + "TAG": new RegExp( "^(" + identifier + "|[*])" ), "ATTR": new RegExp( "^" + attributes ), "PSEUDO": new RegExp( "^" + pseudos ), "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + @@ -723,9 +676,9 @@ var i, rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, rsibling = /[+~]/, - rescape = /'|\\/g, - // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters + // CSS escapes + // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), funescape = function( _, escaped, escapedWhitespace ) { var high = "0x" + escaped - 0x10000; @@ -739,7 +692,41 @@ var i, String.fromCharCode( high + 0x10000 ) : // Supplemental Plane codepoint (surrogate pair) String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); - }; + }, + + // CSS string/identifier serialization + // https://drafts.csswg.org/cssom/#common-serializing-idioms + rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g, + fcssescape = function( ch, asCodePoint ) { + if ( asCodePoint ) { + + // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER + if ( ch === "\0" ) { + return "\uFFFD"; + } + + // Control characters and (dependent upon position) numbers get escaped as code points + return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; + } + + // Other potentially-special ASCII characters get backslash-escaped + return "\\" + ch; + }, + + // Used for iframes + // See setDocument() + // Removing the function wrapper causes a "Permission Denied" + // error in IE + unloadHandler = function() { + setDocument(); + }, + + disabledAncestor = addCombinator( + function( elem ) { + return elem.disabled === true; + }, + { dir: "parentNode", next: "legend" } + ); // Optimize for push.apply( _, NodeList ) try { @@ -771,104 +758,128 @@ try { } function Sizzle( selector, context, results, seed ) { - var match, elem, m, nodeType, - // QSA vars - i, groups, old, nid, newContext, newSelector; + var m, i, elem, nid, match, groups, newSelector, + newContext = context && context.ownerDocument, - if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { - setDocument( context ); - } + // nodeType defaults to 9, since context defaults to document + nodeType = context ? context.nodeType : 9; - context = context || document; results = results || []; - if ( !selector || typeof selector !== "string" ) { + // Return early from calls with invalid selector or context + if ( typeof selector !== "string" || !selector || + nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { + return results; } - if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) { - return []; - } + // Try to shortcut find operations (as opposed to filters) in HTML documents + if ( !seed ) { - if ( documentIsHTML && !seed ) { - - // Shortcuts - if ( (match = rquickExpr.exec( selector )) ) { - // Speed-up: Sizzle("#ID") - if ( (m = match[1]) ) { - if ( nodeType === 9 ) { - elem = context.getElementById( m ); - // Check parentNode to catch when Blackberry 4.6 returns - // nodes that are no longer in the document (jQuery #6963) - if ( elem && elem.parentNode ) { - // Handle the case where IE, Opera, and Webkit return items - // by name instead of ID - if ( elem.id === m ) { - results.push( elem ); + if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { + setDocument( context ); + } + context = context || document; + + if ( documentIsHTML ) { + + // If the selector is sufficiently simple, try using a "get*By*" DOM method + // (excepting DocumentFragment context, where the methods don't exist) + if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) { + + // ID selector + if ( (m = match[1]) ) { + + // Document context + if ( nodeType === 9 ) { + if ( (elem = context.getElementById( m )) ) { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { return results; } + + // Element context } else { - return results; - } - } else { - // Context is not a document - if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) && - contains( context, elem ) && elem.id === m ) { - results.push( elem ); - return results; + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( newContext && (elem = newContext.getElementById( m )) && + contains( context, elem ) && + elem.id === m ) { + + results.push( elem ); + return results; + } } - } - // Speed-up: Sizzle("TAG") - } else if ( match[2] ) { - push.apply( results, context.getElementsByTagName( selector ) ); - return results; + // Type selector + } else if ( match[2] ) { + push.apply( results, context.getElementsByTagName( selector ) ); + return results; - // Speed-up: Sizzle(".CLASS") - } else if ( (m = match[3]) && support.getElementsByClassName && context.getElementsByClassName ) { - push.apply( results, context.getElementsByClassName( m ) ); - return results; + // Class selector + } else if ( (m = match[3]) && support.getElementsByClassName && + context.getElementsByClassName ) { + + push.apply( results, context.getElementsByClassName( m ) ); + return results; + } } - } - // QSA path - if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { - nid = old = expando; - newContext = context; - newSelector = nodeType === 9 && selector; + // Take advantage of querySelectorAll + if ( support.qsa && + !compilerCache[ selector + " " ] && + (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { - // qSA works strangely on Element-rooted queries - // We can work around this by specifying an extra ID on the root - // and working up from there (Thanks to Andrew Dupont for the technique) - // IE 8 doesn't work on object elements - if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { - groups = tokenize( selector ); + if ( nodeType !== 1 ) { + newContext = context; + newSelector = selector; - if ( (old = context.getAttribute("id")) ) { - nid = old.replace( rescape, "\\$&" ); - } else { - context.setAttribute( "id", nid ); - } - nid = "[id='" + nid + "'] "; + // qSA looks outside Element context, which is not what we want + // Thanks to Andrew Dupont for this workaround technique + // Support: IE <=8 + // Exclude object elements + } else if ( context.nodeName.toLowerCase() !== "object" ) { - i = groups.length; - while ( i-- ) { - groups[i] = nid + toSelector( groups[i] ); + // Capture the context ID, setting it first if necessary + if ( (nid = context.getAttribute( "id" )) ) { + nid = nid.replace( rcssescape, fcssescape ); + } else { + context.setAttribute( "id", (nid = expando) ); + } + + // Prefix every selector in the list + groups = tokenize( selector ); + i = groups.length; + while ( i-- ) { + groups[i] = "#" + nid + " " + toSelector( groups[i] ); + } + newSelector = groups.join( "," ); + + // Expand context for sibling selectors + newContext = rsibling.test( selector ) && testContext( context.parentNode ) || + context; } - newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context; - newSelector = groups.join(","); - } - if ( newSelector ) { - try { - push.apply( results, - newContext.querySelectorAll( newSelector ) - ); - return results; - } catch(qsaError) { - } finally { - if ( !old ) { - context.removeAttribute("id"); + if ( newSelector ) { + try { + push.apply( results, + newContext.querySelectorAll( newSelector ) + ); + return results; + } catch ( qsaError ) { + } finally { + if ( nid === expando ) { + context.removeAttribute( "id" ); + } } } } @@ -881,7 +892,7 @@ function Sizzle( selector, context, results, seed ) { /** * Create key-value caches of limited size - * @returns {Function(string, Object)} Returns the Object data after storing it on itself with + * @returns {function(string, object)} Returns the Object data after storing it on itself with * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) * deleting the oldest entry */ @@ -910,22 +921,22 @@ function markFunction( fn ) { /** * Support testing using an element - * @param {Function} fn Passed the created div and expects a boolean result + * @param {Function} fn Passed the created element and returns a boolean result */ function assert( fn ) { - var div = document.createElement("div"); + var el = document.createElement("fieldset"); try { - return !!fn( div ); + return !!fn( el ); } catch (e) { return false; } finally { // Remove from its parent by default - if ( div.parentNode ) { - div.parentNode.removeChild( div ); + if ( el.parentNode ) { + el.parentNode.removeChild( el ); } // release memory in IE - div = null; + el = null; } } @@ -936,7 +947,7 @@ function assert( fn ) { */ function addHandle( attrs, handler ) { var arr = attrs.split("|"), - i = attrs.length; + i = arr.length; while ( i-- ) { Expr.attrHandle[ arr[i] ] = handler; @@ -952,8 +963,7 @@ function addHandle( attrs, handler ) { function siblingCheck( a, b ) { var cur = b && a, diff = cur && a.nodeType === 1 && b.nodeType === 1 && - ( ~b.sourceIndex || MAX_NEGATIVE ) - - ( ~a.sourceIndex || MAX_NEGATIVE ); + a.sourceIndex - b.sourceIndex; // Use IE sourceIndex if available on both nodes if ( diff ) { @@ -994,6 +1004,34 @@ function createButtonPseudo( type ) { }; } +/** + * Returns a function to use in pseudos for :enabled/:disabled + * @param {Boolean} disabled true for :disabled; false for :enabled + */ +function createDisabledPseudo( disabled ) { + // Known :disabled false positives: + // IE: *[disabled]:not(button, input, select, textarea, optgroup, option, menuitem, fieldset) + // not IE: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable + return function( elem ) { + + // Check form elements and option elements for explicit disabling + return "label" in elem && elem.disabled === disabled || + "form" in elem && elem.disabled === disabled || + + // Check non-disabled form elements for fieldset[disabled] ancestors + "form" in elem && elem.disabled === false && ( + // Support: IE6-11+ + // Ancestry is covered for us + elem.isDisabled === disabled || + + // Otherwise, assume any non-