scripts.js 65 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977
  1. // ------------- JQUERY APPEAR ---------------------------------------------- //
  2. // ============ https://github.com/morr/jquery.appear ====================== //
  3. // -------------------------------------------------------------------------- //
  4. (function($) {
  5. var selectors = [];
  6. var check_binded = false;
  7. var check_lock = false;
  8. var defaults = {
  9. interval: 250,
  10. force_process: false
  11. }
  12. var $window = $(window);
  13. var $prior_appeared;
  14. function process() {
  15. check_lock = false;
  16. for (var index = 0, selectorsLength = selectors.length; index < selectorsLength; index++) {
  17. var $appeared = $(selectors[index]).filter(function() {
  18. return $(this).is(':appeared');
  19. });
  20. $appeared.trigger('appear', [$appeared]);
  21. if ($prior_appeared) {
  22. var $disappeared = $prior_appeared.not($appeared);
  23. $disappeared.trigger('disappear', [$disappeared]);
  24. }
  25. $prior_appeared = $appeared;
  26. }
  27. }
  28. // "appeared" custom filter
  29. $.expr[':']['appeared'] = function(element) {
  30. var $element = $(element);
  31. if (!$element.is(':visible')) {
  32. return false;
  33. }
  34. var window_left = $window.scrollLeft();
  35. var window_top = $window.scrollTop();
  36. var offset = $element.offset();
  37. var left = offset.left;
  38. var top = offset.top;
  39. if (top + $element.height() >= window_top &&
  40. top - ($element.data('appear-top-offset') || 0) <= window_top + $window.height() &&
  41. left + $element.width() >= window_left &&
  42. left - ($element.data('appear-left-offset') || 0) <= window_left + $window.width()) {
  43. return true;
  44. } else {
  45. return false;
  46. }
  47. }
  48. $.fn.extend({
  49. // watching for element's appearance in browser viewport
  50. appear: function(options) {
  51. var opts = $.extend({}, defaults, options || {});
  52. var selector = this.selector || this;
  53. if (!check_binded) {
  54. var on_check = function() {
  55. if (check_lock) {
  56. return;
  57. }
  58. check_lock = true;
  59. setTimeout(process, opts.interval);
  60. };
  61. $(window).scroll(on_check).resize(on_check);
  62. check_binded = true;
  63. }
  64. if (opts.force_process) {
  65. setTimeout(process, opts.interval);
  66. }
  67. selectors.push(selector);
  68. return $(selector);
  69. }
  70. });
  71. $.extend({
  72. // force elements's appearance check
  73. force_appear: function() {
  74. if (check_binded) {
  75. process();
  76. return true;
  77. };
  78. return false;
  79. }
  80. });
  81. })(jQuery);
  82. // ------------- DRAW FILL SVG ---------------------------------------------- //
  83. // ============ https://github.com/callmenick/Draw-Fill-SVG ================= //
  84. // -------------------------------------------------------------------------- //
  85. (function( window ){
  86. 'use strict';
  87. /**
  88. * Cross browser transition end events
  89. *
  90. * Use modernizr to detect cross browser transition end events. Make sure
  91. * to include Modernizr in your doc and have "Modernizr.prefixed()" checked
  92. * off in the extensibility section.
  93. */
  94. var transEndEventNames = {
  95. "WebkitTransition" : "webkitTransitionEnd",
  96. "MozTransition" : "transitionend",
  97. "OTransition" : "oTransitionEnd",
  98. "msTransition" : "MSTransitionEnd",
  99. "transition" : "transitionend"
  100. },
  101. transEndEventName = transEndEventNames[ Modernizr.prefixed('transition') ];
  102. /**
  103. * Extend obj function
  104. *
  105. */
  106. function extend( a, b ) {
  107. for( var key in b ) {
  108. if( b.hasOwnProperty( key ) ) {
  109. a[key] = b[key];
  110. }
  111. }
  112. return a;
  113. }
  114. /**
  115. * DrawFillSVG constructor
  116. *
  117. */
  118. function DrawFillSVG( options ) {
  119. this.options = extend( {}, this.options );
  120. extend( this.options, options );
  121. this._init();
  122. }
  123. /**
  124. * DrawFillSVG options
  125. *
  126. * Available options:
  127. * elementId - the ID of the element to draw
  128. */
  129. DrawFillSVG.prototype.options = {
  130. elementId : "svg"
  131. }
  132. /**
  133. * DrawFillSVG _init
  134. *
  135. * Initialise DrawFillSVG
  136. */
  137. DrawFillSVG.prototype._init = function() {
  138. this.svg = document.getElementById(this.options.elementId);
  139. this.paths = this.svg.querySelectorAll("path");
  140. this._initAnimation();
  141. }
  142. /**
  143. * DrawFillSVG _initAnimation()
  144. *
  145. * Reset some style properties on our paths, add some transitions, set the
  146. * stroke-dasharray to the length of the path, and the stroke-dashoffset to
  147. * the length of the path pushing it out of view initially. Then, set the
  148. * stroke-dashoffset to 0, animating the strokes in a drawing manner. Then,
  149. * run the path filler sequence.
  150. */
  151. DrawFillSVG.prototype._initAnimation = function() {
  152. for ( var i = 0; i < this.paths.length; i++ ) {
  153. var path = this.paths[i];
  154. var length = path.getTotalLength();
  155. // reset opacities
  156. path.style.fillOpacity = 0;
  157. path.style.strokeOpacity = 1;
  158. // reset transitions
  159. path.style.transition = path.style.WebkitTransition = "none";
  160. // reset stroke dash array and stroke dash offset
  161. path.style.strokeDasharray = length + " " + length;
  162. path.style.strokeDashoffset = length;
  163. path.getBoundingClientRect();
  164. // apply new transitions
  165. path.style.transition = path.style.WebkitTransition = "stroke-dashoffset 2s ease-in-out";
  166. // go baby go
  167. path.style.strokeDashoffset = 0;
  168. // fill the path
  169. this._fillPath( path );
  170. }
  171. }
  172. /**
  173. * DrawFillSVG _fillPath()
  174. *
  175. * Resets the transition props, then fills the path and fades out the stroke
  176. * by updating the styles.
  177. */
  178. DrawFillSVG.prototype._fillPath = function( path ) {
  179. path.addEventListener( transEndEventName, function() {
  180. // reset transitions
  181. path.style.transition = path.style.WebkitTransition = "none";
  182. path.style.transition = path.style.WebkitTransition = "fill-opacity 1s ease-in-out, stroke-opacity 1s ease-in-out";
  183. // edit props
  184. path.style.fillOpacity = 1;
  185. path.style.strokeOpacity = 0;
  186. } );
  187. }
  188. /**
  189. * DrawFillSVG replay
  190. *
  191. * A public function that allows you to replay the animation if you want. For
  192. * example, click a button, and replay the animation.
  193. */
  194. DrawFillSVG.prototype.replay = function() {
  195. this._initAnimation();
  196. }
  197. /**
  198. * Add to global namespace
  199. */
  200. window.DrawFillSVG = DrawFillSVG;
  201. })( window );
  202. // ------------- JQUERY TYPED.JS -------------------------------------------- //
  203. // ============ https://github.com/mattboldt/typed.js/ ====================== //
  204. // -------------------------------------------------------------------------- //
  205. !function($){
  206. "use strict";
  207. var Typed = function(el, options){
  208. // chosen element to manipulate text
  209. this.el = $(el);
  210. // options
  211. this.options = $.extend({}, $.fn.typed.defaults, options);
  212. // text content of element
  213. this.baseText = this.el.text() || this.el.attr('placeholder') || '';
  214. // typing speed
  215. this.typeSpeed = this.options.typeSpeed;
  216. // add a delay before typing starts
  217. this.startDelay = this.options.startDelay;
  218. // backspacing speed
  219. this.backSpeed = this.options.backSpeed;
  220. // amount of time to wait before backspacing
  221. this.backDelay = this.options.backDelay;
  222. // input strings of text
  223. this.strings = this.options.strings;
  224. // character number position of current string
  225. this.strPos = 0;
  226. // current array position
  227. this.arrayPos = 0;
  228. // number to stop backspacing on.
  229. // default 0, can change depending on how many chars
  230. // you want to remove at the time
  231. this.stopNum = 0;
  232. // Looping logic
  233. this.loop = this.options.loop;
  234. this.loopCount = this.options.loopCount;
  235. this.curLoop = 0;
  236. // for stopping
  237. this.stop = false;
  238. // show cursor
  239. this.showCursor = this.isInput ? false : this.options.showCursor;
  240. // custom cursor
  241. this.cursorChar = this.options.cursorChar;
  242. // attribute to type
  243. this.isInput = this.el.is('input');
  244. this.attr = this.options.attr || (this.isInput ? 'placeholder' : null);
  245. // All systems go!
  246. this.build();
  247. };
  248. Typed.prototype = {
  249. constructor: Typed
  250. , init: function(){
  251. // begin the loop w/ first current string (global self.string)
  252. // current string will be passed as an argument each time after this
  253. var self = this;
  254. self.timeout = setTimeout(function() {
  255. // Start typing
  256. self.typewrite(self.strings[self.arrayPos], self.strPos);
  257. }, self.startDelay);
  258. }
  259. , build: function(){
  260. // Insert cursor
  261. if (this.showCursor === true){
  262. this.cursor = $("<span class=\"typed-cursor\">" + this.cursorChar + "</span>");
  263. this.el.after(this.cursor);
  264. }
  265. this.init();
  266. }
  267. // pass current string state to each function, types 1 char per call
  268. , typewrite: function(curString, curStrPos){
  269. // exit when stopped
  270. if(this.stop === true)
  271. return;
  272. // varying values for setTimeout during typing
  273. // can't be global since number changes each time loop is executed
  274. var humanize = Math.round(Math.random() * (100 - 30)) + this.typeSpeed;
  275. var self = this;
  276. // ------------- optional ------------- //
  277. // backpaces a certain string faster
  278. // ------------------------------------ //
  279. // if (self.arrayPos == 1){
  280. // self.backDelay = 50;
  281. // }
  282. // else{ self.backDelay = 500; }
  283. // contain typing function in a timeout humanize'd delay
  284. self.timeout = setTimeout(function() {
  285. // check for an escape character before a pause value
  286. // format: \^\d+ .. eg: ^1000 .. should be able to print the ^ too using ^^
  287. // single ^ are removed from string
  288. var charPause = 0;
  289. var substr = curString.substr(curStrPos);
  290. if (substr.charAt(0) === '^') {
  291. var skip = 1; // skip atleast 1
  292. if(/^\^\d+/.test(substr)) {
  293. substr = /\d+/.exec(substr)[0];
  294. skip += substr.length;
  295. charPause = parseInt(substr);
  296. }
  297. // strip out the escape character and pause value so they're not printed
  298. curString = curString.substring(0,curStrPos)+curString.substring(curStrPos+skip);
  299. }
  300. // timeout for any pause after a character
  301. self.timeout = setTimeout(function() {
  302. if(curStrPos === curString.length) {
  303. // fires callback function
  304. self.options.onStringTyped(self.arrayPos);
  305. // is this the final string
  306. if(self.arrayPos === self.strings.length-1) {
  307. // animation that occurs on the last typed string
  308. self.options.callback();
  309. self.curLoop++;
  310. // quit if we wont loop back
  311. if(self.loop === false || self.curLoop === self.loopCount)
  312. return;
  313. }
  314. self.timeout = setTimeout(function(){
  315. self.backspace(curString, curStrPos);
  316. }, self.backDelay);
  317. } else {
  318. /* call before functions if applicable */
  319. if(curStrPos === 0)
  320. self.options.preStringTyped(self.arrayPos);
  321. // start typing each new char into existing string
  322. // curString: arg, self.baseText: original text inside element
  323. var nextString = self.baseText + curString.substr(0, curStrPos+1);
  324. if (self.attr) {
  325. self.el.attr(self.attr, nextString);
  326. } else {
  327. self.el.text(nextString);
  328. }
  329. // add characters one by one
  330. curStrPos++;
  331. // loop the function
  332. self.typewrite(curString, curStrPos);
  333. }
  334. // end of character pause
  335. }, charPause);
  336. // humanized value for typing
  337. }, humanize);
  338. }
  339. , backspace: function(curString, curStrPos){
  340. // exit when stopped
  341. if (this.stop === true) {
  342. return;
  343. }
  344. // varying values for setTimeout during typing
  345. // can't be global since number changes each time loop is executed
  346. var humanize = Math.round(Math.random() * (100 - 30)) + this.backSpeed;
  347. var self = this;
  348. self.timeout = setTimeout(function() {
  349. // ----- this part is optional ----- //
  350. // check string array position
  351. // on the first string, only delete one word
  352. // the stopNum actually represents the amount of chars to
  353. // ------------- CUSTOM OPTIONS --------------------------------------------- //
  354. // ========================================================================== //
  355. // -------------------------------------------------------------------------- //
  356. if (self.arrayPos == 1) {
  357. self.stopNum = 17;
  358. self.backDelay = 500;
  359. }
  360. else if (self.arrayPos == 2) {
  361. self.stopNum = 54;
  362. }
  363. else{self.stopNum = 0;}
  364. // ----- continue important stuff ----- //
  365. // replace text with base text + typed characters
  366. var nextString = self.baseText + curString.substr(0, curStrPos);
  367. if (self.attr) {
  368. self.el.attr(self.attr, nextString);
  369. } else {
  370. self.el.text(nextString);
  371. }
  372. // if the number (id of character in current string) is
  373. // less than the stop number, keep going
  374. if (curStrPos > self.stopNum){
  375. // subtract characters one by one
  376. curStrPos--;
  377. // loop the function
  378. self.backspace(curString, curStrPos);
  379. }
  380. // if the stop number has been reached, increase
  381. // array position to next string
  382. else if (curStrPos <= self.stopNum) {
  383. self.arrayPos++;
  384. if(self.arrayPos === self.strings.length) {
  385. self.arrayPos = 0;
  386. self.init();
  387. } else
  388. self.typewrite(self.strings[self.arrayPos], curStrPos);
  389. }
  390. // humanized value for typing
  391. }, humanize);
  392. }
  393. // Start & Stop currently not working
  394. // , stop: function() {
  395. // var self = this;
  396. // self.stop = true;
  397. // clearInterval(self.timeout);
  398. // }
  399. // , start: function() {
  400. // var self = this;
  401. // if(self.stop === false)
  402. // return;
  403. // this.stop = false;
  404. // this.init();
  405. // }
  406. // Reset and rebuild the element
  407. , reset: function(){
  408. var self = this;
  409. clearInterval(self.timeout);
  410. var id = this.el.attr('id');
  411. this.el.after('<span id="' + id + '"/>')
  412. this.el.remove();
  413. this.cursor.remove();
  414. // Send the callback
  415. self.options.resetCallback();
  416. }
  417. };
  418. $.fn.typed = function (option) {
  419. return this.each(function () {
  420. var $this = $(this)
  421. , data = $this.data('typed')
  422. , options = typeof option == 'object' && option;
  423. if (!data) $this.data('typed', (data = new Typed(this, options)));
  424. if (typeof option == 'string') data[option]();
  425. });
  426. };
  427. $.fn.typed.defaults = {
  428. strings: ["These are the default values...", "You know what you should do?", "Use your own!", "Have a great day!"],
  429. // typing speed
  430. typeSpeed: 0,
  431. // time before typing starts
  432. startDelay: 0,
  433. // backspacing speed
  434. backSpeed: 0,
  435. // time before backspacing
  436. backDelay: 500,
  437. // loop
  438. loop: false,
  439. // false = infinite
  440. loopCount: false,
  441. // show cursor
  442. showCursor: true,
  443. // character for cursor
  444. cursorChar: "|",
  445. // attribute to type (null == text)
  446. attr: null,
  447. // call when done callback function
  448. callback: function() {},
  449. // starting callback function before each string
  450. preStringTyped: function() {},
  451. //callback for every typed string
  452. onStringTyped: function() {},
  453. // callback for reset
  454. resetCallback: function() {}
  455. };
  456. }(window.jQuery);
  457. // ------------- JQUERY SCROLLTO--------------------------------------------- //
  458. // ============ https://github.com/balupton/jquery-scrollto ================= //
  459. // -------------------------------------------------------------------------- //
  460. /*global define:false require:false */
  461. (function (name, context, definition) {
  462. if (typeof module != 'undefined' && module.exports) module.exports = definition();
  463. else if (typeof define == 'function' && define.amd) define(definition);
  464. else context[name] = definition();
  465. })('jquery-scrollto', this, function(){
  466. // Prepare
  467. var jQuery, $, ScrollTo;
  468. jQuery = $ = window.jQuery || require('jquery');
  469. // Fix scrolling animations on html/body on safari
  470. $.propHooks.scrollTop = $.propHooks.scrollLeft = {
  471. get: function(elem,prop) {
  472. var result = null;
  473. if ( elem.tagName === 'HTML' || elem.tagName === 'BODY' ) {
  474. if ( prop === 'scrollLeft' ) {
  475. result = window.scrollX;
  476. } else if ( prop === 'scrollTop' ) {
  477. result = window.scrollY;
  478. }
  479. }
  480. if ( result == null ) {
  481. result = elem[prop];
  482. }
  483. return result;
  484. }
  485. };
  486. $.Tween.propHooks.scrollTop = $.Tween.propHooks.scrollLeft = {
  487. get: function(tween) {
  488. return $.propHooks.scrollTop.get(tween.elem, tween.prop);
  489. },
  490. set: function(tween) {
  491. // Our safari fix
  492. if ( tween.elem.tagName === 'HTML' || tween.elem.tagName === 'BODY' ) {
  493. // Defaults
  494. tween.options.bodyScrollLeft = (tween.options.bodyScrollLeft || window.scrollX);
  495. tween.options.bodyScrollTop = (tween.options.bodyScrollTop || window.scrollY);
  496. // Apply
  497. if ( tween.prop === 'scrollLeft' ) {
  498. tween.options.bodyScrollLeft = Math.round(tween.now);
  499. }
  500. else if ( tween.prop === 'scrollTop' ) {
  501. tween.options.bodyScrollTop = Math.round(tween.now);
  502. }
  503. // Apply
  504. window.scrollTo(tween.options.bodyScrollLeft, tween.options.bodyScrollTop);
  505. }
  506. // jQuery's IE8 Fix
  507. else if ( tween.elem.nodeType && tween.elem.parentNode ) {
  508. tween.elem[ tween.prop ] = tween.now;
  509. }
  510. }
  511. };
  512. // jQuery ScrollTo
  513. ScrollTo = {
  514. // Configuration
  515. config: {
  516. duration: 400,
  517. easing: 'swing',
  518. callback: undefined,
  519. durationMode: 'each',
  520. offsetTop: 0,
  521. offsetLeft: 0
  522. },
  523. // Set Configuration
  524. configure: function(options){
  525. // Apply Options to Config
  526. $.extend(ScrollTo.config, options||{});
  527. // Chain
  528. return this;
  529. },
  530. // Perform the Scroll Animation for the Collections
  531. // We use $inline here, so we can determine the actual offset start for each overflow:scroll item
  532. // Each collection is for each overflow:scroll item
  533. scroll: function(collections, config){
  534. // Prepare
  535. var collection, $container, container, $target, $inline, position, containerTagName,
  536. containerScrollTop, containerScrollLeft,
  537. containerScrollTopEnd, containerScrollLeftEnd,
  538. startOffsetTop, targetOffsetTop, targetOffsetTopAdjusted,
  539. startOffsetLeft, targetOffsetLeft, targetOffsetLeftAdjusted,
  540. scrollOptions,
  541. callback;
  542. // Determine the Scroll
  543. collection = collections.pop();
  544. $container = collection.$container;
  545. $target = collection.$target;
  546. containerTagName = $container.prop('tagName');
  547. // Prepare the Inline Element of the Container
  548. $inline = $('<span/>').css({
  549. 'position': 'absolute',
  550. 'top': '0px',
  551. 'left': '0px'
  552. });
  553. position = $container.css('position');
  554. // Insert the Inline Element of the Container
  555. $container.css({position:'relative'});
  556. $inline.appendTo($container);
  557. // Determine the top offset
  558. startOffsetTop = $inline.offset().top;
  559. targetOffsetTop = $target.offset().top;
  560. targetOffsetTopAdjusted = targetOffsetTop - startOffsetTop - parseInt(config.offsetTop,10);
  561. // Determine the left offset
  562. startOffsetLeft = $inline.offset().left;
  563. targetOffsetLeft = $target.offset().left;
  564. targetOffsetLeftAdjusted = targetOffsetLeft - startOffsetLeft - parseInt(config.offsetLeft,10);
  565. // Determine current scroll positions
  566. containerScrollTop = $container.prop('scrollTop');
  567. containerScrollLeft = $container.prop('scrollLeft');
  568. // Reset the Inline Element of the Container
  569. $inline.remove();
  570. $container.css({position:position});
  571. // Prepare the scroll options
  572. scrollOptions = {};
  573. // Prepare the callback
  574. callback = function(event){
  575. // Check
  576. if ( collections.length === 0 ) {
  577. // Callback
  578. if ( typeof config.callback === 'function' ) {
  579. config.callback();
  580. }
  581. }
  582. else {
  583. // Recurse
  584. ScrollTo.scroll(collections,config);
  585. }
  586. // Return true
  587. return true;
  588. };
  589. // Handle if we only want to scroll if we are outside the viewport
  590. if ( config.onlyIfOutside ) {
  591. // Determine current scroll positions
  592. containerScrollTopEnd = containerScrollTop + $container.height();
  593. containerScrollLeftEnd = containerScrollLeft + $container.width();
  594. // Check if we are in the range of the visible area of the container
  595. if ( containerScrollTop < targetOffsetTopAdjusted && targetOffsetTopAdjusted < containerScrollTopEnd ) {
  596. targetOffsetTopAdjusted = containerScrollTop;
  597. }
  598. if ( containerScrollLeft < targetOffsetLeftAdjusted && targetOffsetLeftAdjusted < containerScrollLeftEnd ) {
  599. targetOffsetLeftAdjusted = containerScrollLeft;
  600. }
  601. }
  602. // Determine the scroll options
  603. if ( targetOffsetTopAdjusted !== containerScrollTop ) {
  604. scrollOptions.scrollTop = targetOffsetTopAdjusted;
  605. }
  606. if ( targetOffsetLeftAdjusted !== containerScrollLeft ) {
  607. scrollOptions.scrollLeft = targetOffsetLeftAdjusted;
  608. }
  609. // Check to see if the scroll is necessary
  610. if ( $container.prop('scrollHeight') === $container.width() ) {
  611. delete scrollOptions.scrollTop;
  612. }
  613. if ( $container.prop('scrollWidth') === $container.width() ) {
  614. delete scrollOptions.scrollLeft;
  615. }
  616. // Perform the scroll
  617. if ( scrollOptions.scrollTop != null || scrollOptions.scrollLeft != null ) {
  618. $container.animate(scrollOptions, {
  619. duration: config.duration,
  620. easing: config.easing,
  621. complete: callback
  622. });
  623. }
  624. else {
  625. callback();
  626. }
  627. // Return true
  628. return true;
  629. },
  630. // ScrollTo the Element using the Options
  631. fn: function(options){
  632. // Prepare
  633. var collections, config, $container, container;
  634. collections = [];
  635. // Prepare
  636. var $target = $(this);
  637. if ( $target.length === 0 ) {
  638. // Chain
  639. return this;
  640. }
  641. // Handle Options
  642. config = $.extend({},ScrollTo.config,options);
  643. // Fetch
  644. $container = $target.parent();
  645. container = $container.get(0);
  646. // Cycle through the containers
  647. while ( ($container.length === 1) && (container !== document.body) && (container !== document) ) {
  648. // Check Container for scroll differences
  649. var containerScrollTop, containerScrollLeft;
  650. containerScrollTop = $container.css('overflow-y') !== 'visible' && container.scrollHeight !== container.clientHeight;
  651. containerScrollLeft = $container.css('overflow-x') !== 'visible' && container.scrollWidth !== container.clientWidth;
  652. if ( containerScrollTop || containerScrollLeft ) {
  653. // Push the Collection
  654. collections.push({
  655. '$container': $container,
  656. '$target': $target
  657. });
  658. // Update the Target
  659. $target = $container;
  660. }
  661. // Update the Container
  662. $container = $container.parent();
  663. container = $container.get(0);
  664. }
  665. // Add the final collection
  666. collections.push({
  667. '$container': $('html'),
  668. // document.body doesn't work in firefox, html works for all
  669. // internet explorer starts at the beggining
  670. '$target': $target
  671. });
  672. // Adjust the Config
  673. if ( config.durationMode === 'all' ) {
  674. config.duration /= collections.length;
  675. }
  676. // Handle
  677. ScrollTo.scroll(collections,config);
  678. // Chain
  679. return this;
  680. }
  681. };
  682. // Apply our extensions to jQuery
  683. $.ScrollTo = $.ScrollTo || ScrollTo;
  684. $.fn.ScrollTo = $.fn.ScrollTo || ScrollTo.fn;
  685. // Export
  686. return ScrollTo;
  687. });
  688. // ------------- WOW ANIMATE ------------------------------------------------ //
  689. // ==============https://github.com/matthieua/WOW =========================== //
  690. // -------------------------------------------------------------------------- //
  691. (function() {
  692. var MutationObserver, Util, WeakMap, getComputedStyle, getComputedStyleRX,
  693. __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
  694. __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
  695. Util = (function() {
  696. function Util() {}
  697. Util.prototype.extend = function(custom, defaults) {
  698. var key, value;
  699. for (key in defaults) {
  700. value = defaults[key];
  701. if (custom[key] == null) {
  702. custom[key] = value;
  703. }
  704. }
  705. return custom;
  706. };
  707. Util.prototype.isMobile = function(agent) {
  708. return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(agent);
  709. };
  710. Util.prototype.addEvent = function(elem, event, fn) {
  711. if (elem.addEventListener != null) {
  712. return elem.addEventListener(event, fn, false);
  713. } else if (elem.attachEvent != null) {
  714. return elem.attachEvent("on" + event, fn);
  715. } else {
  716. return elem[event] = fn;
  717. }
  718. };
  719. Util.prototype.removeEvent = function(elem, event, fn) {
  720. if (elem.removeEventListener != null) {
  721. return elem.removeEventListener(event, fn, false);
  722. } else if (elem.detachEvent != null) {
  723. return elem.detachEvent("on" + event, fn);
  724. } else {
  725. return delete elem[event];
  726. }
  727. };
  728. Util.prototype.innerHeight = function() {
  729. if ('innerHeight' in window) {
  730. return window.innerHeight;
  731. } else {
  732. return document.documentElement.clientHeight;
  733. }
  734. };
  735. return Util;
  736. })();
  737. WeakMap = this.WeakMap || this.MozWeakMap || (WeakMap = (function() {
  738. function WeakMap() {
  739. this.keys = [];
  740. this.values = [];
  741. }
  742. WeakMap.prototype.get = function(key) {
  743. var i, item, _i, _len, _ref;
  744. _ref = this.keys;
  745. for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
  746. item = _ref[i];
  747. if (item === key) {
  748. return this.values[i];
  749. }
  750. }
  751. };
  752. WeakMap.prototype.set = function(key, value) {
  753. var i, item, _i, _len, _ref;
  754. _ref = this.keys;
  755. for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
  756. item = _ref[i];
  757. if (item === key) {
  758. this.values[i] = value;
  759. return;
  760. }
  761. }
  762. this.keys.push(key);
  763. return this.values.push(value);
  764. };
  765. return WeakMap;
  766. })());
  767. MutationObserver = this.MutationObserver || this.WebkitMutationObserver || this.MozMutationObserver || (MutationObserver = (function() {
  768. function MutationObserver() {
  769. if (typeof console !== "undefined" && console !== null) {
  770. console.warn('MutationObserver is not supported by your browser.');
  771. }
  772. if (typeof console !== "undefined" && console !== null) {
  773. console.warn('WOW.js cannot detect dom mutations, please call .sync() after loading new content.');
  774. }
  775. }
  776. MutationObserver.notSupported = true;
  777. MutationObserver.prototype.observe = function() {};
  778. return MutationObserver;
  779. })());
  780. getComputedStyle = this.getComputedStyle || function(el, pseudo) {
  781. this.getPropertyValue = function(prop) {
  782. var _ref;
  783. if (prop === 'float') {
  784. prop = 'styleFloat';
  785. }
  786. if (getComputedStyleRX.test(prop)) {
  787. prop.replace(getComputedStyleRX, function(_, char) {
  788. return char.toUpperCase();
  789. });
  790. }
  791. return ((_ref = el.currentStyle) != null ? _ref[prop] : void 0) || null;
  792. };
  793. return this;
  794. };
  795. getComputedStyleRX = /(\-([a-z]){1})/g;
  796. this.WOW = (function() {
  797. WOW.prototype.defaults = {
  798. boxClass: 'wow',
  799. animateClass: 'animated',
  800. offset: 0,
  801. mobile: true,
  802. live: true
  803. };
  804. function WOW(options) {
  805. if (options == null) {
  806. options = {};
  807. }
  808. this.scrollCallback = __bind(this.scrollCallback, this);
  809. this.scrollHandler = __bind(this.scrollHandler, this);
  810. this.start = __bind(this.start, this);
  811. this.scrolled = true;
  812. this.config = this.util().extend(options, this.defaults);
  813. this.animationNameCache = new WeakMap();
  814. }
  815. WOW.prototype.init = function() {
  816. var _ref;
  817. this.element = window.document.documentElement;
  818. if ((_ref = document.readyState) === "interactive" || _ref === "complete") {
  819. this.start();
  820. } else {
  821. this.util().addEvent(document, 'DOMContentLoaded', this.start);
  822. }
  823. return this.finished = [];
  824. };
  825. WOW.prototype.start = function() {
  826. var box, _i, _len, _ref;
  827. this.stopped = false;
  828. this.boxes = (function() {
  829. var _i, _len, _ref, _results;
  830. _ref = this.element.querySelectorAll("." + this.config.boxClass);
  831. _results = [];
  832. for (_i = 0, _len = _ref.length; _i < _len; _i++) {
  833. box = _ref[_i];
  834. _results.push(box);
  835. }
  836. return _results;
  837. }).call(this);
  838. this.all = (function() {
  839. var _i, _len, _ref, _results;
  840. _ref = this.boxes;
  841. _results = [];
  842. for (_i = 0, _len = _ref.length; _i < _len; _i++) {
  843. box = _ref[_i];
  844. _results.push(box);
  845. }
  846. return _results;
  847. }).call(this);
  848. if (this.boxes.length) {
  849. if (this.disabled()) {
  850. this.resetStyle();
  851. } else {
  852. _ref = this.boxes;
  853. for (_i = 0, _len = _ref.length; _i < _len; _i++) {
  854. box = _ref[_i];
  855. this.applyStyle(box, true);
  856. }
  857. this.util().addEvent(window, 'scroll', this.scrollHandler);
  858. this.util().addEvent(window, 'resize', this.scrollHandler);
  859. this.interval = setInterval(this.scrollCallback, 50);
  860. }
  861. }
  862. if (this.config.live) {
  863. return new MutationObserver((function(_this) {
  864. return function(records) {
  865. var node, record, _j, _len1, _results;
  866. _results = [];
  867. for (_j = 0, _len1 = records.length; _j < _len1; _j++) {
  868. record = records[_j];
  869. _results.push((function() {
  870. var _k, _len2, _ref1, _results1;
  871. _ref1 = record.addedNodes || [];
  872. _results1 = [];
  873. for (_k = 0, _len2 = _ref1.length; _k < _len2; _k++) {
  874. node = _ref1[_k];
  875. _results1.push(this.doSync(node));
  876. }
  877. return _results1;
  878. }).call(_this));
  879. }
  880. return _results;
  881. };
  882. })(this)).observe(document.body, {
  883. childList: true,
  884. subtree: true
  885. });
  886. }
  887. };
  888. WOW.prototype.stop = function() {
  889. this.stopped = true;
  890. this.util().removeEvent(window, 'scroll', this.scrollHandler);
  891. this.util().removeEvent(window, 'resize', this.scrollHandler);
  892. if (this.interval != null) {
  893. return clearInterval(this.interval);
  894. }
  895. };
  896. WOW.prototype.sync = function(element) {
  897. if (MutationObserver.notSupported) {
  898. return this.doSync(this.element);
  899. }
  900. };
  901. WOW.prototype.doSync = function(element) {
  902. var box, _i, _len, _ref, _results;
  903. if (element == null) {
  904. element = this.element;
  905. }
  906. if (element.nodeType !== 1) {
  907. return;
  908. }
  909. element = element.parentNode || element;
  910. _ref = element.querySelectorAll("." + this.config.boxClass);
  911. _results = [];
  912. for (_i = 0, _len = _ref.length; _i < _len; _i++) {
  913. box = _ref[_i];
  914. if (__indexOf.call(this.all, box) < 0) {
  915. this.boxes.push(box);
  916. this.all.push(box);
  917. if (this.stopped || this.disabled()) {
  918. this.resetStyle();
  919. } else {
  920. this.applyStyle(box, true);
  921. }
  922. _results.push(this.scrolled = true);
  923. } else {
  924. _results.push(void 0);
  925. }
  926. }
  927. return _results;
  928. };
  929. WOW.prototype.show = function(box) {
  930. this.applyStyle(box);
  931. return box.className = "" + box.className + " " + this.config.animateClass;
  932. };
  933. WOW.prototype.applyStyle = function(box, hidden) {
  934. var delay, duration, iteration;
  935. duration = box.getAttribute('data-wow-duration');
  936. delay = box.getAttribute('data-wow-delay');
  937. iteration = box.getAttribute('data-wow-iteration');
  938. return this.animate((function(_this) {
  939. return function() {
  940. return _this.customStyle(box, hidden, duration, delay, iteration);
  941. };
  942. })(this));
  943. };
  944. WOW.prototype.animate = (function() {
  945. if ('requestAnimationFrame' in window) {
  946. return function(callback) {
  947. return window.requestAnimationFrame(callback);
  948. };
  949. } else {
  950. return function(callback) {
  951. return callback();
  952. };
  953. }
  954. })();
  955. WOW.prototype.resetStyle = function() {
  956. var box, _i, _len, _ref, _results;
  957. _ref = this.boxes;
  958. _results = [];
  959. for (_i = 0, _len = _ref.length; _i < _len; _i++) {
  960. box = _ref[_i];
  961. _results.push(box.style.visibility = 'visible');
  962. }
  963. return _results;
  964. };
  965. WOW.prototype.customStyle = function(box, hidden, duration, delay, iteration) {
  966. if (hidden) {
  967. this.cacheAnimationName(box);
  968. }
  969. box.style.visibility = hidden ? 'hidden' : 'visible';
  970. if (duration) {
  971. this.vendorSet(box.style, {
  972. animationDuration: duration
  973. });
  974. }
  975. if (delay) {
  976. this.vendorSet(box.style, {
  977. animationDelay: delay
  978. });
  979. }
  980. if (iteration) {
  981. this.vendorSet(box.style, {
  982. animationIterationCount: iteration
  983. });
  984. }
  985. this.vendorSet(box.style, {
  986. animationName: hidden ? 'none' : this.cachedAnimationName(box)
  987. });
  988. return box;
  989. };
  990. WOW.prototype.vendors = ["moz", "webkit"];
  991. WOW.prototype.vendorSet = function(elem, properties) {
  992. var name, value, vendor, _results;
  993. _results = [];
  994. for (name in properties) {
  995. value = properties[name];
  996. elem["" + name] = value;
  997. _results.push((function() {
  998. var _i, _len, _ref, _results1;
  999. _ref = this.vendors;
  1000. _results1 = [];
  1001. for (_i = 0, _len = _ref.length; _i < _len; _i++) {
  1002. vendor = _ref[_i];
  1003. _results1.push(elem["" + vendor + (name.charAt(0).toUpperCase()) + (name.substr(1))] = value);
  1004. }
  1005. return _results1;
  1006. }).call(this));
  1007. }
  1008. return _results;
  1009. };
  1010. WOW.prototype.vendorCSS = function(elem, property) {
  1011. var result, style, vendor, _i, _len, _ref;
  1012. style = getComputedStyle(elem);
  1013. result = style.getPropertyCSSValue(property);
  1014. _ref = this.vendors;
  1015. for (_i = 0, _len = _ref.length; _i < _len; _i++) {
  1016. vendor = _ref[_i];
  1017. result = result || style.getPropertyCSSValue("-" + vendor + "-" + property);
  1018. }
  1019. return result;
  1020. };
  1021. WOW.prototype.animationName = function(box) {
  1022. var animationName;
  1023. try {
  1024. animationName = this.vendorCSS(box, 'animation-name').cssText;
  1025. } catch (_error) {
  1026. animationName = getComputedStyle(box).getPropertyValue('animation-name');
  1027. }
  1028. if (animationName === 'none') {
  1029. return '';
  1030. } else {
  1031. return animationName;
  1032. }
  1033. };
  1034. WOW.prototype.cacheAnimationName = function(box) {
  1035. return this.animationNameCache.set(box, this.animationName(box));
  1036. };
  1037. WOW.prototype.cachedAnimationName = function(box) {
  1038. return this.animationNameCache.get(box);
  1039. };
  1040. WOW.prototype.scrollHandler = function() {
  1041. return this.scrolled = true;
  1042. };
  1043. WOW.prototype.scrollCallback = function() {
  1044. var box;
  1045. if (this.scrolled) {
  1046. this.scrolled = false;
  1047. this.boxes = (function() {
  1048. var _i, _len, _ref, _results;
  1049. _ref = this.boxes;
  1050. _results = [];
  1051. for (_i = 0, _len = _ref.length; _i < _len; _i++) {
  1052. box = _ref[_i];
  1053. if (!(box)) {
  1054. continue;
  1055. }
  1056. if (this.isVisible(box)) {
  1057. this.show(box);
  1058. continue;
  1059. }
  1060. _results.push(box);
  1061. }
  1062. return _results;
  1063. }).call(this);
  1064. if (!(this.boxes.length || this.config.live)) {
  1065. return this.stop();
  1066. }
  1067. }
  1068. };
  1069. WOW.prototype.offsetTop = function(element) {
  1070. var top;
  1071. while (element.offsetTop === void 0) {
  1072. element = element.parentNode;
  1073. }
  1074. top = element.offsetTop;
  1075. while (element = element.offsetParent) {
  1076. top += element.offsetTop;
  1077. }
  1078. return top;
  1079. };
  1080. WOW.prototype.isVisible = function(box) {
  1081. var bottom, offset, top, viewBottom, viewTop;
  1082. offset = box.getAttribute('data-wow-offset') || this.config.offset;
  1083. viewTop = window.pageYOffset;
  1084. viewBottom = viewTop + Math.min(this.element.clientHeight, this.util().innerHeight()) - offset;
  1085. top = this.offsetTop(box);
  1086. bottom = top + box.clientHeight;
  1087. return top <= viewBottom && bottom >= viewTop;
  1088. };
  1089. WOW.prototype.util = function() {
  1090. return this._util != null ? this._util : this._util = new Util();
  1091. };
  1092. WOW.prototype.disabled = function() {
  1093. return !this.config.mobile && this.util().isMobile(navigator.userAgent);
  1094. };
  1095. return WOW;
  1096. })();
  1097. }).call(this);
  1098. // ------------- JQUERY SMOOTHSTATE ----------------------------------------- //
  1099. // ============ https://github.com/miguel-perez/jquery.smoothState.js ======= //
  1100. // -------------------------------------------------------------------------- //
  1101. ;(function ( $, window, document, undefined ) {
  1102. "use strict";
  1103. var
  1104. /** Used later to scroll page to the top */
  1105. $body = $("html, body"),
  1106. /** Used in development mode to console out useful warnings */
  1107. consl = (window.console || false),
  1108. /** Plugin default options */
  1109. defaults = {
  1110. /** jquery element string to specify which anchors smoothstate should bind to */
  1111. anchors : "a",
  1112. /** If set to true, smoothState will prefetch a link's contents on hover */
  1113. prefetch : false,
  1114. /** A selecor that deinfes with links should be ignored by smoothState */
  1115. blacklist : ".no-smoothstate, [target]",
  1116. /** If set to true, smoothState will log useful debug information instead of aborting */
  1117. development : false,
  1118. /** The number of pages smoothState will try to store in memory and not request again */
  1119. pageCacheSize : 0,
  1120. /** A function that can be used to alter urls before they are used to request content */
  1121. alterRequestUrl : function (url) {
  1122. return url;
  1123. },
  1124. /** Run when a link has been activated */
  1125. onStart : {
  1126. duration: 0,
  1127. render: function (url, $container) {
  1128. $body.scrollTop(0);
  1129. }
  1130. },
  1131. /** Run if the page request is still pending and onStart has finished animating */
  1132. onProgress : {
  1133. duration: 0,
  1134. render: function (url, $container) {
  1135. $body.css("cursor", "wait");
  1136. $body.find("a").css("cursor", "wait");
  1137. }
  1138. },
  1139. /** Run when requested content is ready to be injected into the page */
  1140. onEnd : {
  1141. duration: 0,
  1142. render: function (url, $container, $content) {
  1143. $body.css("cursor", "auto");
  1144. $body.find("a").css("cursor", "auto");
  1145. $container.html($content);
  1146. }
  1147. },
  1148. /** Run when content has been injected and all animations are complete */
  1149. callback : function(url, $container, $content) {
  1150. }
  1151. },
  1152. /** Utility functions that are decoupled from SmoothState */
  1153. utility = {
  1154. /**
  1155. * Checks to see if the url is external
  1156. * @param {string} url - url being evaluated
  1157. * @see http://stackoverflow.com/questions/6238351/fastest-way-to-detect-external-urls
  1158. *
  1159. */
  1160. isExternal: function (url) {
  1161. var match = url.match(/^([^:\/?#]+:)?(?:\/\/([^\/?#]*))?([^?#]+)?(\?[^#]*)?(#.*)?/);
  1162. if (typeof match[1] === "string" && match[1].length > 0 && match[1].toLowerCase() !== window.location.protocol) {
  1163. return true;
  1164. }
  1165. if (typeof match[2] === "string" && match[2].length > 0 && match[2].replace(new RegExp(":(" + {"http:": 80, "https:": 443}[window.location.protocol] + ")?$"), "") !== window.location.host) {
  1166. return true;
  1167. }
  1168. return false;
  1169. },
  1170. /**
  1171. * Checks to see if the url is an internal hash
  1172. * @param {string} url - url being evaluated
  1173. *
  1174. */
  1175. isHash: function (url) {
  1176. var hasPathname = (url.indexOf(window.location.pathname) > 0) ? true : false,
  1177. hasHash = (url.indexOf("#") > 0) ? true : false;
  1178. return (hasPathname && hasHash) ? true : false;
  1179. },
  1180. /**
  1181. * Checks to see if we should be loading this URL
  1182. * @param {string} url - url being evaluated
  1183. * @param {string} blacklist - jquery selector
  1184. *
  1185. */
  1186. shouldLoad: function ($anchor, blacklist) {
  1187. var url = $anchor.prop("href");
  1188. // URL will only be loaded if it"s not an external link, hash, or blacklisted
  1189. return (!utility.isExternal(url) && !utility.isHash(url) && !$anchor.is(blacklist));
  1190. },
  1191. /**
  1192. * Prevents jQuery from stripping elements from $(html)
  1193. * @param {string} url - url being evaluated
  1194. * @author Ben Alman http://benalman.com/
  1195. * @see https://gist.github.com/cowboy/742952
  1196. *
  1197. */
  1198. htmlDoc: function (html) {
  1199. var parent,
  1200. elems = $(),
  1201. matchTag = /<(\/?)(html|head|body|title|base|meta)(\s+[^>]*)?>/ig,
  1202. prefix = "ss" + Math.round(Math.random() * 100000),
  1203. htmlParsed = html.replace(matchTag, function(tag, slash, name, attrs) {
  1204. var obj = {};
  1205. if (!slash) {
  1206. elems = elems.add("<" + name + "/>");
  1207. if (attrs) {
  1208. $.each($("<div" + attrs + "/>")[0].attributes, function(i, attr) {
  1209. obj[attr.name] = attr.value;
  1210. });
  1211. }
  1212. elems.eq(-1).attr(obj);
  1213. }
  1214. return "<" + slash + "div" + (slash ? "" : " id='" + prefix + (elems.length - 1) + "'") + ">";
  1215. });
  1216. // If no placeholder elements were necessary, just return normal
  1217. // jQuery-parsed HTML.
  1218. if (!elems.length) {
  1219. return $(html);
  1220. }
  1221. // Create parent node if it hasn"t been created yet.
  1222. if (!parent) {
  1223. parent = $("<div/>");
  1224. }
  1225. // Create the parent node and append the parsed, place-held HTML.
  1226. parent.html(htmlParsed);
  1227. // Replace each placeholder element with its intended element.
  1228. $.each(elems, function(i) {
  1229. var elem = parent.find("#" + prefix + i).before(elems[i]);
  1230. elems.eq(i).html(elem.contents());
  1231. elem.remove();
  1232. });
  1233. return parent.children().unwrap();
  1234. },
  1235. /**
  1236. * Resets an object if it has too many properties
  1237. *
  1238. * This is used to clear the "cache" object that stores
  1239. * all of the html. This would prevent the client from
  1240. * running out of memory and allow the user to hit the
  1241. * server for a fresh copy of the content.
  1242. *
  1243. * @param {object} obj
  1244. * @param {number} cap
  1245. *
  1246. */
  1247. clearIfOverCapacity: function (obj, cap) {
  1248. // Polyfill Object.keys if it doesn"t exist
  1249. if (!Object.keys) {
  1250. Object.keys = function (obj) {
  1251. var keys = [],
  1252. k;
  1253. for (k in obj) {
  1254. if (Object.prototype.hasOwnProperty.call(obj, k)) {
  1255. keys.push(k);
  1256. }
  1257. }
  1258. return keys;
  1259. };
  1260. }
  1261. if (Object.keys(obj).length > cap) {
  1262. obj = {};
  1263. }
  1264. return obj;
  1265. },
  1266. /**
  1267. * Finds the inner content of an element, by an ID, from a jQuery object
  1268. * @param {string} id
  1269. * @param {object} $html
  1270. *
  1271. */
  1272. getContentById: function (id, $html) {
  1273. $html = ($html instanceof jQuery) ? $html : utility.htmlDoc($html);
  1274. var $insideElem = $html.find(id),
  1275. updatedContainer = ($insideElem.length) ? $.trim($insideElem.html()) : $html.filter(id).html(),
  1276. newContent = (updatedContainer.length) ? $(updatedContainer) : null;
  1277. return newContent;
  1278. },
  1279. /**
  1280. * Stores html content as jquery object in given object
  1281. * @param {object} object - object contents will be stored into
  1282. * @param {string} url - url to be used as the prop
  1283. * @param {jquery} html - contents to store
  1284. *
  1285. */
  1286. storePageIn: function (object, url, $html) {
  1287. $html = ($html instanceof jQuery) ? $html : utility.htmlDoc($html);
  1288. object[url] = { // Content is indexed by the url
  1289. status: "loaded",
  1290. title: $html.find("title").text(), // Stores the title of the page
  1291. html: $html // Stores the contents of the page
  1292. };
  1293. return object;
  1294. },
  1295. /**
  1296. * Triggers an "allanimationend" event when all animations are complete
  1297. * @param {object} $element - jQuery object that should trigger event
  1298. * @param {string} resetOn - which other events to trigger allanimationend on
  1299. *
  1300. */
  1301. triggerAllAnimationEndEvent: function ($element, resetOn) {
  1302. resetOn = " " + resetOn || "";
  1303. var animationCount = 0,
  1304. animationstart = "animationstart webkitAnimationStart oanimationstart MSAnimationStart",
  1305. animationend = "animationend webkitAnimationEnd oanimationend MSAnimationEnd",
  1306. eventname = "allanimationend",
  1307. onAnimationStart = function (e) {
  1308. if ($(e.delegateTarget).is($element)) {
  1309. e.stopPropagation();
  1310. animationCount ++;
  1311. }
  1312. },
  1313. onAnimationEnd = function (e) {
  1314. if ($(e.delegateTarget).is($element)) {
  1315. e.stopPropagation();
  1316. animationCount --;
  1317. if(animationCount === 0) {
  1318. $element.trigger(eventname);
  1319. }
  1320. }
  1321. };
  1322. $element.on(animationstart, onAnimationStart);
  1323. $element.on(animationend, onAnimationEnd);
  1324. $element.on("allanimationend" + resetOn, function(){
  1325. animationCount = 0;
  1326. utility.redraw($element);
  1327. });
  1328. },
  1329. /** Forces browser to redraw elements */
  1330. redraw: function ($element) {
  1331. $element.height(0);
  1332. setTimeout(function(){$element.height("auto");}, 0);
  1333. }
  1334. },
  1335. /** Handles the popstate event, like when the user hits "back" */
  1336. onPopState = function ( e ) {
  1337. if(e.state !== null) {
  1338. var url = window.location.href,
  1339. $page = $("#" + e.state.id),
  1340. page = $page.data("smoothState");
  1341. if(page.href !== url && !utility.isHash(url)) {
  1342. page.load(url, true);
  1343. }
  1344. }
  1345. },
  1346. /** Constructor function */
  1347. SmoothState = function ( element, options ) {
  1348. var
  1349. /** Container element smoothState is run on */
  1350. $container = $(element),
  1351. /** Variable that stores pages after they are requested */
  1352. cache = {},
  1353. /** Url of the content that is currently displayed */
  1354. currentHref = window.location.href,
  1355. /**
  1356. * Loads the contents of a url into our container
  1357. *
  1358. * @param {string} url
  1359. * @param {bool} isPopped - used to determine if whe should
  1360. * add a new item into the history object
  1361. *
  1362. */
  1363. load = function (url, isPopped) {
  1364. /** Makes this an optional variable by setting a default */
  1365. isPopped = isPopped || false;
  1366. var
  1367. /** Used to check if the onProgress function has been run */
  1368. hasRunCallback = false,
  1369. callbBackEnded = false,
  1370. /** List of responses for the states of the page request */
  1371. responses = {
  1372. /** Page is ready, update the content */
  1373. loaded: function() {
  1374. var eventName = hasRunCallback ? "ss.onProgressEnd" : "ss.onStartEnd";
  1375. if(!callbBackEnded || !hasRunCallback) {
  1376. $container.one(eventName, function(){
  1377. updateContent(url);
  1378. });
  1379. } else if(callbBackEnded) {
  1380. updateContent(url);
  1381. }
  1382. if(!isPopped) {
  1383. window.history.pushState({ id: $container.prop("id") }, cache[url].title, url);
  1384. }
  1385. },
  1386. /** Loading, wait 10 ms and check again */
  1387. fetching: function() {
  1388. if(!hasRunCallback) {
  1389. hasRunCallback = true;
  1390. // Run the onProgress callback and set trigger
  1391. $container.one("ss.onStartEnd", function(){
  1392. options.onProgress.render(url, $container, null);
  1393. setTimeout(function(){
  1394. $container.trigger("ss.onProgressEnd");
  1395. callbBackEnded = true;
  1396. }, options.onStart.duration);
  1397. });
  1398. }
  1399. setTimeout(function () {
  1400. // Might of been canceled, better check!
  1401. if(cache.hasOwnProperty(url)){
  1402. responses[cache[url].status]();
  1403. }
  1404. }, 10);
  1405. },
  1406. /** Error, abort and redirect */
  1407. error: function(){
  1408. window.location = url;
  1409. }
  1410. };
  1411. if (!cache.hasOwnProperty(url)) {
  1412. fetch(url);
  1413. }
  1414. // Run the onStart callback and set trigger
  1415. options.onStart.render(url, $container, null);
  1416. setTimeout(function(){
  1417. $container.trigger("ss.onStartEnd");
  1418. }, options.onStart.duration);
  1419. // Start checking for the status of content
  1420. responses[cache[url].status]();
  1421. },
  1422. /** Updates the contents from cache[url] */
  1423. updateContent = function (url) {
  1424. // If the content has been requested and is done:
  1425. var containerId = "#" + $container.prop("id"),
  1426. $content = cache[url] ? utility.getContentById(containerId, cache[url].html) : null;
  1427. if($content) {
  1428. document.title = cache[url].title;
  1429. $container.data("smoothState").href = url;
  1430. // Call the onEnd callback and set trigger
  1431. options.onEnd.render(url, $container, $content);
  1432. $container.one("ss.onEndEnd", function(){
  1433. options.callback(url, $container, $content);
  1434. });
  1435. setTimeout(function(){
  1436. $container.trigger("ss.onEndEnd");
  1437. }, options.onEnd.duration);
  1438. } else if (!$content && options.development && consl) {
  1439. // Throw warning to help debug in development mode
  1440. consl.warn("No element with an id of " + containerId + " in response from " + url + " in " + cache);
  1441. } else {
  1442. // No content availble to update with, aborting...
  1443. window.location = url;
  1444. }
  1445. },
  1446. /**
  1447. * Fetches the contents of a url and stores it in the "cache" varible
  1448. * @param {string} url
  1449. *
  1450. */
  1451. fetch = function (url) {
  1452. // Don"t fetch we have the content already
  1453. if(cache.hasOwnProperty(url)) {
  1454. return;
  1455. }
  1456. cache = utility.clearIfOverCapacity(cache, options.pageCacheSize);
  1457. cache[url] = { status: "fetching" };
  1458. var requestUrl = options.alterRequestUrl(url) || url,
  1459. request = $.ajax(requestUrl);
  1460. // Store contents in cache variable if successful
  1461. request.success(function (html) {
  1462. // Clear cache varible if it"s getting too big
  1463. utility.storePageIn(cache, url, html);
  1464. $container.data("smoothState").cache = cache;
  1465. });
  1466. // Mark as error
  1467. request.error(function () {
  1468. cache[url].status = "error";
  1469. });
  1470. },
  1471. /**
  1472. * Binds to the hover event of a link, used for prefetching content
  1473. *
  1474. * @param {object} event
  1475. *
  1476. */
  1477. hoverAnchor = function (event) {
  1478. var $anchor = $(event.currentTarget),
  1479. url = $anchor.prop("href");
  1480. if (utility.shouldLoad($anchor, options.blacklist)) {
  1481. event.stopPropagation();
  1482. fetch(url);
  1483. }
  1484. },
  1485. /**
  1486. * Binds to the click event of a link, used to show the content
  1487. *
  1488. * @param {object} event
  1489. *
  1490. */
  1491. clickAnchor = function (event) {
  1492. var $anchor = $(event.currentTarget),
  1493. url = $anchor.prop("href");
  1494. // Ctrl (or Cmd) + click must open a new tab
  1495. if (!event.metaKey && !event.ctrlKey && utility.shouldLoad($anchor, options.blacklist)) {
  1496. // stopPropagation so that event doesn"t fire on parent containers.
  1497. event.stopPropagation();
  1498. event.preventDefault();
  1499. load(url);
  1500. }
  1501. },
  1502. /**
  1503. * Binds all events and inits functionality
  1504. *
  1505. * @param {object} event
  1506. *
  1507. */
  1508. bindEventHandlers = function ($element) {
  1509. //@todo: Handle form submissions
  1510. $element.on("click", options.anchors, clickAnchor);
  1511. if (options.prefetch) {
  1512. $element.on("mouseover touchstart", options.anchors, hoverAnchor);
  1513. }
  1514. },
  1515. /** Used to restart css animations with a class */
  1516. toggleAnimationClass = function (classname) {
  1517. var classes = $container.addClass(classname).prop("class");
  1518. $container.removeClass(classes);
  1519. setTimeout(function(){
  1520. $container.addClass(classes);
  1521. },0);
  1522. $container.one("ss.onStartEnd ss.onProgressEnd ss.onEndEnd", function(){
  1523. $container.removeClass(classname);
  1524. });
  1525. };
  1526. /** Override defaults with options passed in */
  1527. options = $.extend(defaults, options);
  1528. /** Sets a default state */
  1529. if(window.history.state === null) {
  1530. window.history.replaceState({ id: $container.prop("id") }, document.title, currentHref);
  1531. }
  1532. /** Stores the current page in cache variable */
  1533. utility.storePageIn(cache, currentHref, document.documentElement.outerHTML);
  1534. /** Bind all of the event handlers on the container, not anchors */
  1535. utility.triggerAllAnimationEndEvent($container, "ss.onStartEnd ss.onProgressEnd ss.onEndEnd");
  1536. /** Bind all of the event handlers on the container, not anchors */
  1537. bindEventHandlers($container);
  1538. /** Public methods */
  1539. return {
  1540. href: currentHref,
  1541. cache: cache,
  1542. load: load,
  1543. fetch: fetch,
  1544. toggleAnimationClass: toggleAnimationClass
  1545. };
  1546. },
  1547. /** Returns elements with SmoothState attached to it */
  1548. declareSmoothState = function ( options ) {
  1549. return this.each(function () {
  1550. // Checks to make sure the smoothState element has an id and isn"t already bound
  1551. if(this.id && !$.data(this, "smoothState")) {
  1552. // Makes public methods available via $("element").data("smoothState");
  1553. $.data(this, "smoothState", new SmoothState(this, options));
  1554. } else if (!this.id && consl) {
  1555. // Throw warning if in development mode
  1556. consl.warn("Every smoothState container needs an id but the following one does not have one:", this);
  1557. }
  1558. });
  1559. };
  1560. /** Sets the popstate function */
  1561. window.onpopstate = onPopState;
  1562. /** Makes utility functions public for unit tests */
  1563. $.smoothStateUtility = utility;
  1564. /** Defines the smoothState plugin */
  1565. $.fn.smoothState = declareSmoothState;
  1566. })(jQuery, window, document);
  1567. // ------------- jQuery Cookie Plugin v1.4.1 -------------------------------- //
  1568. // ============ https://github.com/carhartl/jquery-cookie =================== //
  1569. // -------------------------------------------------------------------------- //
  1570. (function (factory) {
  1571. if (typeof define === 'function' && define.amd) {
  1572. // AMD
  1573. define(['jquery'], factory);
  1574. } else if (typeof exports === 'object') {
  1575. // CommonJS
  1576. factory(require('jquery'));
  1577. } else {
  1578. // Browser globals
  1579. factory(jQuery);
  1580. }
  1581. }(function ($) {
  1582. var pluses = /\+/g;
  1583. function encode(s) {
  1584. return config.raw ? s : encodeURIComponent(s);
  1585. }
  1586. function decode(s) {
  1587. return config.raw ? s : decodeURIComponent(s);
  1588. }
  1589. function stringifyCookieValue(value) {
  1590. return encode(config.json ? JSON.stringify(value) : String(value));
  1591. }
  1592. function parseCookieValue(s) {
  1593. if (s.indexOf('"') === 0) {
  1594. // This is a quoted cookie as according to RFC2068, unescape...
  1595. s = s.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\');
  1596. }
  1597. try {
  1598. // Replace server-side written pluses with spaces.
  1599. // If we can't decode the cookie, ignore it, it's unusable.
  1600. // If we can't parse the cookie, ignore it, it's unusable.
  1601. s = decodeURIComponent(s.replace(pluses, ' '));
  1602. return config.json ? JSON.parse(s) : s;
  1603. } catch(e) {}
  1604. }
  1605. function read(s, converter) {
  1606. var value = config.raw ? s : parseCookieValue(s);
  1607. return $.isFunction(converter) ? converter(value) : value;
  1608. }
  1609. var config = $.cookie = function (key, value, options) {
  1610. // Write
  1611. if (arguments.length > 1 && !$.isFunction(value)) {
  1612. options = $.extend({}, config.defaults, options);
  1613. if (typeof options.expires === 'number') {
  1614. var days = options.expires, t = options.expires = new Date();
  1615. t.setTime(+t + days * 864e+5);
  1616. }
  1617. return (document.cookie = [
  1618. encode(key), '=', stringifyCookieValue(value),
  1619. options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
  1620. options.path ? '; path=' + options.path : '',
  1621. options.domain ? '; domain=' + options.domain : '',
  1622. options.secure ? '; secure' : ''
  1623. ].join(''));
  1624. }
  1625. // Read
  1626. var result = key ? undefined : {};
  1627. // To prevent the for loop in the first place assign an empty array
  1628. // in case there are no cookies at all. Also prevents odd result when
  1629. // calling $.cookie().
  1630. var cookies = document.cookie ? document.cookie.split('; ') : [];
  1631. for (var i = 0, l = cookies.length; i < l; i++) {
  1632. var parts = cookies[i].split('=');
  1633. var name = decode(parts.shift());
  1634. var cookie = parts.join('=');
  1635. if (key && key === name) {
  1636. // If second argument (value) is a function it's a converter...
  1637. result = read(cookie, value);
  1638. break;
  1639. }
  1640. // Prevent storing a cookie that we couldn't decode.
  1641. if (!key && (cookie = read(cookie)) !== undefined) {
  1642. result[name] = cookie;
  1643. }
  1644. }
  1645. return result;
  1646. };
  1647. config.defaults = {};
  1648. $.removeCookie = function (key, options) {
  1649. if ($.cookie(key) === undefined) {
  1650. return false;
  1651. }
  1652. // Must not alter options, thus extending a fresh object...
  1653. $.cookie(key, '', $.extend({}, options, { expires: -1 }));
  1654. return !$.cookie(key);
  1655. };
  1656. }));