vendor: 3,606 bytes, lines 1-88
1/******/ (function(modules) { // webpackBootstrap 2/******/ // The module cache 3/******/ var installedModules = {}; 4/******/ 5/******/ // The require function 6/******/ function __webpack_require__(moduleId) { 7/******/ 8/******/ // Check if module is in cache 9/******/ if(installedModules[moduleId]) { 10/******/ return installedModules[moduleId].exports; 11/******/ } 12/******/ // Create a new module (and put it into the cache) 13/******/ var module = installedModules[moduleId] = { 14/******/ i: moduleId, 15/******/ l: false, 16/******/ exports: {} 17/******/ }; 18/******/ 19/******/ // Execute the module function 20/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 21/******/ 22/******/ // Flag the module as loaded 23/******/ module.l = true; 24/******/ 25/******/ // Return the exports of the module 26/******/ return module.exports; 27/******/ } 28/******/ 29/******/ 30/******/ // expose the modules object (__webpack_modules__) 31/******/ __webpack_require__.m = modules; 32/******/ 33/******/ // expose the module cache 34/******/ __webpack_require__.c = installedModules; 35/******/ 36/******/ // define getter function for harmony exports 37/******/ __webpack_require__.d = function(exports, name, getter) { 38/******/ if(!__webpack_require__.o(exports, name)) { 39/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); 40/******/ } 41/******/ }; 42/******/ 43/******/ // define __esModule on exports 44/******/ __webpack_require__.r = function(exports) { 45/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { 46/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); 47/******/ } 48/******/ Object.defineProperty(exports, '__esModule', { value: true }); 49/******/ }; 50/******/ 51/******/ // create a fake namespace object 52/******/ // mode & 1: value is a module id, require it 53/******/ // mode & 2: merge all properties of value into the ns 54/******/ // mode & 4: return value when already ns object 55/******/ // mode & 8|1: behave like require 56/******/ __webpack_require__.t = function(value, mode) { 57/******/ if(mode & 1) value = __webpack_require__(value); 58/******/ if(mode & 8) return value; 59/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; 60/******/ var ns = Object.create(null); 61/******/ __webpack_require__.r(ns); 62/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); 63/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); 64/******/ return ns; 65/******/ }; 66/******/ 67/******/ // getDefaultExport function for compatibility with non-harmony modules 68/******/ __webpack_require__.n = function(module) { 69/******/ var getter = module && module.__esModule ? 70/******/ function getDefault() { return module['default']; } : 71/******/ function getModuleExports() { return module; }; 72/******/ __webpack_require__.d(getter, 'a', getter); 73/******/ return getter; 74/******/ }; 75/******/ 76/******/ // Object.prototype.hasOwnProperty.call 77/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; 78/******/ 79/******/ // __webpack_public_path__ 80/******/ __webpack_require__.p = ""; 81/******/ 82/******/ 83/******/ // Load entry module and return exports 84/******/ return __webpack_require__(__webpack_require__.s = "./js/app.js"); 85/******/ }) 86/************************************************************************/ 87/******/ ({ 88
89/***/ "./js/app.js": 90/*!*******************!*\ 91 !*** ./js/app.js ***! 92 \*******************/ 93/*! no exports provided */ 94/***/ (function(module, __webpack_exports__, __webpack_require__) { 95 96"use strict"; 97__webpack_require__.r(__webpack_exports__); 98/* WEBPACK VAR INJECTION */(function(global) {/* harmony import */ var _sub_silencio_anim__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./sub/silencio_anim */ "./js/sub/silencio_anim.js"); 99"use scrict"; 100 101global.$ = __webpack_require__(/*! jquery */ "./node_modules/jquery/dist/jquery.js"); 102var MobileDetect = __webpack_require__(/*! mobile-detect */ "./node_modules/mobile-detect/mobile-detect.js"); 103global.md = new MobileDetect(window.navigator.userAgent); 104var mainWidth; 105 106 107 108$(function(){ 109 110 // window.anim = new silencio_anim(); 111 112 vh(); 113 114 let animX = (window.innerWidth * .5) - (window.innerWidth * .7); 115 let animY = (window.innerHeight * .5) - (window.innerWidth * .6); 116 $('.anim').css({ 117 'transform' : 'translate3d('+animX+'px, '+animY+'px, 0)' 118 }); 119 120 setTimeout(function(){ 121 $('body').addClass('in'); 122 },100); 123 124 $(window).on('load pageshow', function(){ 125 setTimeout(function(){ 126 $(window).trigger('scroll'); 127 $('body').addClass('in'); 128 },500); 129 }); 130 131 $(window).on('beforeunload', function(){ 132 setTimeout(function(){ 133 $('body').removeClass('in'); 134 },500); 135 }); 136 137 binds(); 138}); 139 140 141function binds(){ 142 $('.burger').click(function(e){ 143 e.preventDefault(); 144 $('html').toggleClass('nav-open'); 145 }); 146 147 if($('html').hasClass('home')) { 148 $('.nav--top a').unbind('click').click(function(e){ 149 e.preventDefault(); 150 var id = $(this).attr('href'); 151 if(id!='##') { 152 $('html').animate({'scrollTop' : $(id).position().top }, 500); 153 } else { 154 $('html').animate({'scrollTop' : 0 }, 500); 155 } 156 $('html').removeClass('nav-open'); 157 }); 158 } 159 160 $(window).unbind('mousemove').mousemove(function(e){ 161 let prcx = e.offsetX / window.innerWidth; 162 let prcy = e.offsetY / window.innerHeight; 163 console.log(prcx, prcy); 164 }); 165 166 $(window).unbind('mousemove').mousemove(function(e){ 167 let wx = $('.anim').outerWidth() / 2; 168 let wy = $('.anim').outerHeight() / 2; 169 let prcx = e.clientX / window.innerWidth; 170 let prcy = e.clientY / window.innerHeight; 171 let x = (window.innerWidth * prcx) - wx; 172 let y = (window.innerHeight * prcy) - wy; 173 let rotx = (.5-prcx) * -100; 174 let roty = (.5-prcy) * 100; 175 $('.anim').css({ 176 'transform' : 'translate3d('+x+'px, '+y+'px, 0) rotateY('+rotx+'deg) rotateX('+roty+'deg)', 177 }); 178 }); 179 // $('.home-grid a, .close a').unbind('click').click(function(e){ 180 // if(!e.ctrlKey&&!e.altKey&&!e.shiftKey) { 181 // e.preventDefault(); 182 // var href = $(this).attr('href'); 183 // $('body').removeClass('in'); 184 // setTimeout(function(){ 185 // window.location.href = href; 186 // }, 300); 187 // } 188 // }); 189 190 var spinSpeed = 50; 191 $('.image--mouseovers').unbind('mouseenter mouseleave').mouseenter(function(){ 192 $(this).children().each(function(idx){ 193 var t = $(this); 194 setTimeout(function(){ 195 $(t).siblings().css('opacity',0); 196 $(t).css('opacity',1); 197 }, spinSpeed*idx); 198 }); 199 }).mouseleave(function(){ 200 var len = $(this).children().length; 201 $(this).children().each(function(idx){ 202 var t = $(this); 203 setTimeout(function(){ 204 $(t).siblings().css('opacity',0); 205 $(t).css('opacity',1); 206 if(idx==0) { 207 setTimeout(function(){ 208 $(t).css('opacity',0); 209 }, spinSpeed); 210 } 211 }, spinSpeed*(len-idx)); 212 }); 213 }); 214} 215 216function vh(){ 217 window.vh = window.innerHeight * 0.01; 218 document.documentElement.style.setProperty('--vh', `${window.vh}px`); 219} 220 221function resize(){ 222 let newMainWidth = $('main').outerWidth(); 223 if(newMainWidth!==mainWidth ||Â !md.mobile()){ 224 vh(); 225 } 226 mainWidth = newMainWidth; 227} 228 229$(window).resize(function(){ 230 resize(); 231}); 232 233/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../node_modules/webpack/buildin/global.js */ "./node_modules/webpack/buildin/global.js"))) 234 235/***/ }), 236
vendor: 38,800 bytes, lines 237-256
237/***/ "./js/sub/dat.gui.min.js": 238/*!*******************************!*\ 239 !*** ./js/sub/dat.gui.min.js ***! 240 \*******************************/ 241/*! no static exports found */ 242/***/ (function(module, exports, __webpack_require__) { 243 244/** 245 * dat-gui JavaScript Controller Library 246 * http://code.google.com/p/dat-gui 247 * 248 * Copyright 2011 Data Arts Team, Google Creative Lab 249 * 250 * Licensed under the Apache License, Version 2.0 (the "License"); 251 * you may not use this file except in compliance with the License. 252 * You may obtain a copy of the License at 253 * 254 * http://www.apache.org/licenses/LICENSE-2.0 255 */ 256!function(e,t){ true?t(exports):undefined}(this,function(e){"use strict";function t(e,t){var n=e.__state.conversionName.toString(),o=Math.round(e.r),i=Math.round(e.g),r=Math.round(e.b),s=e.a,a=Math.round(e.h),l=e.s.toFixed(1),d=e.v.toFixed(1);if(t||"THREE_CHAR_HEX"===n||"SIX_CHAR_HEX"===n){for(var c=e.hex.toString(16);c.length<6;)c="0"+c;return"#"+c}return"CSS_RGB"===n?"rgb("+o+","+i+","+r+")":"CSS_RGBA"===n?"rgba("+o+","+i+","+r+","+s+")":"HEX"===n?"0x"+e.hex.toString(16):"RGB_ARRAY"===n?"["+o+","+i+","+r+"]":"RGBA_ARRAY"===n?"["+o+","+i+","+r+","+s+"]":"RGB_OBJ"===n?"{r:"+o+",g:"+i+",b:"+r+"}":"RGBA_OBJ"===n?"{r:"+o+",g:"+i+",b:"+r+",a:"+s+"}":"HSV_OBJ"===n?"{h:"+a+",s:"+l+",v:"+d+"}":"HSVA_OBJ"===n?"{h:"+a+",s:"+l+",v:"+d+",a:"+s+"}":"unknown format"}function n(e,t,n){Object.defineProperty(e,t,{get:function(){return"RGB"===this.__state.space?this.__state[t]:(I.recalculateRGB(this,t,n),this.__state[t])},set:function(e){"RGB"!==this.__state.space&&(I.recalculateRGB(this,t,n),this.__state.space="RGB"),this.__state[t]=e}})}function o(e,t){Object.defineProperty(e,t,{get:function(){return"HSV"===this.__state.space?this.__state[t]:(I.recalculateHSV(this),this.__state[t])},set:function(e){"HSV"!==this.__state.space&&(I.recalculateHSV(this),this.__state.space="HSV"),this.__state[t]=e}})}function i(e){if("0"===e||S.isUndefined(e))return 0;var t=e.match(U);return S.isNull(t)?0:parseFloat(t[1])}function r(e){var t=e.toString();return t.indexOf(".")>-1?t.length-t.indexOf(".")-1:0}function s(e,t){var n=Math.pow(10,t);return Math.round(e*n)/n}function a(e,t,n,o,i){return o+(e-t)/(n-t)*(i-o)}function l(e,t,n,o){e.style.background="",S.each(ee,function(i){e.style.cssText+="background: "+i+"linear-gradient("+t+", "+n+" 0%, "+o+" 100%); "})}function d(e){e.style.background="",e.style.cssText+="background: -moz-linear-gradient(top, #ff0000 0%, #ff00ff 17%, #0000ff 34%, #00ffff 50%, #00ff00 67%, #ffff00 84%, #ff0000 100%);",e.style.cssText+="background: -webkit-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);",e.style.cssText+="background: -o-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);",e.style.cssText+="background: -ms-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);",e.style.cssText+="background: linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);"}function c(e,t,n){var o=document.createElement("li");return t&&o.appendChild(t),n?e.__ul.insertBefore(o,n):e.__ul.appendChild(o),e.onResize(),o}function u(e){X.unbind(window,"resize",e.__resizeHandler),e.saveToLocalStorageIfPossible&&X.unbind(window,"unload",e.saveToLocalStorageIfPossible)}function _(e,t){var n=e.__preset_select[e.__preset_select.selectedIndex];n.innerHTML=t?n.value+"*":n.value}function h(e,t,n){if(n.__li=t,n.__gui=e,S.extend(n,{options:function(t){if(arguments.length>1){var o=n.__li.nextElementSibling;return n.remove(),f(e,n.object,n.property,{before:o,factoryArgs:[S.toArray(arguments)]})}if(S.isArray(t)||S.isObject(t)){var i=n.__li.nextElementSibling;return n.remove(),f(e,n.object,n.property,{before:i,factoryArgs:[t]})}},name:function(e){return n.__li.firstElementChild.firstElementChild.innerHTML=e,n},listen:function(){return n.__gui.listen(n),n},remove:function(){return n.__gui.remove(n),n}}),n instanceof q){var o=new Q(n.object,n.property,{min:n.__min,max:n.__max,step:n.__step});S.each(["updateDisplay","onChange","onFinishChange","step"],function(e){var t=n[e],i=o[e];n[e]=o[e]=function(){var e=Array.prototype.slice.call(arguments);return i.apply(o,e),t.apply(n,e)}}),X.addClass(t,"has-slider"),n.domElement.insertBefore(o.domElement,n.domElement.firstElementChild)}else if(n instanceof Q){var i=function(t){if(S.isNumber(n.__min)&&S.isNumber(n.__max)){var o=n.__li.firstElementChild.firstElementChild.innerHTML,i=n.__gui.__listening.indexOf(n)>-1;n.remove();var r=f(e,n.object,n.property,{before:n.__li.nextElementSibling,factoryArgs:[n.__min,n.__max,n.__step]});return r.name(o),i&&r.listen(),r}return t};n.min=S.compose(i,n.min),n.max=S.compose(i,n.max)}else n instanceof K?(X.bind(t,"click",function(){X.fakeEvent(n.__checkbox,"click")}),X.bind(n.__checkbox,"click",function(e){e.stopPropagation()})):n instanceof Z?(X.bind(t,"click",function(){X.fakeEvent(n.__button,"click")}),X.bind(t,"mouseover",function(){X.addClass(n.__button,"hover")}),X.bind(t,"mouseout",function(){X.removeClass(n.__button,"hover")})):n instanceof $&&(X.addClass(t,"color"),n.updateDisplay=S.compose(function(e){return t.style.borderLeftColor=n.__color.toString(),e},n.updateDisplay),n.updateDisplay());n.setValue=S.compose(function(t){return e.getRoot().__preset_select&&n.isModified()&&_(e.getRoot(),!0),t},n.setValue)}function p(e,t){var n=e.getRoot(),o=n.__rememberedObjects.indexOf(t.object);if(-1!==o){var i=n.__rememberedObjectIndecesToControllers[o];if(void 0===i&&(i={},n.__rememberedObjectIndecesToControllers[o]=i),i[t.property]=t,n.load&&n.load.remembered){var r=n.load.remembered,s=void 0;if(r[e.preset])s=r[e.preset];else{if(!r[se])return;s=r[se]}if(s[o]&&void 0!==s[o][t.property]){var a=s[o][t.property];t.initialValue=a,t.setValue(a)}}}}function f(e,t,n,o){if(void 0===t[n])throw new Error('Object "'+t+'" has no property "'+n+'"');var i=void 0;if(o.color)i=new $(t,n);else{var r=[t,n].concat(o.factoryArgs);i=ne.apply(e,r)}o.before instanceof z&&(o.before=o.before.__li),p(e,i),X.addClass(i.domElement,"c");var s=document.createElement("span");X.addClass(s,"property-name"),s.innerHTML=i.property;var a=document.createElement("div");a.appendChild(s),a.appendChild(i.domElement);var l=c(e,a,o.before);return X.addClass(l,he.CLASS_CONTROLLER_ROW),i instanceof $?X.addClass(l,"color"):X.addClass(l,H(i.getValue())),h(e,l,i),e.__controllers.push(i),i}function m(e,t){return document.location.href+"."+t}function g(e,t,n){var o=document.createElement("option");o.innerHTML=t,o.value=t,e.__preset_select.appendChild(o),n&&(e.__preset_select.selectedIndex=e.__preset_select.length-1)}function b(e,t){t.style.display=e.useLocalStorage?"block":"none"}function v(e){var t=e.__save_row=document.createElement("li");X.addClass(e.domElement,"has-save"),e.__ul.insertBefore(t,e.__ul.firstChild),X.addClass(t,"save-row");var n=document.createElement("span");n.innerHTML=" ",X.addClass(n,"button gears");var o=document.createElement("span");o.innerHTML="Save",X.addClass(o,"button"),X.addClass(o,"save");var i=document.createElement("span");i.innerHTML="New",X.addClass(i,"button"),X.addClass(i,"save-as");var r=document.createElement("span");r.innerHTML="Revert",X.addClass(r,"button"),X.addClass(r,"revert");var s=e.__preset_select=document.createElement("select");if(e.load&&e.load.remembered?S.each(e.load.remembered,function(t,n){g(e,n,n===e.preset)}):g(e,se,!1),X.bind(s,"change",function(){for(var t=0;t<e.__preset_select.length;t++)e.__preset_select[t].innerHTML=e.__preset_select[t].value;e.preset=this.value}),t.appendChild(s),t.appendChild(n),t.appendChild(o),t.appendChild(i),t.appendChild(r),ae){var a=document.getElementById("dg-local-explain"),l=document.getElementById("dg-local-storage");document.getElementById("dg-save-locally").style.display="block","true"===localStorage.getItem(m(e,"isLocal"))&&l.setAttribute("checked","checked"),b(e,a),X.bind(l,"change",function(){e.useLocalStorage=!e.useLocalStorage,b(e,a)})}var d=document.getElementById("dg-new-constructor");X.bind(d,"keydown",function(e){!e.metaKey||67!==e.which&&67!==e.keyCode||le.hide()}),X.bind(n,"click",function(){d.innerHTML=JSON.stringify(e.getSaveObject(),void 0,2),le.show(),d.focus(),d.select()}),X.bind(o,"click",function(){e.save()}),X.bind(i,"click",function(){var t=prompt("Enter a new preset name.");t&&e.saveAs(t)}),X.bind(r,"click",function(){e.revert()})}function y(e){function t(t){return t.preventDefault(),e.width+=i-t.clientX,e.onResize(),i=t.clientX,!1}function n(){X.removeClass(e.__closeButton,he.CLASS_DRAG),X.unbind(window,"mousemove",t),X.unbind(window,"mouseup",n)}function o(o){return o.preventDefault(),i=o.clientX,X.addClass(e.__closeButton,he.CLASS_DRAG),X.bind(window,"mousemove",t),X.bind(window,"mouseup",n),!1}var i=void 0;e.__resize_handle=document.createElement("div"),S.extend(e.__resize_handle.style,{width:"6px",marginLeft:"-3px",height:"200px",cursor:"ew-resize",position:"absolute"}),X.bind(e.__resize_handle,"mousedown",o),X.bind(e.__closeButton,"mousedown",o),e.domElement.insertBefore(e.__resize_handle,e.domElement.firstElementChild)}function w(e,t){e.domElement.style.width=t+"px",e.__save_row&&e.autoPlace&&(e.__save_row.style.width=t+"px"),e.__closeButton&&(e.__closeButton.style.width=t+"px")}function x(e,t){var n={};return S.each(e.__rememberedObjects,function(o,i){var r={},s=e.__rememberedObjectIndecesToControllers[i];S.each(s,function(e,n){r[n]=t?e.initialValue:e.getValue()}),n[i]=r}),n}function E(e){for(var t=0;t<e.__preset_select.length;t++)e.__preset_select[t].value===e.preset&&(e.__preset_select.selectedIndex=t)}function C(e){0!==e.length&&oe.call(window,function(){C(e)}),S.each(e,function(e){e.updateDisplay()})}var A=Array.prototype.forEach,k=Array.prototype.slice,S={BREAK:{},extend:function(e){return this.each(k.call(arguments,1),function(t){(this.isObject(t)?Object.keys(t):[]).forEach(function(n){this.isUndefined(t[n])||(e[n]=t[n])}.bind(this))},this),e},defaults:function(e){return this.each(k.call(arguments,1),function(t){(this.isObject(t)?Object.keys(t):[]).forEach(function(n){this.isUndefined(e[n])&&(e[n]=t[n])}.bind(this))},this),e},compose:function(){var e=k.call(arguments);return function(){for(var t=k.call(arguments),n=e.length-1;n>=0;n--)t=[e[n].apply(this,t)];return t[0]}},each:function(e,t,n){if(e)if(A&&e.forEach&&e.forEach===A)e.forEach(t,n);else if(e.length===e.length+0){var o=void 0,i=void 0;for(o=0,i=e.length;o<i;o++)if(o in e&&t.call(n,e[o],o)===this.BREAK)return}else for(var r in e)if(t.call(n,e[r],r)===this.BREAK)return},defer:function(e){setTimeout(e,0)},debounce:function(e,t,n){var o=void 0;return function(){var i=this,r=arguments,s=n||!o;clearTimeout(o),o=setTimeout(function(){o=null,n||e.apply(i,r)},t),s&&e.apply(i,r)}},toArray:function(e){return e.toArray?e.toArray():k.call(e)},isUndefined:function(e){return void 0===e},isNull:function(e){return null===e},isNaN:function(e){function t(t){return e.apply(this,arguments)}return t.toString=function(){return e.toString()},t}(function(e){return isNaN(e)}),isArray:Array.isArray||function(e){return e.constructor===Array},isObject:function(e){return e===Object(e)},isNumber:function(e){return e===e+0},isString:function(e){return e===e+""},isBoolean:function(e){return!1===e||!0===e},isFunction:function(e){return"[object Function]"===Object.prototype.toString.call(e)}},O=[{litmus:S.isString,conversions:{THREE_CHAR_HEX:{read:function(e){var t=e.match(/^#([A-F0-9])([A-F0-9])([A-F0-9])$/i);return null!==t&&{space:"HEX",hex:parseInt("0x"+t[1].toString()+t[1].toString()+t[2].toString()+t[2].toString()+t[3].toString()+t[3].toString(),0)}},write:t},SIX_CHAR_HEX:{read:function(e){var t=e.match(/^#([A-F0-9]{6})$/i);return null!==t&&{space:"HEX",hex:parseInt("0x"+t[1].toString(),0)}},write:t},CSS_RGB:{read:function(e){var t=e.match(/^rgb\(\s*(.+)\s*,\s*(.+)\s*,\s*(.+)\s*\)/);return null!==t&&{space:"RGB",r:parseFloat(t[1]),g:parseFloat(t[2]),b:parseFloat(t[3])}},write:t},CSS_RGBA:{read:function(e){var t=e.match(/^rgba\(\s*(.+)\s*,\s*(.+)\s*,\s*(.+)\s*,\s*(.+)\s*\)/);return null!==t&&{space:"RGB",r:parseFloat(t[1]),g:parseFloat(t[2]),b:parseFloat(t[3]),a:parseFloat(t[4])}},write:t}}},{litmus:S.isNumber,conversions:{HEX:{read:function(e){return{space:"HEX",hex:e,conversionName:"HEX"}},write:function(e){return e.hex}}}},{litmus:S.isArray,conversions:{RGB_ARRAY:{read:function(e){return 3===e.length&&{space:"RGB",r:e[0],g:e[1],b:e[2]}},write:function(e){return[e.r,e.g,e.b]}},RGBA_ARRAY:{read:function(e){return 4===e.length&&{space:"RGB",r:e[0],g:e[1],b:e[2],a:e[3]}},write:function(e){return[e.r,e.g,e.b,e.a]}}}},{litmus:S.isObject,conversions:{RGBA_OBJ:{read:function(e){return!!(S.isNumber(e.r)&&S.isNumber(e.g)&&S.isNumber(e.b)&&S.isNumber(e.a))&&{space:"RGB",r:e.r,g:e.g,b:e.b,a:e.a}},write:function(e){return{r:e.r,g:e.g,b:e.b,a:e.a}}},RGB_OBJ:{read:function(e){return!!(S.isNumber(e.r)&&S.isNumber(e.g)&&S.isNumber(e.b))&&{space:"RGB",r:e.r,g:e.g,b:e.b}},write:function(e){return{r:e.r,g:e.g,b:e.b}}},HSVA_OBJ:{read:function(e){return!!(S.isNumber(e.h)&&S.isNumber(e.s)&&S.isNumber(e.v)&&S.isNumber(e.a))&&{space:"HSV",h:e.h,s:e.s,v:e.v,a:e.a}},write:function(e){return{h:e.h,s:e.s,v:e.v,a:e.a}}},HSV_OBJ:{read:function(e){return!!(S.isNumber(e.h)&&S.isNumber(e.s)&&S.isNumber(e.v))&&{space:"HSV",h:e.h,s:e.s,v:e.v}},write:function(e){return{h:e.h,s:e.s,v:e.v}}}}}],T=void 0,L=void 0,R=function(){L=!1;var e=arguments.length>1?S.toArray(arguments):arguments[0];return S.each(O,function(t){if(t.litmus(e))return S.each(t.conversions,function(t,n){if(T=t.read(e),!1===L&&!1!==T)return L=T,T.conversionName=n,T.conversion=t,S.BREAK}),S.BREAK}),L},B=void 0,N={hsv_to_rgb:function(e,t,n){var o=Math.floor(e/60)%6,i=e/60-Math.floor(e/60),r=n*(1-t),s=n*(1-i*t),a=n*(1-(1-i)*t),l=[[n,a,r],[s,n,r],[r,n,a],[r,s,n],[a,r,n],[n,r,s]][o];return{r:255*l[0],g:255*l[1],b:255*l[2]}},rgb_to_hsv:function(e,t,n){var o=Math.min(e,t,n),i=Math.max(e,t,n),r=i-o,s=void 0,a=void 0;return 0===i?{h:NaN,s:0,v:0}:(a=r/i,s=e===i?(t-n)/r:t===i?2+(n-e)/r:4+(e-t)/r,(s/=6)<0&&(s+=1),{h:360*s,s:a,v:i/255})},rgb_to_hex:function(e,t,n){var o=this.hex_with_component(0,2,e);return o=this.hex_with_component(o,1,t),o=this.hex_with_component(o,0,n)},component_from_hex:function(e,t){return e>>8*t&255},hex_with_component:function(e,t,n){return n<<(B=8*t)|e&~(255<<B)}},H="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},F=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")},P=function(){function e(e,t){for(var n=0;n<t.length;n++){var o=t[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(e,o.key,o)}}return function(t,n,o){return n&&e(t.prototype,n),o&&e(t,o),t}}(),j=function e(t,n,o){null===t&&(t=Function.prototype);var i=Object.getOwnPropertyDescriptor(t,n);if(void 0===i){var r=Object.getPrototypeOf(t);return null===r?void 0:e(r,n,o)}if("value"in i)return i.value;var s=i.get;if(void 0!==s)return s.call(o)},D=function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)},V=function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t},I=function(){function e(){if(F(this,e),this.__state=R.apply(this,arguments),!1===this.__state)throw new Error("Failed to interpret color arguments");this.__state.a=this.__state.a||1}return P(e,[{key:"toString",value:function(){return t(this)}},{key:"toHexString",value:function(){return t(this,!0)}},{key:"toOriginal",value:function(){return this.__state.conversion.write(this)}}]),e}();I.recalculateRGB=function(e,t,n){if("HEX"===e.__state.space)e.__state[t]=N.component_from_hex(e.__state.hex,n);else{if("HSV"!==e.__state.space)throw new Error("Corrupted color state");S.extend(e.__state,N.hsv_to_rgb(e.__state.h,e.__state.s,e.__state.v))}},I.recalculateHSV=function(e){var t=N.rgb_to_hsv(e.r,e.g,e.b);S.extend(e.__state,{s:t.s,v:t.v}),S.isNaN(t.h)?S.isUndefined(e.__state.h)&&(e.__state.h=0):e.__state.h=t.h},I.COMPONENTS=["r","g","b","h","s","v","hex","a"],n(I.prototype,"r",2),n(I.prototype,"g",1),n(I.prototype,"b",0),o(I.prototype,"h"),o(I.prototype,"s"),o(I.prototype,"v"),Object.defineProperty(I.prototype,"a",{get:function(){return this.__state.a},set:function(e){this.__state.a=e}}),Object.defineProperty(I.prototype,"hex",{get:function(){return"HEX"!==!this.__state.space&&(this.__state.hex=N.rgb_to_hex(this.r,this.g,this.b)),this.__state.hex},set:function(e){this.__state.space="HEX",this.__state.hex=e}});var z=function(){function e(t,n){F(this,e),this.initialValue=t[n],this.domElement=document.createElement("div"),this.object=t,this.property=n,this.__onChange=void 0,this.__onFinishChange=void 0}return P(e,[{key:"onChange",value:function(e){return this.__onChange=e,this}},{key:"onFinishChange",value:function(e){return this.__onFinishChange=e,this}},{key:"setValue",value:function(e){return this.object[this.property]=e,this.__onChange&&this.__onChange.call(this,e),this.updateDisplay(),this}},{key:"getValue",value:function(){return this.object[this.property]}},{key:"updateDisplay",value:function(){return this}},{key:"isModified",value:function(){return this.initialValue!==this.getValue()}}]),e}(),M={HTMLEvents:["change"],MouseEvents:["click","mousemove","mousedown","mouseup","mouseover"],KeyboardEvents:["keydown"]},G={};S.each(M,function(e,t){S.each(e,function(e){G[e]=t})});var U=/(\d+(\.\d+)?)px/,X={makeSelectable:function(e,t){void 0!==e&&void 0!==e.style&&(e.onselectstart=t?function(){return!1}:function(){},e.style.MozUserSelect=t?"auto":"none",e.style.KhtmlUserSelect=t?"auto":"none",e.unselectable=t?"on":"off")},makeFullscreen:function(e,t,n){var o=n,i=t;S.isUndefined(i)&&(i=!0),S.isUndefined(o)&&(o=!0),e.style.position="absolute",i&&(e.style.left=0,e.style.right=0),o&&(e.style.top=0,e.style.bottom=0)},fakeEvent:function(e,t,n,o){var i=n||{},r=G[t];if(!r)throw new Error("Event type "+t+" not supported.");var s=document.createEvent(r);switch(r){case"MouseEvents":var a=i.x||i.clientX||0,l=i.y||i.clientY||0;s.initMouseEvent(t,i.bubbles||!1,i.cancelable||!0,window,i.clickCount||1,0,0,a,l,!1,!1,!1,!1,0,null);break;case"KeyboardEvents":var d=s.initKeyboardEvent||s.initKeyEvent;S.defaults(i,{cancelable:!0,ctrlKey:!1,altKey:!1,shiftKey:!1,metaKey:!1,keyCode:void 0,charCode:void 0}),d(t,i.bubbles||!1,i.cancelable,window,i.ctrlKey,i.altKey,i.shiftKey,i.metaKey,i.keyCode,i.charCode);break;default:s.initEvent(t,i.bubbles||!1,i.cancelable||!0)}S.defaults(s,o),e.dispatchEvent(s)},bind:function(e,t,n,o){var i=o||!1;return e.addEventListener?e.addEventListener(t,n,i):e.attachEvent&&e.attachEvent("on"+t,n),X},unbind:function(e,t,n,o){var i=o||!1;return e.removeEventListener?e.removeEventListener(t,n,i):e.detachEvent&&e.detachEvent("on"+t,n),X},addClass:function(e,t){if(void 0===e.className)e.className=t;else if(e.className!==t){var n=e.className.split(/ +/);-1===n.indexOf(t)&&(n.push(t),e.className=n.join(" ").replace(/^\s+/,"").replace(/\s+$/,""))}return X},removeClass:function(e,t){if(t)if(e.className===t)e.removeAttribute("class");else{var n=e.className.split(/ +/),o=n.indexOf(t);-1!==o&&(n.splice(o,1),e.className=n.join(" "))}else e.className=void 0;return X},hasClass:function(e,t){return new RegExp("(?:^|\\s+)"+t+"(?:\\s+|$)").test(e.className)||!1},getWidth:function(e){var t=getComputedStyle(e);return i(t["border-left-width"])+i(t["border-right-width"])+i(t["padding-left"])+i(t["padding-right"])+i(t.width)},getHeight:function(e){var t=getComputedStyle(e);return i(t["border-top-width"])+i(t["border-bottom-width"])+i(t["padding-top"])+i(t["padding-bottom"])+i(t.height)},getOffset:function(e){var t=e,n={left:0,top:0};if(t.offsetParent)do{n.left+=t.offsetLeft,n.top+=t.offsetTop,t=t.offsetParent}while(t);return n},isActive:function(e){return e===document.activeElement&&(e.type||e.href)}},K=function(e){function t(e,n){F(this,t);var o=V(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e,n)),i=o;return o.__prev=o.getValue(),o.__checkbox=document.createElement("input"),o.__checkbox.setAttribute("type","checkbox"),X.bind(o.__checkbox,"change",function(){i.setValue(!i.__prev)},!1),o.domElement.appendChild(o.__checkbox),o.updateDisplay(),o}return D(t,z),P(t,[{key:"setValue",value:function(e){var n=j(t.prototype.__proto__||Object.getPrototypeOf(t.prototype),"setValue",this).call(this,e);return this.__onFinishChange&&this.__onFinishChange.call(this,this.getValue()),this.__prev=this.getValue(),n}},{key:"updateDisplay",value:function(){return!0===this.getValue()?(this.__checkbox.setAttribute("checked","checked"),this.__checkbox.checked=!0,this.__prev=!0):(this.__checkbox.checked=!1,this.__prev=!1),j(t.prototype.__proto__||Object.getPrototypeOf(t.prototype),"updateDisplay",this).call(this)}}]),t}(),Y=function(e){function t(e,n,o){F(this,t);var i=V(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e,n)),r=o,s=i;if(i.__select=document.createElement("select"),S.isArray(r)){var a={};S.each(r,function(e){a[e]=e}),r=a}return S.each(r,function(e,t){var n=document.createElement("option");n.innerHTML=t,n.setAttribute("value",e),s.__select.appendChild(n)}),i.updateDisplay(),X.bind(i.__select,"change",function(){var e=this.options[this.selectedIndex].value;s.setValue(e)}),i.domElement.appendChild(i.__select),i}return D(t,z),P(t,[{key:"setValue",value:function(e){var n=j(t.prototype.__proto__||Object.getPrototypeOf(t.prototype),"setValue",this).call(this,e);return this.__onFinishChange&&this.__onFinishChange.call(this,this.getValue()),n}},{key:"updateDisplay",value:function(){return X.isActive(this.__select)?this:(this.__select.value=this.getValue(),j(t.prototype.__proto__||Object.getPrototypeOf(t.prototype),"updateDisplay",this).call(this))}}]),t}(),J=function(e){function t(e,n){function o(){r.setValue(r.__input.value)}F(this,t);var i=V(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e,n)),r=i;return i.__input=document.createElement("input"),i.__input.setAttribute("type","text"),X.bind(i.__input,"keyup",o),X.bind(i.__input,"change",o),X.bind(i.__input,"blur",function(){r.__onFinishChange&&r.__onFinishChange.call(r,r.getValue())}),X.bind(i.__input,"keydown",function(e){13===e.keyCode&&this.blur()}),i.updateDisplay(),i.domElement.appendChild(i.__input),i}return D(t,z),P(t,[{key:"updateDisplay",value:function(){return X.isActive(this.__input)||(this.__input.value=this.getValue()),j(t.prototype.__proto__||Object.getPrototypeOf(t.prototype),"updateDisplay",this).call(this)}}]),t}(),W=function(e){function t(e,n,o){F(this,t);var i=V(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e,n)),s=o||{};return i.__min=s.min,i.__max=s.max,i.__step=s.step,S.isUndefined(i.__step)?0===i.initialValue?i.__impliedStep=1:i.__impliedStep=Math.pow(10,Math.floor(Math.log(Math.abs(i.initialValue))/Math.LN10))/10:i.__impliedStep=i.__step,i.__precision=r(i.__impliedStep),i}return D(t,z),P(t,[{key:"setValue",value:function(e){var n=e;return void 0!==this.__min&&n<this.__min?n=this.__min:void 0!==this.__max&&n>this.__max&&(n=this.__max),void 0!==this.__step&&n%this.__step!=0&&(n=Math.round(n/this.__step)*this.__step),j(t.prototype.__proto__||Object.getPrototypeOf(t.prototype),"setValue",this).call(this,n)}},{key:"min",value:function(e){return this.__min=e,this}},{key:"max",value:function(e){return this.__max=e,this}},{key:"step",value:function(e){return this.__step=e,this.__impliedStep=e,this.__precision=r(e),this}}]),t}(),Q=function(e){function t(e,n,o){function i(){l.__onFinishChange&&l.__onFinishChange.call(l,l.getValue())}function r(e){var t=d-e.clientY;l.setValue(l.getValue()+t*l.__impliedStep),d=e.clientY}function s(){X.unbind(window,"mousemove",r),X.unbind(window,"mouseup",s),i()}F(this,t);var a=V(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e,n,o));a.__truncationSuspended=!1;var l=a,d=void 0;return a.__input=document.createElement("input"),a.__input.setAttribute("type","text"),X.bind(a.__input,"change",function(){var e=parseFloat(l.__input.value);S.isNaN(e)||l.setValue(e)}),X.bind(a.__input,"blur",function(){i()}),X.bind(a.__input,"mousedown",function(e){X.bind(window,"mousemove",r),X.bind(window,"mouseup",s),d=e.clientY}),X.bind(a.__input,"keydown",function(e){13===e.keyCode&&(l.__truncationSuspended=!0,this.blur(),l.__truncationSuspended=!1,i())}),a.updateDisplay(),a.domElement.appendChild(a.__input),a}return D(t,W),P(t,[{key:"updateDisplay",value:function(){return this.__input.value=this.__truncationSuspended?this.getValue():s(this.getValue(),this.__precision),j(t.prototype.__proto__||Object.getPrototypeOf(t.prototype),"updateDisplay",this).call(this)}}]),t}(),q=function(e){function t(e,n,o,i,r){function s(e){e.preventDefault();var t=_.__background.getBoundingClientRect();return _.setValue(a(e.clientX,t.left,t.right,_.__min,_.__max)),!1}function l(){X.unbind(window,"mousemove",s),X.unbind(window,"mouseup",l),_.__onFinishChange&&_.__onFinishChange.call(_,_.getValue())}function d(e){var t=e.touches[0].clientX,n=_.__background.getBoundingClientRect();_.setValue(a(t,n.left,n.right,_.__min,_.__max))}function c(){X.unbind(window,"touchmove",d),X.unbind(window,"touchend",c),_.__onFinishChange&&_.__onFinishChange.call(_,_.getValue())}F(this,t);var u=V(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e,n,{min:o,max:i,step:r})),_=u;return u.__background=document.createElement("div"),u.__foreground=document.createElement("div"),X.bind(u.__background,"mousedown",function(e){document.activeElement.blur(),X.bind(window,"mousemove",s),X.bind(window,"mouseup",l),s(e)}),X.bind(u.__background,"touchstart",function(e){1===e.touches.length&&(X.bind(window,"touchmove",d),X.bind(window,"touchend",c),d(e))}),X.addClass(u.__background,"slider"),X.addClass(u.__foreground,"slider-fg"),u.updateDisplay(),u.__background.appendChild(u.__foreground),u.domElement.appendChild(u.__background),u}return D(t,W),P(t,[{key:"updateDisplay",value:function(){var e=(this.getValue()-this.__min)/(this.__max-this.__min);return this.__foreground.style.width=100*e+"%",j(t.prototype.__proto__||Object.getPrototypeOf(t.prototype),"updateDisplay",this).call(this)}}]),t}(),Z=function(e){function t(e,n,o){F(this,t);var i=V(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e,n)),r=i;return i.__button=document.createElement("div"),i.__button.innerHTML=void 0===o?"Fire":o,X.bind(i.__button,"click",function(e){return e.preventDefault(),r.fire(),!1}),X.addClass(i.__button,"button"),i.domElement.appendChild(i.__button),i}return D(t,z),P(t,[{key:"fire",value:function(){this.__onChange&&this.__onChange.call(this),this.getValue().call(this.object),this.__onFinishChange&&this.__onFinishChange.call(this,this.getValue())}}]),t}(),$=function(e){function t(e,n){function o(e){u(e),X.bind(window,"mousemove",u),X.bind(window,"touchmove",u),X.bind(window,"mouseup",r),X.bind(window,"touchend",r)}function i(e){_(e),X.bind(window,"mousemove",_),X.bind(window,"touchmove",_),X.bind(window,"mouseup",s),X.bind(window,"touchend",s)}function r(){X.unbind(window,"mousemove",u),X.unbind(window,"touchmove",u),X.unbind(window,"mouseup",r),X.unbind(window,"touchend",r),c()}function s(){X.unbind(window,"mousemove",_),X.unbind(window,"touchmove",_),X.unbind(window,"mouseup",s),X.unbind(window,"touchend",s),c()}function a(){var e=R(this.value);!1!==e?(p.__color.__state=e,p.setValue(p.__color.toOriginal())):this.value=p.__color.toString()}function c(){p.__onFinishChange&&p.__onFinishChange.call(p,p.__color.toOriginal())}function u(e){-1===e.type.indexOf("touch")&&e.preventDefault();var t=p.__saturation_field.getBoundingClientRect(),n=e.touches&&e.touches[0]||e,o=n.clientX,i=n.clientY,r=(o-t.left)/(t.right-t.left),s=1-(i-t.top)/(t.bottom-t.top);return s>1?s=1:s<0&&(s=0),r>1?r=1:r<0&&(r=0),p.__color.v=s,p.__color.s=r,p.setValue(p.__color.toOriginal()),!1}function _(e){-1===e.type.indexOf("touch")&&e.preventDefault();var t=p.__hue_field.getBoundingClientRect(),n=1-((e.touches&&e.touches[0]||e).clientY-t.top)/(t.bottom-t.top);return n>1?n=1:n<0&&(n=0),p.__color.h=360*n,p.setValue(p.__color.toOriginal()),!1}F(this,t);var h=V(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e,n));h.__color=new I(h.getValue()),h.__temp=new I(0);var p=h;h.domElement=document.createElement("div"),X.makeSelectable(h.domElement,!1),h.__selector=document.createElement("div"),h.__selector.className="selector",h.__saturation_field=document.createElement("div"),h.__saturation_field.className="saturation-field",h.__field_knob=document.createElement("div"),h.__field_knob.className="field-knob",h.__field_knob_border="2px solid ",h.__hue_knob=document.createElement("div"),h.__hue_knob.className="hue-knob",h.__hue_field=document.createElement("div"),h.__hue_field.className="hue-field",h.__input=document.createElement("input"),h.__input.type="text",h.__input_textShadow="0 1px 1px ",X.bind(h.__input,"keydown",function(e){13===e.keyCode&&a.call(this)}),X.bind(h.__input,"blur",a),X.bind(h.__selector,"mousedown",function(){X.addClass(this,"drag").bind(window,"mouseup",function(){X.removeClass(p.__selector,"drag")})}),X.bind(h.__selector,"touchstart",function(){X.addClass(this,"drag").bind(window,"touchend",function(){X.removeClass(p.__selector,"drag")})});var f=document.createElement("div");return S.extend(h.__selector.style,{width:"122px",height:"102px",padding:"3px",backgroundColor:"#222",boxShadow:"0px 1px 3px rgba(0,0,0,0.3)"}),S.extend(h.__field_knob.style,{position:"absolute",width:"12px",height:"12px",border:h.__field_knob_border+(h.__color.v<.5?"#fff":"#000"),boxShadow:"0px 1px 3px rgba(0,0,0,0.5)",borderRadius:"12px",zIndex:1}),S.extend(h.__hue_knob.style,{position:"absolute",width:"15px",height:"2px",borderRight:"4px solid #fff",zIndex:1}),S.extend(h.__saturation_field.style,{width:"100px",height:"100px",border:"1px solid #555",marginRight:"3px",display:"inline-block",cursor:"pointer"}),S.extend(f.style,{width:"100%",height:"100%",background:"none"}),l(f,"top","rgba(0,0,0,0)","#000"),S.extend(h.__hue_field.style,{width:"15px",height:"100px",border:"1px solid #555",cursor:"ns-resize",position:"absolute",top:"3px",right:"3px"}),d(h.__hue_field),S.extend(h.__input.style,{outline:"none",textAlign:"center",color:"#fff",border:0,fontWeight:"bold",textShadow:h.__input_textShadow+"rgba(0,0,0,0.7)"}),X.bind(h.__saturation_field,"mousedown",o),X.bind(h.__saturation_field,"touchstart",o),X.bind(h.__field_knob,"mousedown",o),X.bind(h.__field_knob,"touchstart",o),X.bind(h.__hue_field,"mousedown",i),X.bind(h.__hue_field,"touchstart",i),h.__saturation_field.appendChild(f),h.__selector.appendChild(h.__field_knob),h.__selector.appendChild(h.__saturation_field),h.__selector.appendChild(h.__hue_field),h.__hue_field.appendChild(h.__hue_knob),h.domElement.appendChild(h.__input),h.domElement.appendChild(h.__selector),h.updateDisplay(),h}return D(t,z),P(t,[{key:"updateDisplay",value:function(){var e=R(this.getValue());if(!1!==e){var t=!1;S.each(I.COMPONENTS,function(n){if(!S.isUndefined(e[n])&&!S.isUndefined(this.__color.__state[n])&&e[n]!==this.__color.__state[n])return t=!0,{}},this),t&&S.extend(this.__color.__state,e)}S.extend(this.__temp.__state,this.__color.__state),this.__temp.a=1;var n=this.__color.v<.5||this.__color.s>.5?255:0,o=255-n;S.extend(this.__field_knob.style,{marginLeft:100*this.__color.s-7+"px",marginTop:100*(1-this.__color.v)-7+"px",backgroundColor:this.__temp.toHexString(),border:this.__field_knob_border+"rgb("+n+","+n+","+n+")"}),this.__hue_knob.style.marginTop=100*(1-this.__color.h/360)+"px",this.__temp.s=1,this.__temp.v=1,l(this.__saturation_field,"left","#fff",this.__temp.toHexString()),this.__input.value=this.__color.toString(),S.extend(this.__input.style,{backgroundColor:this.__color.toHexString(),color:"rgb("+n+","+n+","+n+")",textShadow:this.__input_textShadow+"rgba("+o+","+o+","+o+",.7)"})}}]),t}(),ee=["-moz-","-o-","-webkit-","-ms-",""],te={load:function(e,t){var n=t||document,o=n.createElement("link");o.type="text/css",o.rel="stylesheet",o.href=e,n.getElementsByTagName("head")[0].appendChild(o)},inject:function(e,t){var n=t||document,o=document.createElement("style");o.type="text/css",o.innerHTML=e;var i=n.getElementsByTagName("head")[0];try{i.appendChild(o)}catch(e){}}},ne=function(e,t){var n=e[t];return S.isArray(arguments[2])||S.isObject(arguments[2])?new Y(e,t,arguments[2]):S.isNumber(n)?S.isNumber(arguments[2])&&S.isNumber(arguments[3])?S.isNumber(arguments[4])?new q(e,t,arguments[2],arguments[3],arguments[4]):new q(e,t,arguments[2],arguments[3]):S.isNumber(arguments[4])?new Q(e,t,{min:arguments[2],max:arguments[3],step:arguments[4]}):new Q(e,t,{min:arguments[2],max:arguments[3]}):S.isString(n)?new J(e,t):S.isFunction(n)?new Z(e,t,""):S.isBoolean(n)?new K(e,t):null},oe=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(e){setTimeout(e,1e3/60)},ie=function(){function e(){F(this,e),this.backgroundElement=document.createElement("div"),S.extend(this.backgroundElement.style,{backgroundColor:"rgba(0,0,0,0.8)",top:0,left:0,display:"none",zIndex:"1000",opacity:0,WebkitTransition:"opacity 0.2s linear",transition:"opacity 0.2s linear"}),X.makeFullscreen(this.backgroundElement),this.backgroundElement.style.position="fixed",this.domElement=document.createElement("div"),S.extend(this.domElement.style,{position:"fixed",display:"none",zIndex:"1001",opacity:0,WebkitTransition:"-webkit-transform 0.2s ease-out, opacity 0.2s linear",transition:"transform 0.2s ease-out, opacity 0.2s linear"}),document.body.appendChild(this.backgroundElement),document.body.appendChild(this.domElement);var t=this;X.bind(this.backgroundElement,"click",function(){t.hide()})}return P(e,[{key:"show",value:function(){var e=this;this.backgroundElement.style.display="block",this.domElement.style.display="block",this.domElement.style.opacity=0,this.domElement.style.webkitTransform="scale(1.1)",this.layout(),S.defer(function(){e.backgroundElement.style.opacity=1,e.domElement.style.opacity=1,e.domElement.style.webkitTransform="scale(1)"})}},{key:"hide",value:function(){var e=this,t=function t(){e.domElement.style.display="none",e.backgroundElement.style.display="none",X.unbind(e.domElement,"webkitTransitionEnd",t),X.unbind(e.domElement,"transitionend",t),X.unbind(e.domElement,"oTransitionEnd",t)};X.bind(this.domElement,"webkitTransitionEnd",t),X.bind(this.domElement,"transitionend",t),X.bind(this.domElement,"oTransitionEnd",t),this.backgroundElement.style.opacity=0,this.domElement.style.opacity=0,this.domElement.style.webkitTransform="scale(1.1)"}},{key:"layout",value:function(){this.domElement.style.left=window.innerWidth/2-X.getWidth(this.domElement)/2+"px",this.domElement.style.top=window.innerHeight/2-X.getHeight(this.domElement)/2+"px"}}]),e}(),re=function(e){if(e&&"undefined"!=typeof window){var t=document.createElement("style");return t.setAttribute("type","text/css"),t.innerHTML=e,document.head.appendChild(t),e}}(".dg ul{list-style:none;margin:0;padding:0;width:100%;clear:both}.dg.ac{position:fixed;top:0;left:0;right:0;height:0;z-index:0}.dg:not(.ac) .main{overflow:hidden}.dg.main{-webkit-transition:opacity .1s linear;-o-transition:opacity .1s linear;-moz-transition:opacity .1s linear;transition:opacity .1s linear}.dg.main.taller-than-window{overflow-y:auto}.dg.main.taller-than-window .close-button{opacity:1;margin-top:-1px;border-top:1px solid #2c2c2c}.dg.main ul.closed .close-button{opacity:1 !important}.dg.main:hover .close-button,.dg.main .close-button.drag{opacity:1}.dg.main .close-button{-webkit-transition:opacity .1s linear;-o-transition:opacity .1s linear;-moz-transition:opacity .1s linear;transition:opacity .1s linear;border:0;line-height:19px;height:20px;cursor:pointer;text-align:center;background-color:#000}.dg.main .close-button.close-top{position:relative}.dg.main .close-button.close-bottom{position:absolute}.dg.main .close-button:hover{background-color:#111}.dg.a{float:right;margin-right:15px;overflow-y:visible}.dg.a.has-save>ul.close-top{margin-top:0}.dg.a.has-save>ul.close-bottom{margin-top:27px}.dg.a.has-save>ul.closed{margin-top:0}.dg.a .save-row{top:0;z-index:1002}.dg.a .save-row.close-top{position:relative}.dg.a .save-row.close-bottom{position:fixed}.dg li{-webkit-transition:height .1s ease-out;-o-transition:height .1s ease-out;-moz-transition:height .1s ease-out;transition:height .1s ease-out;-webkit-transition:overflow .1s linear;-o-transition:overflow .1s linear;-moz-transition:overflow .1s linear;transition:overflow .1s linear}.dg li:not(.folder){cursor:auto;height:27px;line-height:27px;padding:0 4px 0 5px}.dg li.folder{padding:0;border-left:4px solid rgba(0,0,0,0)}.dg li.title{cursor:pointer;margin-left:-4px}.dg .closed li:not(.title),.dg .closed ul li,.dg .closed ul li>*{height:0;overflow:hidden;border:0}.dg .cr{clear:both;padding-left:3px;height:27px;overflow:hidden}.dg .property-name{cursor:default;float:left;clear:left;width:40%;overflow:hidden;text-overflow:ellipsis}.dg .c{float:left;width:60%;position:relative}.dg .c input[type=text]{border:0;margin-top:4px;padding:3px;width:100%;float:right}.dg .has-slider input[type=text]{width:30%;margin-left:0}.dg .slider{float:left;width:66%;margin-left:-5px;margin-right:0;height:19px;margin-top:4px}.dg .slider-fg{height:100%}.dg .c input[type=checkbox]{margin-top:7px}.dg .c select{margin-top:5px}.dg .cr.function,.dg .cr.function .property-name,.dg .cr.function *,.dg .cr.boolean,.dg .cr.boolean *{cursor:pointer}.dg .cr.color{overflow:visible}.dg .selector{display:none;position:absolute;margin-left:-9px;margin-top:23px;z-index:10}.dg .c:hover .selector,.dg .selector.drag{display:block}.dg li.save-row{padding:0}.dg li.save-row .button{display:inline-block;padding:0px 6px}.dg.dialogue{background-color:#222;width:460px;padding:15px;font-size:13px;line-height:15px}#dg-new-constructor{padding:10px;color:#222;font-family:Monaco, monospace;font-size:10px;border:0;resize:none;box-shadow:inset 1px 1px 1px #888;word-wrap:break-word;margin:12px 0;display:block;width:440px;overflow-y:scroll;height:100px;position:relative}#dg-local-explain{display:none;font-size:11px;line-height:17px;border-radius:3px;background-color:#333;padding:8px;margin-top:10px}#dg-local-explain code{font-size:10px}#dat-gui-save-locally{display:none}.dg{color:#eee;
256font:11px 'Lucida Grande', sans-serif;text-shadow:0 -1px 0 #111}.dg.main::-webkit-scrollbar{width:5px;background:#1a1a1a}.dg.main::-webkit-scrollbar-corner{height:0;display:none}.dg.main::-webkit-scrollbar-thumb{border-radius:5px;background:#676767}.dg li:not(.folder){background:#1a1a1a;border-bottom:1px solid #2c2c2c}.dg li.save-row{line-height:25px;background:#dad5cb;border:0}.dg li.save-row select{margin-left:5px;width:108px}.dg li.save-row .button{margin-left:5px;margin-top:1px;border-radius:2px;font-size:9px;line-height:7px;padding:4px 4px 5px 4px;background:#c5bdad;color:#fff;text-shadow:0 1px 0 #b0a58f;box-shadow:0 -1px 0 #b0a58f;cursor:pointer}.dg li.save-row .button.gears{background:#c5bdad url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAANCAYAAAB/9ZQ7AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAQJJREFUeNpiYKAU/P//PwGIC/ApCABiBSAW+I8AClAcgKxQ4T9hoMAEUrxx2QSGN6+egDX+/vWT4e7N82AMYoPAx/evwWoYoSYbACX2s7KxCxzcsezDh3evFoDEBYTEEqycggWAzA9AuUSQQgeYPa9fPv6/YWm/Acx5IPb7ty/fw+QZblw67vDs8R0YHyQhgObx+yAJkBqmG5dPPDh1aPOGR/eugW0G4vlIoTIfyFcA+QekhhHJhPdQxbiAIguMBTQZrPD7108M6roWYDFQiIAAv6Aow/1bFwXgis+f2LUAynwoIaNcz8XNx3Dl7MEJUDGQpx9gtQ8YCueB+D26OECAAQDadt7e46D42QAAAABJRU5ErkJggg==) 2px 1px no-repeat;height:7px;width:8px}.dg li.save-row .button:hover{background-color:#bab19e;box-shadow:0 -1px 0 #b0a58f}.dg li.folder{border-bottom:0}.dg li.title{padding-left:16px;background:#000 url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlI+hKgFxoCgAOw==) 6px 10px no-repeat;cursor:pointer;border-bottom:1px solid rgba(255,255,255,0.2)}.dg .closed li.title{background-image:url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlGIWqMCbWAEAOw==)}.dg .cr.boolean{border-left:3px solid #806787}.dg .cr.color{border-left:3px solid}.dg .cr.function{border-left:3px solid #e61d5f}.dg .cr.number{border-left:3px solid #2FA1D6}.dg .cr.number input[type=text]{color:#2FA1D6}.dg .cr.string{border-left:3px solid #1ed36f}.dg .cr.string input[type=text]{color:#1ed36f}.dg .cr.function:hover,.dg .cr.boolean:hover{background:#111}.dg .c input[type=text]{background:#303030;outline:none}.dg .c input[type=text]:hover{background:#3c3c3c}.dg .c input[type=text]:focus{background:#494949;color:#fff}.dg .c .slider{background:#303030;cursor:ew-resize}.dg .c .slider-fg{background:#2FA1D6;max-width:100%}.dg .c .slider:hover{background:#3c3c3c}.dg .c .slider:hover .slider-fg{background:#44abda}\n");te.inject(re);var se="Default",ae=function(){try{return!!window.localStorage}catch(e){return!1}}(),le=void 0,de=!0,ce=void 0,ue=!1,_e=[],he=function e(t){var n=this,o=t||{};this.domElement=document.createElement("div"),this.__ul=document.createElement("ul"),this.domElement.appendChild(this.__ul),X.addClass(this.domElement,"dg"),this.__folders={},this.__controllers=[],this.__rememberedObjects=[],this.__rememberedObjectIndecesToControllers=[],this.__listening=[],o=S.defaults(o,{closeOnTop:!1,autoPlace:!0,width:e.DEFAULT_WIDTH}),o=S.defaults(o,{resizable:o.autoPlace,hideable:o.autoPlace}),S.isUndefined(o.load)?o.load={preset:se}:o.preset&&(o.load.preset=o.preset),S.isUndefined(o.parent)&&o.hideable&&_e.push(this),o.resizable=S.isUndefined(o.parent)&&o.resizable,o.autoPlace&&S.isUndefined(o.scrollable)&&(o.scrollable=!0);var i=ae&&"true"===localStorage.getItem(m(this,"isLocal")),r=void 0,s=void 0;if(Object.defineProperties(this,{parent:{get:function(){return o.parent}},scrollable:{get:function(){return o.scrollable}},autoPlace:{get:function(){return o.autoPlace}},closeOnTop:{get:function(){return o.closeOnTop}},preset:{get:function(){return n.parent?n.getRoot().preset:o.load.preset},set:function(e){n.parent?n.getRoot().preset=e:o.load.preset=e,E(this),n.revert()}},width:{get:function(){return o.width},set:function(e){o.width=e,w(n,e)}},name:{get:function(){return o.name},set:function(e){o.name=e,s&&(s.innerHTML=o.name)}},closed:{get:function(){return o.closed},set:function(t){o.closed=t,o.closed?X.addClass(n.__ul,e.CLASS_CLOSED):X.removeClass(n.__ul,e.CLASS_CLOSED),this.onResize(),n.__closeButton&&(n.__closeButton.innerHTML=t?e.TEXT_OPEN:e.TEXT_CLOSED)}},load:{get:function(){return o.load}},useLocalStorage:{get:function(){return i},set:function(e){ae&&(i=e,e?X.bind(window,"unload",r):X.unbind(window,"unload",r),localStorage.setItem(m(n,"isLocal"),e))}}}),S.isUndefined(o.parent)){if(o.closed=!1,X.addClass(this.domElement,e.CLASS_MAIN),X.makeSelectable(this.domElement,!1),ae&&i){n.useLocalStorage=!0;var a=localStorage.getItem(m(this,"gui"));a&&(o.load=JSON.parse(a))}this.__closeButton=document.createElement("div"),this.__closeButton.innerHTML=e.TEXT_CLOSED,X.addClass(this.__closeButton,e.CLASS_CLOSE_BUTTON),o.closeOnTop?(X.addClass(this.__closeButton,e.CLASS_CLOSE_TOP),this.domElement.insertBefore(this.__closeButton,this.domElement.childNodes[0])):(X.addClass(this.__closeButton,e.CLASS_CLOSE_BOTTOM),this.domElement.appendChild(this.__closeButton)),X.bind(this.__closeButton,"click",function(){n.closed=!n.closed})}else{void 0===o.closed&&(o.closed=!0);var l=document.createTextNode(o.name);X.addClass(l,"controller-name"),s=c(n,l);X.addClass(this.__ul,e.CLASS_CLOSED),X.addClass(s,"title"),X.bind(s,"click",function(e){return e.preventDefault(),n.closed=!n.closed,!1}),o.closed||(this.closed=!1)}o.autoPlace&&(S.isUndefined(o.parent)&&(de&&(ce=document.createElement("div"),X.addClass(ce,"dg"),X.addClass(ce,e.CLASS_AUTO_PLACE_CONTAINER),document.body.appendChild(ce),de=!1),ce.appendChild(this.domElement),X.addClass(this.domElement,e.CLASS_AUTO_PLACE)),this.parent||w(n,o.width)),this.__resizeHandler=function(){n.onResizeDebounced()},X.bind(window,"resize",this.__resizeHandler),X.bind(this.__ul,"webkitTransitionEnd",this.__resizeHandler),X.bind(this.__ul,"transitionend",this.__resizeHandler),X.bind(this.__ul,"oTransitionEnd",this.__resizeHandler),this.onResize(),o.resizable&&y(this),r=function(){ae&&"true"===localStorage.getItem(m(n,"isLocal"))&&localStorage.setItem(m(n,"gui"),JSON.stringify(n.get
vendor: 5,470 bytes, lines 256-260
256SaveObject()))},this.saveToLocalStorageIfPossible=r,o.parent||function(){var e=n.getRoot();e.width+=1,S.defer(function(){e.width-=1})}()};he.toggleHide=function(){ue=!ue,S.each(_e,function(e){e.domElement.style.display=ue?"none":""})},he.CLASS_AUTO_PLACE="a",he.CLASS_AUTO_PLACE_CONTAINER="ac",he.CLASS_MAIN="main",he.CLASS_CONTROLLER_ROW="cr",he.CLASS_TOO_TALL="taller-than-window",he.CLASS_CLOSED="closed",he.CLASS_CLOSE_BUTTON="close-button",he.CLASS_CLOSE_TOP="close-top",he.CLASS_CLOSE_BOTTOM="close-bottom",he.CLASS_DRAG="drag",he.DEFAULT_WIDTH=245,he.TEXT_CLOSED="Close Controls",he.TEXT_OPEN="Open Controls",he._keydownHandler=function(e){"text"===document.activeElement.type||72!==e.which&&72!==e.keyCode||he.toggleHide()},X.bind(window,"keydown",he._keydownHandler,!1),S.extend(he.prototype,{add:function(e,t){return f(this,e,t,{factoryArgs:Array.prototype.slice.call(arguments,2)})},addColor:function(e,t){return f(this,e,t,{color:!0})},remove:function(e){this.__ul.removeChild(e.__li),this.__controllers.splice(this.__controllers.indexOf(e),1);var t=this;S.defer(function(){t.onResize()})},destroy:function(){if(this.parent)throw new Error("Only the root GUI should be removed with .destroy(). For subfolders, use gui.removeFolder(folder) instead.");this.autoPlace&&ce.removeChild(this.domElement);var e=this;S.each(this.__folders,function(t){e.removeFolder(t)}),X.unbind(window,"keydown",he._keydownHandler,!1),u(this)},addFolder:function(e){if(void 0!==this.__folders[e])throw new Error('You already have a folder in this GUI by the name "'+e+'"');var t={name:e,parent:this};t.autoPlace=this.autoPlace,this.load&&this.load.folders&&this.load.folders[e]&&(t.closed=this.load.folders[e].closed,t.load=this.load.folders[e]);var n=new he(t);this.__folders[e]=n;var o=c(this,n.domElement);return X.addClass(o,"folder"),n},removeFolder:function(e){this.__ul.removeChild(e.domElement.parentElement),delete this.__folders[e.name],this.load&&this.load.folders&&this.load.folders[e.name]&&delete this.load.folders[e.name],u(e);var t=this;S.each(e.__folders,function(t){e.removeFolder(t)}),S.defer(function(){t.onResize()})},open:function(){this.closed=!1},close:function(){this.closed=!0},onResize:function(){var e=this.getRoot();if(e.scrollable){var t=X.getOffset(e.__ul).top,n=0;S.each(e.__ul.childNodes,function(t){e.autoPlace&&t===e.__save_row||(n+=X.getHeight(t))}),window.innerHeight-t-20<n?(X.addClass(e.domElement,he.CLASS_TOO_TALL),e.__ul.style.height=window.innerHeight-t-20+"px"):(X.removeClass(e.domElement,he.CLASS_TOO_TALL),e.__ul.style.height="auto")}e.__resize_handle&&S.defer(function(){e.__resize_handle.style.height=e.__ul.offsetHeight+"px"}),e.__closeButton&&(e.__closeButton.style.width=e.width+"px")},onResizeDebounced:S.debounce(function(){this.onResize()},50),remember:function(){if(S.isUndefined(le)&&((le=new ie).domElement.innerHTML='<div id="dg-save" class="dg dialogue">\n\n Here\'s the new load parameter for your <code>GUI</code>\'s constructor:\n\n <textarea id="dg-new-constructor"></textarea>\n\n <div id="dg-save-locally">\n\n <input id="dg-local-storage" type="checkbox"/> Automatically save\n values to <code>localStorage</code> on exit.\n\n <div id="dg-local-explain">The values saved to <code>localStorage</code> will\n override those passed to <code>dat.GUI</code>\'s constructor. This makes it\n easier to work incrementally, but <code>localStorage</code> is fragile,\n and your friends may not see the same values you do.\n\n </div>\n\n </div>\n\n</div>'),this.parent)throw new Error("You can only call remember on a top level GUI.");var e=this;S.each(Array.prototype.slice.call(arguments),function(t){0===e.__rememberedObjects.length&&v(e),-1===e.__rememberedObjects.indexOf(t)&&e.__rememberedObjects.push(t)}),this.autoPlace&&w(this,this.width)},getRoot:function(){for(var e=this;e.parent;)e=e.parent;return e},getSaveObject:function(){var e=this.load;return e.closed=this.closed,this.__rememberedObjects.length>0&&(e.preset=this.preset,e.remembered||(e.remembered={}),e.remembered[this.preset]=x(this)),e.folders={},S.each(this.__folders,function(t,n){e.folders[n]=t.getSaveObject()}),e},save:function(){this.load.remembered||(this.load.remembered={}),this.load.remembered[this.preset]=x(this),_(this,!1),this.saveToLocalStorageIfPossible()},saveAs:function(e){this.load.remembered||(this.load.remembered={},this.load.remembered[se]=x(this,!0)),this.load.remembered[e]=x(this),this.preset=e,g(this,e,!0),this.saveToLocalStorageIfPossible()},revert:function(e){S.each(this.__controllers,function(t){this.getRoot().load.remembered?p(e||this.getRoot(),t):t.setValue(t.initialValue),t.__onFinishChange&&t.__onFinishChange.call(t,t.getValue())},this),S.each(this.__folders,function(e){e.revert(e)}),e||_(this.getRoot(),!1)},listen:function(e){var t=0===this.__listening.length;this.__listening.push(e),t&&C(this.__listening)},updateDisplay:function(){S.each(this.__controllers,function(e){e.updateDisplay()}),S.each(this.__folders,function(e){e.updateDisplay()})}});var pe={Color:I,math:N,interpret:R},fe={Controller:z,BooleanController:K,OptionController:Y,StringController:J,NumberController:W,NumberControllerBox:Q,NumberControllerSlider:q,FunctionController:Z,ColorController:$},me={dom:X},ge={GUI:he},be=he,ve={color:pe,controllers:fe,dom:me,gui:ge,GUI:be};e.color=pe,e.controllers=fe,e.dom=me,e.gui=ge,e.GUI=be,e.default=ve,Object.defineProperty(e,"__esModule",{value:!0})}); 257 258 259/***/ }), 260
261/***/ "./js/sub/silencio_anim.js": 262/*!*********************************!*\ 263 !*** ./js/sub/silencio_anim.js ***! 264 \*********************************/ 265/*! no exports provided */ 266/***/ (function(module, __webpack_exports__, __webpack_require__) { 267 268"use strict"; 269__webpack_require__.r(__webpack_exports__); 270/* harmony import */ var _dat_gui_min_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./dat.gui.min.js */ "./js/sub/dat.gui.min.js"); 271/* harmony import */ var _dat_gui_min_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_dat_gui_min_js__WEBPACK_IMPORTED_MODULE_0__); 272 273 274'use strict'; 275 276 277// Simulation code 278 279var canvas = document.getElementsByTagName('canvas')[0]; 280resizeCanvas(); 281 282var config = { 283 284 SIM_RESOLUTION: 512, 285 DYE_RESOLUTION: 512, 286 CAPTURE_RESOLUTION: 512, 287 DENSITY_DISSIPATION: 3.5, 288 VELOCITY_DISSIPATION: 2.5, 289 PRESSURE: 0.68, 290 PRESSURE_ITERATIONS: 10, 291 CURL: 0.5, 292 SPLAT_RADIUS: 2.8, 293 SPLAT_FORCE: 5000, 294 SHADING: false, 295 COLORFUL: false, 296 COLOR_UPDATE_SPEED: 20, 297 PAUSED: false, 298 // BACK_COLOR: { r: 0, g: 0, b: 0 }, 299 BACK_COLOR: { r: 242, g: 242, b: 242 }, 300 TRANSPARENT: false, 301 BLOOM: false, 302 BLOOM_ITERATIONS: 8, 303 BLOOM_RESOLUTION: 256, 304 BLOOM_INTENSITY: 0.8, 305 BLOOM_THRESHOLD: 0.6, 306 BLOOM_SOFT_KNEE: 0.7, 307 SUNRAYS: true, 308 SUNRAYS_RESOLUTION: 196, 309 SUNRAYS_WEIGHT: 0.7, 310 // SIM_RESOLUTION: 128, 311 // DYE_RESOLUTION: 1024, 312 // CAPTURE_RESOLUTION: 512, 313 // DENSITY_DISSIPATION: 3.4, 314 // VELOCITY_DISSIPATION: 4, 315 // PRESSURE: 0.8, 316 // PRESSURE_ITERATIONS: 20, 317 // CURL: 30, 318 // SPLAT_RADIUS: 1, 319 // SPLAT_FORCE: 6000, 320 // SHADING: false, 321 // COLORFUL: false, 322 // COLOR_UPDATE_SPEED: 1, 323 // PAUSED: false, 324 // BACK_COLOR: { r: 242, g: 242, b: 242 }, 325 // TRANSPARENT: false, 326 // BLOOM: false, 327 // BLOOM_ITERATIONS: 8, 328 // BLOOM_RESOLUTION: 256, 329 // BLOOM_INTENSITY: 0.8, 330 // BLOOM_THRESHOLD: 0.6, 331 // BLOOM_SOFT_KNEE: 0.7, 332 // SUNRAYS: false, 333 // SUNRAYS_RESOLUTION: 196, 334 // SUNRAYS_WEIGHT: 1.0, 335} 336 337const THECOLOR = { 338 r: 255, 339 g: 89, 340 b: 91 341}; 342 343 // r: .9, 344 // g: .349, 345 // b: .3568 346 347function pointerPrototype () { 348 this.id = -1; 349 this.texcoordX = 0.5; //scaleByPixelRatio(canvas.clientWidth); 350 this.texcoordY = 0.5; //scaleByPixelRatio(canvas.clientWidth); 351 this.prevTexcoordX = 0.5; //scaleByPixelRatio(canvas.clientWidth); 352 this.prevTexcoordY = 0.5; //scaleByPixelRatio(canvas.clientHeight); 353 this.deltaX = 0; 354 this.deltaY = 0; 355 this.down = true; 356 this.moved = true; 357 // this.color = [30, 0, 0]; 358 this.color = THECOLOR; 359} 360 361var pointers = []; 362var splatStack = []; 363 364// setTimeout(function(){ 365 pointers.push(new pointerPrototype()); 366 console.log(pointers[0]); 367 368 window.pointer = pointers[0]; 369// }, 200); 370 371window.posX = scaleByPixelRatio(canvas.clientWidth / 2); 372window.posY = scaleByPixelRatio(canvas.clientHeight / 2); 373updatePointerMoveData(pointers[0], window.posX, window.posY); 374console.log(window.posX, window.posY); 375 376var ref = getWebGLContext(canvas); 377var gl = ref.gl; 378var ext = ref.ext; 379 380// if (isMobile()) { 381// config.DYE_RESOLUTION = 512; 382// } 383// if (!ext.supportLinearFiltering) { 384// config.DYE_RESOLUTION = 512; 385// config.SHADING = false; 386// config.BLOOM = false; 387// config.SUNRAYS = false; 388// } 389 390// startGUI(); 391 392function getWebGLContext (canvas) { 393 var params = { alpha: true, depth: false, stencil: false, antialias: false, preserveDrawingBuffer: false }; 394 395 var gl = canvas.getContext('webgl2', params); 396 var isWebGL2 = !!gl; 397 if (!isWebGL2) 398 { gl = canvas.getContext('webgl', params) || canvas.getContext('experimental-webgl', params); } 399 400 var halfFloat; 401 var supportLinearFiltering; 402 if (isWebGL2) { 403 gl.getExtension('EXT_color_buffer_float'); 404 supportLinearFiltering = gl.getExtension('OES_texture_float_linear'); 405 } else { 406 halfFloat = gl.getExtension('OES_texture_half_float'); 407 supportLinearFiltering = gl.getExtension('OES_texture_half_float_linear'); 408 } 409 410 gl.clearColor(0.0, 0.0, 0.0, 1.0); 411 412 var halfFloatTexType = isWebGL2 ? gl.HALF_FLOAT : halfFloat.HALF_FLOAT_OES; 413 var formatRGBA; 414 var formatRG; 415 var formatR; 416 417 if (isWebGL2) 418 {
419 formatRGBA = getSupportedFormat(gl, gl.RGBA16F, gl.RGBA, halfFloatTexType); 420 formatRG = getSupportedFormat(gl, gl.RG16F, gl.RG, halfFloatTexType); 421 formatR = getSupportedFormat(gl, gl.R16F, gl.RED, halfFloatTexType); 422 } 423 else 424 { 425 formatRGBA = getSupportedFormat(gl, gl.RGBA, gl.RGBA, halfFloatTexType); 426 formatRG = getSupportedFormat(gl, gl.RGBA, gl.RGBA, halfFloatTexType); 427 formatR = getSupportedFormat(gl, gl.RGBA, gl.RGBA, halfFloatTexType); 428 } 429 430 // ga('send', 'event', isWebGL2 ? 'webgl2' : 'webgl', formatRGBA == null ? 'not supported' : 'supported'); 431 432 return { 433 gl: gl, 434 ext: { 435 formatRGBA: formatRGBA, 436 formatRG: formatRG, 437 formatR: formatR, 438 halfFloatTexType: halfFloatTexType, 439 supportLinearFiltering: supportLinearFiltering 440 } 441 }; 442} 443 444function getSupportedFormat (gl, internalFormat, format, type) 445{ 446 if (!supportRenderTextureFormat(gl, internalFormat, format, type)) 447 { 448 switch (internalFormat) 449 { 450 case gl.R16F: 451 return getSupportedFormat(gl, gl.RG16F, gl.RG, type); 452 case gl.RG16F: 453 return getSupportedFormat(gl, gl.RGBA16F, gl.RGBA, type); 454 default: 455 return null; 456 } 457 } 458 459 return { 460 internalFormat: internalFormat, 461 format: format 462 } 463} 464 465function supportRenderTextureFormat (gl, internalFormat, format, type) { 466 var texture = gl.createTexture(); 467 gl.bindTexture(gl.TEXTURE_2D, texture); 468 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); 469 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); 470 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); 471 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); 472 gl.texImage2D(gl.TEXTURE_2D, 0, internalFormat, 4, 4, 0, format, type, null); 473 474 var fbo = gl.createFramebuffer(); 475 gl.bindFramebuffer(gl.FRAMEBUFFER, fbo); 476 gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0); 477 478 var status = gl.checkFramebufferStatus(gl.FRAMEBUFFER); 479 return status == gl.FRAMEBUFFER_COMPLETE; 480} 481 482function startGUI () { 483 var gui = new _dat_gui_min_js__WEBPACK_IMPORTED_MODULE_0___default.a.GUI({ width: 300 }); 484 gui.add(config, 'DYE_RESOLUTION', { 'high': 1024, 'medium': 512, 'low': 256, 'very low': 128 }).name('quality').onFinishChange(initFramebuffers); 485 gui.add(config, 'SIM_RESOLUTION', { '32': 32, '64': 64, '128': 128, '256': 256 }).name('sim resolution').onFinishChange(initFramebuffers); 486 gui.add(config, 'DENSITY_DISSIPATION', 0, 4.0).name('density diffusion'); 487 gui.add(config, 'VELOCITY_DISSIPATION', 0, 6.0).name('velocity diffusion'); 488 gui.add(config, 'PRESSURE', 0.0, 1.0).name('pressure'); 489 gui.add(config, 'CURL', 0, 50).name('vorticity').step(1); 490 gui.add(config, 'SPLAT_RADIUS', 0.01, 4.0).name('splat radius'); 491 gui.add(config, 'SPLAT_FORCE', 50, 10000).name('splat force'); 492 gui.add(config, 'SHADING').name('shading').onFinishChange(updateKeywords); 493 gui.add(config, 'COLORFUL').name('colorful'); 494 gui.add(config, 'PAUSED').name('paused').listen(); 495 496 gui.add({ fun: function () { 497 splatStack.push(parseInt(Math.random() * 20) + 5); 498 } }, 'fun').name('Random splats'); 499 500 var bloomFolder = gui.addFolder('Bloom'); 501 bloomFolder.add(config, 'BLOOM').name('enabled').onFinishChange(updateKeywords); 502 bloomFolder.add(config, 'BLOOM_INTENSITY', 0.1, 2.0).name('intensity'); 503 bloomFolder.add(config, 'BLOOM_THRESHOLD', 0.0, 1.0).name('threshold'); 504 505 var sunraysFolder = gui.addFolder('Sunrays'); 506 sunraysFolder.add(config, 'SUNRAYS').name('enabled').onFinishChange(updateKeywords); 507 sunraysFolder.add(config, 'SUNRAYS_WEIGHT', 0.3, 1.0).name('weight'); 508 509 var captureFolder = gui.addFolder('Capture'); 510 captureFolder.addColor(config, 'BACK_COLOR').name('background color'); 511 captureFolder.add(config, 'TRANSPARENT').name('transparent'); 512 captureFolder.add({ fun: captureScreenshot }, 'fun').name('take screenshot'); 513 514 gui.close(); 515} 516 517function isMobile () { 518 return /Mobi|Android/i.test(navigator.userAgent); 519} 520 521function captureScreenshot () { 522 var res = getResolution(config.CAPTURE_RESOLUTION); 523 var target = createFBO(res.width, res.height, ext.formatRGBA.internalFormat, ext.formatRGBA.format, ext.halfFloatTexType, gl.NEAREST); 524 render(target); 525 526 var texture = framebufferToTexture(target); 527 texture = normalizeTexture(texture, target.width, target.height); 528 529 var captureCanvas = textureToCanvas(texture, target.width, target.height); 530 var datauri = captureCanvas.toDataURL(); 531 downloadURI('fluid.png', datauri); 532 URL.revokeObjectURL(datauri); 533} 534 535function framebufferToTexture (target) { 536 gl.bindFramebuffer(gl.FRAMEBUFFER, target.fbo); 537 var length = target.width * target.height * 4; 538 var texture = new Float32Array(length); 539 gl.readPixels(0, 0, target.width, target.height, gl.RGBA, gl.FLOAT, texture); 540 return texture; 541} 542 543function normalizeTexture (texture, width, height) { 544 var result = new Uint8Array(texture.length); 545 var id = 0; 546 for (var i = height - 1; i >= 0; i--) { 547 for (var j = 0; j < width; j++) { 548 var nid = i * width * 4 + j * 4; 549 result[nid + 0] = clamp01(texture[id + 0]) * 255; 550 result[nid + 1] = clamp01(texture[id + 1]) * 255; 551 result[nid + 2] = clamp01(texture[id + 2]) * 255; 552 result[nid + 3] = clamp01(texture[id + 3]) * 255; 553 id += 4; 554 } 555 } 556 return result; 557} 558 559function clamp01 (input) { 560 return Math.min(Math.max(input, 0), 1); 561} 562 563function textureToCanvas (texture, width, height) { 564 var captureCanvas = document.createElement('canvas'); 565 var ctx = captureCanvas.getContext('2d'); 566 captureCanvas.width = width; 567 captureCanvas.height = height; 568 569 var imageData = ctx.createImageData(width, height); 570 imageData.data.set(texture); 571 ctx.putImageData(imageData, 0, 0); 572 573 return captureCanvas; 574} 575 576function downloadURI (filename, uri) { 577 var link = document.createElement('a'); 578 link.download = filename; 579 link.href = uri; 580 document.body.appendChild(link); 581 link.click(); 582 document.body.removeChild(link); 583} 584 585var Material = function Material (vertexShader, fragmentShaderSource) { 586 this.vertexShader = vertexShader; 587 this.fragmentShaderSource = fragmentShaderSource; 588 this.programs = []; 589 this.activeProgram = null; 590 this.uniforms = []; 591}; 592 593Material.prototype.setKeywords = function setKeywords (keywords) { 594 var hash = 0; 595 for (var i = 0; i < keywords.length; i++) 596 { hash += hashCode(keywords[i]); } 597 598 var program = this.programs[hash]; 599 if (program == null) 600 { 601 var fragmentShader = compileShader(gl.FRAGMENT_SHADER, this.fragmentShaderSource, keywords); 602 program = createProgram(this.vertexShader, fragmentShader); 603 this.programs[hash] = program; 604 } 605 606 if (program == this.activeProgram) { return; } 607 608 this.uniforms = getUniforms(program); 609 this.activeProgram = program; 610}; 611 612Material.prototype.bind = function bind () { 613 gl.useProgram(this.activeProgram); 614}; 615 616var Program = function Program (vertexShader, fragmentShader) { 617 this.uniforms = {}; 618 this.program = createProgram(vertexShader, fragmentShader); 619 this.uniforms = getUniforms(this.program); 620}; 621 622Program.prototype.bind = function bind () { 623 gl.useProgram(this.program); 624}; 625 626function createProgram (vertexShader, fragmentShader) { 627 var program = gl.createProgram(); 628 gl.attachShader(program, vertexShader); 629 gl.attachShader(program, fragmentShader); 630 gl.linkProgram(program); 631 632 if (!gl.getProgramParameter(program, gl.LINK_STATUS)) 633 { throw gl.getProgramInfoLog(program); } 634 635 return program; 636} 637 638function getUniforms (program) { 639 var uniforms = []; 640 var uniformCount = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS); 641 for (var i = 0; i < uniformCount; i++) { 642 var uniformName = gl.getActiveUniform(program, i).name; 643 uniforms[uniformName] = gl.getUniformLocation(program, uniformName); 644 } 645 return uniforms; 646} 647 648function compileShader (type, source, keywords) { 649 source = addKeywords(source, keywords); 650 651 var shader = gl.createShader(type); 652 gl.shaderSource(shader, source); 653 gl.compileShader(shader); 654 655 if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) 656 { throw gl.getShaderInfoLog(shader); } 657 658 return shader; 659}; 660 661function addKeywords (source, keywords) { 662 if (keywords == null) { return source; } 663 var keywordsString = ''; 664 keywords.forEach(function (keyword) { 665 keywordsString += '#define ' + keyword + '\n'; 666 }); 667 return keywordsString + source; 668} 669 670var baseVertexShader = compileShader(gl.VERTEX_SHADER, ` 671 precision highp float; 672 673 attribute vec2 aPosition; 674 varying vec2 vUv; 675 varying vec2 vL; 676 varying vec2 vR; 677 varying vec2 vT; 678 varying vec2 vB; 679 uniform vec2 texelSize; 680 681 void main () { 682 vUv = aPosition * 0.5 + 0.5;
683 vL = vUv - vec2(texelSize.x, 0.0); 684 vR = vUv + vec2(texelSize.x, 0.0); 685 vT = vUv + vec2(0.0, texelSize.y); 686 vB = vUv - vec2(0.0, texelSize.y); 687 gl_Position = vec4(aPosition, 0.0, 1.0); 688 } 689`); 690 691var blurVertexShader = compileShader(gl.VERTEX_SHADER, ` 692 precision highp float; 693 694 attribute vec2 aPosition; 695 varying vec2 vUv; 696 varying vec2 vL; 697 varying vec2 vR; 698 uniform vec2 texelSize; 699 700 void main () { 701 vUv = aPosition * 0.5 + 0.5; 702 float offset = 1.33333333; 703 vL = vUv - texelSize * offset; 704 vR = vUv + texelSize * offset; 705 gl_Position = vec4(aPosition, 0.0, 1.0); 706 } 707`); 708 709var blurShader = compileShader(gl.FRAGMENT_SHADER, ` 710 precision mediump float; 711 precision mediump sampler2D; 712 713 varying vec2 vUv; 714 varying vec2 vL; 715 varying vec2 vR; 716 uniform sampler2D uTexture; 717 718 void main () { 719 vec4 sum = texture2D(uTexture, vUv) * 0.29411764; 720 sum += texture2D(uTexture, vL) * 0.50294117; 721 sum += texture2D(uTexture, vR) * 0.50294117; 722 gl_FragColor = sum; 723 } 724`); 725 726var copyShader = compileShader(gl.FRAGMENT_SHADER, ` 727 precision mediump float; 728 precision mediump sampler2D; 729 730 varying highp vec2 vUv; 731 uniform sampler2D uTexture; 732 733 void main () { 734 gl_FragColor = texture2D(uTexture, vUv); 735 } 736`); 737 738var clearShader = compileShader(gl.FRAGMENT_SHADER, ` 739 precision mediump float; 740 precision mediump sampler2D; 741 742 varying highp vec2 vUv; 743 uniform sampler2D uTexture; 744 uniform float value; 745 746 void main () { 747 gl_FragColor = value * texture2D(uTexture, vUv); 748 } 749`); 750 751var colorShader = compileShader(gl.FRAGMENT_SHADER, ` 752 precision mediump float; 753 754 uniform vec4 color; 755 756 void main () { 757 gl_FragColor = color; 758 } 759`); 760 761var checkerboardShader = compileShader(gl.FRAGMENT_SHADER, ` 762 precision highp float; 763 precision highp sampler2D; 764 765 varying vec2 vUv; 766 uniform sampler2D uTexture; 767 uniform float aspectRatio; 768 769 #define SCALE 25.0 770 771 void main () { 772 vec2 uv = floor(vUv * SCALE * vec2(aspectRatio, 1.0)); 773 float v = mod(uv.x + uv.y, 2.0); 774 v = v * 0.1 + 0.8; 775 gl_FragColor = vec4(vec3(v), 1.0); 776 } 777`); 778 779var displayShaderSource = ` 780 precision highp float; 781 precision highp sampler2D; 782 783 varying vec2 vUv; 784 varying vec2 vL; 785 varying vec2 vR; 786 varying vec2 vT; 787 varying vec2 vB; 788 uniform sampler2D uTexture; 789 uniform sampler2D uBloom; 790 uniform sampler2D uSunrays; 791 uniform sampler2D uDithering; 792 uniform vec2 ditherScale; 793 uniform vec2 texelSize; 794 795 vec3 linearToGamma (vec3 color) { 796 color = max(color, vec3(0)); 797 return max(1.055 * pow(color, vec3(0.416666667)) - 0.055, vec3(0)); 798 } 799 800 void main () { 801 vec3 c = texture2D(uTexture, vUv).rgb; 802 803 #ifdef SHADING 804 vec3 lc = texture2D(uTexture, vL).rgb; 805 vec3 rc = texture2D(uTexture, vR).rgb; 806 vec3 tc = texture2D(uTexture, vT).rgb; 807 vec3 bc = texture2D(uTexture, vB).rgb; 808 809 float dx = length(rc) - length(lc); 810 float dy = length(tc) - length(bc); 811 812 vec3 n = normalize(vec3(dx, dy, length(texelSize))); 813 vec3 l = vec3(0.0, 0.0, 1.0); 814 815 float diffuse = clamp(dot(n, l) + 0.7, 0.7, 1.0); 816 c *= diffuse; 817 #endif 818 819 #ifdef BLOOM 820 vec3 bloom = texture2D(uBloom, vUv).rgb; 821 #endif 822 823 #ifdef SUNRAYS 824 float sunrays = texture2D(uSunrays, vUv).r; 825 c *= sunrays; 826 #ifdef BLOOM 827 bloom *= sunrays; 828 #endif 829 #endif 830 831 #ifdef BLOOM 832 float noise = texture2D(uDithering, vUv * ditherScale).r; 833 noise = noise * 2.0 - 1.0; 834 bloom += noise / 255.0; 835 bloom = linearToGamma(bloom); 836 c += bloom; 837 #endif 838 839 float a = max(c.r, max(c.g, c.b)); 840 gl_FragColor = vec4(c, a); 841 } 842`; 843 844var bloomPrefilterShader = compileShader(gl.FRAGMENT_SHADER, ` 845 precision mediump float; 846 precision mediump sampler2D; 847 848 varying vec2 vUv; 849 uniform sampler2D uTexture; 850 uniform vec3 curve; 851 uniform float threshold; 852 853 void main () { 854 vec3 c = texture2D(uTexture, vUv).rgb; 855 float br = max(c.r, max(c.g, c.b)); 856 float rq = clamp(br - curve.x, 0.0, curve.y); 857 rq = curve.z * rq * rq; 858 c *= max(rq, br - threshold) / max(br, 0.0001); 859 gl_FragColor = vec4(c, 0.0); 860 } 861`); 862 863var bloomBlurShader = compileShader(gl.FRAGMENT_SHADER, ` 864 precision mediump float; 865 precision mediump sampler2D; 866 867 varying vec2 vL; 868 varying vec2 vR; 869 varying vec2 vT; 870 varying vec2 vB; 871 uniform sampler2D uTexture; 872 873 void main () { 874 vec4 sum = vec4(0.0); 875 sum += texture2D(uTexture, vL); 876 sum += texture2D(uTexture, vR); 877 sum += texture2D(uTexture, vT); 878 sum += texture2D(uTexture, vB); 879 sum *= 0.25; 880 gl_FragColor = sum; 881 } 882`); 883 884var bloomFinalShader = compileShader(gl.FRAGMENT_SHADER, ` 885 precision mediump float; 886 precision mediump sampler2D; 887 888 varying vec2 vL; 889 varying vec2 vR; 890 varying vec2 vT; 891 varying vec2 vB; 892 uniform sampler2D uTexture; 893 uniform float intensity; 894 895 void main () { 896 vec4 sum = vec4(0.0); 897 sum += texture2D(uTexture, vL); 898 sum += texture2D(uTexture, vR); 899 sum += texture2D(uTexture, vT); 900 sum += texture2D(uTexture, vB); 901 sum *= 0.25; 902 gl_FragColor = sum * intensity; 903 } 904`); 905 906var sunraysMaskShader = compileShader(gl.FRAGMENT_SHADER, ` 907 precision highp float; 908 precision highp sampler2D; 909 910 varying vec2 vUv; 911 uniform sampler2D uTexture; 912 913 void main () { 914 vec4 c = texture2D(uTexture, vUv); 915 float br = max(c.r, max(c.g, c.b)); 916 c.a = 1.0 - min(max(br * 20.0, 0.0), 0.8); 917 gl_FragColor = c; 918 } 919`); 920 921var sunraysShader = compileShader(gl.FRAGMENT_SHADER, ` 922 precision highp float; 923 precision highp sampler2D; 924 925 varying vec2 vUv; 926 uniform sampler2D uTexture; 927 uniform float weight; 928 929 #define ITERATIONS 16 930 931 void main () { 932 float Density = 0.3; 933 float Decay = 0.95; 934 float Exposure = 0.7; 935 936 vec2 coord = vUv; 937 vec2 dir = vUv - 0.5; 938 939 dir *= 1.0 / float(ITERATIONS) * Density; 940 float illuminationDecay = 1.0; 941 942 float color = texture2D(uTexture, vUv).a; 943 944 for (int i = 0; i < ITERATIONS; i++) 945 { 946 coord -= dir; 947 float col = texture2D(uTexture, coord).a; 948 color += col * illuminationDecay * weight; 949 illuminationDecay *= Decay; 950 } 951 952 gl_FragColor = vec4(color * Exposure, 0.0, 0.0, 1.0); 953 } 954`); 955 956var splatShader = compileShader(gl.FRAGMENT_SHADER, ` 957 precision highp float; 958 precision highp sampler2D; 959 960 varying vec2 vUv; 961 uniform sampler2D uTarget; 962 uniform float aspectRatio; 963 uniform vec3 color; 964 uniform vec2 point; 965 uniform float radius; 966 967 void main () { 968 vec2 p = vUv - point.xy; 969 p.x *= aspectRatio; 970 vec3 splat = exp(-dot(p, p) / radius) * min(color, vec3(.07, .015, .015)); 971 vec3 base = texture2D(uTarget, vUv).xyz; 972 gl_FragColor = vec4(base + splat, 1.0); 973 } 974`); 975 976// MAXIMUM RED VALUES 977// 1, 978// .349, 979// .3568 980 981var advectionShader = compileShader(gl.FRAGMENT_SHADER, ` 982 precision highp float; 983 precision highp sampler2D; 984 985 varying vec2 vUv; 986 uniform sampler2D uVelocity; 987 uniform sampler2D uSource; 988 uniform vec2 texelSize; 989 uniform vec2 dyeTexelSize; 990 uniform float dt; 991 uniform float dissipation; 992 993 vec4 bilerp (sampler2D sam, vec2 uv, vec2 tsize) { 994 vec2 st = uv / tsize - 0.5; 995 996 vec2 iuv = floor(st); 997 vec2 fuv = fract(st); 998 999 vec4 a = texture2D(sam, (iuv + vec2(0.5, 0.5)) * tsize); 1000 vec4 b = texture2D(sam, (iuv + vec2(1.5, 0.5)) * tsize); 1001 vec4 c = texture2D(sam, (iuv + vec2(0.5, 1.5)) * tsize); 1002 vec4 d = texture2D(sam, (iuv + vec2(1.5, 1.5)) * tsize); 1003 1004 return mix(mix(a, b, fuv.x), mix(c, d, fuv.x), fuv.y); 1005 } 1006 1007 void main () {
1008 #ifdef MANUAL_FILTERING 1009 vec2 coord = vUv - dt * bilerp(uVelocity, vUv, texelSize).xy * texelSize; 1010 vec4 result = bilerp(uSource, coord, dyeTexelSize); 1011 #else 1012 vec2 coord = vUv - dt * texture2D(uVelocity, vUv).xy * texelSize; 1013 vec4 result = texture2D(uSource, coord); 1014 #endif 1015 float decay = 1.0 + dissipation * dt; 1016 gl_FragColor = result / decay; 1017 }`, 1018 ext.supportLinearFiltering ? null : ['MANUAL_FILTERING'] 1019); 1020 1021var divergenceShader = compileShader(gl.FRAGMENT_SHADER, ` 1022 precision mediump float; 1023 precision mediump sampler2D; 1024 1025 varying highp vec2 vUv; 1026 varying highp vec2 vL; 1027 varying highp vec2 vR; 1028 varying highp vec2 vT; 1029 varying highp vec2 vB; 1030 uniform sampler2D uVelocity; 1031 1032 void main () { 1033 float L = texture2D(uVelocity, vL).x; 1034 float R = texture2D(uVelocity, vR).x; 1035 float T = texture2D(uVelocity, vT).y; 1036 float B = texture2D(uVelocity, vB).y; 1037 1038 vec2 C = texture2D(uVelocity, vUv).xy; 1039 if (vL.x < 0.0) { L = -C.x; } 1040 if (vR.x > 1.0) { R = -C.x; } 1041 if (vT.y > 1.0) { T = -C.y; } 1042 if (vB.y < 0.0) { B = -C.y; } 1043 1044 float div = 0.5 * (R - L + T - B); 1045 gl_FragColor = vec4(div, 0.0, 0.0, 1.0); 1046 } 1047`); 1048 1049var curlShader = compileShader(gl.FRAGMENT_SHADER, ` 1050 precision mediump float; 1051 precision mediump sampler2D; 1052 1053 varying highp vec2 vUv; 1054 varying highp vec2 vL; 1055 varying highp vec2 vR; 1056 varying highp vec2 vT; 1057 varying highp vec2 vB; 1058 uniform sampler2D uVelocity; 1059 1060 void main () { 1061 float L = texture2D(uVelocity, vL).y; 1062 float R = texture2D(uVelocity, vR).y; 1063 float T = texture2D(uVelocity, vT).x; 1064 float B = texture2D(uVelocity, vB).x; 1065 float vorticity = R - L - T + B; 1066 gl_FragColor = vec4(0.5 * vorticity, 0.0, 0.0, 1.0); 1067 } 1068`); 1069 1070var vorticityShader = compileShader(gl.FRAGMENT_SHADER, ` 1071 precision highp float; 1072 precision highp sampler2D; 1073 1074 varying vec2 vUv; 1075 varying vec2 vL; 1076 varying vec2 vR; 1077 varying vec2 vT; 1078 varying vec2 vB; 1079 uniform sampler2D uVelocity; 1080 uniform sampler2D uCurl; 1081 uniform float curl; 1082 uniform float dt; 1083 1084 void main () { 1085 float L = texture2D(uCurl, vL).x; 1086 float R = texture2D(uCurl, vR).x; 1087 float T = texture2D(uCurl, vT).x; 1088 float B = texture2D(uCurl, vB).x; 1089 float C = texture2D(uCurl, vUv).x; 1090 1091 vec2 force = 0.5 * vec2(abs(T) - abs(B), abs(R) - abs(L)); 1092 force /= length(force) + 0.0001; 1093 force *= curl * C; 1094 force.y *= -1.0; 1095 1096 vec2 vel = texture2D(uVelocity, vUv).xy; 1097 gl_FragColor = vec4(vel + force * dt, 0.0, 1.0); 1098 } 1099`); 1100 1101var pressureShader = compileShader(gl.FRAGMENT_SHADER, ` 1102 precision mediump float; 1103 precision mediump sampler2D; 1104 1105 varying highp vec2 vUv; 1106 varying highp vec2 vL; 1107 varying highp vec2 vR; 1108 varying highp vec2 vT; 1109 varying highp vec2 vB; 1110 uniform sampler2D uPressure; 1111 uniform sampler2D uDivergence; 1112 1113 void main () { 1114 float L = texture2D(uPressure, vL).x; 1115 float R = texture2D(uPressure, vR).x; 1116 float T = texture2D(uPressure, vT).x; 1117 float B = texture2D(uPressure, vB).x; 1118 float C = texture2D(uPressure, vUv).x; 1119 float divergence = texture2D(uDivergence, vUv).x; 1120 float pressure = (L + R + B + T - divergence) * 0.25; 1121 gl_FragColor = vec4(pressure, 0.0, 0.0, 1.0); 1122 } 1123`); 1124 1125var gradientSubtractShader = compileShader(gl.FRAGMENT_SHADER, ` 1126 precision mediump float; 1127 precision mediump sampler2D; 1128 1129 varying highp vec2 vUv; 1130 varying highp vec2 vL; 1131 varying highp vec2 vR; 1132 varying highp vec2 vT; 1133 varying highp vec2 vB; 1134 uniform sampler2D uPressure; 1135 uniform sampler2D uVelocity; 1136 1137 void main () { 1138 float L = texture2D(uPressure, vL).x; 1139 float R = texture2D(uPressure, vR).x; 1140 float T = texture2D(uPressure, vT).x; 1141 float B = texture2D(uPressure, vB).x; 1142 vec2 velocity = texture2D(uVelocity, vUv).xy; 1143 velocity.xy -= vec2(R - L, T - B); 1144 gl_FragColor = vec4(velocity, 0.0, 1.0); 1145 } 1146`); 1147 1148var blit = (function () { 1149 gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer()); 1150 gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1, -1, -1, 1, 1, 1, 1, -1]), gl.STATIC_DRAW); 1151 gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, gl.createBuffer()); 1152 gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array([0, 1, 2, 0, 2, 3]), gl.STATIC_DRAW); 1153 gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0); 1154 gl.enableVertexAttribArray(0); 1155 1156 return function (destination) { 1157 gl.bindFramebuffer(gl.FRAMEBUFFER, destination); 1158 gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0); 1159 } 1160})(); 1161 1162var dye; 1163var velocity; 1164var divergence; 1165var curl; 1166var pressure; 1167var bloom; 1168var bloomFramebuffers = []; 1169var sunrays; 1170var sunraysTemp; 1171 1172var ditheringTexture = createTextureAsync('LDR_LLL1_0.png'); 1173 1174var blurProgram = new Program(blurVertexShader, blurShader); 1175var copyProgram = new Program(baseVertexShader, copyShader); 1176var clearProgram = new Program(baseVertexShader, clearShader); 1177var colorProgram = new Program(baseVertexShader, colorShader); 1178var checkerboardProgram = new Program(baseVertexShader, checkerboardShader); 1179var bloomPrefilterProgram = new Program(baseVertexShader, bloomPrefilterShader); 1180var bloomBlurProgram = new Program(baseVertexShader, bloomBlurShader); 1181var bloomFinalProgram = new Program(baseVertexShader, bloomFinalShader); 1182var sunraysMaskProgram = new Program(baseVertexShader, sunraysMaskShader); 1183var sunraysProgram = new Program(baseVertexShader, sunraysShader); 1184var splatProgram = new Program(baseVertexShader, splatShader); 1185var advectionProgram = new Program(baseVertexShader, advectionShader); 1186var divergenceProgram = new Program(baseVertexShader, divergenceShader); 1187var curlProgram = new Program(baseVertexShader, curlShader); 1188var vorticityProgram = new Program(baseVertexShader, vorticitySh
1188ader); 1189var pressureProgram = new Program(baseVertexShader, pressureShader); 1190var gradienSubtractProgram = new Program(baseVertexShader, gradientSubtractShader); 1191 1192var displayMaterial = new Material(baseVertexShader, displayShaderSource); 1193 1194function initFramebuffers () { 1195 var simRes = getResolution(config.SIM_RESOLUTION); 1196 var dyeRes = getResolution(config.DYE_RESOLUTION); 1197 1198 var texType = ext.halfFloatTexType; 1199 var rgba = ext.formatRGBA; 1200 var rg = ext.formatRG; 1201 var r = ext.formatR; 1202 var filtering = ext.supportLinearFiltering ? gl.LINEAR : gl.NEAREST; 1203 1204 if (dye == null) 1205 { dye = createDoubleFBO(dyeRes.width, dyeRes.height, rgba.internalFormat, rgba.format, texType, filtering); } 1206 else 1207 { dye = resizeDoubleFBO(dye, dyeRes.width, dyeRes.height, rgba.internalFormat, rgba.format, texType, filtering); } 1208 1209 if (velocity == null) 1210 { velocity = createDoubleFBO(simRes.width, simRes.height, rg.internalFormat, rg.format, texType, filtering); } 1211 else 1212 { velocity = resizeDoubleFBO(velocity, simRes.width, simRes.height, rg.internalFormat, rg.format, texType, filtering); } 1213 1214 divergence = createFBO (simRes.width, simRes.height, r.internalFormat, r.format, texType, gl.NEAREST); 1215 curl = createFBO (simRes.width, simRes.height, r.internalFormat, r.format, texType, gl.NEAREST); 1216 pressure = createDoubleFBO(simRes.width, simRes.height, r.internalFormat, r.format, texType, gl.NEAREST); 1217 1218 initBloomFramebuffers(); 1219 initSunraysFramebuffers(); 1220} 1221 1222function initBloomFramebuffers () { 1223 var res = getResolution(config.BLOOM_RESOLUTION); 1224 1225 var texType = ext.halfFloatTexType; 1226 var rgba = ext.formatRGBA; 1227 var filtering = ext.supportLinearFiltering ? gl.LINEAR : gl.NEAREST; 1228 1229 bloom = createFBO(res.width, res.height, rgba.internalFormat, rgba.format, texType, filtering); 1230 1231 bloomFramebuffers.length = 0; 1232 for (var i = 0; i < config.BLOOM_ITERATIONS; i++) 1233 { 1234 var width = res.width >> (i + 1); 1235 var height = res.height >> (i + 1); 1236 1237 if (width < 2 || height < 2) { break; } 1238 1239 var fbo = createFBO(width, height, rgba.internalFormat, rgba.format, texType, filtering); 1240 bloomFramebuffers.push(fbo); 1241 } 1242} 1243 1244function initSunraysFramebuffers () { 1245 var res = getResolution(config.SUNRAYS_RESOLUTION); 1246 1247 var texType = ext.halfFloatTexType; 1248 var r = ext.formatR; 1249 var filtering = ext.supportLinearFiltering ? gl.LINEAR : gl.NEAREST; 1250 1251 sunrays = createFBO(res.width, res.height, r.internalFormat, r.format, texType, filtering); 1252 sunraysTemp = createFBO(res.width, res.height, r.internalFormat, r.format, texType, filtering); 1253} 1254 1255function createFBO (w, h, internalFormat, format, type, param) { 1256 gl.activeTexture(gl.TEXTURE0); 1257 var texture = gl.createTexture(); 1258 gl.bindTexture(gl.TEXTURE_2D, texture); 1259 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, param); 1260 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, param); 1261 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); 1262 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); 1263 gl.texImage2D(gl.TEXTURE_2D, 0, internalFormat, w, h, 0, format, type, null); 1264 1265 var fbo = gl.createFramebuffer(); 1266 gl.bindFramebuffer(gl.FRAMEBUFFER, fbo); 1267 gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0); 1268 gl.viewport(0, 0, w, h); 1269 gl.clear(gl.COLOR_BUFFER_BIT); 1270 1271 var texelSizeX = 1.0 / w; 1272 var texelSizeY = 1.0 / h; 1273 1274 return { 1275 texture: texture, 1276 fbo: fbo, 1277 width: w, 1278 height: h, 1279 texelSizeX: texelSizeX, 1280 texelSizeY: texelSizeY, 1281 attach: function attach (id) { 1282 gl.activeTexture(gl.TEXTURE0 + id); 1283 gl.bindTexture(gl.TEXTURE_2D, texture); 1284 return id; 1285 } 1286 }; 1287} 1288 1289function createDoubleFBO (w, h, internalFormat, format, type, param) { 1290 var fbo1 = createFBO(w, h, internalFormat, format, type, param); 1291 var fbo2 = createFBO(w, h, internalFormat, format, type, param); 1292 1293 return { 1294 width: w, 1295 height: h, 1296 texelSizeX: fbo1.texelSizeX, 1297 texelSizeY: fbo1.texelSizeY, 1298 get read () { 1299 return fbo1; 1300 }, 1301 set read (value) { 1302 fbo1 = value; 1303 }, 1304 get write () { 1305 return fbo2; 1306 }, 1307 set write (value) { 1308 fbo2 = value; 1309 }, 1310 swap: function swap () { 1311 var temp = fbo1; 1312 fbo1 = fbo2; 1313 fbo2 = temp; 1314 } 1315 } 1316} 1317 1318function resizeFBO (target, w, h, internalFormat, format, type, param) { 1319 var newFBO = createFBO(w, h, internalFormat, format, type, param); 1320 copyProgram.bind(); 1321 gl.uniform1i(copyProgram.uniforms.uTexture, target.attach(0)); 1322 blit(newFBO.fbo); 1323 return newFBO; 1324} 1325 1326function resizeDoubleFBO (target, w, h, internalFormat, format, type, param) { 1327 if (target.width == w && target.height == h) 1328 { return target; } 1329 target.read = resizeFBO(target.read, w, h, internalFormat, format, type, param); 1330 target.write = createFBO(w, h, internalFormat, format, type, param); 1331 target.width = w; 1332 target.height = h; 1333 target.texelSizeX = 1.0 / w; 1334 target.texelSizeY = 1.0 / h; 1335 return target; 1336} 1337 1338function createTextureAsync (url) { 1339 var texture = gl.createTexture(); 1340 gl.bindTexture(gl.TEXTURE_2D, texture); 1341 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); 1342 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); 1343 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT); 1344 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT); 1345 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, 1, 1, 0, gl.RGB, gl.UNSIGNED_BYTE, new Uint8Array([255, 255, 255])); 1346 1347 var obj = { 1348 texture: texture, 1349 width: 1, 1350 height: 1, 1351 attach: function attach (id) { 1352 gl.activeTexture(gl.TEXTURE0 + id); 1353 gl.bindTexture(gl.TEXTURE_2D, texture); 1354 return id; 1355 } 1356 }; 1357 1358 var image = new Image(); 1359 image.onload = function () { 1360 obj.width = image.width; 1361 obj.height = image.height; 1362 gl.bindTexture(gl.TEXTURE_2D, texture); 1363 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, image); 1364 }; 1365 image.src = url; 1366 1367 return obj; 1368} 1369 1370function updateKeywords () { 1371 var displayKeywords = []; 1372 if (config.SHADING) { displayKeywords.push("SHADING"); } 1373 if (config.BLOOM) { displayKeywords.push("BLOOM"); } 1374 if (config.SUNRAYS) { displayKeywords.push("SUNRAYS"); } 1375 displayMaterial.setKeywords(displayKeywords); 1376} 1377 1378updateKeywords(); 1379initFramebuffers(); 1380multipleSplats(parseInt(Math.random() * 20) + 5); 1381 1382var lastUpdateTime = Date.now(); 1383var colorUpdateTimer = 0.0; 1384update(); 1385 1386function update () { 1387 var dt = calcDeltaTime(); 1388 1389 if (resizeCanvas()) 1390 { initFramebuffers(); } 1391 updateColors(dt); 1392 applyInputs(); 1393 1394 1395 if (!config.PAUSED) 1396 { step(dt); } 1397 render(null); 1398 requestAnimationFrame(update); 1399} 1400 1401function calcDeltaTime () { 1402 var now = Date.now(); 1403 var dt = (now - lastUpdateTime) / 1000; 1404 dt = Math.min(dt, 0.016666);
1405 lastUpdateTime = now; 1406 return dt; 1407} 1408 1409function resizeCanvas () { 1410 var width = scaleByPixelRatio(canvas.clientWidth); 1411 var height = scaleByPixelRatio(canvas.clientHeight); 1412 if (canvas.width != width || canvas.height != height) { 1413 canvas.width = width; 1414 canvas.height = height; 1415 return true; 1416 } 1417 return false; 1418} 1419 1420function updateColors (dt) { 1421 if (!config.COLORFUL) { return; } 1422 1423 colorUpdateTimer += dt * config.COLOR_UPDATE_SPEED; 1424 if (colorUpdateTimer >= 1) { 1425 colorUpdateTimer = wrap(colorUpdateTimer, 0, 1); 1426 pointers.forEach(function (p) { 1427 p.color = generateColor(); 1428 }); 1429 } 1430} 1431 1432function applyInputs () { 1433 if (splatStack.length > 0) 1434 { multipleSplats(splatStack.pop()); } 1435 1436 pointers.forEach(function (p) { 1437 // if (p.moved) { 1438 // p.moved = false; 1439 splatPointer(p); 1440 // } 1441 }); 1442} 1443 1444function step (dt) { 1445 gl.disable(gl.BLEND); 1446 gl.viewport(0, 0, velocity.width, velocity.height); 1447 1448 // curlProgram.bind(); 1449 // gl.uniform2f(curlProgram.uniforms.texelSize, velocity.texelSizeX, velocity.texelSizeY); 1450 // gl.uniform1i(curlProgram.uniforms.uVelocity, velocity.read.attach(0)); 1451 // blit(curl.fbo); 1452 // 1453 // vorticityProgram.bind(); 1454 // gl.uniform2f(vorticityProgram.uniforms.texelSize, velocity.texelSizeX, velocity.texelSizeY); 1455 // gl.uniform1i(vorticityProgram.uniforms.uVelocity, velocity.read.attach(0)); 1456 // gl.uniform1i(vorticityProgram.uniforms.uCurl, curl.attach(1)); 1457 // gl.uniform1f(vorticityProgram.uniforms.curl, config.CURL); 1458 // gl.uniform1f(vorticityProgram.uniforms.dt, dt); 1459 // blit(velocity.write.fbo); 1460 // velocity.swap(); 1461 1462 divergenceProgram.bind(); 1463 gl.uniform2f(divergenceProgram.uniforms.texelSize, velocity.texelSizeX, velocity.texelSizeY); 1464 gl.uniform1i(divergenceProgram.uniforms.uVelocity, velocity.read.attach(0)); 1465 blit(divergence.fbo); 1466 1467 clearProgram.bind(); 1468 gl.uniform1i(clearProgram.uniforms.uTexture, pressure.read.attach(0)); 1469 gl.uniform1f(clearProgram.uniforms.value, config.PRESSURE); 1470 blit(pressure.write.fbo); 1471 pressure.swap(); 1472 1473 pressureProgram.bind(); 1474 gl.uniform2f(pressureProgram.uniforms.texelSize, velocity.texelSizeX, velocity.texelSizeY); 1475 gl.uniform1i(pressureProgram.uniforms.uDivergence, divergence.attach(0)); 1476 for (var i = 0; i < config.PRESSURE_ITERATIONS; i++) { 1477 gl.uniform1i(pressureProgram.uniforms.uPressure, pressure.read.attach(1)); 1478 blit(pressure.write.fbo); 1479 pressure.swap(); 1480 } 1481 1482 gradienSubtractProgram.bind(); 1483 gl.uniform2f(gradienSubtractProgram.uniforms.texelSize, velocity.texelSizeX, velocity.texelSizeY); 1484 gl.uniform1i(gradienSubtractProgram.uniforms.uPressure, pressure.read.attach(0)); 1485 gl.uniform1i(gradienSubtractProgram.uniforms.uVelocity, velocity.read.attach(1)); 1486 blit(velocity.write.fbo); 1487 velocity.swap(); 1488 1489 advectionProgram.bind(); 1490 gl.uniform2f(advectionProgram.uniforms.texelSize, velocity.texelSizeX, velocity.texelSizeY); 1491 if (!ext.supportLinearFiltering) 1492 { gl.uniform2f(advectionProgram.uniforms.dyeTexelSize, velocity.texelSizeX, velocity.texelSizeY); } 1493 var velocityId = velocity.read.attach(0); 1494 gl.uniform1i(advectionProgram.uniforms.uVelocity, velocityId); 1495 gl.uniform1i(advectionProgram.uniforms.uSource, velocityId); 1496 gl.uniform1f(advectionProgram.uniforms.dt, dt); 1497 gl.uniform1f(advectionProgram.uniforms.dissipation, config.VELOCITY_DISSIPATION); 1498 blit(velocity.write.fbo); 1499 velocity.swap(); 1500 1501 gl.viewport(0, 0, dye.width, dye.height); 1502 1503 if (!ext.supportLinearFiltering) 1504 { gl.uniform2f(advectionProgram.uniforms.dyeTexelSize, dye.texelSizeX, dye.texelSizeY); } 1505 gl.uniform1i(advectionProgram.uniforms.uVelocity, velocity.read.attach(0)); 1506 gl.uniform1i(advectionProgram.uniforms.uSource, dye.read.attach(1)); 1507 gl.uniform1f(advectionProgram.uniforms.dissipation, config.DENSITY_DISSIPATION); 1508 blit(dye.write.fbo); 1509 dye.swap(); 1510} 1511 1512function render (target) { 1513 if (config.BLOOM) 1514 { applyBloom(dye.read, bloom); } 1515 if (config.SUNRAYS) { 1516 applySunrays(dye.read, dye.write, sunrays); 1517 blur(sunrays, sunraysTemp, 1); 1518 } 1519 1520 if (target == null || !config.TRANSPARENT) { 1521 gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); 1522 gl.enable(gl.BLEND); 1523 } 1524 else { 1525 gl.disable(gl.BLEND); 1526 } 1527 1528 var width = target == null ? gl.drawingBufferWidth : target.width; 1529 var height = target == null ? gl.drawingBufferHeight : target.height; 1530 gl.viewport(0, 0, width, height); 1531 1532 var fbo = target == null ? null : target.fbo; 1533 if (!config.TRANSPARENT) 1534 { drawColor(fbo, normalizeColor(config.BACK_COLOR)); } 1535 if (target == null && config.TRANSPARENT) 1536 { drawCheckerboard(fbo); } 1537 drawDisplay(fbo, width, height); 1538} 1539 1540function drawColor (fbo, color) { 1541 colorProgram.bind(); 1542 gl.uniform4f(colorProgram.uniforms.color, color.r, color.g, color.b, 1); 1543 blit(fbo); 1544} 1545 1546function drawCheckerboard (fbo) { 1547 checkerboardProgram.bind(); 1548 gl.uniform1f(checkerboardProgram.uniforms.aspectRatio, canvas.width / canvas.height); 1549 blit(fbo); 1550} 1551 1552function drawDisplay (fbo, width, height) { 1553 displayMaterial.bind(); 1554 if (config.SHADING) 1555 { gl.uniform2f(displayMaterial.uniforms.texelSize, 1.0 / width, 1.0 / height); } 1556 gl.uniform1i(displayMaterial.uniforms.uTexture, dye.read.attach(0)); 1557 if (config.BLOOM) { 1558 gl.uniform1i(displayMaterial.uniforms.uBloom, bloom.attach(1)); 1559 gl.uniform1i(displayMaterial.uniforms.uDithering, ditheringTexture.attach(2)); 1560 var scale = getTextureScale(ditheringTexture, width, height); 1561 gl.uniform2f(displayMaterial.uniforms.ditherScale, scale.x, scale.y); 1562 } 1563 if (config.SUNRAYS) 1564 { gl.uniform1i(displayMaterial.uniforms.uSunrays, sunrays.attach(3)); } 1565 blit(fbo); 1566} 1567 1568function applyBloom (source, destination) { 1569 if (bloomFramebuffers.length < 2) 1570 { return; } 1571 1572 var last = destination; 1573 1574 gl.disable(gl.BLEND); 1575 bloomPrefilterProgram.bind(); 1576 var knee = config.BLOOM_THRESHOLD * config.BLOOM_SOFT_KNEE + 0.0001; 1577 var curve0 = config.BLOOM_THRESHOLD - knee; 1578 var curve1 = knee * 2; 1579 var curve2 = 0.25 / knee; 1580 gl.uniform3f(bloomPrefilterProgram.uniforms.curve, curve0, curve1, curve2); 1581 gl.uniform1f(bloomPrefilterProgram.uniforms.threshold, config.BLOOM_THRESHOLD); 1582 gl.uniform1i(bloomPrefilterProgram.uniforms.uTexture, source.attach(0)); 1583 gl.viewport(0, 0, last.width, last.height); 1584 blit(last.fbo); 1585 1586 bloomBlurProgram.bind(); 1587 for (var i = 0; i < bloomFramebuffers.length; i++) { 1588 var dest = bloomFramebuffers[i]; 1589 gl.uniform2f(bloomBlurProgram.uniforms.texelSize, last.texelSizeX, last.texelSizeY); 1590 gl.uniform1i(bloomBlurProgram.uniforms.uTexture, last.attach(0)); 1591 gl.viewport(0, 0, dest.width, dest.height); 1592 blit(dest.fbo); 1593 last = dest; 1594 } 1595 1596 gl.blendFunc(gl.ONE, gl.ONE); 1597 gl.enable(gl.BLEND); 1598 1599 for (var i$1 = bloomFramebuffers.length - 2; i$1 >= 0; i$1--) { 1600 var baseTex = bloomFramebuffers[i$1]; 1601 gl.uniform2f(bloomBlurProgram.uniforms.texelSize, last.texelSizeX, last.texelSizeY); 1602 gl.uniform1i(bloomBlurProgram.uniforms.uTexture, last.attach(0)); 1603 gl.viewport(0, 0, baseTex.width, baseTex.height); 1604 blit(baseTex.fbo); 1605 last = baseTex; 1606 } 1607 1608 gl.disable(gl.BLEND); 1609 bloomFinalProgram.bind(); 1610 gl.uniform2f(bloomFinalProgram.uniforms.texelSize, last.texelSizeX, last.texelSizeY); 1611 gl.uniform1i(bloomFinalProgram.uniforms.uTexture, last.attach(0)); 1612 gl.uniform1f(bloomFinalProgram.uniforms.intensity, config.BLOOM_INTENSITY); 1613 gl.viewport(0, 0, destination.width, destination.height); 1614 blit(destination.fbo); 1615} 1616 1617function applySunrays (source, mask, destination) { 1618 gl.disable(gl.BLEND); 1619 sunraysMaskProgram.bind(); 1620 gl.uniform1i(sunraysMaskProgram.uniforms.uTexture, source.attach(0)); 1621 gl.viewport(0, 0, mask.width, mask.height); 1622 blit(mask.fbo); 1623 1624 sunraysProgram.bind(); 1625 gl.uniform1f(sunraysProgram.uniforms.weight, config.SUNRAYS_WEIGHT); 1626 gl.uniform1i(sunraysProgram.uniforms.uTexture, mask.attach(0)); 1627 gl.viewport(0, 0, destination.width, destination.height); 1628 blit(destination.fbo); 1629} 1630 1631function blur (target, temp, iterations) { 1632 blurProgram.bind(); 1633 for (var i = 0; i < iterations; i++) { 1634 gl.uniform2f(blurProgram.uniforms.texelSize, target.texelSizeX, 0.0); 1635 gl.uniform1i(blurProgram.uniforms.uTexture, target.attach(0)); 1636 blit(temp.fbo); 1637 1638 gl.uniform2f(blurProgram.uniforms.texelSize, 0.0, target.texelSizeY); 1639 gl.uniform1i(blurProgram.uniforms.uTexture, temp.attach(0)); 1640 blit(target.fbo); 1641 } 1642} 1643 1644function splatPointer (pointer) { 1645 var dx = pointer.deltaX * config.SPLAT_FORCE; 1646 var dy = pointer.deltaY * config.SPLAT_FORCE; 1647 splat(pointer.texcoordX, pointer.texcoordY, dx, dy, pointer.color); 1648} 1649 1650function multipleSplats (amount) { 1651 for (var i = 0; i < amount; i++) { 1652 var color = generateColor(); 1653 // color.r *= 10.0; 1654 // color.g *= 10.0; 1655 // color.b *= 10.0; 1656 var x = Math.random(); 1657 var y = Math.random(); 1658 var dx = 1000 * (Math.random() - 0.5); 1659 var dy = 1000 * (Math.random() - 0.5); 1660 splat(x, y, dx, dy, color); 1661 } 1662} 1663 1664function splat (x, y, dx, dy, color) { 1665 gl.viewport(0, 0, velocity.width, velocity.height); 1666 splatProgram.bind(); 1667 gl.uniform1i(splatProgram.uniforms.uTarget, velocity.read.attach(0)); 1668 gl.uniform1f(splatProgram.uniforms.aspectRatio, canvas.width / canvas.height); 1669 gl.uniform2f(splatProgram.uniforms.point, x, y); 1670 gl.uniform3f(splatProgram.uniforms.color, dx, dy, 0.0); 1671 gl.uniform1f(splatProgram.uniforms.radius, correctRadius(config.SPLAT_RADIUS / 100.0)); 1672 blit(velocity.write.fbo); 1673 velocity.swap(); 1674 1675 gl.viewport(0, 0, dye.width, dye.height); 1676 gl.uniform1i(splatProgram.uniforms.uTarget, dye.read.attach(0)); 1677 gl.uniform3f(splatProgram.uniforms.color, color.r, color.g, color.b); 1678 blit(dye.write.fbo); 1679 dye.swap(); 1680} 1681 1682function correctRadius (radius) { 1683 var aspectRatio = canvas.width / canvas.height; 1684 if (aspectRatio > 1) 1685 { radius *= aspectRatio; }
1686 return radius; 1687} 1688 1689document.addEventListener('mousedown', function (e) { 1690 // console.log(pointer); 1691 // var posX = scaleByPixelRatio(e.offsetX); 1692 // var posY = scaleByPixelRatio(e.offsetY); 1693 // var pointer = pointers.find(function (p) { return p.id == -1; }); 1694 // if (pointer == null) 1695 // { pointer = new pointerPrototype(); } 1696 // updatePointerDownData(pointer, -1, posX, posY); 1697}); 1698 1699 1700document.addEventListener('mousemove', function (e) { 1701 var pointer = pointers.find(function (p) { return p.id == -1; }); 1702 if (pointer == null) { 1703 pointer = new pointerPrototype(); 1704 } else { 1705 window.posX = scaleByPixelRatio(e.clientX); 1706 window.posY = scaleByPixelRatio(e.clientY); 1707 // console.log(window.posX, window.posY); 1708 updatePointerMoveData(pointer, window.posX, window.posY); 1709 } 1710}); 1711 1712window.addEventListener('mouseup', function () { 1713 updatePointerUpData(pointers[0]); 1714}); 1715 1716document.addEventListener('touchstart', function (e) { 1717 e.preventDefault(); 1718 var touches = e.targetTouches; 1719 while (touches.length >= pointers.length) 1720 { pointers.push(new pointerPrototype()); } 1721 for (var i = 0; i < touches.length; i++) { 1722 var posX = scaleByPixelRatio(touches[i].clientX); 1723 var posY = scaleByPixelRatio(touches[i].clientY); 1724 updatePointerDownData(pointers[i + 1], touches[i].identifier, posX, posY); 1725 } 1726}); 1727 1728document.addEventListener('touchmove', function (e) { 1729 e.preventDefault(); 1730 var touches = e.targetTouches; 1731 for (var i = 0; i < touches.length; i++) { 1732 var pointer = pointers[i + 1]; 1733 if (!pointer.down) { continue; } 1734 var posX = scaleByPixelRatio(touches[i].clientX); 1735 var posY = scaleByPixelRatio(touches[i].clientY); 1736 updatePointerMoveData(pointer, posX, posY); 1737 } 1738}, false); 1739 1740document.addEventListener('touchend', function (e) { 1741 var touches = e.changedTouches; 1742 var loop = function ( i ) { 1743 var pointer = pointers.find(function (p) { return p.id == touches[i].identifier; }); 1744 if (pointer == null) { return; } 1745 updatePointerUpData(pointer); 1746 }; 1747 1748 for (var i = 0; i < touches.length; i++) 1749 loop( i ); 1750}); 1751 1752// window.addEventListener('keydown', function (e) { 1753// if (e.code === 'KeyP') 1754// { config.PAUSED = !config.PAUSED; } 1755// if (e.key === ' ') 1756// { splatStack.push(parseInt(Math.random() * 20) + 5); } 1757// }); 1758 1759function updatePointerDownData (pointer, id, posX, posY) { 1760 pointer.id = id; 1761 pointer.down = true; 1762 pointer.moved = false; 1763 pointer.texcoordX = posX / canvas.width; 1764 pointer.texcoordY = 1.0 - posY / canvas.height; 1765 pointer.prevTexcoordX = pointer.texcoordX; 1766 pointer.prevTexcoordY = pointer.texcoordY; 1767 pointer.deltaX = 0; 1768 pointer.deltaY = 0; 1769 // pointer.color = generateColor(); 1770} 1771 1772function updatePointerMoveData (pointer, posX, posY) { 1773 pointer.prevTexcoordX = pointer.texcoordX; 1774 pointer.prevTexcoordY = pointer.texcoordY; 1775 pointer.texcoordX = posX / canvas.width; 1776 pointer.texcoordY = 1.0 - posY / canvas.height; 1777 pointer.deltaX = correctDeltaX(pointer.texcoordX - pointer.prevTexcoordX); 1778 pointer.deltaY = correctDeltaY(pointer.texcoordY - pointer.prevTexcoordY); 1779 pointer.moved = true; //Math.abs(pointer.deltaX) > 0 || Math.abs(pointer.deltaY) > 0; 1780} 1781 1782function updatePointerUpData (pointer) { 1783 pointer.down = false; 1784} 1785 1786function correctDeltaX (delta) { 1787 var aspectRatio = canvas.width / canvas.height; 1788 if (aspectRatio < 1) { delta *= aspectRatio; } 1789 return delta; 1790} 1791 1792function correctDeltaY (delta) { 1793 var aspectRatio = canvas.width / canvas.height; 1794 if (aspectRatio > 1) { delta /= aspectRatio; } 1795 return delta; 1796} 1797 1798function generateColor () { 1799 // var c = HSVtoRGB(Math.random(), 1.0, 1.0); 1800 // c.r *= 0.15; 1801 // c.g *= 0.15; 1802 // c.b *= 0.15; 1803 var c = THECOLOR; 1804 1805 return c; 1806} 1807 1808function HSVtoRGB (h, s, v) { 1809 var r, g, b, i, f, p, q, t; 1810 i = Math.floor(h * 6); 1811 f = h * 6 - i; 1812 p = v * (1 - s); 1813 q = v * (1 - f * s); 1814 t = v * (1 - (1 - f) * s); 1815 1816 switch (i % 6) { 1817 case 0: r = v, g = t, b = p; break; 1818 case 1: r = q, g = v, b = p; break; 1819 case 2: r = p, g = v, b = t; break; 1820 case 3: r = p, g = q, b = v; break; 1821 case 4: r = t, g = p, b = v; break; 1822 case 5: r = v, g = p, b = q; break; 1823 } 1824 1825 return { 1826 r: r, 1827 g: g, 1828 b: b 1829 }; 1830} 1831 1832function normalizeColor (input) { 1833 var output = { 1834 r: input.r / 255, 1835 g: input.g / 255, 1836 b: input.b / 255 1837 }; 1838 return output; 1839} 1840 1841function wrap (value, min, max) { 1842 var range = max - min; 1843 if (range == 0) { return min; } 1844 return (value - min) % range + min; 1845} 1846 1847function getResolution (resolution) { 1848 var aspectRatio = gl.drawingBufferWidth / gl.drawingBufferHeight; 1849 if (aspectRatio < 1) 1850 { aspectRatio = 1.0 / aspectRatio; } 1851 1852 var min = Math.round(resolution); 1853 var max = Math.round(resolution * aspectRatio); 1854 1855 if (gl.drawingBufferWidth > gl.drawingBufferHeight) 1856 { return { width: max, height: min }; } 1857 else 1858 { return { width: min, height: max }; } 1859} 1860 1861function getTextureScale (texture, width, height) { 1862 return { 1863 x: width / texture.width, 1864 y: height / texture.height 1865 }; 1866} 1867 1868function scaleByPixelRatio (input) { 1869 var pixelRatio = window.devicePixelRatio || 1; 1870 return Math.floor(input * pixelRatio); 1871} 1872 1873function hashCode (s) { 1874 if (s.length == 0) { return 0; } 1875 var hash = 0; 1876 for (var i = 0; i < s.length; i++) {
1877 hash = (hash << 5) - hash + s.charCodeAt(i); 1878 hash |= 0; // Convert to 32bit integer 1879 } 1880 return hash; 1881}; 1882 1883 1884/***/ }), 1885
vendor: 289,075 bytes, lines 1886-12778
1886/***/ "./node_modules/jquery/dist/jquery.js": 1887/*!********************************************!*\ 1888 !*** ./node_modules/jquery/dist/jquery.js ***! 1889 \********************************************/ 1890/*! no static exports found */ 1891/***/ (function(module, exports, __webpack_require__) { 1892 1893var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! 1894 * jQuery JavaScript Library v3.6.0 1895 * https://jquery.com/ 1896 * 1897 * Includes Sizzle.js 1898 * https://sizzlejs.com/ 1899 * 1900 * Copyright OpenJS Foundation and other contributors 1901 * Released under the MIT license 1902 * https://jquery.org/license 1903 * 1904 * Date: 2021-03-02T17:08Z 1905 */ 1906( function( global, factory ) { 1907 1908 "use strict"; 1909 1910 if ( true && typeof module.exports === "object" ) { 1911 1912 // For CommonJS and CommonJS-like environments where a proper `window` 1913 // is present, execute the factory and get jQuery. 1914 // For environments that do not have a `window` with a `document` 1915 // (such as Node.js), expose a factory as module.exports. 1916 // This accentuates the need for the creation of a real `window`. 1917 // e.g. var jQuery = require("jquery")(window); 1918 // See ticket #14549 for more info. 1919 module.exports = global.document ? 1920 factory( global, true ) : 1921 function( w ) { 1922 if ( !w.document ) { 1923 throw new Error( "jQuery requires a window with a document" ); 1924 } 1925 return factory( w ); 1926 }; 1927 } else { 1928 factory( global ); 1929 } 1930 1931// Pass this if window is not defined yet 1932} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) { 1933 1934// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1 1935// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode 1936// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common 1937// enough that all such attempts are guarded in a try block. 1938"use strict"; 1939 1940var arr = []; 1941 1942var getProto = Object.getPrototypeOf; 1943 1944var slice = arr.slice; 1945 1946var flat = arr.flat ? function( array ) { 1947 return arr.flat.call( array ); 1948} : function( array ) { 1949 return arr.concat.apply( [], array ); 1950}; 1951 1952 1953var push = arr.push; 1954 1955var indexOf = arr.indexOf; 1956 1957var class2type = {}; 1958 1959var toString = class2type.toString; 1960 1961var hasOwn = class2type.hasOwnProperty; 1962 1963var fnToString = hasOwn.toString; 1964 1965var ObjectFunctionString = fnToString.call( Object ); 1966 1967var support = {}; 1968 1969var isFunction = function isFunction( obj ) { 1970 1971 // Support: Chrome <=57, Firefox <=52 1972 // In some browsers, typeof returns "function" for HTML <object> elements 1973 // (i.e., `typeof document.createElement( "object" ) === "function"`). 1974 // We don't want to classify *any* DOM node as a function. 1975 // Support: QtWeb <=3.8.5, WebKit <=534.34, wkhtmltopdf tool <=0.12.5 1976 // Plus for old WebKit, typeof returns "function" for HTML collections 1977 // (e.g., `typeof document.getElementsByTagName("div") === "function"`). (gh-4756) 1978 return typeof obj === "function" && typeof obj.nodeType !== "number" && 1979 typeof obj.item !== "function"; 1980 }; 1981 1982 1983var isWindow = function isWindow( obj ) { 1984 return obj != null && obj === obj.window; 1985 }; 1986 1987 1988var document = window.document; 1989 1990 1991 1992 var preservedScriptAttributes = { 1993 type: true, 1994 src: true, 1995 nonce: true, 1996 noModule: true 1997 }; 1998 1999 function DOMEval( code, node, doc ) { 2000 doc = doc || document; 2001 2002 var i, val, 2003 script = doc.createElement( "script" ); 2004 2005 script.text = code; 2006 if ( node ) { 2007 for ( i in preservedScriptAttributes ) { 2008 2009 // Support: Firefox 64+, Edge 18+ 2010 // Some browsers don't support the "nonce" property on scripts. 2011 // On the other hand, just using `getAttribute` is not enough as 2012 // the `nonce` attribute is reset to an empty string whenever it 2013 // becomes browsing-context connected. 2014 // See https://github.com/whatwg/html/issues/2369 2015 // See https://html.spec.whatwg.org/#nonce-attributes 2016 // The `node.getAttribute` check was added for the sake of 2017 // `jQuery.globalEval` so that it can fake a nonce-containing node 2018 // via an object. 2019 val = node[ i ] || node.getAttribute && node.getAttribute( i ); 2020 if ( val ) { 2021 script.setAttribute( i, val ); 2022 } 2023 } 2024 } 2025 doc.head.appendChild( script ).parentNode.removeChild( script ); 2026 } 2027 2028 2029function toType( obj ) { 2030 if ( obj == null ) { 2031 return obj + ""; 2032 } 2033 2034 // Support: Android <=2.3 only (functionish RegExp) 2035 return typeof obj === "object" || typeof obj === "function" ? 2036 class2type[ toString.call( obj ) ] || "object" : 2037 typeof obj; 2038} 2039/* global Symbol */ 2040// Defining this global in .eslintrc.json would create a danger of using the global 2041// unguarded in another place, it seems safer to define global only for this module 2042 2043 2044 2045var 2046 version = "3.6.0", 2047 2048 // Define a local copy of jQuery 2049 jQuery = function( selector, context ) { 2050 2051 // The jQuery object is actually just the init constructor 'enhanced' 2052 // Need init if jQuery is called (just allow error to be thrown if not included) 2053 return new jQuery.fn.init( selector, context ); 2054 }; 2055 2056jQuery.fn = jQuery.prototype = { 2057 2058 // The current version of jQuery being used 2059 jquery: version, 2060 2061 constructor: jQuery, 2062 2063 // The default length of a jQuery object is 0 2064 length: 0, 2065 2066 toArray: function() { 2067 return slice.call( this ); 2068 }, 2069 2070 // Get the Nth element in the matched element set OR 2071 // Get the whole matched element set as a clean array 2072 get: function( num ) { 2073 2074 // Return all the elements in a clean array 2075 if ( num == null ) { 2076 return slice.call( this ); 2077 } 2078 2079 // Return just the one element from the set 2080 return num < 0 ? this[ num + this.length ] : this[ num ]; 2081 }, 2082 2083 // Take an array of elements and push it onto the stack 2084 // (returning the new matched element set) 2085 pushStack: function( elems ) { 2086 2087 // Build a new jQuery matched element set 2088 var ret = jQuery.merge( this.constructor(), elems ); 2089 2090 // Add the old object onto the stack (as a reference) 2091 ret.prevObject = this; 2092 2093 // Return the newly-formed element set 2094 return ret; 2095 }, 2096 2097 // Execute a callback for every element in the matched set. 2098 each: function( callback ) { 2099 return jQuery.each( this, callback ); 2100 }, 2101 2102 map: function( callback ) { 2103 return this.pushStack( jQuery.map( this, function( elem, i ) { 2104 return callback.call( elem, i, elem ); 2105 } ) ); 2106 }, 2107 2108 slice: function() { 2109 return this.pushStack( slice.apply( this, arguments ) ); 2110 }, 2111 2112 first: function() { 2113 return this.eq( 0 ); 2114 }, 2115 2116 last: function() { 2117 return this.eq( -1 ); 2118 }, 2119 2120 even: function() { 2121 return this.pushStack( jQuery.grep( this, function( _elem, i ) { 2122 return ( i + 1 ) % 2; 2123 } ) ); 2124 }, 2125 2126 odd: function() { 2127 return this.pushStack( jQuery.grep( this, function( _elem, i ) { 2128 return i % 2; 2129 } ) ); 2130 }, 2131 2132 eq: function( i ) { 2133 var len = this.length, 2134 j = +i + ( i < 0 ? len : 0 ); 2135 return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); 2136 }, 2137 2138 end: function() { 2139 return this.prevObject || this.constructor(); 2140 }, 2141 2142 // For internal use only. 2143 // Behaves like an Array's method, not like a jQuery method. 2144 push: push, 2145 sort: arr.sort, 2146 splice: arr.splice 2147}; 2148 2149jQuery.extend = jQuery.fn.extend = function() { 2150 var options, name, src, copy, copyIsArray, clone, 2151 target = arguments[ 0 ] || {}, 2152 i = 1, 2153 length = arguments.length, 2154 deep = false; 2155 2156 // Handle a deep copy situation 2157 if ( typeof target === "boolean" ) { 2158 deep = target; 2159 2160 // Skip the boolean and the target 2161 target = arguments[ i ] || {}; 2162 i++; 2163 } 2164 2165 // Handle case when target is a string or something (possible in deep copy) 2166 if ( typeof target !== "object" && !isFunction( target ) ) { 2167 target = {}; 2168 } 2169 2170 // Extend jQuery itself if only one argument is passed 2171 if ( i === length ) { 2172 target = this; 2173 i--; 2174 } 2175 2176 for ( ; i < length; i++ ) { 2177 2178 // Only deal with non-null/undefined values 2179 if ( ( options = arguments[ i ] ) != null ) { 2180 2181 // Extend the base object 2182 for ( name in options ) { 2183 copy = options[ name ]; 2184 2185 // Prevent Object.prototype pollution 2186 // Prevent never-ending loop 2187 if ( name === "__proto__" || target === copy ) { 2188 continue; 2189 } 2190 2191 // Recurse if we're merging plain objects or arrays 2192 if ( deep && copy && ( jQuery.isPlainObject( copy ) || 2193 ( copyIsArray = Array.isArray( copy ) ) ) ) { 2194 src = target[ name ]; 2195 2196 // Ensure proper type for the source value 2197 if ( copyIsArray && !Array.isArray( src ) ) { 2198 clone = []; 2199 } else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) { 2200 clone = {}; 2201 } else { 2202 clone = src; 2203 } 2204 copyIsArray = false; 2205 2206 // Never move original objects, clone them 2207 target[ name ] = jQuery.extend( deep, clone, copy ); 2208 2209 // Don't bring in undefined values 2210 } else if ( copy !== undefined ) { 2211 target[ name ] = copy; 2212 } 2213 } 2214 } 2215 } 2216 2217 // Return the modified object 2218 return target; 2219}; 2220 2221jQuery.extend( { 2222 2223 // Unique for each copy of jQuery on the page 2224 expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), 2225 2226 // Assume jQuery is ready without the ready module 2227 isReady: true, 2228 2229 error: function( msg ) { 2230 throw new Error( msg ); 2231 }, 2232 2233 noop: function() {}, 2234 2235 isPlainObject: function( obj ) { 2236 var proto, Ctor; 2237 2238 // Detect obvious negatives 2239 // Use toString instead of jQuery.type to catch host objects 2240 if ( !obj || toString.call( obj ) !== "[object Object]" ) { 2241 return false; 2242 } 2243 2244 proto = getProto( obj ); 2245 2246 // Objects with no prototype (e.g., `Object.create( null )`) are plain 2247 if ( !proto ) { 2248 return true; 2249 } 2250 2251 // Objects with prototype are plain iff they were constructed by a global Object function 2252 Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor; 2253 return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString; 2254 }, 2255 2256 isEmptyObject: function( obj ) { 2257 var name; 2258 2259 for ( name in obj ) { 2260 return false; 2261 } 2262 return true; 2263 }, 2264 2265 // Evaluates a script in a provided context; falls back to the global one 2266 // if not specified. 2267 globalEval: function( code, options, doc ) { 2268 DOMEval( code, { nonce: options && options.nonce }, doc ); 2269 }, 2270 2271 each: function( obj, callback ) { 2272 var length, i = 0; 2273 2274 if ( isArrayLike( obj ) ) { 2275 length = obj.length; 2276 for ( ; i < length; i++ ) { 2277 if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { 2278 break; 2279 } 2280 } 2281 } else { 2282 for ( i in obj ) { 2283 if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { 2284 break; 2285 } 2286 } 2287 } 2288 2289 return obj; 2290 }, 2291 2292 // results is for internal usage only 2293 makeArray: function( arr, results ) { 2294 var ret = results || []; 2295 2296 if ( arr != null ) { 2297 if ( isArrayLike( Object( arr ) ) ) { 2298 jQuery.merge( ret, 2299 typeof arr === "string" ? 2300 [ arr ] : arr 2301 ); 2302 } else { 2303 push.call( ret, arr ); 2304 } 2305 } 2306 2307 return ret; 2308 }, 2309 2310 inArray: function( elem, arr, i ) { 2311 return arr == null ? -1 : indexOf.call( arr, elem, i ); 2312 }, 2313 2314 // Support: Android <=4.0 only, PhantomJS 1 only 2315 // push.apply(_, arraylike) throws on ancient WebKit 2316 merge: function( first, second ) { 2317 var len = +second.length, 2318 j = 0, 2319 i = first.length; 2320 2321 for ( ; j < len; j++ ) { 2322 first[ i++ ] = second[ j ]; 2323 } 2324 2325 first.length = i; 2326 2327 return first; 2328 }, 2329 2330 grep: function( elems, callback, invert ) { 2331 var callbackInverse, 2332 matches = [], 2333 i = 0, 2334 length = elems.length, 2335 callbackExpect = !invert; 2336 2337 // Go through the array, only saving the items 2338 // that pass the validator function 2339 for ( ; i < length; i++ ) { 2340 callbackInverse = !callback( elems[ i ], i ); 2341 if ( callbackInverse !== callbackExpect ) { 2342 matches.push( elems[ i ] ); 2343 } 2344 } 2345 2346 return matches; 2347 }, 2348 2349 // arg is for internal usage only 2350 map: function( elems, callback, arg ) { 2351 var length, value, 2352 i = 0, 2353 ret = []; 2354 2355 // Go through the array, translating each of the items to their new values 2356 if ( isArrayLike( elems ) ) { 2357 length = elems.length; 2358 for ( ; i < length; i++ ) { 2359 value = callback( elems[ i ], i, arg ); 2360 2361 if ( value != null ) { 2362 ret.push( value ); 2363 } 2364 } 2365 2366 // Go through every key on the object, 2367 } else { 2368 for ( i in elems ) { 2369 value = callback( elems[ i ], i, arg ); 2370 2371 if ( value != null ) { 2372 ret.push( value ); 2373 } 2374 } 2375 } 2376 2377 // Flatten any nested arrays 2378 return flat( ret ); 2379 }, 2380 2381 // A global GUID counter for objects 2382 guid: 1, 2383 2384 // jQuery.support is not used in Core but other projects attach their 2385 // properties to it so it needs to exist. 2386 support: support 2387} ); 2388 2389if ( typeof Symbol === "function" ) { 2390 jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ]; 2391} 2392 2393// Populate the class2type map 2394jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), 2395 function( _i, name ) { 2396 class2type[ "[object " + name + "]" ] = name.toLowerCase(); 2397 } ); 2398 2399function isArrayLike( obj ) { 2400 2401 // Support: real iOS 8.2 only (not reproducible in simulator) 2402 // `in` check used to prevent JIT error (gh-2145) 2403 // hasOwn isn't used here due to false negatives 2404 // regarding Nodelist length in IE 2405 var length = !!obj && "length" in obj && obj.length, 2406 type = toType( obj ); 2407 2408 if ( isFunction( obj ) || isWindow( obj ) ) { 2409 return false; 2410 } 2411 2412 return type === "array" || length === 0 || 2413 typeof length === "number" && length > 0 && ( length - 1 ) in obj; 2414} 2415var Sizzle = 2416/*! 2417 * Sizzle CSS Selector Engine v2.3.6 2418 * https://sizzlejs.com/ 2419 * 2420 * Copyright JS Foundation and other contributors 2421 * Released under the MIT license 2422 * https://js.foundation/ 2423 * 2424 * Date: 2021-02-16 2425 */ 2426( function( window ) { 2427var i, 2428 support, 2429 Expr, 2430 getText, 2431 isXML, 2432 tokenize, 2433 compile, 2434 select, 2435 outermostContext, 2436 sortInput, 2437 hasDuplicate, 2438 2439 // Local document vars 2440 setDocument, 2441 document, 2442 docElem, 2443 documentIsHTML, 2444 rbuggyQSA, 2445 rbuggyMatches, 2446 matches, 2447 contains, 2448 2449 // Instance-specific data 2450 expando = "sizzle" + 1 * new Date(), 2451 preferredDoc = window.document, 2452 dirruns = 0, 2453 done = 0, 2454 classCache = createCache(), 2455 tokenCache = createCache(), 2456 compilerCache = createCache(), 2457 nonnativeSelectorCache = createCache(), 2458 sortOrder = function( a, b ) { 2459 if ( a === b ) { 2460 hasDuplicate = true; 2461 } 2462 return 0; 2463 }, 2464 2465 // Instance methods 2466 hasOwn = ( {} ).hasOwnProperty, 2467 arr = [], 2468 pop = arr.pop, 2469 pushNative = arr.push, 2470 push = arr.push, 2471 slice = arr.slice, 2472 2473 // Use a stripped-down indexOf as it's faster than native 2474 // https://jsperf.com/thor-indexof-vs-for/5 2475 indexOf = function( list, elem ) { 2476 var i = 0, 2477 len = list.length; 2478 for ( ; i < len; i++ ) { 2479 if ( list[ i ] === elem ) { 2480 return i; 2481 } 2482 } 2483 return -1; 2484 }, 2485 2486 booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|" + 2487 "ismap|loop|multiple|open|readonly|required|scoped", 2488 2489 // Regular expressions 2490 2491 // http://www.w3.org/TR/css3-selectors/#whitespace 2492 whitespace = "[\\x20\\t\\r\\n\\f]", 2493 2494 // https://www.w3.org/TR/css-syntax-3/#ident-token-diagram 2495 identifier = "(?:\\\\[\\da-fA-F]{1,6}" + whitespace + 2496 "?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+", 2497 2498 // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors 2499 attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + 2500 2501 // Operator (capture 2) 2502 "*([*^$|!~]?=)" + whitespace + 2503 2504 // "Attribute values must be CSS identifiers [capture 5] 2505 // or strings [capture 3 or capture 4]" 2506 "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + 2507 whitespace + "*\\]", 2508 2509 pseudos = ":(" + identifier + ")(?:\\((" + 2510 2511 // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: 2512 // 1. quoted (capture 3; capture 4 or capture 5) 2513 "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + 2514 2515 // 2. simple (capture 6) 2516 "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + 2517 2518 // 3. anything else (capture 2) 2519 ".*" + 2520 ")\\)|)", 2521 2522 // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter 2523 rwhitespace = new RegExp( whitespace + "+", "g" ), 2524 rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + 2525 whitespace + "+$", "g" ), 2526 2527 rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), 2528 rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + 2529 "*" ), 2530 rdescend = new RegExp( whitespace + "|>" ), 2531 2532 rpseudo = new RegExp( pseudos ), 2533 ridentifier = new RegExp( "^" + identifier + "$" ), 2534 2535 matchExpr = { 2536 "ID": new RegExp( "^#(" + identifier + ")" ), 2537 "CLASS": new RegExp( "^\\.(" + identifier + ")" ), 2538 "TAG": new RegExp( "^(" + identifier + "|[*])" ), 2539 "ATTR": new RegExp( "^" + attributes ), 2540 "PSEUDO": new RegExp( "^" + pseudos ), 2541 "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + 2542 whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + 2543 whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), 2544 "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), 2545 2546 // For use in libraries implementing .is() 2547 // We use this for POS matching in `select` 2548 "needsContext": new RegExp( "^" + whitespace + 2549 "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + 2550 "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) 2551 }, 2552 2553 rhtml = /HTML$/i, 2554 rinputs = /^(?:input|select|textarea|button)$/i, 2555 rheader = /^h\d$/i, 2556 2557 rnative = /^[^{]+\{\s*\[native \w/, 2558 2559 // Easily-parseable/retrievable ID or TAG or CLASS selectors 2560 rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, 2561 2562 rsibling = /[+~]/, 2563 2564 // CSS escapes 2565 // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters 2566 runescape = new RegExp( "\\\\[\\da-fA-F]{1,6}" + whitespace + "?|\\\\([^\\r\\n\\f])", "g" ), 2567 funescape = function( escape, nonHex ) { 2568 var high = "0x" + escape.slice( 1 ) - 0x10000; 2569 2570 return nonHex ? 2571 2572 // Strip the backslash prefix from a non-hex escape sequence 2573 nonHex : 2574 2575 // Replace a hexadecimal escape sequence with the encoded Unicode code point 2576 // Support: IE <=11+ 2577 // For values outside the Basic Multilingual Plane (BMP), manually construct a 2578 // surrogate pair 2579 high < 0 ? 2580 String.fromCharCode( high + 0x10000 ) : 2581 String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); 2582 }, 2583 2584 // CSS string/identifier serialization 2585 // https://drafts.csswg.org/cssom/#common-serializing-idioms 2586 rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g, 2587 fcssescape = function( ch, asCodePoint ) { 2588 if ( asCodePoint ) { 2589 2590 // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER 2591 if ( ch === "\0" ) { 2592 return "\uFFFD"; 2593 } 2594 2595 // Control characters and (dependent upon position) numbers get escaped as code points 2596 return ch.slice( 0, -1 ) + "\\" + 2597 ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; 2598 } 2599 2600 // Other potentially-special ASCII characters get backslash-escaped 2601 return "\\" + ch; 2602 }, 2603 2604 // Used for iframes 2605 // See setDocument() 2606 // Removing the function wrapper causes a "Permission Denied" 2607 // error in IE 2608 unloadHandler = function() { 2609 setDocument(); 2610 }, 2611 2612 inDisabledFieldset = addCombinator( 2613 function( elem ) { 2614 return elem.disabled === true && elem.nodeName.toLowerCase() === "fieldset"; 2615 }, 2616 { dir: "parentNode", next: "legend" } 2617 ); 2618 2619// Optimize for push.apply( _, NodeList ) 2620try { 2621 push.apply( 2622 ( arr = slice.call( preferredDoc.childNodes ) ), 2623 preferredDoc.childNodes 2624 ); 2625 2626 // Support: Android<4.0 2627 // Detect silently failing push.apply 2628 // eslint-disable-next-line no-unused-expressions 2629 arr[ preferredDoc.childNodes.length ].nodeType; 2630} catch ( e ) { 2631 push = { apply: arr.length ? 2632 2633 // Leverage slice if possible 2634 function( target, els ) { 2635 pushNative.apply( target, slice.call( els ) ); 2636 } : 2637 2638 // Support: IE<9 2639 // Otherwise append directly 2640 function( target, els ) { 2641 var j = target.length, 2642 i = 0; 2643 2644 // Can't trust NodeList.length 2645 while ( ( target[ j++ ] = els[ i++ ] ) ) {} 2646 target.length = j - 1; 2647 } 2648 }; 2649} 2650 2651function Sizzle( selector, context, results, seed ) { 2652 var m, i, elem, nid, match, groups, newSelector, 2653 newContext = context && context.ownerDocument, 2654 2655 // nodeType defaults to 9, since context defaults to document 2656 nodeType = context ? context.nodeType : 9; 2657 2658 results = results || []; 2659 2660 // Return early from calls with invalid selector or context 2661 if ( typeof selector !== "string" || !selector || 2662 nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { 2663 2664 return results; 2665 } 2666 2667 // Try to shortcut find operations (as opposed to filters) in HTML documents 2668 if ( !seed ) { 2669 setDocument( context ); 2670 context = context || document; 2671 2672 if ( documentIsHTML ) { 2673 2674 // If the selector is sufficiently simple, try using a "get*By*" DOM method 2675 // (excepting DocumentFragment context, where the methods don't exist) 2676 if ( nodeType !== 11 && ( match = rquickExpr.exec( selector ) ) ) { 2677 2678 // ID selector 2679 if ( ( m = match[ 1 ] ) ) { 2680 2681 // Document context 2682 if ( nodeType === 9 ) { 2683 if ( ( elem = context.getElementById( m ) ) ) { 2684 2685 // Support: IE, Opera, Webkit 2686 // TODO: identify versions 2687 // getElementById can match elements by name instead of ID 2688 if ( elem.id === m ) { 2689 results.push( elem ); 2690 return results; 2691 } 2692 } else { 2693 return results; 2694 } 2695 2696 // Element context 2697 } else { 2698 2699 // Support: IE, Opera, Webkit 2700 // TODO: identify versions 2701 // getElementById can match elements by name instead of ID 2702 if ( newContext && ( elem = newContext.getElementById( m ) ) && 2703 contains( context, elem ) && 2704 elem.id === m ) { 2705 2706 results.push( elem ); 2707 return results; 2708 } 2709 } 2710 2711 // Type selector 2712 } else if ( match[ 2 ] ) { 2713 push.apply( results, context.getElementsByTagName( selector ) ); 2714 return results; 2715 2716 // Class selector 2717 } else if ( ( m = match[ 3 ] ) && support.getElementsByClassName && 2718 context.getElementsByClassName ) { 2719 2720 push.apply( results, context.getElementsByClassName( m ) ); 2721 return results; 2722 } 2723 } 2724 2725 // Take advantage of querySelectorAll 2726 if ( support.qsa && 2727 !nonnativeSelectorCache[ selector + " " ] && 2728 ( !rbuggyQSA || !rbuggyQSA.test( selector ) ) && 2729 2730 // Support: IE 8 only 2731 // Exclude object elements 2732 ( nodeType !== 1 || context.nodeName.toLowerCase() !== "object" ) ) { 2733 2734 newSelector = selector; 2735 newContext = context; 2736 2737 // qSA considers elements outside a scoping root when evaluating child or 2738 // descendant combinators, which is not what we want. 2739 // In such cases, we work around the behavior by prefixing every selector in the 2740 // list with an ID selector referencing the scope context. 2741 // The technique has to be used as well when a leading combinator is used 2742 // as such selectors are not recognized by querySelectorAll. 2743 // Thanks to Andrew Dupont for this technique. 2744 if ( nodeType === 1 && 2745 ( rdescend.test( selector ) || rcombinators.test( selector ) ) ) { 2746 2747 // Expand context for sibling selectors 2748 newContext = rsibling.test( selector ) && testContext( context.parentNode ) || 2749 context; 2750 2751 // We can use :scope instead of the ID hack if the browser 2752 // supports it & if we're not changing the context. 2753 if ( newContext !== context || !support.scope ) { 2754 2755 // Capture the context ID, setting it first if necessary 2756 if ( ( nid = context.getAttribute( "id" ) ) ) { 2757 nid = nid.replace( rcssescape, fcssescape ); 2758 } else { 2759 context.setAttribute( "id", ( nid = expando ) ); 2760 } 2761 } 2762 2763 // Prefix every selector in the list 2764 groups = tokenize( selector ); 2765 i = groups.length; 2766 while ( i-- ) { 2767 groups[ i ] = ( nid ? "#" + nid : ":scope" ) + " " + 2768 toSelector( groups[ i ] ); 2769 } 2770 newSelector = groups.join( "," ); 2771 } 2772 2773 try { 2774 push.apply( results, 2775 newContext.querySelectorAll( newSelector ) 2776 ); 2777 return results; 2778 } catch ( qsaError ) { 2779 nonnativeSelectorCache( selector, true ); 2780 } finally { 2781 if ( nid === expando ) { 2782 context.removeAttribute( "id" ); 2783 } 2784 } 2785 } 2786 } 2787 } 2788 2789 // All others 2790 return select( selector.replace( rtrim, "$1" ), context, results, seed ); 2791} 2792 2793/** 2794 * Create key-value caches of limited size 2795 * @returns {function(string, object)} Returns the Object data after storing it on itself with 2796 * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) 2797 * deleting the oldest entry 2798 */ 2799function createCache() { 2800 var keys = []; 2801 2802 function cache( key, value ) { 2803 2804 // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) 2805 if ( keys.push( key + " " ) > Expr.cacheLength ) { 2806 2807 // Only keep the most recent entries 2808 delete cache[ keys.shift() ]; 2809 } 2810 return ( cache[ key + " " ] = value ); 2811 } 2812 return cache; 2813} 2814 2815/** 2816 * Mark a function for special use by Sizzle 2817 * @param {Function} fn The function to mark 2818 */ 2819function markFunction( fn ) { 2820 fn[ expando ] = true; 2821 return fn; 2822} 2823 2824/** 2825 * Support testing using an element 2826 * @param {Function} fn Passed the created element and returns a boolean result 2827 */ 2828function assert( fn ) { 2829 var el = document.createElement( "fieldset" ); 2830 2831 try { 2832 return !!fn( el ); 2833 } catch ( e ) { 2834 return false; 2835 } finally { 2836 2837 // Remove from its parent by default 2838 if ( el.parentNode ) { 2839 el.parentNode.removeChild( el ); 2840 } 2841 2842 // release memory in IE 2843 el = null; 2844 } 2845} 2846 2847/** 2848 * Adds the same handler for all of the specified attrs 2849 * @param {String} attrs Pipe-separated list of attributes 2850 * @param {Function} handler The method that will be applied 2851 */ 2852function addHandle( attrs, handler ) { 2853 var arr = attrs.split( "|" ), 2854 i = arr.length; 2855 2856 while ( i-- ) { 2857 Expr.attrHandle[ arr[ i ] ] = handler; 2858 } 2859} 2860 2861/** 2862 * Checks document order of two siblings 2863 * @param {Element} a 2864 * @param {Element} b 2865 * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b 2866 */ 2867function siblingCheck( a, b ) { 2868 var cur = b && a, 2869 diff = cur && a.nodeType === 1 && b.nodeType === 1 && 2870 a.sourceIndex - b.sourceIndex; 2871 2872 // Use IE sourceIndex if available on both nodes 2873 if ( diff ) { 2874 return diff; 2875 } 2876 2877 // Check if b follows a 2878 if ( cur ) { 2879 while ( ( cur = cur.nextSibling ) ) { 2880 if ( cur === b ) { 2881 return -1; 2882 } 2883 } 2884 } 2885 2886 return a ? 1 : -1; 2887} 2888 2889/** 2890 * Returns a function to use in pseudos for input types 2891 * @param {String} type 2892 */ 2893function createInputPseudo( type ) { 2894 return function( elem ) { 2895 var name = elem.nodeName.toLowerCase(); 2896 return name === "input" && elem.type === type; 2897 }; 2898} 2899 2900/** 2901 * Returns a function to use in pseudos for buttons 2902 * @param {String} type 2903 */ 2904function createButtonPseudo( type ) { 2905 return function( elem ) { 2906 var name = elem.nodeName.toLowerCase(); 2907 return ( name === "input" || name === "button" ) && elem.type === type; 2908 }; 2909} 2910 2911/** 2912 * Returns a function to use in pseudos for :enabled/:disabled 2913 * @param {Boolean} disabled true for :disabled; false for :enabled 2914 */ 2915function createDisabledPseudo( disabled ) { 2916 2917 // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable 2918 return function( elem ) { 2919 2920 // Only certain elements can match :enabled or :disabled 2921 // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled 2922 // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled 2923 if ( "form" in elem ) { 2924 2925 // Check for inherited disabledness on relevant non-disabled elements: 2926 // * listed form-associated elements in a disabled fieldset 2927 // https://html.spec.whatwg.org/multipage/forms.html#category-listed 2928 // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled 2929 // * option elements in a disabled optgroup 2930 // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled 2931 // All such elements have a "form" property. 2932 if ( elem.parentNode && elem.disabled === false ) { 2933 2934 // Option elements defer to a parent optgroup if present 2935 if ( "label" in elem ) { 2936 if ( "label" in elem.parentNode ) { 2937 return elem.parentNode.disabled === disabled; 2938 } else { 2939 return elem.disabled === disabled; 2940 } 2941 } 2942 2943 // Support: IE 6 - 11 2944 // Use the isDisabled shortcut property to check for disabled fieldset ancestors 2945 return elem.isDisabled === disabled || 2946 2947 // Where there is no isDisabled, check manually 2948 /* jshint -W018 */ 2949 elem.isDisabled !== !disabled && 2950 inDisabledFieldset( elem ) === disabled; 2951 } 2952 2953 return elem.disabled === disabled; 2954 2955 // Try to winnow out elements that can't be disabled before trusting the disabled property. 2956 // Some victims get caught in our net (label, legend, menu, track), but it shouldn't 2957 // even exist on them, let alone have a boolean value. 2958 } else if ( "label" in elem ) { 2959 return elem.disabled === disabled; 2960 } 2961 2962 // Remaining elements are neither :enabled nor :disabled 2963 return false; 2964 }; 2965} 2966 2967/** 2968 * Returns a function to use in pseudos for positionals 2969 * @param {Function} fn 2970 */ 2971function createPositionalPseudo( fn ) { 2972 return markFunction( function( argument ) { 2973 argument = +argument; 2974 return markFunction( function( seed, matches ) { 2975 var j, 2976 matchIndexes = fn( [], seed.length, argument ), 2977 i = matchIndexes.length; 2978 2979 // Match elements found at the specified indexes 2980 while ( i-- ) { 2981 if ( seed[ ( j = matchIndexes[ i ] ) ] ) { 2982 seed[ j ] = !( matches[ j ] = seed[ j ] ); 2983 } 2984 } 2985 } ); 2986 } ); 2987} 2988 2989/** 2990 * Checks a node for validity as a Sizzle context 2991 * @param {Element|Object=} context 2992 * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value 2993 */ 2994function testContext( context ) { 2995 return context && typeof context.getElementsByTagName !== "undefined" && context; 2996} 2997 2998// Expose support vars for convenience 2999support = Sizzle.support = {}; 3000 3001/** 3002 * Detects XML nodes 3003 * @param {Element|Object} elem An element or a document 3004 * @returns {Boolean} True iff elem is a non-HTML XML node 3005 */ 3006isXML = Sizzle.isXML = function( elem ) { 3007 var namespace = elem && elem.namespaceURI, 3008 docElem = elem && ( elem.ownerDocument || elem ).documentElement; 3009 3010 // Support: IE <=8 3011 // Assume HTML when documentElement doesn't yet exist, such as inside loading iframes 3012 // https://bugs.jquery.com/ticket/4833 3013 return !rhtml.test( namespace || docElem && docElem.nodeName || "HTML" ); 3014}; 3015 3016/** 3017 * Sets document-related variables once based on the current document 3018 * @param {Element|Object} [doc] An element or document object to use to set the document 3019 * @returns {Object} Returns the current document 3020 */ 3021setDocument = Sizzle.setDocument = function( node ) { 3022 var hasCompare, subWindow, 3023 doc = node ? node.ownerDocument || node : preferredDoc; 3024 3025 // Return early if doc is invalid or already selected 3026 // Support: IE 11+, Edge 17 - 18+ 3027 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 3028 // two documents; shallow comparisons work. 3029 // eslint-disable-next-line eqeqeq 3030 if ( doc == document || doc.nodeType !== 9 || !doc.documentElement ) { 3031 return document; 3032 } 3033 3034 // Update global variables 3035 document = doc; 3036 docElem = document.documentElement; 3037 documentIsHTML = !isXML( document ); 3038 3039 // Support: IE 9 - 11+, Edge 12 - 18+ 3040 // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) 3041 // Support: IE 11+, Edge 17 - 18+ 3042 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 3043 // two documents; shallow comparisons work. 3044 // eslint-disable-next-line eqeqeq 3045 if ( preferredDoc != document && 3046 ( subWindow = document.defaultView ) && subWindow.top !== subWindow ) { 3047 3048 // Support: IE 11, Edge 3049 if ( subWindow.addEventListener ) { 3050 subWindow.addEventListener( "unload", unloadHandler, false ); 3051 3052 // Support: IE 9 - 10 only 3053 } else if ( subWindow.attachEvent ) { 3054 subWindow.attachEvent( "onunload", unloadHandler ); 3055 } 3056 } 3057 3058 // Support: IE 8 - 11+, Edge 12 - 18+, Chrome <=16 - 25 only, Firefox <=3.6 - 31 only, 3059 // Safari 4 - 5 only, Opera <=11.6 - 12.x only 3060 // IE/Edge & older browsers don't support the :scope pseudo-class. 3061 // Support: Safari 6.0 only 3062 // Safari 6.0 supports :scope but it's an alias of :root there. 3063 support.scope = assert( function( el ) { 3064 docElem.appendChild( el ).appendChild( document.createElement( "div" ) ); 3065 return typeof el.querySelectorAll !== "undefined" && 3066 !el.querySelectorAll( ":scope fieldset div" ).length; 3067 } ); 3068 3069 /* Attributes 3070 ---------------------------------------------------------------------- */ 3071 3072 // Support: IE<8 3073 // Verify that getAttribute really returns attributes and not properties 3074 // (excepting IE8 booleans) 3075 support.attributes = assert( function( el ) { 3076 el.className = "i"; 3077 return !el.getAttribute( "className" ); 3078 } ); 3079 3080 /* getElement(s)By* 3081 ---------------------------------------------------------------------- */ 3082 3083 // Check if getElementsByTagName("*") returns only elements 3084 support.getElementsByTagName = assert( function( el ) { 3085 el.appendChild( document.createComment( "" ) ); 3086 return !el.getElementsByTagName( "*" ).length; 3087 } ); 3088 3089 // Support: IE<9 3090 support.getElementsByClassName = rnative.test( document.getElementsByClassName ); 3091 3092 // Support: IE<10 3093 // Check if getElementById returns elements by name 3094 // The broken getElementById methods don't pick up programmatically-set names, 3095 // so use a roundabout getElementsByName test 3096 support.getById = assert( function( el ) { 3097 docElem.appendChild( el ).id = expando; 3098 return !document.getElementsByName || !document.getElementsByName( expando ).length; 3099 } ); 3100 3101 // ID filter and find 3102 if ( support.getById ) { 3103 Expr.filter[ "ID" ] = function( id ) { 3104 var attrId = id.replace( runescape, funescape ); 3105 return function( elem ) { 3106 return elem.getAttribute( "id" ) === attrId; 3107 }; 3108 }; 3109 Expr.find[ "ID" ] = function( id, context ) { 3110 if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { 3111 var elem = context.getElementById( id ); 3112 return elem ? [ elem ] : []; 3113 } 3114 }; 3115 } else { 3116 Expr.filter[ "ID" ] = function( id ) { 3117 var attrId = id.replace( runescape, funescape ); 3118 return function( elem ) { 3119 var node = typeof elem.getAttributeNode !== "undefined" && 3120 elem.getAttributeNode( "id" ); 3121 return node && node.value === attrId; 3122 }; 3123 }; 3124 3125 // Support: IE 6 - 7 only 3126 // getElementById is not reliable as a find shortcut 3127 Expr.find[ "ID" ] = function( id, context ) { 3128 if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { 3129 var node, i, elems, 3130 elem = context.getElementById( id ); 3131 3132 if ( elem ) { 3133 3134 // Verify the id attribute 3135 node = elem.getAttributeNode( "id" ); 3136 if ( node && node.value === id ) { 3137 return [ elem ]; 3138 } 3139 3140 // Fall back on getElementsByName 3141 elems = context.getElementsByName( id ); 3142 i = 0; 3143 while ( ( elem = elems[ i++ ] ) ) { 3144 node = elem.getAttributeNode( "id" ); 3145 if ( node && node.value === id ) { 3146 return [ elem ]; 3147 } 3148 } 3149 } 3150 3151 return []; 3152 } 3153 }; 3154 } 3155 3156 // Tag 3157 Expr.find[ "TAG" ] = support.getElementsByTagName ? 3158 function( tag, context ) { 3159 if ( typeof context.getElementsByTagName !== "undefined" ) { 3160 return context.getElementsByTagName( tag ); 3161 3162 // DocumentFragment nodes don't have gEBTN 3163 } else if ( support.qsa ) { 3164 return context.querySelectorAll( tag ); 3165 } 3166 } : 3167 3168 function( tag, context ) { 3169 var elem, 3170 tmp = [], 3171 i = 0, 3172 3173 // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too 3174 results = context.getElementsByTagName( tag ); 3175 3176 // Filter out possible comments 3177 if ( tag === "*" ) { 3178 while ( ( elem = results[ i++ ] ) ) { 3179 if ( elem.nodeType === 1 ) { 3180 tmp.push( elem ); 3181 } 3182 } 3183 3184 return tmp; 3185 } 3186 return results; 3187 }; 3188 3189 // Class 3190 Expr.find[ "CLASS" ] = support.getElementsByClassName && function( className, context ) { 3191 if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { 3192 return context.getElementsByClassName( className ); 3193 } 3194 }; 3195 3196 /* QSA/matchesSelector 3197 ---------------------------------------------------------------------- */ 3198 3199 // QSA and matchesSelector support 3200 3201 // matchesSelector(:active) reports false when true (IE9/Opera 11.5) 3202 rbuggyMatches = []; 3203 3204 // qSa(:focus) reports false when true (Chrome 21) 3205 // We allow this because of a bug in IE8/9 that throws an error 3206 // whenever `document.activeElement` is accessed on an iframe 3207 // So, we allow :focus to pass through QSA all the time to avoid the IE error 3208 // See https://bugs.jquery.com/ticket/13378 3209 rbuggyQSA = []; 3210 3211 if ( ( support.qsa = rnative.test( document.querySelectorAll ) ) ) { 3212 3213 // Build QSA regex 3214 // Regex strategy adopted from Diego Perini 3215 assert( function( el ) { 3216 3217 var input; 3218 3219 // Select is set to empty string on purpose 3220 // This is to test IE's treatment of not explicitly 3221 // setting a boolean content attribute, 3222 // since its presence should be enough 3223 // https://bugs.jquery.com/ticket/12359 3224 docElem.appendChild( el ).innerHTML = "<a id='" + expando + "'></a>" + 3225 "<select id='" + expando + "-\r\\' msallowcapture=''>" + 3226 "<option selected=''></option></select>"; 3227 3228 // Support: IE8, Opera 11-12.16 3229 // Nothing should be selected when empty strings follow ^= or $= or *= 3230 // The test attribute must be unknown in Opera but "safe" for WinRT 3231 // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section 3232 if ( el.querySelectorAll( "[msallowcapture^='']" ).length ) { 3233 rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); 3234 } 3235 3236 // Support: IE8 3237 // Boolean attributes and "value" are not treated correctly 3238 if ( !el.querySelectorAll( "[selected]" ).length ) { 3239 rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); 3240 } 3241 3242 // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ 3243 if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) { 3244 rbuggyQSA.push( "~=" ); 3245 } 3246 3247 // Support: IE 11+, Edge 15 - 18+ 3248 // IE 11/Edge don't find elements on a `[name='']` query in some cases. 3249 // Adding a temporary attribute to the document before the selection works 3250 // around the issue. 3251 // Interestingly, IE 10 & older don't seem to have the issue. 3252 input = document.createElement( "input" ); 3253 input.setAttribute( "name", "" ); 3254 el.appendChild( input ); 3255 if ( !el.querySelectorAll( "[name='']" ).length ) { 3256 rbuggyQSA.push( "\\[" + whitespace + "*name" + whitespace + "*=" + 3257 whitespace + "*(?:''|\"\")" ); 3258 } 3259 3260 // Webkit/Opera - :checked should return selected option elements 3261 // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked 3262 // IE8 throws error here and will not see later tests 3263 if ( !el.querySelectorAll( ":checked" ).length ) { 3264 rbuggyQSA.push( ":checked" ); 3265 } 3266 3267 // Support: Safari 8+, iOS 8+ 3268 // https://bugs.webkit.org/show_bug.cgi?id=136851 3269 // In-page `selector#id sibling-combinator selector` fails 3270 if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) { 3271 rbuggyQSA.push( ".#.+[+~]" ); 3272 } 3273 3274 // Support: Firefox <=3.6 - 5 only 3275 // Old Firefox doesn't throw on a badly-escaped identifier. 3276 el.querySelectorAll( "\\\f" ); 3277 rbuggyQSA.push( "[\\r\\n\\f]" ); 3278 } ); 3279 3280 assert( function( el ) { 3281 el.innerHTML = "<a href='' disabled='disabled'></a>" + 3282 "<select disabled='disabled'><option/></select>"; 3283 3284 // Support: Windows 8 Native Apps 3285 // The type and name attributes are restricted during .innerHTML assignment 3286 var input = document.createElement( "input" ); 3287 input.setAttribute( "type", "hidden" ); 3288 el.appendChild( input ).setAttribute( "name", "D" ); 3289 3290 // Support: IE8 3291 // Enforce case-sensitivity of name attribute 3292 if ( el.querySelectorAll( "[name=d]" ).length ) { 3293 rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); 3294 } 3295 3296 // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) 3297 // IE8 throws error here and will not see later tests 3298 if ( el.querySelectorAll( ":enabled" ).length !== 2 ) { 3299 rbuggyQSA.push( ":enabled", ":disabled" ); 3300 } 3301 3302 // Support: IE9-11+ 3303 // IE's :disabled selector does not pick up the children of disabled fieldsets 3304 docElem.appendChild( el ).disabled = true; 3305 if ( el.querySelectorAll( ":disabled" ).length !== 2 ) { 3306 rbuggyQSA.push( ":enabled", ":disabled" ); 3307 } 3308 3309 // Support: Opera 10 - 11 only 3310 // Opera 10-11 does not throw on post-comma invalid pseudos 3311 el.querySelectorAll( "*,:x" ); 3312 rbuggyQSA.push( ",.*:" ); 3313 } ); 3314 } 3315 3316 if ( ( support.matchesSelector = rnative.test( ( matches = docElem.matches || 3317 docElem.webkitMatchesSelector || 3318 docElem.mozMatchesSelector || 3319 docElem.oMatchesSelector || 3320 docElem.msMatchesSelector ) ) ) ) { 3321 3322 assert( function( el ) { 3323 3324 // Check to see if it's possible to do matchesSelector 3325 // on a disconnected node (IE 9) 3326 support.disconnectedMatch = matches.call( el, "*" ); 3327 3328 // This should fail with an exception 3329 // Gecko does not error, returns false instead 3330 matches.call( el, "[s!='']:x" ); 3331 rbuggyMatches.push( "!=", pseudos ); 3332 } ); 3333 } 3334 3335 rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join( "|" ) ); 3336 rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join( "|" ) ); 3337 3338 /* Contains 3339 ---------------------------------------------------------------------- */ 3340 hasCompare = rnative.test( docElem.compareDocumentPosition ); 3341 3342 // Element contains another 3343 // Purposefully self-exclusive 3344 // As in, an element does not contain itself 3345 contains = hasCompare || rnative.test( docElem.contains ) ? 3346 function( a, b ) { 3347 var adown = a.nodeType === 9 ? a.documentElement : a, 3348 bup = b && b.parentNode; 3349 return a === bup || !!( bup && bup.nodeType === 1 && ( 3350 adown.contains ? 3351 adown.contains( bup ) : 3352 a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 3353 ) ); 3354 } : 3355 function( a, b ) { 3356 if ( b ) { 3357 while ( ( b = b.parentNode ) ) { 3358 if ( b === a ) { 3359 return true; 3360 } 3361 } 3362 } 3363 return false; 3364 }; 3365 3366 /* Sorting 3367 ---------------------------------------------------------------------- */ 3368 3369 // Document order sorting 3370 sortOrder = hasCompare ? 3371 function( a, b ) { 3372 3373 // Flag for duplicate removal 3374 if ( a === b ) { 3375 hasDuplicate = true; 3376 return 0; 3377 } 3378 3379 // Sort on method existence if only one input has compareDocumentPosition 3380 var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; 3381 if ( compare ) { 3382 return compare; 3383 } 3384 3385 // Calculate position if both inputs belong to the same document 3386 // Support: IE 11+, Edge 17 - 18+ 3387 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 3388 // two documents; shallow comparisons work. 3389 // eslint-disable-next-line eqeqeq 3390 compare = ( a.ownerDocument || a ) == ( b.ownerDocument || b ) ? 3391 a.compareDocumentPosition( b ) : 3392 3393 // Otherwise we know they are disconnected 3394 1; 3395 3396 // Disconnected nodes 3397 if ( compare & 1 || 3398 ( !support.sortDetached && b.compareDocumentPosition( a ) === compare ) ) { 3399 3400 // Choose the first element that is related to our preferred document 3401 // Support: IE 11+, Edge 17 - 18+ 3402 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 3403 // two documents; shallow comparisons work. 3404 // eslint-disable-next-line eqeqeq 3405 if ( a == document || a.ownerDocument == preferredDoc && 3406 contains( preferredDoc, a ) ) { 3407 return -1; 3408 } 3409 3410 // Support: IE 11+, Edge 17 - 18+ 3411 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 3412 // two documents; shallow comparisons work. 3413 // eslint-disable-next-line eqeqeq 3414 if ( b == document || b.ownerDocument == preferredDoc && 3415 contains( preferredDoc, b ) ) { 3416 return 1; 3417 } 3418 3419 // Maintain original order 3420 return sortInput ? 3421 ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : 3422 0; 3423 } 3424 3425 return compare & 4 ? -1 : 1; 3426 } : 3427 function( a, b ) { 3428 3429 // Exit early if the nodes are identical 3430 if ( a === b ) { 3431 hasDuplicate = true; 3432 return 0; 3433 } 3434 3435 var cur, 3436 i = 0, 3437 aup = a.parentNode, 3438 bup = b.parentNode, 3439 ap = [ a ], 3440 bp = [ b ]; 3441 3442 // Parentless nodes are either documents or disconnected 3443 if ( !aup || !bup ) { 3444 3445 // Support: IE 11+, Edge 17 - 18+ 3446 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 3447 // two documents; shallow comparisons work. 3448 /* eslint-disable eqeqeq */ 3449 return a == document ? -1 : 3450 b == document ? 1 : 3451 /* eslint-enable eqeqeq */ 3452 aup ? -1 : 3453 bup ? 1 : 3454 sortInput ? 3455 ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : 3456 0; 3457 3458 // If the nodes are siblings, we can do a quick check 3459 } else if ( aup === bup ) { 3460 return siblingCheck( a, b ); 3461 } 3462 3463 // Otherwise we need full lists of their ancestors for comparison 3464 cur = a; 3465 while ( ( cur = cur.parentNode ) ) { 3466 ap.unshift( cur ); 3467 } 3468 cur = b; 3469 while ( ( cur = cur.parentNode ) ) { 3470 bp.unshift( cur ); 3471 } 3472 3473 // Walk down the tree looking for a discrepancy 3474 while ( ap[ i ] === bp[ i ] ) { 3475 i++; 3476 } 3477 3478 return i ? 3479 3480 // Do a sibling check if the nodes have a common ancestor 3481 siblingCheck( ap[ i ], bp[ i ] ) : 3482 3483 // Otherwise nodes in our document sort first 3484 // Support: IE 11+, Edge 17 - 18+ 3485 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 3486 // two documents; shallow comparisons work. 3487 /* eslint-disable eqeqeq */ 3488 ap[ i ] == preferredDoc ? -1 : 3489 bp[ i ] == preferredDoc ? 1 : 3490 /* eslint-enable eqeqeq */ 3491 0; 3492 }; 3493 3494 return document; 3495}; 3496 3497Sizzle.matches = function( expr, elements ) { 3498 return Sizzle( expr, null, null, elements ); 3499}; 3500 3501Sizzle.matchesSelector = function( elem, expr ) { 3502 setDocument( elem ); 3503 3504 if ( support.matchesSelector && documentIsHTML && 3505 !nonnativeSelectorCache[ expr + " " ] && 3506 ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && 3507 ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { 3508 3509 try { 3510 var ret = matches.call( elem, expr ); 3511 3512 // IE 9's matchesSelector returns false on disconnected nodes 3513 if ( ret || support.disconnectedMatch || 3514 3515 // As well, disconnected nodes are said to be in a document 3516 // fragment in IE 9 3517 elem.document && elem.document.nodeType !== 11 ) { 3518 return ret; 3519 } 3520 } catch ( e ) { 3521 nonnativeSelectorCache( expr, true ); 3522 } 3523 } 3524 3525 return Sizzle( expr, document, null, [ elem ] ).length > 0; 3526}; 3527 3528Sizzle.contains = function( context, elem ) { 3529 3530 // Set document vars if needed 3531 // Support: IE 11+, Edge 17 - 18+ 3532 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 3533 // two documents; shallow comparisons work. 3534 // eslint-disable-next-line eqeqeq 3535 if ( ( context.ownerDocument || context ) != document ) { 3536 setDocument( context ); 3537 } 3538 return contains( context, elem ); 3539}; 3540 3541Sizzle.attr = function( elem, name ) { 3542 3543 // Set document vars if needed 3544 // Support: IE 11+, Edge 17 - 18+ 3545 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 3546 // two documents; shallow comparisons work. 3547 // eslint-disable-next-line eqeqeq 3548 if ( ( elem.ownerDocument || elem ) != document ) { 3549 setDocument( elem ); 3550 } 3551 3552 var fn = Expr.attrHandle[ name.toLowerCase() ], 3553 3554 // Don't get fooled by Object.prototype properties (jQuery #13807) 3555 val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? 3556 fn( elem, name, !documentIsHTML ) : 3557 undefined; 3558 3559 return val !== undefined ? 3560 val : 3561 support.attributes || !documentIsHTML ? 3562 elem.getAttribute( name ) : 3563 ( val = elem.getAttributeNode( name ) ) && val.specified ? 3564 val.value : 3565 null; 3566}; 3567 3568Sizzle.escape = function( sel ) { 3569 return ( sel + "" ).replace( rcssescape, fcssescape ); 3570}; 3571 3572Sizzle.error = function( msg ) { 3573 throw new Error( "Syntax error, unrecognized expression: " + msg ); 3574}; 3575 3576/** 3577 * Document sorting and removing duplicates 3578 * @param {ArrayLike} results 3579 */ 3580Sizzle.uniqueSort = function( results ) { 3581 var elem, 3582 duplicates = [], 3583 j = 0, 3584 i = 0; 3585 3586 // Unless we *know* we can detect duplicates, assume their presence 3587 hasDuplicate = !support.detectDuplicates; 3588 sortInput = !support.sortStable && results.slice( 0 ); 3589 results.sort( sortOrder ); 3590 3591 if ( hasDuplicate ) { 3592 while ( ( elem = results[ i++ ] ) ) { 3593 if ( elem === results[ i ] ) { 3594 j = duplicates.push( i ); 3595 } 3596 } 3597 while ( j-- ) { 3598 results.splice( duplicates[ j ], 1 ); 3599 } 3600 } 3601 3602 // Clear input after sorting to release objects 3603 // See https://github.com/jquery/sizzle/pull/225 3604 sortInput = null; 3605 3606 return results; 3607}; 3608 3609/** 3610 * Utility function for retrieving the text value of an array of DOM nodes 3611 * @param {Array|Element} elem 3612 */ 3613getText = Sizzle.getText = function( elem ) { 3614 var node, 3615 ret = "", 3616 i = 0, 3617 nodeType = elem.nodeType; 3618 3619 if ( !nodeType ) { 3620 3621 // If no nodeType, this is expected to be an array 3622 while ( ( node = elem[ i++ ] ) ) { 3623 3624 // Do not traverse comment nodes 3625 ret += getText( node ); 3626 } 3627 } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { 3628 3629 // Use textContent for elements 3630 // innerText usage removed for consistency of new lines (jQuery #11153) 3631 if ( typeof elem.textContent === "string" ) { 3632 return elem.textContent; 3633 } else { 3634 3635 // Traverse its children 3636 for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { 3637 ret += getText( elem ); 3638 } 3639 } 3640 } else if ( nodeType === 3 || nodeType === 4 ) { 3641 return elem.nodeValue; 3642 } 3643 3644 // Do not include comment or processing instruction nodes 3645 3646 return ret; 3647}; 3648 3649Expr = Sizzle.selectors = { 3650 3651 // Can be adjusted by the user 3652 cacheLength: 50, 3653 3654 createPseudo: markFunction, 3655 3656 match: matchExpr, 3657 3658 attrHandle: {}, 3659 3660 find: {}, 3661 3662 relative: { 3663 ">": { dir: "parentNode", first: true }, 3664 " ": { dir: "parentNode" }, 3665 "+": { dir: "previousSibling", first: true }, 3666 "~": { dir: "previousSibling" } 3667 }, 3668 3669 preFilter: { 3670 "ATTR": function( match ) { 3671 match[ 1 ] = match[ 1 ].replace( runescape, funescape ); 3672 3673 // Move the given value to match[3] whether quoted or unquoted 3674 match[ 3 ] = ( match[ 3 ] || match[ 4 ] || 3675 match[ 5 ] || "" ).replace( runescape, funescape ); 3676 3677 if ( match[ 2 ] === "~=" ) { 3678 match[ 3 ] = " " + match[ 3 ] + " "; 3679 } 3680 3681 return match.slice( 0, 4 ); 3682 }, 3683 3684 "CHILD": function( match ) { 3685 3686 /* matches from matchExpr["CHILD"] 3687 1 type (only|nth|...) 3688 2 what (child|of-type) 3689 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) 3690 4 xn-component of xn+y argument ([+-]?\d*n|) 3691 5 sign of xn-component 3692 6 x of xn-component 3693 7 sign of y-component 3694 8 y of y-component 3695 */ 3696 match[ 1 ] = match[ 1 ].toLowerCase(); 3697 3698 if ( match[ 1 ].slice( 0, 3 ) === "nth" ) { 3699 3700 // nth-* requires argument 3701 if ( !match[ 3 ] ) { 3702 Sizzle.error( match[ 0 ] ); 3703 } 3704 3705 // numeric x and y parameters for Expr.filter.CHILD 3706 // remember that false/true cast respectively to 0/1 3707 match[ 4 ] = +( match[ 4 ] ? 3708 match[ 5 ] + ( match[ 6 ] || 1 ) : 3709 2 * ( match[ 3 ] === "even" || match[ 3 ] === "odd" ) ); 3710 match[ 5 ] = +( ( match[ 7 ] + match[ 8 ] ) || match[ 3 ] === "odd" ); 3711 3712 // other types prohibit arguments 3713 } else if ( match[ 3 ] ) { 3714 Sizzle.error( match[ 0 ] ); 3715 } 3716 3717 return match; 3718 }, 3719 3720 "PSEUDO": function( match ) { 3721 var excess, 3722 unquoted = !match[ 6 ] && match[ 2 ]; 3723 3724 if ( matchExpr[ "CHILD" ].test( match[ 0 ] ) ) { 3725 return null; 3726 } 3727 3728 // Accept quoted arguments as-is 3729 if ( match[ 3 ] ) { 3730 match[ 2 ] = match[ 4 ] || match[ 5 ] || ""; 3731 3732 // Strip excess characters from unquoted arguments 3733 } else if ( unquoted && rpseudo.test( unquoted ) && 3734 3735 // Get excess from tokenize (recursively) 3736 ( excess = tokenize( unquoted, true ) ) && 3737 3738 // advance to the next closing parenthesis 3739 ( excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length ) ) { 3740 3741 // excess is a negative index 3742 match[ 0 ] = match[ 0 ].slice( 0, excess ); 3743 match[ 2 ] = unquoted.slice( 0, excess ); 3744 } 3745 3746 // Return only captures needed by the pseudo filter method (type and argument) 3747 return match.slice( 0, 3 ); 3748 } 3749 }, 3750 3751 filter: { 3752 3753 "TAG": function( nodeNameSelector ) { 3754 var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); 3755 return nodeNameSelector === "*" ? 3756 function() { 3757 return true; 3758 } : 3759 function( elem ) { 3760 return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; 3761 }; 3762 }, 3763 3764 "CLASS": function( className ) { 3765 var pattern = classCache[ className + " " ]; 3766 3767 return pattern || 3768 ( pattern = new RegExp( "(^|" + whitespace + 3769 ")" + className + "(" + whitespace + "|$)" ) ) && classCache( 3770 className, function( elem ) { 3771 return pattern.test( 3772 typeof elem.className === "string" && elem.className || 3773 typeof elem.getAttribute !== "undefined" && 3774 elem.getAttribute( "class" ) || 3775 "" 3776 ); 3777 } ); 3778 }, 3779 3780 "ATTR": function( name, operator, check ) { 3781 return function( elem ) { 3782 var result = Sizzle.attr( elem, name ); 3783 3784 if ( result == null ) { 3785 return operator === "!="; 3786 } 3787 if ( !operator ) { 3788 return true; 3789 } 3790 3791 result += ""; 3792 3793 /* eslint-disable max-len */ 3794 3795 return operator === "=" ? result === check : 3796 operator === "!=" ? result !== check : 3797 operator === "^=" ? check && result.indexOf( check ) === 0 : 3798 operator === "*=" ? check && result.indexOf( check ) > -1 : 3799 operator === "$=" ? check && result.slice( -check.length ) === check : 3800 operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : 3801 operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : 3802 false; 3803 /* eslint-enable max-len */ 3804 3805 }; 3806 }, 3807 3808 "CHILD": function( type, what, _argument, first, last ) { 3809 var simple = type.slice( 0, 3 ) !== "nth", 3810 forward = type.slice( -4 ) !== "last", 3811 ofType = what === "of-type"; 3812 3813 return first === 1 && last === 0 ? 3814 3815 // Shortcut for :nth-*(n) 3816 function( elem ) { 3817 return !!elem.parentNode; 3818 } : 3819 3820 function( elem, _context, xml ) { 3821 var cache, uniqueCache, outerCache, node, nodeIndex, start, 3822 dir = simple !== forward ? "nextSibling" : "previousSibling", 3823 parent = elem.parentNode, 3824 name = ofType && elem.nodeName.toLowerCase(), 3825 useCache = !xml && !ofType, 3826 diff = false; 3827 3828 if ( parent ) { 3829 3830 // :(first|last|only)-(child|of-type) 3831 if ( simple ) { 3832 while ( dir ) { 3833 node = elem; 3834 while ( ( node = node[ dir ] ) ) { 3835 if ( ofType ? 3836 node.nodeName.toLowerCase() === name : 3837 node.nodeType === 1 ) { 3838 3839 return false; 3840 } 3841 } 3842 3843 // Reverse direction for :only-* (if we haven't yet done so) 3844 start = dir = type === "only" && !start && "nextSibling"; 3845 } 3846 return true; 3847 } 3848 3849 start = [ forward ? parent.firstChild : parent.lastChild ]; 3850 3851 // non-xml :nth-child(...) stores cache data on `parent` 3852 if ( forward && useCache ) { 3853 3854 // Seek `elem` from a previously-cached index 3855 3856 // ...in a gzip-friendly way 3857 node = parent; 3858 outerCache = node[ expando ] || ( node[ expando ] = {} ); 3859 3860 // Support: IE <9 only 3861 // Defend against cloned attroperties (jQuery gh-1709) 3862 uniqueCache = outerCache[ node.uniqueID ] || 3863 ( outerCache[ node.uniqueID ] = {} ); 3864 3865 cache = uniqueCache[ type ] || []; 3866 nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; 3867 diff = nodeIndex && cache[ 2 ]; 3868 node = nodeIndex && parent.childNodes[ nodeIndex ]; 3869 3870 while ( ( node = ++nodeIndex && node && node[ dir ] || 3871 3872 // Fallback to seeking `elem` from the start 3873 ( diff = nodeIndex = 0 ) || start.pop() ) ) { 3874 3875 // When found, cache indexes on `parent` and break 3876 if ( node.nodeType === 1 && ++diff && node === elem ) { 3877 uniqueCache[ type ] = [ dirruns, nodeIndex, diff ]; 3878 break; 3879 } 3880 } 3881 3882 } else { 3883 3884 // Use previously-cached element index if available 3885 if ( useCache ) { 3886 3887 // ...in a gzip-friendly way 3888 node = elem; 3889 outerCache = node[ expando ] || ( node[ expando ] = {} ); 3890 3891 // Support: IE <9 only 3892 // Defend against cloned attroperties (jQuery gh-1709) 3893 uniqueCache = outerCache[ node.uniqueID ] || 3894 ( outerCache[ node.uniqueID ] = {} ); 3895 3896 cache = uniqueCache[ type ] || []; 3897 nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; 3898 diff = nodeIndex; 3899 } 3900 3901 // xml :nth-child(...) 3902 // or :nth-last-child(...) or :nth(-last)?-of-type(...) 3903 if ( diff === false ) { 3904 3905 // Use the same loop as above to seek `elem` from the start 3906 while ( ( node = ++nodeIndex && node && node[ dir ] || 3907 ( diff = nodeIndex = 0 ) || start.pop() ) ) { 3908 3909 if ( ( ofType ? 3910 node.nodeName.toLowerCase() === name : 3911 node.nodeType === 1 ) && 3912 ++diff ) { 3913 3914 // Cache the index of each encountered element 3915 if ( useCache ) { 3916 outerCache = node[ expando ] || 3917 ( node[ expando ] = {} ); 3918 3919 // Support: IE <9 only 3920 // Defend against cloned attroperties (jQuery gh-1709) 3921 uniqueCache = outerCache[ node.uniqueID ] || 3922 ( outerCache[ node.uniqueID ] = {} ); 3923 3924 uniqueCache[ type ] = [ dirruns, diff ]; 3925 } 3926 3927 if ( node === elem ) { 3928 break; 3929 } 3930 } 3931 } 3932 } 3933 } 3934 3935 // Incorporate the offset, then check against cycle size 3936 diff -= last; 3937 return diff === first || ( diff % first === 0 && diff / first >= 0 ); 3938 } 3939 }; 3940 }, 3941 3942 "PSEUDO": function( pseudo, argument ) { 3943 3944 // pseudo-class names are case-insensitive 3945 // http://www.w3.org/TR/selectors/#pseudo-classes 3946 // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters 3947 // Remember that setFilters inherits from pseudos 3948 var args, 3949 fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || 3950 Sizzle.error( "unsupported pseudo: " + pseudo ); 3951 3952 // The user may use createPseudo to indicate that 3953 // arguments are needed to create the filter function 3954 // just as Sizzle does 3955 if ( fn[ expando ] ) { 3956 return fn( argument ); 3957 } 3958 3959 // But maintain support for old signatures 3960 if ( fn.length > 1 ) { 3961 args = [ pseudo, pseudo, "", argument ]; 3962 return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? 3963 markFunction( function( seed, matches ) { 3964 var idx, 3965 matched = fn( seed, argument ), 3966 i = matched.length; 3967 while ( i-- ) { 3968 idx = indexOf( seed, matched[ i ] ); 3969 seed[ idx ] = !( matches[ idx ] = matched[ i ] ); 3970 } 3971 } ) : 3972 function( elem ) { 3973 return fn( elem, 0, args ); 3974 }; 3975 } 3976 3977 return fn; 3978 } 3979 }, 3980 3981 pseudos: { 3982 3983 // Potentially complex pseudos 3984 "not": markFunction( function( selector ) { 3985 3986 // Trim the selector passed to compile 3987 // to avoid treating leading and trailing 3988 // spaces as combinators 3989 var input = [], 3990 results = [], 3991 matcher = compile( selector.replace( rtrim, "$1" ) ); 3992 3993 return matcher[ expando ] ? 3994 markFunction( function( seed, matches, _context, xml ) { 3995 var elem, 3996 unmatched = matcher( seed, null, xml, [] ), 3997 i = seed.length; 3998 3999 // Match elements unmatched by `matcher` 4000 while ( i-- ) { 4001 if ( ( elem = unmatched[ i ] ) ) { 4002 seed[ i ] = !( matches[ i ] = elem ); 4003 } 4004 } 4005 } ) : 4006 function( elem, _context, xml ) { 4007 input[ 0 ] = elem; 4008 matcher( input, null, xml, results ); 4009 4010 // Don't keep the element (issue #299) 4011 input[ 0 ] = null; 4012 return !results.pop(); 4013 }; 4014 } ), 4015 4016 "has": markFunction( function( selector ) { 4017 return function( elem ) { 4018 return Sizzle( selector, elem ).length > 0; 4019 }; 4020 } ), 4021 4022 "contains": markFunction( function( text ) { 4023 text = text.replace( runescape, funescape ); 4024 return function( elem ) { 4025 return ( elem.textContent || getText( elem ) ).indexOf( text ) > -1; 4026 }; 4027 } ), 4028 4029 // "Whether an element is represented by a :lang() selector 4030 // is based solely on the element's language value 4031 // being equal to the identifier C, 4032 // or beginning with the identifier C immediately followed by "-". 4033 // The matching of C against the element's language value is performed case-insensitively. 4034 // The identifier C does not have to be a valid language name." 4035 // http://www.w3.org/TR/selectors/#lang-pseudo 4036 "lang": markFunction( function( lang ) { 4037 4038 // lang value must be a valid identifier 4039 if ( !ridentifier.test( lang || "" ) ) { 4040 Sizzle.error( "unsupported lang: " + lang ); 4041 } 4042 lang = lang.replace( runescape, funescape ).toLowerCase(); 4043 return function( elem ) { 4044 var elemLang; 4045 do { 4046 if ( ( elemLang = documentIsHTML ? 4047 elem.lang : 4048 elem.getAttribute( "xml:lang" ) || elem.getAttribute( "lang" ) ) ) { 4049 4050 elemLang = elemLang.toLowerCase(); 4051 return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; 4052 } 4053 } while ( ( elem = elem.parentNode ) && elem.nodeType === 1 ); 4054 return false; 4055 }; 4056 } ), 4057 4058 // Miscellaneous 4059 "target": function( elem ) { 4060 var hash = window.location && window.location.hash; 4061 return hash && hash.slice( 1 ) === elem.id; 4062 }, 4063 4064 "root": function( elem ) { 4065 return elem === docElem; 4066 }, 4067 4068 "focus": function( elem ) { 4069 return elem === document.activeElement && 4070 ( !document.hasFocus || document.hasFocus() ) && 4071 !!( elem.type || elem.href || ~elem.tabIndex ); 4072 }, 4073 4074 // Boolean properties 4075 "enabled": createDisabledPseudo( false ), 4076 "disabled": createDisabledPseudo( true ), 4077 4078 "checked": function( elem ) { 4079 4080 // In CSS3, :checked should return both checked and selected elements 4081 // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked 4082 var nodeName = elem.nodeName.toLowerCase(); 4083 return ( nodeName === "input" && !!elem.checked ) || 4084 ( nodeName === "option" && !!elem.selected ); 4085 }, 4086 4087 "selected": function( elem ) { 4088 4089 // Accessing this property makes selected-by-default 4090 // options in Safari work properly 4091 if ( elem.parentNode ) { 4092 // eslint-disable-next-line no-unused-expressions 4093 elem.parentNode.selectedIndex; 4094 } 4095 4096 return elem.selected === true; 4097 }, 4098 4099 // Contents 4100 "empty": function( elem ) { 4101 4102 // http://www.w3.org/TR/selectors/#empty-pseudo 4103 // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), 4104 // but not by others (comment: 8; processing instruction: 7; etc.) 4105 // nodeType < 6 works because attributes (2) do not appear as children 4106 for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { 4107 if ( elem.nodeType < 6 ) { 4108 return false; 4109 } 4110 } 4111 return true; 4112 }, 4113 4114 "parent": function( elem ) { 4115 return !Expr.pseudos[ "empty" ]( elem ); 4116 }, 4117 4118 // Element/input types 4119 "header": function( elem ) { 4120 return rheader.test( elem.nodeName ); 4121 }, 4122 4123 "input": function( elem ) { 4124 return rinputs.test( elem.nodeName ); 4125 }, 4126 4127 "button": function( elem ) { 4128 var name = elem.nodeName.toLowerCase(); 4129 return name === "input" && elem.type === "button" || name === "button"; 4130 }, 4131 4132 "text": function( elem ) { 4133 var attr; 4134 return elem.nodeName.toLowerCase() === "input" && 4135 elem.type === "text" && 4136 4137 // Support: IE<8 4138 // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" 4139 ( ( attr = elem.getAttribute( "type" ) ) == null || 4140 attr.toLowerCase() === "text" ); 4141 }, 4142 4143 // Position-in-collection 4144 "first": createPositionalPseudo( function() { 4145 return [ 0 ]; 4146 } ), 4147 4148 "last": createPositionalPseudo( function( _matchIndexes, length ) { 4149 return [ length - 1 ]; 4150 } ), 4151 4152 "eq": createPositionalPseudo( function( _matchIndexes, length, argument ) { 4153 return [ argument < 0 ? argument + length : argument ]; 4154 } ), 4155 4156 "even": createPositionalPseudo( function( matchIndexes, length ) { 4157 var i = 0; 4158 for ( ; i < length; i += 2 ) { 4159 matchIndexes.push( i ); 4160 } 4161 return matchIndexes; 4162 } ), 4163 4164 "odd": createPositionalPseudo( function( matchIndexes, length ) { 4165 var i = 1; 4166 for ( ; i < length; i += 2 ) { 4167 matchIndexes.push( i ); 4168 } 4169 return matchIndexes; 4170 } ), 4171 4172 "lt": createPositionalPseudo( function( matchIndexes, length, argument ) { 4173 var i = argument < 0 ? 4174 argument + length : 4175 argument > length ? 4176 length : 4177 argument; 4178 for ( ; --i >= 0; ) { 4179 matchIndexes.push( i ); 4180 } 4181 return matchIndexes; 4182 } ), 4183 4184 "gt": createPositionalPseudo( function( matchIndexes, length, argument ) { 4185 var i = argument < 0 ? argument + length : argument; 4186 for ( ; ++i < length; ) { 4187 matchIndexes.push( i ); 4188 } 4189 return matchIndexes; 4190 } ) 4191 } 4192}; 4193 4194Expr.pseudos[ "nth" ] = Expr.pseudos[ "eq" ]; 4195 4196// Add button/input type pseudos 4197for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { 4198 Expr.pseudos[ i ] = createInputPseudo( i ); 4199} 4200for ( i in { submit: true, reset: true } ) { 4201 Expr.pseudos[ i ] = createButtonPseudo( i ); 4202} 4203 4204// Easy API for creating new setFilters 4205function setFilters() {} 4206setFilters.prototype = Expr.filters = Expr.pseudos; 4207Expr.setFilters = new setFilters(); 4208 4209tokenize = Sizzle.tokenize = function( selector, parseOnly ) { 4210 var matched, match, tokens, type, 4211 soFar, groups, preFilters, 4212 cached = tokenCache[ selector + " " ]; 4213 4214 if ( cached ) { 4215 return parseOnly ? 0 : cached.slice( 0 ); 4216 } 4217 4218 soFar = selector; 4219 groups = []; 4220 preFilters = Expr.preFilter; 4221 4222 while ( soFar ) { 4223 4224 // Comma and first run 4225 if ( !matched || ( match = rcomma.exec( soFar ) ) ) { 4226 if ( match ) { 4227 4228 // Don't consume trailing commas as valid 4229 soFar = soFar.slice( match[ 0 ].length ) || soFar; 4230 } 4231 groups.push( ( tokens = [] ) ); 4232 } 4233 4234 matched = false; 4235 4236 // Combinators 4237 if ( ( match = rcombinators.exec( soFar ) ) ) { 4238 matched = match.shift(); 4239 tokens.push( { 4240 value: matched, 4241 4242 // Cast descendant combinators to space 4243 type: match[ 0 ].replace( rtrim, " " ) 4244 } ); 4245 soFar = soFar.slice( matched.length ); 4246 } 4247 4248 // Filters 4249 for ( type in Expr.filter ) { 4250 if ( ( match = matchExpr[ type ].exec( soFar ) ) && ( !preFilters[ type ] || 4251 ( match = preFilters[ type ]( match ) ) ) ) { 4252 matched = match.shift(); 4253 tokens.push( { 4254 value: matched, 4255 type: type, 4256 matches: match 4257 } ); 4258 soFar = soFar.slice( matched.length ); 4259 } 4260 } 4261 4262 if ( !matched ) { 4263 break; 4264 } 4265 } 4266 4267 // Return the length of the invalid excess 4268 // if we're just parsing 4269 // Otherwise, throw an error or return tokens 4270 return parseOnly ? 4271 soFar.length : 4272 soFar ? 4273 Sizzle.error( selector ) : 4274 4275 // Cache the tokens 4276 tokenCache( selector, groups ).slice( 0 ); 4277}; 4278 4279function toSelector( tokens ) { 4280 var i = 0, 4281 len = tokens.length, 4282 selector = ""; 4283 for ( ; i < len; i++ ) { 4284 selector += tokens[ i ].value; 4285 } 4286 return selector; 4287} 4288 4289function addCombinator( matcher, combinator, base ) { 4290 var dir = combinator.dir, 4291 skip = combinator.next, 4292 key = skip || dir, 4293 checkNonElements = base && key === "parentNode", 4294 doneName = done++; 4295 4296 return combinator.first ? 4297 4298 // Check against closest ancestor/preceding element 4299 function( elem, context, xml ) { 4300 while ( ( elem = elem[ dir ] ) ) { 4301 if ( elem.nodeType === 1 || checkNonElements ) { 4302 return matcher( elem, context, xml ); 4303 } 4304 } 4305 return false; 4306 } : 4307 4308 // Check against all ancestor/preceding elements 4309 function( elem, context, xml ) { 4310 var oldCache, uniqueCache, outerCache, 4311 newCache = [ dirruns, doneName ]; 4312 4313 // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching 4314 if ( xml ) { 4315 while ( ( elem = elem[ dir ] ) ) { 4316 if ( elem.nodeType === 1 || checkNonElements ) { 4317 if ( matcher( elem, context, xml ) ) { 4318 return true; 4319 } 4320 } 4321 } 4322 } else { 4323 while ( ( elem = elem[ dir ] ) ) { 4324 if ( elem.nodeType === 1 || checkNonElements ) { 4325 outerCache = elem[ expando ] || ( elem[ expando ] = {} ); 4326 4327 // Support: IE <9 only 4328 // Defend against cloned attroperties (jQuery gh-1709) 4329 uniqueCache = outerCache[ elem.uniqueID ] || 4330 ( outerCache[ elem.uniqueID ] = {} ); 4331 4332 if ( skip && skip === elem.nodeName.toLowerCase() ) { 4333 elem = elem[ dir ] || elem; 4334 } else if ( ( oldCache = uniqueCache[ key ] ) && 4335 oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { 4336 4337 // Assign to newCache so results back-propagate to previous elements 4338 return ( newCache[ 2 ] = oldCache[ 2 ] ); 4339 } else { 4340 4341 // Reuse newcache so results back-propagate to previous elements 4342 uniqueCache[ key ] = newCache; 4343 4344 // A match means we're done; a fail means we have to keep checking 4345 if ( ( newCache[ 2 ] = matcher( elem, context, xml ) ) ) { 4346 return true; 4347 } 4348 } 4349 } 4350 } 4351 } 4352 return false; 4353 }; 4354} 4355 4356function elementMatcher( matchers ) { 4357 return matchers.length > 1 ? 4358 function( elem, context, xml ) { 4359 var i = matchers.length; 4360 while ( i-- ) { 4361 if ( !matchers[ i ]( elem, context, xml ) ) { 4362 return false; 4363 } 4364 } 4365 return true; 4366 } : 4367 matchers[ 0 ]; 4368} 4369 4370function multipleContexts( selector, contexts, results ) { 4371 var i = 0, 4372 len = contexts.length; 4373 for ( ; i < len; i++ ) { 4374 Sizzle( selector, contexts[ i ], results ); 4375 } 4376 return results; 4377} 4378 4379function condense( unmatched, map, filter, context, xml ) { 4380 var elem, 4381 newUnmatched = [], 4382 i = 0, 4383 len = unmatched.length, 4384 mapped = map != null; 4385 4386 for ( ; i < len; i++ ) { 4387 if ( ( elem = unmatched[ i ] ) ) { 4388 if ( !filter || filter( elem, context, xml ) ) { 4389 newUnmatched.push( elem ); 4390 if ( mapped ) { 4391 map.push( i ); 4392 } 4393 } 4394 } 4395 } 4396 4397 return newUnmatched; 4398} 4399 4400function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { 4401 if ( postFilter && !postFilter[ expando ] ) { 4402 postFilter = setMatcher( postFilter ); 4403 } 4404 if ( postFinder && !postFinder[ expando ] ) { 4405 postFinder = setMatcher( postFinder, postSelector ); 4406 } 4407 return markFunction( function( seed, results, context, xml ) { 4408 var temp, i, elem, 4409 preMap = [], 4410 postMap = [], 4411 preexisting = results.length, 4412 4413 // Get initial elements from seed or context 4414 elems = seed || multipleContexts( 4415 selector || "*", 4416 context.nodeType ? [ context ] : context, 4417 [] 4418 ), 4419 4420 // Prefilter to get matcher input, preserving a map for seed-results synchronization 4421 matcherIn = preFilter && ( seed || !selector ) ? 4422 condense( elems, preMap, preFilter, context, xml ) : 4423 elems, 4424 4425 matcherOut = matcher ? 4426 4427 // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, 4428 postFinder || ( seed ? preFilter : preexisting || postFilter ) ? 4429 4430 // ...intermediate processing is necessary 4431 [] : 4432 4433 // ...otherwise use results directly 4434 results : 4435 matcherIn; 4436 4437 // Find primary matches 4438 if ( matcher ) { 4439 matcher( matcherIn, matcherOut, context, xml ); 4440 } 4441 4442 // Apply postFilter 4443 if ( postFilter ) { 4444 temp = condense( matcherOut, postMap ); 4445 postFilter( temp, [], context, xml ); 4446 4447 // Un-match failing elements by moving them back to matcherIn 4448 i = temp.length; 4449 while ( i-- ) { 4450 if ( ( elem = temp[ i ] ) ) { 4451 matcherOut[ postMap[ i ] ] = !( matcherIn[ postMap[ i ] ] = elem ); 4452 } 4453 } 4454 } 4455 4456 if ( seed ) { 4457 if ( postFinder || preFilter ) { 4458 if ( postFinder ) { 4459 4460 // Get the final matcherOut by condensing this intermediate into postFinder contexts 4461 temp = []; 4462 i = matcherOut.length; 4463 while ( i-- ) { 4464 if ( ( elem = matcherOut[ i ] ) ) { 4465 4466 // Restore matcherIn since elem is not yet a final match 4467 temp.push( ( matcherIn[ i ] = elem ) ); 4468 } 4469 } 4470 postFinder( null, ( matcherOut = [] ), temp, xml ); 4471 } 4472 4473 // Move matched elements from seed to results to keep them synchronized 4474 i = matcherOut.length; 4475 while ( i-- ) { 4476 if ( ( elem = matcherOut[ i ] ) && 4477 ( temp = postFinder ? indexOf( seed, elem ) : preMap[ i ] ) > -1 ) { 4478 4479 seed[ temp ] = !( results[ temp ] = elem ); 4480 } 4481 } 4482 } 4483 4484 // Add elements to results, through postFinder if defined 4485 } else { 4486 matcherOut = condense( 4487 matcherOut === results ? 4488 matcherOut.splice( preexisting, matcherOut.length ) : 4489 matcherOut 4490 ); 4491 if ( postFinder ) { 4492 postFinder( null, results, matcherOut, xml ); 4493 } else { 4494 push.apply( results, matcherOut ); 4495 } 4496 } 4497 } ); 4498} 4499 4500function matcherFromTokens( tokens ) { 4501 var checkContext, matcher, j, 4502 len = tokens.length, 4503 leadingRelative = Expr.relative[ tokens[ 0 ].type ], 4504 implicitRelative = leadingRelative || Expr.relative[ " " ], 4505 i = leadingRelative ? 1 : 0, 4506 4507 // The foundational matcher ensures that elements are reachable from top-level context(s) 4508 matchContext = addCombinator( function( elem ) { 4509 return elem === checkContext; 4510 }, implicitRelative, true ), 4511 matchAnyContext = addCombinator( function( elem ) { 4512 return indexOf( checkContext, elem ) > -1; 4513 }, implicitRelative, true ), 4514 matchers = [ function( elem, context, xml ) { 4515 var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( 4516 ( checkContext = context ).nodeType ? 4517 matchContext( elem, context, xml ) : 4518 matchAnyContext( elem, context, xml ) ); 4519 4520 // Avoid hanging onto element (issue #299) 4521 checkContext = null; 4522 return ret; 4523 } ]; 4524 4525 for ( ; i < len; i++ ) { 4526 if ( ( matcher = Expr.relative[ tokens[ i ].type ] ) ) { 4527 matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ]; 4528 } else { 4529 matcher = Expr.filter[ tokens[ i ].type ].apply( null, tokens[ i ].matches ); 4530 4531 // Return special upon seeing a positional matcher 4532 if ( matcher[ expando ] ) { 4533 4534 // Find the next relative operator (if any) for proper handling 4535 j = ++i; 4536 for ( ; j < len; j++ ) { 4537 if ( Expr.relative[ tokens[ j ].type ] ) { 4538 break; 4539 } 4540 } 4541 return setMatcher( 4542 i > 1 && elementMatcher( matchers ), 4543 i > 1 && toSelector( 4544 4545 // If the preceding token was a descendant combinator, insert an implicit any-element `*` 4546 tokens 4547 .slice( 0, i - 1 ) 4548 .concat( { value: tokens[ i - 2 ].type === " " ? "*" : "" } ) 4549 ).replace( rtrim, "$1" ), 4550 matcher, 4551 i < j && matcherFromTokens( tokens.slice( i, j ) ), 4552 j < len && matcherFromTokens( ( tokens = tokens.slice( j ) ) ), 4553 j < len && toSelector( tokens ) 4554 ); 4555 } 4556 matchers.push( matcher ); 4557 } 4558 } 4559 4560 return elementMatcher( matchers ); 4561} 4562 4563function matcherFromGroupMatchers( elementMatchers, setMatchers ) { 4564 var bySet = setMatchers.length > 0, 4565 byElement = elementMatchers.length > 0, 4566 superMatcher = function( seed, context, xml, results, outermost ) { 4567 var elem, j, matcher, 4568 matchedCount = 0, 4569 i = "0", 4570 unmatched = seed && [], 4571 setMatched = [], 4572 contextBackup = outermostContext, 4573 4574 // We must always have either seed elements or outermost context 4575 elems = seed || byElement && Expr.find[ "TAG" ]( "*", outermost ), 4576 4577 // Use integer dirruns iff this is the outermost matcher 4578 dirrunsUnique = ( dirruns += contextBackup == null ? 1 : Math.random() || 0.1 ), 4579 len = elems.length; 4580 4581 if ( outermost ) { 4582 4583 // Support: IE 11+, Edge 17 - 18+ 4584 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 4585 // two documents; shallow comparisons work. 4586 // eslint-disable-next-line eqeqeq 4587 outermostContext = context == document || context || outermost; 4588 } 4589 4590 // Add elements passing elementMatchers directly to results 4591 // Support: IE<9, Safari 4592 // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id 4593 for ( ; i !== len && ( elem = elems[ i ] ) != null; i++ ) { 4594 if ( byElement && elem ) { 4595 j = 0; 4596 4597 // Support: IE 11+, Edge 17 - 18+ 4598 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 4599 // two documents; shallow comparisons work. 4600 // eslint-disable-next-line eqeqeq 4601 if ( !context && elem.ownerDocument != document ) { 4602 setDocument( elem ); 4603 xml = !documentIsHTML; 4604 } 4605 while ( ( matcher = elementMatchers[ j++ ] ) ) { 4606 if ( matcher( elem, context || document, xml ) ) { 4607 results.push( elem ); 4608 break; 4609 } 4610 } 4611 if ( outermost ) { 4612 dirruns = dirrunsUnique; 4613 } 4614 } 4615 4616 // Track unmatched elements for set filters 4617 if ( bySet ) { 4618 4619 // They will have gone through all possible matchers 4620 if ( ( elem = !matcher && elem ) ) { 4621 matchedCount--; 4622 } 4623 4624 // Lengthen the array for every element, matched or not 4625 if ( seed ) { 4626 unmatched.push( elem ); 4627 } 4628 } 4629 } 4630 4631 // `i` is now the count of elements visited above, and adding it to `matchedCount` 4632 // makes the latter nonnegative. 4633 matchedCount += i; 4634 4635 // Apply set filters to unmatched elements 4636 // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` 4637 // equals `i`), unless we didn't visit _any_ elements in the above loop because we have 4638 // no element matchers and no seed. 4639 // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that 4640 // case, which will result in a "00" `matchedCount` that differs from `i` but is also 4641 // numerically zero. 4642 if ( bySet && i !== matchedCount ) { 4643 j = 0; 4644 while ( ( matcher = setMatchers[ j++ ] ) ) { 4645 matcher( unmatched, setMatched, context, xml ); 4646 } 4647 4648 if ( seed ) { 4649 4650 // Reintegrate element matches to eliminate the need for sorting 4651 if ( matchedCount > 0 ) { 4652 while ( i-- ) { 4653 if ( !( unmatched[ i ] || setMatched[ i ] ) ) { 4654 setMatched[ i ] = pop.call( results ); 4655 } 4656 } 4657 } 4658 4659 // Discard index placeholder values to get only actual matches 4660 setMatched = condense( setMatched ); 4661 } 4662 4663 // Add matches to results 4664 push.apply( results, setMatched ); 4665 4666 // Seedless set matches succeeding multiple successful matchers stipulate sorting 4667 if ( outermost && !seed && setMatched.length > 0 && 4668 ( matchedCount + setMatchers.length ) > 1 ) { 4669 4670 Sizzle.uniqueSort( results ); 4671 } 4672 } 4673 4674 // Override manipulation of globals by nested matchers 4675 if ( outermost ) { 4676 dirruns = dirrunsUnique; 4677 outermostContext = contextBackup; 4678 } 4679 4680 return unmatched; 4681 }; 4682 4683 return bySet ? 4684 markFunction( superMatcher ) : 4685 superMatcher; 4686} 4687 4688compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { 4689 var i, 4690 setMatchers = [], 4691 elementMatchers = [], 4692 cached = compilerCache[ selector + " " ]; 4693 4694 if ( !cached ) { 4695 4696 // Generate a function of recursive functions that can be used to check each element 4697 if ( !match ) { 4698 match = tokenize( selector ); 4699 } 4700 i = match.length; 4701 while ( i-- ) { 4702 cached = matcherFromTokens( match[ i ] ); 4703 if ( cached[ expando ] ) { 4704 setMatchers.push( cached ); 4705 } else { 4706 elementMatchers.push( cached ); 4707 } 4708 } 4709 4710 // Cache the compiled function 4711 cached = compilerCache( 4712 selector, 4713 matcherFromGroupMatchers( elementMatchers, setMatchers ) 4714 ); 4715 4716 // Save selector and tokenization 4717 cached.selector = selector; 4718 } 4719 return cached; 4720}; 4721 4722/** 4723 * A low-level selection function that works with Sizzle's compiled 4724 * selector functions 4725 * @param {String|Function} selector A selector or a pre-compiled 4726 * selector function built with Sizzle.compile 4727 * @param {Element} context 4728 * @param {Array} [results] 4729 * @param {Array} [seed] A set of elements to match against 4730 */ 4731select = Sizzle.select = function( selector, context, results, seed ) { 4732 var i, tokens, token, type, find, 4733 compiled = typeof selector === "function" && selector, 4734 match = !seed && tokenize( ( selector = compiled.selector || selector ) ); 4735 4736 results = results || []; 4737 4738 // Try to minimize operations if there is only one selector in the list and no seed 4739 // (the latter of which guarantees us context) 4740 if ( match.length === 1 ) { 4741 4742 // Reduce context if the leading compound selector is an ID 4743 tokens = match[ 0 ] = match[ 0 ].slice( 0 ); 4744 if ( tokens.length > 2 && ( token = tokens[ 0 ] ).type === "ID" && 4745 context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[ 1 ].type ] ) { 4746 4747 context = ( Expr.find[ "ID" ]( token.matches[ 0 ] 4748 .replace( runescape, funescape ), context ) || [] )[ 0 ]; 4749 if ( !context ) { 4750 return results; 4751 4752 // Precompiled matchers will still verify ancestry, so step up a level 4753 } else if ( compiled ) { 4754 context = context.parentNode; 4755 } 4756 4757 selector = selector.slice( tokens.shift().value.length ); 4758 } 4759 4760 // Fetch a seed set for right-to-left matching 4761 i = matchExpr[ "needsContext" ].test( selector ) ? 0 : tokens.length; 4762 while ( i-- ) { 4763 token = tokens[ i ]; 4764 4765 // Abort if we hit a combinator 4766 if ( Expr.relative[ ( type = token.type ) ] ) { 4767 break; 4768 } 4769 if ( ( find = Expr.find[ type ] ) ) { 4770 4771 // Search, expanding context for leading sibling combinators 4772 if ( ( seed = find( 4773 token.matches[ 0 ].replace( runescape, funescape ), 4774 rsibling.test( tokens[ 0 ].type ) && testContext( context.parentNode ) || 4775 context 4776 ) ) ) { 4777 4778 // If seed is empty or no tokens remain, we can return early 4779 tokens.splice( i, 1 ); 4780 selector = seed.length && toSelector( tokens ); 4781 if ( !selector ) { 4782 push.apply( results, seed ); 4783 return results; 4784 } 4785 4786 break; 4787 } 4788 } 4789 } 4790 } 4791 4792 // Compile and execute a filtering function if one is not provided 4793 // Provide `match` to avoid retokenization if we modified the selector above 4794 ( compiled || compile( selector, match ) )( 4795 seed, 4796 context, 4797 !documentIsHTML, 4798 results, 4799 !context || rsibling.test( selector ) && testContext( context.parentNode ) || context 4800 ); 4801 return results; 4802}; 4803 4804// One-time assignments 4805 4806// Sort stability 4807support.sortStable = expando.split( "" ).sort( sortOrder ).join( "" ) === expando; 4808 4809// Support: Chrome 14-35+ 4810// Always assume duplicates if they aren't passed to the comparison function 4811support.detectDuplicates = !!hasDuplicate; 4812 4813// Initialize against the default document 4814setDocument(); 4815 4816// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) 4817// Detached nodes confoundingly follow *each other* 4818support.sortDetached = assert( function( el ) { 4819 4820 // Should return 1, but returns 4 (following) 4821 return el.compareDocumentPosition( document.createElement( "fieldset" ) ) & 1; 4822} ); 4823 4824// Support: IE<8 4825// Prevent attribute/property "interpolation" 4826// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx 4827if ( !assert( function( el ) { 4828 el.innerHTML = "<a href='#'></a>"; 4829 return el.firstChild.getAttribute( "href" ) === "#"; 4830} ) ) { 4831 addHandle( "type|href|height|width", function( elem, name, isXML ) { 4832 if ( !isXML ) { 4833 return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); 4834 } 4835 } ); 4836} 4837 4838// Support: IE<9 4839// Use defaultValue in place of getAttribute("value") 4840if ( !support.attributes || !assert( function( el ) { 4841 el.innerHTML = "<input/>"; 4842 el.firstChild.setAttribute( "value", "" ); 4843 return el.firstChild.getAttribute( "value" ) === ""; 4844} ) ) { 4845 addHandle( "value", function( elem, _name, isXML ) { 4846 if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { 4847 return elem.defaultValue; 4848 } 4849 } ); 4850} 4851 4852// Support: IE<9 4853// Use getAttributeNode to fetch booleans when getAttribute lies 4854if ( !assert( function( el ) { 4855 return el.getAttribute( "disabled" ) == null; 4856} ) ) { 4857 addHandle( booleans, function( elem, name, isXML ) { 4858 var val; 4859 if ( !isXML ) { 4860 return elem[ name ] === true ? name.toLowerCase() : 4861 ( val = elem.getAttributeNode( name ) ) && val.specified ? 4862 val.value : 4863 null; 4864 } 4865 } ); 4866} 4867 4868return Sizzle; 4869 4870} )( window ); 4871 4872 4873 4874jQuery.find = Sizzle; 4875jQuery.expr = Sizzle.selectors; 4876 4877// Deprecated 4878jQuery.expr[ ":" ] = jQuery.expr.pseudos; 4879jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort; 4880jQuery.text = Sizzle.getText; 4881jQuery.isXMLDoc = Sizzle.isXML; 4882jQuery.contains = Sizzle.contains; 4883jQuery.escapeSelector = Sizzle.escape; 4884 4885 4886 4887 4888var dir = function( elem, dir, until ) { 4889 var matched = [], 4890 truncate = until !== undefined; 4891 4892 while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) { 4893 if ( elem.nodeType === 1 ) { 4894 if ( truncate && jQuery( elem ).is( until ) ) { 4895 break; 4896 } 4897 matched.push( elem ); 4898 } 4899 } 4900 return matched; 4901}; 4902 4903 4904var siblings = function( n, elem ) { 4905 var matched = []; 4906 4907 for ( ; n; n = n.nextSibling ) { 4908 if ( n.nodeType === 1 && n !== elem ) { 4909 matched.push( n ); 4910 } 4911 } 4912 4913 return matched; 4914}; 4915 4916 4917var rneedsContext = jQuery.expr.match.needsContext; 4918 4919 4920 4921function nodeName( elem, name ) { 4922 4923 return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); 4924 4925} 4926var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i ); 4927 4928 4929 4930// Implement the identical functionality for filter and not 4931function winnow( elements, qualifier, not ) { 4932 if ( isFunction( qualifier ) ) { 4933 return jQuery.grep( elements, function( elem, i ) { 4934 return !!qualifier.call( elem, i, elem ) !== not; 4935 } ); 4936 } 4937 4938 // Single element 4939 if ( qualifier.nodeType ) { 4940 return jQuery.grep( elements, function( elem ) { 4941 return ( elem === qualifier ) !== not; 4942 } ); 4943 } 4944 4945 // Arraylike of elements (jQuery, arguments, Array) 4946 if ( typeof qualifier !== "string" ) { 4947 return jQuery.grep( elements, function( elem ) { 4948 return ( indexOf.call( qualifier, elem ) > -1 ) !== not; 4949 } ); 4950 } 4951 4952 // Filtered directly for both simple and complex selectors 4953 return jQuery.filter( qualifier, elements, not ); 4954} 4955 4956jQuery.filter = function( expr, elems, not ) { 4957 var elem = elems[ 0 ]; 4958 4959 if ( not ) { 4960 expr = ":not(" + expr + ")"; 4961 } 4962 4963 if ( elems.length === 1 && elem.nodeType === 1 ) { 4964 return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : []; 4965 } 4966 4967 return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { 4968 return elem.nodeType === 1; 4969 } ) ); 4970}; 4971 4972jQuery.fn.extend( { 4973 find: function( selector ) { 4974 var i, ret, 4975 len = this.length, 4976 self = this; 4977 4978 if ( typeof selector !== "string" ) { 4979 return this.pushStack( jQuery( selector ).filter( function() { 4980 for ( i = 0; i < len; i++ ) { 4981 if ( jQuery.contains( self[ i ], this ) ) { 4982 return true; 4983 } 4984 } 4985 } ) ); 4986 } 4987 4988 ret = this.pushStack( [] ); 4989 4990 for ( i = 0; i < len; i++ ) { 4991 jQuery.find( selector, self[ i ], ret ); 4992 } 4993 4994 return len > 1 ? jQuery.uniqueSort( ret ) : ret; 4995 }, 4996 filter: function( selector ) { 4997 return this.pushStack( winnow( this, selector || [], false ) ); 4998 }, 4999 not: function( selector ) { 5000 return this.pushStack( winnow( this, selector || [], true ) ); 5001 }, 5002 is: function( selector ) { 5003 return !!winnow( 5004 this, 5005 5006 // If this is a positional/relative selector, check membership in the returned set 5007 // so $("p:first").is("p:last") won't return true for a doc with two "p". 5008 typeof selector === "string" && rneedsContext.test( selector ) ? 5009 jQuery( selector ) : 5010 selector || [], 5011 false 5012 ).length; 5013 } 5014} ); 5015 5016 5017// Initialize a jQuery object 5018 5019 5020// A central reference to the root jQuery(document) 5021var rootjQuery, 5022 5023 // A simple way to check for HTML strings 5024 // Prioritize #id over <tag> to avoid XSS via location.hash (#9521) 5025 // Strict HTML recognition (#11290: must start with <) 5026 // Shortcut simple #id case for speed 5027 rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/, 5028 5029 init = jQuery.fn.init = function( selector, context, root ) { 5030 var match, elem; 5031 5032 // HANDLE: $(""), $(null), $(undefined), $(false) 5033 if ( !selector ) { 5034 return this; 5035 } 5036 5037 // Method init() accepts an alternate rootjQuery 5038 // so migrate can support jQuery.sub (gh-2101) 5039 root = root || rootjQuery; 5040 5041 // Handle HTML strings 5042 if ( typeof selector === "string" ) { 5043 if ( selector[ 0 ] === "<" && 5044 selector[ selector.length - 1 ] === ">" && 5045 selector.length >= 3 ) { 5046 5047 // Assume that strings that start and end with <> are HTML and skip the regex check 5048 match = [ null, selector, null ]; 5049 5050 } else { 5051 match = rquickExpr.exec( selector ); 5052 } 5053 5054 // Match html or make sure no context is specified for #id 5055 if ( match && ( match[ 1 ] || !context ) ) { 5056 5057 // HANDLE: $(html) -> $(array) 5058 if ( match[ 1 ] ) { 5059 context = context instanceof jQuery ? context[ 0 ] : context; 5060 5061 // Option to run scripts is true for back-compat 5062 // Intentionally let the error be thrown if parseHTML is not present 5063 jQuery.merge( this, jQuery.parseHTML( 5064 match[ 1 ], 5065 context && context.nodeType ? context.ownerDocument || context : document, 5066 true 5067 ) ); 5068 5069 // HANDLE: $(html, props) 5070 if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) { 5071 for ( match in context ) { 5072 5073 // Properties of context are called as methods if possible 5074 if ( isFunction( this[ match ] ) ) { 5075 this[ match ]( context[ match ] ); 5076 5077 // ...and otherwise set as attributes 5078 } else { 5079 this.attr( match, context[ match ] ); 5080 } 5081 } 5082 } 5083 5084 return this; 5085 5086 // HANDLE: $(#id) 5087 } else { 5088 elem = document.getElementById( match[ 2 ] ); 5089 5090 if ( elem ) { 5091 5092 // Inject the element directly into the jQuery object 5093 this[ 0 ] = elem; 5094 this.length = 1; 5095 } 5096 return this; 5097 } 5098 5099 // HANDLE: $(expr, $(...)) 5100 } else if ( !context || context.jquery ) { 5101 return ( context || root ).find( selector ); 5102 5103 // HANDLE: $(expr, context) 5104 // (which is just equivalent to: $(context).find(expr) 5105 } else { 5106 return this.constructor( context ).find( selector ); 5107 } 5108 5109 // HANDLE: $(DOMElement) 5110 } else if ( selector.nodeType ) { 5111 this[ 0 ] = selector; 5112 this.length = 1; 5113 return this; 5114 5115 // HANDLE: $(function) 5116 // Shortcut for document ready 5117 } else if ( isFunction( selector ) ) { 5118 return root.ready !== undefined ? 5119 root.ready( selector ) : 5120 5121 // Execute immediately if ready is not present 5122 selector( jQuery ); 5123 } 5124 5125 return jQuery.makeArray( selector, this ); 5126 }; 5127 5128// Give the init function the jQuery prototype for later instantiation 5129init.prototype = jQuery.fn; 5130 5131// Initialize central reference 5132rootjQuery = jQuery( document ); 5133 5134 5135var rparentsprev = /^(?:parents|prev(?:Until|All))/, 5136 5137 // Methods guaranteed to produce a unique set when starting from a unique set 5138 guaranteedUnique = { 5139 children: true, 5140 contents: true, 5141 next: true, 5142 prev: true 5143 }; 5144 5145jQuery.fn.extend( { 5146 has: function( target ) { 5147 var targets = jQuery( target, this ), 5148 l = targets.length; 5149 5150 return this.filter( function() { 5151 var i = 0; 5152 for ( ; i < l; i++ ) { 5153 if ( jQuery.contains( this, targets[ i ] ) ) { 5154 return true; 5155 } 5156 } 5157 } ); 5158 }, 5159 5160 closest: function( selectors, context ) { 5161 var cur, 5162 i = 0, 5163 l = this.length, 5164 matched = [], 5165 targets = typeof selectors !== "string" && jQuery( selectors ); 5166 5167 // Positional selectors never match, since there's no _selection_ context 5168 if ( !rneedsContext.test( selectors ) ) { 5169 for ( ; i < l; i++ ) { 5170 for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) { 5171 5172 // Always skip document fragments 5173 if ( cur.nodeType < 11 && ( targets ? 5174 targets.index( cur ) > -1 : 5175 5176 // Don't pass non-elements to Sizzle 5177 cur.nodeType === 1 && 5178 jQuery.find.matchesSelector( cur, selectors ) ) ) { 5179 5180 matched.push( cur ); 5181 break; 5182 } 5183 } 5184 } 5185 } 5186 5187 return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched ); 5188 }, 5189 5190 // Determine the position of an element within the set 5191 index: function( elem ) { 5192 5193 // No argument, return index in parent 5194 if ( !elem ) { 5195 return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; 5196 } 5197 5198 // Index in selector 5199 if ( typeof elem === "string" ) { 5200 return indexOf.call( jQuery( elem ), this[ 0 ] ); 5201 } 5202 5203 // Locate the position of the desired element 5204 return indexOf.call( this, 5205 5206 // If it receives a jQuery object, the first element is used 5207 elem.jquery ? elem[ 0 ] : elem 5208 ); 5209 }, 5210 5211 add: function( selector, context ) { 5212 return this.pushStack( 5213 jQuery.uniqueSort( 5214 jQuery.merge( this.get(), jQuery( selector, context ) ) 5215 ) 5216 ); 5217 }, 5218 5219 addBack: function( selector ) { 5220 return this.add( selector == null ? 5221 this.prevObject : this.prevObject.filter( selector ) 5222 ); 5223 } 5224} ); 5225 5226function sibling( cur, dir ) { 5227 while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {} 5228 return cur; 5229} 5230 5231jQuery.each( { 5232 parent: function( elem ) { 5233 var parent = elem.parentNode; 5234 return parent && parent.nodeType !== 11 ? parent : null; 5235 }, 5236 parents: function( elem ) { 5237 return dir( elem, "parentNode" ); 5238 }, 5239 parentsUntil: function( elem, _i, until ) { 5240 return dir( elem, "parentNode", until ); 5241 }, 5242 next: function( elem ) { 5243 return sibling( elem, "nextSibling" ); 5244 }, 5245 prev: function( elem ) { 5246 return sibling( elem, "previousSibling" ); 5247 }, 5248 nextAll: function( elem ) { 5249 return dir( elem, "nextSibling" ); 5250 }, 5251 prevAll: function( elem ) { 5252 return dir( elem, "previousSibling" ); 5253 }, 5254 nextUntil: function( elem, _i, until ) { 5255 return dir( elem, "nextSibling", until ); 5256 }, 5257 prevUntil: function( elem, _i, until ) { 5258 return dir( elem, "previousSibling", until ); 5259 }, 5260 siblings: function( elem ) { 5261 return siblings( ( elem.parentNode || {} ).firstChild, elem ); 5262 }, 5263 children: function( elem ) { 5264 return siblings( elem.firstChild ); 5265 }, 5266 contents: function( elem ) { 5267 if ( elem.contentDocument != null && 5268 5269 // Support: IE 11+ 5270 // <object> elements with no `data` attribute has an object 5271 // `contentDocument` with a `null` prototype. 5272 getProto( elem.contentDocument ) ) { 5273 5274 return elem.contentDocument; 5275 } 5276 5277 // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only 5278 // Treat the template element as a regular one in browsers that 5279 // don't support it. 5280 if ( nodeName( elem, "template" ) ) { 5281 elem = elem.content || elem; 5282 } 5283 5284 return jQuery.merge( [], elem.childNodes ); 5285 } 5286}, function( name, fn ) { 5287 jQuery.fn[ name ] = function( until, selector ) { 5288 var matched = jQuery.map( this, fn, until ); 5289 5290 if ( name.slice( -5 ) !== "Until" ) { 5291 selector = until; 5292 } 5293 5294 if ( selector && typeof selector === "string" ) { 5295 matched = jQuery.filter( selector, matched ); 5296 } 5297 5298 if ( this.length > 1 ) { 5299 5300 // Remove duplicates 5301 if ( !guaranteedUnique[ name ] ) { 5302 jQuery.uniqueSort( matched ); 5303 } 5304 5305 // Reverse order for parents* and prev-derivatives 5306 if ( rparentsprev.test( name ) ) { 5307 matched.reverse(); 5308 } 5309 } 5310 5311 return this.pushStack( matched ); 5312 }; 5313} ); 5314var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g ); 5315 5316 5317 5318// Convert String-formatted options into Object-formatted ones 5319function createOptions( options ) { 5320 var object = {}; 5321 jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) { 5322 object[ flag ] = true; 5323 } ); 5324 return object; 5325} 5326 5327/* 5328 * Create a callback list using the following parameters: 5329 * 5330 * options: an optional list of space-separated options that will change how 5331 * the callback list behaves or a more traditional option object 5332 * 5333 * By default a callback list will act like an event callback list and can be 5334 * "fired" multiple times. 5335 * 5336 * Possible options: 5337 * 5338 * once: will ensure the callback list can only be fired once (like a Deferred) 5339 * 5340 * memory: will keep track of previous values and will call any callback added 5341 * after the list has been fired right away with the latest "memorized" 5342 * values (like a Deferred) 5343 * 5344 * unique: will ensure a callback can only be added once (no duplicate in the list) 5345 * 5346 * stopOnFalse: interrupt callings when a callback returns false 5347 * 5348 */ 5349jQuery.Callbacks = function( options ) { 5350 5351 // Convert options from String-formatted to Object-formatted if needed 5352 // (we check in cache first) 5353 options = typeof options === "string" ? 5354 createOptions( options ) : 5355 jQuery.extend( {}, options ); 5356 5357 var // Flag to know if list is currently firing 5358 firing, 5359 5360 // Last fire value for non-forgettable lists 5361 memory, 5362 5363 // Flag to know if list was already fired 5364 fired, 5365 5366 // Flag to prevent firing 5367 locked, 5368 5369 // Actual callback list 5370 list = [], 5371 5372 // Queue of execution data for repeatable lists 5373 queue = [], 5374 5375 // Index of currently firing callback (modified by add/remove as needed) 5376 firingIndex = -1, 5377 5378 // Fire callbacks 5379 fire = function() { 5380 5381 // Enforce single-firing 5382 locked = locked || options.once; 5383 5384 // Execute callbacks for all pending executions, 5385 // respecting firingIndex overrides and runtime changes 5386 fired = firing = true; 5387 for ( ; queue.length; firingIndex = -1 ) { 5388 memory = queue.shift(); 5389 while ( ++firingIndex < list.length ) { 5390 5391 // Run callback and check for early termination 5392 if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false && 5393 options.stopOnFalse ) { 5394 5395 // Jump to end and forget the data so .add doesn't re-fire 5396 firingIndex = list.length; 5397 memory = false; 5398 } 5399 } 5400 } 5401 5402 // Forget the data if we're done with it 5403 if ( !options.memory ) { 5404 memory = false; 5405 } 5406 5407 firing = false; 5408 5409 // Clean up if we're done firing for good 5410 if ( locked ) { 5411 5412 // Keep an empty list if we have data for future add calls 5413 if ( memory ) { 5414 list = []; 5415 5416 // Otherwise, this object is spent 5417 } else { 5418 list = ""; 5419 } 5420 } 5421 }, 5422 5423 // Actual Callbacks object 5424 self = { 5425 5426 // Add a callback or a collection of callbacks to the list 5427 add: function() { 5428 if ( list ) { 5429 5430 // If we have memory from a past run, we should fire after adding 5431 if ( memory && !firing ) { 5432 firingIndex = list.length - 1; 5433 queue.push( memory ); 5434 } 5435 5436 ( function add( args ) { 5437 jQuery.each( args, function( _, arg ) { 5438 if ( isFunction( arg ) ) { 5439 if ( !options.unique || !self.has( arg ) ) { 5440 list.push( arg ); 5441 } 5442 } else if ( arg && arg.length && toType( arg ) !== "string" ) { 5443 5444 // Inspect recursively 5445 add( arg ); 5446 } 5447 } ); 5448 } )( arguments ); 5449 5450 if ( memory && !firing ) { 5451 fire(); 5452 } 5453 } 5454 return this; 5455 }, 5456 5457 // Remove a callback from the list 5458 remove: function() { 5459 jQuery.each( arguments, function( _, arg ) { 5460 var index; 5461 while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { 5462 list.splice( index, 1 ); 5463 5464 // Handle firing indexes 5465 if ( index <= firingIndex ) { 5466 firingIndex--; 5467 } 5468 } 5469 } ); 5470 return this; 5471 }, 5472 5473 // Check if a given callback is in the list. 5474 // If no argument is given, return whether or not list has callbacks attached. 5475 has: function( fn ) { 5476 return fn ? 5477 jQuery.inArray( fn, list ) > -1 : 5478 list.length > 0; 5479 }, 5480 5481 // Remove all callbacks from the list 5482 empty: function() { 5483 if ( list ) { 5484 list = []; 5485 } 5486 return this; 5487 }, 5488 5489 // Disable .fire and .add 5490 // Abort any current/pending executions 5491 // Clear all callbacks and values 5492 disable: function() { 5493 locked = queue = []; 5494 list = memory = ""; 5495 return this; 5496 }, 5497 disabled: function() { 5498 return !list; 5499 }, 5500 5501 // Disable .fire 5502 // Also disable .add unless we have memory (since it would have no effect) 5503 // Abort any pending executions 5504 lock: function() { 5505 locked = queue = []; 5506 if ( !memory && !firing ) { 5507 list = memory = ""; 5508 } 5509 return this; 5510 }, 5511 locked: function() { 5512 return !!locked; 5513 }, 5514 5515 // Call all callbacks with the given context and arguments 5516 fireWith: function( context, args ) { 5517 if ( !locked ) { 5518 args = args || []; 5519 args = [ context, args.slice ? args.slice() : args ]; 5520 queue.push( args ); 5521 if ( !firing ) { 5522 fire(); 5523 } 5524 } 5525 return this; 5526 }, 5527 5528 // Call all the callbacks with the given arguments 5529 fire: function() { 5530 self.fireWith( this, arguments ); 5531 return this; 5532 }, 5533 5534 // To know if the callbacks have already been called at least once 5535 fired: function() { 5536 return !!fired; 5537 } 5538 }; 5539 5540 return self; 5541}; 5542 5543 5544function Identity( v ) { 5545 return v; 5546} 5547function Thrower( ex ) { 5548 throw ex; 5549} 5550 5551function adoptValue( value, resolve, reject, noValue ) { 5552 var method; 5553 5554 try { 5555 5556 // Check for promise aspect first to privilege synchronous behavior 5557 if ( value && isFunction( ( method = value.promise ) ) ) { 5558 method.call( value ).done( resolve ).fail( reject ); 5559 5560 // Other thenables 5561 } else if ( value && isFunction( ( method = value.then ) ) ) { 5562 method.call( value, resolve, reject ); 5563 5564 // Other non-thenables 5565 } else { 5566 5567 // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer: 5568 // * false: [ value ].slice( 0 ) => resolve( value ) 5569 // * true: [ value ].slice( 1 ) => resolve() 5570 resolve.apply( undefined, [ value ].slice( noValue ) ); 5571 } 5572 5573 // For Promises/A+, convert exceptions into rejections 5574 // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in 5575 // Deferred#then to conditionally suppress rejection. 5576 } catch ( value ) { 5577 5578 // Support: Android 4.0 only 5579 // Strict mode functions invoked without .call/.apply get global-object context 5580 reject.apply( undefined, [ value ] ); 5581 } 5582} 5583 5584jQuery.extend( { 5585 5586 Deferred: function( func ) { 5587 var tuples = [ 5588 5589 // action, add listener, callbacks, 5590 // ... .then handlers, argument index, [final state] 5591 [ "notify", "progress", jQuery.Callbacks( "memory" ), 5592 jQuery.Callbacks( "memory" ), 2 ], 5593 [ "resolve", "done", jQuery.Callbacks( "once memory" ), 5594 jQuery.Callbacks( "once memory" ), 0, "resolved" ], 5595 [ "reject", "fail", jQuery.Callbacks( "once memory" ), 5596 jQuery.Callbacks( "once memory" ), 1, "rejected" ] 5597 ], 5598 state = "pending", 5599 promise = { 5600 state: function() { 5601 return state; 5602 }, 5603 always: function() { 5604 deferred.done( arguments ).fail( arguments ); 5605 return this; 5606 }, 5607 "catch": function( fn ) { 5608 return promise.then( null, fn ); 5609 }, 5610 5611 // Keep pipe for back-compat 5612 pipe: function( /* fnDone, fnFail, fnProgress */ ) { 5613 var fns = arguments; 5614 5615 return jQuery.Deferred( function( newDefer ) { 5616 jQuery.each( tuples, function( _i, tuple ) { 5617 5618 // Map tuples (progress, done, fail) to arguments (done, fail, progress) 5619 var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ]; 5620 5621 // deferred.progress(function() { bind to newDefer or newDefer.notify }) 5622 // deferred.done(function() { bind to newDefer or newDefer.resolve }) 5623 // deferred.fail(function() { bind to newDefer or newDefer.reject }) 5624 deferred[ tuple[ 1 ] ]( function() { 5625 var returned = fn && fn.apply( this, arguments ); 5626 if ( returned && isFunction( returned.promise ) ) { 5627 returned.promise() 5628 .progress( newDefer.notify ) 5629 .done( newDefer.resolve ) 5630 .fail( newDefer.reject ); 5631 } else { 5632 newDefer[ tuple[ 0 ] + "With" ]( 5633 this, 5634 fn ? [ returned ] : arguments 5635 ); 5636 } 5637 } ); 5638 } ); 5639 fns = null; 5640 } ).promise(); 5641 }, 5642 then: function( onFulfilled, onRejected, onProgress ) { 5643 var maxDepth = 0; 5644 function resolve( depth, deferred, handler, special ) { 5645 return function() { 5646 var that = this, 5647 args = arguments, 5648 mightThrow = function() { 5649 var returned, then; 5650 5651 // Support: Promises/A+ section 2.3.3.3.3 5652 // https://promisesaplus.com/#point-59 5653 // Ignore double-resolution attempts 5654 if ( depth < maxDepth ) { 5655 return; 5656 } 5657 5658 returned = handler.apply( that, args ); 5659 5660 // Support: Promises/A+ section 2.3.1 5661 // https://promisesaplus.com/#point-48 5662 if ( returned === deferred.promise() ) { 5663 throw new TypeError( "Thenable self-resolution" ); 5664 } 5665 5666 // Support: Promises/A+ sections 2.3.3.1, 3.5 5667 // https://promisesaplus.com/#point-54 5668 // https://promisesaplus.com/#point-75 5669 // Retrieve `then` only once 5670 then = returned && 5671 5672 // Support: Promises/A+ section 2.3.4 5673 // https://promisesaplus.com/#point-64 5674 // Only check objects and functions for thenability 5675 ( typeof returned === "object" || 5676 typeof returned === "function" ) && 5677 returned.then; 5678 5679 // Handle a returned thenable 5680 if ( isFunction( then ) ) { 5681 5682 // Special processors (notify) just wait for resolution 5683 if ( special ) { 5684 then.call( 5685 returned, 5686 resolve( maxDepth, deferred, Identity, special ), 5687 resolve( maxDepth, deferred, Thrower, special ) 5688 ); 5689 5690 // Normal processors (resolve) also hook into progress 5691 } else { 5692 5693 // ...and disregard older resolution values 5694 maxDepth++; 5695 5696 then.call( 5697 returned, 5698 resolve( maxDepth, deferred, Identity, special ), 5699 resolve( maxDepth, deferred, Thrower, special ), 5700 resolve( maxDepth, deferred, Identity, 5701 deferred.notifyWith ) 5702 ); 5703 } 5704 5705 // Handle all other returned values 5706 } else { 5707 5708 // Only substitute handlers pass on context 5709 // and multiple values (non-spec behavior) 5710 if ( handler !== Identity ) { 5711 that = undefined; 5712 args = [ returned ]; 5713 } 5714 5715 // Process the value(s) 5716 // Default process is resolve 5717 ( special || deferred.resolveWith )( that, args ); 5718 } 5719 }, 5720 5721 // Only normal processors (resolve) catch and reject exceptions 5722 process = special ? 5723 mightThrow : 5724 function() { 5725 try { 5726 mightThrow(); 5727 } catch ( e ) { 5728 5729 if ( jQuery.Deferred.exceptionHook ) { 5730 jQuery.Deferred.exceptionHook( e, 5731 process.stackTrace ); 5732 } 5733 5734 // Support: Promises/A+ section 2.3.3.3.4.1 5735 // https://promisesaplus.com/#point-61 5736 // Ignore post-resolution exceptions 5737 if ( depth + 1 >= maxDepth ) { 5738 5739 // Only substitute handlers pass on context 5740 // and multiple values (non-spec behavior) 5741 if ( handler !== Thrower ) { 5742 that = undefined; 5743 args = [ e ]; 5744 } 5745 5746 deferred.rejectWith( that, args ); 5747 } 5748 } 5749 }; 5750 5751 // Support: Promises/A+ section 2.3.3.3.1 5752 // https://promisesaplus.com/#point-57 5753 // Re-resolve promises immediately to dodge false rejection from 5754 // subsequent errors 5755 if ( depth ) { 5756 process(); 5757 } else { 5758 5759 // Call an optional hook to record the stack, in case of exception 5760 // since it's otherwise lost when execution goes async 5761 if ( jQuery.Deferred.getStackHook ) { 5762 process.stackTrace = jQuery.Deferred.getStackHook(); 5763 } 5764 window.setTimeout( process ); 5765 } 5766 }; 5767 } 5768 5769 return jQuery.Deferred( function( newDefer ) { 5770 5771 // progress_handlers.add( ... ) 5772 tuples[ 0 ][ 3 ].add( 5773 resolve( 5774 0, 5775 newDefer, 5776 isFunction( onProgress ) ? 5777 onProgress : 5778 Identity, 5779 newDefer.notifyWith 5780 ) 5781 ); 5782 5783 // fulfilled_handlers.add( ... ) 5784 tuples[ 1 ][ 3 ].add( 5785 resolve( 5786 0, 5787 newDefer, 5788 isFunction( onFulfilled ) ? 5789 onFulfilled : 5790 Identity 5791 ) 5792 ); 5793 5794 // rejected_handlers.add( ... ) 5795 tuples[ 2 ][ 3 ].add( 5796 resolve( 5797 0, 5798 newDefer, 5799 isFunction( onRejected ) ? 5800 onRejected : 5801 Thrower 5802 ) 5803 ); 5804 } ).promise(); 5805 }, 5806 5807 // Get a promise for this deferred 5808 // If obj is provided, the promise aspect is added to the object 5809 promise: function( obj ) { 5810 return obj != null ? jQuery.extend( obj, promise ) : promise; 5811 } 5812 }, 5813 deferred = {}; 5814 5815 // Add list-specific methods 5816 jQuery.each( tuples, function( i, tuple ) { 5817 var list = tuple[ 2 ], 5818 stateString = tuple[ 5 ]; 5819 5820 // promise.progress = list.add 5821 // promise.done = list.add 5822 // promise.fail = list.add 5823 promise[ tuple[ 1 ] ] = list.add; 5824 5825 // Handle state 5826 if ( stateString ) { 5827 list.add( 5828 function() { 5829 5830 // state = "resolved" (i.e., fulfilled) 5831 // state = "rejected" 5832 state = stateString; 5833 }, 5834 5835 // rejected_callbacks.disable 5836 // fulfilled_callbacks.disable 5837 tuples[ 3 - i ][ 2 ].disable, 5838 5839 // rejected_handlers.disable 5840 // fulfilled_handlers.disable 5841 tuples[ 3 - i ][ 3 ].disable, 5842 5843 // progress_callbacks.lock 5844 tuples[ 0 ][ 2 ].lock, 5845 5846 // progress_handlers.lock 5847 tuples[ 0 ][ 3 ].lock 5848 ); 5849 } 5850 5851 // progress_handlers.fire 5852 // fulfilled_handlers.fire 5853 // rejected_handlers.fire 5854 list.add( tuple[ 3 ].fire ); 5855 5856 // deferred.notify = function() { deferred.notifyWith(...) } 5857 // deferred.resolve = function() { deferred.resolveWith(...) } 5858 // deferred.reject = function() { deferred.rejectWith(...) } 5859 deferred[ tuple[ 0 ] ] = function() { 5860 deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments ); 5861 return this; 5862 }; 5863 5864 // deferred.notifyWith = list.fireWith 5865 // deferred.resolveWith = list.fireWith 5866 // deferred.rejectWith = list.fireWith 5867 deferred[ tuple[ 0 ] + "With" ] = list.fireWith; 5868 } ); 5869 5870 // Make the deferred a promise 5871 promise.promise( deferred ); 5872 5873 // Call given func if any 5874 if ( func ) { 5875 func.call( deferred, deferred ); 5876 } 5877 5878 // All done! 5879 return deferred; 5880 }, 5881 5882 // Deferred helper 5883 when: function( singleValue ) { 5884 var 5885 5886 // count of uncompleted subordinates 5887 remaining = arguments.length, 5888 5889 // count of unprocessed arguments 5890 i = remaining, 5891 5892 // subordinate fulfillment data 5893 resolveContexts = Array( i ), 5894 resolveValues = slice.call( arguments ), 5895 5896 // the primary Deferred 5897 primary = jQuery.Deferred(), 5898 5899 // subordinate callback factory 5900 updateFunc = function( i ) { 5901 return function( value ) { 5902 resolveContexts[ i ] = this; 5903 resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; 5904 if ( !( --remaining ) ) { 5905 primary.resolveWith( resolveContexts, resolveValues ); 5906 } 5907 }; 5908 }; 5909 5910 // Single- and empty arguments are adopted like Promise.resolve 5911 if ( remaining <= 1 ) { 5912 adoptValue( singleValue, primary.done( updateFunc( i ) ).resolve, primary.reject, 5913 !remaining ); 5914 5915 // Use .then() to unwrap secondary thenables (cf. gh-3000) 5916 if ( primary.state() === "pending" || 5917 isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) { 5918 5919 return primary.then(); 5920 } 5921 } 5922 5923 // Multiple arguments are aggregated like Promise.all array elements 5924 while ( i-- ) { 5925 adoptValue( resolveValues[ i ], updateFunc( i ), primary.reject ); 5926 } 5927 5928 return primary.promise(); 5929 } 5930} ); 5931 5932 5933// These usually indicate a programmer mistake during development, 5934// warn about them ASAP rather than swallowing them by default. 5935var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/; 5936 5937jQuery.Deferred.exceptionHook = function( error, stack ) { 5938 5939 // Support: IE 8 - 9 only 5940 // Console exists when dev tools are open, which can happen at any time 5941 if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) { 5942 window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack ); 5943 } 5944}; 5945 5946 5947 5948 5949jQuery.readyException = function( error ) { 5950 window.setTimeout( function() { 5951 throw error; 5952 } ); 5953}; 5954 5955 5956 5957 5958// The deferred used on DOM ready 5959var readyList = jQuery.Deferred(); 5960 5961jQuery.fn.ready = function( fn ) { 5962 5963 readyList 5964 .then( fn ) 5965 5966 // Wrap jQuery.readyException in a function so that the lookup 5967 // happens at the time of error handling instead of callback 5968 // registration. 5969 .catch( function( error ) { 5970 jQuery.readyException( error ); 5971 } ); 5972 5973 return this; 5974}; 5975 5976jQuery.extend( { 5977 5978 // Is the DOM ready to be used? Set to true once it occurs. 5979 isReady: false, 5980 5981 // A counter to track how many items to wait for before 5982 // the ready event fires. See #6781 5983 readyWait: 1, 5984 5985 // Handle when the DOM is ready 5986 ready: function( wait ) { 5987 5988 // Abort if there are pending holds or we're already ready 5989 if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { 5990 return; 5991 } 5992 5993 // Remember that the DOM is ready 5994 jQuery.isReady = true; 5995 5996 // If a normal DOM Ready event fired, decrement, and wait if need be 5997 if ( wait !== true && --jQuery.readyWait > 0 ) { 5998 return; 5999 } 6000 6001 // If there are functions bound, to execute 6002 readyList.resolveWith( document, [ jQuery ] ); 6003 } 6004} ); 6005 6006jQuery.ready.then = readyList.then; 6007 6008// The ready event handler and self cleanup method 6009function completed() { 6010 document.removeEventListener( "DOMContentLoaded", completed ); 6011 window.removeEventListener( "load", completed ); 6012 jQuery.ready(); 6013} 6014 6015// Catch cases where $(document).ready() is called 6016// after the browser event has already occurred. 6017// Support: IE <=9 - 10 only 6018// Older IE sometimes signals "interactive" too soon 6019if ( document.readyState === "complete" || 6020 ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { 6021 6022 // Handle it asynchronously to allow scripts the opportunity to delay ready 6023 window.setTimeout( jQuery.ready ); 6024 6025} else { 6026 6027 // Use the handy event callback 6028 document.addEventListener( "DOMContentLoaded", completed ); 6029 6030 // A fallback to window.onload, that will always work 6031 window.addEventListener( "load", completed ); 6032} 6033 6034 6035 6036 6037// Multifunctional method to get and set values of a collection 6038// The value/s can optionally be executed if it's a function 6039var access = function( elems, fn, key, value, chainable, emptyGet, raw ) { 6040 var i = 0, 6041 len = elems.length, 6042 bulk = key == null; 6043 6044 // Sets many values 6045 if ( toType( key ) === "object" ) { 6046 chainable = true; 6047 for ( i in key ) { 6048 access( elems, fn, i, key[ i ], true, emptyGet, raw ); 6049 } 6050 6051 // Sets one value 6052 } else if ( value !== undefined ) { 6053 chainable = true; 6054 6055 if ( !isFunction( value ) ) { 6056 raw = true; 6057 } 6058 6059 if ( bulk ) { 6060 6061 // Bulk operations run against the entire set 6062 if ( raw ) { 6063 fn.call( elems, value ); 6064 fn = null; 6065 6066 // ...except when executing function values 6067 } else { 6068 bulk = fn; 6069 fn = function( elem, _key, value ) { 6070 return bulk.call( jQuery( elem ), value ); 6071 }; 6072 } 6073 } 6074 6075 if ( fn ) { 6076 for ( ; i < len; i++ ) { 6077 fn( 6078 elems[ i ], key, raw ? 6079 value : 6080 value.call( elems[ i ], i, fn( elems[ i ], key ) ) 6081 ); 6082 } 6083 } 6084 } 6085 6086 if ( chainable ) { 6087 return elems; 6088 } 6089 6090 // Gets 6091 if ( bulk ) { 6092 return fn.call( elems ); 6093 } 6094 6095 return len ? fn( elems[ 0 ], key ) : emptyGet; 6096}; 6097 6098 6099// Matches dashed string for camelizing 6100var rmsPrefix = /^-ms-/, 6101 rdashAlpha = /-([a-z])/g; 6102 6103// Used by camelCase as callback to replace() 6104function fcamelCase( _all, letter ) { 6105 return letter.toUpperCase(); 6106} 6107 6108// Convert dashed to camelCase; used by the css and data modules 6109// Support: IE <=9 - 11, Edge 12 - 15 6110// Microsoft forgot to hump their vendor prefix (#9572) 6111function camelCase( string ) { 6112 return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); 6113} 6114var acceptData = function( owner ) { 6115 6116 // Accepts only: 6117 // - Node 6118 // - Node.ELEMENT_NODE 6119 // - Node.DOCUMENT_NODE 6120 // - Object 6121 // - Any 6122 return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); 6123}; 6124 6125 6126 6127 6128function Data() { 6129 this.expando = jQuery.expando + Data.uid++; 6130} 6131 6132Data.uid = 1; 6133 6134Data.prototype = { 6135 6136 cache: function( owner ) { 6137 6138 // Check if the owner object already has a cache 6139 var value = owner[ this.expando ]; 6140 6141 // If not, create one 6142 if ( !value ) { 6143 value = {}; 6144 6145 // We can accept data for non-element nodes in modern browsers, 6146 // but we should not, see #8335. 6147 // Always return an empty object. 6148 if ( acceptData( owner ) ) { 6149 6150 // If it is a node unlikely to be stringify-ed or looped over 6151 // use plain assignment 6152 if ( owner.nodeType ) { 6153 owner[ this.expando ] = value; 6154 6155 // Otherwise secure it in a non-enumerable property 6156 // configurable must be true to allow the property to be 6157 // deleted when data is removed 6158 } else { 6159 Object.defineProperty( owner, this.expando, { 6160 value: value, 6161 configurable: true 6162 } ); 6163 } 6164 } 6165 } 6166 6167 return value; 6168 }, 6169 set: function( owner, data, value ) { 6170 var prop, 6171 cache = this.cache( owner ); 6172 6173 // Handle: [ owner, key, value ] args 6174 // Always use camelCase key (gh-2257) 6175 if ( typeof data === "string" ) { 6176 cache[ camelCase( data ) ] = value; 6177 6178 // Handle: [ owner, { properties } ] args 6179 } else { 6180 6181 // Copy the properties one-by-one to the cache object 6182 for ( prop in data ) { 6183 cache[ camelCase( prop ) ] = data[ prop ]; 6184 } 6185 } 6186 return cache; 6187 }, 6188 get: function( owner, key ) { 6189 return key === undefined ? 6190 this.cache( owner ) : 6191 6192 // Always use camelCase key (gh-2257) 6193 owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ]; 6194 }, 6195 access: function( owner, key, value ) { 6196 6197 // In cases where either: 6198 // 6199 // 1. No key was specified 6200 // 2. A string key was specified, but no value provided 6201 // 6202 // Take the "read" path and allow the get method to determine 6203 // which value to return, respectively either: 6204 // 6205 // 1. The entire cache object 6206 // 2. The data stored at the key 6207 // 6208 if ( key === undefined || 6209 ( ( key && typeof key === "string" ) && value === undefined ) ) { 6210 6211 return this.get( owner, key ); 6212 } 6213 6214 // When the key is not a string, or both a key and value 6215 // are specified, set or extend (existing objects) with either: 6216 // 6217 // 1. An object of properties 6218 // 2. A key and value 6219 // 6220 this.set( owner, key, value ); 6221 6222 // Since the "set" path can have two possible entry points 6223 // return the expected data based on which path was taken[*] 6224 return value !== undefined ? value : key; 6225 }, 6226 remove: function( owner, key ) { 6227 var i, 6228 cache = owner[ this.expando ]; 6229 6230 if ( cache === undefined ) { 6231 return; 6232 } 6233 6234 if ( key !== undefined ) { 6235 6236 // Support array or space separated string of keys 6237 if ( Array.isArray( key ) ) { 6238 6239 // If key is an array of keys... 6240 // We always set camelCase keys, so remove that. 6241 key = key.map( camelCase ); 6242 } else { 6243 key = camelCase( key ); 6244 6245 // If a key with the spaces exists, use it. 6246 // Otherwise, create an array by matching non-whitespace 6247 key = key in cache ? 6248 [ key ] : 6249 ( key.match( rnothtmlwhite ) || [] ); 6250 } 6251 6252 i = key.length; 6253 6254 while ( i-- ) { 6255 delete cache[ key[ i ] ]; 6256 } 6257 } 6258 6259 // Remove the expando if there's no more data 6260 if ( key === undefined || jQuery.isEmptyObject( cache ) ) { 6261 6262 // Support: Chrome <=35 - 45 6263 // Webkit & Blink performance suffers when deleting properties 6264 // from DOM nodes, so set to undefined instead 6265 // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted) 6266 if ( owner.nodeType ) { 6267 owner[ this.expando ] = undefined; 6268 } else { 6269 delete owner[ this.expando ]; 6270 } 6271 } 6272 }, 6273 hasData: function( owner ) { 6274 var cache = owner[ this.expando ]; 6275 return cache !== undefined && !jQuery.isEmptyObject( cache ); 6276 } 6277}; 6278var dataPriv = new Data(); 6279 6280var dataUser = new Data(); 6281 6282 6283 6284// Implementation Summary 6285// 6286// 1. Enforce API surface and semantic compatibility with 1.9.x branch 6287// 2. Improve the module's maintainability by reducing the storage 6288// paths to a single mechanism. 6289// 3. Use the same single mechanism to support "private" and "user" data. 6290// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) 6291// 5. Avoid exposing implementation details on user objects (eg. expando properties) 6292// 6. Provide a clear path for implementation upgrade to WeakMap in 2014 6293 6294var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, 6295 rmultiDash = /[A-Z]/g; 6296 6297function getData( data ) { 6298 if ( data === "true" ) { 6299 return true; 6300 } 6301 6302 if ( data === "false" ) { 6303 return false; 6304 } 6305 6306 if ( data === "null" ) { 6307 return null; 6308 } 6309 6310 // Only convert to a number if it doesn't change the string 6311 if ( data === +data + "" ) { 6312 return +data; 6313 } 6314 6315 if ( rbrace.test( data ) ) { 6316 return JSON.parse( data ); 6317 } 6318 6319 return data; 6320} 6321 6322function dataAttr( elem, key, data ) { 6323 var name; 6324 6325 // If nothing was found internally, try to fetch any 6326 // data from the HTML5 data-* attribute 6327 if ( data === undefined && elem.nodeType === 1 ) { 6328 name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase(); 6329 data = elem.getAttribute( name ); 6330 6331 if ( typeof data === "string" ) { 6332 try { 6333 data = getData( data ); 6334 } catch ( e ) {} 6335 6336 // Make sure we set the data so it isn't changed later 6337 dataUser.set( elem, key, data ); 6338 } else { 6339 data = undefined; 6340 } 6341 } 6342 return data; 6343} 6344 6345jQuery.extend( { 6346 hasData: function( elem ) { 6347 return dataUser.hasData( elem ) || dataPriv.hasData( elem ); 6348 }, 6349 6350 data: function( elem, name, data ) { 6351 return dataUser.access( elem, name, data ); 6352 }, 6353 6354 removeData: function( elem, name ) { 6355 dataUser.remove( elem, name ); 6356 }, 6357 6358 // TODO: Now that all calls to _data and _removeData have been replaced 6359 // with direct calls to dataPriv methods, these can be deprecated. 6360 _data: function( elem, name, data ) { 6361 return dataPriv.access( elem, name, data ); 6362 }, 6363 6364 _removeData: function( elem, name ) { 6365 dataPriv.remove( elem, name ); 6366 } 6367} ); 6368 6369jQuery.fn.extend( { 6370 data: function( key, value ) { 6371 var i, name, data, 6372 elem = this[ 0 ], 6373 attrs = elem && elem.attributes; 6374 6375 // Gets all values 6376 if ( key === undefined ) { 6377 if ( this.length ) { 6378 data = dataUser.get( elem ); 6379 6380 if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) { 6381 i = attrs.length; 6382 while ( i-- ) { 6383 6384 // Support: IE 11 only 6385 // The attrs elements can be null (#14894) 6386 if ( attrs[ i ] ) { 6387 name = attrs[ i ].name; 6388 if ( name.indexOf( "data-" ) === 0 ) { 6389 name = camelCase( name.slice( 5 ) ); 6390 dataAttr( elem, name, data[ name ] ); 6391 } 6392 } 6393 } 6394 dataPriv.set( elem, "hasDataAttrs", true ); 6395 } 6396 } 6397 6398 return data; 6399 } 6400 6401 // Sets multiple values 6402 if ( typeof key === "object" ) { 6403 return this.each( function() { 6404 dataUser.set( this, key ); 6405 } ); 6406 } 6407 6408 return access( this, function( value ) { 6409 var data; 6410 6411 // The calling jQuery object (element matches) is not empty 6412 // (and therefore has an element appears at this[ 0 ]) and the 6413 // `value` parameter was not undefined. An empty jQuery object 6414 // will result in `undefined` for elem = this[ 0 ] which will 6415 // throw an exception if an attempt to read a data cache is made. 6416 if ( elem && value === undefined ) { 6417 6418 // Attempt to get data from the cache 6419 // The key will always be camelCased in Data 6420 data = dataUser.get( elem, key ); 6421 if ( data !== undefined ) { 6422 return data; 6423 } 6424 6425 // Attempt to "discover" the data in 6426 // HTML5 custom data-* attrs 6427 data = dataAttr( elem, key ); 6428 if ( data !== undefined ) { 6429 return data; 6430 } 6431 6432 // We tried really hard, but the data doesn't exist. 6433 return; 6434 } 6435 6436 // Set the data... 6437 this.each( function() { 6438 6439 // We always store the camelCased key 6440 dataUser.set( this, key, value ); 6441 } ); 6442 }, null, value, arguments.length > 1, null, true ); 6443 }, 6444 6445 removeData: function( key ) { 6446 return this.each( function() { 6447 dataUser.remove( this, key ); 6448 } ); 6449 } 6450} ); 6451 6452 6453jQuery.extend( { 6454 queue: function( elem, type, data ) { 6455 var queue; 6456 6457 if ( elem ) { 6458 type = ( type || "fx" ) + "queue"; 6459 queue = dataPriv.get( elem, type ); 6460 6461 // Speed up dequeue by getting out quickly if this is just a lookup 6462 if ( data ) { 6463 if ( !queue || Array.isArray( data ) ) { 6464 queue = dataPriv.access( elem, type, jQuery.makeArray( data ) ); 6465 } else { 6466 queue.push( data ); 6467 } 6468 } 6469 return queue || []; 6470 } 6471 }, 6472 6473 dequeue: function( elem, type ) { 6474 type = type || "fx"; 6475 6476 var queue = jQuery.queue( elem, type ), 6477 startLength = queue.length, 6478 fn = queue.shift(), 6479 hooks = jQuery._queueHooks( elem, type ), 6480 next = function() { 6481 jQuery.dequeue( elem, type ); 6482 }; 6483 6484 // If the fx queue is dequeued, always remove the progress sentinel 6485 if ( fn === "inprogress" ) { 6486 fn = queue.shift(); 6487 startLength--; 6488 } 6489 6490 if ( fn ) { 6491 6492 // Add a progress sentinel to prevent the fx queue from being 6493 // automatically dequeued 6494 if ( type === "fx" ) { 6495 queue.unshift( "inprogress" ); 6496 } 6497 6498 // Clear up the last queue stop function 6499 delete hooks.stop; 6500 fn.call( elem, next, hooks ); 6501 } 6502 6503 if ( !startLength && hooks ) { 6504 hooks.empty.fire(); 6505 } 6506 }, 6507 6508 // Not public - generate a queueHooks object, or return the current one 6509 _queueHooks: function( elem, type ) { 6510 var key = type + "queueHooks"; 6511 return dataPriv.get( elem, key ) || dataPriv.access( elem, key, { 6512 empty: jQuery.Callbacks( "once memory" ).add( function() { 6513 dataPriv.remove( elem, [ type + "queue", key ] ); 6514 } ) 6515 } ); 6516 } 6517} ); 6518 6519jQuery.fn.extend( { 6520 queue: function( type, data ) { 6521 var setter = 2; 6522 6523 if ( typeof type !== "string" ) { 6524 data = type; 6525 type = "fx"; 6526 setter--; 6527 } 6528 6529 if ( arguments.length < setter ) { 6530 return jQuery.queue( this[ 0 ], type ); 6531 } 6532 6533 return data === undefined ? 6534 this : 6535 this.each( function() { 6536 var queue = jQuery.queue( this, type, data ); 6537 6538 // Ensure a hooks for this queue 6539 jQuery._queueHooks( this, type ); 6540 6541 if ( type === "fx" && queue[ 0 ] !== "inprogress" ) { 6542 jQuery.dequeue( this, type ); 6543 } 6544 } ); 6545 }, 6546 dequeue: function( type ) { 6547 return this.each( function() { 6548 jQuery.dequeue( this, type ); 6549 } ); 6550 }, 6551 clearQueue: function( type ) { 6552 return this.queue( type || "fx", [] ); 6553 }, 6554 6555 // Get a promise resolved when queues of a certain type 6556 // are emptied (fx is the type by default) 6557 promise: function( type, obj ) { 6558 var tmp, 6559 count = 1, 6560 defer = jQuery.Deferred(), 6561 elements = this, 6562 i = this.length, 6563 resolve = function() { 6564 if ( !( --count ) ) { 6565 defer.resolveWith( elements, [ elements ] ); 6566 } 6567 }; 6568 6569 if ( typeof type !== "string" ) { 6570 obj = type; 6571 type = undefined; 6572 } 6573 type = type || "fx"; 6574 6575 while ( i-- ) { 6576 tmp = dataPriv.get( elements[ i ], type + "queueHooks" ); 6577 if ( tmp && tmp.empty ) { 6578 count++; 6579 tmp.empty.add( resolve ); 6580 } 6581 } 6582 resolve(); 6583 return defer.promise( obj ); 6584 } 6585} ); 6586var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source; 6587 6588var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ); 6589 6590 6591var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; 6592 6593var documentElement = document.documentElement; 6594 6595 6596 6597 var isAttached = function( elem ) { 6598 return jQuery.contains( elem.ownerDocument, elem ); 6599 }, 6600 composed = { composed: true }; 6601 6602 // Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only 6603 // Check attachment across shadow DOM boundaries when possible (gh-3504) 6604 // Support: iOS 10.0-10.2 only 6605 // Early iOS 10 versions support `attachShadow` but not `getRootNode`, 6606 // leading to errors. We need to check for `getRootNode`. 6607 if ( documentElement.getRootNode ) { 6608 isAttached = function( elem ) { 6609 return jQuery.contains( elem.ownerDocument, elem ) || 6610 elem.getRootNode( composed ) === elem.ownerDocument; 6611 }; 6612 } 6613var isHiddenWithinTree = function( elem, el ) { 6614 6615 // isHiddenWithinTree might be called from jQuery#filter function; 6616 // in that case, element will be second argument 6617 elem = el || elem; 6618 6619 // Inline style trumps all 6620 return elem.style.display === "none" || 6621 elem.style.display === "" && 6622 6623 // Otherwise, check computed style 6624 // Support: Firefox <=43 - 45 6625 // Disconnected elements can have computed display: none, so first confirm that elem is 6626 // in the document. 6627 isAttached( elem ) && 6628 6629 jQuery.css( elem, "display" ) === "none"; 6630 }; 6631 6632 6633 6634function adjustCSS( elem, prop, valueParts, tween ) { 6635 var adjusted, scale, 6636 maxIterations = 20, 6637 currentValue = tween ? 6638 function() { 6639 return tween.cur(); 6640 } : 6641 function() { 6642 return jQuery.css( elem, prop, "" ); 6643 }, 6644 initial = currentValue(), 6645 unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), 6646 6647 // Starting value computation is required for potential unit mismatches 6648 initialInUnit = elem.nodeType && 6649 ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) && 6650 rcssNum.exec( jQuery.css( elem, prop ) ); 6651 6652 if ( initialInUnit && initialInUnit[ 3 ] !== unit ) { 6653 6654 // Support: Firefox <=54 6655 // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144) 6656 initial = initial / 2; 6657 6658 // Trust units reported by jQuery.css 6659 unit = unit || initialInUnit[ 3 ]; 6660 6661 // Iteratively approximate from a nonzero starting point 6662 initialInUnit = +initial || 1; 6663 6664 while ( maxIterations-- ) { 6665 6666 // Evaluate and update our best guess (doubling guesses that zero out). 6667 // Finish if the scale equals or crosses 1 (making the old*new product non-positive). 6668 jQuery.style( elem, prop, initialInUnit + unit ); 6669 if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) { 6670 maxIterations = 0; 6671 } 6672 initialInUnit = initialInUnit / scale; 6673 6674 } 6675 6676 initialInUnit = initialInUnit * 2; 6677 jQuery.style( elem, prop, initialInUnit + unit ); 6678 6679 // Make sure we update the tween properties later on 6680 valueParts = valueParts || []; 6681 } 6682 6683 if ( valueParts ) { 6684 initialInUnit = +initialInUnit || +initial || 0; 6685 6686 // Apply relative offset (+=/-=) if specified 6687 adjusted = valueParts[ 1 ] ? 6688 initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] : 6689 +valueParts[ 2 ]; 6690 if ( tween ) { 6691 tween.unit = unit; 6692 tween.start = initialInUnit; 6693 tween.end = adjusted; 6694 } 6695 } 6696 return adjusted; 6697} 6698 6699 6700var defaultDisplayMap = {}; 6701 6702function getDefaultDisplay( elem ) { 6703 var temp, 6704 doc = elem.ownerDocument, 6705 nodeName = elem.nodeName, 6706 display = defaultDisplayMap[ nodeName ]; 6707 6708 if ( display ) { 6709 return display; 6710 } 6711 6712 temp = doc.body.appendChild( doc.createElement( nodeName ) ); 6713 display = jQuery.css( temp, "display" ); 6714 6715 temp.parentNode.removeChild( temp ); 6716 6717 if ( display === "none" ) { 6718 display = "block"; 6719 } 6720 defaultDisplayMap[ nodeName ] = display; 6721 6722 return display; 6723} 6724 6725function showHide( elements, show ) { 6726 var display, elem, 6727 values = [], 6728 index = 0, 6729 length = elements.length; 6730 6731 // Determine new display value for elements that need to change 6732 for ( ; index < length; index++ ) { 6733 elem = elements[ index ]; 6734 if ( !elem.style ) { 6735 continue; 6736 } 6737 6738 display = elem.style.display; 6739 if ( show ) { 6740 6741 // Since we force visibility upon cascade-hidden elements, an immediate (and slow) 6742 // check is required in this first loop unless we have a nonempty display value (either 6743 // inline or about-to-be-restored) 6744 if ( display === "none" ) { 6745 values[ index ] = dataPriv.get( elem, "display" ) || null; 6746 if ( !values[ index ] ) { 6747 elem.style.display = ""; 6748 } 6749 } 6750 if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) { 6751 values[ index ] = getDefaultDisplay( elem ); 6752 } 6753 } else { 6754 if ( display !== "none" ) { 6755 values[ index ] = "none"; 6756 6757 // Remember what we're overwriting 6758 dataPriv.set( elem, "display", display ); 6759 } 6760 } 6761 } 6762 6763 // Set the display of the elements in a second loop to avoid constant reflow 6764 for ( index = 0; index < length; index++ ) { 6765 if ( values[ index ] != null ) { 6766 elements[ index ].style.display = values[ index ]; 6767 } 6768 } 6769 6770 return elements; 6771} 6772 6773jQuery.fn.extend( { 6774 show: function() { 6775 return showHide( this, true ); 6776 }, 6777 hide: function() { 6778 return showHide( this ); 6779 }, 6780 toggle: function( state ) { 6781 if ( typeof state === "boolean" ) { 6782 return state ? this.show() : this.hide(); 6783 } 6784 6785 return this.each( function() { 6786 if ( isHiddenWithinTree( this ) ) { 6787 jQuery( this ).show(); 6788 } else { 6789 jQuery( this ).hide(); 6790 } 6791 } ); 6792 } 6793} ); 6794var rcheckableType = ( /^(?:checkbox|radio)$/i ); 6795 6796var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]*)/i ); 6797 6798var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i ); 6799 6800 6801 6802( function() { 6803 var fragment = document.createDocumentFragment(), 6804 div = fragment.appendChild( document.createElement( "div" ) ), 6805 input = document.createElement( "input" ); 6806 6807 // Support: Android 4.0 - 4.3 only 6808 // Check state lost if the name is set (#11217) 6809 // Support: Windows Web Apps (WWA) 6810 // `name` and `type` must use .setAttribute for WWA (#14901) 6811 input.setAttribute( "type", "radio" ); 6812 input.setAttribute( "checked", "checked" ); 6813 input.setAttribute( "name", "t" ); 6814 6815 div.appendChild( input ); 6816 6817 // Support: Android <=4.1 only 6818 // Older WebKit doesn't clone checked state correctly in fragments 6819 support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; 6820 6821 // Support: IE <=11 only 6822 // Make sure textarea (and checkbox) defaultValue is properly cloned 6823 div.innerHTML = "<textarea>x</textarea>"; 6824 support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; 6825 6826 // Support: IE <=9 only 6827 // IE <=9 replaces <option> tags with their contents when inserted outside of 6828 // the select element. 6829 div.innerHTML = "<option></option>"; 6830 support.option = !!div.lastChild; 6831} )(); 6832 6833 6834// We have to close these tags to support XHTML (#13200) 6835var wrapMap = { 6836 6837 // XHTML parsers do not magically insert elements in the 6838 // same way that tag soup parsers do. So we cannot shorten 6839 // this by omitting <tbody> or other required elements. 6840 thead: [ 1, "<table>", "</table>" ], 6841 col: [ 2, "<table><colgroup>", "</colgroup></table>" ], 6842 tr: [ 2, "<table><tbody>", "</tbody></table>" ], 6843 td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ], 6844 6845 _default: [ 0, "", "" ] 6846}; 6847 6848wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; 6849wrapMap.th = wrapMap.td; 6850 6851// Support: IE <=9 only 6852if ( !support.option ) { 6853 wrapMap.optgroup = wrapMap.option = [ 1, "<select multiple='multiple'>", "</select>" ]; 6854} 6855 6856 6857function getAll( context, tag ) { 6858 6859 // Support: IE <=9 - 11 only 6860 // Use typeof to avoid zero-argument method invocation on host objects (#15151) 6861 var ret; 6862 6863 if ( typeof context.getElementsByTagName !== "undefined" ) { 6864 ret = context.getElementsByTagName( tag || "*" ); 6865 6866 } else if ( typeof context.querySelectorAll !== "undefined" ) { 6867 ret = context.querySelectorAll( tag || "*" ); 6868 6869 } else { 6870 ret = []; 6871 } 6872 6873 if ( tag === undefined || tag && nodeName( context, tag ) ) { 6874 return jQuery.merge( [ context ], ret ); 6875 } 6876 6877 return ret; 6878} 6879 6880 6881// Mark scripts as having already been evaluated 6882function setGlobalEval( elems, refElements ) { 6883 var i = 0, 6884 l = elems.length; 6885 6886 for ( ; i < l; i++ ) { 6887 dataPriv.set( 6888 elems[ i ], 6889 "globalEval", 6890 !refElements || dataPriv.get( refElements[ i ], "globalEval" ) 6891 ); 6892 } 6893} 6894 6895 6896var rhtml = /<|&#?\w+;/; 6897 6898function buildFragment( elems, context, scripts, selection, ignored ) { 6899 var elem, tmp, tag, wrap, attached, j, 6900 fragment = context.createDocumentFragment(), 6901 nodes = [], 6902 i = 0, 6903 l = elems.length; 6904 6905 for ( ; i < l; i++ ) { 6906 elem = elems[ i ]; 6907 6908 if ( elem || elem === 0 ) { 6909 6910 // Add nodes directly 6911 if ( toType( elem ) === "object" ) { 6912 6913 // Support: Android <=4.0 only, PhantomJS 1 only 6914 // push.apply(_, arraylike) throws on ancient WebKit 6915 jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); 6916 6917 // Convert non-html into a text node 6918 } else if ( !rhtml.test( elem ) ) { 6919 nodes.push( context.createTextNode( elem ) ); 6920 6921 // Convert html into DOM nodes 6922 } else { 6923 tmp = tmp || fragment.appendChild( context.createElement( "div" ) ); 6924 6925 // Deserialize a standard representation 6926 tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); 6927 wrap = wrapMap[ tag ] || wrapMap._default; 6928 tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ]; 6929 6930 // Descend through wrappers to the right content 6931 j = wrap[ 0 ]; 6932 while ( j-- ) { 6933 tmp = tmp.lastChild; 6934 } 6935 6936 // Support: Android <=4.0 only, PhantomJS 1 only 6937 // push.apply(_, arraylike) throws on ancient WebKit 6938 jQuery.merge( nodes, tmp.childNodes ); 6939 6940 // Remember the top-level container 6941 tmp = fragment.firstChild; 6942 6943 // Ensure the created nodes are orphaned (#12392) 6944 tmp.textContent = ""; 6945 } 6946 } 6947 } 6948 6949 // Remove wrapper from fragment 6950 fragment.textContent = ""; 6951 6952 i = 0; 6953 while ( ( elem = nodes[ i++ ] ) ) { 6954 6955 // Skip elements already in the context collection (trac-4087) 6956 if ( selection && jQuery.inArray( elem, selection ) > -1 ) { 6957 if ( ignored ) { 6958 ignored.push( elem ); 6959 } 6960 continue; 6961 } 6962 6963 attached = isAttached( elem ); 6964 6965 // Append to fragment 6966 tmp = getAll( fragment.appendChild( elem ), "script" ); 6967 6968 // Preserve script evaluation history 6969 if ( attached ) { 6970 setGlobalEval( tmp ); 6971 } 6972 6973 // Capture executables 6974 if ( scripts ) { 6975 j = 0; 6976 while ( ( elem = tmp[ j++ ] ) ) { 6977 if ( rscriptType.test( elem.type || "" ) ) { 6978 scripts.push( elem ); 6979 } 6980 } 6981 } 6982 } 6983 6984 return fragment; 6985} 6986 6987 6988var rtypenamespace = /^([^.]*)(?:\.(.+)|)/; 6989 6990function returnTrue() { 6991 return true; 6992} 6993 6994function returnFalse() { 6995 return false; 6996} 6997 6998// Support: IE <=9 - 11+ 6999// focus() and blur() are asynchronous, except when they are no-op. 7000// So expect focus to be synchronous when the element is already active, 7001// and blur to be synchronous when the element is not already active. 7002// (focus and blur are always synchronous in other supported browsers, 7003// this just defines when we can count on it). 7004function expectSync( elem, type ) { 7005 return ( elem === safeActiveElement() ) === ( type === "focus" ); 7006} 7007 7008// Support: IE <=9 only 7009// Accessing document.activeElement can throw unexpectedly 7010// https://bugs.jquery.com/ticket/13393 7011function safeActiveElement() { 7012 try { 7013 return document.activeElement; 7014 } catch ( err ) { } 7015} 7016 7017function on( elem, types, selector, data, fn, one ) { 7018 var origFn, type; 7019 7020 // Types can be a map of types/handlers 7021 if ( typeof types === "object" ) { 7022 7023 // ( types-Object, selector, data ) 7024 if ( typeof selector !== "string" ) { 7025 7026 // ( types-Object, data ) 7027 data = data || selector; 7028 selector = undefined; 7029 } 7030 for ( type in types ) { 7031 on( elem, type, selector, data, types[ type ], one ); 7032 } 7033 return elem; 7034 } 7035 7036 if ( data == null && fn == null ) { 7037 7038 // ( types, fn ) 7039 fn = selector; 7040 data = selector = undefined; 7041 } else if ( fn == null ) { 7042 if ( typeof selector === "string" ) { 7043 7044 // ( types, selector, fn ) 7045 fn = data; 7046 data = undefined; 7047 } else { 7048 7049 // ( types, data, fn ) 7050 fn = data; 7051 data = selector; 7052 selector = undefined; 7053 } 7054 } 7055 if ( fn === false ) { 7056 fn = returnFalse; 7057 } else if ( !fn ) { 7058 return elem; 7059 } 7060 7061 if ( one === 1 ) { 7062 origFn = fn; 7063 fn = function( event ) { 7064 7065 // Can use an empty set, since event contains the info 7066 jQuery().off( event ); 7067 return origFn.apply( this, arguments ); 7068 }; 7069 7070 // Use same guid so caller can remove using origFn 7071 fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); 7072 } 7073 return elem.each( function() { 7074 jQuery.event.add( this, types, fn, data, selector ); 7075 } ); 7076} 7077 7078/* 7079 * Helper functions for managing events -- not part of the public interface. 7080 * Props to Dean Edwards' addEvent library for many of the ideas. 7081 */ 7082jQuery.event = { 7083 7084 global: {}, 7085 7086 add: function( elem, types, handler, data, selector ) { 7087 7088 var handleObjIn, eventHandle, tmp, 7089 events, t, handleObj, 7090 special, handlers, type, namespaces, origType, 7091 elemData = dataPriv.get( elem ); 7092 7093 // Only attach events to objects that accept data 7094 if ( !acceptData( elem ) ) { 7095 return; 7096 } 7097 7098 // Caller can pass in an object of custom data in lieu of the handler 7099 if ( handler.handler ) { 7100 handleObjIn = handler; 7101 handler = handleObjIn.handler; 7102 selector = handleObjIn.selector; 7103 } 7104 7105 // Ensure that invalid selectors throw exceptions at attach time 7106 // Evaluate against documentElement in case elem is a non-element node (e.g., document) 7107 if ( selector ) { 7108 jQuery.find.matchesSelector( documentElement, selector ); 7109 } 7110 7111 // Make sure that the handler has a unique ID, used to find/remove it later 7112 if ( !handler.guid ) { 7113 handler.guid = jQuery.guid++; 7114 } 7115 7116 // Init the element's event structure and main handler, if this is the first 7117 if ( !( events = elemData.events ) ) { 7118 events = elemData.events = Object.create( null ); 7119 } 7120 if ( !( eventHandle = elemData.handle ) ) { 7121 eventHandle = elemData.handle = function( e ) { 7122 7123 // Discard the second event of a jQuery.event.trigger() and 7124 // when an event is called after a page has unloaded 7125 return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? 7126 jQuery.event.dispatch.apply( elem, arguments ) : undefined; 7127 }; 7128 } 7129 7130 // Handle multiple events separated by a space 7131 types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; 7132 t = types.length; 7133 while ( t-- ) { 7134 tmp = rtypenamespace.exec( types[ t ] ) || []; 7135 type = origType = tmp[ 1 ]; 7136 namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); 7137 7138 // There *must* be a type, no attaching namespace-only handlers 7139 if ( !type ) { 7140 continue; 7141 } 7142 7143 // If event changes its type, use the special event handlers for the changed type 7144 special = jQuery.event.special[ type ] || {}; 7145 7146 // If selector defined, determine special event api type, otherwise given type 7147 type = ( selector ? special.delegateType : special.bindType ) || type; 7148 7149 // Update special based on newly reset type 7150 special = jQuery.event.special[ type ] || {}; 7151 7152 // handleObj is passed to all event handlers 7153 handleObj = jQuery.extend( { 7154 type: type, 7155 origType: origType, 7156 data: data, 7157 handler: handler, 7158 guid: handler.guid, 7159 selector: selector, 7160 needsContext: selector && jQuery.expr.match.needsContext.test( selector ), 7161 namespace: namespaces.join( "." ) 7162 }, handleObjIn ); 7163 7164 // Init the event handler queue if we're the first 7165 if ( !( handlers = events[ type ] ) ) { 7166 handlers = events[ type ] = []; 7167 handlers.delegateCount = 0; 7168 7169 // Only use addEventListener if the special events handler returns false 7170 if ( !special.setup || 7171 special.setup.call( elem, data, namespaces, eventHandle ) === false ) { 7172 7173 if ( elem.addEventListener ) { 7174 elem.addEventListener( type, eventHandle ); 7175 } 7176 } 7177 } 7178 7179 if ( special.add ) { 7180 special.add.call( elem, handleObj ); 7181 7182 if ( !handleObj.handler.guid ) { 7183 handleObj.handler.guid = handler.guid; 7184 } 7185 } 7186 7187 // Add to the element's handler list, delegates in front 7188 if ( selector ) { 7189 handlers.splice( handlers.delegateCount++, 0, handleObj ); 7190 } else { 7191 handlers.push( handleObj ); 7192 } 7193 7194 // Keep track of which events have ever been used, for event optimization 7195 jQuery.event.global[ type ] = true; 7196 } 7197 7198 }, 7199 7200 // Detach an event or set of events from an element 7201 remove: function( elem, types, handler, selector, mappedTypes ) { 7202 7203 var j, origCount, tmp, 7204 events, t, handleObj, 7205 special, handlers, type, namespaces, origType, 7206 elemData = dataPriv.hasData( elem ) && dataPriv.get( elem ); 7207 7208 if ( !elemData || !( events = elemData.events ) ) { 7209 return; 7210 } 7211 7212 // Once for each type.namespace in types; type may be omitted 7213 types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; 7214 t = types.length; 7215 while ( t-- ) { 7216 tmp = rtypenamespace.exec( types[ t ] ) || []; 7217 type = origType = tmp[ 1 ]; 7218 namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); 7219 7220 // Unbind all events (on this namespace, if provided) for the element 7221 if ( !type ) { 7222 for ( type in events ) { 7223 jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); 7224 } 7225 continue; 7226 } 7227 7228 special = jQuery.event.special[ type ] || {}; 7229 type = ( selector ? special.delegateType : special.bindType ) || type; 7230 handlers = events[ type ] || []; 7231 tmp = tmp[ 2 ] && 7232 new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ); 7233 7234 // Remove matching events 7235 origCount = j = handlers.length; 7236 while ( j-- ) { 7237 handleObj = handlers[ j ]; 7238 7239 if ( ( mappedTypes || origType === handleObj.origType ) && 7240 ( !handler || handler.guid === handleObj.guid ) && 7241 ( !tmp || tmp.test( handleObj.namespace ) ) && 7242 ( !selector || selector === handleObj.selector || 7243 selector === "**" && handleObj.selector ) ) { 7244 handlers.splice( j, 1 ); 7245 7246 if ( handleObj.selector ) { 7247 handlers.delegateCount--; 7248 } 7249 if ( special.remove ) { 7250 special.remove.call( elem, handleObj ); 7251 } 7252 } 7253 } 7254 7255 // Remove generic event handler if we removed something and no more handlers exist 7256 // (avoids potential for endless recursion during removal of special event handlers) 7257 if ( origCount && !handlers.length ) { 7258 if ( !special.teardown || 7259 special.teardown.call( elem, namespaces, elemData.handle ) === false ) { 7260 7261 jQuery.removeEvent( elem, type, elemData.handle ); 7262 } 7263 7264 delete events[ type ]; 7265 } 7266 } 7267 7268 // Remove data and the expando if it's no longer used 7269 if ( jQuery.isEmptyObject( events ) ) { 7270 dataPriv.remove( elem, "handle events" ); 7271 } 7272 }, 7273 7274 dispatch: function( nativeEvent ) { 7275 7276 var i, j, ret, matched, handleObj, handlerQueue, 7277 args = new Array( arguments.length ), 7278 7279 // Make a writable jQuery.Event from the native event object 7280 event = jQuery.event.fix( nativeEvent ), 7281 7282 handlers = ( 7283 dataPriv.get( this, "events" ) || Object.create( null ) 7284 )[ event.type ] || [], 7285 special = jQuery.event.special[ event.type ] || {}; 7286 7287 // Use the fix-ed jQuery.Event rather than the (read-only) native event 7288 args[ 0 ] = event; 7289 7290 for ( i = 1; i < arguments.length; i++ ) { 7291 args[ i ] = arguments[ i ]; 7292 } 7293 7294 event.delegateTarget = this; 7295 7296 // Call the preDispatch hook for the mapped type, and let it bail if desired 7297 if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { 7298 return; 7299 } 7300 7301 // Determine handlers 7302 handlerQueue = jQuery.event.handlers.call( this, event, handlers ); 7303 7304 // Run delegates first; they may want to stop propagation beneath us 7305 i = 0; 7306 while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { 7307 event.currentTarget = matched.elem; 7308 7309 j = 0; 7310 while ( ( handleObj = matched.handlers[ j++ ] ) && 7311 !event.isImmediatePropagationStopped() ) { 7312 7313 // If the event is namespaced, then each handler is only invoked if it is 7314 // specially universal or its namespaces are a superset of the event's. 7315 if ( !event.rnamespace || handleObj.namespace === false || 7316 event.rnamespace.test( handleObj.namespace ) ) { 7317 7318 event.handleObj = handleObj; 7319 event.data = handleObj.data; 7320 7321 ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle || 7322 handleObj.handler ).apply( matched.elem, args ); 7323 7324 if ( ret !== undefined ) { 7325 if ( ( event.result = ret ) === false ) { 7326 event.preventDefault(); 7327 event.stopPropagation(); 7328 } 7329 } 7330 } 7331 } 7332 } 7333 7334 // Call the postDispatch hook for the mapped type 7335 if ( special.postDispatch ) { 7336 special.postDispatch.call( this, event ); 7337 } 7338 7339 return event.result; 7340 }, 7341 7342 handlers: function( event, handlers ) { 7343 var i, handleObj, sel, matchedHandlers, matchedSelectors, 7344 handlerQueue = [], 7345 delegateCount = handlers.delegateCount, 7346 cur = event.target; 7347 7348 // Find delegate handlers 7349 if ( delegateCount && 7350 7351 // Support: IE <=9 7352 // Black-hole SVG <use> instance trees (trac-13180) 7353 cur.nodeType && 7354 7355 // Support: Firefox <=42 7356 // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861) 7357 // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click 7358 // Support: IE 11 only 7359 // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343) 7360 !( event.type === "click" && event.button >= 1 ) ) { 7361 7362 for ( ; cur !== this; cur = cur.parentNode || this ) { 7363 7364 // Don't check non-elements (#13208) 7365 // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) 7366 if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) { 7367 matchedHandlers = []; 7368 matchedSelectors = {}; 7369 for ( i = 0; i < delegateCount; i++ ) { 7370 handleObj = handlers[ i ]; 7371 7372 // Don't conflict with Object.prototype properties (#13203) 7373 sel = handleObj.selector + " "; 7374 7375 if ( matchedSelectors[ sel ] === undefined ) { 7376 matchedSelectors[ sel ] = handleObj.needsContext ? 7377 jQuery( sel, this ).index( cur ) > -1 : 7378 jQuery.find( sel, this, null, [ cur ] ).length; 7379 } 7380 if ( matchedSelectors[ sel ] ) { 7381 matchedHandlers.push( handleObj ); 7382 } 7383 } 7384 if ( matchedHandlers.length ) { 7385 handlerQueue.push( { elem: cur, handlers: matchedHandlers } ); 7386 } 7387 } 7388 } 7389 } 7390 7391 // Add the remaining (directly-bound) handlers 7392 cur = this; 7393 if ( delegateCount < handlers.length ) { 7394 handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } ); 7395 } 7396 7397 return handlerQueue; 7398 }, 7399 7400 addProp: function( name, hook ) { 7401 Object.defineProperty( jQuery.Event.prototype, name, { 7402 enumerable: true, 7403 configurable: true, 7404 7405 get: isFunction( hook ) ? 7406 function() { 7407 if ( this.originalEvent ) { 7408 return hook( this.originalEvent ); 7409 } 7410 } : 7411 function() { 7412 if ( this.originalEvent ) { 7413 return this.originalEvent[ name ]; 7414 } 7415 }, 7416 7417 set: function( value ) { 7418 Object.defineProperty( this, name, { 7419 enumerable: true, 7420 configurable: true, 7421 writable: true, 7422 value: value 7423 } ); 7424 } 7425 } ); 7426 }, 7427 7428 fix: function( originalEvent ) { 7429 return originalEvent[ jQuery.expando ] ? 7430 originalEvent : 7431 new jQuery.Event( originalEvent ); 7432 }, 7433 7434 special: { 7435 load: { 7436 7437 // Prevent triggered image.load events from bubbling to window.load 7438 noBubble: true 7439 }, 7440 click: { 7441 7442 // Utilize native event to ensure correct state for checkable inputs 7443 setup: function( data ) { 7444 7445 // For mutual compressibility with _default, replace `this` access with a local var. 7446 // `|| data` is dead code meant only to preserve the variable through minification. 7447 var el = this || data; 7448 7449 // Claim the first handler 7450 if ( rcheckableType.test( el.type ) && 7451 el.click && nodeName( el, "input" ) ) { 7452 7453 // dataPriv.set( el, "click", ... ) 7454 leverageNative( el, "click", returnTrue ); 7455 } 7456 7457 // Return false to allow normal processing in the caller 7458 return false; 7459 }, 7460 trigger: function( data ) { 7461 7462 // For mutual compressibility with _default, replace `this` access with a local var. 7463 // `|| data` is dead code meant only to preserve the variable through minification. 7464 var el = this || data; 7465 7466 // Force setup before triggering a click 7467 if ( rcheckableType.test( el.type ) && 7468 el.click && nodeName( el, "input" ) ) { 7469 7470 leverageNative( el, "click" ); 7471 } 7472 7473 // Return non-false to allow normal event-path propagation 7474 return true; 7475 }, 7476 7477 // For cross-browser consistency, suppress native .click() on links 7478 // Also prevent it if we're currently inside a leveraged native-event stack 7479 _default: function( event ) { 7480 var target = event.target; 7481 return rcheckableType.test( target.type ) && 7482 target.click && nodeName( target, "input" ) && 7483 dataPriv.get( target, "click" ) || 7484 nodeName( target, "a" ); 7485 } 7486 }, 7487 7488 beforeunload: { 7489 postDispatch: function( event ) { 7490 7491 // Support: Firefox 20+ 7492 // Firefox doesn't alert if the returnValue field is not set. 7493 if ( event.result !== undefined && event.originalEvent ) { 7494 event.originalEvent.returnValue = event.result; 7495 } 7496 } 7497 } 7498 } 7499}; 7500 7501// Ensure the presence of an event listener that handles manually-triggered 7502// synthetic events by interrupting progress until reinvoked in response to 7503// *native* events that it fires directly, ensuring that state changes have 7504// already occurred before other listeners are invoked. 7505function leverageNative( el, type, expectSync ) { 7506 7507 // Missing expectSync indicates a trigger call, which must force setup through jQuery.event.add 7508 if ( !expectSync ) { 7509 if ( dataPriv.get( el, type ) === undefined ) { 7510 jQuery.event.add( el, type, returnTrue ); 7511 } 7512 return; 7513 } 7514 7515 // Register the controller as a special universal handler for all event namespaces 7516 dataPriv.set( el, type, false ); 7517 jQuery.event.add( el, type, { 7518 namespace: false, 7519 handler: function( event ) { 7520 var notAsync, result, 7521 saved = dataPriv.get( this, type ); 7522 7523 if ( ( event.isTrigger & 1 ) && this[ type ] ) { 7524 7525 // Interrupt processing of the outer synthetic .trigger()ed event 7526 // Saved data should be false in such cases, but might be a leftover capture object 7527 // from an async native handler (gh-4350) 7528 if ( !saved.length ) { 7529 7530 // Store arguments for use when handling the inner native event 7531 // There will always be at least one argument (an event object), so this array 7532 // will not be confused with a leftover capture object. 7533 saved = slice.call( arguments ); 7534 dataPriv.set( this, type, saved ); 7535 7536 // Trigger the native event and capture its result 7537 // Support: IE <=9 - 11+ 7538 // focus() and blur() are asynchronous 7539 notAsync = expectSync( this, type ); 7540 this[ type ](); 7541 result = dataPriv.get( this, type ); 7542 if ( saved !== result || notAsync ) { 7543 dataPriv.set( this, type, false ); 7544 } else { 7545 result = {}; 7546 } 7547 if ( saved !== result ) { 7548 7549 // Cancel the outer synthetic event 7550 event.stopImmediatePropagation(); 7551 event.preventDefault(); 7552 7553 // Support: Chrome 86+ 7554 // In Chrome, if an element having a focusout handler is blurred by 7555 // clicking outside of it, it invokes the handler synchronously. If 7556 // that handler calls `.remove()` on the element, the data is cleared, 7557 // leaving `result` undefined. We need to guard against this. 7558 return result && result.value; 7559 } 7560 7561 // If this is an inner synthetic event for an event with a bubbling surrogate 7562 // (focus or blur), assume that the surrogate already propagated from triggering the 7563 // native event and prevent that from happening again here. 7564 // This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the 7565 // bubbling surrogate propagates *after* the non-bubbling base), but that seems 7566 // less bad than duplication. 7567 } else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) { 7568 event.stopPropagation(); 7569 } 7570 7571 // If this is a native event triggered above, everything is now in order 7572 // Fire an inner synthetic event with the original arguments 7573 } else if ( saved.length ) { 7574 7575 // ...and capture the result 7576 dataPriv.set( this, type, { 7577 value: jQuery.event.trigger( 7578 7579 // Support: IE <=9 - 11+ 7580 // Extend with the prototype to reset the above stopImmediatePropagation() 7581 jQuery.extend( saved[ 0 ], jQuery.Event.prototype ), 7582 saved.slice( 1 ), 7583 this 7584 ) 7585 } ); 7586 7587 // Abort handling of the native event 7588 event.stopImmediatePropagation(); 7589 } 7590 } 7591 } ); 7592} 7593 7594jQuery.removeEvent = function( elem, type, handle ) { 7595 7596 // This "if" is needed for plain objects 7597 if ( elem.removeEventListener ) { 7598 elem.removeEventListener( type, handle ); 7599 } 7600}; 7601 7602jQuery.Event = function( src, props ) { 7603 7604 // Allow instantiation without the 'new' keyword 7605 if ( !( this instanceof jQuery.Event ) ) { 7606 return new jQuery.Event( src, props ); 7607 } 7608 7609 // Event object 7610 if ( src && src.type ) { 7611 this.originalEvent = src; 7612 this.type = src.type; 7613 7614 // Events bubbling up the document may have been marked as prevented 7615 // by a handler lower down the tree; reflect the correct value. 7616 this.isDefaultPrevented = src.defaultPrevented || 7617 src.defaultPrevented === undefined && 7618 7619 // Support: Android <=2.3 only 7620 src.returnValue === false ? 7621 returnTrue : 7622 returnFalse; 7623 7624 // Create target properties 7625 // Support: Safari <=6 - 7 only 7626 // Target should not be a text node (#504, #13143) 7627 this.target = ( src.target && src.target.nodeType === 3 ) ? 7628 src.target.parentNode : 7629 src.target; 7630 7631 this.currentTarget = src.currentTarget; 7632 this.relatedTarget = src.relatedTarget; 7633 7634 // Event type 7635 } else { 7636 this.type = src; 7637 } 7638 7639 // Put explicitly provided properties onto the event object 7640 if ( props ) { 7641 jQuery.extend( this, props ); 7642 } 7643 7644 // Create a timestamp if incoming event doesn't have one 7645 this.timeStamp = src && src.timeStamp || Date.now(); 7646 7647 // Mark it as fixed 7648 this[ jQuery.expando ] = true; 7649}; 7650 7651// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding 7652// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html 7653jQuery.Event.prototype = { 7654 constructor: jQuery.Event, 7655 isDefaultPrevented: returnFalse, 7656 isPropagationStopped: returnFalse, 7657 isImmediatePropagationStopped: returnFalse, 7658 isSimulated: false, 7659 7660 preventDefault: function() { 7661 var e = this.originalEvent; 7662 7663 this.isDefaultPrevented = returnTrue; 7664 7665 if ( e && !this.isSimulated ) { 7666 e.preventDefault(); 7667 } 7668 }, 7669 stopPropagation: function() { 7670 var e = this.originalEvent; 7671 7672 this.isPropagationStopped = returnTrue; 7673 7674 if ( e && !this.isSimulated ) { 7675 e.stopPropagation(); 7676 } 7677 }, 7678 stopImmediatePropagation: function() { 7679 var e = this.originalEvent; 7680 7681 this.isImmediatePropagationStopped = returnTrue; 7682 7683 if ( e && !this.isSimulated ) { 7684 e.stopImmediatePropagation(); 7685 } 7686 7687 this.stopPropagation(); 7688 } 7689}; 7690 7691// Includes all common event props including KeyEvent and MouseEvent specific props 7692jQuery.each( { 7693 altKey: true, 7694 bubbles: true, 7695 cancelable: true, 7696 changedTouches: true, 7697 ctrlKey: true, 7698 detail: true, 7699 eventPhase: true, 7700 metaKey: true, 7701 pageX: true, 7702 pageY: true, 7703 shiftKey: true, 7704 view: true, 7705 "char": true, 7706 code: true, 7707 charCode: true, 7708 key: true, 7709 keyCode: true, 7710 button: true, 7711 buttons: true, 7712 clientX: true, 7713 clientY: true, 7714 offsetX: true, 7715 offsetY: true, 7716 pointerId: true, 7717 pointerType: true, 7718 screenX: true, 7719 screenY: true, 7720 targetTouches: true, 7721 toElement: true, 7722 touches: true, 7723 which: true 7724}, jQuery.event.addProp ); 7725 7726jQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateType ) { 7727 jQuery.event.special[ type ] = { 7728 7729 // Utilize native event if possible so blur/focus sequence is correct 7730 setup: function() { 7731 7732 // Claim the first handler 7733 // dataPriv.set( this, "focus", ... ) 7734 // dataPriv.set( this, "blur", ... ) 7735 leverageNative( this, type, expectSync ); 7736 7737 // Return false to allow normal processing in the caller 7738 return false; 7739 }, 7740 trigger: function() { 7741 7742 // Force setup before trigger 7743 leverageNative( this, type ); 7744 7745 // Return non-false to allow normal event-path propagation 7746 return true; 7747 }, 7748 7749 // Suppress native focus or blur as it's already being fired 7750 // in leverageNative. 7751 _default: function() { 7752 return true; 7753 }, 7754 7755 delegateType: delegateType 7756 }; 7757} ); 7758 7759// Create mouseenter/leave events using mouseover/out and event-time checks 7760// so that event delegation works in jQuery. 7761// Do the same for pointerenter/pointerleave and pointerover/pointerout 7762// 7763// Support: Safari 7 only 7764// Safari sends mouseenter too often; see: 7765// https://bugs.chromium.org/p/chromium/issues/detail?id=470258 7766// for the description of the bug (it existed in older Chrome versions as well). 7767jQuery.each( { 7768 mouseenter: "mouseover", 7769 mouseleave: "mouseout", 7770 pointerenter: "pointerover", 7771 pointerleave: "pointerout" 7772}, function( orig, fix ) { 7773 jQuery.event.special[ orig ] = { 7774 delegateType: fix, 7775 bindType: fix, 7776 7777 handle: function( event ) { 7778 var ret, 7779 target = this, 7780 related = event.relatedTarget, 7781 handleObj = event.handleObj; 7782 7783 // For mouseenter/leave call the handler if related is outside the target. 7784 // NB: No relatedTarget if the mouse left/entered the browser window 7785 if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) { 7786 event.type = handleObj.origType; 7787 ret = handleObj.handler.apply( this, arguments ); 7788 event.type = fix; 7789 } 7790 return ret; 7791 } 7792 }; 7793} ); 7794 7795jQuery.fn.extend( { 7796 7797 on: function( types, selector, data, fn ) { 7798 return on( this, types, selector, data, fn ); 7799 }, 7800 one: function( types, selector, data, fn ) { 7801 return on( this, types, selector, data, fn, 1 ); 7802 }, 7803 off: function( types, selector, fn ) { 7804 var handleObj, type; 7805 if ( types && types.preventDefault && types.handleObj ) { 7806 7807 // ( event ) dispatched jQuery.Event 7808 handleObj = types.handleObj; 7809 jQuery( types.delegateTarget ).off( 7810 handleObj.namespace ? 7811 handleObj.origType + "." + handleObj.namespace : 7812 handleObj.origType, 7813 handleObj.selector, 7814 handleObj.handler 7815 ); 7816 return this; 7817 } 7818 if ( typeof types === "object" ) { 7819 7820 // ( types-object [, selector] ) 7821 for ( type in types ) { 7822 this.off( type, selector, types[ type ] ); 7823 } 7824 return this; 7825 } 7826 if ( selector === false || typeof selector === "function" ) { 7827 7828 // ( types [, fn] ) 7829 fn = selector; 7830 selector = undefined; 7831 } 7832 if ( fn === false ) { 7833 fn = returnFalse; 7834 } 7835 return this.each( function() { 7836 jQuery.event.remove( this, types, fn, selector ); 7837 } ); 7838 } 7839} ); 7840 7841 7842var 7843 7844 // Support: IE <=10 - 11, Edge 12 - 13 only 7845 // In IE/Edge using regex groups here causes severe slowdowns. 7846 // See https://connect.microsoft.com/IE/feedback/details/1736512/ 7847 rnoInnerhtml = /<script|<style|<link/i, 7848 7849 // checked="checked" or checked 7850 rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, 7851 rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g; 7852 7853// Prefer a tbody over its parent table for containing new rows 7854function manipulationTarget( elem, content ) { 7855 if ( nodeName( elem, "table" ) && 7856 nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) { 7857 7858 return jQuery( elem ).children( "tbody" )[ 0 ] || elem; 7859 } 7860 7861 return elem; 7862} 7863 7864// Replace/restore the type attribute of script elements for safe DOM manipulation 7865function disableScript( elem ) { 7866 elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type; 7867 return elem; 7868} 7869function restoreScript( elem ) { 7870 if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) { 7871 elem.type = elem.type.slice( 5 ); 7872 } else { 7873 elem.removeAttribute( "type" ); 7874 } 7875 7876 return elem; 7877} 7878 7879function cloneCopyEvent( src, dest ) { 7880 var i, l, type, pdataOld, udataOld, udataCur, events; 7881 7882 if ( dest.nodeType !== 1 ) { 7883 return; 7884 } 7885 7886 // 1. Copy private data: events, handlers, etc. 7887 if ( dataPriv.hasData( src ) ) { 7888 pdataOld = dataPriv.get( src ); 7889 events = pdataOld.events; 7890 7891 if ( events ) { 7892 dataPriv.remove( dest, "handle events" ); 7893 7894 for ( type in events ) { 7895 for ( i = 0, l = events[ type ].length; i < l; i++ ) { 7896 jQuery.event.add( dest, type, events[ type ][ i ] ); 7897 } 7898 } 7899 } 7900 } 7901 7902 // 2. Copy user data 7903 if ( dataUser.hasData( src ) ) { 7904 udataOld = dataUser.access( src ); 7905 udataCur = jQuery.extend( {}, udataOld ); 7906 7907 dataUser.set( dest, udataCur ); 7908 } 7909} 7910 7911// Fix IE bugs, see support tests 7912function fixInput( src, dest ) { 7913 var nodeName = dest.nodeName.toLowerCase(); 7914 7915 // Fails to persist the checked state of a cloned checkbox or radio button. 7916 if ( nodeName === "input" && rcheckableType.test( src.type ) ) { 7917 dest.checked = src.checked; 7918 7919 // Fails to return the selected option to the default selected state when cloning options 7920 } else if ( nodeName === "input" || nodeName === "textarea" ) { 7921 dest.defaultValue = src.defaultValue; 7922 } 7923} 7924 7925function domManip( collection, args, callback, ignored ) { 7926 7927 // Flatten any nested arrays 7928 args = flat( args ); 7929 7930 var fragment, first, scripts, hasScripts, node, doc, 7931 i = 0, 7932 l = collection.length, 7933 iNoClone = l - 1, 7934 value = args[ 0 ], 7935 valueIsFunction = isFunction( value ); 7936 7937 // We can't cloneNode fragments that contain checked, in WebKit 7938 if ( valueIsFunction || 7939 ( l > 1 && typeof value === "string" && 7940 !support.checkClone && rchecked.test( value ) ) ) { 7941 return collection.each( function( index ) { 7942 var self = collection.eq( index ); 7943 if ( valueIsFunction ) { 7944 args[ 0 ] = value.call( this, index, self.html() ); 7945 } 7946 domManip( self, args, callback, ignored ); 7947 } ); 7948 } 7949 7950 if ( l ) { 7951 fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); 7952 first = fragment.firstChild; 7953 7954 if ( fragment.childNodes.length === 1 ) { 7955 fragment = first; 7956 } 7957 7958 // Require either new content or an interest in ignored elements to invoke the callback 7959 if ( first || ignored ) { 7960 scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); 7961 hasScripts = scripts.length; 7962 7963 // Use the original fragment for the last item 7964 // instead of the first because it can end up 7965 // being emptied incorrectly in certain situations (#8070). 7966 for ( ; i < l; i++ ) { 7967 node = fragment; 7968 7969 if ( i !== iNoClone ) { 7970 node = jQuery.clone( node, true, true ); 7971 7972 // Keep references to cloned scripts for later restoration 7973 if ( hasScripts ) { 7974 7975 // Support: Android <=4.0 only, PhantomJS 1 only 7976 // push.apply(_, arraylike) throws on ancient WebKit 7977 jQuery.merge( scripts, getAll( node, "script" ) ); 7978 } 7979 } 7980 7981 callback.call( collection[ i ], node, i ); 7982 } 7983 7984 if ( hasScripts ) { 7985 doc = scripts[ scripts.length - 1 ].ownerDocument; 7986 7987 // Reenable scripts 7988 jQuery.map( scripts, restoreScript ); 7989 7990 // Evaluate executable scripts on first document insertion 7991 for ( i = 0; i < hasScripts; i++ ) { 7992 node = scripts[ i ]; 7993 if ( rscriptType.test( node.type || "" ) && 7994 !dataPriv.access( node, "globalEval" ) && 7995 jQuery.contains( doc, node ) ) { 7996 7997 if ( node.src && ( node.type || "" ).toLowerCase() !== "module" ) { 7998 7999 // Optional AJAX dependency, but won't run scripts if not present 8000 if ( jQuery._evalUrl && !node.noModule ) { 8001 jQuery._evalUrl( node.src, { 8002 nonce: node.nonce || node.getAttribute( "nonce" ) 8003 }, doc ); 8004 } 8005 } else { 8006 DOMEval( node.textContent.replace( rcleanScript, "" ), node, doc ); 8007 } 8008 } 8009 } 8010 } 8011 } 8012 } 8013 8014 return collection; 8015} 8016 8017function remove( elem, selector, keepData ) { 8018 var node, 8019 nodes = selector ? jQuery.filter( selector, elem ) : elem, 8020 i = 0; 8021 8022 for ( ; ( node = nodes[ i ] ) != null; i++ ) { 8023 if ( !keepData && node.nodeType === 1 ) { 8024 jQuery.cleanData( getAll( node ) ); 8025 } 8026 8027 if ( node.parentNode ) { 8028 if ( keepData && isAttached( node ) ) { 8029 setGlobalEval( getAll( node, "script" ) ); 8030 } 8031 node.parentNode.removeChild( node ); 8032 } 8033 } 8034 8035 return elem; 8036} 8037 8038jQuery.extend( { 8039 htmlPrefilter: function( html ) { 8040 return html; 8041 }, 8042 8043 clone: function( elem, dataAndEvents, deepDataAndEvents ) { 8044 var i, l, srcElements, destElements, 8045 clone = elem.cloneNode( true ), 8046 inPage = isAttached( elem ); 8047 8048 // Fix IE cloning issues 8049 if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && 8050 !jQuery.isXMLDoc( elem ) ) { 8051 8052 // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2 8053 destElements = getAll( clone ); 8054 srcElements = getAll( elem ); 8055 8056 for ( i = 0, l = srcElements.length; i < l; i++ ) { 8057 fixInput( srcElements[ i ], destElements[ i ] ); 8058 } 8059 } 8060 8061 // Copy the events from the original to the clone 8062 if ( dataAndEvents ) { 8063 if ( deepDataAndEvents ) { 8064 srcElements = srcElements || getAll( elem ); 8065 destElements = destElements || getAll( clone ); 8066 8067 for ( i = 0, l = srcElements.length; i < l; i++ ) { 8068 cloneCopyEvent( srcElements[ i ], destElements[ i ] ); 8069 } 8070 } else { 8071 cloneCopyEvent( elem, clone ); 8072 } 8073 } 8074 8075 // Preserve script evaluation history 8076 destElements = getAll( clone, "script" ); 8077 if ( destElements.length > 0 ) { 8078 setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); 8079 } 8080 8081 // Return the cloned set 8082 return clone; 8083 }, 8084 8085 cleanData: function( elems ) { 8086 var data, elem, type, 8087 special = jQuery.event.special, 8088 i = 0; 8089 8090 for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) { 8091 if ( acceptData( elem ) ) { 8092 if ( ( data = elem[ dataPriv.expando ] ) ) { 8093 if ( data.events ) { 8094 for ( type in data.events ) { 8095 if ( special[ type ] ) { 8096 jQuery.event.remove( elem, type ); 8097 8098 // This is a shortcut to avoid jQuery.event.remove's overhead 8099 } else { 8100 jQuery.removeEvent( elem, type, data.handle ); 8101 } 8102 } 8103 } 8104 8105 // Support: Chrome <=35 - 45+ 8106 // Assign undefined instead of using delete, see Data#remove 8107 elem[ dataPriv.expando ] = undefined; 8108 } 8109 if ( elem[ dataUser.expando ] ) { 8110 8111 // Support: Chrome <=35 - 45+ 8112 // Assign undefined instead of using delete, see Data#remove 8113 elem[ dataUser.expando ] = undefined; 8114 } 8115 } 8116 } 8117 } 8118} ); 8119 8120jQuery.fn.extend( { 8121 detach: function( selector ) { 8122 return remove( this, selector, true ); 8123 }, 8124 8125 remove: function( selector ) { 8126 return remove( this, selector ); 8127 }, 8128 8129 text: function( value ) { 8130 return access( this, function( value ) { 8131 return value === undefined ? 8132 jQuery.text( this ) : 8133 this.empty().each( function() { 8134 if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { 8135 this.textContent = value; 8136 } 8137 } ); 8138 }, null, value, arguments.length ); 8139 }, 8140 8141 append: function() { 8142 return domManip( this, arguments, function( elem ) { 8143 if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { 8144 var target = manipulationTarget( this, elem ); 8145 target.appendChild( elem ); 8146 } 8147 } ); 8148 }, 8149 8150 prepend: function() { 8151 return domManip( this, arguments, function( elem ) { 8152 if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { 8153 var target = manipulationTarget( this, elem ); 8154 target.insertBefore( elem, target.firstChild ); 8155 } 8156 } ); 8157 }, 8158 8159 before: function() { 8160 return domManip( this, arguments, function( elem ) { 8161 if ( this.parentNode ) { 8162 this.parentNode.insertBefore( elem, this ); 8163 } 8164 } ); 8165 }, 8166 8167 after: function() { 8168 return domManip( this, arguments, function( elem ) { 8169 if ( this.parentNode ) { 8170 this.parentNode.insertBefore( elem, this.nextSibling ); 8171 } 8172 } ); 8173 }, 8174 8175 empty: function() { 8176 var elem, 8177 i = 0; 8178 8179 for ( ; ( elem = this[ i ] ) != null; i++ ) { 8180 if ( elem.nodeType === 1 ) { 8181 8182 // Prevent memory leaks 8183 jQuery.cleanData( getAll( elem, false ) ); 8184 8185 // Remove any remaining nodes 8186 elem.textContent = ""; 8187 } 8188 } 8189 8190 return this; 8191 }, 8192 8193 clone: function( dataAndEvents, deepDataAndEvents ) { 8194 dataAndEvents = dataAndEvents == null ? false : dataAndEvents; 8195 deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; 8196 8197 return this.map( function() { 8198 return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); 8199 } ); 8200 }, 8201 8202 html: function( value ) { 8203 return access( this, function( value ) { 8204 var elem = this[ 0 ] || {}, 8205 i = 0, 8206 l = this.length; 8207 8208 if ( value === undefined && elem.nodeType === 1 ) { 8209 return elem.innerHTML; 8210 } 8211 8212 // See if we can take a shortcut and just use innerHTML 8213 if ( typeof value === "string" && !rnoInnerhtml.test( value ) && 8214 !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { 8215 8216 value = jQuery.htmlPrefilter( value ); 8217 8218 try { 8219 for ( ; i < l; i++ ) { 8220 elem = this[ i ] || {}; 8221 8222 // Remove element nodes and prevent memory leaks 8223 if ( elem.nodeType === 1 ) { 8224 jQuery.cleanData( getAll( elem, false ) ); 8225 elem.innerHTML = value; 8226 } 8227 } 8228 8229 elem = 0; 8230 8231 // If using innerHTML throws an exception, use the fallback method 8232 } catch ( e ) {} 8233 } 8234 8235 if ( elem ) { 8236 this.empty().append( value ); 8237 } 8238 }, null, value, arguments.length ); 8239 }, 8240 8241 replaceWith: function() { 8242 var ignored = []; 8243 8244 // Make the changes, replacing each non-ignored context element with the new content 8245 return domManip( this, arguments, function( elem ) { 8246 var parent = this.parentNode; 8247 8248 if ( jQuery.inArray( this, ignored ) < 0 ) { 8249 jQuery.cleanData( getAll( this ) ); 8250 if ( parent ) { 8251 parent.replaceChild( elem, this ); 8252 } 8253 } 8254 8255 // Force callback invocation 8256 }, ignored ); 8257 } 8258} ); 8259 8260jQuery.each( { 8261 appendTo: "append", 8262 prependTo: "prepend", 8263 insertBefore: "before", 8264 insertAfter: "after", 8265 replaceAll: "replaceWith" 8266}, function( name, original ) { 8267 jQuery.fn[ name ] = function( selector ) { 8268 var elems, 8269 ret = [], 8270 insert = jQuery( selector ), 8271 last = insert.length - 1, 8272 i = 0; 8273 8274 for ( ; i <= last; i++ ) { 8275 elems = i === last ? this : this.clone( true ); 8276 jQuery( insert[ i ] )[ original ]( elems ); 8277 8278 // Support: Android <=4.0 only, PhantomJS 1 only 8279 // .get() because push.apply(_, arraylike) throws on ancient WebKit 8280 push.apply( ret, elems.get() ); 8281 } 8282 8283 return this.pushStack( ret ); 8284 }; 8285} ); 8286var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); 8287 8288var getStyles = function( elem ) { 8289 8290 // Support: IE <=11 only, Firefox <=30 (#15098, #14150) 8291 // IE throws on elements created in popups 8292 // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" 8293 var view = elem.ownerDocument.defaultView; 8294 8295 if ( !view || !view.opener ) { 8296 view = window; 8297 } 8298 8299 return view.getComputedStyle( elem ); 8300 }; 8301 8302var swap = function( elem, options, callback ) { 8303 var ret, name, 8304 old = {}; 8305 8306 // Remember the old values, and insert the new ones 8307 for ( name in options ) { 8308 old[ name ] = elem.style[ name ]; 8309 elem.style[ name ] = options[ name ]; 8310 } 8311 8312 ret = callback.call( elem ); 8313 8314 // Revert the old values 8315 for ( name in options ) { 8316 elem.style[ name ] = old[ name ]; 8317 } 8318 8319 return ret; 8320}; 8321 8322 8323var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" ); 8324 8325 8326 8327( function() { 8328 8329 // Executing both pixelPosition & boxSizingReliable tests require only one layout 8330 // so they're executed at the same time to save the second computation. 8331 function computeStyleTests() { 8332 8333 // This is a singleton, we need to execute it only once 8334 if ( !div ) { 8335 return; 8336 } 8337 8338 container.style.cssText = "position:absolute;left:-11111px;width:60px;" + 8339 "margin-top:1px;padding:0;border:0"; 8340 div.style.cssText = 8341 "position:relative;display:block;box-sizing:border-box;overflow:scroll;" + 8342 "margin:auto;border:1px;padding:1px;" + 8343 "width:60%;top:1%"; 8344 documentElement.appendChild( container ).appendChild( div ); 8345 8346 var divStyle = window.getComputedStyle( div ); 8347 pixelPositionVal = divStyle.top !== "1%"; 8348 8349 // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44 8350 reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12; 8351 8352 // Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3 8353 // Some styles come back with percentage values, even though they shouldn't 8354 div.style.right = "60%"; 8355 pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36; 8356 8357 // Support: IE 9 - 11 only 8358 // Detect misreporting of content dimensions for box-sizing:border-box elements 8359 boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36; 8360 8361 // Support: IE 9 only 8362 // Detect overflow:scroll screwiness (gh-3699) 8363 // Support: Chrome <=64 8364 // Don't get tricked when zoom affects offsetWidth (gh-4029) 8365 div.style.position = "absolute"; 8366 scrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12; 8367 8368 documentElement.removeChild( container ); 8369 8370 // Nullify the div so it wouldn't be stored in the memory and 8371 // it will also be a sign that checks already performed 8372 div = null; 8373 } 8374 8375 function roundPixelMeasures( measure ) { 8376 return Math.round( parseFloat( measure ) ); 8377 } 8378 8379 var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal, 8380 reliableTrDimensionsVal, reliableMarginLeftVal, 8381 container = document.createElement( "div" ), 8382 div = document.createElement( "div" ); 8383 8384 // Finish early in limited (non-browser) environments 8385 if ( !div.style ) { 8386 return; 8387 } 8388 8389 // Support: IE <=9 - 11 only 8390 // Style of cloned element affects source element cloned (#8908) 8391 div.style.backgroundClip = "content-box"; 8392 div.cloneNode( true ).style.backgroundClip = ""; 8393 support.clearCloneStyle = div.style.backgroundClip === "content-box"; 8394 8395 jQuery.extend( support, { 8396 boxSizingReliable: function() { 8397 computeStyleTests(); 8398 return boxSizingReliableVal; 8399 }, 8400 pixelBoxStyles: function() { 8401 computeStyleTests(); 8402 return pixelBoxStylesVal; 8403 }, 8404 pixelPosition: function() { 8405 computeStyleTests(); 8406 return pixelPositionVal; 8407 }, 8408 reliableMarginLeft: function() { 8409 computeStyleTests(); 8410 return reliableMarginLeftVal; 8411 }, 8412 scrollboxSize: function() { 8413 computeStyleTests(); 8414 return scrollboxSizeVal; 8415 }, 8416 8417 // Support: IE 9 - 11+, Edge 15 - 18+ 8418 // IE/Edge misreport `getComputedStyle` of table rows with width/height 8419 // set in CSS while `offset*` properties report correct values. 8420 // Behavior in IE 9 is more subtle than in newer versions & it passes 8421 // some versions of this test; make sure not to make it pass there! 8422 // 8423 // Support: Firefox 70+ 8424 // Only Firefox includes border widths 8425 // in computed dimensions. (gh-4529) 8426 reliableTrDimensions: function() { 8427 var table, tr, trChild, trStyle; 8428 if ( reliableTrDimensionsVal == null ) { 8429 table = document.createElement( "table" ); 8430 tr = document.createElement( "tr" ); 8431 trChild = document.createElement( "div" ); 8432 8433 table.style.cssText = "position:absolute;left:-11111px;border-collapse:separate"; 8434 tr.style.cssText = "border:1px solid"; 8435 8436 // Support: Chrome 86+ 8437 // Height set through cssText does not get applied. 8438 // Computed height then comes back as 0. 8439 tr.style.height = "1px"; 8440 trChild.style.height = "9px"; 8441 8442 // Support: Android 8 Chrome 86+ 8443 // In our bodyBackground.html iframe, 8444 // display for all div elements is set to "inline", 8445 // which causes a problem only in Android 8 Chrome 86. 8446 // Ensuring the div is display: block 8447 // gets around this issue. 8448 trChild.style.display = "block"; 8449 8450 documentElement 8451 .appendChild( table ) 8452 .appendChild( tr ) 8453 .appendChild( trChild ); 8454 8455 trStyle = window.getComputedStyle( tr ); 8456 reliableTrDimensionsVal = ( parseInt( trStyle.height, 10 ) + 8457 parseInt( trStyle.borderTopWidth, 10 ) + 8458 parseInt( trStyle.borderBottomWidth, 10 ) ) === tr.offsetHeight; 8459 8460 documentElement.removeChild( table ); 8461 } 8462 return reliableTrDimensionsVal; 8463 } 8464 } ); 8465} )(); 8466 8467 8468function curCSS( elem, name, computed ) { 8469 var width, minWidth, maxWidth, ret, 8470 8471 // Support: Firefox 51+ 8472 // Retrieving style before computed somehow 8473 // fixes an issue with getting wrong values 8474 // on detached elements 8475 style = elem.style; 8476 8477 computed = computed || getStyles( elem ); 8478 8479 // getPropertyValue is needed for: 8480 // .css('filter') (IE 9 only, #12537) 8481 // .css('--customProperty) (#3144) 8482 if ( computed ) { 8483 ret = computed.getPropertyValue( name ) || computed[ name ]; 8484 8485 if ( ret === "" && !isAttached( elem ) ) { 8486 ret = jQuery.style( elem, name ); 8487 } 8488 8489 // A tribute to the "awesome hack by Dean Edwards" 8490 // Android Browser returns percentage for some values, 8491 // but width seems to be reliably pixels. 8492 // This is against the CSSOM draft spec: 8493 // https://drafts.csswg.org/cssom/#resolved-values 8494 if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) { 8495 8496 // Remember the original values 8497 width = style.width; 8498 minWidth = style.minWidth; 8499 maxWidth = style.maxWidth; 8500 8501 // Put in the new values to get a computed value out 8502 style.minWidth = style.maxWidth = style.width = ret; 8503 ret = computed.width; 8504 8505 // Revert the changed values 8506 style.width = width; 8507 style.minWidth = minWidth; 8508 style.maxWidth = maxWidth; 8509 } 8510 } 8511 8512 return ret !== undefined ? 8513 8514 // Support: IE <=9 - 11 only 8515 // IE returns zIndex value as an integer. 8516 ret + "" : 8517 ret; 8518} 8519 8520 8521function addGetHookIf( conditionFn, hookFn ) { 8522 8523 // Define the hook, we'll check on the first run if it's really needed. 8524 return { 8525 get: function() { 8526 if ( conditionFn() ) { 8527 8528 // Hook not needed (or it's not possible to use it due 8529 // to missing dependency), remove it. 8530 delete this.get; 8531 return; 8532 } 8533 8534 // Hook needed; redefine it so that the support test is not executed again. 8535 return ( this.get = hookFn ).apply( this, arguments ); 8536 } 8537 }; 8538} 8539 8540 8541var cssPrefixes = [ "Webkit", "Moz", "ms" ], 8542 emptyStyle = document.createElement( "div" ).style, 8543 vendorProps = {}; 8544 8545// Return a vendor-prefixed property or undefined 8546function vendorPropName( name ) { 8547 8548 // Check for vendor prefixed names 8549 var capName = name[ 0 ].toUpperCase() + name.slice( 1 ), 8550 i = cssPrefixes.length; 8551 8552 while ( i-- ) { 8553 name = cssPrefixes[ i ] + capName; 8554 if ( name in emptyStyle ) { 8555 return name; 8556 } 8557 } 8558} 8559 8560// Return a potentially-mapped jQuery.cssProps or vendor prefixed property 8561function finalPropName( name ) { 8562 var final = jQuery.cssProps[ name ] || vendorProps[ name ]; 8563 8564 if ( final ) { 8565 return final; 8566 } 8567 if ( name in emptyStyle ) { 8568 return name; 8569 } 8570 return vendorProps[ name ] = vendorPropName( name ) || name; 8571} 8572 8573 8574var 8575 8576 // Swappable if display is none or starts with table 8577 // except "table", "table-cell", or "table-caption" 8578 // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display 8579 rdisplayswap = /^(none|table(?!-c[ea]).+)/, 8580 rcustomProp = /^--/, 8581 cssShow = { position: "absolute", visibility: "hidden", display: "block" }, 8582 cssNormalTransform = { 8583 letterSpacing: "0", 8584 fontWeight: "400" 8585 }; 8586 8587function setPositiveNumber( _elem, value, subtract ) { 8588 8589 // Any relative (+/-) values have already been 8590 // normalized at this point 8591 var matches = rcssNum.exec( value ); 8592 return matches ? 8593 8594 // Guard against undefined "subtract", e.g., when used as in cssHooks 8595 Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) : 8596 value; 8597} 8598 8599function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) { 8600 var i = dimension === "width" ? 1 : 0, 8601 extra = 0, 8602 delta = 0; 8603 8604 // Adjustment may not be necessary 8605 if ( box === ( isBorderBox ? "border" : "content" ) ) { 8606 return 0; 8607 } 8608 8609 for ( ; i < 4; i += 2 ) { 8610 8611 // Both box models exclude margin 8612 if ( box === "margin" ) { 8613 delta += jQuery.css( elem, box + cssExpand[ i ], true, styles ); 8614 } 8615 8616 // If we get here with a content-box, we're seeking "padding" or "border" or "margin" 8617 if ( !isBorderBox ) { 8618 8619 // Add padding 8620 delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); 8621 8622 // For "border" or "margin", add border 8623 if ( box !== "padding" ) { 8624 delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); 8625 8626 // But still keep track of it otherwise 8627 } else { 8628 extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); 8629 } 8630 8631 // If we get here with a border-box (content + padding + border), we're seeking "content" or 8632 // "padding" or "margin" 8633 } else { 8634 8635 // For "content", subtract padding 8636 if ( box === "content" ) { 8637 delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); 8638 } 8639 8640 // For "content" or "padding", subtract border 8641 if ( box !== "margin" ) { 8642 delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); 8643 } 8644 } 8645 } 8646 8647 // Account for positive content-box scroll gutter when requested by providing computedVal 8648 if ( !isBorderBox && computedVal >= 0 ) { 8649 8650 // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border 8651 // Assuming integer scroll gutter, subtract the rest and round down 8652 delta += Math.max( 0, Math.ceil( 8653 elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - 8654 computedVal - 8655 delta - 8656 extra - 8657 0.5 8658 8659 // If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter 8660 // Use an explicit zero to avoid NaN (gh-3964) 8661 ) ) || 0; 8662 } 8663 8664 return delta; 8665} 8666 8667function getWidthOrHeight( elem, dimension, extra ) { 8668 8669 // Start with computed style 8670 var styles = getStyles( elem ), 8671 8672 // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322). 8673 // Fake content-box until we know it's needed to know the true value. 8674 boxSizingNeeded = !support.boxSizingReliable() || extra, 8675 isBorderBox = boxSizingNeeded && 8676 jQuery.css( elem, "boxSizing", false, styles ) === "border-box", 8677 valueIsBorderBox = isBorderBox, 8678 8679 val = curCSS( elem, dimension, styles ), 8680 offsetProp = "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ); 8681 8682 // Support: Firefox <=54 8683 // Return a confounding non-pixel value or feign ignorance, as appropriate. 8684 if ( rnumnonpx.test( val ) ) { 8685 if ( !extra ) { 8686 return val; 8687 } 8688 val = "auto"; 8689 } 8690 8691 8692 // Support: IE 9 - 11 only 8693 // Use offsetWidth/offsetHeight for when box sizing is unreliable. 8694 // In those cases, the computed value can be trusted to be border-box. 8695 if ( ( !support.boxSizingReliable() && isBorderBox || 8696 8697 // Support: IE 10 - 11+, Edge 15 - 18+ 8698 // IE/Edge misreport `getComputedStyle` of table rows with width/height 8699 // set in CSS while `offset*` properties report correct values. 8700 // Interestingly, in some cases IE 9 doesn't suffer from this issue. 8701 !support.reliableTrDimensions() && nodeName( elem, "tr" ) || 8702 8703 // Fall back to offsetWidth/offsetHeight when value is "auto" 8704 // This happens for inline elements with no explicit setting (gh-3571) 8705 val === "auto" || 8706 8707 // Support: Android <=4.1 - 4.3 only 8708 // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602) 8709 !parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) && 8710 8711 // Make sure the element is visible & connected 8712 elem.getClientRects().length ) { 8713 8714 isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; 8715 8716 // Where available, offsetWidth/offsetHeight approximate border box dimensions. 8717 // Where not available (e.g., SVG), assume unreliable box-sizing and interpret the 8718 // retrieved value as a content box dimension. 8719 valueIsBorderBox = offsetProp in elem; 8720 if ( valueIsBorderBox ) { 8721 val = elem[ offsetProp ]; 8722 } 8723 } 8724 8725 // Normalize "" and auto 8726 val = parseFloat( val ) || 0; 8727 8728 // Adjust for the element's box model 8729 return ( val + 8730 boxModelAdjustment( 8731 elem, 8732 dimension, 8733 extra || ( isBorderBox ? "border" : "content" ), 8734 valueIsBorderBox, 8735 styles, 8736 8737 // Provide the current computed size to request scroll gutter calculation (gh-3589) 8738 val 8739 ) 8740 ) + "px"; 8741} 8742 8743jQuery.extend( { 8744 8745 // Add in style property hooks for overriding the default 8746 // behavior of getting and setting a style property 8747 cssHooks: { 8748 opacity: { 8749 get: function( elem, computed ) { 8750 if ( computed ) { 8751 8752 // We should always get a number back from opacity 8753 var ret = curCSS( elem, "opacity" ); 8754 return ret === "" ? "1" : ret; 8755 } 8756 } 8757 } 8758 }, 8759 8760 // Don't automatically add "px" to these possibly-unitless properties 8761 cssNumber: { 8762 "animationIterationCount": true, 8763 "columnCount": true, 8764 "fillOpacity": true, 8765 "flexGrow": true, 8766 "flexShrink": true, 8767 "fontWeight": true, 8768 "gridArea": true, 8769 "gridColumn": true, 8770 "gridColumnEnd": true, 8771 "gridColumnStart": true, 8772 "gridRow": true, 8773 "gridRowEnd": true, 8774 "gridRowStart": true, 8775 "lineHeight": true, 8776 "opacity": true, 8777 "order": true, 8778 "orphans": true, 8779 "widows": true, 8780 "zIndex": true, 8781 "zoom": true 8782 }, 8783 8784 // Add in properties whose names you wish to fix before 8785 // setting or getting the value 8786 cssProps: {}, 8787 8788 // Get and set the style property on a DOM Node 8789 style: function( elem, name, value, extra ) { 8790 8791 // Don't set styles on text and comment nodes 8792 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { 8793 return; 8794 } 8795 8796 // Make sure that we're working with the right name 8797 var ret, type, hooks, 8798 origName = camelCase( name ), 8799 isCustomProp = rcustomProp.test( name ), 8800 style = elem.style; 8801 8802 // Make sure that we're working with the right name. We don't 8803 // want to query the value if it is a CSS custom property 8804 // since they are user-defined. 8805 if ( !isCustomProp ) { 8806 name = finalPropName( origName ); 8807 } 8808 8809 // Gets hook for the prefixed version, then unprefixed version 8810 hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; 8811 8812 // Check if we're setting a value 8813 if ( value !== undefined ) { 8814 type = typeof value; 8815 8816 // Convert "+=" or "-=" to relative numbers (#7345) 8817 if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) { 8818 value = adjustCSS( elem, name, ret ); 8819 8820 // Fixes bug #9237 8821 type = "number"; 8822 } 8823 8824 // Make sure that null and NaN values aren't set (#7116) 8825 if ( value == null || value !== value ) { 8826 return; 8827 } 8828 8829 // If a number was passed in, add the unit (except for certain CSS properties) 8830 // The isCustomProp check can be removed in jQuery 4.0 when we only auto-append 8831 // "px" to a few hardcoded values. 8832 if ( type === "number" && !isCustomProp ) { 8833 value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" ); 8834 } 8835 8836 // background-* props affect original clone's values 8837 if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) { 8838 style[ name ] = "inherit"; 8839 } 8840 8841 // If a hook was provided, use that value, otherwise just set the specified value 8842 if ( !hooks || !( "set" in hooks ) || 8843 ( value = hooks.set( elem, value, extra ) ) !== undefined ) { 8844 8845 if ( isCustomProp ) { 8846 style.setProperty( name, value ); 8847 } else { 8848 style[ name ] = value; 8849 } 8850 } 8851 8852 } else { 8853 8854 // If a hook was provided get the non-computed value from there 8855 if ( hooks && "get" in hooks && 8856 ( ret = hooks.get( elem, false, extra ) ) !== undefined ) { 8857 8858 return ret; 8859 } 8860 8861 // Otherwise just get the value from the style object 8862 return style[ name ]; 8863 } 8864 }, 8865 8866 css: function( elem, name, extra, styles ) { 8867 var val, num, hooks, 8868 origName = camelCase( name ), 8869 isCustomProp = rcustomProp.test( name ); 8870 8871 // Make sure that we're working with the right name. We don't 8872 // want to modify the value if it is a CSS custom property 8873 // since they are user-defined. 8874 if ( !isCustomProp ) { 8875 name = finalPropName( origName ); 8876 } 8877 8878 // Try prefixed name followed by the unprefixed name 8879 hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; 8880 8881 // If a hook was provided get the computed value from there 8882 if ( hooks && "get" in hooks ) { 8883 val = hooks.get( elem, true, extra ); 8884 } 8885 8886 // Otherwise, if a way to get the computed value exists, use that 8887 if ( val === undefined ) { 8888 val = curCSS( elem, name, styles ); 8889 } 8890 8891 // Convert "normal" to computed value 8892 if ( val === "normal" && name in cssNormalTransform ) { 8893 val = cssNormalTransform[ name ]; 8894 } 8895 8896 // Make numeric if forced or a qualifier was provided and val looks numeric 8897 if ( extra === "" || extra ) { 8898 num = parseFloat( val ); 8899 return extra === true || isFinite( num ) ? num || 0 : val; 8900 } 8901 8902 return val; 8903 } 8904} ); 8905 8906jQuery.each( [ "height", "width" ], function( _i, dimension ) { 8907 jQuery.cssHooks[ dimension ] = { 8908 get: function( elem, computed, extra ) { 8909 if ( computed ) { 8910 8911 // Certain elements can have dimension info if we invisibly show them 8912 // but it must have a current display style that would benefit 8913 return rdisplayswap.test( jQuery.css( elem, "display" ) ) && 8914 8915 // Support: Safari 8+ 8916 // Table columns in Safari have non-zero offsetWidth & zero 8917 // getBoundingClientRect().width unless display is changed. 8918 // Support: IE <=11 only 8919 // Running getBoundingClientRect on a disconnected node 8920 // in IE throws an error. 8921 ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ? 8922 swap( elem, cssShow, function() { 8923 return getWidthOrHeight( elem, dimension, extra ); 8924 } ) : 8925 getWidthOrHeight( elem, dimension, extra ); 8926 } 8927 }, 8928 8929 set: function( elem, value, extra ) { 8930 var matches, 8931 styles = getStyles( elem ), 8932 8933 // Only read styles.position if the test has a chance to fail 8934 // to avoid forcing a reflow. 8935 scrollboxSizeBuggy = !support.scrollboxSize() && 8936 styles.position === "absolute", 8937 8938 // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991) 8939 boxSizingNeeded = scrollboxSizeBuggy || extra, 8940 isBorderBox = boxSizingNeeded && 8941 jQuery.css( elem, "boxSizing", false, styles ) === "border-box", 8942 subtract = extra ? 8943 boxModelAdjustment( 8944 elem, 8945 dimension, 8946 extra, 8947 isBorderBox, 8948 styles 8949 ) : 8950 0; 8951 8952 // Account for unreliable border-box dimensions by comparing offset* to computed and 8953 // faking a content-box to get border and padding (gh-3699) 8954 if ( isBorderBox && scrollboxSizeBuggy ) { 8955 subtract -= Math.ceil( 8956 elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - 8957 parseFloat( styles[ dimension ] ) - 8958 boxModelAdjustment( elem, dimension, "border", false, styles ) - 8959 0.5 8960 ); 8961 } 8962 8963 // Convert to pixels if value adjustment is needed 8964 if ( subtract && ( matches = rcssNum.exec( value ) ) && 8965 ( matches[ 3 ] || "px" ) !== "px" ) { 8966 8967 elem.style[ dimension ] = value; 8968 value = jQuery.css( elem, dimension ); 8969 } 8970 8971 return setPositiveNumber( elem, value, subtract ); 8972 } 8973 }; 8974} ); 8975 8976jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft, 8977 function( elem, computed ) { 8978 if ( computed ) { 8979 return ( parseFloat( curCSS( elem, "marginLeft" ) ) || 8980 elem.getBoundingClientRect().left - 8981 swap( elem, { marginLeft: 0 }, function() { 8982 return elem.getBoundingClientRect().left; 8983 } ) 8984 ) + "px"; 8985 } 8986 } 8987); 8988 8989// These hooks are used by animate to expand properties 8990jQuery.each( { 8991 margin: "", 8992 padding: "", 8993 border: "Width" 8994}, function( prefix, suffix ) { 8995 jQuery.cssHooks[ prefix + suffix ] = { 8996 expand: function( value ) { 8997 var i = 0, 8998 expanded = {}, 8999 9000 // Assumes a single number if not a string 9001 parts = typeof value === "string" ? value.split( " " ) : [ value ]; 9002 9003 for ( ; i < 4; i++ ) { 9004 expanded[ prefix + cssExpand[ i ] + suffix ] = 9005 parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; 9006 } 9007 9008 return expanded; 9009 } 9010 }; 9011 9012 if ( prefix !== "margin" ) { 9013 jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; 9014 } 9015} ); 9016 9017jQuery.fn.extend( { 9018 css: function( name, value ) { 9019 return access( this, function( elem, name, value ) { 9020 var styles, len, 9021 map = {}, 9022 i = 0; 9023 9024 if ( Array.isArray( name ) ) { 9025 styles = getStyles( elem ); 9026 len = name.length; 9027 9028 for ( ; i < len; i++ ) { 9029 map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); 9030 } 9031 9032 return map; 9033 } 9034 9035 return value !== undefined ? 9036 jQuery.style( elem, name, value ) : 9037 jQuery.css( elem, name ); 9038 }, name, value, arguments.length > 1 ); 9039 } 9040} ); 9041 9042 9043function Tween( elem, options, prop, end, easing ) { 9044 return new Tween.prototype.init( elem, options, prop, end, easing ); 9045} 9046jQuery.Tween = Tween; 9047 9048Tween.prototype = { 9049 constructor: Tween, 9050 init: function( elem, options, prop, end, easing, unit ) { 9051 this.elem = elem; 9052 this.prop = prop; 9053 this.easing = easing || jQuery.easing._default; 9054 this.options = options; 9055 this.start = this.now = this.cur(); 9056 this.end = end; 9057 this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); 9058 }, 9059 cur: function() { 9060 var hooks = Tween.propHooks[ this.prop ]; 9061 9062 return hooks && hooks.get ? 9063 hooks.get( this ) : 9064 Tween.propHooks._default.get( this ); 9065 }, 9066 run: function( percent ) { 9067 var eased, 9068 hooks = Tween.propHooks[ this.prop ]; 9069 9070 if ( this.options.duration ) { 9071 this.pos = eased = jQuery.easing[ this.easing ]( 9072 percent, this.options.duration * percent, 0, 1, this.options.duration 9073 ); 9074 } else { 9075 this.pos = eased = percent; 9076 } 9077 this.now = ( this.end - this.start ) * eased + this.start; 9078 9079 if ( this.options.step ) { 9080 this.options.step.call( this.elem, this.now, this ); 9081 } 9082 9083 if ( hooks && hooks.set ) { 9084 hooks.set( this ); 9085 } else { 9086 Tween.propHooks._default.set( this ); 9087 } 9088 return this; 9089 } 9090}; 9091 9092Tween.prototype.init.prototype = Tween.prototype; 9093 9094Tween.propHooks = { 9095 _default: { 9096 get: function( tween ) { 9097 var result; 9098 9099 // Use a property on the element directly when it is not a DOM element, 9100 // or when there is no matching style property that exists. 9101 if ( tween.elem.nodeType !== 1 || 9102 tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) { 9103 return tween.elem[ tween.prop ]; 9104 } 9105 9106 // Passing an empty string as a 3rd parameter to .css will automatically 9107 // attempt a parseFloat and fallback to a string if the parse fails. 9108 // Simple values such as "10px" are parsed to Float; 9109 // complex values such as "rotate(1rad)" are returned as-is. 9110 result = jQuery.css( tween.elem, tween.prop, "" ); 9111 9112 // Empty strings, null, undefined and "auto" are converted to 0. 9113 return !result || result === "auto" ? 0 : result; 9114 }, 9115 set: function( tween ) { 9116 9117 // Use step hook for back compat. 9118 // Use cssHook if its there. 9119 // Use .style if available and use plain properties where available. 9120 if ( jQuery.fx.step[ tween.prop ] ) { 9121 jQuery.fx.step[ tween.prop ]( tween ); 9122 } else if ( tween.elem.nodeType === 1 && ( 9123 jQuery.cssHooks[ tween.prop ] || 9124 tween.elem.style[ finalPropName( tween.prop ) ] != null ) ) { 9125 jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); 9126 } else { 9127 tween.elem[ tween.prop ] = tween.now; 9128 } 9129 } 9130 } 9131}; 9132 9133// Support: IE <=9 only 9134// Panic based approach to setting things on disconnected nodes 9135Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { 9136 set: function( tween ) { 9137 if ( tween.elem.nodeType && tween.elem.parentNode ) { 9138 tween.elem[ tween.prop ] = tween.now; 9139 } 9140 } 9141}; 9142 9143jQuery.easing = { 9144 linear: function( p ) { 9145 return p; 9146 }, 9147 swing: function( p ) { 9148 return 0.5 - Math.cos( p * Math.PI ) / 2; 9149 }, 9150 _default: "swing" 9151}; 9152 9153jQuery.fx = Tween.prototype.init; 9154 9155// Back compat <1.8 extension point 9156jQuery.fx.step = {}; 9157 9158 9159 9160 9161var 9162 fxNow, inProgress, 9163 rfxtypes = /^(?:toggle|show|hide)$/, 9164 rrun = /queueHooks$/; 9165 9166function schedule() { 9167 if ( inProgress ) { 9168 if ( document.hidden === false && window.requestAnimationFrame ) { 9169 window.requestAnimationFrame( schedule ); 9170 } else { 9171 window.setTimeout( schedule, jQuery.fx.interval ); 9172 } 9173 9174 jQuery.fx.tick(); 9175 } 9176} 9177 9178// Animations created synchronously will run synchronously 9179function createFxNow() { 9180 window.setTimeout( function() { 9181 fxNow = undefined; 9182 } ); 9183 return ( fxNow = Date.now() ); 9184} 9185 9186// Generate parameters to create a standard animation 9187function genFx( type, includeWidth ) { 9188 var which, 9189 i = 0, 9190 attrs = { height: type }; 9191 9192 // If we include width, step value is 1 to do all cssExpand values, 9193 // otherwise step value is 2 to skip over Left and Right 9194 includeWidth = includeWidth ? 1 : 0; 9195 for ( ; i < 4; i += 2 - includeWidth ) { 9196 which = cssExpand[ i ]; 9197 attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; 9198 } 9199 9200 if ( includeWidth ) { 9201 attrs.opacity = attrs.width = type; 9202 } 9203 9204 return attrs; 9205} 9206 9207function createTween( value, prop, animation ) { 9208 var tween, 9209 collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ), 9210 index = 0, 9211 length = collection.length; 9212 for ( ; index < length; index++ ) { 9213 if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) { 9214 9215 // We're done with this property 9216 return tween; 9217 } 9218 } 9219} 9220 9221function defaultPrefilter( elem, props, opts ) { 9222 var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display, 9223 isBox = "width" in props || "height" in props, 9224 anim = this, 9225 orig = {}, 9226 style = elem.style, 9227 hidden = elem.nodeType && isHiddenWithinTree( elem ), 9228 dataShow = dataPriv.get( elem, "fxshow" ); 9229 9230 // Queue-skipping animations hijack the fx hooks 9231 if ( !opts.queue ) { 9232 hooks = jQuery._queueHooks( elem, "fx" ); 9233 if ( hooks.unqueued == null ) { 9234 hooks.unqueued = 0; 9235 oldfire = hooks.empty.fire; 9236 hooks.empty.fire = function() { 9237 if ( !hooks.unqueued ) { 9238 oldfire(); 9239 } 9240 }; 9241 } 9242 hooks.unqueued++; 9243 9244 anim.always( function() { 9245 9246 // Ensure the complete handler is called before this completes 9247 anim.always( function() { 9248 hooks.unqueued--; 9249 if ( !jQuery.queue( elem, "fx" ).length ) { 9250 hooks.empty.fire(); 9251 } 9252 } ); 9253 } ); 9254 } 9255 9256 // Detect show/hide animations 9257 for ( prop in props ) { 9258 value = props[ prop ]; 9259 if ( rfxtypes.test( value ) ) { 9260 delete props[ prop ]; 9261 toggle = toggle || value === "toggle"; 9262 if ( value === ( hidden ? "hide" : "show" ) ) { 9263 9264 // Pretend to be hidden if this is a "show" and 9265 // there is still data from a stopped show/hide 9266 if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) { 9267 hidden = true; 9268 9269 // Ignore all other no-op show/hide data 9270 } else { 9271 continue; 9272 } 9273 } 9274 orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop ); 9275 } 9276 } 9277 9278 // Bail out if this is a no-op like .hide().hide() 9279 propTween = !jQuery.isEmptyObject( props ); 9280 if ( !propTween && jQuery.isEmptyObject( orig ) ) { 9281 return; 9282 } 9283 9284 // Restrict "overflow" and "display" styles during box animations 9285 if ( isBox && elem.nodeType === 1 ) { 9286 9287 // Support: IE <=9 - 11, Edge 12 - 15 9288 // Record all 3 overflow attributes because IE does not infer the shorthand 9289 // from identically-valued overflowX and overflowY and Edge just mirrors 9290 // the overflowX value there. 9291 opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; 9292 9293 // Identify a display type, preferring old show/hide data over the CSS cascade 9294 restoreDisplay = dataShow && dataShow.display; 9295 if ( restoreDisplay == null ) { 9296 restoreDisplay = dataPriv.get( elem, "display" ); 9297 } 9298 display = jQuery.css( elem, "display" ); 9299 if ( display === "none" ) { 9300 if ( restoreDisplay ) { 9301 display = restoreDisplay; 9302 } else { 9303 9304 // Get nonempty value(s) by temporarily forcing visibility 9305 showHide( [ elem ], true ); 9306 restoreDisplay = elem.style.display || restoreDisplay; 9307 display = jQuery.css( elem, "display" ); 9308 showHide( [ elem ] ); 9309 } 9310 } 9311 9312 // Animate inline elements as inline-block 9313 if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) { 9314 if ( jQuery.css( elem, "float" ) === "none" ) { 9315 9316 // Restore the original display value at the end of pure show/hide animations 9317 if ( !propTween ) { 9318 anim.done( function() { 9319 style.display = restoreDisplay; 9320 } ); 9321 if ( restoreDisplay == null ) { 9322 display = style.display; 9323 restoreDisplay = display === "none" ? "" : display; 9324 } 9325 } 9326 style.display = "inline-block"; 9327 } 9328 } 9329 } 9330 9331 if ( opts.overflow ) { 9332 style.overflow = "hidden"; 9333 anim.always( function() { 9334 style.overflow = opts.overflow[ 0 ]; 9335 style.overflowX = opts.overflow[ 1 ]; 9336 style.overflowY = opts.overflow[ 2 ]; 9337 } ); 9338 } 9339 9340 // Implement show/hide animations 9341 propTween = false; 9342 for ( prop in orig ) { 9343 9344 // General show/hide setup for this element animation 9345 if ( !propTween ) { 9346 if ( dataShow ) { 9347 if ( "hidden" in dataShow ) { 9348 hidden = dataShow.hidden; 9349 } 9350 } else { 9351 dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } ); 9352 } 9353 9354 // Store hidden/visible for toggle so `.stop().toggle()` "reverses" 9355 if ( toggle ) { 9356 dataShow.hidden = !hidden; 9357 } 9358 9359 // Show elements before animating them 9360 if ( hidden ) { 9361 showHide( [ elem ], true ); 9362 } 9363 9364 /* eslint-disable no-loop-func */ 9365 9366 anim.done( function() { 9367 9368 /* eslint-enable no-loop-func */ 9369 9370 // The final step of a "hide" animation is actually hiding the element 9371 if ( !hidden ) { 9372 showHide( [ elem ] ); 9373 } 9374 dataPriv.remove( elem, "fxshow" ); 9375 for ( prop in orig ) { 9376 jQuery.style( elem, prop, orig[ prop ] ); 9377 } 9378 } ); 9379 } 9380 9381 // Per-property setup 9382 propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); 9383 if ( !( prop in dataShow ) ) { 9384 dataShow[ prop ] = propTween.start; 9385 if ( hidden ) { 9386 propTween.end = propTween.start; 9387 propTween.start = 0; 9388 } 9389 } 9390 } 9391} 9392 9393function propFilter( props, specialEasing ) { 9394 var index, name, easing, value, hooks; 9395 9396 // camelCase, specialEasing and expand cssHook pass 9397 for ( index in props ) { 9398 name = camelCase( index ); 9399 easing = specialEasing[ name ]; 9400 value = props[ index ]; 9401 if ( Array.isArray( value ) ) { 9402 easing = value[ 1 ]; 9403 value = props[ index ] = value[ 0 ]; 9404 } 9405 9406 if ( index !== name ) { 9407 props[ name ] = value; 9408 delete props[ index ]; 9409 } 9410 9411 hooks = jQuery.cssHooks[ name ]; 9412 if ( hooks && "expand" in hooks ) { 9413 value = hooks.expand( value ); 9414 delete props[ name ]; 9415 9416 // Not quite $.extend, this won't overwrite existing keys. 9417 // Reusing 'index' because we have the correct "name" 9418 for ( index in value ) { 9419 if ( !( index in props ) ) { 9420 props[ index ] = value[ index ]; 9421 specialEasing[ index ] = easing; 9422 } 9423 } 9424 } else { 9425 specialEasing[ name ] = easing; 9426 } 9427 } 9428} 9429 9430function Animation( elem, properties, options ) { 9431 var result, 9432 stopped, 9433 index = 0, 9434 length = Animation.prefilters.length, 9435 deferred = jQuery.Deferred().always( function() { 9436 9437 // Don't match elem in the :animated selector 9438 delete tick.elem; 9439 } ), 9440 tick = function() { 9441 if ( stopped ) { 9442 return false; 9443 } 9444 var currentTime = fxNow || createFxNow(), 9445 remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), 9446 9447 // Support: Android 2.3 only 9448 // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497) 9449 temp = remaining / animation.duration || 0, 9450 percent = 1 - temp, 9451 index = 0, 9452 length = animation.tweens.length; 9453 9454 for ( ; index < length; index++ ) { 9455 animation.tweens[ index ].run( percent ); 9456 } 9457 9458 deferred.notifyWith( elem, [ animation, percent, remaining ] ); 9459 9460 // If there's more to do, yield 9461 if ( percent < 1 && length ) { 9462 return remaining; 9463 } 9464 9465 // If this was an empty animation, synthesize a final progress notification 9466 if ( !length ) { 9467 deferred.notifyWith( elem, [ animation, 1, 0 ] ); 9468 } 9469 9470 // Resolve the animation and report its conclusion 9471 deferred.resolveWith( elem, [ animation ] ); 9472 return false; 9473 }, 9474 animation = deferred.promise( { 9475 elem: elem, 9476 props: jQuery.extend( {}, properties ), 9477 opts: jQuery.extend( true, { 9478 specialEasing: {}, 9479 easing: jQuery.easing._default 9480 }, options ), 9481 originalProperties: properties, 9482 originalOptions: options, 9483 startTime: fxNow || createFxNow(), 9484 duration: options.duration, 9485 tweens: [], 9486 createTween: function( prop, end ) { 9487 var tween = jQuery.Tween( elem, animation.opts, prop, end, 9488 animation.opts.specialEasing[ prop ] || animation.opts.easing ); 9489 animation.tweens.push( tween ); 9490 return tween; 9491 }, 9492 stop: function( gotoEnd ) { 9493 var index = 0, 9494 9495 // If we are going to the end, we want to run all the tweens 9496 // otherwise we skip this part 9497 length = gotoEnd ? animation.tweens.length : 0; 9498 if ( stopped ) { 9499 return this; 9500 } 9501 stopped = true; 9502 for ( ; index < length; index++ ) { 9503 animation.tweens[ index ].run( 1 ); 9504 } 9505 9506 // Resolve when we played the last frame; otherwise, reject 9507 if ( gotoEnd ) { 9508 deferred.notifyWith( elem, [ animation, 1, 0 ] ); 9509 deferred.resolveWith( elem, [ animation, gotoEnd ] ); 9510 } else { 9511 deferred.rejectWith( elem, [ animation, gotoEnd ] ); 9512 } 9513 return this; 9514 } 9515 } ), 9516 props = animation.props; 9517 9518 propFilter( props, animation.opts.specialEasing ); 9519 9520 for ( ; index < length; index++ ) { 9521 result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts ); 9522 if ( result ) { 9523 if ( isFunction( result.stop ) ) { 9524 jQuery._queueHooks( animation.elem, animation.opts.queue ).stop = 9525 result.stop.bind( result ); 9526 } 9527 return result; 9528 } 9529 } 9530 9531 jQuery.map( props, createTween, animation ); 9532 9533 if ( isFunction( animation.opts.start ) ) { 9534 animation.opts.start.call( elem, animation ); 9535 } 9536 9537 // Attach callbacks from options 9538 animation 9539 .progress( animation.opts.progress ) 9540 .done( animation.opts.done, animation.opts.complete ) 9541 .fail( animation.opts.fail ) 9542 .always( animation.opts.always ); 9543 9544 jQuery.fx.timer( 9545 jQuery.extend( tick, { 9546 elem: elem, 9547 anim: animation, 9548 queue: animation.opts.queue 9549 } ) 9550 ); 9551 9552 return animation; 9553} 9554 9555jQuery.Animation = jQuery.extend( Animation, { 9556 9557 tweeners: { 9558 "*": [ function( prop, value ) { 9559 var tween = this.createTween( prop, value ); 9560 adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween ); 9561 return tween; 9562 } ] 9563 }, 9564 9565 tweener: function( props, callback ) { 9566 if ( isFunction( props ) ) { 9567 callback = props; 9568 props = [ "*" ]; 9569 } else { 9570 props = props.match( rnothtmlwhite ); 9571 } 9572 9573 var prop, 9574 index = 0, 9575 length = props.length; 9576 9577 for ( ; index < length; index++ ) { 9578 prop = props[ index ]; 9579 Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || []; 9580 Animation.tweeners[ prop ].unshift( callback ); 9581 } 9582 }, 9583 9584 prefilters: [ defaultPrefilter ], 9585 9586 prefilter: function( callback, prepend ) { 9587 if ( prepend ) { 9588 Animation.prefilters.unshift( callback ); 9589 } else { 9590 Animation.prefilters.push( callback ); 9591 } 9592 } 9593} ); 9594 9595jQuery.speed = function( speed, easing, fn ) { 9596 var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { 9597 complete: fn || !fn && easing || 9598 isFunction( speed ) && speed, 9599 duration: speed, 9600 easing: fn && easing || easing && !isFunction( easing ) && easing 9601 }; 9602 9603 // Go to the end state if fx are off 9604 if ( jQuery.fx.off ) { 9605 opt.duration = 0; 9606 9607 } else { 9608 if ( typeof opt.duration !== "number" ) { 9609 if ( opt.duration in jQuery.fx.speeds ) { 9610 opt.duration = jQuery.fx.speeds[ opt.duration ]; 9611 9612 } else { 9613 opt.duration = jQuery.fx.speeds._default; 9614 } 9615 } 9616 } 9617 9618 // Normalize opt.queue - true/undefined/null -> "fx" 9619 if ( opt.queue == null || opt.queue === true ) { 9620 opt.queue = "fx"; 9621 } 9622 9623 // Queueing 9624 opt.old = opt.complete; 9625 9626 opt.complete = function() { 9627 if ( isFunction( opt.old ) ) { 9628 opt.old.call( this ); 9629 } 9630 9631 if ( opt.queue ) { 9632 jQuery.dequeue( this, opt.queue ); 9633 } 9634 }; 9635 9636 return opt; 9637}; 9638 9639jQuery.fn.extend( { 9640 fadeTo: function( speed, to, easing, callback ) { 9641 9642 // Show any hidden elements after setting opacity to 0 9643 return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show() 9644 9645 // Animate to the value specified 9646 .end().animate( { opacity: to }, speed, easing, callback ); 9647 }, 9648 animate: function( prop, speed, easing, callback ) { 9649 var empty = jQuery.isEmptyObject( prop ), 9650 optall = jQuery.speed( speed, easing, callback ), 9651 doAnimation = function() { 9652 9653 // Operate on a copy of prop so per-property easing won't be lost 9654 var anim = Animation( this, jQuery.extend( {}, prop ), optall ); 9655 9656 // Empty animations, or finishing resolves immediately 9657 if ( empty || dataPriv.get( this, "finish" ) ) { 9658 anim.stop( true ); 9659 } 9660 }; 9661 9662 doAnimation.finish = doAnimation; 9663 9664 return empty || optall.queue === false ? 9665 this.each( doAnimation ) : 9666 this.queue( optall.queue, doAnimation ); 9667 }, 9668 stop: function( type, clearQueue, gotoEnd ) { 9669 var stopQueue = function( hooks ) { 9670 var stop = hooks.stop; 9671 delete hooks.stop; 9672 stop( gotoEnd ); 9673 }; 9674 9675 if ( typeof type !== "string" ) { 9676 gotoEnd = clearQueue; 9677 clearQueue = type; 9678 type = undefined; 9679 } 9680 if ( clearQueue ) { 9681 this.queue( type || "fx", [] ); 9682 } 9683 9684 return this.each( function() { 9685 var dequeue = true, 9686 index = type != null && type + "queueHooks", 9687 timers = jQuery.timers, 9688 data = dataPriv.get( this ); 9689 9690 if ( index ) { 9691 if ( data[ index ] && data[ index ].stop ) { 9692 stopQueue( data[ index ] ); 9693 } 9694 } else { 9695 for ( index in data ) { 9696 if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { 9697 stopQueue( data[ index ] ); 9698 } 9699 } 9700 } 9701 9702 for ( index = timers.length; index--; ) { 9703 if ( timers[ index ].elem === this && 9704 ( type == null || timers[ index ].queue === type ) ) { 9705 9706 timers[ index ].anim.stop( gotoEnd ); 9707 dequeue = false; 9708 timers.splice( index, 1 ); 9709 } 9710 } 9711 9712 // Start the next in the queue if the last step wasn't forced. 9713 // Timers currently will call their complete callbacks, which 9714 // will dequeue but only if they were gotoEnd. 9715 if ( dequeue || !gotoEnd ) { 9716 jQuery.dequeue( this, type ); 9717 } 9718 } ); 9719 }, 9720 finish: function( type ) { 9721 if ( type !== false ) { 9722 type = type || "fx"; 9723 } 9724 return this.each( function() { 9725 var index, 9726 data = dataPriv.get( this ), 9727 queue = data[ type + "queue" ], 9728 hooks = data[ type + "queueHooks" ], 9729 timers = jQuery.timers, 9730 length = queue ? queue.length : 0; 9731 9732 // Enable finishing flag on private data 9733 data.finish = true; 9734 9735 // Empty the queue first 9736 jQuery.queue( this, type, [] ); 9737 9738 if ( hooks && hooks.stop ) { 9739 hooks.stop.call( this, true ); 9740 } 9741 9742 // Look for any active animations, and finish them 9743 for ( index = timers.length; index--; ) { 9744 if ( timers[ index ].elem === this && timers[ index ].queue === type ) { 9745 timers[ index ].anim.stop( true ); 9746 timers.splice( index, 1 ); 9747 } 9748 } 9749 9750 // Look for any animations in the old queue and finish them 9751 for ( index = 0; index < length; index++ ) { 9752 if ( queue[ index ] && queue[ index ].finish ) { 9753 queue[ index ].finish.call( this ); 9754 } 9755 } 9756 9757 // Turn off finishing flag 9758 delete data.finish; 9759 } ); 9760 } 9761} ); 9762 9763jQuery.each( [ "toggle", "show", "hide" ], function( _i, name ) { 9764 var cssFn = jQuery.fn[ name ]; 9765 jQuery.fn[ name ] = function( speed, easing, callback ) { 9766 return speed == null || typeof speed === "boolean" ? 9767 cssFn.apply( this, arguments ) : 9768 this.animate( genFx( name, true ), speed, easing, callback ); 9769 }; 9770} ); 9771 9772// Generate shortcuts for custom animations 9773jQuery.each( { 9774 slideDown: genFx( "show" ), 9775 slideUp: genFx( "hide" ), 9776 slideToggle: genFx( "toggle" ), 9777 fadeIn: { opacity: "show" }, 9778 fadeOut: { opacity: "hide" }, 9779 fadeToggle: { opacity: "toggle" } 9780}, function( name, props ) { 9781 jQuery.fn[ name ] = function( speed, easing, callback ) { 9782 return this.animate( props, speed, easing, callback ); 9783 }; 9784} ); 9785 9786jQuery.timers = []; 9787jQuery.fx.tick = function() { 9788 var timer, 9789 i = 0, 9790 timers = jQuery.timers; 9791 9792 fxNow = Date.now(); 9793 9794 for ( ; i < timers.length; i++ ) { 9795 timer = timers[ i ]; 9796 9797 // Run the timer and safely remove it when done (allowing for external removal) 9798 if ( !timer() && timers[ i ] === timer ) { 9799 timers.splice( i--, 1 ); 9800 } 9801 } 9802 9803 if ( !timers.length ) { 9804 jQuery.fx.stop(); 9805 } 9806 fxNow = undefined; 9807}; 9808 9809jQuery.fx.timer = function( timer ) { 9810 jQuery.timers.push( timer ); 9811 jQuery.fx.start(); 9812}; 9813 9814jQuery.fx.interval = 13; 9815jQuery.fx.start = function() { 9816 if ( inProgress ) { 9817 return; 9818 } 9819 9820 inProgress = true; 9821 schedule(); 9822}; 9823 9824jQuery.fx.stop = function() { 9825 inProgress = null; 9826}; 9827 9828jQuery.fx.speeds = { 9829 slow: 600, 9830 fast: 200, 9831 9832 // Default speed 9833 _default: 400 9834}; 9835 9836 9837// Based off of the plugin by Clint Helfers, with permission. 9838// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/ 9839jQuery.fn.delay = function( time, type ) { 9840 time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; 9841 type = type || "fx"; 9842 9843 return this.queue( type, function( next, hooks ) { 9844 var timeout = window.setTimeout( next, time ); 9845 hooks.stop = function() { 9846 window.clearTimeout( timeout ); 9847 }; 9848 } ); 9849}; 9850 9851 9852( function() { 9853 var input = document.createElement( "input" ), 9854 select = document.createElement( "select" ), 9855 opt = select.appendChild( document.createElement( "option" ) ); 9856 9857 input.type = "checkbox"; 9858 9859 // Support: Android <=4.3 only 9860 // Default value for a checkbox should be "on" 9861 support.checkOn = input.value !== ""; 9862 9863 // Support: IE <=11 only 9864 // Must access selectedIndex to make default options select 9865 support.optSelected = opt.selected; 9866 9867 // Support: IE <=11 only 9868 // An input loses its value after becoming a radio 9869 input = document.createElement( "input" ); 9870 input.value = "t"; 9871 input.type = "radio"; 9872 support.radioValue = input.value === "t"; 9873} )(); 9874 9875 9876var boolHook, 9877 attrHandle = jQuery.expr.attrHandle; 9878 9879jQuery.fn.extend( { 9880 attr: function( name, value ) { 9881 return access( this, jQuery.attr, name, value, arguments.length > 1 ); 9882 }, 9883 9884 removeAttr: function( name ) { 9885 return this.each( function() { 9886 jQuery.removeAttr( this, name ); 9887 } ); 9888 } 9889} ); 9890 9891jQuery.extend( { 9892 attr: function( elem, name, value ) { 9893 var ret, hooks, 9894 nType = elem.nodeType; 9895 9896 // Don't get/set attributes on text, comment and attribute nodes 9897 if ( nType === 3 || nType === 8 || nType === 2 ) { 9898 return; 9899 } 9900 9901 // Fallback to prop when attributes are not supported 9902 if ( typeof elem.getAttribute === "undefined" ) { 9903 return jQuery.prop( elem, name, value ); 9904 } 9905 9906 // Attribute hooks are determined by the lowercase version 9907 // Grab necessary hook if one is defined 9908 if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { 9909 hooks = jQuery.attrHooks[ name.toLowerCase() ] || 9910 ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined ); 9911 } 9912 9913 if ( value !== undefined ) { 9914 if ( value === null ) { 9915 jQuery.removeAttr( elem, name ); 9916 return; 9917 } 9918 9919 if ( hooks && "set" in hooks && 9920 ( ret = hooks.set( elem, value, name ) ) !== undefined ) { 9921 return ret; 9922 } 9923 9924 elem.setAttribute( name, value + "" ); 9925 return value; 9926 } 9927 9928 if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { 9929 return ret; 9930 } 9931 9932 ret = jQuery.find.attr( elem, name ); 9933 9934 // Non-existent attributes return null, we normalize to undefined 9935 return ret == null ? undefined : ret; 9936 }, 9937 9938 attrHooks: { 9939 type: { 9940 set: function( elem, value ) { 9941 if ( !support.radioValue && value === "radio" && 9942 nodeName( elem, "input" ) ) { 9943 var val = elem.value; 9944 elem.setAttribute( "type", value ); 9945 if ( val ) { 9946 elem.value = val; 9947 } 9948 return value; 9949 } 9950 } 9951 } 9952 }, 9953 9954 removeAttr: function( elem, value ) { 9955 var name, 9956 i = 0, 9957 9958 // Attribute names can contain non-HTML whitespace characters 9959 // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2 9960 attrNames = value && value.match( rnothtmlwhite ); 9961 9962 if ( attrNames && elem.nodeType === 1 ) { 9963 while ( ( name = attrNames[ i++ ] ) ) { 9964 elem.removeAttribute( name ); 9965 } 9966 } 9967 } 9968} ); 9969 9970// Hooks for boolean attributes 9971boolHook = { 9972 set: function( elem, value, name ) { 9973 if ( value === false ) { 9974 9975 // Remove boolean attributes when set to false 9976 jQuery.removeAttr( elem, name ); 9977 } else { 9978 elem.setAttribute( name, name ); 9979 } 9980 return name; 9981 } 9982}; 9983 9984jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( _i, name ) { 9985 var getter = attrHandle[ name ] || jQuery.find.attr; 9986 9987 attrHandle[ name ] = function( elem, name, isXML ) { 9988 var ret, handle, 9989 lowercaseName = name.toLowerCase(); 9990 9991 if ( !isXML ) { 9992 9993 // Avoid an infinite loop by temporarily removing this function from the getter 9994 handle = attrHandle[ lowercaseName ]; 9995 attrHandle[ lowercaseName ] = ret; 9996 ret = getter( elem, name, isXML ) != null ? 9997 lowercaseName : 9998 null; 9999 attrHandle[ lowercaseName ] = handle; 10000 } 10001 return ret; 10002 }; 10003} ); 10004 10005 10006 10007 10008var rfocusable = /^(?:input|select|textarea|button)$/i, 10009 rclickable = /^(?:a|area)$/i; 10010 10011jQuery.fn.extend( { 10012 prop: function( name, value ) { 10013 return access( this, jQuery.prop, name, value, arguments.length > 1 ); 10014 }, 10015 10016 removeProp: function( name ) { 10017 return this.each( function() { 10018 delete this[ jQuery.propFix[ name ] || name ]; 10019 } ); 10020 } 10021} ); 10022 10023jQuery.extend( { 10024 prop: function( elem, name, value ) { 10025 var ret, hooks, 10026 nType = elem.nodeType; 10027 10028 // Don't get/set properties on text, comment and attribute nodes 10029 if ( nType === 3 || nType === 8 || nType === 2 ) { 10030 return; 10031 } 10032 10033 if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { 10034 10035 // Fix name and attach hooks 10036 name = jQuery.propFix[ name ] || name; 10037 hooks = jQuery.propHooks[ name ]; 10038 } 10039 10040 if ( value !== undefined ) { 10041 if ( hooks && "set" in hooks && 10042 ( ret = hooks.set( elem, value, name ) ) !== undefined ) { 10043 return ret; 10044 } 10045 10046 return ( elem[ name ] = value ); 10047 } 10048 10049 if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { 10050 return ret; 10051 } 10052 10053 return elem[ name ]; 10054 }, 10055 10056 propHooks: { 10057 tabIndex: { 10058 get: function( elem ) { 10059 10060 // Support: IE <=9 - 11 only 10061 // elem.tabIndex doesn't always return the 10062 // correct value when it hasn't been explicitly set 10063 // https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ 10064 // Use proper attribute retrieval(#12072) 10065 var tabindex = jQuery.find.attr( elem, "tabindex" ); 10066 10067 if ( tabindex ) { 10068 return parseInt( tabindex, 10 ); 10069 } 10070 10071 if ( 10072 rfocusable.test( elem.nodeName ) || 10073 rclickable.test( elem.nodeName ) && 10074 elem.href 10075 ) { 10076 return 0; 10077 } 10078 10079 return -1; 10080 } 10081 } 10082 }, 10083 10084 propFix: { 10085 "for": "htmlFor", 10086 "class": "className" 10087 } 10088} ); 10089 10090// Support: IE <=11 only 10091// Accessing the selectedIndex property 10092// forces the browser to respect setting selected 10093// on the option 10094// The getter ensures a default option is selected 10095// when in an optgroup 10096// eslint rule "no-unused-expressions" is disabled for this code 10097// since it considers such accessions noop 10098if ( !support.optSelected ) { 10099 jQuery.propHooks.selected = { 10100 get: function( elem ) { 10101 10102 /* eslint no-unused-expressions: "off" */ 10103 10104 var parent = elem.parentNode; 10105 if ( parent && parent.parentNode ) { 10106 parent.parentNode.selectedIndex; 10107 } 10108 return null; 10109 }, 10110 set: function( elem ) { 10111 10112 /* eslint no-unused-expressions: "off" */ 10113 10114 var parent = elem.parentNode; 10115 if ( parent ) { 10116 parent.selectedIndex; 10117 10118 if ( parent.parentNode ) { 10119 parent.parentNode.selectedIndex; 10120 } 10121 } 10122 } 10123 }; 10124} 10125 10126jQuery.each( [ 10127 "tabIndex", 10128 "readOnly", 10129 "maxLength", 10130 "cellSpacing", 10131 "cellPadding", 10132 "rowSpan", 10133 "colSpan", 10134 "useMap", 10135 "frameBorder", 10136 "contentEditable" 10137], function() { 10138 jQuery.propFix[ this.toLowerCase() ] = this; 10139} ); 10140 10141 10142 10143 10144 // Strip and collapse whitespace according to HTML spec 10145 // https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace 10146 function stripAndCollapse( value ) { 10147 var tokens = value.match( rnothtmlwhite ) || []; 10148 return tokens.join( " " ); 10149 } 10150 10151 10152function getClass( elem ) { 10153 return elem.getAttribute && elem.getAttribute( "class" ) || ""; 10154} 10155 10156function classesToArray( value ) { 10157 if ( Array.isArray( value ) ) { 10158 return value; 10159 } 10160 if ( typeof value === "string" ) { 10161 return value.match( rnothtmlwhite ) || []; 10162 } 10163 return []; 10164} 10165 10166jQuery.fn.extend( { 10167 addClass: function( value ) { 10168 var classes, elem, cur, curValue, clazz, j, finalValue, 10169 i = 0; 10170 10171 if ( isFunction( value ) ) { 10172 return this.each( function( j ) { 10173 jQuery( this ).addClass( value.call( this, j, getClass( this ) ) ); 10174 } ); 10175 } 10176 10177 classes = classesToArray( value ); 10178 10179 if ( classes.length ) { 10180 while ( ( elem = this[ i++ ] ) ) { 10181 curValue = getClass( elem ); 10182 cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); 10183 10184 if ( cur ) { 10185 j = 0; 10186 while ( ( clazz = classes[ j++ ] ) ) { 10187 if ( cur.indexOf( " " + clazz + " " ) < 0 ) { 10188 cur += clazz + " "; 10189 } 10190 } 10191 10192 // Only assign if different to avoid unneeded rendering. 10193 finalValue = stripAndCollapse( cur ); 10194 if ( curValue !== finalValue ) { 10195 elem.setAttribute( "class", finalValue ); 10196 } 10197 } 10198 } 10199 } 10200 10201 return this; 10202 }, 10203 10204 removeClass: function( value ) { 10205 var classes, elem, cur, curValue, clazz, j, finalValue, 10206 i = 0; 10207 10208 if ( isFunction( value ) ) { 10209 return this.each( function( j ) { 10210 jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) ); 10211 } ); 10212 } 10213 10214 if ( !arguments.length ) { 10215 return this.attr( "class", "" ); 10216 } 10217 10218 classes = classesToArray( value ); 10219 10220 if ( classes.length ) { 10221 while ( ( elem = this[ i++ ] ) ) { 10222 curValue = getClass( elem ); 10223 10224 // This expression is here for better compressibility (see addClass) 10225 cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); 10226 10227 if ( cur ) { 10228 j = 0; 10229 while ( ( clazz = classes[ j++ ] ) ) { 10230 10231 // Remove *all* instances 10232 while ( cur.indexOf( " " + clazz + " " ) > -1 ) { 10233 cur = cur.replace( " " + clazz + " ", " " ); 10234 } 10235 } 10236 10237 // Only assign if different to avoid unneeded rendering. 10238 finalValue = stripAndCollapse( cur ); 10239 if ( curValue !== finalValue ) { 10240 elem.setAttribute( "class", finalValue ); 10241 } 10242 } 10243 } 10244 } 10245 10246 return this; 10247 }, 10248 10249 toggleClass: function( value, stateVal ) { 10250 var type = typeof value, 10251 isValidValue = type === "string" || Array.isArray( value ); 10252 10253 if ( typeof stateVal === "boolean" && isValidValue ) { 10254 return stateVal ? this.addClass( value ) : this.removeClass( value ); 10255 } 10256 10257 if ( isFunction( value ) ) { 10258 return this.each( function( i ) { 10259 jQuery( this ).toggleClass( 10260 value.call( this, i, getClass( this ), stateVal ), 10261 stateVal 10262 ); 10263 } ); 10264 } 10265 10266 return this.each( function() { 10267 var className, i, self, classNames; 10268 10269 if ( isValidValue ) { 10270 10271 // Toggle individual class names 10272 i = 0; 10273 self = jQuery( this ); 10274 classNames = classesToArray( value ); 10275 10276 while ( ( className = classNames[ i++ ] ) ) { 10277 10278 // Check each className given, space separated list 10279 if ( self.hasClass( className ) ) { 10280 self.removeClass( className ); 10281 } else { 10282 self.addClass( className ); 10283 } 10284 } 10285 10286 // Toggle whole class name 10287 } else if ( value === undefined || type === "boolean" ) { 10288 className = getClass( this ); 10289 if ( className ) { 10290 10291 // Store className if set 10292 dataPriv.set( this, "__className__", className ); 10293 } 10294 10295 // If the element has a class name or if we're passed `false`, 10296 // then remove the whole classname (if there was one, the above saved it). 10297 // Otherwise bring back whatever was previously saved (if anything), 10298 // falling back to the empty string if nothing was stored. 10299 if ( this.setAttribute ) { 10300 this.setAttribute( "class", 10301 className || value === false ? 10302 "" : 10303 dataPriv.get( this, "__className__" ) || "" 10304 ); 10305 } 10306 } 10307 } ); 10308 }, 10309 10310 hasClass: function( selector ) { 10311 var className, elem, 10312 i = 0; 10313 10314 className = " " + selector + " "; 10315 while ( ( elem = this[ i++ ] ) ) { 10316 if ( elem.nodeType === 1 && 10317 ( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) { 10318 return true; 10319 } 10320 } 10321 10322 return false; 10323 } 10324} ); 10325 10326 10327 10328 10329var rreturn = /\r/g; 10330 10331jQuery.fn.extend( { 10332 val: function( value ) { 10333 var hooks, ret, valueIsFunction, 10334 elem = this[ 0 ]; 10335 10336 if ( !arguments.length ) { 10337 if ( elem ) { 10338 hooks = jQuery.valHooks[ elem.type ] || 10339 jQuery.valHooks[ elem.nodeName.toLowerCase() ]; 10340 10341 if ( hooks && 10342 "get" in hooks && 10343 ( ret = hooks.get( elem, "value" ) ) !== undefined 10344 ) { 10345 return ret; 10346 } 10347 10348 ret = elem.value; 10349 10350 // Handle most common string cases 10351 if ( typeof ret === "string" ) { 10352 return ret.replace( rreturn, "" ); 10353 } 10354 10355 // Handle cases where value is null/undef or number 10356 return ret == null ? "" : ret; 10357 } 10358 10359 return; 10360 } 10361 10362 valueIsFunction = isFunction( value ); 10363 10364 return this.each( function( i ) { 10365 var val; 10366 10367 if ( this.nodeType !== 1 ) { 10368 return; 10369 } 10370 10371 if ( valueIsFunction ) { 10372 val = value.call( this, i, jQuery( this ).val() ); 10373 } else { 10374 val = value; 10375 } 10376 10377 // Treat null/undefined as ""; convert numbers to string 10378 if ( val == null ) { 10379 val = ""; 10380 10381 } else if ( typeof val === "number" ) { 10382 val += ""; 10383 10384 } else if ( Array.isArray( val ) ) { 10385 val = jQuery.map( val, function( value ) { 10386 return value == null ? "" : value + ""; 10387 } ); 10388 } 10389 10390 hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; 10391 10392 // If set returns undefined, fall back to normal setting 10393 if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) { 10394 this.value = val; 10395 } 10396 } ); 10397 } 10398} ); 10399 10400jQuery.extend( { 10401 valHooks: { 10402 option: { 10403 get: function( elem ) { 10404 10405 var val = jQuery.find.attr( elem, "value" ); 10406 return val != null ? 10407 val : 10408 10409 // Support: IE <=10 - 11 only 10410 // option.text throws exceptions (#14686, #14858) 10411 // Strip and collapse whitespace 10412 // https://html.spec.whatwg.org/#strip-and-collapse-whitespace 10413 stripAndCollapse( jQuery.text( elem ) ); 10414 } 10415 }, 10416 select: { 10417 get: function( elem ) { 10418 var value, option, i, 10419 options = elem.options, 10420 index = elem.selectedIndex, 10421 one = elem.type === "select-one", 10422 values = one ? null : [], 10423 max = one ? index + 1 : options.length; 10424 10425 if ( index < 0 ) { 10426 i = max; 10427 10428 } else { 10429 i = one ? index : 0; 10430 } 10431 10432 // Loop through all the selected options 10433 for ( ; i < max; i++ ) { 10434 option = options[ i ]; 10435 10436 // Support: IE <=9 only 10437 // IE8-9 doesn't update selected after form reset (#2551) 10438 if ( ( option.selected || i === index ) && 10439 10440 // Don't return options that are disabled or in a disabled optgroup 10441 !option.disabled && 10442 ( !option.parentNode.disabled || 10443 !nodeName( option.parentNode, "optgroup" ) ) ) { 10444 10445 // Get the specific value for the option 10446 value = jQuery( option ).val(); 10447 10448 // We don't need an array for one selects 10449 if ( one ) { 10450 return value; 10451 } 10452 10453 // Multi-Selects return an array 10454 values.push( value ); 10455 } 10456 } 10457 10458 return values; 10459 }, 10460 10461 set: function( elem, value ) { 10462 var optionSet, option, 10463 options = elem.options, 10464 values = jQuery.makeArray( value ), 10465 i = options.length; 10466 10467 while ( i-- ) { 10468 option = options[ i ]; 10469 10470 /* eslint-disable no-cond-assign */ 10471 10472 if ( option.selected = 10473 jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1 10474 ) { 10475 optionSet = true; 10476 } 10477 10478 /* eslint-enable no-cond-assign */ 10479 } 10480 10481 // Force browsers to behave consistently when non-matching value is set 10482 if ( !optionSet ) { 10483 elem.selectedIndex = -1; 10484 } 10485 return values; 10486 } 10487 } 10488 } 10489} ); 10490 10491// Radios and checkboxes getter/setter 10492jQuery.each( [ "radio", "checkbox" ], function() { 10493 jQuery.valHooks[ this ] = { 10494 set: function( elem, value ) { 10495 if ( Array.isArray( value ) ) { 10496 return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 ); 10497 } 10498 } 10499 }; 10500 if ( !support.checkOn ) { 10501 jQuery.valHooks[ this ].get = function( elem ) { 10502 return elem.getAttribute( "value" ) === null ? "on" : elem.value; 10503 }; 10504 } 10505} ); 10506 10507 10508 10509 10510// Return jQuery for attributes-only inclusion 10511 10512 10513support.focusin = "onfocusin" in window; 10514 10515 10516var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, 10517 stopPropagationCallback = function( e ) { 10518 e.stopPropagation(); 10519 }; 10520 10521jQuery.extend( jQuery.event, { 10522 10523 trigger: function( event, data, elem, onlyHandlers ) { 10524 10525 var i, cur, tmp, bubbleType, ontype, handle, special, lastElement, 10526 eventPath = [ elem || document ], 10527 type = hasOwn.call( event, "type" ) ? event.type : event, 10528 namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : []; 10529 10530 cur = lastElement = tmp = elem = elem || document; 10531 10532 // Don't do events on text and comment nodes 10533 if ( elem.nodeType === 3 || elem.nodeType === 8 ) { 10534 return; 10535 } 10536 10537 // focus/blur morphs to focusin/out; ensure we're not firing them right now 10538 if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { 10539 return; 10540 } 10541 10542 if ( type.indexOf( "." ) > -1 ) { 10543 10544 // Namespaced trigger; create a regexp to match event type in handle() 10545 namespaces = type.split( "." ); 10546 type = namespaces.shift(); 10547 namespaces.sort(); 10548 } 10549 ontype = type.indexOf( ":" ) < 0 && "on" + type; 10550 10551 // Caller can pass in a jQuery.Event object, Object, or just an event type string 10552 event = event[ jQuery.expando ] ? 10553 event : 10554 new jQuery.Event( type, typeof event === "object" && event ); 10555 10556 // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) 10557 event.isTrigger = onlyHandlers ? 2 : 3; 10558 event.namespace = namespaces.join( "." ); 10559 event.rnamespace = event.namespace ? 10560 new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) : 10561 null; 10562 10563 // Clean up the event in case it is being reused 10564 event.result = undefined; 10565 if ( !event.target ) { 10566 event.target = elem; 10567 } 10568 10569 // Clone any incoming data and prepend the event, creating the handler arg list 10570 data = data == null ? 10571 [ event ] : 10572 jQuery.makeArray( data, [ event ] ); 10573 10574 // Allow special events to draw outside the lines 10575 special = jQuery.event.special[ type ] || {}; 10576 if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { 10577 return; 10578 } 10579 10580 // Determine event propagation path in advance, per W3C events spec (#9951) 10581 // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) 10582 if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) { 10583 10584 bubbleType = special.delegateType || type; 10585 if ( !rfocusMorph.test( bubbleType + type ) ) { 10586 cur = cur.parentNode; 10587 } 10588 for ( ; cur; cur = cur.parentNode ) { 10589 eventPath.push( cur ); 10590 tmp = cur; 10591 } 10592 10593 // Only add window if we got to document (e.g., not plain obj or detached DOM) 10594 if ( tmp === ( elem.ownerDocument || document ) ) { 10595 eventPath.push( tmp.defaultView || tmp.parentWindow || window ); 10596 } 10597 } 10598 10599 // Fire handlers on the event path 10600 i = 0; 10601 while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) { 10602 lastElement = cur; 10603 event.type = i > 1 ? 10604 bubbleType : 10605 special.bindType || type; 10606 10607 // jQuery handler 10608 handle = ( dataPriv.get( cur, "events" ) || Object.create( null ) )[ event.type ] && 10609 dataPriv.get( cur, "handle" ); 10610 if ( handle ) { 10611 handle.apply( cur, data ); 10612 } 10613 10614 // Native handler 10615 handle = ontype && cur[ ontype ]; 10616 if ( handle && handle.apply && acceptData( cur ) ) { 10617 event.result = handle.apply( cur, data ); 10618 if ( event.result === false ) { 10619 event.preventDefault(); 10620 } 10621 } 10622 } 10623 event.type = type; 10624 10625 // If nobody prevented the default action, do it now 10626 if ( !onlyHandlers && !event.isDefaultPrevented() ) { 10627 10628 if ( ( !special._default || 10629 special._default.apply( eventPath.pop(), data ) === false ) && 10630 acceptData( elem ) ) { 10631 10632 // Call a native DOM method on the target with the same name as the event. 10633 // Don't do default actions on window, that's where global variables be (#6170) 10634 if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) { 10635 10636 // Don't re-trigger an onFOO event when we call its FOO() method 10637 tmp = elem[ ontype ]; 10638 10639 if ( tmp ) { 10640 elem[ ontype ] = null; 10641 } 10642 10643 // Prevent re-triggering of the same event, since we already bubbled it above 10644 jQuery.event.triggered = type; 10645 10646 if ( event.isPropagationStopped() ) { 10647 lastElement.addEventListener( type, stopPropagationCallback ); 10648 } 10649 10650 elem[ type ](); 10651 10652 if ( event.isPropagationStopped() ) { 10653 lastElement.removeEventListener( type, stopPropagationCallback ); 10654 } 10655 10656 jQuery.event.triggered = undefined; 10657 10658 if ( tmp ) { 10659 elem[ ontype ] = tmp; 10660 } 10661 } 10662 } 10663 } 10664 10665 return event.result; 10666 }, 10667 10668 // Piggyback on a donor event to simulate a different one 10669 // Used only for `focus(in | out)` events 10670 simulate: function( type, elem, event ) { 10671 var e = jQuery.extend( 10672 new jQuery.Event(), 10673 event, 10674 { 10675 type: type, 10676 isSimulated: true 10677 } 10678 ); 10679 10680 jQuery.event.trigger( e, null, elem ); 10681 } 10682 10683} ); 10684 10685jQuery.fn.extend( { 10686 10687 trigger: function( type, data ) { 10688 return this.each( function() { 10689 jQuery.event.trigger( type, data, this ); 10690 } ); 10691 }, 10692 triggerHandler: function( type, data ) { 10693 var elem = this[ 0 ]; 10694 if ( elem ) { 10695 return jQuery.event.trigger( type, data, elem, true ); 10696 } 10697 } 10698} ); 10699 10700 10701// Support: Firefox <=44 10702// Firefox doesn't have focus(in | out) events 10703// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 10704// 10705// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1 10706// focus(in | out) events fire after focus & blur events, 10707// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order 10708// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857 10709if ( !support.focusin ) { 10710 jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) { 10711 10712 // Attach a single capturing handler on the document while someone wants focusin/focusout 10713 var handler = function( event ) { 10714 jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) ); 10715 }; 10716 10717 jQuery.event.special[ fix ] = { 10718 setup: function() { 10719 10720 // Handle: regular nodes (via `this.ownerDocument`), window 10721 // (via `this.document`) & document (via `this`). 10722 var doc = this.ownerDocument || this.document || this, 10723 attaches = dataPriv.access( doc, fix ); 10724 10725 if ( !attaches ) { 10726 doc.addEventListener( orig, handler, true ); 10727 } 10728 dataPriv.access( doc, fix, ( attaches || 0 ) + 1 ); 10729 }, 10730 teardown: function() { 10731 var doc = this.ownerDocument || this.document || this, 10732 attaches = dataPriv.access( doc, fix ) - 1; 10733 10734 if ( !attaches ) { 10735 doc.removeEventListener( orig, handler, true ); 10736 dataPriv.remove( doc, fix ); 10737 10738 } else { 10739 dataPriv.access( doc, fix, attaches ); 10740 } 10741 } 10742 }; 10743 } ); 10744} 10745var location = window.location; 10746 10747var nonce = { guid: Date.now() }; 10748 10749var rquery = ( /\?/ ); 10750 10751 10752 10753// Cross-browser xml parsing 10754jQuery.parseXML = function( data ) { 10755 var xml, parserErrorElem; 10756 if ( !data || typeof data !== "string" ) { 10757 return null; 10758 } 10759 10760 // Support: IE 9 - 11 only 10761 // IE throws on parseFromString with invalid input. 10762 try { 10763 xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" ); 10764 } catch ( e ) {} 10765 10766 parserErrorElem = xml && xml.getElementsByTagName( "parsererror" )[ 0 ]; 10767 if ( !xml || parserErrorElem ) { 10768 jQuery.error( "Invalid XML: " + ( 10769 parserErrorElem ? 10770 jQuery.map( parserErrorElem.childNodes, function( el ) { 10771 return el.textContent; 10772 } ).join( "\n" ) : 10773 data 10774 ) ); 10775 } 10776 return xml; 10777}; 10778 10779 10780var 10781 rbracket = /\[\]$/, 10782 rCRLF = /\r?\n/g, 10783 rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, 10784 rsubmittable = /^(?:input|select|textarea|keygen)/i; 10785 10786function buildParams( prefix, obj, traditional, add ) { 10787 var name; 10788 10789 if ( Array.isArray( obj ) ) { 10790 10791 // Serialize array item. 10792 jQuery.each( obj, function( i, v ) { 10793 if ( traditional || rbracket.test( prefix ) ) { 10794 10795 // Treat each array item as a scalar. 10796 add( prefix, v ); 10797 10798 } else { 10799 10800 // Item is non-scalar (array or object), encode its numeric index. 10801 buildParams( 10802 prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]", 10803 v, 10804 traditional, 10805 add 10806 ); 10807 } 10808 } ); 10809 10810 } else if ( !traditional && toType( obj ) === "object" ) { 10811 10812 // Serialize object item. 10813 for ( name in obj ) { 10814 buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); 10815 } 10816 10817 } else { 10818 10819 // Serialize scalar item. 10820 add( prefix, obj ); 10821 } 10822} 10823 10824// Serialize an array of form elements or a set of 10825// key/values into a query string 10826jQuery.param = function( a, traditional ) { 10827 var prefix, 10828 s = [], 10829 add = function( key, valueOrFunction ) { 10830 10831 // If value is a function, invoke it and use its return value 10832 var value = isFunction( valueOrFunction ) ? 10833 valueOrFunction() : 10834 valueOrFunction; 10835 10836 s[ s.length ] = encodeURIComponent( key ) + "=" + 10837 encodeURIComponent( value == null ? "" : value ); 10838 }; 10839 10840 if ( a == null ) { 10841 return ""; 10842 } 10843 10844 // If an array was passed in, assume that it is an array of form elements. 10845 if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { 10846 10847 // Serialize the form elements 10848 jQuery.each( a, function() { 10849 add( this.name, this.value ); 10850 } ); 10851 10852 } else { 10853 10854 // If traditional, encode the "old" way (the way 1.3.2 or older 10855 // did it), otherwise encode params recursively. 10856 for ( prefix in a ) { 10857 buildParams( prefix, a[ prefix ], traditional, add ); 10858 } 10859 } 10860 10861 // Return the resulting serialization 10862 return s.join( "&" ); 10863}; 10864 10865jQuery.fn.extend( { 10866 serialize: function() { 10867 return jQuery.param( this.serializeArray() ); 10868 }, 10869 serializeArray: function() { 10870 return this.map( function() { 10871 10872 // Can add propHook for "elements" to filter or add form elements 10873 var elements = jQuery.prop( this, "elements" ); 10874 return elements ? jQuery.makeArray( elements ) : this; 10875 } ).filter( function() { 10876 var type = this.type; 10877 10878 // Use .is( ":disabled" ) so that fieldset[disabled] works 10879 return this.name && !jQuery( this ).is( ":disabled" ) && 10880 rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && 10881 ( this.checked || !rcheckableType.test( type ) ); 10882 } ).map( function( _i, elem ) { 10883 var val = jQuery( this ).val(); 10884 10885 if ( val == null ) { 10886 return null; 10887 } 10888 10889 if ( Array.isArray( val ) ) { 10890 return jQuery.map( val, function( val ) { 10891 return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; 10892 } ); 10893 } 10894 10895 return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; 10896 } ).get(); 10897 } 10898} ); 10899 10900 10901var 10902 r20 = /%20/g, 10903 rhash = /#.*$/, 10904 rantiCache = /([?&])_=[^&]*/, 10905 rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, 10906 10907 // #7653, #8125, #8152: local protocol detection 10908 rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, 10909 rnoContent = /^(?:GET|HEAD)$/, 10910 rprotocol = /^\/\//, 10911 10912 /* Prefilters 10913 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) 10914 * 2) These are called: 10915 * - BEFORE asking for a transport 10916 * - AFTER param serialization (s.data is a string if s.processData is true) 10917 * 3) key is the dataType 10918 * 4) the catchall symbol "*" can be used 10919 * 5) execution will start with transport dataType and THEN continue down to "*" if needed 10920 */ 10921 prefilters = {}, 10922 10923 /* Transports bindings 10924 * 1) key is the dataType 10925 * 2) the catchall symbol "*" can be used 10926 * 3) selection will start with transport dataType and THEN go to "*" if needed 10927 */ 10928 transports = {}, 10929 10930 // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression 10931 allTypes = "*/".concat( "*" ), 10932 10933 // Anchor tag for parsing the document origin 10934 originAnchor = document.createElement( "a" ); 10935 10936originAnchor.href = location.href; 10937 10938// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport 10939function addToPrefiltersOrTransports( structure ) { 10940 10941 // dataTypeExpression is optional and defaults to "*" 10942 return function( dataTypeExpression, func ) { 10943 10944 if ( typeof dataTypeExpression !== "string" ) { 10945 func = dataTypeExpression; 10946 dataTypeExpression = "*"; 10947 } 10948 10949 var dataType, 10950 i = 0, 10951 dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || []; 10952 10953 if ( isFunction( func ) ) { 10954 10955 // For each dataType in the dataTypeExpression 10956 while ( ( dataType = dataTypes[ i++ ] ) ) { 10957 10958 // Prepend if requested 10959 if ( dataType[ 0 ] === "+" ) { 10960 dataType = dataType.slice( 1 ) || "*"; 10961 ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func ); 10962 10963 // Otherwise append 10964 } else { 10965 ( structure[ dataType ] = structure[ dataType ] || [] ).push( func ); 10966 } 10967 } 10968 } 10969 }; 10970} 10971 10972// Base inspection function for prefilters and transports 10973function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) { 10974 10975 var inspected = {}, 10976 seekingTransport = ( structure === transports ); 10977 10978 function inspect( dataType ) { 10979 var selected; 10980 inspected[ dataType ] = true; 10981 jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) { 10982 var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR ); 10983 if ( typeof dataTypeOrTransport === "string" && 10984 !seekingTransport && !inspected[ dataTypeOrTransport ] ) { 10985 10986 options.dataTypes.unshift( dataTypeOrTransport ); 10987 inspect( dataTypeOrTransport ); 10988 return false; 10989 } else if ( seekingTransport ) { 10990 return !( selected = dataTypeOrTransport ); 10991 } 10992 } ); 10993 return selected; 10994 } 10995 10996 return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" ); 10997} 10998 10999// A special extend for ajax options 11000// that takes "flat" options (not to be deep extended) 11001// Fixes #9887 11002function ajaxExtend( target, src ) { 11003 var key, deep, 11004 flatOptions = jQuery.ajaxSettings.flatOptions || {}; 11005 11006 for ( key in src ) { 11007 if ( src[ key ] !== undefined ) { 11008 ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; 11009 } 11010 } 11011 if ( deep ) { 11012 jQuery.extend( true, target, deep ); 11013 } 11014 11015 return target; 11016} 11017 11018/* Handles responses to an ajax request: 11019 * - finds the right dataType (mediates between content-type and expected dataType) 11020 * - returns the corresponding response 11021 */ 11022function ajaxHandleResponses( s, jqXHR, responses ) { 11023 11024 var ct, type, finalDataType, firstDataType, 11025 contents = s.contents, 11026 dataTypes = s.dataTypes; 11027 11028 // Remove auto dataType and get content-type in the process 11029 while ( dataTypes[ 0 ] === "*" ) { 11030 dataTypes.shift(); 11031 if ( ct === undefined ) { 11032 ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" ); 11033 } 11034 } 11035 11036 // Check if we're dealing with a known content-type 11037 if ( ct ) { 11038 for ( type in contents ) { 11039 if ( contents[ type ] && contents[ type ].test( ct ) ) { 11040 dataTypes.unshift( type ); 11041 break; 11042 } 11043 } 11044 } 11045 11046 // Check to see if we have a response for the expected dataType 11047 if ( dataTypes[ 0 ] in responses ) { 11048 finalDataType = dataTypes[ 0 ]; 11049 } else { 11050 11051 // Try convertible dataTypes 11052 for ( type in responses ) { 11053 if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) { 11054 finalDataType = type; 11055 break; 11056 } 11057 if ( !firstDataType ) { 11058 firstDataType = type; 11059 } 11060 } 11061 11062 // Or just use first one 11063 finalDataType = finalDataType || firstDataType; 11064 } 11065 11066 // If we found a dataType 11067 // We add the dataType to the list if needed 11068 // and return the corresponding response 11069 if ( finalDataType ) { 11070 if ( finalDataType !== dataTypes[ 0 ] ) { 11071 dataTypes.unshift( finalDataType ); 11072 } 11073 return responses[ finalDataType ]; 11074 } 11075} 11076 11077/* Chain conversions given the request and the original response 11078 * Also sets the responseXXX fields on the jqXHR instance 11079 */ 11080function ajaxConvert( s, response, jqXHR, isSuccess ) { 11081 var conv2, current, conv, tmp, prev, 11082 converters = {}, 11083 11084 // Work with a copy of dataTypes in case we need to modify it for conversion 11085 dataTypes = s.dataTypes.slice(); 11086 11087 // Create converters map with lowercased keys 11088 if ( dataTypes[ 1 ] ) { 11089 for ( conv in s.converters ) { 11090 converters[ conv.toLowerCase() ] = s.converters[ conv ]; 11091 } 11092 } 11093 11094 current = dataTypes.shift(); 11095 11096 // Convert to each sequential dataType 11097 while ( current ) { 11098 11099 if ( s.responseFields[ current ] ) { 11100 jqXHR[ s.responseFields[ current ] ] = response; 11101 } 11102 11103 // Apply the dataFilter if provided 11104 if ( !prev && isSuccess && s.dataFilter ) { 11105 response = s.dataFilter( response, s.dataType ); 11106 } 11107 11108 prev = current; 11109 current = dataTypes.shift(); 11110 11111 if ( current ) { 11112 11113 // There's only work to do if current dataType is non-auto 11114 if ( current === "*" ) { 11115 11116 current = prev; 11117 11118 // Convert response if prev dataType is non-auto and differs from current 11119 } else if ( prev !== "*" && prev !== current ) { 11120 11121 // Seek a direct converter 11122 conv = converters[ prev + " " + current ] || converters[ "* " + current ]; 11123 11124 // If none found, seek a pair 11125 if ( !conv ) { 11126 for ( conv2 in converters ) { 11127 11128 // If conv2 outputs current 11129 tmp = conv2.split( " " ); 11130 if ( tmp[ 1 ] === current ) { 11131 11132 // If prev can be converted to accepted input 11133 conv = converters[ prev + " " + tmp[ 0 ] ] || 11134 converters[ "* " + tmp[ 0 ] ]; 11135 if ( conv ) { 11136 11137 // Condense equivalence converters 11138 if ( conv === true ) { 11139 conv = converters[ conv2 ]; 11140 11141 // Otherwise, insert the intermediate dataType 11142 } else if ( converters[ conv2 ] !== true ) { 11143 current = tmp[ 0 ]; 11144 dataTypes.unshift( tmp[ 1 ] ); 11145 } 11146 break; 11147 } 11148 } 11149 } 11150 } 11151 11152 // Apply converter (if not an equivalence) 11153 if ( conv !== true ) { 11154 11155 // Unless errors are allowed to bubble, catch and return them 11156 if ( conv && s.throws ) { 11157 response = conv( response ); 11158 } else { 11159 try { 11160 response = conv( response ); 11161 } catch ( e ) { 11162 return { 11163 state: "parsererror", 11164 error: conv ? e : "No conversion from " + prev + " to " + current 11165 }; 11166 } 11167 } 11168 } 11169 } 11170 } 11171 } 11172 11173 return { state: "success", data: response }; 11174} 11175 11176jQuery.extend( { 11177 11178 // Counter for holding the number of active queries 11179 active: 0, 11180 11181 // Last-Modified header cache for next request 11182 lastModified: {}, 11183 etag: {}, 11184 11185 ajaxSettings: { 11186 url: location.href, 11187 type: "GET", 11188 isLocal: rlocalProtocol.test( location.protocol ), 11189 global: true, 11190 processData: true, 11191 async: true, 11192 contentType: "application/x-www-form-urlencoded; charset=UTF-8", 11193 11194 /* 11195 timeout: 0, 11196 data: null, 11197 dataType: null, 11198 username: null, 11199 password: null, 11200 cache: null, 11201 throws: false, 11202 traditional: false, 11203 headers: {}, 11204 */ 11205 11206 accepts: { 11207 "*": allTypes, 11208 text: "text/plain", 11209 html: "text/html", 11210 xml: "application/xml, text/xml", 11211 json: "application/json, text/javascript" 11212 }, 11213 11214 contents: { 11215 xml: /\bxml\b/, 11216 html: /\bhtml/, 11217 json: /\bjson\b/ 11218 }, 11219 11220 responseFields: { 11221 xml: "responseXML", 11222 text: "responseText", 11223 json: "responseJSON" 11224 }, 11225 11226 // Data converters 11227 // Keys separate source (or catchall "*") and destination types with a single space 11228 converters: { 11229 11230 // Convert anything to text 11231 "* text": String, 11232 11233 // Text to html (true = no transformation) 11234 "text html": true, 11235 11236 // Evaluate text as a json expression 11237 "text json": JSON.parse, 11238 11239 // Parse text as xml 11240 "text xml": jQuery.parseXML 11241 }, 11242 11243 // For options that shouldn't be deep extended: 11244 // you can add your own custom options here if 11245 // and when you create one that shouldn't be 11246 // deep extended (see ajaxExtend) 11247 flatOptions: { 11248 url: true, 11249 context: true 11250 } 11251 }, 11252 11253 // Creates a full fledged settings object into target 11254 // with both ajaxSettings and settings fields. 11255 // If target is omitted, writes into ajaxSettings. 11256 ajaxSetup: function( target, settings ) { 11257 return settings ? 11258 11259 // Building a settings object 11260 ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) : 11261 11262 // Extending ajaxSettings 11263 ajaxExtend( jQuery.ajaxSettings, target ); 11264 }, 11265 11266 ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), 11267 ajaxTransport: addToPrefiltersOrTransports( transports ), 11268 11269 // Main method 11270 ajax: function( url, options ) { 11271 11272 // If url is an object, simulate pre-1.5 signature 11273 if ( typeof url === "object" ) { 11274 options = url; 11275 url = undefined; 11276 } 11277 11278 // Force options to be an object 11279 options = options || {}; 11280 11281 var transport, 11282 11283 // URL without anti-cache param 11284 cacheURL, 11285 11286 // Response headers 11287 responseHeadersString, 11288 responseHeaders, 11289 11290 // timeout handle 11291 timeoutTimer, 11292 11293 // Url cleanup var 11294 urlAnchor, 11295 11296 // Request state (becomes false upon send and true upon completion) 11297 completed, 11298 11299 // To know if global events are to be dispatched 11300 fireGlobals, 11301 11302 // Loop variable 11303 i, 11304 11305 // uncached part of the url 11306 uncached, 11307 11308 // Create the final options object 11309 s = jQuery.ajaxSetup( {}, options ), 11310 11311 // Callbacks context 11312 callbackContext = s.context || s, 11313 11314 // Context for global events is callbackContext if it is a DOM node or jQuery collection 11315 globalEventContext = s.context && 11316 ( callbackContext.nodeType || callbackContext.jquery ) ? 11317 jQuery( callbackContext ) : 11318 jQuery.event, 11319 11320 // Deferreds 11321 deferred = jQuery.Deferred(), 11322 completeDeferred = jQuery.Callbacks( "once memory" ), 11323 11324 // Status-dependent callbacks 11325 statusCode = s.statusCode || {}, 11326 11327 // Headers (they are sent all at once) 11328 requestHeaders = {}, 11329 requestHeadersNames = {}, 11330 11331 // Default abort message 11332 strAbort = "canceled", 11333 11334 // Fake xhr 11335 jqXHR = { 11336 readyState: 0, 11337 11338 // Builds headers hashtable if needed 11339 getResponseHeader: function( key ) { 11340 var match; 11341 if ( completed ) { 11342 if ( !responseHeaders ) { 11343 responseHeaders = {}; 11344 while ( ( match = rheaders.exec( responseHeadersString ) ) ) { 11345 responseHeaders[ match[ 1 ].toLowerCase() + " " ] = 11346 ( responseHeaders[ match[ 1 ].toLowerCase() + " " ] || [] ) 11347 .concat( match[ 2 ] ); 11348 } 11349 } 11350 match = responseHeaders[ key.toLowerCase() + " " ]; 11351 } 11352 return match == null ? null : match.join( ", " ); 11353 }, 11354 11355 // Raw string 11356 getAllResponseHeaders: function() { 11357 return completed ? responseHeadersString : null; 11358 }, 11359 11360 // Caches the header 11361 setRequestHeader: function( name, value ) { 11362 if ( completed == null ) { 11363 name = requestHeadersNames[ name.toLowerCase() ] = 11364 requestHeadersNames[ name.toLowerCase() ] || name; 11365 requestHeaders[ name ] = value; 11366 } 11367 return this; 11368 }, 11369 11370 // Overrides response content-type header 11371 overrideMimeType: function( type ) { 11372 if ( completed == null ) { 11373 s.mimeType = type; 11374 } 11375 return this; 11376 }, 11377 11378 // Status-dependent callbacks 11379 statusCode: function( map ) { 11380 var code; 11381 if ( map ) { 11382 if ( completed ) { 11383 11384 // Execute the appropriate callbacks 11385 jqXHR.always( map[ jqXHR.status ] ); 11386 } else { 11387 11388 // Lazy-add the new callbacks in a way that preserves old ones 11389 for ( code in map ) { 11390 statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; 11391 } 11392 } 11393 } 11394 return this; 11395 }, 11396 11397 // Cancel the request 11398 abort: function( statusText ) { 11399 var finalText = statusText || strAbort; 11400 if ( transport ) { 11401 transport.abort( finalText ); 11402 } 11403 done( 0, finalText ); 11404 return this; 11405 } 11406 }; 11407 11408 // Attach deferreds 11409 deferred.promise( jqXHR ); 11410 11411 // Add protocol if not provided (prefilters might expect it) 11412 // Handle falsy url in the settings object (#10093: consistency with old signature) 11413 // We also use the url parameter if available 11414 s.url = ( ( url || s.url || location.href ) + "" ) 11415 .replace( rprotocol, location.protocol + "//" ); 11416 11417 // Alias method option to type as per ticket #12004 11418 s.type = options.method || options.type || s.method || s.type; 11419 11420 // Extract dataTypes list 11421 s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ]; 11422 11423 // A cross-domain request is in order when the origin doesn't match the current origin. 11424 if ( s.crossDomain == null ) { 11425 urlAnchor = document.createElement( "a" ); 11426 11427 // Support: IE <=8 - 11, Edge 12 - 15 11428 // IE throws exception on accessing the href property if url is malformed, 11429 // e.g. http://example.com:80x/ 11430 try { 11431 urlAnchor.href = s.url; 11432 11433 // Support: IE <=8 - 11 only 11434 // Anchor's host property isn't correctly set when s.url is relative 11435 urlAnchor.href = urlAnchor.href; 11436 s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !== 11437 urlAnchor.protocol + "//" + urlAnchor.host; 11438 } catch ( e ) { 11439 11440 // If there is an error parsing the URL, assume it is crossDomain, 11441 // it can be rejected by the transport if it is invalid 11442 s.crossDomain = true; 11443 } 11444 } 11445 11446 // Convert data if not already a string 11447 if ( s.data && s.processData && typeof s.data !== "string" ) { 11448 s.data = jQuery.param( s.data, s.traditional ); 11449 } 11450 11451 // Apply prefilters 11452 inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); 11453 11454 // If request was aborted inside a prefilter, stop there 11455 if ( completed ) { 11456 return jqXHR; 11457 } 11458 11459 // We can fire global events as of now if asked to 11460 // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118) 11461 fireGlobals = jQuery.event && s.global; 11462 11463 // Watch for a new set of requests 11464 if ( fireGlobals && jQuery.active++ === 0 ) { 11465 jQuery.event.trigger( "ajaxStart" ); 11466 } 11467 11468 // Uppercase the type 11469 s.type = s.type.toUpperCase(); 11470 11471 // Determine if request has content 11472 s.hasContent = !rnoContent.test( s.type ); 11473 11474 // Save the URL in case we're toying with the If-Modified-Since 11475 // and/or If-None-Match header later on 11476 // Remove hash to simplify url manipulation 11477 cacheURL = s.url.replace( rhash, "" ); 11478 11479 // More options handling for requests with no content 11480 if ( !s.hasContent ) { 11481 11482 // Remember the hash so we can put it back 11483 uncached = s.url.slice( cacheURL.length ); 11484 11485 // If data is available and should be processed, append data to url 11486 if ( s.data && ( s.processData || typeof s.data === "string" ) ) { 11487 cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data; 11488 11489 // #9682: remove data so that it's not used in an eventual retry 11490 delete s.data; 11491 } 11492 11493 // Add or update anti-cache param if needed 11494 if ( s.cache === false ) { 11495 cacheURL = cacheURL.replace( rantiCache, "$1" ); 11496 uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce.guid++ ) + 11497 uncached; 11498 } 11499 11500 // Put hash and anti-cache on the URL that will be requested (gh-1732) 11501 s.url = cacheURL + uncached; 11502 11503 // Change '%20' to '+' if this is encoded form body content (gh-2658) 11504 } else if ( s.data && s.processData && 11505 ( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) { 11506 s.data = s.data.replace( r20, "+" ); 11507 } 11508 11509 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. 11510 if ( s.ifModified ) { 11511 if ( jQuery.lastModified[ cacheURL ] ) { 11512 jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); 11513 } 11514 if ( jQuery.etag[ cacheURL ] ) { 11515 jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); 11516 } 11517 } 11518 11519 // Set the correct header, if data is being sent 11520 if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { 11521 jqXHR.setRequestHeader( "Content-Type", s.contentType ); 11522 } 11523 11524 // Set the Accepts header for the server, depending on the dataType 11525 jqXHR.setRequestHeader( 11526 "Accept", 11527 s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ? 11528 s.accepts[ s.dataTypes[ 0 ] ] + 11529 ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : 11530 s.accepts[ "*" ] 11531 ); 11532 11533 // Check for headers option 11534 for ( i in s.headers ) { 11535 jqXHR.setRequestHeader( i, s.headers[ i ] ); 11536 } 11537 11538 // Allow custom headers/mimetypes and early abort 11539 if ( s.beforeSend && 11540 ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) { 11541 11542 // Abort if not done already and return 11543 return jqXHR.abort(); 11544 } 11545 11546 // Aborting is no longer a cancellation 11547 strAbort = "abort"; 11548 11549 // Install callbacks on deferreds 11550 completeDeferred.add( s.complete ); 11551 jqXHR.done( s.success ); 11552 jqXHR.fail( s.error ); 11553 11554 // Get transport 11555 transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); 11556 11557 // If no transport, we auto-abort 11558 if ( !transport ) { 11559 done( -1, "No Transport" ); 11560 } else { 11561 jqXHR.readyState = 1; 11562 11563 // Send global event 11564 if ( fireGlobals ) { 11565 globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); 11566 } 11567 11568 // If request was aborted inside ajaxSend, stop there 11569 if ( completed ) { 11570 return jqXHR; 11571 } 11572 11573 // Timeout 11574 if ( s.async && s.timeout > 0 ) { 11575 timeoutTimer = window.setTimeout( function() { 11576 jqXHR.abort( "timeout" ); 11577 }, s.timeout ); 11578 } 11579 11580 try { 11581 completed = false; 11582 transport.send( requestHeaders, done ); 11583 } catch ( e ) { 11584 11585 // Rethrow post-completion exceptions 11586 if ( completed ) { 11587 throw e; 11588 } 11589 11590 // Propagate others as results 11591 done( -1, e ); 11592 } 11593 } 11594 11595 // Callback for when everything is done 11596 function done( status, nativeStatusText, responses, headers ) { 11597 var isSuccess, success, error, response, modified, 11598 statusText = nativeStatusText; 11599 11600 // Ignore repeat invocations 11601 if ( completed ) { 11602 return; 11603 } 11604 11605 completed = true; 11606 11607 // Clear timeout if it exists 11608 if ( timeoutTimer ) { 11609 window.clearTimeout( timeoutTimer ); 11610 } 11611 11612 // Dereference transport for early garbage collection 11613 // (no matter how long the jqXHR object will be used) 11614 transport = undefined; 11615 11616 // Cache response headers 11617 responseHeadersString = headers || ""; 11618 11619 // Set readyState 11620 jqXHR.readyState = status > 0 ? 4 : 0; 11621 11622 // Determine if successful 11623 isSuccess = status >= 200 && status < 300 || status === 304; 11624 11625 // Get response data 11626 if ( responses ) { 11627 response = ajaxHandleResponses( s, jqXHR, responses ); 11628 } 11629 11630 // Use a noop converter for missing script but not if jsonp 11631 if ( !isSuccess && 11632 jQuery.inArray( "script", s.dataTypes ) > -1 && 11633 jQuery.inArray( "json", s.dataTypes ) < 0 ) { 11634 s.converters[ "text script" ] = function() {}; 11635 } 11636 11637 // Convert no matter what (that way responseXXX fields are always set) 11638 response = ajaxConvert( s, response, jqXHR, isSuccess ); 11639 11640 // If successful, handle type chaining 11641 if ( isSuccess ) { 11642 11643 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. 11644 if ( s.ifModified ) { 11645 modified = jqXHR.getResponseHeader( "Last-Modified" ); 11646 if ( modified ) { 11647 jQuery.lastModified[ cacheURL ] = modified; 11648 } 11649 modified = jqXHR.getResponseHeader( "etag" ); 11650 if ( modified ) { 11651 jQuery.etag[ cacheURL ] = modified; 11652 } 11653 } 11654 11655 // if no content 11656 if ( status === 204 || s.type === "HEAD" ) { 11657 statusText = "nocontent"; 11658 11659 // if not modified 11660 } else if ( status === 304 ) { 11661 statusText = "notmodified"; 11662 11663 // If we have data, let's convert it 11664 } else { 11665 statusText = response.state; 11666 success = response.data; 11667 error = response.error; 11668 isSuccess = !error; 11669 } 11670 } else { 11671 11672 // Extract error from statusText and normalize for non-aborts 11673 error = statusText; 11674 if ( status || !statusText ) { 11675 statusText = "error"; 11676 if ( status < 0 ) { 11677 status = 0; 11678 } 11679 } 11680 } 11681 11682 // Set data for the fake xhr object 11683 jqXHR.status = status; 11684 jqXHR.statusText = ( nativeStatusText || statusText ) + ""; 11685 11686 // Success/Error 11687 if ( isSuccess ) { 11688 deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); 11689 } else { 11690 deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); 11691 } 11692 11693 // Status-dependent callbacks 11694 jqXHR.statusCode( statusCode ); 11695 statusCode = undefined; 11696 11697 if ( fireGlobals ) { 11698 globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", 11699 [ jqXHR, s, isSuccess ? success : error ] ); 11700 } 11701 11702 // Complete 11703 completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); 11704 11705 if ( fireGlobals ) { 11706 globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); 11707 11708 // Handle the global AJAX counter 11709 if ( !( --jQuery.active ) ) { 11710 jQuery.event.trigger( "ajaxStop" ); 11711 } 11712 } 11713 } 11714 11715 return jqXHR; 11716 }, 11717 11718 getJSON: function( url, data, callback ) { 11719 return jQuery.get( url, data, callback, "json" ); 11720 }, 11721 11722 getScript: function( url, callback ) { 11723 return jQuery.get( url, undefined, callback, "script" ); 11724 } 11725} ); 11726 11727jQuery.each( [ "get", "post" ], function( _i, method ) { 11728 jQuery[ method ] = function( url, data, callback, type ) { 11729 11730 // Shift arguments if data argument was omitted 11731 if ( isFunction( data ) ) { 11732 type = type || callback; 11733 callback = data; 11734 data = undefined; 11735 } 11736 11737 // The url can be an options object (which then must have .url) 11738 return jQuery.ajax( jQuery.extend( { 11739 url: url, 11740 type: method, 11741 dataType: type, 11742 data: data, 11743 success: callback 11744 }, jQuery.isPlainObject( url ) && url ) ); 11745 }; 11746} ); 11747 11748jQuery.ajaxPrefilter( function( s ) { 11749 var i; 11750 for ( i in s.headers ) { 11751 if ( i.toLowerCase() === "content-type" ) { 11752 s.contentType = s.headers[ i ] || ""; 11753 } 11754 } 11755} ); 11756 11757 11758jQuery._evalUrl = function( url, options, doc ) { 11759 return jQuery.ajax( { 11760 url: url, 11761 11762 // Make this explicit, since user can override this through ajaxSetup (#11264) 11763 type: "GET", 11764 dataType: "script", 11765 cache: true, 11766 async: false, 11767 global: false, 11768 11769 // Only evaluate the response if it is successful (gh-4126) 11770 // dataFilter is not invoked for failure responses, so using it instead 11771 // of the default converter is kludgy but it works. 11772 converters: { 11773 "text script": function() {} 11774 }, 11775 dataFilter: function( response ) { 11776 jQuery.globalEval( response, options, doc ); 11777 } 11778 } ); 11779}; 11780 11781 11782jQuery.fn.extend( { 11783 wrapAll: function( html ) { 11784 var wrap; 11785 11786 if ( this[ 0 ] ) { 11787 if ( isFunction( html ) ) { 11788 html = html.call( this[ 0 ] ); 11789 } 11790 11791 // The elements to wrap the target around 11792 wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true ); 11793 11794 if ( this[ 0 ].parentNode ) { 11795 wrap.insertBefore( this[ 0 ] ); 11796 } 11797 11798 wrap.map( function() { 11799 var elem = this; 11800 11801 while ( elem.firstElementChild ) { 11802 elem = elem.firstElementChild; 11803 } 11804 11805 return elem; 11806 } ).append( this ); 11807 } 11808 11809 return this; 11810 }, 11811 11812 wrapInner: function( html ) { 11813 if ( isFunction( html ) ) { 11814 return this.each( function( i ) { 11815 jQuery( this ).wrapInner( html.call( this, i ) ); 11816 } ); 11817 } 11818 11819 return this.each( function() { 11820 var self = jQuery( this ), 11821 contents = self.contents(); 11822 11823 if ( contents.length ) { 11824 contents.wrapAll( html ); 11825 11826 } else { 11827 self.append( html ); 11828 } 11829 } ); 11830 }, 11831 11832 wrap: function( html ) { 11833 var htmlIsFunction = isFunction( html ); 11834 11835 return this.each( function( i ) { 11836 jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html ); 11837 } ); 11838 }, 11839 11840 unwrap: function( selector ) { 11841 this.parent( selector ).not( "body" ).each( function() { 11842 jQuery( this ).replaceWith( this.childNodes ); 11843 } ); 11844 return this; 11845 } 11846} ); 11847 11848 11849jQuery.expr.pseudos.hidden = function( elem ) { 11850 return !jQuery.expr.pseudos.visible( elem ); 11851}; 11852jQuery.expr.pseudos.visible = function( elem ) { 11853 return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length ); 11854}; 11855 11856 11857 11858 11859jQuery.ajaxSettings.xhr = function() { 11860 try { 11861 return new window.XMLHttpRequest(); 11862 } catch ( e ) {} 11863}; 11864 11865var xhrSuccessStatus = { 11866 11867 // File protocol always yields status code 0, assume 200 11868 0: 200, 11869 11870 // Support: IE <=9 only 11871 // #1450: sometimes IE returns 1223 when it should be 204 11872 1223: 204 11873 }, 11874 xhrSupported = jQuery.ajaxSettings.xhr(); 11875 11876support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); 11877support.ajax = xhrSupported = !!xhrSupported; 11878 11879jQuery.ajaxTransport( function( options ) { 11880 var callback, errorCallback; 11881 11882 // Cross domain only allowed if supported through XMLHttpRequest 11883 if ( support.cors || xhrSupported && !options.crossDomain ) { 11884 return { 11885 send: function( headers, complete ) { 11886 var i, 11887 xhr = options.xhr(); 11888 11889 xhr.open( 11890 options.type, 11891 options.url, 11892 options.async, 11893 options.username, 11894 options.password 11895 ); 11896 11897 // Apply custom fields if provided 11898 if ( options.xhrFields ) { 11899 for ( i in options.xhrFields ) { 11900 xhr[ i ] = options.xhrFields[ i ]; 11901 } 11902 } 11903 11904 // Override mime type if needed 11905 if ( options.mimeType && xhr.overrideMimeType ) { 11906 xhr.overrideMimeType( options.mimeType ); 11907 } 11908 11909 // X-Requested-With header 11910 // For cross-domain requests, seeing as conditions for a preflight are 11911 // akin to a jigsaw puzzle, we simply never set it to be sure. 11912 // (it can always be set on a per-request basis or even using ajaxSetup) 11913 // For same-domain requests, won't change header if already provided. 11914 if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) { 11915 headers[ "X-Requested-With" ] = "XMLHttpRequest"; 11916 } 11917 11918 // Set headers 11919 for ( i in headers ) { 11920 xhr.setRequestHeader( i, headers[ i ] ); 11921 } 11922 11923 // Callback 11924 callback = function( type ) { 11925 return function() { 11926 if ( callback ) { 11927 callback = errorCallback = xhr.onload = 11928 xhr.onerror = xhr.onabort = xhr.ontimeout = 11929 xhr.onreadystatechange = null; 11930 11931 if ( type === "abort" ) { 11932 xhr.abort(); 11933 } else if ( type === "error" ) { 11934 11935 // Support: IE <=9 only 11936 // On a manual native abort, IE9 throws 11937 // errors on any property access that is not readyState 11938 if ( typeof xhr.status !== "number" ) { 11939 complete( 0, "error" ); 11940 } else { 11941 complete( 11942 11943 // File: protocol always yields status 0; see #8605, #14207 11944 xhr.status, 11945 xhr.statusText 11946 ); 11947 } 11948 } else { 11949 complete( 11950 xhrSuccessStatus[ xhr.status ] || xhr.status, 11951 xhr.statusText, 11952 11953 // Support: IE <=9 only 11954 // IE9 has no XHR2 but throws on binary (trac-11426) 11955 // For XHR2 non-text, let the caller handle it (gh-2498) 11956 ( xhr.responseType || "text" ) !== "text" || 11957 typeof xhr.responseText !== "string" ? 11958 { binary: xhr.response } : 11959 { text: xhr.responseText }, 11960 xhr.getAllResponseHeaders() 11961 ); 11962 } 11963 } 11964 }; 11965 }; 11966 11967 // Listen to events 11968 xhr.onload = callback(); 11969 errorCallback = xhr.onerror = xhr.ontimeout = callback( "error" ); 11970 11971 // Support: IE 9 only 11972 // Use onreadystatechange to replace onabort 11973 // to handle uncaught aborts 11974 if ( xhr.onabort !== undefined ) { 11975 xhr.onabort = errorCallback; 11976 } else { 11977 xhr.onreadystatechange = function() { 11978 11979 // Check readyState before timeout as it changes 11980 if ( xhr.readyState === 4 ) { 11981 11982 // Allow onerror to be called first, 11983 // but that will not handle a native abort 11984 // Also, save errorCallback to a variable 11985 // as xhr.onerror cannot be accessed 11986 window.setTimeout( function() { 11987 if ( callback ) { 11988 errorCallback(); 11989 } 11990 } ); 11991 } 11992 }; 11993 } 11994 11995 // Create the abort callback 11996 callback = callback( "abort" ); 11997 11998 try { 11999 12000 // Do send the request (this may raise an exception) 12001 xhr.send( options.hasContent && options.data || null ); 12002 } catch ( e ) { 12003 12004 // #14683: Only rethrow if this hasn't been notified as an error yet 12005 if ( callback ) { 12006 throw e; 12007 } 12008 } 12009 }, 12010 12011 abort: function() { 12012 if ( callback ) { 12013 callback(); 12014 } 12015 } 12016 }; 12017 } 12018} ); 12019 12020 12021 12022 12023// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432) 12024jQuery.ajaxPrefilter( function( s ) { 12025 if ( s.crossDomain ) { 12026 s.contents.script = false; 12027 } 12028} ); 12029 12030// Install script dataType 12031jQuery.ajaxSetup( { 12032 accepts: { 12033 script: "text/javascript, application/javascript, " + 12034 "application/ecmascript, application/x-ecmascript" 12035 }, 12036 contents: { 12037 script: /\b(?:java|ecma)script\b/ 12038 }, 12039 converters: { 12040 "text script": function( text ) { 12041 jQuery.globalEval( text ); 12042 return text; 12043 } 12044 } 12045} ); 12046 12047// Handle cache's special case and crossDomain 12048jQuery.ajaxPrefilter( "script", function( s ) { 12049 if ( s.cache === undefined ) { 12050 s.cache = false; 12051 } 12052 if ( s.crossDomain ) { 12053 s.type = "GET"; 12054 } 12055} ); 12056 12057// Bind script tag hack transport 12058jQuery.ajaxTransport( "script", function( s ) { 12059 12060 // This transport only deals with cross domain or forced-by-attrs requests 12061 if ( s.crossDomain || s.scriptAttrs ) { 12062 var script, callback; 12063 return { 12064 send: function( _, complete ) { 12065 script = jQuery( "<script>" ) 12066 .attr( s.scriptAttrs || {} ) 12067 .prop( { charset: s.scriptCharset, src: s.url } ) 12068 .on( "load error", callback = function( evt ) { 12069 script.remove(); 12070 callback = null; 12071 if ( evt ) { 12072 complete( evt.type === "error" ? 404 : 200, evt.type ); 12073 } 12074 } ); 12075 12076 // Use native DOM manipulation to avoid our domManip AJAX trickery 12077 document.head.appendChild( script[ 0 ] ); 12078 }, 12079 abort: function() { 12080 if ( callback ) { 12081 callback(); 12082 } 12083 } 12084 }; 12085 } 12086} ); 12087 12088 12089 12090 12091var oldCallbacks = [], 12092 rjsonp = /(=)\?(?=&|$)|\?\?/; 12093 12094// Default jsonp settings 12095jQuery.ajaxSetup( { 12096 jsonp: "callback", 12097 jsonpCallback: function() { 12098 var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce.guid++ ) ); 12099 this[ callback ] = true; 12100 return callback; 12101 } 12102} ); 12103 12104// Detect, normalize options and install callbacks for jsonp requests 12105jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { 12106 12107 var callbackName, overwritten, responseContainer, 12108 jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ? 12109 "url" : 12110 typeof s.data === "string" && 12111 ( s.contentType || "" ) 12112 .indexOf( "application/x-www-form-urlencoded" ) === 0 && 12113 rjsonp.test( s.data ) && "data" 12114 ); 12115 12116 // Handle iff the expected data type is "jsonp" or we have a parameter to set 12117 if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) { 12118 12119 // Get callback name, remembering preexisting value associated with it 12120 callbackName = s.jsonpCallback = isFunction( s.jsonpCallback ) ? 12121 s.jsonpCallback() : 12122 s.jsonpCallback; 12123 12124 // Insert callback into url or form data 12125 if ( jsonProp ) { 12126 s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName ); 12127 } else if ( s.jsonp !== false ) { 12128 s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName; 12129 } 12130 12131 // Use data converter to retrieve json after script execution 12132 s.converters[ "script json" ] = function() { 12133 if ( !responseContainer ) { 12134 jQuery.error( callbackName + " was not called" ); 12135 } 12136 return responseContainer[ 0 ]; 12137 }; 12138 12139 // Force json dataType 12140 s.dataTypes[ 0 ] = "json"; 12141 12142 // Install callback 12143 overwritten = window[ callbackName ]; 12144 window[ callbackName ] = function() { 12145 responseContainer = arguments; 12146 }; 12147 12148 // Clean-up function (fires after converters) 12149 jqXHR.always( function() { 12150 12151 // If previous value didn't exist - remove it 12152 if ( overwritten === undefined ) { 12153 jQuery( window ).removeProp( callbackName ); 12154 12155 // Otherwise restore preexisting value 12156 } else { 12157 window[ callbackName ] = overwritten; 12158 } 12159 12160 // Save back as free 12161 if ( s[ callbackName ] ) { 12162 12163 // Make sure that re-using the options doesn't screw things around 12164 s.jsonpCallback = originalSettings.jsonpCallback; 12165 12166 // Save the callback name for future use 12167 oldCallbacks.push( callbackName ); 12168 } 12169 12170 // Call if it was a function and we have a response 12171 if ( responseContainer && isFunction( overwritten ) ) { 12172 overwritten( responseContainer[ 0 ] ); 12173 } 12174 12175 responseContainer = overwritten = undefined; 12176 } ); 12177 12178 // Delegate to script 12179 return "script"; 12180 } 12181} ); 12182 12183 12184 12185 12186// Support: Safari 8 only 12187// In Safari 8 documents created via document.implementation.createHTMLDocument 12188// collapse sibling forms: the second one becomes a child of the first one. 12189// Because of that, this security measure has to be disabled in Safari 8. 12190// https://bugs.webkit.org/show_bug.cgi?id=137337 12191support.createHTMLDocument = ( function() { 12192 var body = document.implementation.createHTMLDocument( "" ).body; 12193 body.innerHTML = "<form></form><form></form>"; 12194 return body.childNodes.length === 2; 12195} )(); 12196 12197 12198// Argument "data" should be string of html 12199// context (optional): If specified, the fragment will be created in this context, 12200// defaults to document 12201// keepScripts (optional): If true, will include scripts passed in the html string 12202jQuery.parseHTML = function( data, context, keepScripts ) { 12203 if ( typeof data !== "string" ) { 12204 return []; 12205 } 12206 if ( typeof context === "boolean" ) { 12207 keepScripts = context; 12208 context = false; 12209 } 12210 12211 var base, parsed, scripts; 12212 12213 if ( !context ) { 12214 12215 // Stop scripts or inline event handlers from being executed immediately 12216 // by using document.implementation 12217 if ( support.createHTMLDocument ) { 12218 context = document.implementation.createHTMLDocument( "" ); 12219 12220 // Set the base href for the created document 12221 // so any parsed elements with URLs 12222 // are based on the document's URL (gh-2965) 12223 base = context.createElement( "base" ); 12224 base.href = document.location.href; 12225 context.head.appendChild( base ); 12226 } else { 12227 context = document; 12228 } 12229 } 12230 12231 parsed = rsingleTag.exec( data ); 12232 scripts = !keepScripts && []; 12233 12234 // Single tag 12235 if ( parsed ) { 12236 return [ context.createElement( parsed[ 1 ] ) ]; 12237 } 12238 12239 parsed = buildFragment( [ data ], context, scripts ); 12240 12241 if ( scripts && scripts.length ) { 12242 jQuery( scripts ).remove(); 12243 } 12244 12245 return jQuery.merge( [], parsed.childNodes ); 12246}; 12247 12248 12249/** 12250 * Load a url into a page 12251 */ 12252jQuery.fn.load = function( url, params, callback ) { 12253 var selector, type, response, 12254 self = this, 12255 off = url.indexOf( " " ); 12256 12257 if ( off > -1 ) { 12258 selector = stripAndCollapse( url.slice( off ) ); 12259 url = url.slice( 0, off ); 12260 } 12261 12262 // If it's a function 12263 if ( isFunction( params ) ) { 12264 12265 // We assume that it's the callback 12266 callback = params; 12267 params = undefined; 12268 12269 // Otherwise, build a param string 12270 } else if ( params && typeof params === "object" ) { 12271 type = "POST"; 12272 } 12273 12274 // If we have elements to modify, make the request 12275 if ( self.length > 0 ) { 12276 jQuery.ajax( { 12277 url: url, 12278 12279 // If "type" variable is undefined, then "GET" method will be used. 12280 // Make value of this field explicit since 12281 // user can override it through ajaxSetup method 12282 type: type || "GET", 12283 dataType: "html", 12284 data: params 12285 } ).done( function( responseText ) { 12286 12287 // Save response for use in complete callback 12288 response = arguments; 12289 12290 self.html( selector ? 12291 12292 // If a selector was specified, locate the right elements in a dummy div 12293 // Exclude scripts to avoid IE 'Permission Denied' errors 12294 jQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) : 12295 12296 // Otherwise use the full result 12297 responseText ); 12298 12299 // If the request succeeds, this function gets "data", "status", "jqXHR" 12300 // but they are ignored because response was set above. 12301 // If it fails, this function gets "jqXHR", "status", "error" 12302 } ).always( callback && function( jqXHR, status ) { 12303 self.each( function() { 12304 callback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] ); 12305 } ); 12306 } ); 12307 } 12308 12309 return this; 12310}; 12311 12312 12313 12314 12315jQuery.expr.pseudos.animated = function( elem ) { 12316 return jQuery.grep( jQuery.timers, function( fn ) { 12317 return elem === fn.elem; 12318 } ).length; 12319}; 12320 12321 12322 12323 12324jQuery.offset = { 12325 setOffset: function( elem, options, i ) { 12326 var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition, 12327 position = jQuery.css( elem, "position" ), 12328 curElem = jQuery( elem ), 12329 props = {}; 12330 12331 // Set position first, in-case top/left are set even on static elem 12332 if ( position === "static" ) { 12333 elem.style.position = "relative"; 12334 } 12335 12336 curOffset = curElem.offset(); 12337 curCSSTop = jQuery.css( elem, "top" ); 12338 curCSSLeft = jQuery.css( elem, "left" ); 12339 calculatePosition = ( position === "absolute" || position === "fixed" ) && 12340 ( curCSSTop + curCSSLeft ).indexOf( "auto" ) > -1; 12341 12342 // Need to be able to calculate position if either 12343 // top or left is auto and position is either absolute or fixed 12344 if ( calculatePosition ) { 12345 curPosition = curElem.position(); 12346 curTop = curPosition.top; 12347 curLeft = curPosition.left; 12348 12349 } else { 12350 curTop = parseFloat( curCSSTop ) || 0; 12351 curLeft = parseFloat( curCSSLeft ) || 0; 12352 } 12353 12354 if ( isFunction( options ) ) { 12355 12356 // Use jQuery.extend here to allow modification of coordinates argument (gh-1848) 12357 options = options.call( elem, i, jQuery.extend( {}, curOffset ) ); 12358 } 12359 12360 if ( options.top != null ) { 12361 props.top = ( options.top - curOffset.top ) + curTop; 12362 } 12363 if ( options.left != null ) { 12364 props.left = ( options.left - curOffset.left ) + curLeft; 12365 } 12366 12367 if ( "using" in options ) { 12368 options.using.call( elem, props ); 12369 12370 } else { 12371 curElem.css( props ); 12372 } 12373 } 12374}; 12375 12376jQuery.fn.extend( { 12377 12378 // offset() relates an element's border box to the document origin 12379 offset: function( options ) { 12380 12381 // Preserve chaining for setter 12382 if ( arguments.length ) { 12383 return options === undefined ? 12384 this : 12385 this.each( function( i ) { 12386 jQuery.offset.setOffset( this, options, i ); 12387 } ); 12388 } 12389 12390 var rect, win, 12391 elem = this[ 0 ]; 12392 12393 if ( !elem ) { 12394 return; 12395 } 12396 12397 // Return zeros for disconnected and hidden (display: none) elements (gh-2310) 12398 // Support: IE <=11 only 12399 // Running getBoundingClientRect on a 12400 // disconnected node in IE throws an error 12401 if ( !elem.getClientRects().length ) { 12402 return { top: 0, left: 0 }; 12403 } 12404 12405 // Get document-relative position by adding viewport scroll to viewport-relative gBCR 12406 rect = elem.getBoundingClientRect(); 12407 win = elem.ownerDocument.defaultView; 12408 return { 12409 top: rect.top + win.pageYOffset, 12410 left: rect.left + win.pageXOffset 12411 }; 12412 }, 12413 12414 // position() relates an element's margin box to its offset parent's padding box 12415 // This corresponds to the behavior of CSS absolute positioning 12416 position: function() { 12417 if ( !this[ 0 ] ) { 12418 return; 12419 } 12420 12421 var offsetParent, offset, doc, 12422 elem = this[ 0 ], 12423 parentOffset = { top: 0, left: 0 }; 12424 12425 // position:fixed elements are offset from the viewport, which itself always has zero offset 12426 if ( jQuery.css( elem, "position" ) === "fixed" ) { 12427 12428 // Assume position:fixed implies availability of getBoundingClientRect 12429 offset = elem.getBoundingClientRect(); 12430 12431 } else { 12432 offset = this.offset(); 12433 12434 // Account for the *real* offset parent, which can be the document or its root element 12435 // when a statically positioned element is identified 12436 doc = elem.ownerDocument; 12437 offsetParent = elem.offsetParent || doc.documentElement; 12438 while ( offsetParent && 12439 ( offsetParent === doc.body || offsetParent === doc.documentElement ) && 12440 jQuery.css( offsetParent, "position" ) === "static" ) { 12441 12442 offsetParent = offsetParent.parentNode; 12443 } 12444 if ( offsetParent && offsetParent !== elem && offsetParent.nodeType === 1 ) { 12445 12446 // Incorporate borders into its offset, since they are outside its content origin 12447 parentOffset = jQuery( offsetParent ).offset(); 12448 parentOffset.top += jQuery.css( offsetParent, "borderTopWidth", true ); 12449 parentOffset.left += jQuery.css( offsetParent, "borderLeftWidth", true ); 12450 } 12451 } 12452 12453 // Subtract parent offsets and element margins 12454 return { 12455 top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ), 12456 left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true ) 12457 }; 12458 }, 12459 12460 // This method will return documentElement in the following cases: 12461 // 1) For the element inside the iframe without offsetParent, this method will return 12462 // documentElement of the parent window 12463 // 2) For the hidden or detached element 12464 // 3) For body or html element, i.e. in case of the html node - it will return itself 12465 // 12466 // but those exceptions were never presented as a real life use-cases 12467 // and might be considered as more preferable results. 12468 // 12469 // This logic, however, is not guaranteed and can change at any point in the future 12470 offsetParent: function() { 12471 return this.map( function() { 12472 var offsetParent = this.offsetParent; 12473 12474 while ( offsetParent && jQuery.css( offsetParent, "position" ) === "static" ) { 12475 offsetParent = offsetParent.offsetParent; 12476 } 12477 12478 return offsetParent || documentElement; 12479 } ); 12480 } 12481} ); 12482 12483// Create scrollLeft and scrollTop methods 12484jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) { 12485 var top = "pageYOffset" === prop; 12486 12487 jQuery.fn[ method ] = function( val ) { 12488 return access( this, function( elem, method, val ) { 12489 12490 // Coalesce documents and windows 12491 var win; 12492 if ( isWindow( elem ) ) { 12493 win = elem; 12494 } else if ( elem.nodeType === 9 ) { 12495 win = elem.defaultView; 12496 } 12497 12498 if ( val === undefined ) { 12499 return win ? win[ prop ] : elem[ method ]; 12500 } 12501 12502 if ( win ) { 12503 win.scrollTo( 12504 !top ? val : win.pageXOffset, 12505 top ? val : win.pageYOffset 12506 ); 12507 12508 } else { 12509 elem[ method ] = val; 12510 } 12511 }, method, val, arguments.length ); 12512 }; 12513} ); 12514 12515// Support: Safari <=7 - 9.1, Chrome <=37 - 49 12516// Add the top/left cssHooks using jQuery.fn.position 12517// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084 12518// Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347 12519// getComputedStyle returns percent when specified for top/left/bottom/right; 12520// rather than make the css module depend on the offset module, just check for it here 12521jQuery.each( [ "top", "left" ], function( _i, prop ) { 12522 jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition, 12523 function( elem, computed ) { 12524 if ( computed ) { 12525 computed = curCSS( elem, prop ); 12526 12527 // If curCSS returns percentage, fallback to offset 12528 return rnumnonpx.test( computed ) ? 12529 jQuery( elem ).position()[ prop ] + "px" : 12530 computed; 12531 } 12532 } 12533 ); 12534} ); 12535 12536 12537// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods 12538jQuery.each( { Height: "height", Width: "width" }, function( name, type ) { 12539 jQuery.each( { 12540 padding: "inner" + name, 12541 content: type, 12542 "": "outer" + name 12543 }, function( defaultExtra, funcName ) { 12544 12545 // Margin is only for outerHeight, outerWidth 12546 jQuery.fn[ funcName ] = function( margin, value ) { 12547 var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ), 12548 extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" ); 12549 12550 return access( this, function( elem, type, value ) { 12551 var doc; 12552 12553 if ( isWindow( elem ) ) { 12554 12555 // $( window ).outerWidth/Height return w/h including scrollbars (gh-1729) 12556 return funcName.indexOf( "outer" ) === 0 ? 12557 elem[ "inner" + name ] : 12558 elem.document.documentElement[ "client" + name ]; 12559 } 12560 12561 // Get document width or height 12562 if ( elem.nodeType === 9 ) { 12563 doc = elem.documentElement; 12564 12565 // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], 12566 // whichever is greatest 12567 return Math.max( 12568 elem.body[ "scroll" + name ], doc[ "scroll" + name ], 12569 elem.body[ "offset" + name ], doc[ "offset" + name ], 12570 doc[ "client" + name ] 12571 ); 12572 } 12573 12574 return value === undefined ? 12575 12576 // Get width or height on the element, requesting but not forcing parseFloat 12577 jQuery.css( elem, type, extra ) : 12578 12579 // Set width or height on the element 12580 jQuery.style( elem, type, value, extra ); 12581 }, type, chainable ? margin : undefined, chainable ); 12582 }; 12583 } ); 12584} ); 12585 12586 12587jQuery.each( [ 12588 "ajaxStart", 12589 "ajaxStop", 12590 "ajaxComplete", 12591 "ajaxError", 12592 "ajaxSuccess", 12593 "ajaxSend" 12594], function( _i, type ) { 12595 jQuery.fn[ type ] = function( fn ) { 12596 return this.on( type, fn ); 12597 }; 12598} ); 12599 12600 12601 12602 12603jQuery.fn.extend( { 12604 12605 bind: function( types, data, fn ) { 12606 return this.on( types, null, data, fn ); 12607 }, 12608 unbind: function( types, fn ) { 12609 return this.off( types, null, fn ); 12610 }, 12611 12612 delegate: function( selector, types, data, fn ) { 12613 return this.on( types, selector, data, fn ); 12614 }, 12615 undelegate: function( selector, types, fn ) { 12616 12617 // ( namespace ) or ( selector, types [, fn] ) 12618 return arguments.length === 1 ? 12619 this.off( selector, "**" ) : 12620 this.off( types, selector || "**", fn ); 12621 }, 12622 12623 hover: function( fnOver, fnOut ) { 12624 return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); 12625 } 12626} ); 12627 12628jQuery.each( 12629 ( "blur focus focusin focusout resize scroll click dblclick " + 12630 "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + 12631 "change select submit keydown keypress keyup contextmenu" ).split( " " ), 12632 function( _i, name ) { 12633 12634 // Handle event binding 12635 jQuery.fn[ name ] = function( data, fn ) { 12636 return arguments.length > 0 ? 12637 this.on( name, null, data, fn ) : 12638 this.trigger( name ); 12639 }; 12640 } 12641); 12642 12643 12644 12645 12646// Support: Android <=4.0 only 12647// Make sure we trim BOM and NBSP 12648var rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g; 12649 12650// Bind a function to a context, optionally partially applying any 12651// arguments. 12652// jQuery.proxy is deprecated to promote standards (specifically Function#bind) 12653// However, it is not slated for removal any time soon 12654jQuery.proxy = function( fn, context ) { 12655 var tmp, args, proxy; 12656 12657 if ( typeof context === "string" ) { 12658 tmp = fn[ context ]; 12659 context = fn; 12660 fn = tmp; 12661 } 12662 12663 // Quick check to determine if target is callable, in the spec 12664 // this throws a TypeError, but we will just return undefined. 12665 if ( !isFunction( fn ) ) { 12666 return undefined; 12667 } 12668 12669 // Simulated bind 12670 args = slice.call( arguments, 2 ); 12671 proxy = function() { 12672 return fn.apply( context || this, args.concat( slice.call( arguments ) ) ); 12673 }; 12674 12675 // Set the guid of unique handler to the same of original handler, so it can be removed 12676 proxy.guid = fn.guid = fn.guid || jQuery.guid++; 12677 12678 return proxy; 12679}; 12680 12681jQuery.holdReady = function( hold ) { 12682 if ( hold ) { 12683 jQuery.readyWait++; 12684 } else { 12685 jQuery.ready( true ); 12686 } 12687}; 12688jQuery.isArray = Array.isArray; 12689jQuery.parseJSON = JSON.parse; 12690jQuery.nodeName = nodeName; 12691jQuery.isFunction = isFunction; 12692jQuery.isWindow = isWindow; 12693jQuery.camelCase = camelCase; 12694jQuery.type = toType; 12695 12696jQuery.now = Date.now; 12697 12698jQuery.isNumeric = function( obj ) { 12699 12700 // As of jQuery 3.0, isNumeric is limited to 12701 // strings and numbers (primitives or objects) 12702 // that can be coerced to finite numbers (gh-2662) 12703 var type = jQuery.type( obj ); 12704 return ( type === "number" || type === "string" ) && 12705 12706 // parseFloat NaNs numeric-cast false positives ("") 12707 // ...but misinterprets leading-number strings, particularly hex literals ("0x...") 12708 // subtraction forces infinities to NaN 12709 !isNaN( obj - parseFloat( obj ) ); 12710}; 12711 12712jQuery.trim = function( text ) { 12713 return text == null ? 12714 "" : 12715 ( text + "" ).replace( rtrim, "" ); 12716}; 12717 12718 12719 12720// Register as a named AMD module, since jQuery can be concatenated with other 12721// files that may use define, but not via a proper concatenation script that 12722// understands anonymous AMD modules. A named AMD is safest and most robust 12723// way to register. Lowercase jquery is used because AMD module names are 12724// derived from file names, and jQuery is normally delivered in a lowercase 12725// file name. Do this after creating the global so that if an AMD module wants 12726// to call noConflict to hide this version of jQuery, it will work. 12727 12728// Note that for maximum portability, libraries that are not jQuery should 12729// declare themselves as anonymous modules, and avoid setting a global if an 12730// AMD loader is present. jQuery is a special case. For more information, see 12731// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon 12732 12733if ( true ) { 12734 !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = (function() { 12735 return jQuery; 12736 }).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), 12737 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 12738} 12739 12740 12741 12742 12743var 12744 12745 // Map over jQuery in case of overwrite 12746 _jQuery = window.jQuery, 12747 12748 // Map over the $ in case of overwrite 12749 _$ = window.$; 12750 12751jQuery.noConflict = function( deep ) { 12752 if ( window.$ === jQuery ) { 12753 window.$ = _$; 12754 } 12755 12756 if ( deep && window.jQuery === jQuery ) { 12757 window.jQuery = _jQuery; 12758 } 12759 12760 return jQuery; 12761}; 12762 12763// Expose jQuery and $ identifiers, even in AMD 12764// (#7102#comment:10, https://github.com/jquery/jquery/pull/557) 12765// and CommonJS for browser emulators (#13566) 12766if ( typeof noGlobal === "undefined" ) { 12767 window.jQuery = window.$ = jQuery; 12768} 12769 12770 12771 12772 12773return jQuery; 12774} ); 12775 12776 12777/***/ }), 12778
vendor: 70,301 bytes, lines 12779-13794
12779/***/ "./node_modules/mobile-detect/mobile-detect.js": 12780/*!*****************************************************!*\ 12781 !*** ./node_modules/mobile-detect/mobile-detect.js ***! 12782 \*****************************************************/ 12783/*! no static exports found */ 12784/***/ (function(module, exports, __webpack_require__) { 12785 12786// THIS FILE IS GENERATED - DO NOT EDIT! 12787/*!mobile-detect v1.4.5 2021-03-13*/ 12788/*global module:false, define:false*/ 12789/*jshint latedef:false*/ 12790/*!@license Copyright 2013, Heinrich Goebl, License: MIT, see https://github.com/hgoebl/mobile-detect.js*/ 12791(function (define, undefined) { 12792define(function () { 12793 'use strict'; 12794 12795 var impl = {}; 12796 12797 impl.mobileDetectRules = { 12798 "phones": { 12799 "iPhone": "\\biPhone\\b|\\biPod\\b", 12800 "BlackBerry": "BlackBerry|\\bBB10\\b|rim[0-9]+|\\b(BBA100|BBB100|BBD100|BBE100|BBF100|STH100)\\b-[0-9]+", 12801 "Pixel": "; \\bPixel\\b", 12802 "HTC": "HTC|HTC.*(Sensation|Evo|Vision|Explorer|6800|8100|8900|A7272|S510e|C110e|Legend|Desire|T8282)|APX515CKT|Qtek9090|APA9292KT|HD_mini|Sensation.*Z710e|PG86100|Z715e|Desire.*(A8181|HD)|ADR6200|ADR6400L|ADR6425|001HT|Inspire 4G|Android.*\\bEVO\\b|T-Mobile G1|Z520m|Android [0-9.]+; Pixel", 12803 "Nexus": "Nexus One|Nexus S|Galaxy.*Nexus|Android.*Nexus.*Mobile|Nexus 4|Nexus 5|Nexus 5X|Nexus 6", 12804 "Dell": "Dell[;]? (Streak|Aero|Venue|Venue Pro|Flash|Smoke|Mini 3iX)|XCD28|XCD35|\\b001DL\\b|\\b101DL\\b|\\bGS01\\b", 12805 "Motorola": "Motorola|DROIDX|DROID BIONIC|\\bDroid\\b.*Build|Android.*Xoom|HRI39|MOT-|A1260|A1680|A555|A853|A855|A953|A955|A956|Motorola.*ELECTRIFY|Motorola.*i1|i867|i940|MB200|MB300|MB501|MB502|MB508|MB511|MB520|MB525|MB526|MB611|MB612|MB632|MB810|MB855|MB860|MB861|MB865|MB870|ME501|ME502|ME511|ME525|ME600|ME632|ME722|ME811|ME860|ME863|ME865|MT620|MT710|MT716|MT720|MT810|MT870|MT917|Motorola.*TITANIUM|WX435|WX445|XT300|XT301|XT311|XT316|XT317|XT319|XT320|XT390|XT502|XT530|XT531|XT532|XT535|XT603|XT610|XT611|XT615|XT681|XT701|XT702|XT711|XT720|XT800|XT806|XT860|XT862|XT875|XT882|XT883|XT894|XT901|XT907|XT909|XT910|XT912|XT928|XT926|XT915|XT919|XT925|XT1021|\\bMoto E\\b|XT1068|XT1092|XT1052", 12806 "Samsung": "\\bSamsung\\b|SM-G950F|SM-G955F|SM-G9250|GT-19300|SGH-I337|BGT-S5230|GT-B2100|GT-B2700|GT-B2710|GT-B3210|GT-B3310|GT-B3410|GT-B3730|GT-B3740|GT-B5510|GT-B5512|GT-B5722|GT-B6520|GT-B7300|GT-B7320|GT-B7330|GT-B7350|GT-B7510|GT-B7722|GT-B7800|GT-C3010|GT-C3011|GT-C3060|GT-C3200|GT-C3212|GT-C3212I|GT-C3262|GT-C3222|GT-C3300|GT-C3300K|GT-C3303|GT-C3303K|GT-C3310|GT-C3322|GT-C3330|GT-C3350|GT-C3500|GT-C3510|GT-C3530|GT-C3630|GT-C3780|GT-C5010|GT-C5212|GT-C6620|GT-C6625|GT-C6712|GT-E1050|GT-E1070|GT-E1075|GT-E1080|GT-E1081|GT-E1085|GT-E1087|GT-E1100|GT-E1107|GT-E1110|GT-E1120|GT-E1125|GT-E1130|GT-E1160|GT-E1170|GT-E1175|GT-E1180|GT-E1182|GT-E1200|GT-E1210|GT-E1225|GT-E1230|GT-E1390|GT-E2100|GT-E2120|GT-E2121|GT-E2152|GT-E2220|GT-E2222|GT-E2230|GT-E2232|GT-E2250|GT-E2370|GT-E2550|GT-E2652|GT-E3210|GT-E3213|GT-I5500|GT-I5503|GT-I5700|GT-I5800|GT-I5801|GT-I6410|GT-I6420|GT-I7110|GT-I7410|GT-I7500|GT-I8000|GT-I8150|GT-I8160|GT-I8190|GT-I8320|GT-I8330|GT-I8350|GT-I8530|GT-I8700|GT-I8703|GT-I8910|GT-I9000|GT-I9001|GT-I9003|GT-I9010|GT-I9020|GT-I9023|GT-I9070|GT-I9082|GT-I9100|GT-I9103|GT-I9220|GT-I9250|GT-I9300|GT-I9305|GT-I9500|GT-I9505|GT-M3510|GT-M5650|GT-M7500|GT-M7600|GT-M7603|GT-M8800|GT-M8910|GT-N7000|GT-S3110|GT-S3310|GT-S3350|GT-S3353|GT-S3370|GT-S3650|GT-S3653|GT-S3770|GT-S3850|GT-S5210|GT-S5220|GT-S5229|GT-S5230|GT-S5233|GT-S5250|GT-S5253|GT-S5260|GT-S5263|GT-S5270|GT-S5300|GT-S5330|GT-S5350|GT-S5360|GT-S5363|GT-S5369|GT-S5380|GT-S5380D|GT-S5560|GT-S5570|GT-S5600|GT-S5603|GT-S5610|GT-S5620|GT-S5660|GT-S5670|GT-S5690|GT-S5750|GT-S5780|GT-S5830|GT-S5839|GT-S6102|GT-S6500|GT-S7070|GT-S7200|GT-S7220|GT-S7230|GT-S7233|GT-S7250|GT-S7500|GT-S7530|GT-S7550|GT-S7562|GT-S7710|GT-S8000|GT-S8003|GT-S8500|GT-S8530|GT-S8600|SCH-A310|SCH-A530|SCH-A570|SCH-A610|SCH-A630|SCH-A650|SCH-A790|SCH-A795|SCH-A850|SCH-A870|SCH-A890|SCH-A930|SCH-A950|SCH-A970|SCH-A990|SCH-I100|SCH-I110|SCH-I400|SCH-I405|SCH-I500|SCH-I510|SCH-I515|SCH-I600|SCH-I730|SCH-I760|SCH-I770|SCH-I830|SCH-I910|SCH-I920|SCH-I959|SCH-LC11|SCH-N150|SCH-N300|SCH-R100|SCH-R300|SCH-R351|SCH-R400|SCH-R410|SCH-T300|SCH-U310|SCH-U320|SCH-U350|SCH-U360|SCH-U365|SCH-U370|SCH-U380|SCH-U410|SCH-U430|SCH-U450|SCH-U460|SCH-U470|SCH-U490|SCH-U540|SCH-U550|SCH-U620|SCH-U640|SCH-U650|SCH-U660|SCH-U700|SCH-U740|SCH-U750|SCH-U810|SCH-U820|SCH-U900|SCH-U940|SCH-U960|SCS-26UC|SGH-A107|SGH-A117|SGH-A127|SGH-A137|SGH-A157|SGH-A167|SGH-A177|SGH-A187|SGH-A197|SGH-A227|SGH-A237|SGH-A257|SGH-A437|SGH-A517|SGH-A597|SGH-A637|SGH-A657|SGH-A667|SGH-A687|SGH-A697|SGH-A707|SGH-A717|SGH-A727|SGH-A737|SGH-A747|SGH-A767|SGH-A777|SGH-A797|SGH-A817|SGH-A827|SGH-A837|SGH-A847|SGH-A867|SGH-A877|SGH-A887|SGH-A897|SGH-A927|SGH-B100|SGH-B130|SGH-B200|SGH-B220|SGH-C100|SGH-C110|SGH-C120|SGH-C130|SGH-C140|SGH-C160|SGH-C170|SGH-C180|SGH-C200|SGH-C207|SGH-C210|SGH-C225|SGH-C230|SGH-C417|SGH-C450|SGH-D307|SGH-D347|SGH-D357|SGH-D407|SGH-D415|SGH-D780|SGH-D807|SGH-D980|SGH-E105|SGH-E200|SGH-E315|SGH-E316|SGH-E317|SGH-E335|SGH-E590|SGH-E635|SGH-E715|SGH-E890|SGH-F300|SGH-F480|SGH-I200|SGH-I300|SGH-I320|SGH-I550|SGH-I577|SGH-I600|SGH-I607|SGH-I617|SGH-I627|SGH-I637|SGH-I677|SGH-I700|SGH-I717|SGH-I727|SGH-i747M|SGH-I777|SGH-I780|SGH-I827|SGH-I847|SGH-I857|SGH-I896|SGH-I897|SGH-I900|SGH-I907|SGH-I917|SGH-I927|SGH-I937|SGH-I997|SGH-J150|SGH-J200|SGH-L170|SGH-L700|SGH-M110|SGH-M150|SGH-M200|SGH-N105|SGH-N500|SGH-N600|SGH-N620|SGH-N625|SGH-N700|SGH-N710|SGH-P107|SGH-P207|SGH-P300|SGH-P310|SGH-P520|SGH-P735|SGH-P777|SGH-Q105|SGH-R210|SGH-R220|SGH-R225|SGH-S105|SGH-S307|SGH-T109|SGH-T119|SGH-T139|SGH-T209|SGH-T219|SGH-T229|SGH-T239|SGH-T249|SGH-T259|SGH-T309|SGH-T319|SGH-T329|SGH-T339|SGH-T349|SGH-T359|SGH-T369|SGH-T379|SGH-T409|SGH-T429|SGH-T439|SGH-T459|SGH-T469|SGH-T479|SGH-T499|SGH-T509|SGH-T519|SGH-T539|SGH-T559|SGH-T589|SGH-T609|SGH-T619|SGH-T629|SGH-T639|SGH-T659|SGH-T669|SGH-T679|SGH-T709|SGH-T719|SGH-T729|SGH-T739|SGH-T746|SGH-T749|SGH-T759|SGH-T769|SGH-T809|SGH-T819|SGH-T839|SGH-T919|SGH-T929|SGH-T939|SGH-T959|SGH-T989|SGH-U100|SGH-U200|SGH-U800|SGH-V205|SGH-V206|SGH-X100|SGH-X105|SGH-X120|SGH-X140|SGH-X426|SGH-X427|SGH-X475|SGH-X495|SGH-X497|SGH-X507|SGH-X600|SGH-X610|SGH-X620|SGH-X630|SGH-X700|SGH-X820|SGH-X890|SGH-Z130|SGH-Z150|SGH-Z170|SGH-ZX10|SGH-ZX20|SHW-M110|SPH-A120|SPH-A400|SPH-A420|SPH-A460|SPH-A500|SPH-A560|SPH-A600|SPH-A620|SPH-A660|SPH-A700|SPH-A740|SPH-A760|SPH-A790|SPH-A800|SPH-A820|SPH-A840|SPH-A880|SPH-A900|SPH-A940|SPH-A960|SPH-D600|SPH-D700|SPH-D710|SPH-D720|SPH-I300|SPH-I325|SPH-I330|SPH-I350|SPH-I500|SPH-I600|SPH-I700|SPH-L700|SPH-M100|SPH-M220|SPH-M240|SPH-M300|SPH-M305|SPH-M320|SPH-M330|SPH-M350|SPH-M360|SPH-M370|SPH-M380|SPH-M510|SPH-M540|SPH-M550|SPH-M560|SPH-M570|SPH-M580|SPH-M610|SPH-M620|SPH-M630|SPH-M800|SPH-M810|SPH-M850|SPH-M900|SPH-M910|SPH-M920|SPH-M930|SPH-N100|SPH-N200|SPH-N240|SPH-N300|SPH-N400|SPH-Z400|SWC-E100|SCH-i909|GT-N7100|GT-N7105|SCH-I535|SM-N900A|SGH-I317|SGH-T999L|GT-S5360B|GT-I8262|GT-S6802|GT-S6312|GT-S6310|GT-S5312|GT-S5310|GT-I9105|GT-I8510|GT-S6790N|SM-G7105|SM-N9005|GT-S5301|GT-I9295|GT-I9195|SM-C101|GT-S7392|GT-S7560|GT-B7610|GT-I5510|GT-S7582|GT-S7530E|GT-I8750|SM-G9006V|SM-G9008V|SM-G9009D|SM-G900A|SM-G900D|SM-G900F|SM-G900H|SM-G900I|SM-G900J|SM-G900K|SM-G900L|SM-G900M|SM-G900P|SM-G900R4|SM-G900S|SM-G900T|SM-G900V|SM-G900W8|SHV-E160K|SCH-P709|SCH-P729|SM-T2558|GT-I9205|SM-G9350|SM-J120F|SM-G920F|SM-G920V|SM-G930F|SM-N910C|SM-A310F|GT-I9190|SM-J500FN|SM-G903F|SM-J330F|SM-G610F|SM-G981B|SM-G892A|SM-A530F", 12807 "LG": "\\bLG\\b;|LG[- ]?(C800|C900|E400|E610|E900|E-900|F160|F180K|F180L|F180S|730|855|L160|LS740|LS840|LS970|LU6200|MS690|MS695|MS770|MS840|MS870|MS910|P500|P700|P705|VM696|AS680|AS695|AX840|C729|E970|GS505|272|C395|E739BK|E960|L55C|L75C|LS696|LS860|P769BK|P350|P500|P509|P870|UN272|US730|VS840|VS950|LN272|LN510|LS670|LS855|LW690|MN270|MN510|P509|P769|P930|UN200|UN270|UN510|UN610|US670|US740|US760|UX265|UX840|VN271|VN530|VS660|VS700|VS740|VS750|VS910|VS920|VS930|VX9200|VX11000|AX840A|LW770|P506|P925|P999|E612|D955|D802|MS323|M257)|LM-G710", 12808 "Sony": "SonyST|SonyLT|SonyEricsson|SonyEricssonLT15iv|LT18i|E10i|LT28h|LT26w|SonyEricssonMT27i|C5303|C6902|C6903|C6906|C6943|D2533|SOV34|601SO|F8332", 12809 "Asus": "Asus.*Galaxy|PadFone.*Mobile", 12810 "Xiaomi": "^(?!.*\\bx11\\b).*xiaomi.*$|POCOPHONE F1|MI 8|Redmi Note 9S|Redmi Note 5A Prime|N2G47H|M2001J2G|M2001J2I|M1805E10A|M2004J11G|M1902F1G|M2002J9G|M2004J19G|M2003J6A1G", 12811 "NokiaLumia": "Lumia [0-9]{3,4}", 12812 "Micromax": "Micromax.*\\b(A210|A92|A88|A72|A111|A110Q|A115|A116|A110|A90S|A26|A51|A35|A54|A25|A27|A89|A68|A65|A57|A90)\\b", 12813 "Palm": "PalmSource|Palm", 12814 "Vertu": "Vertu|Vertu.*Ltd|Vertu.*Ascent|Vertu.*Ayxta|Vertu.*Constellation(F|Quest)?|Vertu.*Monika|Vertu.*Signature", 12815 "Pantech": "PANTECH|IM-A850S|IM-A840S|IM-A830L|IM-A830K|IM-A830S|IM-A820L|IM-A810K|IM-A810S|IM-A800S|IM-T100K|IM-A725L|IM-A780L|IM-A775C|IM-A770K|IM-A760S|IM-A750K|IM-A740S|IM-A730S|IM-A720L|IM-A710K|IM-A690L|IM-A690S|IM-A650S|IM-A630K|IM-A600S|VEGA PTL21|PT003|P8010|ADR910L|P6030|P6020|P9070|P4100|P9060|P5000|CDM8992|TXT8045|ADR8995|IS11PT|P2030|P6010|P8000|PT002|IS06|CDM8999|P9050|PT001|TXT8040|P2020|P9020|P2000|P7040|P7000|C790", 12816 "Fly": "IQ230|IQ444|IQ450|IQ440|IQ442|IQ441|IQ245|IQ256|IQ236|IQ255|IQ235|IQ245|IQ275|IQ240|IQ285|IQ280|IQ270|IQ260|IQ250", 12817 "Wiko": "KITE 4G|HIGHWAY|GETAWAY|STAIRWAY|DARKSIDE|DARKFULL|DARKNIGHT|DARKMOON|SLIDE|WAX 4G|RAINBOW|BLOOM|SUNSET|GOA(?!nna)|LENNY|BARRY|IGGY|OZZY|CINK FIVE|CINK PEAX|CINK PEAX 2|CINK SLIM|CINK SLIM 2|CINK +|CINK KING|CINK PEAX|CINK SLIM|SUBLIM", 12818 "iMobile": "i-mobile (IQ|i-STYLE|idea|ZAA|Hitz)", 12819 "SimValley": "\\b(SP-80|XT-930|SX-340|XT-930|SX-310|SP-360|SP60|SPT-800|SP-120|SPT-800|SP-140|SPX-5|SPX-8|SP-100|SPX-8|SPX-12)\\b", 12820 "Wolfgang": "AT-B24D|AT-AS50HD|AT-AS40W|AT-AS55HD|AT-AS45q2|AT-B26D|AT-AS50Q", 12821 "Alcatel": "Alcatel", 12822 "Nintendo": "Nintendo (3DS|Switch)", 12823 "Amoi": "Amoi", 12824 "INQ": "INQ", 12825 "OnePlus": "ONEPLUS", 12826 "GenericPhone": "Tapatalk|PDA;|SAGEM|\\bmmp\\b|pocket|\\bpsp\\b|symbian|Smartphone|smartfon|treo|up.browser|up.link|vodafone|\\bwap\\b|nokia|Series40|Series60|S60|SonyEricsson|N900|MAUI.*WAP.*Browser" 12827 }, 12828 "tablets": { 12829 "iPad": "iPad|iPad.*Mobile", 12830 "NexusTablet": "Android.*Nexus[\\s]+(7|9|10)", 12831 "GoogleTablet": "Android.*Pixel C", 12832 "SamsungTablet": "SAMSUNG.*Tablet|Galaxy.*Tab|SC-01C|GT-P1000|GT-P1003|GT-P1010|GT-P3105|GT-P6210|GT-P6800|GT-P6810|GT-P7100|GT-P7300|GT-P7310|GT-P7500|GT-P7510|SCH-I800|SCH-I815|SCH-I905|SGH-I957|SGH-I987|SGH-T849|SGH-T859|SGH-T869|SPH-P100|GT-P3100|GT-P3108|GT-P3110|GT-P5100|GT-P5110|GT-P6200|GT-P7320|GT-P7511|GT-N8000|GT-P8510|SGH-I497|SPH-P500|SGH-T779|SCH-I705|SCH-I915|GT-N8013|GT-P3113|GT-P5113|GT-P8110|GT-N8010|GT-N8005|GT-N8020|GT-P1013|GT-P6201|GT-P7501|GT-N5100|GT-N5105|GT-N5110|SHV-E140K|SHV-E140L|SHV-E140S|SHV-E150S|SHV-E230K|SHV-E230L|SHV-E230S|SHW-M180K|SHW-M180L|SHW-M180S|SHW-M180W|SHW-M300W|SHW-M305W|SHW-M380K|SHW-M380S|SHW-M380W|SHW-M430W|SHW-M480K|SHW-M480S|SHW-M480W|SHW-M485W|SHW-M486W|SHW-M500W|GT-I9228|SCH-P739|SCH-I925|GT-I9200|GT-P5200|GT-P5210|GT-P5210X|SM-T311|SM-T310|SM-T310X|SM-T210|SM-T210R|SM-T211|SM-P600|SM-P601|SM-P605|SM-P900|SM-P901|SM-T217|SM-T217A|SM-T217S|SM-P6000|SM-T3100|SGH-I467|XE500|SM-T110|GT-P5220|GT-I9200X|GT-N5110X|GT-N5120|SM-P905|SM-T111|SM-T2105|SM-T315|SM-T320|SM-T320X|SM-T321|SM-T520|SM-T525|SM-T530NU|SM-T230NU|SM-T330NU|SM-T900|XE500T1C|SM-P605V|SM-P905V|SM-T337V|SM-T537V|SM-T707V|SM-T807V|SM-P600X|SM-P900X|SM-T210X|SM-T230|SM-T230X|SM-T325|GT-P7503|SM-T531|SM-T330|SM-T530|SM-T705|SM-T705C|SM-T535|SM-T331|SM-T800|SM-T700|SM-T537|SM-T807|SM-P907A|SM-T337A|SM-T537A|SM-T707A|SM-T807A|SM-T237|SM-T807P|SM-P607T|SM-T217T|SM-T337T|SM-T807T|SM-T116NQ|SM-T116BU|SM-P550|SM-T350|SM-T550|SM-T9000|SM-P9000|SM-T705Y|SM-T805|GT-P3113|SM-T710|SM-T810|SM-T815|SM-T360|SM-T533|SM-T113|SM-T335|SM-T715|SM-T560|SM-T670|SM-T677|SM-T377|SM-T567|SM-T357T|SM-T555|SM-T561|SM-T713|SM-T719|SM-T813|SM-T819|SM-T580|SM-T355Y?|SM-T280|SM-T817A|SM-T820|SM-W700|SM-P580|SM-T587|SM-P350|SM-P555M|SM-P355M|SM-T113NU|SM-T815Y|SM-T585|SM-T285|SM-T825|SM-W708|SM-T835|SM-T830|SM-T837V|SM-T720|SM-T510|SM-T387V|SM-P610|SM-T290|SM-T515|SM-T590|SM-T595|SM-T725|SM-T817P|SM-P585N0|SM-T395|SM-T295|SM-T865|SM-P610N|SM-P615|SM-T970|SM-T380|SM-T5950|SM-T905|SM-T231|SM-T500|SM-T860", 12833 "Kindle": "Kindle|Silk.*Accelerated|Android.*\\b(KFOT|KFTT|KFJWI|KFJWA|KFOTE|KFSOWI|KFTHWI|KFTHWA|KFAPWI|KFAPWA|WFJWAE|KFSAWA|KFSAWI|KFASWI|KFARWI|KFFOWI|KFGIWI|KFMEWI)\\b|Android.*Silk\/[0-9.]+ like Chrome\/[0-9.]+ (?!Mobile)", 12834 "SurfaceTablet": "Windows NT [0-9.]+; ARM;.*(Tablet|ARMBJS)", 12835 "HPTablet": "HP Slate (7|8|10)|HP ElitePad 900|hp-tablet|EliteBook.*Touch|HP 8|Slate 21|HP SlateBook 10", 12836 "AsusTablet": "^.*PadFone((?!Mobile).)*$|Transformer|TF101|TF101G|TF300T|TF300TG|TF300TL|TF700T|TF700KL|TF701T|TF810C|ME171|ME301T|ME302C|ME371MG|ME370T|ME372MG|ME172V|ME173X|ME400C|Slider SL101|\\bK00F\\b|\\bK00C\\b|\\bK00E\\b|\\bK00L\\b|TX201LA|ME176C|ME102A|\\bM80TA\\b|ME372CL|ME560CG|ME372CG|ME302KL| K010 | K011 | K017 | K01E |ME572C|ME103K|ME170C|ME171C|\\bME70C\\b|ME581C|ME581CL|ME8510C|ME181C|P01Y|PO1MA|P01Z|\\bP027\\b|\\bP024\\b|\\bP00C\\b", 12837 "BlackBerryTablet": "PlayBook|RIM Tablet", 12838 "HTCtablet": "HTC_Flyer_P512|HTC Flyer|HTC Jetstream|HTC-P715a|HTC EVO View 4G|PG41200|PG09410", 12839 "MotorolaTablet": "xoom|sholest|MZ615|MZ605|MZ505|MZ601|MZ602|MZ603|MZ604|MZ606|MZ607|MZ608|MZ609|MZ615|MZ616|MZ617", 12840 "NookTablet": "Android.*Nook|NookColor|nook browser|BNRV200|BNRV200A|BNTV250|BNTV250A|BNTV400|BNTV600|LogicPD Zoom2", 12841 "AcerTablet": "Android.*; \\b(A100|A101|A110|A200|A210|A211|A500|A501|A510|A511|A700|A701|W500|W500P|W501|W501P|W510|W511|W700|G100|G100W|B1-A71|B1-710|B1-711|A1-810|A1-811|A1-830)\\b|W3-810|\\bA3-A10\\b|\\bA3-A11\\b|\\bA3-A20\\b|\\bA3-A30|A3-A40", 12842 "ToshibaTablet": "Android.*(AT100|AT105|AT200|AT205|AT270|AT275|AT300|AT305|AT1S5|AT500|AT570|AT700|AT830)|TOSHIBA.*FOLIO", 12843 "LGTablet": "\\bL-06C|LG-V909|LG-V900|LG-V700|LG-V510|LG-V500|LG-V410|LG-V400|LG-VK810\\b", 12844 "FujitsuTablet": "Android.*\\b(F-01D|F-02F|F-05E|F-10D|M532|Q572)\\b", 12845 "PrestigioTablet": "PMP3170B|PMP3270B|PMP3470B|PMP7170B|PMP3370B|PMP3570C|PMP5870C|PMP3670B|PMP5570C|PMP5770D|PMP3970B|PMP3870C|PMP5580C|PMP5880D|PMP5780D|PMP5588C|PMP7280C|PMP7280C3G|PMP7280|PMP7880D|PMP5597D|PMP5597|PMP7100D|PER3464|PER3274|PER3574|PER3884|PER5274|PER5474|PMP5097CPRO|PMP5097|PMP7380D|PMP5297C|PMP5297C_QUAD|PMP812E|PMP812E3G|PMP812F|PMP810E|PMP880TD|PMT3017|PMT3037|PMT3047|PMT3057|PMT7008|PMT5887|PMT5001|PMT5002", 12846 "LenovoTablet": "Lenovo TAB|Idea(Tab|Pad)( A1|A10| K1|)|ThinkPad([ ]+)?Tablet|YT3-850M|YT3-X90L|YT3-X90F|YT3-X90X|Lenovo.*(S2109|S2110|S5000|S6000|K3011|A3000|A3500|A1000|A2107|A2109|A1107|A5500|A7600|B6000|B8000|B8080)(-|)(FL|F|HV|H|)|TB-X103F|TB-X304X|TB-X304F|TB-X304L|TB-X505F|TB-X505L|TB-X505X|TB-X605F|TB-X605L|TB-8703F|TB-8703X|TB-8703N|TB-8704N|TB-8704F|TB-8704X|TB-8704V|TB-7304F|TB-7304I|TB-7304X|Tab2A7-10F|Tab2A7-20F|TB2-X30L|YT3-X50L|YT3-X50F|YT3-X50M|YT-X705F|YT-X703F|YT-X703L|YT-X705L|YT-X705X|TB2-X30F|TB2-X30L|TB2-X30M|A2107A-F|A2107A-H|TB3-730F|TB3-730M|TB3-730X|TB-7504F|TB-7504X|TB-X704F|TB-X104F|TB3-X70F|TB-X705F|TB-8504F|TB3-X70L|TB3-710F|TB-X704L", 12847 "DellTablet": "Venue 11|Venue 8|Venue 7|Dell Streak 10|Dell Streak 7", 12848 "YarvikTablet": "Android.*\\b(TAB210|TAB211|TAB224|TAB250|TAB260|TAB264|TAB310|TAB360|TAB364|TAB410|TAB411|TAB420|TAB424|TAB450|TAB460|TAB461|TAB464|TAB465|TAB467|TAB468|TAB07-100|TAB07-101|TAB07-150|TAB07-151|TAB07-152|TAB07-200|TAB07-201-3G|TAB07-210|TAB07-211|TAB07-212|TAB07-214|TAB07-220|TAB07-400|TAB07-485|TAB08-150|TAB08-200|TAB08-201-3G|TAB08-201-30|TAB09-100|TAB09-211|TAB09-410|TAB10-150|TAB10-201|TAB10-211|TAB10-400|TAB10-410|TAB13-201|TAB274EUK|TAB275EUK|TAB374EUK|TAB462EUK|TAB474EUK|TAB9-200)\\b", 12849 "MedionTablet": "Android.*\\bOYO\\b|LIFE.*(P9212|P9514|P9516|S9512)|LIFETAB", 12850 "ArnovaTablet": "97G4|AN10G2|AN7bG3|AN7fG3|AN8G3|AN8cG3|AN7G3|AN9G3|AN7dG3|AN7dG3ST|AN7dG3ChildPad|AN10bG3|AN10bG3DT|AN9G2", 12851 "IntensoTablet": "INM8002KP|INM1010FP|INM805ND|Intenso Tab|TAB1004", 12852 "IRUTablet": "M702pro", 12853 "MegafonTablet": "MegaFon V9|\\bZTE V9\\b|Android.*\\bMT7A\\b", 12854 "EbodaTablet": "E-Boda (Supreme|Impresspeed|Izzycomm|Essential)", 12855 "AllViewTablet": "Allview.*(Viva|Alldro|City|Speed|All TV|Frenzy|Quasar|Shine|TX1|AX1|AX2)", 12856 "ArchosTablet": "\\b(101G9|80G9|A101IT)\\b|Qilive 97R|Archos5|\\bARCHOS (70|79|80|90|97|101|FAMILYPAD|)(b|c|)(G10| Cobalt| TITANIUM(HD|)| Xenon| Neon|XSK| 2| XS 2| PLATINUM| CARBON|GAMEPAD)\\b", 12857 "AinolTablet": "NOVO7|NOVO8|NOVO10|Novo7Aurora|Novo7Basic|NOVO7PALADIN|novo9-Spark", 12858 "NokiaLumiaTablet": "Lumia 2520", 12859 "SonyTablet": "Sony.*Tablet|Xperia Tablet|Sony Tablet S|SO-03E|SGPT12|SGPT13|SGPT114|SGPT121|SGPT122|SGPT123|SGPT111|SGPT112|SGPT113|SGPT131|SGPT132|SGPT133|SGPT211|SGPT212|SGPT213|SGP311|SGP312|SGP321|EBRD1101|EBRD1102|EBRD1201|SGP351|SGP341|SGP511|SGP512|SGP521|SGP541|SGP551|SGP621|SGP641|SGP612|SOT31|SGP771|SGP611|SGP612|SGP712", 12860 "PhilipsTablet": "\\b(PI2010|PI3000|PI3100|PI3105|PI3110|PI3205|PI3210|PI3900|PI4010|PI7000|PI7100)\\b", 12861 "CubeTablet": "Android.*(K8GT|U9GT|U10GT|U16GT|U17GT|U18GT|U19GT|U20GT|U23GT|U30GT)|CUBE U8GT", 12862 "CobyTablet": "MID1042|MID1045|MID1125|MID1126|MID7012|MID7014|MID7015|MID7034|MID7035|MID7036|MID7042|MID7048|MID7127|MID8042|MID8048|MID8127|MID9042|MID9740|MID9742|MID7022|MID7010", 12863 "MIDTablet": "M9701|M9000|M9100|M806|M1052|M806|T703|MID701|MID713|MID710|MID727|MID760|MID830|MID728|MID933|MID125|MID810|MID732|MID120|MID930|MID800|MID731|MID900|MID100|MID820|MID735|MID980|MID130|MID833|MID737|MID960|MID135|MID860|MID736|MID140|MID930|MID835|MID733|MID4X10", 12864 "MSITablet": "MSI \\b(Primo 73K|Primo 73L|Primo 81L|Primo 77|Primo 93|Primo 75|Primo 76|Primo 73|Primo 81|Primo 91|Primo 90|Enjoy 71|Enjoy 7|Enjoy 10)\\b", 12865 "SMiTTablet": "Android.*(\\bMID\\b|MID-560|MTV-T1200|MTV-PND531|MTV-P1101|MTV-PND530)", 12866 "RockChipTablet": "Android.*(RK2818|RK2808A|RK2918|RK3066)|RK2738|RK2808A", 12867 "FlyTablet": "IQ310|Fly Vision", 12868 "bqTablet": "Android.*(bq)?.*\\b(Elcano|Curie|Edison|Maxwell|Kepler|Pascal|Tesla|Hypatia|Platon|Newton|Livingstone|Cervantes|Avant|Aquaris ([E|M]10|M8))\\b|Maxwell.*Lite|Maxwell.*Plus", 12869 "HuaweiTablet": "MediaPad|MediaPad 7 Youth|IDEOS S7|S7-201c|S7-202u|S7-101|S7-103|S7-104|S7-105|S7-106|S7-201|S7-Slim|M2-A01L|BAH-L09|BAH-W09|AGS-L09|CMR-AL19", 12870 "NecTablet": "\\bN-06D|\\bN-08D", 12871 "PantechTablet": "Pantech.*P4100", 12872 "BronchoTablet": "Broncho.*(N701|N708|N802|a710)", 12873 "VersusTablet": "TOUCHPAD.*[78910]|\\bTOUCHTAB\\b", 12874 "ZyncTablet": "z1000|Z99 2G|z930|z990|z909|Z919|z900", 12875 "PositivoTablet": "TB07STA|TB10STA|TB07FTA|TB10FTA", 12876 "NabiTablet": "Android.*\\bNabi", 12877 "KoboTablet": "Kobo Touch|\\bK080\\b|\\bVox\\b Build|\\bArc\\b Build", 12878 "DanewTablet": "DSlide.*\\b(700|701R|702|703R|704|802|970|971|972|973|974|1010|1012)\\b", 12879 "TexetTablet": "NaviPad|TB-772A|TM-7045|TM-7055|TM-9750|TM-7016|TM-7024|TM-7026|TM-7041|TM-7043|TM-7047|TM-8041|TM-9741|TM-9747|TM-9748|TM-9751|TM-7022|TM-7021|TM-7020|TM-7011|TM-7010|TM-7023|TM-7025|TM-7037W|TM-7038W|TM-7027W|TM-9720|TM-9725|TM-9737W|TM-1020|TM-9738W|TM-9740|TM-9743W|TB-807A|TB-771A|TB-727A|TB-725A|TB-719A|TB-823A|TB-805A|TB-723A|TB-715A|TB-707A|TB-705A|TB-709A|TB-711A|TB-890HD|TB-880HD|TB-790HD|TB-780HD|TB-770HD|TB-721HD|TB-710HD|TB-434HD|TB-860HD|TB-840HD|TB-760HD|TB-750HD|TB-740HD|TB-730HD|TB-722HD|TB-720HD|TB-700HD|TB-500HD|TB-470HD|TB-431HD|TB-430HD|TB-506|TB-504|TB-446|TB-436|TB-416|TB-146SE|TB-126SE", 12880 "PlaystationTablet": "Playstation.*(Portable|Vita)", 12881 "TrekstorTablet": "ST10416-1|VT10416-1|ST70408-1|ST702xx-1|ST702xx-2|ST80208|ST97216|ST70104-2|VT10416-2|ST10216-2A|SurfTab", 12882 "PyleAudioTablet": "\\b(PTBL10CEU|PTBL10C|PTBL72BC|PTBL72BCEU|PTBL7CEU|PTBL7C|PTBL92BC|PTBL92BCEU|PTBL9CEU|PTBL9CUK|PTBL9C)\\b", 12883 "AdvanTablet": "Android.* \\b(E3A|T3X|T5C|T5B|T3E|T3C|T3B|T1J|T1F|T2A|T1H|T1i|E1C|T1-E|T5-A|T4|E1-B|T2Ci|T1-B|T1-D|O1-A|E1-A|T1-A|T3A|T4i)\\b ", 12884 "DanyTechTablet": "Genius Tab G3|Genius Tab S2|Genius Tab Q3|Genius Tab G4|Genius Tab Q4|Genius Tab G-II|Genius TAB GII|Genius TAB GIII|Genius Tab S1", 12885 "GalapadTablet": "Android [0-9.]+; [a-z-]+; \\bG1\\b", 12886 "MicromaxTablet": "Funbook|Micromax.*\\b(P250|P560|P360|P362|P600|P300|P350|P500|P275)\\b", 12887 "KarbonnTablet": "Android.*\\b(A39|A37|A34|ST8|ST10|ST7|Smart Tab3|Smart Tab2)\\b", 12888 "AllFineTablet": "Fine7 Genius|Fine7 Shine|Fine7 Air|Fine8 Style|Fine9 More|Fine10 Joy|Fine11 Wide", 12889 "PROSCANTablet": "\\b(PEM63|PLT1023G|PLT1041|PLT1044|PLT1044G|PLT1091|PLT4311|PLT4311PL|PLT4315|PLT7030|PLT7033|PLT7033D|PLT7035|PLT7035D|PLT7044K|PLT7045K|PLT7045KB|PLT7071KG|PLT7072|PLT7223G|PLT7225G|PLT7777G|PLT7810K|PLT7849G|PLT7851G|PLT7852G|PLT8015|PLT8031|PLT8034|PLT8036|PLT8080K|PLT8082|PLT8088|PLT8223G|PLT8234G|PLT8235G|PLT8816K|PLT9011|PLT9045K|PLT9233G|PLT9735|PLT9760G|PLT9770G)\\b", 12890 "YONESTablet": "BQ1078|BC1003|BC1077|RK9702|BC9730|BC9001|IT9001|BC7008|BC7010|BC708|BC728|BC7012|BC7030|BC7027|BC7026", 12891 "ChangJiaTablet": "TPC7102|TPC7103|TPC7105|TPC7106|TPC7107|TPC7201|TPC7203|TPC7205|TPC7210|TPC7708|TPC7709|TPC7712|TPC7110|TPC8101|TPC8103|TPC8105|TPC8106|TPC8203|TPC8205|TPC8503|TPC9106|TPC9701|TPC97101|TPC97103|TPC97105|TPC97106|TPC97111|TPC97113|TPC97203|TPC97603|TPC97809|TPC97205|TPC10101|TPC10103|TPC10106|TPC10111|TPC10203|TPC10205|TPC10503", 12892 "GUTablet": "TX-A1301|TX-M9002|Q702|kf026", 12893 "PointOfViewTablet": "TAB-P506|TAB-navi-7-3G-M|TAB-P517|TAB-P-527|TAB-P701|TAB-P703|TAB-P721|TAB-P731N|TAB-P741|TAB-P825|TAB-P905|TAB-P925|TAB-PR945|TAB-PL1015|TAB-P1025|TAB-PI1045|TAB-P1325|TAB-PROTAB[0-9]+|TAB-PROTAB25|TAB-PROTAB26|TAB-PROTAB27|TAB-PROTAB26XL|TAB-PROTAB2-IPS9|TAB-PROTAB30-IPS9|TAB-PROTAB25XXL|TAB-PROTAB26-IPS10|TAB-PROTAB30-IPS10", 12894 "OvermaxTablet": "OV-(SteelCore|NewBase|Basecore|Baseone|Exellen|Quattor|EduTab|Solution|ACTION|BasicTab|TeddyTab|MagicTab|Stream|TB-08|TB-09)|Qualcore 1027", 12895 "HCLTablet": "HCL.*Tablet|Connect-3G-2.0|Connect-2G-2.0|ME Tablet U1|ME Tablet U2|ME Tablet G1|ME Tablet X1|ME Tablet Y2|ME Tablet Sync", 12896 "DPSTablet": "DPS Dream 9|DPS Dual 7", 12897 "VistureTablet": "V97 HD|i75 3G|Visture V4( HD)?|Visture V5( HD)?|Visture V10", 12898 "CrestaTablet": "CTP(-)?810|CTP(-)?818|CTP(-)?828|CTP(-)?838|CTP(-)?888|CTP(-)?978|CTP(-)?980|CTP(-)?987|CTP(-)?988|CTP(-)?989", 12899 "MediatekTablet": "\\bMT8125|MT8389|MT8135|MT8377\\b", 12900 "ConcordeTablet": "Concorde([ ]+)?Tab|ConCorde ReadMan", 12901 "GoCleverTablet": "GOCLEVER TAB|A7GOCLEVER|M1042|M7841|M742|R1042BK|R1041|TAB A975|TAB A7842|TAB A741|TAB A741L|TAB M723G|TAB M721|TAB A1021|TAB I921|TAB R721|TAB I720|TAB T76|TAB R70|TAB R76.2|TAB R106|TAB R83.2|TAB M813G|TAB I721|GCTA722|TAB I70|TAB I71|TAB S73|TAB R73|TAB R74|TAB R93|TAB R75|TAB R76.1|TAB A73|TAB A93|TAB A93.2|TAB T72|TAB R83|TAB R974|TAB R973|TAB A101|TAB A103|TAB A104|TAB A104.2|R105BK|M713G|A972BK|TAB A971|TAB R974.2|TAB R104|TAB R83.3|TAB A1042", 12902 "ModecomTablet": "FreeTAB 9000|FreeTAB 7.4|FreeTAB 7004|FreeTAB 7800|FreeTAB 2096|FreeTAB 7.5|FreeTAB 1014|FreeTAB 1001 |FreeTAB 8001|FreeTAB 9706|FreeTAB 9702|FreeTAB 7003|FreeTAB 7002|FreeTAB 1002|FreeTAB 7801|FreeTAB 1331|FreeTAB 1004|FreeTAB 8002|FreeTAB 8014|FreeTAB 9704|FreeTAB 1003", 12903 "VoninoTablet": "\\b(Argus[ _]?S|Diamond[ _]?79HD|Emerald[ _]?78E|Luna[ _]?70C|Onyx[ _]?S|Onyx[ _]?Z|Orin[ _]?HD|Orin[ _]?S|Otis[ _]?S|SpeedStar[ _]?S|Magnet[ _]?M9|Primus[ _]?94[ _]?3G|Primus[ _]?94HD|Primus[ _]?QS|Android.*\\bQ8\\b|Sirius[ _]?EVO[ _]?QS|Sirius[ _]?QS|Spirit[ _]?S)\\b", 12904 "ECSTablet": "V07OT2|TM105A|S10OT1|TR10CS1", 12905 "StorexTablet": "eZee[_']?(Tab|Go)[0-9]+|TabLC7|Looney Tunes Tab", 12906 "VodafoneTablet": "SmartTab([ ]+)?[0-9]+|SmartTabII10|SmartTabII7|VF-1497|VFD 1400", 12907 "EssentielBTablet": "Smart[ ']?TAB[ ]+?[0-9]+|Family[ ']?TAB2", 12908 "RossMoorTablet": "RM-790|RM-997|RMD-878G|RMD-974R|RMT-705A|RMT-701|RME-601|RMT-501|RMT-711", 12909 "iMobileTablet": "i-mobile i-note", 12910 "TolinoTablet": "tolino tab [0-9.]+|tolino shine", 12911 "AudioSonicTablet": "\\bC-22Q|T7-QC|T-17B|T-17P\\b", 12912 "AMPETablet": "Android.* A78 ", 12913 "SkkTablet": "Android.* (SKYPAD|PHOENIX|CYCLOPS)", 12914 "TecnoTablet": "TECNO P9|TECNO DP8D", 12915 "JXDTablet": "Android.* \\b(F3000|A3300|JXD5000|JXD3000|JXD2000|JXD300B|JXD300|S5800|S7800|S602b|S5110b|S7300|S5300|S602|S603|S5100|S5110|S601|S7100a|P3000F|P3000s|P101|P200s|P1000m|P200m|P9100|P1000s|S6600b|S908|P1000|P300|S18|S6600|S9100)\\b", 12916 "iJoyTablet": "Tablet (Spirit 7|Essentia|Galatea|Fusion|Onix 7|Landa|Titan|Scooby|Deox|Stella|Themis|Argon|Unique 7|Sygnus|Hexen|Finity 7|Cream|Cream X2|Jade|Neon 7|Neron 7|Kandy|Scape|Saphyr 7|Rebel|Biox|Rebel|Rebel 8GB|Myst|Draco 7|Myst|Tab7-004|Myst|Tadeo Jones|Tablet Boing|Arrow|Draco Dual Cam|Aurix|Mint|Amity|Revolution|Finity 9|Neon 9|T9w|Amity 4GB Dual Cam|Stone 4GB|Stone 8GB|Andromeda|Silken|X2|Andromeda II|Halley|Flame|Saphyr 9,7|Touch 8|Planet|Triton|Unique 10|Hexen 10|Memphis 4GB|Memphis 8GB|Onix 10)", 12917 "FX2Tablet": "FX2 PAD7|FX2 PAD10", 12918 "XoroTablet": "KidsPAD 701|PAD[ ]?712|PAD[ ]?714|PAD[ ]?716|PAD[ ]?717|PAD[ ]?718|PAD[ ]?720|PAD[ ]?721|PAD[ ]?722|PAD[ ]?790|PAD[ ]?792|PAD[ ]?900|PAD[ ]?9715D|PAD[ ]?9716DR|PAD[ ]?9718DR|PAD[ ]?9719QR|PAD[ ]?9720QR|TelePAD1030|Telepad1032|TelePAD730|TelePAD731|TelePAD732|TelePAD735Q|TelePAD830|TelePAD9730|TelePAD795|MegaPAD 1331|MegaPAD 1851|MegaPAD 2151", 12919 "ViewsonicTablet": "ViewPad 10pi|ViewPad 10e|ViewPad 10s|ViewPad E72|ViewPad7|ViewPad E100|ViewPad 7e|ViewSonic VB733|VB100a", 12920 "VerizonTablet": "QTAQZ3|QTAIR7|QTAQTZ3|QTASUN1|QTASUN2|QTAXIA1", 12921 "OdysTablet": "LOOX|XENO10|ODYS[ -](Space|EVO|Xpress|NOON)|\\bXELIO\\b|Xelio10Pro|XELIO7PHONETAB|XELIO10EXTREME|XELIOPT2|NEO_QUAD10", 12922 "CaptivaTablet": "CAPTIVA PAD", 12923 "IconbitTablet": "NetTAB|NT-3702|NT-3702S|NT-3702S|NT-3603P|NT-3603P|NT-0704S|NT-0704S|NT-3805C|NT-3805C|NT-0806C|NT-0806C|NT-0909T|NT-0909T|NT-0907S|NT-0907S|NT-0902S|NT-0902S", 12924 "TeclastTablet": "T98 4G|\\bP80\\b|\\bX90HD\\b|X98 Air|X98 Air 3G|\\bX89\\b|P80 3G|\\bX80h\\b|P98 Air|\\bX89HD\\b|P98 3G|\\bP90HD\\b|P89 3G|X98 3G|\\bP70h\\b|P79HD 3G|G18d 3G|\\bP79HD\\b|\\bP89s\\b|\\bA88\\b|\\bP10HD\\b|\\bP19HD\\b|G18 3G|\\bP78HD\\b|\\bA78\\b|\\bP75\\b|G17s 3G|G17h 3G|\\bP85t\\b|\\bP90\\b|\\bP11\\b|\\bP98t\\b|\\bP98HD\\b|\\bG18d\\b|\\bP85s\\b|\\bP11HD\\b|\\bP88s\\b|\\bA80HD\\b|\\bA80se\\b|\\bA10h\\b|\\bP89\\b|\\bP78s\\b|\\bG18\\b|\\bP85\\b|\\bA70h\\b|\\bA70\\b|\\bG17\\b|\\bP18\\b|\\bA80s\\b|\\bA11s\\b|\\bP88HD\\b|\\bA80h\\b|\\bP76s\\b|\\bP76h\\b|\\bP98\\b|\\bA10HD\\b|\\bP78\\b|\\bP88\\b|\\bA11\\b|\\bA10t\\b|\\bP76a\\b|\\bP76t\\b|\\bP76e\\b|\\bP85HD\\b|\\bP85a\\b|\\bP86\\b|\\bP75HD\\b|\\bP76v\\b|\\bA12\\b|\\bP75a\\b|\\bA15\\b|\\bP76Ti\\b|\\bP81HD\\b|\\bA10\\b|\\bT760VE\\b|\\bT720HD\\b|\\bP76\\b|\\bP73\\b|\\bP71\\b|\\bP72\\b|\\bT720SE\\b|\\bC520Ti\\b|\\bT760\\b|\\bT720VE\\b|T720-3GE|T720-WiFi", 12925 "OndaTablet": "\\b(V975i|Vi30|VX530|V701|Vi60|V701s|Vi50|V801s|V719|Vx610w|VX610W|V819i|Vi10|VX580W|Vi10|V711s|V813|V811|V820w|V820|Vi20|V711|VI30W|V712|V891w|V972|V819w|V820w|Vi60|V820w|V711|V813s|V801|V819|V975s|V801|V819|V819|V818|V811|V712|V975m|V101w|V961w|V812|V818|V971|V971s|V919|V989|V116w|V102w|V973|Vi40)\\b[\\s]+|V10 \\b4G\\b", 12926 "JaytechTablet": "TPC-PA762", 12927 "BlaupunktTablet": "Endeavour 800NG|Endeavour 1010", 12928 "DigmaTablet": "\\b(iDx10|iDx9|iDx8|iDx7|iDxD7|iDxD8|iDsQ8|iDsQ7|iDsQ8|iDsD10|iDnD7|3TS804H|iDsQ11|iDj7|iDs10)\\b", 12929 "EvolioTablet": "ARIA_Mini_wifi|Aria[ _]Mini|Evolio X10|Evolio X7|Evolio X8|\\bEvotab\\b|\\bNeura\\b", 12930 "LavaTablet": "QPAD E704|\\bIvoryS\\b|E-TAB IVORY|\\bE-TAB\\b", 12931 "AocTablet": "MW0811|MW0812|MW0922|MTK8382|MW1031|MW0831|MW0821|MW0931|MW0712", 12932 "MpmanTablet": "MP11 OCTA|MP10 OCTA|MPQC1114|MPQC1004|MPQC994|MPQC974|MPQC973|MPQC804|MPQC784|MPQC780|\\bMPG7\\b|MPDCG75|MPDCG71|MPDC1006|MP101DC|MPDC9000|MPDC905|MPDC706HD|MPDC706|MPDC705|MPDC110|MPDC100|MPDC99|MPDC97|MPDC88|MPDC8|MPDC77|MP709|MID701|MID711|MID170|MPDC703|MPQC1010", 12933 "CelkonTablet": "CT695|CT888|CT[\\s]?910|CT7 Tab|CT9 Tab|CT3 Tab|CT2 Tab|CT1 Tab|C820|C720|\\bCT-1\\b", 12934 "WolderTablet": "miTab \\b(DIAMOND|SPACE|BROOKLYN|NEO|FLY|MANHATTAN|FUNK|EVOLUTION|SKY|GOCAR|IRON|GENIUS|POP|MINT|EPSILON|BROADWAY|JUMP|HOP|LEGEND|NEW AGE|LINE|ADVANCE|FEEL|FOLLOW|LIKE|LINK|LIVE|THINK|FREEDOM|CHICAGO|CLEVELAND|BALTIMORE-GH|IOWA|BOSTON|SEATTLE|PHOENIX|DALLAS|IN 101|MasterChef)\\b", 12935 "MediacomTablet": "M-MPI10C3G|M-SP10EG|M-SP10EGP|M-SP10HXAH|M-SP7HXAH|M-SP10HXBH|M-SP8HXAH|M-SP8MXA", 12936 "MiTablet": "\\bMI PAD\\b|\\bHM NOTE 1W\\b", 12937 "NibiruTablet": "Nibiru M1|Nibiru Jupiter One", 12938 "NexoTablet": "NEXO NOVA|NEXO 10|NEXO AVIO|NEXO FREE|NEXO GO|NEXO EVO|NEXO 3G|NEXO SMART|NEXO KIDDO|NEXO MOBI", 12939 "LeaderTablet": "TBLT10Q|TBLT10I|TBL-10WDKB|TBL-10WDKBO2013|TBL-W230V2|TBL-W450|TBL-W500|SV572|TBLT7I|TBA-AC7-8G|TBLT79|TBL-8W16|TBL-10W32|TBL-10WKB|TBL-W100", 12940 "UbislateTablet": "UbiSlate[\\s]?7C", 12941 "PocketBookTablet": "Pocketbook", 12942 "KocasoTablet": "\\b(TB-1207)\\b", 12943 "HisenseTablet": "\\b(F5281|E2371)\\b", 12944 "Hudl": "Hudl HT7S3|Hudl 2", 12945 "TelstraTablet": "T-Hub2", 12946 "GenericTablet": "Android.*\\b97D\\b|Tablet(?!.*PC)|BNTV250A|MID-WCDMA|LogicPD Zoom2|\\bA7EB\\b|CatNova8|A1_07|CT704|CT1002|\\bM721\\b|rk30sdk|\\bEVOTAB\\b|M758A|ET904|ALUMIUM10|Smartfren Tab|Endeavour 1010|Tablet-PC-4|Tagi Tab|\\bM6pro\\b|CT1020W|arc 10HD|\\bTP750\\b|\\bQTAQZ3\\b|WVT101|TM1088|KT107" 12947 }, 12948 "oss": { 12949 "AndroidOS": "Android", 12950 "BlackBerryOS": "blackberry|\\bBB10\\b|rim tablet os", 12951 "PalmOS": "PalmOS|avantgo|blazer|elaine|hiptop|palm|plucker|xiino", 12952 "SymbianOS": "Symbian|SymbOS|Series60|Series40|SYB-[0-9]+|\\bS60\\b", 12953 "WindowsMobileOS": "Windows CE.*(PPC|Smartphone|Mobile|[0-9]{3}x[0-9]{3})|Windows Mobile|Windows Phone [0-9.]+|WCE;", 12954 "WindowsPhoneOS": "Windows Phone 10.0|Windows Phone 8.1|Windows Phone 8.0|Windows Phone OS|XBLWP7|ZuneWP7|Windows NT 6.[23]; ARM;", 12955 "iOS": "\\biPhone.*Mobile|\\biPod|\\biPad|AppleCoreMedia", 12956 "iPadOS": "CPU OS 13", 12957 "SailfishOS": "Sailfish", 12958 "MeeGoOS": "MeeGo", 12959 "MaemoOS": "Maemo", 12960 "JavaOS": "J2ME\/|\\bMIDP\\b|\\bCLDC\\b", 12961 "webOS": "webOS|hpwOS", 12962 "badaOS": "\\bBada\\b", 12963 "BREWOS": "BREW" 12964 }, 12965 "uas": { 12966 "Chrome": "\\bCrMo\\b|CriOS|Android.*Chrome\/[.0-9]* (Mobile)?", 12967 "Dolfin": "\\bDolfin\\b", 12968 "Opera": "Opera.*Mini|Opera.*Mobi|Android.*Opera|Mobile.*OPR\/[0-9.]+$|Coast\/[0-9.]+", 12969 "Skyfire": "Skyfire", 12970 "Edge": "\\bEdgiOS\\b|Mobile Safari\/[.0-9]* Edge", 12971 "IE": "IEMobile|MSIEMobile", 12972 "Firefox": "fennec|firefox.*maemo|(Mobile|Tablet).*Firefox|Firefox.*Mobile|FxiOS", 12973 "Bolt": "bolt", 12974 "TeaShark": "teashark", 12975 "Blazer": "Blazer", 12976 "Safari": "Version((?!\\bEdgiOS\\b).)*Mobile.*Safari|Safari.*Mobile|MobileSafari", 12977 "WeChat": "\\bMicroMessenger\\b", 12978 "UCBrowser": "UC.*Browser|UCWEB", 12979 "baiduboxapp": "baiduboxapp", 12980 "baidubrowser": "baidubrowser", 12981 "DiigoBrowser": "DiigoBrowser", 12982 "Mercury": "\\bMercury\\b", 12983 "ObigoBrowser": "Obigo", 12984 "NetFront": "NF-Browser", 12985 "GenericBrowser": "NokiaBrowser|OviBrowser|OneBrowser|TwonkyBeamBrowser|SEMC.*Browser|FlyFlow|Minimo|NetFront|Novarra-Vision|MQQBrowser|MicroMessenger", 12986 "PaleMoon": "Android.*PaleMoon|Mobile.*PaleMoon" 12987 }, 12988 "props": { 12989 "Mobile": "Mobile\/[VER]", 12990 "Build": "Build\/[VER]", 12991 "Version": "Version\/[VER]", 12992 "VendorID": "VendorID\/[VER]", 12993 "iPad": "iPad.*CPU[a-z ]+[VER]", 12994 "iPhone": "iPhone.*CPU[a-z ]+[VER]", 12995 "iPod": "iPod.*CPU[a-z ]+[VER]", 12996 "Kindle": "Kindle\/[VER]", 12997 "Chrome": [ 12998 "Chrome\/[VER]", 12999 "CriOS\/[VER]", 13000 "CrMo\/[VER]" 13001 ], 13002 "Coast": [ 13003 "Coast\/[VER]" 13004 ], 13005 "Dolfin": "Dolfin\/[VER]", 13006 "Firefox": [ 13007 "Firefox\/[VER]", 13008 "FxiOS\/[VER]" 13009 ], 13010 "Fennec": "Fennec\/[VER]", 13011 "Edge": "Edge\/[VER]", 13012 "IE": [ 13013 "IEMobile\/[VER];", 13014 "IEMobile [VER]", 13015 "MSIE [VER];", 13016 "Trident\/[0-9.]+;.*rv:[VER]" 13017 ], 13018 "NetFront": "NetFront\/[VER]", 13019 "NokiaBrowser": "NokiaBrowser\/[VER]", 13020 "Opera": [ 13021 " OPR\/[VER]", 13022 "Opera Mini\/[VER]", 13023 "Version\/[VER]" 13024 ], 13025 "Opera Mini": "Opera Mini\/[VER]", 13026 "Opera Mobi": "Version\/[VER]", 13027 "UCBrowser": [ 13028 "UCWEB[VER]", 13029 "UC.*Browser\/[VER]" 13030 ], 13031 "MQQBrowser": "MQQBrowser\/[VER]", 13032 "MicroMessenger": "MicroMessenger\/[VER]", 13033 "baiduboxapp": "baiduboxapp\/[VER]", 13034 "baidubrowser": "baidubrowser\/[VER]", 13035 "SamsungBrowser": "SamsungBrowser\/[VER]", 13036 "Iron": "Iron\/[VER]", 13037 "Safari": [ 13038 "Version\/[VER]", 13039 "Safari\/[VER]" 13040 ], 13041 "Skyfire": "Skyfire\/[VER]", 13042 "Tizen": "Tizen\/[VER]", 13043 "Webkit": "webkit[ \/][VER]", 13044 "PaleMoon": "PaleMoon\/[VER]", 13045 "SailfishBrowser": "SailfishBrowser\/[VER]", 13046 "Gecko": "Gecko\/[VER]", 13047 "Trident": "Trident\/[VER]", 13048 "Presto": "Presto\/[VER]", 13049 "Goanna": "Goanna\/[VER]", 13050 "iOS": " \\bi?OS\\b [VER][ ;]{1}", 13051 "Android": "Android [VER]", 13052 "Sailfish": "Sailfish [VER]", 13053 "BlackBerry": [ 13054 "BlackBerry[\\w]+\/[VER]", 13055 "BlackBerry.*Version\/[VER]", 13056 "Version\/[VER]" 13057 ], 13058 "BREW": "BREW [VER]", 13059 "Java": "Java\/[VER]", 13060 "Windows Phone OS": [ 13061 "Windows Phone OS [VER]", 13062 "Windows Phone [VER]" 13063 ], 13064 "Windows Phone": "Windows Phone [VER]", 13065 "Windows CE": "Windows CE\/[VER]", 13066 "Windows NT": "Windows NT [VER]", 13067 "Symbian": [ 13068 "SymbianOS\/[VER]", 13069 "Symbian\/[VER]" 13070 ], 13071 "webOS": [ 13072 "webOS\/[VER]", 13073 "hpwOS\/[VER];" 13074 ] 13075 }, 13076 "utils": { 13077 "Bot": "Googlebot|facebookexternalhit|Google-AMPHTML|s~amp-validator|AdsBot-Google|Google Keyword Suggestion|Facebot|YandexBot|YandexMobileBot|bingbot|ia_archiver|AhrefsBot|Ezooms|GSLFbot|WBSearchBot|Twitterbot|TweetmemeBot|Twikle|PaperLiBot|Wotbox|UnwindFetchor|Exabot|MJ12bot|YandexImages|TurnitinBot|Pingdom|contentkingapp|AspiegelBot", 13078 "MobileBot": "Googlebot-Mobile|AdsBot-Google-Mobile|YahooSeeker\/M1A1-R2D2", 13079 "DesktopMode": "WPDesktop", 13080 "TV": "SonyDTV|HbbTV", 13081 "WebKit": "(webkit)[ \/]([\\w.]+)", 13082 "Console": "\\b(Nintendo|Nintendo WiiU|Nintendo 3DS|Nintendo Switch|PLAYSTATION|Xbox)\\b", 13083 "Watch": "SM-V700" 13084 } 13085}; 13086 13087 // following patterns come from http://detectmobilebrowsers.com/ 13088 impl.detectMobileBrowsers = { 13089 fullPattern: /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i, 13090 shortPattern: /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i, 13091 tabletPattern: /android|ipad|playbook|silk/i 13092 }; 13093 13094 var hasOwnProp = Object.prototype.hasOwnProperty, 13095 isArray; 13096 13097 impl.FALLBACK_PHONE = 'UnknownPhone'; 13098 impl.FALLBACK_TABLET = 'UnknownTablet'; 13099 impl.FALLBACK_MOBILE = 'UnknownMobile'; 13100 13101 isArray = ('isArray' in Array) ? 13102 Array.isArray : function (value) { return Object.prototype.toString.call(value) === '[object Array]'; }; 13103 13104 function equalIC(a, b) { 13105 return a != null && b != null && a.toLowerCase() === b.toLowerCase(); 13106 } 13107 13108 function containsIC(array, value) { 13109 var valueLC, i, len = array.length; 13110 if (!len || !value) { 13111 return false; 13112 } 13113 valueLC = value.toLowerCase(); 13114 for (i = 0; i < len; ++i) { 13115 if (valueLC === array[i].toLowerCase()) { 13116 return true; 13117 } 13118 } 13119 return false; 13120 } 13121 13122 function convertPropsToRegExp(object) { 13123 for (var key in object) { 13124 if (hasOwnProp.call(object, key)) { 13125 object[key] = new RegExp(object[key], 'i'); 13126 } 13127 } 13128 } 13129 13130 function prepareUserAgent(userAgent) { 13131 return (userAgent || '').substr(0, 500); // mitigate vulnerable to ReDoS 13132 } 13133 13134 (function init() { 13135 var key, values, value, i, len, verPos, mobileDetectRules = impl.mobileDetectRules; 13136 for (key in mobileDetectRules.props) { 13137 if (hasOwnProp.call(mobileDetectRules.props, key)) { 13138 values = mobileDetectRules.props[key]; 13139 if (!isArray(values)) { 13140 values = [values]; 13141 } 13142 len = values.length; 13143 for (i = 0; i < len; ++i) { 13144 value = values[i]; 13145 verPos = value.indexOf('[VER]'); 13146 if (verPos >= 0) { 13147 value = value.substring(0, verPos) + '([\\w._\\+]+)' + value.substring(verPos + 5); 13148 } 13149 values[i] = new RegExp(value, 'i'); 13150 } 13151 mobileDetectRules.props[key] = values; 13152 } 13153 } 13154 convertPropsToRegExp(mobileDetectRules.oss); 13155 convertPropsToRegExp(mobileDetectRules.phones); 13156 convertPropsToRegExp(mobileDetectRules.tablets); 13157 convertPropsToRegExp(mobileDetectRules.uas); 13158 convertPropsToRegExp(mobileDetectRules.utils); 13159 13160 // copy some patterns to oss0 which are tested first (see issue#15) 13161 mobileDetectRules.oss0 = { 13162 WindowsPhoneOS: mobileDetectRules.oss.WindowsPhoneOS, 13163 WindowsMobileOS: mobileDetectRules.oss.WindowsMobileOS 13164 }; 13165 }()); 13166 13167 /** 13168 * Test userAgent string against a set of rules and find the first matched key. 13169 * @param {Object} rules (key is String, value is RegExp) 13170 * @param {String} userAgent the navigator.userAgent (or HTTP-Header 'User-Agent'). 13171 * @returns {String|null} the matched key if found, otherwise <tt>null</tt> 13172 * @private 13173 */ 13174 impl.findMatch = function(rules, userAgent) { 13175 for (var key in rules) { 13176 if (hasOwnProp.call(rules, key)) { 13177 if (rules[key].test(userAgent)) { 13178 return key; 13179 } 13180 } 13181 } 13182 return null; 13183 }; 13184 13185 /** 13186 * Test userAgent string against a set of rules and return an array of matched keys. 13187 * @param {Object} rules (key is String, value is RegExp) 13188 * @param {String} userAgent the navigator.userAgent (or HTTP-Header 'User-Agent'). 13189 * @returns {Array} an array of matched keys, may be empty when there is no match, but not <tt>null</tt> 13190 * @private 13191 */ 13192 impl.findMatches = function(rules, userAgent) { 13193 var result = []; 13194 for (var key in rules) { 13195 if (hasOwnProp.call(rules, key)) { 13196 if (rules[key].test(userAgent)) { 13197 result.push(key); 13198 } 13199 } 13200 } 13201 return result; 13202 }; 13203 13204 /** 13205 * Check the version of the given property in the User-Agent. 13206 * 13207 * @param {String} propertyName 13208 * @param {String} userAgent 13209 * @return {String} version or <tt>null</tt> if version not found 13210 * @private 13211 */ 13212 impl.getVersionStr = function (propertyName, userAgent) { 13213 var props = impl.mobileDetectRules.props, patterns, i, len, match; 13214 if (hasOwnProp.call(props, propertyName)) { 13215 patterns = props[propertyName]; 13216 len = patterns.length; 13217 for (i = 0; i < len; ++i) { 13218 match = patterns[i].exec(userAgent); 13219 if (match !== null) { 13220 return match[1]; 13221 } 13222 } 13223 } 13224 return null; 13225 }; 13226 13227 /** 13228 * Check the version of the given property in the User-Agent. 13229 * Will return a float number. (eg. 2_0 will return 2.0, 4.3.1 will return 4.31) 13230 * 13231 * @param {String} propertyName 13232 * @param {String} userAgent 13233 * @return {Number} version or <tt>NaN</tt> if version not found 13234 * @private 13235 */ 13236 impl.getVersion = function (propertyName, userAgent) { 13237 var version = impl.getVersionStr(propertyName, userAgent); 13238 return version ? impl.prepareVersionNo(version) : NaN; 13239 }; 13240 13241 /** 13242 * Prepare the version number. 13243 * 13244 * @param {String} version 13245 * @return {Number} the version number as a floating number 13246 * @private 13247 */ 13248 impl.prepareVersionNo = function (version) { 13249 var numbers; 13250 13251 numbers = version.split(/[a-z._ \/\-]/i); 13252 if (numbers.length === 1) { 13253 version = numbers[0]; 13254 } 13255 if (numbers.length > 1) { 13256 version = numbers[0] + '.'; 13257 numbers.shift(); 13258 version += numbers.join(''); 13259 } 13260 return Number(version); 13261 }; 13262 13263 impl.isMobileFallback = function (userAgent) { 13264 return impl.detectMobileBrowsers.fullPattern.test(userAgent) || 13265 impl.detectMobileBrowsers.shortPattern.test(userAgent.substr(0,4)); 13266 }; 13267 13268 impl.isTabletFallback = function (userAgent) { 13269 return impl.detectMobileBrowsers.tabletPattern.test(userAgent); 13270 }; 13271 13272 impl.prepareDetectionCache = function (cache, userAgent, maxPhoneWidth) { 13273 if (cache.mobile !== undefined) { 13274 return; 13275 } 13276 var phone, tablet, phoneSized; 13277 13278 // first check for stronger tablet rules, then phone (see issue#5) 13279 tablet = impl.findMatch(impl.mobileDetectRules.tablets, userAgent); 13280 if (tablet) { 13281 cache.mobile = cache.tablet = tablet; 13282 cache.phone = null; 13283 return; // unambiguously identified as tablet 13284 } 13285 13286 phone = impl.findMatch(impl.mobileDetectRules.phones, userAgent); 13287 if (phone) { 13288 cache.mobile = cache.phone = phone; 13289 cache.tablet = null; 13290 return; // unambiguously identified as phone 13291 } 13292 13293 // our rules haven't found a match -> try more general fallback rules 13294 if (impl.isMobileFallback(userAgent)) { 13295 phoneSized = MobileDetect.isPhoneSized(maxPhoneWidth); 13296 if (phoneSized === undefined) { 13297 cache.mobile = impl.FALLBACK_MOBILE; 13298 cache.tablet = cache.phone = null; 13299 } else if (phoneSized) { 13300 cache.mobile = cache.phone = impl.FALLBACK_PHONE; 13301 cache.tablet = null; 13302 } else { 13303 cache.mobile = cache.tablet = impl.FALLBACK_TABLET; 13304 cache.phone = null; 13305 } 13306 } else if (impl.isTabletFallback(userAgent)) { 13307 cache.mobile = cache.tablet = impl.FALLBACK_TABLET; 13308 cache.phone = null; 13309 } else { 13310 // not mobile at all! 13311 cache.mobile = cache.tablet = cache.phone = null; 13312 } 13313 }; 13314 13315 // t is a reference to a MobileDetect instance 13316 impl.mobileGrade = function (t) { 13317 // impl note: 13318 // To keep in sync w/ Mobile_Detect.php easily, the following code is tightly aligned to the PHP version. 13319 // When changes are made in Mobile_Detect.php, copy this method and replace: 13320 // $this-> / t. 13321 // self::MOBILE_GRADE_(.) / '$1' 13322 // , self::VERSION_TYPE_FLOAT / (nothing) 13323 // isIOS() / os('iOS') 13324 // [reg] / (nothing) <-- jsdelivr complaining about unescaped unicode character U+00AE 13325 var $isMobile = t.mobile() !== null; 13326 13327 if ( 13328 // Apple iOS 3.2-5.1 - Tested on the original iPad (4.3 / 5.0), iPad 2 (4.3), iPad 3 (5.1), original iPhone (3.1), iPhone 3 (3.2), 3GS (4.3), 4 (4.3 / 5.0), and 4S (5.1) 13329 t.os('iOS') && t.version('iPad')>=4.3 || 13330 t.os('iOS') && t.version('iPhone')>=3.1 || 13331 t.os('iOS') && t.version('iPod')>=3.1 || 13332 13333 // Android 2.1-2.3 - Tested on the HTC Incredible (2.2), original Droid (2.2), HTC Aria (2.1), Google Nexus S (2.3). Functional on 1.5 & 1.6 but performance may be sluggish, tested on Google G1 (1.5) 13334 // Android 3.1 (Honeycomb) - Tested on the Samsung Galaxy Tab 10.1 and Motorola XOOM 13335 // Android 4.0 (ICS) - Tested on a Galaxy Nexus. Note: transition performance can be poor on upgraded devices 13336 // Android 4.1 (Jelly Bean) - Tested on a Galaxy Nexus and Galaxy 7 13337 ( t.version('Android')>2.1 && t.is('Webkit') ) || 13338 13339 // Windows Phone 7-7.5 - Tested on the HTC Surround (7.0) HTC Trophy (7.5), LG-E900 (7.5), Nokia Lumia 800 13340 t.version('Windows Phone OS')>=7.0 || 13341 13342 // Blackberry 7 - Tested on BlackBerry Torch 9810 13343 // Blackberry 6.0 - Tested on the Torch 9800 and Style 9670 13344 t.is('BlackBerry') && t.version('BlackBerry')>=6.0 || 13345 // Blackberry Playbook (1.0-2.0) - Tested on PlayBook 13346 t.match('Playbook.*Tablet') || 13347 13348 // Palm WebOS (1.4-2.0) - Tested on the Palm Pixi (1.4), Pre (1.4), Pre 2 (2.0) 13349 ( t.version('webOS')>=1.4 && t.match('Palm|Pre|Pixi') ) || 13350 // Palm WebOS 3.0 - Tested on HP TouchPad 13351 t.match('hp.*TouchPad') || 13352 13353 // Firefox Mobile (12 Beta) - Tested on Android 2.3 device 13354 ( t.is('Firefox') && t.version('Firefox')>=12 ) || 13355 13356 // Chrome for Android - Tested on Android 4.0, 4.1 device 13357 ( t.is('Chrome') && t.is('AndroidOS') && t.version('Android')>=4.0 ) || 13358 13359 // Skyfire 4.1 - Tested on Android 2.3 device 13360 ( t.is('Skyfire') && t.version('Skyfire')>=4.1 && t.is('AndroidOS') && t.version('Android')>=2.3 ) || 13361 13362 // Opera Mobile 11.5-12: Tested on Android 2.3 13363 ( t.is('Opera') && t.version('Opera Mobi')>11 && t.is('AndroidOS') ) || 13364 13365 // Meego 1.2 - Tested on Nokia 950 and N9 13366 t.is('MeeGoOS') || 13367 13368 // Tizen (pre-release) - Tested on early hardware 13369 t.is('Tizen') || 13370 13371 // Samsung Bada 2.0 - Tested on a Samsung Wave 3, Dolphin browser 13372 // @todo: more tests here! 13373 t.is('Dolfin') && t.version('Bada')>=2.0 || 13374 13375 // UC Browser - Tested on Android 2.3 device 13376 ( (t.is('UC Browser') || t.is('Dolfin')) && t.version('Android')>=2.3 ) || 13377 13378 // Kindle 3 and Fire - Tested on the built-in WebKit browser for each 13379 ( t.match('Kindle Fire') || 13380 t.is('Kindle') && t.version('Kindle')>=3.0 ) || 13381 13382 // Nook Color 1.4.1 - Tested on original Nook Color, not Nook Tablet 13383 t.is('AndroidOS') && t.is('NookTablet') || 13384 13385 // Chrome Desktop 11-21 - Tested on OS X 10.7 and Windows 7 13386 t.version('Chrome')>=11 && !$isMobile || 13387 13388 // Safari Desktop 4-5 - Tested on OS X 10.7 and Windows 7 13389 t.version('Safari')>=5.0 && !$isMobile || 13390 13391 // Firefox Desktop 4-13 - Tested on OS X 10.7 and Windows 7 13392 t.version('Firefox')>=4.0 && !$isMobile || 13393 13394 // Internet Explorer 7-9 - Tested on Windows XP, Vista and 7 13395 t.version('MSIE')>=7.0 && !$isMobile || 13396 13397 // Opera Desktop 10-12 - Tested on OS X 10.7 and Windows 7 13398 // @reference: http://my.opera.com/community/openweb/idopera/ 13399 t.version('Opera')>=10 && !$isMobile 13400 13401 ){ 13402 return 'A'; 13403 } 13404 13405 if ( 13406 t.os('iOS') && t.version('iPad')<4.3 || 13407 t.os('iOS') && t.version('iPhone')<3.1 || 13408 t.os('iOS') && t.version('iPod')<3.1 || 13409 13410 // Blackberry 5.0: Tested on the Storm 2 9550, Bold 9770 13411 t.is('Blackberry') && t.version('BlackBerry')>=5 && t.version('BlackBerry')<6 || 13412 13413 //Opera Mini (5.0-6.5) - Tested on iOS 3.2/4.3 and Android 2.3 13414 ( t.version('Opera Mini')>=5.0 && t.version('Opera Mini')<=6.5 && 13415 (t.version('Android')>=2.3 || t.is('iOS')) ) || 13416 13417 // Nokia Symbian^3 - Tested on Nokia N8 (Symbian^3), C7 (Symbian^3), also works on N97 (Symbian^1) 13418 t.match('NokiaN8|NokiaC7|N97.*Series60|Symbian/3') || 13419 13420 // @todo: report this (tested on Nokia N71) 13421 t.version('Opera Mobi')>=11 && t.is('SymbianOS') 13422 ){ 13423 return 'B'; 13424 } 13425 13426 if ( 13427 // Blackberry 4.x - Tested on the Curve 8330 13428 t.version('BlackBerry')<5.0 || 13429 // Windows Mobile - Tested on the HTC Leo (WinMo 5.2) 13430 t.match('MSIEMobile|Windows CE.*Mobile') || t.version('Windows Mobile')<=5.2 13431 13432 ){ 13433 return 'C'; 13434 } 13435 13436 //All older smartphone platforms and featurephones - Any device that doesn't support media queries 13437 //will receive the basic, C grade experience. 13438 return 'C'; 13439 }; 13440 13441 impl.detectOS = function (ua) { 13442 return impl.findMatch(impl.mobileDetectRules.oss0, ua) || 13443 impl.findMatch(impl.mobileDetectRules.oss, ua); 13444 }; 13445 13446 impl.getDeviceSmallerSide = function () { 13447 return window.screen.width < window.screen.height ? 13448 window.screen.width : 13449 window.screen.height; 13450 }; 13451 13452 /** 13453 * Constructor for MobileDetect object. 13454 * <br> 13455 * Such an object will keep a reference to the given user-agent string and cache most of the detect queries.<br> 13456 * <div style="background-color: #d9edf7; border: 1px solid #bce8f1; color: #3a87ad; padding: 14px; border-radius: 2px; margin-top: 20px"> 13457 * <strong>Find information how to download and install:</strong> 13458 * <a href="https://github.com/hgoebl/mobile-detect.js/">github.com/hgoebl/mobile-detect.js/</a> 13459 * </div> 13460 * 13461 * @example <pre> 13462 * var md = new MobileDetect(window.navigator.userAgent); 13463 * if (md.mobile()) { 13464 * location.href = (md.mobileGrade() === 'A') ? '/mobile/' : '/lynx/'; 13465 * } 13466 * </pre> 13467 * 13468 * @param {string} userAgent typically taken from window.navigator.userAgent or http_header['User-Agent'] 13469 * @param {number} [maxPhoneWidth=600] <strong>only for browsers</strong> specify a value for the maximum 13470 * width of smallest device side (in logical "CSS" pixels) until a device detected as mobile will be handled 13471 * as phone. 13472 * This is only used in cases where the device cannot be classified as phone or tablet.<br> 13473 * See <a href="http://developer.android.com/guide/practices/screens_support.html">Declaring Tablet Layouts 13474 * for Android</a>.<br> 13475 * If you provide a value < 0, then this "fuzzy" check is disabled. 13476 * @constructor 13477 * @global 13478 */ 13479 function MobileDetect(userAgent, maxPhoneWidth) { 13480 this.ua = prepareUserAgent(userAgent); 13481 this._cache = {}; 13482 //600dp is typical 7" tablet minimum width 13483 this.maxPhoneWidth = maxPhoneWidth || 600; 13484 } 13485 13486 MobileDetect.prototype = { 13487 constructor: MobileDetect, 13488 13489 /** 13490 * Returns the detected phone or tablet type or <tt>null</tt> if it is not a mobile device. 13491 * <br> 13492 * For a list of possible return values see {@link MobileDetect#phone} and {@link MobileDetect#tablet}.<br> 13493 * <br> 13494 * If the device is not detected by the regular expressions from Mobile-Detect, a test is made against 13495 * the patterns of <a href="http://detectmobilebrowsers.com/">detectmobilebrowsers.com</a>. If this test 13496 * is positive, a value of <code>UnknownPhone</code>, <code>UnknownTablet</code> or 13497 * <code>UnknownMobile</code> is returned.<br> 13498 * When used in browser, the decision whether phone or tablet is made based on <code>screen.width/height</code>.<br> 13499 * <br> 13500 * When used server-side (node.js), there is no way to tell the difference between <code>UnknownTablet</code> 13501 * and <code>UnknownMobile</code>, so you will get <code>UnknownMobile</code> here.<br> 13502 * Be aware that since v1.0.0 in this special case you will get <code>UnknownMobile</code> only for: 13503 * {@link MobileDetect#mobile}, not for {@link MobileDetect#phone} and {@link MobileDetect#tablet}. 13504 * In versions before v1.0.0 all 3 methods returned <code>UnknownMobile</code> which was tedious to use. 13505 * <br> 13506 * In most cases you will use the return value just as a boolean. 13507 * 13508 * @returns {String} the key for the phone family or tablet family, e.g. "Nexus". 13509 * @function MobileDetect#mobile 13510 */ 13511 mobile: function () { 13512 impl.prepareDetectionCache(this._cache, this.ua, this.maxPhoneWidth); 13513 return this._cache.mobile; 13514 }, 13515 13516 /** 13517 * Returns the detected phone type/family string or <tt>null</tt>. 13518 * <br> 13519 * The returned tablet (family or producer) is one of following keys:<br> 13520 * <br><tt>iPhone, BlackBerry, Pixel, HTC, Nexus, Dell, Motorola, Samsung, LG, Sony, Asus, 13521 * Xiaomi, NokiaLumia, Micromax, Palm, Vertu, Pantech, Fly, Wiko, iMobile, 13522 * SimValley, Wolfgang, Alcatel, Nintendo, Amoi, INQ, OnePlus, GenericPhone</tt><br> 13523 * <br> 13524 * If the device is not detected by the regular expressions from Mobile-Detect, a test is made against 13525 * the patterns of <a href="http://detectmobilebrowsers.com/">detectmobilebrowsers.com</a>. If this test 13526 * is positive, a value of <code>UnknownPhone</code> or <code>UnknownMobile</code> is returned.<br> 13527 * When used in browser, the decision whether phone or tablet is made based on <code>screen.width/height</code>.<br> 13528 * <br> 13529 * When used server-side (node.js), there is no way to tell the difference between <code>UnknownTablet</code> 13530 * and <code>UnknownMobile</code>, so you will get <code>null</code> here, while {@link MobileDetect#mobile} 13531 * will return <code>UnknownMobile</code>.<br> 13532 * Be aware that since v1.0.0 in this special case you will get <code>UnknownMobile</code> only for: 13533 * {@link MobileDetect#mobile}, not for {@link MobileDetect#phone} and {@link MobileDetect#tablet}. 13534 * In versions before v1.0.0 all 3 methods returned <code>UnknownMobile</code> which was tedious to use. 13535 * <br> 13536 * In most cases you will use the return value just as a boolean. 13537 * 13538 * @returns {String} the key of the phone family or producer, e.g. "iPhone" 13539 * @function MobileDetect#phone 13540 */ 13541 phone: function () { 13542 impl.prepareDetectionCache(this._cache, this.ua, this.maxPhoneWidth); 13543 return this._cache.phone; 13544 }, 13545 13546 /** 13547 * Returns the detected tablet type/family string or <tt>null</tt>. 13548 * <br> 13549 * The returned tablet (family or producer) is one of following keys:<br> 13550 * <br><tt>iPad, NexusTablet, GoogleTablet, SamsungTablet, Kindle, SurfaceTablet, 13551 * HPTablet, AsusTablet, BlackBerryTablet, HTCtablet, MotorolaTablet, NookTablet, 13552 * AcerTablet, ToshibaTablet, LGTablet, FujitsuTablet, PrestigioTablet, 13553 * LenovoTablet, DellTablet, YarvikTablet, MedionTablet, ArnovaTablet, 13554 * IntensoTablet, IRUTablet, MegafonTablet, EbodaTablet, AllViewTablet, 13555 * ArchosTablet, AinolTablet, NokiaLumiaTablet, SonyTablet, PhilipsTablet, 13556 * CubeTablet, CobyTablet, MIDTablet, MSITablet, SMiTTablet, RockChipTablet, 13557 * FlyTablet, bqTablet, HuaweiTablet, NecTablet, PantechTablet, BronchoTablet, 13558 * VersusTablet, ZyncTablet, PositivoTablet, NabiTablet, KoboTablet, DanewTablet, 13559 * TexetTablet, PlaystationTablet, TrekstorTablet, PyleAudioTablet, AdvanTablet, 13560 * DanyTechTablet, GalapadTablet, MicromaxTablet, KarbonnTablet, AllFineTablet, 13561 * PROSCANTablet, YONESTablet, ChangJiaTablet, GUTablet, PointOfViewTablet, 13562 * OvermaxTablet, HCLTablet, DPSTablet, VistureTablet, CrestaTablet, 13563 * MediatekTablet, ConcordeTablet, GoCleverTablet, ModecomTablet, VoninoTablet, 13564 * ECSTablet, StorexTablet, VodafoneTablet, EssentielBTablet, RossMoorTablet, 13565 * iMobileTablet, TolinoTablet, AudioSonicTablet, AMPETablet, SkkTablet, 13566 * TecnoTablet, JXDTablet, iJoyTablet, FX2Tablet, XoroTablet, ViewsonicTablet, 13567 * VerizonTablet, OdysTablet, CaptivaTablet, IconbitTablet, TeclastTablet, 13568 * OndaTablet, JaytechTablet, BlaupunktTablet, DigmaTablet, EvolioTablet, 13569 * LavaTablet, AocTablet, MpmanTablet, CelkonTablet, WolderTablet, MediacomTablet, 13570 * MiTablet, NibiruTablet, NexoTablet, LeaderTablet, UbislateTablet, 13571 * PocketBookTablet, KocasoTablet, HisenseTablet, Hudl, TelstraTablet, 13572 * GenericTablet</tt><br> 13573 * <br> 13574 * If the device is not detected by the regular expressions from Mobile-Detect, a test is made against 13575 * the patterns of <a href="http://detectmobilebrowsers.com/">detectmobilebrowsers.com</a>. If this test 13576 * is positive, a value of <code>UnknownTablet</code> or <code>UnknownMobile</code> is returned.<br> 13577 * When used in browser, the decision whether phone or tablet is made based on <code>screen.width/height</code>.<br> 13578 * <br> 13579 * When used server-side (node.js), there is no way to tell the difference between <code>UnknownTablet</code> 13580 * and <code>UnknownMobile</code>, so you will get <code>null</code> here, while {@link MobileDetect#mobile} 13581 * will return <code>UnknownMobile</code>.<br> 13582 * Be aware that since v1.0.0 in this special case you will get <code>UnknownMobile</code> only for: 13583 * {@link MobileDetect#mobile}, not for {@link MobileDetect#phone} and {@link MobileDetect#tablet}. 13584 * In versions before v1.0.0 all 3 methods returned <code>UnknownMobile</code> which was tedious to use. 13585 * <br> 13586 * In most cases you will use the return value just as a boolean. 13587 * 13588 * @returns {String} the key of the tablet family or producer, e.g. "SamsungTablet" 13589 * @function MobileDetect#tablet 13590 */ 13591 tablet: function () { 13592 impl.prepareDetectionCache(this._cache, this.ua, this.maxPhoneWidth); 13593 return this._cache.tablet; 13594 }, 13595 13596 /** 13597 * Returns the (first) detected user-agent string or <tt>null</tt>. 13598 * <br> 13599 * The returned user-agent is one of following keys:<br> 13600 * <br><tt>Chrome, Dolfin, Opera, Skyfire, Edge, IE, Firefox, Bolt, TeaShark, Blazer, 13601 * Safari, WeChat, UCBrowser, baiduboxapp, baidubrowser, DiigoBrowser, Mercury, 13602 * ObigoBrowser, NetFront, GenericBrowser, PaleMoon</tt><br> 13603 * <br> 13604 * In most cases calling {@link MobileDetect#userAgent} will be sufficient. But there are rare 13605 * cases where a mobile device pretends to be more than one particular browser. You can get the 13606 * list of all matches with {@link MobileDetect#userAgents} or check for a particular value by 13607 * providing one of the defined keys as first argument to {@link MobileDetect#is}. 13608 * 13609 * @returns {String} the key for the detected user-agent or <tt>null</tt> 13610 * @function MobileDetect#userAgent 13611 */ 13612 userAgent: function () { 13613 if (this._cache.userAgent === undefined) { 13614 this._cache.userAgent = impl.findMatch(impl.mobileDetectRules.uas, this.ua); 13615 } 13616 return this._cache.userAgent; 13617 }, 13618 13619 /** 13620 * Returns all detected user-agent strings. 13621 * <br> 13622 * The array is empty or contains one or more of following keys:<br> 13623 * <br><tt>Chrome, Dolfin, Opera, Skyfire, Edge, IE, Firefox, Bolt, TeaShark, Blazer, 13624 * Safari, WeChat, UCBrowser, baiduboxapp, baidubrowser, DiigoBrowser, Mercury, 13625 * ObigoBrowser, NetFront, GenericBrowser, PaleMoon</tt><br> 13626 * <br> 13627 * In most cases calling {@link MobileDetect#userAgent} will be sufficient. But there are rare 13628 * cases where a mobile device pretends to be more than one particular browser. You can get the 13629 * list of all matches with {@link MobileDetect#userAgents} or check for a particular value by 13630 * providing one of the defined keys as first argument to {@link MobileDetect#is}. 13631 * 13632 * @returns {Array} the array of detected user-agent keys or <tt>[]</tt> 13633 * @function MobileDetect#userAgents 13634 */ 13635 userAgents: function () { 13636 if (this._cache.userAgents === undefined) { 13637 this._cache.userAgents = impl.findMatches(impl.mobileDetectRules.uas, this.ua); 13638 } 13639 return this._cache.userAgents; 13640 }, 13641 13642 /** 13643 * Returns the detected operating system string or <tt>null</tt>. 13644 * <br> 13645 * The operating system is one of following keys:<br> 13646 * <br><tt>AndroidOS, BlackBerryOS, PalmOS, SymbianOS, WindowsMobileOS, WindowsPhoneOS, 13647 * iOS, iPadOS, SailfishOS, MeeGoOS, MaemoOS, JavaOS, webOS, badaOS, BREWOS</tt><br> 13648 * 13649 * @returns {String} the key for the detected operating system. 13650 * @function MobileDetect#os 13651 */ 13652 os: function () { 13653 if (this._cache.os === undefined) { 13654 this._cache.os = impl.detectOS(this.ua); 13655 } 13656 return this._cache.os; 13657 }, 13658 13659 /** 13660 * Get the version (as Number) of the given property in the User-Agent. 13661 * <br> 13662 * Will return a float number. (eg. 2_0 will return 2.0, 4.3.1 will return 4.31) 13663 * 13664 * @param {String} key a key defining a thing which has a version.<br> 13665 * You can use one of following keys:<br> 13666 * <br><tt>Mobile, Build, Version, VendorID, iPad, iPhone, iPod, Kindle, Chrome, Coast, 13667 * Dolfin, Firefox, Fennec, Edge, IE, NetFront, NokiaBrowser, Opera, Opera Mini, 13668 * Opera Mobi, UCBrowser, MQQBrowser, MicroMessenger, baiduboxapp, baidubrowser, 13669 * SamsungBrowser, Iron, Safari, Skyfire, Tizen, Webkit, PaleMoon, 13670 * SailfishBrowser, Gecko, Trident, Presto, Goanna, iOS, Android, Sailfish, 13671 * BlackBerry, BREW, Java, Windows Phone OS, Windows Phone, Windows CE, Windows 13672 * NT, Symbian, webOS</tt><br> 13673 * 13674 * @returns {Number} the version as float or <tt>NaN</tt> if User-Agent doesn't contain this version. 13675 * Be careful when comparing this value with '==' operator! 13676 * @function MobileDetect#version 13677 */ 13678 version: function (key) { 13679 return impl.getVersion(key, this.ua); 13680 }, 13681 13682 /** 13683 * Get the version (as String) of the given property in the User-Agent. 13684 * <br> 13685 * 13686 * @param {String} key a key defining a thing which has a version.<br> 13687 * You can use one of following keys:<br> 13688 * <br><tt>Mobile, Build, Version, VendorID, iPad, iPhone, iPod, Kindle, Chrome, Coast, 13689 * Dolfin, Firefox, Fennec, Edge, IE, NetFront, NokiaBrowser, Opera, Opera Mini, 13690 * Opera Mobi, UCBrowser, MQQBrowser, MicroMessenger, baiduboxapp, baidubrowser, 13691 * SamsungBrowser, Iron, Safari, Skyfire, Tizen, Webkit, PaleMoon, 13692 * SailfishBrowser, Gecko, Trident, Presto, Goanna, iOS, Android, Sailfish, 13693 * BlackBerry, BREW, Java, Windows Phone OS, Windows Phone, Windows CE, Windows 13694 * NT, Symbian, webOS</tt><br> 13695 * 13696 * @returns {String} the "raw" version as String or <tt>null</tt> if User-Agent doesn't contain this version. 13697 * 13698 * @function MobileDetect#versionStr 13699 */ 13700 versionStr: function (key) { 13701 return impl.getVersionStr(key, this.ua); 13702 }, 13703 13704 /** 13705 * Global test key against userAgent, os, phone, tablet and some other properties of userAgent string. 13706 * 13707 * @param {String} key the key (case-insensitive) of a userAgent, an operating system, phone or 13708 * tablet family.<br> 13709 * For a complete list of possible values, see {@link MobileDetect#userAgent}, 13710 * {@link MobileDetect#os}, {@link MobileDetect#phone}, {@link MobileDetect#tablet}.<br> 13711 * Additionally you have following keys:<br> 13712 * <br><tt>Bot, MobileBot, DesktopMode, TV, WebKit, Console, Watch</tt><br> 13713 * 13714 * @returns {boolean} <tt>true</tt> when the given key is one of the defined keys of userAgent, os, phone, 13715 * tablet or one of the listed additional keys, otherwise <tt>false</tt> 13716 * @function MobileDetect#is 13717 */ 13718 is: function (key) { 13719 return containsIC(this.userAgents(), key) || 13720 equalIC(key, this.os()) || 13721 equalIC(key, this.phone()) || 13722 equalIC(key, this.tablet()) || 13723 containsIC(impl.findMatches(impl.mobileDetectRules.utils, this.ua), key); 13724 }, 13725 13726 /** 13727 * Do a quick test against navigator::userAgent. 13728 * 13729 * @param {String|RegExp} pattern the pattern, either as String or RegExp 13730 * (a string will be converted to a case-insensitive RegExp). 13731 * @returns {boolean} <tt>true</tt> when the pattern matches, otherwise <tt>false</tt> 13732 * @function MobileDetect#match 13733 */ 13734 match: function (pattern) { 13735 if (!(pattern instanceof RegExp)) { 13736 pattern = new RegExp(pattern, 'i'); 13737 } 13738 return pattern.test(this.ua); 13739 }, 13740 13741 /** 13742 * Checks whether the mobile device can be considered as phone regarding <code>screen.width</code>. 13743 * <br> 13744 * Obviously this method makes sense in browser environments only (not for Node.js)! 13745 * @param {number} [maxPhoneWidth] the maximum logical pixels (aka. CSS-pixels) to be considered as phone.<br> 13746 * The argument is optional and if not present or falsy, the value of the constructor is taken. 13747 * @returns {boolean|undefined} <code>undefined</code> if screen size wasn't detectable, else <code>true</code> 13748 * when screen.width is less or equal to maxPhoneWidth, otherwise <code>false</code>.<br> 13749 * Will always return <code>undefined</code> server-side. 13750 */ 13751 isPhoneSized: function (maxPhoneWidth) { 13752 return MobileDetect.isPhoneSized(maxPhoneWidth || this.maxPhoneWidth); 13753 }, 13754 13755 /** 13756 * Returns the mobile grade ('A', 'B', 'C'). 13757 * 13758 * @returns {String} one of the mobile grades ('A', 'B', 'C'). 13759 * @function MobileDetect#mobileGrade 13760 */ 13761 mobileGrade: function () { 13762 if (this._cache.grade === undefined) { 13763 this._cache.grade = impl.mobileGrade(this); 13764 } 13765 return this._cache.grade; 13766 } 13767 }; 13768 13769 // environment-dependent 13770 if (typeof window !== 'undefined' && window.screen) { 13771 MobileDetect.isPhoneSized = function (maxPhoneWidth) { 13772 return maxPhoneWidth < 0 ? undefined : impl.getDeviceSmallerSide() <= maxPhoneWidth; 13773 }; 13774 } else { 13775 MobileDetect.isPhoneSized = function () {}; 13776 } 13777 13778 // should not be replaced by a completely new object - just overwrite existing methods 13779 MobileDetect._impl = impl; 13780 13781 MobileDetect.version = '1.4.5 2021-03-13'; 13782 13783 return MobileDetect; 13784}); // end of call of define() 13785})((function (undefined) { 13786 if ( true && module.exports) { 13787 return function (factory) { module.exports = factory(); }; 13788 } else if (true) { 13789 return __webpack_require__(/*! !webpack amd define */ "./node_modules/webpack/buildin/amd-define.js"); 13790 } else {} 13791})()); 13792 13793/***/ }), 13794
vendor: 353 bytes, lines 13795-13808
13795/***/ "./node_modules/webpack/buildin/amd-define.js": 13796/*!***************************************!*\ 13797 !*** (webpack)/buildin/amd-define.js ***! 13798 \***************************************/ 13799/*! no static exports found */ 13800/***/ (function(module, exports) { 13801 13802module.exports = function() { 13803 throw new Error("define cannot be used indirect"); 13804}; 13805 13806 13807/***/ }), 13808
vendor: 721 bytes, lines 13809-13838
13809/***/ "./node_modules/webpack/buildin/global.js": 13810/*!***********************************!*\ 13811 !*** (webpack)/buildin/global.js ***! 13812 \***********************************/ 13813/*! no static exports found */ 13814/***/ (function(module, exports) { 13815 13816var g; 13817 13818// This works in non-strict mode 13819g = (function() { 13820 return this; 13821})(); 13822 13823try { 13824 // This works if eval is allowed (see CSP) 13825 g = g || new Function("return this")(); 13826} catch (e) { 13827 // This works if the window reference is available 13828 if (typeof window === "object") g = window; 13829} 13830 13831// g can still be undefined, but nothing to do about it... 13832// We return undefined, instead of nothing here, so it's 13833// easier to handle this case. if(!global) { ...} 13834 13835module.exports = g; 13836 13837 13838/***/ })
13838 13839 13840/******/ }); 13841//# sourceMappingURL=app.js.map
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.