Advertisement
Guest User

fotor-opts

a guest
Jul 18th, 2013
499
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*!
  2.  * Fotorama 4.1.17 | http://fotorama.io/license/
  3.  */
  4. (function (window, document, $, undefined) {
  5.   "use strict";
  6. // My little Underscore
  7.  
  8. // List of HTML entities for escaping.
  9. var escapeEntityMap = {
  10.   '&': '&',
  11.   '<': '&lt;',
  12.   '>': '&gt;',
  13.   '"': '&quot;',
  14.   "'": '&#x27;',
  15.   '/': '&#x2F;'
  16. };
  17.  
  18. // Regexes containing the keys and values listed immediately above.
  19. var escapeRegex = new RegExp('[&<>"\'/]', 'g');
  20.  
  21. var _ = {
  22.   escape: function (string) {
  23.     if (string == null) return '';
  24.     return ('' + string).replace(escapeRegex, function (match) {
  25.       return escapeEntityMap[match];
  26.     });
  27.   }
  28. }
  29. /* Modernizr 2.6.2 (Custom Build) | MIT & BSD
  30.  * Build: http://modernizr.com/download/#-csstransforms3d-prefixed-teststyles-testprop-testallprops-prefixes-domprefixes
  31.  */
  32.  
  33. var Modernizr = (function (window, document, undefined) {
  34.  
  35.   var version = '2.6.2',
  36.  
  37.       Modernizr = {},
  38.  
  39.       docElement = document.documentElement,
  40.  
  41.       mod = 'modernizr',
  42.       modElem = document.createElement(mod),
  43.       mStyle = modElem.style,
  44.  
  45.       inputElem,
  46.  
  47.       toString = {}.toString,
  48.  
  49.       prefixes = ' -webkit- -moz- -o- -ms- '.split(' '),
  50.  
  51.       omPrefixes = 'Webkit Moz O ms',
  52.  
  53.       cssomPrefixes = omPrefixes.split(' '),
  54.  
  55.       domPrefixes = omPrefixes.toLowerCase().split(' '),
  56.  
  57.       tests = {},
  58.       inputs = {},
  59.       attrs = {},
  60.  
  61.       classes = [],
  62.  
  63.       slice = classes.slice,
  64.  
  65.       featureName,
  66.  
  67.       injectElementWithStyles = function (rule, callback, nodes, testnames) {
  68.  
  69.         var style, ret, node, docOverflow,
  70.             div = document.createElement('div'),
  71.             body = document.body,
  72.             fakeBody = body || document.createElement('body');
  73.  
  74.         if (parseInt(nodes, 10)) {
  75.           while (nodes--) {
  76.             node = document.createElement('div');
  77.             node.id = testnames ? testnames[nodes] : mod + (nodes + 1);
  78.             div.appendChild(node);
  79.           }
  80.         }
  81.  
  82.         style = ['&#173;', '<style id="s', mod, '">', rule, '</style>'].join('');
  83.         div.id = mod;
  84.         (body ? div : fakeBody).innerHTML += style;
  85.         fakeBody.appendChild(div);
  86.         if (!body) {
  87.           fakeBody.style.background = '';
  88.           fakeBody.style.overflow = 'hidden';
  89.           docOverflow = docElement.style.overflow;
  90.           docElement.style.overflow = 'hidden';
  91.           docElement.appendChild(fakeBody);
  92.         }
  93.  
  94.         ret = callback(div, rule);
  95.         if (!body) {
  96.           fakeBody.parentNode.removeChild(fakeBody);
  97.           docElement.style.overflow = docOverflow;
  98.         } else {
  99.           div.parentNode.removeChild(div);
  100.         }
  101.  
  102.         return !!ret;
  103.  
  104.       },
  105.       _hasOwnProperty = ({}).hasOwnProperty, hasOwnProp;
  106.  
  107.   if (!is(_hasOwnProperty, 'undefined') && !is(_hasOwnProperty.call, 'undefined')) {
  108.     hasOwnProp = function (object, property) {
  109.       return _hasOwnProperty.call(object, property);
  110.     };
  111.   }
  112.   else {
  113.     hasOwnProp = function (object, property) {
  114.       return ((property in object) && is(object.constructor.prototype[property], 'undefined'));
  115.     };
  116.   }
  117.  
  118.  
  119.   if (!Function.prototype.bind) {
  120.     Function.prototype.bind = function bind (that) {
  121.  
  122.       var target = this;
  123.  
  124.       if (typeof target != "function") {
  125.         throw new TypeError();
  126.       }
  127.  
  128.       var args = slice.call(arguments, 1),
  129.           bound = function () {
  130.  
  131.             if (this instanceof bound) {
  132.  
  133.               var F = function () {
  134.               };
  135.               F.prototype = target.prototype;
  136.               var self = new F();
  137.  
  138.               var result = target.apply(
  139.                   self,
  140.                   args.concat(slice.call(arguments))
  141.               );
  142.               if (Object(result) === result) {
  143.                 return result;
  144.               }
  145.               return self;
  146.  
  147.             } else {
  148.  
  149.               return target.apply(
  150.                   that,
  151.                   args.concat(slice.call(arguments))
  152.               );
  153.  
  154.             }
  155.  
  156.           };
  157.  
  158.       return bound;
  159.     };
  160.   }
  161.  
  162.   function setCss (str) {
  163.     mStyle.cssText = str;
  164.   }
  165.  
  166.   function setCssAll (str1, str2) {
  167.     return setCss(prefixes.join(str1 + ';') + ( str2 || '' ));
  168.   }
  169.  
  170.   function is (obj, type) {
  171.     return typeof obj === type;
  172.   }
  173.  
  174.   function contains (str, substr) {
  175.     return !!~('' + str).indexOf(substr);
  176.   }
  177.  
  178.   function testProps (props, prefixed) {
  179.     for (var i in props) {
  180.       var prop = props[i];
  181.       if (!contains(prop, "-") && mStyle[prop] !== undefined) {
  182.         return prefixed == 'pfx' ? prop : true;
  183.       }
  184.     }
  185.     return false;
  186.   }
  187.  
  188.   function testDOMProps (props, obj, elem) {
  189.     for (var i in props) {
  190.       var item = obj[props[i]];
  191.       if (item !== undefined) {
  192.  
  193.         if (elem === false) return props[i];
  194.  
  195.         if (is(item, 'function')) {
  196.           return item.bind(elem || obj);
  197.         }
  198.  
  199.         return item;
  200.       }
  201.     }
  202.     return false;
  203.   }
  204.  
  205.   function testPropsAll (prop, prefixed, elem) {
  206.  
  207.     var ucProp = prop.charAt(0).toUpperCase() + prop.slice(1),
  208.         props = (prop + ' ' + cssomPrefixes.join(ucProp + ' ') + ucProp).split(' ');
  209.  
  210.     if (is(prefixed, "string") || is(prefixed, "undefined")) {
  211.       return testProps(props, prefixed);
  212.  
  213.     } else {
  214.       props = (prop + ' ' + (domPrefixes).join(ucProp + ' ') + ucProp).split(' ');
  215.       return testDOMProps(props, prefixed, elem);
  216.     }
  217.   }
  218.  
  219.   tests['csstransforms3d'] = function () {
  220.  
  221.     var ret = !!testPropsAll('perspective');
  222.  
  223. // Chrome fails that test, ignore
  224. //      if (ret && 'webkitPerspective' in docElement.style) {
  225. //
  226. //          injectElementWithStyles('@media (transform-3d),(-webkit-transform-3d){#modernizr{left:9px;position:absolute;height:3px;}}', function (node, rule) {
  227. //              ret = node.offsetLeft === 9 && node.offsetHeight === 3;
  228. //          });
  229. //      }
  230.     return ret;
  231.   };
  232.  
  233.   for (var feature in tests) {
  234.     if (hasOwnProp(tests, feature)) {
  235.       featureName = feature.toLowerCase();
  236.       Modernizr[featureName] = tests[feature]();
  237.  
  238.       classes.push((Modernizr[featureName] ? '' : 'no-') + featureName);
  239.     }
  240.   }
  241.  
  242.   Modernizr.addTest = function (feature, test) {
  243.     if (typeof feature == 'object') {
  244.       for (var key in feature) {
  245.         if (hasOwnProp(feature, key)) {
  246.           Modernizr.addTest(key, feature[ key ]);
  247.         }
  248.       }
  249.     } else {
  250.  
  251.       feature = feature.toLowerCase();
  252.  
  253.       if (Modernizr[feature] !== undefined) {
  254.         return Modernizr;
  255.       }
  256.  
  257.       test = typeof test == 'function' ? test() : test;
  258.  
  259.       if (typeof enableClasses !== "undefined" && enableClasses) {
  260.         docElement.className += ' ' + (test ? '' : 'no-') + feature;
  261.       }
  262.       Modernizr[feature] = test;
  263.  
  264.     }
  265.  
  266.     return Modernizr;
  267.   };
  268.  
  269.  
  270.   setCss('');
  271.   modElem = inputElem = null;
  272.  
  273.  
  274.   Modernizr._version = version;
  275.  
  276.   Modernizr._prefixes = prefixes;
  277.   Modernizr._domPrefixes = domPrefixes;
  278.   Modernizr._cssomPrefixes = cssomPrefixes;
  279.  
  280.   Modernizr.testProp = function (prop) {
  281.     return testProps([prop]);
  282.   };
  283.  
  284.   Modernizr.testAllProps = testPropsAll;
  285.  
  286.   Modernizr.testStyles = injectElementWithStyles;
  287.   Modernizr.prefixed = function (prop, obj, elem) {
  288.     if (!obj) {
  289.       return testPropsAll(prop, 'pfx');
  290.     } else {
  291.       return testPropsAll(prop, obj, elem);
  292.     }
  293.   };
  294.  
  295.   return Modernizr;
  296. })(window, document);
  297. var
  298.     fullScreenApi = {
  299.       ok: false,
  300.       is: function () {
  301.         return false;
  302.       },
  303.       request: function () {
  304.       },
  305.       cancel: function () {
  306.       },
  307.       event: '',
  308.       prefix: ''
  309.     },
  310.     browserPrefixes = 'webkit moz o ms khtml'.split(' ');
  311.  
  312. // check for native support
  313. if (typeof document.cancelFullScreen != 'undefined') {
  314.   fullScreenApi.ok = true;
  315. } else {
  316.   // check for fullscreen support by vendor prefix
  317.   for (var i = 0, il = browserPrefixes.length; i < il; i++) {
  318.     fullScreenApi.prefix = browserPrefixes[i];
  319.     if (typeof document[fullScreenApi.prefix + 'CancelFullScreen' ] != 'undefined') {
  320.       fullScreenApi.ok = true;
  321.       break;
  322.     }
  323.   }
  324. }
  325.  
  326. // update methods to do something useful
  327. if (fullScreenApi.ok) {
  328.   fullScreenApi.event = fullScreenApi.prefix + 'fullscreenchange';
  329.   fullScreenApi.is = function () {
  330.     switch (this.prefix) {
  331.       case '':
  332.         return document.fullScreen;
  333.       case 'webkit':
  334.         return document.webkitIsFullScreen;
  335.       default:
  336.         return document[this.prefix + 'FullScreen'];
  337.     }
  338.   };
  339.   fullScreenApi.request = function (el) {
  340.     return (this.prefix === '') ? el.requestFullScreen() : el[this.prefix + 'RequestFullScreen']();
  341.   };
  342.   fullScreenApi.cancel = function (el) {
  343.     return (this.prefix === '') ? document.cancelFullScreen() : document[this.prefix + 'CancelFullScreen']();
  344.   };
  345. }
  346. /* Bez v1.0.10-g5ae0136
  347.  * http://github.com/rdallasgray/bez
  348.  *
  349.  * A plugin to convert CSS3 cubic-bezier co-ordinates to jQuery-compatible easing functions
  350.  *
  351.  * With thanks to Nikolay Nemshilov for clarification on the cubic-bezier maths
  352.  * See http://st-on-it.blogspot.com/2011/05/calculating-cubic-bezier-function.html
  353.  *
  354.  * Copyright 2011 Robert Dallas Gray. All rights reserved.
  355.  * Provided under the FreeBSD license: https://github.com/rdallasgray/bez/blob/master/LICENSE.txt
  356.  */
  357. function bez (coOrdArray) {
  358.   var encodedFuncName = "bez_" + $.makeArray(arguments).join("_").replace(".", "p");
  359.   if (typeof $['easing'][encodedFuncName] !== "function") {
  360.     var polyBez = function (p1, p2) {
  361.       var A = [null, null],
  362.           B = [null, null],
  363.           C = [null, null],
  364.           bezCoOrd = function (t, ax) {
  365.             C[ax] = 3 * p1[ax];
  366.             B[ax] = 3 * (p2[ax] - p1[ax]) - C[ax];
  367.             A[ax] = 1 - C[ax] - B[ax];
  368.             return t * (C[ax] + t * (B[ax] + t * A[ax]));
  369.           },
  370.           xDeriv = function (t) {
  371.             return C[0] + t * (2 * B[0] + 3 * A[0] * t);
  372.           },
  373.           xForT = function (t) {
  374.             var x = t, i = 0, z;
  375.             while (++i < 14) {
  376.               z = bezCoOrd(x, 0) - t;
  377.               if (Math.abs(z) < 1e-3) break;
  378.               x -= z / xDeriv(x);
  379.             }
  380.             return x;
  381.           };
  382.       return function (t) {
  383.         return bezCoOrd(xForT(t), 1);
  384.       }
  385.     };
  386.     $['easing'][encodedFuncName] = function (x, t, b, c, d) {
  387.       return c * polyBez([coOrdArray[0], coOrdArray[1]], [coOrdArray[2], coOrdArray[3]])(t / d) + b;
  388.     }
  389.   }
  390.   return encodedFuncName;
  391. }
  392. var _fotoramaClass = 'fotorama',
  393.     _fullscreenClass = 'fullscreen',
  394.  
  395.     wrapClass = _fotoramaClass + '__wrap',
  396.     wrapNotReadyClass = wrapClass + '--not-ready',
  397.     wrapCss3Class = wrapClass + '--css3',
  398.     wrapVideoClass = wrapClass + '--video',
  399.     wrapFadeClass = wrapClass + '--fade',
  400.     wrapSlideClass = wrapClass + '--slide',
  401.     wrapNoControlsClass = wrapClass + '--no-controls',
  402.  
  403.     stageClass = _fotoramaClass + '__stage',
  404.     stageFrameClass = stageClass + '__frame',
  405.     stageFrameVideoClass = stageFrameClass + '--video',
  406.     stageShaftClass = stageClass + '__shaft',
  407.     stageOnlyActiveClass = stageClass + '--only-active',
  408.  
  409.     grabClass = _fotoramaClass + '__grab',
  410.  
  411.     arrClass = _fotoramaClass + '__arr',
  412.     arrDisabledClass = arrClass + '--disabled',
  413.     arrPrevClass = arrClass + '--prev',
  414.     arrNextClass = arrClass + '--next',
  415.     arrArrClass = arrClass + '__arr',
  416.  
  417.     navClass = _fotoramaClass + '__nav',
  418.     navWrapClass = navClass + '-wrap',
  419.     navShaftClass = navClass + '__shaft',
  420.     navDotsClass = navClass + '--dots',
  421.     navThumbsClass = navClass + '--thumbs',
  422.     navFrameClass = navClass + '__frame',
  423.     navFrameDotClass = navFrameClass + '--dot',
  424.     navFrameThumbClass = navFrameClass + '--thumb',
  425.  
  426.     fadeClass = _fotoramaClass + '__fade',
  427.     fadeFrontClass = fadeClass + '-front',
  428.     fadeRearClass = fadeClass + '-rear',
  429.  
  430.  
  431.     shadowClass = _fotoramaClass + '__shadow',
  432.     shadowsClass = shadowClass + 's',
  433.     shadowsLeftClass = shadowsClass + '--left',
  434.     shadowsRightClass = shadowsClass + '--right',
  435.  
  436.     activeClass = _fotoramaClass + '__active',
  437.     selectClass = _fotoramaClass + '__select',
  438.  
  439.     hiddenClass = _fotoramaClass + '--hidden',
  440.  
  441.     fullscreenClass = _fotoramaClass + '--fullscreen',
  442.     fullscreenIconClass = _fotoramaClass + '__fullscreen-icon',
  443.  
  444.     errorClass = _fotoramaClass + '__error',
  445.     loadingClass = _fotoramaClass + '__loading',
  446.     loadedClass = _fotoramaClass + '__loaded',
  447.     loadedFullClass = loadedClass + '--full',
  448.     loadedImgClass = loadedClass + '--img',
  449.     loadClass = _fotoramaClass + '__load',
  450.  
  451.     imgClass = _fotoramaClass + '__img',
  452.     imgFullClass = imgClass + '--full',
  453.  
  454.     dotClass = _fotoramaClass + '__dot',
  455.     thumbClass = _fotoramaClass + '__thumb',
  456.     thumbBorderClass = thumbClass + '-border',
  457.  
  458.     htmlClass = _fotoramaClass + '__html',
  459.  
  460.     videoClass = _fotoramaClass + '__video',
  461.     videoPlayClass = videoClass + '-play',
  462.     videoCloseClass = videoClass + '-close',
  463.  
  464.     captionClass = _fotoramaClass + '__caption',
  465.  
  466.     ooooClass = _fotoramaClass + '__oooo';
  467.  
  468. var $WINDOW = $(window),
  469.     $DOCUMENT = $(document),
  470.     $HTML,
  471.     $BODY,
  472.  
  473.     COMPAT = document.compatMode === 'CSS1Compat',
  474.     QUIRKS_FORCE = document.location.hash.replace('#', '') === 'quirks',
  475.     CSS3 = Modernizr.csstransforms3d && !QUIRKS_FORCE,
  476.     FULLSCREEN = fullScreenApi.ok,
  477.  
  478.     TOUCH_TIMEOUT = 300,
  479.     TRANSITION_DURATION = 333,
  480.     AUTOPLAY_INTERVAL = 5000,
  481.     MARGIN = 2,
  482.     THUMB_SIZE = 64,
  483.  
  484.     WIDTH = 500,
  485.     HEIGHT = 333,
  486.  
  487.     BEZIER = bez([.1, 0, .25, 1]);
  488.  
  489. function noop () {}
  490.  
  491. function minMaxLimit (value, min, max) {
  492.   return Math.max(isNaN(min) ? -Infinity : min, Math.min(isNaN(max) ? Infinity : max, value));
  493. }
  494.  
  495. function readTransform (css) {
  496.   return css.match(/^m/) && css.match(/-?\d+/g)[4];
  497. }
  498.  
  499. function readPosition ($el) {
  500.   if (CSS3) {
  501.     return +readTransform($el.css('transform'));
  502.   } else {
  503.     return +$el.css('left').replace('px', '');
  504.   }
  505. }
  506.  
  507. function getTranslate (pos) {
  508.   var obj = {};
  509.   if (CSS3) {
  510.     obj.transform = 'translate3d(' + pos + 'px,0,0)';
  511.   } else {
  512.     obj.left = pos;
  513.   }
  514.   return obj;
  515. }
  516.  
  517. function getDuration (time) {
  518.   return {'transition-duration': time + 'ms'};
  519. }
  520.  
  521. function numberFromMeasure (value, measure) {
  522.   return +String(value).replace(measure || 'px', '');
  523. }
  524.  
  525. function numberFromPercent (value) {
  526.   return /%$/.test(value) && numberFromMeasure(value, '%');
  527. }
  528.  
  529. function measureIsValid (value) {
  530.   return (!!numberFromMeasure(value) || !!numberFromMeasure(value, '%')) && value;
  531. }
  532.  
  533. function getPosByIndex (index, side, margin, baseIndex) {
  534.   return (index - (baseIndex || 0)) * (side + (margin || 0));
  535. }
  536.  
  537. function getIndexByPos (pos, side, margin, baseIndex) {
  538.   return -Math.round(pos / (side + (margin || 0)) - (baseIndex || 0));
  539. }
  540.  
  541. function bindTransitionEnd ($el) {
  542.   var elData = $el.data();
  543.  
  544.   if (elData.tEnd) return;
  545.  
  546.   //console.log('bindTransitionEnd', $('img', $el).attr('src'));
  547.  
  548.   var el = $el[0],
  549.       transitionEndEvent = {
  550.         WebkitTransition: 'webkitTransitionEnd',
  551.         MozTransition: 'transitionend',
  552.         OTransition: 'oTransitionEnd otransitionend',
  553.         msTransition: 'MSTransitionEnd',
  554.         transition: 'transitionend'
  555.       };
  556.   el.addEventListener(transitionEndEvent[Modernizr.prefixed('transition')], function (e) {
  557.     //console.log('NATIVE transitionend', e.propertyName, elData.tProp && e.propertyName.match(elData.tProp) && 'CALL');
  558.     elData.tProp && e.propertyName.match(elData.tProp) && elData.onEndFn.call(this);
  559.   });
  560.   elData.tEnd = true;
  561. }
  562.  
  563. function afterTransition ($el, property, fn, time) {
  564.   var done,
  565.       elData = $el.data();
  566.  
  567.   //console.log('afterTransition', $el);
  568.  
  569.   if (elData) {
  570.     //clearTimeout(elData.tT);
  571.  
  572.     elData.onEndFn = function () {
  573.       if (done) return;
  574.       //.log('elData.onEndFn()', fn);
  575.       fn.call(this);
  576.       done = true;
  577.     };
  578.     elData.tProp = property;
  579.  
  580.     bindTransitionEnd($el);
  581.  
  582. //    if (!time) return;
  583. //
  584. //    elData.tT = setTimeout(function () {
  585. //      // Если не сработал нативный transitionend (а такое бывает),
  586. //      // через таймаут вызываем onEndFn насильно:
  587. //      //.log('request for FALLBACK', $el, fn);
  588. //      if (done) return;
  589. //      //.log('FALLBACK!!! for transition', $el, fn);
  590. //      elData.onEndFn();
  591. //    }, time * 5);
  592.   }
  593. }
  594.  
  595. function stop ($el) {
  596.   if (CSS3) {
  597.     $el
  598.         .css(getDuration(0))
  599.         .data('onEndFn', noop);
  600.   } else {
  601.     $el.stop();
  602.   }
  603.   if ($el.length) {
  604.     ////console.log('$el.length', $el);
  605.     var lockedLeft = readPosition($el);
  606.     $el.css(getTranslate(lockedLeft));
  607.     return lockedLeft;
  608.   }
  609. }
  610.  
  611. function edgeResistance (pos, edge) {
  612.   return Math.round(pos + ((edge - pos) / 1.5));
  613. }
  614.  
  615. function getProtocol () {
  616.   getProtocol.p = getProtocol.p || (location.protocol === 'https://' ? 'https://' : 'http://');
  617.   return getProtocol.p;
  618. }
  619.  
  620. function parseHref (href) {
  621.   var a = document.createElement('a');
  622.   a.href = href;
  623.   return a;
  624. }
  625.  
  626. function findVideoId (href, forceVideo) {
  627.   if (typeof href !== 'string') return href;
  628.   href = parseHref(href);
  629.  
  630.   // href.host = href.host.replace(/^www./, '').replace(/:80$/, '');
  631.  
  632.   var id,
  633.       type;
  634.  
  635.   if (href.host.match(/youtube\.com/) && href.search) {
  636.     //.log();
  637.     id = href.search.split('v=')[1];
  638.     if (id) {
  639.       var ampersandPosition = id.indexOf('&');
  640.       if (ampersandPosition !== -1) {
  641.         id = id.substring(0, ampersandPosition);
  642.       }
  643.       type = 'youtube';
  644.     }
  645.   } else if (href.host.match(/youtube\.com|youtu\.be/)) {
  646.     id = href.pathname.replace(/^\/(embed\/|v\/)?/, '').replace(/\/.*/, '');
  647.     type = 'youtube';
  648.   } else if (href.host.match(/vimeo\.com/)) {
  649.     type = 'vimeo';
  650.     id = href.pathname.replace(/^\/(video\/)?/, '').replace(/\/.*/, '');
  651.   }
  652.  
  653.   //.log('id, type ', id, type);
  654.  
  655.   if ((!id || !type) && forceVideo) {
  656.     id = href.href;
  657.     type = 'custom';
  658.   }
  659.  
  660.   return id ? {id: id, type: type} : false;
  661. }
  662.  
  663. function getVideoThumbs (dataFrame, data, api) {
  664.   ////console.log('getVideoThumbs');
  665.  
  666.   var img, thumb, video = dataFrame.video;
  667.   if (video.type === 'youtube') {
  668.     thumb = getProtocol() + 'img.youtube.com/vi/' + video.id + '/default.jpg';
  669.     img = thumb.replace(/\/default.jpg$/, '/hqdefault.jpg');
  670.     dataFrame.thumbsReady = true;
  671.   } else if (video.type === 'vimeo') {
  672.     $.ajax({
  673.       url: getProtocol() + 'vimeo.com/api/v2/video/' + video.id + '.json',
  674.       dataType: 'jsonp',
  675.       success: function (json) {
  676.         dataFrame.thumbsReady = true;
  677.         updateData(data, {img: json[0].thumbnail_large, thumb: json[0].thumbnail_small}, dataFrame.i, api);
  678.       }
  679.     });
  680.   } else {
  681.     dataFrame.thumbsReady = true;
  682.   }
  683.  
  684.   return {
  685.     img: img,
  686.     thumb: thumb
  687.   }
  688. }
  689.  
  690. function updateData (data, _dataFrame, i, api) {
  691.   for (var _i = 0, _l = data.length; _i < _l; _i++) {
  692.     var dataFrame = data[_i];
  693.  
  694.     if (dataFrame.i === i && dataFrame.thumbsReady) {
  695.  
  696.       api.splice(_i, 1, {
  697.         i: i,
  698.         video: dataFrame.video,
  699.         videoReady: true,
  700.         caption: dataFrame.caption,
  701.         img: dataFrame.img || _dataFrame.img,
  702.         thumb: dataFrame.thumb || _dataFrame.thumb,
  703.         id: dataFrame.id,
  704.         fit: dataFrame.fit
  705.       });
  706.  
  707.       break;
  708.     }
  709.   }
  710. }
  711.  
  712. function getDataFromHtml ($el) {
  713.   var data = [];
  714.  
  715.   function getDataFromImg ($img, checkVideo) {
  716.     var imgData = $img.data(),
  717.         $child = $img.children('img').eq(0),
  718.         _imgHref = $img.attr('href'),
  719.         _imgSrc = $img.attr('src'),
  720.         _thumbSrc = $child.attr('src'),
  721.         _video = imgData.video,
  722.         video = checkVideo ? findVideoId(_imgHref, _video === true) : false;
  723.  
  724.     if (video) {
  725.       _imgHref = false;
  726.     } else {
  727.       video = findVideoId(_video, _video);
  728.     }
  729.  
  730.     return {
  731.       video: video,
  732.       img: imgData.img || _imgHref || _imgSrc || _thumbSrc,
  733.       thumb: imgData.thumb || _thumbSrc || _imgSrc || _imgHref
  734.     }
  735.   }
  736.  
  737.   $el.children().each(function (i) {
  738.     var $this = $(this),
  739.         dataFrame = $.extend($this.data(), {id: $this.attr('id')});
  740.     if ($this.is('a, img')) {
  741.       $.extend(dataFrame, getDataFromImg($this, true));
  742.     } else if (!$this.is(':empty')) {
  743.       $.extend(dataFrame, {
  744.         html: this,
  745.         _html: $this.html() // Because of IE
  746.       });
  747.     } else return;
  748.  
  749.     data.push(dataFrame);
  750.   });
  751.  
  752.   return data;
  753. }
  754.  
  755. function isHidden (el) {
  756.   return el.offsetWidth === 0 && el.offsetHeight === 0;
  757. }
  758.  
  759. function waitFor (test, fn, timeout) {
  760.   if (test()) {
  761.     fn();
  762.   } else {
  763.     setTimeout(function () {
  764.       waitFor(test, fn);
  765.     }, timeout || 100);
  766.   }
  767. }
  768.  
  769. function setHash (hash) {
  770.   location.replace(location.protocol
  771.       + '//'
  772.       + location.host
  773.       + location.pathname.replace(/^\/?/, '/')
  774.       + location.search
  775.       + '#' + hash);
  776. }
  777.  
  778. function fit ($el, measuresToFit, method) {
  779.   ////console.log('fit');
  780.  
  781.   var elData = $el.data(),
  782.       measures = elData.measures;
  783.  
  784.   if (measures && (!elData.l ||
  785.       elData.l.W !== measures.width ||
  786.       elData.l.H !== measures.height ||
  787.       elData.l.r !== measures.ratio ||
  788.       elData.l.w !== measuresToFit.w ||
  789.       elData.l.h !== measuresToFit.h ||
  790.       elData.l.m !== method)) {
  791.  
  792.     ////console.log('fit execute', measures, measuresToFit);
  793.  
  794.     var width = measures.width,
  795.         height = measures.height,
  796.         ratio = measuresToFit.w / measuresToFit.h,
  797.         biggerRatioFLAG = measures.ratio >= ratio,
  798.         fitFLAG = method === 'scale-down',
  799.         containFLAG = method === 'contain',
  800.         coverFLAG = method === 'cover';
  801.  
  802.     if (biggerRatioFLAG && (fitFLAG || containFLAG) || !biggerRatioFLAG && coverFLAG) {
  803.       width = minMaxLimit(measuresToFit.w, 0, fitFLAG ? width : Infinity);
  804.       height = width / measures.ratio;
  805.     } else if (biggerRatioFLAG && coverFLAG || !biggerRatioFLAG && (fitFLAG || containFLAG)) {
  806.       height = minMaxLimit(measuresToFit.h, 0, fitFLAG ? height : Infinity);
  807.       width = height * measures.ratio;
  808.     }
  809.  
  810.     $el.css({
  811.       width: Math.round(width),
  812.       height: Math.round(height),
  813.       marginLeft: Math.round(-width / 2),
  814.       marginTop: Math.round(-height / 2)
  815.     });
  816.  
  817.     elData.l = {
  818.       W: measures.width,
  819.       H: measures.height,
  820.       r: measures.ratio,
  821.       w: measuresToFit.w,
  822.       h: measuresToFit.h,
  823.       m: method
  824.     }
  825.   }
  826. }
  827.  
  828. function setStyle ($el, style) {
  829.   var el = $el[0];
  830.   if (el.styleSheet) {
  831.     el.styleSheet.cssText = style;
  832.   } else {
  833.     $el.html(style);
  834.   }
  835. }
  836.  
  837. function findShadowEdge (pos, minPos, maxPos) {
  838.   return minPos === maxPos ? false : pos <= minPos ? 'left' : pos >= maxPos ? 'right' : 'left right';
  839. }
  840.  
  841. function getIndexFromHash (hash, data, ok) {
  842.   if (!ok) return false;
  843.  
  844.   var index;
  845.   if (!isNaN(hash)) return +hash;
  846.  
  847.   for (var _i = 0, _l = data.length; _i < _l; _i++) {
  848.     var dataFrame = data[_i];
  849.  
  850.     if (dataFrame.id === hash) {
  851.       index = _i;
  852.       break;
  853.     }
  854.   }
  855.  
  856.   return index;
  857. }
  858.  
  859. function smartClick ($el, fn, _options) {
  860.   _options = _options || {};
  861.  
  862.   $el.each(function () {
  863.     var $this = $(this),
  864.         thisData = $this.data(),
  865.         startEvent;
  866.  
  867.     if (thisData.clickOn) return;
  868.  
  869.     thisData.clickOn = true;
  870.  
  871.     $.extend(touch($this, {
  872.       onStart: function (e) {
  873.         startEvent = e;
  874.         (_options.onStart || noop).call(this, e);
  875.       },
  876.       onMove: _options.onMove || noop,
  877.       onEnd: function (result) {
  878.         if (result.moved || _options.tail.checked) return;
  879.         fn.call(this, startEvent);
  880.       }
  881.     }), _options.tail);
  882.  
  883.   });
  884. }
  885.  
  886. function div (classes, child) {
  887.   return '<div class="' + classes + '">' + (child || '') + '</div>';
  888. }
  889. function slide ($el, options) {
  890.   var elPos = Math.round(options.pos),
  891.       onEndFn = options.onEnd || noop;
  892.  
  893.   if (typeof options.overPos !== 'undefined' && options.overPos !== options.pos) {
  894.     elPos = options.overPos;
  895.     onEndFn = function () {
  896.       slide($el, $.extend({}, options, {overPos: options.pos, time: Math.max(TRANSITION_DURATION, options.time / 2)}))
  897.     };
  898.   }
  899.  
  900.   var translate = getTranslate(elPos);
  901.  
  902.   if (CSS3) {
  903.     $el.css($.extend(getDuration(options.time), translate));
  904.     if (options.time > 10) {
  905.       afterTransition($el, 'transform', onEndFn, options.time);
  906.     } else {
  907.       onEndFn();
  908.     }
  909.   } else {
  910.     $el.stop().animate(translate, options.time, BEZIER, onEndFn);
  911.   }
  912. }
  913.  
  914. function fade ($el1, $el2, $frames, options) {
  915.   //console.log('fade', !!$el1, !!$el2);
  916.  
  917.   var _$el1 = $el1, _$el2 = $el2, crossfadeFLAG = options.method === 'crossfade';
  918.   /*fade.$el1 = */$el1 = $el1 || $($el1);
  919.   /*fade.$el2 = */$el2 = $el2 || $($el2);
  920.  
  921.   var onEndFn = function () {
  922.         if (!onEndFn.done) {
  923.           //$el1.removeClass(fadeRearClass);
  924.           //$el2.removeClass(fadeFrontClass);
  925.           //console.log('onEndFn');
  926.           (options.onEnd || noop)();
  927.           onEndFn.done = true;
  928.         }
  929.       },
  930.       duration = getDuration(options.time),
  931.       duration0 = getDuration(0),
  932.       opacity0 = {opacity: 0},
  933.       opacity1 = {opacity: 1};
  934.  
  935.   $frames.removeClass(fadeRearClass + ' ' + fadeFrontClass);
  936.  
  937.   $el1
  938.       .addClass(fadeRearClass);
  939.   //.removeClass(fadeRearClass);
  940.   $el2
  941.       .addClass(fadeFrontClass);
  942.   //.removeClass(fadeFrontClass);
  943.  
  944.   if (CSS3) {
  945.     stop($el1);
  946.     stop($el2);
  947.  
  948.     crossfadeFLAG && _$el2 && $el1.css($.extend(duration0, opacity0)).width(); // .width() for immediate reflow
  949.  
  950.     $el1.css($.extend(crossfadeFLAG ? duration : duration0, opacity1));
  951.     $el2.css($.extend(duration, opacity0));
  952.  
  953.     if (options.time > 10 && (_$el1 || _$el2)) {
  954.       afterTransition($el1, 'opacity', onEndFn, options.time);
  955.       afterTransition($el2, 'opacity', onEndFn, options.time);
  956.     } else {
  957.       onEndFn();
  958.     }
  959.  
  960.   } else {
  961.     $el1.stop();
  962.     $el2.stop();
  963.  
  964.     if (_$el2) {
  965.       $el1.fadeTo(0, 0);
  966.     }
  967.  
  968.     $el1.fadeTo(options.time, 1, onEndFn);
  969.     crossfadeFLAG && $el2.fadeTo(options.time, 0);
  970.  
  971.     if (!_$el1 && !_$el2) onEndFn();
  972.   }
  973. }
  974. var lastEvent,
  975.     moveEventType,
  976.     preventEvent,
  977.     preventEventTimeout;
  978.  
  979. function extendEvent (e, touchFLAG) {
  980.   ////console.log(e.type);
  981.   e._x = touchFLAG ? e.touches[0].pageX : e.pageX;
  982.   e._y = touchFLAG ? e.touches[0].pageY : e.pageY;
  983. }
  984.  
  985. function touch ($el, options) {
  986.   var el = $el[0],
  987.       tail = {},
  988.       touchEnabledFLAG,
  989.       movableFLAG,
  990.       startEvent,
  991.       eventFlowFLAG,
  992.       movedFLAG,
  993.       $target,
  994.       controlTouch,
  995.       touchFLAG,
  996.       targetIsSelectFLAG,
  997.       targetIsLinkFlag;
  998.  
  999.   function onStart (e) {
  1000.  
  1001.     $target = $(e.target);
  1002.     tail.checked = movableFLAG = movedFLAG = targetIsSelectFLAG = targetIsLinkFlag = false;
  1003.  
  1004.     if (touchEnabledFLAG
  1005.         || eventFlowFLAG
  1006.         || (e.touches && e.touches.length > 1)
  1007.         || e.which > 1
  1008.         /*|| tail.prevent*/
  1009.         || (lastEvent && lastEvent.type !== e.type && preventEvent)
  1010.         || (targetIsSelectFLAG = options.select && $target.is(options.select, el))) return /*tail.prevent !== true || */targetIsSelectFLAG;
  1011.  
  1012.     touchFLAG = e.type.match('touch');
  1013.     targetIsLinkFlag = $target.is('a, a *', el);
  1014.     extendEvent(e, touchFLAG);
  1015.  
  1016.     lastEvent = e;
  1017.     moveEventType = e.type.replace(/down|start/, 'move');
  1018.     startEvent = e;
  1019.     controlTouch = tail.control;
  1020.  
  1021.     (options.onStart || noop).call(el, e, {control: controlTouch, $target: $target});
  1022.  
  1023.     touchEnabledFLAG = eventFlowFLAG = true;
  1024.  
  1025.     if (!touchFLAG) {
  1026.       e.preventDefault();
  1027.     }
  1028.   }
  1029.  
  1030.   function onMove (e) {
  1031.  
  1032.     if (!touchEnabledFLAG
  1033.         || (e.touches && e.touches.length > 1)) {
  1034.       onEnd();
  1035.       return;
  1036.     } else if (moveEventType !== e.type) {
  1037.       return;
  1038.     }
  1039.  
  1040.     extendEvent(e, touchFLAG);
  1041.  
  1042.     var xDiff = Math.abs(e._x - startEvent._x), // opt _x → _pageX
  1043.         yDiff = Math.abs(e._y - startEvent._y),
  1044.         xyDiff = xDiff - yDiff,
  1045.         xWin = !tail.stable || xyDiff >= 3,
  1046.         yWin = xyDiff <= -3;
  1047.  
  1048.     if (!movedFLAG) {
  1049.       movedFLAG = /*!tail.noMove && */ !(!xWin && !yWin);
  1050.     }
  1051.  
  1052.     if (touchFLAG && !tail.checked) {
  1053.       if (xWin || yWin) {
  1054.         tail.checked = true;
  1055.         movableFLAG = xWin;
  1056.       }
  1057.  
  1058.       if (!tail.checked || movableFLAG) {
  1059.         e.preventDefault();
  1060.       }
  1061.     } else if (!touchFLAG || movableFLAG) {
  1062.       e.preventDefault();
  1063.       (options.onMove || noop).call(el, e);
  1064.     } else {
  1065.       touchEnabledFLAG = false;
  1066.     }
  1067.  
  1068.     tail.checked = tail.checked || xWin || yWin;
  1069.   }
  1070.  
  1071.   function onEnd (e) {
  1072.     var _touchEnabledFLAG = touchEnabledFLAG;
  1073.     eventFlowFLAG = tail.control = touchEnabledFLAG = false;
  1074.     if (!_touchEnabledFLAG || (targetIsLinkFlag && !tail.checked)) return;
  1075.     ////console.log('onEnd', e && e.type);
  1076.     e && e.preventDefault();
  1077.     preventEvent = true;
  1078.     clearTimeout(preventEventTimeout);
  1079.     preventEventTimeout = setTimeout(function () {
  1080.       preventEvent = false;
  1081.     }, 1000);
  1082.     (options.onEnd || noop).call(el, {moved: !!movedFLAG, $target: $target, control: controlTouch, startEvent: startEvent, aborted: !e, touch: touchFLAG});
  1083.   }
  1084.  
  1085.  
  1086.   if (el.addEventListener) {
  1087.     el.addEventListener('touchstart', onStart);
  1088.     el.addEventListener('touchmove', onMove);
  1089.     el.addEventListener('touchend', onEnd);
  1090.   }
  1091.  
  1092.   $el.on('mousedown', onStart);
  1093.   $DOCUMENT
  1094.       .on('mousemove', onMove)
  1095.       .on('mouseup', onEnd);
  1096.  
  1097.   $el.on('click', 'a', function (e) {
  1098.     ////console.log('a click', tail.checked);
  1099.     if (tail.checked) {
  1100.       e.preventDefault();
  1101.     }
  1102.   });
  1103.  
  1104.   return tail;
  1105. }
  1106. function moveOnTouch ($el, options) {
  1107.   var el = $el[0],
  1108.       elData = $el.data(),
  1109.       tail = {},
  1110.       startCoo,
  1111.       coo,
  1112.       startElPos,
  1113.       moveElPos,
  1114.       edge,
  1115.       moveTrack,
  1116.       endTime,
  1117.       minPos,
  1118.       maxPos,
  1119.       snap,
  1120.       slowFLAG,
  1121.       controlFLAG,
  1122.       movedFLAG,
  1123.       stableFLAG;
  1124.  
  1125.   function startTracking (e) {
  1126.     startCoo = coo = e._x;
  1127.  
  1128.     moveTrack = [
  1129.       [new Date().getTime(), startCoo]
  1130.     ];
  1131.  
  1132.     startElPos = moveElPos = stop($el);
  1133.  
  1134.     stableFLAG = tail.stable = !(startElPos % snap);
  1135.     !stableFLAG && e.preventDefault();
  1136.  
  1137.     (options.onStart || noop).call(el, e, {pos: startElPos});
  1138.   }
  1139.  
  1140.   function onStart (e, result) {
  1141.     minPos = elData.minPos;
  1142.     maxPos = elData.maxPos;
  1143.     snap = elData.snap;
  1144.  
  1145.     slowFLAG = e.altKey;
  1146.     movedFLAG = false;
  1147.  
  1148.     controlFLAG = result.control;
  1149.  
  1150.     if (!controlFLAG) {
  1151.       startTracking(e);
  1152.     }
  1153.   }
  1154.  
  1155.   function onMove (e) {
  1156.     if (controlFLAG) {
  1157.       controlFLAG = false;
  1158.       startTracking(e);
  1159.     }
  1160.  
  1161.     coo = e._x;
  1162.  
  1163.     moveTrack.push([new Date().getTime(), coo]);
  1164.  
  1165.     moveElPos = startElPos - (startCoo - coo);
  1166.  
  1167.     edge = findShadowEdge(moveElPos, minPos, maxPos);
  1168.  
  1169.     if (moveElPos <= minPos) {
  1170.       moveElPos = edgeResistance(moveElPos, minPos);
  1171.     } else if (moveElPos >= maxPos) {
  1172.       moveElPos = edgeResistance(moveElPos, maxPos);
  1173.     }
  1174.  
  1175.  
  1176.     if (!tail.noMove) {
  1177.       $el.css(getTranslate(moveElPos));
  1178.       if (!movedFLAG) {
  1179.         movedFLAG = true;
  1180.         $BODY.addClass('grabbing');
  1181.       }
  1182.     }
  1183.  
  1184.     (options.onMove || noop).call(el, e, {pos: moveElPos, edge: edge});
  1185.   }
  1186.  
  1187.   function onEnd (result) {
  1188.     if (controlFLAG) return;
  1189.  
  1190.     $BODY.removeClass('grabbing');
  1191.  
  1192.     endTime = new Date().getTime();
  1193.  
  1194.     var _backTimeIdeal = endTime - TOUCH_TIMEOUT,
  1195.         _backTime,
  1196.         _timeDiff,
  1197.         _timeDiffLast,
  1198.         backTime = null,
  1199.         backCoo,
  1200.         virtualPos,
  1201.         limitPos,
  1202.         newPos,
  1203.         overPos,
  1204.         time = TRANSITION_DURATION,
  1205.         speed,
  1206.         friction = options.friction;
  1207.  
  1208.     for (var _i = moveTrack.length - 1; _i >= 0; _i--) {
  1209.       _backTime = moveTrack[_i][0];
  1210.       _timeDiff = Math.abs(_backTime - _backTimeIdeal);
  1211.       if (backTime === null || _timeDiff < _timeDiffLast) {
  1212.         backTime = _backTime;
  1213.         backCoo = moveTrack[_i][1];
  1214.       } else if (backTime === _backTimeIdeal || _timeDiff > _timeDiffLast) {
  1215.         break;
  1216.       }
  1217.       _timeDiffLast = _timeDiff;
  1218.     }
  1219.  
  1220.     newPos = minMaxLimit(moveElPos, minPos, maxPos);
  1221.  
  1222.     var cooDiff = backCoo - coo,
  1223.         forwardFLAG = cooDiff >= 0,
  1224.         timeDiff = endTime - backTime,
  1225.         longTouchFLAG = timeDiff > TOUCH_TIMEOUT,
  1226.         swipeFLAG = !longTouchFLAG && moveElPos !== startElPos && newPos === moveElPos;
  1227.  
  1228.     if (snap) {
  1229.       newPos = minMaxLimit(Math[swipeFLAG ? (forwardFLAG ? 'floor' : 'ceil') : 'round'](moveElPos / snap) * snap, minPos, maxPos);
  1230.       minPos = maxPos = newPos;
  1231.     }
  1232.  
  1233.     if (swipeFLAG && (snap || newPos === moveElPos)) {
  1234.       speed = -(cooDiff / timeDiff);
  1235.       time *= minMaxLimit(Math.abs(speed), options.timeLow, options.timeHigh);
  1236.       virtualPos = Math.round(moveElPos + speed * time / friction);
  1237.  
  1238.       if (!snap) {
  1239.         newPos = virtualPos;
  1240.       }
  1241.  
  1242.       if (!forwardFLAG && virtualPos > maxPos || forwardFLAG && virtualPos < minPos) {
  1243.         limitPos = forwardFLAG ? minPos : maxPos;
  1244.         overPos = virtualPos - limitPos;
  1245.         if (!snap) {
  1246.           newPos = limitPos;
  1247.         }
  1248.         overPos = minMaxLimit(newPos + overPos * .03, limitPos - 50, limitPos + 50);
  1249.         time = Math.abs((moveElPos - overPos) / (speed / friction));
  1250.       }
  1251.     }
  1252.  
  1253.     time *= slowFLAG ? 10 : 1;
  1254.  
  1255.     (options.onEnd || noop).call(el, $.extend(result, {pos: moveElPos, newPos: newPos, overPos: overPos, time: time, moved: (longTouchFLAG && snap) || result.moved}));
  1256.   }
  1257.  
  1258.   tail = $.extend(touch(options.$wrap, {
  1259.     onStart: onStart,
  1260.     onMove: onMove,
  1261.     onEnd: onEnd,
  1262.     select: options.select,
  1263.     control: options.control
  1264.   }), tail);
  1265.  
  1266.   return tail;
  1267. }
  1268. var $oooo = $(div('', div(ooooClass))),
  1269.     ooooInterval,
  1270.     ooooStep = function () {
  1271.       $oooo.attr('class', ooooClass + ' ' + ooooClass + '--' + ooooI);
  1272.       ooooI++;
  1273.       if (ooooI > 4) ooooI = 0;
  1274.     },
  1275.     ooooI;
  1276.  
  1277. function ooooStart ($el) {
  1278.   ooooStop(true);
  1279.   $oooo.appendTo($el);
  1280.   ooooI = 0;
  1281.   ooooStep();
  1282.   ooooInterval = setInterval(ooooStep, 200);
  1283. }
  1284.  
  1285. function ooooStop (leave) {
  1286.   leave || $oooo.detach();
  1287.   clearInterval(ooooInterval);
  1288. }
  1289.  
  1290. jQuery.Fotorama = function ($fotorama, opts) {
  1291.   $HTML = $HTML || $('html');
  1292.   $BODY = $BODY || $('body');
  1293.  
  1294.   $.Fotorama.$load = $.Fotorama.$load || $('<div class="' + loadClass + '"></div>').appendTo($BODY);
  1295.  
  1296.   var that = this,
  1297.       index = _size,
  1298.       stamp = new Date().getTime(),
  1299.       fotorama = $fotorama.addClass(_fotoramaClass + stamp)[0],
  1300.       data,
  1301.       dataFrameCount = 1,
  1302.       fotoramaData = $fotorama.data(),
  1303.       size,
  1304.  
  1305.       $style = $('<style></style>').insertBefore($fotorama),
  1306.  
  1307.       $anchor = $(div(hiddenClass)).insertBefore($fotorama),
  1308.       $wrap = $(div(wrapClass + ' ' + wrapNotReadyClass)),
  1309.       $stage = $(div(stageClass)).appendTo($wrap),
  1310.       stage = $stage[0],
  1311.       $stageShaft = $(div(stageShaftClass)).appendTo($stage),
  1312.       $stageFrame = $(),
  1313.      $arrPrev = $(div(arrClass + ' ' + arrPrevClass, div(arrArrClass))),
  1314.     $arrNext = $(div(arrClass + ' ' + arrNextClass, div(arrArrClass))),
  1315.      $arrs = $arrPrev.add($arrNext).appendTo($stage),
  1316.       $navWrap = $(div(navWrapClass)),
  1317.       $nav = $(div(navClass)).appendTo($navWrap),
  1318.       $navShaft = $(div(navShaftClass)).appendTo($nav),
  1319.       $navFrame,
  1320.       $navDotFrame = $(),
  1321.       $navThumbFrame = $(),
  1322.       stageFrameKey = '$stageFrame',
  1323.       navFrameKey,
  1324.       navDotFrameKey = '$navDotFrame',
  1325.       navThumbFrameKey = '$navThumbFrame',
  1326.  
  1327.       stageShaftData = $stageShaft.data(),
  1328.       navShaftData = $navShaft.data(),
  1329.  
  1330.       $thumbBorder = $(div(thumbBorderClass)).appendTo($navShaft),
  1331.  
  1332.       $fullscreenIcon = $(div(fullscreenIconClass)),
  1333.       $videoPlay = $(div(videoPlayClass)),
  1334.       $videoClose = $(div(videoCloseClass)).appendTo($stage),
  1335.  
  1336.       $videoPlaying,
  1337.  
  1338.       activeIndex = false,
  1339.       activeFrame,
  1340.       repositionIndex,
  1341.       dirtyIndex,
  1342.       lastActiveIndex,
  1343.       prevIndex,
  1344.       nextIndex,
  1345.       startIndex = false,
  1346.  
  1347.       o_loop,
  1348.       o_nav,
  1349.       o_navTop,
  1350.       o_allowFullScreen,
  1351.       o_nativeFullScreen,
  1352.       o_fade,
  1353.       o_thumbSide,
  1354.       o_thumbSide2,
  1355.       lastOptions = {},
  1356.  
  1357.       measures = {},
  1358.       measuresSetFLAG,
  1359.  
  1360.       stageShaftTouchTail = {},
  1361.       navShaftTouchTail = {},
  1362.  
  1363.       scrollTop,
  1364.       scrollLeft,
  1365.       showedFLAG,
  1366.       pausedAutoplayFLAG,
  1367.       stoppedAutoplayFLAG,
  1368.       wrapAppendedFLAG,
  1369.  
  1370.       measuresStash;
  1371.  
  1372.   $wrap[stageFrameKey] = $(div(stageFrameClass));
  1373.   $wrap[navThumbFrameKey] = $(div(navFrameClass + ' ' + navFrameThumbClass, div(thumbClass)));
  1374.   $wrap[navDotFrameKey] = $(div(navFrameClass + ' ' + navFrameDotClass, div(dotClass)));
  1375.  
  1376.  
  1377.   if (CSS3) {
  1378.     $wrap.addClass(wrapCss3Class);
  1379.   }
  1380.  
  1381.   fotoramaData.fotorama = this;
  1382.   that.options = opts;
  1383.   _size++;
  1384.  
  1385.   function checkForVideo () {
  1386.     $.each(data, function (i, dataFrame) {
  1387.       if (!dataFrame.i) {
  1388.         dataFrame.i = dataFrameCount++;
  1389.         var video = findVideoId(dataFrame.video, true);
  1390.         if (video) {
  1391.           var thumbs = {};
  1392.           dataFrame.video = video;
  1393.           if (!dataFrame.img && !dataFrame.thumb) {
  1394.             thumbs = getVideoThumbs(dataFrame, data, that);
  1395.             //////console.log('thumbs', thumbs)
  1396.           } else {
  1397.             dataFrame.thumbsReady = true;
  1398.           }
  1399.           updateData(data, {img: thumbs.img, thumb: thumbs.thumb}, dataFrame.i, that);
  1400.         }
  1401.       }
  1402.     });
  1403.   }
  1404.  
  1405.   function setData () {
  1406.     data = that.data = data || getDataFromHtml($fotorama);
  1407.     size = that.size = data.length;
  1408.  
  1409.     checkForVideo();
  1410.  
  1411.     activeIndex = limitIndex(activeIndex);
  1412.     navAppend.ok = false;
  1413.  
  1414.     if (!size) {
  1415.       //that.destroy();
  1416.     } else if (!wrapAppendedFLAG) {
  1417.       // Заменяем содержимое блока:
  1418.       $fotorama
  1419.           .html('')
  1420.           .append($wrap);
  1421.  
  1422.       $.Fotorama.size++;
  1423.  
  1424.       wrapAppendedFLAG = true;
  1425.     }
  1426.   }
  1427.  
  1428.   function stageNoMove () {
  1429.     stageShaftTouchTail.noMove = size < 2 || $videoPlaying || o_fade;
  1430.  
  1431.     $stageShaft.toggleClass(grabClass, !stageShaftTouchTail.noMove);
  1432.   }
  1433.  
  1434.   function setAutoplayInterval (interval) {
  1435.     if (interval === true) interval = '';
  1436.     opts.autoplay = Math.max(Number(interval) || AUTOPLAY_INTERVAL, TRANSITION_DURATION * 1.5);
  1437.   }
  1438.  
  1439.   function addOrRemove (FLAG) {
  1440.     return FLAG ? 'add' : 'remove';
  1441.   }
  1442.  
  1443.   /**
  1444.    * Options on the fly
  1445.    * */
  1446.   function setOptions () {
  1447.     o_fade = opts.transition === 'crossfade' || opts.transition === 'dissolve';
  1448.  
  1449.     o_loop = opts.loop && (size > 2 || o_fade);
  1450.  
  1451.     var classes = {add: [], remove: []};
  1452.  
  1453.     if (size > 1) {
  1454.       o_nav = opts.nav;
  1455.       o_navTop = opts.navPosition === 'top';
  1456.       classes.remove.push(selectClass);
  1457. if(opts.arrows) {
  1458.       $arrs.show();
  1459. }
  1460.  
  1461. else {
  1462.      $arrs.hide();
  1463. }
  1464.       arrsUpdate();
  1465.     } else {
  1466.       o_nav = false;
  1467.  
  1468.       $arrs.hide();
  1469.     }
  1470.  
  1471.     classes[addOrRemove(size > 1)].push('fotorama__wrap--navigation');
  1472.  
  1473.     if (opts.autoplay) setAutoplayInterval(opts.autoplay);
  1474.  
  1475.     o_thumbSide = numberFromMeasure(opts.thumbWidth) || THUMB_SIZE;
  1476.     o_thumbSide2 = numberFromMeasure(opts.thumbHeight) || THUMB_SIZE;
  1477.  
  1478.     stageNoMove();
  1479.  
  1480.     extendMeasures(opts, true);
  1481.  
  1482.     if (o_nav === true || o_nav === 'dots') {
  1483.       $nav
  1484.           .addClass(navDotsClass)
  1485.           .removeClass(navThumbsClass);
  1486.       frameDraw(size, 'navDot');
  1487.     } else if (o_nav === 'thumbs') {
  1488.       setStyle($style, $.Fotorama.jst.style({w: o_thumbSide, h: o_thumbSide2, m: MARGIN, s: stamp, q: !COMPAT}));
  1489.  
  1490.       $nav
  1491.           .addClass(navThumbsClass)
  1492.           .removeClass(navDotsClass);
  1493.  
  1494.       frameDraw(size, 'navThumb');
  1495.     } else {
  1496.       o_nav = false;
  1497.       $nav.removeClass(navThumbsClass + ' ' + navDotsClass);
  1498.     }
  1499.  
  1500.     o_allowFullScreen = opts.allowFullScreen;
  1501.     $fotorama
  1502.         .insertAfter($anchor)
  1503.         .removeClass(hiddenClass);
  1504.  
  1505.     if (o_nav && o_navTop) {
  1506.       $navWrap.insertBefore($stage);
  1507.     } else {
  1508.       $navWrap.insertAfter($stage);
  1509.     }
  1510.  
  1511.     if (o_allowFullScreen) {
  1512.       $fullscreenIcon.appendTo($stage);
  1513.       o_nativeFullScreen = FULLSCREEN && o_allowFullScreen === 'native';
  1514.     } else {
  1515.       $fullscreenIcon.detach();
  1516.       o_nativeFullScreen = false;
  1517.     }
  1518.  
  1519.     classes[addOrRemove(o_fade)].push(wrapFadeClass);
  1520.     classes[addOrRemove(!o_fade)].push(wrapSlideClass);
  1521.  
  1522.     ooooStop();
  1523.  
  1524.     $wrap
  1525.         .addClass(classes.add.join(' '))
  1526.         .removeClass(classes.remove.join(' '));
  1527.  
  1528.     lastOptions = $.extend({}, opts);
  1529.   }
  1530.  
  1531.   function normalizeIndex (index) {
  1532.     return index < 0 ? (size + (index % size)) % size : index >= size ? index % size : index;
  1533.   }
  1534.  
  1535.   function limitIndex (index) {
  1536.     return minMaxLimit(index, 0, size - 1);
  1537.   }
  1538.  
  1539.   function getPrevIndex (index) {
  1540.     return index > 0 || o_loop ? index - 1 : false;
  1541.   }
  1542.  
  1543.   function getNextIndex (index) {
  1544.     return index < size - 1 || o_loop ? index + 1 : false;
  1545.   }
  1546.  
  1547.   function setStageShaftMinMaxPosAndSnap () {
  1548.     stageShaftData.minPos = o_loop ? -Infinity : -getPosByIndex(size - 1, measures.w, MARGIN, repositionIndex);
  1549.     stageShaftData.maxPos = o_loop ? Infinity : -getPosByIndex(0, measures.w, MARGIN, repositionIndex);
  1550.     stageShaftData.snap = measures.w + MARGIN;
  1551.   }
  1552.  
  1553.   function setNavShaftMinMaxPos () {
  1554.     navShaftData.minPos = Math.min(0, measures.w - $navShaft.width());
  1555.     navShaftData.maxPos = 0;
  1556.  
  1557.     navShaftTouchTail.noMove = navShaftData.minPos === navShaftData.maxPos;
  1558.  
  1559.     $navShaft.toggleClass(grabClass, !navShaftTouchTail.noMove);
  1560.   }
  1561.  
  1562.   function eachIndex (indexes, type, fn) {
  1563.     if (typeof indexes === 'number') {
  1564.       indexes = new Array(indexes);
  1565.       var rangeFLAG = true;
  1566.     }
  1567.     return $.each(indexes, function (i, index) {
  1568.       if (rangeFLAG) index = i;
  1569.       if (typeof(index) === 'number') {
  1570.         var dataFrame = data[normalizeIndex(index)],
  1571.             key = '$' + type + 'Frame',
  1572.             $frame = dataFrame[key];
  1573.  
  1574.         fn.call(this, i, index, dataFrame, $frame, key, $frame && $frame.data());
  1575.       }
  1576.     });
  1577.   }
  1578.  
  1579.   function setMeasures (width, height, ratio, index) {
  1580.     if (!measuresSetFLAG || (measuresSetFLAG === '*' && index === startIndex)) {
  1581.       width = measureIsValid(opts.width) || measureIsValid(width) || WIDTH;
  1582.       height = measureIsValid(opts.height) || measureIsValid(height) || HEIGHT;
  1583.       that.resize({
  1584.         width: width,
  1585.         ratio: opts.ratio || ratio || width / height
  1586.       }, 0, index === startIndex ? true : '*');
  1587.     }
  1588.   }
  1589.  
  1590.   function loadImg (indexes, type, specialMeasures, specialFit, again) {
  1591.     eachIndex(indexes, type, function (i, index, dataFrame, $frame, key, frameData) {
  1592.  
  1593.       if (!$frame) return;
  1594.  
  1595.       var fullFLAG = that.fullScreen && dataFrame.full && !frameData.$full && type === 'stage';
  1596.  
  1597.       if (frameData.$img && !again && !fullFLAG) return;
  1598.  
  1599.       var img = new Image(),
  1600.           $img = $(img),
  1601.           imgData = $img.data();
  1602.  
  1603.       frameData[fullFLAG ? '$full' : '$img'] = $img;
  1604.  
  1605.       var srcKey = type === 'stage' ? (fullFLAG ? 'full' : 'img') : 'thumb',
  1606.           src = dataFrame[srcKey],
  1607.           dummy = fullFLAG ? null : dataFrame[type === 'stage' ? 'thumb' : 'img'];
  1608.  
  1609.       if (type === 'navThumb') $frame = frameData.$wrap;
  1610.  
  1611.       function triggerTriggerEvent (event) {
  1612.         var _index = normalizeIndex(index);
  1613.         triggerEvent(event, {
  1614.           index: _index,
  1615.           src: src,
  1616.           frame: data[_index]
  1617.         });
  1618.       }
  1619.  
  1620.       function error () {
  1621.         //////console.log('error', index, src);
  1622.         $img.remove();
  1623.  
  1624.         $.Fotorama.cache[src] = 'error';
  1625.  
  1626.         if ((!dataFrame.$html || type !== 'stage') && dummy && dummy !== src) {
  1627.           dataFrame[srcKey] = src = dummy;
  1628.           loadImg([index], type, specialMeasures, specialFit, true);
  1629.         } else {
  1630.           if (src && !frameData.$html) {
  1631.             $frame
  1632.                 .trigger('f:error')
  1633.                 .removeClass(loadingClass)
  1634.                 .addClass(errorClass);
  1635.  
  1636.             triggerTriggerEvent('error');
  1637.           } else if (type === 'stage') {
  1638.             $frame
  1639.                 .trigger('f:load')
  1640.                 .removeClass(loadingClass + ' ' + errorClass)
  1641.                 .addClass(loadedClass);
  1642.  
  1643.             triggerTriggerEvent('load');
  1644.             setMeasures();
  1645.           }
  1646.  
  1647.           frameData.state = 'error';
  1648.  
  1649.           if (size > 1 && !dataFrame.html && !dataFrame.deleted && !dataFrame.video && !fullFLAG) {
  1650.             dataFrame.deleted = true;
  1651.             that.splice(index, 1);
  1652.           }
  1653.         }
  1654.       }
  1655.  
  1656.       function loaded () {
  1657.         //////console.log('loaded', index, src);
  1658.  
  1659.         var width = $img.width(),
  1660.             height = $img.height(),
  1661.             ratio = width / height;
  1662.  
  1663.         imgData.measures = {
  1664.           width: width,
  1665.           height: height,
  1666.           ratio: ratio
  1667.         };
  1668.  
  1669.         setMeasures(width, height, ratio, index);
  1670.  
  1671.         $img
  1672.             .off('load error')
  1673.             .addClass(imgClass + (fullFLAG ? ' ' + imgFullClass : ''))
  1674.             .prependTo($frame);
  1675.  
  1676.         fit($img, specialMeasures || measures, specialFit || dataFrame.fit || opts.fit);
  1677.  
  1678.         $.Fotorama.cache[src] = 'loaded';
  1679.         frameData.state = 'loaded';
  1680.  
  1681.         setTimeout(function () {
  1682.           $frame
  1683.               .trigger('f:load')
  1684.               .removeClass(loadingClass + ' ' + errorClass)
  1685.               .addClass(loadedClass + ' ' + (fullFLAG ? loadedFullClass : loadedImgClass));
  1686.  
  1687.           if (type === 'stage') {
  1688.             triggerTriggerEvent('load');
  1689.           }
  1690.         }, 5);
  1691.       }
  1692.  
  1693.       if (!src) {
  1694.         error();
  1695.         return;
  1696.       }
  1697.  
  1698.       function waitAndLoad () {
  1699.         waitFor(function () {
  1700.           return !isHidden(img)/* && !touchedFLAG*/;
  1701.         }, function () {
  1702.           loaded();
  1703.         });
  1704.       }
  1705.  
  1706.       if (!$.Fotorama.cache[src]) {
  1707.         $.Fotorama.cache[src] = '*';
  1708.  
  1709.         $img
  1710.             .on('load', waitAndLoad)
  1711.             .on('error', error);
  1712.       } else {
  1713.         (function justWait () {
  1714.           if ($.Fotorama.cache[src] === 'error') {
  1715.             error();
  1716.           } else if ($.Fotorama.cache[src] === 'loaded') {
  1717.             waitAndLoad();
  1718.           } else {
  1719.             setTimeout(justWait, 100);
  1720.           }
  1721.         })();
  1722.       }
  1723.  
  1724.       img.src = src;
  1725.       $img.appendTo($.Fotorama.$load);
  1726.     });
  1727.   }
  1728.  
  1729.   function updateFotoramaState () {
  1730.     var $frame = that.activeFrame[stageFrameKey];
  1731.  
  1732.     if ($frame && !$frame.data().state) {
  1733.       ooooStart($frame);
  1734.       $frame.on('f:load f:error', function () {
  1735.         $frame.off('f:load f:error');
  1736.         ooooStop();
  1737.       });
  1738.     }
  1739.   }
  1740.  
  1741.   function frameDraw (indexes, type) {
  1742.     eachIndex(indexes, type, function (i, index, dataFrame, $frame, key, frameData) {
  1743.       //////console.log('frameDraw');
  1744.  
  1745.       if ($frame) return;
  1746.  
  1747.       //////console.log('frameDraw execute');
  1748.  
  1749.       $frame = dataFrame[key] = $wrap[key].clone();
  1750.       frameData = $frame.data();
  1751.       frameData.data = dataFrame;
  1752.  
  1753.       if (type === 'stage') {
  1754.  
  1755.         ////////console.log('dataFrame.html', $(dataFrame.html).html());
  1756.  
  1757.         if (dataFrame.html) {
  1758.           var $html = $(dataFrame.html).html(dataFrame._html); // Because of IE
  1759.  
  1760.           $('<div class="' + htmlClass + '"></div>')
  1761.               .append(dataFrame.html)
  1762.               .appendTo($frame);
  1763.         }
  1764.  
  1765.         if (opts.captions && dataFrame.caption) {
  1766.           $('<div class="' + captionClass + '"></div>').append(dataFrame.caption).appendTo($frame);
  1767.         }
  1768.  
  1769.         if (dataFrame.video) {
  1770.           var $oneVideoPlay = $videoPlay.clone();
  1771.  
  1772.           smartClick($oneVideoPlay, function () {
  1773.                 that.playVideo();
  1774.               }, {
  1775.                 onStart: function (e) {
  1776.                   onTouchStart.call(this, e);
  1777.                   stageShaftTouchTail.control = true;
  1778.                 },
  1779.                 tail: stageShaftTouchTail
  1780.               }
  1781.           );
  1782.  
  1783.           $frame
  1784.               .addClass(stageFrameVideoClass)
  1785.               .append($oneVideoPlay);
  1786.         }
  1787.  
  1788.         $stageFrame = $stageFrame.add($frame);
  1789.       } else if (type === 'navDot') {
  1790.         $navDotFrame = $navDotFrame.add($frame);
  1791.       } else if (type === 'navThumb') {
  1792.         frameData.$wrap = $frame.children(':first');
  1793.         $navThumbFrame = $navThumbFrame.add($frame);
  1794.         if (dataFrame.video) {
  1795.           $frame.append($videoPlay.clone());
  1796.         }
  1797.       }
  1798.     });
  1799.   }
  1800.  
  1801.   function callFit ($img, measuresToFit, method) {
  1802.     return $img && $img.length && fit($img, measuresToFit, method);
  1803.   }
  1804.  
  1805.   function stageFramePosition (indexes) {
  1806.     eachIndex(indexes, 'stage', function (i, index, dataFrame, $frame, key, frameData) {
  1807.       if (!$frame) return;
  1808.  
  1809.       $frame
  1810.           .css($.extend({left: o_fade ? 0 : getPosByIndex(index, measures.w, MARGIN, repositionIndex)/*, display: 'block'*/}, o_fade && getDuration(0)));
  1811.       //.fadeTo(0, o_fade && index !== activeIndex ? 0 : 1);
  1812.  
  1813.       if (!frameData.appended) {
  1814.         $frame.appendTo($stageShaft);
  1815.         frameData.appended = true;
  1816.         unloadVideo(dataFrame.$video);
  1817.       }
  1818.  
  1819.  
  1820.  
  1821.       ///
  1822. //          if (frameData.hidden) {
  1823. //              $frame.show();
  1824. //              frameData.hidden = false;
  1825. //
  1826. //          }
  1827.       ///
  1828.  
  1829.       var method = dataFrame.fit || opts.fit;
  1830.  
  1831.       callFit(frameData.$img, measures, method);
  1832.       callFit(frameData.$full, measures, method);
  1833.     });
  1834.   }
  1835.  
  1836.   function thumbsDraw (pos, loadFLAG) {
  1837.     if (o_nav !== 'thumbs' || isNaN(pos)) return;
  1838.  
  1839.     var thumbSide = o_thumbSide + MARGIN,
  1840.         leftIndex = limitIndex(getIndexByPos(pos + thumbSide, thumbSide)),
  1841.         rightIndex = limitIndex(getIndexByPos(pos - measures.w/* - thumbSide*/, thumbSide)),
  1842.         specialMeasures = {};
  1843.  
  1844.     specialMeasures.w = o_thumbSide;
  1845.     specialMeasures.h = o_thumbSide2;
  1846.  
  1847.     $navThumbFrame.each(function () {
  1848.       var $this = $(this),
  1849.           thisData = $this.data(),
  1850.           eq = thisData.eq,
  1851.           specialFit = 'cover';
  1852.  
  1853.       if (eq < leftIndex
  1854.           || eq > rightIndex
  1855.           || callFit(thisData.$img, specialMeasures, specialFit)) return;
  1856.  
  1857.       loadFLAG && loadImg([eq], 'navThumb', specialMeasures, specialFit);
  1858.     });
  1859.   }
  1860.  
  1861.   function navAppend ($navFrame, $navShaft, mainFLAG) {
  1862.     if (!navAppend.ok) {
  1863.       $navFrame = $navFrame
  1864.           .filter(function () {
  1865.             var actual,
  1866.                 $this = $(this),
  1867.                 frameData = $this.data();
  1868.             for (var _i = 0, _l = data.length; _i < _l; _i++) {
  1869.               var dataFrame = data[_i];
  1870.               if (frameData.data === dataFrame) {
  1871.                 actual = true;
  1872.                 frameData.eq = _i;
  1873.                 break;
  1874.               }
  1875.             }
  1876.             if (!actual) {
  1877.               $this.remove();
  1878.             }
  1879.             return actual;
  1880.           })
  1881.           .sort(function (a, b) {
  1882.             return $(a).data().eq - $(b).data().eq;
  1883.           })
  1884.           .appendTo($navShaft);
  1885.  
  1886.       if (mainFLAG) {
  1887.         setNavShaftMinMaxPos();
  1888.       }
  1889.  
  1890.       navAppend.ok = true;
  1891.     }
  1892.   }
  1893.  
  1894.   function arrsUpdate () {
  1895.     $arrs.each(function (i) {
  1896.       $(this).toggleClass(
  1897.           arrDisabledClass,
  1898.           (!o_loop
  1899.               && ((activeIndex === 0 && i === 0)
  1900.               || (activeIndex === size - 1 && i === 1)))
  1901.               && !$videoPlaying
  1902.       );
  1903.     });
  1904.   }
  1905.  
  1906.   function getNavFrameCenter ($navFrame) {
  1907.     return $navFrame.position().left + (o_thumbSide) / 2
  1908.   }
  1909.  
  1910.   function slideThumbBorder (time) {
  1911.     slide($thumbBorder, {
  1912.       time: time * .9,
  1913.       pos: getNavFrameCenter(that.activeFrame[navFrameKey])
  1914.     });
  1915.   }
  1916.  
  1917.   function slideNavShaft (options) {
  1918.     if (data[options.guessIndex][navFrameKey]) {
  1919.       var pos = minMaxLimit(options.coo - getNavFrameCenter(data[options.guessIndex][navFrameKey]), navShaftData.minPos, navShaftData.maxPos),
  1920.           time = options.time * .9;
  1921.       slide($navShaft, {
  1922.         time: time,
  1923.         pos: pos,
  1924.         onEnd: function () {
  1925.           thumbsDraw(pos, true);
  1926.         }
  1927.       });
  1928.  
  1929.       if (time) thumbsDraw(pos);
  1930.       setShadow($nav, findShadowEdge(pos, navShaftData.minPos, navShaftData.maxPos));
  1931.     }
  1932.   }
  1933.  
  1934.   function navUpdate () {
  1935.     //////console.log('navUpdate', o_nav);
  1936.     if (o_nav === 'thumbs') {
  1937.       $navFrame = $navThumbFrame;
  1938.       navFrameKey = navThumbFrameKey;
  1939.     } else if (o_nav) {
  1940.       $navFrame = $navDotFrame;
  1941.       navFrameKey = navDotFrameKey;
  1942.     } else return;
  1943.  
  1944.     navAppend($navFrame, $navShaft, true);
  1945.     $navFrame.removeClass(activeClass);
  1946.     that.activeFrame[navFrameKey].addClass(activeClass);
  1947.   }
  1948.  
  1949.   function stageShaftReposition () {
  1950.     /*if (touchedFLAG) {
  1951.      waitFor(function () {
  1952.      return !touchedFLAG;
  1953.      }, stageShaftReposition, 100);
  1954.      return;
  1955.      }*/
  1956.     repositionIndex = dirtyIndex = activeIndex;
  1957.  
  1958.     var dataFrame = that.activeFrame,
  1959.         $frame = dataFrame[stageFrameKey];
  1960.  
  1961.     if ($frame) {
  1962.       $stageFrame
  1963.           .not(that.activeFrame[stageFrameKey].addClass(activeClass))
  1964.           //.css({display: 'none'})
  1965.         //.hide()
  1966.         //.data('hidden', true)
  1967.           .detach()
  1968.           .data('appended', false)
  1969.           .removeClass(activeClass);
  1970.  
  1971.       stop($stageShaft);
  1972.       $stageShaft.css(getTranslate(0));
  1973.  
  1974.       stageFramePosition([activeIndex, prevIndex, nextIndex]);
  1975.       setStageShaftMinMaxPosAndSnap();
  1976.       setNavShaftMinMaxPos();
  1977.     }
  1978.   }
  1979.  
  1980.   function extendMeasures (options, optsLeave) {
  1981.     options && $.extend(measures, {
  1982.       width: options.width || measures.width,
  1983.       height: options.height,
  1984.       minWidth: options.minWidth,
  1985.       maxWidth: options.maxWidth,
  1986.       minHeight: options.minHeight,
  1987.       maxHeight: options.maxHeight,
  1988.       ratio: (function (_ratio) {
  1989.         if (!_ratio) return;
  1990.         var ratio = Number(_ratio);
  1991.         if (!isNaN(ratio)) {
  1992.           return ratio;
  1993.         } else {
  1994.           ratio = _ratio.split('/');
  1995.           return Number(ratio[0] / ratio[1]) || undefined;
  1996.         }
  1997.       })(options.ratio)
  1998.     })
  1999.         && !optsLeave && $.extend(opts, {
  2000.       width: measures.width,
  2001.       height: measures.height,
  2002.       minWidth: measures.minWidth,
  2003.       maxWidth: measures.maxWidth,
  2004.       minHeight: measures.minHeight,
  2005.       maxHeight: measures.maxHeight,
  2006.       ratio: measures.ratio
  2007.     });
  2008.   }
  2009.  
  2010.   function triggerEvent (event, extra) {
  2011.     ////console.log('triggerEvent', event, extra);
  2012.     $fotorama.trigger(_fotoramaClass + ':' + event, [that, extra]);
  2013.   }
  2014.  
  2015.   function eventData (index) {
  2016.     ////console.log('eventData', index);
  2017.     return {
  2018.       index: index,
  2019.       frame: data[index]
  2020.     }
  2021.   }
  2022.  
  2023.   /*var touchedFLAG; */
  2024.  
  2025.   function onTouchStart () {
  2026.     /*clearTimeout(onTouchEnd.t);
  2027.      touchedFLAG = 1;*/
  2028.  
  2029.     if (opts.stopAutoplayOnTouch) {
  2030.       that.stopAutoplay();
  2031.     } else {
  2032.       pausedAutoplayFLAG = true;
  2033.     }
  2034.   }
  2035.  
  2036.   function releaseAutoplay () {
  2037.     pausedAutoplayFLAG = !(!$videoPlaying && !stoppedAutoplayFLAG);
  2038.   }
  2039.  
  2040.   function changeAutoplay () {
  2041.     clearTimeout(changeAutoplay.t);
  2042.     if (!opts.autoplay || pausedAutoplayFLAG) {
  2043.       if (that.autoplay) {
  2044.         that.autoplay = false;
  2045.         triggerEvent('stopautoplay');
  2046.       }
  2047.  
  2048.       return;
  2049.     }
  2050.  
  2051.     if (!that.autoplay) {
  2052.       that.autoplay = true;
  2053.       triggerEvent('startautoplay');
  2054.     }
  2055.  
  2056.     var _activeIndex = activeIndex;
  2057.  
  2058.     changeAutoplay.t = setTimeout(function () {
  2059.       var frameData = that.activeFrame[stageFrameKey].data();
  2060.       waitFor(function () {
  2061.         return frameData.state || _activeIndex !== activeIndex;
  2062.       }, function () {
  2063.         if (pausedAutoplayFLAG || _activeIndex !== activeIndex) return;
  2064.         that.show({index: normalizeIndex(activeIndex + 1)});
  2065.       });
  2066.     }, opts.autoplay);
  2067.   }
  2068.  
  2069.  
  2070.   that.startAutoplay = function (interval) {
  2071.     if (that.autoplay) return this;
  2072.     pausedAutoplayFLAG = stoppedAutoplayFLAG = false;
  2073.     setAutoplayInterval(interval || opts.autoplay);
  2074.     changeAutoplay();
  2075.  
  2076.     return this;
  2077.   }
  2078.  
  2079.   that.stopAutoplay = function () {
  2080.     if (that.autoplay) {
  2081.       pausedAutoplayFLAG = stoppedAutoplayFLAG = true;
  2082.       changeAutoplay();
  2083.     }
  2084.     return this;
  2085.   };
  2086.  
  2087.   that.show = function (options) {
  2088.     var index,
  2089.         time = TRANSITION_DURATION,
  2090.         overPos;
  2091.  
  2092.     if (typeof options !== 'object') {
  2093.       index = options;
  2094.       options = {};
  2095.     } else {
  2096.       index = options.index;
  2097.       time = typeof options.time === 'number' ? options.time : time;
  2098.       overPos = options.overPos;
  2099.     }
  2100.  
  2101.     if (options.slow) time *= 10;
  2102.  
  2103. //    index = index === '>' ? dirtyIndex + 1 : index === '<' ? dirtyIndex - 1 : index === '<<' ? 0 : index === '>>' ? size - 1 : typeof index === 'string' ? getIndexFromHash(index, data, true) : index;
  2104. //    index = isNaN(index) ? activeIndex || 0 : index;
  2105.  
  2106.     index = index === '>' ? dirtyIndex + 1 : index === '<' ? dirtyIndex - 1 : index === '<<' ? 0 : index === '>>' ? size - 1 : index;
  2107.     index = isNaN(index) ? getIndexFromHash(index, data, true) : index;
  2108.     index = typeof index === 'undefined' ? activeIndex || 0 : index;
  2109.  
  2110.     that.activeIndex = activeIndex = o_loop ? normalizeIndex(index) : limitIndex(index);
  2111.     prevIndex = getPrevIndex(activeIndex);
  2112.     nextIndex = getNextIndex(activeIndex);
  2113.  
  2114.     dirtyIndex = o_loop ? index : activeIndex;
  2115.  
  2116.     that.activeFrame = activeFrame = data[activeIndex];
  2117.  
  2118.     unloadVideo(false, activeFrame.i !== data[normalizeIndex(repositionIndex)].i);
  2119.  
  2120.     frameDraw([activeIndex, prevIndex, nextIndex], 'stage');
  2121.     stageFramePosition([dirtyIndex]);
  2122.  
  2123.     triggerEvent('show', options.direct); // TODO: test that .activeFrame is ready event on the first show
  2124.  
  2125.     function onEnd () {
  2126.  
  2127.       updateFotoramaState();
  2128.       loadImg([activeIndex, prevIndex, nextIndex], 'stage');
  2129.       stageShaftReposition(); /////
  2130.  
  2131.       triggerEvent('showend', options.direct);
  2132.  
  2133.       releaseAutoplay();
  2134.       changeAutoplay();
  2135.     }
  2136.  
  2137.     if (!o_fade) {
  2138.       slide($stageShaft, {
  2139.         pos: -getPosByIndex(dirtyIndex, measures.w, MARGIN, repositionIndex),
  2140.         overPos: overPos,
  2141.         time: time,
  2142.         onEnd: onEnd
  2143.       });
  2144.     } else {
  2145.       var $activeFrame = activeFrame[stageFrameKey],
  2146.           $prevActiveFrame = activeIndex !== lastActiveIndex ? data[lastActiveIndex][stageFrameKey] : null;
  2147.  
  2148.       fade($activeFrame, $prevActiveFrame, $stageFrame, {
  2149.         time: time,
  2150.         method: opts.transition,
  2151.         onEnd: onEnd
  2152.       });
  2153.     }
  2154.  
  2155.     arrsUpdate();
  2156.     navUpdate();
  2157.  
  2158.     if (o_nav) {
  2159.       var guessIndex = limitIndex(activeIndex + minMaxLimit(dirtyIndex - lastActiveIndex, -1, 1)),
  2160.           cooUndefinedFLAG = typeof options.coo === 'undefined';
  2161.  
  2162.       if (cooUndefinedFLAG || guessIndex !== activeIndex) {
  2163.         slideNavShaft({time: time, coo: !cooUndefinedFLAG ? options.coo : measures.w / 2, guessIndex: !cooUndefinedFLAG ? guessIndex : activeIndex});
  2164.       }
  2165.     }
  2166.     if (o_nav === 'thumbs') slideThumbBorder(time);
  2167.  
  2168.     showedFLAG = typeof lastActiveIndex !== 'undefined' && lastActiveIndex !== activeIndex;
  2169.     lastActiveIndex = activeIndex;
  2170.     opts.hash && showedFLAG && !that.eq && setHash(activeFrame.id || activeIndex + 1);
  2171.  
  2172.     return this;
  2173.   };
  2174.  
  2175.   that.requestFullScreen = function () {
  2176.     if (o_allowFullScreen && !that.fullScreen) {
  2177.       scrollTop = $WINDOW.scrollTop();
  2178.       scrollLeft = $WINDOW.scrollLeft();
  2179.  
  2180.       $WINDOW.scrollTop(0).scrollLeft(0);
  2181.  
  2182.       measuresStash = $.extend({}, measures);
  2183.  
  2184.       $fotorama
  2185.           .addClass(fullscreenClass)
  2186.           .appendTo($BODY.addClass(_fullscreenClass));
  2187.  
  2188.  
  2189.       ////console.log('measuresStash', measuresStash, measures);
  2190.  
  2191.       unloadVideo($videoPlaying, true);
  2192.  
  2193.       that.fullScreen = true;
  2194.  
  2195.       if (o_nativeFullScreen) {
  2196.         fullScreenApi.request(fotorama);
  2197.       }
  2198.  
  2199.       //setTimeout(function () {
  2200.         //$WINDOW.scrollTop(scrollTop).scrollLeft(scrollLeft);
  2201.         // Timeout for Safari
  2202.         //$BODY;
  2203.  
  2204.         that.resize();
  2205.         loadImg([activeIndex, prevIndex, nextIndex], 'stage');
  2206.       //}, 0);
  2207.  
  2208.       triggerEvent('fullscreenenter');
  2209.     }
  2210.  
  2211.     return this;
  2212.   };
  2213.  
  2214.   function cancelFullScreen () {
  2215.     ////console.log('/!\ cancelFullScreen');
  2216.  
  2217.     if (that.fullScreen) {
  2218.       that.fullScreen = false;
  2219.  
  2220.       if (FULLSCREEN) {
  2221.         fullScreenApi.cancel(fotorama);
  2222.       }
  2223.  
  2224.       $BODY.removeClass(_fullscreenClass);
  2225.  
  2226.       $fotorama
  2227.           .removeClass(fullscreenClass)
  2228.           .insertAfter($anchor);
  2229.  
  2230.       triggerEvent('fullscreenexit');
  2231.  
  2232.       measures = $.extend({}, measuresStash);
  2233.  
  2234.       ////console.log('measures', measures, measuresStash);
  2235.  
  2236.       unloadVideo($videoPlaying, true);
  2237.  
  2238.       that.resize();
  2239.       loadImg([activeIndex, prevIndex, nextIndex], 'stage');
  2240.  
  2241.       $WINDOW.scrollLeft(scrollLeft).scrollTop(scrollTop);
  2242.     }
  2243.   }
  2244.  
  2245.   that.cancelFullScreen = function () {
  2246.     if (o_nativeFullScreen && fullScreenApi.is()) {
  2247.       fullScreenApi.cancel(document);
  2248.     } else {
  2249.       cancelFullScreen();
  2250.     }
  2251.  
  2252.     return this;
  2253.   };
  2254.  
  2255.   if (document.addEventListener) {
  2256.     document.addEventListener(fullScreenApi.event, function () {
  2257.       if (!fullScreenApi.is() && !$videoPlaying) {
  2258.         cancelFullScreen();
  2259.       }
  2260.     });
  2261.   }
  2262.  
  2263.   $DOCUMENT.on('keydown', function (e) {
  2264.     if ($videoPlaying && e.keyCode === 27) {
  2265.       e.preventDefault();
  2266.       unloadVideo($videoPlaying, true, true);
  2267.     } else if (that.fullScreen || (opts.keyboard && !index)) {
  2268.       if (e.keyCode === 27) {
  2269.         e.preventDefault();
  2270.         that.cancelFullScreen();
  2271.       } else if (e.keyCode === 39 || (e.keyCode === 40 && that.fullScreen)) {
  2272.         e.preventDefault();
  2273.         that.show({index: '>', slow: e.altKey, direct: true});
  2274.       } else if (e.keyCode === 37 || (e.keyCode === 38 && that.fullScreen)) {
  2275.         e.preventDefault();
  2276.         that.show({index: '<', slow: e.altKey, direct: true});
  2277.       }
  2278.     }
  2279.   });
  2280.  
  2281.   if (!index) {
  2282.     $DOCUMENT.on('keydown', 'textarea, input, select', function (e) {
  2283.       if (!that.fullScreen) {
  2284.         e.stopPropagation();
  2285.       }
  2286.     });
  2287.   }
  2288.  
  2289.   that.resize = function (options) {
  2290.     if (!data) return;
  2291.  
  2292.     extendMeasures(!that.fullScreen ? options : {width: '100%', maxWidth: null, minWidth: null, height: '100%', maxHeight: null, minHeight: null}, that.fullScreen);
  2293.  
  2294.     var time = arguments[1] || 0,
  2295.         setFLAG = arguments[2],
  2296.         width = measures.width,
  2297.         height = measures.height,
  2298.         ratio = measures.ratio,
  2299.         windowHeight = window.innerHeight - (o_nav ? $nav.height() : 0);
  2300.  
  2301.     if (measureIsValid(width)) {
  2302.       $wrap.css({width: width, minWidth: measures.minWidth, maxWidth: measures.maxWidth});
  2303.  
  2304.       width = measures.w = $wrap.width();
  2305.       height = numberFromPercent(height) / 100 * windowHeight || numberFromMeasure(height);
  2306.  
  2307.       height = height || (ratio && width / ratio);
  2308.  
  2309.       if (height) {
  2310.         width = Math.round(width);
  2311.         height = measures.h = Math.round(minMaxLimit(height, numberFromPercent(measures.minHeight) / 100 * windowHeight || numberFromMeasure(measures.minHeight), numberFromPercent(measures.maxHeight) / 100 * windowHeight || numberFromMeasure(measures.maxHeight)));
  2312.  
  2313.         stageShaftReposition();
  2314.  
  2315.         $stage
  2316.             .addClass(stageOnlyActiveClass)
  2317.             .stop()
  2318.             .animate({width: width, height: height}, time, function () {
  2319.               $stage.removeClass(stageOnlyActiveClass);
  2320.             });
  2321.  
  2322.         if (o_nav) {
  2323.           $nav
  2324.               .stop()
  2325.               .animate({width: width}, time)
  2326.               .css({left: 0});
  2327.  
  2328.           slideNavShaft({guessIndex: activeIndex, time: time, coo: measures.w / 2});
  2329.           if (o_nav === 'thumbs' && navAppend.ok) slideThumbBorder(time);
  2330.         }
  2331.         measuresSetFLAG = setFLAG || true;
  2332.         ready();
  2333.       }
  2334.     }
  2335.  
  2336.     return this;
  2337.   };
  2338.  
  2339.   that.setOptions = function (options) {
  2340.     $.extend(opts, options);
  2341.     reset();
  2342.     return this;
  2343.   };
  2344.  
  2345.  
  2346.   function setShadow ($el, edge) {
  2347.     $el.removeClass(shadowsLeftClass + ' ' + shadowsRightClass);
  2348.     edge && !$videoPlaying && $el.addClass(edge.replace(/^|\s/g, ' ' + shadowsClass + '--'));
  2349.   }
  2350.  
  2351.   that.destroy = function () {
  2352.     ////console.log('destroy');
  2353.     that.stopAutoplay();
  2354.     $wrap.detach();
  2355.     $fotorama.html(fotoramaData.urtext);
  2356.     wrapAppendedFLAG = false;
  2357.     data = that.data = null;
  2358.     $.Fotorama.size--;
  2359.     return this;
  2360.   };
  2361.  
  2362.   that.playVideo = function () {
  2363.     var dataFrame = that.activeFrame,
  2364.         video = dataFrame.video,
  2365.         _activeIndex = activeIndex;
  2366.  
  2367.     if (typeof video === 'object' && dataFrame.videoReady) {
  2368.       o_nativeFullScreen && that.fullScreen && that.cancelFullScreen();
  2369.  
  2370.       waitFor(function () {
  2371.         return !fullScreenApi.is() || _activeIndex !== activeIndex;
  2372.       }, function () {
  2373.         if (_activeIndex === activeIndex) {
  2374.           dataFrame.$video = dataFrame.$video || $($.Fotorama.jst.video(video));
  2375.           dataFrame.$video.appendTo(dataFrame[stageFrameKey]);
  2376.  
  2377.           $wrap.addClass(wrapVideoClass);
  2378.           $videoPlaying = dataFrame.$video;
  2379.           stageShaftTouchTail.noMove = true;
  2380.  
  2381.           triggerEvent('loadvideo');
  2382.         }
  2383.       });
  2384.     }
  2385.  
  2386.     return this;
  2387.   };
  2388.  
  2389.   that.stopVideo = function () {
  2390.     unloadVideo($videoPlaying, true, true);
  2391.     return this;
  2392.   };
  2393.  
  2394.  
  2395.   function unloadVideo ($video, unloadActiveFLAG, releaseAutoplayFLAG) {
  2396.     if (unloadActiveFLAG) {
  2397.       $wrap.removeClass(wrapVideoClass);
  2398.       $videoPlaying = false;
  2399.  
  2400.       stageNoMove();
  2401.     }
  2402.  
  2403.     if ($video && $video !== $videoPlaying) {
  2404.       $video.remove();
  2405.       triggerEvent('unloadvideo');
  2406.     }
  2407.  
  2408.     if (releaseAutoplayFLAG) {
  2409.       releaseAutoplay();
  2410.       changeAutoplay();
  2411.     }
  2412.   }
  2413.  
  2414.   function toggleControlsClass (FLAG) {
  2415.     $wrap.toggleClass(wrapNoControlsClass, FLAG);
  2416.   }
  2417.  
  2418.   $wrap.hover(
  2419.       function () {
  2420.         toggleControlsClass(false);
  2421.       }, function () {
  2422.         toggleControlsClass(true);
  2423.       }
  2424.   );
  2425.  
  2426.   function onStageTap (e, touch) {
  2427.     if ($videoPlaying) {
  2428.       unloadVideo($videoPlaying, true, true);
  2429.     } else {
  2430.       if (touch) {
  2431.         toggleControlsClass();
  2432.       } else {
  2433.         that.show({index: e.shiftKey || e._x - $stage.offset().left < measures.w / 3 ? '<' : '>', slow: e.altKey, direct: true});
  2434.       }
  2435.     }
  2436.   }
  2437.  
  2438.   stageShaftTouchTail = moveOnTouch($stageShaft, {
  2439.     onStart: onTouchStart,
  2440.     onMove: function (e, result) {
  2441.       setShadow($stage, result.edge);
  2442.     },
  2443.     onEnd: function (result) {
  2444.       setShadow($stage);
  2445.  
  2446.       if (result.moved || (result.touch && result.pos !== result.newPos)) {
  2447.         var index = getIndexByPos(result.newPos, measures.w, MARGIN, repositionIndex);
  2448.         that.show({
  2449.           index: index,
  2450.           time: result.time,
  2451.           overPos: result.overPos,
  2452.           direct: true
  2453.         });
  2454.       } else if (!result.aborted) {
  2455.         onStageTap(result.startEvent, result.touch);
  2456.       }
  2457.     },
  2458.     timeLow: 1,
  2459.     timeHigh: 1,
  2460.     friction: 2,
  2461.     select: '.' + selectClass + ', .' + selectClass + ' *',
  2462.     $wrap: $stage
  2463.   });
  2464.  
  2465.   navShaftTouchTail = moveOnTouch($navShaft, {
  2466.     onStart: onTouchStart,
  2467.     onMove: function (e, result) {
  2468.       setShadow($nav, result.edge);
  2469.     },
  2470.     onEnd: function (result) {
  2471.       function onEnd () {
  2472.         releaseAutoplay();
  2473.         changeAutoplay();
  2474.         thumbsDraw(result.newPos, true);
  2475.       }
  2476.  
  2477.       if (!result.moved) {
  2478.         var target = result.$target.closest('.' + navFrameClass, $navShaft)[0];
  2479.         target && onNavFrameClick.call(target, result.startEvent);
  2480.       } else if (result.pos !== result.newPos) {
  2481.         slide($navShaft, {
  2482.           time: result.time,
  2483.           pos: result.newPos,
  2484.           overPos: result.overPos,
  2485.           onEnd: onEnd
  2486.         });
  2487.         thumbsDraw(result.newPos);
  2488.         setShadow($nav, findShadowEdge(result.newPos, navShaftData.minPos, navShaftData.maxPos));
  2489.       } else {
  2490.         onEnd();
  2491.       }
  2492.     },
  2493.     timeLow: .5,
  2494.     timeHigh: 2,
  2495.     friction: 5,
  2496.     $wrap: $nav
  2497.   });
  2498.  
  2499.   function onNavFrameClick (e, time) {
  2500.     var index = $(this).data().eq;
  2501.     that.show({index: index, slow: e.altKey, direct: true, coo: e._x - $nav.offset().left, time: time});
  2502.   }
  2503.  
  2504.  smartClick($arrs, function (e) {
  2505.     e.preventDefault();
  2506.     if ($videoPlaying) {
  2507.       unloadVideo($videoPlaying, true, true);
  2508.     } else {
  2509.       that.show({index: $arrs.index(this) ? '>' : '<', slow: e.altKey, direct: true});
  2510.     }
  2511.   }, {
  2512.     onStart: function (e) {
  2513.       onTouchStart.call(this, e);
  2514.       stageShaftTouchTail.control = true;
  2515.     },
  2516.     tail: stageShaftTouchTail
  2517.   });
  2518.  
  2519.   // Клик по иконке фуллскрина
  2520. smartClick($fullscreenIcon, function () {
  2521.     if (that.fullScreen) {
  2522.       that.cancelFullScreen();
  2523.     } else {
  2524.       that.requestFullScreen();
  2525.     }
  2526.     releaseAutoplay();
  2527.     changeAutoplay();
  2528.   }, {
  2529.     onStart: function (e) {
  2530.       onTouchStart.call(this, e);
  2531.       stageShaftTouchTail.control = true;
  2532.     },
  2533.     tail: stageShaftTouchTail
  2534.   });
  2535.  
  2536.   function reset () {
  2537.     setData();
  2538.     setOptions();
  2539.  
  2540.     if (!ready.ok) {
  2541.       // Only first time
  2542.       if (opts.hash && location.hash) {
  2543.         startIndex = getIndexFromHash(location.hash.replace(/^#/, ''), data, index === 0);
  2544.       }
  2545.       startIndex = (o_loop ? normalizeIndex(startIndex) : limitIndex(startIndex)) || 0;
  2546.       activeIndex = repositionIndex = dirtyIndex = lastActiveIndex = startIndex;
  2547.     }
  2548.  
  2549.     if (size) {
  2550.       if ($videoPlaying) {
  2551.         unloadVideo($videoPlaying, true);
  2552.       }
  2553.       that.show({index: activeIndex, time: 0});
  2554.       that.resize();
  2555.     } else {
  2556.       that.destroy();
  2557.     }
  2558.   }
  2559.  
  2560.   $.each('load push pop shift unshift reverse sort splice'.split(' '), function (i, method) {
  2561.     that[method] = function () {
  2562.       data = data || [];
  2563.       if (method !== 'load') {
  2564.         Array.prototype[method].apply(data, arguments);
  2565.       } else if (arguments[0] && typeof arguments[0] === 'object' && arguments[0].length) {
  2566.         data = arguments[0];
  2567.       }
  2568.       reset();
  2569.       return that;
  2570.     }
  2571.   });
  2572.  
  2573.   function ready () {
  2574.     if (!ready.ok) {
  2575.       ready.ok = true;
  2576.       $wrap.removeClass(wrapNotReadyClass);
  2577.       triggerEvent('ready');
  2578.     }
  2579.   }
  2580.  
  2581.   $WINDOW.on('resize', that.resize);
  2582.   reset();
  2583. };
  2584.  
  2585. $.fn.fotorama = function (opts) {
  2586.   return this.each(function () {
  2587.     var that = this,
  2588.         $fotorama = $(this),
  2589.         fotoramaData = $fotorama.data(),
  2590.         fotorama = fotoramaData.fotorama;
  2591.  
  2592.     if (!fotorama) {
  2593.       waitFor(function () {
  2594.         return !isHidden(that);
  2595.       }, function () {
  2596.         fotoramaData.urtext = $fotorama.html();
  2597.         new $.Fotorama($fotorama,
  2598.             /* Priority for options:
  2599.              * 1. <div data-loop="true"></div>
  2600.              * 2. $('div').fotorama({loop: false})
  2601.              * 3. Defaults */
  2602.             $.extend(
  2603.                 {},
  2604.                 {
  2605.                   // dimensions
  2606.                   width: null, // 500 || '100%'
  2607.                   minWidth: null,
  2608.                   maxWidth: null, // '100%'
  2609.                   height: null,
  2610.                   minHeight: null,
  2611.                   maxHeight: null,
  2612.                   ratio: null, // '16/9' || 500/333 || 1.5
  2613.  
  2614.                   // navigation, thumbs
  2615.                   nav: 'dots', // 'thumbs' || false
  2616.                   navPosition: 'bottom', // 'top'
  2617.                   thumbWidth: THUMB_SIZE,
  2618.                   thumbHeight: THUMB_SIZE,
  2619.  
  2620.                   allowFullScreen: false, // true || 'native'
  2621.  
  2622.                   fit: 'contain', // 'cover' || 'scale-down' || 'none'
  2623.  
  2624.                   transition: 'slide', // 'crossfade' || 'dissolve'
  2625.  
  2626.                   captions: true,
  2627.  
  2628.                   hash: false,
  2629.  
  2630.                   autoplay: false,
  2631.                   stopAutoplayOnTouch: true,
  2632.  
  2633.                   keyboard: false,
  2634.  
  2635.                   loop: false,
  2636.                   arrows: true
  2637.                 },
  2638.                 $.extend(
  2639.                     {},
  2640.                     opts,
  2641.                     fotoramaData
  2642.                 )
  2643.             )
  2644.         );
  2645.       });
  2646.     } else {
  2647.       fotorama.setOptions(opts);
  2648.     }
  2649.   });
  2650. //  }
  2651. };
  2652.  
  2653. $.Fotorama.cache = {};
  2654.  
  2655. var _size = 0;
  2656. $.Fotorama.size = 0;
  2657.  
  2658. $(function () {
  2659.   $('.' + _fotoramaClass + ':not([data-auto="false"])').fotorama();
  2660. });
  2661. $ = $ || {};
  2662. $.Fotorama = $.Fotorama || {};
  2663. $.Fotorama.jst = $.Fotorama.jst || {};
  2664.  
  2665. $.Fotorama.jst.style = function(v) {
  2666. var __t, __p = '', __e = _.escape;
  2667. __p += '.fotorama' +
  2668. ((__t = ( v.s )) == null ? '' : __t) +
  2669. ' .fotorama__nav--thumbs .fotorama__nav__frame{\npadding:' +
  2670. ((__t = ( v.m )) == null ? '' : __t) +
  2671. 'px;\npadding-left:0;\nwidth:' +
  2672. ((__t = ( v.w )) == null ? '' : __t) +
  2673. 'px;\nheight:' +
  2674. ((__t = ( v.h )) == null ? '' : __t) +
  2675. 'px}\n.fotorama' +
  2676. ((__t = ( v.s )) == null ? '' : __t) +
  2677. ' .fotorama__nav--thumbs .fotorama__nav__frame:last-child{\npadding-right:0}\n.fotorama' +
  2678. ((__t = ( v.s )) == null ? '' : __t) +
  2679. ' .fotorama__thumb{\nwidth:' +
  2680. ((__t = ( v.w )) == null ? '' : __t) +
  2681. 'px;\nheight:' +
  2682. ((__t = ( v.h )) == null ? '' : __t) +
  2683. 'px}\n.fotorama' +
  2684. ((__t = ( v.s )) == null ? '' : __t) +
  2685. ' .fotorama__thumb-border{\nwidth:' +
  2686. ((__t = ( v.w - v.m * (v.q ? 0 : 2) )) == null ? '' : __t) +
  2687. 'px;\nheight:' +
  2688. ((__t = ( v.h - v.m * (v.q ? 0 : 2) )) == null ? '' : __t) +
  2689. 'px;\nborder-width:' +
  2690. ((__t = ( v.m )) == null ? '' : __t) +
  2691. 'px;\nmargin-top:' +
  2692. ((__t = ( v.m )) == null ? '' : __t) +
  2693. 'px;\nmargin-left:' +
  2694. ((__t = ( - v.w / 2 )) == null ? '' : __t) +
  2695. 'px}';
  2696. return __p
  2697. };
  2698.  
  2699. $.Fotorama.jst.video = function(v) {
  2700. var __t, __p = '', __e = _.escape, __j = Array.prototype.join;
  2701. function print() { __p += __j.call(arguments, '') }
  2702. __p += '<div class="fotorama__video"><iframe src="';
  2703.  print(v.type == 'youtube' ? 'http://youtube.com/embed/' + v.id +'?autoplay=1' : v.type == 'vimeo' ? 'http://player.vimeo.com/video/' + v.id + '?autoplay=1&amp;badge=0' : v.id) ;
  2704. __p += '" frameborder="0" allowfullscreen></iframe></div>';
  2705. return __p
  2706. };
  2707. })
  2708. (window, document, jQuery);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement