vendor: 7,302 bytes, lines 1-245
1/*! 2 * Fotorama 4.6.4 | http://fotorama.io/license/ 3 */ 4fotoramaVersion = '4.6.4'; 5(function (window, document, location, $, undefined) { 6 "use strict"; 7var _fotoramaClass = 'fotorama', 8 _fullscreenClass = 'fullscreen', 9 10 wrapClass = _fotoramaClass + '__wrap', 11 wrapCss2Class = wrapClass + '--css2', 12 wrapCss3Class = wrapClass + '--css3', 13 wrapVideoClass = wrapClass + '--video', 14 wrapFadeClass = wrapClass + '--fade', 15 wrapSlideClass = wrapClass + '--slide', 16 wrapNoControlsClass = wrapClass + '--no-controls', 17 wrapNoShadowsClass = wrapClass + '--no-shadows', 18 wrapPanYClass = wrapClass + '--pan-y', 19 wrapRtlClass = wrapClass + '--rtl', 20 wrapOnlyActiveClass = wrapClass + '--only-active', 21 wrapNoCaptionsClass = wrapClass + '--no-captions', 22 wrapToggleArrowsClass = wrapClass + '--toggle-arrows', 23 24 stageClass = _fotoramaClass + '__stage', 25 stageFrameClass = stageClass + '__frame', 26 stageFrameVideoClass = stageFrameClass + '--video', 27 stageShaftClass = stageClass + '__shaft', 28 29 grabClass = _fotoramaClass + '__grab', 30 pointerClass = _fotoramaClass + '__pointer', 31 32 arrClass = _fotoramaClass + '__arr', 33 arrDisabledClass = arrClass + '--disabled', 34 arrPrevClass = arrClass + '--prev', 35 arrNextClass = arrClass + '--next', 36 arrArrClass = arrClass + '__arr', 37 38 navClass = _fotoramaClass + '__nav', 39 navWrapClass = navClass + '-wrap', 40 navShaftClass = navClass + '__shaft', 41 navDotsClass = navClass + '--dots', 42 navThumbsClass = navClass + '--thumbs', 43 navFrameClass = navClass + '__frame', 44 navFrameDotClass = navFrameClass + '--dot', 45 navFrameThumbClass = navFrameClass + '--thumb', 46 47 fadeClass = _fotoramaClass + '__fade', 48 fadeFrontClass = fadeClass + '-front', 49 fadeRearClass = fadeClass + '-rear', 50 51 shadowClass = _fotoramaClass + '__shadow', 52 shadowsClass = shadowClass + 's', 53 shadowsLeftClass = shadowsClass + '--left', 54 shadowsRightClass = shadowsClass + '--right', 55 56 activeClass = _fotoramaClass + '__active', 57 selectClass = _fotoramaClass + '__select', 58 59 hiddenClass = _fotoramaClass + '--hidden', 60 61 fullscreenClass = _fotoramaClass + '--fullscreen', 62 fullscreenIconClass = _fotoramaClass + '__fullscreen-icon', 63 64 errorClass = _fotoramaClass + '__error', 65 loadingClass = _fotoramaClass + '__loading', 66 loadedClass = _fotoramaClass + '__loaded', 67 loadedFullClass = loadedClass + '--full', 68 loadedImgClass = loadedClass + '--img', 69 70 grabbingClass = _fotoramaClass + '__grabbing', 71 72 imgClass = _fotoramaClass + '__img', 73 imgFullClass = imgClass + '--full', 74 75 dotClass = _fotoramaClass + '__dot', 76 thumbClass = _fotoramaClass + '__thumb', 77 thumbBorderClass = thumbClass + '-border', 78 79 htmlClass = _fotoramaClass + '__html', 80 81 videoClass = _fotoramaClass + '__video', 82 videoPlayClass = videoClass + '-play', 83 videoCloseClass = videoClass + '-close', 84 85 captionClass = _fotoramaClass + '__caption', 86 captionWrapClass = _fotoramaClass + '__caption__wrap', 87 88 spinnerClass = _fotoramaClass + '__spinner', 89 90 buttonAttributes = '" tabindex="0" role="button'; 91var JQUERY_VERSION = $ && $.fn.jquery.split('.'); 92 93if (!JQUERY_VERSION 94 || JQUERY_VERSION[0] < 1 95 || (JQUERY_VERSION[0] == 1 && JQUERY_VERSION[1] < 8)) { 96 throw 'Fotorama requires jQuery 1.8 or later and will not run without it.'; 97} 98// My Underscore :-) 99var _ = {}; 100/* Modernizr 2.6.2 (Custom Build) | MIT & BSD 101 * Build: http://modernizr.com/download/#-csstransforms3d-prefixed-teststyles-testprop-testallprops-prefixes-domprefixes 102 */ 103 104var Modernizr = (function (window, document, undefined) { 105 106 var version = '2.6.2', 107 108 Modernizr = {}, 109 110 docElement = document.documentElement, 111 112 mod = 'modernizr', 113 modElem = document.createElement(mod), 114 mStyle = modElem.style, 115 116 inputElem, 117 118 toString = {}.toString, 119 120 prefixes = ' -webkit- -moz- -o- -ms- '.split(' '), 121 122 omPrefixes = 'Webkit Moz O ms', 123 124 cssomPrefixes = omPrefixes.split(' '), 125 126 domPrefixes = omPrefixes.toLowerCase().split(' '), 127 128 tests = {}, 129 inputs = {}, 130 attrs = {}, 131 132 classes = [], 133 134 slice = classes.slice, 135 136 featureName, 137 138 injectElementWithStyles = function (rule, callback, nodes, testnames) { 139 140 var style, ret, node, docOverflow, 141 div = document.createElement('div'), 142 body = document.body, 143 fakeBody = body || document.createElement('body'); 144 145 if (parseInt(nodes, 10)) { 146 while (nodes--) { 147 node = document.createElement('div'); 148 node.id = testnames ? testnames[nodes] : mod + (nodes + 1); 149 div.appendChild(node); 150 } 151 } 152 153 style = ['­', '<style id="s', mod, '">', rule, '</style>'].join(''); 154 div.id = mod; 155 (body ? div : fakeBody).innerHTML += style; 156 fakeBody.appendChild(div); 157 if (!body) { 158 fakeBody.style.background = ''; 159 fakeBody.style.overflow = 'hidden'; 160 docOverflow = docElement.style.overflow; 161 docElement.style.overflow = 'hidden'; 162 docElement.appendChild(fakeBody); 163 } 164 165 ret = callback(div, rule); 166 if (!body) { 167 fakeBody.parentNode.removeChild(fakeBody); 168 docElement.style.overflow = docOverflow; 169 } else { 170 div.parentNode.removeChild(div); 171 } 172 173 return !!ret; 174 175 }, 176 _hasOwnProperty = ({}).hasOwnProperty, hasOwnProp; 177 178 if (!is(_hasOwnProperty, 'undefined') && !is(_hasOwnProperty.call, 'undefined')) { 179 hasOwnProp = function (object, property) { 180 return _hasOwnProperty.call(object, property); 181 }; 182 } 183 else { 184 hasOwnProp = function (object, property) { 185 return ((property in object) && is(object.constructor.prototype[property], 'undefined')); 186 }; 187 } 188 189 190 if (!Function.prototype.bind) { 191 Function.prototype.bind = function bind (that) { 192 193 var target = this; 194 195 if (typeof target != "function") { 196 throw new TypeError(); 197 } 198 199 var args = slice.call(arguments, 1), 200 bound = function () { 201 202 if (this instanceof bound) { 203 204 var F = function () { 205 }; 206 F.prototype = target.prototype; 207 var self = new F(); 208 209 var result = target.apply( 210 self, 211 args.concat(slice.call(arguments)) 212 ); 213 if (Object(result) === result) { 214 return result; 215 } 216 return self; 217 218 } else { 219 220 return target.apply( 221 that, 222 args.concat(slice.call(arguments)) 223 ); 224 225 } 226 227 }; 228 229 return bound; 230 }; 231 } 232 233 function setCss (str) { 234 mStyle.cssText = str; 235 } 236 237 function setCssAll (str1, str2) { 238 return setCss(prefixes.join(str1 + ';') + ( str2 || '' )); 239 } 240 241 function is (obj, type) { 242 return typeof obj === type; 243 } 244 245 function contains (str, substr) {
246 return !!~('' + str).indexOf(substr); 247 } 248 249 function testProps (props, prefixed) { 250 for (var i in props) { 251 var prop = props[i]; 252 if (!contains(prop, "-") && mStyle[prop] !== undefined) { 253 return prefixed == 'pfx' ? prop : true; 254 } 255 } 256 return false; 257 } 258 259 function testDOMProps (props, obj, elem) { 260 for (var i in props) { 261 var item = obj[props[i]]; 262 if (item !== undefined) { 263 264 if (elem === false) return props[i]; 265 266 if (is(item, 'function')) { 267 return item.bind(elem || obj); 268 } 269 270 return item; 271 } 272 } 273 return false; 274 } 275 276 function testPropsAll (prop, prefixed, elem) { 277 278 var ucProp = prop.charAt(0).toUpperCase() + prop.slice(1), 279 props = (prop + ' ' + cssomPrefixes.join(ucProp + ' ') + ucProp).split(' '); 280 281 if (is(prefixed, "string") || is(prefixed, "undefined")) { 282 return testProps(props, prefixed); 283 284 } else { 285 props = (prop + ' ' + (domPrefixes).join(ucProp + ' ') + ucProp).split(' '); 286 return testDOMProps(props, prefixed, elem); 287 } 288 } 289 290 tests['csstransforms3d'] = function () { 291 292 var ret = !!testPropsAll('perspective'); 293 294// Chrome fails that test, ignore 295// if (ret && 'webkitPerspective' in docElement.style) { 296// 297// injectElementWithStyles('@media (transform-3d),(-webkit-transform-3d){#modernizr{left:9px;position:absolute;height:3px;}}', function (node, rule) { 298// ret = node.offsetLeft === 9 && node.offsetHeight === 3; 299// }); 300// } 301 return ret; 302 }; 303 304 for (var feature in tests) { 305 if (hasOwnProp(tests, feature)) { 306 featureName = feature.toLowerCase(); 307 Modernizr[featureName] = tests[feature](); 308 309 classes.push((Modernizr[featureName] ? '' : 'no-') + featureName); 310 } 311 } 312 313 Modernizr.addTest = function (feature, test) { 314 if (typeof feature == 'object') { 315 for (var key in feature) { 316 if (hasOwnProp(feature, key)) { 317 Modernizr.addTest(key, feature[ key ]); 318 } 319 } 320 } else { 321 322 feature = feature.toLowerCase(); 323 324 if (Modernizr[feature] !== undefined) { 325 return Modernizr; 326 } 327 328 test = typeof test == 'function' ? test() : test; 329 330 if (typeof enableClasses !== "undefined" && enableClasses) { 331 docElement.className += ' ' + (test ? '' : 'no-') + feature; 332 } 333 Modernizr[feature] = test; 334 335 } 336 337 return Modernizr; 338 }; 339 340 341 setCss(''); 342 modElem = inputElem = null; 343 344 345 Modernizr._version = version; 346 347 Modernizr._prefixes = prefixes; 348 Modernizr._domPrefixes = domPrefixes; 349 Modernizr._cssomPrefixes = cssomPrefixes; 350 351 Modernizr.testProp = function (prop) { 352 return testProps([prop]); 353 }; 354 355 Modernizr.testAllProps = testPropsAll; 356 357 Modernizr.testStyles = injectElementWithStyles; 358 Modernizr.prefixed = function (prop, obj, elem) { 359 if (!obj) { 360 return testPropsAll(prop, 'pfx'); 361 } else { 362 return testPropsAll(prop, obj, elem); 363 } 364 }; 365 366 return Modernizr; 367})(window, document); 368var fullScreenApi = { 369 ok: false, 370 is: function () { 371 return false; 372 }, 373 request: function () { 374 }, 375 cancel: function () { 376 }, 377 event: '', 378 prefix: '' 379 }, 380 browserPrefixes = 'webkit moz o ms khtml'.split(' '); 381 382// check for native support 383if (typeof document.cancelFullScreen != 'undefined') { 384 fullScreenApi.ok = true; 385} else { 386 // check for fullscreen support by vendor prefix 387 for (var i = 0, il = browserPrefixes.length; i < il; i++) { 388 fullScreenApi.prefix = browserPrefixes[i]; 389 if (typeof document[fullScreenApi.prefix + 'CancelFullScreen' ] != 'undefined') { 390 fullScreenApi.ok = true; 391 break; 392 } 393 } 394} 395 396// update methods to do something useful 397if (fullScreenApi.ok) { 398 fullScreenApi.event = fullScreenApi.prefix + 'fullscreenchange'; 399 fullScreenApi.is = function () { 400 switch (this.prefix) { 401 case '': 402 return document.fullScreen; 403 case 'webkit': 404 return document.webkitIsFullScreen;
405 default: 406 return document[this.prefix + 'FullScreen']; 407 } 408 }; 409 fullScreenApi.request = function (el) { 410 return (this.prefix === '') ? el.requestFullScreen() : el[this.prefix + 'RequestFullScreen'](); 411 }; 412 fullScreenApi.cancel = function (el) { 413 return (this.prefix === '') ? document.cancelFullScreen() : document[this.prefix + 'CancelFullScreen'](); 414 }; 415} 416//fgnass.github.com/spin.js#v1.3.2 417 418/** 419 * Copyright (c) 2011-2013 Felix Gnass 420 * Licensed under the MIT license 421 */ 422 423var Spinner, 424 spinnerDefaults = { 425 lines: 12, // The number of lines to draw 426 length: 5, // The length of each line 427 width: 2, // The line thickness 428 radius: 7, // The radius of the inner circle 429 corners: 1, // Corner roundness (0..1) 430 rotate: 15, // The rotation offset 431 color: 'rgba(128, 128, 128, .75)', 432 hwaccel: true 433 }, 434 spinnerOverride = { 435 top: 'auto', 436 left: 'auto', 437 className: '' 438 }; 439 440(function(root, factory) { 441 442 /* CommonJS */ 443 //if (typeof exports == 'object') module.exports = factory() 444 445 /* AMD module */ 446 //else if (typeof define == 'function' && define.amd) define(factory) 447 448 /* Browser global */ 449 //else root.Spinner = factory() 450 451 Spinner = factory(); 452} 453(this, function() { 454 "use strict"; 455 456 var prefixes = ['webkit', 'Moz', 'ms', 'O'] /* Vendor prefixes */ 457 , animations = {} /* Animation rules keyed by their name */ 458 , useCssAnimations /* Whether to use CSS animations or setTimeout */ 459 460 /** 461 * Utility function to create elements. If no tag name is given, 462 * a DIV is created. Optionally properties can be passed. 463 */ 464 function createEl(tag, prop) { 465 var el = document.createElement(tag || 'div') 466 , n 467 468 for(n in prop) el[n] = prop[n] 469 return el 470 } 471 472 /** 473 * Appends children and returns the parent. 474 */ 475 function ins(parent /* child1, child2, ...*/) { 476 for (var i=1, n=arguments.length; i<n; i++) 477 parent.appendChild(arguments[i]) 478 479 return parent 480 } 481 482 /** 483 * Insert a new stylesheet to hold the @keyframe or VML rules. 484 */ 485 var sheet = (function() { 486 var el = createEl('style', {type : 'text/css'}) 487 ins(document.getElementsByTagName('head')[0], el) 488 return el.sheet || el.styleSheet 489 }()) 490 491 /** 492 * Creates an opacity keyframe animation rule and returns its name. 493 * Since most mobile Webkits have timing issues with animation-delay, 494 * we create separate rules for each line/segment. 495 */ 496 function addAnimation(alpha, trail, i, lines) { 497 var name = ['opacity', trail, ~~(alpha*100), i, lines].join('-') 498 , start = 0.01 + i/lines * 100 499 , z = Math.max(1 - (1-alpha) / trail * (100-start), alpha) 500 , prefix = useCssAnimations.substring(0, useCssAnimations.indexOf('Animation')).toLowerCase() 501 , pre = prefix && '-' + prefix + '-' || '' 502 503 if (!animations[name]) { 504 sheet.insertRule( 505 '@' + pre + 'keyframes ' + name + '{' + 506 '0%{opacity:' + z + '}' + 507 start + '%{opacity:' + alpha + '}' + 508 (start+0.01) + '%{opacity:1}' + 509 (start+trail) % 100 + '%{opacity:' + alpha + '}' + 510 '100%{opacity:' + z + '}' + 511 '}', sheet.cssRules.length) 512 513 animations[name] = 1 514 } 515 516 return name 517 } 518 519 /** 520 * Tries various vendor prefixes and returns the first supported property. 521 */ 522 function vendor(el, prop) { 523 var s = el.style 524 , pp 525 , i 526 527 prop = prop.charAt(0).toUpperCase() + prop.slice(1) 528 for(i=0; i<prefixes.length; i++) { 529 pp = prefixes[i]+prop 530 if(s[pp] !== undefined) return pp 531 } 532 if(s[prop] !== undefined) return prop 533 } 534 535 /** 536 * Sets multiple style properties at once. 537 */ 538 function css(el, prop) { 539 for (var n in prop) 540 el.style[vendor(el, n)||n] = prop[n] 541 542 return el 543 } 544 545 /** 546 * Fills in default values. 547 */ 548 function merge(obj) { 549 for (var i=1; i < arguments.length; i++) { 550 var def = arguments[i] 551 for (var n in def) 552 if (obj[n] === undefined) obj[n] = def[n] 553 } 554 return obj 555 } 556 557 /** 558 * Returns the absolute page-offset of the given element. 559 */ 560 function pos(el) { 561 var o = { x:el.offsetLeft, y:el.offsetTop } 562 while((el = el.offsetParent)) 563 o.x+=el.offsetLeft, o.y+=el.offsetTop 564 565 return o 566 } 567 568 /** 569 * Returns the line color from the given string or array. 570 */ 571 function getColor(color, idx) { 572 return typeof color == 'string' ? color : color[idx % color.length] 573 } 574 575 // Built-in defaults 576 577 var defaults = { 578 lines: 12, // The number of lines to draw 579 length: 7, // The length of each line 580 width: 5, // The line thickness 581 radius: 10, // The radius of the inner circle 582 rotate: 0, // Rotation offset 583 corners: 1, // Roundness (0..1) 584 color: '#000', // #rgb or #rrggbb 585 direction: 1, // 1: clockwise, -1: counterclockwise 586 speed: 1, // Rounds per second 587 trail: 100, // Afterglow percentage 588 opacity: 1/4, // Opacity of the lines 589 fps: 20, // Frames per second when using setTimeout() 590 zIndex: 2e9, // Use a high z-index by default 591 className: 'spinner', // CSS class to assign to the element 592 top: 'auto', // center vertically 593 left: 'auto', // center horizontally 594 position: 'relative' // element position 595 } 596 597 /** The constructor */ 598 function Spinner(o) { 599 if (typeof this == 'undefined') return new Spinner(o) 600 this.opts = merge(o || {}, Spinner.defaults, defaults) 601 } 602 603 // Global defaults that override the built-ins: 604 Spinner.defaults = {} 605
606 merge(Spinner.prototype, { 607 608 /** 609 * Adds the spinner to the given target element. If this instance is already 610 * spinning, it is automatically removed from its previous target b calling 611 * stop() internally. 612 */ 613 spin: function(target) { 614 this.stop() 615 616 var self = this 617 , o = self.opts 618 , el = self.el = css(createEl(0, {className: o.className}), {position: o.position, width: 0, zIndex: o.zIndex}) 619 , mid = o.radius+o.length+o.width 620 , ep // element position 621 , tp // target position 622 623 if (target) { 624 target.insertBefore(el, target.firstChild||null) 625 tp = pos(target) 626 ep = pos(el) 627 css(el, { 628 left: (o.left == 'auto' ? tp.x-ep.x + (target.offsetWidth >> 1) : parseInt(o.left, 10) + mid) + 'px', 629 top: (o.top == 'auto' ? tp.y-ep.y + (target.offsetHeight >> 1) : parseInt(o.top, 10) + mid) + 'px' 630 }) 631 } 632 633 el.setAttribute('role', 'progressbar') 634 self.lines(el, self.opts) 635 636 if (!useCssAnimations) { 637 // No CSS animation support, use setTimeout() instead 638 var i = 0 639 , start = (o.lines - 1) * (1 - o.direction) / 2 640 , alpha 641 , fps = o.fps 642 , f = fps/o.speed 643 , ostep = (1-o.opacity) / (f*o.trail / 100) 644 , astep = f/o.lines 645 646 ;(function anim() { 647 i++; 648 for (var j = 0; j < o.lines; j++) { 649 alpha = Math.max(1 - (i + (o.lines - j) * astep) % f * ostep, o.opacity) 650 651 self.opacity(el, j * o.direction + start, alpha, o) 652 } 653 self.timeout = self.el && setTimeout(anim, ~~(1000/fps)) 654 })() 655 } 656 return self 657 }, 658 659 /** 660 * Stops and removes the Spinner. 661 */ 662 stop: function() { 663 var el = this.el 664 if (el) { 665 clearTimeout(this.timeout) 666 if (el.parentNode) el.parentNode.removeChild(el) 667 this.el = undefined 668 } 669 return this 670 }, 671 672 /** 673 * Internal method that draws the individual lines. Will be overwritten 674 * in VML fallback mode below. 675 */ 676 lines: function(el, o) { 677 var i = 0 678 , start = (o.lines - 1) * (1 - o.direction) / 2 679 , seg 680 681 function fill(color, shadow) { 682 return css(createEl(), { 683 position: 'absolute', 684 width: (o.length+o.width) + 'px', 685 height: o.width + 'px', 686 background: color, 687 boxShadow: shadow, 688 transformOrigin: 'left', 689 transform: 'rotate(' + ~~(360/o.lines*i+o.rotate) + 'deg) translate(' + o.radius+'px' +',0)', 690 borderRadius: (o.corners * o.width>>1) + 'px' 691 }) 692 } 693 694 for (; i < o.lines; i++) { 695 seg = css(createEl(), { 696 position: 'absolute', 697 top: 1+~(o.width/2) + 'px', 698 transform: o.hwaccel ? 'translate3d(0,0,0)' : '', 699 opacity: o.opacity, 700 animation: useCssAnimations && addAnimation(o.opacity, o.trail, start + i * o.direction, o.lines) + ' ' + 1/o.speed + 's linear infinite' 701 }) 702 703 if (o.shadow) ins(seg, css(fill('#000', '0 0 4px ' + '#000'), {top: 2+'px'})) 704 ins(el, ins(seg, fill(getColor(o.color, i), '0 0 1px rgba(0,0,0,.1)'))) 705 } 706 return el 707 }, 708 709 /** 710 * Internal method that adjusts the opacity of a single line. 711 * Will be overwritten in VML fallback mode below. 712 */ 713 opacity: function(el, i, val) { 714 if (i < el.childNodes.length) el.childNodes[i].style.opacity = val 715 } 716 717 }) 718 719 720 function initVML() { 721 722 /* Utility function to create a VML tag */ 723 function vml(tag, attr) { 724 return createEl('<' + tag + ' xmlns="urn:schemas-microsoft.com:vml" class="spin-vml">', attr) 725 } 726 727 // No CSS transforms but VML support, add a CSS rule for VML elements: 728 sheet.addRule('.spin-vml', 'behavior:url(#default#VML)') 729 730 Spinner.prototype.lines = function(el, o) { 731 var r = o.length+o.width 732 , s = 2*r 733 734 function grp() { 735 return css( 736 vml('group', { 737 coordsize: s + ' ' + s, 738 coordorigin: -r + ' ' + -r 739 }), 740 { width: s, height: s } 741 ) 742 } 743 744 var margin = -(o.width+o.length)*2 + 'px' 745 , g = css(grp(), {position: 'absolute', top: margin, left
745: margin}) 746 , i 747 748 function seg(i, dx, filter) { 749 ins(g, 750 ins(css(grp(), {rotation: 360 / o.lines * i + 'deg', left: ~~dx}), 751 ins(css(vml('roundrect', {arcsize: o.corners}), { 752 width: r, 753 height: o.width, 754 left: o.radius, 755 top: -o.width>>1, 756 filter: filter 757 }), 758 vml('fill', {color: getColor(o.color, i), opacity: o.opacity}), 759 vml('stroke', {opacity: 0}) // transparent stroke to fix color bleeding upon opacity change 760 ) 761 ) 762 ) 763 } 764 765 if (o.shadow) 766 for (i = 1; i <= o.lines; i++) 767 seg(i, -2, 'progid:DXImageTransform.Microsoft.Blur(pixelradius=2,makeshadow=1,shadowopacity=.3)') 768 769 for (i = 1; i <= o.lines; i++) seg(i) 770 return ins(el, g) 771 } 772 773 Spinner.prototype.opacity = function(el, i, val, o) { 774 var c = el.firstChild 775 o = o.shadow && o.lines || 0 776 if (c && i+o < c.childNodes.length) { 777 c = c.childNodes[i+o]; c = c && c.firstChild; c = c && c.firstChild 778 if (c) c.opacity = val 779 } 780 } 781 } 782 783 var probe = css(createEl('group'), {behavior: 'url(#default#VML)'}) 784 785 if (!vendor(probe, 'transform') && probe.adj) initVML() 786 else useCssAnimations = vendor(probe, 'animation') 787 788 return Spinner 789 790})); 791 792/* Bez v1.0.10-g5ae0136 793 * http://github.com/rdallasgray/bez 794 * 795 * A plugin to convert CSS3 cubic-bezier co-ordinates to jQuery-compatible easing functions 796 * 797 * With thanks to Nikolay Nemshilov for clarification on the cubic-bezier maths 798 * See http://st-on-it.blogspot.com/2011/05/calculating-cubic-bezier-function.html 799 * 800 * Copyright 2011 Robert Dallas Gray. All rights reserved. 801 * Provided under the FreeBSD license: https://github.com/rdallasgray/bez/blob/master/LICENSE.txt 802 */ 803function bez (coOrdArray) { 804 var encodedFuncName = "bez_" + $.makeArray(arguments).join("_").replace(".", "p"); 805 if (typeof $['easing'][encodedFuncName] !== "function") { 806 var polyBez = function (p1, p2) { 807 var A = [null, null], 808 B = [null, null], 809 C = [null, null], 810 bezCoOrd = function (t, ax) { 811 C[ax] = 3 * p1[ax]; 812 B[ax] = 3 * (p2[ax] - p1[ax]) - C[ax]; 813 A[ax] = 1 - C[ax] - B[ax]; 814 return t * (C[ax] + t * (B[ax] + t * A[ax])); 815 }, 816 xDeriv = function (t) { 817 return C[0] + t * (2 * B[0] + 3 * A[0] * t); 818 }, 819 xForT = function (t) { 820 var x = t, i = 0, z; 821 while (++i < 14) { 822 z = bezCoOrd(x, 0) - t; 823 if (Math.abs(z) < 1e-3) break; 824 x -= z / xDeriv(x); 825 } 826 return x; 827 }; 828 return function (t) { 829 return bezCoOrd(xForT(t), 1); 830 } 831 }; 832 $['easing'][encodedFuncName] = function (x, t, b, c, d) { 833 return c * polyBez([coOrdArray[0], coOrdArray[1]], [coOrdArray[2], coOrdArray[3]])(t / d) + b; 834 } 835 } 836 return encodedFuncName; 837} 838var $WINDOW = $(window), 839 $DOCUMENT = $(document), 840 $HTML, 841 $BODY, 842 843 QUIRKS_FORCE = location.hash.replace('#', '') === 'quirks', 844 TRANSFORMS3D = Modernizr.csstransforms3d, 845 CSS3 = TRANSFORMS3D && !QUIRKS_FORCE, 846 COMPAT = TRANSFORMS3D || document.compatMode === 'CSS1Compat', 847 FULLSCREEN = fullScreenApi.ok, 848 849 MOBILE = navigator.userAgent.match(/Android|webOS|iPhone|iPad|iPod|BlackBerry|Windows Phone/i), 850 SLOW = !CSS3 || MOBILE, 851 852 MS_POINTER = navigator.msPointerEnabled, 853 854 WHEEL = "onwheel" in document.createElement("div") ? "wheel" : document.onmousewheel !== undefined ? "mousewheel" : "DOMMouseScroll", 855 856 TOUCH_TIMEOUT = 250, 857 TRANSITION_DURATION = 300, 858 859 SCROLL_LOCK_TIMEOUT = 1400, 860 861 AUTOPLAY_INTERVAL = 5000, 862 MARGIN = 2, 863 THUMB_SIZE = 64, 864 865 WIDTH = 500, 866 HEIGHT = 333, 867 868 STAGE_FRAME_KEY = '$stageFrame', 869 NAV_DOT_FRAME_KEY = '$navDotFrame', 870 NAV_THUMB_FRAME_KEY = '$navThumbFrame', 871 872 AUTO = 'auto', 873 874 BEZIER = bez([.1, 0, .25, 1]), 875 876 MAX_WIDTH = 99999, 877 878 FIFTYFIFTY = '50%', 879 880 OPTIONS = { 881 // dimensions 882 width: null, // 500 || '100%' 883 minwidth: null, 884 maxwidth: '100%', // '100%' 885 height: null, 886 minheight: null, 887 maxheight: null, 888 889 ratio: null, // '16/9' || 500/333 || 1.5 890 891 margin: MARGIN, 892 glimpse: 0, 893 894 fit: 'contain', // 'cover' || 'scaledown' || 'none' 895 896 position: FIFTYFIFTY, 897 thumbposition: FIFTYFIFTY, 898 899 // navigation, thumbs 900 nav: 'dots', // 'thumbs' || false 901 navposition: 'bottom', // 'top' 902 navwidth: null, 903 thumbwidth: THUMB_SIZE, 904 thumbheight: THUMB_SIZE, 905 thumbmargin: MARGIN, 906 thumbborderwidth: MARGIN, 907 thumbfit: 'cover', // 'contain' || 'scaledown' || 'none' 908
909 allowfullscreen: false, // true || 'native' 910 911 transition: 'slide', // 'crossfade' || 'dissolve' 912 clicktransition: null, 913 transitionduration: TRANSITION_DURATION, 914 915 captions: true, 916 917 hash: false, 918 startindex: 0, 919 920 loop: false, 921 922 autoplay: false, 923 stopautoplayontouch: true, 924 925 keyboard: false, 926 927 arrows: true, 928 click: true, 929 swipe: true, 930 trackpad: false, 931 932 enableifsingleframe: false, 933 934 controlsonstart: true, 935 936 shuffle: false, 937 938 direction: 'ltr', // 'rtl' 939 940 shadows: true, 941 spinner: null 942 }, 943 944 KEYBOARD_OPTIONS = { 945 left: true, 946 right: true, 947 down: false, 948 up: false, 949 space: false, 950 home: false, 951 end: false 952 }; 953function noop () {} 954 955function minMaxLimit (value, min, max) { 956 return Math.max(isNaN(min) ? -Infinity : min, Math.min(isNaN(max) ? Infinity : max, value)); 957} 958 959function readTransform (css) { 960 return css.match(/ma/) && css.match(/-?\d+(?!d)/g)[css.match(/3d/) ? 12 : 4]; 961} 962 963function readPosition ($el) { 964 if (CSS3) { 965 return +readTransform($el.css('transform')); 966 } else { 967 return +$el.css('left').replace('px', ''); 968 } 969} 970 971function getTranslate (pos/*, _001*/) { 972 var obj = {}; 973 if (CSS3) { 974 obj.transform = 'translate3d(' + (pos/* + (_001 ? 0.001 : 0)*/) + 'px,0,0)'; // 0.001 to remove Retina artifacts 975 } else { 976 obj.left = pos; 977 } 978 return obj; 979} 980 981function getDuration (time) { 982 return {'transition-duration': time + 'ms'}; 983} 984 985function unlessNaN (value, alternative) { 986 return isNaN(value) ? alternative : value; 987} 988 989function numberFromMeasure (value, measure) { 990 return unlessNaN(+String(value).replace(measure || 'px', '')); 991} 992 993function numberFromPercent (value) { 994 return /%$/.test(value) ? numberFromMeasure(value, '%') : undefined; 995} 996 997function numberFromWhatever (value, whole) { 998 return unlessNaN(numberFromPercent(value) / 100 * whole, numberFromMeasure(value)); 999} 1000 1001function measureIsValid (value) { 1002 return (!isNaN(numberFromMeasure(value)) || !isNaN(numberFromMeasure(value, '%'))) && value; 1003} 1004 1005function getPosByIndex (index, side, margin, baseIndex) { 1006 ////console.log('getPosByIndex', index, side, margin, baseIndex); 1007 ////console.log((index - (baseIndex || 0)) * (side + (margin || 0))); 1008 1009 return (index - (baseIndex || 0)) * (side + (margin || 0)); 1010} 1011 1012function getIndexByPos (pos, side, margin, baseIndex) { 1013 return -Math.round(pos / (side + (margin || 0)) - (baseIndex || 0)); 1014} 1015 1016function bindTransitionEnd ($el) { 1017 var elData = $el.data(); 1018 1019 if (elData.tEnd) return; 1020 1021 var el = $el[0], 1022 transitionEndEvent = { 1023 WebkitTransition: 'webkitTransitionEnd', 1024 MozTransition: 'transitionend', 1025 OTransition: 'oTransitionEnd otransitionend', 1026 msTransition: 'MSTransitionEnd', 1027 transition: 'transitionend' 1028 }; 1029 addEvent(el, transitionEndEvent[Modernizr.prefixed('transition')], function (e) { 1030 elData.tProp && e.propertyName.match(elData.tProp) && elData.onEndFn(); 1031 }); 1032 elData.tEnd = true; 1033} 1034 1035function afterTransition ($el, property, fn, time) { 1036 var ok, 1037 elData = $el.data(); 1038 1039 if (elData) { 1040 elData.onEndFn = function () { 1041 if (ok) return; 1042 ok = true; 1043 clearTimeout(elData.tT); 1044 fn(); 1045 }; 1046 elData.tProp = property; 1047 1048 // Passive call, just in case of fail of native transition-end event 1049 clearTimeout(elData.tT); 1050 elData.tT = setTimeout(function () { 1051 elData.onEndFn(); 1052 }, time * 1.5); 1053 1054 bindTransitionEnd($el); 1055 } 1056} 1057 1058 1059function stop ($el, left/*, _001*/) { 1060 if ($el.length) { 1061 var elData = $el.data(); 1062 if (CSS3) { 1063 $el.css(getDuration(0)); 1064 elData.onEndFn = noop; 1065 clearTimeout(elData.tT); 1066 } else { 1067 $el.stop(); 1068 } 1069 var lockedLeft = getNumber(left, function () { 1070 return readPosition($el); 1071 }); 1072 1073 $el.css(getTranslate(lockedLeft/*, _001*/));//.width(); // `.width()` for reflow 1074 return lockedLeft; 1075 } 1076} 1077 1078function getNumber () { 1079 var number; 1080 for (var _i = 0, _l = arguments.length; _i < _l; _i++) { 1081 number = _i ? arguments[_i]() : arguments[_i]; 1082 if (typeof number === 'number') { 1083 break; 1084 } 1085 } 1086 1087 return number; 1088} 1089 1090function edgeResistance (pos, edge) { 1091 return Math.round(pos + ((edge - pos) / 1.5)); 1092} 1093 1094function getProtocol () { 1095 getProtocol.p = getProtocol.p || (location.protocol === 'https:' ? 'https://' : 'http://'); 1096 return getProtocol.p; 1097} 1098 1099function parseHref (href) { 1100 var a = document.createElement('a'); 1101 a.href = href; 1102 return a; 1103} 1104 1105function findVideoId (href, forceVideo) { 1106 if (typeof href !== 'string') return href; 1107 href = parseHref(href); 1108 1109 var id, 1110 type; 1111 1112 if (href.host.match(/youtube\.com/) && href.search) { 1113 //.log(); 1114 id = href.search.split('v=')[1]; 1115 if (id) { 1116 var ampersandPosition = id.indexOf('&'); 1117 if (ampersandPosition !== -1) { 1118 id = id.substring(0, ampersandPosition); 1119 } 1120 type = 'youtube'; 1121 } 1122 } else if (href.host.match(/youtube\.com|youtu\.be/)) { 1123 id = href.pathname.replace(/^\/(embed\/|v\/)?/, '').replace(/\/.*/, ''); 1124 type = 'youtube'; 1125 } else if (href.host.match(/vimeo\.com/)) { 1126 type = 'vimeo'; 1127 id = href.pathname.replace(/^\/(video\/)?/, '').replace(/\/.*/, ''); 1128 } 1129 1130 if ((!id || !type) && forceVideo) { 1131 id = href.href; 1132 type = 'custom'; 1133 } 1134 1135 return id ? {id: id, type: type, s: href.search.replace(/^\?/, ''), p: getProtocol()} : false; 1136} 1137 1138function getVideoThumbs (dataFrame, data, fotorama) { 1139 var img, thumb, video = dataFrame.video; 1140 if (video.type === 'youtube') { 1141 thumb = getProtocol() + 'img.youtube.com/vi/' + video.id + '/default.jpg'; 1142 img = thumb.replace(/\/default.jpg$/, '/hqdefault.jpg'); 1143 dataFrame.thumbsReady = true; 1144 } else if (video.type === 'vimeo') { 1145 $.ajax({
1146 url: getProtocol() + 'vimeo.com/api/v2/video/' + video.id + '.json', 1147 dataType: 'jsonp', 1148 success: function (json) { 1149 dataFrame.thumbsReady = true; 1150 updateData(data, {img: json[0].thumbnail_large, thumb: json[0].thumbnail_small}, dataFrame.i, fotorama); 1151 } 1152 }); 1153 } else { 1154 dataFrame.thumbsReady = true; 1155 } 1156 1157 return { 1158 img: img, 1159 thumb: thumb 1160 } 1161} 1162 1163function updateData (data, _dataFrame, i, fotorama) { 1164 for (var _i = 0, _l = data.length; _i < _l; _i++) { 1165 var dataFrame = data[_i]; 1166 1167 if (dataFrame.i === i && dataFrame.thumbsReady) { 1168 var clear = {videoReady: true}; 1169 clear[STAGE_FRAME_KEY] = clear[NAV_THUMB_FRAME_KEY] = clear[NAV_DOT_FRAME_KEY] = false; 1170 1171 fotorama.splice(_i, 1, $.extend( 1172 {}, 1173 dataFrame, 1174 clear, 1175 _dataFrame 1176 )); 1177 1178 break; 1179 } 1180 } 1181} 1182 1183function getDataFromHtml ($el) { 1184 var data = []; 1185 1186 function getDataFromImg ($img, imgData, checkVideo) { 1187 var $child = $img.children('img').eq(0), 1188 _imgHref = $img.attr('href'), 1189 _imgAlt = $img.attr('alt'), 1190 _imgSrc = $img.attr('src'), 1191 _thumbSrc = $child.attr('src'), 1192 _video = imgData.video, 1193 video = checkVideo ? findVideoId(_imgHref, _video === true) : false; 1194 1195 if (video) { 1196 _imgHref = false; 1197 } else { 1198 video = _video; 1199 } 1200 1201 getDimensions($img, $child, $.extend(imgData, { 1202 video: video, 1203 img: imgData.img || _imgHref || _imgSrc || _thumbSrc || imgData.alt, 1204 thumb: imgData.thumb || _thumbSrc || _imgSrc || _imgHref || imgData.alt 1205 })); 1206 } 1207 1208 function getDimensions ($img, $child, imgData) { 1209 var separateThumbFLAG = imgData.thumb && imgData.img !== imgData.thumb, 1210 width = numberFromMeasure(imgData.width || $img.attr('width')), 1211 height = numberFromMeasure(imgData.height || $img.attr('height')), 1212 altText = $img.attr('alt'), 1213 alt = $img.attr('alt'), 1214 title = $img.attr('title'); 1215 1216 if (alt) 1217 { 1218 $.extend(imgData, { 1219 alt: alt 1220 }); 1221 } 1222 1223 if (title) { 1224 $.extend(imgData, { 1225 title: title 1226 }); 1227 } 1228 1229 $.extend(imgData, { 1230 width: width, 1231 height: height, 1232 thumbratio: getRatio(imgData.thumbratio || (numberFromMeasure(imgData.thumbwidth || ($child && $child.attr('width')) || separateThumbFLAG || width) / numberFromMeasure(imgData.thumbheight || ($child && $child.attr('height')) || separateThumbFLAG || height))) 1233 }); 1234 } 1235 1236 $el.children().each(function () { 1237 var $this = $(this), 1238 dataFrame = optionsToLowerCase($.extend($this.data(), {id: $this.attr('id')})); 1239 if ($this.is('a, img')) { 1240 getDataFromImg($this, dataFrame, true); 1241 } else if (!$this.is(':empty')) { 1242 getDimensions($this, null, $.extend(dataFrame, { 1243 html: this, 1244 _html: $this.html() // Because of IE 1245 })); 1246 } else return; 1247 data.push(dataFrame); 1248 }); 1249 debugger; 1250 return data; 1251} 1252 1253function isHidden (el) { 1254 return el.offsetWidth === 0 && el.offsetHeight === 0; 1255} 1256 1257function isDetached (el) { 1258 return !$.contains(document.documentElement, el); 1259} 1260 1261function waitFor (test, fn, timeout, i) { 1262 if (!waitFor.i) { 1263 waitFor.i = 1; 1264 waitFor.ii = [true]; 1265 } 1266 1267 i = i || waitFor.i; 1268 1269 if (typeof waitFor.ii[i] === 'undefined') { 1270 waitFor.ii[i] = true; 1271 } 1272 1273 if (test()) { 1274 fn(); 1275 } else { 1276 waitFor.ii[i] && setTimeout(function () { 1277 waitFor.ii[i] && waitFor(test, fn, timeout, i); 1278 }, timeout || 100); 1279 } 1280 1281 return waitFor.i++; 1282} 1283 1284waitFor.stop = function (i) { 1285 waitFor.ii[i] = false; 1286}; 1287 1288function setHash (hash) { 1289 //////console.time('setHash ' + hash); 1290 location.replace(location.protocol 1291 + '//' 1292 + location.host 1293 + location.pathname.replace(/^\/?/, '/') 1294 + location.search 1295 + '#' + hash); 1296 //////console.timeEnd('setHash ' + hash); 1297} 1298 1299function fit ($el, measuresToFit, method, position) { 1300 var elData = $el.data(), 1301 measures = elData.measures; 1302 1303 if (measures && (!elData.l || 1304 elData.l.W !== measures.width || 1305 elData.l.H !== measures.height || 1306 elData.l.r !== measures.ratio || 1307 elData.l.w !== measuresToFit.w || 1308 elData.l.h !== measuresToFit.h || 1309 elData.l.m !== method || 1310 elData.l.p !== position)) { 1311 1312 //console.log('fit'); 1313 1314 var width = measures.width, 1315 height = measures.height, 1316 ratio = measuresToFit.w / measuresToFit.h, 1317 biggerRatioFLAG = measures.ratio >= ratio, 1318 fitFLAG = method === 'scaledown', 1319 containFLAG = method === 'contain', 1320 coverFLAG = method === 'cover', 1321 pos = parsePosition(position); 1322 1323 if (biggerRatioFLAG && (fitFLAG || containFLAG) || !biggerRatioFLAG && coverFLAG) { 1324 width = minMaxLimit(measuresToFit.w, 0, fitFLAG ? width : Infinity); 1325 height = width / measures.ratio; 1326 } else if (biggerRatioFLAG && coverFLAG || !biggerRatioFLAG && (fitFLAG || containFLAG)) { 1327 height = minMaxLimit(measuresToFit.h, 0, fitFLAG ? height : Infinity); 1328 width = height * measures.ratio; 1329 } 1330 1331 $el.css({ 1332 width: width, 1333 height: height, 1334 left: numberFromWhatever(pos.x, measuresToFit.w - width), 1335 top: numberFromWhatever(pos.y, measuresToFit.h- height) 1336 });
1337 1338 elData.l = { 1339 W: measures.width, 1340 H: measures.height, 1341 r: measures.ratio, 1342 w: measuresToFit.w, 1343 h: measuresToFit.h, 1344 m: method, 1345 p: position 1346 }; 1347 } 1348 1349 return true; 1350} 1351 1352function setStyle ($el, style) { 1353 var el = $el[0]; 1354 if (el.styleSheet) { 1355 el.styleSheet.cssText = style; 1356 } else { 1357 $el.html(style); 1358 } 1359} 1360 1361function findShadowEdge (pos, min, max) { 1362 return min === max ? false : pos <= min ? 'left' : pos >= max ? 'right' : 'left right'; 1363} 1364 1365function getIndexFromHash (hash, data, ok, startindex) { 1366 if (!ok) return false; 1367 if (!isNaN(hash)) return hash - (startindex ? 0 : 1); 1368 1369 var index; 1370 1371 for (var _i = 0, _l = data.length; _i < _l; _i++) { 1372 var dataFrame = data[_i]; 1373 1374 if (dataFrame.id === hash) { 1375 index = _i; 1376 break; 1377 } 1378 } 1379 1380 return index; 1381} 1382 1383function smartClick ($el, fn, _options) { 1384 _options = _options || {}; 1385 1386 $el.each(function () { 1387 var $this = $(this), 1388 thisData = $this.data(), 1389 startEvent; 1390 1391 if (thisData.clickOn) return; 1392 1393 thisData.clickOn = true; 1394 1395 $.extend(touch($this, { 1396 onStart: function (e) { 1397 startEvent = e; 1398 (_options.onStart || noop).call(this, e); 1399 }, 1400 onMove: _options.onMove || noop, 1401 onTouchEnd: _options.onTouchEnd || noop, 1402 onEnd: function (result) { 1403 ////console.log('smartClick → result.moved', result.moved); 1404 if (result.moved) return; 1405 fn.call(this, startEvent); 1406 } 1407 }), {noMove: true}); 1408 }); 1409} 1410 1411function div (classes, child) { 1412 return '<div class="' + classes + '">' + (child || '') + '</div>'; 1413} 1414 1415// Fisher–Yates Shuffle 1416// http://bost.ocks.org/mike/shuffle/ 1417function shuffle (array) { 1418 // While there remain elements to shuffle 1419 var l = array.length; 1420 while (l) { 1421 // Pick a remaining element 1422 var i = Math.floor(Math.random() * l--); 1423 1424 // And swap it with the current element 1425 var t = array[l]; 1426 array[l] = array[i]; 1427 array[i] = t; 1428 } 1429 1430 return array; 1431} 1432 1433function clone (array) { 1434 return Object.prototype.toString.call(array) == '[object Array]' 1435 && $.map(array, function (frame) { 1436 return $.extend({}, frame); 1437 }); 1438} 1439 1440function lockScroll ($el, left, top) { 1441 $el 1442 .scrollLeft(left || 0) 1443 .scrollTop(top || 0); 1444} 1445 1446function optionsToLowerCase (options) { 1447 if (options) { 1448 var opts = {}; 1449 $.each(options, function (key, value) { 1450 opts[key.toLowerCase()] = value; 1451 }); 1452 1453 return opts; 1454 } 1455} 1456 1457function getRatio (_ratio) { 1458 if (!_ratio) return; 1459 var ratio = +_ratio; 1460 if (!isNaN(ratio)) { 1461 return ratio; 1462 } else { 1463 ratio = _ratio.split('/'); 1464 return +ratio[0] / +ratio[1] || undefined; 1465 } 1466} 1467 1468function addEvent (el, e, fn, bool) { 1469 if (!e) return; 1470 el.addEventListener ? el.addEventListener(e, fn, !!bool) : el.attachEvent('on'+e, fn); 1471} 1472 1473function elIsDisabled (el) { 1474 return !!el.getAttribute('disabled'); 1475} 1476 1477function disableAttr (FLAG) { 1478 return {tabindex: FLAG * -1 + '', disabled: FLAG}; 1479} 1480 1481function addEnterUp (el, fn) { 1482 addEvent(el, 'keyup', function (e) { 1483 elIsDisabled(el) || e.keyCode == 13 && fn.call(el, e); 1484 }); 1485} 1486 1487function addFocus (el, fn) { 1488 addEvent(el, 'focus', el.onfocusin = function (e) { 1489 fn.call(el, e); 1490 }, true); 1491} 1492 1493function stopEvent (e, stopPropagation) { 1494 e.preventDefault ? e.preventDefault() : (e.returnValue = false); 1495 stopPropagation && e.stopPropagation && e.stopPropagation(); 1496} 1497 1498function getDirectionSign (forward) { 1499 return forward ? '>' : '<'; 1500} 1501 1502function parsePosition (rule) { 1503 rule = (rule + '').split(/\s+/); 1504 return { 1505 x: measureIsValid(rule[0]) || FIFTYFIFTY, 1506 y: measureIsValid(rule[1]) || FIFTYFIFTY 1507 } 1508} 1509function slide ($el, options) { 1510 var elData = $el.data(), 1511 elPos = Math.round(options.pos), 1512 onEndFn = function () { 1513 elData.sliding = false; 1514 (options.onEnd || noop)(); 1515 }; 1516 1517 if (typeof options.overPos !== 'undefined' && options.overPos !== options.pos) { 1518 elPos = options.overPos; 1519 onEndFn = function () { 1520 slide($el, $.extend({}, options, {overPos: options.pos, time: Math.max(TRANSITION_DURATION, options.time / 2)})) 1521 }; 1522 } 1523 1524 ////////console.time('var translate = $.extend'); 1525 var translate = $.extend(getTranslate(elPos/*, options._001*/), options.width && {width: options.width}); 1526 ////////console.timeEnd('var translate = $.extend'); 1527 1528 elData.sliding = true; 1529 1530 if (CSS3) { 1531 $el.css($.extend(getDuration(options.time), translate)); 1532 if (options.time > 10) {
1533 ////////console.time('afterTransition'); 1534 afterTransition($el, 'transform', onEndFn, options.time); 1535 ////////console.timeEnd('afterTransition'); 1536 } else { 1537 onEndFn(); 1538 } 1539 } else { 1540 $el.stop().animate(translate, options.time, BEZIER, onEndFn); 1541 } 1542} 1543 1544function fade ($el1, $el2, $frames, options, fadeStack, chain) { 1545 var chainedFLAG = typeof chain !== 'undefined'; 1546 if (!chainedFLAG) { 1547 fadeStack.push(arguments); 1548 Array.prototype.push.call(arguments, fadeStack.length); 1549 if (fadeStack.length > 1) return; 1550 } 1551 1552 $el1 = $el1 || $($el1); 1553 $el2 = $el2 || $($el2); 1554 1555 var _$el1 = $el1[0], 1556 _$el2 = $el2[0], 1557 crossfadeFLAG = options.method === 'crossfade', 1558 onEndFn = function () { 1559 if (!onEndFn.done) { 1560 onEndFn.done = true; 1561 var args = (chainedFLAG || fadeStack.shift()) && fadeStack.shift(); 1562 args && fade.apply(this, args); 1563 (options.onEnd || noop)(!!args); 1564 } 1565 }, 1566 time = options.time / (chain || 1); 1567 1568 $frames.removeClass(fadeRearClass + ' ' + fadeFrontClass); 1569 1570 $el1 1571 .stop() 1572 .addClass(fadeRearClass); 1573 $el2 1574 .stop() 1575 .addClass(fadeFrontClass); 1576 1577 crossfadeFLAG && _$el2 && $el1.fadeTo(0, 0); 1578 1579 $el1.fadeTo(crossfadeFLAG ? time : 0, 1, crossfadeFLAG && onEndFn); 1580 $el2.fadeTo(time, 0, onEndFn); 1581 1582 (_$el1 && crossfadeFLAG) || _$el2 || onEndFn(); 1583} 1584var lastEvent, 1585 moveEventType, 1586 preventEvent, 1587 preventEventTimeout; 1588 1589function extendEvent (e) { 1590 var touch = (e.touches || [])[0] || e; 1591 e._x = touch.pageX; 1592 e._y = touch.clientY; 1593 e._now = $.now(); 1594} 1595 1596function touch ($el, options) { 1597 var el = $el[0], 1598 tail = {}, 1599 touchEnabledFLAG, 1600 startEvent, 1601 $target, 1602 controlTouch, 1603 touchFLAG, 1604 targetIsSelectFLAG, 1605 targetIsLinkFlag, 1606 tolerance, 1607 moved; 1608 1609 function onStart (e) { 1610 $target = $(e.target); 1611 tail.checked = targetIsSelectFLAG = targetIsLinkFlag = moved = false; 1612 1613 if (touchEnabledFLAG 1614 || tail.flow 1615 || (e.touches && e.touches.length > 1) 1616 || e.which > 1 1617 || (lastEvent && lastEvent.type !== e.type && preventEvent) 1618 || (targetIsSelectFLAG = options.select && $target.is(options.select, el))) return targetIsSelectFLAG; 1619 1620 touchFLAG = e.type === 'touchstart'; 1621 targetIsLinkFlag = $target.is('a, a *', el); 1622 controlTouch = tail.control; 1623 1624 tolerance = (tail.noMove || tail.noSwipe || controlTouch) ? 16 : !tail.snap ? 4 : 0; 1625 1626 extendEvent(e); 1627 1628 startEvent = lastEvent = e; 1629 moveEventType = e.type.replace(/down|start/, 'move').replace(/Down/, 'Move'); 1630 1631 (options.onStart || noop).call(el, e, {control: controlTouch, $target: $target}); 1632 1633 touchEnabledFLAG = tail.flow = true; 1634 1635 if (!touchFLAG || tail.go) stopEvent(e); 1636 } 1637 1638 function onMove (e) { 1639 if ((e.touches && e.touches.length > 1) 1640 || (MS_POINTER && !e.isPrimary) 1641 || moveEventType !== e.type 1642 || !touchEnabledFLAG) { 1643 touchEnabledFLAG && onEnd(); 1644 (options.onTouchEnd || noop)(); 1645 return; 1646 } 1647 1648 extendEvent(e); 1649 1650 var xDiff = Math.abs(e._x - startEvent._x), // opt _x → _pageX 1651 yDiff = Math.abs(e._y - startEvent._y), 1652 xyDiff = xDiff - yDiff, 1653 xWin = (tail.go || tail.x || xyDiff >= 0) && !tail.noSwipe, 1654 yWin = xyDiff < 0; 1655 1656 if (touchFLAG && !tail.checked) { 1657 if (touchEnabledFLAG = xWin) { 1658 stopEvent(e); 1659 } 1660 } else { 1661 ////console.log('onMove e.preventDefault'); 1662 stopEvent(e); 1663 (options.onMove || noop).call(el, e, {touch: touchFLAG}); 1664 } 1665 1666 if (!moved && Math.sqrt(Math.pow(xDiff, 2) + Math.pow(yDiff, 2)) > tolerance) { 1667 moved = true; 1668 } 1669 1670 tail.checked = tail.checked || xWin || yWin; 1671 } 1672 1673 function onEnd (e) { 1674 //////console.time('touch.js onEnd'); 1675 1676 (options.onTouchEnd || noop)(); 1677 1678 var _touchEnabledFLAG = touchEnabledFLAG; 1679 tail.control = touchEnabledFLAG = false; 1680 1681 if (_touchEnabledFLAG) { 1682 tail.flow = false; 1683 } 1684 1685 if (!_touchEnabledFLAG || (targetIsLinkFlag && !tail.checked)) return; 1686 1687 e && stopEvent(e); 1688 1689 preventEvent = true; 1690 clearTimeout(preventEventTimeout); 1691 preventEventTimeout = setTimeout(function () { 1692 preventEvent = false; 1693 }, 1000); 1694 1695 (options.onEnd || noop).call(el, {moved: moved, $target: $target, control: controlTouch, touch: touchFLAG, startEvent: startEvent, aborted: !e || e.type === 'MSPointerCancel'}); 1696 //////console.timeEnd('touch.js onEnd'); 1697 } 1698 1699 function onOtherStart () { 1700 if (tail.flow) return; 1701 setTimeout(function () { 1702 tail.flow = true; 1703 }, 10); 1704 } 1705 1706 function onOtherEnd () { 1707 if (!tail.flow) return; 1708 setTimeout(function () { 1709 tail.flow = false; 1710 }, TOUCH_TIMEOUT); 1711 } 1712 1713 if (MS_POINTER) { 1714 addEvent(el, 'MSPointerDown', onStart); 1715 addEvent(document, 'MSPointerMove', onMove); 1716 addEvent(document,'MSPointerCancel', onEnd); 1717 addEvent(document, 'MSPointerUp', onEnd); 1718 } else { 1719 addEvent(el, 'touchstart', onStart); 1720 addEvent(el, 'touchmove', onMove); 1721 addEvent(el, 'touchend', onEnd); 1722 1723 addEvent(document, 'touchstart', onOtherStart); 1724 addEvent(document, 'touchend', onOtherEnd); 1725 addEvent(document, 'touchcancel', onOtherEnd); 1726 1727 $WINDOW.on('scroll', onOtherEnd); 1728 1729 $el.on('mousedown', onStart); 1730 $DOCUMENT 1731 .on('mousemove', onMove) 1732 .on('mouseup', onEnd); 1733 } 1734 1735 $el.on('click', 'a', function (e) { 1736 tail.checked && stopEvent(e); 1737 }); 1738 1739 return tail; 1740} 1741 1742function moveOnTouch ($el, options) { 1743 var el = $el[0], 1744 elData = $el.data(), 1745 tail = {}, 1746 startCoo, 1747 coo, 1748 startElPos, 1749 moveElPos, 1750 edge, 1751 moveTrack, 1752 startTime, 1753 endTime, 1754 min, 1755 max, 1756 snap, 1757 slowFLAG, 1758 controlFLAG, 1759 moved, 1760 tracked; 1761 1762 function startTracking (e, noStop) { 1763 tracked = true; 1764 startCoo = coo = e._x; 1765 startTime = e._now; 1766 1767 moveTrack = [ 1768 [startTime, startCoo] 1769 ]; 1770 1771 startElPos = moveElPos = tail.noMove || noStop ? 0 : stop($el, (options.getPos || noop)()/*, options._001*/); 1772 1773 (options.onStart || noop).call(el, e); 1774 } 1775 1776 function onStart (e, result) { 1777 min = tail.min; 1778 max = tail.max; 1779 snap = tail.snap; 1780 1781 slowFLAG = e.altKey; 1782 tracked = moved = false; 1783 1784 controlFLAG = result.control; 1785 1786 if (!controlFLAG && !elData.sliding) { 1787 startTracking(e); 1788 } 1789 } 1790 1791 function onMove (e, result) { 1792 if (!tail.noSwipe) { 1793 if (!tracked) { 1794 startTracking(e); 1795 } 1796 1797 coo = e._x; 1798 1799 moveTrack.push([e._now, coo]); 1800 1801 moveElPos = startElPos - (startCoo - coo); 1802 1803 edge = findShadowEdge(moveElPos, min, max); 1804 1805 if (moveElPos <= min) { 1806 moveElPos = edgeResistance(moveElPos, min); 1807 } else if (moveElPos >= max) { 1808 moveElPos = edgeResistance(moveElPos, max); 1809 } 1810 1811 if (!tail.noMove) { 1812 $el.css(getTranslate(moveElPos/*, options._001*/)); 1813 if (!moved) { 1814 moved = true; 1815 // only for mouse 1816 result.touch || MS_POINTER || $el.addClass(grabbingClass); 1817 } 1818 1819 (options.onMove || noop).call(el, e, {pos: moveElPos, edge: edge});
1820 } 1821 } 1822 } 1823 1824 function onEnd (result) { 1825 //////console.time('moveontouch.js onEnd'); 1826 if (tail.noSwipe && result.moved) return; 1827 1828 if (!tracked) { 1829 startTracking(result.startEvent, true); 1830 } 1831 1832 ////console.log('onEnd'); 1833 1834 result.touch || MS_POINTER || $el.removeClass(grabbingClass); 1835 1836 endTime = $.now(); 1837 1838 var _backTimeIdeal = endTime - TOUCH_TIMEOUT, 1839 _backTime, 1840 _timeDiff, 1841 _timeDiffLast, 1842 backTime = null, 1843 backCoo, 1844 virtualPos, 1845 limitPos, 1846 newPos, 1847 overPos, 1848 time = TRANSITION_DURATION, 1849 speed, 1850 friction = options.friction; 1851 1852 for (var _i = moveTrack.length - 1; _i >= 0; _i--) { 1853 _backTime = moveTrack[_i][0]; 1854 _timeDiff = Math.abs(_backTime - _backTimeIdeal); 1855 if (backTime === null || _timeDiff < _timeDiffLast) { 1856 backTime = _backTime; 1857 backCoo = moveTrack[_i][1]; 1858 } else if (backTime === _backTimeIdeal || _timeDiff > _timeDiffLast) { 1859 break; 1860 } 1861 _timeDiffLast = _timeDiff; 1862 } 1863 1864 newPos = minMaxLimit(moveElPos, min, max); 1865 1866 var cooDiff = backCoo - coo, 1867 forwardFLAG = cooDiff >= 0, 1868 timeDiff = endTime - backTime, 1869 longTouchFLAG = timeDiff > TOUCH_TIMEOUT, 1870 swipeFLAG = !longTouchFLAG && moveElPos !== startElPos && newPos === moveElPos; 1871 1872 if (snap) { 1873 newPos = minMaxLimit(Math[swipeFLAG ? (forwardFLAG ? 'floor' : 'ceil') : 'round'](moveElPos / snap) * snap, min, max); 1874 min = max = newPos; 1875 } 1876 1877 if (swipeFLAG && (snap || newPos === moveElPos)) { 1878 speed = -(cooDiff / timeDiff); 1879 time *= minMaxLimit(Math.abs(speed), options.timeLow, options.timeHigh); 1880 virtualPos = Math.round(moveElPos + speed * time / friction); 1881 1882 if (!snap) { 1883 newPos = virtualPos; 1884 } 1885 1886 if (!forwardFLAG && virtualPos > max || forwardFLAG && virtualPos < min) { 1887 limitPos = forwardFLAG ? min : max; 1888 overPos = virtualPos - limitPos; 1889 if (!snap) { 1890 newPos = limitPos; 1891 } 1892 overPos = minMaxLimit(newPos + overPos * .03, limitPos - 50, limitPos + 50); 1893 time = Math.abs((moveElPos - overPos) / (speed / friction)); 1894 } 1895 } 1896 1897 time *= slowFLAG ? 10 : 1; 1898 1899 (options.onEnd || noop).call(el, $.extend(result, {moved: result.moved || longTouchFLAG && snap, pos: moveElPos, newPos: newPos, overPos: overPos, time: time})); 1900 } 1901 1902 tail = $.extend(touch(options.$wrap, $.extend({}, options, { 1903 onStart: onStart, 1904 onMove: onMove, 1905 onEnd: onEnd 1906 })), tail); 1907 1908 return tail; 1909} 1910function wheel ($el, options) { 1911 var el = $el[0], 1912 lockFLAG, 1913 lastDirection, 1914 lastNow, 1915 tail = { 1916 prevent: {} 1917 }; 1918 1919 addEvent(el, WHEEL, function (e) { 1920 var yDelta = e.wheelDeltaY || -1 * e.deltaY || 0, 1921 xDelta = e.wheelDeltaX || -1 * e.deltaX || 0, 1922 xWin = Math.abs(xDelta) && !Math.abs(yDelta), 1923 direction = getDirectionSign(xDelta < 0), 1924 sameDirection = lastDirection === direction, 1925 now = $.now(), 1926 tooFast = now - lastNow < TOUCH_TIMEOUT; 1927 1928 lastDirection = direction; 1929 lastNow = now; 1930 1931 if (!xWin || !tail.ok || tail.prevent[direction] && !lockFLAG) { 1932 return; 1933 } else { 1934 stopEvent(e, true); 1935 if (lockFLAG && sameDirection && tooFast) { 1936 return; 1937 } 1938 } 1939 1940 if (options.shift) { 1941 lockFLAG = true; 1942 clearTimeout(tail.t); 1943 tail.t = setTimeout(function () { 1944 lockFLAG = false; 1945 }, SCROLL_LOCK_TIMEOUT); 1946 } 1947 1948 (options.onEnd || noop)(e, options.shift ? direction : xDelta); 1949 1950 }); 1951 1952 return tail; 1953} 1954jQuery.Fotorama = function ($fotorama, opts) { 1955 $HTML = $('html'); 1956 $BODY = $('body'); 1957 1958 var that = this, 1959 stamp = $.now(), 1960 stampClass = _fotoramaClass + stamp, 1961 fotorama = $fotorama[0], 1962 data, 1963 dataFrameCount = 1, 1964 fotoramaData = $fotorama.data(), 1965 size, 1966 1967 $style = $('<style></style>'), 1968 1969 $anchor = $(div(hiddenClass)), 1970 $wrap = $(div(wrapClass)), 1971 $stage = $(div(stageClass)).appendTo($wrap), 1972 stage = $stage[0], 1973 1974 $stageShaft = $(div(stageShaftClass)).appendTo($stage), 1975 $stageFrame = $(), 1976 $arrPrev = $(div(arrClass + ' ' + arrPrevClass + buttonAttributes)), 1977 $arrNext = $(div(arrClass + ' ' + arrNextClass + buttonAttributes)), 1978 $arrs = $arrPrev.add($arrNext).appendTo($stage), 1979 $navWrap = $(div(navWrapClass)), 1980 $nav = $(div(navClass)).appendTo($navWrap), 1981 $navShaft = $(div(navShaftClass)).appendTo($nav), 1982 $navFrame, 1983 $navDotFrame = $(), 1984 $navThumbFrame = $(), 1985 1986 stageShaftData = $stageShaft.data(), 1987 navShaftData = $navShaft.data(), 1988 1989 $thumbBorder = $(div(thumbBorderClass)).appendTo($navShaft), 1990 1991 $fullscreenIcon = $(div(fullscreenIconClass + buttonAttributes)), 1992 fullscreenIcon = $fullscreenIcon[0], 1993 $videoPlay = $(div(videoPlayClass)), 1994 $videoClose = $(div(videoCloseClass)).appendTo($stage), 1995 videoClose = $videoClose[0], 1996 1997 spinner, 1998 $spinner = $(div(spinnerClass)), 1999 2000 $videoPlaying, 2001 2002 activeIndex = false, 2003 activeFrame, 2004 activeIndexes, 2005 repositionIndex, 2006 dirtyIndex, 2007 lastActiveIndex, 2008 prevIndex, 2009 nextIndex, 2010 nextAutoplayIndex, 2011 startIndex, 2012 2013 o_loop, 2014 o_nav, 2015 o_navThumbs, 2016 o_navTop, 2017 o_allowFullScreen, 2018 o_nativeFullScreen, 2019 o_fade, 2020 o_thumbSide, 2021 o_thumbSide2, 2022 o_transitionDuration, 2023 o_transition, 2024 o_shadows, 2025 o_rtl, 2026 o_keyboard, 2027 lastOptions = {}, 2028 2029 measures = {}, 2030 measuresSetFLAG, 2031 2032 stageShaftTouchTail = {}, 2033 stageWheelTail = {}, 2034 navShaftTouchTail = {}, 2035 navWheelTail = {}, 2036 2037 scrollTop, 2038 scrollLeft, 2039 2040 showedFLAG, 2041 pausedAutoplayFLAG, 2042 stoppedAutoplayFLAG, 2043 2044 toDeactivate = {}, 2045 toDetach = {}, 2046 2047 measuresStash, 2048 2049 touchedFLAG, 2050 2051 hoverFLAG, 2052
2053 navFrameKey, 2054 stageLeft = 0, 2055 2056 fadeStack = []; 2057 2058 $wrap[STAGE_FRAME_KEY] = $(div(stageFrameClass)); 2059 $wrap[NAV_THUMB_FRAME_KEY] = $(div(navFrameClass + ' ' + navFrameThumbClass + buttonAttributes, div(thumbClass))); 2060 $wrap[NAV_DOT_FRAME_KEY] = $(div(navFrameClass + ' ' + navFrameDotClass + buttonAttributes, div(dotClass))); 2061 2062 toDeactivate[STAGE_FRAME_KEY] = []; 2063 toDeactivate[NAV_THUMB_FRAME_KEY] = []; 2064 toDeactivate[NAV_DOT_FRAME_KEY] = []; 2065 toDetach[STAGE_FRAME_KEY] = {}; 2066 2067 $wrap 2068 .addClass(CSS3 ? wrapCss3Class : wrapCss2Class) 2069 .toggleClass(wrapNoControlsClass, !opts.controlsonstart); 2070 2071 fotoramaData.fotorama = this; 2072 2073 function checkForVideo () { 2074 $.each(data, function (i, dataFrame) { 2075 if (!dataFrame.i) { 2076 dataFrame.i = dataFrameCount++; 2077 var video = findVideoId(dataFrame.video, true); 2078 if (video) { 2079 var thumbs = {}; 2080 dataFrame.video = video; 2081 if (!dataFrame.img && !dataFrame.thumb) { 2082 thumbs = getVideoThumbs(dataFrame, data, that); 2083 } else { 2084 dataFrame.thumbsReady = true; 2085 } 2086 updateData(data, {img: thumbs.img, thumb: thumbs.thumb}, dataFrame.i, that); 2087 } 2088 } 2089 }); 2090 } 2091 2092 function allowKey (key) { 2093 return o_keyboard[key] || that.fullScreen; 2094 } 2095 2096 function bindGlobalEvents (FLAG) { 2097 var keydownCommon = 'keydown.' + _fotoramaClass, 2098 localStamp = _fotoramaClass + stamp, 2099 keydownLocal = 'keydown.' + localStamp, 2100 resizeLocal = 'resize.' + localStamp + ' ' + 'orientationchange.' + localStamp; 2101 2102 if (FLAG) { 2103 $DOCUMENT 2104 .on(keydownLocal, function (e) { 2105 var catched, 2106 index; 2107 2108 if ($videoPlaying && e.keyCode === 27) { 2109 catched = true; 2110 unloadVideo($videoPlaying, true, true); 2111 } else if (that.fullScreen || (opts.keyboard && !that.index)) { 2112 if (e.keyCode === 27) { 2113 catched = true; 2114 that.cancelFullScreen(); 2115 } else if ((e.shiftKey && e.keyCode === 32 && allowKey('space')) || (e.keyCode === 37 && allowKey('left')) || (e.keyCode === 38 && allowKey('up'))) { 2116 index = '<'; 2117 } else if ((e.keyCode === 32 && allowKey('space')) || (e.keyCode === 39 && allowKey('right')) || (e.keyCode === 40 && allowKey('down'))) { 2118 index = '>'; 2119 } else if (e.keyCode === 36 && allowKey('home')) { 2120 index = '<<'; 2121 } else if (e.keyCode === 35 && allowKey('end')) { 2122 index = '>>'; 2123 } 2124 } 2125 2126 (catched || index) && stopEvent(e); 2127 index && that.show({index: index, slow: e.altKey, user: true}); 2128 }); 2129 2130 if (!that.index) { 2131 $DOCUMENT 2132 .off(keydownCommon) 2133 .on(keydownCommon, 'textarea, input, select', function (e) { 2134 !$BODY.hasClass(_fullscreenClass) && e.stopPropagation(); 2135 }); 2136 } 2137 2138 $WINDOW.on(resizeLocal, that.resize); 2139 } else { 2140 $DOCUMENT.off(keydownLocal); 2141 $WINDOW.off(resizeLocal); 2142 } 2143 } 2144 2145 function appendElements (FLAG) { 2146 if (FLAG === appendElements.f) return; 2147 2148 if (FLAG) { 2149 $fotorama 2150 .html('') 2151 .addClass(_fotoramaClass + ' ' + stampClass) 2152 .append($wrap) 2153 .before($style) 2154 .before($anchor); 2155 2156 addInstance(that); 2157 } else { 2158 $wrap.detach(); 2159 $style.detach(); 2160 $anchor.detach(); 2161 $fotorama 2162 .html(fotoramaData.urtext) 2163 .removeClass(stampClass); 2164 2165 hideInstance(that); 2166 } 2167 2168 bindGlobalEvents(FLAG); 2169 appendElements.f = FLAG; 2170 } 2171 2172 function setData () { 2173 data = that.data = data || clone(opts.data) || getDataFromHtml($fotorama); 2174 size = that.size = data.length; 2175 2176 !ready.ok && opts.shuffle && shuffle(data); 2177 2178 checkForVideo(); 2179 2180 activeIndex = limitIndex(activeIndex); 2181 2182 size && appendElements(true); 2183 } 2184
2185 function stageNoMove () { 2186 var _noMove = (size < 2 && !opts.enableifsingleframe) || $videoPlaying; 2187 stageShaftTouchTail.noMove = _noMove || o_fade; 2188 stageShaftTouchTail.noSwipe = _noMove || !opts.swipe; 2189 2190 !o_transition && $stageShaft.toggleClass(grabClass, !opts.click && !stageShaftTouchTail.noMove && !stageShaftTouchTail.noSwipe); 2191 MS_POINTER && $wrap.toggleClass(wrapPanYClass, !stageShaftTouchTail.noSwipe); 2192 } 2193 2194 function setAutoplayInterval (interval) { 2195 if (interval === true) interval = ''; 2196 opts.autoplay = Math.max(+interval || AUTOPLAY_INTERVAL, o_transitionDuration * 1.5); 2197 } 2198 2199 /** 2200 * Options on the fly 2201 * */ 2202 function setOptions () { 2203 that.options = opts = optionsToLowerCase(opts); 2204 2205 o_fade = (opts.transition === 'crossfade' || opts.transition === 'dissolve'); 2206 2207 o_loop = opts.loop && (size > 2 || (o_fade && (!o_transition || o_transition !== 'slide'))); 2208 2209 o_transitionDuration = +opts.transitionduration || TRANSITION_DURATION; 2210 2211 o_rtl = opts.direction === 'rtl'; 2212 2213 o_keyboard = $.extend({}, opts.keyboard && KEYBOARD_OPTIONS, opts.keyboard); 2214 2215 var classes = {add: [], remove: []}; 2216 2217 function addOrRemoveClass (FLAG, value) { 2218 classes[FLAG ? 'add' : 'remove'].push(value); 2219 } 2220 2221 if (size > 1 || opts.enableifsingleframe) { 2222 o_nav = opts.nav; 2223 o_navTop = opts.navposition === 'top'; 2224 classes.remove.push(selectClass); 2225 2226 $arrs.toggle(!!opts.arrows); 2227 } else { 2228 o_nav = false; 2229 $arrs.hide(); 2230 } 2231 2232 spinnerStop(); 2233 spinner = new Spinner($.extend(spinnerDefaults, opts.spinner, spinnerOverride, {direction: o_rtl ? -1 : 1})); 2234 2235 arrsUpdate(); 2236 stageWheelUpdate(); 2237 2238 if (opts.autoplay) setAutoplayInterval(opts.autoplay); 2239 2240 o_thumbSide = numberFromMeasure(opts.thumbwidth) || THUMB_SIZE; 2241 o_thumbSide2 = numberFromMeasure(opts.thumbheight) || THUMB_SIZE; 2242 2243 stageWheelTail.ok = navWheelTail.ok = opts.trackpad && !SLOW; 2244 2245 stageNoMove(); 2246 2247 extendMeasures(opts, [measures]); 2248 2249 o_navThumbs = o_nav === 'thumbs'; 2250 2251 if (o_navThumbs) { 2252 frameDraw(size, 'navThumb'); 2253 2254 $navFrame = $navThumbFrame; 2255 navFrameKey = NAV_THUMB_FRAME_KEY; 2256 2257 setStyle($style, $.Fotorama.jst.style({w: o_thumbSide, h: o_thumbSide2, b: opts.thumbborderwidth, m: opts.thumbmargin, s: stamp, q: !COMPAT})); 2258 2259 $nav 2260 .addClass(navThumbsClass) 2261 .removeClass(navDotsClass); 2262 } else if (o_nav === 'dots') { 2263 frameDraw(size, 'navDot'); 2264 2265 $navFrame = $navDotFrame; 2266 navFrameKey = NAV_DOT_FRAME_KEY; 2267 2268 $nav 2269 .addClass(navDotsClass) 2270 .removeClass(navThumbsClass); 2271 } else { 2272 o_nav = false; 2273 $nav.removeClass(navThumbsClass + ' ' + navDotsClass); 2274 } 2275 2276 if (o_nav) { 2277 if (o_navTop) { 2278 $navWrap.insertBefore($stage); 2279 } else { 2280 $navWrap.insertAfter($stage); 2281 } 2282 frameAppend.nav = false; 2283 frameAppend($navFrame, $navShaft, 'nav'); 2284 } 2285 2286 o_allowFullScreen = opts.allowfullscreen; 2287 2288 if (o_allowFullScreen) { 2289 $fullscreenIcon.prependTo($stage); 2290 o_nativeFullScreen = FULLSCREEN && o_allowFullScreen === 'native'; 2291 } else { 2292 $fullscreenIcon.detach(); 2293 o_nativeFullScreen = false; 2294 } 2295 2296 addOrRemoveClass(o_fade, wrapFadeClass); 2297 addOrRemoveClass(!o_fade, wrapSlideClass); 2298 addOrRemoveClass(!opts.captions, wrapNoCaptionsClass); 2299 addOrRemoveClass(o_rtl, wrapRtlClass); 2300 addOrRemoveClass(opts.arrows !== 'always', wrapToggleArrowsClass); 2301 2302 o_shadows = opts.shadows && !SLOW; 2303 addOrRemoveClass(!o_shadows, wrapNoShadowsClass); 2304 2305 $wrap
2306 .addClass(classes.add.join(' ')) 2307 .removeClass(classes.remove.join(' ')); 2308 2309 lastOptions = $.extend({}, opts); 2310 } 2311 2312 function normalizeIndex (index) { 2313 return index < 0 ? (size + (index % size)) % size : index >= size ? index % size : index; 2314 } 2315 2316 function limitIndex (index) { 2317 return minMaxLimit(index, 0, size - 1); 2318 } 2319 2320 function edgeIndex (index) { 2321 return o_loop ? normalizeIndex(index) : limitIndex(index); 2322 } 2323 2324 function getPrevIndex (index) { 2325 return index > 0 || o_loop ? index - 1 : false; 2326 } 2327 2328 function getNextIndex (index) { 2329 return index < size - 1 || o_loop ? index + 1 : false; 2330 } 2331 2332 function setStageShaftMinmaxAndSnap () { 2333 stageShaftTouchTail.min = o_loop ? -Infinity : -getPosByIndex(size - 1, measures.w, opts.margin, repositionIndex); 2334 stageShaftTouchTail.max = o_loop ? Infinity : -getPosByIndex(0, measures.w, opts.margin, repositionIndex); 2335 stageShaftTouchTail.snap = measures.w + opts.margin; 2336 } 2337 2338 function setNavShaftMinMax () { 2339 ////////console.log('setNavShaftMinMax', measures.nw); 2340 navShaftTouchTail.min = Math.min(0, measures.nw - $navShaft.width()); 2341 navShaftTouchTail.max = 0; 2342 $navShaft.toggleClass(grabClass, !(navShaftTouchTail.noMove = navShaftTouchTail.min === navShaftTouchTail.max)); 2343 } 2344 2345 function eachIndex (indexes, type, fn) { 2346 if (typeof indexes === 'number') { 2347 indexes = new Array(indexes); 2348 var rangeFLAG = true; 2349 } 2350 return $.each(indexes, function (i, index) { 2351 if (rangeFLAG) index = i; 2352 if (typeof index === 'number') { 2353 var dataFrame = data[normalizeIndex(index)]; 2354 2355 if (dataFrame) { 2356 var key = '$' + type + 'Frame', 2357 $frame = dataFrame[key]; 2358 2359 fn.call(this, i, index, dataFrame, $frame, key, $frame && $frame.data()); 2360 } 2361 } 2362 }); 2363 } 2364 2365 function setMeasures (width, height, ratio, index) { 2366 if (!measuresSetFLAG || (measuresSetFLAG === '*' && index === startIndex)) { 2367 2368 //////console.log('setMeasures', index, opts.width, opts.height); 2369 2370 width = measureIsValid(opts.width) || measureIsValid(width) || WIDTH;
2371 height = measureIsValid(opts.height) || measureIsValid(height) || HEIGHT; 2372 that.resize({ 2373 width: width, 2374 ratio: opts.ratio || ratio || width / height 2375 }, 0, index !== startIndex && '*'); 2376 } 2377 } 2378 2379 function loadImg (indexes, type, specialMeasures, method, position, again) { 2380 eachIndex(indexes, type, function (i, index, dataFrame, $frame, key, frameData) { 2381 2382 if (!$frame) return; 2383 2384 var fullFLAG = that.fullScreen && dataFrame.full && dataFrame.full !== dataFrame.img && !frameData.$full && type === 'stage'; 2385 2386 if (frameData.$img && !again && !fullFLAG) return; 2387 2388 var img = new Image(), 2389 $img = $(img), 2390 imgData = $img.data(); 2391 2392 frameData[fullFLAG ? '$full' : '$img'] = $img; 2393 2394 var srcKey = type === 'stage' ? (fullFLAG ? 'full' : 'img') : 'thumb', 2395 src = dataFrame[srcKey], 2396 dummy = fullFLAG ? null : dataFrame[type === 'stage' ? 'thumb' : 'img']; 2397 2398 if (type === 'navThumb') $frame = frameData.$wrap; 2399 2400 function triggerTriggerEvent (event) { 2401 var _index = normalizeIndex(index); 2402 triggerEvent(event, { 2403 index: _index, 2404 src: src, 2405 frame: data[_index] 2406 }); 2407 } 2408 2409 function error () { 2410 $img.remove(); 2411 2412 $.Fotorama.cache[src] = 'error'; 2413 2414 if ((!dataFrame.html || type !== 'stage') && dummy && dummy !== src) { 2415 dataFrame[srcKey] = src = dummy; 2416 loadImg([index], type, specialMeasures, method, position, true); 2417 } else { 2418 if (src && !dataFrame.html && !fullFLAG) { 2419 $frame 2420 .trigger('f:error') 2421 .removeClass(loadingClass) 2422 .addClass(errorClass); 2423 2424 triggerTriggerEvent('error'); 2425 } else if (type === 'stage') { 2426 $frame 2427 .trigger('f:load') 2428 .removeClass(loadingClass + ' ' + errorClass) 2429 .addClass(loadedClass); 2430 2431 triggerTriggerEvent('load'); 2432 setMeasures(); 2433 } 2434 2435 frameData.state = 'error'; 2436 2437 if (size > 1 && data[index] === dataFrame && !dataFrame.html && !dataFrame.deleted && !dataFrame.video && !fullFLAG) { 2438 dataFrame.deleted = true; 2439 that.splice(index, 1); 2440 } 2441 } 2442 } 2443 2444 function loaded () { 2445 //////console.log('loaded: ' + src); 2446 2447 ////console.log('$.Fotorama.measures[src]', $.Fotorama.measures[src]); 2448 2449 $.Fotorama.measures[src] = imgData.measures = $.Fotorama.measures[src] || { 2450 width: img.width, 2451 height: img.height, 2452 ratio: img.width / img.height 2453 }; 2454 2455 setMeasures(imgData.measures.width, imgData.measures.height, imgData.measures.ratio, index); 2456 2457 $img 2458 .off('load error') 2459 .addClass(imgClass + (fullFLAG ? ' ' + imgFullClass : '')) 2460 .prependTo($frame); 2461 2462 fit($img, ($.isFunction(specialMeasures) ? specialMeasures() : specialMeasures) || measures, method || dataFrame.fit || opts.fit, position || dataFrame.position || opts.position); 2463 2464 $.Fotorama.cache[src] = frameData.state = 'loaded'; 2465 2466 setTimeout(function () { 2467 $frame 2468 .trigger('f:load') 2469 .removeClass(loadingClass + ' ' + errorClass) 2470 .addClass(loadedClass + ' ' + (fullFLAG ? loadedFullClass : loadedImgClass)); 2471 2472 if (type === 'stage') { 2473 triggerTriggerEvent('load'); 2474 } else if (dataFrame.thumbratio === AUTO || !dataFrame.thumbratio && opts.thumbratio === AUTO) { 2475 // danger! reflow for all thumbnails 2476 dataFrame.thumbratio = imgData.measures.ratio; 2477 reset(); 2478 } 2479 }, 0); 2480 } 2481 2482 if (!src) { 2483 error(); 2484 return; 2485 } 2486 2487 function waitAndLoad () { 2488 var _i = 10; 2489 waitFor(function () { 2490 return !touchedFLAG || !_i-- && !SLOW; 2491 }, function () { 2492 loaded(); 2493 }); 2494 } 2495 2496 if (!$.Fotorama.cache[src]) { 2497 $.Fotorama.cache[src] = '*'; 2498 2499 $img 2500 .on('load', waitAndLoad) 2501 .on('error', error); 2502 } else { 2503 (function justWait () { 2504 if ($.Fotorama.cache[src] === 'error') { 2505 error(); 2506 } else if ($.Fotorama.cache[src] === 'loaded') { 2507 ////console.log('take from cache: ' + src);
2508 setTimeout(waitAndLoad, 0); 2509 } else { 2510 setTimeout(justWait, 100); 2511 } 2512 })(); 2513 } 2514 2515 frameData.state = ''; 2516 2517 if ( frameData.data.hasOwnProperty('alt') ) { 2518 img.alt= frameData.data.alt; 2519 } 2520 if ( frameData.data.hasOwnProperty('title') ) { 2521 img.title= frameData.data.title; 2522 } 2523 img.src = src; 2524 }); 2525 } 2526 2527 function spinnerSpin ($el) { 2528 $spinner.append(spinner.spin().el).appendTo($el); 2529 } 2530 2531 function spinnerStop () { 2532 $spinner.detach(); 2533 spinner && spinner.stop(); 2534 } 2535 2536 function updateFotoramaState () { 2537 var $frame = activeFrame[STAGE_FRAME_KEY]; 2538 2539 if ($frame && !$frame.data().state) { 2540 spinnerSpin($frame); 2541 $frame.on('f:load f:error', function () { 2542 $frame.off('f:load f:error'); 2543 spinnerStop(); 2544 }); 2545 } 2546 } 2547 2548 function addNavFrameEvents (frame) { 2549 addEnterUp(frame, onNavFrameClick); 2550 addFocus(frame, function () { 2551 2552 setTimeout(function () { 2553 lockScroll($nav); 2554 }, 0); 2555 slideNavShaft({time: o_transitionDuration, guessIndex: $(this).data().eq, minMax: navShaftTouchTail}); 2556 }); 2557 } 2558 2559 function frameDraw (indexes, type) { 2560 eachIndex(indexes, type, function (i, index, dataFrame, $frame, key, frameData) { 2561 if ($frame) return; 2562 2563 $frame = dataFrame[key] = $wrap[key].clone(); 2564 frameData = $frame.data(); 2565 frameData.data = dataFrame; 2566 var frame = $frame[0]; 2567 2568 if (type === 'stage') { 2569 2570 if (dataFrame.html) { 2571 $('<div class="' + htmlClass + '"></div>') 2572 .append( 2573 dataFrame._html ? $(dataFrame.html) 2574 .removeAttr('id') 2575 .html(dataFrame._html) // Because of IE 2576 : dataFrame.html 2577 ) 2578 .appendTo($frame); 2579 } 2580 2581 dataFrame.caption && $(div(captionClass, div(captionWrapClass, dataFrame.caption))).appendTo($frame); 2582 2583 dataFrame.video && $frame 2584 .addClass(stageFrameVideoClass) 2585 .append($videoPlay.clone()); 2586 2587 // This solves tabbing problems 2588 addFocus(frame, function () { 2589 setTimeout(function () { 2590 lockScroll($stage); 2591 }, 0); 2592 clickToShow({index: frameData.eq, user: true}); 2593 }); 2594 2595 $stageFrame = $stageFrame.add($frame); 2596 } else if (type === 'navDot') { 2597 addNavFrameEvents(frame); 2598 $navDotFrame = $navDotFrame.add($frame); 2599 } else if (type === 'navThumb') { 2600 addNavFrameEvents(frame); 2601 frameData.$wrap = $frame.children(':first'); 2602 $navThumbFrame = $navThumbFrame.add($frame); 2603 if (dataFrame.video) { 2604 frameData.$wrap.append($videoPlay.clone()); 2605 } 2606 } 2607 }); 2608 } 2609 2610 function callFit ($img, measuresToFit, method, position) { 2611 return $img && $img.length && fit($img, measuresToFit, method, position); 2612 } 2613 2614 function stageFramePosition (indexes) { 2615 eachIndex(indexes, 'stage', function (i, index, dataFrame, $frame, key, frameData) { 2616 if (!$frame) return; 2617 2618 var normalizedIndex = normalizeIndex(index), 2619 method = dataFrame.fit || opts.fit, 2620 position = dataFrame.position || opts.position; 2621 frameData.eq = normalizedIndex; 2622 2623 toDetach[STAGE_FRAME_KEY][normalizedIndex] = $frame.css($.extend({left: o_fade ? 0 : getPosByIndex(index, measures.w, opts.margin, repositionIndex)}, o_fade && getDuration(0))); 2624 2625 if (isDetached($frame[0])) { 2626 $frame.appendTo($stageShaft); 2627 unloadVideo(dataFrame.$video); 2628 } 2629 2630 callFit(frameData.$img, measures, method, position); 2631 callFit(frameData.$full, measures, method, position); 2632 }); 2633 } 2634 2635 function thumbsDraw (pos, loadFLAG) { 2636 if (o_nav !== 'thumbs' || isNaN(pos)) return; 2637 2638 var leftLimit = -pos, 2639 rightLimit = -pos + measures.nw; 2640 2641 $navThumbFrame.each(function () { 2642 var $this = $(this), 2643 thisData = $this.data(), 2644 eq = thisData.eq, 2645 getSpecialMeasures = function () { 2646 return { 2647 h: o_thumbSide2, 2648 w: thisData.w 2649 } 2650 }, 2651 specialMeasures = getSpecialMeasures(), 2652 dataFrame = data[eq] || {}, 2653 method = dataFrame.thumbfit || opts.thumbfit, 2654 position = dataFrame.thumbposition || opts.thumbposition; 2655 2656 specialMeasures.w = thisData.w; 2657 2658 if (thisData.l + thisData.w < leftLimit 2659 || thisData.l > rightLimit 2660 || callFit(thisData.$img, specialMeasures, method, position)) return; 2661 2662 loadFLAG && loadImg([eq], 'navThumb', getSpecialMeasures, method, position); 2663 });
2664 } 2665 2666 function frameAppend ($frames, $shaft, type) { 2667 if (!frameAppend[type]) { 2668 2669 var thumbsFLAG = type === 'nav' && o_navThumbs, 2670 left = 0; 2671 2672 $shaft.append( 2673 $frames 2674 .filter(function () { 2675 var actual, 2676 $this = $(this), 2677 frameData = $this.data(); 2678 for (var _i = 0, _l = data.length; _i < _l; _i++) { 2679 if (frameData.data === data[_i]) { 2680 actual = true; 2681 frameData.eq = _i; 2682 break; 2683 } 2684 } 2685 return actual || $this.remove() && false; 2686 }) 2687 .sort(function (a, b) { 2688 return $(a).data().eq - $(b).data().eq; 2689 }) 2690 .each(function () { 2691 2692 if (!thumbsFLAG) return; 2693 2694 var $this = $(this), 2695 frameData = $this.data(), 2696 thumbwidth = Math.round(o_thumbSide2 * frameData.data.thumbratio) || o_thumbSide; 2697 2698 frameData.l = left; 2699 frameData.w = thumbwidth; 2700 2701 $this.css({width: thumbwidth}); 2702 2703 left += thumbwidth + opts.thumbmargin; 2704 }) 2705 ); 2706 2707 frameAppend[type] = true; 2708 } 2709 } 2710 2711 function getDirection (x) { 2712 return x - stageLeft > measures.w / 3; 2713 } 2714 2715 function disableDirrection (i) { 2716 return !o_loop && (!(activeIndex + i) || !(activeIndex - size + i)) && !$videoPlaying; 2717 } 2718 2719 function arrsUpdate () { 2720 var disablePrev = disableDirrection(0), 2721 disableNext = disableDirrection(1); 2722 $arrPrev 2723 .toggleClass(arrDisabledClass, disablePrev) 2724 .attr(disableAttr(disablePrev)); 2725 $arrNext 2726 .toggleClass(arrDisabledClass, disableNext) 2727 .attr(disableAttr(disableNext)); 2728 } 2729 2730 function stageWheelUpdate () { 2731 if (stageWheelTail.ok) { 2732 stageWheelTail.prevent = {'<': disableDirrection(0), '>': disableDirrection(1)}; 2733 } 2734 } 2735 2736 function getNavFrameBounds ($navFrame) { 2737 var navFrameData = $navFrame.data(), 2738 left, 2739 width; 2740 2741 if (o_navThumbs) { 2742 left = navFrameData.l; 2743 width = navFrameData.w; 2744 } else { 2745 left = $navFrame.position().left; 2746 width = $navFrame.width(); 2747 } 2748 2749 return { 2750 c: left + width / 2, 2751 min: -left + opts.thumbmargin * 10, 2752 max: -left + measures.w - width - opts.thumbmargin * 10 2753 }; 2754 } 2755 2756 function slideThumbBorder (time) { 2757 var navFrameData = activeFrame[navFrameKey].data(); 2758 slide($thumbBorder, { 2759 time: time * 1.2, 2760 pos: navFrameData.l, 2761 width: navFrameData.w - opts.thumbborderwidth * 2 2762 }); 2763 } 2764 2765 function slideNavShaft (options) { 2766 ////console.log('slideNavShaft', options.guessIndex, options.keep, slideNavShaft.l); 2767 var $guessNavFrame = data[options.guessIndex][navFrameKey]; 2768 if ($guessNavFrame) { 2769 var overflowFLAG = navShaftTouchTail.min !== navShaftTouchTail.max, 2770 minMax = options.minMax || overflowFLAG && getNavFrameBounds(activeFrame[navFrameKey]), 2771 l = overflowFLAG && (options.keep && slideNavShaft.l ? slideNavShaft.l : minMaxLimit((options.coo || measures.nw / 2) - getNavFrameBounds($guessNavFrame).c, minMax.min, minMax.max)), 2772 pos = overflowFLAG && minMaxLimit(l, navShaftTouchTail.min, navShaftTouchTail.max), 2773 time = options.time * 1.1; 2774 2775 slide($navShaft, { 2776 time: time, 2777 pos: pos || 0, 2778 onEnd: function () { 2779 thumbsDraw(pos, true); 2780 } 2781 }); 2782 2783 //if (time) thumbsDraw(pos); 2784 2785 setShadow($nav, findShadowEdge(pos, navShaftTouchTail.min, navShaftTouchTail.max)); 2786 slideNavShaft.l = l; 2787 } 2788 } 2789 2790 function navUpdate () { 2791 deactivateFrames(navFrameKey); 2792 toDeactivate[navFrameKey].push(activeFrame[navFrameKey].addClass(activeClass)); 2793 } 2794 2795 function deactivateFrames (key) { 2796 var _toDeactivate = toDeactivate[key]; 2797 2798 while (_toDeactivate.length) { 2799 _toDeactivate.shift().removeClass(activeClass); 2800 } 2801 } 2802 2803 function detachFrames (key) { 2804 var _toDetach = toDetach[key]; 2805 2806 //////console.log('_toDetach', _toDetach); 2807 //////console.log('activeIndexes', activeIndexes); 2808 2809 $.each(activeIndexes, function (i, index) { 2810 delete _toDetach[normalizeIndex(index)]; 2811 });
2812 2813 $.each(_toDetach, function (index, $frame) { 2814 delete _toDetach[index]; 2815 //////console.log('Detach', index); 2816 $frame.detach(); 2817 }); 2818 } 2819 2820 function stageShaftReposition (skipOnEnd) { 2821 2822 repositionIndex = dirtyIndex = activeIndex; 2823 2824 var $frame = activeFrame[STAGE_FRAME_KEY]; 2825 2826 if ($frame) { 2827 deactivateFrames(STAGE_FRAME_KEY); 2828 toDeactivate[STAGE_FRAME_KEY].push($frame.addClass(activeClass)); 2829 2830 skipOnEnd || that.show.onEnd(true); 2831 stop($stageShaft, 0, true); 2832 2833 detachFrames(STAGE_FRAME_KEY); 2834 stageFramePosition(activeIndexes); 2835 setStageShaftMinmaxAndSnap(); 2836 setNavShaftMinMax(); 2837 } 2838 } 2839 2840 function extendMeasures (options, measuresArray) { 2841 if (!options) return; 2842 2843 $.each(measuresArray, function (i, measures) { 2844 if (!measures) return; 2845 2846 $.extend(measures, { 2847 width: options.width || measures.width, 2848 height: options.height, 2849 minwidth: options.minwidth, 2850 maxwidth: options.maxwidth, 2851 minheight: options.minheight, 2852 maxheight: options.maxheight, 2853 ratio: getRatio(options.ratio) 2854 }) 2855 }); 2856 } 2857 2858 function triggerEvent (event, extra) { 2859 $fotorama.trigger(_fotoramaClass + ':' + event, [that, extra]); 2860 } 2861 2862 function onTouchStart () { 2863 clearTimeout(onTouchEnd.t); 2864 touchedFLAG = 1; 2865 2866 if (opts.stopautoplayontouch) { 2867 that.stopAutoplay(); 2868 } else { 2869 pausedAutoplayFLAG = true; 2870 } 2871 } 2872 2873 function onTouchEnd () { 2874 if (!touchedFLAG) return;
2875 if (!opts.stopautoplayontouch) { 2876 releaseAutoplay(); 2877 changeAutoplay(); 2878 } 2879 2880 onTouchEnd.t = setTimeout(function () { 2881 touchedFLAG = 0; 2882 }, TRANSITION_DURATION + TOUCH_TIMEOUT); 2883 //////console.timeEnd('onTouchEnd'); 2884 } 2885 2886 function releaseAutoplay () { 2887 ////console.log('releaseAutoplay'); 2888 pausedAutoplayFLAG = !!($videoPlaying || stoppedAutoplayFLAG); 2889 } 2890 2891 function changeAutoplay () { 2892 ////console.log('changeAutoplay'); 2893 2894 clearTimeout(changeAutoplay.t); 2895 waitFor.stop(changeAutoplay.w); 2896 2897 if (!opts.autoplay || pausedAutoplayFLAG) { 2898 if (that.autoplay) { 2899 that.autoplay = false; 2900 triggerEvent('stopautoplay'); 2901 } 2902 2903 return; 2904 } 2905 2906 ////console.log('changeAutoplay continue'); 2907 2908 if (!that.autoplay) { 2909 that.autoplay = true; 2910 triggerEvent('startautoplay'); 2911 } 2912 2913 var _activeIndex = activeIndex; 2914 2915 2916 var frameData = activeFrame[STAGE_FRAME_KEY].data(); 2917 changeAutoplay.w = waitFor(function () { 2918 ////console.log('wait for the state of the current frame'); 2919 return frameData.state || _activeIndex !== activeIndex; 2920 }, function () { 2921 ////console.log('the current frame is ready'); 2922 changeAutoplay.t = setTimeout(function () { 2923 ////console.log('changeAutoplay.t setTimeout', pausedAutoplayFLAG, _activeIndex !== activeIndex); 2924 if (pausedAutoplayFLAG || _activeIndex !== activeIndex) return; 2925 2926 var _nextAutoplayIndex = nextAutoplayIndex, 2927 nextFrameData = data[_nextAutoplayIndex][STAGE_FRAME_KEY].data(); 2928 2929 changeAutoplay.w = waitFor(function () { 2930 ////console.log('wait for the state of the next frame'); 2931 return nextFrameData.state || _nextAutoplayIndex !== nextAutoplayIndex; 2932 }, function () { 2933 if (pausedAutoplayFLAG || _nextAutoplayIndex !== nextAutoplayIndex) return; 2934 that.show(o_loop ? getDirectionSign(!o_rtl) : nextAutoplayIndex); 2935 }); 2936 }, opts.autoplay); 2937 }); 2938 2939 } 2940 2941 that.startAutoplay = function (interval) { 2942 if (that.autoplay) return this; 2943 pausedAutoplayFLAG = stoppedAutoplayFLAG = false; 2944 setAutoplayInterval(interval || opts.autoplay); 2945 changeAutoplay(); 2946 2947 return this; 2948 }; 2949 2950 that.stopAutoplay = function () { 2951 if (that.autoplay) { 2952 pausedAutoplayFLAG = stoppedAutoplayFLAG = true; 2953 changeAutoplay(); 2954 } 2955 return this; 2956 }; 2957 2958 that.show = function (options) { 2959 ////console.log('that.show'); 2960 //////console.time('that.show prepare'); 2961 var index; 2962 2963 if (typeof options !== 'object') { 2964 index = options; 2965 options = {}; 2966 } else { 2967 index = options.index; 2968 } 2969 2970 index = index === '>' ? dirtyIndex + 1 : index === '<' ? dirtyIndex - 1 : index === '<<' ? 0 : index === '>>' ? size - 1 : index; 2971 index = isNaN(index) ? getIndexFromHash(index, data, true) : index; 2972 index = typeof index === 'undefined' ? activeIndex || 0 : index; 2973 2974 that.activeIndex = activeIndex = edgeIndex(index); 2975 prevIndex = getPrevIndex(activeIndex); 2976 nextIndex = getNextIndex(activeIndex); 2977 nextAutoplayIndex = normalizeIndex(activeIndex + (o_rtl ? -1 : 1)); 2978 activeIndexes = [activeIndex, prevIndex, nextIndex]; 2979 2980 dirtyIndex = o_loop ? index : activeIndex; 2981 2982 var diffIndex = Math.abs(lastActiveIndex - dirtyIndex), 2983 time = getNumber(options.time, function () { 2984 return Math.min(o_transitionDuration * (1 + (diffIndex - 1) / 12), o_transitionDuration * 2); 2985 }), 2986 overPos = options.overPos; 2987 2988 if (options.slow) time *= 10; 2989 2990 var _activeFrame = activeFrame; 2991 that.activeFrame = activeFrame = data[activeIndex]; 2992 //////console.timeEnd('that.show prepare'); 2993 2994 var silent = _activeFrame === activeFrame && !options.user; 2995 2996 //setTimeout(function () { 2997 //////console.time('unloadVideo'); 2998 unloadVideo($videoPlaying, activeFrame.i !== data[normalizeIndex(repositionIndex)].i); 2999 //////console.timeEnd('unloadVideo'); 3000 //////console.time('frameDraw'); 3001 frameDraw(activeIndexes, 'stage'); 3002 //////console.timeEnd('frameDraw'); 3003 //////console.time('stageFramePosition'); 3004 stageFramePosition(SLOW ? [dirtyIndex] : [dirtyIndex, getPrevIndex(dirtyIndex), getNextIndex(dirtyIndex)]); 3005 //////console.timeEnd('stageFramePosition'); 3006 //////console.time('updateTouchTails'); 3007 updateTouchTails('go', true); 3008 //////console.timeEnd('updateTouchTails'); 3009 //////console.time('triggerEvent'); 3010 3011 silent || triggerEvent('show', { 3012 user: options.user, 3013 time: time 3014 });
3015 //////console.timeEnd('triggerEvent'); 3016 //}, 0); 3017 3018 //////console.time('bind onEnd'); 3019 3020 pausedAutoplayFLAG = true; 3021 3022 var onEnd = that.show.onEnd = function (skipReposition) { 3023 if (onEnd.ok) return; 3024 onEnd.ok = true; 3025 3026 skipReposition || stageShaftReposition(true); 3027 3028 if (!silent) { 3029 triggerEvent('showend', { 3030 user: options.user 3031 }); 3032 } 3033 3034 ////console.log('o_transition', o_transition); 3035 3036 if (!skipReposition && o_transition && o_transition !== opts.transition) { 3037 ////console.log('set transition back to: ' + o_transition); 3038 that.setOptions({transition: o_transition}); 3039 o_transition = false; 3040 return; 3041 } 3042 3043 updateFotoramaState(); 3044 loadImg(activeIndexes, 'stage'); 3045 3046 updateTouchTails('go', false); 3047 stageWheelUpdate(); 3048 3049 stageCursor(); 3050 releaseAutoplay(); 3051 changeAutoplay(); 3052 }; 3053 //////console.timeEnd('bind onEnd'); 3054 3055 if (!o_fade) { 3056 //////console.time('slide'); 3057 slide($stageShaft, { 3058 pos: -getPosByIndex(dirtyIndex, measures.w, opts.margin, repositionIndex), 3059 overPos: overPos, 3060 time: time, 3061 onEnd: onEnd/*, 3062 _001: true*/ 3063 }); 3064 //////console.timeEnd('slide'); 3065 } else { 3066 var $activeFrame = activeFrame[STAGE_FRAME_KEY], 3067 $prevActiveFrame = activeIndex !== lastActiveIndex ? data[lastActiveIndex][STAGE_FRAME_KEY] : null; 3068 3069 fade($activeFrame, $prevActiveFrame, $stageFrame, { 3070 time: time, 3071 method: opts.transition, 3072 onEnd: onEnd 3073 }, fadeStack); 3074 } 3075 3076 //////console.time('arrsUpdate'); 3077 arrsUpdate(); 3078 //////console.timeEnd('arrsUpdate'); 3079 3080 if (o_nav) { 3081 //////console.time('navUpdate'); 3082 navUpdate(); 3083 //////console.timeEnd('navUpdate'); 3084 3085 //////console.time('slideNavShaft'); 3086 var guessIndex = limitIndex(activeIndex + minMaxLimit(dirtyIndex - lastActiveIndex, -1, 1)); 3087 slideNavShaft({time: time, coo: guessIndex !== activeIndex && options.coo, guessIndex: typeof options.coo !== 'undefined' ? guessIndex : activeIndex, keep: silent}); 3088 //////console.timeEnd('slideNavShaft'); 3089 3090 //////console.time('slideThumbBorder'); 3091 if (o_navThumbs) slideThumbBorder(time); 3092 //////console.timeEnd('slideThumbBorder'); 3093 } 3094 3095 //////console.time('that.show end'); 3096 showedFLAG = typeof lastActiveIndex !== 'undefined' && lastActiveIndex !== activeIndex; 3097 lastActiveIndex = activeIndex; 3098 opts.hash && showedFLAG && !that.eq && setHash(activeFrame.id || activeIndex + 1); 3099 //////console.timeEnd('that.show end'); 3100 3101 //////console.timeEnd('that.show'); 3102 3103 return this; 3104 }; 3105 3106 that.requestFullScreen = function () { 3107 if (o_allowFullScreen && !that.fullScreen) { 3108 scrollTop = $WINDOW.scrollTop(); 3109 scrollLeft = $WINDOW.scrollLeft(); 3110 3111 lockScroll($WINDOW); 3112 3113 updateTouchTails('x', true); 3114 3115 measuresStash = $.extend({}, measures); 3116 3117 $fotorama 3118 .addClass(fullscreenClass) 3119 .appendTo($BODY.addClass(_fullscreenClass)); 3120 3121 $HTML.addClass(_fullscreenClass); 3122 3123 unloadVideo($videoPlaying, true, true); 3124 3125 that.fullScreen = true; 3126 3127 if (o_nativeFullScreen) { 3128 fullScreenApi.request(fotorama); 3129 } 3130 3131 that.resize(); 3132 loadImg(activeIndexes, 'stage'); 3133 updateFotoramaState(); 3134 3135 triggerEvent('fullscreenenter'); 3136 } 3137 3138 return this; 3139 }; 3140 3141 function cancelFullScreen () { 3142 if (that.fullScreen) { 3143 that.fullScreen = false; 3144 3145 if (FULLSCREEN) { 3146 fullScreenApi.cancel(fotorama); 3147 } 3148 3149 $BODY.removeClass(_fullscreenClass); 3150 $HTML.removeClass(_fullscreenClass); 3151 3152 $fotorama 3153 .removeClass(fullscreenClass) 3154 .insertAfter($anchor); 3155 3156 measures = $.extend({}, measuresStash); 3157 3158 unloadVideo($videoPlaying, true, true); 3159 3160 updateTouchTails('x', false); 3161 3162 that.resize(); 3163 loadImg(activeIndexes, 'stage'); 3164 3165 lockScroll($WINDOW, scrollLeft, scrollTop); 3166 3167 triggerEvent('fullscreenexit'); 3168 } 3169 } 3170 3171 that.cancelFullScreen = function () { 3172 if (o_nativeFullScreen && fullScreenApi.is()) { 3173 fullScreenApi.cancel(document); 3174 } else { 3175 cancelFullScreen(); 3176 } 3177 3178 return this; 3179 }; 3180 3181 that.toggleFullScreen = function () { 3182 return that[(that.fullScreen ? 'cancel' : 'request') + 'FullScreen'](); 3183 }; 3184 3185 addEvent(document, fullScreenApi.event, function () { 3186 if (data && !fullScreenApi.is() && !$videoPlaying) { 3187 cancelFullScreen(); 3188 } 3189 }); 3190 3191 that.resize = function (options) { 3192 if (!data) return this; 3193 3194 var time = arguments[1] || 0, 3195 setFLAG = arguments[2]; 3196 3197 extendMeasures(!that.fullScreen ? optionsToLowerCase(options) : {width: '100%', maxwidth: null, minwidth: null, height: '100%', maxheight: null, minheight: null}, [measures, setFLAG || that.fullScreen || opts]); 3198 3199 var width = measures.width, 3200 height = measures.height, 3201 ratio = measures.ratio,
3202 windowHeight = $WINDOW.height() - (o_nav ? $nav.height() : 0); 3203 3204 if (measureIsValid(width)) { 3205 $wrap 3206 .addClass(wrapOnlyActiveClass) 3207 .css({width: width, minWidth: measures.minwidth || 0, maxWidth: measures.maxwidth || MAX_WIDTH}); 3208 3209 width = measures.W = measures.w = $wrap.width(); 3210 measures.nw = o_nav && numberFromWhatever(opts.navwidth, width) || width; 3211 3212 if (opts.glimpse) { 3213 // Glimpse 3214 measures.w -= Math.round((numberFromWhatever(opts.glimpse, width) || 0) * 2); 3215 } 3216 3217 $stageShaft.css({width: measures.w, marginLeft: (measures.W - measures.w) / 2}); 3218 3219 //////console.log('measures.W', measures.W); 3220 //////console.log('measures.w', measures.w); 3221 3222 height = numberFromWhatever(height, windowHeight); 3223 3224 height = height || (ratio && width / ratio); 3225 3226 if (height) { 3227 width = Math.round(width); 3228 height = measures.h = Math.round(minMaxLimit(height, numberFromWhatever(measures.minheight, windowHeight), numberFromWhatever(measures.maxheight, windowHeight))); 3229 3230 $stage 3231 .stop() 3232 .animate({width: width, height: height}, time, function () { 3233 $wrap.removeClass(wrapOnlyActiveClass); 3234 }); 3235 3236 stageShaftReposition(); 3237 3238 if (o_nav) { 3239 $nav 3240 .stop() 3241 .animate({width: measures.nw}, time); 3242 3243 slideNavShaft({guessIndex: activeIndex, time: time, keep: true}); 3244 if (o_navThumbs && frameAppend.nav) slideThumbBorder(time); 3245 } 3246 3247 measuresSetFLAG = setFLAG || true; 3248 3249 ready(); 3250 } 3251 } 3252 3253 stageLeft = $stage.offset().left; 3254 3255 return this; 3256 }; 3257 3258 that.setOptions = function (options) { 3259 $.extend(opts, options); 3260 reset(); 3261 return this; 3262 }; 3263 3264 that.shuffle = function () { 3265 data && shuffle(data) && reset(); 3266 return this; 3267 }; 3268 3269 function setShadow ($el, edge) { 3270 //////console.time('setShadow'); 3271 if (o_shadows) { 3272 $el.removeClass(shadowsLeftClass + ' ' + shadowsRightClass); 3273 edge && !$videoPlaying && $el.addClass(edge.replace(/^|\s/g, ' ' + shadowsClass + '--')); 3274 } 3275 //////console.timeEnd('setShadow'); 3276 } 3277 3278 that.destroy = function () { 3279 that.cancelFullScreen(); 3280 that.stopAutoplay(); 3281 3282 data = that.data = null; 3283 3284 appendElements(); 3285 3286 activeIndexes = []; 3287 detachFrames(STAGE_FRAME_KEY); 3288 3289 reset.ok = false; 3290 3291 return this; 3292 }; 3293 3294 that.playVideo = function () { 3295 var dataFrame = activeFrame, 3296 video = dataFrame.video, 3297 _activeIndex = activeIndex; 3298 3299 if (typeof video === 'object' && dataFrame.videoReady) { 3300 o_nativeFullScreen && that.fullScreen && that.cancelFullScreen(); 3301 3302 waitFor(function () { 3303 return !fullScreenApi.is() || _activeIndex !== activeIndex; 3304 }, function () { 3305 if (_activeIndex === activeIndex) { 3306 dataFrame.$video = dataFrame.$video || $($.Fotorama.jst.video(video)); 3307 dataFrame.$video.appendTo(dataFrame[STAGE_FRAME_KEY]); 3308 3309 $wrap.addClass(wrapVideoClass); 3310 $videoPlaying = dataFrame.$video; 3311 3312 stageNoMove(); 3313 3314 $arrs.blur(); 3315 $fullscreenIcon.blur(); 3316 3317 triggerEvent('loadvideo'); 3318 } 3319 }); 3320 } 3321 3322 return this; 3323 }; 3324 3325 that.stopVideo = function () { 3326 unloadVideo($videoPlaying, true, true); 3327 return this; 3328 }; 3329 3330 function unloadVideo ($video, unloadActiveFLAG, releaseAutoplayFLAG) { 3331 if (unloadActiveFLAG) { 3332 $wrap.removeClass(wrapVideoClass); 3333 $videoPlaying = false; 3334 3335 stageNoMove(); 3336 } 3337 3338 if ($video && $video !== $videoPlaying) { 3339 $video.remove(); 3340 triggerEvent('unloadvideo'); 3341 } 3342 3343 if (releaseAutoplayFLAG) { 3344 releaseAutoplay(); 3345 changeAutoplay(); 3346 } 3347 } 3348 3349 function toggleControlsClass (FLAG) {
3350 $wrap.toggleClass(wrapNoControlsClass, FLAG); 3351 } 3352 3353 function stageCursor (e) { 3354 if (stageShaftTouchTail.flow) return; 3355 3356 var x = e ? e.pageX : stageCursor.x, 3357 pointerFLAG = x && !disableDirrection(getDirection(x)) && opts.click; 3358 3359 if (stageCursor.p !== pointerFLAG 3360 && $stage.toggleClass(pointerClass, pointerFLAG)) { 3361 stageCursor.p = pointerFLAG; 3362 stageCursor.x = x; 3363 } 3364 } 3365 3366 $stage.on('mousemove', stageCursor); 3367 3368 function clickToShow (showOptions) { 3369 clearTimeout(clickToShow.t); 3370 3371 if (opts.clicktransition && opts.clicktransition !== opts.transition) { 3372 ////console.log('change transition to: ' + opts.clicktransition); 3373 3374 // this timeout is for yield events flow 3375 setTimeout(function () { 3376 // save original transition for later 3377 var _o_transition = opts.transition; 3378 3379 that.setOptions({transition: opts.clicktransition}); 3380 3381 // now safe to pass base transition to o_transition, so that.show will restor it 3382 o_transition = _o_transition; 3383 // this timeout is here to prevent jerking in some browsers 3384 clickToShow.t = setTimeout(function () { 3385 that.show(showOptions); 3386 }, 10); 3387 }, 0); 3388 } else { 3389 that.show(showOptions); 3390 } 3391 } 3392 3393 function onStageTap (e, toggleControlsFLAG) { 3394 //////console.time('onStageTap'); 3395 var target = e.target, 3396 $target = $(target); 3397 3398 if ($target.hasClass(videoPlayClass)) { 3399 that.playVideo(); 3400 } else if (target === fullscreenIcon) { 3401 that.toggleFullScreen(); 3402 } else if ($videoPlaying) { 3403 target === videoClose && unloadVideo($videoPlaying, true, true); 3404 } else { 3405 if (toggleControlsFLAG) { 3406 toggleControlsClass(); 3407 } else if (opts.click) { 3408 3409 clickToShow({index: e.shiftKey || getDirectionSign(getDirection(e._x)), slow: e.altKey, user: true}); 3410 } 3411 } 3412 //////console.timeEnd('onStageTap'); 3413 } 3414 3415 function updateTouchTails (key, value) { 3416 stageShaftTouchTail[key] = navShaftTouchTail[key] = value; 3417 } 3418 3419 stageShaftTouchTail = moveOnTouch($stageShaft, { 3420 onStart: onTouchStart, 3421 onMove: function (e, result) { 3422 setShadow($stage, result.edge); 3423 }, 3424 onTouchEnd: onTouchEnd, 3425 onEnd: function (result) { 3426 //////console.time('stageShaftTouchTail.onEnd'); 3427 setShadow($stage); 3428 3429 //////console.log('result', result); 3430 3431 var toggleControlsFLAG = (MS_POINTER && !hoverFLAG || result.touch) && opts.arrows && opts.arrows !== 'always'; 3432 3433 if (result.moved || (toggleControlsFLAG && result.pos !== result.newPos && !result.control)) { 3434 var index = getIndexByPos(result.newPos, measures.w, opts.margin, repositionIndex); 3435 that.show({ 3436 index: index, 3437 time: o_fade ? o_transitionDuration : result.time, 3438 overPos: result.overPos, 3439 user: true 3440 }); 3441 } else if (!result.aborted && !result.control) { 3442 onStageTap(result.startEvent, toggleControlsFLAG); 3443 } 3444 //////console.timeEnd('stageShaftTouchTail.onEnd'); 3445 }, 3446// getPos: function () { 3447// return -getPosByIndex(dirtyIndex, measures.w, opts.margin, repositionIndex); 3448// }, 3449 //_001: true, 3450 timeLow: 1, 3451 timeHigh: 1, 3452 friction: 2, 3453 select: '.' + selectClass + ', .' + selectClass + ' *', 3454 $wrap: $stage 3455 }); 3456 3457 navShaftTouchTail = moveOnTouch($navShaft, { 3458 onStart: onTouchStart, 3459 onMove: function (e, result) { 3460 setShadow($nav, result.edge); 3461 }, 3462 onTouchEnd: onTouchEnd, 3463 onEnd: function (result) { 3464 3465 function onEnd () { 3466 slideNavShaft.l = result.newPos; 3467 releaseAutoplay(); 3468 changeAutoplay(); 3469 thumbsDraw(result.newPos, true); 3470 } 3471 3472 if (!result.moved) { 3473 var target = result.$target.closest('.' + navFrameClass, $navShaft)[0]; 3474 target && onNavFrameClick.call(target, result.startEvent); 3475 } else if (result.pos !== result.newPos) { 3476 pausedAutoplayFLAG = true; 3477 slide($navShaft, { 3478 time: result.time, 3479 pos: result.newPos, 3480 overPos: result.overPos, 3481 onEnd: onEnd 3482 }); 3483 thumbsDraw(result.newPos); 3484 o_shadows && setShadow($nav, findShadowEdge(result.newPos, navShaftTouchTail.min, navShaftTouchTail.max)); 3485 } else { 3486 onEnd(); 3487 } 3488 }, 3489 timeLow: .5, 3490 timeHigh: 2, 3491 friction: 5, 3492 $wrap: $nav 3493 }); 3494 3495 stageWheelTail = wheel($stage, { 3496 shift: true, 3497 onEnd: function (e, direction) { 3498 //////console.log('wheel $stage onEnd', direction); 3499 onTouchStart(); 3500 onTouchEnd();
3501 that.show({index: direction, slow: e.altKey}) 3502 } 3503 }); 3504 3505 navWheelTail = wheel($nav, { 3506 onEnd: function (e, direction) { 3507 //////console.log('wheel $nav onEnd', direction); 3508 onTouchStart(); 3509 onTouchEnd(); 3510 var newPos = stop($navShaft) + direction * .25; 3511 $navShaft.css(getTranslate(minMaxLimit(newPos, navShaftTouchTail.min, navShaftTouchTail.max))); 3512 o_shadows && setShadow($nav, findShadowEdge(newPos, navShaftTouchTail.min, navShaftTouchTail.max)); 3513 navWheelTail.prevent = {'<': newPos >= navShaftTouchTail.max, '>': newPos <= navShaftTouchTail.min}; 3514 clearTimeout(navWheelTail.t); 3515 navWheelTail.t = setTimeout(function () { 3516 slideNavShaft.l = newPos; 3517 thumbsDraw(newPos, true) 3518 }, TOUCH_TIMEOUT); 3519 thumbsDraw(newPos); 3520 } 3521 }); 3522 3523 $wrap.hover( 3524 function () { 3525 setTimeout(function () { 3526 if (touchedFLAG) return; 3527 toggleControlsClass(!(hoverFLAG = true)); 3528 }, 0); 3529 }, function () { 3530 if (!hoverFLAG) return; 3531 toggleControlsClass(!(hoverFLAG = false)); 3532 } 3533 ); 3534 3535 function onNavFrameClick (e) { 3536 var index = $(this).data().eq; 3537 clickToShow({index: index, slow: e.altKey, user: true, coo: e._x - $nav.offset().left}); 3538 } 3539 3540 function onArrClick (e) { 3541 clickToShow({index: $arrs.index(this) ? '>' : '<', slow: e.altKey, user: true}); 3542 } 3543 3544 smartClick($arrs, function (e) { 3545 stopEvent(e); 3546 onArrClick.call(this, e); 3547 }, { 3548 onStart: function () { 3549 onTouchStart(); 3550 stageShaftTouchTail.control = true; 3551 }, 3552 onTouchEnd: onTouchEnd 3553 }); 3554 3555 function addFocusOnControls (el) { 3556 addFocus(el, function () { 3557 setTimeout(function () { 3558 lockScroll($stage); 3559 }, 0); 3560 toggleControlsClass(false); 3561 }); 3562 } 3563 3564 $arrs.each(function () { 3565 addEnterUp(this, function (e) { 3566 onArrClick.call(this, e); 3567 }); 3568 addFocusOnControls(this); 3569 }); 3570 3571 addEnterUp(fullscreenIcon, that.toggleFullScreen); 3572 addFocusOnControls(fullscreenIcon); 3573 3574 function reset () { 3575 setData(); 3576 setOptions(); 3577 3578 if (!reset.i) { 3579 reset.i = true; 3580 // Only once 3581 var _startindex = opts.startindex; 3582 if (_startindex || opts.hash && location.hash) { 3583 startIndex = getIndexFromHash(_startindex || location.hash.replace(/^#/, ''), data, that.index === 0 || _startindex, _startindex); 3584 } 3585 activeIndex = repositionIndex = dirtyIndex = lastActiveIndex = startIndex = edgeIndex(startIndex) || 0;/*(o_rtl ? size - 1 : 0)*///; 3586 } 3587 3588 if (size) { 3589 if (changeToRtl()) return; 3590 3591 if ($videoPlaying) { 3592 unloadVideo($videoPlaying, true); 3593 } 3594 3595 activeIndexes = []; 3596 detachFrames(STAGE_FRAME_KEY); 3597 3598 reset.ok = true; 3599 3600 that.show({index: activeIndex, time: 0}); 3601 that.resize(); 3602 } else { 3603 that.destroy(); 3604 } 3605 } 3606 3607 function changeToRtl () { 3608 //////console.log('changeToRtl'); 3609 if (!changeToRtl.f === o_rtl) { 3610 changeToRtl.f = o_rtl; 3611 activeIndex = size - 1 - activeIndex; 3612 //////console.log('changeToRtl execute, activeIndex is', activeIndex); 3613 that.reverse(); 3614 3615 return true; 3616 } 3617 } 3618 3619 $.each('load push pop shift unshift reverse sort splice'.split(' '), function (i, method) { 3620 that[method] = function () { 3621 data = data || []; 3622 if (method !== 'load') { 3623 Array.prototype[method].apply(data, arguments); 3624 } else if (arguments[0] && typeof arguments[0] === 'object' && arguments[0].length) { 3625 data = clone(arguments[0]); 3626 } 3627 reset(); 3628 return that; 3629 } 3630 }); 3631 3632 function ready () { 3633 if (!ready.ok) { 3634 ready.ok = true; 3635 triggerEvent('ready'); 3636 } 3637 } 3638 3639 reset(); 3640}; 3641 3642 3643$.fn.fotorama = function (opts) { 3644 return this.each(function () { 3645 var that = this, 3646 $fotorama = $(this), 3647 fotoramaData = $fotorama.data(), 3648 fotorama = fotoramaData.fotorama; 3649 3650 if (!fotorama) { 3651 waitFor(function () { 3652 return !isHidden(that); 3653 }, function () { 3654 fotoramaData.urtext = $fotorama.html(); 3655 new $.Fotorama($fotorama, 3656 /* Priority for options: 3657 * 1. <div data-loop="true"></div> 3658 * 2. $('div').fotorama({loop: false}) 3659 * 3. Defaults */ 3660 $.extend( 3661 {}, 3662 OPTIONS, 3663 window.fotoramaDefaults, 3664 opts, 3665 fotoramaData 3666 ) 3667 ); 3668 }); 3669 } else { 3670 fotorama.setOptions(opts, true); 3671 } 3672 }); 3673}; 3674$.Fotorama.instances = []; 3675 3676function calculateIndexes () { 3677 $.each($.Fotorama.instances, function (index, instance) { 3678 instance.index = index; 3679 }); 3680} 3681 3682function addInstance (instance) { 3683 $.Fotorama.instances.push(instance); 3684 calculateIndexes(); 3685} 3686 3687function hideInstance (instance) { 3688 $.Fotorama.instances.splice(instance.index, 1); 3689 calculateIndexes(); 3690} 3691$.Fotorama.cache = {}; 3692$.Fotorama.measures = {}; 3693$ = $ || {}; 3694$.Fotorama = $.Fotorama || {}; 3695$.Fotorama.jst = $.Fotorama.jst || {}; 3696 3697$.Fotorama.jst.style = function(v) { 3698var __t, __p = '', __e = _.escape; 3699__p += '.fotorama' + 3700((__t = ( v.s )) == null ? '' : __t) + 3701' .fotorama__nav--thumbs .fotorama__nav__frame{\npadding:' + 3702((__t = ( v.m )) == null ? '' : __t) + 3703'px;\nheight:' + 3704((__t = ( v.h )) == null ? '' : __t) + 3705'px}\n.fotorama' + 3706((__t = ( v.s )) == null ? '' : __t) + 3707' .fotorama__thumb-border{\nheight:' + 3708((__t = ( v.h - v.b * (v.q ? 0 : 2) )) == null ? '' : __t) + 3709'px;\nborder-width:' + 3710((__t = ( v.b )) == null ? '' : __t) + 3711'px;\nmargin-top:' + 3712((__t = ( v.m )) == null ? '' : __t) + 3713'px}'; 3714return __p 3715}; 3716 3717$.Fotorama.jst.video = function(v) { 3718var __t, __p = '', __e = _.escape, __j = Array.prototype.join; 3719function print() { __p += __j.call(arguments, '') } 3720__p += '<div class="fotorama__video"><iframe src="'; 3721 print((v.type == 'youtube' ? v.p + 'youtube.com/embed/' + v.id +'?autoplay=1' : v.type == 'vimeo' ? v.p + 'player.vimeo.com/video/' + v.id + '?autoplay=1&badge=0' : v.id) + (v.s && v.type != 'custom' ? '&' + v.s : '')) ; 3722__p += '" frameborder="0" allowfullscreen></iframe></div>\n'; 3723return __p 3724}; 3725$(function () { 3726 $('.' + _fotoramaClass + ':not([data-auto="false"])').fotorama(); 3727}); 3728})(window, document, location, typeof jQuery !== 'undefined' && 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.