logster 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (245) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/Gemfile +4 -0
  4. data/Guardfile +8 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +38 -0
  7. data/Rakefile +18 -0
  8. data/assets/javascript/app.js +377 -0
  9. data/assets/javascript/external/ember.js +44267 -0
  10. data/assets/javascript/external/ember.min.js +19 -0
  11. data/assets/javascript/external/handlebars.min.js +28 -0
  12. data/assets/javascript/external/jquery.min.js +5 -0
  13. data/assets/javascript/external/lodash.min.js +56 -0
  14. data/assets/javascript/external/moment.min.js +6 -0
  15. data/assets/javascript/templates/application.handlebars +1 -0
  16. data/assets/javascript/templates/index.handlebars +48 -0
  17. data/assets/javascript/templates/message.handlebars +7 -0
  18. data/assets/stylesheets/app.css +188 -0
  19. data/bower_components/ember/.bower.json +22 -0
  20. data/bower_components/ember/.gitignore +5 -0
  21. data/bower_components/ember/Makefile +9 -0
  22. data/bower_components/ember/README.md +12 -0
  23. data/bower_components/ember/bower.json +11 -0
  24. data/bower_components/ember/component.json +13 -0
  25. data/bower_components/ember/composer.json +27 -0
  26. data/bower_components/ember/ember-template-compiler.js +320 -0
  27. data/bower_components/ember/ember.js +44267 -0
  28. data/bower_components/ember/ember.min.js +19 -0
  29. data/bower_components/ember/ember.prod.js +42649 -0
  30. data/bower_components/ember/package.json +11 -0
  31. data/bower_components/handlebars/.bower.json +16 -0
  32. data/bower_components/handlebars/.gitignore +2 -0
  33. data/bower_components/handlebars/README.md +11 -0
  34. data/bower_components/handlebars/bower.json +6 -0
  35. data/bower_components/handlebars/component.json +9 -0
  36. data/bower_components/handlebars/composer.json +35 -0
  37. data/bower_components/handlebars/handlebars-source.gemspec +21 -0
  38. data/bower_components/handlebars/handlebars.amd.js +2719 -0
  39. data/bower_components/handlebars/handlebars.amd.min.js +28 -0
  40. data/bower_components/handlebars/handlebars.js +2746 -0
  41. data/bower_components/handlebars/handlebars.js.nuspec +17 -0
  42. data/bower_components/handlebars/handlebars.min.js +28 -0
  43. data/bower_components/handlebars/handlebars.runtime.amd.js +515 -0
  44. data/bower_components/handlebars/handlebars.runtime.amd.min.js +27 -0
  45. data/bower_components/handlebars/handlebars.runtime.js +530 -0
  46. data/bower_components/handlebars/handlebars.runtime.min.js +27 -0
  47. data/bower_components/handlebars/lib/handlebars/source.rb +11 -0
  48. data/bower_components/jquery/.bower.json +37 -0
  49. data/bower_components/jquery/MIT-LICENSE.txt +21 -0
  50. data/bower_components/jquery/bower.json +27 -0
  51. data/bower_components/jquery/dist/jquery.js +9111 -0
  52. data/bower_components/jquery/dist/jquery.min.js +5 -0
  53. data/bower_components/jquery/dist/jquery.min.map +1 -0
  54. data/bower_components/jquery/src/ajax.js +806 -0
  55. data/bower_components/jquery/src/ajax/jsonp.js +89 -0
  56. data/bower_components/jquery/src/ajax/load.js +75 -0
  57. data/bower_components/jquery/src/ajax/parseJSON.js +13 -0
  58. data/bower_components/jquery/src/ajax/parseXML.js +28 -0
  59. data/bower_components/jquery/src/ajax/script.js +64 -0
  60. data/bower_components/jquery/src/ajax/var/nonce.js +5 -0
  61. data/bower_components/jquery/src/ajax/var/rquery.js +3 -0
  62. data/bower_components/jquery/src/ajax/xhr.js +130 -0
  63. data/bower_components/jquery/src/attributes.js +11 -0
  64. data/bower_components/jquery/src/attributes/attr.js +143 -0
  65. data/bower_components/jquery/src/attributes/classes.js +158 -0
  66. data/bower_components/jquery/src/attributes/prop.js +96 -0
  67. data/bower_components/jquery/src/attributes/support.js +35 -0
  68. data/bower_components/jquery/src/attributes/val.js +153 -0
  69. data/bower_components/jquery/src/callbacks.js +205 -0
  70. data/bower_components/jquery/src/core.js +500 -0
  71. data/bower_components/jquery/src/core/access.js +60 -0
  72. data/bower_components/jquery/src/core/init.js +123 -0
  73. data/bower_components/jquery/src/core/parseHTML.js +39 -0
  74. data/bower_components/jquery/src/core/ready.js +96 -0
  75. data/bower_components/jquery/src/core/var/rsingleTag.js +4 -0
  76. data/bower_components/jquery/src/css.js +455 -0
  77. data/bower_components/jquery/src/css/addGetHookIf.js +24 -0
  78. data/bower_components/jquery/src/css/curCSS.js +57 -0
  79. data/bower_components/jquery/src/css/defaultDisplay.js +69 -0
  80. data/bower_components/jquery/src/css/hiddenVisibleSelectors.js +15 -0
  81. data/bower_components/jquery/src/css/support.js +83 -0
  82. data/bower_components/jquery/src/css/swap.js +28 -0
  83. data/bower_components/jquery/src/css/var/cssExpand.js +3 -0
  84. data/bower_components/jquery/src/css/var/getStyles.js +5 -0
  85. data/bower_components/jquery/src/css/var/isHidden.js +13 -0
  86. data/bower_components/jquery/src/css/var/rmargin.js +3 -0
  87. data/bower_components/jquery/src/css/var/rnumnonpx.js +5 -0
  88. data/bower_components/jquery/src/data.js +175 -0
  89. data/bower_components/jquery/src/data/Data.js +181 -0
  90. data/bower_components/jquery/src/data/accepts.js +20 -0
  91. data/bower_components/jquery/src/data/var/data_priv.js +5 -0
  92. data/bower_components/jquery/src/data/var/data_user.js +5 -0
  93. data/bower_components/jquery/src/deferred.js +149 -0
  94. data/bower_components/jquery/src/deprecated.js +13 -0
  95. data/bower_components/jquery/src/dimensions.js +50 -0
  96. data/bower_components/jquery/src/effects.js +642 -0
  97. data/bower_components/jquery/src/effects/Tween.js +114 -0
  98. data/bower_components/jquery/src/effects/animatedSelector.js +13 -0
  99. data/bower_components/jquery/src/event.js +859 -0
  100. data/bower_components/jquery/src/event/alias.js +39 -0
  101. data/bower_components/jquery/src/event/support.js +9 -0
  102. data/bower_components/jquery/src/exports/amd.js +18 -0
  103. data/bower_components/jquery/src/exports/global.js +32 -0
  104. data/bower_components/jquery/src/intro.js +44 -0
  105. data/bower_components/jquery/src/jquery.js +36 -0
  106. data/bower_components/jquery/src/manipulation.js +583 -0
  107. data/bower_components/jquery/src/manipulation/_evalUrl.js +18 -0
  108. data/bower_components/jquery/src/manipulation/support.js +24 -0
  109. data/bower_components/jquery/src/manipulation/var/rcheckableType.js +3 -0
  110. data/bower_components/jquery/src/offset.js +204 -0
  111. data/bower_components/jquery/src/outro.js +1 -0
  112. data/bower_components/jquery/src/queue.js +142 -0
  113. data/bower_components/jquery/src/queue/delay.js +22 -0
  114. data/bower_components/jquery/src/selector-native.js +171 -0
  115. data/bower_components/jquery/src/selector-sizzle.js +14 -0
  116. data/bower_components/jquery/src/selector.js +1 -0
  117. data/bower_components/jquery/src/serialize.js +111 -0
  118. data/bower_components/jquery/src/sizzle/dist/sizzle.js +2015 -0
  119. data/bower_components/jquery/src/sizzle/dist/sizzle.min.js +3 -0
  120. data/bower_components/jquery/src/sizzle/dist/sizzle.min.map +1 -0
  121. data/bower_components/jquery/src/traversing.js +200 -0
  122. data/bower_components/jquery/src/traversing/findFilter.js +100 -0
  123. data/bower_components/jquery/src/traversing/var/rneedsContext.js +6 -0
  124. data/bower_components/jquery/src/var/arr.js +3 -0
  125. data/bower_components/jquery/src/var/class2type.js +4 -0
  126. data/bower_components/jquery/src/var/concat.js +5 -0
  127. data/bower_components/jquery/src/var/hasOwn.js +5 -0
  128. data/bower_components/jquery/src/var/indexOf.js +5 -0
  129. data/bower_components/jquery/src/var/pnum.js +3 -0
  130. data/bower_components/jquery/src/var/push.js +5 -0
  131. data/bower_components/jquery/src/var/rnotwhite.js +3 -0
  132. data/bower_components/jquery/src/var/slice.js +5 -0
  133. data/bower_components/jquery/src/var/strundefined.js +3 -0
  134. data/bower_components/jquery/src/var/support.js +4 -0
  135. data/bower_components/jquery/src/var/toString.js +5 -0
  136. data/bower_components/jquery/src/var/trim.js +3 -0
  137. data/bower_components/jquery/src/wrap.js +78 -0
  138. data/bower_components/lodash/.bower.json +34 -0
  139. data/bower_components/lodash/LICENSE.txt +22 -0
  140. data/bower_components/lodash/bower.json +23 -0
  141. data/bower_components/lodash/dist/lodash.compat.js +7157 -0
  142. data/bower_components/lodash/dist/lodash.compat.min.js +61 -0
  143. data/bower_components/lodash/dist/lodash.js +6785 -0
  144. data/bower_components/lodash/dist/lodash.min.js +56 -0
  145. data/bower_components/lodash/dist/lodash.underscore.js +4979 -0
  146. data/bower_components/lodash/dist/lodash.underscore.min.js +39 -0
  147. data/bower_components/moment/.bower.json +31 -0
  148. data/bower_components/moment/LICENSE +22 -0
  149. data/bower_components/moment/bower.json +20 -0
  150. data/bower_components/moment/lang/ar-ma.js +56 -0
  151. data/bower_components/moment/lang/ar.js +56 -0
  152. data/bower_components/moment/lang/bg.js +86 -0
  153. data/bower_components/moment/lang/br.js +107 -0
  154. data/bower_components/moment/lang/bs.js +139 -0
  155. data/bower_components/moment/lang/ca.js +66 -0
  156. data/bower_components/moment/lang/cs.js +155 -0
  157. data/bower_components/moment/lang/cv.js +59 -0
  158. data/bower_components/moment/lang/cy.js +77 -0
  159. data/bower_components/moment/lang/da.js +56 -0
  160. data/bower_components/moment/lang/de.js +71 -0
  161. data/bower_components/moment/lang/el.js +79 -0
  162. data/bower_components/moment/lang/en-au.js +62 -0
  163. data/bower_components/moment/lang/en-ca.js +59 -0
  164. data/bower_components/moment/lang/en-gb.js +63 -0
  165. data/bower_components/moment/lang/eo.js +65 -0
  166. data/bower_components/moment/lang/es.js +75 -0
  167. data/bower_components/moment/lang/et.js +76 -0
  168. data/bower_components/moment/lang/eu.js +60 -0
  169. data/bower_components/moment/lang/fa.js +97 -0
  170. data/bower_components/moment/lang/fi.js +103 -0
  171. data/bower_components/moment/lang/fo.js +56 -0
  172. data/bower_components/moment/lang/fr-ca.js +54 -0
  173. data/bower_components/moment/lang/fr.js +58 -0
  174. data/bower_components/moment/lang/gl.js +71 -0
  175. data/bower_components/moment/lang/he.js +77 -0
  176. data/bower_components/moment/lang/hi.js +105 -0
  177. data/bower_components/moment/lang/hr.js +140 -0
  178. data/bower_components/moment/lang/hu.js +105 -0
  179. data/bower_components/moment/lang/hy-am.js +113 -0
  180. data/bower_components/moment/lang/id.js +67 -0
  181. data/bower_components/moment/lang/is.js +124 -0
  182. data/bower_components/moment/lang/it.js +59 -0
  183. data/bower_components/moment/lang/ja.js +58 -0
  184. data/bower_components/moment/lang/ka.js +108 -0
  185. data/bower_components/moment/lang/km.js +55 -0
  186. data/bower_components/moment/lang/ko.js +63 -0
  187. data/bower_components/moment/lang/lb.js +160 -0
  188. data/bower_components/moment/lang/lt.js +118 -0
  189. data/bower_components/moment/lang/lv.js +77 -0
  190. data/bower_components/moment/lang/mk.js +86 -0
  191. data/bower_components/moment/lang/ml.js +64 -0
  192. data/bower_components/moment/lang/mr.js +104 -0
  193. data/bower_components/moment/lang/ms-my.js +66 -0
  194. data/bower_components/moment/lang/nb.js +57 -0
  195. data/bower_components/moment/lang/ne.js +105 -0
  196. data/bower_components/moment/lang/nl.js +67 -0
  197. data/bower_components/moment/lang/nn.js +56 -0
  198. data/bower_components/moment/lang/pl.js +98 -0
  199. data/bower_components/moment/lang/pt-br.js +56 -0
  200. data/bower_components/moment/lang/pt.js +60 -0
  201. data/bower_components/moment/lang/ro.js +72 -0
  202. data/bower_components/moment/lang/ru.js +163 -0
  203. data/bower_components/moment/lang/sk.js +156 -0
  204. data/bower_components/moment/lang/sl.js +144 -0
  205. data/bower_components/moment/lang/sq.js +61 -0
  206. data/bower_components/moment/lang/sr-cyr.js +106 -0
  207. data/bower_components/moment/lang/sr.js +106 -0
  208. data/bower_components/moment/lang/sv.js +63 -0
  209. data/bower_components/moment/lang/ta.js +112 -0
  210. data/bower_components/moment/lang/th.js +58 -0
  211. data/bower_components/moment/lang/tl-ph.js +58 -0
  212. data/bower_components/moment/lang/tr.js +93 -0
  213. data/bower_components/moment/lang/tzm-la.js +55 -0
  214. data/bower_components/moment/lang/tzm.js +55 -0
  215. data/bower_components/moment/lang/uk.js +157 -0
  216. data/bower_components/moment/lang/uz.js +55 -0
  217. data/bower_components/moment/lang/vi.js +62 -0
  218. data/bower_components/moment/lang/zh-cn.js +108 -0
  219. data/bower_components/moment/lang/zh-tw.js +84 -0
  220. data/bower_components/moment/min/langs.js +5991 -0
  221. data/bower_components/moment/min/langs.min.js +3 -0
  222. data/bower_components/moment/min/moment-with-langs.js +7993 -0
  223. data/bower_components/moment/min/moment-with-langs.min.js +9 -0
  224. data/bower_components/moment/min/moment.min.js +6 -0
  225. data/bower_components/moment/moment.js +2489 -0
  226. data/bower_components/moment/readme.md +368 -0
  227. data/lib/logster.rb +9 -0
  228. data/lib/logster/logger.rb +31 -0
  229. data/lib/logster/message.rb +42 -0
  230. data/lib/logster/middleware/reporter.rb +13 -0
  231. data/lib/logster/middleware/viewer.rb +122 -0
  232. data/lib/logster/rails/railtie.rb +39 -0
  233. data/lib/logster/redis_store.rb +124 -0
  234. data/lib/logster/version.rb +3 -0
  235. data/logster.gemspec +30 -0
  236. data/test/logster/middleware/test_viewer.rb +34 -0
  237. data/test/logster/test_redis_store.rb +112 -0
  238. data/test/test_helper.rb +6 -0
  239. data/website/Gemfile +6 -0
  240. data/website/config.ru +2 -0
  241. data/website/data/data.json +1 -0
  242. data/website/docker_container/logster.yml +95 -0
  243. data/website/sample.rb +85 -0
  244. data/website/scripts/persist_logs.rb +13 -0
  245. metadata +375 -0
@@ -0,0 +1,14 @@
1
+ define([
2
+ "./core",
3
+ "sizzle"
4
+ ], function( jQuery, Sizzle ) {
5
+
6
+ jQuery.find = Sizzle;
7
+ jQuery.expr = Sizzle.selectors;
8
+ jQuery.expr[":"] = jQuery.expr.pseudos;
9
+ jQuery.unique = Sizzle.uniqueSort;
10
+ jQuery.text = Sizzle.getText;
11
+ jQuery.isXMLDoc = Sizzle.isXML;
12
+ jQuery.contains = Sizzle.contains;
13
+
14
+ });
@@ -0,0 +1 @@
1
+ define([ "./selector-sizzle" ]);
@@ -0,0 +1,111 @@
1
+ define([
2
+ "./core",
3
+ "./manipulation/var/rcheckableType",
4
+ "./core/init",
5
+ "./traversing", // filter
6
+ "./attributes/prop"
7
+ ], function( jQuery, rcheckableType ) {
8
+
9
+ var r20 = /%20/g,
10
+ rbracket = /\[\]$/,
11
+ rCRLF = /\r?\n/g,
12
+ rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
13
+ rsubmittable = /^(?:input|select|textarea|keygen)/i;
14
+
15
+ function buildParams( prefix, obj, traditional, add ) {
16
+ var name;
17
+
18
+ if ( jQuery.isArray( obj ) ) {
19
+ // Serialize array item.
20
+ jQuery.each( obj, function( i, v ) {
21
+ if ( traditional || rbracket.test( prefix ) ) {
22
+ // Treat each array item as a scalar.
23
+ add( prefix, v );
24
+
25
+ } else {
26
+ // Item is non-scalar (array or object), encode its numeric index.
27
+ buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add );
28
+ }
29
+ });
30
+
31
+ } else if ( !traditional && jQuery.type( obj ) === "object" ) {
32
+ // Serialize object item.
33
+ for ( name in obj ) {
34
+ buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
35
+ }
36
+
37
+ } else {
38
+ // Serialize scalar item.
39
+ add( prefix, obj );
40
+ }
41
+ }
42
+
43
+ // Serialize an array of form elements or a set of
44
+ // key/values into a query string
45
+ jQuery.param = function( a, traditional ) {
46
+ var prefix,
47
+ s = [],
48
+ add = function( key, value ) {
49
+ // If value is a function, invoke it and return its value
50
+ value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value );
51
+ s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
52
+ };
53
+
54
+ // Set traditional to true for jQuery <= 1.3.2 behavior.
55
+ if ( traditional === undefined ) {
56
+ traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
57
+ }
58
+
59
+ // If an array was passed in, assume that it is an array of form elements.
60
+ if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
61
+ // Serialize the form elements
62
+ jQuery.each( a, function() {
63
+ add( this.name, this.value );
64
+ });
65
+
66
+ } else {
67
+ // If traditional, encode the "old" way (the way 1.3.2 or older
68
+ // did it), otherwise encode params recursively.
69
+ for ( prefix in a ) {
70
+ buildParams( prefix, a[ prefix ], traditional, add );
71
+ }
72
+ }
73
+
74
+ // Return the resulting serialization
75
+ return s.join( "&" ).replace( r20, "+" );
76
+ };
77
+
78
+ jQuery.fn.extend({
79
+ serialize: function() {
80
+ return jQuery.param( this.serializeArray() );
81
+ },
82
+ serializeArray: function() {
83
+ return this.map(function() {
84
+ // Can add propHook for "elements" to filter or add form elements
85
+ var elements = jQuery.prop( this, "elements" );
86
+ return elements ? jQuery.makeArray( elements ) : this;
87
+ })
88
+ .filter(function() {
89
+ var type = this.type;
90
+
91
+ // Use .is( ":disabled" ) so that fieldset[disabled] works
92
+ return this.name && !jQuery( this ).is( ":disabled" ) &&
93
+ rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
94
+ ( this.checked || !rcheckableType.test( type ) );
95
+ })
96
+ .map(function( i, elem ) {
97
+ var val = jQuery( this ).val();
98
+
99
+ return val == null ?
100
+ null :
101
+ jQuery.isArray( val ) ?
102
+ jQuery.map( val, function( val ) {
103
+ return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
104
+ }) :
105
+ { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
106
+ }).get();
107
+ }
108
+ });
109
+
110
+ return jQuery;
111
+ });
@@ -0,0 +1,2015 @@
1
+ /*!
2
+ * Sizzle CSS Selector Engine v1.10.16
3
+ * http://sizzlejs.com/
4
+ *
5
+ * Copyright 2013 jQuery Foundation, Inc. and other contributors
6
+ * Released under the MIT license
7
+ * http://jquery.org/license
8
+ *
9
+ * Date: 2014-01-13
10
+ */
11
+ (function( window ) {
12
+
13
+ var i,
14
+ support,
15
+ Expr,
16
+ getText,
17
+ isXML,
18
+ compile,
19
+ outermostContext,
20
+ sortInput,
21
+ hasDuplicate,
22
+
23
+ // Local document vars
24
+ setDocument,
25
+ document,
26
+ docElem,
27
+ documentIsHTML,
28
+ rbuggyQSA,
29
+ rbuggyMatches,
30
+ matches,
31
+ contains,
32
+
33
+ // Instance-specific data
34
+ expando = "sizzle" + -(new Date()),
35
+ preferredDoc = window.document,
36
+ dirruns = 0,
37
+ done = 0,
38
+ classCache = createCache(),
39
+ tokenCache = createCache(),
40
+ compilerCache = createCache(),
41
+ sortOrder = function( a, b ) {
42
+ if ( a === b ) {
43
+ hasDuplicate = true;
44
+ }
45
+ return 0;
46
+ },
47
+
48
+ // General-purpose constants
49
+ strundefined = typeof undefined,
50
+ MAX_NEGATIVE = 1 << 31,
51
+
52
+ // Instance methods
53
+ hasOwn = ({}).hasOwnProperty,
54
+ arr = [],
55
+ pop = arr.pop,
56
+ push_native = arr.push,
57
+ push = arr.push,
58
+ slice = arr.slice,
59
+ // Use a stripped-down indexOf if we can't use a native one
60
+ indexOf = arr.indexOf || function( elem ) {
61
+ var i = 0,
62
+ len = this.length;
63
+ for ( ; i < len; i++ ) {
64
+ if ( this[i] === elem ) {
65
+ return i;
66
+ }
67
+ }
68
+ return -1;
69
+ },
70
+
71
+ booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
72
+
73
+ // Regular expressions
74
+
75
+ // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace
76
+ whitespace = "[\\x20\\t\\r\\n\\f]",
77
+ // http://www.w3.org/TR/css3-syntax/#characters
78
+ characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
79
+
80
+ // Loosely modeled on CSS identifier characters
81
+ // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors
82
+ // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
83
+ identifier = characterEncoding.replace( "w", "w#" ),
84
+
85
+ // Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors
86
+ attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace +
87
+ "*(?:([*^$|!~]?=)" + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]",
88
+
89
+ // Prefer arguments quoted,
90
+ // then not containing pseudos/brackets,
91
+ // then attribute selectors/non-parenthetical expressions,
92
+ // then anything else
93
+ // These preferences are here to reduce the number of selectors
94
+ // needing tokenize in the PSEUDO preFilter
95
+ pseudos = ":(" + characterEncoding + ")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|" + attributes.replace( 3, 8 ) + ")*)|.*)\\)|)",
96
+
97
+ // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
98
+ rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
99
+
100
+ rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
101
+ rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
102
+
103
+ rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ),
104
+
105
+ rpseudo = new RegExp( pseudos ),
106
+ ridentifier = new RegExp( "^" + identifier + "$" ),
107
+
108
+ matchExpr = {
109
+ "ID": new RegExp( "^#(" + characterEncoding + ")" ),
110
+ "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ),
111
+ "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ),
112
+ "ATTR": new RegExp( "^" + attributes ),
113
+ "PSEUDO": new RegExp( "^" + pseudos ),
114
+ "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
115
+ "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
116
+ "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
117
+ "bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
118
+ // For use in libraries implementing .is()
119
+ // We use this for POS matching in `select`
120
+ "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
121
+ whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
122
+ },
123
+
124
+ rinputs = /^(?:input|select|textarea|button)$/i,
125
+ rheader = /^h\d$/i,
126
+
127
+ rnative = /^[^{]+\{\s*\[native \w/,
128
+
129
+ // Easily-parseable/retrievable ID or TAG or CLASS selectors
130
+ rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
131
+
132
+ rsibling = /[+~]/,
133
+ rescape = /'|\\/g,
134
+
135
+ // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
136
+ runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
137
+ funescape = function( _, escaped, escapedWhitespace ) {
138
+ var high = "0x" + escaped - 0x10000;
139
+ // NaN means non-codepoint
140
+ // Support: Firefox
141
+ // Workaround erroneous numeric interpretation of +"0x"
142
+ return high !== high || escapedWhitespace ?
143
+ escaped :
144
+ high < 0 ?
145
+ // BMP codepoint
146
+ String.fromCharCode( high + 0x10000 ) :
147
+ // Supplemental Plane codepoint (surrogate pair)
148
+ String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
149
+ };
150
+
151
+ // Optimize for push.apply( _, NodeList )
152
+ try {
153
+ push.apply(
154
+ (arr = slice.call( preferredDoc.childNodes )),
155
+ preferredDoc.childNodes
156
+ );
157
+ // Support: Android<4.0
158
+ // Detect silently failing push.apply
159
+ arr[ preferredDoc.childNodes.length ].nodeType;
160
+ } catch ( e ) {
161
+ push = { apply: arr.length ?
162
+
163
+ // Leverage slice if possible
164
+ function( target, els ) {
165
+ push_native.apply( target, slice.call(els) );
166
+ } :
167
+
168
+ // Support: IE<9
169
+ // Otherwise append directly
170
+ function( target, els ) {
171
+ var j = target.length,
172
+ i = 0;
173
+ // Can't trust NodeList.length
174
+ while ( (target[j++] = els[i++]) ) {}
175
+ target.length = j - 1;
176
+ }
177
+ };
178
+ }
179
+
180
+ function Sizzle( selector, context, results, seed ) {
181
+ var match, elem, m, nodeType,
182
+ // QSA vars
183
+ i, groups, old, nid, newContext, newSelector;
184
+
185
+ if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
186
+ setDocument( context );
187
+ }
188
+
189
+ context = context || document;
190
+ results = results || [];
191
+
192
+ if ( !selector || typeof selector !== "string" ) {
193
+ return results;
194
+ }
195
+
196
+ if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) {
197
+ return [];
198
+ }
199
+
200
+ if ( documentIsHTML && !seed ) {
201
+
202
+ // Shortcuts
203
+ if ( (match = rquickExpr.exec( selector )) ) {
204
+ // Speed-up: Sizzle("#ID")
205
+ if ( (m = match[1]) ) {
206
+ if ( nodeType === 9 ) {
207
+ elem = context.getElementById( m );
208
+ // Check parentNode to catch when Blackberry 4.6 returns
209
+ // nodes that are no longer in the document (jQuery #6963)
210
+ if ( elem && elem.parentNode ) {
211
+ // Handle the case where IE, Opera, and Webkit return items
212
+ // by name instead of ID
213
+ if ( elem.id === m ) {
214
+ results.push( elem );
215
+ return results;
216
+ }
217
+ } else {
218
+ return results;
219
+ }
220
+ } else {
221
+ // Context is not a document
222
+ if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&
223
+ contains( context, elem ) && elem.id === m ) {
224
+ results.push( elem );
225
+ return results;
226
+ }
227
+ }
228
+
229
+ // Speed-up: Sizzle("TAG")
230
+ } else if ( match[2] ) {
231
+ push.apply( results, context.getElementsByTagName( selector ) );
232
+ return results;
233
+
234
+ // Speed-up: Sizzle(".CLASS")
235
+ } else if ( (m = match[3]) && support.getElementsByClassName && context.getElementsByClassName ) {
236
+ push.apply( results, context.getElementsByClassName( m ) );
237
+ return results;
238
+ }
239
+ }
240
+
241
+ // QSA path
242
+ if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
243
+ nid = old = expando;
244
+ newContext = context;
245
+ newSelector = nodeType === 9 && selector;
246
+
247
+ // qSA works strangely on Element-rooted queries
248
+ // We can work around this by specifying an extra ID on the root
249
+ // and working up from there (Thanks to Andrew Dupont for the technique)
250
+ // IE 8 doesn't work on object elements
251
+ if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
252
+ groups = tokenize( selector );
253
+
254
+ if ( (old = context.getAttribute("id")) ) {
255
+ nid = old.replace( rescape, "\\$&" );
256
+ } else {
257
+ context.setAttribute( "id", nid );
258
+ }
259
+ nid = "[id='" + nid + "'] ";
260
+
261
+ i = groups.length;
262
+ while ( i-- ) {
263
+ groups[i] = nid + toSelector( groups[i] );
264
+ }
265
+ newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context;
266
+ newSelector = groups.join(",");
267
+ }
268
+
269
+ if ( newSelector ) {
270
+ try {
271
+ push.apply( results,
272
+ newContext.querySelectorAll( newSelector )
273
+ );
274
+ return results;
275
+ } catch(qsaError) {
276
+ } finally {
277
+ if ( !old ) {
278
+ context.removeAttribute("id");
279
+ }
280
+ }
281
+ }
282
+ }
283
+ }
284
+
285
+ // All others
286
+ return select( selector.replace( rtrim, "$1" ), context, results, seed );
287
+ }
288
+
289
+ /**
290
+ * Create key-value caches of limited size
291
+ * @returns {Function(string, Object)} Returns the Object data after storing it on itself with
292
+ * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
293
+ * deleting the oldest entry
294
+ */
295
+ function createCache() {
296
+ var keys = [];
297
+
298
+ function cache( key, value ) {
299
+ // Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
300
+ if ( keys.push( key + " " ) > Expr.cacheLength ) {
301
+ // Only keep the most recent entries
302
+ delete cache[ keys.shift() ];
303
+ }
304
+ return (cache[ key + " " ] = value);
305
+ }
306
+ return cache;
307
+ }
308
+
309
+ /**
310
+ * Mark a function for special use by Sizzle
311
+ * @param {Function} fn The function to mark
312
+ */
313
+ function markFunction( fn ) {
314
+ fn[ expando ] = true;
315
+ return fn;
316
+ }
317
+
318
+ /**
319
+ * Support testing using an element
320
+ * @param {Function} fn Passed the created div and expects a boolean result
321
+ */
322
+ function assert( fn ) {
323
+ var div = document.createElement("div");
324
+
325
+ try {
326
+ return !!fn( div );
327
+ } catch (e) {
328
+ return false;
329
+ } finally {
330
+ // Remove from its parent by default
331
+ if ( div.parentNode ) {
332
+ div.parentNode.removeChild( div );
333
+ }
334
+ // release memory in IE
335
+ div = null;
336
+ }
337
+ }
338
+
339
+ /**
340
+ * Adds the same handler for all of the specified attrs
341
+ * @param {String} attrs Pipe-separated list of attributes
342
+ * @param {Function} handler The method that will be applied
343
+ */
344
+ function addHandle( attrs, handler ) {
345
+ var arr = attrs.split("|"),
346
+ i = attrs.length;
347
+
348
+ while ( i-- ) {
349
+ Expr.attrHandle[ arr[i] ] = handler;
350
+ }
351
+ }
352
+
353
+ /**
354
+ * Checks document order of two siblings
355
+ * @param {Element} a
356
+ * @param {Element} b
357
+ * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
358
+ */
359
+ function siblingCheck( a, b ) {
360
+ var cur = b && a,
361
+ diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
362
+ ( ~b.sourceIndex || MAX_NEGATIVE ) -
363
+ ( ~a.sourceIndex || MAX_NEGATIVE );
364
+
365
+ // Use IE sourceIndex if available on both nodes
366
+ if ( diff ) {
367
+ return diff;
368
+ }
369
+
370
+ // Check if b follows a
371
+ if ( cur ) {
372
+ while ( (cur = cur.nextSibling) ) {
373
+ if ( cur === b ) {
374
+ return -1;
375
+ }
376
+ }
377
+ }
378
+
379
+ return a ? 1 : -1;
380
+ }
381
+
382
+ /**
383
+ * Returns a function to use in pseudos for input types
384
+ * @param {String} type
385
+ */
386
+ function createInputPseudo( type ) {
387
+ return function( elem ) {
388
+ var name = elem.nodeName.toLowerCase();
389
+ return name === "input" && elem.type === type;
390
+ };
391
+ }
392
+
393
+ /**
394
+ * Returns a function to use in pseudos for buttons
395
+ * @param {String} type
396
+ */
397
+ function createButtonPseudo( type ) {
398
+ return function( elem ) {
399
+ var name = elem.nodeName.toLowerCase();
400
+ return (name === "input" || name === "button") && elem.type === type;
401
+ };
402
+ }
403
+
404
+ /**
405
+ * Returns a function to use in pseudos for positionals
406
+ * @param {Function} fn
407
+ */
408
+ function createPositionalPseudo( fn ) {
409
+ return markFunction(function( argument ) {
410
+ argument = +argument;
411
+ return markFunction(function( seed, matches ) {
412
+ var j,
413
+ matchIndexes = fn( [], seed.length, argument ),
414
+ i = matchIndexes.length;
415
+
416
+ // Match elements found at the specified indexes
417
+ while ( i-- ) {
418
+ if ( seed[ (j = matchIndexes[i]) ] ) {
419
+ seed[j] = !(matches[j] = seed[j]);
420
+ }
421
+ }
422
+ });
423
+ });
424
+ }
425
+
426
+ /**
427
+ * Checks a node for validity as a Sizzle context
428
+ * @param {Element|Object=} context
429
+ * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
430
+ */
431
+ function testContext( context ) {
432
+ return context && typeof context.getElementsByTagName !== strundefined && context;
433
+ }
434
+
435
+ // Expose support vars for convenience
436
+ support = Sizzle.support = {};
437
+
438
+ /**
439
+ * Detects XML nodes
440
+ * @param {Element|Object} elem An element or a document
441
+ * @returns {Boolean} True iff elem is a non-HTML XML node
442
+ */
443
+ isXML = Sizzle.isXML = function( elem ) {
444
+ // documentElement is verified for cases where it doesn't yet exist
445
+ // (such as loading iframes in IE - #4833)
446
+ var documentElement = elem && (elem.ownerDocument || elem).documentElement;
447
+ return documentElement ? documentElement.nodeName !== "HTML" : false;
448
+ };
449
+
450
+ /**
451
+ * Sets document-related variables once based on the current document
452
+ * @param {Element|Object} [doc] An element or document object to use to set the document
453
+ * @returns {Object} Returns the current document
454
+ */
455
+ setDocument = Sizzle.setDocument = function( node ) {
456
+ var hasCompare,
457
+ doc = node ? node.ownerDocument || node : preferredDoc,
458
+ parent = doc.defaultView;
459
+
460
+ // If no document and documentElement is available, return
461
+ if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
462
+ return document;
463
+ }
464
+
465
+ // Set our document
466
+ document = doc;
467
+ docElem = doc.documentElement;
468
+
469
+ // Support tests
470
+ documentIsHTML = !isXML( doc );
471
+
472
+ // Support: IE>8
473
+ // If iframe document is assigned to "document" variable and if iframe has been reloaded,
474
+ // IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936
475
+ // IE6-8 do not support the defaultView property so parent will be undefined
476
+ if ( parent && parent !== parent.top ) {
477
+ // IE11 does not have attachEvent, so all must suffer
478
+ if ( parent.addEventListener ) {
479
+ parent.addEventListener( "unload", function() {
480
+ setDocument();
481
+ }, false );
482
+ } else if ( parent.attachEvent ) {
483
+ parent.attachEvent( "onunload", function() {
484
+ setDocument();
485
+ });
486
+ }
487
+ }
488
+
489
+ /* Attributes
490
+ ---------------------------------------------------------------------- */
491
+
492
+ // Support: IE<8
493
+ // Verify that getAttribute really returns attributes and not properties (excepting IE8 booleans)
494
+ support.attributes = assert(function( div ) {
495
+ div.className = "i";
496
+ return !div.getAttribute("className");
497
+ });
498
+
499
+ /* getElement(s)By*
500
+ ---------------------------------------------------------------------- */
501
+
502
+ // Check if getElementsByTagName("*") returns only elements
503
+ support.getElementsByTagName = assert(function( div ) {
504
+ div.appendChild( doc.createComment("") );
505
+ return !div.getElementsByTagName("*").length;
506
+ });
507
+
508
+ // Check if getElementsByClassName can be trusted
509
+ support.getElementsByClassName = rnative.test( doc.getElementsByClassName ) && assert(function( div ) {
510
+ div.innerHTML = "<div class='a'></div><div class='a i'></div>";
511
+
512
+ // Support: Safari<4
513
+ // Catch class over-caching
514
+ div.firstChild.className = "i";
515
+ // Support: Opera<10
516
+ // Catch gEBCN failure to find non-leading classes
517
+ return div.getElementsByClassName("i").length === 2;
518
+ });
519
+
520
+ // Support: IE<10
521
+ // Check if getElementById returns elements by name
522
+ // The broken getElementById methods don't pick up programatically-set names,
523
+ // so use a roundabout getElementsByName test
524
+ support.getById = assert(function( div ) {
525
+ docElem.appendChild( div ).id = expando;
526
+ return !doc.getElementsByName || !doc.getElementsByName( expando ).length;
527
+ });
528
+
529
+ // ID find and filter
530
+ if ( support.getById ) {
531
+ Expr.find["ID"] = function( id, context ) {
532
+ if ( typeof context.getElementById !== strundefined && documentIsHTML ) {
533
+ var m = context.getElementById( id );
534
+ // Check parentNode to catch when Blackberry 4.6 returns
535
+ // nodes that are no longer in the document #6963
536
+ return m && m.parentNode ? [m] : [];
537
+ }
538
+ };
539
+ Expr.filter["ID"] = function( id ) {
540
+ var attrId = id.replace( runescape, funescape );
541
+ return function( elem ) {
542
+ return elem.getAttribute("id") === attrId;
543
+ };
544
+ };
545
+ } else {
546
+ // Support: IE6/7
547
+ // getElementById is not reliable as a find shortcut
548
+ delete Expr.find["ID"];
549
+
550
+ Expr.filter["ID"] = function( id ) {
551
+ var attrId = id.replace( runescape, funescape );
552
+ return function( elem ) {
553
+ var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id");
554
+ return node && node.value === attrId;
555
+ };
556
+ };
557
+ }
558
+
559
+ // Tag
560
+ Expr.find["TAG"] = support.getElementsByTagName ?
561
+ function( tag, context ) {
562
+ if ( typeof context.getElementsByTagName !== strundefined ) {
563
+ return context.getElementsByTagName( tag );
564
+ }
565
+ } :
566
+ function( tag, context ) {
567
+ var elem,
568
+ tmp = [],
569
+ i = 0,
570
+ results = context.getElementsByTagName( tag );
571
+
572
+ // Filter out possible comments
573
+ if ( tag === "*" ) {
574
+ while ( (elem = results[i++]) ) {
575
+ if ( elem.nodeType === 1 ) {
576
+ tmp.push( elem );
577
+ }
578
+ }
579
+
580
+ return tmp;
581
+ }
582
+ return results;
583
+ };
584
+
585
+ // Class
586
+ Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
587
+ if ( typeof context.getElementsByClassName !== strundefined && documentIsHTML ) {
588
+ return context.getElementsByClassName( className );
589
+ }
590
+ };
591
+
592
+ /* QSA/matchesSelector
593
+ ---------------------------------------------------------------------- */
594
+
595
+ // QSA and matchesSelector support
596
+
597
+ // matchesSelector(:active) reports false when true (IE9/Opera 11.5)
598
+ rbuggyMatches = [];
599
+
600
+ // qSa(:focus) reports false when true (Chrome 21)
601
+ // We allow this because of a bug in IE8/9 that throws an error
602
+ // whenever `document.activeElement` is accessed on an iframe
603
+ // So, we allow :focus to pass through QSA all the time to avoid the IE error
604
+ // See http://bugs.jquery.com/ticket/13378
605
+ rbuggyQSA = [];
606
+
607
+ if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) {
608
+ // Build QSA regex
609
+ // Regex strategy adopted from Diego Perini
610
+ assert(function( div ) {
611
+ // Select is set to empty string on purpose
612
+ // This is to test IE's treatment of not explicitly
613
+ // setting a boolean content attribute,
614
+ // since its presence should be enough
615
+ // http://bugs.jquery.com/ticket/12359
616
+ div.innerHTML = "<select t=''><option selected=''></option></select>";
617
+
618
+ // Support: IE8, Opera 10-12
619
+ // Nothing should be selected when empty strings follow ^= or $= or *=
620
+ if ( div.querySelectorAll("[t^='']").length ) {
621
+ rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
622
+ }
623
+
624
+ // Support: IE8
625
+ // Boolean attributes and "value" are not treated correctly
626
+ if ( !div.querySelectorAll("[selected]").length ) {
627
+ rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
628
+ }
629
+
630
+ // Webkit/Opera - :checked should return selected option elements
631
+ // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
632
+ // IE8 throws error here and will not see later tests
633
+ if ( !div.querySelectorAll(":checked").length ) {
634
+ rbuggyQSA.push(":checked");
635
+ }
636
+ });
637
+
638
+ assert(function( div ) {
639
+ // Support: Windows 8 Native Apps
640
+ // The type and name attributes are restricted during .innerHTML assignment
641
+ var input = doc.createElement("input");
642
+ input.setAttribute( "type", "hidden" );
643
+ div.appendChild( input ).setAttribute( "name", "D" );
644
+
645
+ // Support: IE8
646
+ // Enforce case-sensitivity of name attribute
647
+ if ( div.querySelectorAll("[name=d]").length ) {
648
+ rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
649
+ }
650
+
651
+ // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
652
+ // IE8 throws error here and will not see later tests
653
+ if ( !div.querySelectorAll(":enabled").length ) {
654
+ rbuggyQSA.push( ":enabled", ":disabled" );
655
+ }
656
+
657
+ // Opera 10-11 does not throw on post-comma invalid pseudos
658
+ div.querySelectorAll("*,:x");
659
+ rbuggyQSA.push(",.*:");
660
+ });
661
+ }
662
+
663
+ if ( (support.matchesSelector = rnative.test( (matches = docElem.webkitMatchesSelector ||
664
+ docElem.mozMatchesSelector ||
665
+ docElem.oMatchesSelector ||
666
+ docElem.msMatchesSelector) )) ) {
667
+
668
+ assert(function( div ) {
669
+ // Check to see if it's possible to do matchesSelector
670
+ // on a disconnected node (IE 9)
671
+ support.disconnectedMatch = matches.call( div, "div" );
672
+
673
+ // This should fail with an exception
674
+ // Gecko does not error, returns false instead
675
+ matches.call( div, "[s!='']:x" );
676
+ rbuggyMatches.push( "!=", pseudos );
677
+ });
678
+ }
679
+
680
+ rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
681
+ rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
682
+
683
+ /* Contains
684
+ ---------------------------------------------------------------------- */
685
+ hasCompare = rnative.test( docElem.compareDocumentPosition );
686
+
687
+ // Element contains another
688
+ // Purposefully does not implement inclusive descendent
689
+ // As in, an element does not contain itself
690
+ contains = hasCompare || rnative.test( docElem.contains ) ?
691
+ function( a, b ) {
692
+ var adown = a.nodeType === 9 ? a.documentElement : a,
693
+ bup = b && b.parentNode;
694
+ return a === bup || !!( bup && bup.nodeType === 1 && (
695
+ adown.contains ?
696
+ adown.contains( bup ) :
697
+ a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
698
+ ));
699
+ } :
700
+ function( a, b ) {
701
+ if ( b ) {
702
+ while ( (b = b.parentNode) ) {
703
+ if ( b === a ) {
704
+ return true;
705
+ }
706
+ }
707
+ }
708
+ return false;
709
+ };
710
+
711
+ /* Sorting
712
+ ---------------------------------------------------------------------- */
713
+
714
+ // Document order sorting
715
+ sortOrder = hasCompare ?
716
+ function( a, b ) {
717
+
718
+ // Flag for duplicate removal
719
+ if ( a === b ) {
720
+ hasDuplicate = true;
721
+ return 0;
722
+ }
723
+
724
+ // Sort on method existence if only one input has compareDocumentPosition
725
+ var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
726
+ if ( compare ) {
727
+ return compare;
728
+ }
729
+
730
+ // Calculate position if both inputs belong to the same document
731
+ compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
732
+ a.compareDocumentPosition( b ) :
733
+
734
+ // Otherwise we know they are disconnected
735
+ 1;
736
+
737
+ // Disconnected nodes
738
+ if ( compare & 1 ||
739
+ (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
740
+
741
+ // Choose the first element that is related to our preferred document
742
+ if ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
743
+ return -1;
744
+ }
745
+ if ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
746
+ return 1;
747
+ }
748
+
749
+ // Maintain original order
750
+ return sortInput ?
751
+ ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
752
+ 0;
753
+ }
754
+
755
+ return compare & 4 ? -1 : 1;
756
+ } :
757
+ function( a, b ) {
758
+ // Exit early if the nodes are identical
759
+ if ( a === b ) {
760
+ hasDuplicate = true;
761
+ return 0;
762
+ }
763
+
764
+ var cur,
765
+ i = 0,
766
+ aup = a.parentNode,
767
+ bup = b.parentNode,
768
+ ap = [ a ],
769
+ bp = [ b ];
770
+
771
+ // Parentless nodes are either documents or disconnected
772
+ if ( !aup || !bup ) {
773
+ return a === doc ? -1 :
774
+ b === doc ? 1 :
775
+ aup ? -1 :
776
+ bup ? 1 :
777
+ sortInput ?
778
+ ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
779
+ 0;
780
+
781
+ // If the nodes are siblings, we can do a quick check
782
+ } else if ( aup === bup ) {
783
+ return siblingCheck( a, b );
784
+ }
785
+
786
+ // Otherwise we need full lists of their ancestors for comparison
787
+ cur = a;
788
+ while ( (cur = cur.parentNode) ) {
789
+ ap.unshift( cur );
790
+ }
791
+ cur = b;
792
+ while ( (cur = cur.parentNode) ) {
793
+ bp.unshift( cur );
794
+ }
795
+
796
+ // Walk down the tree looking for a discrepancy
797
+ while ( ap[i] === bp[i] ) {
798
+ i++;
799
+ }
800
+
801
+ return i ?
802
+ // Do a sibling check if the nodes have a common ancestor
803
+ siblingCheck( ap[i], bp[i] ) :
804
+
805
+ // Otherwise nodes in our document sort first
806
+ ap[i] === preferredDoc ? -1 :
807
+ bp[i] === preferredDoc ? 1 :
808
+ 0;
809
+ };
810
+
811
+ return doc;
812
+ };
813
+
814
+ Sizzle.matches = function( expr, elements ) {
815
+ return Sizzle( expr, null, null, elements );
816
+ };
817
+
818
+ Sizzle.matchesSelector = function( elem, expr ) {
819
+ // Set document vars if needed
820
+ if ( ( elem.ownerDocument || elem ) !== document ) {
821
+ setDocument( elem );
822
+ }
823
+
824
+ // Make sure that attribute selectors are quoted
825
+ expr = expr.replace( rattributeQuotes, "='$1']" );
826
+
827
+ if ( support.matchesSelector && documentIsHTML &&
828
+ ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
829
+ ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) {
830
+
831
+ try {
832
+ var ret = matches.call( elem, expr );
833
+
834
+ // IE 9's matchesSelector returns false on disconnected nodes
835
+ if ( ret || support.disconnectedMatch ||
836
+ // As well, disconnected nodes are said to be in a document
837
+ // fragment in IE 9
838
+ elem.document && elem.document.nodeType !== 11 ) {
839
+ return ret;
840
+ }
841
+ } catch(e) {}
842
+ }
843
+
844
+ return Sizzle( expr, document, null, [elem] ).length > 0;
845
+ };
846
+
847
+ Sizzle.contains = function( context, elem ) {
848
+ // Set document vars if needed
849
+ if ( ( context.ownerDocument || context ) !== document ) {
850
+ setDocument( context );
851
+ }
852
+ return contains( context, elem );
853
+ };
854
+
855
+ Sizzle.attr = function( elem, name ) {
856
+ // Set document vars if needed
857
+ if ( ( elem.ownerDocument || elem ) !== document ) {
858
+ setDocument( elem );
859
+ }
860
+
861
+ var fn = Expr.attrHandle[ name.toLowerCase() ],
862
+ // Don't get fooled by Object.prototype properties (jQuery #13807)
863
+ val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
864
+ fn( elem, name, !documentIsHTML ) :
865
+ undefined;
866
+
867
+ return val !== undefined ?
868
+ val :
869
+ support.attributes || !documentIsHTML ?
870
+ elem.getAttribute( name ) :
871
+ (val = elem.getAttributeNode(name)) && val.specified ?
872
+ val.value :
873
+ null;
874
+ };
875
+
876
+ Sizzle.error = function( msg ) {
877
+ throw new Error( "Syntax error, unrecognized expression: " + msg );
878
+ };
879
+
880
+ /**
881
+ * Document sorting and removing duplicates
882
+ * @param {ArrayLike} results
883
+ */
884
+ Sizzle.uniqueSort = function( results ) {
885
+ var elem,
886
+ duplicates = [],
887
+ j = 0,
888
+ i = 0;
889
+
890
+ // Unless we *know* we can detect duplicates, assume their presence
891
+ hasDuplicate = !support.detectDuplicates;
892
+ sortInput = !support.sortStable && results.slice( 0 );
893
+ results.sort( sortOrder );
894
+
895
+ if ( hasDuplicate ) {
896
+ while ( (elem = results[i++]) ) {
897
+ if ( elem === results[ i ] ) {
898
+ j = duplicates.push( i );
899
+ }
900
+ }
901
+ while ( j-- ) {
902
+ results.splice( duplicates[ j ], 1 );
903
+ }
904
+ }
905
+
906
+ // Clear input after sorting to release objects
907
+ // See https://github.com/jquery/sizzle/pull/225
908
+ sortInput = null;
909
+
910
+ return results;
911
+ };
912
+
913
+ /**
914
+ * Utility function for retrieving the text value of an array of DOM nodes
915
+ * @param {Array|Element} elem
916
+ */
917
+ getText = Sizzle.getText = function( elem ) {
918
+ var node,
919
+ ret = "",
920
+ i = 0,
921
+ nodeType = elem.nodeType;
922
+
923
+ if ( !nodeType ) {
924
+ // If no nodeType, this is expected to be an array
925
+ while ( (node = elem[i++]) ) {
926
+ // Do not traverse comment nodes
927
+ ret += getText( node );
928
+ }
929
+ } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
930
+ // Use textContent for elements
931
+ // innerText usage removed for consistency of new lines (jQuery #11153)
932
+ if ( typeof elem.textContent === "string" ) {
933
+ return elem.textContent;
934
+ } else {
935
+ // Traverse its children
936
+ for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
937
+ ret += getText( elem );
938
+ }
939
+ }
940
+ } else if ( nodeType === 3 || nodeType === 4 ) {
941
+ return elem.nodeValue;
942
+ }
943
+ // Do not include comment or processing instruction nodes
944
+
945
+ return ret;
946
+ };
947
+
948
+ Expr = Sizzle.selectors = {
949
+
950
+ // Can be adjusted by the user
951
+ cacheLength: 50,
952
+
953
+ createPseudo: markFunction,
954
+
955
+ match: matchExpr,
956
+
957
+ attrHandle: {},
958
+
959
+ find: {},
960
+
961
+ relative: {
962
+ ">": { dir: "parentNode", first: true },
963
+ " ": { dir: "parentNode" },
964
+ "+": { dir: "previousSibling", first: true },
965
+ "~": { dir: "previousSibling" }
966
+ },
967
+
968
+ preFilter: {
969
+ "ATTR": function( match ) {
970
+ match[1] = match[1].replace( runescape, funescape );
971
+
972
+ // Move the given value to match[3] whether quoted or unquoted
973
+ match[3] = ( match[4] || match[5] || "" ).replace( runescape, funescape );
974
+
975
+ if ( match[2] === "~=" ) {
976
+ match[3] = " " + match[3] + " ";
977
+ }
978
+
979
+ return match.slice( 0, 4 );
980
+ },
981
+
982
+ "CHILD": function( match ) {
983
+ /* matches from matchExpr["CHILD"]
984
+ 1 type (only|nth|...)
985
+ 2 what (child|of-type)
986
+ 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
987
+ 4 xn-component of xn+y argument ([+-]?\d*n|)
988
+ 5 sign of xn-component
989
+ 6 x of xn-component
990
+ 7 sign of y-component
991
+ 8 y of y-component
992
+ */
993
+ match[1] = match[1].toLowerCase();
994
+
995
+ if ( match[1].slice( 0, 3 ) === "nth" ) {
996
+ // nth-* requires argument
997
+ if ( !match[3] ) {
998
+ Sizzle.error( match[0] );
999
+ }
1000
+
1001
+ // numeric x and y parameters for Expr.filter.CHILD
1002
+ // remember that false/true cast respectively to 0/1
1003
+ match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
1004
+ match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
1005
+
1006
+ // other types prohibit arguments
1007
+ } else if ( match[3] ) {
1008
+ Sizzle.error( match[0] );
1009
+ }
1010
+
1011
+ return match;
1012
+ },
1013
+
1014
+ "PSEUDO": function( match ) {
1015
+ var excess,
1016
+ unquoted = !match[5] && match[2];
1017
+
1018
+ if ( matchExpr["CHILD"].test( match[0] ) ) {
1019
+ return null;
1020
+ }
1021
+
1022
+ // Accept quoted arguments as-is
1023
+ if ( match[3] && match[4] !== undefined ) {
1024
+ match[2] = match[4];
1025
+
1026
+ // Strip excess characters from unquoted arguments
1027
+ } else if ( unquoted && rpseudo.test( unquoted ) &&
1028
+ // Get excess from tokenize (recursively)
1029
+ (excess = tokenize( unquoted, true )) &&
1030
+ // advance to the next closing parenthesis
1031
+ (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
1032
+
1033
+ // excess is a negative index
1034
+ match[0] = match[0].slice( 0, excess );
1035
+ match[2] = unquoted.slice( 0, excess );
1036
+ }
1037
+
1038
+ // Return only captures needed by the pseudo filter method (type and argument)
1039
+ return match.slice( 0, 3 );
1040
+ }
1041
+ },
1042
+
1043
+ filter: {
1044
+
1045
+ "TAG": function( nodeNameSelector ) {
1046
+ var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
1047
+ return nodeNameSelector === "*" ?
1048
+ function() { return true; } :
1049
+ function( elem ) {
1050
+ return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
1051
+ };
1052
+ },
1053
+
1054
+ "CLASS": function( className ) {
1055
+ var pattern = classCache[ className + " " ];
1056
+
1057
+ return pattern ||
1058
+ (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
1059
+ classCache( className, function( elem ) {
1060
+ return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute("class") || "" );
1061
+ });
1062
+ },
1063
+
1064
+ "ATTR": function( name, operator, check ) {
1065
+ return function( elem ) {
1066
+ var result = Sizzle.attr( elem, name );
1067
+
1068
+ if ( result == null ) {
1069
+ return operator === "!=";
1070
+ }
1071
+ if ( !operator ) {
1072
+ return true;
1073
+ }
1074
+
1075
+ result += "";
1076
+
1077
+ return operator === "=" ? result === check :
1078
+ operator === "!=" ? result !== check :
1079
+ operator === "^=" ? check && result.indexOf( check ) === 0 :
1080
+ operator === "*=" ? check && result.indexOf( check ) > -1 :
1081
+ operator === "$=" ? check && result.slice( -check.length ) === check :
1082
+ operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 :
1083
+ operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
1084
+ false;
1085
+ };
1086
+ },
1087
+
1088
+ "CHILD": function( type, what, argument, first, last ) {
1089
+ var simple = type.slice( 0, 3 ) !== "nth",
1090
+ forward = type.slice( -4 ) !== "last",
1091
+ ofType = what === "of-type";
1092
+
1093
+ return first === 1 && last === 0 ?
1094
+
1095
+ // Shortcut for :nth-*(n)
1096
+ function( elem ) {
1097
+ return !!elem.parentNode;
1098
+ } :
1099
+
1100
+ function( elem, context, xml ) {
1101
+ var cache, outerCache, node, diff, nodeIndex, start,
1102
+ dir = simple !== forward ? "nextSibling" : "previousSibling",
1103
+ parent = elem.parentNode,
1104
+ name = ofType && elem.nodeName.toLowerCase(),
1105
+ useCache = !xml && !ofType;
1106
+
1107
+ if ( parent ) {
1108
+
1109
+ // :(first|last|only)-(child|of-type)
1110
+ if ( simple ) {
1111
+ while ( dir ) {
1112
+ node = elem;
1113
+ while ( (node = node[ dir ]) ) {
1114
+ if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) {
1115
+ return false;
1116
+ }
1117
+ }
1118
+ // Reverse direction for :only-* (if we haven't yet done so)
1119
+ start = dir = type === "only" && !start && "nextSibling";
1120
+ }
1121
+ return true;
1122
+ }
1123
+
1124
+ start = [ forward ? parent.firstChild : parent.lastChild ];
1125
+
1126
+ // non-xml :nth-child(...) stores cache data on `parent`
1127
+ if ( forward && useCache ) {
1128
+ // Seek `elem` from a previously-cached index
1129
+ outerCache = parent[ expando ] || (parent[ expando ] = {});
1130
+ cache = outerCache[ type ] || [];
1131
+ nodeIndex = cache[0] === dirruns && cache[1];
1132
+ diff = cache[0] === dirruns && cache[2];
1133
+ node = nodeIndex && parent.childNodes[ nodeIndex ];
1134
+
1135
+ while ( (node = ++nodeIndex && node && node[ dir ] ||
1136
+
1137
+ // Fallback to seeking `elem` from the start
1138
+ (diff = nodeIndex = 0) || start.pop()) ) {
1139
+
1140
+ // When found, cache indexes on `parent` and break
1141
+ if ( node.nodeType === 1 && ++diff && node === elem ) {
1142
+ outerCache[ type ] = [ dirruns, nodeIndex, diff ];
1143
+ break;
1144
+ }
1145
+ }
1146
+
1147
+ // Use previously-cached element index if available
1148
+ } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) {
1149
+ diff = cache[1];
1150
+
1151
+ // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...)
1152
+ } else {
1153
+ // Use the same loop as above to seek `elem` from the start
1154
+ while ( (node = ++nodeIndex && node && node[ dir ] ||
1155
+ (diff = nodeIndex = 0) || start.pop()) ) {
1156
+
1157
+ if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) {
1158
+ // Cache the index of each encountered element
1159
+ if ( useCache ) {
1160
+ (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ];
1161
+ }
1162
+
1163
+ if ( node === elem ) {
1164
+ break;
1165
+ }
1166
+ }
1167
+ }
1168
+ }
1169
+
1170
+ // Incorporate the offset, then check against cycle size
1171
+ diff -= last;
1172
+ return diff === first || ( diff % first === 0 && diff / first >= 0 );
1173
+ }
1174
+ };
1175
+ },
1176
+
1177
+ "PSEUDO": function( pseudo, argument ) {
1178
+ // pseudo-class names are case-insensitive
1179
+ // http://www.w3.org/TR/selectors/#pseudo-classes
1180
+ // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
1181
+ // Remember that setFilters inherits from pseudos
1182
+ var args,
1183
+ fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
1184
+ Sizzle.error( "unsupported pseudo: " + pseudo );
1185
+
1186
+ // The user may use createPseudo to indicate that
1187
+ // arguments are needed to create the filter function
1188
+ // just as Sizzle does
1189
+ if ( fn[ expando ] ) {
1190
+ return fn( argument );
1191
+ }
1192
+
1193
+ // But maintain support for old signatures
1194
+ if ( fn.length > 1 ) {
1195
+ args = [ pseudo, pseudo, "", argument ];
1196
+ return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
1197
+ markFunction(function( seed, matches ) {
1198
+ var idx,
1199
+ matched = fn( seed, argument ),
1200
+ i = matched.length;
1201
+ while ( i-- ) {
1202
+ idx = indexOf.call( seed, matched[i] );
1203
+ seed[ idx ] = !( matches[ idx ] = matched[i] );
1204
+ }
1205
+ }) :
1206
+ function( elem ) {
1207
+ return fn( elem, 0, args );
1208
+ };
1209
+ }
1210
+
1211
+ return fn;
1212
+ }
1213
+ },
1214
+
1215
+ pseudos: {
1216
+ // Potentially complex pseudos
1217
+ "not": markFunction(function( selector ) {
1218
+ // Trim the selector passed to compile
1219
+ // to avoid treating leading and trailing
1220
+ // spaces as combinators
1221
+ var input = [],
1222
+ results = [],
1223
+ matcher = compile( selector.replace( rtrim, "$1" ) );
1224
+
1225
+ return matcher[ expando ] ?
1226
+ markFunction(function( seed, matches, context, xml ) {
1227
+ var elem,
1228
+ unmatched = matcher( seed, null, xml, [] ),
1229
+ i = seed.length;
1230
+
1231
+ // Match elements unmatched by `matcher`
1232
+ while ( i-- ) {
1233
+ if ( (elem = unmatched[i]) ) {
1234
+ seed[i] = !(matches[i] = elem);
1235
+ }
1236
+ }
1237
+ }) :
1238
+ function( elem, context, xml ) {
1239
+ input[0] = elem;
1240
+ matcher( input, null, xml, results );
1241
+ return !results.pop();
1242
+ };
1243
+ }),
1244
+
1245
+ "has": markFunction(function( selector ) {
1246
+ return function( elem ) {
1247
+ return Sizzle( selector, elem ).length > 0;
1248
+ };
1249
+ }),
1250
+
1251
+ "contains": markFunction(function( text ) {
1252
+ return function( elem ) {
1253
+ return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
1254
+ };
1255
+ }),
1256
+
1257
+ // "Whether an element is represented by a :lang() selector
1258
+ // is based solely on the element's language value
1259
+ // being equal to the identifier C,
1260
+ // or beginning with the identifier C immediately followed by "-".
1261
+ // The matching of C against the element's language value is performed case-insensitively.
1262
+ // The identifier C does not have to be a valid language name."
1263
+ // http://www.w3.org/TR/selectors/#lang-pseudo
1264
+ "lang": markFunction( function( lang ) {
1265
+ // lang value must be a valid identifier
1266
+ if ( !ridentifier.test(lang || "") ) {
1267
+ Sizzle.error( "unsupported lang: " + lang );
1268
+ }
1269
+ lang = lang.replace( runescape, funescape ).toLowerCase();
1270
+ return function( elem ) {
1271
+ var elemLang;
1272
+ do {
1273
+ if ( (elemLang = documentIsHTML ?
1274
+ elem.lang :
1275
+ elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
1276
+
1277
+ elemLang = elemLang.toLowerCase();
1278
+ return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
1279
+ }
1280
+ } while ( (elem = elem.parentNode) && elem.nodeType === 1 );
1281
+ return false;
1282
+ };
1283
+ }),
1284
+
1285
+ // Miscellaneous
1286
+ "target": function( elem ) {
1287
+ var hash = window.location && window.location.hash;
1288
+ return hash && hash.slice( 1 ) === elem.id;
1289
+ },
1290
+
1291
+ "root": function( elem ) {
1292
+ return elem === docElem;
1293
+ },
1294
+
1295
+ "focus": function( elem ) {
1296
+ return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
1297
+ },
1298
+
1299
+ // Boolean properties
1300
+ "enabled": function( elem ) {
1301
+ return elem.disabled === false;
1302
+ },
1303
+
1304
+ "disabled": function( elem ) {
1305
+ return elem.disabled === true;
1306
+ },
1307
+
1308
+ "checked": function( elem ) {
1309
+ // In CSS3, :checked should return both checked and selected elements
1310
+ // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
1311
+ var nodeName = elem.nodeName.toLowerCase();
1312
+ return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
1313
+ },
1314
+
1315
+ "selected": function( elem ) {
1316
+ // Accessing this property makes selected-by-default
1317
+ // options in Safari work properly
1318
+ if ( elem.parentNode ) {
1319
+ elem.parentNode.selectedIndex;
1320
+ }
1321
+
1322
+ return elem.selected === true;
1323
+ },
1324
+
1325
+ // Contents
1326
+ "empty": function( elem ) {
1327
+ // http://www.w3.org/TR/selectors/#empty-pseudo
1328
+ // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
1329
+ // but not by others (comment: 8; processing instruction: 7; etc.)
1330
+ // nodeType < 6 works because attributes (2) do not appear as children
1331
+ for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
1332
+ if ( elem.nodeType < 6 ) {
1333
+ return false;
1334
+ }
1335
+ }
1336
+ return true;
1337
+ },
1338
+
1339
+ "parent": function( elem ) {
1340
+ return !Expr.pseudos["empty"]( elem );
1341
+ },
1342
+
1343
+ // Element/input types
1344
+ "header": function( elem ) {
1345
+ return rheader.test( elem.nodeName );
1346
+ },
1347
+
1348
+ "input": function( elem ) {
1349
+ return rinputs.test( elem.nodeName );
1350
+ },
1351
+
1352
+ "button": function( elem ) {
1353
+ var name = elem.nodeName.toLowerCase();
1354
+ return name === "input" && elem.type === "button" || name === "button";
1355
+ },
1356
+
1357
+ "text": function( elem ) {
1358
+ var attr;
1359
+ return elem.nodeName.toLowerCase() === "input" &&
1360
+ elem.type === "text" &&
1361
+
1362
+ // Support: IE<8
1363
+ // New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
1364
+ ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" );
1365
+ },
1366
+
1367
+ // Position-in-collection
1368
+ "first": createPositionalPseudo(function() {
1369
+ return [ 0 ];
1370
+ }),
1371
+
1372
+ "last": createPositionalPseudo(function( matchIndexes, length ) {
1373
+ return [ length - 1 ];
1374
+ }),
1375
+
1376
+ "eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
1377
+ return [ argument < 0 ? argument + length : argument ];
1378
+ }),
1379
+
1380
+ "even": createPositionalPseudo(function( matchIndexes, length ) {
1381
+ var i = 0;
1382
+ for ( ; i < length; i += 2 ) {
1383
+ matchIndexes.push( i );
1384
+ }
1385
+ return matchIndexes;
1386
+ }),
1387
+
1388
+ "odd": createPositionalPseudo(function( matchIndexes, length ) {
1389
+ var i = 1;
1390
+ for ( ; i < length; i += 2 ) {
1391
+ matchIndexes.push( i );
1392
+ }
1393
+ return matchIndexes;
1394
+ }),
1395
+
1396
+ "lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
1397
+ var i = argument < 0 ? argument + length : argument;
1398
+ for ( ; --i >= 0; ) {
1399
+ matchIndexes.push( i );
1400
+ }
1401
+ return matchIndexes;
1402
+ }),
1403
+
1404
+ "gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
1405
+ var i = argument < 0 ? argument + length : argument;
1406
+ for ( ; ++i < length; ) {
1407
+ matchIndexes.push( i );
1408
+ }
1409
+ return matchIndexes;
1410
+ })
1411
+ }
1412
+ };
1413
+
1414
+ Expr.pseudos["nth"] = Expr.pseudos["eq"];
1415
+
1416
+ // Add button/input type pseudos
1417
+ for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
1418
+ Expr.pseudos[ i ] = createInputPseudo( i );
1419
+ }
1420
+ for ( i in { submit: true, reset: true } ) {
1421
+ Expr.pseudos[ i ] = createButtonPseudo( i );
1422
+ }
1423
+
1424
+ // Easy API for creating new setFilters
1425
+ function setFilters() {}
1426
+ setFilters.prototype = Expr.filters = Expr.pseudos;
1427
+ Expr.setFilters = new setFilters();
1428
+
1429
+ function tokenize( selector, parseOnly ) {
1430
+ var matched, match, tokens, type,
1431
+ soFar, groups, preFilters,
1432
+ cached = tokenCache[ selector + " " ];
1433
+
1434
+ if ( cached ) {
1435
+ return parseOnly ? 0 : cached.slice( 0 );
1436
+ }
1437
+
1438
+ soFar = selector;
1439
+ groups = [];
1440
+ preFilters = Expr.preFilter;
1441
+
1442
+ while ( soFar ) {
1443
+
1444
+ // Comma and first run
1445
+ if ( !matched || (match = rcomma.exec( soFar )) ) {
1446
+ if ( match ) {
1447
+ // Don't consume trailing commas as valid
1448
+ soFar = soFar.slice( match[0].length ) || soFar;
1449
+ }
1450
+ groups.push( (tokens = []) );
1451
+ }
1452
+
1453
+ matched = false;
1454
+
1455
+ // Combinators
1456
+ if ( (match = rcombinators.exec( soFar )) ) {
1457
+ matched = match.shift();
1458
+ tokens.push({
1459
+ value: matched,
1460
+ // Cast descendant combinators to space
1461
+ type: match[0].replace( rtrim, " " )
1462
+ });
1463
+ soFar = soFar.slice( matched.length );
1464
+ }
1465
+
1466
+ // Filters
1467
+ for ( type in Expr.filter ) {
1468
+ if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
1469
+ (match = preFilters[ type ]( match ))) ) {
1470
+ matched = match.shift();
1471
+ tokens.push({
1472
+ value: matched,
1473
+ type: type,
1474
+ matches: match
1475
+ });
1476
+ soFar = soFar.slice( matched.length );
1477
+ }
1478
+ }
1479
+
1480
+ if ( !matched ) {
1481
+ break;
1482
+ }
1483
+ }
1484
+
1485
+ // Return the length of the invalid excess
1486
+ // if we're just parsing
1487
+ // Otherwise, throw an error or return tokens
1488
+ return parseOnly ?
1489
+ soFar.length :
1490
+ soFar ?
1491
+ Sizzle.error( selector ) :
1492
+ // Cache the tokens
1493
+ tokenCache( selector, groups ).slice( 0 );
1494
+ }
1495
+
1496
+ function toSelector( tokens ) {
1497
+ var i = 0,
1498
+ len = tokens.length,
1499
+ selector = "";
1500
+ for ( ; i < len; i++ ) {
1501
+ selector += tokens[i].value;
1502
+ }
1503
+ return selector;
1504
+ }
1505
+
1506
+ function addCombinator( matcher, combinator, base ) {
1507
+ var dir = combinator.dir,
1508
+ checkNonElements = base && dir === "parentNode",
1509
+ doneName = done++;
1510
+
1511
+ return combinator.first ?
1512
+ // Check against closest ancestor/preceding element
1513
+ function( elem, context, xml ) {
1514
+ while ( (elem = elem[ dir ]) ) {
1515
+ if ( elem.nodeType === 1 || checkNonElements ) {
1516
+ return matcher( elem, context, xml );
1517
+ }
1518
+ }
1519
+ } :
1520
+
1521
+ // Check against all ancestor/preceding elements
1522
+ function( elem, context, xml ) {
1523
+ var oldCache, outerCache,
1524
+ newCache = [ dirruns, doneName ];
1525
+
1526
+ // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching
1527
+ if ( xml ) {
1528
+ while ( (elem = elem[ dir ]) ) {
1529
+ if ( elem.nodeType === 1 || checkNonElements ) {
1530
+ if ( matcher( elem, context, xml ) ) {
1531
+ return true;
1532
+ }
1533
+ }
1534
+ }
1535
+ } else {
1536
+ while ( (elem = elem[ dir ]) ) {
1537
+ if ( elem.nodeType === 1 || checkNonElements ) {
1538
+ outerCache = elem[ expando ] || (elem[ expando ] = {});
1539
+ if ( (oldCache = outerCache[ dir ]) &&
1540
+ oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
1541
+
1542
+ // Assign to newCache so results back-propagate to previous elements
1543
+ return (newCache[ 2 ] = oldCache[ 2 ]);
1544
+ } else {
1545
+ // Reuse newcache so results back-propagate to previous elements
1546
+ outerCache[ dir ] = newCache;
1547
+
1548
+ // A match means we're done; a fail means we have to keep checking
1549
+ if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
1550
+ return true;
1551
+ }
1552
+ }
1553
+ }
1554
+ }
1555
+ }
1556
+ };
1557
+ }
1558
+
1559
+ function elementMatcher( matchers ) {
1560
+ return matchers.length > 1 ?
1561
+ function( elem, context, xml ) {
1562
+ var i = matchers.length;
1563
+ while ( i-- ) {
1564
+ if ( !matchers[i]( elem, context, xml ) ) {
1565
+ return false;
1566
+ }
1567
+ }
1568
+ return true;
1569
+ } :
1570
+ matchers[0];
1571
+ }
1572
+
1573
+ function condense( unmatched, map, filter, context, xml ) {
1574
+ var elem,
1575
+ newUnmatched = [],
1576
+ i = 0,
1577
+ len = unmatched.length,
1578
+ mapped = map != null;
1579
+
1580
+ for ( ; i < len; i++ ) {
1581
+ if ( (elem = unmatched[i]) ) {
1582
+ if ( !filter || filter( elem, context, xml ) ) {
1583
+ newUnmatched.push( elem );
1584
+ if ( mapped ) {
1585
+ map.push( i );
1586
+ }
1587
+ }
1588
+ }
1589
+ }
1590
+
1591
+ return newUnmatched;
1592
+ }
1593
+
1594
+ function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
1595
+ if ( postFilter && !postFilter[ expando ] ) {
1596
+ postFilter = setMatcher( postFilter );
1597
+ }
1598
+ if ( postFinder && !postFinder[ expando ] ) {
1599
+ postFinder = setMatcher( postFinder, postSelector );
1600
+ }
1601
+ return markFunction(function( seed, results, context, xml ) {
1602
+ var temp, i, elem,
1603
+ preMap = [],
1604
+ postMap = [],
1605
+ preexisting = results.length,
1606
+
1607
+ // Get initial elements from seed or context
1608
+ elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
1609
+
1610
+ // Prefilter to get matcher input, preserving a map for seed-results synchronization
1611
+ matcherIn = preFilter && ( seed || !selector ) ?
1612
+ condense( elems, preMap, preFilter, context, xml ) :
1613
+ elems,
1614
+
1615
+ matcherOut = matcher ?
1616
+ // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
1617
+ postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
1618
+
1619
+ // ...intermediate processing is necessary
1620
+ [] :
1621
+
1622
+ // ...otherwise use results directly
1623
+ results :
1624
+ matcherIn;
1625
+
1626
+ // Find primary matches
1627
+ if ( matcher ) {
1628
+ matcher( matcherIn, matcherOut, context, xml );
1629
+ }
1630
+
1631
+ // Apply postFilter
1632
+ if ( postFilter ) {
1633
+ temp = condense( matcherOut, postMap );
1634
+ postFilter( temp, [], context, xml );
1635
+
1636
+ // Un-match failing elements by moving them back to matcherIn
1637
+ i = temp.length;
1638
+ while ( i-- ) {
1639
+ if ( (elem = temp[i]) ) {
1640
+ matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
1641
+ }
1642
+ }
1643
+ }
1644
+
1645
+ if ( seed ) {
1646
+ if ( postFinder || preFilter ) {
1647
+ if ( postFinder ) {
1648
+ // Get the final matcherOut by condensing this intermediate into postFinder contexts
1649
+ temp = [];
1650
+ i = matcherOut.length;
1651
+ while ( i-- ) {
1652
+ if ( (elem = matcherOut[i]) ) {
1653
+ // Restore matcherIn since elem is not yet a final match
1654
+ temp.push( (matcherIn[i] = elem) );
1655
+ }
1656
+ }
1657
+ postFinder( null, (matcherOut = []), temp, xml );
1658
+ }
1659
+
1660
+ // Move matched elements from seed to results to keep them synchronized
1661
+ i = matcherOut.length;
1662
+ while ( i-- ) {
1663
+ if ( (elem = matcherOut[i]) &&
1664
+ (temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) {
1665
+
1666
+ seed[temp] = !(results[temp] = elem);
1667
+ }
1668
+ }
1669
+ }
1670
+
1671
+ // Add elements to results, through postFinder if defined
1672
+ } else {
1673
+ matcherOut = condense(
1674
+ matcherOut === results ?
1675
+ matcherOut.splice( preexisting, matcherOut.length ) :
1676
+ matcherOut
1677
+ );
1678
+ if ( postFinder ) {
1679
+ postFinder( null, results, matcherOut, xml );
1680
+ } else {
1681
+ push.apply( results, matcherOut );
1682
+ }
1683
+ }
1684
+ });
1685
+ }
1686
+
1687
+ function matcherFromTokens( tokens ) {
1688
+ var checkContext, matcher, j,
1689
+ len = tokens.length,
1690
+ leadingRelative = Expr.relative[ tokens[0].type ],
1691
+ implicitRelative = leadingRelative || Expr.relative[" "],
1692
+ i = leadingRelative ? 1 : 0,
1693
+
1694
+ // The foundational matcher ensures that elements are reachable from top-level context(s)
1695
+ matchContext = addCombinator( function( elem ) {
1696
+ return elem === checkContext;
1697
+ }, implicitRelative, true ),
1698
+ matchAnyContext = addCombinator( function( elem ) {
1699
+ return indexOf.call( checkContext, elem ) > -1;
1700
+ }, implicitRelative, true ),
1701
+ matchers = [ function( elem, context, xml ) {
1702
+ return ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
1703
+ (checkContext = context).nodeType ?
1704
+ matchContext( elem, context, xml ) :
1705
+ matchAnyContext( elem, context, xml ) );
1706
+ } ];
1707
+
1708
+ for ( ; i < len; i++ ) {
1709
+ if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
1710
+ matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
1711
+ } else {
1712
+ matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
1713
+
1714
+ // Return special upon seeing a positional matcher
1715
+ if ( matcher[ expando ] ) {
1716
+ // Find the next relative operator (if any) for proper handling
1717
+ j = ++i;
1718
+ for ( ; j < len; j++ ) {
1719
+ if ( Expr.relative[ tokens[j].type ] ) {
1720
+ break;
1721
+ }
1722
+ }
1723
+ return setMatcher(
1724
+ i > 1 && elementMatcher( matchers ),
1725
+ i > 1 && toSelector(
1726
+ // If the preceding token was a descendant combinator, insert an implicit any-element `*`
1727
+ tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
1728
+ ).replace( rtrim, "$1" ),
1729
+ matcher,
1730
+ i < j && matcherFromTokens( tokens.slice( i, j ) ),
1731
+ j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
1732
+ j < len && toSelector( tokens )
1733
+ );
1734
+ }
1735
+ matchers.push( matcher );
1736
+ }
1737
+ }
1738
+
1739
+ return elementMatcher( matchers );
1740
+ }
1741
+
1742
+ function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
1743
+ var bySet = setMatchers.length > 0,
1744
+ byElement = elementMatchers.length > 0,
1745
+ superMatcher = function( seed, context, xml, results, outermost ) {
1746
+ var elem, j, matcher,
1747
+ matchedCount = 0,
1748
+ i = "0",
1749
+ unmatched = seed && [],
1750
+ setMatched = [],
1751
+ contextBackup = outermostContext,
1752
+ // We must always have either seed elements or outermost context
1753
+ elems = seed || byElement && Expr.find["TAG"]( "*", outermost ),
1754
+ // Use integer dirruns iff this is the outermost matcher
1755
+ dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
1756
+ len = elems.length;
1757
+
1758
+ if ( outermost ) {
1759
+ outermostContext = context !== document && context;
1760
+ }
1761
+
1762
+ // Add elements passing elementMatchers directly to results
1763
+ // Keep `i` a string if there are no elements so `matchedCount` will be "00" below
1764
+ // Support: IE<9, Safari
1765
+ // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
1766
+ for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
1767
+ if ( byElement && elem ) {
1768
+ j = 0;
1769
+ while ( (matcher = elementMatchers[j++]) ) {
1770
+ if ( matcher( elem, context, xml ) ) {
1771
+ results.push( elem );
1772
+ break;
1773
+ }
1774
+ }
1775
+ if ( outermost ) {
1776
+ dirruns = dirrunsUnique;
1777
+ }
1778
+ }
1779
+
1780
+ // Track unmatched elements for set filters
1781
+ if ( bySet ) {
1782
+ // They will have gone through all possible matchers
1783
+ if ( (elem = !matcher && elem) ) {
1784
+ matchedCount--;
1785
+ }
1786
+
1787
+ // Lengthen the array for every element, matched or not
1788
+ if ( seed ) {
1789
+ unmatched.push( elem );
1790
+ }
1791
+ }
1792
+ }
1793
+
1794
+ // Apply set filters to unmatched elements
1795
+ matchedCount += i;
1796
+ if ( bySet && i !== matchedCount ) {
1797
+ j = 0;
1798
+ while ( (matcher = setMatchers[j++]) ) {
1799
+ matcher( unmatched, setMatched, context, xml );
1800
+ }
1801
+
1802
+ if ( seed ) {
1803
+ // Reintegrate element matches to eliminate the need for sorting
1804
+ if ( matchedCount > 0 ) {
1805
+ while ( i-- ) {
1806
+ if ( !(unmatched[i] || setMatched[i]) ) {
1807
+ setMatched[i] = pop.call( results );
1808
+ }
1809
+ }
1810
+ }
1811
+
1812
+ // Discard index placeholder values to get only actual matches
1813
+ setMatched = condense( setMatched );
1814
+ }
1815
+
1816
+ // Add matches to results
1817
+ push.apply( results, setMatched );
1818
+
1819
+ // Seedless set matches succeeding multiple successful matchers stipulate sorting
1820
+ if ( outermost && !seed && setMatched.length > 0 &&
1821
+ ( matchedCount + setMatchers.length ) > 1 ) {
1822
+
1823
+ Sizzle.uniqueSort( results );
1824
+ }
1825
+ }
1826
+
1827
+ // Override manipulation of globals by nested matchers
1828
+ if ( outermost ) {
1829
+ dirruns = dirrunsUnique;
1830
+ outermostContext = contextBackup;
1831
+ }
1832
+
1833
+ return unmatched;
1834
+ };
1835
+
1836
+ return bySet ?
1837
+ markFunction( superMatcher ) :
1838
+ superMatcher;
1839
+ }
1840
+
1841
+ compile = Sizzle.compile = function( selector, group /* Internal Use Only */ ) {
1842
+ var i,
1843
+ setMatchers = [],
1844
+ elementMatchers = [],
1845
+ cached = compilerCache[ selector + " " ];
1846
+
1847
+ if ( !cached ) {
1848
+ // Generate a function of recursive functions that can be used to check each element
1849
+ if ( !group ) {
1850
+ group = tokenize( selector );
1851
+ }
1852
+ i = group.length;
1853
+ while ( i-- ) {
1854
+ cached = matcherFromTokens( group[i] );
1855
+ if ( cached[ expando ] ) {
1856
+ setMatchers.push( cached );
1857
+ } else {
1858
+ elementMatchers.push( cached );
1859
+ }
1860
+ }
1861
+
1862
+ // Cache the compiled function
1863
+ cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
1864
+ }
1865
+ return cached;
1866
+ };
1867
+
1868
+ function multipleContexts( selector, contexts, results ) {
1869
+ var i = 0,
1870
+ len = contexts.length;
1871
+ for ( ; i < len; i++ ) {
1872
+ Sizzle( selector, contexts[i], results );
1873
+ }
1874
+ return results;
1875
+ }
1876
+
1877
+ function select( selector, context, results, seed ) {
1878
+ var i, tokens, token, type, find,
1879
+ match = tokenize( selector );
1880
+
1881
+ if ( !seed ) {
1882
+ // Try to minimize operations if there is only one group
1883
+ if ( match.length === 1 ) {
1884
+
1885
+ // Take a shortcut and set the context if the root selector is an ID
1886
+ tokens = match[0] = match[0].slice( 0 );
1887
+ if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
1888
+ support.getById && context.nodeType === 9 && documentIsHTML &&
1889
+ Expr.relative[ tokens[1].type ] ) {
1890
+
1891
+ context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
1892
+ if ( !context ) {
1893
+ return results;
1894
+ }
1895
+ selector = selector.slice( tokens.shift().value.length );
1896
+ }
1897
+
1898
+ // Fetch a seed set for right-to-left matching
1899
+ i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
1900
+ while ( i-- ) {
1901
+ token = tokens[i];
1902
+
1903
+ // Abort if we hit a combinator
1904
+ if ( Expr.relative[ (type = token.type) ] ) {
1905
+ break;
1906
+ }
1907
+ if ( (find = Expr.find[ type ]) ) {
1908
+ // Search, expanding context for leading sibling combinators
1909
+ if ( (seed = find(
1910
+ token.matches[0].replace( runescape, funescape ),
1911
+ rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context
1912
+ )) ) {
1913
+
1914
+ // If seed is empty or no tokens remain, we can return early
1915
+ tokens.splice( i, 1 );
1916
+ selector = seed.length && toSelector( tokens );
1917
+ if ( !selector ) {
1918
+ push.apply( results, seed );
1919
+ return results;
1920
+ }
1921
+
1922
+ break;
1923
+ }
1924
+ }
1925
+ }
1926
+ }
1927
+ }
1928
+
1929
+ // Compile and execute a filtering function
1930
+ // Provide `match` to avoid retokenization if we modified the selector above
1931
+ compile( selector, match )(
1932
+ seed,
1933
+ context,
1934
+ !documentIsHTML,
1935
+ results,
1936
+ rsibling.test( selector ) && testContext( context.parentNode ) || context
1937
+ );
1938
+ return results;
1939
+ }
1940
+
1941
+ // One-time assignments
1942
+
1943
+ // Sort stability
1944
+ support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
1945
+
1946
+ // Support: Chrome<14
1947
+ // Always assume duplicates if they aren't passed to the comparison function
1948
+ support.detectDuplicates = !!hasDuplicate;
1949
+
1950
+ // Initialize against the default document
1951
+ setDocument();
1952
+
1953
+ // Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
1954
+ // Detached nodes confoundingly follow *each other*
1955
+ support.sortDetached = assert(function( div1 ) {
1956
+ // Should return 1, but returns 4 (following)
1957
+ return div1.compareDocumentPosition( document.createElement("div") ) & 1;
1958
+ });
1959
+
1960
+ // Support: IE<8
1961
+ // Prevent attribute/property "interpolation"
1962
+ // http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
1963
+ if ( !assert(function( div ) {
1964
+ div.innerHTML = "<a href='#'></a>";
1965
+ return div.firstChild.getAttribute("href") === "#" ;
1966
+ }) ) {
1967
+ addHandle( "type|href|height|width", function( elem, name, isXML ) {
1968
+ if ( !isXML ) {
1969
+ return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
1970
+ }
1971
+ });
1972
+ }
1973
+
1974
+ // Support: IE<9
1975
+ // Use defaultValue in place of getAttribute("value")
1976
+ if ( !support.attributes || !assert(function( div ) {
1977
+ div.innerHTML = "<input/>";
1978
+ div.firstChild.setAttribute( "value", "" );
1979
+ return div.firstChild.getAttribute( "value" ) === "";
1980
+ }) ) {
1981
+ addHandle( "value", function( elem, name, isXML ) {
1982
+ if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
1983
+ return elem.defaultValue;
1984
+ }
1985
+ });
1986
+ }
1987
+
1988
+ // Support: IE<9
1989
+ // Use getAttributeNode to fetch booleans when getAttribute lies
1990
+ if ( !assert(function( div ) {
1991
+ return div.getAttribute("disabled") == null;
1992
+ }) ) {
1993
+ addHandle( booleans, function( elem, name, isXML ) {
1994
+ var val;
1995
+ if ( !isXML ) {
1996
+ return elem[ name ] === true ? name.toLowerCase() :
1997
+ (val = elem.getAttributeNode( name )) && val.specified ?
1998
+ val.value :
1999
+ null;
2000
+ }
2001
+ });
2002
+ }
2003
+
2004
+ // EXPOSE
2005
+ if ( typeof define === "function" && define.amd ) {
2006
+ define(function() { return Sizzle; });
2007
+ // Sizzle requires that there be a global window in Common-JS like environments
2008
+ } else if ( typeof module !== "undefined" && module.exports ) {
2009
+ module.exports = Sizzle;
2010
+ } else {
2011
+ window.Sizzle = Sizzle;
2012
+ }
2013
+ // EXPOSE
2014
+
2015
+ })( window );