PageSourceSearch

https://gumballcandymachine.com/js/40c14f6b855be7928fa0b768e92ef58e.js

js gumballcandymachine.com collected 2026-10-07 12:52:37 UTC 48,048 bytes, 1,512 lines download raw bytes

1/*!
2* jQuery cycletwo; build: v20131005
3* http://jquery.malsup.com/cycletwo/
4* Copyright (c) 2013 M. Alsup; Dual licensed: MIT/GPL
5*/
6
7/*! core engine; version: 20131003 */
8;(function($) {
9"use strict";
10
11var version = '20131003';
12
13$.fn.cycletwo = function( options ) 
14{
15    // fix mistakes with the ready state
16    var o;
17    if ( this.length === 0 && !$.isReady ) {
18        o = { s: this.selector, c: this.context };
19        $.fn.cycletwo.log('requeuing slideshow (dom not ready)');
20        $(function() {
21            $( o.s, o.c ).cycletwo(options);
22        });
23        return this;
24    }
25
26    return this.each(function() {
27        var data, opts, shortName, val;
28        var container = $(this);
29        var log = $.fn.cycletwo.log;
30
31        if ( container.data('cycletwo.opts') )
32            return; // already initialized
33
34        if ( container.data('cycletwo-log') === false || 
35            ( options && options.log === false ) ||
36            ( opts && opts.log === false) ) {
37            log = $.noop;
38        }
39
40        log('--c2 init--');
41        data = container.data();
42        for (var p in data) {
43            // allow props to be accessed sans 'cycletwo' prefix and log the overrides
44            if (data.hasOwnProperty(p) && /^cycletwo[A-Z]+/.test(p) ) {
45                val = data[p];
46                shortName = p.match(/^cycletwo(.*)/)[1].replace(/^[A-Z]/, lowerCase);
47                log(shortName+':', val, '('+typeof val +')');
48                data[shortName] = val;
49            }
50        }
51
52        opts = $.extend( {}, $.fn.cycletwo.defaults, data, options || {});
53
54        opts.timeoutId = 0;
55        opts.paused = opts.paused || false; // #57
56        opts.container = container;
57        opts._maxZ = opts.maxZ;
58
59        opts.API = $.extend ( { _container: container }, $.fn.cycletwo.API );
60        opts.API.log = log;
61        opts.API.trigger = function( eventName, args ) {
62            opts.container.trigger( eventName, args );
63            return opts.API;
64        };
65
66        container.data( 'cycletwo.opts', opts );
67        container.data( 'cycletwo.API', opts.API );
68
69        // opportunity for plugins to modify opts and API
70        opts.API.trigger('cycletwo-bootstrap', [ opts, opts.API ]);
71
72        opts.API.addInitialSlides();
73        opts.API.preInitSlideshow();
74
75        if ( opts.slides.length )
76            opts.API.initSlideshow();
77    });
78};
79
80$.fn.cycletwo.API = {
81    opts: function() {
82        return this._container.data( 'cycletwo.opts' );
83    },
84    addInitialSlides: function() {
85        var opts = this.opts();
86        var slides = opts.slides;
87        opts.slideCount = 0;
88        opts.slides = $(); // empty set
89        
90        // add slides that already exist
91        slides = slides.jquery ? slides : opts.container.find( slides );
92
93        if ( opts.random ) {
94            slides.sort(function() {return Math.random() - 0.5;});
95        }
96
97        opts.API.add( slides );
98    },
99
100    preInitSlideshow: function() {
101        var opts = this.opts();
102        opts.API.trigger('cycletwo-pre-initialize', [ opts ]);
103        var tx = $.fn.cycletwo.transitions[opts.fx];
104        if (tx && $.isFunction(tx.preInit))
105            tx.preInit( opts );
106        opts._preInitialized = true;
107    },
108
109    postInitSlideshow: function() {
110        var opts = this.opts();
111        opts.API.trigger('cycletwo-post-initialize', [ opts ]);
112        var tx = $.fn.cycletwo.transitions[opts.fx];
113        if (tx && $.isFunction(tx.postInit))
114            tx.postInit( opts );
115    },
116
117    initSlideshow: function() {
118        var opts = this.opts();
119        var pauseObj = opts.container;
120        var slideOpts;
121        opts.API.calcFirstSlide();
122
123        if ( opts.container.css('position') == 'static' )
124            opts.container.css('position', 'relative');
125
126        $(opts.slides[opts.currSlide]).css('opacity',1).show();
127        opts.API.stackSlides( opts.slides[opts.currSlide], opts.slides[opts.nextSlide], !opts.reverse );
128
129        if ( opts.pauseOnHover ) {
130            // allow pauseOnHover to specify an element
131            if ( opts.pauseOnHover !== true )
132                pauseObj = $( opts.pauseOnHover );
133
134            pauseObj.hover(
135                function(){ opts.API.pause( true ); }, 
136                function(){ opts.API.resume( true ); }
137            );
138        }
139
140        // stage initial transition
141        if ( opts.timeout ) {
142            slideOpts = opts.API.getSlideOpts( opts.currSlide );
143            opts.API.queueTransition( slideOpts, slideOpts.timeout + opts.delay );
144        }
145
146        opts._initialized = true;
147        opts.API.updateView( true );
148        opts.API.trigger('cycletwo-initialized', [ opts ]);
149        opts.API.postInitSlideshow();
150    },
151
152    pause: function( hover ) {
153        var opts = this.opts(),
154            slideOpts = opts.API.getSlideOpts(),
155            alreadyPaused = opts.hoverPaused || opts.paused;
156
157        if ( hover )
158            opts.hoverPaused = true; 
159        else
160            opts.paused = true;
161
162        if ( ! alreadyPaused ) {
163            opts.container.addClass('cycletwo-paused');
164            opts.API.trigger('cycletwo-paused', [ opts ]).log('cycletwo-paused');
165
166            if ( slideOpts.timeout ) {
167                clearTimeout( opts.timeoutId );
168                opts.timeoutId = 0;
169                
170                // determine how much time is left for the current slide
171                opts._remainingTimeout -= ( $.now() - opts._lastQueue );
172                if ( opts._remainingTimeout < 0 || isNaN(opts._remainingTimeout) )
173                    opts._remainingTimeout = undefined;
174            }
175        }
176    },
177
178    resume: function( hover ) {
179        var opts = this.opts(),
180            alreadyResumed = !opts.hoverPaused && !opts.paused,
181            remaining;
182
183        if ( hover )
184            opts.hoverPaused = false; 
185        else
186            opts.paused = false;
187
188    
189        if ( ! alreadyResumed ) {
190            opts.container.removeClass('cycletwo-paused');
191            // #gh-230; if an animation is in progress then don't queue a new transition; it will
192            // happen naturally
193            if ( opts.slides.filter(':animated').length === 0 )
194                opts.API.queueTransition( opts.API.getSlideOpts(), opts._remainingTimeout );
195            opts.API.trigger('cycletwo-resumed', [ opts, opts._remainingTimeout ] ).log('cycletwo-resumed');
196        }
197    },
198
199    add: function( slides, prepend ) {
200        var opts = this.opts();
201        var oldSlideCount = opts.slideCount;
202        var startSlideshow = false;
203        var len;
204
205        if ( $.type(slides) == 'string')
206            slides = $.trim( slides );
207
208        $( slides ).each(function(i) {
209            var slideOpts;
210            var slide = $(this);
211
212            if ( prepend )
213                opts.container.prepend( slide );
214            else
215                opts.container.append( slide );
216
217            opts.slideCount++;
218            slideOpts = opts.API.buildSlideOpts( slide );
219
220            if ( prepend )
221                opts.slides = $( slide ).add( opts.slides );
222            else
223                opts.slides = opts.slides.add( slide );
224
225            opts.API.initSlide( slideOpts, slide, --opts._maxZ );
226
227            slide.data('cycletwo.opts', slideOpts);
228            opts.API.trigger('cycletwo-slide-added', [ opts, slideOpts, slide ]);
229        });
230
231        opts.API.updateView( true );
232
233        startSlideshow = opts._preInitialized && (oldSlideCount < 2 && opts.slideCount >= 1);
234        if ( startSlideshow ) {
235            if ( !opts._initialized )
236                opts.API.initSlideshow();
237            else if ( opts.timeout ) {
238                len = opts.slides.length;
239                opts.nextSlide = opts.reverse ? len - 1 : 1;
240                if ( !opts.timeoutId ) {
241                    opts.API.queueTransition( opts );
242                }
243            }
244        }
245    },
246
247    calcFirstSlide: function() {
248        var opts = this.opts();
249        var firstSlideIndex;
250        firstSlideIndex = parseInt( opts.startingSlide || 0, 10 );
251        if (firstSlideIndex >= opts.slides.length || firstSlideIndex < 0)
252            firstSlideIndex = 0;
253
254        opts.currSlide = firstSlideIndex;
255        if ( opts.reverse ) {
256            opts.nextSlide = firstSlideIndex - 1;
257            if (opts.nextSlide < 0)
258                opts.nextSlide = opts.slides.length - 1;
259        }
260        else {
261            opts.nextSlide = firstSlideIndex + 1;
262            if (opts.nextSlide == opts.slides.length)
263                opts.nextSlide = 0;
264        }
265    },
266
267    calcNextSlide: function() {
268        var opts = this.opts();
269        var roll;
270        if ( opts.reverse ) {
271            roll = (opts.nextSlide - 1) < 0;
272            opts.nextSlide = roll ? opts.slideCount - 1 : opts.nextSlide-1;
273            opts.currSlide = roll ? 0 : opts.nextSlide+1;
274        }
275        else {
276            roll = (opts.nextSlide + 1) == opts.slides.length;
277            opts.nextSlide = roll ? 0 : opts.nextSlide+1;
278            opts.currSlide = roll ? opts.slides.length-1 : opts.nextSlide-1;
279        }
280    },
281
282    calcTx: function( slideOpts, manual ) {
283        var opts = slideOpts;
284        var tx;
285        if ( manual && opts.manualFx )
286            tx = $.fn.cycletwo.transitions[opts.manualFx];
287        if ( !tx )
288            tx = $.fn.cycletwo.transitions[opts.fx];
289
290        if (!tx) {
291            tx = $.fn.cycletwo.transitions.fade;
292            opts.API.log('Transition "' + opts.fx + '" not found.  Using fade.');
293        }
294        return tx;
295    },
296
297    prepareTx: function( manual, fwd ) {
298        var opts = this.opts();
299        var after, curr, next, slideOpts, tx;
300
301        if ( opts.slideCount < 2 ) {
302            opts.timeoutId = 0;
303            return;
304        }
305        if ( manual && ( !opts.busy || opts.manualTrump ) ) {
306            opts.API.stopTransition();
307            opts.busy = false;
308            clearTimeout(opts.timeoutId);
309            opts.timeoutId = 0;
310        }
311        if ( opts.busy )
312            return;
313        if ( opts.timeoutId === 0 && !manual )
314            return;
315
316        curr = opts.slides[opts.currSlide];
317        next = opts.slides[opts.nextSlide];
318        slideOpts = opts.API.getSlideOpts( opts.nextSlide );
319        tx = opts.API.calcTx( slideOpts, manual );
320
321        opts._tx = tx;
322
323        if ( manual && slideOpts.manualSpeed !== undefined )
324            slideOpts.speed = slideOpts.manualSpeed;
325
326        // if ( opts.nextSlide === opts.currSlide )
327        //     opts.API.calcNextSlide();
328
329        // ensure that:
330        //      1. advancing to a different slide
331        //      2. this is either a manual event (prev/next, pager, cmd) or 
332        //              a timer event and slideshow is not paused
333        if ( opts.nextSlide != opts.currSlide && 
334            (manual || (!opts.paused && !opts.hoverPaused && opts.timeout) )) { // #62
335
336            opts.API.trigger('cycletwo-before', [ slideOpts, curr, next, fwd ]);
337            if ( tx.before )
338                tx.before( slideOpts, curr, next, fwd );
339
340            after = function() {
341                opts.busy = false;
342                // #76; bail if slideshow has been destroyed
343                if (! opts.container.data( 'cycletwo.opts' ) )
344                    return;
345
346                if (tx.after)
347                    tx.after( slideOpts, curr, next, fwd );
348                opts.API.trigger('cycletwo-after', [ slideOpts, curr, next, fwd ]);
349                opts.API.queueTransition( slideOpts);
350                opts.API.updateView( true );
351            };
352
353            opts.busy = true;
354            if (tx.transition)
355                tx.transition(slideOpts, curr, next, fwd, after);
356            else
357                opts.API.doTransition( slideOpts, curr, next, fwd, after);
358
359            opts.API.calcNextSlide();
360            opts.API.updateView();
361        } else {
362            opts.API.queueTransition( slideOpts );
363        }
364    },
365
366    // perform the actual animation
367    doTransition: function( slideOpts, currEl, nextEl, fwd, callback) {
368        var opts = slideOpts;
369        var curr = $(currEl), next = $(nextEl);
370        var fn = function() {
371            // make sure animIn has something so that callback doesn't trigger immediately
372            next.animate(opts.animIn || { opacity: 1}, opts.speed, opts.easeIn || opts.easing, callback);
373        };
374
375        next.css(opts.cssBefore || {});
376        curr.animate(opts.animOut || {}, opts.speed, opts.easeOut || opts.easing, function() {
377            curr.css(opts.cssAfter || {});
378            if (!opts.sync) {
379                fn();
380            }
381        });
382        if (opts.sync) {
383            fn();
384        }
385    },
386
387    queueTransition: function( slideOpts, specificTimeout ) {
388        var opts = this.opts();
389        var timeout = specificTimeout !== undefined ? specificTimeout : slideOpts.timeout;
390        if (opts.nextSlide === 0 && --opts.loop === 0) {
391            opts.API.log('terminating; loop=0');
392            opts.timeout = 0;
393            if ( timeout ) {
394                setTimeout(function() {
395                    opts.API.trigger('cycletwo-finished', [ opts ]);
396                }, timeout);
397            }
398            else {
399                opts.API.trigger('cycletwo-finished', [ opts ]);
400            }
401            // reset nextSlide
402            opts.nextSlide = opts.currSlide;
403            return;
404        }
405        if ( timeout ) {
406            opts._lastQueue = $.now();
407            if ( specificTimeout === undefined )
408                opts._remainingTimeout = slideOpts.timeout;
409
410            if ( !opts.paused && ! opts.hoverPaused ) {
411                opts.timeoutId = setTimeout(function() { 
412                    opts.API.prepareTx( false, !opts.reverse ); 
413                }, timeout );
414            }
415        }
416    },
417
418    stopTransition: function() {
419        var opts = this.opts();
420        if ( opts.slides.filter(':animated').length ) {
421            opts.slides.stop(false, true);
422            opts.API.trigger('cycletwo-transition-stopped', [ opts ]);
423        }
424
425        if ( opts._tx && opts._tx.stopTransition )
426            opts._tx.stopTransition( opts );
427    },
428
429    // advance slide forward or back
430    advanceSlide: function( val ) {
431        var opts = this.opts();
432        clearTimeout(opts.timeoutId);
433        opts.timeoutId = 0;
434        opts.nextSlide = opts.currSlide + val;
435        
436        if (opts.nextSlide < 0)
437            opts.nextSlide = opts.slides.length - 1;
438        else if (opts.nextSlide >= opts.slides.length)
439            opts.nextSlide = 0;
440
441        opts.API.prepareTx( true,  val >= 0 );
442        return false;
443    },
444
445    buildSlideOpts: function( slide ) {
446        var opts = this.opts();
447        var val, shortName;
448        var slideOpts = slide.data() || {};
449        for (var p in slideOpts) {
450            // allow props to be accessed sans 'cycletwo' prefix and log the overrides
451            if (slideOpts.hasOwnProperty(p) && /^cycletwo[A-Z]+/.test(p) ) {
452                val = slideOpts[p];
453                shortName = p.match(/^cycletwo(.*)/)[1].replace(/^[A-Z]/, lowerCase);
454                opts.API.log('['+(opts.slideCount-1)+']', shortName+':', val, '('+typeof val +')');
455                slideOpts[shortName] = val;
456            }
457        }
458
459        slideOpts = $.extend( {}, $.fn.cycletwo.defaults, opts, slideOpts );
460        slideOpts.slideNum = opts.slideCount;
461
462        try {
463            // these props should always be read from the master state object
464            delete slideOpts.API;
465            delete slideOpts.slideCount;
466            delete slideOpts.currSlide;
467            delete slideOpts.nextSlide;
468            delete slideOpts.slides;
469        } catch(e) {
470            // no op
471        }
472        return slideOpts;
473    },
474
475    getSlideOpts: function( index ) {
476        var opts = this.opts();
477        if ( index === undefined )
478            index = opts.currSlide;
479
480        var slide = opts.slides[index];
481        var slideOpts = $(slide).data('cycletwo.opts');
482        return $.extend( {}, opts, slideOpts );
483    },
484    
485    initSlide: function( slideOpts, slide, suggestedZindex ) {
486        var opts = this.opts();
487        slide.css( slideOpts.slideCss || {} );
488        if ( suggestedZindex > 0 )
489            slide.css( 'zIndex', suggestedZindex );
490
491        // ensure that speed settings are sane
492        if ( isNaN( slideOpts.speed ) )
493            slideOpts.speed = $.fx.speeds[slideOpts.speed] || $.fx.speeds._default;
494        if ( !slideOpts.sync )
495            slideOpts.speed = slideOpts.speed / 2;
496
497        slide.addClass( opts.slideClass );
498    },
499
500    updateView: function( isAfter, isDuring ) {
501        var opts = this.opts();
502        if ( !opts._initialized )
503            return;
504        var slideOpts = opts.API.getSlideOpts();
505        var currSlide = opts.slides[ opts.currSlide ];
506
507        if ( ! isAfter && isDuring !== true ) {
508            opts.API.trigger('cycletwo-update-view-before', [ opts, slideOpts, currSlide ]);
509            if ( opts.updateView < 0 )
510                return;
511        }
512
513        if ( opts.slideActiveClass ) {
514            opts.slides.removeClass( opts.slideActiveClass )
515                .eq( opts.currSlide ).addClass( opts.slideActiveClass );
516        }
517
518        if ( isAfter && opts.hideNonActive )
519            opts.slides.filter( ':not(.' + opts.slideActiveClass + ')' ).hide();
520
521        opts.API.trigger('cycletwo-update-view', [ opts, slideOpts, currSlide, isAfter ]);
522        
523        if ( isAfter )
524            opts.API.trigger('cycletwo-update-view-after', [ opts, slideOpts, currSlide ]);
525    },
526
527    getComponent: function( name ) {
528        var opts = this.opts();
529        var selector = opts[name];
530        if (typeof selector === 'string') {
531            // if selector is a child, sibling combinator, adjancent selector then use find, otherwise query full dom
532            return (/^\s*[\>|\+|~]/).test( selector ) ? opts.container.find( selector ) : $( selector );
533        }
534        if (selector.jquery)
535            return selector;
536        
537        return $(selector);
538    },
539
540    stackSlides: function( curr, next, fwd ) {
541        var opts = this.opts();
542        if ( !curr ) {
543            curr = opts.slides[opts.currSlide];
544            next = opts.slides[opts.nextSlide];
545            fwd = !opts.reverse;
546        }
547
548        // reset the zIndex for the common case:
549        // curr slide on top,  next slide beneath, and the rest in order to be shown
550        $(curr).css('zIndex', opts.maxZ);
551
552        var i;
553        var z = opts.maxZ - 2;
554        var len = opts.slideCount;
555        if (fwd) {
556            for ( i = opts.currSlide + 1; i < len; i++ )
557                $( opts.slides[i] ).css( 'zIndex', z-- );
558            for ( i = 0; i < opts.currSlide; i++ )
559                $( opts.slides[i] ).css( 'zIndex', z-- );
560        }
561        else {
562            for ( i = opts.currSlide - 1; i >= 0; i-- )
563                $( opts.slides[i] ).css( 'zIndex', z-- );
564            for ( i = len - 1; i > opts.currSlide; i-- )
565                $( opts.slides[i] ).css( 'zIndex', z-- );
566        }
567
568        $(next).css('zIndex', opts.maxZ - 1);
569    },
570
571    getSlideIndex: function( el ) {
572        return this.opts().slides.index( el );
573    }
574
575}; // API
576
577// default logger
578$.fn.cycletwo.log = function log() {
579    /*global console:true */
580    if (window.console && console.log)
581        console.log('[cycletwo] ' + Array.prototype.join.call(arguments, ' ') );
582};
583
584$.fn.cycletwo.version = function() { return 'cycletwo: ' + version; };
585
586// helper functions
587
588function lowerCase(s) {
589    return (s || '').toLowerCase();
590}
591
592// expose transition object
593$.fn.cycletwo.transitions = {
594    custom: {
595    },
596    none: {
597        before: function( opts, curr, next, fwd ) {
598            opts.API.stackSlides( next, curr, fwd );
599            opts.cssBefore = { opacity: 1, display: 'block' };
600        }
601    },
602    fade: {
603        before: function( opts, curr, next, fwd ) {
604            var css = opts.API.getSlideOpts( opts.nextSlide ).slideCss || {};
605            opts.API.stackSlides( curr, next, fwd );
606            opts.cssBefore = $.extend(css, { opacity: 0, display: 'block' });
607            opts.animIn = { opacity: 1 };
608            opts.animOut = { opacity: 0 };
609        }
610    },
611    fadeout: {
612        before: function( opts , curr, next, fwd ) {
613            var css = opts.API.getSlideOpts( opts.nextSlide ).slideCss || {};
614            opts.API.stackSlides( curr, next, fwd );
615            opts.cssBefore = $.extend(css, { opacity: 1, display: 'block' });
616            opts.animOut = { opacity: 0 };
617        }
618    },
619    scrollHorz: {
620        before: function( opts, curr, next, fwd ) {
621            opts.API.stackSlides( curr, next, fwd );
622            var w = opts.container.css('overflow','hidden').width();
623            opts.cssBefore = { left: fwd ? w : - w, top: 0, opacity: 1, display: 'block' };
624            opts.cssAfter = { zIndex: opts._maxZ - 2, left: 0 };
625            opts.animIn = { left: 0 };
626            opts.animOut = { left: fwd ? -w : w };
627        }
628    }
629};
630
631// @see: http://jquery.malsup.com/cycletwo/api
632$.fn.cycletwo.defaults = {
633    allowWrap:        true,
634    autoSelector:     '.cycletwo-slideshow[data-cycletwo-auto-init!=false]',
635    delay:            0,
636    easing:           null,
637    fx:              'fade',
638    hideNonActive:    true,
639    loop:             0,
640    manualFx:         undefined,
641    manualSpeed:      undefined,
642    manualTrump:      true,
643    maxZ:             100,
644    pauseOnHover:     false,
645    reverse:          false,
646    slideActiveClass: 'cycletwo-slide-active',
647    slideClass:       'cycletwo-slide',
648    slideCss:         { position: 'absolute', top: 0, left: 0 },
649    slides:          '> img',
650    speed:            500,
651    startingSlide:    0,
652    sync:             true,
653    timeout:          4000,
654    updateView:       -1
655};
656
657// automatically find and run slideshows
658$(document).ready(function() {
659    $( $.fn.cycletwo.defaults.autoSelector ).cycletwo();
660});
661
662})(jQuery);
663
664/*! cycletwo autoheight plugin; Copyright (c) M.Alsup, 2012; version: 20130304 */
665(function($) {
666"use strict";
667
668$.extend($.fn.cycletwo.defaults, {
669    autoHeight: 0 // setting this option to false disables autoHeight logic
670});    
671
672$(document).on( 'cycletwo-initialized', function( e, opts ) {
673    var autoHeight = opts.autoHeight;
674    var t = $.type( autoHeight );
675    var resizeThrottle = null;
676    var ratio;
677
678    if ( t !== 'string' && t !== 'number' )
679        return;
680
681    // bind events
682    opts.container.on( 'cycletwo-slide-added cycletwo-slide-removed', initAutoHeight );
683    opts.container.on( 'cycletwo-destroyed', onDestroy );
684
685    if ( autoHeight == 'container' ) {
686        opts.container.on( 'cycletwo-before', onBefore );
687    }
688    else if ( t === 'string' && /\d+\:\d+/.test( autoHeight ) ) { 
689        // use ratio
690        ratio = autoHeight.match(/(\d+)\:(\d+)/);
691        ratio = ratio[1] / ratio[2];
692        opts._autoHeightRatio = ratio;
693    }
694
695    // if autoHeight is a number then we don't need to recalculate the sentinel
696    // index on resize
697    if ( t !== 'number' ) {
698        // bind unique resize handler per slideshow (so it can be 'off-ed' in onDestroy)
699        opts._autoHeightOnResize = function () {
700            clearTimeout( resizeThrottle );
701            resizeThrottle = setTimeout( onResize, 50 );
702        };
703
704        $(window).on( 'resize orientationchange', opts._autoHeightOnResize );
705    }
706
707    setTimeout( onResize, 30 );
708
709    function onResize() {
710        initAutoHeight( e, opts );
711    }
712});
713
714function initAutoHeight( e, opts ) {
715    var clone, height, sentinelIndex;
716    var autoHeight = opts.autoHeight;
717
718    if ( autoHeight == 'container' ) {
719        height = $( opts.slides[ opts.currSlide ] ).outerHeight();
720        opts.container.height( height );
721    }
722    else if ( opts._autoHeightRatio ) { 
723        opts.container.height( opts.container.width() / opts._autoHeightRatio );
724    }
725    else if ( autoHeight === 'calc' || ( $.type( autoHeight ) == 'number' && autoHeight >= 0 ) ) {
726        if ( autoHeight === 'calc' )
727            sentinelIndex = calcSentinelIndex( e, opts );
728        else if ( autoHeight >= opts.slides.length )
729            sentinelIndex = 0;
730        else 
731            sentinelIndex = autoHeight;
732
733        // only recreate sentinel if index is different
734        if ( sentinelIndex == opts._sentinelIndex )
735            return;
736
737        opts._sentinelIndex = sentinelIndex;
738        if ( opts._sentinel )
739            opts._sentinel.remove();
740
741        // clone existing slide as sentinel
742        clone = $( opts.slides[ sentinelIndex ].cloneNode(true) );
743        
744        // #50; remove special attributes from cloned content
745        clone.removeAttr( 'id name rel' ).find( '[id],[name],[rel]' ).removeAttr( 'id name rel' );
746
747        clone.css({
748            position: 'static',
749            visibility: 'hidden',
750            display: 'block'
751        }).prependTo( opts.container ).addClass('cycletwo-sentinel cycletwo-slide').removeClass('cycletwo-slide-active');
752        clone.find( '*' ).css( 'visibility', 'hidden' );
753
754        opts._sentinel = clone;
755    }
756}    
757
758function calcSentinelIndex( e, opts ) {
759    var index = 0, max = -1;
760
761    // calculate tallest slide index
762    opts.slides.each(function(i) {
763        var h = $(this).height();
764        if ( h > max ) {
765            max = h;
766            index = i;
767        }
768    });
769    return index;
770}
771
772function onBefore( e, opts, outgoing, incoming, forward ) {
773    var h = $(incoming).outerHeight();
774    var duration = opts.sync ? opts.speed / 2 : opts.speed;
775    opts.container.animate( { height: h }, duration );
776}
777
778function onDestroy( e, opts ) {
779    if ( opts._autoHeightOnResize ) {
780        $(window).off( 'resize orientationchange', opts._autoHeightOnResize );
781        opts._autoHeightOnResize = null;
782    }
783    opts.container.off( 'cycletwo-slide-added cycletwo-slide-removed', initAutoHeight );
784    opts.container.off( 'cycletwo-destroyed', onDestroy );
785    opts.container.off( 'cycletwo-before', onBefore );
786
787    if ( opts._sentinel ) {
788        opts._sentinel.remove();
789        opts._sentinel = null;
790    }
791}
792
793})(jQuery);
794
795/*! caption plugin for cycletwo;  version: 20130306 */
796(function($) {
797"use strict";
798
799$.extend($.fn.cycletwo.defaults, {
800    caption:          '> .cycletwo-caption',
801    captionTemplate:  '{{slideNum}} / {{slideCount}}',
802    overlay:          '> .cycletwo-overlay',
803    overlayTemplate:  '<div>{{title}}</div><div>{{desc}}</div>',
804    captionModule:    'caption'
805});    
806
807$(document).on( 'cycletwo-update-view', function( e, opts, slideOpts, currSlide ) {
808    if ( opts.captionModule !== 'caption' )
809        return;
810    var el;
811    $.each(['caption','overlay'], function() {
812        var name = this; 
813        var template = slideOpts[name+'Template'];
814        var el = opts.API.getComponent( name );
815        if( el.length && template ) {
816            el.html( opts.API.tmpl( template, slideOpts, opts, currSlide ) );
817            el.show();
818        }
819        else {
820            el.hide();
821        }
822    });
823});
824
825$(document).on( 'cycletwo-destroyed', function( e, opts ) {
826    var el;
827    $.each(['caption','overlay'], function() {
828        var name = this, template = opts[name+'Template'];
829        if ( opts[name] && template ) {
830            el = opts.API.getComponent( 'caption' );
831            el.empty();
832        }
833    });
834});
835
836})(jQuery);
837
838/*! command plugin for cycletwo;  version: 20130707 */
839(function($) {
840"use strict";
841
842var c2 = $.fn.cycletwo;
843
844$.fn.cycletwo = function( options ) {
845    var cmd, cmdFn, opts;
846    var args = $.makeArray( arguments );
847
848    if ( $.type( options ) == 'number' ) {
849        return this.cycletwo( 'goto', options );
850    }
851
852    if ( $.type( options ) == 'string' ) {
853        return this.each(function() {
854            var cmdArgs;
855            cmd = options;
856            opts = $(this).data('cycletwo.opts');
857
858            if ( opts === undefined ) {
859                c2.log('slideshow must be initialized before sending commands; "' + cmd + '" ignored');
860                return;
861            }
862            else {
863                cmd = cmd == 'goto' ? 'jump' : cmd; // issue #3; change 'goto' to 'jump' internally
864                cmdFn = opts.API[ cmd ];
865                if ( $.isFunction( cmdFn )) {
866                    cmdArgs = $.makeArray( args );
867                    cmdArgs.shift();
868                    return cmdFn.apply( opts.API, cmdArgs );
869                }
870                else {
871                    c2.log( 'unknown command: ', cmd );
872                }
873            }
874        });
875    }
876    else {
877        return c2.apply( this, arguments );
878    }
879};
880
881// copy props
882$.extend( $.fn.cycletwo, c2 );
883
884$.extend( c2.API, {
885    next: function() {
886        var opts = this.opts();
887        if ( opts.busy && ! opts.manualTrump )
888            return;
889        
890        var count = opts.reverse ? -1 : 1;
891        if ( opts.allowWrap === false && ( opts.currSlide + count ) >= opts.slideCount )
892            return;
893
894        opts.API.advanceSlide( count );
895        opts.API.trigger('cycletwo-next', [ opts ]).log('cycletwo-next');
896    },
897
898    prev: function() {
899        var opts = this.opts();
900        if ( opts.busy && ! opts.manualTrump )
901            return;
902        var count = opts.reverse ? 1 : -1;
903        if ( opts.allowWrap === false && ( opts.currSlide + count ) < 0 )
904            return;
905
906        opts.API.advanceSlide( count );
907        opts.API.trigger('cycletwo-prev', [ opts ]).log('cycletwo-prev');
908    },
909
910    destroy: function() {
911        this.stop(); //#204
912
913        var opts = this.opts();
914        var clean = $.isFunction( $._data ) ? $._data : $.noop;  // hack for #184 and #201
915        clearTimeout(opts.timeoutId);
916        opts.timeoutId = 0;
917        opts.API.stop();
918        opts.API.trigger( 'cycletwo-destroyed', [ opts ] ).log('cycletwo-destroyed');
919        opts.container.removeData();
920        clean( opts.container[0], 'parsedAttrs', false );
921
922        // #75; remove inline styles
923        if ( ! opts.retainStylesOnDestroy ) {
924            opts.container.removeAttr( 'style' );
925            opts.slides.removeAttr( 'style' );
926            opts.slides.removeClass( opts.slideActiveClass );
927        }
928        opts.slides.each(function() {
929            $(this).removeData();
930            clean( this, 'parsedAttrs', false );
931        });
932    },
933
934    jump: function( index ) {
935        // go to the requested slide
936        var fwd;
937        var opts = this.opts();
938        if ( opts.busy && ! opts.manualTrump )
939            return;
940        var num = parseInt( index, 10 );
941        if (isNaN(num) || num < 0 || num >= opts.slides.length) {
942            opts.API.log('goto: invalid slide index: ' + num);
943            return;
944        }
945        if (num == opts.currSlide) {
946            opts.API.log('goto: skipping, already on slide', num);
947            return;
948        }
949        opts.nextSlide = num;
950        clearTimeout(opts.timeoutId);
951        opts.timeoutId = 0;
952        opts.API.log('goto: ', num, ' (zero-index)');
953        fwd = opts.currSlide < opts.nextSlide;
954        opts.API.prepareTx( true, fwd );
955    },
956
957    stop: function() {
958        var opts = this.opts();
959        var pauseObj = opts.container;
960        clearTimeout(opts.timeoutId);
961        opts.timeoutId = 0;
962        opts.API.stopTransition();
963        if ( opts.pauseOnHover ) {
964            if ( opts.pauseOnHover !== true )
965                pauseObj = $( opts.pauseOnHover );
966            pauseObj.off('mouseenter mouseleave');
967        }
968        opts.API.trigger('cycletwo-stopped', [ opts ]).log('cycletwo-stopped');
969    },
970
971    reinit: function() {
972        var opts = this.opts();
973        opts.API.destroy();
974        opts.container.cycletwo();
975    },
976
977    remove: function( index ) {
978        var opts = this.opts();
979        var slide, slideToRemove, slides = [], slideNum = 1;
980        for ( var i=0; i < opts.slides.length; i++ ) {
981            slide = opts.slides[i];
982            if ( i == index ) {
983                slideToRemove = slide;
984            }
985            else {
986                slides.push( slide );
987                $( slide ).data('cycletwo.opts').slideNum = slideNum;
988                slideNum++;
989            }
990        }
991        if ( slideToRemove ) {
992            opts.slides = $( slides );
993            opts.slideCount--;
994            $( slideToRemove ).remove();
995            if (index == opts.currSlide)
996                opts.API.advanceSlide( 1 );
997            else if ( index < opts.currSlide )
998                opts.currSlide--;
999            else
1000                opts.currSlide++;
1001
1002            opts.API.trigger('cycletwo-slide-removed', [ opts, index, slideToRemove ]).log('cycletwo-slide-removed');
1003            opts.API.updateView();
1004        }
1005    }
1006
1007});
1008
1009// listen for clicks on elements with data-cycle-cmd attribute
1010$(document).on('click.cycletwo', '[data-cycle-cmd]', function(e) {
1011    // issue cycletwo command
1012    e.preventDefault();
1013    var el = $(this);
1014    var command = el.data('cycletwo-cmd');
1015    var context = el.data('cycletwo-context') || '.cycletwo-slideshow';
1016    $(context).cycletwo(command, el.data('cycletwo-arg'));
1017});
1018
1019
1020})(jQuery);
1021
1022/*! hash plugin for cycletwo;  version: 20130905 */
1023(function($) {
1024"use strict";
1025
1026$(document).on( 'cycletwo-pre-initialize', function( e, opts ) {
1027    onHashChange( opts, true );
1028
1029    opts._onHashChange = function() {
1030        onHashChange( opts, false );
1031    };
1032
1033    $( window ).on( 'hashchange', opts._onHashChange);
1034});
1035
1036$(document).on( 'cycletwo-update-view', function( e, opts, slideOpts ) {
1037    if ( slideOpts.hash && ( '#' + slideOpts.hash ) != window.location.hash ) {
1038        opts._hashFence = true;
1039        window.location.hash = slideOpts.hash;
1040    }
1041});
1042
1043$(document).on( 'cycletwo-destroyed', function( e, opts) {
1044    if ( opts._onHashChange ) {
1045        $( window ).off( 'hashchange', opts._onHashChange );
1046    }
1047});
1048
1049function onHashChange( opts, setStartingSlide ) {
1050    var hash;
1051    if ( opts._hashFence ) {
1052        opts._hashFence = false;
1053        return;
1054    }
1055    
1056    hash = window.location.hash.substring(1);
1057
1058    opts.slides.each(function(i) {
1059        if ( $(this).data( 'cycletwo-hash' ) == hash ) {
1060            if ( setStartingSlide === true ) {
1061                opts.startingSlide = i;
1062            }
1063            else {
1064                var fwd = opts.currSlide < i;
1065                opts.nextSlide = i;
1066                opts.API.prepareTx( true, fwd );
1067            }
1068            return false;
1069        }
1070    });
1071}
1072
1073})(jQuery);
1074
1075/*! loader plugin for cycletwo;  version: 20130307 */
1076(function($) {
1077"use strict";
1078
1079$.extend($.fn.cycletwo.defaults, {
1080    loader: false
1081});
1082
1083$(document).on( 'cycletwo-bootstrap', function( e, opts ) {
1084    var addFn;
1085
1086    if ( !opts.loader )
1087        return;
1088
1089    // override API.add for this slideshow
1090    addFn = opts.API.add;
1091    opts.API.add = add;
1092
1093    function add( slides, prepend ) {
1094        var slideArr = [];
1095        if ( $.type( slides ) == 'string' )
1096            slides = $.trim( slides );
1097        else if ( $.type( slides) === 'array' ) {
1098            for (var i=0; i < slides.length; i++ )
1099                slides[i] = $(slides[i])[0];
1100        }
1101
1102        slides = $( slides );
1103        var slideCount = slides.length;
1104
1105        if ( ! slideCount )
1106            return;
1107
1108        slides.hide().appendTo('body').each(function(i) { // appendTo fixes #56
1109            var count = 0;
1110            var slide = $(this);
1111            var images = slide.is('img') ? slide : slide.find('img');
1112            slide.data('index', i);
1113            // allow some images to be marked as unimportant (and filter out images w/o src value)
1114            images = images.filter(':not(.cycletwo-loader-ignore)').filter(':not([src=""])');
1115            if ( ! images.length ) {
1116                --slideCount;
1117                slideArr.push( slide );
1118                return;
1119            }
1120
1121            count = images.length;
1122            images.each(function() {
1123                // add images that are already loaded
1124                if ( this.complete ) {
1125                    imageLoaded();
1126                }
1127                else {
1128                    $(this).load(function() {
1129                        imageLoaded();
1130                    }).error(function() {
1131                        if ( --count === 0 ) {
1132                            // ignore this slide
1133                            opts.API.log('slide skipped; img not loaded:', this.src);
1134                            if ( --slideCount === 0 && opts.loader == 'wait') {
1135                                addFn.apply( opts.API, [ slideArr, prepend ] );
1136                            }
1137                        }
1138                    });
1139                }
1140            });
1141
1142            function imageLoaded() {
1143                if ( --count === 0 ) {
1144                    --slideCount;
1145                    addSlide( slide );
1146                }
1147            }
1148        });
1149
1150        if ( slideCount )
1151            opts.container.addClass('cycletwo-loading');
1152        
1153
1154        function addSlide( slide ) {
1155            var curr;
1156            if ( opts.loader == 'wait' ) {
1157                slideArr.push( slide );
1158                if ( slideCount === 0 ) {
1159                    // #59; sort slides into original markup order
1160                    slideArr.sort( sorter );
1161                    addFn.apply( opts.API, [ slideArr, prepend ] );
1162                    opts.container.removeClass('cycletwo-loading');
1163                }
1164            }
1165            else {
1166                curr = $(opts.slides[opts.currSlide]);
1167                addFn.apply( opts.API, [ slide, prepend ] );
1168                curr.show();
1169                opts.container.removeClass('cycletwo-loading');
1170            }
1171        }
1172
1173        function sorter(a, b) {
1174            return a.data('index') - b.data('index');
1175        }
1176    }
1177});
1178
1179})(jQuery);
1180
1181/*! pager plugin for cycletwo;  version: 20130525 */
1182(function($) {
1183"use strict";
1184
1185$.extend($.fn.cycletwo.defaults, {
1186    pager:            '> .cycletwo-pager',
1187    pagerActiveClass: 'cycletwo-pager-active',
1188    pagerEvent:       'click.cycletwo',
1189    pagerTemplate:    '<span>&bull;</span>'
1190});    
1191
1192$(document).on( 'cycletwo-bootstrap', function( e, opts, API ) {
1193    // add method to API
1194    API.buildPagerLink = buildPagerLink;
1195});
1196
1197$(document).on( 'cycletwo-slide-added', function( e, opts, slideOpts, slideAdded ) {
1198    if ( opts.pager ) {
1199        opts.API.buildPagerLink ( opts, slideOpts, slideAdded );
1200        opts.API.page = page;
1201    }
1202});
1203
1204$(document).on( 'cycletwo-slide-removed', function( e, opts, index, slideRemoved ) {
1205    if ( opts.pager ) {
1206        var pagers = opts.API.getComponent( 'pager' );
1207        pagers.each(function() {
1208            var pager = $(this);
1209            $( pager.children()[index] ).remove();
1210        });
1211    }
1212});
1213
1214$(document).on( 'cycletwo-update-view', function( e, opts, slideOpts ) {
1215    var pagers;
1216
1217    if ( opts.pager ) {
1218        pagers = opts.API.getComponent( 'pager' );
1219        pagers.each(function() {
1220           $(this).children().removeClass( opts.pagerActiveClass )
1221            .eq( opts.currSlide ).addClass( opts.pagerActiveClass );
1222        });
1223    }
1224});
1225
1226$(document).on( 'cycletwo-destroyed', function( e, opts ) {
1227    var pager = opts.API.getComponent( 'pager' );
1228
1229    if ( pager ) {
1230        pager.children().off( opts.pagerEvent ); // #202
1231        if ( opts.pagerTemplate )
1232            pager.empty();
1233    }
1234});
1235
1236function buildPagerLink( opts, slideOpts, slide ) {
1237    var pagerLink;
1238    var pagers = opts.API.getComponent( 'pager' );
1239    pagers.each(function() {
1240        var pager = $(this);
1241        if ( slideOpts.pagerTemplate ) {
1242            var markup = opts.API.tmpl( slideOpts.pagerTemplate, slideOpts, opts, slide[0] );
1243            pagerLink = $( markup ).appendTo( pager );
1244        }
1245        else {
1246            pagerLink = pager.children().eq( opts.slideCount - 1 );
1247        }
1248        pagerLink.on( opts.pagerEvent, function(e) {
1249            e.preventDefault();
1250            opts.API.page( pager, e.currentTarget);
1251        });
1252    });
1253}
1254
1255function page( pager, target ) {
1256    /*jshint validthis:true */
1257    var opts = this.opts();
1258    if ( opts.busy && ! opts.manualTrump )
1259        return;
1260
1261    var index = pager.children().index( target );
1262    var nextSlide = index;
1263    var fwd = opts.currSlide < nextSlide;
1264    if (opts.currSlide == nextSlide) {
1265        return; // no op, clicked pager for the currently displayed slide
1266    }
1267    opts.nextSlide = nextSlide;
1268    opts.API.prepareTx( true, fwd );
1269    opts.API.trigger('cycletwo-pager-activated', [opts, pager, target ]);
1270}
1271
1272})(jQuery);
1273
1274
1275/*! prevnext plugin for cycletwo;  version: 20130709 */
1276(function($) {
1277"use strict";
1278
1279$.extend($.fn.cycletwo.defaults, {
1280    next:           '> .cycletwo-next',
1281    nextEvent:      'click.cycletwo',
1282    disabledClass:  'disabled',
1283    prev:           '> .cycletwo-prev',
1284    prevEvent:      'click.cycletwo',
1285    swipe:          false
1286});
1287
1288$(document).on( 'cycletwo-initialized', function( e, opts ) {
1289    opts.API.getComponent( 'next' ).on( opts.nextEvent, function(e) {
1290        e.preventDefault();
1291        opts.API.next();
1292    });
1293
1294    opts.API.getComponent( 'prev' ).on( opts.prevEvent, function(e) {
1295        e.preventDefault();
1296        opts.API.prev();
1297    });
1298
1299    if ( opts.swipe ) {
1300        var nextEvent = opts.swipeVert ? 'swipeUp.cycletwo' : 'swipeLeft.cycletwo swipeleft.cycletwo';
1301        var prevEvent = opts.swipeVert ? 'swipeDown.cycletwo' : 'swipeRight.cycletwo swiperight.cycletwo';
1302        opts.container.on( nextEvent, function(e) {
1303            opts.API.next();
1304        });
1305        opts.container.on( prevEvent, function() {
1306            opts.API.prev();
1307        });
1308    }
1309});
1310
1311$(document).on( 'cycletwo-update-view', function( e, opts, slideOpts, currSlide ) {
1312    if ( opts.allowWrap )
1313        return;
1314
1315    var cls = opts.disabledClass;
1316    var next = opts.API.getComponent( 'next' );
1317    var prev = opts.API.getComponent( 'prev' );
1318    var prevBoundry = opts._prevBoundry || 0;
1319    var nextBoundry = (opts._nextBoundry !== undefined)?opts._nextBoundry:opts.slideCount - 1;
1320
1321    if ( opts.currSlide == nextBoundry )
1322        next.addClass( cls ).prop( 'disabled', true );
1323    else
1324        next.removeClass( cls ).prop( 'disabled', false );
1325
1326    if ( opts.currSlide === prevBoundry )
1327        prev.addClass( cls ).prop( 'disabled', true );
1328    else
1329        prev.removeClass( cls ).prop( 'disabled', false );
1330});
1331
1332
1333$(document).on( 'cycletwo-destroyed', function( e, opts ) {
1334    opts.API.getComponent( 'prev' ).off( opts.nextEvent );
1335    opts.API.getComponent( 'next' ).off( opts.prevEvent );
1336    opts.container.off( 'swipeleft.cycletwo swiperight.cycletwo swipeLeft.cycletwo swipeRight.cycletwo swipeUp.cycletwo swipeDown.cycletwo' );
1337});
1338
1339})(jQuery);
1340
1341/*! progressive loader plugin for cycletwo;  version: 20130315 */
1342(function($) {
1343"use strict";
1344
1345$.extend($.fn.cycletwo.defaults, {
1346    progressive: false
1347});
1348
1349$(document).on( 'cycletwo-pre-initialize', function( e, opts ) {
1350    if ( !opts.progressive )
1351        return;
1352
1353    var API = opts.API;
1354    var nextFn = API.next;
1355    var prevFn = API.prev;
1356    var prepareTxFn = API.prepareTx;
1357    var type = $.type( opts.progressive );
1358    var slides, scriptEl;
1359
1360    if ( type == 'array' ) {
1361        slides = opts.progressive;
1362    }
1363    else if ($.isFunction( opts.progressive ) ) {
1364        slides = opts.progressive( opts );
1365    }
1366    else if ( type == 'string' ) {
1367        scriptEl = $( opts.progressive );
1368        slides = $.trim( scriptEl.html() );
1369        if ( !slides )
1370            return;
1371        // is it json array?
1372        if ( /^(\[)/.test( slides ) ) {
1373            try {
1374                slides = $.parseJSON( slides );
1375            }
1376            catch(err) {
1377                API.log( 'error parsing progressive slides', err );
1378                return;
1379            }
1380        }
1381        else {
1382            // plain text, split on delimeter
1383            slides = slides.split( new RegExp( scriptEl.data('cycletwo-split') || '\n') );
1384            
1385            // #95; look for empty slide
1386            if ( ! slides[ slides.length - 1 ] )
1387                slides.pop();
1388        }
1389    }
1390
1391
1392
1393    if ( prepareTxFn ) {
1394        API.prepareTx = function( manual, fwd ) {
1395            var index, slide;
1396
1397            if ( manual || slides.length === 0 ) {
1398                prepareTxFn.apply( opts.API, [ manual, fwd ] );
1399                return;
1400            }
1401
1402            if ( fwd && opts.currSlide == ( opts.slideCount-1) ) {
1403                slide = slides[ 0 ];
1404                slides = slides.slice( 1 );
1405                opts.container.one('cycletwo-slide-added', function(e, opts ) {
1406                    setTimeout(function() {
1407                        opts.API.advanceSlide( 1 );
1408                    },50);
1409                });
1410                opts.API.add( slide );
1411            }
1412            else if ( !fwd && opts.currSlide === 0 ) {
1413                index = slides.length-1;
1414                slide = slides[ index ];
1415                slides = slides.slice( 0, index );
1416                opts.container.one('cycletwo-slide-added', function(e, opts ) {
1417                    setTimeout(function() {
1418                        opts.currSlide = 1;
1419                        opts.API.advanceSlide( -1 );
1420                    },50);
1421                });
1422                opts.API.add( slide, true );
1423            }
1424            else {
1425                prepareTxFn.apply( opts.API, [ manual, fwd ] );
1426            }
1427        };
1428    }
1429
1430    if ( nextFn ) {
1431        API.next = function() {
1432            var opts = this.opts();
1433            if ( slides.length && opts.currSlide == ( opts.slideCount - 1 ) ) {
1434                var slide = slides[ 0 ];
1435                slides = slides.slice( 1 );
1436                opts.container.one('cycletwo-slide-added', function(e, opts ) {
1437                    nextFn.apply( opts.API );
1438                    opts.container.removeClass('cycletwo-loading');
1439                });
1440                opts.container.addClass('cycletwo-loading');
1441                opts.API.add( slide );
1442            }
1443            else {
1444                nextFn.apply( opts.API );    
1445            }
1446        };
1447    }
1448    
1449    if ( prevFn ) {
1450        API.prev = function() {
1451            var opts = this.opts();
1452            if ( slides.length && opts.currSlide === 0 ) {
1453                var index = slides.length-1;
1454                var slide = slides[ index ];
1455                slides = slides.slice( 0, index );
1456                opts.container.one('cycletwo-slide-added', function(e, opts ) {
1457                    opts.currSlide = 1;
1458                    opts.API.advanceSlide( -1 );
1459                    opts.container.removeClass('cycletwo-loading');
1460                });
1461                opts.container.addClass('cycletwo-loading');
1462                opts.API.add( slide, true );
1463            }
1464            else {
1465                prevFn.apply( opts.API );
1466            }
1467        };
1468    }
1469});
1470
1471})(jQuery);
1472
1473/*! tmpl plugin for cycletwo;  version: 20121227 */
1474(function($) {
1475"use strict";
1476
1477$.extend($.fn.cycletwo.defaults, {
1478    tmplRegex: '{{((.)?.*?)}}'
1479});
1480
1481$.extend($.fn.cycletwo.API, {
1482    tmpl: function( str, opts /*, ... */) {
1483        var regex = new RegExp( opts.tmplRegex || $.fn.cycletwo.defaults.tmplRegex, 'g' );
1484        var args = $.makeArray( arguments );
1485        args.shift();
1486        return str.replace(regex, function(_, str) {
1487            var i, j, obj, prop, names = str.split('.');
1488            for (i=0; i < args.length; i++) {
1489                obj = args[i];
1490                if ( ! obj )
1491                    continue;
1492                if (names.length > 1) {
1493                    prop = obj;
1494                    for (j=0; j < names.length; j++) {
1495                        obj = prop;
1496                        prop = prop[ names[j] ] || str;
1497                    }
1498                } else {
1499                    prop = obj[str];
1500                }
1501
1502                if ($.isFunction(prop))
1503                    return prop.apply(obj, args);
1504                if (prop !== undefined && prop !== null && prop != str)
1505                    return prop;
1506            }
1507            return str;
1508        });
1509    }
1510});    
1511
1512})(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.