vendor: 4,607 bytes, lines 1-131
1/*! 2 * Materialize v0.98.0 (http://materializecss.com) 3 * Copyright 2014-2015 Materialize 4 * MIT License (https://raw.githubusercontent.com/Dogfalo/materialize/master/LICENSE) 5 */ 6// Check for jQuery. 7if (typeof(jQuery) === 'undefined') { 8 var jQuery; 9 // Check if require is a defined function. 10 if (typeof(require) === 'function') { 11 jQuery = $ = require('jquery'); 12 // Else use the dollar sign alias. 13 } else { 14 jQuery = $; 15 } 16} 17;/* 18 * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/ 19 * 20 * Uses the built in easing capabilities added In jQuery 1.1 21 * to offer multiple easing options 22 * 23 * TERMS OF USE - jQuery Easing 24 * 25 * Open source under the BSD License. 26 * 27 * Copyright © 2008 George McGinley Smith 28 * All rights reserved. 29 * 30 * Redistribution and use in source and binary forms, with or without modification, 31 * are permitted provided that the following conditions are met: 32 * 33 * Redistributions of source code must retain the above copyright notice, this list of 34 * conditions and the following disclaimer. 35 * Redistributions in binary form must reproduce the above copyright notice, this list 36 * of conditions and the following disclaimer in the documentation and/or other materials 37 * provided with the distribution. 38 * 39 * Neither the name of the author nor the names of contributors may be used to endorse 40 * or promote products derived from this software without specific prior written permission. 41 * 42 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 43 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 44 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 45 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 46 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 47 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 48 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 49 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 50 * OF THE POSSIBILITY OF SUCH DAMAGE. 51 * 52*/ 53 54// t: current time, b: begInnIng value, c: change In value, d: duration 55jQuery.easing['jswing'] = jQuery.easing['swing']; 56 57jQuery.extend( jQuery.easing, 58{ 59 def: 'easeOutQuad', 60 swing: function (x, t, b, c, d) { 61 //alert(jQuery.easing.default); 62 return jQuery.easing[jQuery.easing.def](x, t, b, c, d); 63 }, 64 easeInQuad: function (x, t, b, c, d) { 65 return c*(t/=d)*t + b; 66 }, 67 easeOutQuad: function (x, t, b, c, d) { 68 return -c *(t/=d)*(t-2) + b; 69 }, 70 easeInOutQuad: function (x, t, b, c, d) { 71 if ((t/=d/2) < 1) return c/2*t*t + b; 72 return -c/2 * ((--t)*(t-2) - 1) + b; 73 }, 74 easeInCubic: function (x, t, b, c, d) { 75 return c*(t/=d)*t*t + b; 76 }, 77 easeOutCubic: function (x, t, b, c, d) { 78 return c*((t=t/d-1)*t*t + 1) + b; 79 }, 80 easeInOutCubic: function (x, t, b, c, d) { 81 if ((t/=d/2) < 1) return c/2*t*t*t + b; 82 return c/2*((t-=2)*t*t + 2) + b; 83 }, 84 easeInQuart: function (x, t, b, c, d) { 85 return c*(t/=d)*t*t*t + b; 86 }, 87 easeOutQuart: function (x, t, b, c, d) { 88 return -c * ((t=t/d-1)*t*t*t - 1) + b; 89 }, 90 easeInOutQuart: function (x, t, b, c, d) { 91 if ((t/=d/2) < 1) return c/2*t*t*t*t + b; 92 return -c/2 * ((t-=2)*t*t*t - 2) + b; 93 }, 94 easeInQuint: function (x, t, b, c, d) { 95 return c*(t/=d)*t*t*t*t + b; 96 }, 97 easeOutQuint: function (x, t, b, c, d) { 98 return c*((t=t/d-1)*t*t*t*t + 1) + b; 99 }, 100 easeInOutQuint: function (x, t, b, c, d) { 101 if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b; 102 return c/2*((t-=2)*t*t*t*t + 2) + b; 103 }, 104 easeInSine: function (x, t, b, c, d) { 105 return -c * Math.cos(t/d * (Math.PI/2)) + c + b; 106 }, 107 easeOutSine: function (x, t, b, c, d) { 108 return c * Math.sin(t/d * (Math.PI/2)) + b; 109 }, 110 easeInOutSine: function (x, t, b, c, d) { 111 return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b; 112 }, 113 easeInExpo: function (x, t, b, c, d) { 114 return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b; 115 }, 116 easeOutExpo: function (x, t, b, c, d) { 117 return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b; 118 }, 119 easeInOutExpo: function (x, t, b, c, d) { 120 if (t==0) return b; 121 if (t==d) return b+c; 122 if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b; 123 return c/2 * (-Math.pow(2, -10 * --t) + 2) + b; 124 }, 125 easeInCirc: function (x, t, b, c, d) { 126 return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b; 127 }, 128 easeOutCirc: function (x, t, b, c, d) { 129 return c * Math.sqrt(1 - (t=t/d-1)*t) + b; 130 }, 131 easeInOutCirc: function (x, t, b, c, d) {
vendor: 4,191 bytes, lines 132-228
132 if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b; 133 return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b; 134 }, 135 easeInElastic: function (x, t, b, c, d) { 136 var s=1.70158;var p=0;var a=c; 137 if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3; 138 if (a < Math.abs(c)) { a=c; var s=p/4; } 139 else var s = p/(2*Math.PI) * Math.asin (c/a); 140 return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b; 141 }, 142 easeOutElastic: function (x, t, b, c, d) { 143 var s=1.70158;var p=0;var a=c; 144 if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3; 145 if (a < Math.abs(c)) { a=c; var s=p/4; } 146 else var s = p/(2*Math.PI) * Math.asin (c/a); 147 return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b; 148 }, 149 easeInOutElastic: function (x, t, b, c, d) { 150 var s=1.70158;var p=0;var a=c; 151 if (t==0) return b; if ((t/=d/2)==2) return b+c; if (!p) p=d*(.3*1.5); 152 if (a < Math.abs(c)) { a=c; var s=p/4; } 153 else var s = p/(2*Math.PI) * Math.asin (c/a); 154 if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b; 155 return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b; 156 }, 157 easeInBack: function (x, t, b, c, d, s) { 158 if (s == undefined) s = 1.70158; 159 return c*(t/=d)*t*((s+1)*t - s) + b; 160 }, 161 easeOutBack: function (x, t, b, c, d, s) { 162 if (s == undefined) s = 1.70158; 163 return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b; 164 }, 165 easeInOutBack: function (x, t, b, c, d, s) { 166 if (s == undefined) s = 1.70158; 167 if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b; 168 return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b; 169 }, 170 easeInBounce: function (x, t, b, c, d) { 171 return c - jQuery.easing.easeOutBounce (x, d-t, 0, c, d) + b; 172 }, 173 easeOutBounce: function (x, t, b, c, d) { 174 if ((t/=d) < (1/2.75)) { 175 return c*(7.5625*t*t) + b; 176 } else if (t < (2/2.75)) { 177 return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b; 178 } else if (t < (2.5/2.75)) { 179 return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b; 180 } else { 181 return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b; 182 } 183 }, 184 easeInOutBounce: function (x, t, b, c, d) { 185 if (t < d/2) return jQuery.easing.easeInBounce (x, t*2, 0, c, d) * .5 + b; 186 return jQuery.easing.easeOutBounce (x, t*2-d, 0, c, d) * .5 + c*.5 + b; 187 } 188}); 189 190/* 191 * 192 * TERMS OF USE - EASING EQUATIONS 193 * 194 * Open source under the BSD License. 195 * 196 * Copyright © 2001 Robert Penner 197 * All rights reserved. 198 * 199 * Redistribution and use in source and binary forms, with or without modification, 200 * are permitted provided that the following conditions are met: 201 * 202 * Redistributions of source code must retain the above copyright notice, this list of 203 * conditions and the following disclaimer. 204 * Redistributions in binary form must reproduce the above copyright notice, this list 205 * of conditions and the following disclaimer in the documentation and/or other materials 206 * provided with the distribution. 207 * 208 * Neither the name of the author nor the names of contributors may be used to endorse 209 * or promote products derived from this software without specific prior written permission. 210 * 211 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 212 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 213 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 214 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 215 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 216 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 217 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 218 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 219 * OF THE POSSIBILITY OF SUCH DAMAGE. 220 * 221 */;// Custom Easing 222jQuery.extend( jQuery.easing, 223{ 224 easeInOutMaterial: function (x, t, b, c, d) { 225 if ((t/=d/2) < 1) return c/2*t*t + b; 226 return c/4*((t-=2)*t*t + 2) + b; 227 } 228});;/*! VelocityJS.org (1.2.3). (C) 2014 Julian Shapiro. MIT @license: en.wikipedia.org/wiki/MIT_License */
vendor: 34,619 bytes, lines 229-232
229/*! VelocityJS.org jQuery Shim (1.0.1). (C) 2014 The jQuery Foundation. MIT @license: en.wikipedia.org/wiki/MIT_License. */ 230/*! Note that this has been modified by Materialize to confirm that Velocity is not already being imported. */ 231jQuery.Velocity?console.log("Velocity is already loaded. You may be needlessly importing Velocity again; note that Materialize includes Velocity."):(!function(e){function t(e){var t=e.length,a=r.type(e);return"function"===a||r.isWindow(e)?!1:1===e.nodeType&&t?!0:"array"===a||0===t||"number"==typeof t&&t>0&&t-1 in e}if(!e.jQuery){var r=function(e,t){return new r.fn.init(e,t)};r.isWindow=function(e){return null!=e&&e==e.window},r.type=function(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[i.call(e)]||"object":typeof e},r.isArray=Array.isArray||function(e){return"array"===r.type(e)},r.isPlainObject=function(e){var t;if(!e||"object"!==r.type(e)||e.nodeType||r.isWindow(e))return!1;try{if(e.constructor&&!o.call(e,"constructor")&&!o.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(a){return!1}for(t in e);return void 0===t||o.call(e,t)},r.each=function(e,r,a){var n,o=0,i=e.length,s=t(e);if(a){if(s)for(;i>o&&(n=r.apply(e[o],a),n!==!1);o++);else for(o in e)if(n=r.apply(e[o],a),n===!1)break}else if(s)for(;i>o&&(n=r.call(e[o],o,e[o]),n!==!1);o++);else for(o in e)if(n=r.call(e[o],o,e[o]),n===!1)break;return e},r.data=function(e,t,n){if(void 0===n){var o=e[r.expando],i=o&&a[o];if(void 0===t)return i;if(i&&t in i)return i[t]}else if(void 0!==t){var o=e[r.expando]||(e[r.expando]=++r.uuid);return a[o]=a[o]||{},a[o][t]=n,n}},r.removeData=function(e,t){var n=e[r.expando],o=n&&a[n];o&&r.each(t,function(e,t){delete o[t]})},r.extend=function(){var e,t,a,n,o,i,s=arguments[0]||{},l=1,u=arguments.length,c=!1;for("boolean"==typeof s&&(c=s,s=arguments[l]||{},l++),"object"!=typeof s&&"function"!==r.type(s)&&(s={}),l===u&&(s=this,l--);u>l;l++)if(null!=(o=arguments[l]))for(n in o)e=s[n],a=o[n],s!==a&&(c&&a&&(r.isPlainObject(a)||(t=r.isArray(a)))?(t?(t=!1,i=e&&r.isArray(e)?e:[]):i=e&&r.isPlainObject(e)?e:{},s[n]=r.extend(c,i,a)):void 0!==a&&(s[n]=a));return s},r.queue=function(e,a,n){function o(e,r){var a=r||[];return null!=e&&(t(Object(e))?!function(e,t){for(var r=+t.length,a=0,n=e.length;r>a;)e[n++]=t[a++];if(r!==r)for(;void 0!==t[a];)e[n++]=t[a++];return e.length=n,e}(a,"string"==typeof e?[e]:e):[].push.call(a,e)),a}if(e){a=(a||"fx")+"queue";var i=r.data(e,a);return n?(!i||r.isArray(n)?i=r.data(e,a,o(n)):i.push(n),i):i||[]}},r.dequeue=function(e,t){r.each(e.nodeType?[e]:e,function(e,a){t=t||"fx";var n=r.queue(a,t),o=n.shift();"inprogress"===o&&(o=n.shift()),o&&("fx"===t&&n.unshift("inprogress"),o.call(a,function(){r.dequeue(a,t)}))})},r.fn=r.prototype={init:function(e){if(e.nodeType)return this[0]=e,this;throw new Error("Not a DOM node.")},offset:function(){var t=this[0].getBoundingClientRect?this[0].getBoundingClientRect():{top:0,left:0};return{top:t.top+(e.pageYOffset||document.scrollTop||0)-(document.clientTop||0),left:t.left+(e.pageXOffset||document.scrollLeft||0)-(document.clientLeft||0)}},position:function(){function e(){for(var e=this.offsetParent||document;e&&"html"===!e.nodeType.toLowerCase&&"static"===e.style.position;)e=e.offsetParent;return e||document}var t=this[0],e=e.apply(t),a=this.offset(),n=/^(?:body|html)$/i.test(e.nodeName)?{top:0,left:0}:r(e).offset();return a.top-=parseFloat(t.style.marginTop)||0,a.left-=parseFloat(t.style.marginLeft)||0,e.style&&(n.top+=parseFloat(e.style.borderTopWidth)||0,n.left+=parseFloat(e.style.borderLeftWidth)||0),{top:a.top-n.top,left:a.left-n.left}}};var a={};r.expando="velocity"+(new Date).getTime(),r.uuid=0;for(var n={},o=n.hasOwnProperty,i=n.toString,s="Boolean Number String Function Array Date RegExp Object Error".split(" "),l=0;l<s.length;l++)n["[object "+s[l]+"]"]=s[l].toLowerCase();r.fn.init.prototype=r.fn,e.Velocity={Utilities:r}}}(window),function(e){"object"==typeof module&&"object"==typeof module.exports?module.exports=e():"function"==typeof define&&define.amd?define(e):e()}(function(){return function(e,t,r,a){function n(e){for(var t=-1,r=e?e.length:0,a=[];++t<r;){var n=e[t];n&&a.push(n)}return a}function o(e){return m.isWrapped(e)?e=[].slice.call(e):m.isNode(e)&&(e=[e]),e}function i(e){var t=f.data(e,"velocity");return null===t?a:t}function s(e){return function(t){return Math.round(t*e)*(1/e)}}function l(e,r,a,n){function o(e,t){return 1-3*t+3*e}function i(e,t){return 3*t-6*e}function s(e){return 3*e}function l(e,t,r){return((o(t,r)*e+i(t,r))*e+s(t))*e}function u(e,t,r){return 3*o(t,r)*e*e+2*i(t,r)*e+s(t)}function c(t,r){for(var n=0;m>n;++n){var o=u(r,e,a);if(0===o)return r;var i=l(r,e,a)-t;r-=i/o}return r}function p(){for(var t=0;b>t;++t)w[t]=l(t*x,e,a)}function f(t,r,n){var o,i,s=0;do i=r+(n-r)/2,o=l(i,e,a)-t,o>0?n=i:r=i;while(Math.abs(o)>h&&++s<v);return i}function d(t){for(var r=0,n=1,o=b-1;n!=o&&w[n]<=t;++n)r+=x;--n;var i=(t-w[n])/(w[n+1]-w[n]),s=r+i*x,l=u(s,e,a);return l>=y?c(t,s):0==l?s:f(t,r,r+x)}function g(){V=!0,(e!=r||a!=n)&&p()}var m=4,y=.001,h=1e-7,v=10,b=11,x=1/(b-1),S="Float32Array"in t;if(4!==arguments.length)return!1;for(var P=0;4>P;++P)if("number"!=typeof arguments[P]||isNaN(arguments[P])||!isFinite(arguments[P]))return!1;e=Math.min(e,1),a=Math.min(a,1),e=Math.max(e,0),a=Math.max(a,0);var w=S?new Float32Array(b):new Array(b),V=!1,C=function(t){return V||g(),e===r&&a===n?t:0===t?0:1===t?1:l(d(t),r,n)};C.getControlPoints=function(){return[{x:e,y:r},{x:a,y:n}]};var T="generateBezier("+[e,r,a,n]+")";return C.toString=function(){return T},C}function u(e,t){var r=e;return m.isString(e)?b.Easings[e]||(r=!1):r=m.isArray(e)&&1===e.length?s.apply(null,e):m.isArray(e)&&2===e.length?x.apply(null,e.concat([t])):m.isArray(e)&&4===e.length?l.apply(null,e):!1,r===!1&&(r=b.Easings[b.defaults.easing]?b.defaults.easing:v),r}function c(e){if(e){var t=(new Date).getTime(),r=b.State.calls.length;r>1e4&&(b.State.calls=n(b.State.calls));for(var o=0;r>o;o++)if(b.State.calls[o]){var s=b.State.calls[o],l=s[0],u=s[2],d=s[3],g=!!d,y=null;d||(d=b.State.calls[o][3]=t-16);for(var h=Math.min((t-d)/u.duration,1),v=0,x=l.length;x>v;v++){var P=l[v],V=P.element;if(i(V)){var C=!1;if(u.display!==a&&null!==u.display&&"none"!==u.display){if("flex"===u.display){var T=["-webkit-box","-moz-box","-ms-flexbox","-webkit-flex"];f.each(T,function(e,t){S.setPropertyValue(V,"display",t)})}S.setPropertyValue(V,"display",u.display)}u.visibility!==a&&"hidden"!==u.visibility&&S.setPropertyValue(V,"visibility",u.visibility);for(var k in P)if("element"!==k){var A,F=P[k],j=m.isString(F.easing)?b.Easings[F.easing]:F.easing;if(1===h)A=F.endValue;else{var E=F.endValue-F.startValue;if(A=F.startValue+E*j(h,u,E),!g&&A===F.currentValue)continue}if(F.currentValue=A,"tween"===k)y=A;else{if(S.Hooks.registered[k]){var H=S.Hooks.getRoot(k),N=i(V).rootPropertyValueCache[H];N&&(F.rootPropertyValue=N)}var L=S.setPropertyValue(V,k,F.currentValue+(0===parseFloat(A)?"":F.unitType),F.rootPropertyValue,F.scrollData);S.Hooks.registered[k]&&(i(V).rootPropertyValueCache[H]=S.Normalizations.registered[H]?S.Normalizations.registered[H]("extract",null,L[1]):L[1]),"transform"===L[0]&&(C=!0)}}u.mobileHA&&i(V).transformCache.translate3d===a&&(i(V).transformCache.translate3d="(0px, 0px, 0px)",C=!0),C&&S.flushTransformCache(V)}}u.display!==a&&"none"!==u.display&&(b.State.calls[o][2].display=!1),u.visibility!==a&&"hidden"!==u.visibility&&(b.State.calls[o][2].visibility=!1),u.progress&&u.progress.call(s[1],s[1],h,Math.max(0,d+u.duration-t),d,y),1===h&&p(o)}}b.State.isTicking&&w(c)}function p(e,t){if(!b.State.calls[e])return!1;for(var r=b.State.calls[e][0],n=b.State.calls[e][1],o=b.State.calls[e][2],s=b.State.calls[e][4],l=!1,u=0,c=r.length;c>u;u++){var p=r[u].element;if(t||o.loop||("none"===o.display&&S.setPropertyValue(p,"display",o.display),"hidden"===o.visibility&&S.setPropertyValue(p,"visibility",o.visibility)),o.loop!==!0&&(f.queue(p)[1]===a||!/\.velocityQueueEntryFlag/i.test(f.queue(p)[1]))&&i(p)){i(p).isAnimating=!1,i(p).rootPropertyValueCache={};var d=!1;f.each(S.Lists.transforms3D,function(e,t){var r=/^scale/.test(t)?1:0,n=i(p).transformCache[t];i(p).transformCache[t]!==a&&new RegExp("^\\("+r+"[^.]").test(n)&&(d=!0,delete i(p).transformCache[t])}),o.mobileHA&&(d=!0,delete i(p).transformCache.translate3d),d&&S.flushTransformCache(p),S.Values.removeClass(p,"velocity-animating")}if(!t&&o.complete&&!o.loop&&u===c-1)try{o.complete.call(n,n)}catch(g){setTimeout(function(){throw g},1)}s&&o.loop!==!0&&s(n),i(p)&&o.loop===!0&&!t&&(f.each(i(p).tweensContainer,function(e,t){/^rotate/.test(e)&&360===parseFloat(t.endValue)&&(t.endValue=0,t.startValue=360),/^backgroundPosition/.test(e)&&100===parseFloat(t.endValue)&&"%"===t.unitType&&(t.endValue=0,t.startValue=100)}),b(p,"reverse",{loop:!0,delay:o.delay})),o.queue!==!1&&f.dequeue(p,o.queue)}b.State.calls[e]=!1;for(var m=0,y=b.State.calls.length;y>m;m++)if(b.State.calls[m]!==!1){l=!0;break}l===!1&&(b.State.isTicking=!1,delete b.State.calls,b.State.calls=[])}var f,d=function(){if(r.documentMode)return r.documentMode;for(var e=7;e>4;e--){var t=r.createElement("div");if(t.innerHTML="<!--[if IE "+e+"]><span></span><![endif]-->",t.getElementsByTagName("span").length)return t=null,e}return a}(),g=function(){var e=0;return t.webkitRequestAnimationFrame||t.mozRequestAnimationFrame||function(t){var r,a=(new Date).getTime();return r=Math.max(0,16-(a-e)),e=a+r,setTimeout(function(){t(a+r)},r)}}(),m={isString:function(e){return"string"==typeof e},isArray:Array.isArray||function(e){return"[object Array]"===Object.prototype.toString.call(e)},isFunction:function(e){return"[object Function]"===Object.prototype.toString.call(e)},isNode:function(e){return e&&e.nodeType},isNodeList:function(e){return"object"==typeof e&&/^\[object (HTMLCollection|NodeList|Object)\]$/.test(Object.prototype.toString.call(e))&&e.length!==a&&(0===e.length||"object"==typeof e[0]&&e[0].nodeType>0)},isWrapped:function(e){return e&&(e.jquery||t.Zepto&&t.Zepto.zepto.isZ(e))},isSVG:function(e){return t.SVGElement&&e instanceof t.SVGElement},isEmptyObject:function(e){for(var t in e)return!1;return!0}},y=!1;if(e.fn&&e.fn.jquery?(f=e,y=!0):f=t.Velocity.Utilities,8>=d&&!y)throw new Error("Velocity: IE8 and below require jQuery to be loaded before Velocity.");if(7>=d)return void(jQuery.fn.velocity=jQuery.fn.animate);var h=400,v="swing",b={State:{isMobile:/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent),isAndroid:/Android/i.test(navigator.userAgent),isGingerbread:/Android 2\.3\.[3-7]/i.test(navigator.userAgent),isChrome:t.chrome,isFirefox:/Firefox/i.test(navigator.userAgent),prefixElement:r.createElement("div"),prefixMatches:{},scrollAnchor:null,scrollPropertyLeft:null,scrollPropertyTop:null,isTicking:!1,calls:[]},CSS:{},Utilities:f,Redirects:{},Easings:{},Promise:t.Promise,defaults:{queue:"",duration:h,easing:v,begin:a,complete:a,progress:a,display:a,visibility:a,loop:!1,delay:!1,mobileHA:!0,_cacheValues:!0},init:function(e){f.data(e,"velocity",{isSVG:m.isSVG(e),isAnimating:!1,computedStyle:null,tweensContainer:null,rootPropertyValueCache:{},transformCache:{}})},hook:null,mock:!1,version:{major:1,minor:2,patch:2},debug:!1};t.pageYOffset!==a?(b.State.scrollAnchor=t,b.State.scrollPropertyLeft="pageXOffset",b.State.scrollPropertyTop="pageYOffset"):(b.State.scrollAnchor=r.documentElement||r.body.parentNode||r.body,b.State.scrollPropertyLeft="scrollLeft",b.State.scrollPropertyTop="scrollTop");var x=function(){function e(e){return-e.tension*e.x-e.friction*e.v}function t(t,r,a){var n={x:t.x+a.dx*r,v:t.v+a.dv*r,tension:t.tension,friction:t.friction};return{dx:n.v,dv:e(n)}}function r(r,a){var n={dx:r.v,dv:e(r)},o=t(r,.5*a,n),i=t(r,.5*a,o),s=t(r,a,i),l=1/6*(n.dx+2*(o.dx+i.dx)+s.dx),u=1/6*(n.dv+2*(o.dv+i.dv)+s.dv);return r.x=r.x+l*a,r.v=r.v+u*a,r}return function a(e,t,n){var o,i,s,l={x:-1,v:0,tension:null,friction:null},u=[0],c=0,p=1e-4,f=.016;for(e=parseFloat(e)||500,t=parseFloat(t)||20,n=n||null,l.tension=e,l.friction=t,o=null!==n,o?(c=a(e,t),i=c/n*f):i=f;s=r(s||l,i),u.push(1+s.x),c+=16,Math.abs(s.x)>p&&Math.abs(s.v)>p;);return o?function(e){return u[e*(u.length-1)|0]}:c}}();b.Easings={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},spring:function(e){return 1-Math.cos(4.5*e*Math.PI)*Math.exp(6*-e)}},f.each([["ease",[.25,.1,.25,1]],["ease-in",[.42,0,1,1]],["ease-out",[0,0,.58,1]],["ease-in-out",[.42,0,.58,1]],["easeInSine",[.47,0,.745,.715]],["easeOutSine",[.39,.575,.565,1]],["easeInOutSine",[.445,.05,.55,.95]],["easeInQuad",[.55,.085,.68,.53]],["easeOutQuad",[.25,.46,.45,.94]],["easeInOutQuad",[.455,.03,.515,.955]],["easeInCubic",[.55,.055,.675,.19]],["easeOutCubic",[.215,.61,.355,1]],["easeInOutCubic",[.645,.045,.355,1]],["easeInQuart",[.895,.03,.685,.22]],["easeOutQuart",[.165,.84,.44,1]],["easeInOutQuart",[.77,0,.175,1]],["easeInQuint",[.755,.05,.855,.06]],["easeOutQuint",[.23,1,.32,1]],["easeInOutQuint",[.86,0,.07,1]],["easeInExpo",[.95,.05,.795,.035]],["easeOutExpo",[.19,1,.22,1]],["easeInOutExpo",[1,0,0,1]],["easeInCirc",[.6,.04,.98,.335]],["easeOutCirc",[.075,.82,.165,1]],["easeInOutCirc",[.785,.135,.15,.86]]],function(e,t){b.Easings[t[0]]=l.apply(null,t[1])});var S=b.CSS={RegEx:{isHex:/^#([A-f\d]{3}){1,2}$/i,valueUnwrap:/^[A-z]+\((.*)\)$/i,wrappedValueAlreadyExtracted:/[0-9.]+ [0-9.]+ [0-9.]+( [0-9.]+)?/,valueSplit:/([A-z]+\(.+\))|(([A-z0-9#-.]+?)(?=\s|$))/gi},Lists:{colors:["fill","stroke","stopColor","color","backgroundColor","borderColor","borderTopColor","borderRightColor","borderBottomColor","borderLeftColor","outlineColor"],transformsBase:["translateX","translateY","scale","scaleX","scaleY","skewX","skewY","rotateZ"],transforms3D:["transformPerspective","translateZ","scaleZ","rotateX","rotateY"]},Hooks:{templates:{textShadow:["Color X Y Blur","black 0px 0px 0px"],boxShadow:["Color X Y Blur Spread","black 0px 0px 0px 0px"],clip:["Top Right Bottom Left","0px 0px 0px 0px"],backgroundPosition:["X Y","0% 0%"],transformOrigin:["X Y Z","50% 50% 0px"],perspectiveOrigin:["X Y","50% 50%"]},registered:{},register:function(){for(var e=0;e<S.Lists.colors.length;e++){var t="color"===S.Lists.colors[e]?"0 0 0 1":"255 255 255 1";S.Hooks.templates[S.Lists.colors[e]]=["Red Green Blue Alpha",t]}var r,a,n;if(d)for(r in S.Hooks.templates){a=S.Hooks.templates[r],n=a[0].split(" ");var o=a[1].match(S.RegEx.valueSplit);"Color"===n[0]&&(n.push(n.shift()),o.push(o.shift()),S.Hooks.templates[r]=[n.join(" "),o.join(" ")])}for(r in S.Hooks.templates){a=S.Hooks.templates[r],n=a[0].split(" ");for(var e in n){var i=r+n[e],s=e;S.Hooks.registered[i]=[r,s]}}},getRoot:function(e){var t=S.Hooks.registered[e];return t?t[0]:e},cleanRootPropertyValue:function(e,t){return S.RegEx.valueUnwrap.test(t)&&(t=t.match(S.RegEx.valueUnwrap)[1]),S.Values.isCSSNullValue(t)&&(t=S.Hooks.templates[e][1]),t},extractValue:function(e,t){var r=S.Hooks.registered[e];if(r){var a=r[0],n=r[1];return t=S.Hooks.cleanRootPropertyValue(a,t),t.toString().match(S.RegEx.valueSplit)[n]}return t},injectValue:function(e,t,r){var a=S.Hooks.registered[e];if(a){var n,o,i=a[0],s=a[1];return r=S.Hooks.cleanRootPropertyValue(i,r),n=r.toString().match(S.RegEx.valueSplit),n[s]=t,o=n.join(" ")}return r}},Normalizations:{registered:{clip:function(e,t,r){switch(e){case"name":return"clip";case"extract":var a;return S.RegEx.wrappedValueAlreadyExtracted.test(r)?a=r:(a=r.toString().match(S.RegEx.valueUnwrap),a=a?a[1].replace(/,(\s+)?/g," "):r),a;case"inject":return"rect("+r+")"}},blur:function(e,t,r){switch(e){case"name":return b.State.isFirefox?"filter":"-webkit-filter";case"extract":var a=parseFloat(r);if(!a&&0!==a){var n=r.toString().match(/blur\(([0-9]+[A-z]+)\)/i);a=n?n[1]:0}return a;case"inject":return parseFloat(r)?"blur("+r+")":"none"}},opacity:function(e,t,r){if(8>=d)switch(e){case"name":return"filter";case"extract":var a=r.toString().match(/alpha\(opacity=(.*)\)/i);return r=a?a[1]/100:1;case"inject":return t.style.zoom=1,parseFloat(r)>=1?"":"alpha(opacity="+parseInt(100*parseFloat(r),10)+")"}else switch(e){case"name":return"opacity";case"extract":return r;case"inject":return r}}},register:function(){9>=d||b.State.isGingerbread||(S.Lists.transformsBase=S.Lists.transformsBase.concat(S.Lists.transforms3D));for(var e=0;e<S.Lists.transformsBase.length;e++)!function(){var t=S.Lists.transformsBase[e];S.Normalizations.registered[t]=function(e,r,n){switch(e){case"name":return"transform";case"extract":return i(r)===a||i(r).transformCache[t]===a?/^scale/i.test(t)?1:0:i(r).transformCache[t].replace(/[()]/g,"");case"inject":var o=!1;switch(t.substr(0,t.length-1)){case"translate":o=!/(%|px|em|rem|vw|vh|\d)$/i.test(n);break;case"scal":case"scale":b.State.isAndroid&&i(r).transformCache[t]===a&&1>n&&(n=1),o=!/(\d)$/i.test(n);break;case"skew":o=!/(deg|\d)$/i.test(n);break;case"rotate":o=!/(deg|\d)$/i.test(n)}return o||(i(r).transformCache[t]="("+n+")"),i(r).transformCache[t]}}}();for(var e=0;e<S.Lists.colors.length;e++)!function(){var t=S.Lists.colors[e];S.Normalizations.registered[t]=function(e,r,n){switch(e){case"name":return t;case"extract":var o;if(S.RegEx.wrappedValueAlreadyExtracted.test(n))o=n;else{var i,s={black:"rgb(0, 0, 0)",blue:"rgb(0, 0, 255)",gray:"rgb(128, 128, 128)",green:"rgb(0, 128, 0)",red:"rgb(255, 0, 0)",white:"rgb(255, 255, 255)"};/^[A-z]+$/i.test(n)?i=s[n]!==a?s[n]:s.black:S.RegEx.isHex.test(n)?i="rgb("+S.Values.hexToRgb(n).join(" ")+")":/^rgba?\(/i.test(n)||(i=s.black),o=(i||n).toString().match(S.RegEx.valueUnwrap)[1].replace(/,(\s+)?/g," ")}return 8>=d||3!==o.split(" ").length||(o+=" 1"),o;case"inject":return 8>=d?4===n.split(" ").length&&(n=n.split(/\s+/).slice(0,3).join(" ")):3===n.split(" ").length&&(n+=" 1"),(8>=d?"rgb":"rgba")+"("+n.replace(/\s+/g,",").replace(/\.(\d)+(?=,)/g,"")+")"}}}()}},Names:{camelCase:function(e){return e.replace(/-(\w)/g,function(e,t){return t.toUpperCase()})},SVGAttribute:function(e){var t="width|height|x|y|cx|cy|r|rx|ry|x1|x2|y1|y2";return(d||b.State.isAndroid&&!b.State.isChrome)&&(t+="|transform"),new RegExp("^("+t+")$","i").test(e)},prefixCheck:function(e){if(b.State.prefixMatches[e])return[b.State.prefixMatches[e],!0];for(var t=["","Webkit","Moz","ms","O"],r=0,a=t.length;a>r;r++){var n;if(n=0===r?e:t[r]+e.replace(/^\w/,function(e){return e.toUpperCase()}),m.isString(b.State.prefixElement.style[n]))return b.State.prefixMatches[e]=n,[n,!0]}return[e,!1]}},Values:{hexToRgb:function(e){var t,r=/^#?([a-f\d])([a-f\d])([a-f\d])$/i,a=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i;return e=e.replace(r,function(e,t,r,a){return t+t+r+r+a+a}),t=a.exec(e),t?[parseInt(t[1],16),parseInt(t[2],16),parseInt(t[3],16)]:[0,0,0]},isCSSNullValue:function(e){return 0==e||/^(none|auto|transparent|(rgba\(0, ?0, ?0, ?0\)))$/i.test(e)},getUnitType:function(e){return/^(rotate|skew)/i.test(e)?"deg":/(^(scale|scaleX|scaleY|scaleZ|alpha|flexGrow|flexHeight|zIndex|fontWeight)$)|((opacity|red|green|blue|alpha)$)/i.test(e)?"":"px"},getDisplayType:function(e){var t=e&&e.tagName.toString().toLowerCase();return/^(b|big|i|small|tt|abbr|acronym|cite|code|dfn|em|kbd|strong|samp|var|a|bdo|br|img|map|object|q|script|span|sub|sup|button|input|label|select|textarea)$/i.test(t)?"inline":/^(li)$/i.test(t)?"list-item":/^(tr)$/i.test(t)?"table-row":/^(table)$/i.test(t)?"table":/^(tbody)$/i.test(t)?"table-row-group":"block"},addClass:function(e,t){e.classList?e.classList.add(t):e.className+=(e.className.length?" ":"")+t},removeClass:function(e,t){e.classList?e.classList.remove(t):e.className=e.className.toString().replace(new RegExp("(^|\\s)"+t.split(" ").join("|")+"(\\s|$)","gi")," ")}},getPropertyValue:function(e,r,n,o){function s(e,r){function n(){u&&S.setPropertyValue(e,"display","none")}var l=0;if(8>=d)l=f.css(e,r);else{var u=!1;if(/^(width|height)$/.test(r)&&0===S.getPropertyValue(e,"display")&&(u=!0,S.setPropertyValue(e,"display",S.Values.getDisplayType(e))),!o){if("height"===r&&"border-box"!==S.getPropertyValue(e,"boxSizing").toString().toLowerCase()){var c=e.offsetHeight-(parseFloat(S.getPropertyValue(e,"borderTopWidth"))||0)-(parseFloat(S.getPropertyValue(e,"borderBottomWidth"))||0)-(parseFloat(S.getPropertyValue(e,"paddingTop"))||0)-(parseFloat(S.getPropertyValue(e,"paddingBottom"))||0);return n(),c}if("width"===r&&"border-box"!==S.getPropertyValue(e,"boxSizing").toString().toLowerCase()){var p=e.offsetWidth-(parseFloat(S.getPropertyValue(e,"borderLeftWidth"))||0)-(parseFloat(S.getPropertyValue(e,"borderRightWidth"))||0)-(parseFloat(S.getPropertyValue(e,"paddingLeft"))||0)-(parseFloat(S.getPropertyValue(e,"paddingRight"))||0);return n(),p}}var g;g=i(e)===a?t.getComputedStyle(e,null):i(e).computedStyle?i(e).computedStyle:i(e).computedStyle=t.getComputedStyle(e,null),"borderColor"===r&&(r="borderTopColor"),l=9===d&&"filter"===r?g.getPropertyValue(r):g[r],(""===l||null===l)&&(l=e.style[r]),n()}if("auto"===l&&/^(top|right|bottom|left)$/i.test(r)){var m=s(e,"position");("fixed"===m||"absolute"===m&&/top|left/i.test(r))&&(l=f(e).position()[r]+"px")}return l}var l;if(S.Hooks.registered[r]){var u=r,c=S.Hooks.getRoot(u);n===a&&(n=S.getPropertyValue(e,S.Names.prefixCheck(c)[0])),S.Normalizations.registered[c]&&(n=S.Normalizations.registered[c]("extract",e,n)),l=S.Hooks.extractValue(u,n)}else if(S.Normalizations.registered[r]){var p,g;p=S.Normalizations.registered[r]("name",e),"transform"!==p&&(g=s(e,S.Names.prefixCheck(p)[0]),S.Values.isCSSNullValue(g)&&S.Hooks.templates[r]&&(g=S.Hooks.templates[r][1])),l=S.Normalizations.registered[r]("extract",e,g)}if(!/^[\d-]/.test(l))if(i(e)&&i(e).isSVG&&S.Names.SVGAttribute(r))if(/^(height|width)$/i.test(r))try{l=e.getBBox()[r]}catch(m){l=0}else l=e.getAttribute(r);else l=s(e,S.Names.prefixCheck(r)[0]);return S.Values.isCSSNullValue(l)&&(l=0),b.debug>=2&&console.log("Get "+r+": "+l),l},setPropertyValue:function(e,r,a,n,o){var s=r;if("scroll"===r)o.container?o.container["scroll"+o.direction]=a:"Left"===o.direction?t.scrollTo(a,o.alternateValue):t.scrollTo(o.alternateValue,a);else if(S.Normalizations.registered[r]&&"transform"===S.Normalizations.registered[r]("name",e))S.Normalizations.registered[r]("inject",e,a),s="transform",a=i(e).transformCache[r];else{if(S.Hooks.registered[r]){var l=r,u=S.Hooks.getRoot(r);n=n||S.getPropertyValue(e,u),a=S.Hooks.injectValue(l,a,n),r=u}if(S.Normalizations.registered[r]&&(a=S.Normalizations.registered[r]("inject",e,a),r=S.Normalizations.registered[r]("name",e)),s=S.Names.prefixCheck(r)[0],8>=d)try{e.style[s]=a}catch(c){b.debug&&console.log("Browser does not support ["+a+"] for ["+s+"]")}else i(e)&&i(e).isSVG&&S.Names.SVGAttribute(r)?e.setAttribute(r,a):e.style[s]=a;b.debug>=2&&console.log("Set "+r+" ("+s+"): "+a)}return[s,a]},flushTransformCache:function(e){function t(t){return parseFloat(S.getPropertyValue(e,t))}var r="";if((d||b.State.isAndroid&&!b.State.isChrome)&&i(e).isSVG){var a={translate:[t("translateX"),t("translateY")],skewX:[t("skewX")],skewY:[t("skewY")],scale:1!==t("scale")?[t("scale"),t("scale")]:[t("scaleX"),t("scaleY")],rotate:[t("rotateZ"),0,0]};f.each(i(e).transformCache,function(e){/^translate/i.test(e)?e="translate":/^scale/i.test(e)?e="scale":/^rotate/i.test(e)&&(e="rotate"),a[e]&&(r+=e+"("+a[e].join(" ")+") ",delete a[e])})}else{var n,o;f.each(i(e).transformCache,function(t){return n=i(e).transformCache[t],"transformPerspective"===t?(o=n,!0):(9===d&&"rotateZ"===t&&(t="rotate"),void(r+=t+n+" "))}),o&&(r="perspective"+o+" "+r)}S.setPropertyValue(e,"transform",r)}};S.Hooks.register(),S.Normalizations.register(),b.hook=function(e,t,r){var n=a;return e=o(e),f.each(e,function(e,o){if(i(o)===a&&b.init(o),r===a)n===a&&(n=b.CSS.getPropertyValue(o,t));else{var s=b.CSS.setPropertyValue(o,t,r);"transform"===s[0]&&b.CSS.flushTransformCache(o),n=s}}),n};var P=function(){function e(){return s?k.promise||null:l}function n(){function e(e){function p(e,t){var r=a,n=a,i=a;return m.isArray(e)?(r=e[0],!m.isArray(e[1])&&/^[\d-]/.test(e[1])||m.isFunction(e[1])||S.RegEx.isHex.test(e[1])?i=e[1]:(m.isString(e[1])&&!S.RegEx.isHex.test(e[1])||m.isArray(e[1]))&&(n=t?e[1]:u(e[1],s.duration),e[2]!==a&&(i=e[2]))):r=e,t||(n=n||s.easing),m.isFunction(r)&&(r=r.call(o,V,w)),m.isFunction(i)&&(i=i.call(o,V,w)),[r||0,n,i]}function d(e,t){var r,a;return a=(t||"0").toString().toLowerCase().replace(/[%A-z]+$/,function(e){return r=e,""}),r||(r=S.Values.getUnitType(e)),[a,r]}function h(){var e={myParent:o.parentNode||r.body,position:S.getPropertyValue(o,"position"),fontSize:S.getPropertyValue(o,"fontSize")},a=e.position===L.lastPosition&&e.myParent===L.lastParent,n=e.fontSize===L.lastFontSize;L.lastParent=e.myParent,L.lastPosition=e.position,L.lastFontSize=e.fontSize;var s=100,l={};if(n&&a)l.emToPx=L.lastEmToPx,l.percentToPxWidth=L.lastPercentToPxWidth,l.percentToPxHeight=L.lastPercentToPxHeight;else{var u=i(o).isSVG?r.createElementNS("http://www.w3.org/2000/svg","rect"):r.createElement("div");b.init(u),e.myParent.appendChild(u),f.each(["overflow","overflowX","overflowY"],function(e,t){b.CSS.setPropertyValue(u,t,"hidden")}),b.CSS.setPropertyValue(u,"position",e.position),b.CSS.setPropertyValue(u,"fontSize",e.fontSize),b.CSS.setPropertyValue(u,"boxSizing","content-box"),f.each(["minWidth","maxWidth","width","minHeight","maxHeight","height"],function(e,t){b.CSS.setPropertyValue(u,t,s+"%")}),b.CSS.setPropertyValue(u,"paddingLeft",s+"em"),l.percentToPxWidth=L.lastPercentToPxWidth=(parseFloat(S.getPropertyValue(u,"width",null,!0))||1)/s,l.percentToPxHeight=L.lastPercentToPxHeight=(parseFloat(S.getPropertyValue(u,"height",null,!0))||1)/s,l.emToPx=L.lastEmToPx=(parseFloat(S.getPropertyValue(u,"paddingLeft"))||1)/s,e.myParent.removeChild(u)}return null===L.remToPx&&(L.remToPx=parseFloat(S.getPropertyValue(r.body,"fontSize"))||16),null===L.vwToPx&&(L.vwToPx=parseFloat(t.innerWidth)/100,L.vhToPx=parseFloat(t.innerHeight)/100),l.remToPx=L.remToPx,l.vwToPx=L.vwToPx,l.vhToPx=L.vhToPx,b.debug>=1&&console.log("Unit ratios: "+JSON.stringify(l),o),l}if(s.begin&&0===V)try{s.begin.call(g,g)}catch(x){setTimeout(function(){throw x},1)}if("scroll"===A){var P,C,T,F=/^x$/i.test(s.axis)?"Left":"Top",j=parseFloat(s.offset)||0;s.container?m.isWrapped(s.container)||m.isNode(s.container)?(s.container=s.container[0]||s.container,P=s.container["scroll"+F],T=P+f(o).position()[F.toLowerCase()]+j):s.container=null:(P=b.State.scrollAnchor[b.State["scrollProperty"+F]],C=b.State.scrollAnchor[b.State["scrollProperty"+("Left"===F?"Top":"Left")]],T=f(o).offset()[F.toLowerCase()]+j),l={scroll:{rootPropertyValue:!1,startValue:P,currentValue:P,endValue:T,unitType:"",easing:s.easing,scrollData:{container:s.container,direction:F,alternateValue:C}},element:o},b.debug&&console.log("tweensContainer (scroll): ",l.scroll,o)}else if("reverse"===A){if(!i(o).tweensContainer)return void f.dequeue(o,s.queue);"none"===i(o).opts.display&&(i(o).opts.display="auto"),"hidden"===i(o).opts.visibility&&(i(o).opts.visibility="visible"),i(o).opts.loop=!1,i(o).opts.begin=null,i(o).opts.complete=null,v.easing||delete s.easing,v.duration||delete s.duration,s=f.extend({},i(o).opts,s);var E=f.extend(!0,{},i(o).tweensContainer);for(var H in E)if("element"!==H){var N=E[H].startValue;E[H].startValue=E[H].currentValue=E[H].endValue,E[H].endValue=N,m.isEmptyObject(v)||(E[H].easing=s.easing),b.debug&&console.log("reverse tweensContainer ("+H+"): "+JSON.stringify(E[H]),o)}l=E}else if("start"===A){var E;i(o).tweensContainer&&i(o).isAnimating===!0&&(E=i(o).tweensContainer),f.each(y,function(e,t){if(RegExp("^"+S.Lists.colors.join("$|^")+"$").test(e)){var r=p(t,!0),n=r[0],o=r[1],i=r[2];if(S.RegEx.isHex.test(n)){for(var s=["Red","Green","Blue"],l=S.Values.hexToRgb(n),u=i?S.Values.hexToRgb(i):a,c=0;c<s.length;c++){var f=[l[c]];o&&f.push(o),u!==a&&f.push(u[c]),y[e+s[c]]=f}delete y[e]}}});for(var z in y){var O=p(y[z]),q=O[0],$=O[1],M=O[2];z=S.Names.camelCase(z);var I=S.Hooks.getRoot(z),B=!1;if(i(o).isSVG||"tween"===I||S.Names.prefixCheck(I)[1]!==!1||S.Normalizations.registered[I]!==a){(s.display!==a&&null!==s.display&&"none"!==s.display||s.visibility!==a&&"hidden"!==s.visibility)&&/opacity|filter/.test(z)&&!M&&0!==q&&(M=0),s._cacheValues&&E&&E[z]?(M===a&&(M=E[z].endValue+E[z].unitType),B=i(o).rootPropertyValueCache[I]):S.Hooks.registered[z]?M===a?(B=S.getPropertyValue(o,I),M=S.getPropertyValue(o,z,B)):B=S.Hooks.templates[I][1]:M===a&&(M=S.getPropertyValue(o,z));var W,G,Y,D=!1;if(W=d(z,M),M=W[0],Y=W[1],W=d(z,q),q=W[0].replace(/^([+-\/*])=/,function(e,t){return D=t,""}),G=W[1],M=parseFloat(M)||0,q=parseFloat(q)||0,"%"===G&&(/^(fontSize|lineHeight)$/.test(z)?(q/=100,G="em"):/^scale/.test(z)?(q/=100,G=""):/(Red|Green|Blue)$/i.test(z)&&(q=q/100*255,G="")),/[\/*]/.test(D))G=Y;else if(Y!==G&&0!==M)if(0===q)G=Y;else{n=n||h();var Q=/margin|padding|left|right|width|text|word|letter/i.test(z)||/X$/.test(z)||"x"===z?"x":"y";switch(Y){case"%":M*="x"===Q?n.percentToPxWidth:n.percentToPxHeight;break;case"px":break;default:M*=n[Y+"ToPx"]}switch(G){case"%":M*=1/("x"===Q?n.percentToPxWidth:n.percentToPxHeight);break;case"px":break;default:M*=1/n[G+"ToPx"]}}switch(D){case"+":q=M+q;break;case"-":q=M-q;break;case"*":q=M*q;break;case"/":q=M/q}l[z]={rootPropertyValue:B,startValue:M,currentValue:M,endValue:q,unitType:G,easing:$},b.debug&&console.log("tweensContainer ("+z+"): "+JSON.stringify(l[z]),o)}else b.debug&&console.log("Skipping ["+I+"] due to a lack of browser support.")}l.element=o}l.element&&(S.Values.addClass(o,"velocity-animating"),R.push(l),""===s.queue&&(i(o).tweensContainer=l,i(o).opts=s),i(o).isAnimating=!0,V===w-1?(b.State.calls.push([R,g,s,null,k.resolver]),b.State.isTicking===!1&&(b.State.isTicking=!0,c())):V++)}var n,o=this,s=f.extend({},b.defaults,v),l={};switch(i(o)===a&&b.init(o),parseFloat(s.delay)&&s.queue!==!1&&f.queue(o,s.queue,function(e){b.velocityQueueEntryFlag=!0,i(o).delayTimer={setTimeout:setTimeout(e,parseFloat(s.delay)),next:e}}),s.duration.toString().toLowerCase()){case"fast":s.duration=200;break;case"normal":s.duration=h;break;case"slow":s.duration=600;break;default:s.duration=parseFloat(s.duration)||1}b.mock!==!1&&(b.mock===!0?s.duration=s.delay=1:(s.duration*=parseFloat(b.mock)||1,s.delay*=parseFloat(b.mock)||1)),s.easing=u(s.easing,s.duration),s.begin&&!m.isFunction(s.begin)&&(s.begin=null),s.progress&&!m.isFunction(s.progress)&&(s.progress=null),s.complete&&!m.isFunction(s.complete)&&(s.complete=null),s.display!==a&&null!==s.display&&(s.display=s.display.toString().toLowerCase(),"auto"===s.display&&(s.display=b.CSS.Values.getDisplayType(o))),s.visibility!==a&&null!==s.visibility&&(s.visibility=s.visibility.toString().toLowerCase()),s.mobileHA=s.mobileHA&&b.State.isMobile&&!b.State.isGingerbread,s.queue===!1?s.delay?setTimeout(e,s.delay):e():f.queue(o,s.queue,function(t,r){return r===!0?(k.promise&&k.resolver(g),!0):(b.velocityQueueEntryFlag=!0,void e(t))}),""!==s.queue&&"fx"!==s.queue||"inprogress"===f.queue(o)[0]||f.dequeue(o)}var s,l,d,g,y,v,x=arguments[0]&&(arguments[0].p||f.isPlainObject(arguments[0].properties)&&!arguments[0].properties.names||m.isString(arguments[0].properties));if(m.isWrapped(this)?(s=!1,d=0,g=this,l=this):(s=!0,d=1,g=x?arguments[0].elements||arguments[0].e:arguments[0]),g=o(g)){x?(y=arguments[0].properties||arguments[0].p,v=arguments[0].options||arguments[0].o):(y=arguments[d],v=arguments[d+1]);var w=g.length,V=0;if(!/^(stop|finish)$/i.test(y)&&!f.isPlainObject(v)){var C=d+1;v={};for(var T=C;T<arguments.length;T++)m.isArray(arguments[T])||!/^(fast|normal|slow)$/i.test(arguments[T])&&!/^\d/.test(arguments[T])?m.isString(arguments[T])||m.isArray(arguments[T])?v.easing=arguments[T]:m.isFunction(arguments[T])&&(v.complete=arguments[T]):v.duration=arguments[T]}var k={promise:null,resolver:null,rejecter:null};s&&b.Promise&&(k.promise=new b.Promise(function(e,t){k.resolver=e,k.rejecter=t}));var A;switch(y){case"scroll":A="scroll";break;case"reverse":A="reverse";break;case"finish":case"stop":f.each(g,function(e,t){i(t)&&i(t).delayTimer&&(clearTimeout(i(t).delayTimer.setTimeout),i(t).delayTimer.next&&i(t).delayTimer.next(),delete i(t).delayTimer)});var F=[];return f.each(b.State.calls,function(e,t){t&&f.each(t[1],function(r,n){var o=v===a?"":v;return o===!0||t[2].queue===o||v===a&&t[2].queue===!1?void f.each(g,function(r,a){a===n&&((v===!0||m.isString(v))&&(f.each(f.queue(a,m.isString(v)?v:""),function(e,t){ 232m.isFunction(t)&&t(null,!0)}),f.queue(a,m.isString(v)?v:"",[])),"stop"===y?(i(a)&&i(a).tweensContainer&&o!==!1&&f.each(i(a).tweensContainer,function(e,t){t.endValue=t.currentValue}),F.push(e)):"finish"===y&&(t[2].duration=1))}):!0})}),"stop"===y&&(f.each(F,function(e,t){p(t,!0)}),k.promise&&k.resolver(g)),e();default:if(!f.isPlainObject(y)||m.isEmptyObject(y)){if(m.isString(y)&&b.Redirects[y]){var j=f.extend({},v),E=j.duration,H=j.delay||0;return j.backwards===!0&&(g=f.extend(!0,[],g).reverse()),f.each(g,function(e,t){parseFloat(j.stagger)?j.delay=H+parseFloat(j.stagger)*e:m.isFunction(j.stagger)&&(j.delay=H+j.stagger.call(t,e,w)),j.drag&&(j.duration=parseFloat(E)||(/^(callout|transition)/.test(y)?1e3:h),j.duration=Math.max(j.duration*(j.backwards?1-e/w:(e+1)/w),.75*j.duration,200)),b.Redirects[y].call(t,t,j||{},e,w,g,k.promise?k:a)}),e()}var N="Velocity: First argument ("+y+") was not a property map, a known action, or a registered redirect. Aborting.";return k.promise?k.rejecter(new Error(N)):console.log(N),e()}A="start"}var L={lastParent:null,lastPosition:null,lastFontSize:null,lastPercentToPxWidth:null,lastPercentToPxHeight:null,lastEmToPx:null,remToPx:null,vwToPx:null,vhToPx:null},R=[];f.each(g,function(e,t){m.isNode(t)&&n.call(t)});var z,j=f.extend({},b.defaults,v);if(j.loop=parseInt(j.loop),z=2*j.loop-1,j.loop)for(var O=0;z>O;O++){var q={delay:j.delay,progress:j.progress};O===z-1&&(q.display=j.display,q.visibility=j.visibility,q.complete=j.complete),P(g,"reverse",q)}return e()}};b=f.extend(P,b),b.animate=P;var w=t.requestAnimationFrame||g;return b.State.isMobile||r.hidden===a||r.addEventListener("visibilitychange",function(){r.hidden?(w=function(e){return setTimeout(function(){e(!0)},16)},c()):w=t.requestAnimationFrame||g}),e.Velocity=b,e!==t&&(e.fn.velocity=P,e.fn.velocity.defaults=b.defaults),f.each(["Down","Up"],function(e,t){b.Redirects["slide"+t]=function(e,r,n,o,i,s){var l=f.extend({},r),u=l.begin,c=l.complete,p={height:"",marginTop:"",marginBottom:"",paddingTop:"",paddingBottom:""},d={};l.display===a&&(l.display="Down"===t?"inline"===b.CSS.Values.getDisplayType(e)?"inline-block":"block":"none"),l.begin=function(){u&&u.call(i,i);for(var r in p){d[r]=e.style[r];var a=b.CSS.getPropertyValue(e,r);p[r]="Down"===t?[a,0]:[0,a]}d.overflow=e.style.overflow,e.style.overflow="hidden"},l.complete=function(){for(var t in d)e.style[t]=d[t];
vendor: 20,121 bytes, lines 232-290
232c&&c.call(i,i),s&&s.resolver(i)},b(e,p,l)}}),f.each(["In","Out"],function(e,t){b.Redirects["fade"+t]=function(e,r,n,o,i,s){var l=f.extend({},r),u={opacity:"In"===t?1:0},c=l.complete;l.complete=n!==o-1?l.begin=null:function(){c&&c.call(i,i),s&&s.resolver(i)},l.display===a&&(l.display="In"===t?"auto":"none"),b(this,u,l)}}),b}(window.jQuery||window.Zepto||window,window,document)})); 233;!function(a,b,c,d){"use strict";function k(a,b,c){return setTimeout(q(a,c),b)}function l(a,b,c){return Array.isArray(a)?(m(a,c[b],c),!0):!1}function m(a,b,c){var e;if(a)if(a.forEach)a.forEach(b,c);else if(a.length!==d)for(e=0;e<a.length;)b.call(c,a[e],e,a),e++;else for(e in a)a.hasOwnProperty(e)&&b.call(c,a[e],e,a)}function n(a,b,c){for(var e=Object.keys(b),f=0;f<e.length;)(!c||c&&a[e[f]]===d)&&(a[e[f]]=b[e[f]]),f++;return a}function o(a,b){return n(a,b,!0)}function p(a,b,c){var e,d=b.prototype;e=a.prototype=Object.create(d),e.constructor=a,e._super=d,c&&n(e,c)}function q(a,b){return function(){return a.apply(b,arguments)}}function r(a,b){return typeof a==g?a.apply(b?b[0]||d:d,b):a}function s(a,b){return a===d?b:a}function t(a,b,c){m(x(b),function(b){a.addEventListener(b,c,!1)})}function u(a,b,c){m(x(b),function(b){a.removeEventListener(b,c,!1)})}function v(a,b){for(;a;){if(a==b)return!0;a=a.parentNode}return!1}function w(a,b){return a.indexOf(b)>-1}function x(a){return a.trim().split(/\s+/g)}function y(a,b,c){if(a.indexOf&&!c)return a.indexOf(b);for(var d=0;d<a.length;){if(c&&a[d][c]==b||!c&&a[d]===b)return d;d++}return-1}function z(a){return Array.prototype.slice.call(a,0)}function A(a,b,c){for(var d=[],e=[],f=0;f<a.length;){var g=b?a[f][b]:a[f];y(e,g)<0&&d.push(a[f]),e[f]=g,f++}return c&&(d=b?d.sort(function(a,c){return a[b]>c[b]}):d.sort()),d}function B(a,b){for(var c,f,g=b[0].toUpperCase()+b.slice(1),h=0;h<e.length;){if(c=e[h],f=c?c+g:b,f in a)return f;h++}return d}function D(){return C++}function E(a){var b=a.ownerDocument;return b.defaultView||b.parentWindow}function ab(a,b){var c=this;this.manager=a,this.callback=b,this.element=a.element,this.target=a.options.inputTarget,this.domHandler=function(b){r(a.options.enable,[a])&&c.handler(b)},this.init()}function bb(a){var b,c=a.options.inputClass;return b=c?c:H?wb:I?Eb:G?Gb:rb,new b(a,cb)}function cb(a,b,c){var d=c.pointers.length,e=c.changedPointers.length,f=b&O&&0===d-e,g=b&(Q|R)&&0===d-e;c.isFirst=!!f,c.isFinal=!!g,f&&(a.session={}),c.eventType=b,db(a,c),a.emit("hammer.input",c),a.recognize(c),a.session.prevInput=c}function db(a,b){var c=a.session,d=b.pointers,e=d.length;c.firstInput||(c.firstInput=gb(b)),e>1&&!c.firstMultiple?c.firstMultiple=gb(b):1===e&&(c.firstMultiple=!1);var f=c.firstInput,g=c.firstMultiple,h=g?g.center:f.center,i=b.center=hb(d);b.timeStamp=j(),b.deltaTime=b.timeStamp-f.timeStamp,b.angle=lb(h,i),b.distance=kb(h,i),eb(c,b),b.offsetDirection=jb(b.deltaX,b.deltaY),b.scale=g?nb(g.pointers,d):1,b.rotation=g?mb(g.pointers,d):0,fb(c,b);var k=a.element;v(b.srcEvent.target,k)&&(k=b.srcEvent.target),b.target=k}function eb(a,b){var c=b.center,d=a.offsetDelta||{},e=a.prevDelta||{},f=a.prevInput||{};(b.eventType===O||f.eventType===Q)&&(e=a.prevDelta={x:f.deltaX||0,y:f.deltaY||0},d=a.offsetDelta={x:c.x,y:c.y}),b.deltaX=e.x+(c.x-d.x),b.deltaY=e.y+(c.y-d.y)}function fb(a,b){var f,g,h,j,c=a.lastInterval||b,e=b.timeStamp-c.timeStamp;if(b.eventType!=R&&(e>N||c.velocity===d)){var k=c.deltaX-b.deltaX,l=c.deltaY-b.deltaY,m=ib(e,k,l);g=m.x,h=m.y,f=i(m.x)>i(m.y)?m.x:m.y,j=jb(k,l),a.lastInterval=b}else f=c.velocity,g=c.velocityX,h=c.velocityY,j=c.direction;b.velocity=f,b.velocityX=g,b.velocityY=h,b.direction=j}function gb(a){for(var b=[],c=0;c<a.pointers.length;)b[c]={clientX:h(a.pointers[c].clientX),clientY:h(a.pointers[c].clientY)},c++;return{timeStamp:j(),pointers:b,center:hb(b),deltaX:a.deltaX,deltaY:a.deltaY}}function hb(a){var b=a.length;if(1===b)return{x:h(a[0].clientX),y:h(a[0].clientY)};for(var c=0,d=0,e=0;b>e;)c+=a[e].clientX,d+=a[e].clientY,e++;return{x:h(c/b),y:h(d/b)}}function ib(a,b,c){return{x:b/a||0,y:c/a||0}}function jb(a,b){return a===b?S:i(a)>=i(b)?a>0?T:U:b>0?V:W}function kb(a,b,c){c||(c=$);var d=b[c[0]]-a[c[0]],e=b[c[1]]-a[c[1]];return Math.sqrt(d*d+e*e)}function lb(a,b,c){c||(c=$);var d=b[c[0]]-a[c[0]],e=b[c[1]]-a[c[1]];return 180*Math.atan2(e,d)/Math.PI}function mb(a,b){return lb(b[1],b[0],_)-lb(a[1],a[0],_)}function nb(a,b){return kb(b[0],b[1],_)/kb(a[0],a[1],_)}function rb(){this.evEl=pb,this.evWin=qb,this.allow=!0,this.pressed=!1,ab.apply(this,arguments)}function wb(){this.evEl=ub,this.evWin=vb,ab.apply(this,arguments),this.store=this.manager.session.pointerEvents=[]}function Ab(){this.evTarget=yb,this.evWin=zb,this.started=!1,ab.apply(this,arguments)}function Bb(a,b){var c=z(a.touches),d=z(a.changedTouches);return b&(Q|R)&&(c=A(c.concat(d),"identifier",!0)),[c,d]}function Eb(){this.evTarget=Db,this.targetIds={},ab.apply(this,arguments)}function Fb(a,b){var c=z(a.touches),d=this.targetIds;if(b&(O|P)&&1===c.length)return d[c[0].identifier]=!0,[c,c];var e,f,g=z(a.changedTouches),h=[],i=this.target;if(f=c.filter(function(a){return v(a.target,i)}),b===O)for(e=0;e<f.length;)d[f[e].identifier]=!0,e++;for(e=0;e<g.length;)d[g[e].identifier]&&h.push(g[e]),b&(Q|R)&&delete d[g[e].identifier],e++;return h.length?[A(f.concat(h),"identifier",!0),h]:void 0}function Gb(){ab.apply(this,arguments);var a=q(this.handler,this);this.touch=new Eb(this.manager,a),this.mouse=new rb(this.manager,a)}function Pb(a,b){this.manager=a,this.set(b)}function Qb(a){if(w(a,Mb))return Mb;var b=w(a,Nb),c=w(a,Ob);return b&&c?Nb+" "+Ob:b||c?b?Nb:Ob:w(a,Lb)?Lb:Kb}function Yb(a){this.id=D(),this.manager=null,this.options=o(a||{},this.defaults),this.options.enable=s(this.options.enable,!0),this.state=Rb,this.simultaneous={},this.requireFail=[]}function Zb(a){return a&Wb?"cancel":a&Ub?"end":a&Tb?"move":a&Sb?"start":""}function $b(a){return a==W?"down":a==V?"up":a==T?"left":a==U?"right":""}function _b(a,b){var c=b.manager;return c?c.get(a):a}function ac(){Yb.apply(this,arguments)}function bc(){ac.apply(this,arguments),this.pX=null,this.pY=null}function cc(){ac.apply(this,arguments)}function dc(){Yb.apply(this,arguments),this._timer=null,this._input=null}function ec(){ac.apply(this,arguments)}function fc(){ac.apply(this,arguments)}function gc(){Yb.apply(this,arguments),this.pTime=!1,this.pCenter=!1,this._timer=null,this._input=null,this.count=0}function hc(a,b){return b=b||{},b.recognizers=s(b.recognizers,hc.defaults.preset),new kc(a,b)}function kc(a,b){b=b||{},this.options=o(b,hc.defaults),this.options.inputTarget=this.options.inputTarget||a,this.handlers={},this.session={},this.recognizers=[],this.element=a,this.input=bb(this),this.touchAction=new Pb(this,this.options.touchAction),lc(this,!0),m(b.recognizers,function(a){var b=this.add(new a[0](a[1]));a[2]&&b.recognizeWith(a[2]),a[3]&&b.requireFailure(a[3])},this)}function lc(a,b){var c=a.element;m(a.options.cssProps,function(a,d){c.style[B(c.style,d)]=b?a:""})}function mc(a,c){var d=b.createEvent("Event");d.initEvent(a,!0,!0),d.gesture=c,c.target.dispatchEvent(d)}var e=["","webkit","moz","MS","ms","o"],f=b.createElement("div"),g="function",h=Math.round,i=Math.abs,j=Date.now,C=1,F=/mobile|tablet|ip(ad|hone|od)|android/i,G="ontouchstart"in a,H=B(a,"PointerEvent")!==d,I=G&&F.test(navigator.userAgent),J="touch",K="pen",L="mouse",M="kinect",N=25,O=1,P=2,Q=4,R=8,S=1,T=2,U=4,V=8,W=16,X=T|U,Y=V|W,Z=X|Y,$=["x","y"],_=["clientX","clientY"];ab.prototype={handler:function(){},init:function(){this.evEl&&t(this.element,this.evEl,this.domHandler),this.evTarget&&t(this.target,this.evTarget,this.domHandler),this.evWin&&t(E(this.element),this.evWin,this.domHandler)},destroy:function(){this.evEl&&u(this.element,this.evEl,this.domHandler),this.evTarget&&u(this.target,this.evTarget,this.domHandler),this.evWin&&u(E(this.element),this.evWin,this.domHandler)}};var ob={mousedown:O,mousemove:P,mouseup:Q},pb="mousedown",qb="mousemove mouseup";p(rb,ab,{handler:function(a){var b=ob[a.type];b&O&&0===a.button&&(this.pressed=!0),b&P&&1!==a.which&&(b=Q),this.pressed&&this.allow&&(b&Q&&(this.pressed=!1),this.callback(this.manager,b,{pointers:[a],changedPointers:[a],pointerType:L,srcEvent:a}))}});var sb={pointerdown:O,pointermove:P,pointerup:Q,pointercancel:R,pointerout:R},tb={2:J,3:K,4:L,5:M},ub="pointerdown",vb="pointermove pointerup pointercancel";a.MSPointerEvent&&(ub="MSPointerDown",vb="MSPointerMove MSPointerUp MSPointerCancel"),p(wb,ab,{handler:function(a){var b=this.store,c=!1,d=a.type.toLowerCase().replace("ms",""),e=sb[d],f=tb[a.pointerType]||a.pointerType,g=f==J,h=y(b,a.pointerId,"pointerId");e&O&&(0===a.button||g)?0>h&&(b.push(a),h=b.length-1):e&(Q|R)&&(c=!0),0>h||(b[h]=a,this.callback(this.manager,e,{pointers:b,changedPointers:[a],pointerType:f,srcEvent:a}),c&&b.splice(h,1))}});var xb={touchstart:O,touchmove:P,touchend:Q,touchcancel:R},yb="touchstart",zb="touchstart touchmove touchend touchcancel";p(Ab,ab,{handler:function(a){var b=xb[a.type];if(b===O&&(this.started=!0),this.started){var c=Bb.call(this,a,b);b&(Q|R)&&0===c[0].length-c[1].length&&(this.started=!1),this.callback(this.manager,b,{pointers:c[0],changedPointers:c[1],pointerType:J,srcEvent:a})}}});var Cb={touchstart:O,touchmove:P,touchend:Q,touchcancel:R},Db="touchstart touchmove touchend touchcancel";p(Eb,ab,{handler:function(a){var b=Cb[a.type],c=Fb.call(this,a,b);c&&this.callback(this.manager,b,{pointers:c[0],changedPointers:c[1],pointerType:J,srcEvent:a})}}),p(Gb,ab,{handler:function(a,b,c){var d=c.pointerType==J,e=c.pointerType==L;if(d)this.mouse.allow=!1;else if(e&&!this.mouse.allow)return;b&(Q|R)&&(this.mouse.allow=!0),this.callback(a,b,c)},destroy:function(){this.touch.destroy(),this.mouse.destroy()}});var Hb=B(f.style,"touchAction"),Ib=Hb!==d,Jb="compute",Kb="auto",Lb="manipulation",Mb="none",Nb="pan-x",Ob="pan-y";Pb.prototype={set:function(a){a==Jb&&(a=this.compute()),Ib&&(this.manager.element.style[Hb]=a),this.actions=a.toLowerCase().trim()},update:function(){this.set(this.manager.options.touchAction)},compute:function(){var a=[];return m(this.manager.recognizers,function(b){r(b.options.enable,[b])&&(a=a.concat(b.getTouchAction()))}),Qb(a.join(" "))},preventDefaults:function(a){if(!Ib){var b=a.srcEvent,c=a.offsetDirection;if(this.manager.session.prevented)return b.preventDefault(),void 0;var d=this.actions,e=w(d,Mb),f=w(d,Ob),g=w(d,Nb);return e||f&&c&X||g&&c&Y?this.preventSrc(b):void 0}},preventSrc:function(a){this.manager.session.prevented=!0,a.preventDefault()}};var Rb=1,Sb=2,Tb=4,Ub=8,Vb=Ub,Wb=16,Xb=32;Yb.prototype={defaults:{},set:function(a){return n(this.options,a),this.manager&&this.manager.touchAction.update(),this},recognizeWith:function(a){if(l(a,"recognizeWith",this))return this;var b=this.simultaneous;return a=_b(a,this),b[a.id]||(b[a.id]=a,a.recognizeWith(this)),this},dropRecognizeWith:function(a){return l(a,"dropRecognizeWith",this)?this:(a=_b(a,this),delete this.simultaneous[a.id],this)},requireFailure:function(a){if(l(a,"requireFailure",this))return this;var b=this.requireFail;return a=_b(a,this),-1===y(b,a)&&(b.push(a),a.requireFailure(this)),this},dropRequireFailure:function(a){if(l(a,"dropRequireFailure",this))return this;a=_b(a,this);var b=y(this.requireFail,a);return b>-1&&this.requireFail.splice(b,1),this},hasRequireFailures:function(){return this.requireFail.length>0},canRecognizeWith:function(a){return!!this.simultaneous[a.id]},emit:function(a){function d(d){b.manager.emit(b.options.event+(d?Zb(c):""),a)}var b=this,c=this.state;Ub>c&&d(!0),d(),c>=Ub&&d(!0)},tryEmit:function(a){return this.canEmit()?this.emit(a):(this.state=Xb,void 0)},canEmit:function(){for(var a=0;a<this.requireFail.length;){if(!(this.requireFail[a].state&(Xb|Rb)))return!1;a++}return!0},recognize:function(a){var b=n({},a);return r(this.options.enable,[this,b])?(this.state&(Vb|Wb|Xb)&&(this.state=Rb),this.state=this.process(b),this.state&(Sb|Tb|Ub|Wb)&&this.tryEmit(b),void 0):(this.reset(),this.state=Xb,void 0)},process:function(){},getTouchAction:function(){},reset:function(){}},p(ac,Yb,{defaults:{pointers:1},attrTest:function(a){var b=this.options.pointers;return 0===b||a.pointers.length===b},process:function(a){var b=this.state,c=a.eventType,d=b&(Sb|Tb),e=this.attrTest(a);return d&&(c&R||!e)?b|Wb:d||e?c&Q?b|Ub:b&Sb?b|Tb:Sb:Xb}}),p(bc,ac,{defaults:{event:"pan",threshold:10,pointers:1,direction:Z},getTouchAction:function(){var a=this.options.direction,b=[];return a&X&&b.push(Ob),a&Y&&b.push(Nb),b},directionTest:function(a){var b=this.options,c=!0,d=a.distance,e=a.direction,f=a.deltaX,g=a.deltaY;return e&b.direction||(b.direction&X?(e=0===f?S:0>f?T:U,c=f!=this.pX,d=Math.abs(a.deltaX)):(e=0===g?S:0>g?V:W,c=g!=this.pY,d=Math.abs(a.deltaY))),a.direction=e,c&&d>b.threshold&&e&b.direction},attrTest:function(a){return ac.prototype.attrTest.call(this,a)&&(this.state&Sb||!(this.state&Sb)&&this.directionTest(a))},emit:function(a){this.pX=a.deltaX,this.pY=a.deltaY;var b=$b(a.direction);b&&this.manager.emit(this.options.event+b,a),this._super.emit.call(this,a)}}),p(cc,ac,{defaults:{event:"pinch",threshold:0,pointers:2},getTouchAction:function(){return[Mb]},attrTest:function(a){return this._super.attrTest.call(this,a)&&(Math.abs(a.scale-1)>this.options.threshold||this.state&Sb)},emit:function(a){if(this._super.emit.call(this,a),1!==a.scale){var b=a.scale<1?"in":"out";this.manager.emit(this.options.event+b,a)}}}),p(dc,Yb,{defaults:{event:"press",pointers:1,time:500,threshold:5},getTouchAction:function(){return[Kb]},process:function(a){var b=this.options,c=a.pointers.length===b.pointers,d=a.distance<b.threshold,e=a.deltaTime>b.time;if(this._input=a,!d||!c||a.eventType&(Q|R)&&!e)this.reset();else if(a.eventType&O)this.reset(),this._timer=k(function(){this.state=Vb,this.tryEmit()},b.time,this);else if(a.eventType&Q)return Vb;return Xb},reset:function(){clearTimeout(this._timer)},emit:function(a){this.state===Vb&&(a&&a.eventType&Q?this.manager.emit(this.options.event+"up",a):(this._input.timeStamp=j(),this.manager.emit(this.options.event,this._input)))}}),p(ec,ac,{defaults:{event:"rotate",threshold:0,pointers:2},getTouchAction:function(){return[Mb]},attrTest:function(a){return this._super.attrTest.call(this,a)&&(Math.abs(a.rotation)>this.options.threshold||this.state&Sb)}}),p(fc,ac,{defaults:{event:"swipe",threshold:10,velocity:.65,direction:X|Y,pointers:1},getTouchAction:function(){return bc.prototype.getTouchAction.call(this)},attrTest:function(a){var c,b=this.options.direction;return b&(X|Y)?c=a.velocity:b&X?c=a.velocityX:b&Y&&(c=a.velocityY),this._super.attrTest.call(this,a)&&b&a.direction&&a.distance>this.options.threshold&&i(c)>this.options.velocity&&a.eventType&Q},emit:function(a){var b=$b(a.direction);b&&this.manager.emit(this.options.event+b,a),this.manager.emit(this.options.event,a)}}),p(gc,Yb,{defaults:{event:"tap",pointers:1,taps:1,interval:300,time:250,threshold:2,posThreshold:10},getTouchAction:function(){return[Lb]},process:function(a){var b=this.options,c=a.pointers.length===b.pointers,d=a.distance<b.threshold,e=a.deltaTime<b.time;if(this.reset(),a.eventType&O&&0===this.count)return this.failTimeout();if(d&&e&&c){if(a.eventType!=Q)return this.failTimeout();var f=this.pTime?a.timeStamp-this.pTime<b.interval:!0,g=!this.pCenter||kb(this.pCenter,a.center)<b.posThreshold;this.pTime=a.timeStamp,this.pCenter=a.center,g&&f?this.count+=1:this.count=1,this._input=a;var h=this.count%b.taps;if(0===h)return this.hasRequireFailures()?(this._timer=k(function(){this.state=Vb,this.tryEmit()},b.interval,this),Sb):Vb}return Xb},failTimeout:function(){return this._timer=k(function(){this.state=Xb},this.options.interval,this),Xb},reset:function(){clearTimeout(this._timer)},emit:function(){this.state==Vb&&(this._input.tapCount=this.count,this.manager.emit(this.options.event,this._input))}}),hc.VERSION="2.0.4",hc.defaults={domEvents:!1,touchAction:Jb,enable:!0,inputTarget:null,inputClass:null,preset:[[ec,{enable:!1}],[cc,{enable:!1},["rotate"]],[fc,{direction:X}],[bc,{direction:X},["swipe"]],[gc],[gc,{event:"doubletap",taps:2},["tap"]],[dc]],cssProps:{userSelect:"default",touchSelect:"none",touchCallout:"none",contentZooming:"none",userDrag:"none",tapHighlightColor:"rgba(0,0,0,0)"}};var ic=1,jc=2;kc.prototype={set:function(a){return n(this.options,a),a.touchAction&&this.touchAction.update(),a.inputTarget&&(this.input.destroy(),this.input.target=a.inputTarget,this.input.init()),this},stop:function(a){this.session.stopped=a?jc:ic},recognize:function(a){var b=this.session;if(!b.stopped){this.touchAction.preventDefaults(a);var c,d=this.recognizers,e=b.curRecognizer;(!e||e&&e.state&Vb)&&(e=b.curRecognizer=null);for(var f=0;f<d.length;)c=d[f],b.stopped===jc||e&&c!=e&&!c.canRecognizeWith(e)?c.reset():c.recognize(a),!e&&c.state&(Sb|Tb|Ub)&&(e=b.curRecognizer=c),f++}},get:function(a){if(a instanceof Yb)return a;for(var b=this.recognizers,c=0;c<b.length;c++)if(b[c].options.event==a)return b[c];return null},add:function(a){if(l(a,"add",this))return this;var b=this.get(a.options.event);return b&&this.remove(b),this.recognizers.push(a),a.manager=this,this.touchAction.update(),a},remove:function(a){if(l(a,"remove",this))return this;var b=this.recognizers;return a=this.get(a),b.splice(y(b,a),1),this.touchAction.update(),this},on:function(a,b){var c=this.handlers;return m(x(a),function(a){c[a]=c[a]||[],c[a].push(b)}),this},off:function(a,b){var c=this.handlers;return m(x(a),function(a){b?c[a].splice(y(c[a],b),1):delete c[a]}),this},emit:function(a,b){this.options.domEvents&&mc(a,b);var c=this.handlers[a]&&this.handlers[a].slice();if(c&&c.length){b.type=a,b.preventDefault=function(){b.srcEvent.preventDefault()};for(var d=0;d<c.length;)c[d](b),d++}},destroy:function(){this.element&&lc(this,!1),this.handlers={},this.session={},this.input.destroy(),this.element=null}},n(hc,{INPUT_START:O,INPUT_MOVE:P,INPUT_END:Q,INPUT_CANCEL:R,STATE_POSSIBLE:Rb,STATE_BEGAN:Sb,STATE_CHANGED:Tb,STATE_ENDED:Ub,STATE_RECOGNIZED:Vb,STATE_CANCELLED:Wb,STATE_FAILED:Xb,DIRECTION_NONE:S,DIRECTION_LEFT:T,DIRECTION_RIGHT:U,DIRECTION_UP:V,DIRECTION_DOWN:W,DIRECTION_HORIZONTAL:X,DIRECTION_VERTICAL:Y,DIRECTION_ALL:Z,Manager:kc,Input:ab,TouchAction:Pb,TouchInput:Eb,MouseInput:rb,PointerEventInput:wb,TouchMouseInput:Gb,SingleTouchInput:Ab,Recognizer:Yb,AttrRecognizer:ac,Tap:gc,Pan:bc,Swipe:fc,Pinch:cc,Rotate:ec,Press:dc,on:t,off:u,each:m,merge:o,extend:n,inherit:p,bindFn:q,prefixed:B}),typeof define==g&&define.amd?define(function(){return hc}):"undefined"!=typeof module&&module.exports?module.exports=hc:a[c]=hc}(window,document,"Hammer");;(function(factory) { 234 if (typeof define === 'function' && define.amd) { 235 define(['jquery', 'hammerjs'], factory); 236 } else if (typeof exports === 'object') { 237 factory(require('jquery'), require('hammerjs')); 238 } else { 239 factory(jQuery, Hammer); 240 } 241}(function($, Hammer) { 242 function hammerify(el, options) { 243 var $el = $(el); 244 if(!$el.data("hammer")) { 245 $el.data("hammer", new Hammer($el[0], options)); 246 } 247 } 248 249 $.fn.hammer = function(options) { 250 return this.each(function() { 251 hammerify(this, options); 252 }); 253 }; 254 255 // extend the emit method to also trigger jQuery events 256 Hammer.Manager.prototype.emit = (function(originalEmit) { 257 return function(type, data) { 258 originalEmit.call(this, type, data); 259 $(this.element).trigger({ 260 type: type, 261 gesture: data 262 }); 263 }; 264 })(Hammer.Manager.prototype.emit); 265})); 266;// Required for Meteor package, the use of window prevents export by Meteor 267(function(window){ 268 if(window.Package){ 269 Materialize = {}; 270 } else { 271 window.Materialize = {}; 272 } 273})(window); 274 275 276/* 277 * raf.js 278 * https://github.com/ngryman/raf.js 279 * 280 * original requestAnimationFrame polyfill by Erik Möller 281 * inspired from paul_irish gist and post 282 * 283 * Copyright (c) 2013 ngryman 284 * Licensed under the MIT license. 285 */ 286(function(window) { 287 var lastTime = 0, 288 vendors = ['webkit', 'moz'], 289 requestAnimationFrame = window.requestAnimationFrame, 290 cancelAnimationFrame = window.cancelAnimationFrame,
291 i = vendors.length; 292 293 // try to un-prefix existing raf 294 while (--i >= 0 && !requestAnimationFrame) { 295 requestAnimationFrame = window[vendors[i] + 'RequestAnimationFrame']; 296 cancelAnimationFrame = window[vendors[i] + 'CancelRequestAnimationFrame']; 297 } 298 299 // polyfill with setTimeout fallback 300 // heavily inspired from @darius gist mod: https://gist.github.com/paulirish/1579671#comment-837945 301 if (!requestAnimationFrame || !cancelAnimationFrame) { 302 requestAnimationFrame = function(callback) { 303 var now = +Date.now(), 304 nextTime = Math.max(lastTime + 16, now); 305 return setTimeout(function() { 306 callback(lastTime = nextTime); 307 }, nextTime - now); 308 }; 309 310 cancelAnimationFrame = clearTimeout; 311 } 312 313 // export to window 314 window.requestAnimationFrame = requestAnimationFrame; 315 window.cancelAnimationFrame = cancelAnimationFrame; 316}(window)); 317 318 319// Unique ID 320Materialize.guid = (function() { 321 function s4() { 322 return Math.floor((1 + Math.random()) * 0x10000) 323 .toString(16) 324 .substring(1); 325 } 326 return function() { 327 return s4() + s4() + '-' + s4() + '-' + s4() + '-' + 328 s4() + '-' + s4() + s4() + s4(); 329 }; 330})(); 331 332/** 333 * Escapes hash from special characters 334 * @param {string} hash String returned from this.hash 335 * @returns {string} 336 */ 337Materialize.escapeHash = function(hash) { 338 return hash.replace( /(:|\.|\[|\]|,|=)/g, "\\$1" ); 339}; 340 341Materialize.elementOrParentIsFixed = function(element) { 342 var $element = $(element); 343 var $checkElements = $element.add($element.parents()); 344 var isFixed = false; 345 $checkElements.each(function(){ 346 if ($(this).css("position") === "fixed") { 347 isFixed = true; 348 return false; 349 } 350 }); 351 return isFixed; 352}; 353 354 355/** 356 * Get time in ms 357 * @license https://raw.github.com/jashkenas/underscore/master/LICENSE 358 * @type {function} 359 * @return {number} 360 */ 361var getTime = (Date.now || function () { 362 return new Date().getTime(); 363}); 364 365 366/** 367 * Returns a function, that, when invoked, will only be triggered at most once 368 * during a given window of time. Normally, the throttled function will run 369 * as much as it can, without ever going more than once per `wait` duration; 370 * but if you'd like to disable the execution on the leading edge, pass 371 * `{leading: false}`. To disable execution on the trailing edge, ditto. 372 * @license https://raw.github.com/jashkenas/underscore/master/LICENSE 373 * @param {function} func 374 * @param {number} wait 375 * @param {Object=} options 376 * @returns {Function} 377 */ 378Materialize.throttle = function(func, wait, options) { 379 var context, args, result; 380 var timeout = null; 381 var previous = 0; 382 options || (options = {}); 383 var later = function () { 384 previous = options.leading === false ? 0 : getTime(); 385 timeout = null; 386 result = func.apply(context, args); 387 context = args = null; 388 }; 389 return function () { 390 var now = getTime(); 391 if (!previous && options.leading === false) previous = now; 392 var remaining = wait - (now - previous); 393 context = this; 394 args = arguments; 395 if (remaining <= 0) { 396 clearTimeout(timeout); 397 timeout = null; 398 previous = now; 399 result = func.apply(context, args); 400 context = args = null; 401 } else if (!timeout && options.trailing !== false) { 402 timeout = setTimeout(later, remaining); 403 } 404 return result; 405 }; 406}; 407 408 409// Velocity has conflicts when loaded with jQuery, this will check for it 410// First, check if in noConflict mode 411var Vel; 412if (jQuery) { 413 Vel = jQuery.Velocity; 414} else if ($) { 415 Vel = $.Velocity; 416} else { 417 Vel = Velocity; 418} 419;(function ($) { 420 $.fn.collapsible = function(options) { 421 var defaults = { 422 accordion: undefined, 423 onOpen: undefined, 424 onClose: undefined 425 }; 426 427 options = $.extend(defaults, options); 428 429 430 return this.each(function() { 431 432 var $this = $(this); 433 434 var $panel_headers = $(this).find('> li > .collapsible-header'); 435 436 var collapsible_type = $this.data("collapsible"); 437 438 // Turn off any existing event handlers 439 $this.off('click.collapse', '> li > .collapsible-header'); 440 $panel_headers.off('click.collapse'); 441 442 443 /**************** 444 Helper Functions 445 ****************/ 446 447 // Accordion Open 448 function accordionOpen(object) { 449 $panel_headers = $this.find('> li > .collapsible-header'); 450 if (object.hasClass('active')) { 451 object.parent().addClass('active'); 452 } 453 else { 454 object.parent().removeClass('active'); 455 } 456 if (object.parent().hasClass('active')){
457 object.siblings('.collapsible-body').stop(true,false).slideDown({ duration: 350, easing: "easeOutQuart", queue: false, complete: function() {$(this).css('height', '');}}); 458 } 459 else{ 460 object.siblings('.collapsible-body').stop(true,false).slideUp({ duration: 350, easing: "easeOutQuart", queue: false, complete: function() {$(this).css('height', '');}}); 461 } 462 463 $panel_headers.not(object).removeClass('active').parent().removeClass('active'); 464 465 // Close previously open accordion elements. 466 $panel_headers.not(object).parent().children('.collapsible-body').stop(true,false).each(function() { 467 if ($(this).is(':visible')) { 468 $(this).slideUp({ 469 duration: 350, 470 easing: "easeOutQuart", 471 queue: false, 472 complete: 473 function() { 474 $(this).css('height', ''); 475 execCallbacks($(this).siblings('.collapsible-header')); 476 } 477 }); 478 } 479 }); 480 } 481 482 // Expandable Open 483 function expandableOpen(object) { 484 if (object.hasClass('active')) { 485 object.parent().addClass('active'); 486 } 487 else { 488 object.parent().removeClass('active'); 489 } 490 if (object.parent().hasClass('active')){ 491 object.siblings('.collapsible-body').stop(true,false).slideDown({ duration: 350, easing: "easeOutQuart", queue: false, complete: function() {$(this).css('height', '');}}); 492 } 493 else { 494 object.siblings('.collapsible-body').stop(true,false).slideUp({ duration: 350, easing: "easeOutQuart", queue: false, complete: function() {$(this).css('height', '');}}); 495 } 496 } 497 498 // Open collapsible. object: .collapsible-header 499 function collapsibleOpen(object) { 500 if (options.accordion || collapsible_type === "accordion" || collapsible_type === undefined) { // Handle Accordion 501 accordionOpen(object); 502 } else { // Handle Expandables 503 expandableOpen(object); 504 } 505 506 execCallbacks(object); 507 } 508 509 // Handle callbacks 510 function execCallbacks(object) { 511 if (object.hasClass('active')) { 512 if (typeof(options.onOpen) === "function") { 513 options.onOpen.call(this, object.parent()); 514 } 515 } else { 516 if (typeof(options.onClose) === "function") { 517 options.onClose.call(this, object.parent()); 518 } 519 } 520 } 521 522 /** 523 * Check if object is children of panel header 524 * @param {Object} object Jquery object 525 * @return {Boolean} true if it is children 526 */ 527 function isChildrenOfPanelHeader(object) { 528 529 var panelHeader = getPanelHeader(object); 530 531 return panelHeader.length > 0; 532 } 533 534 /** 535 * Get panel header from a children element 536 * @param {Object} object Jquery object 537 * @return {Object} panel header object 538 */ 539 function getPanelHeader(object) { 540 541 return object.closest('li > .collapsible-header'); 542 } 543 544 /***** End Helper Functions *****/ 545 546 547 548 // Add click handler to only direct collapsible header children 549 $this.on('click.collapse', '> li > .collapsible-header', function(e) { 550 var element = $(e.target); 551 552 if (isChildrenOfPanelHeader(element)) { 553 element = getPanelHeader(element); 554 } 555 556 element.toggleClass('active'); 557 558 collapsibleOpen(element); 559 }); 560 561 562 // Open first active 563 if (options.accordion || collapsible_type === "accordion" || collapsible_type === undefined) { // Handle Accordion 564 collapsibleOpen($panel_headers.filter('.active').first()); 565 566 } else { // Handle Expandables 567 $panel_headers.filter('.active').each(function() { 568 collapsibleOpen($(this)); 569 }); 570 } 571 572 }); 573 }; 574 575 $(document).ready(function(){ 576 $('.collapsible').collapsible(); 577 }); 578}( jQuery ));;(function ($) { 579 580 // Add posibility to scroll to selected option 581 // usefull for select for example 582 $.fn.scrollTo = function(elem) { 583 $(this).scrollTop($(this).scrollTop() - $(this).offset().top + $(elem).offset().top); 584 return this; 585 }; 586 587 $.fn.dropdown = function (options) { 588 var defaults = { 589 inDuration: 300, 590 outDuration: 225, 591 constrainWidth: true, // Constrains width of dropdown to the activator
592 hover: false, 593 gutter: 0, // Spacing from edge 594 belowOrigin: false, 595 alignment: 'left', 596 stopPropagation: false 597 }; 598 599 // Open dropdown. 600 if (options === "open") { 601 this.each(function() { 602 $(this).trigger('open'); 603 }); 604 return false; 605 } 606 607 // Close dropdown. 608 if (options === "close") { 609 this.each(function() { 610 $(this).trigger('close'); 611 }); 612 return false; 613 } 614 615 this.each(function(){ 616 var origin = $(this); 617 var curr_options = $.extend({}, defaults, options); 618 var isFocused = false; 619 620 // Dropdown menu 621 var activates = $("#"+ origin.attr('data-activates')); 622 623 function updateOptions() { 624 if (origin.data('induration') !== undefined) 625 curr_options.inDuration = origin.data('induration'); 626 if (origin.data('outduration') !== undefined) 627 curr_options.outDuration = origin.data('outduration'); 628 if (origin.data('constrainwidth') !== undefined) 629 curr_options.constrainWidth = origin.data('constrainwidth'); 630 if (origin.data('hover') !== undefined) 631 curr_options.hover = origin.data('hover'); 632 if (origin.data('gutter') !== undefined) 633 curr_options.gutter = origin.data('gutter'); 634 if (origin.data('beloworigin') !== undefined) 635 curr_options.belowOrigin = origin.data('beloworigin'); 636 if (origin.data('alignment') !== undefined) 637 curr_options.alignment = origin.data('alignment'); 638 if (origin.data('stoppropagation') !== undefined) 639 curr_options.stopPropagation = origin.data('stoppropagation'); 640 } 641 642 updateOptions(); 643 644 // Attach dropdown to its activator 645 origin.after(activates); 646 647 /* 648 Helper function to position and resize dropdown. 649 Used in hover and click handler. 650 */ 651 function placeDropdown(eventType) { 652 // Check for simultaneous focus and click events. 653 if (eventType === 'focus') { 654 isFocused = true; 655 } 656 657 // Check html data attributes 658 updateOptions(); 659 660 // Set Dropdown state 661 activates.addClass('active'); 662 origin.addClass('active'); 663 origin.attr("aria-expanded","true"); 664 665 // Constrain width 666 if (curr_options.constrainWidth === true) { 667 activates.css('width', origin.outerWidth()); 668 669 } else { 670 activates.css('white-space', 'nowrap'); 671 } 672 673 // Offscreen detection 674 var windowHeight = window.innerHeight; 675 var originHeight = origin.innerHeight(); 676 var offsetLeft = origin.offset().left; 677 var offsetTop = origin.offset().top - $(window).scrollTop(); 678 var currAlignment = curr_options.alignment; 679 var gutterSpacing = 0; 680 var leftPosition = 0; 681 682 // Below Origin 683 var verticalOffset = 0; 684 if (curr_options.belowOrigin === true) { 685 verticalOffset = originHeight; 686 } 687 688 // Check for scrolling positioned container. 689 var scrollYOffset = 0; 690 var scrollXOffset = 0; 691 var wrapper = origin.parent(); 692 if (!wrapper.is('body')) { 693 if (wrapper[0].scrollHeight > wrapper[0].clientHeight) { 694 scrollYOffset = wrapper[0].scrollTop; 695 } 696 if (wrapper[0].scrollWidth > wrapper[0].clientWidth) { 697 scrollXOffset = wrapper[0].scrollLeft; 698 } 699 } 700 701 702 if (offsetLeft + activates.innerWidth() > $(window).width()) { 703 // Dropdown goes past screen on right, force right alignment 704 currAlignment = 'right'; 705 706 } else if (offsetLeft - activates.innerWidth() + origin.innerWidth() < 0) { 707 // Dropdown goes past screen on left, force left alignment 708 currAlignment = 'left'; 709 } 710 // Vertical bottom offscreen detection 711 if (offsetTop + activates.innerHeight() > windowHeight) { 712 // If going upwards still goes offscreen, just crop height of dropdown. 713 if (offsetTop + originHeight - activates.innerHeight() < 0 && !activates.hasClass('dropdown-side-nav')) { 714 var adjustedHeight = windowHeight - offsetTop - verticalOffset; 715 activates.css('max-height', adjustedHeight); 716 } else { 717 // Flow upwards. 718 if (!verticalOffset) { 719 verticalOffset += originHeight; 720 } 721 verticalOffset -= activates.innerHeight(); 722 } 723 } 724 725 // Handle edge alignment 726 if (currAlignment === 'left') { 727 gutterSpacing = curr_options.gutter; 728 leftPosition = origin.position().left + gutterSpacing; 729 } 730 else if (currAlignment === 'right') { 731 var offsetRight = origin.position().left + origin.outerWidth() - activates.outerWidth(); 732 gutterSpacing = -curr_options.gutter; 733 leftPosition = offsetRight + gutterSpacing; 734 } 735 736 // Position dropdown 737 activates.css({ 738 position: 'absolute', 739 top: origin.position().top + verticalOffset + scrollYOffset, 740 left: leftPosition + scrollXOffset 741 }); 742 743 744 // Show dropdown 745 activates.stop(true, true).css('opacity', 0) 746 .slideDown({ 747 queue: false, 748 duration: curr_options.inDuration, 749 easing: 'easeOutCubic', 750 complete: function() { 751 $(this).css('height', ''); 752 } 753 }) 754 .animate( {opacity: 1}, {queue: false, duration: curr_options.inDuration, easing: 'easeOutSine'}); 755 756 // Add click close handler to document 757 $(document).bind('click.'+ activates.attr('id'), function (e) { 758 if (!activates.is(e.target) && !origin.is(e.target) && (!origin.find(e.target).length) ) { 759 hideDropdown(); 760 $(document).unbind('click.' + activates.attr('id')); 761 } 762 }); 763 } 764 765 function hideDropdown() { 766 // Check for simultaneous focus and click events. 767 isFocused = false;
768 activates.fadeOut(curr_options.outDuration); 769 activates.removeClass('active'); 770 origin.removeClass('active'); 771 origin.attr("aria-expanded","false"); 772 $(document).unbind('click.'+ activates.attr('id') + ' touchstart.' + activates.attr('id')); 773 setTimeout(function() { activates.css('max-height', ''); }, curr_options.outDuration); 774 } 775 776 /*** 724117273529605-submenu-mousemove-fix Start changes for the delay dropdown-content section ***/ 777 // Hover 778 if (curr_options.hover) { 779 var open = false; 780 origin.unbind('click.' + origin.attr('id')); 781 782 // Hover handler to show dropdown 783 origin.on('mouseenter', function(e){ // Mouse over 784 if (open === false) { 785 /* Set a Timeout that lasts slightly longer than the mouseleave() delay so this can be evaluated after 786 * mouseleave() logic is run */ 787 setTimeout( function () { 788 /* If no other dropdown-button has the dropdown visible, then dis
788play this dropdown. Else, do not show 789 * this dropdown since we do not want two dropdowns shown at the same time. */ 790 if ( !$('.dropdown-button').hasClass('active') ) { 791 placeDropdown(); 792 open = true; 793 } 794 }, 100 ); 795 796 } 797 798 }); 799 800 origin.on('mouseleave', function(e){ 801 // If hover on origin then to something other than dropdown content, then close 802 var toEl = e.toElement || e.relatedTarget; // added browser compatibility for target element 803 804 if(!$(toEl).closest('.dropdown-content').is(activates)) { 805 /* Set a delay so that */ 806 setTimeout( function () { 807 /* After the delay, when the mouse moves grab the element that it is currently over */ 808 $(document).one("mousemove", function(e) { 809 var targetEvent = e.target; 810 /* If the target is not a dropdown menu, then hide the dropdown menu */ 811 if(!$(targetEvent).closest('.dropdown-content').is(activates)) { 812 activates.stop(true, true); 813 hideDropdown(); 814 open = false; 815 } 816 }); 817 }, 75); 818 } 819 }); 820 821 // Display the normal behavior when the mouse leaves the dropdown content 822 activates.on('mouseleave', function(e){ // Mouse out 823 var toEl = e.toElement || e.relatedTarget; 824 if(!$(toEl).closest('.dropdown-button').is(origin)) { 825 activates.stop(true, true); 826 hideDropdown(); 827 open = false; 828 } 829 }); 830 /*** 724117273529605-submenu-mousemove-fix End changes for the delay dropdown-content section ***/ 831 832 // Click 833 } else { 834 // Click handler to show dropdown 835 origin.unbind('click.' + origin.attr('id')); 836 origin.bind('click.'+origin.attr('id'), function(e){ 837 if (origin.is('.side-nav-dropdown-button')) { 838 // Prevent item click on side nav from opening dropdown. This was causing a conflict with click following the link 839 } else if (!isFocused) { 840 if ( origin[0] == e.currentTarget && 841 !origin.hasClass('active') && 842 ($(e.target).closest('.dropdown-content').length === 0)) { 843 e.preventDefault(); // Prevents button click from moving window 844 if (curr_options.stopPropagation) { 845 e.stopPropagation(); 846 } 847 placeDropdown('click'); 848 } 849 // If origin is clicked and menu is open, close menu 850 else if (origin.hasClass('active')) { 851 hideDropdown(); 852 $(document).unbind('click.'+ activates.attr('id')); 853 } 854 } 855 }); 856 857 } // End else 858 859 // Listen to open and close event - useful for select component 860 origin.on('open', function(e, eventType) { 861 placeDropdown(eventType); 862 }); 863 origin.on('close', hideDropdown); 864 865 866 }); 867 }; // End dropdown plugin 868 869 $(document).ready(function(){ 870 $('.dropdown-button').dropdown(); 871 }); 872}( jQuery )); 873;(function($) { 874 var _stack = 0, 875 _lastID = 0, 876 _generateID = function() { 877 _lastID++; 878 return 'materialize-modal-overlay-' + _lastID; 879 }; 880 881 var methods = { 882 init : function(options) { 883 var defaults = { 884 opacity: 0.5, 885 inDuration: 350, 886 outDuration: 250, 887 ready: undefined, 888 complete: undefined, 889 dismissible: true, 890 startingTop: '4%', 891 endingTop: '10%' 892 }; 893 894 // Override defaults 895 options = $.extend(defaults, options); 896 897 return this.each(function() { 898 var $modal = $(this); 899 var modal_id = $(this).attr("id") || '#' + $(this).data('target'); 900 901 var closeModal = function() { 902 var overlayID = $modal.data('overlay-id');
903 var $overlay = $('#' + overlayID); 904 $modal.removeClass('open'); 905 906 // Enable scrolling 907 $('body').css({ 908 overflow: '', 909 width: '' 910 }); 911 912 $modal.find('.modal-close').off('click.close'); 913 $(document).off('keyup.modal' + overlayID); 914 915 $overlay.velocity( { opacity: 0}, {duration: options.outDuration, queue: false, ease: "easeOutQuart"}); 916 917 918 // Define Bottom Sheet animation 919 var exitVelocityOptions = { 920 duration: options.outDuration, 921 queue: false, 922 ease: "easeOutCubic", 923 // Handle modal ready callback 924 complete: function() { 925 $(this).css({display:"none"}); 926 927 // Call complete callback 928 if (typeof(options.complete) === "function") { 929 options.complete.call(this, $modal); 930 } 931 $overlay.remove(); 932 _stack--; 933 } 934 }; 935 if ($modal.hasClass('bottom-sheet')) { 936 $modal.velocity({bottom: "-100%", opacity: 0}, exitVelocityOptions); 937 } 938 else { 939 $modal.velocity( 940 { top: options.startingTop, opacity: 0, scaleX: 0.7}, 941 exitVelocityOptions 942 ); 943 } 944 }; 945 946 var openModal = function($trigger) { 947 var $body = $('body'); 948 var oldWidth = $body.innerWidth(); 949 $body.css('overflow', 'hidden'); 950 $body.width(oldWidth); 951 952 if ($modal.hasClass('open')) { 953 return; 954 } 955 956 var overlayID = _generateID();
957 var $overlay = $('<div class="modal-overlay"></div>'); 958 lStack = (++_stack); 959 960 // Store a reference of the overlay 961 $overlay.attr('id', overlayID).css('z-index', 1000 + lStack * 2); 962 $modal.data('overlay-id', overlayID).css('z-index', 1000 + lStack * 2 + 1); 963 $modal.addClass('open'); 964 965 $("body").append($overlay); 966 967 if (options.dismissible) { 968 $overlay.click(function() { 969 closeModal(); 970 }); 971 // Return on ESC 972 $(document).on('keyup.modal' + overlayID, function(e) { 973 if (e.keyCode === 27) { // ESC key 974 closeModal(); 975 } 976 }); 977 } 978 979 $modal.find(".modal-close").on('click.close', function(e) { 980 closeModal(); 981 }); 982 983 $overlay.css({ display : "block", opacity : 0 }); 984 985 $modal.css({ 986 display : "block", 987 opacity: 0 988 }); 989 990 $overlay.velocity({opacity: options.opacity}, {duration: options.inDuration, queue: false, ease: "easeOutCubic"}); 991 $modal.data('associated-overlay', $overlay[0]); 992 993 // Define Bottom Sheet animation 994 var enterVelocityOptions = { 995 duration: options.inDuration, 996 queue: false, 997 ease: "easeOutCubic", 998 // Handle modal ready callback 999 complete: function() { 1000 if (typeof(options.ready) === "function") { 1001 options.ready.call(this, $modal, $trigger); 1002 } 1003 } 1004 }; 1005 if ($modal.hasClass('bottom-sheet')) { 1006 $modal.velocity({bottom: "0", opacity: 1}, enterVelocityOptions); 1007 } 1008 else { 1009 $.Velocity.hook($modal, "scaleX", 0.7); 1010 $modal.css({ top: options.startingTop }); 1011 $modal.velocity({top: options.endingTop, opacity: 1, scaleX: '1'}, enterVelocityOptions); 1012 } 1013 1014 }; 1015 1016 // Reset handlers 1017 $(document).off('click.modalTrigger', 'a[href="#' + modal_id + '"], [data-target="' + modal_id + '"]'); 1018 $(this).off('openModal'); 1019 $(this).off('closeModal'); 1020 1021 // Close Handlers 1022 $(document).on('click.modalTrigger', 'a[href="#' + modal_id + '"], [data-target="' + modal_id + '"]', function(e) { 1023 options.startingTop = ($(this).offset().top - $(window).scrollTop()) /1.15; 1024 openModal($(this)); 1025 e.preventDefault(); 1026 }); // done set on click 1027 1028 $(this).on('openModal', function() { 1029 var modal_id = $(this).attr("href") || '#' + $(this).data('target'); 1030 openModal(); 1031 }); 1032 1033 $(this).on('closeModal', function() { 1034 closeModal(); 1035 }); 1036 }); // done return 1037 }, 1038 open : function() { 1039 $(this).trigger('openModal'); 1040 }, 1041 close : function() { 1042 $(this).trigger('closeModal'); 1043 } 1044 }; 1045 1046 $.fn.modal = function(methodOrOptions) { 1047 if ( methods[methodOrOptions] ) { 1048 return methods[ methodOrOptions ].apply( this, Array.prototype.slice.call( arguments, 1 )); 1049 } else if ( typeof methodOrOptions === 'object' || ! methodOrOptions ) { 1050 // Default to "init" 1051 return methods.init.apply( this, arguments ); 1052 } else { 1053 $.error( 'Method ' + methodOrOptions + ' does not exist on jQuery.modal' ); 1054 } 1055 }; 1056})(jQuery); 1057;(function ($) { 1058 1059 $.fn.materialbox = function () { 1060 1061 return this.each(function() { 1062 1063 if ($(this).hasClass('initialized')) { 1064 return; 1065 } 1066 1067 $(this).addClass('initialized'); 1068 1069 var overlayActive = false; 1070 var doneAnimating = true; 1071 var inDuration = 275; 1072 var outDuration = 200; 1073 var origin = $(this); 1074 var placeholder = $('<div></div>').addClass('material-placeholder'); 1075 var originalWidth = 0; 1076 var originalHeight = 0; 1077 var ancestorsChanged; 1078 var ancestor; 1079 origin.wrap(placeholder); 1080 1081 1082 origin.on('click', function(){ 1083 var placeholder = origin.parent('.material-placeholder'); 1084 var windowWidth = window.innerWidth; 1085 var windowHeight = window.innerHeight; 1086 var originalWidth = origin.width(); 1087 var originalHeight = origin.height(); 1088 1089 1090 // If already modal, return to original 1091 if (doneAnimating === false) { 1092 returnToOriginal(); 1093 return false;
1094 } 1095 else if (overlayActive && doneAnimating===true) { 1096 returnToOriginal(); 1097 return false; 1098 } 1099 1100 1101 // Set states 1102 doneAnimating = false; 1103 origin.addClass('active'); 1104 overlayActive = true; 1105 1106 // Set positioning for placeholder 1107 placeholder.css({ 1108 width: placeholder[0].getBoundingClientRect().width, 1109 height: placeholder[0].getBoundingClientRect().height, 1110 position: 'relative', 1111 top: 0, 1112 left: 0 1113 }); 1114 1115 // Find ancestor with overflow: hidden; and remove it 1116 ancestorsChanged = undefined; 1117 ancestor = placeholder[0].parentNode; 1118 var count = 0; 1119 while (ancestor !== null && !$(ancestor).is(document)) { 1120 var curr = $(ancestor); 1121 if (curr.css('overflow') !== 'visible') { 1122 curr.css('overflow', 'visible'); 1123 if (ancestorsChanged === undefined) { 1124 ancestorsChanged = curr; 1125 } 1126 else { 1127 ancestorsChanged = ancestorsChanged.add(curr); 1128 } 1129 } 1130 ancestor = ancestor.parentNode; 1131 } 1132 1133 // Set css on origin 1134 origin.css({ 1135 position: 'absolute', 1136 'z-index': 1000, 1137 'will-change': 'left, top, width, height' 1138 }) 1139 .data('width', originalWidth) 1140 .data('height', originalHeight); 1141 1142 // Add overlay 1143 var overlay = $('<div id="materialbox-overlay"></div>') 1144 .css({ 1145 opacity: 0 1146 }) 1147 .click(function(){ 1148 if (doneAnimating === true) 1149 returnToOriginal(); 1150 }); 1151 1152 // Put before in origin image to preserve z-index layering. 1153 origin.before(overlay); 1154 1155 // Set dimensions if needed 1156 var overlayOffset = overlay[0].getBoundingClientRect(); 1157 overlay.css({ 1158 width: windowWidth, 1159 height: windowHeight, 1160 left: -1 * overlayOffset.left, 1161 top: -1 * overlayOffset.top 1162 }) 1163 1164 // Animate Overlay 1165 overlay.velocity({opacity: 1}, 1166 {duration: inDuration, queue: false, easing: 'easeOutQuad'} ); 1167 1168 // Add and animate caption if it exists 1169 if (origin.data('caption') !== "") { 1170 var $photo_caption = $('<div class="materialbox-caption"></div>'); 1171 $photo_caption.text(origin.data('caption')); 1172 $('body').append($photo_caption); 1173 $photo_caption.css({ "display": "inline" }); 1174 $photo_caption.velocity({opacity: 1}, {duration: inDuration, queue: false, easing: 'easeOutQuad'}); 1175 } 1176 1177 // Resize Image 1178 var ratio = 0; 1179 var widthPercent = originalWidth / windowWidth; 1180 var heightPercent = originalHeight / windowHeight; 1181 var newWidth = 0; 1182 var newHeight = 0; 1183 1184 if (widthPercent > heightPercent) { 1185 ratio = originalHeight / originalWidth; 1186 newWidth = windowWidth * 0.9; 1187 newHeight = windowWidth * 0.9 * ratio; 1188 } 1189 else { 1190 ratio = originalWidth / originalHeight; 1191 newWidth = (windowHeight * 0.9) * ratio; 1192 newHeight = windowHeight * 0.9; 1193 } 1194 1195 // Animate image + set z-index 1196 if(origin.hasClass('responsive-img')) { 1197 origin.velocity({'max-width': newWidth, 'width': originalWidth}, {duration: 0, queue: false, 1198 complete: function(){ 1199 origin.css({left: 0, top: 0}) 1200 .velocity( 1201 { 1202 height: newHeight, 1203 width: newWidth, 1204 left: $(document).scrollLeft() + windowWidth/2 - origin.parent('.material-placeholder').offset().left - newWidth/2, 1205 top: $(document).scrollTop() + windowHeight/2 - origin.parent('.material-placeholder').offset().top - newHeight/ 2 1206 }, 1207 { 1208 duration: inDuration, 1209 queue: false, 1210 easing: 'easeOutQuad', 1211 complete: function(){doneAnimating = true;} 1212 } 1213 ); 1214 } // End Complete 1215 }); // End Velocity 1216 } 1217 else { 1218 origin.css('left', 0) 1219 .css('top', 0) 1220 .velocity( 1221 { 1222 height: newHeight, 1223 width: newWidth, 1224 left: $(document).scrollLeft() + windowWidth/2 - origin.parent('.material-placeholder').offset().left - newWidth/2, 1225 top: $(document).scrollTop() + windowHeight/2 - origin.parent('.material-placeholder').offset().top - newHeight/ 2 1226 }, 1227 { 1228 duration: inDuration, 1229 queue: false, 1230 easing: 'easeOutQuad', 1231 complete: function(){doneAnimating = true;} 1232 } 1233 ); // End Velocity 1234 } 1235 1236 }); // End origin on click 1237 1238 1239 // Return on scroll 1240 $(window).scroll(function() { 1241 if (overlayActive) { 1242 returnToOriginal(); 1243 } 1244 }); 1245 1246 // Return on ESC 1247 $(document).keyup(function(e) { 1248 1249 if (e.keyCode === 27 && doneAnimating === true) { // ESC key 1250 if (overlayActive) { 1251 returnToOriginal(); 1252 } 1253 } 1254 }); 1255 1256 1257 // This function returns the modaled image to the original spot 1258 function returnToOriginal() { 1259 1260 doneAnimating = false;
1261 1262 var placeholder = origin.parent('.material-placeholder'); 1263 var windowWidth = window.innerWidth; 1264 var windowHeight = window.innerHeight; 1265 var originalWidth = origin.data('width'); 1266 var originalHeight = origin.data('height'); 1267 1268 origin.velocity("stop", true); 1269 $('#materialbox-overlay').velocity("stop", true); 1270 $('.materialbox-caption').velocity("stop", true); 1271 1272 1273 $('#materialbox-overlay').velocity({opacity: 0}, { 1274 duration: outDuration, // Delay prevents animation overlapping 1275 queue: false, easing: 'easeOutQuad', 1276 complete: function(){ 1277 // Remove Overlay 1278 overlayActive = false; 1279 $(this).remove(); 1280 } 1281 }); 1282 1283 // Resize Image 1284 origin.velocity( 1285 { 1286 width: originalWidth, 1287 height: originalHeight, 1288 left: 0, 1289 top: 0 1290 }, 1291 { 1292 duration: outDuration, 1293 queue: false, easing: 'easeOutQuad' 1294 } 1295 ); 1296 1297 // Remove Caption + reset css settings on image 1298 $('.materialbox-caption').velocity({opacity: 0}, { 1299 duration: outDuration, // Delay prevents animation overlapping 1300 queue: false, easing: 'easeOutQuad', 1301 complete: function(){ 1302 placeholder.css({ 1303 height: '', 1304 width: '', 1305 position: '', 1306 top: '', 1307 left: '' 1308 }); 1309 1310 origin.css({ 1311 height: '', 1312 top: '', 1313 left: '', 1314 width: '', 1315 'max-width': '', 1316 position: '', 1317 'z-index': '', 1318 'will-change': '' 1319 }); 1320 1321 // Remove class 1322 origin.removeClass('active'); 1323 doneAnimating = true; 1324 $(this).remove(); 1325 1326 // Remove overflow overrides on ancestors 1327 if (ancestorsChanged) { 1328 ancestorsChanged.css('overflow', ''); 1329 } 1330 } 1331 }); 1332 1333 } 1334 }); 1335 }; 1336 1337 $(document).ready(function(){ 1338 $('.materialboxed').materialbox(); 1339 }); 1340 1341}( jQuery )); 1342;(function ($) { 1343 1344 $.fn.parallax = function () { 1345 var window_width = $(window).width(); 1346 // Parallax Scripts 1347 return this.each(function(i) { 1348 var $this = $(this); 1349 $this.addClass('parallax'); 1350 1351 function updateParallax(initial) { 1352 var container_height; 1353 if (window_width < 601) { 1354 container_height = ($this.height() > 0) ? $this.height() : $this.children("img").height(); 1355 } 1356 else { 1357 container_height = ($this.height() > 0) ? $this.height() : 500; 1358 } 1359 var $img = $this.children("img").first(); 1360 var img_height = $img.height(); 1361 var parallax_dist = img_height - container_height; 1362 var bottom = $this.offset().top + container_height; 1363 var top = $this.offset().top; 1364 var scrollTop = $(window).scrollTop(); 1365 var windowHeight = window.innerHeight; 1366 var windowBottom = scrollTop + windowHeight; 1367 var percentScrolled = (windowBottom - top) / (container_height + windowHeight); 1368 var parallax = Math.round((parallax_dist * percentScrolled)); 1369 1370 if (initial) { 1371 $img.css('display', 'block'); 1372 } 1373 if ((bottom > scrollTop) && (top < (scrollTop + windowHeight))) { 1374 $img.css('transform', "translate3D(-50%," + parallax + "px, 0)"); 1375 } 1376 1377 } 1378 1379 // Wait for image load 1380 $this.children("img").one("load", function() { 1381 updateParallax(true); 1382 }).each(function() { 1383 if (this.complete) $(this).trigger("load"); 1384 }); 1385 1386 $(window).scroll(function() { 1387 window_width = $(window).width(); 1388 updateParallax(false); 1389 }); 1390 1391 $(window).resize(function() { 1392 window_width = $(window).width(); 1393 updateParallax(false); 1394 }); 1395 1396 }); 1397 1398 }; 1399}( jQuery )); 1400;(function ($) { 1401 1402 var methods = { 1403 init : function(options) { 1404 var defaults = { 1405 onShow: null, 1406 swipeable: false, 1407 responsiveThreshold: Infinity, // breakpoint for swipeable 1408 }; 1409 options = $.extend(defaults, options); 1410 1411 return this.each(function() { 1412 1413 // For each set of tabs, we want to keep track of 1414 // which tab is active and its associated content 1415 var $this = $(this), 1416 window_width = $(window).width(); 1417 1418 var $active, $content, $links = $this.find('li.tab a'), 1419 $tabs_width = $this.width(), 1420 $tabs_content = $(), 1421 $tabs_wrapper, 1422 $tab_width = Math.max($tabs_width, $this[0].scrollWidth) / $links.length, 1423 $indicator, 1424 index = prev_index = 0, 1425 clicked = false, 1426 clickedTimeout, 1427 transition = 300; 1428 1429 1430 // Finds right attribute for indicator based on active tab. 1431 // el: jQuery Object 1432 var calcRightPos = function(el) { 1433 return $tabs_width - el.position().left - el.outerWidth() - $this.scrollLeft(); 1434 }; 1435 1436 // Finds left attribute for indicator based on active tab. 1437 // el: jQuery Object 1438 var calcLeftPos = function(el) { 1439 return el.position().left + $this.scrollLeft(); 1440 }; 1441 1442 // Animates Indicator to active tab. 1443 // prev_index: Number 1444 var animateIndicator = function(prev_index) { 1445 if ((index - prev_index) >= 0) { 1446 $indicator.velocity({"right": calcRightPos($active) }, { duration: transition, queue: false, easing: 'easeOutQuad'}); 1447 $indicator.velocity({"left": calcLeftPos($active) }, {duration: transition, queue: false, easing: 'easeOutQuad', delay: 90}); 1448 1449 } else { 1450 $indicator.velocity({"left": calcLeftPos($active) }, { duration: transition, queue: false, easing: 'easeOutQuad'}); 1451 $indicator.velocity({"right": calcRightPos($active) }, {duration: transition, queue: false, easing: 'easeOutQuad', delay: 90}); 1452 } 1453 }; 1454 1455 // Change swipeable according to responsive threshold 1456 if (options.swipeable) { 1457 if (window_width > options.responsiveThreshold) { 1458 options.swipeable = false;
1459 } 1460 } 1461 1462 1463 // If the location.hash matches one of the links, use that as the active tab. 1464 $active = $($links.filter('[href="'+location.hash+'"]')); 1465 1466 // If no match is found, use the first link or any with class 'active' as the initial active tab. 1467 if ($active.length === 0) { 1468 $active = $(this).find('li.tab a.active').first(); 1469 } 1470 if ($active.length === 0) { 1471 $active = $(this).find('li.tab a').first(); 1472 } 1473 1474 $active.addClass('active'); 1475 index = $links.index($active); 1476 if (index < 0) { 1477 index = 0; 1478 } 1479 1480 if ($active[0] !== undefined) { 1481 $content = $($active[0].hash); 1482 $content.addClass('active'); 1483 } 1484 1485 // append indicator then set indicator width to tab width 1486 if (!$this.find('.indicator').length) { 1487 $this.append('<div class="indicator"></div>'); 1488 } 1489 $indicator = $this.find('.indicator'); 1490 1491 // we make sure that the indicator is at the end of the tabs 1492 $this.append($indicator); 1493 1494 if ($this.is(":visible")) { 1495 // $indicator.css({"right": $tabs_width - ((index + 1) * $tab_width)}); 1496 // $indicator.css({"left": index * $tab_width}); 1497 setTimeout(function() { 1498 $indicator.css({"right": calcRightPos($active) }); 1499 $indicator.css({"left": calcLeftPos($active) }); 1500 }, 0); 1501 } 1502 $(window).resize(function () { 1503 $tabs_width = $this.width(); 1504 $tab_width = Math.max($tabs_width, $this[0].scrollWidth) / $links.length; 1505 if (index < 0) { 1506 index = 0; 1507 } 1508 if ($tab_width !== 0 && $tabs_width !== 0) { 1509 $indicator.css({"right": calcRightPos($active) }); 1510 $indicator.css({"left": calcLeftPos($active) }); 1511 } 1512 }); 1513 1514 // Initialize Tabs Content. 1515 if (options.swipeable) { 1516 $links.each(function () { 1517 var $curr_content = $(Materialize.escapeHash(this.hash)); 1518 $curr_content.addClass('carousel-item'); 1519 $tabs_content = $tabs_content.add($curr_content); 1520 }); 1521 $tabs_wrapper = $tabs_content.wrapAll('<div class="tabs-content carousel"></div>'); 1522 $tabs_content.css('display', ''); 1523 $('.tabs-content.carousel').carousel({ 1524 fullWidth: true, 1525 noWrap: true, 1526 onCycleTo: function(item) { 1527 if (!clicked) { 1528 var prev_index = index; 1529 index = $tabs_wrapper.index(item); 1530 $active = $links.eq(index); 1531 animateIndicator(prev_index); 1532 } 1533 }, 1534 }); 1535 } else { 1536 // Hide the remaining content 1537 $links.not($active).each(function () { 1538 $(Materialize.escapeHash(this.hash)).hide(); 1539 }); 1540 } 1541 1542 1543 // Bind the click event handler 1544 $this.on('click', 'a', function(e) { 1545 if ($(this).parent().hasClass('disabled')) { 1546 e.preventDefault(); 1547 return; 1548 } 1549 1550 // Act as regular link if target attribute is specified. 1551 if (!!$(this).attr("target")) { 1552 return; 1553 } 1554 1555 clicked = true; 1556 $tabs_width = $this.width(); 1557 $tab_width = Math.max($tabs_width, $this[0].scrollWidth) / $links.length; 1558 1559 // Make the old tab inactive. 1560 $active.removeClass('active'); 1561 var $oldContent = $content 1562 1563 // Update the variables with the new link and content 1564 $active = $(this); 1565 $content = $(Materialize.escapeHash(this.hash)); 1566 $links = $this.find('li.tab a'); 1567 var activeRect = $active.position(); 1568 1569 // Make the tab active. 1570 $active.addClass('active'); 1571 prev_index = index; 1572 index = $links.index($(this)); 1573 if (index < 0) { 1574 index = 0; 1575 } 1576 // Change url to current tab 1577 // window.location.hash = $active.attr('href'); 1578 1579 // Swap content 1580 if (options.swipeable) { 1581 if ($tabs_content.length) { 1582 $tabs_content.carousel('set', index); 1583 } 1584 } else { 1585 if ($content !== undefined) { 1586 $content.show(); 1587 $content.addClass('active'); 1588 if (typeof(options.onShow) === "function") { 1589 options.onShow.call(this, $content); 1590 } 1591 } 1592 1593 if ($oldContent !== undefined && 1594 !$oldContent.is($content)) { 1595 $oldContent.hide(); 1596 $oldContent.removeClass('active'); 1597 } 1598 } 1599 1600 // Reset clicked state 1601 clickedTimeout = setTimeout(function(){ clicked = false; }, transition); 1602 1603 // Update indicator 1604 animateIndicator(prev_index); 1605
1606 // Prevent the anchor's default click action 1607 e.preventDefault(); 1608 }); 1609 }); 1610 1611 }, 1612 select_tab : function( id ) { 1613 this.find('a[href="#' + id + '"]').trigger('click'); 1614 } 1615 }; 1616 1617 $.fn.tabs = function(methodOrOptions) { 1618 if ( methods[methodOrOptions] ) { 1619 return methods[ methodOrOptions ].apply( this, Array.prototype.slice.call( arguments, 1 )); 1620 } else if ( typeof methodOrOptions === 'object' || ! methodOrOptions ) { 1621 // Default to "init" 1622 return methods.init.apply( this, arguments ); 1623 } else { 1624 $.error( 'Method ' + methodOrOptions + ' does not exist on jQuery.tabs' ); 1625 } 1626 }; 1627 1628 $(document).ready(function(){ 1629 $('ul.tabs').tabs(); 1630 }); 1631}( jQuery )); 1632;(function ($) { 1633 $.fn.tooltip = function (options) { 1634 var timeout = null, 1635 margin = 5; 1636 1637 // Defaults 1638 var defaults = { 1639 delay: 350, 1640 tooltip: '', 1641 position: 'bottom', 1642 html: false 1643 }; 1644 1645 // Remove tooltip from the activator 1646 if (options === "remove") { 1647 this.each(function() { 1648 $('#' + $(this).attr('data-tooltip-id')).remove(); 1649 $(this).off('mouseenter.tooltip mouseleave.tooltip'); 1650 }); 1651 return false; 1652 } 1653 1654 options = $.extend(defaults, options); 1655 1656 return this.each(function() { 1657 var tooltipId = Materialize.guid(); 1658 var origin = $(this); 1659 1660 // Destroy old tooltip 1661 if (origin.attr('data-tooltip-id')) { 1662 $('#' + origin.attr('data-tooltip-id')).remove(); 1663 } 1664 1665 origin.attr('data-tooltip-id', tooltipId); 1666 1667 // Get attributes. 1668 var allowHtml, 1669 tooltipDelay, 1670 tooltipPosition, 1671 tooltipText, 1672 tooltipEl, 1673 backdrop; 1674 var setAttributes = function() { 1675 allowHtml = origin.attr('data-html') ? origin.attr('data-html') === 'true' : options.html; 1676 tooltipDelay = origin.attr('data-delay'); 1677 tooltipDelay = (tooltipDelay === undefined || tooltipDelay === '') ? 1678 options.delay : tooltipDelay; 1679 tooltipPosition = origin.attr('data-position'); 1680 tooltipPosition = (tooltipPosition === undefined || tooltipPosition === '') ? 1681 options.position : tooltipPosition; 1682 tooltipText = origin.attr('data-tooltip'); 1683 tooltipText = (tooltipText === undefined || tooltipText === '') ? 1684 options.tooltip : tooltipText; 1685 }; 1686 setAttributes(); 1687 1688 var renderTooltipEl = function() { 1689 var tooltip = $('<div class="material-tooltip"></div>'); 1690 1691 // Create Text span 1692 if (allowHtml) { 1693 tooltipText = $('<span></span>').html(tooltipText); 1694 } else{ 1695 tooltipText = $('<span></span>').text(tooltipText); 1696 } 1697 1698 // Create tooltip 1699 tooltip.append(tooltipText) 1700 .appendTo($('body')) 1701 .attr('id', tooltipId); 1702 1703 // Create backdrop 1704 backdrop = $('<div class="backdrop"></div>'); 1705 backdrop.appendTo(tooltip); 1706 return tooltip; 1707 }; 1708 tooltipEl = renderTooltipEl(); 1709 1710 // Destroy previously binded events 1711 origin.off('mouseenter.tooltip mouseleave.tooltip'); 1712 // Mouse In 1713 var started = false, timeoutRef; 1714 origin.on({'mouseenter.tooltip': function(e) { 1715 var showTooltip = function() { 1716 setAttributes(); 1717 started = true; 1718 tooltipEl.velocity('stop'); 1719 backdrop.velocity('stop'); 1720 tooltipEl.css({ visibility: 'visible', left: '0px', top: '0px' }); 1721 1722 // Tooltip positioning 1723 var originWidth = origin.outerWidth(); 1724 var originHeight = origin.outerHeight(); 1725 var tooltipHeight = tooltipEl.outerHeight(); 1726 var tooltipWidth = tooltipEl.outerWidth(); 1727 var tooltipVerticalMovement = '0px'; 1728 var tooltipHorizontalMovement = '0px'; 1729 var backdropOffsetWidth = backdrop[0].offsetWidth; 1730 var backdropOffsetHeight = backdrop[0].offsetHeight; 1731 var scaleXFactor = 8; 1732 var scaleYFactor = 8; 1733 var scaleFactor = 0; 1734 var targetTop, targetLeft, newCoordinates; 1735 1736 if (tooltipPosition === "top") { 1737 // Top Position 1738 targetTop = origin.offset().top - tooltipHeight - margin; 1739 targetLeft = origin.offset().left + originWidth/2 - tooltipWidth/2; 1740 newCoordinates = repositionWithinScreen(targetLeft, targetTop, tooltipWidth, tooltipHeight); 1741 tooltipVerticalMovement = '-10px'; 1742 backdrop.css({ 1743 bottom: 0, 1744 left: 0, 1745 borderRadius: '14px 14px 0 0', 1746 transformOrigin: '50% 100%', 1747 marginTop: tooltipHeight, 1748 marginLeft: (tooltipWidth/2) - (backdropOffsetWidth/2) 1749 }); 1750 } 1751 // Left Position 1752 else if (tooltipPosition === "left") { 1753 targetTop = origin.offset().top + originHeight/2 - tooltipHeight/2; 1754 targetLeft = origin.offset().left - tooltipWidth - margin; 1755 newCoordinates = repositionWithinScreen(targetLeft, targetTop, tooltipWidth, tooltipHeight); 1756 1757 tooltipHorizontalMovement = '-10px'; 1758 backdrop.css({ 1759 top: '-7px', 1760 right: 0, 1761 width: '14px', 1762 height: '14px', 1763 borderRadius: '14px 0 0 14px', 1764 transformOrigin: '95% 50%', 1765 marginTop: tooltipHeight/2, 1766 marginLeft: tooltipWidth 1767 }); 1768 } 1769 // Right Position 1770 else if (tooltipPosition === "right") { 1771 targetTop = origin.offset().top + originHeight/2 - tooltipHeight/2; 1772 targetLeft = origin.offset().left + originWidth + margin; 1773 newCoordinates = repositionWithinScreen(targetLeft, targetTop, tooltipWidth, tooltipHeight); 1774 1775 tooltipHorizontalMovement = '+10px'; 1776 backdrop.css({ 1777 top: '-7px', 1778 left: 0, 1779 width: '14px', 1780 height: '14px', 1781 borderRadius: '0 14px 14px 0', 1782 transformOrigin: '5% 50%', 1783 marginTop: tooltipHeight/2, 1784 marginLeft: '0px' 1785 }); 1786 } 1787 else { 1788 // Bottom Position 1789 targetTop = origin.offset().top + origin.outerHeight() + margin; 1790 targetLeft = origin.offset().left + originWidth/2 - tooltipWidth/2; 1791 newCoordinates = repositionWithinScreen(targetLeft, targetTop, tooltipWidth, tooltipHeight); 1792 tooltipVerticalMovement = '+10px'; 1793 backdrop.css({ 1794 top: 0, 1795 left: 0, 1796 marginLeft: (tooltipWidth/2) - (backdropOffsetWidth/2) 1797 }); 1798 } 1799 1800 // Set tooptip css placement 1801 tooltipEl.css({ 1802 top: newCoordinates.y, 1803 left: newCoordinates.x 1804 }); 1805 1806 // Calculate Scale to fill 1807 scaleXFactor = Math.SQRT2 * tooltipWidth / parseInt(backdropOffsetWidth); 1808 scaleYFactor = Math.SQRT2 * tooltipHeight / parseInt(backdropOffsetHeight); 1809 scaleFactor = Math.max(scaleXFactor, scaleYFactor); 1810 1811 tooltipEl.velocity({ translateY: tooltipVerticalMovement, translateX: tooltipHorizontalMovement}, { duration: 350, queue: false }) 1812 .velocity({opacity: 1}, {duration: 300, delay: 50, queue: false}); 1813 backdrop.css({ visibility: 'visible' }) 1814 .velocity({opacity:1},{duration: 55, delay: 0, queue: false}) 1815 .velocity({scaleX: scaleFactor, scaleY: scaleFactor}, {duration: 300, delay: 0, queue: false, easing: 'easeInOutQuad'}); 1816 }; 1817 1818 timeoutRef = setTimeout(showTooltip, tooltipDelay); // End Interval 1819 1820 // Mouse Out 1821 }, 1822 'mouseleave.tooltip': function(){ 1823 // Reset State 1824 started = false;
1825 clearTimeout(timeoutRef); 1826 1827 // Animate back 1828 setTimeout(function() { 1829 if (started !== true) { 1830 tooltipEl.velocity({ 1831 opacity: 0, translateY: 0, translateX: 0}, { duration: 225, queue: false}); 1832 backdrop.velocity({opacity: 0, scaleX: 1, scaleY: 1}, { 1833 duration:225, 1834 queue: false, 1835 complete: function(){ 1836 backdrop.css({ visibility: 'hidden' }); 1837 tooltipEl.css({ visibility: 'hidden' }); 1838 started = false;} 1839 }); 1840 } 1841 },225); 1842 } 1843 }); 1844 }); 1845 }; 1846 1847 var repositionWithinScreen = function(x, y, width, height) { 1848 var newX = x; 1849 var newY = y; 1850 1851 if (newX < 0) { 1852 newX = 4; 1853 } else if (newX + width > window.innerWidth) { 1854 newX -= newX + width - window.innerWidth; 1855 } 1856 1857 if (newY < 0) { 1858 newY = 4; 1859 } else if (newY + height > window.innerHeight + $(window).scrollTop) { 1860 newY -= newY + height - window.innerHeight; 1861 } 1862 1863 return {x: newX, y: newY}; 1864 }; 1865 1866 $(document).ready(function(){ 1867 $('.tooltipped').tooltip(); 1868 }); 1869}( jQuery )); 1870;/*! 1871 * Waves v0.6.4 1872 * http://fian.my.id/Waves 1873 * 1874 * Copyright 2014 Alfiana E. Sibuea and other contributors 1875 * Released under the MIT license 1876 * https://github.com/fians/Waves/blob/master/LICENSE 1877 */ 1878 1879;(function(window) { 1880 'use strict'; 1881 1882 var Waves = Waves || {}; 1883 var $$ = document.querySelectorAll.bind(document); 1884 1885 // Find exact position of element 1886 function isWindow(obj) { 1887 return obj !== null && obj === obj.window; 1888 } 1889 1890 function getWindow(elem) { 1891 return isWindow(elem) ? elem : elem.nodeType === 9 && elem.defaultView; 1892 } 1893 1894 function offset(elem) { 1895 var docElem, win, 1896 box = {top: 0, left: 0}, 1897 doc = elem && elem.ownerDocument; 1898 1899 docElem = doc.documentElement; 1900 1901 if (typeof elem.getBoundingClientRect !== typeof undefined) { 1902 box = elem.getBoundingClientRect(); 1903 } 1904 win = getWindow(doc); 1905 return { 1906 top: box.top + win.pageYOffset - docElem.clientTop, 1907 left: box.left + win.pageXOffset - docElem.clientLeft 1908 }; 1909 } 1910 1911 function convertStyle(obj) { 1912 var style = ''; 1913 1914 for (var a in obj) { 1915 if (obj.hasOwnProperty(a)) { 1916 style += (a + ':' + obj[a] + ';'); 1917 } 1918 } 1919 1920 return style; 1921 } 1922 1923 var Effect = { 1924 1925 // Effect delay 1926 duration: 750, 1927 1928 show: function(e, element) { 1929 1930 // Disable right click 1931 if (e.button === 2) { 1932 return false; 1933 } 1934 1935 var el = element || this; 1936 1937 // Create ripple 1938 var ripple = document.createElement('div'); 1939 ripple.className = 'waves-ripple'; 1940 el.appendChild(ripple); 1941 1942 // Get click coordinate and element witdh 1943 var pos = offset(el); 1944 var relativeY = (e.pageY - pos.top); 1945 var relativeX = (e.pageX - pos.left); 1946 var scale = 'scale('+((el.clientWidth / 100) * 10)+')'; 1947 1948 // Support for touch devices 1949 if ('touches' in e) { 1950 relativeY = (e.touches[0].pageY - pos.top); 1951 relativeX = (e.touches[0].pageX - pos.left); 1952 } 1953 1954 // Attach data to element 1955 ripple.setAttribute('data-hold', Date.now()); 1956 ripple.setAttribute('data-scale', scale); 1957 ripple.setAttribute('data-x', relativeX); 1958 ripple.setAttribute('data-y', relativeY); 1959 1960 // Set ripple position 1961 var rippleStyle = { 1962 'top': relativeY+'px', 1963 'left': relativeX+'px' 1964 }; 1965 1966 ripple.className = ripple.className + ' waves-notransition'; 1967 ripple.setAttribute('style', convertStyle(rippleStyle)); 1968 ripple.className = ripple.className.replace('waves-notransition', ''); 1969 1970 // Scale the ripple 1971 rippleStyle['-webkit-transform'] = scale; 1972 rippleStyle['-moz-transform'] = scale; 1973 rippleStyle['-ms-transform'] = scale;
vendor: 5,219 bytes, lines 1974-2107
1974 rippleStyle['-o-transform'] = scale; 1975 rippleStyle.transform = scale; 1976 rippleStyle.opacity = '1'; 1977 1978 rippleStyle['-webkit-transition-duration'] = Effect.duration + 'ms'; 1979 rippleStyle['-moz-transition-duration'] = Effect.duration + 'ms'; 1980 rippleStyle['-o-transition-duration'] = Effect.duration + 'ms'; 1981 rippleStyle['transition-duration'] = Effect.duration + 'ms'; 1982 1983 rippleStyle['-webkit-transition-timing-function'] = 'cubic-bezier(0.250, 0.460, 0.450, 0.940)'; 1984 rippleStyle['-moz-transition-timing-function'] = 'cubic-bezier(0.250, 0.460, 0.450, 0.940)'; 1985 rippleStyle['-o-transition-timing-function'] = 'cubic-bezier(0.250, 0.460, 0.450, 0.940)'; 1986 rippleStyle['transition-timing-function'] = 'cubic-bezier(0.250, 0.460, 0.450, 0.940)'; 1987 1988 ripple.setAttribute('style', convertStyle(rippleStyle)); 1989 }, 1990 1991 hide: function(e) { 1992 TouchHandler.touchup(e); 1993 1994 var el = this; 1995 var width = el.clientWidth * 1.4; 1996 1997 // Get first ripple 1998 var ripple = null; 1999 var ripples = el.getElementsByClassName('waves-ripple'); 2000 if (ripples.length > 0) { 2001 ripple = ripples[ripples.length - 1]; 2002 } else { 2003 return false; 2004 } 2005 2006 var relativeX = ripple.getAttribute('data-x'); 2007 var relativeY = ripple.getAttribute('data-y'); 2008 var scale = ripple.getAttribute('data-scale'); 2009 2010 // Get delay beetween mousedown and mouse leave 2011 var diff = Date.now() - Number(ripple.getAttribute('data-hold')); 2012 var delay = 350 - diff; 2013 2014 if (delay < 0) { 2015 delay = 0; 2016 } 2017 2018 // Fade out ripple after delay 2019 setTimeout(function() { 2020 var style = { 2021 'top': relativeY+'px', 2022 'left': relativeX+'px', 2023 'opacity': '0', 2024 2025 // Duration 2026 '-webkit-transition-duration': Effect.duration + 'ms', 2027 '-moz-transition-duration': Effect.duration + 'ms', 2028 '-o-transition-duration': Effect.duration + 'ms', 2029 'transition-duration': Effect.duration + 'ms', 2030 '-webkit-transform': scale, 2031 '-moz-transform': scale, 2032 '-ms-transform': scale, 2033 '-o-transform': scale, 2034 'transform': scale, 2035 }; 2036 2037 ripple.setAttribute('style', convertStyle(style)); 2038 2039 setTimeout(function() { 2040 try { 2041 el.removeChild(ripple); 2042 } catch(e) { 2043 return false; 2044 } 2045 }, Effect.duration); 2046 }, delay); 2047 }, 2048 2049 // Little hack to make <input> can perform waves effect 2050 wrapInput: function(elements) { 2051 for (var a = 0; a < elements.length; a++) { 2052 var el = elements[a]; 2053 2054 if (el.tagName.toLowerCase() === 'input') { 2055 var parent = el.parentNode; 2056 2057 // If input already have parent just pass through 2058 if (parent.tagName.toLowerCase() === 'i' && parent.className.indexOf('waves-effect') !== -1) { 2059 continue; 2060 } 2061 2062 // Put element class and style to the specified parent 2063 var wrapper = document.createElement('i'); 2064 wrapper.className = el.className + ' waves-input-wrapper'; 2065 2066 var elementStyle = el.getAttribute('style'); 2067 2068 if (!elementStyle) { 2069 elementStyle = ''; 2070 } 2071 2072 wrapper.setAttribute('style', elementStyle); 2073 2074 el.className = 'waves-button-input'; 2075 el.removeAttribute('style'); 2076 2077 // Put element as child 2078 parent.replaceChild(wrapper, el); 2079 wrapper.appendChild(el); 2080 } 2081 } 2082 } 2083 }; 2084 2085 2086 /** 2087 * Disable mousedown event for 500ms during and after touch 2088 */ 2089 var TouchHandler = { 2090 /* uses an integer rather than bool so there's no issues with 2091 * needing to clear timeouts if another touch event occurred 2092 * within the 500ms. Cannot mouseup between touchstart and 2093 * touchend, nor in the 500ms after touchend. */ 2094 touches: 0, 2095 allowEvent: function(e) { 2096 var allow = true; 2097 2098 if (e.type === 'touchstart') { 2099 TouchHandler.touches += 1; //push 2100 } else if (e.type === 'touchend' || e.type === 'touchcancel') { 2101 setTimeout(function() { 2102 if (TouchHandler.touches > 0) { 2103 TouchHandler.touches -= 1; //pop after 500ms 2104 } 2105 }, 500); 2106 } else if (e.type === 'mousedown' && TouchHandler.touches > 0) { 2107 allow = false;
2108 } 2109 2110 return allow; 2111 }, 2112 touchup: function(e) { 2113 TouchHandler.allowEvent(e); 2114 } 2115 }; 2116 2117 2118 /** 2119 * Delegated click handler for .waves-effect element. 2120 * returns null when .waves-effect element not in "click tree" 2121 */ 2122 function getWavesEffectElement(e) { 2123 if (TouchHandler.allowEvent(e) === false) { 2124 return null; 2125 } 2126 2127 var element = null; 2128 var target = e.target || e.srcElement; 2129 2130 while (target.parentElement !== null) { 2131 if (!(target instanceof SVGElement) && target.className.indexOf('waves-effect') !== -1) { 2132 element = target; 2133 break; 2134 } else if (target.classList.contains('waves-effect')) { 2135 element = target; 2136 break; 2137 } 2138 target = target.parentElement; 2139 } 2140 2141 return element; 2142 } 2143 2144 /** 2145 * Bubble the click and show effect if .waves-effect elem was found 2146 */ 2147 function showEffect(e) { 2148 var element = getWavesEffectElement(e); 2149 2150 if (element !== null) {
vendor: 1,370 bytes, lines 2151-2189
2151 Effect.show(e, element); 2152 2153 if ('ontouchstart' in window) { 2154 element.addEventListener('touchend', Effect.hide, false); 2155 element.addEventListener('touchcancel', Effect.hide, false); 2156 } 2157 2158 element.addEventListener('mouseup', Effect.hide, false); 2159 element.addEventListener('mouseleave', Effect.hide, false); 2160 } 2161 } 2162 2163 Waves.displayEffect = function(options) { 2164 options = options || {}; 2165 2166 if ('duration' in options) { 2167 Effect.duration = options.duration; 2168 } 2169 2170 //Wrap input inside <i> tag 2171 Effect.wrapInput($$('.waves-effect')); 2172 2173 if ('ontouchstart' in window) { 2174 document.body.addEventListener('touchstart', showEffect, false); 2175 } 2176 2177 document.body.addEventListener('mousedown', showEffect, false); 2178 }; 2179 2180 /** 2181 * Attach Waves to an input element (or any element which doesn't 2182 * bubble mouseup/mousedown events). 2183 * Intended to be used with dynamically loaded forms/inputs, or 2184 * where the user doesn't want a delegated click handler. 2185 */ 2186 Waves.attach = function(element) { 2187 //FUTURE: automatically add waves classes and allow users 2188 // to specify them with an options param? Eg. light/classic/button 2189 if (element.tagName.toLowerCase() === 'input') {
2190 Effect.wrapInput([element]); 2191 element = element.parentElement; 2192 } 2193 2194 if ('ontouchstart' in window) { 2195 element.addEventListener('touchstart', showEffect, false); 2196 } 2197 2198 element.addEventListener('mousedown', showEffect, false); 2199 }; 2200 2201 window.Waves = Waves; 2202 2203 document.addEventListener('DOMContentLoaded', function() { 2204 Waves.displayEffect(); 2205 }, false); 2206 2207})(window); 2208;Materialize.toast = function (message, displayLength, className, completeCallback) { 2209 className = className || ""; 2210 2211 var container = document.getElementById('toast-container'); 2212 2213 // Create toast container if it does not exist 2214 if (container === null) { 2215 // create notification container 2216 container = document.createElement('div'); 2217 container.id = 'toast-container'; 2218 document.body.appendChild(container); 2219 } 2220 2221 // Select and append toast 2222 var newToast = createToast(message); 2223 2224 // only append toast if message is not undefined 2225 if(message){ 2226 container.appendChild(newToast); 2227 } 2228 2229 newToast.style.opacity = 0; 2230 2231 // Animate toast in 2232 Vel(newToast, {translateY: '-35px', opacity: 1 }, {duration: 300, 2233 easing: 'easeOutCubic', 2234 queue: false}); 2235 2236 // Allows timer to be pause while being panned 2237 var timeLeft = displayLength; 2238 var counterInterval; 2239 if (timeLeft != null) { 2240 counterInterval = setInterval (function(){ 2241 if (newToast.parentNode === null) 2242 window.clearInterval(counterInterval); 2243 2244 // If toast is not being dragged, decrease its time remaining 2245 if (!newToast.classList.contains('panning')) { 2246 timeLeft -= 20; 2247 } 2248 2249 if (timeLeft <= 0) { 2250 // Animate toast out 2251 Vel(newToast, {"opacity": 0, marginTop: '-40px'}, { duration: 375, 2252 easing: 'easeOutExpo', 2253 queue: false, 2254 complete: function(){ 2255 // Call the optional callback 2256 if(typeof(completeCallback) === "function") 2257 completeCallback(); 2258 // Remove toast after it times out 2259 this[0].parentNode.removeChild(this[0]); 2260 } 2261 }); 2262 window.clearInterval(counterInterval); 2263 } 2264 }, 20); 2265 } 2266 2267 2268 2269 function createToast(html) { 2270 2271 // Create toast 2272 var toast = document.createElement('div'); 2273 toast.classList.add('toast'); 2274 if (className) { 2275 var classes = className.split(' '); 2276 2277 for (var i = 0, count = classes.length; i < count; i++) { 2278 toast.classList.add(classes[i]); 2279 } 2280 } 2281 // If type of parameter is HTML Element 2282 if ( typeof HTMLElement === "object" ? html instanceof HTMLElement : html && typeof html === "object" && html !== null && html.nodeType === 1 && typeof html.nodeName==="string" 2283) { 2284 toast.appendChild(html); 2285 } 2286 else if (html instanceof jQuery) { 2287 // Check if it is jQuery object 2288 toast.appendChild(html[0]); 2289 } 2290 else { 2291 // Insert as text; 2292 toast.innerHTML = html; 2293 } 2294 // Bind hammer 2295 var hammerHandler = new Hammer(toast, {prevent_default: false}); 2296 hammerHandler.on('pan', function(e) { 2297 var deltaX = e.deltaX; 2298 var activationDistance = 80; 2299 2300 // Change toast state 2301 if (!toast.classList.contains('panning')){ 2302 toast.classList.add('panning'); 2303 } 2304 2305 var opacityPercent = 1-Math.abs(deltaX / activationDistance); 2306 if (opacityPercent < 0) 2307 opacityPercent = 0; 2308 2309 Vel(toast, {left: deltaX, opacity: opacityPercent }, {duration: 50, queue: false, easing: 'easeOutQuad'}); 2310 2311 }); 2312 2313 hammerHandler.on('panend', function(e) { 2314 var deltaX = e.deltaX; 2315 var activationDistance = 80; 2316 2317 // If toast dragged past activation point 2318 if (Math.abs(deltaX) > activationDistance) { 2319 Vel(toast, {marginTop: '-40px'}, { duration: 375, 2320 easing: 'easeOutExpo', 2321 queue: false, 2322 complete: function(){ 2323 if(typeof(completeCallback) === "function") { 2324 completeCallback(); 2325 } 2326 toast.parentNode.removeChild(toast); 2327 } 2328 }); 2329 2330 } else { 2331 toast.classList.remove('panning'); 2332 // Put toast back into original position 2333 Vel(toast, { left: 0, opacity: 1 }, { duration: 300, 2334 easing: 'easeOutExpo', 2335 queue: false 2336 }); 2337 2338 } 2339 }); 2340 2341 return toast; 2342 } 2343}; 2344;(function ($) { 2345 2346 var methods = { 2347 init : function(options) { 2348 var defaults = { 2349 menuWidth: 300, 2350 edge: 'left', 2351 closeOnClick: false, 2352 draggable: true 2353 }; 2354 options = $.extend(defaults, options); 2355 2356 $(this).each(function(){ 2357 var $this = $(this); 2358 var menuId = $this.attr('data-activates'); 2359 var menu = $("#"+ menuId); 2360 2361 // Set to width 2362 if (options.menuWidth != 300) { 2363 menu.css('width', options.menuWidth); 2364 } 2365 2366 // Add Touch Area 2367 var $dragTarget = $('.drag-target[data-sidenav="' + menuId + '"]'); 2368 if (options.draggable) { 2369 // Regenerate dragTarget 2370 if ($dragTarget.length) { 2371 $dragTarget.remove(); 2372 } 2373
2374 $dragTarget = $('<div class="drag-target"></div>').attr('data-sidenav', menuId); 2375 $('body').append($dragTarget); 2376 } else { 2377 $dragTarget = $(); 2378 } 2379 2380 if (options.edge == 'left') { 2381 menu.css('transform', 'translateX(-100%)'); 2382 $dragTarget.css({'left': 0}); // Add Touch Area 2383 } 2384 else { 2385 menu.addClass('right-aligned') // Change text-alignment to right 2386 .css('transform', 'translateX(100%)'); 2387 $dragTarget.css({'right': 0}); // Add Touch Area 2388 } 2389 2390 // If fixed sidenav, bring menu out 2391 if (menu.hasClass('fixed')) { 2392 if (window.innerWidth > 992) { 2393 menu.css('transform', 'translateX(0)'); 2394 } 2395 } 2396 2397 // Window resize to reset on large screens fixed 2398 if (menu.hasClass('fixed')) { 2399 $(window).resize( function() { 2400 if (window.innerWidth > 992) { 2401 // Close menu if window is resized bigger than 992 and user has fixed sidenav 2402 if ($('#sidenav-overlay').length !== 0 && menuOut) { 2403 removeMenu(true); 2404 } 2405 else { 2406 // menu.removeAttr('style'); 2407 menu.css('transform', 'translateX(0%)'); 2408 // menu.css('width', options.menuWidth); 2409 } 2410 } 2411 else if (menuOut === false){ 2412 if (options.edge === 'left') { 2413 menu.css('transform', 'translateX(-100%)'); 2414 } else { 2415 menu.css('transform', 'translateX(100%)'); 2416 } 2417 2418 } 2419 2420 }); 2421 } 2422 2423 // if closeOnClick, then add close event for all a tags in side sideNav 2424 if (options.closeOnClick === true) { 2425 menu.on("click.itemclick", "a:not(.collapsible-header)", function(){ 2426 removeMenu(); 2427 }); 2428 } 2429 2430 var removeMenu = function(restoreNav) { 2431 panning = false; 2432 menuOut = false;
2433 // Reenable scrolling 2434 $('body').css({ 2435 overflow: '', 2436 width: '' 2437 }); 2438 2439 $('#sidenav-overlay').velocity({opacity: 0}, {duration: 200, 2440 queue: false, easing: 'easeOutQuad', 2441 complete: function() { 2442 $(this).remove(); 2443 } }); 2444 if (options.edge === 'left') { 2445 // Reset phantom div 2446 $dragTarget.css({width: '', right: '', left: '0'}); 2447 menu.velocity( 2448 {'translateX': '-100%'}, 2449 { duration: 200, 2450 queue: false, 2451 easing: 'easeOutCubic', 2452 complete: function() { 2453 if (restoreNav === true) { 2454 // Restore Fixed sidenav 2455 menu.removeAttr('style'); 2456 menu.css('width', options.menuWidth); 2457 } 2458 } 2459 2460 }); 2461 } 2462 else { 2463 // Reset phantom div 2464 $dragTarget.css({width: '', right: '0', left: ''}); 2465 menu.velocity( 2466 {'translateX': '100%'}, 2467 { duration: 200, 2468 queue: false, 2469 easing: 'easeOutCubic', 2470 complete: function() { 2471 if (restoreNav === true) { 2472 // Restore Fixed sidenav 2473 menu.removeAttr('style'); 2474 menu.css('width', options.menuWidth); 2475 } 2476 } 2477 }); 2478 } 2479 }; 2480 2481 2482 2483 // Touch Event 2484 var panning = false; 2485 var menuOut = false;
2486 2487 if (options.draggable) { 2488 $dragTarget.on('click', function(){ 2489 if (menuOut) { 2490 removeMenu(); 2491 } 2492 }); 2493 2494 $dragTarget.hammer({ 2495 prevent_default: false 2496 }).bind('pan', function(e) { 2497 2498 if (e.gesture.pointerType == "touch") { 2499 2500 var direction = e.gesture.direction; 2501 var x = e.gesture.center.x; 2502 var y = e.gesture.center.y; 2503 var velocityX = e.gesture.velocityX; 2504 2505 // Disable Scrolling 2506 var $body = $('body'); 2507 var $overlay = $('#sidenav-overlay'); 2508 var oldWidth = $body.innerWidth(); 2509 $body.css('overflow', 'hidden'); 2510 $body.width(oldWidth); 2511 2512 // If overlay does not exist, create one and if it is clicked, close menu 2513 if ($overlay.length === 0) { 2514 $overlay = $('<div id="sidenav-overlay"></div>'); 2515 $overlay.css('opacity', 0).click( function(){ 2516 removeMenu(); 2517 }); 2518 $('body').append($overlay); 2519 } 2520 2521 // Keep within boundaries 2522 if (options.edge === 'left') { 2523 if (x > options.menuWidth) { x = options.menuWidth; } 2524 else if (x < 0) { x = 0; } 2525 } 2526 2527 if (options.edge === 'left') { 2528 // Left Direction 2529 if (x < (options.menuWidth / 2)) { menuOut = false; } 2530 // Right Direction 2531 else if (x >= (options.menuWidth / 2)) { menuOut = true; } 2532 menu.css('transform', 'translateX(' + (x - options.menuWidth) + 'px)'); 2533 } 2534 else { 2535 // Left Direction 2536 if (x < (window.innerWidth - options.menuWidth / 2)) { 2537 menuOut = true; 2538 } 2539 // Right Direction 2540 else if (x >= (window.innerWidth - options.menuWidth / 2)) { 2541 menuOut = false;
2542 } 2543 var rightPos = (x - options.menuWidth / 2); 2544 if (rightPos < 0) { 2545 rightPos = 0; 2546 } 2547 2548 menu.css('transform', 'translateX(' + rightPos + 'px)'); 2549 } 2550 2551 2552 // Percentage overlay 2553 var overlayPerc; 2554 if (options.edge === 'left') { 2555 overlayPerc = x / options.menuWidth; 2556 $overlay.velocity({opacity: overlayPerc }, {duration: 10, queue: false, easing: 'easeOutQuad'}); 2557 } 2558 else { 2559 overlayPerc = Math.abs((x - window.innerWidth) / options.menuWidth); 2560 $overlay.velocity({opacity: overlayPerc }, {duration: 10, queue: false, easing: 'easeOutQuad'}); 2561 } 2562 } 2563 2564 }).bind('panend', function(e) { 2565 2566 if (e.gesture.pointerType == "touch") { 2567 var $overlay = $('<div id="sidenav-overlay"></div>'); 2568 var velocityX = e.gesture.velocityX; 2569 var x = e.gesture.center.x; 2570 var leftPos = x - options.menuWidth; 2571 var rightPos = x - options.menuWidth / 2; 2572 if (leftPos > 0 ) { 2573 leftPos = 0; 2574 } 2575 if (rightPos < 0) { 2576 rightPos = 0; 2577 } 2578 panning = false; 2579 2580 if (options.edge === 'left') { 2581 // If velocityX <= 0.3 then the user is flinging the menu closed so ignore menuOut 2582 if ((menuOut && velocityX <= 0.3) || velocityX < -0.5) { 2583 // Return menu to open 2584 if (leftPos !== 0) { 2585 menu.velocity({'translateX': [0, leftPos]}, {duration: 300, queue: false, easing: 'easeOutQuad'}); 2586 } 2587 2588 $overlay.velocity({opacity: 1 }, {duration: 50, queue: false, easing: 'easeOutQuad'}); 2589 $dragTarget.css({width: 'calc(100% - 300px)', right: 0, left: ''}); 2590 menuOut = true; 2591 } 2592 else if (!menuOut || velocityX > 0.3) { 2593 // Enable Scrolling 2594 $('body').css({ 2595 overflow: '', 2596 width: '' 2597 }); 2598 // Slide menu closed 2599 menu.velocity({'translateX': [-1 * options.menuWidth - 10, leftPos]}, {duration: 200, queue: false, easing: 'easeOutQuad'}); 2600 $overlay.velocity({opacity: 0 }, {duration: 200, queue: false, easing: 'easeOutQuad', 2601 complete: function () { 2602 $(this).remove(); 2603 }}); 2604 $dragTarget.css({width: '10px', right: '', left: 0}); 2605 } 2606 } 2607 else { 2608 if ((menuOut && velocityX >= -0.3) || velocityX > 0.5) { 2609 // Return menu to open 2610 if (rightPos !== 0) { 2611 menu.velocity({'translateX': [0, rightPos]}, {duration: 300, queue: false, easing: 'easeOutQuad'}); 2612 } 2613 2614 $overlay.velocity({opacity: 1 }, {duration: 50, queue: false, easing: 'easeOutQuad'}); 2615 $dragTarget.css({width: 'calc(100% - 300px)', right: '', left: 0}); 2616 menuOut = true; 2617 } 2618 else if (!menuOut || velocityX < -0.3) { 2619 // Enable Scrolling 2620 $('body').css({ 2621 overflow: '', 2622 width: '' 2623 }); 2624 2625 // Slide menu closed 2626 menu.velocity({'translateX': [options.menuWidth + 10, rightPos]}, {duration: 200, queue: false, easing: 'easeOutQuad'}); 2627 $overlay.velocity({opacity: 0 }, {duration: 200, queue: false, easing: 'easeOutQuad', 2628 complete: function () { 2629 $(this).remove(); 2630 }}); 2631 $dragTarget.css({width: '10px', right: 0, left: ''}); 2632 } 2633 } 2634 2635 } 2636 }); 2637 } 2638 2639 $this.off('click.sidenav').on('click.sidenav', function() { 2640 if (menuOut === true) { 2641 menuOut = false;
2642 panning = false; 2643 removeMenu(); 2644 } 2645 else { 2646 2647 // Disable Scrolling 2648 var $body = $('body'); 2649 var $overlay = $('<div id="sidenav-overlay"></div>'); 2650 var oldWidth = $body.innerWidth(); 2651 $body.css('overflow', 'hidden'); 2652 $body.width(oldWidth); 2653 2654 // Push current drag target on top of DOM tree 2655 $('body').append($dragTarget); 2656 2657 if (options.edge === 'left') { 2658 $dragTarget.css({width: 'calc(100% - 300px)', right: 0, left: ''}); 2659 menu.velocity({'translateX': [0, -1 * options.menuWidth]}, {duration: 300, queue: false, easing: 'easeOutQuad'}); 2660 } 2661 else { 2662 $dragTarget.css({width: 'calc(100% - 300px)', right: '', left: 0}); 2663 menu.velocity({'translateX': [0, options.menuWidth]}, {duration: 300, queue: false, easing: 'easeOutQuad'}); 2664 } 2665 2666 $overlay.css('opacity', 0) 2667 .click(function(){ 2668 menuOut = false;
2669 panning = false; 2670 removeMenu(); 2671 $overlay.velocity({opacity: 0}, {duration: 300, queue: false, easing: 'easeOutQuad', 2672 complete: function() { 2673 $(this).remove(); 2674 } }); 2675 2676 }); 2677 $('body').append($overlay); 2678 $overlay.velocity({opacity: 1}, {duration: 300, queue: false, easing: 'easeOutQuad', 2679 complete: function () { 2680 menuOut = true; 2681 panning = false; 2682 } 2683 }); 2684 } 2685 2686 return false; 2687 }); 2688 }); 2689 2690 2691 }, 2692 destroy: function () { 2693 var $overlay = $('#sidenav-overlay'); 2694 var $dragTarget = $('.drag-target[data-sidenav="' + $(this).attr('data-activates') + '"]'); 2695 $overlay.trigger('click'); 2696 $dragTarget.remove(); 2697 $(this).off('click'); 2698 $overlay.remove(); 2699 }, 2700 show : function() { 2701 this.trigger('click'); 2702 }, 2703 hide : function() { 2704 $('#sidenav-overlay').trigger('click'); 2705 } 2706 }; 2707 2708 2709 $.fn.sideNav = function(methodOrOptions) { 2710 if ( methods[methodOrOptions] ) { 2711 return methods[ methodOrOptions ].apply( this, Array.prototype.slice.call( arguments, 1 )); 2712 } else if ( typeof methodOrOptions === 'object' || ! methodOrOptions ) { 2713 // Default to "init" 2714 return methods.init.apply( this, arguments ); 2715 } else { 2716 $.error( 'Method ' + methodOrOptions + ' does not exist on jQuery.sideNav' ); 2717 } 2718 }; // Plugin end 2719}( jQuery )); 2720;/** 2721 * Extend jquery with a scrollspy plugin. 2722 * This watches the window scroll and fires events when elements are scrolled into viewport. 2723 * 2724 * throttle() and getTime() taken from Underscore.js 2725 * https://github.com/jashkenas/underscore 2726 * 2727 * @author Copyright 2013 John Smart 2728 * @license https://raw.github.com/thesmart/jquery-scrollspy/master/LICENSE 2729 * @see https://github.com/thesmart 2730 * @version 0.1.2 2731 */ 2732(function($) { 2733 2734 var jWindow = $(window); 2735 var elements = []; 2736 var elementsInView = []; 2737 var isSpying = false; 2738 var ticks = 0; 2739 var unique_id = 1; 2740 var offset = { 2741 top : 0, 2742 right : 0, 2743 bottom : 0, 2744 left : 0, 2745 } 2746 2747 /** 2748 * Find elements that are within the boundary 2749 * @param {number} top 2750 * @param {number} right 2751 * @param {number} bottom 2752 * @param {number} left 2753 * @return {jQuery} A collection of elements 2754 */ 2755 function findElements(top, right, bottom, left) { 2756 var hits = $(); 2757 $.each(elements, function(i, element) { 2758 if (element.height() > 0) { 2759 var elTop = element.offset().top, 2760 elLeft = element.offset().left, 2761 elRight = elLeft + element.width(), 2762 elBottom = elTop + element.height(); 2763 2764 var isIntersect = !(elLeft > right || 2765 elRight < left || 2766 elTop > bottom || 2767 elBottom < top); 2768 2769 if (isIntersect) { 2770 hits.push(element); 2771 } 2772 } 2773 }); 2774 2775 return hits; 2776 } 2777 2778 2779 /** 2780 * Called when the user scrolls the window 2781 */ 2782 function onScroll(scrollOffset) { 2783 // unique tick id 2784 ++ticks; 2785 2786 // viewport rectangle 2787 var top = jWindow.scrollTop(), 2788 left = jWindow.scrollLeft(), 2789 right = left + jWindow.width(), 2790 bottom = top + jWindow.height(); 2791 2792 // determine which elements are in view 2793 var intersections = findElements(top+offset.top + scrollOffset || 200, right+offset.right, bottom+offset.bottom, left+offset.left); 2794 $.each(intersections, function(i, element) { 2795 2796 var lastTick = element.data('scrollSpy:ticks'); 2797 if (typeof lastTick != 'number') { 2798 // entered into view 2799 element.triggerHandler('scrollSpy:enter'); 2800 } 2801 2802 // update tick id 2803 element.data('scrollSpy:ticks', ticks); 2804 }); 2805 2806 // determine which elements are no longer in view 2807 $.each(elementsInView, function(i, element) { 2808 var lastTick = element.data('scrollSpy:ticks'); 2809 if (typeof lastTick == 'number' && lastTick !== ticks) { 2810 // exited from view 2811 element.triggerHandler('scrollSpy:exit'); 2812 element.data('scrollSpy:ticks', null); 2813 } 2814 }); 2815 2816 // remember elements in view for next tick 2817 elementsInView = intersections; 2818 } 2819 2820 /** 2821 * Called when window is resized 2822 */ 2823 function onWinSize() { 2824 jWindow.trigger('scrollSpy:winSize'); 2825 } 2826 2827 2828 /** 2829 * Enables ScrollSpy using a selector 2830 * @param {jQuery|string} selector The elements collection, or a selector 2831 * @param {Object=} options Optional. 2832 throttle : number -> scrollspy throttling. Default: 100 ms 2833 offsetTop : number -> offset from top. Default: 0 2834 offsetRight : number -> offset from right. Default: 0 2835 offsetBottom : number -> offset from bottom. Default: 0 2836 offsetLeft : number -> offset from left. Default: 0 2837 * @returns {jQuery} 2838 */ 2839 $.scrollSpy = function(selector, options) { 2840 var defaults = { 2841 throttle: 100, 2842 scrollOffset: 200 // offset - 200 allows elements near bottom of page to scroll 2843 }; 2844 options = $.extend(defaults, options); 2845 2846 var visible = []; 2847 selector = $(selector); 2848 selector.each(function(i, element) { 2849 elements.push($(element)); 2850 $(element).data("scrollSpy:id", i); 2851 // Smooth scroll to section 2852 $('a[href="#' + $(element).attr('id') + '"]').click(function(e) { 2853 e.preventDefault(); 2854 var offset = $(Materialize.escapeHash(this.hash)).offset().top + 1; 2855 $('html, body').animate({ scrollTop: offset - options.scrollOffset }, {duration: 400, queue: false, easing: 'easeOutCubic'}); 2856 }); 2857 }); 2858 2859 offset.top = options.offsetTop || 0; 2860 offset.right = options.offsetRight || 0; 2861 offset.bottom = options.offsetBottom || 0; 2862 offset.left = options.offsetLeft || 0; 2863 2864 var throttledScroll = Materialize.throttle(function() { 2865 onScroll(options.scrollOffset); 2866 }, options.throttle || 100); 2867 var readyScroll = function(){ 2868 $(document).ready(throttledScroll); 2869 }; 2870 2871 if (!isSpying) { 2872 jWindow.on('scroll', readyScroll); 2873 jWindow.on('resize', readyScroll); 2874 isSpying = true; 2875 } 2876 2877 // perform a scan once, after current execution context, and after dom is ready 2878 setTimeout(readyScroll, 0); 2879 2880 2881 selector.on('scrollSpy:enter', function() { 2882 visible = $.grep(visible, function(value) { 2883 return value.height() != 0; 2884 }); 2885 2886 var $this = $(this); 2887 2888 if (visible[0]) { 2889 $('a[href="#' + visible[0].attr('id') + '"]').removeClass('active'); 2890 if ($this.data('scrollSpy:id') < visible[0].data('scrollSpy:id')) { 2891 visible.unshift($(this)); 2892 } 2893 else { 2894 visible.push($(this)); 2895 } 2896 } 2897 else { 2898 visible.push($(this)); 2899 } 2900 2901 2902 $('a[href="#' + visible[0].attr('id') + '"]').addClass('active'); 2903 }); 2904 selector.on('scrollSpy:exit', function() { 2905 visible = $.grep(visible, function(value) { 2906 return value.height() != 0; 2907 }); 2908 2909 if (visible[0]) { 2910 $('a[href="#' + visible[0].attr('id') + '"]').removeClass('active'); 2911 var $this = $(this); 2912 visible = $.grep(visible, function(value) { 2913 return value.attr('id') != $this.attr('id'); 2914 }); 2915 if (visible[0]) { // Check if empty 2916 $('a[href="#' + visible[0].attr('id') + '"]').addClass('active'); 2917 } 2918 } 2919 }); 2920 2921 return selector; 2922 }; 2923 2924 /** 2925 * Listen for window resize events 2926 * @param {Object=} options Optional. Set { throttle: number } to change throttling. Default: 100 ms 2927 * @returns {jQuery} $(window) 2928 */ 2929 $.winSizeSpy = function(options) { 2930 $.winSizeSpy = function() { return jWindow; }; // lock from multiple calls 2931 options = options || { 2932 throttle: 100 2933 }; 2934 return jWindow.on('resize', Materialize.throttle(onWinSize, options.throttle || 100)); 2935 }; 2936 2937 /** 2938 * Enables ScrollSpy on a collection of elements 2939 * e.g. $('.scrollSpy').scrollSpy() 2940 * @param {Object=} options Optional. 2941 throttle : number -> scrollspy throttling. Default: 100 ms 2942 offsetTop : number -> offset from top. Default: 0 2943 offsetRight : number -> offset from right. Default: 0 2944 offsetBottom : number -> offset from bottom. Default: 0 2945 offsetLeft : number -> offset from left. Default: 0 2946 * @returns {jQuery} 2947 */ 2948 $.fn.scrollSpy = function(options) { 2949 return $.scrollSpy($(this), options); 2950 }; 2951 2952})(jQuery); 2953;(function ($) { 2954 $(document).ready(function() { 2955 2956 // Function to update labels of text fields 2957 Materialize.updateTextFields = function() { 2958 var input_selector = 'input[type=text], input[type=password], input[type=email], input[type=url], input[type=tel], input[type=number], input[type=search], textarea'; 2959 $(input_selector).each(function(index, element) { 2960 var $this = $(this); 2961 if ($(element).val().length > 0 || element.autofocus || $this.attr('placeholder') !== undefined) { 2962 $this.siblings('label').addClass('active'); 2963 } else if ($(element)[0].validity) { 2964 $this.siblings('label').toggleClass('active', $(element)[0].validity.badInput === true); 2965 } else { 2966 $this.siblings('label').removeClass('active'); 2967 } 2968 }); 2969 }; 2970 2971 // Text based inputs 2972 var input_selector = 'input[type=text], input[type=password], input[type=email], input[type=url], input[type=tel], input[type=number], input[type=search], textarea'; 2973 2974 // Add active if form auto complete 2975 $(document).on('change', input_selector, function () { 2976 if($(this).val().length !== 0 || $(this).attr('placeholder') !== undefined) { 2977 $(this).siblings('label').addClass('active'); 2978 } 2979 validate_field($(this)); 2980 }); 2981 2982 // Add active if input element has been pre-populated on document ready 2983 $(document).ready(function() { 2984 Materialize.updateTextFields(); 2985 }); 2986 2987 // HTML DOM FORM RESET handling 2988 $(document).on('reset', function(e) { 2989 var formReset = $(e.target); 2990 if (formReset.is('form')) { 2991 formReset.find(input_selector).removeClass('valid').removeClass('invalid'); 2992 formReset.find(input_selector).each(function () { 2993 if ($(this).attr('value') === '') { 2994 $(this).siblings('label').removeClass('active'); 2995 } 2996 }); 2997 2998 // Reset select 2999 formReset.find('select.initialized').each(function () { 3000 var reset_text = formReset.find('option[selected]').text(); 3001 formReset.siblings('input.select-dropdown').val(reset_text); 3002 }); 3003 } 3004 }); 3005 3006 // Add active when element has focus 3007 $(document).on('focus', input_selector, function () { 3008 $(this).siblings('label, .prefix').addClass('active'); 3009 }); 3010 3011 $(document).on('blur', input_selector, function () { 3012 var $inputElement = $(this); 3013 var selector = ".prefix"; 3014 3015 if ($inputElement.val().length === 0 && $inputElement[0].validity.badInput !== true && $inputElement.attr('placeholder')
3015=== undefined) { 3016 selector += ", label"; 3017 } 3018 3019 $inputElement.siblings(selector).removeClass('active'); 3020 3021 validate_field($inputElement); 3022 }); 3023 3024 window.validate_field = function(object) { 3025 var hasLength = object.attr('data-length') !== undefined; 3026 var lenAttr = parseInt(object.attr('data-length')); 3027 var len = object.val().length; 3028 3029 if (object.val().length === 0 && object[0].validity.badInput === false) { 3030 if (object.hasClass('validate')) { 3031 object.removeClass('valid'); 3032 object.removeClass('invalid'); 3033 } 3034 } 3035 else { 3036 if (object.hasClass('validate')) { 3037 // Check for character counter attributes 3038 if ((object.is(':valid') && hasLength && (len <= lenAttr)) || (object.is(':valid') && !hasLength)) { 3039 object.removeClass('invalid'); 3040 object.addClass('valid'); 3041 } 3042 else { 3043 object.removeClass('valid'); 3044 object.addClass('invalid'); 3045 } 3046 } 3047 } 3048 }; 3049 3050 // Radio and Checkbox focus class 3051 var radio_checkbox = 'input[type=radio], input[type=checkbox]'; 3052 $(document).on('keyup.radio', radio_checkbox, function(e) { 3053 // TAB, check if tabbing to radio or checkbox. 3054 if (e.which === 9) { 3055 $(this).addClass('tabbed'); 3056 var $this = $(this); 3057 $this.one('blur', function(e) { 3058 3059 $(this).removeClass('tabbed'); 3060 }); 3061 return; 3062 } 3063 }); 3064 3065 // Textarea Auto Resize 3066 var hiddenDiv = $('.hiddendiv').first(); 3067 if (!hiddenDiv.length) { 3068 hiddenDiv = $('<div class="hiddendiv common"></div>'); 3069 $('body').append(hiddenDiv); 3070 } 3071 var text_area_selector = '.materialize-textarea'; 3072 3073 function textareaAutoResize($textarea) { 3074 // Set font properties of hiddenDiv 3075 3076 var fontFamily = $textarea.css('font-family'); 3077 var fontSize = $textarea.css('font-size'); 3078 var lineHeight = $textarea.css('line-height'); 3079 3080 if (fontSize) { hiddenDiv.css('font-size', fontSize); } 3081 if (fontFamily) { hiddenDiv.css('font-family', fontFamily); } 3082 if (lineHeight) { hiddenDiv.css('line-height', lineHeight); } 3083 3084 if ($textarea.attr('wrap') === "off") { 3085 hiddenDiv.css('overflow-wrap', "normal") 3086 .css('white-space', "pre"); 3087 } 3088 3089 hiddenDiv.text($textarea.val() + '\n'); 3090 var content = hiddenDiv.html().replace(/\n/g, '<br>'); 3091 hiddenDiv.html(content); 3092 3093 3094 // When textarea is hidden, width goes crazy. 3095 // Approximate with half of window size 3096 3097 if ($textarea.is(':visible')) { 3098 hiddenDiv.css('width', $textarea.width()); 3099 } 3100 else { 3101 hiddenDiv.css('width', $(window).width()/2); 3102 } 3103 3104 $textarea.css('height', hiddenDiv.height()); 3105 } 3106 3107 $(text_area_selector).each(function () { 3108 var $textarea = $(this); 3109 if ($textarea.val().length) { 3110 textareaAutoResize($textarea); 3111 } 3112 }); 3113 3114 $('body').on('keyup keydown autoresize', text_area_selector, function () { 3115 textareaAutoResize($(this)); 3116 }); 3117 3118 // File Input Path 3119 $(document).on('change', '.file-field input[type="file"]', function () { 3120 var file_field = $(this).closest('.file-field'); 3121 var path_input = file_field.find('input.file-path'); 3122 var files = $(this)[0].files; 3123 var file_names = []; 3124 for (var i = 0; i < files.length; i++) { 3125 file_names.push(files[i].name); 3126 } 3127 path_input.val(file_names.join(", ")); 3128 path_input.trigger('change'); 3129 }); 3130 3131 /**************** 3132 * Range Input * 3133 ****************/ 3134 3135 var range_type = 'input[type=range]'; 3136 var range_mousedown = false; 3137 var left; 3138 3139 $(range_type).each(function () { 3140 var thumb = $('<span class="thumb"><span class="value"></span></span>'); 3141 $(this).after(thumb); 3142 }); 3143 3144 var range_wrapper = '.range-field'; 3145 $(document).on('change', range_type, function(e) { 3146 var thumb = $(this).siblings('.thumb'); 3147 thumb.find('.value').html($(this).val()); 3148 }); 3149 3150 $(document).on('input mousedown touchstart', range_type, function(e) { 3151 var thumb = $(this).siblings('.thumb'); 3152 var width = $(this).outerWidth(); 3153 3154 // If thumb indicator does not exist yet, create it 3155 if (thumb.length <= 0) { 3156 thumb = $('<span class="thumb"><span class="value"></span></span>'); 3157 $(this).after(thumb); 3158 } 3159 3160 // Set indicator value 3161 thumb.find('.value').html($(this).val()); 3162 3163 range_mousedown = true; 3164 $(this).addClass('active'); 3165 3166 if (!thumb.hasClass('active')) { 3167 thumb.velocity({ height: "30px", width: "30px", top: "-20px", marginLeft: "-15px"}, { duration: 300, easing: 'easeOutExpo' }); 3168 } 3169
3170 if (e.type !== 'input') { 3171 if(e.pageX === undefined || e.pageX === null){//mobile 3172 left = e.originalEvent.touches[0].pageX - $(this).offset().left; 3173 } 3174 else{ // desktop 3175 left = e.pageX - $(this).offset().left; 3176 } 3177 if (left < 0) { 3178 left = 0; 3179 } 3180 else if (left > width) { 3181 left = width; 3182 } 3183 thumb.addClass('active').css('left', left); 3184 } 3185 3186 thumb.find('.value').html($(this).val()); 3187 }); 3188 3189 $(document).on('mouseup touchend', range_wrapper, function() { 3190 range_mousedown = false; 3191 $(this).removeClass('active'); 3192 }); 3193 3194 $(document).on('mousemove touchmove', range_wrapper, function(e) { 3195 var thumb = $(this).children('.thumb'); 3196 var left; 3197 if (range_mousedown) { 3198 if (!thumb.hasClass('active')) { 3199 thumb.velocity({ height: '30px', width: '30px', top: '-20px', marginLeft: '-15px'}, { duration: 300, easing: 'easeOutExpo' }); 3200 } 3201 if (e.pageX === undefined || e.pageX === null) { //mobile 3202 left = e.originalEvent.touches[0].pageX - $(this).offset().left; 3203 } 3204 else{ // desktop 3205 left = e.pageX - $(this).offset().left; 3206 } 3207 var width = $(this).outerWidth(); 3208 3209 if (left < 0) { 3210 left = 0; 3211 } 3212 else if (left > width) { 3213 left = width; 3214 } 3215 thumb.addClass('active').css('left', left); 3216 thumb.find('.value').html(thumb.siblings(range_type).val()); 3217 } 3218 }); 3219 3220 $(document).on('mouseout touchleave', range_wrapper, function() { 3221 if (!range_mousedown) { 3222 3223 var thumb = $(this).children('.thumb'); 3224 3225 if (thumb.hasClass('active')) { 3226 thumb.velocity({ height: '0', width: '0', top: '10px', marginLeft: '-6px'}, { duration: 100 }); 3227 } 3228 thumb.removeClass('active'); 3229 } 3230 }); 3231 3232 /************************** 3233 * Auto complete plugin * 3234 *************************/ 3235 $.fn.autocomplete = function (options) { 3236 // Defaults 3237 var defaults = { 3238 data: {}, 3239 limit: Infinity, 3240 onAutocomplete: null 3241 }; 3242 3243 options = $.extend(defaults, options); 3244 3245 return this.each(function() { 3246 var $input = $(this); 3247 var data = options.data, 3248 count = 0, 3249 activeIndex = 0, 3250 oldVal, 3251 $inputDiv = $input.closest('.input-field'); // Div to append on 3252 3253 // Check if data isn't empty 3254 if (!$.isEmptyObject(data)) { 3255 var $autocomplete = $('<ul class="autocomplete-content dropdown-content"></ul>'); 3256 var $oldAutocomplete; 3257 3258 // Append autocomplete element. 3259 // Prevent double structure init. 3260 if ($inputDiv.length) { 3261 $oldAutocomplete = $inputDiv.children('.autocomplete-content.dropdown-content').first(); 3262 if (!$oldAutocomplete.length) { 3263 $inputDiv.append($autocomplete); // Set ul in body 3264 } 3265 } else { 3266 $oldAutocomplete = $input.next('.autocomplete-content.dropdown-content'); 3267 if (!$oldAutocomplete.length) { 3268 $input.after($autocomplete); 3269 } 3270 } 3271 if ($oldAutocomplete.length) { 3272 $autocomplete = $oldAutocomplete; 3273 } 3274 3275 // Highlight partial match. 3276 var highlight = function(string, $el) { 3277 var img = $el.find('img'); 3278 var matchStart = $el.text().toLowerCase().indexOf("" + string.toLowerCase() + ""), 3279 matchEnd = matchStart + string.length - 1, 3280 beforeMatch = $el.text().slice(0, matchStart), 3281 matchText = $el.text().slice(matchStart, matchEnd + 1), 3282 afterMatch = $el.text().slice(matchEnd + 1); 3283 $el.html("<span>" + beforeMatch + "<span class='highlight'>" + matchText + "</span>" + afterMatch + "</span>"); 3284 if (img.length) { 3285 $el.prepend(img); 3286 } 3287 }; 3288 3289 // Reset current element position 3290 var resetCurrentElement = function() { 3291 activeIndex = 0; 3292 $autocomplete.find('.active').removeClass('active'); 3293 } 3294 3295 // Perform search 3296 $input.off('keyup.autocomplete').on('keyup.autocomplete', function (e) { 3297 // Reset count. 3298 count = 0; 3299 3300 // Don't capture enter or arrow key usage. 3301 if (e.which === 13 ||
3302 e.which === 38 || 3303 e.which === 40) { 3304 return; 3305 } 3306 3307 var val = $input.val().toLowerCase(); 3308 3309 // Check if the input isn't empty 3310 if (oldVal !== val) { 3311 $autocomplete.empty(); 3312 resetCurrentElement(); 3313 3314 if (val !== '') { 3315 for(var key in data) { 3316 if (data.hasOwnProperty(key) && 3317 key.toLowerCase().indexOf(val) !== -1 && 3318 key.toLowerCase() !== val) { 3319 // Break if past limit 3320 if (count >= options.limit) { 3321 break; 3322 } 3323 3324 var autocompleteOption = $('<li></li>'); 3325 if (!!data[key]) { 3326 autocompleteOption.append('<img src="'+ data[key] +'" class="right circle"><span>'+ key +'</span>'); 3327 } else { 3328 autocompleteOption.append('<span>'+ key +'</span>'); 3329 } 3330 3331 $autocomplete.append(autocompleteOption); 3332 highlight(val, autocompleteOption); 3333 count++; 3334 } 3335 } 3336 } 3337 } 3338 3339 // Update oldVal 3340 oldVal = val; 3341 }); 3342 3343 $input.off('keydown.autocomplete').on('keydown.autocomplete', function (e) { 3344 // Arrow keys and enter key usage 3345 var keyCode = e.which, 3346 liElement, 3347 numItems = $autocomplete.children('li').length, 3348 $active = $autocomplete.children('.active').first(); 3349 3350 // select element on Enter 3351 if (keyCode === 13) { 3352 liElement = $autocomplete.children('li').eq(activeIndex); 3353 if (liElement.length) { 3354 liElement.click(); 3355 e.preventDefault(); 3356 } 3357 return; 3358 } 3359 3360 // Capture up and down key 3361 if ( keyCode === 38 || keyCode === 40 ) { 3362 e.preventDefault(); 3363 3364 if (keyCode === 38 && 3365 activeIndex > 0) { 3366 activeIndex--; 3367 } 3368 3369 if (keyCode === 40 && 3370 activeIndex < (numItems - 1) && 3371 $active.length) { 3372 activeIndex++; 3373 } 3374 3375 $active.removeClass('active'); 3376 $autocomplete.children('li').eq(activeIndex).addClass('active'); 3377 } 3378 }); 3379 3380 // Set input value 3381 $autocomplete.on('click', 'li', function () { 3382 var text = $(this).text().trim(); 3383 $input.val(text); 3384 $input.trigger('change'); 3385 $autocomplete.empty(); 3386 resetCurrentElement(); 3387 3388 // Handle onAutocomplete callback. 3389 if (typeof(options.onAutocomplete) === "function") { 3390 options.onAutocomplete.call(this, text); 3391 } 3392 }); 3393 } 3394 }); 3395 }; 3396 3397 }); // End of $(document).ready 3398 3399 /******************* 3400 * Select Plugin * 3401 ******************/ 3402 $.fn.material_select = function (callback) { 3403 $(this).each(function(){ 3404 var $select = $(this); 3405 3406 if ($select.hasClass('browser-default')) { 3407 return; // Continue to next (return false breaks out of entire loop) 3408 } 3409 3410 var multiple = $select.attr('multiple') ? true : false, 3411 lastID = $select.data('select-id'); // Tear down structure if Select needs to be rebuilt 3412 3413 if (lastID) { 3414 $select.parent().find('span.caret').remove(); 3415 $select.parent().find('input').remove(); 3416 3417 $select.unwrap(); 3418 $('ul#select-options-'+lastID).remove(); 3419 } 3420 3421 // If destroying the select, remove the selelct-id and reset it to it's uninitialized state. 3422 if(callback === 'destroy') { 3423 $select.data('select-id', null).removeClass('initialized'); 3424 return; 3425 } 3426 3427 var uniqueID = Materialize.guid(); 3428 $select.data('select-id', uniqueID); 3429 var wrapper = $('<div class="select-wrapper"></div>'); 3430 wrapper.addClass($select.attr('class')); 3431 var options = $('<ul id="select-options-' + uniqueID +'" class="dropdown-content select-dropdown ' + (multiple ? 'multiple-select-dropdown' : '') + '"></ul>'), 3432 selectChildren = $select.children('option, optgroup'), 3433 valuesSelected = [], 3434 optionsHover = false;
3435 3436 var label = $select.find('option:selected').html() || $select.find('option:first').html() || ""; 3437 3438 // Function that renders and appends the option taking into 3439 // account type and possible image icon. 3440 var appendOptionWithIcon = function(select, option, type) { 3441 // Add disabled attr if disabled 3442 var disabledClass = (option.is(':disabled')) ? 'disabled ' : ''; 3443 var optgroupClass = (type === 'optgroup-option') ? 'optgroup-option ' : ''; 3444 3445 // add icons 3446 var icon_url = option.data('icon'); 3447 var classes = option.attr('class'); 3448 if (!!icon_url) { 3449 var classString = ''; 3450 if (!!classes) classString = ' class="' + classes + '"'; 3451 3452 // Check for multiple type. 3453 if (type === 'multiple') { 3454 options.append($('<li class="' + disabledClass + '"><img alt="" src="' + icon_url + '"' + classString + '><span><input type="checkbox"' + disabledClass + '/><label></label>' + option.html() + '</span></li>')); 3455 } else { 3456 options.append($('<li class="' + disabledClass + optgroupClass + '"><img alt="" src="' + icon_url + '"' + classString + '><span>' + option.html() + '</span></li>')); 3457 } 3458 return true; 3459 } 3460 3461 // Check for multiple type. 3462 if (type === 'multiple') { 3463 options.append($('<li class="' + disabledClass + '"><span><input type="checkbox"' + disabledClass + '/><label></label>' + option.html() + '</span></li>')); 3464 } else { 3465 options.append($('<li class="' + disabledClass + optgroupClass + '"><span>' + option.html() + '</span></li>')); 3466 } 3467 }; 3468 3469 /* Create dropdown structure. */ 3470 if (selectChildren.length) { 3471 selectChildren.each(function() { 3472 if ($(this).is('option')) { 3473 // Direct descendant option. 3474 if (multiple) { 3475 appendOptionWithIcon($select, $(this), 'multiple'); 3476 3477 } else { 3478 appendOptionWithIcon($select, $(this)); 3479 } 3480 } else if ($(this).is('optgroup')) { 3481 // Optgroup. 3482 var selectOptions = $(this).children('option'); 3483 options.append($('<li class="optgroup"><span>' + $(this).attr('label') + '</span></li>')); 3484 3485 selectOptions.each(function() { 3486 appendOptionWithIcon($select, $(this), 'optgroup-option'); 3487 }); 3488 } 3489 }); 3490 } 3491 3492 options.find('li:not(.optgroup)').each(function (i) { 3493 $(this).click(function (e) { 3494 // Check if option element is disabled 3495 if (!$(this).hasClass('disabled') && !$(this).hasClass('optgroup')) { 3496 var selected = true; 3497 3498 if (multiple) { 3499 $('input[type="checkbox"]', this).prop('checked', function(i, v) { return !v; }); 3500 selected = toggleEntryFromArray(valuesSelected, $(this).index(), $select); 3501 $newSelect.trigger('focus'); 3502 } else { 3503 options.find('li').removeClass('active'); 3504 $(this).toggleClass('active'); 3505 $newSelect.val($(this).text()); 3506 } 3507 3508 activateOption(options, $(this)); 3509 $select.find('option').eq(i).prop('selected', selected); 3510 // Trigger onchange() event 3511 $select.trigger('change'); 3512 if (typeof callback !== 'undefined') callback(); 3513 } 3514 3515 e.stopPropagation(); 3516 }); 3517 }); 3518 3519 // Wrap Elements 3520 $select.wrap(wrapper); 3521 // Add Select Display Element 3522 var dropdownIcon = $('<span class="caret">▼</span>'); 3523 if ($select.is(':disabled')) 3524 dropdownIcon.addClass('disabled'); 3525 3526 // escape double quotes 3527 var sanitizedLabelHtml = label.replace(/"/g, '"'); 3528 3529 var $newSelect = $('<input type="text" class="select-dropdown" readonly="true" ' + (($select.is(':disabled')) ? 'disabled' : '') + ' data-activates="select-options-' + uniqueID +'" value="'+ sanitizedLabelHtml +'"/>'); 3530 $select.before($newSelect); 3531 $newSelect.before(dropdownIcon); 3532 3533 $newSelect.after(options); 3534 // Check if section element is disabled 3535 if (!$select.is(':disabled')) { 3536 $newSelect.dropdown({'hover': false, 'closeOnClick': false}); 3537 } 3538 3539 // Copy tabindex 3540 if ($select.attr('tabindex')) { 3541 $($newSelect[0]).attr('tabindex', $select.attr('tabindex')); 3542 } 3543 3544 $select.addClass('initialized'); 3545 3546 $newSelect.on({
3547 'focus': function (){ 3548 if ($('ul.select-dropdown').not(options[0]).is(':visible')) { 3549 $('input.select-dropdown').trigger('close'); 3550 } 3551 if (!options.is(':visible')) { 3552 $(this).trigger('open', ['focus']); 3553 var label = $(this).val(); 3554 if (multiple && label.indexOf(',') >= 0) { 3555 label = label.split(',')[0]; 3556 } 3557 3558 var selectedOption = options.find('li').filter(function() { 3559 return $(this).text().toLowerCase() === label.toLowerCase(); 3560 })[0]; 3561 activateOption(options, selectedOption, true); 3562 } 3563 }, 3564 'click': function (e){ 3565 e.stopPropagation(); 3566 } 3567 }); 3568 3569 $newSelect.on('blur', function() { 3570 if (!multiple) { 3571 $(this).trigger('close'); 3572 } 3573 options.find('li.selected').removeClass('selected'); 3574 }); 3575 3576 options.hover(function() { 3577 optionsHover = true; 3578 }, function () { 3579 optionsHover = false; 3580 }); 3581 3582 $(window).on({ 3583 'click': function () { 3584 multiple && (optionsHover || $newSelect.trigger('close')); 3585 } 3586 }); 3587 3588 // Add initial multiple selections. 3589 if (multiple) { 3590 $select.find("option:selected:not(:disabled)").each(function () { 3591 var index = $(this).index(); 3592 3593 toggleEntryFromArray(valuesSelected, index, $select); 3594 options.find("li").eq(index).find(":checkbox").prop("checked", true); 3595 }); 3596 } 3597 3598 /** 3599 * Make option as selected and scroll to selected position 3600 * @param {jQuery} collection Select options jQuery element 3601 * @param {Element} newOption element of the new option 3602 * @param {Boolean} firstActivation If on first activation of select 3603 */ 3604 var activateOption = function(collection, newOption, firstActivation) { 3605 if (newOption) { 3606 collection.find('li.selected').removeClass('selected'); 3607 var option = $(newOption); 3608 option.addClass('selected'); 3609 if (!multiple || !!firstActivation) { 3610 options.scrollTo(option); 3611 } 3612 } 3613 }; 3614 3615 // Allow user to search by typing 3616 // this array is cleared after 1 second 3617 var filterQuery = [], 3618 onKeyDown = function(e){ 3619 // TAB - switch to another input 3620 if(e.which == 9){ 3621 $newSelect.trigger('close'); 3622 return; 3623 } 3624 3625 // ARROW DOWN WHEN SELECT IS CLOSED - open select options 3626 if(e.which == 40 && !options.is(':visible')){ 3627 $newSelect.trigger('open'); 3628 return; 3629 } 3630 3631 // ENTER WHEN SELECT IS CLOSED - submit form 3632 if(e.which == 13 && !options.is(':visible')){ 3633 return; 3634 } 3635 3636 e.preventDefault(); 3637 3638 // CASE WHEN USER TYPE LETTERS 3639 var letter = String.fromCharCode(e.which).toLowerCase(), 3640 nonLetters = [9,13,27,38,40]; 3641 if (letter && (nonLetters.indexOf(e.which) === -1)) { 3642 filterQuery.push(letter); 3643 3644 var string = filterQuery.join(''), 3645 newOption = options.find('li').filter(function() { 3646 return $(this).text().toLowerCase().indexOf(string) === 0; 3647 })[0]; 3648 3649 if (newOption) { 3650 activateOption(options, newOption); 3651 } 3652 } 3653 3654 // ENTER - select option and close when select options are opened 3655 if (e.which == 13) { 3656 var activeOption = options.find('li.selected:not(.disabled)')[0]; 3657 if(activeOption){ 3658 $(activeOption).trigger('click'); 3659 if (!multiple) { 3660 $newSelect.trigger('close'); 3661 } 3662 } 3663 } 3664 3665 // ARROW DOWN - move to next not disabled option 3666 if (e.which == 40) { 3667 if (options.find('li.selected').length) { 3668 newOption = options.find('li.selected').next('li:not(.disabled)')[0]; 3669 } else { 3670 newOption = options.find('li:not(.disabled)')[0]; 3671 } 3672 activateOption(options, newOption); 3673 } 3674 3675 // ESC - close options 3676 if (e.which == 27) { 3677 $newSelect.trigger('close'); 3678 } 3679 3680 // ARROW UP - move to previous not disabled option 3681 if (e.which == 38) { 3682 newOption = options.find('li.selected').prev('li:not(.disabled)')[0]; 3683 if(newOption) 3684 activateOption(options, newOption); 3685 } 3686 3687 // Automaticaly clean filter query so user can search again by starting letters 3688 setTimeout(function(){ filterQuery = []; }, 1000); 3689 }; 3690
3691 $newSelect.on('keydown', onKeyDown); 3692 }); 3693 3694 function toggleEntryFromArray(entriesArray, entryIndex, select) { 3695 var index = entriesArray.indexOf(entryIndex), 3696 notAdded = index === -1; 3697 3698 if (notAdded) { 3699 entriesArray.push(entryIndex); 3700 } else { 3701 entriesArray.splice(index, 1); 3702 } 3703 3704 select.siblings('ul.dropdown-content').find('li').eq(entryIndex).toggleClass('active'); 3705 3706 // use notAdded instead of true (to detect if the option is selected or not) 3707 select.find('option').eq(entryIndex).prop('selected', notAdded); 3708 setValueToInput(entriesArray, select); 3709 3710 return notAdded; 3711 } 3712 3713 function setValueToInput(entriesArray, select) { 3714 var value = ''; 3715 3716 for (var i = 0, count = entriesArray.length; i < count; i++) { 3717 var text = select.find('option').eq(entriesArray[i]).text(); 3718 3719 i === 0 ? value += text : value += ', ' + text; 3720 } 3721 3722 if (value === '') { 3723 value = select.find('option:disabled').eq(0).text(); 3724 } 3725 3726 select.siblings('input.select-dropdown').val(value); 3727 } 3728 }; 3729 3730}( jQuery )); 3731;(function ($) { 3732 3733 var methods = { 3734 3735 init : function(options) { 3736 var defaults = { 3737 indicators: true, 3738 height: 400, 3739 transition: 500, 3740 interval: 6000 3741 }; 3742 options = $.extend(defaults, options); 3743 3744 return this.each(function() { 3745 3746 // For each slider, we want to keep track of 3747 // which slide is active and its associated content 3748 var $this = $(this); 3749 var $slider = $this.find('ul.slides').first(); 3750 var $slides = $slider.find('> li'); 3751 var $active_index = $slider.find('.active').index(); 3752 var $active, $indicators, $interval; 3753 if ($active_index != -1) { $active = $slides.eq($active_index); } 3754 3755 // Transitions the caption depending on alignment 3756 function captionTransition(caption, duration) { 3757 if (caption.hasClass("center-align")) { 3758 caption.velocity({opacity: 0, translateY: -100}, {duration: duration, queue: false}); 3759 } 3760 else if (caption.hasClass("right-align")) { 3761 caption.velocity({opacity: 0, translateX: 100}, {duration: duration, queue: false}); 3762 } 3763 else if (caption.hasClass("left-align")) { 3764 caption.velocity({opacity: 0, translateX: -100}, {duration: duration, queue: false}); 3765 } 3766 } 3767 3768 // This function will transition the slide to any index of the next slide 3769 function moveToSlide(index) { 3770 // Wrap around indices. 3771 if (index >= $slides.length) index = 0; 3772 else if (index < 0) index = $slides.length -1; 3773 3774 $active_index = $slider.find('.active').index(); 3775 3776 // Only do if index changes 3777 if ($active_index != index) { 3778 $active = $slides.eq($active_index); 3779 $caption = $active.find('.caption'); 3780 3781 $active.removeClass('active'); 3782 $active.velocity({opacity: 0}, {duration: options.transition, queue: false, easing: 'easeOutQuad', 3783 complete: function() { 3784 $slides.not('.active').velocity({opacity: 0, translateX: 0, translateY: 0}, {duration: 0, queue: false}); 3785 } }); 3786 captionTransition($caption, options.transition); 3787 3788 3789 // Update indicators 3790 if (options.indicators) { 3791 $indicators.eq($active_index).removeClass('active'); 3792 } 3793 3794 $slides.eq(index).velocity({opacity: 1}, {duration: options.transition, queue: false, easing: 'easeOutQuad'}); 3795 $slides.eq(index).find('.caption').velocity({opacity: 1, translateX: 0, translateY: 0}, {duration: options.transition, delay: options.transition, queue: false, easing: 'easeOutQuad'}); 3796 $slides.eq(index).addClass('active'); 3797 3798 3799 // Update indicators 3800 if (options.indicators) { 3801 $indicators.eq(index).addClass('active'); 3802 } 3803 } 3804 } 3805 3806 // Set height of slider 3807 // If fullscreen, do nothing 3808 if (!$this.hasClass('fullscreen')) { 3809 if (options.indicators) { 3810 // Add height if indicators are present 3811 $this.height(options.height + 40); 3812 } 3813 else { 3814 $this.height(options.height); 3815 } 3816 $slider.height(options.height); 3817 } 3818 3819 3820 // Set initial positions of captions 3821 $slides.find('.caption').each(function () { 3822 captionTransition($(this), 0); 3823 }); 3824 3825 // Move img src into background-image 3826 $slides.find('img').each(function () { 3827 var placeholderBase64 = 'data:image/gif;base64,R0lGODlhAQABAIABAP///wAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=='; 3828 if ($(this).attr('src') !== placeholderBase64) { 3829 $(this).css('background-image', 'url(' + $(this).attr('src') + ')' ); 3830 $(this).attr('src', placeholderBase64); 3831 } 3832 }); 3833 3834 // dynamically add indicators 3835 if (options.indicators) { 3836 $indicators = $('<ul class="indicators"></ul>'); 3837 $slides.each(function( index ) { 3838 var $indicator = $('<li class="indicator-item" role="listitem" aria-label="Next Slide" tabindex="0"></li>'); 3839 3840 // Handle clicks on indicators 3841 $indicator.click(function () { 3842 var $parent = $slider.parent(); 3843 var curr_index = $parent.find($(this)).index(); 3844 moveToSlide(curr_index); 3845 3846 // reset interval 3847 clearInterval($interval); 3848 $interval = setInterval( 3849 function(){ 3850 $active_index = $slider.find('.active').index(); 3851 if ($slides.length == $active_index + 1) $active_index = 0; // loop to start 3852 else $active_index += 1; 3853 3854 moveToSlide($active_index); 3855 3856 }, options.transition + options.interval 3857 ); 3858 }); 3859 $indicators.append($indicator); 3860 }); 3861 $this.append($indicators); 3862 $indicators = $this.find('ul.indicators').find('li.indicator-item'); 3863 } 3864 3865 if ($active) { 3866 $active.show(); 3867 } 3868 else { 3869 $slides.first().addClass('active').velocity({opacity: 1}, {duration: options.transition, queue: false, easing: 'easeOutQuad'}); 3870 3871 $active_index = 0; 3872 $active = $slides.eq($active_index); 3873 3874 // Update indicators 3875 if (options.indicators) { 3876 $indicators.eq($active_index).addClass('active'); 3877 } 3878 } 3879 3880 // Adjust height to current slide 3881 $active.find('img').each(function() { 3882 $active.find('.caption').velocity({opacity: 1, translateX: 0, translateY: 0}, {duration: options.transition, queue: false, easing: 'easeOutQuad'}); 3883 }); 3884 3885 // auto scroll 3886 $interval = setInterval( 3887 function(){ 3888 $active_index = $slider.find('.active').index(); 3889 moveToSlide($active_index + 1); 3890 3891 }, options.transition + options.interval 3892 ); 3893 3894 3895 // HammerJS, Swipe navigation 3896 3897 // Touch Event 3898 var panning = false;
3899 var swipeLeft = false; 3900 var swipeRight = false; 3901 3902 $this.hammer({ 3903 prevent_default: false 3904 }).bind('pan', function(e) { 3905 if (e.gesture.pointerType === "touch") { 3906 3907 // reset interval 3908 clearInterval($interval); 3909 3910 var direction = e.gesture.direction; 3911 var x = e.gesture.deltaX; 3912 var velocityX = e.gesture.velocityX; 3913 var velocityY = e.gesture.velocityY; 3914 3915 $curr_slide = $slider.find('.active'); 3916 if (Math.abs(velocityX) > Math.abs(velocityY)) { 3917 $curr_slide.velocity({ translateX: x 3918 }, {duration: 50, queue: false, easing: 'easeOutQuad'}); 3919 } 3920 3921 // Swipe Left 3922 if (direction === 4 && (x > ($this.innerWidth() / 2) || velocityX < -0.65)) { 3923 swipeRight = true; 3924 } 3925 // Swipe Right 3926 else if (direction === 2 && (x < (-1 * $this.innerWidth() / 2) || velocityX > 0.65)) { 3927 swipeLeft = true; 3928 } 3929 3930 // Make Slide Behind active slide visible 3931 var next_slide; 3932 if (swipeLeft) { 3933 next_slide = $curr_slide.next(); 3934 if (next_slide.length === 0) { 3935 next_slide = $slides.first(); 3936 } 3937 next_slide.velocity({ opacity: 1 3938 }, {duration: 300, queue: false, easing: 'easeOutQuad'}); 3939 } 3940 if (swipeRight) { 3941 next_slide = $curr_slide.prev(); 3942 if (next_slide.length === 0) { 3943 next_slide = $slides.last(); 3944 } 3945 next_slide.velocity({ opacity: 1 3946 }, {duration: 300, queue: false, easing: 'easeOutQuad'}); 3947 } 3948 3949 3950 } 3951 3952 }).bind('panend', function(e) { 3953 if (e.gesture.pointerType === "touch") { 3954 3955 $curr_slide = $slider.find('.active'); 3956 panning = false; 3957 curr_index = $slider.find('.active').index(); 3958 3959 if (!swipeRight && !swipeLeft || $slides.length <=1) { 3960 // Return to original spot 3961 $curr_slide.velocity({ translateX: 0 3962 }, {duration: 300, queue: false, easing: 'easeOutQuad'}); 3963 } 3964 else if (swipeLeft) { 3965 moveToSlide(curr_index + 1); 3966 $curr_slide.velocity({translateX: -1 * $this.innerWidth() }, {duration: 300, queue: false, easing: 'easeOutQuad', 3967 complete: function() { 3968 $curr_slide.velocity({opacity: 0, translateX: 0}, {duration: 0, queue: false}); 3969 } }); 3970 } 3971 else if (swipeRight) { 3972 moveToSlide(curr_index - 1); 3973 $curr_slide.velocity({translateX: $this.innerWidth() }, {duration: 300, queue: false, easing: 'easeOutQuad', 3974 complete: function() { 3975 $curr_slide.velocity({opacity: 0, translateX: 0}, {duration: 0, queue: false}); 3976 } }); 3977 } 3978 swipeLeft = false; 3979 swipeRight = false; 3980 3981 // Restart interval 3982 clearInterval($interval); 3983 $interval = setInterval( 3984 function(){ 3985 $active_index = $slider.find('.active').index(); 3986 if ($slides.length == $active_index + 1) $active_index = 0; // loop to start 3987 else $active_index += 1; 3988 3989 moveToSlide($active_index); 3990 3991 }, options.transition + options.interval 3992 ); 3993 } 3994 }); 3995 3996 $this.on('sliderPause', function() { 3997 clearInterval($interval); 3998 }); 3999 4000 $this.on('sliderStart', function() { 4001 clearInterval($interval); 4002 $interval = setInterval( 4003 function(){ 4004 $active_index = $slider.find('.active').index(); 4005 if ($slides.length == $active_index + 1) $active_index = 0; // loop to start 4006 else $active_index += 1; 4007 4008 moveToSlide($active_index); 4009 4010 }, options.transition + options.interval 4011 ); 4012 }); 4013 4014 $this.on('sliderNext', function() { 4015 $active_index = $slider.find('.active').index(); 4016 moveToSlide($active_index + 1); 4017 }); 4018 4019 $this.on('sliderPrev', function() { 4020 $active_index = $slider.find('.active').index(); 4021 moveToSlide($active_index - 1); 4022 }); 4023 4024 }); 4025 4026 4027 4028 }, 4029 pause : function() { 4030 $(this).trigger('sliderPause'); 4031 }, 4032 start : function() { 4033 $(this).trigger('sliderStart'); 4034 }, 4035 next : function() { 4036 $(this).trigger('sliderNext'); 4037 }, 4038 prev : function() { 4039 $(this).trigger('sliderPrev'); 4040 } 4041 }; 4042 4043 4044 $.fn.slider = function(methodOrOptions) { 4045 if ( methods[methodOrOptions] ) { 4046 return methods[ methodOrOptions ].apply( this, Array.prototype.slice.call( arguments, 1 )); 4047 } else if ( typeof methodOrOptions === 'object' || ! methodOrOptions ) { 4048 // Default to "init" 4049 return methods.init.apply( this, arguments ); 4050 } else { 4051 $.error( 'Method ' + methodOrOptions + ' does not exist on jQuery.tooltip' ); 4052 } 4053 }; // Plugin end 4054}( jQuery )); 4055;(function ($) { 4056 $(document).ready(function() { 4057 4058 $(document).on('click.card', '.card', function (e) { 4059 if ($(this).find('> .card-reveal').length) { 4060 if ($(e.target).is($('.card-reveal .card-title')) || $(e.target).is($('.card-reveal .card-title i'))) { 4061 // Make Reveal animate down and display none 4062 $(this).find('.card-reveal').velocity( 4063 {translateY: 0}, { 4064 duration: 225, 4065 queue: false, 4066 easing: 'easeInOutQuad', 4067 complete: function() { $(this).css({ display: 'none'}); } 4068 } 4069 ); 4070 } 4071 else if ($(e.target).is($('.card .activator')) || 4072 $(e.target).is($('.card .activator i')) ) { 4073 $(e.target).closest('.card').css('overflow', 'hidden'); 4074 $(this).find('.card-reveal').css({ display: 'block'}).velocity("stop", false).velocity({translateY: '-100%'}, {duration: 300, queue: false, easing: 'easeInOutQuad'}); 4075 } 4076 } 4077 }); 4078 4079 }); 4080}( jQuery ));;(function ($) { 4081 var materialChipsDefaults = { 4082 data: [], 4083 placeholder: '', 4084 secondaryPlaceholder: '', 4085 autocompleteData: {}, 4086 autocompleteLimit: Infinity, 4087 }; 4088 4089 $(document).ready(function() { 4090 // Handle removal of static chips. 4091 $(document).on('click', '.chip .close', function(e){ 4092 var $chips = $(this).closest('.chips'); 4093 if ($chips.attr('data-initialized')) { 4094 return; 4095 } 4096 $(this).closest('.chip').remove(); 4097 }); 4098 }); 4099 4100 $.fn.material_chip = function (options) { 4101 var self = this; 4102 this.$el = $(this); 4103 this.$document = $(document); 4104 this.SELS = { 4105 CHIPS: '.chips', 4106 CHIP: '.chip', 4107 INPUT: 'input', 4108 DELETE: '.material-icons', 4109 SELECTED_CHIP: '.selected', 4110 }; 4111 4112 if ('data' === options) { 4113 return this.$el.data('chips'); 4114 } 4115 4116 var curr_options = $.extend({}, materialChipsDefaults, options); 4117 self.hasAutocomplete = !$.isEmptyObject(curr_options.autocompleteData); 4118 4119 // Initialize 4120 this.init = function() { 4121 var i = 0; 4122 var chips; 4123 self.$el.each(function(){ 4124 var $chips = $(this); 4125 var chipId = Materialize.guid(); 4126 self.chipId = chipId; 4127 4128 if (!curr_options.data || !(curr_options.data instanceof Array)) { 4129 curr_options.data = []; 4130 } 4131 $chips.data('chips', curr_options.data); 4132 $chips.attr('data-index', i); 4133 $chips.attr('data-initialized', true); 4134 4135 if (!$chips.hasClass(self.SELS.CHIPS)) { 4136 $chips.addClass('chips'); 4137 } 4138 4139 self.chips($chips, chipId); 4140 i++; 4141 }); 4142 }; 4143 4144 this.handleEvents = function() { 4145 var SELS = self.SELS; 4146 4147 self.$document.off('click.chips-focus', SELS.CHIPS).on('click.chips-focus', SELS.CHIPS, function(e){ 4148 $(e.target).find(SELS.INPUT).focus(); 4149 }); 4150 4151 self.$document.off('click.chips-select', SELS.CHIP).on('click.chips-select', SELS.CHIP, function(e){ 4152 var $chip = $(e.target); 4153 if ($chip.length) { 4154 var wasSelected = $chip.hasClass('selected'); 4155 var $chips = $chip.closest(SELS.CHIPS); 4156 $(SELS.CHIP).removeClass('selected'); 4157 4158 if (!wasSelected) { 4159 self.selectChip($chip.index(), $chips); 4160 } 4161 } 4162 }); 4163 4164 self.$document.off('keydown.chips').on('keydown.chips', function(e){ 4165 if ($(e.target).is('input, textarea')) { 4166 return; 4167 } 4168 4169 // delete 4170 var $chip = self.$document.find(SELS.CHIP + SELS.SELECTED_CHIP); 4171 var $chips = $chip.closest(SELS.CHIPS); 4172 var length = $chip.siblings(SELS.CHIP).length; 4173 var index; 4174 4175 if (!$chip.length) { 4176 return; 4177 } 4178 4179 if (e.which === 8 || e.which === 46) { 4180 e.preventDefault(); 4181 4182 index = $chip.index(); 4183 self.deleteChip(index, $chips); 4184 4185 var selectIndex = null; 4186 if ((index + 1) < length) { 4187 selectIndex = index; 4188 } else if (index === length || (index + 1) === length) { 4189 selectIndex = length - 1; 4190 } 4191 4192 if (selectIndex < 0) selectIndex = null; 4193 4194 if (null !== selectIndex) { 4195 self.selectChip(selectIndex, $chips); 4196 } 4197 if (!length) $chips.find('input').focus(); 4198 4199 // left 4200 } else if (e.which === 37) { 4201 index = $chip.index() - 1; 4202 if (index < 0) { 4203 return; 4204 } 4205 $(SELS.CHIP).removeClass('selected'); 4206 self.selectChip(index, $chips); 4207 4208 // right 4209 } else if (e.which === 39) { 4210 index = $chip.index() + 1; 4211 $(SELS.CHIP).removeClass('selected'); 4212 if (index > length) { 4213 $chips.find('input').focus(); 4214 return; 4215 } 4216 self.selectChip(index, $chips); 4217 } 4218 }); 4219 4220 self.$document.off('focusin.chips', SELS.CHIPS + ' ' + SELS.INPUT).on('focusin.chips', SELS.CHIPS + ' ' + SELS.INPUT, function(e){ 4221 var $currChips = $(e.target).closest(SELS.CHIPS); 4222 $currChips.addClass('focus'); 4223 $currChips.siblings('label, .prefix').addClass('active'); 4224 $(SELS.CHIP).removeClass('selected'); 4225 }); 4226 4227 self.$document.off('focusout.chips', SELS.CHIPS + ' ' + SELS.INPUT).on('focusout.chips', SELS.CHIPS + ' ' + SELS.INPUT, function(e){ 4228 var $currChips = $(e.target).closest(SELS.CHIPS); 4229 $currChips.removeClass('focus'); 4230 4231 // Remove active if empty 4232 if (!$currChips.data('chips').length) { 4233 $currChips.siblings('label').removeClass('active'); 4234 } 4235 $currChips.siblings('.prefix').removeClass('active'); 4236 }); 4237 4238 self.$document.off('keydown.chips-add', SELS.CHIPS + ' ' + SELS.INPUT).on('keydown.chips-add', SELS.CHIPS + ' ' + SELS.INPUT, function(e){ 4239 var $target = $(e.target); 4240 var $chips = $target.closest(SELS.CHIPS); 4241 var chipsLength = $chips.children(SELS.CHIP).length; 4242 4243 // enter 4244 if (13 === e.which) { 4245 // Override enter if autocompleting. 4246 if (self.hasAutocomplete && 4247 $chips.find('.autocomplete-content.dropdown-content').length && 4248 $chips.find('.autocomplete-content.dropdown-content').children().length) { 4249 return; 4250 } 4251 4252 e.preventDefault(); 4253 self.addChip({tag: $target.val()}, $chips); 4254 $target.val(''); 4255 return; 4256 } 4257 4258 // delete or left 4259 if ((8 === e.keyCode || 37 === e.keyCode) && '' === $target.val() && chipsLength) { 4260 e.preventDefault(); 4261 self.selectChip(chipsLength - 1, $chips); 4262 $target.blur(); 4263 return; 4264 } 4265 }); 4266 4267 // Click on delete icon in chip. 4268 self.$document.off('click.chips-delete', SELS.CHIPS + ' ' + SELS.DELETE).on('click.chips-delete', SELS.CHIPS + ' ' + SELS.DELETE, function(e) { 4269 var $target = $(e.target); 4270 var $chips = $target.closest(SELS.CHIPS); 4271 var $chip = $target.closest(SELS.CHIP); 4272 e.stopPropagation(); 4273 self.deleteChip($chip.index(), $chips); 4274 $chips.find('input').focus(); 4275 }); 4276 }; 4277 4278 this.chips = function($chips, chipId) { 4279 var html = ''; 4280 $chips.data('chips').forEach(function(elem){ 4281 html += self.renderChip(elem); 4282 }); 4283 html += '<input id="' + chipId +'" class="input" placeholder="">'; 4284 $chips.html(html); 4285 self.setPlaceholder($chips); 4286 4287 // Set for attribute for label 4288 var label = $chips.next('label'); 4289 if (label.length) { 4290 label.attr('for', chipId); 4291 4292 if ($chips.data('chips').length) { 4293 label.addClass('active'); 4294 } 4295 } 4296 4297 // Setup autocomplete if needed. 4298 var input = $('#' + chipId); 4299 if (self.hasAutocomplete) { 4300 input.autocomplete({ 4301 data: curr_options.autocompleteData, 4302 limit: curr_options.autocompleteLimit, 4303 onAutocomplete: function(val) { 4304 self.addChip({tag: val}, $chips); 4305 input.val(''); 4306 input.focus(); 4307 }, 4308 }) 4309 } 4310 }; 4311 4312 this.renderChip = function(elem) { 4313 if (!elem.tag) return; 4314 4315 var html = '<div class="chip">' + elem.tag; 4316 if (elem.image) { 4317 html += ' <img src="' + elem.image + '"> '; 4318 } 4319 html += '<i class="material-icons close">close</i>'; 4320 html += '</div>'; 4321 return html; 4322 }; 4323 4324 this.setPlaceholder = function($chips) { 4325 if ($chips.data('chips').length && curr_options.placeholder) { 4326 $chips.find('input').prop('placeholder', curr_options.placeholder); 4327 4328 } else if (!$chips.data('chips').length && curr_options.secondaryPlaceholder) { 4329 $chips.find('input').prop('placeholder', curr_options.secondaryPlaceholder); 4330 } 4331 }; 4332 4333 this.isValid = function($chips, elem) { 4334 var chips = $chips.data('chips'); 4335 var exists = false;
4336 for (var i=0; i < chips.length; i++) { 4337 if (chips[i].tag === elem.tag) { 4338 exists = true; 4339 return; 4340 } 4341 } 4342 return '' !== elem.tag && !exists; 4343 }; 4344 4345 this.addChip = function(elem, $chips) { 4346 if (!self.isValid($chips, elem)) { 4347 return; 4348 } 4349 var chipHtml = self.renderChip(elem); 4350 var newData = []; 4351 var oldData = $chips.data('chips'); 4352 for (var i = 0; i < oldData.length; i++) { 4353 newData.push(oldData[i]); 4354 } 4355 newData.push(elem); 4356 4357 $chips.data('chips', newData); 4358 $(chipHtml).insertBefore($chips.find('input')); 4359 $chips.trigger('chip.add', elem); 4360 self.setPlaceholder($chips); 4361 }; 4362 4363 this.deleteChip = function(chipIndex, $chips) { 4364 var chip = $chips.data('chips')[chipIndex]; 4365 $chips.find('.chip').eq(chipIndex).remove(); 4366 4367 var newData = []; 4368 var oldData = $chips.data('chips'); 4369 for (var i = 0; i < oldData.length; i++) { 4370 if (i !== chipIndex) { 4371 newData.push(oldData[i]); 4372 } 4373 } 4374 4375 $chips.data('chips', newData); 4376 $chips.trigger('chip.delete', chip); 4377 self.setPlaceholder($chips); 4378 }; 4379 4380 this.selectChip = function(chipIndex, $chips) { 4381 var $chip = $chips.find('.chip').eq(chipIndex); 4382 if ($chip && false === $chip.hasClass('selected')) { 4383 $chip.addClass('selected'); 4384 $chips.trigger('chip.select', $chips.data('chips')[chipIndex]); 4385 } 4386 }; 4387 4388 this.getChipsElement = function(index, $chips) { 4389 return $chips.eq(index); 4390 }; 4391 4392 // init 4393 this.init(); 4394 4395 this.handleEvents(); 4396 }; 4397}( jQuery )); 4398;(function ($) { 4399 $.fn.pushpin = function (options) { 4400 // Defaults 4401 var defaults = { 4402 top: 0, 4403 bottom: Infinity, 4404 offset: 0 4405 }; 4406 4407 // Remove pushpin event and classes 4408 if (options === "remove") { 4409 this.each(function () { 4410 if (id = $(this).data('pushpin-id')) { 4411 $(window).off('scroll.' + id); 4412 $(this).removeData('pushpin-id').removeClass('pin-top pinned pin-bottom').removeAttr('style'); 4413 } 4414 }); 4415 return false; 4416 } 4417 4418 options = $.extend(defaults, options); 4419 4420 4421 $index = 0; 4422 return this.each(function() { 4423 var $uniqueId = Materialize.guid(), 4424 $this = $(this), 4425 $original_offset = $(this).offset().top; 4426 4427 function removePinClasses(object) { 4428 object.removeClass('pin-top'); 4429 object.removeClass('pinned'); 4430 object.removeClass('pin-bottom'); 4431 } 4432 4433 function updateElements(objects, scrolled) { 4434 objects.each(function () { 4435 // Add position fixed (because its between top and bottom) 4436 if (options.top <= scrolled && options.bottom >= scrolled && !$(this).hasClass('pinned')) { 4437 removePinClasses($(this)); 4438 $(this).css('top', options.offset); 4439 $(this).addClass('pinned'); 4440 } 4441 4442 // Add pin-top (when scrolled position is above top) 4443 if (scrolled < options.top && !$(this).hasClass('pin-top')) { 4444 removePinClasses($(this)); 4445 $(this).css('top', 0); 4446 $(this).addClass('pin-top'); 4447 } 4448 4449 // Add pin-bottom (when scrolled position is below bottom) 4450 if (scrolled > options.bottom && !$(this).hasClass('pin-bottom')) { 4451 removePinClasses($(this)); 4452 $(this).addClass('pin-bottom'); 4453 $(this).css('top', options.bottom - $original_offset); 4454 } 4455 }); 4456 } 4457 4458 $(this).data('pushpin-id', $uniqueId); 4459 updateElements($this, $(window).scrollTop()); 4460 $(window).on('scroll.' + $uniqueId, function () { 4461 var $scrolled = $(window).scrollTop() + options.offset; 4462 updateElements($this, $scrolled); 4463 }); 4464 4465 }); 4466 4467 }; 4468}( jQuery ));;(function ($) { 4469 $(document).ready(function() { 4470 4471 // jQuery reverse 4472 $.fn.reverse = [].reverse; 4473 4474 // Hover behaviour: make sure this doesn't work on .click-to-toggle FABs! 4475 $(document).on('mouseenter.fixedActionBtn', '.fixed-action-btn:not(.click-to-toggle):not(.toolbar)', function(e) { 4476 var $this = $(this); 4477 openFABMenu($this); 4478 }); 4479 $(document).on('mouseleave.fixedActionBtn', '.fixed-action-btn:not(.click-to-toggle):not(.toolbar)', function(e) { 4480 var $this = $(this); 4481 closeFABMenu($this); 4482 }); 4483 4484 // Toggle-on-click behaviour. 4485 $(document).on('click.fabClickToggle', '.fixed-action-btn.click-to-toggle > a', function(e) { 4486 var $this = $(this); 4487 var $menu = $this.parent(); 4488 if ($menu.hasClass('active')) { 4489 closeFABMenu($menu); 4490 } else { 4491 openFABMenu($menu); 4492 } 4493 }); 4494 4495 // Toolbar transition behaviour. 4496 $(document).on('click.fabToolbar', '.fixed-action-btn.toolbar > a', function(e) { 4497 var $this = $(this); 4498 var $menu = $this.parent(); 4499 FABtoToolbar($menu); 4500 }); 4501 4502 }); 4503 4504 $.fn.extend({ 4505 openFAB: function() { 4506 openFABMenu($(this)); 4507 }, 4508 closeFAB: function() { 4509 closeFABMenu($(this)); 4510 }, 4511 openToolbar: function() { 4512 FABtoToolbar($(this)); 4513 }, 4514 closeToolbar: function() { 4515 toolbarToFAB($(this)); 4516 } 4517 }); 4518 4519 4520 var openFABMenu = function (btn) { 4521 var $this = btn; 4522 if ($this.hasClass('active') === false) { 4523 4524 // Get direction option 4525 var horizontal = $this.hasClass('horizontal'); 4526 var offsetY, offsetX; 4527 4528 if (horizontal === true) { 4529 offsetX = 40; 4530 } else { 4531 offsetY = 40; 4532 } 4533 4534 $this.addClass('active'); 4535 $this.find('ul .btn-floating').velocity( 4536 { scaleY: ".4", scaleX: ".4", translateY: offsetY + 'px', translateX: offsetX + 'px'}, 4537 { duration: 0 }); 4538 4539 var time = 0; 4540 $this.find('ul .btn-floating').reverse().each( function () { 4541 $(this).velocity( 4542 { opacity: "1", scaleX: "1", scaleY: "1", translateY: "0", translateX: '0'},
4543 { duration: 80, delay: time }); 4544 time += 40; 4545 }); 4546 } 4547 }; 4548 4549 var closeFABMenu = function (btn) { 4550 var $this = btn; 4551 // Get direction option 4552 var horizontal = $this.hasClass('horizontal'); 4553 var offsetY, offsetX; 4554 4555 if (horizontal === true) { 4556 offsetX = 40; 4557 } else { 4558 offsetY = 40; 4559 } 4560 4561 $this.removeClass('active'); 4562 var time = 0; 4563 $this.find('ul .btn-floating').velocity("stop", true); 4564 $this.find('ul .btn-floating').velocity( 4565 { opacity: "0", scaleX: ".4", scaleY: ".4", translateY: offsetY + 'px', translateX: offsetX + 'px'}, 4566 { duration: 80 } 4567 ); 4568 }; 4569 4570 4571 /** 4572 * Transform FAB into toolbar 4573 * @param {Object} object jQuery object 4574 */ 4575 var FABtoToolbar = function(btn) { 4576 if (btn.attr('data-open') === "true") { 4577 return; 4578 } 4579 4580 var offsetX, offsetY, scaleFactor; 4581 var windowWidth = window.innerWidth; 4582 var windowHeight = window.innerHeight; 4583 var btnRect = btn[0].getBoundingClientRect(); 4584 var anchor = btn.find('> a').first(); 4585 var menu = btn.find('> ul').first(); 4586 var backdrop = $('<div class="fab-backdrop"></div>'); 4587 var fabColor = anchor.css('background-color'); 4588 anchor.append(backdrop); 4589 4590 offsetX = btnRect.left - (windowWidth / 2) + (btnRect.width / 2); 4591 offsetY = windowHeight - btnRect.bottom; 4592 scaleFactor = windowWidth / backdrop.width(); 4593 btn.attr('data-origin-bottom', btnRect.bottom); 4594 btn.attr('data-origin-left', btnRect.left); 4595 btn.attr('data-origin-width', btnRect.width); 4596 4597 // Set initial state 4598 btn.addClass('active'); 4599 btn.attr('data-open', true); 4600 btn.css({ 4601 'text-align': 'center', 4602 width: '100%', 4603 bottom: 0, 4604 left: 0, 4605 transform: 'translateX(' + offsetX + 'px)', 4606 transition: 'none' 4607 }); 4608 anchor.css({ 4609 transform: 'translateY(' + -offsetY + 'px)', 4610 transition: 'none' 4611 }); 4612 backdrop.css({ 4613 'background-color': fabColor 4614 }); 4615 4616 4617 setTimeout(function() { 4618 btn.css({ 4619 transform: '', 4620 transition: 'transform .2s cubic-bezier(0.550, 0.085, 0.680, 0.530), background-color 0s linear .2s' 4621 }); 4622 anchor.css({ 4623 overflow: 'visible', 4624 transform: '', 4625 transition: 'transform .2s' 4626 }); 4627 4628 setTimeout(function() { 4629 btn.css({ 4630 overflow: 'hidden', 4631 'background-color': fabColor 4632 }); 4633 backdrop.css({ 4634 transform: 'scale(' + scaleFactor + ')', 4635 transition: 'transform .2s cubic-bezier(0.550, 0.055, 0.675, 0.190)' 4636 }); 4637 menu.find('> li > a').css({ 4638 opacity: 1 4639 }); 4640 4641 // Scroll to close. 4642 $(window).on('scroll.fabToolbarClose', function() { 4643 toolbarToFAB(btn); 4644 $(window).off('scroll.fabToolbarClose'); 4645 $(document).off('click.fabToolbarClose'); 4646 }); 4647 4648 $(document).on('click.fabToolbarClose', function(e) { 4649 if (!$(e.target).closest(menu).length) { 4650 toolbarToFAB(btn); 4651 $(window).off('scroll.fabToolbarClose'); 4652 $(document).off('click.fabToolbarClose'); 4653 } 4654 }); 4655 }, 100); 4656 }, 0); 4657 }; 4658 4659 /** 4660 * Transform toolbar back into FAB 4661 * @param {Object} object jQuery object 4662 */ 4663 var toolbarToFAB = function(btn) { 4664 if (btn.attr('data-open') !== "true") { 4665 return; 4666 } 4667 4668 var offsetX, offsetY, scaleFactor; 4669 var windowWidth = window.innerWidth; 4670 var windowHeight = window.innerHeight; 4671 var btnWidth = btn.attr('data-origin-width'); 4672 var btnBottom = btn.attr('data-origin-bottom'); 4673 var btnLeft = btn.attr('data-origin-left'); 4674 var anchor = btn.find('> .btn-floating').first(); 4675 var menu = btn.find('> ul').first(); 4676 var backdrop = btn.find('.fab-backdrop'); 4677 var fabColor = anchor.css('background-color'); 4678 4679 offsetX = btnLeft - (windowWidth / 2) + (btnWidth / 2); 4680 offsetY = windowHeight - btnBottom; 4681 scaleFactor = windowWidth / backdrop.width(); 4682 4683 4684 // Hide backdrop 4685 btn.removeClass('active'); 4686 btn.attr('data-open', false); 4687 btn.css({ 4688 'background-color': 'transparent', 4689 transition: 'none' 4690 }); 4691 anchor.css({ 4692 transition: 'none' 4693 }); 4694 backdrop.css({ 4695 transform: 'scale(0)', 4696 'background-color': fabColor 4697 }); 4698 menu.find('> li > a').css({ 4699 opacity: '' 4700 }); 4701 4702 setTimeout(function() { 4703 backdrop.remove(); 4704 4705 // Set initial state. 4706 btn.css({ 4707 'text-align': '', 4708 width: '', 4709 bottom: '', 4710 left: '', 4711 overflow: '', 4712 'background-color': '', 4713 transform: 'translate3d(' + -offsetX + 'px,0,0)' 4714 }); 4715 anchor.css({ 4716 overflow: '', 4717 transform: 'translate3d(0,' + offsetY + 'px,0)' 4718 }); 4719 4720 setTimeout(function() { 4721 btn.css({
4722 transform: 'translate3d(0,0,0)', 4723 transition: 'transform .2s' 4724 }); 4725 anchor.css({ 4726 transform: 'translate3d(0,0,0)', 4727 transition: 'transform .2s cubic-bezier(0.550, 0.055, 0.675, 0.190)' 4728 }); 4729 }, 20); 4730 }, 200); 4731 }; 4732 4733 4734}( jQuery )); 4735;(function ($) { 4736 // Image transition function 4737 Materialize.fadeInImage = function(selectorOrEl) { 4738 var element; 4739 if (typeof(selectorOrEl) === 'string') { 4740 element = $(selectorOrEl); 4741 } else if (typeof(selectorOrEl) === 'object') { 4742 element = selectorOrEl; 4743 } else { 4744 return; 4745 } 4746 element.css({opacity: 0}); 4747 $(element).velocity({opacity: 1}, { 4748 duration: 650, 4749 queue: false, 4750 easing: 'easeOutSine' 4751 }); 4752 $(element).velocity({opacity: 1}, { 4753 duration: 1300, 4754 queue: false, 4755 easing: 'swing', 4756 step: function(now, fx) { 4757 fx.start = 100; 4758 var grayscale_setting = now/100; 4759 var brightness_setting = 150 - (100 - now)/1.75; 4760 4761 if (brightness_setting < 100) { 4762 brightness_setting = 100; 4763 } 4764 if (now >= 0) { 4765 $(this).css({ 4766 "-webkit-filter": "grayscale("+grayscale_setting+")" + "brightness("+brightness_setting+"%)", 4767 "filter": "grayscale("+grayscale_setting+")" + "brightness("+brightness_setting+"%)" 4768 }); 4769 } 4770 } 4771 }); 4772 }; 4773 4774 // Horizontal staggered list 4775 Materialize.showStaggeredList = function(selectorOrEl) { 4776 var element; 4777 if (typeof(selectorOrEl) === 'string') { 4778 element = $(selectorOrEl); 4779 } else if (typeof(selectorOrEl) === 'object') { 4780 element = selectorOrEl; 4781 } else { 4782 return; 4783 } 4784 var time = 0; 4785 element.find('li').velocity( 4786 { translateX: "-100px"}, 4787 { duration: 0 }); 4788 4789 element.find('li').each(function() { 4790 $(this).velocity( 4791 { opacity: "1", translateX: "0"}, 4792 { duration: 800, delay: time, easing: [60, 10] }); 4793 time += 120; 4794 }); 4795 }; 4796 4797 4798 $(document).ready(function() { 4799 4800 // Touch Event 4801 var swipeLeft = false; 4802 var swipeRight = false; 4803 4804 4805 // Dismissible Collections 4806 $('.dismissable').each(function() { 4807 $(this).hammer({ 4808 prevent_default: false 4809 }).bind('pan', function(e) { 4810 if (e.gesture.pointerType === "touch") { 4811 var $this = $(this); 4812 var direction = e.gesture.direction; 4813 var x = e.gesture.deltaX; 4814 var velocityX = e.gesture.velocityX; 4815 4816 $this.velocity({ translateX: x 4817 }, {duration: 50, queue: false, easing: 'easeOutQuad'}); 4818 4819 // Swipe Left 4820 if (direction === 4 && (x > ($this.innerWidth() / 2) || velocityX < -0.75)) { 4821 swipeLeft = true; 4822 } 4823 4824 // Swipe Right 4825 if (direction === 2 && (x < (-1 * $this.innerWidth() / 2) || velocityX > 0.75)) { 4826 swipeRight = true; 4827 } 4828 } 4829 }).bind('panend', function(e) { 4830 // Reset if collection is moved back into original position 4831 if (Math.abs(e.gesture.deltaX) < ($(this).innerWidth() / 2)) { 4832 swipeRight = false; 4833 swipeLeft = false; 4834 } 4835 4836 if (e.gesture.pointerType === "touch") { 4837 var $this = $(this); 4838 if (swipeLeft || swipeRight) { 4839 var fullWidth; 4840 if (swipeLeft) { fullWidth = $this.innerWidth(); } 4841 else { fullWidth = -1 * $this.innerWidth(); } 4842 4843 $this.velocity({ translateX: fullWidth, 4844 }, {duration: 100, queue: false, easing: 'easeOutQuad', complete: 4845 function() { 4846 $this.css('border', 'none'); 4847 $this.velocity({ height: 0, padding: 0, 4848 }, {duration: 200, queue: false, easing: 'easeOutQuad', complete: 4849 function() { $this.remove(); } 4850 }); 4851 } 4852 }); 4853 } 4854 else { 4855 $this.velocity({ translateX: 0, 4856 }, {duration: 100, queue: false, easing: 'easeOutQuad'}); 4857 } 4858 swipeLeft = false; 4859 swipeRight = false;
4860 } 4861 }); 4862 4863 }); 4864 }); 4865}( jQuery )); 4866;(function($) { 4867 4868 var scrollFireEventsHandled = false; 4869 4870 // Input: Array of JSON objects {selector, offset, callback} 4871 Materialize.scrollFire = function(options) { 4872 var onScroll = function() { 4873 var windowScroll = window.pageYOffset + window.innerHeight; 4874 4875 for (var i = 0 ; i < options.length; i++) { 4876 // Get options from each line 4877 var value = options[i]; 4878 var selector = value.selector, 4879 offset = value.offset, 4880 callback = value.callback; 4881 4882 var currentElement = document.querySelector(selector); 4883 if ( currentElement !== null) { 4884 var elementOffset = currentElement.getBoundingClientRect().top + window.pageYOffset; 4885 4886 if (windowScroll > (elementOffset + offset)) { 4887 if (value.done !== true) { 4888 if (typeof(callback) === 'function') { 4889 callback.call(this, currentElement); 4890 } else if (typeof(callback) === 'string') { 4891 var callbackFunc = new Function(callback); 4892 callbackFunc(currentElement); 4893 } 4894 value.done = true; 4895 } 4896 } 4897 } 4898 } 4899 }; 4900 4901 4902 var throttledScroll = Materialize.throttle(function() { 4903 onScroll(); 4904 }, options.throttle || 100); 4905 4906 if (!scrollFireEventsHandled) { 4907 window.addEventListener("scroll", throttledScroll); 4908 window.addEventListener("resize", throttledScroll); 4909 scrollFireEventsHandled = true; 4910 } 4911 4912 // perform a scan once, after current execution context, and after dom is ready 4913 setTimeout(throttledScroll, 0); 4914 }; 4915 4916})(jQuery); 4917;/*! 4918 * pickadate.js v3.5.0, 2014/04/13 4919 * By Amsul, http://amsul.ca 4920 * Hosted on http://amsul.github.io/pickadate.js 4921 * Licensed under MIT 4922 */ 4923 4924(function ( factory ) { 4925 4926 // AMD. 4927 if ( typeof define == 'function' && define.amd ) 4928 define( 'picker', ['jquery'], factory ) 4929 4930 // Node.js/browserify. 4931 else if ( typeof exports == 'object' ) 4932 module.exports = factory( require('jquery') ) 4933 4934 // Browser globals. 4935 else this.Picker = factory( jQuery ) 4936 4937}(function( $ ) { 4938 4939var $window = $( window ) 4940var $document = $( document ) 4941var $html = $( document.documentElement ) 4942 4943 4944/** 4945 * The picker constructor that creates a blank picker. 4946 */ 4947function PickerConstructor( ELEMENT, NAME, COMPONENT, OPTIONS ) { 4948 4949 // If thereâs no element, return the picker constructor. 4950 if ( !ELEMENT ) return PickerConstructor 4951 4952 4953 var 4954 IS_DEFAULT_THEME = false, 4955 4956 4957 // The state of the picker. 4958 STATE = { 4959 id: ELEMENT.id || 'P' + Math.abs( ~~(Math.random() * new Date()) ) 4960 }, 4961 4962 4963 // Merge the defaults and options passed. 4964 SETTINGS = COMPONENT ? $.extend( true, {}, COMPONENT.defaults, OPTIONS ) : OPTIONS || {}, 4965 4966 4967 // Merge the default classes with the settings classes. 4968 CLASSES = $.extend( {}, PickerConstructor.klasses(), SETTINGS.klass ), 4969 4970 4971 // The element node wrapper into a jQuery object. 4972 $ELEMENT = $( ELEMENT ), 4973 4974 4975 // Pseudo picker constructor. 4976 PickerInstance = function() { 4977 return this.start() 4978 }, 4979 4980 4981 // The picker prototype. 4982 P = PickerInstance.prototype = { 4983 4984 constructor: PickerInstance, 4985 4986 $node: $ELEMENT, 4987 4988 4989 /** 4990 * Initialize everything 4991 */ 4992 start: function() { 4993 4994 // If itâs already started, do nothing. 4995 if ( STATE && STATE.start ) return P 4996 4997 4998 // Update the picker states. 4999 STATE.methods = {} 5000 STATE.start = true 5001 STATE.open = false 5002 STATE.type = ELEMENT.type 5003 5004 5005 // Confirm focus state, convert into text input to remove UA stylings, 5006 // and set as readonly to prevent keyboard popup. 5007 ELEMENT.autofocus = ELEMENT == getActiveElement() 5008 ELEMENT.readOnly = !SETTINGS.editable 5009 ELEMENT.id = ELEMENT.id || STATE.id 5010 if ( ELEMENT.type != 'text' ) { 5011 ELEMENT.type = 'text' 5012 } 5013 5014 5015 // Create a new picker component with the settings. 5016 P.component = new COMPONENT(P, SETTINGS) 5017 5018 5019 // Create the picker root with a holder and then prepare it. 5020 P.$root = $( PickerConstructor._.node('div', createWrappedComponent(), CLASSES.picker, 'id="' + ELEMENT.id + '_root" tabindex="0"') ) 5021 prepareElementRoot() 5022 5023 5024 // If thereâs a format for the hidden input element, create the element. 5025 if ( SETTINGS.formatSubmit ) { 5026 prepareElementHidden() 5027 } 5028 5029 5030 // Prepare the input element. 5031 prepareElement() 5032 5033 5034 // Insert the root as specified in the settings. 5035 if ( SETTINGS.container ) $( SETTINGS.container ).append( P.$root ) 5036 else $ELEMENT.after( P.$root ) 5037 5038 5039 // Bind the default component and settings events. 5040 P.on({ 5041 start: P.component.onStart, 5042 render: P.component.onRender, 5043 stop: P.component.onStop, 5044 open: P.component.onOpen, 5045 close: P.component.onClose, 5046 set: P.component.onSet 5047 }).on({ 5048 start: SETTINGS.onStart, 5049 render: SETTINGS.onRender, 5050 stop: SETTINGS.onStop, 5051 open: SETTINGS.onOpen, 5052 close: SETTINGS.onClose, 5053 set: SETTINGS.onSet 5054 }) 5055 5056 5057 // Once weâre all set, check the theme in use. 5058 IS_DEFAULT_THEME = isUsingDefaultTheme( P.$root.children()[ 0 ] ) 5059 5060 5061 // If the element has autofocus, open the picker. 5062 if ( ELEMENT.autofocus ) { 5063 P.open() 5064 } 5065 5066 5067 // Trigger queued the âstartâ and ârenderâ events. 5068 return P.trigger( 'start' ).trigger( 'render' ) 5069 }, //start 5070 5071 5072 /**
5073 * Render a new picker 5074 */ 5075 render: function( entireComponent ) { 5076 5077 // Insert a new component holder in the root or box. 5078 if ( entireComponent ) P.$root.html( createWrappedComponent() ) 5079 else P.$root.find( '.' + CLASSES.box ).html( P.component.nodes( STATE.open ) ) 5080 5081 // Trigger the queued ârenderâ events. 5082 return P.trigger( 'render' ) 5083 }, //render 5084 5085 5086 /** 5087 * Destroy everything 5088 */ 5089 stop: function() { 5090 5091 // If itâs already stopped, do nothing. 5092 if ( !STATE.start ) return P 5093 5094 // Then close the picker. 5095 P.close() 5096 5097 // Remove the hidden field. 5098 if ( P._hidden ) { 5099 P._hidden.parentNode.removeChild( P._hidden ) 5100 } 5101 5102 // Remove the root. 5103 P.$root.remove() 5104 5105 // Remove the input class, remove the stored data, and unbind 5106 // the events (after a tick for IE - see `P.close`). 5107 $ELEMENT.removeClass( CLASSES.input ).removeData( NAME ) 5108 setTimeout( function() { 5109 $ELEMENT.off( '.' + STATE.id ) 5110 }, 0) 5111 5112 // Restore the element state 5113 ELEMENT.type = STATE.type 5114 ELEMENT.readOnly = false 5115 5116 // Trigger the queued âstopâ events. 5117 P.trigger( 'stop' ) 5118 5119 // Reset the picker states. 5120 STATE.methods = {} 5121 STATE.start = false 5122 5123 return P 5124 }, //stop 5125 5126 5127 /** 5128 * Open up the picker 5129 */ 5130 open: function( dontGiveFocus ) { 5131 5132 // If itâs already open, do nothing. 5133 if ( STATE.open ) return P 5134 5135 // Add the âactiveâ class. 5136 $ELEMENT.addClass( CLASSES.active ) 5137 aria( ELEMENT, 'expanded', true ) 5138 5139 // * A Firefox bug, when `html` has `overflow:hidden`, results in 5140 // killing transitions :(. So add the âopenedâ state on the next tick. 5141 // Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=625289 5142 setTimeout( function() { 5143 5144 // Add the âopenedâ class to the picker root. 5145 P.$root.addClass( CLASSES.opened ) 5146 aria( P.$root[0], 'hidden', false ) 5147 5148 }, 0 ) 5149 5150 // If we have to give focus, bind the element and doc events. 5151 if ( dontGiveFocus !== false ) { 5152 5153 // Set it as open. 5154 STATE.open = true 5155 5156 // Prevent the page from scrolling. 5157 if ( IS_DEFAULT_THEME ) { 5158 $html. 5159 css( 'overflow', 'hidden' ). 5160 css( 'padding-right', '+=' + getScrollbarWidth() ) 5161 } 5162 5163 // Pass focus to the root elementâs jQuery object. 5164 // * Workaround for iOS8 to bring the pickerâs root into view. 5165 P.$root.eq(0).focus() 5166 5167 // Bind the document events. 5168 $document.on( 'click.' + STATE.id + ' focusin.' + STATE.id, function( event ) { 5169 5170 var target = event.target 5171 5172 // If the target of the event is not the element, close the picker picker. 5173 // * Donât worry about clicks or focusins on the root because those donât bubble up. 5174 // Also, for Firefox, a click on an `option` element bubbles up directly 5175 // to the doc. So make sure the target wasn't the doc. 5176 // * In Firefox stopPropagation() doesnât prevent right-click events from bubbling, 5177 // which causes the picker to unexpectedly close when right-clicking it. So make 5178 // sure the event wasnât a right-click. 5179 if ( target != ELEMENT && target != document && event.which != 3 ) { 5180 5181 // If the target was the holder that c
5181overs the screen, 5182 // keep the element focused to maintain tabindex. 5183 P.close( target === P.$root.children()[0] ) 5184 } 5185 5186 }).on( 'keydown.' + STATE.id, function( event ) { 5187 5188 var 5189 // Get the keycode. 5190 keycode = event.keyCode, 5191 5192 // Translate that to a selection change. 5193 keycodeToMove = P.component.key[ keycode ], 5194 5195 // Grab the target. 5196 target = event.target 5197 5198 5199 // On escape, close the picker and give focus. 5200 if ( keycode == 27 ) { 5201 P.close( true ) 5202 } 5203 5204 5205 // Check if there is a key movement or âenterâ keypress on the element. 5206 else if ( target == P.$root[0] && ( keycodeToMove || keycode == 13 ) ) { 5207 5208 // Prevent the default action to stop page movement. 5209 event.preventDefault() 5210 5211 // Trigger the key movement action. 5212 if ( keycodeToMove ) { 5213 PickerConstructor._.trigger( P.component.key.go, P, [ PickerConstructor._.trigger( keycodeToMove ) ] ) 5214 } 5215 5216 // On âenterâ, if the highlighted item isnât disabled, set the value and close. 5217 else if ( !P.$root.find( '.' + CLASSES.highlighted ).hasClass( CLASSES.disabled ) ) { 5218 P.set( 'select', P.component.item.highlight ).close() 5219 } 5220 } 5221 5222 5223 // If the target is within the root and âenterâ is pressed, 5224 // prevent the default action and trigger a click on the target instead. 5225 else if ( $.contains( P.$root[0], target ) && keycode == 13 ) { 5226 event.preventDefault() 5227 target.click() 5228 } 5229 }) 5230 } 5231 5232 // Trigger the queued âopenâ events. 5233 return P.trigger( 'open' ) 5234 }, //open 5235 5236 5237 /** 5238 * Close the picker 5239 */ 5240 close: function( giveFocus ) { 5241 5242 // If we need to give focus, do it before changing states. 5243 if ( giveFocus ) { 5244 // ....ah yes! It wouldâve been incomplete without a crazy workaround for IE :| 5245 // The focus is triggered *after* the close has completed - causing it 5246 // to open again. So unbind and rebind the event at the next tick. 5247 P.$root.off( 'focus.toOpen' ).eq(0).focus() 5248 setTimeout( function() { 5249 P.$root.on( 'focus.toOpen', handleFocusToOpenEvent ) 5250 }, 0 ) 5251 } 5252 5253 // Remove the âactiveâ class. 5254 $ELEMENT.removeClass( CLASSES.active ) 5255 aria( ELEMENT, 'expanded', false ) 5256 5257 // * A Firefox bug, when `html` has `overflow:hidden`, results in 5258 // killing transitions :(. So remove the âopenedâ state on the next tick. 5259 // Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=625289 5260 setTimeout( function() { 5261 5262 // Remove the âopenedâ and âfocusedâ class from the picker root. 5263 P.$root.removeClass( CLASSES.opened + ' ' + CLASSES.focused ) 5264 aria( P.$root[0], 'hidden', true ) 5265 5266 }, 0 ) 5267 5268 // If itâs already closed, do nothing more. 5269 if ( !STATE.open ) return P 5270 5271 // Set it as closed. 5272 STATE.open = false 5273 5274 // Allow the page to scroll. 5275 if ( IS_DEFAULT_THEME ) { 5276 $html. 5277 css( 'overflow', '' ). 5278 css( 'padding-right', '-=' + getScrollbarWidth() ) 5279 } 5280 5281 // Unbind the document events. 5282 $document.off( '.' + STATE.id ) 5283 5284 // Trigger the queued âcloseâ events. 5285 return P.trigger( 'close' ) 5286 }, //close 5287 5288 5289 /** 5290 * Clear the values 5291 */ 5292 clear: function( options ) { 5293 return P.set( 'clear', null, options ) 5294 }, //clear 5295 5296 5297 /** 5298 * Set something 5299 */ 5300 set: function( thing, value, options ) { 5301 5302 var thingItem, thingValue, 5303 thingIsObject = $.isPlainObject( thing ), 5304 thingObject = thingIsObject ? thing : {} 5305 5306 // Make sure we have usable options. 5307 options = thingIsObject && $.isPlainObject( value ) ? value : options || {} 5308 5309 if ( thing ) { 5310 5311 // If the thing isnât an object, make it one. 5312 if ( !thingIsObject ) { 5313 thingObject[ thing ] = value 5314 } 5315 5316 // Go through the things of items to set. 5317 for ( thingItem in thingObject ) { 5318 5319 // Grab the value of the thing. 5320 thingValue = thingObject[ thingItem ] 5321 5322 // First, if the item exists and thereâs a value, set it. 5323 if ( thingItem in P.component.item ) { 5324 if ( thingValue === undefined ) thingValue = null 5325 P.component.set( thingItem, thingValue, options ) 5326 } 5327 5328 // Then, check to update the element value and broadcast a change. 5329 if ( thingItem == 'select' || thingItem == 'clear' ) { 5330 $ELEMENT. 5331 val( thingItem == 'clear' ? '' : P.get( thingItem, SETTINGS.format ) ). 5332 trigger( 'change' ) 5333 } 5334 } 5335 5336 // Render a new picker. 5337 P.render() 5338 } 5339 5340 // When the method isnât muted, trigger queued âsetâ events and pass the `thingObject`. 5341 return options.muted ? P : P.trigger( 'set', thingObject ) 5342 }, //set 5343 5344 5345 /** 5346 * Get something 5347 */ 5348 get: function( thing, format ) { 5349 5350 // Make sure thereâs something to get. 5351 thing = thing || 'value' 5352 5353 // If a picker state exists, return that. 5354 if ( STATE[ thing ] != null ) { 5355 return STATE[ thing ] 5356 } 5357 5358 // Return the submission value, if that. 5359 if ( thing == 'valueSubmit' ) { 5360 if ( P._hidden ) { 5361 return P._hidden.value 5362 } 5363 thing = 'value' 5364 } 5365 5366 // Return the value, if that. 5367 if ( thing == 'value' ) { 5368 return ELEMENT.value 5369 } 5370 5371 // Check if a component item exists, return that. 5372 if ( thing in P.component.item ) { 5373 if ( typeof format == 'string' ) { 5374 var thingValue = P.component.get( thing ) 5375 return thingValue ? 5376 PickerConstructor._.trigger( 5377 P.component.formats.toString, 5378 P.component, 5379 [ format, thingValue ] 5380 ) : '' 5381 } 5382 return P.component.get( thing ) 5383 } 5384 }, //get 5385 5386 5387 5388 /** 5389 * Bind events on the things. 5390 */ 5391 on: function( thing, method, internal ) { 5392 5393 var thingName, thingMethod, 5394 thingIsObject = $.isPlainObject( thing ), 5395 thingObject = thingIsObject ? thing : {} 5396 5397 if ( thing ) { 5398 5399 // If the thing isnât an object, make it one. 5400 if ( !thingIsObject ) { 5401 thingObject[ thing ] = method 5402 } 5403 5404 // Go through the things to bind to. 5405 for ( thingName in thingObject ) { 5406 5407 // Grab the method of the thing. 5408 thingMethod = thingObject[ thingName ] 5409 5410 // If it was an internal binding, prefix it. 5411 if ( internal ) { 5412 thingName = '_' + thingName 5413 } 5414 5415 // Make sure the thing methods collection exists. 5416 STATE.methods[ thingName ] = STATE.methods[ thingName ] || [] 5417 5418 // Add the method to the relative method collection. 5419 STATE.methods[ thingName ].push( thingMethod ) 5420 } 5421 } 5422 5423 return P 5424 }, //on 5425 5426 5427 5428 /** 5429 * Unbind events on the things. 5430 */ 5431 off: function() { 5432 var i, thingName, 5433 names = arguments; 5434 for ( i = 0, namesCount = names.length; i < namesCount; i += 1 ) { 5435 thingName = names[i] 5436 if ( thingName in STATE.methods ) { 5437 delete STATE.methods[thingName] 5438 } 5439 } 5440 return P 5441 }, 5442 5443 5444 /** 5445 * Fire off method events. 5446 */ 5447 trigger: function( name, data ) { 5448 var _trigger = function( name ) { 5449 var methodList = STATE.methods[ name ] 5450 if ( methodList ) { 5451 methodList.map( function( method ) { 5452 PickerConstructor._.trigger( method, P, [ data ] ) 5453 }) 5454 } 5455 } 5456 _trigger( '_' + name ) 5457 _trigger( name ) 5458 return P 5459 }
5459 //trigger 5460 } //PickerInstance.prototype 5461 5462 5463 /** 5464 * Wrap the picker holder components together. 5465 */ 5466 function createWrappedComponent() { 5467 5468 // Create a picker wrapper holder 5469 return PickerConstructor._.node( 'div', 5470 5471 // Create a picker wrapper node 5472 PickerConstructor._.node( 'div', 5473 5474 // Create a picker frame 5475 PickerConstructor._.node( 'div', 5476 5477 // Create a picker box node 5478 PickerConstructor._.node( 'div', 5479 5480 // Create the components nodes. 5481 P.component.nodes( STATE.open ), 5482 5483 // The picker box class 5484 CLASSES.box 5485 ), 5486 5487 // Picker wrap class 5488 CLASSES.wrap 5489 ), 5490 5491 // Picker frame class 5492 CLASSES.frame 5493 ), 5494 5495 // Picker holder class 5496 CLASSES.holder 5497 ) //endreturn 5498 } //createWrappedComponent 5499 5500 5501 5502 /** 5503 * Prepare the input element with all bindings. 5504 */ 5505 function prepareElement() { 5506 5507 $ELEMENT. 5508 5509 // Store the picker data by component name. 5510 data(NAME, P). 5511 5512 // Add the âinputâ class name. 5513 addClass(CLASSES.input). 5514 5515 // Remove the tabindex. 5516 attr('tabindex', -1). 5517 5518 // If thereâs a `data-value`, update the value of the element. 5519 val( $ELEMENT.data('value') ? 5520 P.get('select', SETTINGS.format) : 5521 ELEMENT.value 5522 ) 5523 5524 5525 // Only bind keydown events if the element isnât editable. 5526 if ( !SETTINGS.editable ) { 5527 5528 $ELEMENT. 5529 5530 // On focus/click, focus onto the root to open it up. 5531 on( 'focus.' + STATE.id + ' click.' + STATE.id, function( event ) { 5532 event.preventDefault() 5533 P.$root.eq(0).focus() 5534 }). 5535 5536 // Handle keyboard event based on the picker being opened or not. 5537 on( 'keydown.' + STATE.id, handleKeydownEvent ) 5538 } 5539 5540 5541 // Update the aria attributes. 5542 aria(ELEMENT, { 5543 haspopup: true, 5544 expanded: false, 5545 readonly: false, 5546 owns: ELEMENT.id + '_root' 5547 }) 5548 } 5549 5550 5551 /** 5552 * Prepare the root picker element with all bindings. 5553 */ 5554 function prepareElementRoot() { 5555 5556 P.$root. 5557 5558 on({ 5559 5560 // For iOS8. 5561 keydown: handleKeydownEvent, 5562 5563 // When something within the root is focused, stop from bubbling 5564 // to the doc and remove the âfocusedâ state from the root. 5565 focusin: function( event ) { 5566 P.$root.removeClass( CLASSES.focused ) 5567 event.stopPropagation() 5568 }, 5569 5570 // When something within the root holder is clicked, stop it 5571 // from bubbling to the doc. 5572 'mousedown click': function( event ) { 5573 5574 var target = event.target 5575 5576 // Make sure the target isnât the root holder so it can bubble up. 5577 if ( target != P.$root.children()[ 0 ] ) { 5578 5579 event.stopPropagation() 5580 5581 // * For mousedown events, cancel the default action in order to 5582 // prevent cases where focus is shifted onto external elements 5583 // when using things like jQuery mobile or MagnificPopup (ref: #249 & #120). 5584 // Also, for Firefox, donât prevent action on the `option` element. 5585 if ( event.type == 'mousedown' && !$( target ).is( 'input, select, textarea, button, option' )) { 5586 5587 event.preventDefault() 5588 5589 // Re-focus onto the root so that users can click away 5590 // from elements focused within the picker. 5591 P.$root.eq(0).focus() 5592 } 5593 } 5594 } 5595 }). 5596 5597 // Add/remove the âtargetâ class on focus and blur. 5598 on({ 5599 focus: function() { 5600 $ELEMENT.addClass( CLASSES.target ) 5601 }, 5602 blur: function() { 5603 $ELEMENT.removeClass( CLASSES.target ) 5604 } 5605 }). 5606 5607 // Open the picker and adjust the root âfocusedâ state 5608 on( 'focus.toOpen', handleFocusToOpenEvent ). 5609 5610 // If thereâs a click on an actionable element, carry out the actions.
5611 on( 'click', '[data-pick], [data-nav], [data-clear], [data-close]', function() { 5612 5613 var $target = $( this ), 5614 targetData = $target.data(), 5615 targetDisabled = $target.hasClass( CLASSES.navDisabled ) || $target.hasClass( CLASSES.disabled ), 5616 5617 // * For IE, non-focusable elements can be active elements as well 5618 // (http://stackoverflow.com/a/2684561). 5619 activeElement = getActiveElement() 5620 activeElement = activeElement && ( activeElement.type || activeElement.href ) 5621 5622 // If itâs disabled or nothing inside is actively focused, re-focus the element. 5623 if ( targetDisabled || activeElement && !$.contains( P.$root[0], activeElement ) ) { 5624 P.$root.eq(0).focus() 5625 } 5626 5627 // If something is superficially changed, update the `highlight` based on the `nav`. 5628 if ( !targetDisabled && targetData.nav ) { 5629 P.set( 'highlight', P.component.item.highlight, { nav: targetData.nav } ) 5630 } 5631 5632 // If something is picked, set `select` then close with focus. 5633 else if ( !targetDisabled && 'pick' in targetData ) { 5634 P.set( 'select', targetData.pick ) 5635 } 5636 5637 // If a âclearâ button is pressed, empty the values and close with focus. 5638 else if ( targetData.clear ) { 5639 P.clear().close( true ) 5640 } 5641 5642 else if ( targetData.close ) { 5643 P.close( true ) 5644 } 5645 5646 }) //P.$root 5647 5648 aria( P.$root[0], 'hidden', true ) 5649 } 5650 5651 5652 /** 5653 * Prepare the hidden input element along with all bindings. 5654 */ 5655 function prepareElementHidden() { 5656 5657 var name 5658 5659 if ( SETTINGS.hiddenName === true ) { 5660 name = ELEMENT.name 5661 ELEMENT.name = '' 5662 } 5663 else { 5664 name = [ 5665 typeof SETTINGS.hiddenPrefix == 'string' ? SETTINGS.hiddenPrefix : '', 5666 typeof SETTINGS.hiddenSuffix == 'string' ? SETTINGS.hiddenSuffix : '_submit' 5667 ] 5668 name = name[0] + ELEMENT.name + name[1] 5669 } 5670 5671 P._hidden = $( 5672 '<input ' + 5673 'type=hidden ' + 5674 5675 // Create the name using the original inputâs with a prefix and suffix. 5676 'name="' + name + '"' + 5677 5678 // If the element has a value, set the hidden value as well. 5679 ( 5680 $ELEMENT.data('value') || ELEMENT.value ? 5681 ' value="' + P.get('select', SETTINGS.formatSubmit) + '"' : 5682 '' 5683 ) + 5684 '>' 5685 )[0] 5686 5687 $ELEMENT. 5688 5689 // If the value changes, update the hidden input with the correct format. 5690 on('change.' + STATE.id, function() { 5691 P._hidden.value = ELEMENT.value ? 5692 P.get('select', SETTINGS.formatSubmit) : 5693 '' 5694 }) 5695 5696 5697 // Insert the hidden input as specified in the settings. 5698 if ( SETTINGS.container ) $( SETTINGS.container ).append( P._hidden ) 5699 else $ELEMENT.after( P._hidden ) 5700 } 5701 5702 5703 // For iOS8. 5704 function handleKeydownEvent( event ) { 5705 5706 var keycode = event.keyCode, 5707 5708 // Check if one of the delete keys was pressed. 5709 isKeycodeDelete = /^(8|46)$/.test(keycode) 5710 5711 // For some reason IE clears the input value on âescapeâ. 5712 if ( keycode == 27 ) { 5713 P.close() 5714 return false 5715 } 5716 5717 // Check if `space` or `delete` was pressed or the picker is closed with a key movement. 5718 if ( keycode == 32 || isKeycodeDelete || !STATE.open && P.component.key[keycode] ) { 5719 5720 // Prevent it from moving the page and bubbling to doc. 5721 event.preventDefault() 5722 event.stopPropagation() 5723 5724 // If `delete` was pressed, clear the values and close the picker. 5725 // Otherwise open the picker. 5726 if ( isKeycodeDelete ) { P.clear().close() } 5727 else { P.open() } 5728 } 5729 } 5730 5731 5732 // Separated for IE 5733 function handleFocusToOpenEvent( event ) { 5734 5735 // Stop the event from propagating to the doc. 5736 event.stopPropagation() 5737 5738 // If itâs a focus event, add the âfocusedâ class to the root. 5739 if ( event.type == 'focus' ) { 5740 P.$root.addClass( CLASSES.focused ) 5741 } 5742 5743 // And then finally open the picker. 5744 P.open() 5745 } 5746 5747 5748 // Return a new picker instance. 5749 return new PickerInstance() 5750} //PickerConstructor 5751 5752 5753 5754/** 5755 * The default classes and prefix to use for the HTML classes. 5756 */ 5757PickerConstructor.klasses = function( prefix ) { 5758 prefix = prefix || 'picker' 5759 return { 5760 5761 picker: prefix, 5762 opened: prefix + '--opened', 5763 focused: prefix + '--focused', 5764 5765 input: prefix + '__input', 5766 active: prefix + '__input--active', 5767 target: prefix + '__input--target', 5768 5769 holder: prefix + '__holder', 5770 5771 frame: prefix + '__frame', 5772 wrap: prefix + '__wrap', 5773 5774 box: prefix + '__box' 5775 } 5776} //PickerConstructor.klasses 5777 5778 5779 5780/** 5781 * Check if the default theme is being used. 5782 */ 5783function isUsingDefaultTheme( element ) { 5784 5785 var theme, 5786 prop = 'position' 5787 5788 // For IE. 5789 if ( element.currentStyle ) { 5790 theme = element.currentStyle[prop] 5791 } 5792 5793 // For normal browsers. 5794 else if ( window.getComputedStyle ) { 5795 theme = getComputedStyle( element )[prop] 5796 } 5797 5798 return theme == 'fixed' 5799} 5800 5801 5802 5803/** 5804 * Get the width of the browserâs scrollbar. 5805 * Taken from: https://github.com/VodkaBears/Remodal/blob/master/src/jquery.remodal.js 5806 */ 5807function getScrollbarWidth() { 5808 5809 if ( $html.height() <= $window.height() ) { 5810 return 0 5811 } 5812 5813 var $outer = $( '<div style="visibility:hidden;width:100px" />' ). 5814 appendTo( 'body' ) 5815 5816 // Get the width without scrollbars. 5817 var widthWithoutScroll = $outer[0].offsetWidth 5818 5819 // Force adding scrollbars. 5820 $outer.css( 'overflow', 'scroll' ) 5821 5822 // Add the inner div. 5823 var $inner = $( '<div style="width:100%" />' ).appendTo( $outer ) 5824 5825 // Get the width with scrollbars. 5826 var widthWithScroll = $inner[0].offsetWidth 5827 5828 // Remove the divs. 5829 $outer.remove() 5830 5831 // Return the difference between the widths. 5832 return widthWithoutScroll - widthWithScroll 5833} 5834 5835 5836 5837/** 5838 * PickerConstructor helper methods. 5839 */ 5840PickerConstructor._ = { 5841 5842 /** 5843 * Create a group of nodes. Expects: 5844 * ` 5845 { 5846 min: {Integer}, 5847 max: {Integer}, 5848 i: {Integer}, 5849 node: {String}, 5850 item: {Function} 5851 } 5852 * ` 5853 */ 5854 group: function( groupObject ) { 5855 5856 var 5857 // Scope for the looped object 5858 loopObjectScope, 5859 5860 // Create the nodes list 5861 nodesList = '', 5862 5863 // The counter starts from the `min` 5864 counter = PickerConstructor._.trigger( groupObject.min, groupObject ) 5865 5866 5867 // Loop from the `min` to `max`, incrementing by `i` 5868 for ( ; counter <= PickerConstructor._.trigger( groupObject.max, groupObject, [ counter ] ); counter += groupObject.i ) { 5869 5870 // Trigger the `item` function within scope of the object 5871 loopObjectScope = PickerConstructor._.trigger( groupObject.item, groupObject, [ counter ] ) 5872 5873 // Splice the subgroup and create nodes out of the sub nodes 5874 nodesList += PickerConstructor._.node( 5875 groupObject.node, 5876 loopObjectScope[ 0 ], // the node 5877 loopObjectScope[ 1 ], // the classes 5878 loopObjectScope[ 2 ] // the attributes 5879 ) 5880 } 5881 5882 // Return the list of nodes 5883 return nodesList 5884 }, //group 5885 5886 5887 /** 5888 * Create a dom node string 5889 */ 5890 node: function( wrapper, item, klass, attribute ) { 5891 5892 // If the item is false-y, just return an empty string 5893 if ( !item ) return '' 5894 5895 // If the item is an array, do a join 5896 item = $.isArray( item ) ? item.join( '' ) : item 5897 5898 // Check for the class 5899 klass = klass ? ' class="' + klass + '"' : '' 5900 5901 // Check for any attributes 5902 attribute = attribute ? ' ' + attribute : '' 5903 5904 // Return the wrapped item 5905 return '<' + wrapper + klass + attribute + '>' + item + '</' + wrapper + '>' 5906 }, //node 5907 5908 5909 /** 5910 * Lead numbers below 10 with a zero. 5911 */ 5912 lead: function( number ) { 5913 return ( number < 10 ? '0': '' ) + number 5914 }, 5915 5916 5917 /** 5918 * Trigger a function otherwise return the value. 5919 */ 5920 trigger: function( callback, scope, args ) { 5921 return typeof callback == 'function' ? callback.apply( scope, args || [] ) : callback 5922 }, 5923 5924 5925 /** 5926 * If the second character is a digit, length is 2 otherwise 1. 5927 */ 5928 digits: function( string ) { 5929 return ( /\d/ ).test( string[ 1 ] ) ? 2 : 1 5930 }, 5931 5932 5933 /** 5934 * Tell if something is a date object. 5935 */ 5936 isDate: function( value ) { 5937 return {}.toString.call( value ).indexOf( 'Date' ) > -1 && this.isInteger( value.getDate() ) 5938 }, 5939 5940 5941 /** 5942 * Tell if something is an integer. 5943 */ 5944 isInteger: function( value ) { 5945 return {}.toString.call( value ).indexOf( 'Number' ) > -1 && value % 1 === 0 5946 }, 5947 5948 5949 /** 5950 * Create ARIA attribute strings. 5951 */ 5952 ariaAttr: ariaAttr 5953} //PickerConstructor._ 5954 5955 5956 5957/** 5958 * Extend the picker with a component and defaults. 5959 */ 5960PickerConstructor.extend = function( name, Component ) { 5961 5962 // Extend jQuery. 5963 $.fn[ name ] = function( options, action ) { 5964 5965 // Grab the component data. 5966 var componentData = this.data( name ) 5967 5968 // If the picker is requested, return the data object. 5969 if ( options == 'picker' ) { 5970 return componentData 5971 } 5972 5973 // If the component data exists and `options` is a string, carry out the action. 5974 if ( componentData && typeof options == 'string' ) { 5975 return PickerConstructor._.trigger( componentData[ options ], componentData, [ action ] ) 5976 } 5977 5978 // Otherwise go through each matched element and if the component 5979 // doesnât exist, create a new picker using `this` element 5980 // and merging the defaults and options with a deep copy. 5981 return this.each( function() { 5982 var $this = $( this ) 5983 if ( !$this.data( name ) ) { 5984 new PickerConstructor( this, name, Component, options ) 5985 } 5986 }) 5987 } 5988 5989 // Set the defaults. 5990 $.fn[ name ].defaults = Component.defaults 5991} //PickerConstructor.extend 5992 5993 5994 5995function aria(element, attribute, value) { 5996 if ( $.isPlainObject(attribute) ) { 5997 for ( var key in attribute ) { 5998 ariaSet(element, key, attribute[key]) 5999 } 6000 } 6001 else { 6002 ariaSet(element, attribute, value) 6003 } 6004} 6005function ariaSet(element, attribute, value) { 6006 element.setAttribute( 6007 (attribute == 'role' ? '' : 'aria-') + attribute, 6008 value 6009 ) 6010} 6011function ariaAttr(attribute, data) { 6012 if ( !$.isPlainObject(attribute) ) { 6013 attribute = { attribute: data } 6014 } 6015 data = '' 6016 for ( var key in attribute ) { 6017 var attr = (key == 'role' ? '' : 'aria-') + key, 6018 attrVal = attribute[key] 6019 data += attrVal == null ? '' : attr + '="' + attribute[key] + '"' 6020 } 6021 return data 6022} 6023 6024// IE8 bug throws an error for activeElements within iframes. 6025function getActiveElement() { 6026 try { 6027 return document.activeElement 6028 } catch ( err ) { } 6029} 6030 6031 6032 6033// Expose the picker constructor. 6034return PickerConstructor 6035 6036 6037})); 6038 6039 6040;/*! 6041 * Date picker for pickadate.js v3.5.0 6042 * http://amsul.github.io/pickadate.js/date.htm 6043 */ 6044 6045(function ( factory ) { 6046 6047 // AMD. 6048 if ( typeof define == 'function' && define.amd ) 6049 define( ['picker', 'jquery'], factory ) 6050 6051 // Node.js/browserify. 6052 else if ( typeof exports == 'object' ) 6053 module.exports = factory( require('./picker.js'), require('jquery') ) 6054 6055 // Browser globals. 6056 else factory( Picker, jQuery ) 6057 6058}(function( Picker, $ ) { 6059 6060 6061/** 6062 * Globals and constants 6063 */ 6064var DAYS_IN_WEEK = 7, 6065 WEEKS_IN_CALENDAR = 6, 6066 _ = Picker._ 6067 6068 6069 6070/** 6071 * The date picker constructor 6072 */ 6073function DatePicker( picker, settings ) { 6074 6075 var calendar = this, 6076 element = picker.$node[ 0 ], 6077 elementValue = element.value, 6078 elementDataValue = picker.$node.data( 'value' ), 6079 valueString = elementDataValue || elementValue, 6080 formatString = elementDataValue ? settings.formatSubmit : settings.format, 6081 isRTL = function() { 6082 6083 return element.currentStyle ? 6084 6085 // For IE. 6086 element.currentStyle.direction == 'rtl' : 6087 6088 // For normal browsers. 6089 getComputedStyle( picker.$root[0] ).direction == 'rtl' 6090 } 6091 6092 calendar.settings = settings 6093 calendar.$node = picker.$node 6094 6095 // The queue of methods that will be used to build item objects. 6096 calendar.queue = { 6097 min: 'measure create', 6098 max: 'measure create', 6099 now: 'now create', 6100 select: 'parse create validate', 6101 highlight: 'parse navigate create validate', 6102 view: 'parse create validate viewset', 6103 disable: 'deactivate', 6104 enable: 'activate' 6105 } 6106 6107 // The component's item object. 6108 calendar.item = {} 6109 6110 calendar.item.clear = null 6111 calendar.item.disable = ( settings.disable || [] ).slice( 0 ) 6112 calendar.item.enable = -(function( collectionDisabled ) { 6113 return collectionDisabled[ 0 ] === true ? collectionDisabled.shift() : -1 6114 })( calendar.item.disable ) 6115 6116 calendar. 6117 set( 'min', settings.min ). 6118 set( 'max', settings.max ). 6119 set( 'now' ) 6120 6121 // When thereâs a value, set the `select`, which in turn 6122 // also sets the `highlight` and `view`. 6123 if ( valueString ) { 6124 calendar.set( 'select', valueString, { format: formatString }) 6125 } 6126 6127 // If thereâs no value, default to highlighting âtodayâ. 6128 else { 6129 calendar. 6130 set( 'select', null ). 6131 set( 'highlight', calendar.item.now ) 6132 } 6133 6134 6135 // The keycode to movement mapping. 6136 calendar.key = { 6137 40: 7, // Down 6138 38: -7, // Up 6139 39: function() { return isRTL() ? -1 : 1 }, // Right 6140 37: function() { return isRTL() ? 1 : -1 }, // Left 6141 go: function( timeChange ) { 6142 var highlightedObject = calendar.item.highlight, 6143 targetDate = new Date( highlightedObject.year, highlightedObject.month, highlightedObject.date + timeChange ) 6144 calendar.set( 6145 'highlight', 6146 targetDate, 6147 { interval: timeChange } 6148 ) 6149 this.render() 6150 } 6151 } 6152 6153 6154 // Bind some picker events. 6155 picker. 6156 on( 'render', function() { 6157 picker.$root.find( '.' + settings.klass.selectMonth ).on( 'change', function() { 6158 var value = this.value 6159 if ( value ) { 6160 picker.set( 'highlight', [ picker.get( 'view' ).year, value, picker.get( 'highlight' ).date ] ) 6161 picker.$root.find( '.' + settings.klass.selectMonth ).trigger( 'focus' ) 6162 } 6163 }) 6164 picker.$root.find( '.' + settings.klass.selectYear ).on( 'change', function() { 6165 var value = this.value 6166 if ( value ) { 6167 picker.set( 'highlight', [ value, picker.get( 'view' ).month, picker.get( 'highlight' ).date ] ) 6168 picker.$root.find( '.' + settings.klass.selectYear ).trigger( 'focus' ) 6169 } 6170 }) 6171 }, 1 ). 6172 on( 'open', function() { 6173 var includeToday = '' 6174 if ( calendar.disabled( calendar.get('now') ) ) { 6175 includeToday = ':not(.' + settings.klass.buttonToday + ')' 6176 } 6177 picker.$root.find( 'button' + includeToday + ', select' ).attr( 'disabled', false ) 6178 }, 1 ). 6179 on( 'close', function() { 6180 picker.$root.find( 'button, select' ).attr( 'disabled', true ) 6181 }, 1 ) 6182 6183} //DatePicker 6184 6185 6186/** 6187 * Set a
6187datepicker item object. 6188 */ 6189DatePicker.prototype.set = function( type, value, options ) { 6190 6191 var calendar = this, 6192 calendarItem = calendar.item 6193 6194 // If the value is `null` just set it immediately. 6195 if ( value === null ) { 6196 if ( type == 'clear' ) type = 'select' 6197 calendarItem[ type ] = value 6198 return calendar 6199 } 6200 6201 // Otherwise go through the queue of methods, and invoke the functions. 6202 // Update this as the time unit, and set the final value as this item. 6203 // * In the case of `enable`, keep the queue but set `disable` instead. 6204 // And in the case of `flip`, keep the queue but set `enable` instead. 6205 calendarItem[ ( type == 'enable' ? 'disable' : type == 'flip' ? 'enable' : type ) ] = calendar.queue[ type ].split( ' ' ).map( function( method ) { 6206 value = calendar[ method ]( type, value, options ) 6207 return value 6208 }).pop() 6209 6210 // Check if we need to cascade through more updates. 6211 if ( type == 'select' ) { 6212 calendar.set( 'highlight', calendarItem.select, options ) 6213 } 6214 else if ( type == 'highlight' ) { 6215 calendar.set( 'view', calendarItem.highlight, options ) 6216 } 6217 else if ( type.match( /^(flip|min|max|disable|enable)$/ ) ) { 6218 if ( calendarItem.select && calendar.disabled( calendarItem.select ) ) { 6219 calendar.set( 'select', calendarItem.select, options ) 6220 } 6221 if ( calendarItem.highlight && calendar.disabled( calendarItem.highlight ) ) { 6222 calendar.set( 'highlight', calendarItem.highlight, options ) 6223 } 6224 } 6225 6226 return calendar 6227} //DatePicker.prototype.set 6228 6229 6230/** 6231 * Get a datepicker item object. 6232 */ 6233DatePicker.prototype.get = function( type ) { 6234 return this.item[ type ] 6235} //DatePicker.prototype.get 6236 6237 6238/** 6239 * Create a picker date object. 6240 */ 6241DatePicker.prototype.create = function( type, value, options ) { 6242 6243 var isInfiniteValue, 6244 calendar = this 6245 6246 // If thereâs no value, use the type as the value. 6247 value = value === undefined ? type : value 6248 6249 6250 // If itâs infinity, update the value. 6251 if ( value == -Infinity || value == Infinity ) { 6252 isInfiniteValue = value 6253 } 6254 6255 // If itâs an object, use the native date object. 6256 else if ( $.isPlainObject( value ) && _.isInteger( value.pick ) ) { 6257 value = value.obj 6258 } 6259 6260 // If itâs an array, convert it into a date and make sure 6261 // that itâs a valid date â otherwise default to today. 6262 else if ( $.isArray( value ) ) { 6263 value = new Date( value[ 0 ], value[ 1 ], value[ 2 ] ) 6264 value = _.isDate( value ) ? value : calendar.create().obj 6265 } 6266 6267 // If itâs a number or date object, make a normalized date. 6268 else if ( _.isInteger( value ) || _.isDate( value ) ) { 6269 value = calendar.normalize( new Date( value ), options ) 6270 } 6271 6272 // If itâs a literal true or any other case, set it to now. 6273 else /*if ( value === true )*/ { 6274 value = calendar.now( type, value, options ) 6275 } 6276 6277 // Return the compiled object. 6278 return { 6279 year: isInfiniteValue || value.getFullYear(), 6280 month: isInfiniteValue || value.getMonth(), 6281 date: isInfiniteValue || value.getDate(), 6282 day: isInfiniteValue || value.getDay(), 6283 obj: isInfiniteValue || value, 6284 pick: isInfiniteValue || value.getTime() 6285 } 6286} //DatePicker.prototype.create 6287 6288 6289/** 6290 * Create a range limit object using an array, date object, 6291 * literal âtrueâ, or integer relative to another time. 6292 */ 6293DatePicker.prototype.createRange = function( from, to ) { 6294 6295 var calendar = this, 6296 createDate = function( date ) { 6297 if ( date === true || $.isArray( date ) || _.isDate( date ) ) { 6298 return calendar.create( date ) 6299 } 6300 return date 6301 } 6302 6303 // Create objects if possible. 6304 if ( !_.isInteger( from ) ) { 6305 from = createDate( from ) 6306 } 6307 if ( !_.isInteger( to ) ) { 6308 to = createDate( to ) 6309 } 6310 6311 // Create relative dates. 6312 if ( _.isInteger( from ) && $.isPlainObject( to ) ) { 6313 from = [ to.year, to.month, to.date + from ]; 6314 } 6315 else if ( _.isInteger( to ) && $.isPlainObject( from ) ) { 6316 to = [ from.year, from.month, from.date + to ]; 6317 } 6318 6319 return { 6320 from: createDate( from ), 6321 to: createDate( to ) 6322 } 6323} //DatePicker.prototype.createRange 6324 6325 6326/** 6327 * Check if a date unit falls within a date range object. 6328 */ 6329DatePicker.prototype.withinRange = function( range, dateUnit ) { 6330 range = this.createRange(range.from, range.to) 6331 return dateUnit.pick >= range.from.pick && dateUnit.pick <= range.to.pick 6332} 6333 6334 6335/** 6336 * Check if two date range objects overlap. 6337 */ 6338DatePicker.prototype.overlapRanges = function( one, two ) { 6339 6340 var calendar = this 6341 6342 // Convert the ranges into comparable dates. 6343 one = calendar.createRange( one.from, one.to ) 6344 two = calendar.createRange( two.from, two.to ) 6345 6346 return calendar.withinRange( one, two.from ) || calendar.withinRange( one, two.to ) || 6347 calendar.withinRange( two, one.from ) || calendar.withinRange( two, one.to ) 6348} 6349 6350 6351/** 6352 * Get the date today. 6353 */ 6354DatePicker.prototype.now = function( type, value, options ) { 6355 value = new Date() 6356 if ( options && options.rel ) { 6357 value.setDate( value.getDate() + options.rel ) 6358 } 6359 return this.normalize( value, options ) 6360} 6361 6362 6363/** 6364 * Navigate to next/prev month. 6365 */ 6366DatePicker.prototype.navigate = function( type, value, options ) { 6367 6368 var targetDateObject, 6369 targetYear, 6370 targetMonth, 6371 targetDate, 6372 isTargetArray = $.isArray( value ), 6373 isTargetObject = $.isPlainObject( value ), 6374 viewsetObject = this.item.view/*, 6375 safety = 100*/ 6376 6377 6378 if ( isTargetArray || isTargetObject ) { 6379 6380 if ( isTargetObject ) { 6381 targetYear = value.year 6382 targetMonth = value.month 6383 targetDate = value.date 6384 } 6385 else { 6386 targetYear = +value[0] 6387 targetMonth = +value[1] 6388 targetDate = +value[2] 6389 } 6390 6391 // If weâre navigating months but the view is in a different 6392 // month, navigate to the viewâs year and month. 6393 if ( options && options.nav && viewsetObject && viewsetObject.month !== targetMonth ) { 6394 targetYear = viewsetObject.year 6395 targetMonth = viewsetObject.month 6396 } 6397 6398 // Figure out the expected target year and month. 6399 targetDateObject = new Date( targetYear, targetMonth + ( options && options.nav ? options.nav : 0 ), 1 ) 6400 targetYear = targetDateObject.getFullYear() 6401 targetMonth = targetDateObject.getMonth() 6402 6403 // If the month weâre going to doesnât have enough days, 6404 // keep decreasing the date until we reach the monthâs last date. 6405 while ( /*safety &&*/ new Date( targetYear, targetMonth, targetDate ).getMonth() !== targetMonth ) { 6406 targetDate -= 1 6407 /*safety -= 1 6408 if ( !safety ) { 6409 throw 'Fell into an infinite loop while navigating to ' + new Date( targetYear, targetMonth, targetDate ) + '.' 6410 }*/ 6411 } 6412 6413 value = [ targetYear, targetMonth, targetDate ] 6414 } 6415 6416 return value 6417} //DatePicker.prototype.navigate 6418 6419 6420/** 6421 * Normalize a date by setting the hours to midnight. 6422 */ 6423DatePicker.prototype.normalize = function( value/*, options*/ ) { 6424 value.setHours( 0, 0, 0, 0 ) 6425 return value 6426} 6427 6428 6429/** 6430 * Measure the range of dates. 6431 */ 6432DatePicker.prototype.measure = function( type, value/*, options*/ ) { 6433 6434 var calendar = this 6435 6436 // If itâs anything false-y, remove the limits. 6437 if ( !value ) { 6438 value = type == 'min' ? -Infinity : Infinity 6439 } 6440 6441 // If itâs a string, parse it. 6442 else if ( typeof value == 'string' ) { 6443 value = calendar.parse( type, value ) 6444 } 6445 6446 // If it's an integer, get a date relative to today. 6447 else if ( _.isInteger( value ) ) { 6448 value = calendar.now( type, value, { rel: value } ) 6449 } 6450 6451 return value 6452} ///DatePicker.prototype.measure 6453 6454 6455/** 6456 * Create a viewset object based on navigation. 6457 */ 6458DatePicker.prototype.viewset = function( type, dateObject/*, options*/ ) { 6459 return this.create([ dateObject.year, dateObject.month, 1 ]) 6460} 6461 6462 6463/** 6464 * Validate a date as enabled and shift if needed. 6465 */ 6466DatePicker.prototype.validate = function( type, dateObject, options ) { 6467 6468 var calendar = this, 6469 6470 // Keep a reference to the original date. 6471 originalDateObject = dateObject, 6472 6473 // Make sure we have an interval. 6474 interval = options && options.interval ? options.interval : 1, 6475 6476 // Check if the calendar enabled dates are inverted. 6477 isFlippedBase = calendar.item.enable === -1, 6478 6479 // Check if we have any enabled dates after/before now. 6480 hasEnabledBeforeTarget, hasEnabledAfterTarget, 6481 6482 // The min & max limits. 6483 minLimitObject = calendar.item.min, 6484 maxLimitObject = calendar.item.max, 6485 6486 // Check if weâve reached the limit during shifting. 6487 reachedMin, reachedMax, 6488 6489 // Check if the calendar is inverted and at least one weekday is enabled. 6490 hasEnabledWeekdays = isFlippedBase && calendar.item.disable.filter( function( value ) { 6491 6492 // If thereâs a date, check where it is relative to the target. 6493 if ( $.isArray( value ) ) { 6494 var dateTime = calendar.create( value ).pick 6495 if ( dateTime < dateObject.pick ) hasEnabledBeforeTarget = true 6496 else if ( dateTime > dateObject.pick ) hasEnabledAfterTarget = true 6497 } 6498 6499 // Return only integers for enabled weekdays. 6500 return _.isInteger( value ) 6501 }).length/*, 6502 6503 safety = 100*/ 6504 6505 6506 6507 // Cases to validate for: 6508 // [1] Not inverted and date disabled. 6509 // [2] Inverted and some dates enabled. 6510 // [3] Not inverted and out of range. 6511 // 6512 // Cases to **not** validate for: 6513 // ⢠Navigating months. 6514 // ⢠Not inverted and date enabled. 6515 // ⢠Inverted and all dates disabled. 6516 // ⢠..and anything else. 6517 if ( !options || !options.nav ) if ( 6518 /* 1 */ ( !isFlippedBase && calendar.disabled( dateObject ) ) || 6519 /* 2 */ ( isFlippedBase && calendar.disabled( dateObject ) && ( hasEnabledWeekdays || hasEnabledBeforeTarget || hasEnabledAfterTarget ) ) || 6520 /* 3 */ ( !isFlippedBase && (dateObject.pick <= minLimitObject.pick || dateObject.pick >= maxLimitObject.pick) ) 6521 ) { 6522 6523 6524 // When inverted, flip the direction if there arenât any enabled weekdays 6525 // and there are no enabled dates in the direction of the interval. 6526 if ( isFlippedBase && !hasEnabledWeekdays && ( ( !hasEnabledAfterTarget && interval > 0 ) || ( !hasEnabledBeforeTarget && interval < 0 ) ) ) { 6527 interval *= -1 6528 } 6529 6530 6531 // Keep looping until we reach an enabled date. 6532 while ( /*safety &&*/ calendar.disabled( dateObject ) ) { 6533 6534 /*safety -= 1 6535 if ( !safety ) { 6536 throw 'Fell into an infinite loop while validating ' + dateObject.obj + '.' 6537 }*/ 6538 6539 6540 // If weâve looped into the next/prev month with a large interval, return to the original date and flatten the interval. 6541 if ( Math.abs( interval ) > 1 && ( dateObject.month < originalDateObject.month || dateObject.month > originalDateObject.month ) ) { 6542 dateObject = originalDateObject 6543 interval = interval > 0 ? 1 : -1 6544 } 6545 6546 6547 // If weâve reached the min/max limit, reverse the direction, flatten the interval and set it to the limit. 6548 if ( dateObject.pick <= minLimitObject.pick ) { 6549 reachedMin = true 6550 interval = 1 6551 dateObject = calendar.create([ 6552 minLimitObject.year, 6553 minLimitObject.month, 6554 minLimitObject.date + (dateObject.pick === minLimitObject.pick ? 0 : -1) 6555 ]) 6556 } 6557 else if ( dateObject.pick >= maxLimitObject.pick ) { 6558 reachedMax = true 6559 interval = -1 6560 dateObject = calendar.create([ 6561 maxLimitObject.year, 6562 maxLimitObject.month, 6563 maxLimitObject.date + (dateObject.pick === maxLimitObject.pick ? 0 : 1) 6564 ]) 6565 } 6566 6567 6568 // If weâve reached both limits, just break out of the loop. 6569 if ( reachedMin && reachedMax ) { 6570 break 6571 } 6572 6573 6574 // Finally, create the shifted date using the interval and keep looping. 6575 dateObject = calendar.create([ dateObject.year, dateObject.month, dateObject.date + interval ]) 6576 } 6577 6578 } //endif 6579 6580 6581 // Return the date object settled on. 6582 return dateObject 6583} //DatePicker.prototype.validate 6584 6585 6586/** 6587 * Check if a date is disabled. 6588 */ 6589DatePicker.prototype.disabled = function( dateToVerify ) { 6590 6591 var 6592 calendar = this, 6593 6594 // Filter through the disabled dates to check if this is one. 6595 isDisabledMatch = calendar.item.disable.filter( function( dateToDisable ) { 6596 6597 // If the date is a number, match the weekday with 0index and `firstDay` check. 6598 if ( _.isInteger( dateToDisable ) ) { 6599 return dateToVerify.day === ( calendar.settings.firstDay ? dateToDisable : dateToDisable - 1 ) % 7 6600 } 6601 6602 // If itâs an array or a native JS date, create and match the exact date. 6603 if ( $.isArray( dateToDisable ) || _.isDate( dateToDisable ) ) { 6604 return dateToVerify.pick === calendar.create( dateToDisable ).pick 6605 } 6606 6607 // If itâs an object, match a date within the âfromâ and âtoâ range. 6608 if ( $.isPlainObject( dateToDisable ) ) { 6609 return calendar.withinRange( dateToDisable, dateToVerify ) 6610 } 6611 }) 6612 6613 // If this date matches a disabled date, confirm itâs not inverted. 6614 isDisabledMatch = isDisabledMatch.length && !isDisabledMatch.filter(function( dateToDisable ) { 6615 return $.isArray( dateToDisable ) && dateToDisable[3] == 'inverted' || 6616 $.isPlainObject( dateToDisable ) && dateToDisable.inverted 6617 }).length 6618 6619 // Check the calendar âenabledâ flag and respectively flip the 6620 // disabled state. Then also check if itâs beyond the min/max limits. 6621 return calendar.item.enable === -1 ? !isDisabledMatch : isDisabledMatch || 6622 dateToVerify.pick < calendar.item.min.pick || 6623 dateToVerify.pick > calendar.item.max.pick 6624 6625} //DatePicker.prototype.disabled 6626 6627 6628/** 6629 * Parse a string into a usable type. 6630 */ 6631DatePicker.prototype.parse = function( type, value, options ) { 6632 6633 var calendar = this, 6634 parsingObject = {} 6635 6636 // If itâs already parsed, weâre good. 6637 if ( !value || typeof value != 'string' ) { 6638 return value 6639 } 6640 6641 // We need a `.format` to parse the value with. 6642 if ( !( options && options.format ) ) { 6643 options = options || {} 6644 options.format = calendar.settings.format 6645 } 6646 6647 // Convert the format into an array and then map through it. 6648 calendar.formats.toArray( options.format ).map( function( label ) { 6649 6650 var 6651 // Grab the formatting label. 6652 formattingLabel = calendar.formats[ label ], 6653 6654 // The format length is from the formatting label function or the 6655 // label length without the escaping exclamation (!) mark. 6656 formatLength = formattingLabel ? _.trigger( formattingLabel, calendar, [ value, parsingObject ] ) : label.replace( /^!/, '' ).length 6657 6658 // If there's a format label, split the value up to the format length. 6659 // Then add it to the parsing object with appropriate label. 6660 if ( formattingLabel ) { 6661 parsingObject[ label ] = value.substr( 0, formatLength ) 6662 } 6663 6664 // Update the value as the substring from format length to end. 6665 value = value.substr( formatLength ) 6666 }) 6667 6668 // Compensate for month 0index. 6669 return [ 6670 parsingObject.yyyy || parsingObject.yy, 6671 +( parsingObject.mm || parsingObject.m ) - 1, 6672 parsingObject.dd || parsingObject.d 6673 ] 6674} //DatePicker.prototype.parse 6675 6676 6677/** 6678 * Various formats to display the object in. 6679 */ 6680DatePicker.protot
6680ype.formats = (function() { 6681 6682 // Return the length of the first word in a collection. 6683 function getWordLengthFromCollection( string, collection, dateObject ) { 6684 6685 // Grab the first word from the string. 6686 var word = string.match( /\w+/ )[ 0 ] 6687 6688 // If there's no month index, add it to the date object 6689 if ( !dateObject.mm && !dateObject.m ) { 6690 dateObject.m = collection.indexOf( word ) + 1 6691 } 6692 6693 // Return the length of the word. 6694 return word.length 6695 } 6696 6697 // Get the length of the first word in a string. 6698 function getFirstWordLength( string ) { 6699 return string.match( /\w+/ )[ 0 ].length 6700 } 6701 6702 return { 6703 6704 d: function( string, dateObject ) { 6705 6706 // If there's string, then get the digits length. 6707 // Otherwise return the selected date. 6708 return string ? _.digits( string ) : dateObject.date 6709 }, 6710 dd: function( string, dateObject ) { 6711 6712 // If there's a string, then the length is always 2. 6713 // Otherwise return the selected date with a leading zero. 6714 return string ? 2 : _.lead( dateObject.date ) 6715 }, 6716 ddd: function( string, dateObject ) { 6717 6718 // If there's a string, then get the length of the first word. 6719 // Otherwise return the short selected weekday. 6720 return string ? getFirstWordLength( string ) : this.settings.weekdaysShort[ dateObject.day ] 6721 }, 6722 dddd: function( string, dateObject ) { 6723 6724 // If there's a string, then get the length of the first word. 6725 // Otherwise return the full selected weekday. 6726 return string ? getFirstWordLength( string ) : this.settings.weekdaysFull[ dateObject.day ] 6727 }, 6728 m: function( string, dateObject ) { 6729 6730 // If there's a string, then get the length of the digits 6731 // Otherwise return the selected month with 0index compensation. 6732 return string ? _.digits( string ) : dateObject.month + 1 6733 }, 6734 mm: function( string, dateObject ) { 6735 6736 // If there's a string, then the length is always 2. 6737 // Otherwise return the selected month with 0index and leading zero. 6738 return string ? 2 : _.lead( dateObject.month + 1 ) 6739 }, 6740 mmm: function( string, dateObject ) { 6741 6742 var collection = this.settings.monthsShort 6743 6744 // If there's a string, get length of the relevant month from the short 6745 // months collection. Otherwise return the selected month from that collection. 6746 return string ? getWordLengthFromCollection( string, collection, dateObject ) : collection[ dateObject.month ] 6747 }, 6748 mmmm: function( string, dateObject ) { 6749 6750 var collection = this.settings.monthsFull 6751 6752 // If there's a string, get length of the relevant month from the full 6753 // months collection. Otherwise return the selected month from that collection. 6754 return string ? getWordLengthFromCollection( string, collection, dateObject ) : collection[ dateObject.month ] 6755 }, 6756 yy: function( string, dateObject ) { 6757 6758 // If there's a string, then the length is always 2. 6759 // Otherwise return the selected year by slicing out the first 2 digits. 6760 return string ? 2 : ( '' + dateObject.year ).slice( 2 ) 6761 }, 6762 yyyy: function( string, dateObject ) { 6763 6764 // If there's a string, then the length is always 4. 6765 // Otherwise return the selected year. 6766 return string ? 4 : dateObject.year 6767 }, 6768 6769 // Create an array by splitting the formatting string passed. 6770 toArray: function( formatString ) { return formatString.split( /(d{1,4}|m{1,4}|y{4}|yy|!.)/g ) }, 6771 6772 // Format an object into a string using the formatting options. 6773 toString: function ( formatString, itemObject ) { 6774 var calendar = this 6775 return calendar.formats.toArray( formatString ).map( function( label ) { 6776 return _.trigger( calendar.formats[ label ], calendar, [ 0, itemObject ] ) || label.replace( /^!/, '' ) 6777 }).join( '' ) 6778 } 6779 } 6780})() //DatePicker.prototype.formats 6781 6782 6783 6784 6785/** 6786 * Check if two date units are the exact. 6787 */ 6788DatePicker.prototype.isDateExact = function( one, two ) { 6789 6790 var calendar = this 6791 6792 // When weâre working with weekdays, do a direct comparison. 6793 if ( 6794 ( _.isInteger( one ) && _.isInteger( two ) ) || 6795 ( typeof one == 'boolean' && typeof two == 'boolean' ) 6796 ) { 6797 return one === two 6798 } 6799 6800 // When weâre working with date representations, compare the âpickâ value. 6801 if ( 6802 ( _.isDate( one ) || $.isArray( one ) ) && 6803 ( _.isDate( two ) || $.isArray( two ) ) 6804 ) { 6805 return calendar.create( one ).pick === calendar.create( two ).pick 6806 } 6807 6808 // When weâre working with range objects, compare the âfromâ and âtoâ. 6809 if ( $.isPlainObject( one ) && $.isPlainObject( two ) ) { 6810 return calendar.isDateExact( one.from, two.from ) && calendar.isDateExact( one.to, two.to ) 6811 } 6812 6813 return false 6814} 6815 6816 6817/** 6818 * Check if two date units overlap. 6819 */ 6820DatePicker.prototype.isDateOverlap = function( one, two ) { 6821 6822 var calendar = this, 6823 firstDay = calendar.settings.firstDay ? 1 : 0 6824 6825 // When weâre working with a weekday index, compare the days. 6826 if ( _.isInteger( one ) && ( _.isDate( two ) || $.isArray( two ) ) ) { 6827 one = one % 7 + firstDay 6828 return one === calendar.create( two ).day + 1 6829 } 6830 if ( _.isInteger( two ) && ( _.isDate( one ) || $.isArray( one ) ) ) { 6831 two = two % 7 + firstDay 6832 return two === calendar.create( one ).day + 1 6833 } 6834 6835 // When weâre working with range objects, check if the ranges overlap. 6836 if ( $.isPlainObject( one ) && $.isPlainObject( two ) ) { 6837 return calendar.overlapRanges( one, two ) 6838 } 6839 6840 return false 6841} 6842 6843 6844/** 6845 * Flip the âenabledâ state. 6846 */ 6847DatePicker.prototype.flipEnable = function(val) { 6848 var itemObject = this.item 6849 itemObject.enable = val || (itemObject.enable == -1 ? 1 : -1) 6850} 6851 6852 6853/** 6854 * Mark a collection of dates as âdisabledâ. 6855 */ 6856DatePicker.prototype.deactivate = function( type, datesToDisable ) { 6857 6858 var calendar = this, 6859 disabledItems = calendar.item.disable.slice(0) 6860 6861 6862 // If weâre flipping, thatâs all we need to do. 6863 if ( datesToDisable == 'flip' ) { 6864 calendar.flipEnable() 6865 } 6866 6867 else if ( datesToDisable === false ) { 6868 calendar.flipEnable(1) 6869 disabledItems = [] 6870 } 6871 6872 else if ( datesToDisable === true ) { 6873 calendar.flipEnable(-1) 6874 disabledItems = [] 6875 } 6876 6877 // Otherwise go through the dates to disable. 6878 else { 6879 6880 datesToDisable.map(function( unitToDisable ) { 6881 6882 var matchFound 6883 6884 // When we have disabled items, check for matches. 6885 // If something is matched, immediately break out. 6886 for ( var index = 0; index < disabledItems.length; index += 1 ) { 6887 if ( calendar.isDateExact( unitToDisable, disabledItems[index] ) ) { 6888 matchFound = true 6889 break 6890 } 6891 } 6892 6893 // If nothing was found, add the validated unit to the collection. 6894 if ( !matchFound ) { 6895 if ( 6896 _.isInteger( unitToDisable ) || 6897 _.isDate( unitToDisable ) || 6898 $.isArray( unitToDisable ) || 6899 ( $.isPlainObject( unitToDisable ) && unitToDisable.from && unitToDisable.to ) 6900 ) { 6901 disabledItems.push( unitToDisable ) 6902 } 6903 } 6904 }) 6905 } 6906 6907 // Return the updated collection. 6908 return disabledItems 6909} //DatePicker.prototype.deactivate 6910 6911 6912/** 6913 * Mark a collection of dates as âenabledâ. 6914 */ 6915DatePicker.prototype.activate = function( type, datesToEnable ) { 6916 6917 var calendar = this, 6918 disabledItems = calendar.item.disable, 6919 disabledItemsCount = disabledItems.length 6920 6921 // If weâre flipping, thatâs all we need to do. 6922 if ( datesToEnable == 'flip' ) { 6923 calendar.flipEnable() 6924 } 6925 6926 else if ( datesToEnable === true ) { 6927 calendar.flipEnable(1) 6928 disabledItems = [] 6929 } 6930 6931 else if ( datesToEnable === false ) { 6932 calendar.flipEnable(-1) 6933 disabledItems = [] 6934 } 6935 6936 // Otherwise go through the disabled dates. 6937 else { 6938 6939 datesToEnable.map(function( unitToEnable ) { 6940 6941 var matchFound, 6942 disabledUnit, 6943 index, 6944 isExactRange 6945 6946 // Go through the disabled items and try to find a match. 6947 for ( index = 0; index < disabledItemsCount; index += 1 ) { 6948 6949 disabledUnit = disabledItems[index] 6950 6951 // When an exact match is found, remove it from the collection. 6952 if ( calendar.isDateExact( disabledUnit, unitToEnable ) ) { 6953 matchFound = disabledItems[index] = null 6954 isExactRange = true 6955 break 6956 } 6957 6958 // When an overlapped match is found, add the âinvertedâ state to it. 6959 else if ( calendar.isDateOverlap( disabledUnit, unitToEnable ) ) { 6960 if ( $.isPlainObject( unitToEnable ) ) { 6961 unitToEnable.inverted = true 6962 matchFound = unitToEnable 6963 } 6964 else if ( $.isArray( unitToEnable ) ) { 6965 matchFound = unitToEnable 6966 if ( !matchFound[3] ) matchFound.push( '
6966inverted' ) 6967 } 6968 else if ( _.isDate( unitToEnable ) ) { 6969 matchFound = [ unitToEnable.getFullYear(), unitToEnable.getMonth(), unitToEnable.getDate(), 'inverted' ] 6970 } 6971 break 6972 } 6973 } 6974 6975 // If a match was found, remove a previous duplicate entry. 6976 if ( matchFound ) for ( index = 0; index < disabledItemsCount; index += 1 ) { 6977 if ( calendar.isDateExact( disabledItems[index], unitToEnable ) ) { 6978 disabledItems[index] = null 6979 break 6980 } 6981 } 6982 6983 // In the event that weâre dealing with an exact range of dates, 6984 // make sure there are no âinvertedâ dates because of it. 6985 if ( isExactRange ) for ( index = 0; index < disabledItemsCount; index += 1 ) { 6986 if ( calendar.isDateOverlap( disabledItems[index], unitToEnable ) ) { 6987 disabledItems[index] = null 6988 break 6989 } 6990 } 6991 6992 // If something is still matched, add it into the collection. 6993 if ( matchFound ) { 6994 disabledItems.push( matchFound ) 6995 } 6996 }) 6997 } 6998 6999 // Return the updated collection. 7000 return disabledItems.filter(function( val ) { return val != null }) 7001} //DatePicker.prototype.activate 7002 7003 7004/** 7005 * Create a string for the nodes in the picker. 7006 */ 7007DatePicker.prototype.nodes = function( isOpen ) { 7008 7009 var 7010 calendar = this, 7011 settings = calendar.settings, 7012 calendarItem = calendar.item, 7013 nowObject = calendarItem.now, 7014 selectedObject = calendarItem.select, 7015 highlightedObject = calendarItem.highlight, 7016 viewsetObject = calendarItem.view, 7017 disabledCollection = calendarItem.disable, 7018 minLimitObject = calendarItem.min, 7019 maxLimitObject = calendarItem.max, 7020 7021 7022 // Create the calendar table head using a copy of weekday labels collection. 7023 // * We do a copy so we don't mutate the original array. 7024 tableHead = (function( collection, fullCollection ) { 7025 7026 // If the first day should be Monday, move Sunday to the end. 7027 if ( settings.firstDay ) { 7028 collection.push( collection.shift() ) 7029 fullCollection.push( fullCollection.shift() ) 7030 } 7031 7032 // Create and return the table head group. 7033 return _.node( 7034 'thead', 7035 _.node( 7036 'tr', 7037 _.group({ 7038 min: 0, 7039 max: DAYS_IN_WEEK - 1, 7040 i: 1, 7041 node: 'th', 7042 item: function( counter ) { 7043 return [ 7044 collection[ counter ], 7045 settings.klass.weekdays, 7046 'scope=col title="' + fullCollection[ counter ] + '"' 7047 ] 7048 } 7049 }) 7050 ) 7051 ) //endreturn 7052 7053 // Materialize modified 7054 })( ( settings.showWeekdaysFull ? settings.weekdaysFull : settings.weekdaysLetter ).slice( 0 ), settings.weekdaysFull.slice( 0 ) ), //tableHead 7055 7056 7057 // Create the nav for next/prev month. 7058 createMonthNav = function( next ) { 7059 7060 // Otherwise, return the created month tag. 7061 return _.node( 7062 'div', 7063 ' ', 7064 settings.klass[ 'nav' + ( next ? 'Next' : 'Prev' ) ] + ( 7065 7066 // If the focused month is outside the range, disabled the button. 7067 ( next && viewsetObject.year >= maxLimitObject.year && viewsetObject.month >= maxLimitObject.month ) || 7068 ( !next && viewsetObject.year <= minLimitObject.year && viewsetObject.month <= minLimitObject.month ) ? 7069 ' ' + settings.klass.navDisabled : '' 7070 ), 7071 'data-nav=' + ( next || -1 ) + ' ' + 7072 _.ariaAttr({ 7073 role: 'button', 7074 controls: calendar.$node[0].id + '_table' 7075 }) + ' ' + 7076 'title="' + (next ? settings.labelMonthNext : settings.labelMonthPrev ) + '"' 7077 ) //endreturn 7078 }, //createMonthNav 7079 7080 7081 // Create the month label. 7082 //Materialize modified 7083 createMonthLabel = function(override) { 7084 7085 var monthsCollection = settings.showMonthsShort ? settings.monthsShort : settings.monthsFull 7086 7087 // Materialize modified 7088 if (override == "short_months") { 7089 monthsCollection = settings.monthsShort; 7090 } 7091 7092 // If there are months to select, add a dropdown menu. 7093 if ( settings.selectMonths && override == undefined) { 7094
7095 return _.node( 'select', 7096 _.group({ 7097 min: 0, 7098 max: 11, 7099 i: 1, 7100 node: 'option', 7101 item: function( loopedMonth ) { 7102 7103 return [ 7104 7105 // The looped month and no classes. 7106 monthsCollection[ loopedMonth ], 0, 7107 7108 // Set the value and selected index. 7109 'value=' + loopedMonth + 7110 ( viewsetObject.month == loopedMonth ? ' selected' : '' ) + 7111 ( 7112 ( 7113 ( viewsetObject.year == minLimitObject.year && loopedMonth < minLimitObject.month ) || 7114 ( viewsetObject.year == maxLimitObject.year && loopedMonth > maxLimitObject.month ) 7115 ) ? 7116 ' disabled' : '' 7117 ) 7118 ] 7119 } 7120 }), 7121 settings.klass.selectMonth + ' browser-default', 7122 ( isOpen ? '' : 'disabled' ) + ' ' + 7123 _.ariaAttr({ controls: calendar.$node[0].id + '_table' }) + ' ' + 7124 'title="' + settings.labelMonthSelect + '"' 7125 ) 7126 } 7127 7128 // Materialize modified 7129 if (override == "short_months") 7130 if (selectedObject != null) 7131 return _.node( 'div', monthsCollection[ selectedObject.month ] ); 7132 else return _.node( 'div', monthsCollection[ viewsetObject.month ] ); 7133 7134 // If there's a need for a month selector 7135 return _.node( 'div', monthsCollection[ viewsetObject.month ], settings.klass.month ) 7136 }, //createMonthLabel 7137 7138 7139 // Create the year label. 7140 // Materialize modified 7141 createYearLabel = function(override) { 7142 7143 var focusedYear = viewsetObject.year, 7144 7145 // If years selector is set to a literal "true", set it to 5. Otherwise 7146 // divide in half to get half before and half after focused year. 7147 numberYears = settings.selectYears === true ? 5 : ~~( settings.selectYears / 2 ) 7148 7149 // If there are years to select, add a dropdown menu. 7150 if ( numberYears ) { 7151 7152 var 7153 minYear = minLimitObject.year, 7154 maxYear = maxLimitObject.year, 7155 lowestYear = focusedYear - numberYears, 7156 highestYear = focusedYear + numberYears 7157 7158 // If the min year is greater than the lowest year, increase the highest year 7159 // by the difference and set the lowest year to the min year. 7160 if ( minYear > lowestYear ) { 7161 highestYear += minYear - lowestYear 7162 lowestYear = minYear 7163 } 7164 7165 // If the max year is less than the highest year, decrease the lowest year 7166 // by the lower of the two: available and needed years. Then set the 7167 // highest year to the max year. 7168 if ( maxYear < highestYear ) { 7169 7170 var availableYears = lowestYear - minYear, 7171 neededYears = highestYear - maxYear 7172 7173 lowestYear -= availableYears > neededYears ? neededYears : availableYears 7174 highestYear = maxYear 7175 } 7176 7177 if ( settings.selectYears && override == undefined ) { 7178 return _.node( 'select', 7179 _.group({ 7180 min: lowestYear, 7181 max: highestYear, 7182 i: 1, 7183 node: 'option', 7184 item: function( loopedYear ) { 7185 return [ 7186 7187 // The looped year and no classes. 7188 loopedYear, 0, 7189 7190 // Set the value and selected index. 7191 'value=' + loopedYear + ( focusedYear == loopedYear ? ' selected' : '' ) 7192 ] 7193 } 7194 }), 7195 settings.klass.selectYear + ' browser-default', 7196 ( isOpen ? '' : 'disabled' ) + ' ' + _.ariaAttr({ controls: calendar.$node[0].id + '_table' }) + ' ' + 7197 'title="' + settings.labelYearSelect + '"' 7198 ) 7199 } 7200 } 7201 7202 // Materialize modified 7203 if (override == "raw")
7204 return _.node( 'div', focusedYear ) 7205 7206 // Otherwise just return the year focused 7207 return _.node( 'div', focusedYear, settings.klass.year ) 7208 } //createYearLabel 7209 7210 7211 // Materialize modified 7212 createDayLabel = function() { 7213 if (selectedObject != null) 7214 return _.node( 'div', selectedObject.date) 7215 else return _.node( 'div', nowObject.date) 7216 } 7217 createWeekdayLabel = function() { 7218 var display_day; 7219 7220 if (selectedObject != null) 7221 display_day = selectedObject.day; 7222 else 7223 display_day = nowObject.day; 7224 var weekday = settings.weekdaysFull[ display_day ] 7225 return weekday 7226 } 7227 7228 7229 // Create and return the entire calendar. 7230return _.node( 7231 // Date presentation View 7232 'div', 7233 _.node( 7234 'div', 7235 createWeekdayLabel(), 7236 "picker__weekday-display" 7237 )+ 7238 _.node( 7239 // Div for short Month 7240 'div', 7241 createMonthLabel("short_months"), 7242 settings.klass.month_display 7243 )+ 7244 _.node( 7245 // Div for Day 7246 'div', 7247 createDayLabel() , 7248 settings.klass.day_display 7249 )+ 7250 _.node( 7251 // Div for Year 7252 'div', 7253 createYearLabel("raw") , 7254 settings.klass.year_display 7255 ), 7256 settings.klass.date_display 7257 )+ 7258 // Calendar container 7259 _.node('div', 7260 _.node('div', 7261 ( settings.selectYears ? createMonthLabel() + createYearLabel() : createMonthLabel() + createYearLabel() ) + 7262 createMonthNav() + createMonthNav( 1 ), 7263 settings.klass.header 7264 ) + _.node( 7265 'table', 7266 tableHead + 7267 _.node( 7268 'tbody', 7269 _.group({ 7270 min: 0, 7271 max: WEEKS_IN_CALENDAR - 1, 7272 i: 1, 7273 node: 'tr', 7274 item: function( rowCounter ) { 7275 7276 // If Monday is the first day and the month starts on Sunday, shift the date back a week. 7277 var shiftDateBy = settings.firstDay && calendar.create([ viewsetObject.year, viewsetObject.month, 1 ]).day === 0 ? -7 : 0 7278 7279 return [ 7280 _.group({ 7281 min: DAYS_IN_WEEK * rowCounter - viewsetObject.day + shiftDateBy + 1, // Add 1 for weekday 0index 7282 max: function() { 7283 return this.min + DAYS_IN_WEEK - 1 7284 }, 7285 i: 1, 7286 node: 'td', 7287 item: function( targetDate ) { 7288 7289 // Convert the time date from a relative date to a target date. 7290 targetDate = calendar.create([ viewsetObject.year, viewsetObject.month, targetDate + ( settings.firstDay ? 1 : 0 ) ]) 7291 7292 var isSelected = selectedObject && selectedObject.pick == targetDate.pick, 7293 isHighlighted = highlightedObject && highlightedObject.pick == targetDate.pick, 7294 isDisabled = disabledCollection && calendar.disabled( targetDate ) || targetDate.pick < minLimitObject.pick || targetDate.pick > maxLimitObject.pick, 7295 formattedDate = _.trigger( calendar.formats.toString, calendar, [ settings.format, targetDate ] ) 7296 7297 return [ 7298 _.node( 7299 'div', 7300 targetDate.date, 7301 (function( klasses ) { 7302 7303 // Add the `infocus` or `outfocus` classes based on month in view. 7304 klasses.push( viewsetObject.month == targetDate.month ? settings.klass.infocus : settings.klass.outfocus ) 7305 7306 // Add the `today` class if needed. 7307 if ( nowObject.pick == targetDate.pick ) { 7308 klasses.push( settings.klass.now ) 7309 } 7310 7311 // Add the `selected` class if something's selected and the time matches. 7312 if ( isSelected ) { 7313 klasses.push( settings.klass.selected ) 7314 } 7315 7316 // Add the `highlighted` class if something's highlighted and the time matches. 7317 if ( isHighlighted ) { 7318 klasses.push( settings.klass.highlighted ) 7319 } 7320 7321 // Add the `disabled` class if something's disabled and the object matches. 7322 if ( isDisabled ) { 7323 klasses.push( settings.klass.disabled ) 7324 } 7325 7326 return klasses.join( ' ' ) 7327 })([ settings.klass.day ]), 7328 'data-pick=' + targetDate.pick + ' ' + _.ariaAttr({ 7329 role: 'gridcell', 7330 label: formattedDate, 7331 selected: isSelected && calendar.$node.val() === formattedDate ? true : null, 7332 activedescendant: isHighlighted ? true : null, 7333 disabled: isDisabled ? true : null 7334 }) 7335 ), 7336 '', 7337 _.ariaAttr({ role: 'presentation' }) 7338 ] //endreturn 7339 } 7340 }) 7341 ] //endreturn 7342 } 7343 }) 7344 ), 7345 settings.klass.table, 7346 'id="' + calendar.$node[0].id + '_table' + '" ' + _.ariaAttr({ 7347 role: 'grid', 7348 controls: calendar.$node[0].id, 7349 readonly: true 7350 }) 7351 ) 7352 , settings.klass.calendar_container) // end calendar 7353 7354 + 7355 7356 // * For Firefox forms to submit, make sure to set the buttonsâ `type` attributes as âbuttonâ. 7357 _.node( 7358 'div', 7359 _.node( 'button', settings.today, "btn-flat picker__today",
7360 'type=button data-pick=' + nowObject.pick + 7361 ( isOpen && !calendar.disabled(nowObject) ? '' : ' disabled' ) + ' ' + 7362 _.ariaAttr({ controls: calendar.$node[0].id }) ) + 7363 _.node( 'button', settings.clear, "btn-flat picker__clear", 7364 'type=button data-clear=1' + 7365 ( isOpen ? '' : ' disabled' ) + ' ' + 7366 _.ariaAttr({ controls: calendar.$node[0].id }) ) + 7367 _.node('button', settings.close, "btn-flat picker__close", 7368 'type=button data-close=true ' + 7369 ( isOpen ? '' : ' disabled' ) + ' ' + 7370 _.ariaAttr({ controls: calendar.$node[0].id }) ), 7371 settings.klass.footer 7372 ) //endreturn 7373} //DatePicker.prototype.nodes 7374 7375 7376 7377 7378/** 7379 * The date picker defaults. 7380 */ 7381DatePicker.defaults = (function( prefix ) { 7382 7383 return { 7384 7385 // The title label to use for the month nav buttons 7386 labelMonthNext: 'Next month', 7387 labelMonthPrev: 'Previous month', 7388 7389 // The title label to use for the dropdown selectors 7390 labelMonthSelect: 'Select a month', 7391 labelYearSelect: 'Select a year', 7392 7393 // Months and weekdays 7394 monthsFull: [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ], 7395 monthsShort: [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ], 7396 weekdaysFull: [ 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday' ], 7397 weekdaysShort: [ 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat' ], 7398 7399 // Materialize modified 7400 weekdaysLetter: [ 'S', 'M', 'T', 'W', 'T', 'F', 'S' ], 7401 7402 // Today and clear 7403 today: 'Today', 7404 clear: 'Clear', 7405 close: 'Close', 7406 7407 // The format to show on the `input` element 7408 format: 'd mmmm, yyyy', 7409 7410 // Classes 7411 klass: { 7412 7413 table: prefix + 'table', 7414 7415 header: prefix + 'header', 7416 7417 7418 // Materialize Added klasses 7419 date_display: prefix + 'date-display', 7420 day_display: prefix + 'day-display', 7421 month_display: prefix + 'month-display', 7422 year_display: prefix + 'year-display', 7423 calendar_container: prefix + 'calendar-container', 7424 // end 7425 7426 7427 7428 navPrev: prefix + 'nav--prev', 7429 navNext: prefix + 'nav--next', 7430 navDisabled: prefix + 'nav--disabled', 7431 7432 month: prefix + 'month', 7433 year: prefix + 'year', 7434 7435 selectMonth: prefix + 'select--month', 7436 selectYear: prefix + 'select--year', 7437 7438 weekdays: prefix + 'weekday', 7439 7440 day: prefix + 'day', 7441 disabled: prefix + 'day--disabled', 7442 selected: prefix + 'day--selected', 7443 highlighted: prefix + 'day--highlighted', 7444 now: prefix + 'day--today', 7445 infocus: prefix + 'day--infocus', 7446 outfocus: prefix + 'day--outfocus', 7447 7448 footer: prefix + 'footer', 7449 7450 buttonClear: prefix + 'button--clear', 7451 buttonToday: prefix + 'button--today', 7452 buttonClose: prefix + 'button--close' 7453 } 7454 } 7455})( Picker.klasses().picker + '__' ) 7456 7457 7458 7459 7460 7461/** 7462 * Extend the picker to add the date picker. 7463 */ 7464Picker.extend( 'pickadate', DatePicker ) 7465 7466 7467})); 7468 7469 7470;(function ($) { 7471 7472 $.fn.characterCounter = function(){ 7473 return this.each(function(){ 7474 var $input = $(this); 7475 var $counterElement = $input.parent().find('span[class="character-counter"]'); 7476 7477 // character counter has already been added appended to the parent container 7478 if ($counterElement.length) { 7479 return; 7480 } 7481 7482 var itHasLengthAttribute = $input.attr('data-length') !== undefined; 7483 7484 if(itHasLengthAttribute){ 7485 $input.on('input', updateCounter); 7486 $input.on('focus', updateCounter); 7487 $input.on('blur', removeCounterElement); 7488 7489 addCounterElement($input); 7490 } 7491 7492 }); 7493 }; 7494 7495 function updateCounter(){ 7496 var maxLength = +$(this).attr('data-length'), 7497 actualLength = +$(this).val().length, 7498 isValidLength = actualLength <= maxLength; 7499 7500 $(this).parent().find('span[class="character-counter"]') 7501 .html( actualLength + '/' + maxLength); 7502 7503 addInputStyle(isValidLength, $(this)); 7504 } 7505 7506 function addCounterElement($input) { 7507 var $counterElement = $input.parent().find('span[class="character-counter"]'); 7508 7509 if ($counterElement.length) { 7510 return; 7511 } 7512 7513 $counterElement = $('<span/>') 7514 .addClass('character-counter') 7515 .css('float','right') 7516 .css('font-size','12px') 7517 .css('height', 1); 7518 7519 $input.parent().append($counterElement); 7520 } 7521 7522 function removeCounterElement(){ 7523 $(this).parent().find('span[class="character-counter"]').html(''); 7524 } 7525 7526 function addInputStyle(isValidLength, $input){ 7527 var inputHasInvalidClass = $input.hasClass('invalid'); 7528 if (isValidLength && inputHasInvalidClass) { 7529 $input.removeClass('invalid'); 7530 } 7531 else if(!isValidLength && !inputHasInvalidClass){ 7532 $input.removeClass('valid'); 7533 $input.addClass('invalid'); 7534 } 7535 } 7536 7537 $(document).ready(function(){ 7538 $('input, textarea').characterCounter(); 7539 }); 7540 7541}( jQuery )); 7542;(function ($) { 7543 7544 var methods = { 7545 7546 init : function(options) { 7547 var defaults = { 7548 duration: 200, // ms 7549 dist: -100, // zoom scale 7550 shift: 0, // spacing for center image 7551 padding: 0, // Padding between non center items 7552 fullWidth: false, // Change to full width styles 7553 indicators: false, // Toggle indicators 7554 noWrap: false, // Don't wrap around and cycle through items. 7555 onCycleTo: null // Callback for when a new slide is cycled to. 7556 }; 7557 options = $.extend(defaults, options); 7558 7559 return this.each(function() { 7560 7561 var images, item_width, item_height, offset, center, pressed, dim, count, 7562 reference, referenceY, amplitude, target, velocity, 7563 xform, frame, timestamp, ticker, dragged, vertical_dragged; 7564 var $indicators = $('<ul class="indicators"></ul>'); 7565 7566 7567 // Initialize 7568 var view = $(this); 7569 var showIndicators = view.attr('data-indicators') || options.indicators; 7570 7571 // Don't double initialize. 7572 if (view.hasClass('initialized')) { 7573 // Redraw carousel. 7574 $(this).trigger('carouselNext', [0.000001]); 7575 return true; 7576 } 7577 7578 7579 // Options 7580 if (options.fullWidth) { 7581 options.dist = 0; 7582 var firstImage = view.find('.carousel-item img').first(); 7583 if (firstImage.length) { 7584 imageHeight = firstImage.on('load', function(){ 7585 view.css('height', $(this).height()); 7586 }); 7587 } else { 7588 imageHeight = view.find('.carousel-item').first().height(); 7589 view.css('height', imageHeight); 7590 } 7591 7592 // Offset fixed items when indicators. 7593 if (showIndicators) { 7594 view.find('.carousel-fixed-item').addClass('with-indicators'); 7595 } 7596 } 7597 7598 7599 view.addClass('initialized'); 7600 pressed = false;
7601 offset = target = 0; 7602 images = []; 7603 item_width = view.find('.carousel-item').first().innerWidth(); 7604 item_height = view.find('.carousel-item').first().innerHeight(); 7605 dim = item_width * 2 + options.padding; 7606 7607 view.find('.carousel-item').each(function (i) { 7608 images.push($(this)[0]); 7609 if (showIndicators) { 7610 var $indicator = $('<li class="indicator-item" role="listitem" aria-label="Next Slide" tabindex="0"></li>'); 7611 7612 // Add active to first by default. 7613 if (i === 0) { 7614 $indicator.addClass('active'); 7615 } 7616 7617 // Handle clicks on indicators. 7618 $indicator.click(function (e) { 7619 e.stopPropagation(); 7620 7621 var index = $(this).index(); 7622 cycleTo(index); 7623 }); 7624 $indicators.append($indicator); 7625 } 7626 }); 7627 7628 if (showIndicators) { 7629 view.append($indicators); 7630 } 7631 count = images.length; 7632 7633 7634 function setupEvents() { 7635 if (typeof window.ontouchstart !== 'undefined') { 7636 view[0].addEventListener('touchstart', tap); 7637 view[0].addEventListener('touchmove', drag); 7638 view[0].addEventListener('touchend', release); 7639 } 7640 view[0].addEventListener('mousedown', tap); 7641 view[0].addEventListener('mousemove', drag); 7642 view[0].addEventListener('mouseup', release); 7643 view[0].addEventListener('mouseleave', release); 7644 view[0].addEventListener('click', click); 7645 } 7646 7647 function xpos(e) { 7648 // touch event 7649 if (e.targetTouches && (e.targetTouches.length >= 1)) { 7650 return e.targetTouches[0].clientX; 7651 } 7652 7653 // mouse event 7654 return e.clientX; 7655 } 7656 7657 function ypos(e) { 7658 // touch event 7659 if (e.targetTouches && (e.targetTouches.length >= 1)) { 7660 return e.targetTouches[0].clientY; 7661 } 7662 7663 // mouse event 7664 return e.clientY; 7665 } 7666 7667 function wrap(x) { 7668 return (x >= count) ? (x % count) : (x < 0) ? wrap(count + (x % count)) : x; 7669 } 7670 7671 function scroll(x) { 7672 var i, half, delta, dir, tween, el, alignment, xTranslation; 7673 var lastCenter = center; 7674 7675 offset = (typeof x === 'number') ? x : offset; 7676 center = Math.floor((offset + dim / 2) / dim); 7677 delta = offset - center * dim; 7678 dir = (delta < 0) ? 1 : -1; 7679 tween = -dir * delta * 2 / dim; 7680 half = count >> 1; 7681 7682 if (!options.fullWidth) { 7683 alignment = 'translateX(' + (view[0].clientWidth - item_width) / 2 + 'px) '; 7684 alignment += 'translateY(' + (view[0].clientHeight - item_height) / 2 + 'px)'; 7685 } else { 7686 alignment = 'translateX(0)'; 7687 } 7688 7689 // Set indicator active 7690 if (showIndicators) { 7691 var diff = (center % count); 7692 var activeIndicator = $indicators.find('.indicator-item.active'); 7693 if (activeIndicator.index() !== diff) { 7694 activeIndicator.removeClass('active'); 7695 $indicators.find('.indicator-item').eq(diff).addClass('active'); 7696 } 7697 } 7698 7699 // center 7700 // Don't show wrapped items. 7701 if (!options.noWrap || (center >= 0 && center < count)) { 7702 el = images[wrap(center)]; 7703 7704 // Add active class to center item. 7705 if (!$(el).hasClass('active')) { 7706 view.find('.carousel-item').removeClass('active'); 7707 $(el).addClass('active'); 7708 } 7709 el.style[xform] = alignment + 7710 ' translateX(' + (-delta / 2) + 'px)' + 7711 ' translateX(' + (dir * options.shift * tween * i) + 'px)' + 7712 ' translateZ(' + (options.dist * tween) + 'px)'; 7713 el.style.zIndex = 0; 7714 if (options.fullWidth) { tweenedOpacity = 1; } 7715 else { tweenedOpacity = 1 - 0.2 * tween; } 7716 el.style.opacity = tweenedOpacity; 7717 el.style.display = 'block'; 7718 } 7719 7720 for (i = 1; i <= half; ++i) { 7721 // right side 7722 if (options.fullWidth) { 7723 zTranslation = options.dist; 7724 tweenedOpacity = (i === half && delta < 0) ? 1 - tween : 1; 7725 } else { 7726 zTranslation = options.dist * (i * 2 + tween * dir); 7727 tweenedOpacity = 1 - 0.2 * (i * 2 + tween * dir); 7728 } 7729 // Don't show wrapped items. 7730 if (!options.noWrap || center + i < count) { 7731 el = images[wrap(center + i)]; 7732 el.style[xform] = alignment + 7733 ' translateX(' + (options.shift + (dim * i - delta) / 2) + 'px)' + 7734 ' translateZ(' + zTranslation + 'px)'; 7735 el.style.zIndex = -i; 7736 el.style.opacity = tweenedOpacity; 7737 el.style.display = 'block'; 7738 } 7739 7740 7741 // left side 7742 if (options.fullWidth) { 7743 zTranslation = options.dist; 7744 tweenedOpacity = (i === half && delta > 0) ? 1 - tween : 1; 7745 } else { 7746 zTranslation = options.dist * (i * 2 - tween * dir); 7747 tweenedOpacity = 1 - 0.2 * (i * 2 - tween * dir); 7748 } 7749 // Don't show wrapped items. 7750 if (!options.noWrap || center - i >= 0) { 7751 el = images[wrap(center - i)]; 7752 el.style[xform] = alignment + 7753 ' translateX(' + (-options.shift + (-dim * i - delta) / 2) + 'px)' + 7754 ' translateZ(' + zTranslation + 'px)'; 7755 el.style.zIndex = -i; 7756 el.style.opacity = tweenedOpacity; 7757 el.style.display = 'block'; 7758 } 7759 } 7760 7761 // center 7762 // Don't show wrapped items. 7763 if (!options.noWrap || (center >= 0 && center < count)) { 7764 el = images[wrap(center)]; 7765 el.style[xform] = alignment + 7766 ' translateX(' + (-delta / 2) + 'px)' + 7767 ' translateX(' + (dir * options.shift * tween) + 'px)' + 7768 ' translateZ(' + (options.dist * tween) + 'px)'; 7769 el.style.zIndex = 0; 7770 if (options.fullWidth) { tweenedOpacity = 1; } 7771 else { tweenedOpacity = 1 - 0.2 * tween; } 7772 el.style.opacity = tweenedOpacity; 7773 el.style.display = 'block'; 7774 } 7775 7776 // onCycleTo callback 7777 if (lastCenter !== center && 7778 typeof(options.onCycleTo) === "function") { 7779 var $curr_item = view.find('.carousel-item').eq(wrap(center)); 7780 options.onCycleTo.call(this, $curr_item, dragged); 7781 } 7782 } 7783 7784 function track() { 7785 var now, elapsed, delta, v; 7786 7787 now = Date.now();
7788 elapsed = now - timestamp; 7789 timestamp = now; 7790 delta = offset - frame; 7791 frame = offset; 7792 7793 v = 1000 * delta / (1 + elapsed); 7794 velocity = 0.8 * v + 0.2 * velocity; 7795 } 7796 7797 function autoScroll() { 7798 var elapsed, delta; 7799 7800 if (amplitude) { 7801 elapsed = Date.now() - timestamp; 7802 delta = amplitude * Math.exp(-elapsed / options.duration); 7803 if (delta > 2 || delta < -2) { 7804 scroll(target - delta); 7805 requestAnimationFrame(autoScroll); 7806 } else { 7807 scroll(target); 7808 } 7809 } 7810 } 7811 7812 function click(e) { 7813 // Disable clicks if carousel was dragged. 7814 if (dragged) { 7815 e.preventDefault(); 7816 e.stopPropagation(); 7817 return false; 7818 7819 } else if (!options.fullWidth) { 7820 var clickedIndex = $(e.target).closest('.carousel-item').index(); 7821 var diff = (center % count) - clickedIndex; 7822 7823 // Disable clicks if carousel was shifted by click 7824 if (diff !== 0) { 7825 e.preventDefault(); 7826 e.stopPropagation(); 7827 } 7828 cycleTo(clickedIndex); 7829 } 7830 } 7831 7832 function cycleTo(n) { 7833 var diff = (center % count) - n; 7834 7835 // Account for wraparound. 7836 if (!options.noWrap) { 7837 if (diff < 0) { 7838 if (Math.abs(diff + count) < Math.abs(diff)) { diff += count; } 7839 7840 } else if (diff > 0) { 7841 if (Math.abs(diff - count) < diff) { diff -= count; } 7842 } 7843 } 7844 7845 // Call prev or next accordingly. 7846 if (diff < 0) { 7847 view.trigger('carouselNext', [Math.abs(diff)]); 7848 7849 } else if (diff > 0) { 7850 view.trigger('carouselPrev', [diff]); 7851 } 7852 } 7853 7854 function tap(e) { 7855 pressed = true; 7856 dragged = false; 7857 vertical_dragged = false; 7858 reference = xpos(e); 7859 referenceY = ypos(e); 7860 7861 velocity = amplitude = 0; 7862 frame = offset; 7863 timestamp = Date.now(); 7864 clearInterval(ticker); 7865 ticker = setInterval(track, 100); 7866 7867 } 7868 7869 function drag(e) { 7870 var x, delta, deltaY; 7871 if (pressed) { 7872 x = xpos(e); 7873 y = ypos(e); 7874 delta = reference - x; 7875 deltaY = Math.abs(referenceY - y); 7876 if (deltaY < 30 && !vertical_dragged) { 7877 // If vertical scrolling don't allow dragging. 7878 if (delta > 2 || delta < -2) { 7879 dragged = true; 7880 reference = x; 7881 scroll(offset + delta); 7882 } 7883 7884 } else if (dragged) { 7885 // If dragging don't allow vertical scroll. 7886 e.preventDefault(); 7887 e.stopPropagation(); 7888 return false; 7889 7890 } else { 7891 // Vertical scrolling. 7892 vertical_dragged = true; 7893 } 7894 } 7895 7896 if (dragged) { 7897 // If dragging don't allow vertical scroll. 7898 e.preventDefault(); 7899 e.stopPropagation(); 7900 return false; 7901 } 7902 } 7903 7904 function release(e) { 7905 if (pressed) { 7906 pressed = false; 7907 } else { 7908 return; 7909 } 7910 7911 clearInterval(ticker); 7912 target = offset; 7913 if (velocity > 10 || velocity < -10) { 7914 amplitude = 0.9 * velocity; 7915 target = offset + amplitude; 7916 } 7917 target = Math.round(target / dim) * dim; 7918 7919 // No wrap of items. 7920 if (options.noWrap) { 7921 if (target >= dim * (count - 1)) { 7922 target = dim * (count - 1); 7923 } else if (target < 0) { 7924 target = 0; 7925 } 7926 } 7927 amplitude = target - offset; 7928 timestamp = Date.now(); 7929 requestAnimationFrame(autoScroll); 7930 7931 if (dragged) { 7932 e.preventDefault(); 7933 e.stopPropagation(); 7934 } 7935 return false;
7936 } 7937 7938 xform = 'transform'; 7939 ['webkit', 'Moz', 'O', 'ms'].every(function (prefix) { 7940 var e = prefix + 'Transform'; 7941 if (typeof document.body.style[e] !== 'undefined') { 7942 xform = e; 7943 return false; 7944 } 7945 return true; 7946 }); 7947 7948 7949 $(window).on('resize.carousel', function() { 7950 if (options.fullWidth) { 7951 item_width = view.find('.carousel-item').first().innerWidth(); 7952 item_height = view.find('.carousel-item').first().innerHeight(); 7953 dim = item_width * 2 + options.padding; 7954 offset = center * 2 * item_width; 7955 target = offset; 7956 } else { 7957 scroll(); 7958 } 7959 }); 7960 7961 setupEvents(); 7962 scroll(offset); 7963 7964 $(this).on('carouselNext', function(e, n) { 7965 if (n === undefined) { 7966 n = 1; 7967 } 7968 target = (dim * Math.round(offset / dim)) + (dim * n); 7969 if (offset !== target) { 7970 amplitude = target - offset; 7971 timestamp = Date.now(); 7972 requestAnimationFrame(autoScroll); 7973 } 7974 }); 7975 7976 $(this).on('carouselPrev', function(e, n) { 7977 if (n === undefined) { 7978 n = 1; 7979 } 7980 target = (dim * Math.round(offset / dim)) - (dim * n); 7981 if (offset !== target) { 7982 amplitude = target - offset; 7983 timestamp = Date.now(); 7984 requestAnimationFrame(autoScroll); 7985 } 7986 }); 7987 7988 $(this).on('carouselSet', function(e, n) { 7989 if (n === undefined) { 7990 n = 0; 7991 } 7992 cycleTo(n); 7993 }); 7994 7995 }); 7996 7997 7998 7999 }, 8000 next : function(n) { 8001 $(this).trigger('carouselNext', [n]); 8002 }, 8003 prev : function(n) { 8004 $(this).trigger('carouselPrev', [n]); 8005 }, 8006 set : function(n) { 8007 $(this).trigger('carouselSet', [n]); 8008 } 8009 }; 8010 8011 8012 $.fn.carousel = function(methodOrOptions) { 8013 if ( methods[methodOrOptions] ) { 8014 return methods[ methodOrOptions ].apply( this, Array.prototype.slice.call( arguments, 1 )); 8015 } else if ( typeof methodOrOptions === 'object' || ! methodOrOptions ) { 8016 // Default to "init" 8017 return methods.init.apply( this, arguments ); 8018 } else { 8019 $.error( 'Method ' + methodOrOptions + ' does not exist on jQuery.carousel' ); 8020 } 8021 }; // Plugin end 8022}( jQuery ));
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.