vendor: 4,719 bytes, lines 1-147
1/* ---------------------------------------------------------- 2 * Plugins 3 * ---------------------------------------------------------- */ 4 5(function (global, factory) { 6 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : 7 typeof define === 'function' && define.amd ? define(['exports'], factory) : 8 (global = global || self, factory(global.window = global.window || {})); 9}(this, (function (exports) { 'use strict'; 10 11 function _inheritsLoose(subClass, superClass) { 12 subClass.prototype = Object.create(superClass.prototype); 13 subClass.prototype.constructor = subClass; 14 subClass.__proto__ = superClass; 15 } 16 17 function _assertThisInitialized(self) { 18 if (self === void 0) { 19 throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); 20 } 21 22 return self; 23 } 24 25 /*! 26 * GSAP 3.6.1 27 * https://greensock.com 28 * 29 * @license Copyright 2008-2021, GreenSock. All rights reserved. 30 * Subject to the terms at https://greensock.com/standard-license or for 31 * Club GreenSock members, the agreement issued with that membership. 32 * @author: Jack Doyle, [email protected] 33 */ 34 var _config = { 35 autoSleep: 120, 36 force3D: "auto", 37 nullTargetWarn: 1, 38 units: { 39 lineHeight: "" 40 } 41 }, 42 _defaults = { 43 duration: .5, 44 overwrite: false, 45 delay: 0 46 }, 47 _suppressOverwrites, 48 _bigNum = 1e8, 49 _tinyNum = 1 / _bigNum, 50 _2PI = Math.PI * 2, 51 _HALF_PI = _2PI / 4, 52 _gsID = 0, 53 _sqrt = Math.sqrt, 54 _cos = Math.cos, 55 _sin = Math.sin, 56 _isString = function _isString(value) { 57 return typeof value === "string"; 58 }, 59 _isFunction = function _isFunction(value) { 60 return typeof value === "function"; 61 }, 62 _isNumber = function _isNumber(value) { 63 return typeof value === "number"; 64 }, 65 _isUndefined = function _isUndefined(value) { 66 return typeof value === "undefined"; 67 }, 68 _isObject = function _isObject(value) { 69 return typeof value === "object"; 70 }, 71 _isNotFalse = function _isNotFalse(value) { 72 return value !== false; 73 }, 74 _windowExists = function _windowExists() { 75 return typeof window !== "undefined"; 76 }, 77 _isFuncOrString = function _isFuncOrString(value) { 78 return _isFunction(value) || _isString(value); 79 }, 80 _isTypedArray = typeof ArrayBuffer === "function" && ArrayBuffer.isView || function () {}, 81 _isArray = Array.isArray, 82 _strictNumExp = /(?:-?\.?\d|\.)+/gi, 83 _numExp = /[-+=.]*\d+[.e\-+]*\d*[e\-+]*\d*/g, 84 _numWithUnitExp = /[-+=.]*\d+[.e-]*\d*[a-z%]*/g, 85 _complexStringNumExp = /[-+=.]*\d+\.?\d*(?:e-|e\+)?\d*/gi, 86 _relExp = /[+-]=-?[.\d]+/, 87 _delimitedValueExp = /[#\-+.]*\b[a-z\d-=+%.]+/gi, 88 _unitExp = /[\d.+\-=]+(?:e[-+]\d*)*/i, 89 _globalTimeline, 90 _win, 91 _coreInitted, 92 _doc, 93 _globals = {}, 94 _installScope = {}, 95 _coreReady, 96 _install = function _install(scope) { 97 return (_installScope = _merge(scope, _globals)) && gsap; 98 }, 99 _missingPlugin = function _missingPlugin(property, value) { 100 return console.warn("Invalid property", property, "set to", value, "Missing plugin? gsap.registerPlugin()"); 101 }, 102 _warn = function _warn(message, suppress) { 103 return !suppress && console.warn(message); 104 }, 105 _addGlobal = function _addGlobal(name, obj) { 106 return name && (_globals[name] = obj) && _installScope && (_installScope[name] = obj) || _globals; 107 }, 108 _emptyFunc = function _emptyFunc() { 109 return 0; 110 }, 111 _reservedProps = {}, 112 _lazyTweens = [], 113 _lazyLookup = {}, 114 _lastRenderedFrame, 115 _plugins = {}, 116 _effects = {}, 117 _nextGCFrame = 30, 118 _harnessPlugins = [], 119 _callbackNames = "", 120 _harness = function _harness(targets) { 121 var target = targets[0], 122 harnessPlugin, 123 i; 124 _isObject(target) || _isFunction(target) || (targets = [targets]); 125 126 if (!(harnessPlugin = (target._gsap || {}).harness)) { 127 i = _harnessPlugins.length; 128 129 while (i-- && !_harnessPlugins[i].targetTest(target)) {} 130 131 harnessPlugin = _harnessPlugins[i]; 132 } 133 134 i = targets.length; 135 136 while (i--) { 137 targets[i] && (targets[i]._gsap || (targets[i]._gsap = new GSCache(targets[i], harnessPlugin))) || targets.splice(i, 1); 138 } 139 140 return targets; 141 }, 142 _getCache = function _getCache(target) { 143 return target._gsap || _harness(toArray(target))[0]._gsap; 144 }, 145 _getProperty = function _getProperty(target, property, v) { 146 return (v = target[property]) && _isFunction(v) ? target[property]() : _isUndefined(v) && target.getAttribute && target.getAttribute(property) || v; 147 },
vendor: 7,717 bytes, lines 148-411
148 _forEachName = function _forEachName(names, func) { 149 return (names = names.split(",")).forEach(func) || names; 150 }, 151 _round = function _round(value) { 152 return Math.round(value * 100000) / 100000 || 0; 153 }, 154 _arrayContainsAny = function _arrayContainsAny(toSearch, toFind) { 155 var l = toFind.length, 156 i = 0; 157 158 for (; toSearch.indexOf(toFind[i]) < 0 && ++i < l;) {} 159 160 return i < l; 161 }, 162 _parseVars = function _parseVars(params, type, parent) { 163 var isLegacy = _isNumber(params[1]), 164 varsIndex = (isLegacy ? 2 : 1) + (type < 2 ? 0 : 1), 165 vars = params[varsIndex], 166 irVars; 167 168 isLegacy && (vars.duration = params[1]); 169 vars.parent = parent; 170 171 if (type) { 172 irVars = vars; 173 174 while (parent && !("immediateRender" in irVars)) { 175 irVars = parent.vars.defaults || {}; 176 parent = _isNotFalse(parent.vars.inherit) && parent.parent; 177 } 178 179 vars.immediateRender = _isNotFalse(irVars.immediateRender); 180 type < 2 ? vars.runBackwards = 1 : vars.startAt = params[varsIndex - 1]; 181 } 182 183 return vars; 184 }, 185 _lazyRender = function _lazyRender() { 186 var l = _lazyTweens.length, 187 a = _lazyTweens.slice(0), 188 i, 189 tween; 190 191 _lazyLookup = {}; 192 _lazyTweens.length = 0; 193 194 for (i = 0; i < l; i++) { 195 tween = a[i]; 196 tween && tween._lazy && (tween.render(tween._lazy[0], tween._lazy[1], true)._lazy = 0); 197 } 198 }, 199 _lazySafeRender = function _lazySafeRender(animation, time, suppressEvents, force) { 200 _lazyTweens.length && _lazyRender(); 201 animation.render(time, suppressEvents, force); 202 _lazyTweens.length && _lazyRender(); 203 }, 204 _numericIfPossible = function _numericIfPossible(value) { 205 var n = parseFloat(value); 206 return (n || n === 0) && (value + "").match(_delimitedValueExp).length < 2 ? n : _isString(value) ? value.trim() : value; 207 }, 208 _passThrough = function _passThrough(p) { 209 return p; 210 }, 211 _setDefaults = function _setDefaults(obj, defaults) { 212 for (var p in defaults) { 213 p in obj || (obj[p] = defaults[p]); 214 } 215 216 return obj; 217 }, 218 _setKeyframeDefaults = function _setKeyframeDefaults(obj, defaults) { 219 for (var p in defaults) { 220 p in obj || p === "duration" || p === "ease" || (obj[p] = defaults[p]); 221 } 222 }, 223 _merge = function _merge(base, toMerge) { 224 for (var p in toMerge) { 225 base[p] = toMerge[p]; 226 } 227 228 return base; 229 }, 230 _mergeDeep = function _mergeDeep(base, toMerge) { 231 for (var p in toMerge) { 232 p !== "__proto__" && p !== "constructor" && p !== "prototype" && (base[p] = _isObject(toMerge[p]) ? _mergeDeep(base[p] || (base[p] = {}), toMerge[p]) : toMerge[p]); 233 } 234 235 return base; 236 }, 237 _copyExcluding = function _copyExcluding(obj, excluding) { 238 var copy = {}, 239 p; 240 241 for (p in obj) { 242 p in excluding || (copy[p] = obj[p]); 243 } 244 245 return copy; 246 }, 247 _inheritDefaults = function _inheritDefaults(vars) { 248 var parent = vars.parent || _globalTimeline, 249 func = vars.keyframes ? _setKeyframeDefaults : _setDefaults; 250 251 if (_isNotFalse(vars.inherit)) { 252 while (parent) { 253 func(vars, parent.vars.defaults); 254 parent = parent.parent || parent._dp; 255 } 256 } 257 258 return vars; 259 }, 260 _arraysMatch = function _arraysMatch(a1, a2) { 261 var i = a1.length, 262 match = i === a2.length; 263 264 while (match && i-- && a1[i] === a2[i]) {} 265 266 return i < 0; 267 }, 268 _addLinkedListItem = function _addLinkedListItem(parent, child, firstProp, lastProp, sortBy) { 269 if (firstProp === void 0) { 270 firstProp = "_first"; 271 } 272 273 if (lastProp === void 0) { 274 lastProp = "_last"; 275 } 276 277 var prev = parent[lastProp], 278 t; 279 280 if (sortBy) { 281 t = child[sortBy]; 282 283 while (prev && prev[sortBy] > t) { 284 prev = prev._prev; 285 } 286 } 287 288 if (prev) { 289 child._next = prev._next; 290 prev._next = child; 291 } else { 292 child._next = parent[firstProp]; 293 parent[firstProp] = child; 294 } 295 296 if (child._next) { 297 child._next._prev = child; 298 } else { 299 parent[lastProp] = child; 300 } 301 302 child._prev = prev; 303 child.parent = child._dp = parent; 304 return child; 305 }, 306 _removeLinkedListItem = function _removeLinkedListItem(parent, child, firstProp, lastProp) { 307 if (firstProp === void 0) { 308 firstProp = "_first"; 309 } 310 311 if (lastProp === void 0) { 312 lastProp = "_last"; 313 } 314 315 var prev = child._prev, 316 next = child._next; 317 318 if (prev) { 319 prev._next = next; 320 } else if (parent[firstProp] === child) { 321 parent[firstProp] = next; 322 } 323 324 if (next) { 325 next._prev = prev; 326 } else if (parent[lastProp] === child) { 327 parent[lastProp] = prev; 328 } 329 330 child._next = child._prev = child.parent = null; 331 }, 332 _removeFromParent = function _removeFromParent(child, onlyIfParentHasAutoRemove) { 333 child.parent && (!onlyIfParentHasAutoRemove || child.parent.autoRemoveChildren) && child.parent.remove(child); 334 child._act = 0; 335 }, 336 _uncache = function _uncache(animation, child) { 337 if (animation && (!child || child._end > animation._dur || child._start < 0)) { 338 var a = animation; 339 340 while (a) { 341 a._dirty = 1; 342 a = a.parent; 343 } 344 } 345 346 return animation; 347 }, 348 _recacheAncestors = function _recacheAncestors(animation) { 349 var parent = animation.parent; 350 351 while (parent && parent.parent) { 352 parent._dirty = 1; 353 parent.totalDuration(); 354 parent = parent.parent; 355 } 356 357 return animation; 358 }, 359 _hasNoPausedAncestors = function _hasNoPausedAncestors(animation) { 360 return !animation || animation._ts && _hasNoPausedAncestors(animation.parent); 361 }, 362 _elapsedCycleDuration = function _elapsedCycleDuration(animation) { 363 return animation._repeat ? _animationCycle(animation._tTime, animation = animation.duration() + animation._rDelay) * animation : 0; 364 }, 365 _animationCycle = function _animationCycle(tTime, cycleDuration) { 366 var whole = Math.floor(tTime /= cycleDuration); 367 return tTime && whole === tTime ? whole - 1 : whole; 368 }, 369 _parentToChildTotalTime = function _parentToChildTotalTime(parentTime, child) { 370 return (parentTime - child._start) * child._ts + (child._ts >= 0 ? 0 : child._dirty ? child.totalDuration() : child._tDur); 371 }, 372 _setEnd = function _setEnd(animation) { 373 return animation._end = _round(animation._start + (animation._tDur / Math.abs(animation._ts || animation._rts || _tinyNum) || 0)); 374 }, 375 _alignPlayhead = function _alignPlayhead(animation, totalTime) { 376 var parent = animation._dp; 377 378 if (parent && parent.smoothChildTiming && animation._ts) { 379 animation._start = _round(parent._time - (animation._ts > 0 ? totalTime / animation._ts : ((animation._dirty ? animation.totalDuration() : animation._tDur) - totalTime) / -animation._ts)); 380 381 _setEnd(animation); 382 383 parent._dirty || _uncache(parent, animation); 384 } 385 386 return animation; 387 }, 388 _postAddChecks = function _postAddChecks(timeline, child) { 389 var t; 390 391 if (child._time || child._initted && !child._dur) { 392 t = _parentToChildTotalTime(timeline.rawTime(), child); 393 394 if (!child._dur || _clamp(0, child.totalDuration(), t) - child._tTime > _tinyNum) { 395 child.render(t, true); 396 } 397 } 398 399 if (_uncache(timeline, child)._dp && timeline._initted && timeline._time >= timeline._dur && timeline._ts) { 400 if (timeline._dur < timeline.duration()) { 401 t = timeline; 402 403 while (t._dp) { 404 t.rawTime() >= 0 && t.totalTime(t._tTime); 405 t = t._dp; 406 } 407 } 408 409 timeline._zTime = -_tinyNum; 410 } 411 },
412 _addToTimeline = function _addToTimeline(timeline, child, position, skipChecks) { 413 child.parent && _removeFromParent(child); 414 child._start = _round(position + child._delay); 415 child._end = _round(child._start + (child.totalDuration() / Math.abs(child.timeScale()) || 0)); 416 417 _addLinkedListItem(timeline, child, "_first", "_last", timeline._sort ? "_start" : 0); 418 419 timeline._recent = child; 420 skipChecks || _postAddChecks(timeline, child); 421 return timeline; 422 }, 423 _scrollTrigger = function _scrollTrigger(animation, trigger) { 424 return (_globals.ScrollTrigger || _missingPlugin("scrollTrigger", trigger)) && _globals.ScrollTrigger.create(trigger, animation); 425 }, 426 _attemptInitTween = function _attemptInitTween(tween, totalTime, force, suppressEvents) { 427 _initTween(tween, totalTime); 428 429 if (!tween._initted) { 430 return 1; 431 } 432 433 if (!force && tween._pt && (tween._dur && tween.vars.lazy !== false || !tween._dur && tween.vars.lazy) && _lastRenderedFrame !== _ticker.frame) { 434 _lazyTweens.push(tween); 435 436 tween._lazy = [totalTime, suppressEvents]; 437 return 1; 438 } 439 }, 440 _parentPlayheadIsBeforeStart = function _parentPlayheadIsBeforeStart(_ref) { 441 var parent = _ref.parent; 442 return parent && parent._ts && parent._initted && !parent._lock && (parent.rawTime() < 0 || _parentPlayheadIsBeforeStart(parent)); 443 }, 444 _renderZeroDurationTween = function _renderZeroDurationTween(tween, totalTime, suppressEvents, force) { 445 var prevRatio = tween.ratio, 446 ratio = totalTime < 0 || !totalTime && (!tween._start && _parentPlayheadIsBeforeStart(tween) || (tween._ts < 0 || tween._dp._ts < 0) && tween.data !== "isFromStart" && tween.data !== "isStart") ? 0 : 1, 447 repeatDelay = tween._rDelay, 448 tTime = 0, 449 pt, 450 iteration, 451 prevIteration; 452 453 if (repeatDelay && tween._repeat) { 454 tTime = _clamp(0, tween._tDur, totalTime); 455 iteration = _animationCycle(tTime, repeatDelay); 456 prevIteration = _animationCycle(tween._tTime, repeatDelay); 457 tween._yoyo && iteration & 1 && (ratio = 1 - ratio); 458 459 if (iteration !== prevIteration) { 460 prevRatio = 1 - ratio; 461 tween.vars.repeatRefresh && tween._initted && tween.invalidate(); 462 } 463 } 464 465 if (ratio !== prevRatio || force || tween._zTime === _tinyNum || !totalTime && tween._zTime) { 466 if (!tween._initted && _attemptInitTween(tween, totalTime, force, suppressEvents)) { 467 return; 468 } 469 470 prevIteration = tween._zTime; 471 tween._zTime = totalTime || (suppressEvents ? _tinyNum : 0); 472 suppressEvents || (suppressEvents = totalTime && !prevIteration); 473 tween.ratio = ratio; 474 tween._from && (ratio = 1 - ratio); 475 tween._time = 0; 476 tween._tTime = tTime; 477 pt = tween._pt; 478 479 while (pt) { 480 pt.r(ratio, pt.d); 481 pt = pt._next; 482 } 483 484 tween._startAt && totalTime < 0 && tween._startAt.render(totalTime, true, true);
vendor: 9,020 bytes, lines 485-753
485 tween._onUpdate && !suppressEvents && _callback(tween, "onUpdate"); 486 tTime && tween._repeat && !suppressEvents && tween.parent && _callback(tween, "onRepeat"); 487 488 if ((totalTime >= tween._tDur || totalTime < 0) && tween.ratio === ratio) { 489 ratio && _removeFromParent(tween, 1); 490 491 if (!suppressEvents) { 492 _callback(tween, ratio ? "onComplete" : "onReverseComplete", true); 493 494 tween._prom && tween._prom(); 495 } 496 } 497 } else if (!tween._zTime) { 498 tween._zTime = totalTime; 499 } 500 }, 501 _findNextPauseTween = function _findNextPauseTween(animation, prevTime, time) { 502 var child; 503 504 if (time > prevTime) { 505 child = animation._first; 506 507 while (child && child._start <= time) { 508 if (!child._dur && child.data === "isPause" && child._start > prevTime) { 509 return child; 510 } 511 512 child = child._next; 513 } 514 } else { 515 child = animation._last; 516 517 while (child && child._start >= time) { 518 if (!child._dur && child.data === "isPause" && child._start < prevTime) { 519 return child; 520 } 521 522 child = child._prev; 523 } 524 } 525 }, 526 _setDuration = function _setDuration(animation, duration, skipUncache, leavePlayhead) { 527 var repeat = animation._repeat, 528 dur = _round(duration) || 0, 529 totalProgress = animation._tTime / animation._tDur; 530 totalProgress && !leavePlayhead && (animation._time *= dur / animation._dur); 531 animation._dur = dur; 532 animation._tDur = !repeat ? dur : repeat < 0 ? 1e10 : _round(dur * (repeat + 1) + animation._rDelay * repeat); 533 totalProgress && !leavePlayhead ? _alignPlayhead(animation, animation._tTime = animation._tDur * totalProgress) : animation.parent && _setEnd(animation); 534 skipUncache || _uncache(animation.parent, animation); 535 return animation; 536 }, 537 _onUpdateTotalDuration = function _onUpdateTotalDuration(animation) { 538 return animation instanceof Timeline ? _uncache(animation) : _setDuration(animation, animation._dur); 539 }, 540 _zeroPosition = { 541 _start: 0, 542 endTime: _emptyFunc 543 }, 544 _parsePosition = function _parsePosition(animation, position) { 545 var labels = animation.labels, 546 recent = animation._recent || _zeroPosition, 547 clippedDuration = animation.duration() >= _bigNum ? recent.endTime(false) : animation._dur, 548 i, 549 offset; 550 551 if (_isString(position) && (isNaN(position) || position in labels)) { 552 i = position.charAt(0); 553 554 if (i === "<" || i === ">") { 555 return (i === "<" ? recent._start : recent.endTime(recent._repeat >= 0)) + (parseFloat(position.substr(1)) || 0); 556 } 557 558 i = position.indexOf("="); 559 560 if (i < 0) { 561 position in labels || (labels[position] = clippedDuration); 562 return labels[position]; 563 } 564 565 offset = +(position.charAt(i - 1) + position.substr(i + 1)); 566 return i > 1 ? _parsePosition(animation, position.substr(0, i - 1)) + offset : clippedDuration + offset; 567 } 568 569 return position == null ? clippedDuration : +position; 570 }, 571 _conditionalReturn = function _conditionalReturn(value, func) { 572 return value || value === 0 ? func(value) : func; 573 }, 574 _clamp = function _clamp(min, max, value) { 575 return value < min ? min : value > max ? max : value; 576 }, 577 getUnit = function getUnit(value) { 578 if (typeof value !== "string") { 579 return ""; 580 } 581 582 var v = _unitExp.exec(value); 583 584 return v ? value.substr(v.index + v[0].length) : ""; 585 }, 586 clamp = function clamp(min, max, value) { 587 return _conditionalReturn(value, function (v) { 588 return _clamp(min, max, v); 589 }); 590 }, 591 _slice = [].slice, 592 _isArrayLike = function _isArrayLike(value, nonEmpty) { 593 return value && _isObject(value) && "length" in value && (!nonEmpty && !value.length || value.length - 1 in value && _isObject(value[0])) && !value.nodeType && value !== _win; 594 }, 595 _flatten = function _flatten(ar, leaveStrings, accumulator) { 596 if (accumulator === void 0) { 597 accumulator = []; 598 } 599 600 return ar.forEach(function (value) { 601 var _accumulator; 602 603 return _isString(value) && !leaveStrings || _isArrayLike(value, 1) ? (_accumulator = accumulator).push.apply(_accumulator, toArray(value)) : accumulator.push(value); 604 }) || accumulator; 605 }, 606 toArray = function toArray(value, leaveStrings) { 607 return _isString(value) && !leaveStrings && (_coreInitted || !_wake()) ? _slice.call(_doc.querySelectorAll(value), 0) : _isArray(value) ? _flatten(value, leaveStrings) : _isArrayLike(value) ? _slice.call(value, 0) : value ? [value] : []; 608 }, 609 shuffle = function shuffle(a) { 610 return a.sort(function () { 611 return .5 - Math.random(); 612 }); 613 }, 614 distribute = function distribute(v) { 615 if (_isFunction(v)) { 616 return v; 617 } 618 619 var vars = _isObject(v) ? v : { 620 each: v 621 }, 622 ease = _parseEase(vars.ease), 623 from = vars.from || 0, 624 base = parseFloat(vars.base) || 0, 625 cache = {}, 626 isDecimal = from > 0 && from < 1, 627 ratios = isNaN(from) || isDecimal, 628 axis = vars.axis, 629 ratioX = from, 630 ratioY = from; 631 632 if (_isString(from)) { 633 ratioX = ratioY = { 634 center: .5, 635 edges: .5, 636 end: 1 637 }[from] || 0; 638 } else if (!isDecimal && ratios) { 639 ratioX = from[0]; 640 ratioY = from[1]; 641 } 642 643 return function (i, target, a) { 644 var l = (a || vars).length, 645 distances = cache[l], 646 originX, 647 originY, 648 x, 649 y, 650 d, 651 j, 652 max, 653 min, 654 wrapAt; 655 656 if (!distances) { 657 wrapAt = vars.grid === "auto" ? 0 : (vars.grid || [1, _bigNum])[1]; 658 659 if (!wrapAt) { 660 max = -_bigNum; 661 662 while (max < (max = a[wrapAt++].getBoundingClientRect().left) && wrapAt < l) {} 663 664 wrapAt--; 665 } 666 667 distances = cache[l] = []; 668 originX = ratios ? Math.min(wrapAt, l) * ratioX - .5 : from % wrapAt; 669 originY = ratios ? l * ratioY / wrapAt - .5 : from / wrapAt | 0; 670 max = 0; 671 min = _bigNum; 672 673 for (j = 0; j < l; j++) { 674 x = j % wrapAt - originX; 675 y = originY - (j / wrapAt | 0); 676 distances[j] = d = !axis ? _sqrt(x * x + y * y) : Math.abs(axis === "y" ? y : x); 677 d > max && (max = d); 678 d < min && (min = d); 679 } 680 681 from === "random" && shuffle(distances); 682 distances.max = max - min; 683 distances.min = min; 684 distances.v = l = (parseFloat(vars.amount) || parseFloat(vars.each) * (wrapAt > l ? l - 1 : !axis ? Math.max(wrapAt, l / wrapAt) : axis === "y" ? l / wrapAt : wrapAt) || 0) * (from === "edges" ? -1 : 1); 685 distances.b = l < 0 ? base - l : base; 686 distances.u = getUnit(vars.amount || vars.each) || 0; 687 ease = ease && l < 0 ? _invertEase(ease) : ease; 688 } 689 690 l = (distances[i] - distances.min) / distances.max || 0; 691 return _round(distances.b + (ease ? ease(l) : l) * distances.v) + distances.u; 692 }; 693 }, 694 _roundModifier = function _roundModifier(v) { 695 var p = v < 1 ? Math.pow(10, (v + "").length - 2) : 1; 696 return function (raw) { 697 var n = Math.round(parseFloat(raw) / v) * v * p; 698 return (n - n % 1) / p + (_isNumber(raw) ? 0 : getUnit(raw)); 699 }; 700 }, 701 snap = function snap(snapTo, value) { 702 var isArray = _isArray(snapTo), 703 radius, 704 is2D; 705 706 if (!isArray && _isObject(snapTo)) { 707 radius = isArray = snapTo.radius || _bigNum; 708 709 if (snapTo.values) { 710 snapTo = toArray(snapTo.values); 711 712 if (is2D = !_isNumber(snapTo[0])) { 713 radius *= radius; 714 } 715 } else { 716 snapTo = _roundModifier(snapTo.increment); 717 } 718 } 719 720 return _conditionalReturn(value, !isArray ? _roundModifier(snapTo) : _isFunction(snapTo) ? function (raw) { 721 is2D = snapTo(raw); 722 return Math.abs(is2D - raw) <= radius ? is2D : raw; 723 } : function (raw) { 724 var x = parseFloat(is2D ? raw.x : raw), 725 y = parseFloat(is2D ? raw.y : 0), 726 min = _bigNum, 727 closest = 0, 728 i = snapTo.length, 729 dx, 730 dy; 731 732 while (i--) { 733 if (is2D) { 734 dx = snapTo[i].x - x; 735 dy = snapTo[i].y - y; 736 dx = dx * dx + dy * dy; 737 } else { 738 dx = Math.abs(snapTo[i] - x); 739 } 740 741 if (dx < min) { 742 min = dx; 743 closest = i; 744 } 745 } 746 747 closest = !radius || min <= radius ? snapTo[closest] : raw; 748 return is2D || closest === raw || _isNumber(raw) ? closest : closest + getUnit(raw); 749 }); 750 }, 751 random = function random(min, max, roundingIncrement, returnFunction) { 752 return _conditionalReturn(_isArray(min) ? !max : roundingIncrement === true ? !!(roundingIncrement = 0) : !returnFunction, function () { 753 return _isArray(min) ? min[~~(Math.random() * min.length)] : (roundingIncrement = roundingIncrement || 1e
vendor: 4,723 bytes, lines 753-909
753-5) && (returnFunction = roundingIncrement < 1 ? Math.pow(10, (roundingIncrement + "").length - 2) : 1) && Math.floor(Math.round((min - roundingIncrement / 2 + Math.random() * (max - min + roundingIncrement * .99)) / roundingIncrement) * roundingIncrement * returnFunction) / returnFunction; 754 }); 755 }, 756 pipe = function pipe() { 757 for (var _len = arguments.length, functions = new Array(_len), _key = 0; _key < _len; _key++) { 758 functions[_key] = arguments[_key]; 759 } 760 761 return function (value) { 762 return functions.reduce(function (v, f) { 763 return f(v); 764 }, value); 765 }; 766 }, 767 unitize = function unitize(func, unit) { 768 return function (value) { 769 return func(parseFloat(value)) + (unit || getUnit(value)); 770 }; 771 }, 772 normalize = function normalize(min, max, value) { 773 return mapRange(min, max, 0, 1, value); 774 }, 775 _wrapArray = function _wrapArray(a, wrapper, value) { 776 return _conditionalReturn(value, function (index) { 777 return a[~~wrapper(index)]; 778 }); 779 }, 780 wrap = function wrap(min, max, value) { 781 var range = max - min; 782 return _isArray(min) ? _wrapArray(min, wrap(0, min.length), max) : _conditionalReturn(value, function (value) { 783 return (range + (value - min) % range) % range + min; 784 }); 785 }, 786 wrapYoyo = function wrapYoyo(min, max, value) { 787 var range = max - min, 788 total = range * 2; 789 return _isArray(min) ? _wrapArray(min, wrapYoyo(0, min.length - 1), max) : _conditionalReturn(value, function (value) { 790 value = (total + (value - min) % total) % total || 0; 791 return min + (value > range ? total - value : value); 792 }); 793 }, 794 _replaceRandom = function _replaceRandom(value) { 795 var prev = 0, 796 s = "", 797 i, 798 nums, 799 end, 800 isArray; 801 802 while (~(i = value.indexOf("random(", prev))) { 803 end = value.indexOf(")", i); 804 isArray = value.charAt(i + 7) === "["; 805 nums = value.substr(i + 7, end - i - 7).match(isArray ? _delimitedValueExp : _strictNumExp); 806 s += value.substr(prev, i - prev) + random(isArray ? nums : +nums[0], isArray ? 0 : +nums[1], +nums[2] || 1e-5); 807 prev = end + 1; 808 } 809 810 return s + value.substr(prev, value.length - prev); 811 }, 812 mapRange = function mapRange(inMin, inMax, outMin, outMax, value) { 813 var inRange = inMax - inMin, 814 outRange = outMax - outMin; 815 return _conditionalReturn(value, function (value) { 816 return outMin + ((value - inMin) / inRange * outRange || 0); 817 }); 818 }, 819 interpolate = function interpolate(start, end, progress, mutate) { 820 var func = isNaN(start + end) ? 0 : function (p) { 821 return (1 - p) * start + p * end; 822 }; 823 824 if (!func) { 825 var isString = _isString(start), 826 master = {}, 827 p, 828 i, 829 interpolators, 830 l, 831 il; 832 833 progress === true && (mutate = 1) && (progress = null); 834 835 if (isString) { 836 start = { 837 p: start 838 }; 839 end = { 840 p: end 841 }; 842 } else if (_isArray(start) && !_isArray(end)) { 843 interpolators = []; 844 l = start.length; 845 il = l - 2; 846 847 for (i = 1; i < l; i++) { 848 interpolators.push(interpolate(start[i - 1], start[i])); 849 } 850 851 l--; 852 853 func = function func(p) { 854 p *= l; 855 var i = Math.min(il, ~~p); 856 return interpolators[i](p - i); 857 }; 858 859 progress = end; 860 } else if (!mutate) { 861 start = _merge(_isArray(start) ? [] : {}, start); 862 } 863 864 if (!interpolators) { 865 for (p in end) { 866 _addPropTween.call(master, start, p, "get", end[p]); 867 } 868 869 func = function func(p) { 870 return _renderPropTweens(p, master) || (isString ? start.p : start); 871 }; 872 } 873 } 874 875 return _conditionalReturn(progress, func); 876 }, 877 _getLabelInDirection = function _getLabelInDirection(timeline, fromTime, backward) { 878 var labels = timeline.labels, 879 min = _bigNum, 880 p, 881 distance, 882 label; 883 884 for (p in labels) { 885 distance = labels[p] - fromTime; 886 887 if (distance < 0 === !!backward && distance && min > (distance = Math.abs(distance))) { 888 label = p; 889 min = distance; 890 } 891 } 892 893 return label; 894 }, 895 _callback = function _callback(animation, type, executeLazyFirst) { 896 var v = animation.vars, 897 callback = v[type], 898 params, 899 scope; 900 901 if (!callback) { 902 return; 903 } 904 905 params = v[type + "Params"]; 906 scope = v.callbackScope || animation; 907 executeLazyFirst && _lazyTweens.length && _lazyRender(); 908 return params ? callback.apply(scope, params) : callback.call(scope); 909 },
vendor: 7,655 bytes, lines 910-1195
910 _interrupt = function _interrupt(animation) { 911 _removeFromParent(animation); 912 913 animation.scrollTrigger && animation.scrollTrigger.kill(false); 914 animation.progress() < 1 && _callback(animation, "onInterrupt"); 915 return animation; 916 }, 917 _quickTween, 918 _createPlugin = function _createPlugin(config) { 919 config = !config.name && config["default"] || config; 920 921 var name = config.name, 922 isFunc = _isFunction(config), 923 Plugin = name && !isFunc && config.init ? function () { 924 this._props = []; 925 } : config, 926 instanceDefaults = { 927 init: _emptyFunc, 928 render: _renderPropTweens, 929 add: _addPropTween, 930 kill: _killPropTweensOf, 931 modifier: _addPluginModifier, 932 rawVars: 0 933 }, 934 statics = { 935 targetTest: 0, 936 get: 0, 937 getSetter: _getSetter, 938 aliases: {}, 939 register: 0 940 }; 941 942 _wake(); 943 944 if (config !== Plugin) { 945 if (_plugins[name]) { 946 return; 947 } 948 949 _setDefaults(Plugin, _setDefaults(_copyExcluding(config, instanceDefaults), statics)); 950 951 _merge(Plugin.prototype, _merge(instanceDefaults, _copyExcluding(config, statics))); 952 953 _plugins[Plugin.prop = name] = Plugin; 954 955 if (config.targetTest) { 956 _harnessPlugins.push(Plugin); 957 958 _reservedProps[name] = 1; 959 } 960 961 name = (name === "css" ? "CSS" : name.charAt(0).toUpperCase() + name.substr(1)) + "Plugin"; 962 } 963 964 _addGlobal(name, Plugin); 965 966 config.register && config.register(gsap, Plugin, PropTween); 967 }, 968 _255 = 255, 969 _colorLookup = { 970 aqua: [0, _255, _255], 971 lime: [0, _255, 0], 972 silver: [192, 192, 192], 973 black: [0, 0, 0], 974 maroon: [128, 0, 0], 975 teal: [0, 128, 128], 976 blue: [0, 0, _255], 977 navy: [0, 0, 128], 978 white: [_255, _255, _255], 979 olive: [128, 128, 0], 980 yellow: [_255, _255, 0], 981 orange: [_255, 165, 0], 982 gray: [128, 128, 128], 983 purple: [128, 0, 128], 984 green: [0, 128, 0], 985 red: [_255, 0, 0], 986 pink: [_255, 192, 203], 987 cyan: [0, _255, _255], 988 transparent: [_255, _255, _255, 0] 989 }, 990 _hue = function _hue(h, m1, m2) { 991 h = h < 0 ? h + 1 : h > 1 ? h - 1 : h; 992 return (h * 6 < 1 ? m1 + (m2 - m1) * h * 6 : h < .5 ? m2 : h * 3 < 2 ? m1 + (m2 - m1) * (2 / 3 - h) * 6 : m1) * _255 + .5 | 0; 993 }, 994 splitColor = function splitColor(v, toHSL, forceAlpha) { 995 var a = !v ? _colorLookup.black : _isNumber(v) ? [v >> 16, v >> 8 & _255, v & _255] : 0, 996 r, 997 g, 998 b, 999 h, 1000 s, 1001 l, 1002 max, 1003 min, 1004 d, 1005 wasHSL; 1006 1007 if (!a) { 1008 if (v.substr(-1) === ",") { 1009 v = v.substr(0, v.length - 1); 1010 } 1011 1012 if (_colorLookup[v]) { 1013 a = _colorLookup[v]; 1014 } else if (v.charAt(0) === "#") { 1015 if (v.length < 6) { 1016 r = v.charAt(1); 1017 g = v.charAt(2); 1018 b = v.charAt(3); 1019 v = "#" + r + r + g + g + b + b + (v.length === 5 ? v.charAt(4) + v.charAt(4) : ""); 1020 } 1021 1022 if (v.length === 9) { 1023 a = parseInt(v.substr(1, 6), 16); 1024 return [a >> 16, a >> 8 & _255, a & _255, parseInt(v.substr(7), 16) / 255]; 1025 } 1026 1027 v = parseInt(v.substr(1), 16); 1028 a = [v >> 16, v >> 8 & _255, v & _255]; 1029 } else if (v.substr(0, 3) === "hsl") { 1030 a = wasHSL = v.match(_strictNumExp); 1031 1032 if (!toHSL) { 1033 h = +a[0] % 360 / 360; 1034 s = +a[1] / 100; 1035 l = +a[2] / 100; 1036 g = l <= .5 ? l * (s + 1) : l + s - l * s; 1037 r = l * 2 - g; 1038 a.length > 3 && (a[3] *= 1); 1039 a[0] = _hue(h + 1 / 3, r, g); 1040 a[1] = _hue(h, r, g); 1041 a[2] = _hue(h - 1 / 3, r, g); 1042 } else if (~v.indexOf("=")) { 1043 a = v.match(_numExp); 1044 forceAlpha && a.length < 4 && (a[3] = 1); 1045 return a; 1046 } 1047 } else { 1048 a = v.match(_strictNumExp) || _colorLookup.transparent; 1049 } 1050 1051 a = a.map(Number); 1052 } 1053 1054 if (toHSL && !wasHSL) { 1055 r = a[0] / _255; 1056 g = a[1] / _255; 1057 b = a[2] / _255; 1058 max = Math.max(r, g, b); 1059 min = Math.min(r, g, b); 1060 l = (max + min) / 2; 1061 1062 if (max === min) { 1063 h = s = 0; 1064 } else { 1065 d = max - min; 1066 s = l > 0.5 ? d / (2 - max - min) : d / (max + min); 1067 h = max === r ? (g - b) / d + (g < b ? 6 : 0) : max === g ? (b - r) / d + 2 : (r - g) / d + 4; 1068 h *= 60; 1069 } 1070 1071 a[0] = ~~(h + .5); 1072 a[1] = ~~(s * 100 + .5); 1073 a[2] = ~~(l * 100 + .5); 1074 } 1075 1076 forceAlpha && a.length < 4 && (a[3] = 1); 1077 return a; 1078 }, 1079 _colorOrderData = function _colorOrderData(v) { 1080 var values = [], 1081 c = [], 1082 i = -1; 1083 v.split(_colorExp).forEach(function (v) { 1084 var a = v.match(_numWithUnitExp) || []; 1085 values.push.apply(values, a); 1086 c.push(i += a.length + 1); 1087 }); 1088 values.c = c; 1089 return values; 1090 }, 1091 _formatColors = function _formatColors(s, toHSL, orderMatchData) { 1092 var result = "", 1093 colors = (s + result).match(_colorExp), 1094 type = toHSL ? "hsla(" : "rgba(", 1095 i = 0, 1096 c, 1097 shell, 1098 d, 1099 l; 1100 1101 if (!colors) { 1102 return s; 1103 } 1104 1105 colors = colors.map(function (color) { 1106 return (color = splitColor(color, toHSL, 1)) && type + (toHSL ? color[0] + "," + color[1] + "%," + color[2] + "%," + color[3] : color.join(",")) + ")"; 1107 }); 1108 1109 if (orderMatchData) { 1110 d = _colorOrderData(s); 1111 c = orderMatchData.c; 1112 1113 if (c.join(result) !== d.c.join(result)) { 1114 shell = s.replace(_colorExp, "1").split(_numWithUnitExp); 1115 l = shell.length - 1; 1116 1117 for (; i < l; i++) { 1118 result += shell[i] + (~c.indexOf(i) ? colors.shift() || type + "0,0,0,0)" : (d.length ? d : colors.length ? colors : orderMatchData).shift()); 1119 } 1120 } 1121 } 1122 1123 if (!shell) { 1124 shell = s.split(_colorExp); 1125 l = shell.length - 1; 1126 1127 for (; i < l; i++) { 1128 result += shell[i] + colors[i]; 1129 } 1130 } 1131 1132 return result + shell[l]; 1133 }, 1134 _colorExp = function () { 1135 var s = "(?:\\b(?:(?:rgb|rgba|hsl|hsla)\\(.+?\\))|\\B#(?:[0-9a-f]{3,4}){1,2}\\b", 1136 p; 1137 1138 for (p in _colorLookup) { 1139 s += "|" + p + "\\b"; 1140 } 1141 1142 return new RegExp(s + ")", "gi"); 1143 }(), 1144 _hslExp = /hsl[a]?\(/, 1145 _colorStringFilter = function _colorStringFilter(a) { 1146 var combined = a.join(" "), 1147 toHSL; 1148 _colorExp.lastIndex = 0; 1149 1150 if (_colorExp.test(combined)) { 1151 toHSL = _hslExp.test(combined); 1152 a[1] = _formatColors(a[1], toHSL); 1153 a[0] = _formatColors(a[0], toHSL, _colorOrderData(a[1])); 1154 return true; 1155 } 1156 }, 1157 _tickerActive, 1158 _ticker = function () { 1159 var _getTime = Date.now, 1160 _lagThreshold = 500, 1161 _adjustedLag = 33, 1162 _startTime = _getTime(), 1163 _lastUpdate = _startTime, 1164 _gap = 1000 / 240, 1165 _nextTime = _gap, 1166 _listeners = [], 1167 _id, 1168 _req, 1169 _raf, 1170 _self, 1171 _delta, 1172 _i, 1173 _tick = function _tick(v) { 1174 var elapsed = _getTime() - _lastUpdate, 1175 manual = v === true, 1176 overlap, 1177 dispatch, 1178 time, 1179 frame; 1180 1181 elapsed > _lagThreshold && (_startTime += elapsed - _adjustedLag); 1182 _lastUpdate += elapsed; 1183 time = _lastUpdate - _startTime; 1184 overlap = time - _nextTime; 1185 1186 if (overlap > 0 || manual) { 1187 frame = ++_self.frame; 1188 _delta = time - _self.time * 1000; 1189 _self.time = time = time / 1000; 1190 _nextTime += overlap + (overlap >= _gap ? 4 : _gap - overlap); 1191 dispatch = 1; 1192 } 1193 1194 manual || (_id = _req(_tick)); 1195
vendor: 4,054 bytes, lines 1196-1323
1196 if (dispatch) { 1197 for (_i = 0; _i < _listeners.length; _i++) { 1198 _listeners[_i](time, _delta, frame, v); 1199 } 1200 } 1201 }; 1202 1203 _self = { 1204 time: 0, 1205 frame: 0, 1206 tick: function tick() { 1207 _tick(true); 1208 }, 1209 deltaRatio: function deltaRatio(fps) { 1210 return _delta / (1000 / (fps || 60)); 1211 }, 1212 wake: function wake() { 1213 if (_coreReady) { 1214 if (!_coreInitted && _windowExists()) { 1215 _win = _coreInitted = window; 1216 _doc = _win.document || {}; 1217 _globals.gsap = gsap; 1218 (_win.gsapVersions || (_win.gsapVersions = [])).push(gsap.version); 1219 1220 _install(_installScope || _win.GreenSockGlobals || !_win.gsap && _win || {}); 1221 1222 _raf = _win.requestAnimationFrame; 1223 } 1224 1225 _id && _self.sleep(); 1226 1227 _req = _raf || function (f) { 1228 return setTimeout(f, _nextTime - _self.time * 1000 + 1 | 0); 1229 }; 1230 1231 _tickerActive = 1; 1232 1233 _tick(2); 1234 } 1235 }, 1236 sleep: function sleep() { 1237 (_raf ? _win.cancelAnimationFrame : clearTimeout)(_id); 1238 _tickerActive = 0; 1239 _req = _emptyFunc; 1240 }, 1241 lagSmoothing: function lagSmoothing(threshold, adjustedLag) { 1242 _lagThreshold = threshold || 1 / _tinyNum; 1243 _adjustedLag = Math.min(adjustedLag, _lagThreshold, 0); 1244 }, 1245 fps: function fps(_fps) { 1246 _gap = 1000 / (_fps || 240); 1247 _nextTime = _self.time * 1000 + _gap; 1248 }, 1249 add: function add(callback) { 1250 _listeners.indexOf(callback) < 0 && _listeners.push(callback); 1251 1252 _wake(); 1253 }, 1254 remove: function remove(callback) { 1255 var i; 1256 ~(i = _listeners.indexOf(callback)) && _listeners.splice(i, 1) && _i >= i && _i--; 1257 }, 1258 _listeners: _listeners 1259 }; 1260 return _self; 1261 }(), 1262 _wake = function _wake() { 1263 return !_tickerActive && _ticker.wake(); 1264 }, 1265 _easeMap = {}, 1266 _customEaseExp = /^[\d.\-M][\d.\-,\s]/, 1267 _quotesExp = /["']/g, 1268 _parseObjectInString = function _parseObjectInString(value) { 1269 var obj = {}, 1270 split = value.substr(1, value.length - 3).split(":"), 1271 key = split[0], 1272 i = 1, 1273 l = split.length, 1274 index, 1275 val, 1276 parsedVal; 1277 1278 for (; i < l; i++) { 1279 val = split[i]; 1280 index = i !== l - 1 ? val.lastIndexOf(",") : val.length; 1281 parsedVal = val.substr(0, index); 1282 obj[key] = isNaN(parsedVal) ? parsedVal.replace(_quotesExp, "").trim() : +parsedVal; 1283 key = val.substr(index + 1).trim(); 1284 } 1285 1286 return obj; 1287 }, 1288 _valueInParentheses = function _valueInParentheses(value) { 1289 var open = value.indexOf("(") + 1, 1290 close = value.indexOf(")"), 1291 nested = value.indexOf("(", open); 1292 return value.substring(open, ~nested && nested < close ? value.indexOf(")", close + 1) : close); 1293 }, 1294 _configEaseFromString = function _configEaseFromString(name) { 1295 var split = (name + "").split("("), 1296 ease = _easeMap[split[0]]; 1297 return ease && split.length > 1 && ease.config ? ease.config.apply(null, ~name.indexOf("{") ? [_parseObjectInString(split[1])] : _valueInParentheses(name).split(",").map(_numericIfPossible)) : _easeMap._CE && _customEaseExp.test(name) ? _easeMap._CE("", name) : ease; 1298 }, 1299 _invertEase = function _invertEase(ease) { 1300 return function (p) { 1301 return 1 - ease(1 - p); 1302 }; 1303 }, 1304 _propagateYoyoEase = function _propagateYoyoEase(timeline, isYoyo) { 1305 var child = timeline._first, 1306 ease; 1307 1308 while (child) { 1309 if (child instanceof Timeline) { 1310 _propagateYoyoEase(child, isYoyo); 1311 } else if (child.vars.yoyoEase && (!child._yoyo || !child._repeat) && child._yoyo !== isYoyo) { 1312 if (child.timeline) { 1313 _propagateYoyoEase(child.timeline, isYoyo); 1314 } else { 1315 ease = child._ease; 1316 child._ease = child._yEase; 1317 child._yEase = ease; 1318 child._yoyo = isYoyo; 1319 } 1320 } 1321 1322 child = child._next; 1323 }
vendor: 3,445 bytes, lines 1323-1434
1323 1324 }, 1325 _parseEase = function _parseEase(ease, defaultEase) { 1326 return !ease ? defaultEase : (_isFunction(ease) ? ease : _easeMap[ease] || _configEaseFromString(ease)) || defaultEase; 1327 }, 1328 _insertEase = function _insertEase(names, easeIn, easeOut, easeInOut) { 1329 if (easeOut === void 0) { 1330 easeOut = function easeOut(p) { 1331 return 1 - easeIn(1 - p); 1332 }; 1333 } 1334 1335 if (easeInOut === void 0) { 1336 easeInOut = function easeInOut(p) { 1337 return p < .5 ? easeIn(p * 2) / 2 : 1 - easeIn((1 - p) * 2) / 2; 1338 }; 1339 } 1340 1341 var ease = { 1342 easeIn: easeIn, 1343 easeOut: easeOut, 1344 easeInOut: easeInOut 1345 }, 1346 lowercaseName; 1347 1348 _forEachName(names, function (name) { 1349 _easeMap[name] = _globals[name] = ease; 1350 _easeMap[lowercaseName = name.toLowerCase()] = easeOut; 1351 1352 for (var p in ease) { 1353 _easeMap[lowercaseName + (p === "easeIn" ? ".in" : p === "easeOut" ? ".out" : ".inOut")] = _easeMap[name + "." + p] = ease[p]; 1354 } 1355 }); 1356 1357 return ease; 1358 }, 1359 _easeInOutFromOut = function _easeInOutFromOut(easeOut) { 1360 return function (p) { 1361 return p < .5 ? (1 - easeOut(1 - p * 2)) / 2 : .5 + easeOut((p - .5) * 2) / 2; 1362 }; 1363 }, 1364 _configElastic = function _configElastic(type, amplitude, period) { 1365 var p1 = amplitude >= 1 ? amplitude : 1, 1366 p2 = (period || (type ? .3 : .45)) / (amplitude < 1 ? amplitude : 1), 1367 p3 = p2 / _2PI * (Math.asin(1 / p1) || 0), 1368 easeOut = function easeOut(p) { 1369 return p === 1 ? 1 : p1 * Math.pow(2, -10 * p) * _sin((p - p3) * p2) + 1; 1370 }, 1371 ease = type === "out" ? easeOut : type === "in" ? function (p) { 1372 return 1 - easeOut(1 - p); 1373 } : _easeInOutFromOut(easeOut); 1374 1375 p2 = _2PI / p2; 1376 1377 ease.config = function (amplitude, period) { 1378 return _configElastic(type, amplitude, period); 1379 }; 1380 1381 return ease; 1382 }, 1383 _configBack = function _configBack(type, overshoot) { 1384 if (overshoot === void 0) { 1385 overshoot = 1.70158; 1386 } 1387 1388 var easeOut = function easeOut(p) { 1389 return p ? --p * p * ((overshoot + 1) * p + overshoot) + 1 : 0; 1390 }, 1391 ease = type === "out" ? easeOut : type === "in" ? function (p) { 1392 return 1 - easeOut(1 - p); 1393 } : _easeInOutFromOut(easeOut); 1394 1395 ease.config = function (overshoot) { 1396 return _configBack(type, overshoot); 1397 }; 1398 1399 return ease; 1400 }; 1401 1402 _forEachName("Linear,Quad,Cubic,Quart,Quint,Strong", function (name, i) { 1403 var power = i < 5 ? i + 1 : i; 1404 1405 _insertEase(name + ",Power" + (power - 1), i ? function (p) { 1406 return Math.pow(p, power); 1407 } : function (p) { 1408 return p; 1409 }, function (p) { 1410 return 1 - Math.pow(1 - p, power); 1411 }, function (p) { 1412 return p < .5 ? Math.pow(p * 2, power) / 2 : 1 - Math.pow((1 - p) * 2, power) / 2; 1413 }); 1414 }); 1415 1416 _easeMap.Linear.easeNone = _easeMap.none = _easeMap.Linear.easeIn; 1417 1418 _insertEase("Elastic", _configElastic("in"), _configElastic("out"), _configElastic()); 1419 1420 (function (n, c) { 1421 var n1 = 1 / c, 1422 n2 = 2 * n1, 1423 n3 = 2.5 * n1, 1424 easeOut = function easeOut(p) { 1425 return p < n1 ? n * p * p : p < n2 ? n * Math.pow(p - 1.5 / c, 2) + .75 : p < n3 ? n * (p -= 2.25 / c) * p + .9375 : n * Math.pow(p - 2.625 / c, 2) + .984375; 1426 }; 1427 1428 _insertEase("Bounce", function (p) { 1429 return 1 - easeOut(1 - p); 1430 }, easeOut); 1431 })(7.5625, 2.75); 1432 1433 _insertEase("Expo", function (p) { 1434 return
vendor: 6,382 bytes, lines 1434-1617
1434p ? Math.pow(2, 10 * (p - 1)) : 0; 1435 }); 1436 1437 _insertEase("Circ", function (p) { 1438 return -(_sqrt(1 - p * p) - 1); 1439 }); 1440 1441 _insertEase("Sine", function (p) { 1442 return p === 1 ? 1 : -_cos(p * _HALF_PI) + 1; 1443 }); 1444 1445 _insertEase("Back", _configBack("in"), _configBack("out"), _configBack()); 1446 1447 _easeMap.SteppedEase = _easeMap.steps = _globals.SteppedEase = { 1448 config: function config(steps, immediateStart) { 1449 if (steps === void 0) { 1450 steps = 1; 1451 } 1452 1453 var p1 = 1 / steps, 1454 p2 = steps + (immediateStart ? 0 : 1), 1455 p3 = immediateStart ? 1 : 0, 1456 max = 1 - _tinyNum; 1457 return function (p) { 1458 return ((p2 * _clamp(0, max, p) | 0) + p3) * p1; 1459 }; 1460 } 1461 }; 1462 _defaults.ease = _easeMap["quad.out"]; 1463 1464 _forEachName("onComplete,onUpdate,onStart,onRepeat,onReverseComplete,onInterrupt", function (name) { 1465 return _callbackNames += name + "," + name + "Params,"; 1466 }); 1467 1468 var GSCache = function GSCache(target, harness) { 1469 this.id = _gsID++; 1470 target._gsap = this; 1471 this.target = target; 1472 this.harness = harness; 1473 this.get = harness ? harness.get : _getProperty; 1474 this.set = harness ? harness.getSetter : _getSetter; 1475 }; 1476 var Animation = function () { 1477 function Animation(vars, time) { 1478 var parent = vars.parent || _globalTimeline; 1479 this.vars = vars; 1480 this._delay = +vars.delay || 0; 1481 1482 if (this._repeat = vars.repeat === Infinity ? -2 : vars.repeat || 0) { 1483 this._rDelay = vars.repeatDelay || 0; 1484 this._yoyo = !!vars.yoyo || !!vars.yoyoEase; 1485 } 1486 1487 this._ts = 1; 1488 1489 _setDuration(this, +vars.duration, 1, 1); 1490 1491 this.data = vars.data; 1492 _tickerActive || _ticker.wake(); 1493 parent && _addToTimeline(parent, this, time || time === 0 ? time : parent._time, 1); 1494 vars.reversed && this.reverse(); 1495 vars.paused && this.paused(true); 1496 } 1497 1498 var _proto = Animation.prototype; 1499 1500 _proto.delay = function delay(value) { 1501 if (value || value === 0) { 1502 this.parent && this.parent.smoothChildTiming && this.startTime(this._start + value - this._delay); 1503 this._delay = value; 1504 return this; 1505 } 1506 1507 return this._delay; 1508 }; 1509 1510 _proto.duration = function duration(value) { 1511 return arguments.length ? this.totalDuration(this._repeat > 0 ? value + (value + this._rDelay) * this._repeat : value) : this.totalDuration() && this._dur; 1512 }; 1513 1514 _proto.totalDuration = function totalDuration(value) { 1515 if (!arguments.length) { 1516 return this._tDur; 1517 } 1518 1519 this._dirty = 0; 1520 return _setDuration(this, this._repeat < 0 ? value : (value - this._repeat * this._rDelay) / (this._repeat + 1)); 1521 }; 1522 1523 _proto.totalTime = function totalTime(_totalTime, suppressEvents) { 1524 _wake(); 1525 1526 if (!arguments.length) { 1527 return this._tTime; 1528 } 1529 1530 var parent = this._dp; 1531 1532 if (parent && parent.smoothChildTiming && this._ts) { 1533 _alignPlayhead(this, _totalTime); 1534 1535 !parent._dp || parent.parent || _postAddChecks(parent, this); 1536 1537 while (parent.parent) { 1538 if (parent.parent._time !== parent._start + (parent._ts >= 0 ? parent._tTime / parent._ts : (parent.totalDuration() - parent._tTime) / -parent._ts)) { 1539 parent.totalTime(parent._tTime, true); 1540 } 1541 1542 parent = parent.parent; 1543 } 1544 1545 if (!this.parent && this._dp.autoRemoveChildren && (this._ts > 0 && _totalTime < this._tDur || this._ts < 0 && _totalTime > 0 || !this._tDur && !_totalTime)) { 1546 _addToTimeline(this._dp, this, this._start - this._delay); 1547 } 1548 } 1549 1550 if (this._tTime !== _totalTime || !this._dur && !suppressEvents || this._initted && Math.abs(this._zTime) === _tinyNum || !_totalTime && !this._initted && (this.add || this._ptLookup)) { 1551 this._ts || (this._pTime = _totalTime); 1552 1553 _lazySafeRender(this, _totalTime, suppressEvents); 1554 } 1555 1556 return this; 1557 }; 1558 1559 _proto.time = function time(value, suppressEvents) { 1560 return arguments.length ? this.totalTime(Math.min(this.totalDuration(), value + _elapsedCycleDuration(this)) % this._dur || (value ? this._dur : 0), suppressEvents) : this._time; 1561 }; 1562 1563 _proto.totalProgress = function totalProgress(value, suppressEvents) { 1564 return arguments.length ? this.totalTime(this.totalDuration() * value, suppressEvents) : this.totalDuration() ? Math.min(1, this._tTime / this._tDur) : this.ratio; 1565 }; 1566 1567 _proto.progress = function progress(value, suppressEvents) { 1568 return arguments.length ? this.totalTime(this.duration() * (this._yoyo && !(this.iteration() & 1) ? 1 - value : value) + _elapsedCycleDuration(this), suppressEvents) : this.duration() ? Math.min(1, this._time / this._dur) : this.ratio; 1569 }; 1570 1571 _proto.iteration = function iteration(value, suppressEvents) { 1572 var cycleDuration = this.duration() + this._rDelay; 1573 1574 return arguments.length ? this.totalTime(this._time + (value - 1) * cycleDuration, suppressEvents) : this._repeat ? _animationCycle(this._tTime, cycleDuration) + 1 : 1; 1575 }; 1576 1577 _proto.timeScale = function timeScale(value) { 1578 if (!arguments.length) { 1579 return this._rts === -_tinyNum ? 0 : this._rts; 1580 } 1581 1582 if (this._rts === value) { 1583 return this; 1584 } 1585 1586 var tTime = this.parent && this._ts ? _parentToChildTotalTime(this.parent._time, this) : this._tTime; 1587 this._rts = +value || 0; 1588 this._ts = this._ps || value === -_tinyNum ? 0 : this._rts; 1589 return _recacheAncestors(this.totalTime(_clamp(-this._delay, this._tDur, tTime), true)); 1590 }; 1591 1592 _proto.paused = function paused(value) { 1593 if (!arguments.length) { 1594 return this._ps; 1595 } 1596 1597 if (this._ps !== value) { 1598 this._ps = value; 1599 1600 if (value) { 1601 this._pTime = this._tTime || Math.max(-this._delay, this.rawTime()); 1602 this._ts = this._act = 0; 1603 } else { 1604 _wake(); 1605 1606 this._ts = this._rts; 1607 this.totalTime(this.parent && !this.parent.smoothChildTiming ? this.rawTime() : this._tTime || this._pTime, this.progress() === 1 && (this._tTime -= _tinyNum) && Math.abs(this._zTime) !== _tinyNum); 1608 } 1609 } 1610 1611 return this; 1612 }; 1613 1614 _proto.startTime = function startTime(value) { 1615 if (arguments.length) { 1616 this._start = value; 1617 var parent = this.parent || this._dp;
vendor: 2,817 bytes, lines 1618-1708
1618 parent && (parent._sort || !this.parent) && _addToTimeline(parent, this, value - this._delay); 1619 return this; 1620 } 1621 1622 return this._start; 1623 }; 1624 1625 _proto.endTime = function endTime(includeRepeats) { 1626 return this._start + (_isNotFalse(includeRepeats) ? this.totalDuration() : this.duration()) / Math.abs(this._ts); 1627 }; 1628 1629 _proto.rawTime = function rawTime(wrapRepeats) { 1630 var parent = this.parent || this._dp; 1631 return !parent ? this._tTime : wrapRepeats && (!this._ts || this._repeat && this._time && this.totalProgress() < 1) ? this._tTime % (this._dur + this._rDelay) : !this._ts ? this._tTime : _parentToChildTotalTime(parent.rawTime(wrapRepeats), this); 1632 }; 1633 1634 _proto.globalTime = function globalTime(rawTime) { 1635 var animation = this, 1636 time = arguments.length ? rawTime : animation.rawTime(); 1637 1638 while (animation) { 1639 time = animation._start + time / (animation._ts || 1); 1640 animation = animation._dp; 1641 } 1642 1643 return time; 1644 }; 1645 1646 _proto.repeat = function repeat(value) { 1647 if (arguments.length) { 1648 this._repeat = value === Infinity ? -2 : value; 1649 return _onUpdateTotalDuration(this); 1650 } 1651 1652 return this._repeat === -2 ? Infinity : this._repeat; 1653 }; 1654 1655 _proto.repeatDelay = function repeatDelay(value) { 1656 if (arguments.length) { 1657 this._rDelay = value; 1658 return _onUpdateTotalDuration(this); 1659 } 1660 1661 return this._rDelay; 1662 }; 1663 1664 _proto.yoyo = function yoyo(value) { 1665 if (arguments.length) { 1666 this._yoyo = value; 1667 return this; 1668 } 1669 1670 return this._yoyo; 1671 }; 1672 1673 _proto.seek = function seek(position, suppressEvents) { 1674 return this.totalTime(_parsePosition(this, position), _isNotFalse(suppressEvents)); 1675 }; 1676 1677 _proto.restart = function restart(includeDelay, suppressEvents) { 1678 return this.play().totalTime(includeDelay ? -this._delay : 0, _isNotFalse(suppressEvents)); 1679 }; 1680 1681 _proto.play = function play(from, suppressEvents) { 1682 from != null && this.seek(from, suppressEvents); 1683 return this.reversed(false).paused(false); 1684 }; 1685 1686 _proto.reverse = function reverse(from, suppressEvents) { 1687 from != null && this.seek(from || this.totalDuration(), suppressEvents); 1688 return this.reversed(true).paused(false); 1689 }; 1690 1691 _proto.pause = function pause(atTime, suppressEvents) { 1692 atTime != null && this.seek(atTime, suppressEvents); 1693 return this.paused(true); 1694 }; 1695 1696 _proto.resume = function resume() { 1697 return this.paused(false); 1698 }; 1699 1700 _proto.reversed = function reversed(value) { 1701 if (arguments.length) { 1702 !!value !== this.reversed() && this.timeScale(-this._rts || (value ? -_tinyNum : 0)); 1703 return this; 1704 } 1705 1706 return this._rts < 0; 1707 }; 1708
vendor: 8,594 bytes, lines 1709-1972
1709 _proto.invalidate = function invalidate() { 1710 this._initted = this._act = 0; 1711 this._zTime = -_tinyNum; 1712 return this; 1713 }; 1714 1715 _proto.isActive = function isActive() { 1716 var parent = this.parent || this._dp, 1717 start = this._start, 1718 rawTime; 1719 return !!(!parent || this._ts && this._initted && parent.isActive() && (rawTime = parent.rawTime(true)) >= start && rawTime < this.endTime(true) - _tinyNum); 1720 }; 1721 1722 _proto.eventCallback = function eventCallback(type, callback, params) { 1723 var vars = this.vars; 1724 1725 if (arguments.length > 1) { 1726 if (!callback) { 1727 delete vars[type]; 1728 } else { 1729 vars[type] = callback; 1730 params && (vars[type + "Params"] = params); 1731 type === "onUpdate" && (this._onUpdate = callback); 1732 } 1733 1734 return this; 1735 } 1736 1737 return vars[type]; 1738 }; 1739 1740 _proto.then = function then(onFulfilled) { 1741 var self = this; 1742 return new Promise(function (resolve) { 1743 var f = _isFunction(onFulfilled) ? onFulfilled : _passThrough, 1744 _resolve = function _resolve() { 1745 var _then = self.then; 1746 self.then = null; 1747 _isFunction(f) && (f = f(self)) && (f.then || f === self) && (self.then = _then); 1748 resolve(f); 1749 self.then = _then; 1750 }; 1751 1752 if (self._initted && self.totalProgress() === 1 && self._ts >= 0 || !self._tTime && self._ts < 0) { 1753 _resolve(); 1754 } else { 1755 self._prom = _resolve; 1756 } 1757 }); 1758 }; 1759 1760 _proto.kill = function kill() { 1761 _interrupt(this); 1762 }; 1763 1764 return Animation; 1765 }(); 1766 1767 _setDefaults(Animation.prototype, { 1768 _time: 0, 1769 _start: 0, 1770 _end: 0, 1771 _tTime: 0, 1772 _tDur: 0, 1773 _dirty: 0, 1774 _repeat: 0, 1775 _yoyo: false, 1776 parent: null, 1777 _initted: false, 1778 _rDelay: 0, 1779 _ts: 1, 1780 _dp: 0, 1781 ratio: 0, 1782 _zTime: -_tinyNum, 1783 _prom: 0, 1784 _ps: false, 1785 _rts: 1 1786 }); 1787 1788 var Timeline = function (_Animation) { 1789 _inheritsLoose(Timeline, _Animation); 1790 1791 function Timeline(vars, time) { 1792 var _this; 1793 1794 if (vars === void 0) { 1795 vars = {}; 1796 } 1797 1798 _this = _Animation.call(this, vars, time) || this; 1799 _this.labels = {}; 1800 _this.smoothChildTiming = !!vars.smoothChildTiming; 1801 _this.autoRemoveChildren = !!vars.autoRemoveChildren; 1802 _this._sort = _isNotFalse(vars.sortChildren); 1803 _this.parent && _postAddChecks(_this.parent, _assertThisInitialized(_this)); 1804 vars.scrollTrigger && _scrollTrigger(_assertThisInitialized(_this), vars.scrollTrigger); 1805 return _this; 1806 } 1807 1808 var _proto2 = Timeline.prototype; 1809 1810 _proto2.to = function to(targets, vars, position) { 1811 new Tween(targets, _parseVars(arguments, 0, this), _parsePosition(this, _isNumber(vars) ? arguments[3] : position)); 1812 return this; 1813 }; 1814 1815 _proto2.from = function from(targets, vars, position) { 1816 new Tween(targets, _parseVars(arguments, 1, this), _parsePosition(this, _isNumber(vars) ? arguments[3] : position)); 1817 return this; 1818 }; 1819 1820 _proto2.fromTo = function fromTo(targets, fromVars, toVars, position) { 1821 new Tween(targets, _parseVars(arguments, 2, this), _parsePosition(this, _isNumber(fromVars) ? arguments[4] : position)); 1822 return this; 1823 }; 1824 1825 _proto2.set = function set(targets, vars, position) { 1826 vars.duration = 0; 1827 vars.parent = this; 1828 _inheritDefaults(vars).repeatDelay || (vars.repeat = 0); 1829 vars.immediateRender = !!vars.immediateRender; 1830 new Tween(targets, vars, _parsePosition(this, position), 1); 1831 return this; 1832 }; 1833 1834 _proto2.call = function call(callback, params, position) { 1835 return _addToTimeline(this, Tween.delayedCall(0, callback, params), _parsePosition(this, position)); 1836 }; 1837 1838 _proto2.staggerTo = function staggerTo(targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams) { 1839 vars.duration = duration; 1840 vars.stagger = vars.stagger || stagger; 1841 vars.onComplete = onCompleteAll; 1842 vars.onCompleteParams = onCompleteAllParams; 1843 vars.parent = this; 1844 new Tween(targets, vars, _parsePosition(this, position)); 1845 return this; 1846 }; 1847 1848 _proto2.staggerFrom = function staggerFrom(targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams) { 1849 vars.runBackwards = 1; 1850 _inheritDefaults(vars).immediateRender = _isNotFalse(vars.immediateRender); 1851 return this.staggerTo(targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams); 1852 }; 1853 1854 _proto2.staggerFromTo = function staggerFromTo(targets, duration, fromVars, toVars, stagger, position, onCompleteAll, onCompleteAllParams) { 1855 toVars.startAt = fromVars; 1856 _inheritDefaults(toVars).immediateRender = _isNotFalse(toVars.immediateRender); 1857 return this.staggerTo(targets, duration, toVars, stagger, position, onCompleteAll, onCompleteAllParams); 1858 }; 1859 1860 _proto2.render = function render(totalTime, suppressEvents, force) { 1861 var prevTime = this._time, 1862 tDur = this._dirty ? this.totalDuration() : this._tDur, 1863 dur = this._dur, 1864 tTime = this !== _globalTimeline && totalTime > tDur - _tinyNum && totalTime >= 0 ? tDur : totalTime < _tinyNum ? 0 : totalTime, 1865 crossingStart = this._zTime < 0 !== totalTime < 0 && (this._initted || !dur), 1866 time, 1867 child, 1868 next, 1869 iteration, 1870 cycleDuration, 1871 prevPaused, 1872 pauseTween, 1873 timeScale, 1874 prevStart, 1875 prevIteration, 1876 yoyo, 1877 isYoyo; 1878 1879 if (tTime !== this._tTime || force || crossingStart) { 1880 if (prevTime !== this._time && dur) { 1881 tTime += this._time - prevTime; 1882 totalTime += this._time - prevTime; 1883 } 1884 1885 time = tTime; 1886 prevStart = this._start; 1887 timeScale = this._ts; 1888 prevPaused = !timeScale; 1889 1890 if (crossingStart) { 1891 dur || (prevTime = this._zTime); 1892 (totalTime || !suppressEvents) && (this._zTime = totalTime); 1893 } 1894 1895 if (this._repeat) { 1896 yoyo = this._yoyo; 1897 cycleDuration = dur + this._rDelay; 1898 1899 if (this._repeat < -1 && totalTime < 0) { 1900 return this.totalTime(cycleDuration * 100 + totalTime, suppressEvents, force); 1901 } 1902 1903 time = _round(tTime % cycleDuration); 1904 1905 if (tTime === tDur) { 1906 iteration = this._repeat; 1907 time = dur; 1908 } else { 1909 iteration = ~~(tTime / cycleDuration); 1910 1911 if (iteration && iteration === tTime / cycleDuration) { 1912 time = dur; 1913 iteration--; 1914 } 1915 1916 time > dur && (time = dur); 1917 } 1918 1919 prevIteration = _animationCycle(this._tTime, cycleDuration); 1920 !prevTime && this._tTime && prevIteration !== iteration && (prevIteration = iteration); 1921 1922 if (yoyo && iteration & 1) { 1923 time = dur - time; 1924 isYoyo = 1; 1925 } 1926 1927 if (iteration !== prevIteration && !this._lock) { 1928 var rewinding = yoyo && prevIteration & 1, 1929 doesWrap = rewinding === (yoyo && iteration & 1); 1930 iteration < prevIteration && (rewinding = !rewinding); 1931 prevTime = rewinding ? 0 : dur; 1932 this._lock = 1; 1933 this.render(prevTime || (isYoyo ? 0 : _round(iteration * cycleDuration)), suppressEvents, !dur)._lock = 0; 1934 !suppressEvents && this.parent && _callback(this, "onRepeat"); 1935 this.vars.repeatRefresh && !isYoyo && (this.invalidate()._lock = 1); 1936 1937 if (prevTime && prevTime !== this._time || prevPaused !== !this._ts || this.vars.onRepeat && !this.parent && !this._act) { 1938 return this; 1939 } 1940 1941 dur = this._dur; 1942 tDur = this._tDur; 1943 1944 if (doesWrap) { 1945 this._lock = 2; 1946 prevTime = rewinding ? dur : -0.0001; 1947 this.render(prevTime, true); 1948 } 1949 1950 this._lock = 0; 1951 1952 if (!this._ts && !prevPaused) { 1953 return this; 1954 } 1955 1956 _propagateYoyoEase(this, isYoyo); 1957 } 1958 } 1959 1960 if (this._hasPause && !this._forcing && this._lock < 2) { 1961 pauseTween = _findNextPauseTween(this, _round(prevTime), _round(time)); 1962 1963 if (pauseTween) { 1964 tTime -= time - (time = pauseTween._start); 1965 } 1966 } 1967 1968 this._tTime = tTime; 1969 this._time = time; 1970 this._act = !timeScale; 1971 1972 if (!this._initted) {
vendor: 14,850 bytes, lines 1973-2493
1973 this._onUpdate = this.vars.onUpdate; 1974 this._initted = 1; 1975 this._zTime = totalTime; 1976 prevTime = 0; 1977 } 1978 1979 !prevTime && time && !suppressEvents && _callback(this, "onStart"); 1980 1981 if (time >= prevTime && totalTime >= 0) { 1982 child = this._first; 1983 1984 while (child) { 1985 next = child._next; 1986 1987 if ((child._act || time >= child._start) && child._ts && pauseTween !== child) { 1988 if (child.parent !== this) { 1989 return this.render(totalTime, suppressEvents, force); 1990 } 1991 1992 child.render(child._ts > 0 ? (time - child._start) * child._ts : (child._dirty ? child.totalDuration() : child._tDur) + (time - child._start) * child._ts, suppressEvents, force); 1993 1994 if (time !== this._time || !this._ts && !prevPaused) { 1995 pauseTween = 0; 1996 next && (tTime += this._zTime = -_tinyNum); 1997 break; 1998 } 1999 } 2000 2001 child = next; 2002 } 2003 } else { 2004 child = this._last; 2005 var adjustedTime = totalTime < 0 ? totalTime : time; 2006 2007 while (child) { 2008 next = child._prev; 2009 2010 if ((child._act || adjustedTime <= child._end) && child._ts && pauseTween !== child) { 2011 if (child.parent !== this) { 2012 return this.render(totalTime, suppressEvents, force); 2013 } 2014 2015 child.render(child._ts > 0 ? (adjustedTime - child._start) * child._ts : (child._dirty ? child.totalDuration() : child._tDur) + (adjustedTime - child._start) * child._ts, suppressEvents, force); 2016 2017 if (time !== this._time || !this._ts && !prevPaused) { 2018 pauseTween = 0; 2019 next && (tTime += this._zTime = adjustedTime ? -_tinyNum : _tinyNum); 2020 break; 2021 } 2022 } 2023 2024 child = next; 2025 } 2026 } 2027 2028 if (pauseTween && !suppressEvents) { 2029 this.pause(); 2030 pauseTween.render(time >= prevTime ? 0 : -_tinyNum)._zTime = time >= prevTime ? 1 : -1; 2031 2032 if (this._ts) { 2033 this._start = prevStart; 2034 2035 _setEnd(this); 2036 2037 return this.render(totalTime, suppressEvents, force); 2038 } 2039 } 2040 2041 this._onUpdate && !suppressEvents && _callback(this, "onUpdate", true); 2042 if (tTime === tDur && tDur >= this.totalDuration() || !tTime && prevTime) if (prevStart === this._start || Math.abs(timeScale) !== Math.abs(this._ts)) if (!this._lock) { 2043 (totalTime || !dur) && (tTime === tDur && this._ts > 0 || !tTime && this._ts < 0) && _removeFromParent(this, 1); 2044 2045 if (!suppressEvents && !(totalTime < 0 && !prevTime) && (tTime || prevTime)) { 2046 _callback(this, tTime === tDur ? "onComplete" : "onReverseComplete", true); 2047 2048 this._prom && !(tTime < tDur && this.timeScale() > 0) && this._prom(); 2049 } 2050 } 2051 } 2052 2053 return this; 2054 }; 2055 2056 _proto2.add = function add(child, position) { 2057 var _this2 = this; 2058 2059 _isNumber(position) || (position = _parsePosition(this, position)); 2060 2061 if (!(child instanceof Animation)) { 2062 if (_isArray(child)) { 2063 child.forEach(function (obj) { 2064 return _this2.add(obj, position); 2065 }); 2066 return this; 2067 } 2068 2069 if (_isString(child)) { 2070 return this.addLabel(child, position); 2071 } 2072 2073 if (_isFunction(child)) { 2074 child = Tween.delayedCall(0, child); 2075 } else { 2076 return this; 2077 } 2078 } 2079 2080 return this !== child ? _addToTimeline(this, child, position) : this; 2081 }; 2082 2083 _proto2.getChildren = function getChildren(nested, tweens, timelines, ignoreBeforeTime) { 2084 if (nested === void 0) { 2085 nested = true; 2086 } 2087 2088 if (tweens === void 0) { 2089 tweens = true; 2090 } 2091 2092 if (timelines === void 0) { 2093 timelines = true; 2094 } 2095 2096 if (ignoreBeforeTime === void 0) { 2097 ignoreBeforeTime = -_bigNum; 2098 } 2099 2100 var a = [], 2101 child = this._first; 2102 2103 while (child) { 2104 if (child._start >= ignoreBeforeTime) { 2105 if (child instanceof Tween) { 2106 tweens && a.push(child); 2107 } else { 2108 timelines && a.push(child); 2109 nested && a.push.apply(a, child.getChildren(true, tweens, timelines)); 2110 } 2111 } 2112 2113 child = child._next; 2114 } 2115 2116 return a; 2117 }; 2118 2119 _proto2.getById = function getById(id) { 2120 var animations = this.getChildren(1, 1, 1), 2121 i = animations.length; 2122 2123 while (i--) { 2124 if (animations[i].vars.id === id) { 2125 return animations[i]; 2126 } 2127 } 2128 }; 2129 2130 _proto2.remove = function remove(child) { 2131 if (_isString(child)) { 2132 return this.removeLabel(child); 2133 } 2134 2135 if (_isFunction(child)) { 2136 return this.killTweensOf(child); 2137 } 2138 2139 _removeLinkedListItem(this, child); 2140 2141 if (child === this._recent) { 2142 this._recent = this._last; 2143 } 2144 2145 return _uncache(this); 2146 }; 2147 2148 _proto2.totalTime = function totalTime(_totalTime2, suppressEvents) { 2149 if (!arguments.length) { 2150 return this._tTime; 2151 } 2152 2153 this._forcing = 1; 2154 2155 if (!this._dp && this._ts) { 2156 this._start = _round(_ticker.time - (this._ts > 0 ? _totalTime2 / this._ts : (this.totalDuration() - _totalTime2) / -this._ts)); 2157 } 2158 2159 _Animation.prototype.totalTime.call(this, _totalTime2, suppressEvents); 2160 2161 this._forcing = 0; 2162 return this; 2163 }; 2164 2165 _proto2.addLabel = function addLabel(label, position) { 2166 this.labels[label] = _parsePosition(this, position); 2167 return this; 2168 }; 2169 2170 _proto2.removeLabel = function removeLabel(label) { 2171 delete this.labels[label]; 2172 return this; 2173 }; 2174 2175 _proto2.addPause = function addPause(position, callback, params) { 2176 var t = Tween.delayedCall(0, callback || _emptyFunc, params); 2177 t.data = "isPause"; 2178 this._hasPause = 1; 2179 return _addToTimeline(this, t, _parsePosition(this, position)); 2180 }; 2181 2182 _proto2.removePause = function removePause(position) { 2183 var child = this._first; 2184 position = _parsePosition(this, position); 2185 2186 while (child) { 2187 if (child._start === position && child.data === "isPause") { 2188 _removeFromParent(child); 2189 } 2190 2191 child = child._next; 2192 } 2193 }; 2194 2195 _proto2.killTweensOf = function killTweensOf(targets, props, onlyActive) { 2196 var tweens = this.getTweensOf(targets, onlyActive), 2197 i = tweens.length; 2198 2199 while (i--) { 2200 _overwritingTween !== tweens[i] && tweens[i].kill(targets, props); 2201 } 2202 2203 return this; 2204 }; 2205 2206 _proto2.getTweensOf = function getTweensOf(targets, onlyActive) { 2207 var a = [], 2208 parsedTargets = toArray(targets), 2209 child = this._first, 2210 isGlobalTime = _isNumber(onlyActive), 2211 children; 2212 2213 while (child) { 2214 if (child instanceof Tween) { 2215 if (_arrayContainsAny(child._targets, parsedTargets) && (isGlobalTime ? (!_overwritingTween || child._initted && child._ts) && child.globalTime(0) <= onlyActive && child.globalTime(child.totalDuration()) > onlyActive : !onlyActive || child.isActive())) { 2216 a.push(child); 2217 } 2218 } else if ((children = child.getTweensOf(parsedTargets, onlyActive)).length) { 2219 a.push.apply(a, children); 2220 } 2221 2222 child = child._next; 2223 } 2224 2225 return a; 2226 }; 2227 2228 _proto2.tweenTo = function tweenTo(position, vars) { 2229 vars = vars || {}; 2230 2231 var tl = this, 2232 endTime = _parsePosition(tl, position), 2233 _vars = vars, 2234 startAt = _vars.startAt, 2235 _onStart = _vars.onStart, 2236 onStartParams = _vars.onStartParams, 2237 immediateRender = _vars.immediateRender, 2238 tween = Tween.to(tl, _setDefaults({ 2239 ease: vars.ease || "none", 2240 lazy: false, 2241 immediateRender: false, 2242 time: endTime, 2243 overwrite: "auto", 2244 duration: vars.duration || Math.abs((endTime - (startAt && "time" in startAt ? startAt.time : tl._time)) / tl.timeScale()) || _tinyNum, 2245 onStart: function onStart() { 2246 tl.pause(); 2247 var duration = vars.duration || Math.abs((endTime - tl._time) / tl.timeScale()); 2248 tween._dur !== duration && _setDuration(tween, duration, 0, 1).render(tween._time, true, true); 2249 _onStart && _onStart.apply(tween, onStartParams || []); 2250 } 2251 }, vars)); 2252 2253 return immediateRender ? tween.render(0) : tween; 2254 }; 2255 2256 _proto2.tweenFromTo = function tweenFromTo(fromPosition, toPosition, vars) { 2257 return this.tweenTo(toPosition, _setDefaults({ 2258 startAt: { 2259 time: _parsePosition(this, fromPosition) 2260 } 2261 }, vars)); 2262 }; 2263 2264 _proto2.recent = function recent() { 2265 return this._recent; 2266 }; 2267 2268 _proto2.nextLabel = function nextLabel(afterTime) { 2269 if (afterTime === void 0) { 2270 afterTime = this._time; 2271 } 2272 2273 return _getLabelInDirection(this, _parsePosition(this, afterTime)); 2274 }; 2275 2276 _proto2.previousLabel = function previousLabel(beforeTime) { 2277 if (beforeTime === void 0) { 2278 beforeTime = this._time; 2279 } 2280 2281 return _getLabelInDirection(this, _parsePosition(this, beforeTime), 1); 2282 }; 2283 2284 _proto2.currentLabel = function currentLabel(value) { 2285 return arguments.length ? this.seek(value, true) : this.previousLabel(this._time + _tinyNum); 2286 }; 2287 2288 _proto2.shiftChildren = function shiftChildren(amount, adjustLabels, ignoreBeforeTime) { 2289 if (ignoreBeforeTime === void 0) { 2290 ignoreBeforeTime = 0; 2291 } 2292 2293 var child = this._first, 2294 labels = this.labels, 2295 p; 2296 2297 while (child) { 2298 if (child._start >= ignoreBeforeTime) { 2299 child._start += amount; 2300 child._end += amount; 2301 } 2302 2303 child = child._next; 2304 } 2305 2306 if (adjustLabels) { 2307 for (p in labels) { 2308 if (labels[p] >= ignoreBeforeTime) { 2309 labels[p] += amount; 2310 } 2311 } 2312 } 2313 2314 return _uncache(this); 2315 }; 2316 2317 _proto2.invalidate = function invalidate() { 2318 var child = this._first; 2319 this._lock = 0; 2320 2321 while (child) { 2322 child.invalidate(); 2323 child = child._next; 2324 } 2325 2326 return _Animation.prototype.invalidate.call(this); 2327 }; 2328 2329 _proto2.clear = function clear(includeLabels) { 2330 if (includeLabels === void 0) { 2331 includeLabels = true; 2332 } 2333 2334 var child = this._first, 2335 next; 2336 2337 while (child) { 2338 next = child._next; 2339 this.remove(child); 2340 child = next; 2341 } 2342 2343 this._dp && (this._time = this._tTime = this._pTime = 0); 2344 includeLabels && (this.labels = {}); 2345 return _uncache(this); 2346 }; 2347 2348 _proto2.totalDuration = function totalDuration(value) { 2349 var max = 0, 2350 self = this, 2351 child = self._last, 2352 prevStart = _bigNum, 2353 prev, 2354 start, 2355 parent; 2356 2357 if (arguments.length) { 2358 return self.timeScale((self._repeat < 0 ? self.duration() : self.totalDuration()) / (self.reversed() ? -value : value)); 2359 } 2360 2361 if (self._dirty) { 2362 parent = self.parent; 2363 2364 while (child) { 2365 prev = child._prev; 2366 child._dirty && child.totalDuration(); 2367 start = child._start; 2368 2369 if (start > prevStart && self._sort && child._ts && !self._lock) { 2370 self._lock = 1; 2371 _addToTimeline(self, child, start - child._delay, 1)._lock = 0; 2372 } else { 2373 prevStart = start; 2374 } 2375 2376 if (start < 0 && child._ts) { 2377 max -= start; 2378 2379 if (!parent && !self._dp || parent && parent.smoothChildTiming) { 2380 self._start += start / self._ts; 2381 self._time -= start; 2382 self._tTime -= start; 2383 } 2384 2385 self.shiftChildren(-start, false, -1e999); 2386 prevStart = 0; 2387 } 2388 2389 child._end > max && child._ts && (max = child._end); 2390 child = prev; 2391 } 2392 2393 _setDuration(self, self === _globalTimeline && self._time > max ? self._time : max, 1, 1); 2394 2395 self._dirty = 0; 2396 } 2397 2398 return self._tDur; 2399 }; 2400 2401 Timeline.updateRoot = function updateRoot(time) { 2402 if (_globalTimeline._ts) { 2403 _lazySafeRender(_globalTimeline, _parentToChildTotalTime(time, _globalTimeline)); 2404 2405 _lastRenderedFrame = _ticker.frame; 2406 } 2407 2408 if (_ticker.frame >= _nextGCFrame) { 2409 _nextGCFrame += _config.autoSleep || 120; 2410 var child = _globalTimeline._first; 2411 if (!child || !child._ts) if (_config.autoSleep && _ticker._listeners.length < 2) { 2412 while (child && !child._ts) { 2413 child = child._next; 2414 } 2415 2416 child || _ticker.sleep(); 2417 } 2418 } 2419 }; 2420 2421 return Timeline; 2422 }(Animation); 2423 2424 _setDefaults(Timeline.prototype, { 2425 _lock: 0, 2426 _hasPause: 0, 2427 _forcing: 0 2428 }); 2429 2430 var _addComplexStringPropTween = function _addComplexStringPropTween(target, prop, start, end, setter, stringFilter, funcParam) { 2431 var pt = new PropTween(this._pt, target, prop, 0, 1, _renderComplexString, null, setter), 2432 index = 0, 2433 matchIndex = 0, 2434 result, 2435 startNums, 2436 color, 2437 endNum, 2438 chunk, 2439 startNum, 2440 hasRandom, 2441 a; 2442 pt.b = start; 2443 pt.e = end; 2444 start += ""; 2445 end += ""; 2446 2447 if (hasRandom = ~end.indexOf("random(")) { 2448 end = _replaceRandom(end); 2449 } 2450 2451 if (stringFilter) { 2452 a = [start, end]; 2453 stringFilter(a, target, prop); 2454 start = a[0]; 2455 end = a[1]; 2456 } 2457 2458 startNums = start.match(_complexStringNumExp) || []; 2459 2460 while (result = _complexStringNumExp.exec(end)) { 2461 endNum = result[0]; 2462 chunk = end.substring(index, result.index); 2463 2464 if (color) { 2465 color = (color + 1) % 5; 2466 } else if (chunk.substr(-5) === "rgba(") { 2467 color = 1; 2468 } 2469 2470 if (endNum !== startNums[matchIndex++]) { 2471 startNum = parseFloat(startNums[matchIndex - 1]) || 0; 2472 pt._pt = { 2473 _next: pt._pt, 2474 p: chunk || matchIndex === 1 ? chunk : ",", 2475 s: startNum, 2476 c: endNum.charAt(1) === "=" ? parseFloat(endNum.substr(2)) * (endNum.charAt(0) === "-" ? -1 : 1) : parseFloat(endNum) - startNum, 2477 m: color && color < 4 ? Math.round : 0 2478 }; 2479 index = _complexStringNumExp.lastIndex; 2480 } 2481 } 2482 2483 pt.c = index < end.length ? end.substring(index, end.length) : ""; 2484 pt.fp = funcParam; 2485 2486 if (_relExp.test(end) || hasRandom) { 2487 pt.e = 0; 2488 } 2489 2490 this._pt = pt; 2491 return pt; 2492 }, 2493 _addPropTween = function _addPropTween(target, prop, start, end, index, targets, modifier, stringFilter, funcParam) {
vendor: 7,950 bytes, lines 2494-2719
2494 _isFunction(end) && (end = end(index || 0, target, targets)); 2495 var currentValue = target[prop], 2496 parsedStart = start !== "get" ? start : !_isFunction(currentValue) ? currentValue : funcParam ? target[prop.indexOf("set") || !_isFunction(target["get" + prop.substr(3)]) ? prop : "get" + prop.substr(3)](funcParam) : target[prop](), 2497 setter = !_isFunction(currentValue) ? _setterPlain : funcParam ? _setterFuncWithParam : _setterFunc, 2498 pt; 2499 2500 if (_isString(end)) { 2501 if (~end.indexOf("random(")) { 2502 end = _replaceRandom(end); 2503 } 2504 2505 if (end.charAt(1) === "=") { 2506 end = parseFloat(parsedStart) + parseFloat(end.substr(2)) * (end.charAt(0) === "-" ? -1 : 1) + (getUnit(parsedStart) || 0); 2507 } 2508 } 2509 2510 if (parsedStart !== end) { 2511 if (!isNaN(parsedStart * end)) { 2512 pt = new PropTween(this._pt, target, prop, +parsedStart || 0, end - (parsedStart || 0), typeof currentValue === "boolean" ? _renderBoolean : _renderPlain, 0, setter); 2513 funcParam && (pt.fp = funcParam); 2514 modifier && pt.modifier(modifier, this, target); 2515 return this._pt = pt; 2516 } 2517 2518 !currentValue && !(prop in target) && _missingPlugin(prop, end); 2519 return _addComplexStringPropTween.call(this, target, prop, parsedStart, end, setter, stringFilter || _config.stringFilter, funcParam); 2520 } 2521 }, 2522 _processVars = function _processVars(vars, index, target, targets, tween) { 2523 _isFunction(vars) && (vars = _parseFuncOrString(vars, tween, index, target, targets)); 2524 2525 if (!_isObject(vars) || vars.style && vars.nodeType || _isArray(vars) || _isTypedArray(vars)) { 2526 return _isString(vars) ? _parseFuncOrString(vars, tween, index, target, targets) : vars; 2527 } 2528 2529 var copy = {}, 2530 p; 2531 2532 for (p in vars) { 2533 copy[p] = _parseFuncOrString(vars[p], tween, index, target, targets); 2534 } 2535 2536 return copy; 2537 }, 2538 _checkPlugin = function _checkPlugin(property, vars, tween, index, target, targets) { 2539 var plugin, pt, ptLookup, i; 2540 2541 if (_plugins[property] && (plugin = new _plugins[property]()).init(target, plugin.rawVars ? vars[property] : _processVars(vars[property], index, target, targets, tween), tween, index, targets) !== false) { 2542 tween._pt = pt = new PropTween(tween._pt, target, property, 0, 1, plugin.render, plugin, 0, plugin.priority); 2543 2544 if (tween !== _quickTween) { 2545 ptLookup = tween._ptLookup[tween._targets.indexOf(target)]; 2546 i = plugin._props.length; 2547 2548 while (i--) { 2549 ptLookup[plugin._props[i]] = pt; 2550 } 2551 } 2552 } 2553 2554 return plugin; 2555 }, 2556 _overwritingTween, 2557 _initTween = function _initTween(tween, time) { 2558 var vars = tween.vars, 2559 ease = vars.ease, 2560 startAt = vars.startAt, 2561 immediateRender = vars.immediateRender, 2562 lazy = vars.lazy, 2563 onUpdate = vars.onUpdate, 2564 onUpdateParams = vars.onUpdateParams, 2565 callbackScope = vars.callbackScope, 2566 runBackwards = vars.runBackwards, 2567 yoyoEase = vars.yoyoEase, 2568 keyframes = vars.keyframes, 2569 autoRevert = vars.autoRevert, 2570 dur = tween._dur, 2571 prevStartAt = tween._startAt, 2572 targets = tween._targets, 2573 parent = tween.parent, 2574 fullTargets = parent && parent.data === "nested" ? parent.parent._targets : targets, 2575 autoOverwrite = tween._overwrite === "auto" && !_suppressOverwrites, 2576 tl = tween.timeline, 2577 cleanVars, 2578 i, 2579 p, 2580 pt, 2581 target, 2582 hasPriority, 2583 gsData, 2584 harness, 2585 plugin, 2586 ptLookup, 2587 index, 2588 harnessVars, 2589 overwritten; 2590 tl && (!keyframes || !ease) && (ease = "none"); 2591 tween._ease = _parseEase(ease, _defaults.ease); 2592 tween._yEase = yoyoEase ? _invertEase(_parseEase(yoyoEase === true ? ease : yoyoEase, _defaults.ease)) : 0; 2593 2594 if (yoyoEase && tween._yoyo && !tween._repeat) { 2595 yoyoEase = tween._yEase; 2596 tween._yEase = tween._ease; 2597 tween._ease = yoyoEase; 2598 } 2599 2600 if (!tl) { 2601 harness = targets[0] ? _getCache(targets[0]).harness : 0; 2602 harnessVars = harness && vars[harness.prop]; 2603 cleanVars = _copyExcluding(vars, _reservedProps); 2604 prevStartAt && prevStartAt.render(-1, true).kill(); 2605 2606 if (startAt) { 2607 _removeFromParent(tween._startAt = Tween.set(targets, _setDefaults({ 2608 data: "isStart", 2609 overwrite: false, 2610 parent: parent, 2611 immediateRender: true, 2612 lazy: _isNotFalse(lazy), 2613 startAt: null, 2614 delay: 0, 2615 onUpdate: onUpdate, 2616 onUpdateParams: onUpdateParams, 2617 callbackScope: callbackScope, 2618 stagger: 0 2619 }, startAt))); 2620 2621 if (immediateRender) { 2622 if (time > 0) { 2623 autoRevert || (tween._startAt = 0); 2624 } else if (dur && !(time < 0 && prevStartAt)) { 2625 time && (tween._zTime = time); 2626 return; 2627 } 2628 } else if (autoRevert === false) { 2629 tween._startAt = 0; 2630 } 2631 } else if (runBackwards && dur) { 2632 if (prevStartAt) { 2633 !autoRevert && (tween._startAt = 0); 2634 } else { 2635 time && (immediateRender = false); 2636 p = _setDefaults({ 2637 overwrite: false, 2638 data: "isFromStart", 2639 lazy: immediateRender && _isNotFalse(lazy), 2640 immediateRender: immediateRender, 2641 stagger: 0, 2642 parent: parent 2643 }, cleanVars); 2644 harnessVars && (p[harness.prop] = harnessVars); 2645 2646 _removeFromParent(tween._startAt = Tween.set(targets, p)); 2647 2648 if (!immediateRender) { 2649 _initTween(tween._startAt, _tinyNum); 2650 } else if (!time) { 2651 return; 2652 } 2653 } 2654 } 2655 2656 tween._pt = 0; 2657 lazy = dur && _isNotFalse(lazy) || lazy && !dur; 2658 2659 for (i = 0; i < targets.length; i++) { 2660 target = targets[i]; 2661 gsData = target._gsap || _harness(targets)[i]._gsap; 2662 tween._ptLookup[i] = ptLookup = {}; 2663 _lazyLookup[gsData.id] && _lazyTweens.length && _lazyRender(); 2664 index = fullTargets === targets ? i : fullTargets.indexOf(target); 2665 2666 if (harness && (plugin = new harness()).init(target, harnessVars || cleanVars, tween, index, fullTargets) !== false) { 2667 tween._pt = pt = new PropTween(tween._pt, target, plugin.name, 0, 1, plugin.render, plugin, 0, plugin.priority); 2668 2669 plugin._props.forEach(function (name) { 2670 ptLookup[name] = pt; 2671 }); 2672 2673 plugin.priority && (hasPriority = 1); 2674 } 2675 2676 if (!harness || harnessVars) { 2677 for (p in cleanVars) { 2678 if (_plugins[p] && (plugin = _checkPlugin(p, cleanVars, tween, index, target, fullTargets))) { 2679 plugin.priority && (hasPriority = 1); 2680 } else { 2681 ptLookup[p] = pt = _addPropTween.call(tween, target, p, "get", cleanVars[p], index, fullTargets, 0, vars.stringFilter); 2682 } 2683 } 2684 } 2685 2686 tween._op && tween._op[i] && tween.kill(target, tween._op[i]); 2687 2688 if (autoOverwrite && tween._pt) { 2689 _overwritingTween = tween; 2690 2691 _globalTimeline.killTweensOf(target, ptLookup, tween.globalTime(0)); 2692 2693 overwritten = !tween.parent; 2694 _overwritingTween = 0; 2695 } 2696 2697 tween._pt && lazy && (_lazyLookup[gsData.id] = 1); 2698 } 2699 2700 hasPriority && _sortPropTweensByPriority(tween); 2701 tween._onInit && tween._onInit(tween); 2702 } 2703 2704 tween._from = !tl && !!vars.runBackwards; 2705 tween._onUpdate = onUpdate; 2706 tween._initted = (!tween._op || tween._pt) && !overwritten; 2707 }, 2708 _addAliasesToVars = function _addAliasesToVars(targets, vars) { 2709 var harness = targets[0] ? _getCache(targets[0]).harness : 0, 2710 propertyAliases = harness && harness.aliases, 2711 copy, 2712 p, 2713 i, 2714 aliases; 2715 2716 if (!propertyAliases) { 2717 return vars; 2718 } 2719
2720 copy = _merge({}, vars); 2721 2722 for (p in propertyAliases) { 2723 if (p in copy) { 2724 aliases = propertyAliases[p].split(","); 2725 i = aliases.length; 2726 2727 while (i--) { 2728 copy[aliases[i]] = copy[p]; 2729 } 2730 } 2731 } 2732 2733 return copy; 2734 }, 2735 _parseFuncOrString = function _parseFuncOrString(value, tween, i, target, targets) { 2736 return _isFunction(value) ? value.call(tween, i, target, targets) : _isString(value) && ~value.indexOf("random(") ? _replaceRandom(value) : value; 2737 }, 2738 _staggerTweenProps = _callbackNames + "repeat,repeatDelay,yoyo,repeatRefresh,yoyoEase", 2739 _staggerPropsToSkip = (_staggerTweenProps + ",id,stagger,delay,duration,paused,scrollTrigger").split(","); 2740 2741 var Tween = function (_Animation2) { 2742 _inheritsLoose(Tween, _Animation2); 2743 2744 function Tween(targets, vars, time, skipInherit) { 2745 var _this3; 2746 2747 if (typeof vars === "number") { 2748 time.duration = vars; 2749 vars = time; 2750 time = null; 2751 } 2752 2753 _this3 = _Animation2.call(this, skipInherit ? vars : _inheritDefaults(vars), time) || this; 2754 var _this3$vars = _this3.vars, 2755 duration = _this3$vars.duration, 2756 delay = _this3$vars.delay, 2757 immediateRender = _this3$vars.immediateRender, 2758 stagger = _this3$vars.stagger, 2759 overwrite = _this3$vars.overwrite, 2760 keyframes = _this3$vars.keyframes, 2761 defaults = _this3$vars.defaults, 2762 scrollTrigger = _this3$vars.scrollTrigger, 2763 yoyoEase = _this3$vars.yoyoEase, 2764 parent = _this3.parent, 2765 parsedTargets = (_isArray(targets) || _isTypedArray(targets) ? _isNumber(targets[0]) : "length" in vars) ? [targets] : toArray(targets), 2766 tl, 2767 i, 2768 copy, 2769 l, 2770 p, 2771 curTarget, 2772 staggerFunc, 2773 staggerVarsToMerge; 2774 _this3._targets = parsedTargets.length ? _harness(parsedTargets) : _warn("GSAP target " + targets + " not found. https://greensock.com", !_config.nullTargetWarn) || []; 2775 _this3._ptLookup = []; 2776 _this3._overwrite = overwrite; 2777 2778 if (keyframes || stagger || _isFuncOrString(duration) || _isFuncOrString(delay)) { 2779 vars = _this3.vars; 2780 tl = _this3.timeline = new Timeline({ 2781 data: "nested", 2782 defaults: defaults || {} 2783 }); 2784 tl.kill(); 2785 tl.parent = tl._dp = _assertThisInitialized(_this3); 2786 tl._start = 0; 2787 2788 if (keyframes) { 2789 _setDefaults(tl.vars.defaults, { 2790 ease: "none" 2791 }); 2792 2793 keyframes.forEach(function (frame) { 2794 return tl.to(parsedTargets, frame, ">"); 2795 }); 2796 } else { 2797 l = parsedTargets.length; 2798 staggerFunc = stagger ? distribute(stagger) : _emptyFunc; 2799 2800 if (_isObject(stagger)) { 2801 for (p in stagger) { 2802 if (~_staggerTweenProps.indexOf(p)) { 2803 staggerVarsToMerge || (staggerVarsToMerge = {}); 2804 staggerVarsToMerge[p] = stagger[p]; 2805 } 2806 } 2807 } 2808 2809 for (i = 0; i < l; i++) { 2810 copy = {}; 2811 2812 for (p in vars) { 2813 if (_staggerPropsToSkip.indexOf(p) < 0) { 2814 copy[p] = vars[p]; 2815 } 2816 } 2817 2818 copy.stagger = 0; 2819 yoyoEase && (copy.yoyoEase = yoyoEase); 2820 staggerVarsToMerge && _merge(copy, staggerVarsToMerge); 2821 curTarget = parsedTargets[i]; 2822 copy.duration = +_parseFuncOrString(duration, _assertThisInitialized(_this3), i, curTarget, parsedTargets); 2823 copy.delay = (+_parseFuncOrString(delay, _assertThisInitialized(_this3), i, curTarget, parsedTargets) || 0) - _this3._delay; 2824 2825 if (!stagger && l === 1 && copy.delay) { 2826 _this3._delay = delay = copy.delay; 2827 _this3._start += delay; 2828 copy.delay = 0; 2829 } 2830 2831 tl.to(curTarget, copy, staggerFunc(i, curTarget, parsedTargets)); 2832 } 2833 2834 tl.duration() ? duration = delay = 0 : _this3.timeline = 0; 2835 } 2836 2837 duration || _this3.duration(duration = tl.duration()); 2838 } else { 2839 _this3.timeline = 0; 2840 } 2841 2842 if (overwrite === true && !_suppressOverwrites) { 2843 _overwritingTween = _assertThisInitialized(_this3); 2844 2845 _globalTimeline.killTweensOf(parsedTargets); 2846 2847 _overwritingTween = 0; 2848 } 2849 2850 parent && _postAddChecks(parent, _assertThisInitialized(_this3)); 2851 2852 if (immediateRender || !duration && !keyframes && _this3._start === _round(parent._time) && _isNotFalse(immediateRender) && _hasNoPausedAncestors(_assertThisInitialized(_this3)) && parent.data !== "nested") { 2853 _this3._tTime = -_tinyNum; 2854 2855 _this3.render(Math.max(0, -delay)); 2856 } 2857 2858 scrollTrigger && _scrollTrigger(_assertThisInitialized(_this3), scrollTrigger); 2859 return _this3; 2860 } 2861 2862 var _proto3 = Tween.prototype; 2863 2864 _proto3.render = function render(totalTime, suppressEvents, force) { 2865 var prevTime = this._time, 2866 tDur = this._tDur, 2867 dur = this._dur, 2868 tTime = totalTime > tDur - _tinyNum && totalTime >= 0 ? tDur : totalTime < _tinyNum ? 0 : totalTime, 2869 time, 2870 pt, 2871 iteration, 2872 cycleDuration, 2873 prevIteration, 2874 isYoyo, 2875 ratio, 2876 timeline, 2877 yoyoEase; 2878 2879 if (!dur) { 2880 _renderZeroDurationTween(this, totalTime, suppressEvents, force); 2881 } else if (tTime !== this._tTime || !totalTime || force || !this._initted && this._tTime || this._startAt && this._zTime < 0 !== totalTime < 0) { 2882 time = tTime; 2883 timeline = this.timeline; 2884 2885 if (this._repeat) { 2886 cycleDuration = dur + this._rDelay; 2887 2888 if (this._repeat < -1 && totalTime < 0) { 2889 return this.totalTime(cycleDuration * 100 + totalTime, suppressEvents, force); 2890 } 2891 2892 time = _round(tTime % cycleDuration); 2893 2894 if (tTime === tDur) { 2895 iteration = this._repeat; 2896 time = dur; 2897 } else { 2898 iteration = ~~(tTime / cycleDuration); 2899 2900 if (iteration && iteration === tTime / cycleDuration) { 2901 time = dur; 2902 iteration--; 2903 } 2904 2905 time > dur && (time = dur); 2906 } 2907 2908 isYoyo = this._yoyo && iteration & 1; 2909 2910 if (isYoyo) { 2911 yoyoEase = this._yEase; 2912 time = dur - time; 2913 } 2914 2915 prevIteration = _animationCycle(this._tTime, cycleDuration); 2916 2917 if (time === prevTime && !force && this._initted) { 2918 return this; 2919 } 2920 2921 if (iteration !== prevIteration) { 2922 timeline && this._yEase && _propagateYoyoEase(timeline, isYoyo); 2923 2924 if (this.vars.repeatRefresh && !isYoyo && !this._lock) { 2925 this._lock = force = 1; 2926 this.render(_round(cycleDuration * iteration), true).invalidate()._lock = 0; 2927 } 2928 } 2929 } 2930 2931 if (!this._initted) { 2932 if (_attemptInitTween(this, totalTime < 0 ? totalTime : time, force, suppressEvents)) { 2933 this._tTime = 0; 2934 return this; 2935 } 2936 2937 if (dur !== this._dur) { 2938 return this.render(totalTime, suppressEvents, force); 2939 } 2940 } 2941 2942 this._tTime = tTime; 2943 this._time = time; 2944 2945 if (!this._act && this._ts) { 2946 this._act = 1; 2947 this._lazy = 0; 2948 } 2949 2950 this.ratio = ratio = (yoyoEase || this._ease)(time / dur); 2951 2952 if (this._from) { 2953 this.ratio = ratio = 1 - ratio; 2954 } 2955
2956 time && !prevTime && !suppressEvents && _callback(this, "onStart"); 2957 pt = this._pt; 2958 2959 while (pt) { 2960 pt.r(ratio, pt.d); 2961 pt = pt._next; 2962 } 2963 2964 timeline && timeline.render(totalTime < 0 ? totalTime : !time && isYoyo ? -_tinyNum : timeline._dur * ratio, suppressEvents, force) || this._startAt && (this._zTime = totalTime); 2965 2966 if (this._onUpdate && !suppressEvents) { 2967 totalTime < 0 && this._startAt && this._startAt.render(totalTime, true, force); 2968 2969 _callback(this, "onUpdate"); 2970 } 2971 2972 this._repeat && iteration !== prevIteration && this.vars.onRepeat && !suppressEvents && this.parent && _callback(this, "onRepeat"); 2973 2974 if ((tTime === this._tDur || !tTime) && this._tTime === tTime) { 2975 totalTime < 0 && this._startAt && !this._onUpdate && this._startAt.render(totalTime, true, true); 2976 (totalTime || !dur) && (tTime === this._tDur && this._ts > 0 || !tTime && this._ts < 0) && _removeFromParent(this, 1); 2977 2978 if (!suppressEvents && !(totalTime < 0 && !prevTime) && (tTime || prevTime)) { 2979 _callback(this, tTime === tDur ? "onComplete" : "onReverseComplete", true); 2980 2981 this._prom && !(tTime < tDur && this.timeScale() > 0) && this._prom(); 2982 } 2983 } 2984 } 2985 2986 return this; 2987 }; 2988 2989 _proto3.targets = function targets() { 2990 return this._targets; 2991 }; 2992
vendor: 12,946 bytes, lines 2993-3420
2993 _proto3.invalidate = function invalidate() { 2994 this._pt = this._op = this._startAt = this._onUpdate = this._lazy = this.ratio = 0; 2995 this._ptLookup = []; 2996 this.timeline && this.timeline.invalidate(); 2997 return _Animation2.prototype.invalidate.call(this); 2998 }; 2999 3000 _proto3.kill = function kill(targets, vars) { 3001 if (vars === void 0) { 3002 vars = "all"; 3003 } 3004 3005 if (!targets && (!vars || vars === "all")) { 3006 this._lazy = this._pt = 0; 3007 return this.parent ? _interrupt(this) : this; 3008 } 3009 3010 if (this.timeline) { 3011 var tDur = this.timeline.totalDuration(); 3012 this.timeline.killTweensOf(targets, vars, _overwritingTween && _overwritingTween.vars.overwrite !== true)._first || _interrupt(this); 3013 this.parent && tDur !== this.timeline.totalDuration() && _setDuration(this, this._dur * this.timeline._tDur / tDur, 0, 1); 3014 return this; 3015 } 3016 3017 var parsedTargets = this._targets, 3018 killingTargets = targets ? toArray(targets) : parsedTargets, 3019 propTweenLookup = this._ptLookup, 3020 firstPT = this._pt, 3021 overwrittenProps, 3022 curLookup, 3023 curOverwriteProps, 3024 props, 3025 p, 3026 pt, 3027 i; 3028 3029 if ((!vars || vars === "all") && _arraysMatch(parsedTargets, killingTargets)) { 3030 vars === "all" && (this._pt = 0); 3031 return _interrupt(this); 3032 } 3033 3034 overwrittenProps = this._op = this._op || []; 3035 3036 if (vars !== "all") { 3037 if (_isString(vars)) { 3038 p = {}; 3039 3040 _forEachName(vars, function (name) { 3041 return p[name] = 1; 3042 }); 3043 3044 vars = p; 3045 } 3046 3047 vars = _addAliasesToVars(parsedTargets, vars); 3048 } 3049 3050 i = parsedTargets.length; 3051 3052 while (i--) { 3053 if (~killingTargets.indexOf(parsedTargets[i])) { 3054 curLookup = propTweenLookup[i]; 3055 3056 if (vars === "all") { 3057 overwrittenProps[i] = vars; 3058 props = curLookup; 3059 curOverwriteProps = {}; 3060 } else { 3061 curOverwriteProps = overwrittenProps[i] = overwrittenProps[i] || {}; 3062 props = vars; 3063 } 3064 3065 for (p in props) { 3066 pt = curLookup && curLookup[p]; 3067 3068 if (pt) { 3069 if (!("kill" in pt.d) || pt.d.kill(p) === true) { 3070 _removeLinkedListItem(this, pt, "_pt"); 3071 } 3072 3073 delete curLookup[p]; 3074 } 3075 3076 if (curOverwriteProps !== "all") { 3077 curOverwriteProps[p] = 1; 3078 } 3079 } 3080 } 3081 } 3082 3083 this._initted && !this._pt && firstPT && _interrupt(this); 3084 return this; 3085 }; 3086 3087 Tween.to = function to(targets, vars) { 3088 return new Tween(targets, vars, arguments[2]); 3089 }; 3090 3091 Tween.from = function from(targets, vars) { 3092 return new Tween(targets, _parseVars(arguments, 1)); 3093 }; 3094 3095 Tween.delayedCall = function delayedCall(delay, callback, params, scope) { 3096 return new Tween(callback, 0, { 3097 immediateRender: false, 3098 lazy: false, 3099 overwrite: false, 3100 delay: delay, 3101 onComplete: callback, 3102 onReverseComplete: callback, 3103 onCompleteParams: params, 3104 onReverseCompleteParams: params, 3105 callbackScope: scope 3106 }); 3107 }; 3108 3109 Tween.fromTo = function fromTo(targets, fromVars, toVars) { 3110 return new Tween(targets, _parseVars(arguments, 2)); 3111 }; 3112 3113 Tween.set = function set(targets, vars) { 3114 vars.duration = 0; 3115 vars.repeatDelay || (vars.repeat = 0); 3116 return new Tween(targets, vars); 3117 }; 3118 3119 Tween.killTweensOf = function killTweensOf(targets, props, onlyActive) { 3120 return _globalTimeline.killTweensOf(targets, props, onlyActive); 3121 }; 3122 3123 return Tween; 3124 }(Animation); 3125 3126 _setDefaults(Tween.prototype, { 3127 _targets: [], 3128 _lazy: 0, 3129 _startAt: 0, 3130 _op: 0, 3131 _onInit: 0 3132 }); 3133 3134 _forEachName("staggerTo,staggerFrom,staggerFromTo", function (name) { 3135 Tween[name] = function () { 3136 var tl = new Timeline(), 3137 params = _slice.call(arguments, 0); 3138 3139 params.splice(name === "staggerFromTo" ? 5 : 4, 0, 0); 3140 return tl[name].apply(tl, params); 3141 }; 3142 }); 3143 3144 var _setterPlain = function _setterPlain(target, property, value) { 3145 return target[property] = value; 3146 }, 3147 _setterFunc = function _setterFunc(target, property, value) { 3148 return target[property](value); 3149 }, 3150 _setterFuncWithParam = function _setterFuncWithParam(target, property, value, data) { 3151 return target[property](data.fp, value); 3152 }, 3153 _setterAttribute = function _setterAttribute(target, property, value) { 3154 return target.setAttribute(property, value); 3155 }, 3156 _getSetter = function _getSetter(target, property) { 3157 return _isFunction(target[property]) ? _setterFunc : _isUndefined(target[property]) && target.setAttribute ? _setterAttribute : _setterPlain; 3158 }, 3159 _renderPlain = function _renderPlain(ratio, data) { 3160 return data.set(data.t, data.p, Math.round((data.s + data.c * ratio) * 10000) / 10000, data); 3161 }, 3162 _renderBoolean = function _renderBoolean(ratio, data) { 3163 return data.set(data.t, data.p, !!(data.s + data.c * ratio), data); 3164 }, 3165 _renderComplexString = function _renderComplexString(ratio, data) { 3166 var pt = data._pt, 3167 s = ""; 3168 3169 if (!ratio && data.b) { 3170 s = data.b; 3171 } else if (ratio === 1 && data.e) { 3172 s = data.e; 3173 } else { 3174 while (pt) { 3175 s = pt.p + (pt.m ? pt.m(pt.s + pt.c * ratio) : Math.round((pt.s + pt.c * ratio) * 10000) / 10000) + s; 3176 pt = pt._next; 3177 } 3178 3179 s += data.c; 3180 } 3181 3182 data.set(data.t, data.p, s, data); 3183 }, 3184 _renderPropTweens = function _renderPropTweens(ratio, data) { 3185 var pt = data._pt; 3186 3187 while (pt) { 3188 pt.r(ratio, pt.d); 3189 pt = pt._next; 3190 } 3191 }, 3192 _addPluginModifier = function _addPluginModifier(modifier, tween, target, property) { 3193 var pt = this._pt, 3194 next; 3195 3196 while (pt) { 3197 next = pt._next; 3198 pt.p === property && pt.modifier(modifier, tween, target); 3199 pt = next; 3200 } 3201 }, 3202 _killPropTweensOf = function _killPropTweensOf(property) { 3203 var pt = this._pt, 3204 hasNonDependentRemaining, 3205 next; 3206 3207 while (pt) { 3208 next = pt._next; 3209 3210 if (pt.p === property && !pt.op || pt.op === property) { 3211 _removeLinkedListItem(this, pt, "_pt"); 3212 } else if (!pt.dep) { 3213 hasNonDependentRemaining = 1; 3214 } 3215 3216 pt = next; 3217 } 3218 3219 return !hasNonDependentRemaining; 3220 }, 3221 _setterWithModifier = function _setterWithModifier(target, property, value, data) { 3222 data.mSet(target, property, data.m.call(data.tween, value, data.mt), data); 3223 }, 3224 _sortPropTweensByPriority = function _sortPropTweensByPriority(parent) { 3225 var pt = parent._pt, 3226 next, 3227 pt2, 3228 first, 3229 last; 3230 3231 while (pt) { 3232 next = pt._next; 3233 pt2 = first; 3234 3235 while (pt2 && pt2.pr > pt.pr) { 3236 pt2 = pt2._next; 3237 } 3238 3239 if (pt._prev = pt2 ? pt2._prev : last) { 3240 pt._prev._next = pt; 3241 } else { 3242 first = pt; 3243 } 3244 3245 if (pt._next = pt2) { 3246 pt2._prev = pt; 3247 } else { 3248 last = pt; 3249 } 3250 3251 pt = next; 3252 } 3253 3254 parent._pt = first; 3255 }; 3256 3257 var PropTween = function () { 3258 function PropTween(next, target, prop, start, change, renderer, data, setter, priority) { 3259 this.t = target; 3260 this.s = start; 3261 this.c = change; 3262 this.p = prop; 3263 this.r = renderer || _renderPlain; 3264 this.d = data || this; 3265 this.set = setter || _setterPlain; 3266 this.pr = priority || 0; 3267 this._next = next; 3268 3269 if (next) { 3270 next._prev = this; 3271 } 3272 } 3273 3274 var _proto4 = PropTween.prototype; 3275 3276 _proto4.modifier = function modifier(func, tween, target) { 3277 this.mSet = this.mSet || this.set; 3278 this.set = _setterWithModifier; 3279 this.m = func; 3280 this.mt = target; 3281 this.tween = tween; 3282 }; 3283 3284 return PropTween; 3285 }(); 3286 3287 _forEachName(_callbackNames + "parent,duration,ease,delay,overwrite,runBackwards,startAt,yoyo,immediateRender,repeat,repeatDelay,data,paused,reversed,lazy,callbackScope,stringFilter,id,yoyoEase,stagger,inherit,repeatRefresh,keyframes,autoRevert,scrollTrigger", function (name) { 3288 return _reservedProps[name] = 1; 3289 }); 3290 3291 _globals.TweenMax = _globals.TweenLite = Tween; 3292 _globals.TimelineLite = _globals.TimelineMax = Timeline; 3293 _globalTimeline = new Timeline({ 3294 sortChildren: false, 3295 defaults: _defaults, 3296 autoRemoveChildren: true, 3297 id: "root", 3298 smoothChildTiming: true 3299 }); 3300 _config.stringFilter = _colorStringFilter; 3301 var _gsap = { 3302 registerPlugin: function registerPlugin() { 3303 for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { 3304 args[_key2] = arguments[_key2]; 3305 } 3306 3307 args.forEach(function (config) { 3308 return _createPlugin(config); 3309 }); 3310 }, 3311 timeline: function timeline(vars) { 3312 return new Timeline(vars); 3313 }, 3314 getTweensOf: function getTweensOf(targets, onlyActive) { 3315 return _globalTimeline.getTweensOf(targets, onlyActive); 3316 }, 3317 getProperty: function getProperty(target, property, unit, uncache) { 3318 _isString(target) && (target = toArray(target)[0]); 3319 3320 var getter = _getCache(target || {}).get, 3321 format = unit ? _passThrough : _numericIfPossible; 3322 3323 unit === "native" && (unit = ""); 3324 return !target ? target : !property ? function (property, unit, uncache) { 3325 return format((_plugins[property] && _plugins[property].get || getter)(target, property, unit, uncache)); 3326 } : format((_plugins[property] && _plugins[property].get || getter)(target, property, unit, uncache)); 3327 }, 3328 quickSetter: function quickSetter(target, property, unit) { 3329 target = toArray(target); 3330 3331 if (target.length > 1) { 3332 var setters = target.map(function (t) { 3333 return gsap.quickSetter(t, property, unit); 3334 }), 3335 l = setters.length; 3336 return function (value) { 3337 var i = l; 3338 3339 while (i--) { 3340 setters[i](value); 3341 } 3342 }; 3343 } 3344 3345 target = target[0] || {}; 3346 3347 var Plugin = _plugins[property], 3348 cache = _getCache(target), 3349 p = cache.harness && (cache.harness.aliases || {})[property] || property, 3350 setter = Plugin ? function (value) { 3351 var p = new Plugin(); 3352 _quickTween._pt = 0; 3353 p.init(target, unit ? value + unit : value, _quickTween, 0, [target]); 3354 p.render(1, p); 3355 _quickTween._pt && _renderPropTweens(1, _quickTween); 3356 } : cache.set(target, p); 3357 3358 return Plugin ? setter : function (value) { 3359 return setter(target, p, unit ? value + unit : value, cache, 1); 3360 }; 3361 }, 3362 isTweening: function isTweening(targets) { 3363 return _globalTimeline.getTweensOf(targets, true).length > 0; 3364 }, 3365 defaults: function defaults(value) { 3366 value && value.ease && (value.ease = _parseEase(value.ease, _defaults.ease)); 3367 return _mergeDeep(_defaults, value || {}); 3368 }, 3369 config: function config(value) { 3370 return _mergeDeep(_config, value || {}); 3371 }, 3372 registerEffect: function registerEffect(_ref2) { 3373 var name = _ref2.name, 3374 effect = _ref2.effect, 3375 plugins = _ref2.plugins, 3376 defaults = _ref2.defaults, 3377 extendTimeline = _ref2.extendTimeline; 3378 (plugins || "").split(",").forEach(function (pluginName) { 3379 return pluginName && !_plugins[pluginName] && !_globals[pluginName] && _warn(name + " effect requires " + pluginName + " plugin."); 3380 }); 3381 3382 _effects[name] = function (targets, vars, tl) { 3383 return effect(toArray(targets), _setDefaults(vars || {}, defaults), tl); 3384 }; 3385 3386 if (extendTimeline) { 3387 Timeline.prototype[name] = function (targets, vars, position) { 3388 return this.add(_effects[name](targets, _isObject(vars) ? vars : (position = vars) && {}, this), position); 3389 }; 3390 } 3391 }, 3392 registerEase: function registerEase(name, ease) { 3393 _easeMap[name] = _parseEase(ease); 3394 }, 3395 parseEase: function parseEase(ease, defaultEase) { 3396 return arguments.length ? _parseEase(ease, defaultEase) : _easeMap; 3397 }, 3398 getById: function getById(id) { 3399 return _globalTimeline.getById(id); 3400 }, 3401 exportRoot: function exportRoot(vars, includeDelayedCalls) { 3402 if (vars === void 0) { 3403 vars = {}; 3404 } 3405 3406 var tl = new Timeline(vars), 3407 child, 3408 next; 3409 tl.smoothChildTiming = _isNotFalse(vars.smoothChildTiming); 3410 3411 _globalTimeline.remove(tl); 3412 3413 tl._dp = 0; 3414 tl._time = tl._tTime = _globalTimeline._time; 3415 child = _globalTimeline._first; 3416 3417 while (child) { 3418 next = child._next; 3419 3420 if (includeDelayedCalls || !(!child._dur && child instanceof Tween && child.vars.onComplete === child._targets[0])) {
3421 _addToTimeline(tl, child, child._start - child._delay); 3422 } 3423 3424 child = next; 3425 } 3426 3427 _addToTimeline(_globalTimeline, tl, 0); 3428 3429 return tl; 3430 }, 3431 utils: { 3432 wrap: wrap, 3433 wrapYoyo: wrapYoyo, 3434 distribute: distribute, 3435 random: random, 3436 snap: snap, 3437 normalize: normalize, 3438 getUnit: getUnit, 3439 clamp: clamp, 3440 splitColor: splitColor, 3441 toArray: toArray, 3442 mapRange: mapRange, 3443 pipe: pipe, 3444 unitize: unitize, 3445 interpolate: interpolate, 3446 shuffle: shuffle 3447 }, 3448 install: _install, 3449 effects: _effects, 3450 ticker: _ticker, 3451 updateRoot: Timeline.updateRoot, 3452 plugins: _plugins, 3453 globalTimeline: _globalTimeline, 3454 core: { 3455 PropTween: PropTween, 3456 globals: _addGlobal, 3457 Tween: Tween, 3458 Timeline: Timeline, 3459 Animation: Animation, 3460 getCache: _getCache, 3461 _removeLinkedListItem: _removeLinkedListItem, 3462 suppressOverwrites: function suppressOverwrites(value) { 3463 return _suppressOverwrites = value; 3464 } 3465 } 3466 }; 3467 3468 _forEachName("to,from,fromTo,delayedCall,set,killTweensOf", function (name) { 3469 return _gsap[name] = Tween[name]; 3470 }); 3471 3472 _ticker.add(Timeline.updateRoot); 3473 3474 _quickTween = _gsap.to({}, { 3475 duration: 0 3476 }); 3477 3478 var _getPluginPropTween = function _getPluginPropTween(plugin, prop
vendor: 18,114 bytes, lines 3478-4050
3478) { 3479 var pt = plugin._pt; 3480 3481 while (pt && pt.p !== prop && pt.op !== prop && pt.fp !== prop) { 3482 pt = pt._next; 3483 } 3484 3485 return pt; 3486 }, 3487 _addModifiers = function _addModifiers(tween, modifiers) { 3488 var targets = tween._targets, 3489 p, 3490 i, 3491 pt; 3492 3493 for (p in modifiers) { 3494 i = targets.length; 3495 3496 while (i--) { 3497 pt = tween._ptLookup[i][p]; 3498 3499 if (pt && (pt = pt.d)) { 3500 if (pt._pt) { 3501 pt = _getPluginPropTween(pt, p); 3502 } 3503 3504 pt && pt.modifier && pt.modifier(modifiers[p], tween, targets[i], p); 3505 } 3506 } 3507 } 3508 }, 3509 _buildModifierPlugin = function _buildModifierPlugin(name, modifier) { 3510 return { 3511 name: name, 3512 rawVars: 1, 3513 init: function init(target, vars, tween) { 3514 tween._onInit = function (tween) { 3515 var temp, p; 3516 3517 if (_isString(vars)) { 3518 temp = {}; 3519 3520 _forEachName(vars, function (name) { 3521 return temp[name] = 1; 3522 }); 3523 3524 vars = temp; 3525 } 3526 3527 if (modifier) { 3528 temp = {}; 3529 3530 for (p in vars) { 3531 temp[p] = modifier(vars[p]); 3532 } 3533 3534 vars = temp; 3535 } 3536 3537 _addModifiers(tween, vars); 3538 }; 3539 } 3540 }; 3541 }; 3542 3543 var gsap = _gsap.registerPlugin({ 3544 name: "attr", 3545 init: function init(target, vars, tween, index, targets) { 3546 var p, pt; 3547 3548 for (p in vars) { 3549 pt = this.add(target, "setAttribute", (target.getAttribute(p) || 0) + "", vars[p], index, targets, 0, 0, p); 3550 pt && (pt.op = p); 3551 3552 this._props.push(p); 3553 } 3554 } 3555 }, { 3556 name: "endArray", 3557 init: function init(target, value) { 3558 var i = value.length; 3559 3560 while (i--) { 3561 this.add(target, i, target[i] || 0, value[i]); 3562 } 3563 } 3564 }, _buildModifierPlugin("roundProps", _roundModifier), _buildModifierPlugin("modifiers"), _buildModifierPlugin("snap", snap)) || _gsap; 3565 Tween.version = Timeline.version = gsap.version = "3.6.1"; 3566 _coreReady = 1; 3567 3568 if (_windowExists()) { 3569 _wake(); 3570 } 3571 3572 var Power0 = _easeMap.Power0, 3573 Power1 = _easeMap.Power1, 3574 Power2 = _easeMap.Power2, 3575 Power3 = _easeMap.Power3, 3576 Power4 = _easeMap.Power4, 3577 Linear = _easeMap.Linear, 3578 Quad = _easeMap.Quad, 3579 Cubic = _easeMap.Cubic, 3580 Quart = _easeMap.Quart, 3581 Quint = _easeMap.Quint, 3582 Strong = _easeMap.Strong, 3583 Elastic = _easeMap.Elastic, 3584 Back = _easeMap.Back, 3585 SteppedEase = _easeMap.SteppedEase, 3586 Bounce = _easeMap.Bounce, 3587 Sine = _easeMap.Sine, 3588 Expo = _easeMap.Expo, 3589 Circ = _easeMap.Circ; 3590 3591 var _win$1, 3592 _doc$1, 3593 _docElement, 3594 _pluginInitted, 3595 _tempDiv, 3596 _tempDivStyler, 3597 _recentSetterPlugin, 3598 _windowExists$1 = function _windowExists() { 3599 return typeof window !== "undefined"; 3600 }, 3601 _transformProps = {}, 3602 _RAD2DEG = 180 / Math.PI, 3603 _DEG2RAD = Math.PI / 180, 3604 _atan2 = Math.atan2, 3605 _bigNum$1 = 1e8, 3606 _capsExp = /([A-Z])/g, 3607 _horizontalExp = /(?:left|right|width|margin|padding|x)/i, 3608 _complexExp = /[\s,\(]\S/, 3609 _propertyAliases = { 3610 autoAlpha: "opacity,visibility", 3611 scale: "scaleX,scaleY", 3612 alpha: "opacity" 3613 }, 3614 _renderCSSProp = function _renderCSSProp(ratio, data) { 3615 return data.set(data.t, data.p, Math.round((data.s + data.c * ratio) * 10000) / 10000 + data.u, data); 3616 }, 3617 _renderPropWithEnd = function _renderPropWithEnd(ratio, data) { 3618 return data.set(data.t, data.p, ratio === 1 ? data.e : Math.round((data.s + data.c * ratio) * 10000) / 10000 + data.u, data); 3619 }, 3620 _renderCSSPropWithBeginning = function _renderCSSPropWithBeginning(ratio, data) { 3621 return data.set(data.t, data.p, ratio ? Math.round((data.s + data.c * ratio) * 10000) / 10000 + data.u : data.b, data); 3622 }, 3623 _renderRoundedCSSProp = function _renderRoundedCSSProp(ratio, data) { 3624 var value = data.s + data.c * ratio; 3625 data.set(data.t, data.p, ~~(value + (value < 0 ? -.5 : .5)) + data.u, data); 3626 }, 3627 _renderNonTweeningValue = function _renderNonTweeningValue(ratio, data) { 3628 return data.set(data.t, data.p, ratio ? data.e : data.b, data); 3629 }, 3630 _renderNonTweeningValueOnlyAtEnd = function _renderNonTweeningValueOnlyAtEnd(ratio, data) { 3631 return data.set(data.t, data.p, ratio !== 1 ? data.b : data.e, data); 3632 }, 3633 _setterCSSStyle = function _setterCSSStyle(target, property, value) { 3634 return target.style[property] = value; 3635 }, 3636 _setterCSSProp = function _setterCSSProp(target, property, value) { 3637 return target.style.setProperty(property, value); 3638 }, 3639 _setterTransform = function _setterTransform(target, property, value) { 3640 return target._gsap[property] = value; 3641 }, 3642 _setterScale = function _setterScale(target, property, value) { 3643 return target._gsap.scaleX = target._gsap.scaleY = value; 3644 }, 3645 _setterScaleWithRender = function _setterScaleWithRender(target, property, value, data, ratio) { 3646 var cache = target._gsap; 3647 cache.scaleX = cache.scaleY = value; 3648 cache.renderTransform(ratio, cache); 3649 }, 3650 _setterTransformWithRender = function _setterTransformWithRender(target, property, value, data, ratio) { 3651 var cache = target._gsap; 3652 cache[property] = value; 3653 cache.renderTransform(ratio, cache); 3654 }, 3655 _transformProp = "transform", 3656 _transformOriginProp = _transformProp + "Origin", 3657 _supports3D, 3658 _createElement = function _createElement(type, ns) { 3659 var e = _doc$1.createElementNS ? _doc$1.createElementNS((ns || "http://www.w3.org/1999/xhtml").replace(/^https/, "http"), type) : _doc$1.createElement(type); 3660 return e.style ? e : _doc$1.createElement(type); 3661 }, 3662 _getComputedProperty = function _getComputedProperty(target, property, skipPrefixFallback) { 3663 var cs = getComputedStyle(target); 3664 return cs[property] || cs.getPropertyValue(property.replace(_capsExp, "-$1").toLowerCase()) || cs.getPropertyValue(property) || !skipPrefixFallback && _getComputedProperty(target, _checkPropPrefix(property) || property, 1) || ""; 3665 }, 3666 _prefixes = "O,Moz,ms,Ms,Webkit".split(","), 3667 _checkPropPrefix = function _checkPropPrefix(property, element, preferPrefix) { 3668 var e = element || _tempDiv, 3669 s = e.style, 3670 i = 5; 3671 3672 if (property in s && !preferPrefix) { 3673 return property; 3674 } 3675 3676 property = property.charAt(0).toUpperCase() + property.substr(1); 3677 3678 while (i-- && !(_prefixes[i] + property in s)) {} 3679 3680 return i < 0 ? null : (i === 3 ? "ms" : i >= 0 ? _prefixes[i] : "") + property; 3681 }, 3682 _initCore = function _initCore() { 3683 if (_windowExists$1() && window.document) { 3684 _win$1 = window; 3685 _doc$1 = _win$1.document; 3686 _docElement = _doc$1.documentElement; 3687 _tempDiv = _createElement("div") || { 3688 style: {} 3689 }; 3690 _tempDivStyler = _createElement("div"); 3691 _transformProp = _checkPropPrefix(_transformProp); 3692 _transformOriginProp = _transformProp + "Origin"; 3693 _tempDiv.style.cssText = "border-width:0;line-height:0;position:absolute;padding:0"; 3694 _supports3D = !!_checkPropPrefix("perspective"); 3695 _pluginInitted = 1; 3696 } 3697 }, 3698 _getBBoxHack = function _getBBoxHack(swapIfPossible) { 3699 var svg = _createElement("svg", this.ownerSVGElement && this.ownerSVGElement.getAttribute("xmlns") || "http://www.w3.org/2000/svg"), 3700 oldParent = this.parentNode, 3701 oldSibling = this.nextSibling, 3702 oldCSS = this.style.cssText, 3703 bbox; 3704 3705 _docElement.appendChild(svg); 3706 3707 svg.appendChild(this); 3708 this.style.display = "block"; 3709 3710 if (swapIfPossible) { 3711 try { 3712 bbox = this.getBBox(); 3713 this._gsapBBox = this.getBBox; 3714 this.getBBox = _getBBoxHack; 3715 } catch (e) {} 3716 } else if (this._gsapBBox) { 3717 bbox = this._gsapBBox(); 3718 } 3719 3720 if (oldParent) { 3721 if (oldSibling) { 3722 oldParent.insertBefore(this, oldSibling); 3723 } else { 3724 oldParent.appendChild(this); 3725 } 3726 } 3727 3728 _docElement.removeChild(svg); 3729 3730 this.style.cssText = oldCSS; 3731 return bbox; 3732 }, 3733 _getAttributeFallbacks = function _getAttributeFallbacks(target, attributesArray) { 3734 var i = attributesArray.length; 3735 3736 while (i--) { 3737 if (target.hasAttribute(attributesArray[i])) { 3738 return target.getAttribute(attributesArray[i]); 3739 } 3740 } 3741 }, 3742 _getBBox = function _getBBox(target) { 3743 var bounds; 3744 3745 try { 3746 bounds = target.getBBox(); 3747 } catch (error) { 3748 bounds = _getBBoxHack.call(target, true); 3749 } 3750 3751 bounds && (bounds.width || bounds.height) || target.getBBox === _getBBoxHack || (bounds = _getBBoxHack.call(target, true)); 3752 return bounds && !bounds.width && !bounds.x && !bounds.y ? { 3753 x: +_getAttributeFallbacks(target, ["x", "cx", "x1"]) || 0, 3754 y: +_getAttributeFallbacks(target, ["y", "cy", "y1"]) || 0, 3755 width: 0, 3756 height: 0 3757 } : bounds; 3758 }, 3759 _isSVG = function _isSVG(e) { 3760 return !!(e.getCTM && (!e.parentNode || e.ownerSVGElement) && _getBBox(e)); 3761 }, 3762 _removeProperty = function _removeProperty(target, property) { 3763 if (property) { 3764 var style = target.style; 3765 3766 if (property in _transformProps && property !== _transformOriginProp) { 3767 property = _transformProp; 3768 } 3769 3770 if (style.removeProperty) { 3771 if (property.substr(0, 2) === "ms" || property.substr(0, 6) === "webkit") { 3772 property = "-" + property; 3773 } 3774 3775 style.removeProperty(property.replace(_capsExp, "-$1").toLowerCase()); 3776 } else { 3777 style.removeAttribute(property); 3778 } 3779 } 3780 }, 3781 _addNonTweeningPT = function _addNonTweeningPT(plugin, target, property, beginning, end, onlySetAtEnd) { 3782 var pt = new PropTween(plugin._pt, target, property, 0, 1, onlySetAtEnd ? _renderNonTweeningValueOnlyAtEnd : _renderNonTweeningValue); 3783 plugin._pt = pt; 3784 pt.b = beginning; 3785 pt.e = end; 3786 3787 plugin._props.push(property); 3788 3789 return pt; 3790 }, 3791 _nonConvertibleUnits = { 3792 deg: 1, 3793 rad: 1, 3794 turn: 1 3795 }, 3796 _convertToUnit = function _convertToUnit(target, property, value, unit) { 3797 var curValue = parseFloat(value) || 0, 3798 curUnit = (value + "").trim().substr((curValue + "").length) || "px", 3799 style = _tempDiv.style, 3800 horizontal = _horizontalExp.test(property), 3801 isRootSVG = target.tagName.toLowerCase() === "svg", 3802 measureProperty = (isRootSVG ? "client" : "offset") + (horizontal ? "Width" : "Height"), 3803 amount = 100, 3804 toPixels = unit === "px", 3805 toPercent = unit === "%", 3806 px, 3807 parent, 3808 cache, 3809 isSVG; 3810 3811 if (unit === curUnit || !curValue || _nonConvertibleUnits[unit] || _nonConvertibleUnits[curUnit]) { 3812 return curValue; 3813 } 3814 3815 curUnit !== "px" && !toPixels && (curValue = _convertToUnit(target, property, value, "px")); 3816 isSVG = target.getCTM && _isSVG(target); 3817 3818 if ((toPercent || curUnit === "%") && (_transformProps[property] || ~property.indexOf("adius"))) { 3819 px = isSVG ? target.getBBox()[horizontal ? "width" : "height"] : target[measureProperty]; 3820 return _round(toPercent ? curValue / px * amount : curValue / 100 * px); 3821 } 3822 3823 style[horizontal ? "width" : "height"] = amount + (toPixels ? curUnit : unit); 3824 parent = ~property.indexOf("adius") || unit === "em" && target.appendChild && !isRootSVG ? target : target.parentNode; 3825 3826 if (isSVG) { 3827 parent = (target.ownerSVGElement || {}).parentNode; 3828 } 3829 3830 if (!parent || parent === _doc$1 || !parent.appendChild) { 3831 parent = _doc$1.body; 3832 } 3833 3834 cache = parent._gsap; 3835 3836 if (cache && toPercent && cache.width && horizontal && cache.time === _ticker.time) { 3837 return _round(curValue / cache.width * amount); 3838 } else { 3839 (toPercent || curUnit === "%") && (style.position = _getComputedProperty(target, "position")); 3840 parent === target && (style.position = "static"); 3841 parent.appendChild(_tempDiv); 3842 px = _tempDiv[measureProperty]; 3843 parent.removeChild(_tempDiv); 3844 style.position = "absolute"; 3845 3846 if (horizontal && toPercent) { 3847 cache = _getCache(parent); 3848 cache.time = _ticker.time; 3849 cache.width = parent[measureProperty]; 3850 } 3851 } 3852 3853 return _round(toPixels ? px * curValue / amount : px && curValue ? amount / px * curValue : 0); 3854 }, 3855 _get = function _get(target, property, unit, uncache) { 3856 var value; 3857 _pluginInitted || _initCore(); 3858 3859 if (property in _propertyAliases && property !== "transform") { 3860 property = _propertyAliases[property]; 3861 3862 if (~property.indexOf(",")) { 3863 property = property.split(",")[0]; 3864 } 3865 } 3866 3867 if (_transformProps[property] && property !== "transform") { 3868 value = _parseTransform(target, uncache); 3869 value = property !== "transformOrigin" ? value[property] : _firstTwoOnly(_getComputedProperty(target, _transformOriginProp)) + " " + value.zOrigin + "px"; 3870 } else { 3871 value = target.style[property]; 3872 3873 if (!value || value === "auto" || uncache || ~(value + "").indexOf("calc(")) { 3874 value = _specialProps[property] && _specialProps[property](target, property, unit) || _getComputedProperty(target, property) || _getProperty(target, property) || (property === "opacity" ? 1 : 0); 3875 } 3876 } 3877 3878 return unit && !~(value + "").trim().indexOf(" ") ? _convertToUnit(target, property, value, unit) + unit : value; 3879 }, 3880 _tweenComplexCSSString = function _tweenComplexCSSString(target, prop, start, end) { 3881 if (!start || start === "none") { 3882 var p = _checkPropPrefix(prop, target, 1), 3883 s = p && _getComputedProperty(target, p, 1); 3884 3885 if (s && s !== start) { 3886 prop = p; 3887 start = s; 3888 } else if (prop === "borderColor") { 3889 start = _getComputedProperty(target, "borderTopColor"); 3890 } 3891 } 3892 3893 var pt = new PropTween(this._pt, target.style, prop, 0, 1, _renderComplexString), 3894 index = 0, 3895 matchIndex = 0, 3896 a, 3897 result, 3898 startValues, 3899 startNum, 3900 color, 3901 startValue, 3902 endValue, 3903 endNum, 3904 chunk, 3905 endUnit, 3906 startUnit, 3907 relative, 3908 endValues; 3909 pt.b = start; 3910 pt.e = end; 3911 start += ""; 3912 end += ""; 3913 3914 if (end === "auto") { 3915 target.style[prop] = end; 3916 end = _getComputedProperty(target, prop) || end; 3917 target.style[prop] = start; 3918 } 3919 3920 a = [start, end]; 3921 3922 _colorStringFilter(a); 3923 3924 start = a[0]; 3925 end = a[1]; 3926 startValues = start.match(_numWithUnitExp) || []; 3927 endValues = end.match(_numWithUnitExp) || []; 3928 3929 if (endValues.length) { 3930 while (result = _numWithUnitExp.exec(end)) { 3931 endValue = result[0]; 3932 chunk = end.substring(index, result.index); 3933 3934 if (color) { 3935 color = (color + 1) % 5; 3936 } else if (chunk.substr(-5) === "rgba(" || chunk.substr(-5) === "hsla(") { 3937 color = 1; 3938 } 3939 3940 if (endValue !== (startValue = startValues[matchIndex++] || "")) { 3941 startNum = parseFloat(startValue) || 0; 3942 startUnit = startValue.substr((startNum + "").length); 3943 relative = endValue.charAt(1) === "=" ? +(endValue.charAt(0) + "1") : 0; 3944 3945 if (relative) { 3946 endValue = endValue.substr(2); 3947 } 3948 3949 endNum = parseFloat(endValue); 3950 endUnit = endValue.substr((endNum + "").length); 3951 index = _numWithUnitExp.lastIndex - endUnit.length; 3952 3953 if (!endUnit) { 3954 endUnit = endUnit || _config.units[prop] || startUnit; 3955 3956 if (index === end.length) { 3957 end += endUnit; 3958 pt.e += endUnit; 3959 } 3960 } 3961 3962 if (startUnit !== endUnit) { 3963 startNum = _convertToUnit(target, prop, startValue, endUnit) || 0; 3964 } 3965 3966 pt._pt = { 3967 _next: pt._pt, 3968 p: chunk || matchIndex === 1 ? chunk : ",", 3969 s: startNum, 3970 c: relative ? relative * endNum : endNum - startNum, 3971 m: color && color < 4 || prop === "zIndex" ? Math.round : 0 3972 }; 3973 } 3974 } 3975 3976 pt.c = index < end.length ? end.substring(index, end.length) : ""; 3977 } else { 3978 pt.r = prop === "display" && end === "none" ? _renderNonTweeningValueOnlyAtEnd : _renderNonTweeningValue; 3979 } 3980 3981 _relExp.test(end) && (pt.e = 0); 3982 this._pt = pt; 3983 return pt; 3984 }, 3985 _keywordToPercent = { 3986 top: "0%", 3987 bottom: "100%", 3988 left: "0%", 3989 right: "100%", 3990 center: "50%" 3991 }, 3992 _convertKeywordsToPercentages = function _convertKeywordsToPercentages(value) { 3993 var split = value.split(" "), 3994 x = split[0], 3995 y = split[1] || "50%"; 3996 3997 if (x === "top" || x === "bottom" || y === "left" || y === "right") { 3998 value = x; 3999 x = y; 4000 y = value; 4001 } 4002 4003 split[0] = _keywordToPercent[x] || x; 4004 split[1] = _keywordToPercent[y] || y; 4005 return split.join(" "); 4006 }, 4007 _renderClearProps = function _renderClearProps(ratio, data) { 4008 if (data.tween && data.tween._time === data.tween._dur) { 4009 var target = data.t, 4010 style = target.style, 4011 props = data.u, 4012 cache = target._gsap, 4013 prop, 4014 clearTransforms, 4015 i; 4016 4017 if (props === "all" || props === true) { 4018 style.cssText = ""; 4019 clearTransforms = 1; 4020 } else { 4021 props = props.split(","); 4022 i = props.length; 4023 4024 while (--i > -1) { 4025 prop = props[i]; 4026 4027 if (_transformProps[prop]) { 4028 clearTransforms = 1; 4029 prop = prop === "transformOrigin" ? _transformOriginProp : _transformProp; 4030 } 4031 4032 _removeProperty(target, prop); 4033 } 4034 } 4035 4036 if (clearTransforms) { 4037 _removeProperty(target, _transformProp); 4038 4039 if (cache) { 4040 cache.svg && target.removeAttribute("transform"); 4041 4042 _parseTransform(target, 1); 4043 4044 cache.uncache = 1; 4045 } 4046 } 4047 } 4048 }, 4049 _specialProps = { 4050 clearProps: function clearProps(plugin, target, property, endValue, tween) {
vendor: 3,001 bytes, lines 4051-4131
4051 if (tween.data !== "isFromStart") { 4052 var pt = plugin._pt = new PropTween(plugin._pt, target, property, 0, 0, _renderClearProps); 4053 pt.u = endValue; 4054 pt.pr = -10; 4055 pt.tween = tween; 4056 4057 plugin._props.push(property); 4058 4059 return 1; 4060 } 4061 } 4062 }, 4063 _identity2DMatrix = [1, 0, 0, 1, 0, 0], 4064 _rotationalProperties = {}, 4065 _isNullTransform = function _isNullTransform(value) { 4066 return value === "matrix(1, 0, 0, 1, 0, 0)" || value === "none" || !value; 4067 }, 4068 _getComputedTransformMatrixAsArray = function _getComputedTransformMatrixAsArray(target) { 4069 var matrixString = _getComputedProperty(target, _transformProp); 4070 4071 return _isNullTransform(matrixString) ? _identity2DMatrix : matrixString.substr(7).match(_numExp).map(_round); 4072 }, 4073 _getMatrix = function _getMatrix(target, force2D) { 4074 var cache = target._gsap || _getCache(target), 4075 style = target.style, 4076 matrix = _getComputedTransformMatrixAsArray(target), 4077 parent, 4078 nextSibling, 4079 temp, 4080 addedToDOM; 4081 4082 if (cache.svg && target.getAttribute("transform")) { 4083 temp = target.transform.baseVal.consolidate().matrix; 4084 matrix = [temp.a, temp.b, temp.c, temp.d, temp.e, temp.f]; 4085 return matrix.join(",") === "1,0,0,1,0,0" ? _identity2DMatrix : matrix; 4086 } else if (matrix === _identity2DMatrix && !target.offsetParent && target !== _docElement && !cache.svg) { 4087 temp = style.display; 4088 style.display = "block"; 4089 parent = target.parentNode; 4090 4091 if (!parent || !target.offsetParent) { 4092 addedToDOM = 1; 4093 nextSibling = target.nextSibling; 4094 4095 _docElement.appendChild(target); 4096 } 4097 4098 matrix = _getComputedTransformMatrixAsArray(target); 4099 temp ? style.display = temp : _removeProperty(target, "display"); 4100 4101 if (addedToDOM) { 4102 nextSibling ? parent.insertBefore(target, nextSibling) : parent ? parent.appendChild(target) : _docElement.removeChild(target); 4103 } 4104 } 4105 4106 return force2D && matrix.length > 6 ? [matrix[0], matrix[1], matrix[4], matrix[5], matrix[12], matrix[13]] : matrix; 4107 }, 4108 _applySVGOrigin = function _applySVGOrigin(target, origin, originIsAbsolute, smooth, matrixArray, pluginToAddPropTweensTo) { 4109 var cache = target._gsap, 4110 matrix = matrixArray || _getMatrix(target, true), 4111 xOriginOld = cache.xOrigin || 0, 4112 yOriginOld = cache.yOrigin || 0, 4113 xOffsetOld = cache.xOffset || 0, 4114 yOffsetOld = cache.yOffset || 0, 4115 a = matrix[0], 4116 b = matrix[1], 4117 c = matrix[2], 4118 d = matrix[3], 4119 tx = matrix[4], 4120 ty = matrix[5], 4121 originSplit = origin.split(" "), 4122 xOrigin = parseFloat(originSplit[0]) || 0, 4123 yOrigin = parseFloat(originSplit[1]) || 0, 4124 bounds, 4125 determinant, 4126 x, 4127 y; 4128 4129 if (!originIsAbsolute) { 4130 bounds = _getBBox(target); 4131 xOrigin = bounds.x + (~originSplit[0].indexOf("%") ? xOrigin / 100 * boun
vendor: 6,518 bytes, lines 4131-4339
4131ds.width : xOrigin); 4132 yOrigin = bounds.y + (~(originSplit[1] || originSplit[0]).indexOf("%") ? yOrigin / 100 * bounds.height : yOrigin); 4133 } else if (matrix !== _identity2DMatrix && (determinant = a * d - b * c)) { 4134 x = xOrigin * (d / determinant) + yOrigin * (-c / determinant) + (c * ty - d * tx) / determinant; 4135 y = xOrigin * (-b / determinant) + yOrigin * (a / determinant) - (a * ty - b * tx) / determinant; 4136 xOrigin = x; 4137 yOrigin = y; 4138 } 4139 4140 if (smooth || smooth !== false && cache.smooth) { 4141 tx = xOrigin - xOriginOld; 4142 ty = yOrigin - yOriginOld; 4143 cache.xOffset = xOffsetOld + (tx * a + ty * c) - tx; 4144 cache.yOffset = yOffsetOld + (tx * b + ty * d) - ty; 4145 } else { 4146 cache.xOffset = cache.yOffset = 0; 4147 } 4148 4149 cache.xOrigin = xOrigin; 4150 cache.yOrigin = yOrigin; 4151 cache.smooth = !!smooth; 4152 cache.origin = origin; 4153 cache.originIsAbsolute = !!originIsAbsolute; 4154 target.style[_transformOriginProp] = "0px 0px"; 4155 4156 if (pluginToAddPropTweensTo) { 4157 _addNonTweeningPT(pluginToAddPropTweensTo, cache, "xOrigin", xOriginOld, xOrigin); 4158 4159 _addNonTweeningPT(pluginToAddPropTweensTo, cache, "yOrigin", yOriginOld, yOrigin); 4160 4161 _addNonTweeningPT(pluginToAddPropTweensTo, cache, "xOffset", xOffsetOld, cache.xOffset); 4162 4163 _addNonTweeningPT(pluginToAddPropTweensTo, cache, "yOffset", yOffsetOld, cache.yOffset); 4164 } 4165 4166 target.setAttribute("data-svg-origin", xOrigin + " " + yOrigin); 4167 }, 4168 _parseTransform = function _parseTransform(target, uncache) { 4169 var cache = target._gsap || new GSCache(target); 4170 4171 if ("x" in cache && !uncache && !cache.uncache) { 4172 return cache; 4173 } 4174 4175 var style = target.style, 4176 invertedScaleX = cache.scaleX < 0, 4177 px = "px", 4178 deg = "deg", 4179 origin = _getComputedProperty(target, _transformOriginProp) || "0", 4180 x, 4181 y, 4182 z, 4183 scaleX, 4184 scaleY, 4185 rotation, 4186 rotationX, 4187 rotationY, 4188 skewX, 4189 skewY, 4190 perspective, 4191 xOrigin, 4192 yOrigin, 4193 matrix, 4194 angle, 4195 cos, 4196 sin, 4197 a, 4198 b, 4199 c, 4200 d, 4201 a12, 4202 a22, 4203 t1, 4204 t2, 4205 t3, 4206 a13, 4207 a23, 4208 a33, 4209 a42, 4210 a43, 4211 a32; 4212 x = y = z = rotation = rotationX = rotationY = skewX = skewY = perspective = 0; 4213 scaleX = scaleY = 1; 4214 cache.svg = !!(target.getCTM && _isSVG(target)); 4215 matrix = _getMatrix(target, cache.svg); 4216 4217 if (cache.svg) { 4218 t1 = !cache.uncache && !uncache && target.getAttribute("data-svg-origin"); 4219 4220 _applySVGOrigin(target, t1 || origin, !!t1 || cache.originIsAbsolute, cache.smooth !== false, matrix); 4221 } 4222 4223 xOrigin = cache.xOrigin || 0; 4224 yOrigin = cache.yOrigin || 0; 4225 4226 if (matrix !== _identity2DMatrix) { 4227 a = matrix[0]; 4228 b = matrix[1]; 4229 c = matrix[2]; 4230 d = matrix[3]; 4231 x = a12 = matrix[4]; 4232 y = a22 = matrix[5]; 4233 4234 if (matrix.length === 6) { 4235 scaleX = Math.sqrt(a * a + b * b); 4236 scaleY = Math.sqrt(d * d + c * c); 4237 rotation = a || b ? _atan2(b, a) * _RAD2DEG : 0; 4238 skewX = c || d ? _atan2(c, d) * _RAD2DEG + rotation : 0; 4239 skewX && (scaleY *= Math.abs(Math.cos(skewX * _DEG2RAD))); 4240 4241 if (cache.svg) { 4242 x -= xOrigin - (xOrigin * a + yOrigin * c); 4243 y -= yOrigin - (xOrigin * b + yOrigin * d); 4244 } 4245 } else { 4246 a32 = matrix[6]; 4247 a42 = matrix[7]; 4248 a13 = matrix[8]; 4249 a23 = matrix[9]; 4250 a33 = matrix[10]; 4251 a43 = matrix[11]; 4252 x = matrix[12]; 4253 y = matrix[13]; 4254 z = matrix[14]; 4255 angle = _atan2(a32, a33); 4256 rotationX = angle * _RAD2DEG; 4257 4258 if (angle) { 4259 cos = Math.cos(-angle); 4260 sin = Math.sin(-angle); 4261 t1 = a12 * cos + a13 * sin; 4262 t2 = a22 * cos + a23 * sin; 4263 t3 = a32 * cos + a33 * sin; 4264 a13 = a12 * -sin + a13 * cos; 4265 a23 = a22 * -sin + a23 * cos; 4266 a33 = a32 * -sin + a33 * cos; 4267 a43 = a42 * -sin + a43 * cos; 4268 a12 = t1; 4269 a22 = t2; 4270 a32 = t3; 4271 } 4272 4273 angle = _atan2(-c, a33); 4274 rotationY = angle * _RAD2DEG; 4275 4276 if (angle) { 4277 cos = Math.cos(-angle); 4278 sin = Math.sin(-angle); 4279 t1 = a * cos - a13 * sin; 4280 t2 = b * cos - a23 * sin; 4281 t3 = c * cos - a33 * sin; 4282 a43 = d * sin + a43 * cos; 4283 a = t1; 4284 b = t2; 4285 c = t3; 4286 } 4287 4288 angle = _atan2(b, a); 4289 rotation = angle * _RAD2DEG; 4290 4291 if (angle) { 4292 cos = Math.cos(angle); 4293 sin = Math.sin(angle); 4294 t1 = a * cos + b * sin; 4295 t2 = a12 * cos + a22 * sin; 4296 b = b * cos - a * sin; 4297 a22 = a22 * cos - a12 * sin; 4298 a = t1; 4299 a12 = t2; 4300 } 4301 4302 if (rotationX && Math.abs(rotationX) + Math.abs(rotation) > 359.9) { 4303 rotationX = rotation = 0; 4304 rotationY = 180 - rotationY; 4305 } 4306 4307 scaleX = _round(Math.sqrt(a * a + b * b + c * c)); 4308 scaleY = _round(Math.sqrt(a22 * a22 + a32 * a32)); 4309 angle = _atan2(a12, a22); 4310 skewX = Math.abs(angle) > 0.0002 ? angle * _RAD2DEG : 0; 4311 perspective = a43 ? 1 / (a43 < 0 ? -a43 : a43) : 0; 4312 } 4313 4314 if (cache.svg) { 4315 t1 = target.getAttribute("transform"); 4316 cache.forceCSS = target.setAttribute("transform", "") || !_isNullTransform(_getComputedProperty(target, _transformProp)); 4317 t1 && target.setAttribute("transform", t1); 4318 } 4319 } 4320 4321 if (Math.abs(skewX) > 90 && Math.abs(skewX) < 270) { 4322 if (invertedScaleX) { 4323 scaleX *= -1; 4324 skewX += rotation <= 0 ? 180 : -180; 4325 rotation += rotation <= 0 ? 180 : -180; 4326 } else { 4327 scaleY *= -1; 4328 skewX += skewX <= 0 ? 180 : -180; 4329 } 4330 } 4331 4332 cache.x = x - ((cache.xPercent = x && (cache.xPercent || (Math.round(target.offsetWidth / 2) === Math.round(-x) ? -50 : 0))) ? target.offsetWidth * cache.xPercent / 100 : 0) + px; 4333 cache.y = y - ((cache.yPercent = y && (cache.yPercent || (Math.round(target.offsetHeight / 2) === Math.round(-y) ? -50 : 0))) ? target.offsetHeight * cache.yPercent / 100 : 0) + px; 4334 cache.z = z + px; 4335 cache.scaleX = _round(scaleX); 4336 cache.scaleY = _round(scaleY); 4337 cache.rotation = _round(rotation) + deg; 4338 cache.rotationX = _round(rotationX) + deg; 4339 cache.rotationY = _round(rotationY) + deg;
vendor: 4,199 bytes, lines 4340-4467
4340 cache.skewX = skewX + deg; 4341 cache.skewY = skewY + deg; 4342 cache.transformPerspective = perspective + px; 4343 4344 if (cache.zOrigin = parseFloat(origin.split(" ")[2]) || 0) { 4345 style[_transformOriginProp] = _firstTwoOnly(origin); 4346 } 4347 4348 cache.xOffset = cache.yOffset = 0; 4349 cache.force3D = _config.force3D; 4350 cache.renderTransform = cache.svg ? _renderSVGTransforms : _supports3D ? _renderCSSTransforms : _renderNon3DTransforms; 4351 cache.uncache = 0; 4352 return cache; 4353 }, 4354 _firstTwoOnly = function _firstTwoOnly(value) { 4355 return (value = value.split(" "))[0] + " " + value[1]; 4356 }, 4357 _addPxTranslate = function _addPxTranslate(target, start, value) { 4358 var unit = getUnit(start); 4359 return _round(parseFloat(start) + parseFloat(_convertToUnit(target, "x", value + "px", unit))) + unit; 4360 }, 4361 _renderNon3DTransforms = function _renderNon3DTransforms(ratio, cache) { 4362 cache.z = "0px"; 4363 cache.rotationY = cache.rotationX = "0deg"; 4364 cache.force3D = 0; 4365 4366 _renderCSSTransforms(ratio, cache); 4367 }, 4368 _zeroDeg = "0deg", 4369 _zeroPx = "0px", 4370 _endParenthesis = ") ", 4371 _renderCSSTransforms = function _renderCSSTransforms(ratio, cache) { 4372 var _ref = cache || this, 4373 xPercent = _ref.xPercent, 4374 yPercent = _ref.yPercent, 4375 x = _ref.x, 4376 y = _ref.y, 4377 z = _ref.z, 4378 rotation = _ref.rotation, 4379 rotationY = _ref.rotationY, 4380 rotationX = _ref.rotationX, 4381 skewX = _ref.skewX, 4382 skewY = _ref.skewY, 4383 scaleX = _ref.scaleX, 4384 scaleY = _ref.scaleY, 4385 transformPerspective = _ref.transformPerspective, 4386 force3D = _ref.force3D, 4387 target = _ref.target, 4388 zOrigin = _ref.zOrigin, 4389 transforms = "", 4390 use3D = force3D === "auto" && ratio && ratio !== 1 || force3D === true; 4391 4392 if (zOrigin && (rotationX !== _zeroDeg || rotationY !== _zeroDeg)) { 4393 var angle = parseFloat(rotationY) * _DEG2RAD, 4394 a13 = Math.sin(angle), 4395 a33 = Math.cos(angle), 4396 cos; 4397 4398 angle = parseFloat(rotationX) * _DEG2RAD; 4399 cos = Math.cos(angle); 4400 x = _addPxTranslate(target, x, a13 * cos * -zOrigin); 4401 y = _addPxTranslate(target, y, -Math.sin(angle) * -zOrigin); 4402 z = _addPxTranslate(target, z, a33 * cos * -zOrigin + zOrigin); 4403 } 4404 4405 if (transformPerspective !== _zeroPx) { 4406 transforms += "perspective(" + transformPerspective + _endParenthesis; 4407 } 4408 4409 if (xPercent || yPercent) { 4410 transforms += "translate(" + xPercent + "%, " + yPercent + "%) "; 4411 } 4412 4413 if (use3D || x !== _zeroPx || y !== _zeroPx || z !== _zeroPx) { 4414 transforms += z !== _zeroPx || use3D ? "translate3d(" + x + ", " + y + ", " + z + ") " : "translate(" + x + ", " + y + _endParenthesis; 4415 } 4416 4417 if (rotation !== _zeroDeg) { 4418 transforms += "rotate(" + rotation + _endParenthesis; 4419 } 4420 4421 if (rotationY !== _zeroDeg) { 4422 transforms += "rotateY(" + rotationY + _endParenthesis; 4423 } 4424 4425 if (rotationX !== _zeroDeg) { 4426 transforms += "rotateX(" + rotationX + _endParenthesis; 4427 } 4428 4429 if (skewX !== _zeroDeg || skewY !== _zeroDeg) { 4430 transforms += "skew(" + skewX + ", " + skewY + _endParenthesis; 4431 } 4432 4433 if (scaleX !== 1 || scaleY !== 1) { 4434 transforms += "scale(" + scaleX + ", " + scaleY + _endParenthesis; 4435 } 4436 4437 target.style[_transformProp] = transforms || "translate(0, 0)"; 4438 }, 4439 _renderSVGTransforms = function _renderSVGTransforms(ratio, cache) { 4440 var _ref2 = cache || this, 4441 xPercent = _ref2.xPercent, 4442 yPercent = _ref2.yPercent, 4443 x = _ref2.x, 4444 y = _ref2.y, 4445 rotation = _ref2.rotation, 4446 skewX = _ref2.skewX, 4447 skewY = _ref2.skewY, 4448 scaleX = _ref2.scaleX, 4449 scaleY = _ref2.scaleY, 4450 target = _ref2.target, 4451 xOrigin = _ref2.xOrigin, 4452 yOrigin = _ref2.yOrigin, 4453 xOffset = _ref2.xOffset, 4454 yOffset = _ref2.yOffset, 4455 forceCSS = _ref2.forceCSS, 4456 tx = parseFloat(x), 4457 ty = parseFloat(y), 4458 a11, 4459 a21, 4460 a12, 4461 a22, 4462 temp; 4463 4464 rotation = parseFloat(rotation); 4465 skewX = parseFloat(skewX); 4466 skewY = parseFloat(skewY); 4467
vendor: 4,432 bytes, lines 4468-4616
4468 if (skewY) { 4469 skewY = parseFloat(skewY); 4470 skewX += skewY; 4471 rotation += skewY; 4472 } 4473 4474 if (rotation || skewX) { 4475 rotation *= _DEG2RAD; 4476 skewX *= _DEG2RAD; 4477 a11 = Math.cos(rotation) * scaleX; 4478 a21 = Math.sin(rotation) * scaleX; 4479 a12 = Math.sin(rotation - skewX) * -scaleY; 4480 a22 = Math.cos(rotation - skewX) * scaleY; 4481 4482 if (skewX) { 4483 skewY *= _DEG2RAD; 4484 temp = Math.tan(skewX - skewY); 4485 temp = Math.sqrt(1 + temp * temp); 4486 a12 *= temp; 4487 a22 *= temp; 4488 4489 if (skewY) { 4490 temp = Math.tan(skewY); 4491 temp = Math.sqrt(1 + temp * temp); 4492 a11 *= temp; 4493 a21 *= temp; 4494 } 4495 } 4496 4497 a11 = _round(a11); 4498 a21 = _round(a21); 4499 a12 = _round(a12); 4500 a22 = _round(a22); 4501 } else { 4502 a11 = scaleX; 4503 a22 = scaleY; 4504 a21 = a12 = 0; 4505 } 4506 4507 if (tx && !~(x + "").indexOf("px") || ty && !~(y + "").indexOf("px")) { 4508 tx = _convertToUnit(target, "x", x, "px"); 4509 ty = _convertToUnit(target, "y", y, "px"); 4510 } 4511 4512 if (xOrigin || yOrigin || xOffset || yOffset) { 4513 tx = _round(tx + xOrigin - (xOrigin * a11 + yOrigin * a12) + xOffset); 4514 ty = _round(ty + yOrigin - (xOrigin * a21 + yOrigin * a22) + yOffset); 4515 } 4516 4517 if (xPercent || yPercent) { 4518 temp = target.getBBox(); 4519 tx = _round(tx + xPercent / 100 * temp.width); 4520 ty = _round(ty + yPercent / 100 * temp.height); 4521 } 4522 4523 temp = "matrix(" + a11 + "," + a21 + "," + a12 + "," + a22 + "," + tx + "," + ty + ")"; 4524 target.setAttribute("transform", temp); 4525 forceCSS && (target.style[_transformProp] = temp); 4526 }, 4527 _addRotationalPropTween = function _addRotationalPropTween(plugin, target, property, startNum, endValue, relative) { 4528 var cap = 360, 4529 isString = _isString(endValue), 4530 endNum = parseFloat(endValue) * (isString && ~endValue.indexOf("rad") ? _RAD2DEG : 1), 4531 change = relative ? endNum * relative : endNum - startNum, 4532 finalValue = startNum + change + "deg", 4533 direction, 4534 pt; 4535 4536 if (isString) { 4537 direction = endValue.split("_")[1]; 4538 4539 if (direction === "short") { 4540 change %= cap; 4541 4542 if (change !== change % (cap / 2)) { 4543 change += change < 0 ? cap : -cap; 4544 } 4545 } 4546 4547 if (direction === "cw" && change < 0) { 4548 change = (change + cap * _bigNum$1) % cap - ~~(change / cap) * cap; 4549 } else if (direction === "ccw" && change > 0) { 4550 change = (change - cap * _bigNum$1) % cap - ~~(change / cap) * cap; 4551 } 4552 } 4553 4554 plugin._pt = pt = new PropTween(plugin._pt, target, property, startNum, change, _renderPropWithEnd); 4555 pt.e = finalValue; 4556 pt.u = "deg"; 4557 4558 plugin._props.push(property); 4559 4560 return pt; 4561 }, 4562 _assign = function _assign(target, source) { 4563 for (var p in source) { 4564 target[p] = source[p]; 4565 } 4566 4567 return target; 4568 }, 4569 _addRawTransformPTs = function _addRawTransformPTs(plugin, transforms, target) { 4570 var startCache = _assign({}, target._gsap), 4571 exclude = "perspective,force3D,transformOrigin,svgOrigin", 4572 style = target.style, 4573 endCache, 4574 p, 4575 startValue, 4576 endValue, 4577 startNum, 4578 endNum, 4579 startUnit, 4580 endUnit; 4581 4582 if (startCache.svg) { 4583 startValue = target.getAttribute("transform"); 4584 target.setAttribute("transform", ""); 4585 style[_transformProp] = transforms; 4586 endCache = _parseTransform(target, 1); 4587 4588 _removeProperty(target, _transformProp); 4589 4590 target.setAttribute("transform", startValue); 4591 } else { 4592 startValue = getComputedStyle(target)[_transformProp]; 4593 style[_transformProp] = transforms; 4594 endCache = _parseTransform(target, 1); 4595 style[_transformProp] = startValue; 4596 } 4597 4598 for (p in _transformProps) { 4599 startValue = startCache[p]; 4600 endValue = endCache[p]; 4601 4602 if (startValue !== endValue && exclude.indexOf(p) < 0) { 4603 startUnit = getUnit(startValue); 4604 endUnit = getUnit(endValue); 4605 startNum = startUnit !== endUnit ? _convertToUnit(target, p, startValue, endUnit) : parseFloat(startValue); 4606 endNum = parseFloat(endValue); 4607 plugin._pt = new PropTween(plugin._pt, endCache, p, startNum, endNum - startNum, _renderCSSProp); 4608 plugin._pt.u = endUnit || 0; 4609 4610 plugin._props.push(p); 4611 } 4612 } 4613 4614 _assign(endCache, startCache); 4615 }; 4616
vendor: 4,076 bytes, lines 4617-4738
4617 _forEachName("padding,margin,Width,Radius", function (name, index) { 4618 var t = "Top", 4619 r = "Right", 4620 b = "Bottom", 4621 l = "Left", 4622 props = (index < 3 ? [t, r, b, l] : [t + l, t + r, b + r, b + l]).map(function (side) { 4623 return index < 2 ? name + side : "border" + side + name; 4624 }); 4625 4626 _specialProps[index > 1 ? "border" + name : name] = function (plugin, target, property, endValue, tween) { 4627 var a, vars; 4628 4629 if (arguments.length < 4) { 4630 a = props.map(function (prop) { 4631 return _get(plugin, prop, property); 4632 }); 4633 vars = a.join(" "); 4634 return vars.split(a[0]).length === 5 ? a[0] : vars; 4635 } 4636 4637 a = (endValue + "").split(" "); 4638 vars = {}; 4639 props.forEach(function (prop, i) { 4640 return vars[prop] = a[i] = a[i] || a[(i - 1) / 2 | 0]; 4641 }); 4642 plugin.init(target, vars, tween); 4643 }; 4644 }); 4645 4646 var CSSPlugin = { 4647 name: "css", 4648 register: _initCore, 4649 targetTest: function targetTest(target) { 4650 return target.style && target.nodeType; 4651 }, 4652 init: function init(target, vars, tween, index, targets) { 4653 var props = this._props, 4654 style = target.style, 4655 startAt = tween.vars.startAt, 4656 startValue, 4657 endValue, 4658 endNum, 4659 startNum, 4660 type, 4661 specialProp, 4662 p, 4663 startUnit, 4664 endUnit, 4665 relative, 4666 isTransformRelated, 4667 transformPropTween, 4668 cache, 4669 smooth, 4670 hasPriority; 4671 _pluginInitted || _initCore(); 4672 4673 for (p in vars) { 4674 if (p === "autoRound") { 4675 continue; 4676 } 4677 4678 endValue = vars[p]; 4679 4680 if (_plugins[p] && _checkPlugin(p, vars, tween, index, target, targets)) { 4681 continue; 4682 } 4683 4684 type = typeof endValue; 4685 specialProp = _specialProps[p]; 4686 4687 if (type === "function") { 4688 endValue = endValue.call(tween, index, target, targets); 4689 type = typeof endValue; 4690 } 4691 4692 if (type === "string" && ~endValue.indexOf("random(")) { 4693 endValue = _replaceRandom(endValue); 4694 } 4695 4696 if (specialProp) { 4697 specialProp(this, target, p, endValue, tween) && (hasPriority = 1); 4698 } else if (p.substr(0, 2) === "--") { 4699 startValue = (getComputedStyle(target).getPropertyValue(p) + "").trim(); 4700 endValue += ""; 4701 _colorExp.lastIndex = 0; 4702 4703 if (!_colorExp.test(startValue)) { 4704 startUnit = getUnit(startValue); 4705 endUnit = getUnit(endValue); 4706 } 4707 4708 endUnit ? startUnit !== endUnit && (startValue = _convertToUnit(target, p, startValue, endUnit) + endUnit) : startUnit && (endValue += startUnit); 4709 this.add(style, "setProperty", startValue, endValue, index, targets, 0, 0, p); 4710 } else if (type !== "undefined") { 4711 if (startAt && p in startAt) { 4712 startValue = typeof startAt[p] === "function" ? startAt[p].call(tween, index, target, targets) : startAt[p]; 4713 p in _config.units && !getUnit(startValue) && (startValue += _config.units[p]); 4714 (startValue + "").charAt(1) === "=" && (startValue = _get(target, p)); 4715 } else { 4716 startValue = _get(target, p); 4717 } 4718 4719 startNum = parseFloat(startValue); 4720 relative = type === "string" && endValue.charAt(1) === "=" ? +(endValue.charAt(0) + "1") : 0; 4721 relative && (endValue = endValue.substr(2)); 4722 endNum = parseFloat(endValue); 4723 4724 if (p in _propertyAliases) { 4725 if (p === "autoAlpha") { 4726 if (startNum === 1 && _get(target, "visibility") === "hidden" && endNum) { 4727 startNum = 0; 4728 } 4729 4730 _addNonTweeningPT(this, style, "visibility", startNum ? "inherit" : "hidden", endNum ? "inherit" : "hidden", !endNum); 4731 } 4732 4733 if (p !== "scale" && p !== "transform") { 4734 p = _propertyAliases[p]; 4735 ~p.indexOf(",") && (p = p.split(",")[0]); 4736 } 4737 } 4738
vendor: 4,279 bytes, lines 4739-4832
4739 isTransformRelated = p in _transformProps; 4740 4741 if (isTransformRelated) { 4742 if (!transformPropTween) { 4743 cache = target._gsap; 4744 cache.renderTransform && !vars.parseTransform || _parseTransform(target, vars.parseTransform); 4745 smooth = vars.smoothOrigin !== false && cache.smooth; 4746 transformPropTween = this._pt = new PropTween(this._pt, style, _transformProp, 0, 1, cache.renderTransform, cache, 0, -1); 4747 transformPropTween.dep = 1; 4748 } 4749 4750 if (p === "scale") { 4751 this._pt = new PropTween(this._pt, cache, "scaleY", cache.scaleY, relative ? relative * endNum : endNum - cache.scaleY); 4752 props.push("scaleY", p); 4753 p += "X"; 4754 } else if (p === "transformOrigin") { 4755 endValue = _convertKeywordsToPercentages(endValue); 4756 4757 if (cache.svg) { 4758 _applySVGOrigin(target, endValue, 0, smooth, 0, this); 4759 } else { 4760 endUnit = parseFloat(endValue.split(" ")[2]) || 0; 4761 endUnit !== cache.zOrigin && _addNonTweeningPT(this, cache, "zOrigin", cache.zOrigin, endUnit); 4762 4763 _addNonTweeningPT(this, style, p, _firstTwoOnly(startValue), _firstTwoOnly(endValue)); 4764 } 4765 4766 continue; 4767 } else if (p === "svgOrigin") { 4768 _applySVGOrigin(target, endValue, 1, smooth, 0, this); 4769 4770 continue; 4771 } else if (p in _rotationalProperties) { 4772 _addRotationalPropTween(this, cache, p, startNum, endValue, relative); 4773 4774 continue; 4775 } else if (p === "smoothOrigin") { 4776 _addNonTweeningPT(this, cache, "smooth", cache.smooth, endValue); 4777 4778 continue; 4779 } else if (p === "force3D") { 4780 cache[p] = endValue; 4781 continue; 4782 } else if (p === "transform") { 4783 _addRawTransformPTs(this, endValue, target); 4784 4785 continue; 4786 } 4787 } else if (!(p in style)) { 4788 p = _checkPropPrefix(p) || p; 4789 } 4790 4791 if (isTransformRelated || (endNum || endNum === 0) && (startNum || startNum === 0) && !_complexExp.test(endValue) && p in style) { 4792 startUnit = (startValue + "").substr((startNum + "").length); 4793 endNum || (endNum = 0); 4794 endUnit = getUnit(endValue) || (p in _config.units ? _config.units[p] : startUnit); 4795 startUnit !== endUnit && (startNum = _convertToUnit(target, p, startValue, endUnit)); 4796 this._pt = new PropTween(this._pt, isTransformRelated ? cache : style, p, startNum, relative ? relative * endNum : endNum - startNum, !isTransformRelated && (endUnit === "px" || p === "zIndex") && vars.autoRound !== false ? _renderRoundedCSSProp : _renderCSSProp); 4797 this._pt.u = endUnit || 0; 4798 4799 if (startUnit !== endUnit) { 4800 this._pt.b = startValue; 4801 this._pt.r = _renderCSSPropWithBeginning; 4802 } 4803 } else if (!(p in style)) { 4804 if (p in target) { 4805 this.add(target, p, target[p], endValue, index, targets); 4806 } else { 4807 _missingPlugin(p, endValue); 4808 4809 continue; 4810 } 4811 } else { 4812 _tweenComplexCSSString.call(this, target, p, startValue, endValue); 4813 } 4814 4815 props.push(p); 4816 } 4817 } 4818 4819 hasPriority && _sortPropTweensByPriority(this); 4820 }, 4821 get: _get, 4822 aliases: _propertyAliases, 4823 getSetter: function getSetter(target, property, plugin) { 4824 var p = _propertyAliases[property]; 4825 p && p.indexOf(",") < 0 && (property = p); 4826 return property in _transformProps && property !== _transformOriginProp && (target._gsap.x || _get(target, "x")) ? plugin && _recentSetterPlugin === plugin ? property === "scale" ? _setterScale : _setterTransform : (_recentSetterPlugin = plugin || {}) && (property === "scale" ? _setterScaleWithRender : _setterTransformWithRender) : target.style && !_isUndefined(target.style[property]) ? _setterCSSStyle : ~property.indexOf("-") ? _setterCSSProp : _getSetter(target, property); 4827 }, 4828 core: { 4829 _removeProperty: _removeProperty, 4830 _getMatrix: _getMatrix 4831 } 4832 };
4833 gsap.utils.checkPrefix = _checkPropPrefix; 4834 4835 (function (positionAndScale, rotation, others, aliases) { 4836 var all = _forEachName(positionAndScale + "," + rotation + "," + others, function (name) { 4837 _transformProps[name] = 1; 4838 }); 4839 4840 _forEachName(rotation, function (name) { 4841 _config.units[name] = "deg"; 4842 _rotationalProperties[name] = 1; 4843 }); 4844 4845 _propertyAliases[all[13]] = positionAndScale + "," + rotation; 4846 4847 _forEachName(aliases, function (name) { 4848 var split = name.split(":"); 4849 _propertyAliases[split[1]] = all[split[0]]; 4850 }); 4851 })("x,y,z,scale,scaleX,scaleY,xPercent,yPercent", "rotation,rotationX,rotationY,skewX,skewY", "transform,transformOrigin,svgOrigin,force3D,smoothOrigin,transformPerspective", "0:translateX,1:translateY,2:translateZ,8:rotate,8:rotationZ,8:rotateZ,9:rotateX,10:rotateY"); 4852 4853 _forEachName("x,y,z,top,right,bottom,left,width,height,fontSize,padding,margin,perspective", function (name) { 4854 _config.units[name] = "px"; 4855 }); 4856 4857 gsap.registerPlugin(CSSPlugin); 4858 4859 var gsapWithCSS = gsap.registerPlugin(CSSPlugin) || gsap, 4860 TweenMaxWithCSS = gsapWithCSS.core.Tween; 4861 4862 exports.Back = Back; 4863 exports.Bounce = Bounce; 4864 exports.CSSPlugin = CSSPlugin; 4865 exports.Circ = Circ; 4866 exports.Cubic = Cubic; 4867 exports.Elastic = Elastic; 4868 exports.Expo = Expo; 4869 exports.Linear = Linear; 4870 exports.Power0 = Power0; 4871 exports.Power1 = Power1; 4872 exports.Power2 = Power2; 4873 exports.Power3 = Power3; 4874 exports.Power4 = Power4; 4875 exports.Quad = Quad; 4876 exports.Quart = Quart; 4877 exports.Quint = Quint; 4878 exports.Sine = Sine; 4879 exports.SteppedEase = SteppedEase; 4880 exports.Strong = Strong; 4881 exports.TimelineLite = Timeline; 4882 exports.TimelineMax = Timeline; 4883 exports.TweenLite = Tween; 4884 exports.TweenMax = TweenMaxWithCSS; 4885 exports.default = gsapWithCSS; 4886 exports.gsap = gsapWithCSS; 4887 4888 if (typeof(window) === 'undefined' || window !== exports) {Object.defineProperty(exports, '__esModule', { value: true });} else {delete window.default;} 4889 4890}))); 4891 4892(function(window, $) { 4893 'use strict'; 4894 var counter = 0, 4895 $headCache = $('head'), 4896 oldBigText = window.BigText, 4897 oldjQueryMethod = $.fn.bigtext, 4898 BigText = { 4899 DEBUG_MODE: false, 4900 DEFAULT_MIN_FONT_SIZE_PX: null, 4901 DEFAULT_MAX_FONT_SIZE_PX: 528, 4902 GLOBAL_STYLE_ID: 'bigtext-style', 4903 STYLE_ID: 'bigtext-id', 4904 LINE_CLASS_PREFIX: 'bigtext-line', 4905 EXEMPT_CLASS: 'bigtext-exempt', 4906 noConflict: function(restore) 4907 { 4908 if(restore) { 4909 $.fn.bigtext = oldjQueryMethod; 4910 window.BigText = oldBigText; 4911 } 4912 return BigText; 4913 }, 4914 supports: { 4915 wholeNumberFontSizeOnly: (function() { 4916 if( !( 'getComputedStyle' in window ) ) { 4917 return true; 4918 } 4919 var test = $('<div/>').css({ 4920 position: 'absolute', 4921 'font-size': '14.1px' 4922 }).insertBefore( $('script').eq(0) ), 4923 computedStyle = window.getComputedStyle( test[0], null ); 4924 4925 var ret = computedStyle && computedStyle.getPropertyValue( 'font-size' ) === '14px'; 4926 test.remove(); 4927 return ret; 4928 })() 4929 }, 4930 init: function() { 4931 if(!$('#'+BigText.GLOBAL_STYLE_ID).length) { 4932 $headCache.append(BigText.generateStyleTag(BigText.GLOBAL_STYLE_ID, ['.bigtext * { white-space: nowrap; } .bigtext > * { display: block; }', 4933 '.bigtext .' + BigText.EXEMPT_CLASS + ', .bigtext .' + BigText.EXEMPT_CLASS + ' * { white-space: normal; }'])); 4934 } 4935 }, 4936 bindResize: function(eventName, resizeFunction) { 4937 var timeoutId; 4938 $(window).unbind(eventName).bind(eventName, function() { 4939 if( timeoutId ) { 4940 clearTimeout( timeoutId ); 4941 } 4942 timeoutId = setTimeout( resizeFunction, 300 ); 4943 }); 4944 }, 4945 getStyleId: function(id) 4946 { 4947 return BigText.STYLE_ID + '-' + id; 4948 }, 4949 generateStyleTag: function(id, css) 4950 { 4951 return $('<style>' + css.join('\n') + '</style>').attr('id', id); 4952 }, 4953 clearCss: function(id) 4954 { 4955 var styleId = BigText.getStyleId(id); 4956 $('#' + styleId).remove(); 4957 }, 4958 generateCss: function(id, linesFontSizes, lineWordSpacings, minFontSizes) 4959 { 4960 var css = []; 4961 4962 BigText.clearCss(id); 4963 4964 for(var j=0, k=linesFontSizes.length; j<k; j++) { 4965 css.push('#' + id + ' .' + BigText.LINE_CLASS_PREFIX + j + ' {' + 4966 (minFontSizes[j] ? ' white-space: normal;' : '') + 4967 (linesFontSizes[j] ? ' font-size: ' + linesFontSizes[j] + 'px;' : '') + 4968 (lineWordSpacings[j] ? ' word-spacing: ' + lineWordSpacings[j] + 'px;' : '') + 4969 '}'); 4970 } 4971 4972 return BigText.generateStyleTag(BigText.getStyleId(id), css); 4973 }, 4974 jQueryMethod: function(options) 4975 {
4976 BigText.init(); 4977 4978 options = $.extend({ 4979 minfontsize: BigText.DEFAULT_MIN_FONT_SIZE_PX, 4980 maxfontsize: BigText.DEFAULT_MAX_FONT_SIZE_PX, 4981 childSelector: '', 4982 resize: true 4983 }, options || {}); 4984 4985 this.each(function() 4986 { 4987 var $t = $(this).addClass('bigtext'), 4988 maxWidth = $t.width(), 4989 id = $t.attr('id'), 4990 $children = options.childSelector ? $t.find( options.childSelector ) : $t.children(); 4991 4992 if(!id) { 4993 id = 'bigtext-id' + (counter++); 4994 $t.attr('id', id); 4995 } 4996 4997 if(options.resize) { 4998 BigText.bindResize('resize.bigtext-event-' + id, function() 4999 { 5000 // TODO only call this if the width has changed. 5001 BigText.jQueryMethod.call($('#' + id), options); 5002 }); 5003 } 5004 5005 BigText.clearCss(id); 5006 5007 $children.addClass(function(lineNumber, className) 5008 { 5009 // remove existing line classes. 5010 return [className.replace(new RegExp('\\b' + BigText.LINE_CLASS_PREFIX + '\\d+\\b'), ''), 5011 BigText.LINE_CLASS_PREFIX + lineNumber].join(' '); 5012 }); 5013 5014 var sizes = calculateSizes($t, $children, maxWidth, options.maxfontsize, options.minfontsize); 5015 $headCache.append(BigText.generateCss(id, sizes.fontSizes, sizes.wordSpacings, sizes.minFontSizes)); 5016 }); 5017 5018 return this.trigger('bigtext:complete'); 5019 } 5020 }; 5021 5022 function testLineDimensions($line, maxWidth, property, size, interval, units, previousWidth) 5023 { 5024 var width; 5025 previousWidth = typeof previousWidth === 'number' ? previousWidth : 0; 5026 $line.css(property, size + units); 5027 5028 width = $line.width(); 5029 5030 if(width >= maxWidth) { 5031 5032 $line.css(property, ''); 5033 5034 if(width === maxWidth) { 5035 return { 5036 match: 'exact', 5037 size: parseFloat((parseFloat(size) - 0.1).toFixed(3)) 5038 }; 5039 } 5040 5041 // Since this is an estimate, we calculate how far over the width we went with the new value. 5042 // If this is word-spacing (our last resort guess) and the over is less than the under, we keep the higher value. 5043 // Otherwise, we revert to the underestimate. 5044 var under = maxWidth - previousWidth, 5045 over = width - maxWidth; 5046 5047 return { 5048 match: 'estimate', 5049 size: parseFloat((parseFloat(size) - (property === 'word-spacing' && previousWidth && ( over < under ) ? 0 : interval)).toFixed(3)) 5050 }; 5051 } 5052 5053 return width; 5054 } 5055 5056 function calculateSizes($t, $children, maxWidth, maxFontSize, minFontSize) 5057 { 5058 var $c = $t.clone(true) 5059 .addClass('bigtext-cloned') 5060 .css({ 5061 fontFamily: $t.css('font-family'), 5062 textTransform: $t.css('text-transform'), 5063 wordSpacing: $t.css('word-spacing'), 5064 letterSpacing: $t.css('letter-spacing'), 5065 position: 'absolute', 5066 left: BigText.DEBUG_MODE ? 0 : -9999, 5067 top: BigText.DEBUG_MODE ? 0 : -9999 5068 }) 5069 .appendTo(document.body); 5070 5071 // font-size isn't the only thing we can modify, we can also mess with: 5072 // word-spacing and letter-spacing. WebKit does not respect subpixel 5073 // letter-spacing, word-spacing, or font-size. 5074 // TODO try -webkit-transform: scale() as a workaround. 5075 var fontSizes = [], 5076 wordSpacings = [], 5077 minFontSizes = [], 5078 ratios = []; 5079 5080 $children.css('float', 'left').each(function() { 5081 var $line = $(this), 5082 // TODO replace 8, 4 with a proportional size to the calculated font-size. 5083 intervals = BigText.supports.wholeNumberFontSizeOnly ? [8, 4, 1] : [8, 4, 1, 0.1], 5084 lineMax, 5085 newFontSize; 5086 5087 if($line.hasClass(BigText.EXEMPT_CLASS)) { 5088 fontSizes.push(null); 5089 ratios.push(null); 5090 minFontSizes.push(false); 5091 return; 5092 } 5093 5094 // TODO we can cache this ratio? 5095 var autoGuessSubtraction = 32, // font size in px 5096 currentFontSize = parseFloat($line.css('font-size')), 5097 ratio = ( $line.width() / currentFontSize ).toFixed(6); 5098 5099 newFontSize = parseInt( maxWidth / ratio, 10 ) - autoGuessSubtraction; 5100 5101 outer: for(var m=0, n=intervals.length; m<n; m++) { 5102 inner: for(var j=1, k=10; j<=k; j++) { 5103 if(newFontSize + j*intervals[m] > maxFontSize) { 5104 newFontSize = maxFontSize; 5105 break outer; 5106 } 5107 5108 lineMax = testLineDimensions($line, maxWidth, 'font-size', newFontSize + j*intervals[m], intervals[m], 'px', lineMax); 5109 if(typeof lineMax !== 'number') { 5110 newFontSize = lineMax.size; 5111 5112 if(lineMax.match === 'exact') { 5113 break outer; 5114 } 5115 break inner; 5116 } 5117 } 5118 } 5119 5120 ratios.push(maxWidth / newFontSize); 5121 5122 if(newFontSize > maxFontSize) { 5123 fontSizes.push(maxFontSize); 5124 minFontSizes.push(false); 5125 } else if(!!minFontSize && newFontSize < minFontSize) { 5126 fontSizes.push(minFontSize); 5127 minFontSizes.push(true); 5128 } else { 5129 fontSizes.push(newFontSize); 5130 minFontSizes.push(false); 5131 } 5132 }).each(function(lineNumber) { 5133 var $line = $(this), 5134 wordSpacing = 0, 5135 interval = 1, 5136 maxWordSpacing; 5137 5138 if($line.hasClass(BigText.EXEMPT_CLASS)) { 5139 wordSpacings.push(null); 5140 return; 5141 } 5142 5143 // must re-use font-size, even though it was removed above. 5144 $line.css('font-size', fontSizes[lineNumber] + 'px'); 5145 5146 for(var m=1, n=3; m<n; m+=interval) { 5147 maxWordSpacing = testLineDimensions($line, maxWidth, 'word-spacing', m, interval, 'px', maxWordSpacing); 5148 if(typeof maxWordSpacing !== 'number') { 5149 wordSpacing = maxWordSpacing.size; 5150 break; 5151 } 5152 } 5153 5154 $line.css('font-size', ''); 5155 wordSpacings.push(wordSpacing); 5156 }).removeAttr('style'); 5157 5158 if( !BigText.DEBUG_MODE ) { 5159 $c.remove(); 5160 } else { 5161 $c.css({ 5162 'background-color': 'rgba(255,255,255,.4)' 5163 }); 5164 } 5165 5166 return { 5167 fontSizes: fontSizes, 5168 wordSpacings: wordSpacings, 5169 ratios: ratios, 5170 minFontSizes: minFontSizes 5171 }; 5172 } 5173 5174 $.fn.bigtext = BigText.jQueryMethod; 5175 window.BigText = BigText; 5176 5177})(this, jQuery); 5178/*! 5179 * Isotope PACKAGED v3.0.6 5180 * 5181 * Licensed GPLv3 for open source use 5182 * or Isotope Commercial License for commercial use 5183 * 5184 * https://isotope.metafizzy.co 5185 * Copyright 2010-2018 Metafizzy
vendor: 15,902 bytes, lines 5185-5835
5185 5186 */ 5187 5188/** 5189 * Bridget makes jQuery widgets 5190 * v2.0.1 5191 * MIT license 5192 */ 5193 5194/* jshint browser: true, strict: true, undef: true, unused: true */ 5195 5196( function( window, factory ) { 5197 // universal module definition 5198 /*jshint strict: false */ /* globals define, module, require */ 5199 if ( typeof define == 'function' && define.amd ) { 5200 // AMD 5201 define( 'jquery-bridget/jquery-bridget',[ 'jquery' ], function( jQuery ) { 5202 return factory( window, jQuery ); 5203 }); 5204 } else if ( typeof module == 'object' && module.exports ) { 5205 // CommonJS 5206 module.exports = factory( 5207 window, 5208 require('jquery') 5209 ); 5210 } else { 5211 // browser global 5212 window.jQueryBridget = factory( 5213 window, 5214 window.jQuery 5215 ); 5216 } 5217 5218}( window, function factory( window, jQuery ) { 5219'use strict'; 5220 5221// ----- utils ----- // 5222 5223var arraySlice = Array.prototype.slice; 5224 5225// helper function for logging errors 5226// $.error breaks jQuery chaining 5227var console = window.console; 5228var logError = typeof console == 'undefined' ? function() {} : 5229 function( message ) { 5230 console.error( message ); 5231 }; 5232 5233// ----- jQueryBridget ----- // 5234 5235function jQueryBridget( namespace, PluginClass, $ ) { 5236 $ = $ || jQuery || window.jQuery; 5237 if ( !$ ) { 5238 return; 5239 } 5240 5241 // add option method -> $().plugin('option', {...}) 5242 if ( !PluginClass.prototype.option ) { 5243 // option setter 5244 PluginClass.prototype.option = function( opts ) { 5245 // bail out if not an object 5246 if ( !$.isPlainObject( opts ) ){ 5247 return; 5248 } 5249 this.options = $.extend( true, this.options, opts ); 5250 }; 5251 } 5252 5253 // make jQuery plugin 5254 $.fn[ namespace ] = function( arg0 /*, arg1 */ ) { 5255 if ( typeof arg0 == 'string' ) { 5256 // method call $().plugin( 'methodName', { options } ) 5257 // shift arguments by 1 5258 var args = arraySlice.call( arguments, 1 ); 5259 return methodCall( this, arg0, args ); 5260 } 5261 // just $().plugin({ options }) 5262 plainCall( this, arg0 ); 5263 return this; 5264 }; 5265 5266 // $().plugin('methodName') 5267 function methodCall( $elems, methodName, args ) { 5268 var returnValue; 5269 var pluginMethodStr = '$().' + namespace + '("' + methodName + '")'; 5270 5271 $elems.each( function( i, elem ) { 5272 // get instance 5273 var instance = $.data( elem, namespace ); 5274 if ( !instance ) { 5275 logError( namespace + ' not initialized. Cannot call methods, i.e. ' + 5276 pluginMethodStr ); 5277 return; 5278 } 5279 5280 var method = instance[ methodName ]; 5281 if ( !method || methodName.charAt(0) == '_' ) { 5282 logError( pluginMethodStr + ' is not a valid method' ); 5283 return; 5284 } 5285 5286 // apply method, get return value 5287 var value = method.apply( instance, args ); 5288 // set return value if value is returned, use only first value 5289 returnValue = returnValue === undefined ? value : returnValue; 5290 }); 5291 5292 return returnValue !== undefined ? returnValue : $elems; 5293 } 5294 5295 function plainCall( $elems, options ) { 5296 $elems.each( function( i, elem ) { 5297 var instance = $.data( elem, namespace ); 5298 if ( instance ) { 5299 // set options & init 5300 instance.option( options ); 5301 instance._init(); 5302 } else { 5303 // initialize new instance 5304 instance = new PluginClass( elem, options ); 5305 $.data( elem, namespace, instance ); 5306 } 5307 }); 5308 } 5309 5310 updateJQuery( $ ); 5311 5312} 5313 5314// ----- updateJQuery ----- // 5315 5316// set $.bridget for v1 backwards compatibility 5317function updateJQuery( $ ) { 5318 if ( !$ || ( $ && $.bridget ) ) { 5319 return; 5320 } 5321 $.bridget = jQueryBridget; 5322} 5323 5324updateJQuery( jQuery || window.jQuery ); 5325 5326// ----- ----- // 5327 5328return jQueryBridget; 5329 5330})); 5331 5332/** 5333 * EvEmitter v1.1.0 5334 * Lil' event emitter 5335 * MIT License 5336 */ 5337 5338/* jshint unused: true, undef: true, strict: true */ 5339 5340( function( global, factory ) { 5341 // universal module definition 5342 /* jshint strict: false */ /* globals define, module, window */ 5343 if ( typeof define == 'function' && define.amd ) { 5344 // AMD - RequireJS 5345 define( 'ev-emitter/ev-emitter',factory ); 5346 } else if ( typeof module == 'object' && module.exports ) { 5347 // CommonJS - Browserify, Webpack 5348 module.exports = factory(); 5349 } else { 5350 // Browser globals 5351 global.EvEmitter = factory(); 5352 } 5353 5354}( typeof window != 'undefined' ? window : this, function() { 5355 5356 5357 5358function EvEmitter() {} 5359 5360var proto = EvEmitter.prototype; 5361 5362proto.on = function( eventName, listener ) { 5363 if ( !eventName || !listener ) { 5364 return; 5365 } 5366 // set events hash 5367 var events = this._events = this._events || {}; 5368 // set listeners array 5369 var listeners = events[ eventName ] = events[ eventName ] || []; 5370 // only add once 5371 if ( listeners.indexOf( listener ) == -1 ) { 5372 listeners.push( listener ); 5373 } 5374 5375 return this; 5376}; 5377 5378proto.once = function( eventName, listener ) { 5379 if ( !eventName || !listener ) { 5380 return; 5381 } 5382 // add event 5383 this.on( eventName, listener ); 5384 // set once flag 5385 // set onceEvents hash 5386 var onceEvents = this._onceEvents = this._onceEvents || {}; 5387 // set onceListeners object 5388 var onceListeners = onceEvents[ eventName ] = onceEvents[ eventName ] || {}; 5389 // set flag 5390 onceListeners[ listener ] = true; 5391 5392 return this; 5393}; 5394 5395proto.off = function( eventName, listener ) { 5396 var listeners = this._events && this._events[ eventName ]; 5397 if ( !listeners || !listeners.length ) { 5398 return; 5399 } 5400 var index = listeners.indexOf( listener ); 5401 if ( index != -1 ) { 5402 listeners.splice( index, 1 ); 5403 } 5404 5405 return this; 5406}; 5407 5408proto.emitEvent = function( eventName, args ) { 5409 var listeners = this._events && this._events[ eventName ]; 5410 if ( !listeners || !listeners.length ) { 5411 return; 5412 } 5413 // copy over to avoid interference if .off() in listener 5414 listeners = listeners.slice(0); 5415 args = args || []; 5416 // once stuff 5417 var onceListeners = this._onceEvents && this._onceEvents[ eventName ]; 5418 5419 for ( var i=0; i < listeners.length; i++ ) { 5420 var listener = listeners[i] 5421 var isOnce = onceListeners && onceListeners[ listener ]; 5422 if ( isOnce ) { 5423 // remove listener 5424 // remove before trigger to prevent recursion 5425 this.off( eventName, listener ); 5426 // unset once flag 5427 delete onceListeners[ listener ]; 5428 } 5429 // trigger listener 5430 listener.apply( this, args ); 5431 } 5432 5433 return this; 5434}; 5435 5436proto.allOff = function() { 5437 delete this._events; 5438 delete this._onceEvents; 5439}; 5440 5441return EvEmitter; 5442 5443})); 5444 5445/*! 5446 * getSize v2.0.3 5447 * measure size of elements 5448 * MIT license 5449 */ 5450 5451/* jshint browser: true, strict: true, undef: true, unused: true */ 5452/* globals console: false */ 5453 5454( function( window, factory ) { 5455 /* jshint strict: false */ /* globals define, module */ 5456 if ( typeof define == 'function' && define.amd ) { 5457 // AMD 5458 define( 'get-size/get-size',factory ); 5459 } else if ( typeof module == 'object' && module.exports ) { 5460 // CommonJS 5461 module.exports = factory(); 5462 } else { 5463 // browser global 5464 window.getSize = factory(); 5465 } 5466 5467})( window, function factory() { 5468'use strict'; 5469 5470// -------------------------- helpers -------------------------- // 5471 5472// get a number from a string, not a percentage 5473function getStyleSize( value ) { 5474 var num = parseFloat( value ); 5475 // not a percent like '100%', and a number 5476 var isValid = value.indexOf('%') == -1 && !isNaN( num ); 5477 return isValid && num; 5478} 5479 5480function noop() {} 5481 5482var logError = typeof console == 'undefined' ? noop : 5483 function( message ) { 5484 console.error( message ); 5485 }; 5486 5487// -------------------------- measurements -------------------------- // 5488 5489var measurements = [ 5490 'paddingLeft', 5491 'paddingRight', 5492 'paddingTop', 5493 'paddingBottom', 5494 'marginLeft', 5495 'marginRight', 5496 'marginTop', 5497 'marginBottom', 5498 'borderLeftWidth', 5499 'borderRightWidth', 5500 'borderTopWidth', 5501 'borderBottomWidth' 5502]; 5503 5504var measurementsLength = measurements.length; 5505 5506function getZeroSize() { 5507 var size = { 5508 width: 0, 5509 height: 0, 5510 innerWidth: 0, 5511 innerHeight: 0, 5512 outerWidth: 0, 5513 outerHeight: 0 5514 }; 5515 for ( var i=0; i < measurementsLength; i++ ) { 5516 var measurement = measurements[i]; 5517 size[ measurement ] = 0; 5518 } 5519 return size; 5520} 5521 5522// -------------------------- getStyle -------------------------- // 5523 5524/** 5525 * getStyle, get style of element, check for Firefox bug 5526 * https://bugzilla.mozilla.org/show_bug.cgi?id=548397 5527 */ 5528function getStyle( elem ) { 5529 var style = getComputedStyle( elem ); 5530 if ( !style ) { 5531 logError( 'Style returned ' + style + 5532 '. Are you running this code in a hidden iframe on Firefox? ' + 5533 'See https://bit.ly/getsizebug1' ); 5534 } 5535 return style; 5536} 5537 5538// -------------------------- setup -------------------------- // 5539 5540var isSetup = false; 5541 5542var isBoxSizeOuter; 5543 5544/** 5545 * setup 5546 * check isBoxSizerOuter 5547 * do on first getSize() rather than on page load for Firefox bug 5548 */ 5549function setup() { 5550 // setup once 5551 if ( isSetup ) { 5552 return; 5553 } 5554 isSetup = true; 5555 5556 // -------------------------- box sizing -------------------------- // 5557 5558 /** 5559 * Chrome & Safari measure the outer-width on style.width on border-box elems 5560 * IE11 & Firefox<29 measures the inner-width 5561 */ 5562 var div = document.createElement('div'); 5563 div.style.width = '200px'; 5564 div.style.padding = '1px 2px 3px 4px'; 5565 div.style.borderStyle = 'solid'; 5566 div.style.borderWidth = '1px 2px 3px 4px'; 5567 div.style.boxSizing = 'border-box'; 5568 5569 var body = document.body || document.documentElement; 5570 body.appendChild( div ); 5571 var style = getStyle( div ); 5572 // round value for browser zoom. desandro/masonry#928 5573 isBoxSizeOuter = Math.round( getStyleSize( style.width ) ) == 200; 5574 getSize.isBoxSizeOuter = isBoxSizeOuter; 5575 5576 body.removeChild( div ); 5577} 5578 5579// -------------------------- getSize -------------------------- // 5580 5581function getSize( elem ) { 5582 setup(); 5583 5584 // use querySeletor if elem is string 5585 if ( typeof elem == 'string' ) { 5586 elem = document.querySelector( elem ); 5587 } 5588 5589 // do not proceed on non-objects 5590 if ( !elem || typeof elem != 'object' || !elem.nodeType ) { 5591 return; 5592 } 5593 5594 var style = getStyle( elem ); 5595 5596 // if hidden, everything is 0 5597 if ( style.display == 'none' ) { 5598 return getZeroSize(); 5599 } 5600 5601 var size = {}; 5602 size.width = elem.offsetWidth; 5603 size.height = elem.offsetHeight; 5604 5605 var isBorderBox = size.isBorderBox = style.boxSizing == 'border-box'; 5606 5607 // get all measurements 5608 for ( var i=0; i < measurementsLength; i++ ) { 5609 var measurement = measurements[i]; 5610 var value = style[ measurement ]; 5611 var num = parseFloat( value ); 5612 // any 'auto', 'medium' value will be 0 5613 size[ measurement ] = !isNaN( num ) ? num : 0; 5614 } 5615 5616 var paddingWidth = size.paddingLeft + size.paddingRight; 5617 var paddingHeight = size.paddingTop + size.paddingBottom; 5618 var marginWidth = size.marginLeft + size.marginRight; 5619 var marginHeight = size.marginTop + size.marginBottom; 5620 var borderWidth = size.borderLeftWidth + size.borderRightWidth; 5621 var borderHeight = size.borderTopWidth + size.borderBottomWidth; 5622 5623 var isBorderBoxSizeOuter = isBorderBox && isBoxSizeOuter; 5624 5625 // overwrite width and height if we can get it from style 5626 var styleWidth = getStyleSize( style.width ); 5627 if ( styleWidth !== false ) { 5628 size.width = styleWidth + 5629 // add padding and border unless it's already including it 5630 ( isBorderBoxSizeOuter ? 0 : paddingWidth + borderWidth ); 5631 } 5632 5633 var styleHeight = getStyleSize( style.height ); 5634 if ( styleHeight !== false ) { 5635 size.height = styleHeight + 5636 // add padding and border unless it's already including it 5637 ( isBorderBoxSizeOuter ? 0 : paddingHeight + borderHeight ); 5638 } 5639 5640 size.innerWidth = size.width - ( paddingWidth + borderWidth ); 5641 size.innerHeight = size.height - ( paddingHeight + borderHeight ); 5642 5643 size.outerWidth = size.width + marginWidth; 5644 size.outerHeight = size.height + marginHeight; 5645 5646 return size; 5647} 5648 5649return getSize; 5650 5651}); 5652 5653/** 5654 * matchesSelector v2.0.2 5655 * matchesSelector( element, '.selector' ) 5656 * MIT license 5657 */ 5658 5659/*jshint browser: true, strict: true, undef: true, unused: true */ 5660 5661( function( window, factory ) { 5662 /*global define: false, module: false */ 5663 'use strict'; 5664 // universal module definition 5665 if ( typeof define == 'function' && define.amd ) { 5666 // AMD 5667 define( 'desandro-matches-selector/matches-selector',factory ); 5668 } else if ( typeof module == 'object' && module.exports ) { 5669 // CommonJS 5670 module.exports = factory(); 5671 } else { 5672 // browser global 5673 window.matchesSelector = factory(); 5674 } 5675 5676}( window, function factory() { 5677 'use strict'; 5678 5679 var matchesMethod = ( function() { 5680 var ElemProto = window.Element.prototype; 5681 // check for the standard method name first 5682 if ( ElemProto.matches ) { 5683 return 'matches'; 5684 } 5685 // check un-prefixed 5686 if ( ElemProto.matchesSelector ) { 5687 return 'matchesSelector'; 5688 } 5689 // check vendor prefixes 5690 var prefixes = [ 'webkit', 'moz', 'ms', 'o' ]; 5691 5692 for ( var i=0; i < prefixes.length; i++ ) { 5693 var prefix = prefixes[i]; 5694 var method = prefix + 'MatchesSelector'; 5695 if ( ElemProto[ method ] ) { 5696 return method; 5697 } 5698 } 5699 })(); 5700 5701 return function matchesSelector( elem, selector ) { 5702 return elem[ matchesMethod ]( selector ); 5703 }; 5704 5705})); 5706 5707/** 5708 * Fizzy UI utils v2.0.7 5709 * MIT license 5710 */ 5711 5712/*jshint browser: true, undef: true, unused: true, strict: true */ 5713 5714( function( window, factory ) { 5715 // universal module definition 5716 /*jshint strict: false */ /*globals define, module, require */ 5717 5718 if ( typeof define == 'function' && define.amd ) { 5719 // AMD 5720 define( 'fizzy-ui-utils/utils',[ 5721 'desandro-matches-selector/matches-selector' 5722 ], function( matchesSelector ) { 5723 return factory( window, matchesSelector ); 5724 }); 5725 } else if ( typeof module == 'object' && module.exports ) { 5726 // CommonJS 5727 module.exports = factory( 5728 window, 5729 require('desandro-matches-selector') 5730 ); 5731 } else { 5732 // browser global 5733 window.fizzyUIUtils = factory( 5734 window, 5735 window.matchesSelector 5736 ); 5737 } 5738 5739}( window, function factory( window, matchesSelector ) { 5740 5741 5742 5743var utils = {}; 5744 5745// ----- extend ----- // 5746 5747// extends objects 5748utils.extend = function( a, b ) { 5749 for ( var prop in b ) { 5750 a[ prop ] = b[ prop ]; 5751 } 5752 return a; 5753}; 5754 5755// ----- modulo ----- // 5756 5757utils.modulo = function( num, div ) { 5758 return ( ( num % div ) + div ) % div; 5759}; 5760 5761// ----- makeArray ----- // 5762 5763var arraySlice = Array.prototype.slice; 5764 5765// turn element or nodeList into an array 5766utils.makeArray = function( obj ) { 5767 if ( Array.isArray( obj ) ) { 5768 // use object if already an array 5769 return obj; 5770 } 5771 // return empty array if undefined or null. #6 5772 if ( obj === null || obj === undefined ) { 5773 return []; 5774 } 5775 5776 var isArrayLike = typeof obj == 'object' && typeof obj.length == 'number'; 5777 if ( isArrayLike ) { 5778 // convert nodeList to array 5779 return arraySlice.call( obj ); 5780 } 5781 5782 // array of single index 5783 return [ obj ]; 5784}; 5785 5786// ----- removeFrom ----- // 5787 5788utils.removeFrom = function( ary, obj ) { 5789 var index = ary.indexOf( obj ); 5790 if ( index != -1 ) { 5791 ary.splice( index, 1 ); 5792 } 5793}; 5794 5795// ----- getParent ----- // 5796 5797utils.getParent = function( elem, selector ) { 5798 while ( elem.parentNode && elem != document.body ) { 5799 elem = elem.parentNode; 5800 if ( matchesSelector( elem, selector ) ) { 5801 return elem; 5802 } 5803 } 5804}; 5805 5806// ----- getQueryElement ----- // 5807 5808// use element as selector string 5809utils.getQueryElement = function( elem ) { 5810 if ( typeof elem == 'string' ) { 5811 return document.querySelector( elem ); 5812 } 5813 return elem; 5814}; 5815 5816// ----- handleEvent ----- // 5817 5818// enable .ontype to trigger from .addEventListener( elem, 'type' ) 5819utils.handleEvent = function( event ) { 5820 var method = 'on' + event.type; 5821 if ( this[ method ] ) { 5822 this[ method ]( event ); 5823 } 5824}; 5825 5826// ----- filterFindElements ----- // 5827 5828utils.filterFindElements = function( elems, selector ) { 5829 // make array of elems 5830 elems = utils.makeArray( elems ); 5831 var ffElems = []; 5832 5833 elems.forEach( function( elem ) { 5834 // check that elem is an actual element 5835
5835// START UNCODE EDIT 5836 // if ( !( elem instanceof HTMLElement ) ) { 5837 if ( !( elem instanceof HTMLElement ) && !SiteParameters.is_frontend_editor ) { 5838 // END UNCODE EDIT
vendor: 23,480 bytes, lines 5838-6750
5838 5839 return; 5840 } 5841 // add elem if no selector 5842 if ( !selector ) { 5843 ffElems.push( elem ); 5844 return; 5845 } 5846 // filter & find items if we have a selector 5847 // filter 5848 if ( matchesSelector( elem, selector ) ) { 5849 ffElems.push( elem ); 5850 } 5851 // find children 5852 var childElems = elem.querySelectorAll( selector ); 5853 // concat childElems to filterFound array 5854 for ( var i=0; i < childElems.length; i++ ) { 5855 ffElems.push( childElems[i] ); 5856 } 5857 }); 5858 5859 return ffElems; 5860}; 5861 5862// ----- debounceMethod ----- // 5863 5864utils.debounceMethod = function( _class, methodName, threshold ) { 5865 threshold = threshold || 100; 5866 // original method 5867 var method = _class.prototype[ methodName ]; 5868 var timeoutName = methodName + 'Timeout'; 5869 5870 _class.prototype[ methodName ] = function() { 5871 var timeout = this[ timeoutName ]; 5872 clearTimeout( timeout ); 5873 5874 var args = arguments; 5875 var _this = this; 5876 this[ timeoutName ] = setTimeout( function() { 5877 method.apply( _this, args ); 5878 delete _this[ timeoutName ]; 5879 }, threshold ); 5880 }; 5881}; 5882 5883// ----- docReady ----- // 5884 5885utils.docReady = function( callback ) { 5886 var readyState = document.readyState; 5887 if ( readyState == 'complete' || readyState == 'interactive' ) { 5888 // do async to allow for other scripts to run. metafizzy/flickity#441 5889 setTimeout( callback ); 5890 } else { 5891 document.addEventListener( 'DOMContentLoaded', callback ); 5892 } 5893}; 5894 5895// ----- htmlInit ----- // 5896 5897// http://jamesroberts.name/blog/2010/02/22/string-functions-for-javascript-trim-to-camel-case-to-dashed-and-to-underscore/ 5898utils.toDashed = function( str ) { 5899 return str.replace( /(.)([A-Z])/g, function( match, $1, $2 ) { 5900 return $1 + '-' + $2; 5901 }).toLowerCase(); 5902}; 5903 5904var console = window.console; 5905/** 5906 * allow user to initialize classes via [data-namespace] or .js-namespace class 5907 * htmlInit( Widget, 'widgetName' ) 5908 * options are parsed from data-namespace-options 5909 */ 5910utils.htmlInit = function( WidgetClass, namespace ) { 5911 utils.docReady( function() { 5912 var dashedNamespace = utils.toDashed( namespace ); 5913 var dataAttr = 'data-' + dashedNamespace; 5914 var dataAttrElems = document.querySelectorAll( '[' + dataAttr + ']' ); 5915 var jsDashElems = document.querySelectorAll( '.js-' + dashedNamespace ); 5916 var elems = utils.makeArray( dataAttrElems ) 5917 .concat( utils.makeArray( jsDashElems ) ); 5918 var dataOptionsAttr = dataAttr + '-options'; 5919 var jQuery = window.jQuery; 5920 5921 elems.forEach( function( elem ) { 5922 var attr = elem.getAttribute( dataAttr ) || 5923 elem.getAttribute( dataOptionsAttr ); 5924 var options; 5925 try { 5926 options = attr && JSON.parse( attr ); 5927 } catch ( error ) { 5928 // log error, do not initialize 5929 if ( console ) { 5930 console.error( 'Error parsing ' + dataAttr + ' on ' + elem.className + 5931 ': ' + error ); 5932 } 5933 return; 5934 } 5935 // initialize 5936 var instance = new WidgetClass( elem, options ); 5937 // make available via $().data('namespace') 5938 if ( jQuery ) { 5939 jQuery.data( elem, namespace, instance ); 5940 } 5941 }); 5942 5943 }); 5944}; 5945 5946// ----- ----- // 5947 5948return utils; 5949 5950})); 5951 5952/** 5953 * Outlayer Item 5954 */ 5955 5956( function( window, factory ) { 5957 // universal module definition 5958 /* jshint strict: false */ /* globals define, module, require */ 5959 if ( typeof define == 'function' && define.amd ) { 5960 // AMD - RequireJS 5961 define( 'outlayer/item',[ 5962 'ev-emitter/ev-emitter', 5963 'get-size/get-size' 5964 ], 5965 factory 5966 ); 5967 } else if ( typeof module == 'object' && module.exports ) { 5968 // CommonJS - Browserify, Webpack 5969 module.exports = factory( 5970 require('ev-emitter'), 5971 require('get-size') 5972 ); 5973 } else { 5974 // browser global 5975 window.Outlayer = {}; 5976 window.Outlayer.Item = factory( 5977 window.EvEmitter, 5978 window.getSize 5979 ); 5980 } 5981 5982}( window, function factory( EvEmitter, getSize ) { 5983'use strict'; 5984 5985// ----- helpers ----- // 5986 5987function isEmptyObj( obj ) { 5988 for ( var prop in obj ) { 5989 return false; 5990 } 5991 prop = null; 5992 return true; 5993} 5994 5995// -------------------------- CSS3 support -------------------------- // 5996 5997 5998var docElemStyle = document.documentElement.style; 5999 6000var transitionProperty = typeof docElemStyle.transition == 'string' ? 6001 'transition' : 'WebkitTransition'; 6002var transformProperty = typeof docElemStyle.transform == 'string' ? 6003 'transform' : 'WebkitTransform'; 6004 6005var transitionEndEvent = { 6006 WebkitTransition: 'webkitTransitionEnd', 6007 transition: 'transitionend' 6008}[ transitionProperty ]; 6009 6010// cache all vendor properties that could have vendor prefix 6011var vendorProperties = { 6012 transform: transformProperty, 6013 transition: transitionProperty, 6014 transitionDuration: transitionProperty + 'Duration', 6015 transitionProperty: transitionProperty + 'Property', 6016 transitionDelay: transitionProperty + 'Delay' 6017}; 6018 6019// -------------------------- Item -------------------------- // 6020 6021function Item( element, layout ) { 6022 if ( !element ) { 6023 return; 6024 } 6025 6026 this.element = element; 6027 // parent layout class, i.e. Masonry, Isotope, or Packery 6028 this.layout = layout; 6029 this.position = { 6030 x: 0, 6031 y: 0 6032 }; 6033 6034 this._create(); 6035} 6036 6037// inherit EvEmitter 6038var proto = Item.prototype = Object.create( EvEmitter.prototype ); 6039proto.constructor = Item; 6040 6041proto._create = function() { 6042 // transition objects 6043 this._transn = { 6044 ingProperties: {}, 6045 clean: {}, 6046 onEnd: {} 6047 }; 6048 6049 this.css({ 6050 position: 'absolute' 6051 }); 6052}; 6053 6054// trigger specified handler for event type 6055proto.handleEvent = function( event ) { 6056 var method = 'on' + event.type; 6057 if ( this[ method ] ) { 6058 this[ method ]( event ); 6059 } 6060}; 6061 6062proto.getSize = function() { 6063 this.size = getSize( this.element ); 6064}; 6065 6066/** 6067 * apply CSS styles to element 6068 * @param {Object} style 6069 */ 6070proto.css = function( style ) { 6071 var elemStyle = this.element.style; 6072 6073 for ( var prop in style ) { 6074 // use vendor property if available 6075 var supportedProp = vendorProperties[ prop ] || prop; 6076 elemStyle[ supportedProp ] = style[ prop ]; 6077 } 6078}; 6079 6080 // measure position, and sets it 6081proto.getPosition = function() { 6082 var style = getComputedStyle( this.element ); 6083 var isOriginLeft = this.layout._getOption('originLeft'); 6084 var isOriginTop = this.layout._getOption('originTop'); 6085 var xValue = style[ isOriginLeft ? 'left' : 'right' ]; 6086 var yValue = style[ isOriginTop ? 'top' : 'bottom' ]; 6087 var x = parseFloat( xValue ); 6088 var y = parseFloat( yValue ); 6089 // convert percent to pixels 6090 var layoutSize = this.layout.size; 6091 if ( xValue.indexOf('%') != -1 ) { 6092 x = ( x / 100 ) * layoutSize.width; 6093 } 6094 if ( yValue.indexOf('%') != -1 ) { 6095 y = ( y / 100 ) * layoutSize.height; 6096 } 6097 // clean up 'auto' or other non-integer values 6098 x = isNaN( x ) ? 0 : x; 6099 y = isNaN( y ) ? 0 : y; 6100 // remove padding from measurement 6101 x -= isOriginLeft ? layoutSize.paddingLeft : layoutSize.paddingRight; 6102 y -= isOriginTop ? layoutSize.paddingTop : layoutSize.paddingBottom; 6103 6104 this.position.x = x; 6105 this.position.y = y; 6106}; 6107 6108// set settled position, apply padding 6109proto.layoutPosition = function() { 6110 var layoutSize = this.layout.size; 6111 var style = {}; 6112 var isOriginLeft = this.layout._getOption('originLeft'); 6113 var isOriginTop = this.layout._getOption('originTop'); 6114 6115 // x 6116 var xPadding = isOriginLeft ? 'paddingLeft' : 'paddingRight'; 6117 var xProperty = isOriginLeft ? 'left' : 'right'; 6118 var xResetProperty = isOriginLeft ? 'right' : 'left'; 6119 6120 var x = this.position.x + layoutSize[ xPadding ]; 6121 // set in percentage or pixels 6122 style[ xProperty ] = this.getXValue( x ); 6123 // reset other property 6124 style[ xResetProperty ] = ''; 6125 6126 // y 6127 var yPadding = isOriginTop ? 'paddingTop' : 'paddingBottom'; 6128 var yProperty = isOriginTop ? 'top' : 'bottom'; 6129 var yResetProperty = isOriginTop ? 'bottom' : 'top'; 6130 6131 var y = this.position.y + layoutSize[ yPadding ]; 6132 // set in percentage or pixels 6133 style[ yProperty ] = this.getYValue( y ); 6134 // reset other property 6135 style[ yResetProperty ] = ''; 6136 6137 this.css( style ); 6138 this.emitEvent( 'layout', [ this ] ); 6139}; 6140 6141proto.getXValue = function( x ) { 6142 var isHorizontal = this.layout._getOption('horizontal'); 6143 return this.layout.options.percentPosition && !isHorizontal ? 6144 ( ( x / this.layout.size.width ) * 100 ) + '%' : x + 'px'; 6145}; 6146 6147proto.getYValue = function( y ) { 6148 var isHorizontal = this.layout._getOption('horizontal'); 6149 return this.layout.options.percentPosition && isHorizontal ? 6150 ( ( y / this.layout.size.height ) * 100 ) + '%' : y + 'px'; 6151}; 6152 6153proto._transitionTo = function( x, y ) { 6154 this.getPosition(); 6155 // get current x & y from top/left 6156 var curX = this.position.x; 6157 var curY = this.position.y; 6158 6159 var didNotMove = x == this.position.x && y == this.position.y; 6160 6161 // save end position 6162 this.setPosition( x, y ); 6163 6164 // if did not move and not transitioning, just go to layout 6165 if ( didNotMove && !this.isTransitioning ) { 6166 this.layoutPosition(); 6167 return; 6168 } 6169 6170 var transX = x - curX; 6171 var transY = y - curY; 6172 var transitionStyle = {}; 6173 transitionStyle.transform = this.getTranslate( transX, transY ); 6174 6175 this.transition({ 6176 to: transitionStyle, 6177 onTransitionEnd: { 6178 transform: this.layoutPosition 6179 }, 6180 isCleaning: true 6181 }); 6182}; 6183 6184proto.getTranslate = function( x, y ) { 6185 // flip cooridinates if origin on right or bottom 6186 var isOriginLeft = this.layout._getOption('originLeft'); 6187 var isOriginTop = this.layout._getOption('originTop'); 6188 x = isOriginLeft ? x : -x; 6189 y = isOriginTop ? y : -y; 6190 return 'translate3d(' + x + 'px, ' + y + 'px, 0)'; 6191}; 6192 6193// non transition + transform support 6194proto.goTo = function( x, y ) { 6195 this.setPosition( x, y ); 6196 this.layoutPosition(); 6197}; 6198 6199proto.moveTo = proto._transitionTo; 6200 6201proto.setPosition = function( x, y ) { 6202 this.position.x = parseFloat( x ); 6203 this.position.y = parseFloat( y ); 6204}; 6205 6206// ----- transition ----- // 6207 6208/** 6209 * @param {Object} style - CSS 6210 * @param {Function} onTransitionEnd 6211 */ 6212 6213// non transition, just trigger callback 6214proto._nonTransition = function( args ) { 6215 this.css( args.to ); 6216 if ( args.isCleaning ) { 6217 this._removeStyles( args.to ); 6218 } 6219 for ( var prop in args.onTransitionEnd ) { 6220 args.onTransitionEnd[ prop ].call( this ); 6221 } 6222}; 6223 6224/** 6225 * proper transition 6226 * @param {Object} args - arguments 6227 * @param {Object} to - style to transition to 6228 * @param {Object} from - style to start transition from 6229 * @param {Boolean} isCleaning - removes transition styles after transition 6230 * @param {Function} onTransitionEnd - callback 6231 */ 6232proto.transition = function( args ) { 6233 // redirect to nonTransition if no transition duration 6234 if ( !parseFloat( this.layout.options.transitionDuration ) ) { 6235 this._nonTransition( args ); 6236 return; 6237 } 6238 6239 var _transition = this._transn; 6240 // keep track of onTransitionEnd callback by css property 6241 for ( var prop in args.onTransitionEnd ) { 6242 _transition.onEnd[ prop ] = args.onTransitionEnd[ prop ]; 6243 } 6244 // keep track of properties that are transitioning 6245 for ( prop in args.to ) { 6246 _transition.ingProperties[ prop ] = true; 6247 // keep track of properties to clean up when transition is done 6248 if ( args.isCleaning ) { 6249 _transition.clean[ prop ] = true; 6250 } 6251 } 6252 6253 // set from styles 6254 if ( args.from ) { 6255 this.css( args.from ); 6256 // force redraw. http://blog.alexmaccaw.com/css-transitions 6257 var h = this.element.offsetHeight; 6258 // hack for JSHint to hush about unused var 6259 h = null; 6260 } 6261 // enable transition 6262 this.enableTransition( args.to ); 6263 // set styles that are transitioning 6264 this.css( args.to ); 6265 6266 this.isTransitioning = true; 6267 6268}; 6269 6270// dash before all cap letters, including first for 6271// WebkitTransform => -webkit-transform 6272function toDashedAll( str ) { 6273 return str.replace( /([A-Z])/g, function( $1 ) { 6274 return '-' + $1.toLowerCase(); 6275 }); 6276} 6277 6278var transitionProps = 'opacity,' + toDashedAll( transformProperty ); 6279 6280proto.enableTransition = function(/* style */) { 6281 // HACK changing transitionProperty during a transition 6282 // will cause transition to jump 6283 if ( this.isTransitioning ) { 6284 return; 6285 } 6286 6287 // make `transition: foo, bar, baz` from style object 6288 // HACK un-comment this when enableTransition can work 6289 // while a transition is happening 6290 // var transitionValues = []; 6291 // for ( var prop in style ) { 6292 // // dash-ify camelCased properties like WebkitTransition 6293 // prop = vendorProperties[ prop ] || prop; 6294 // transitionValues.push( toDashedAll( prop ) ); 6295 // } 6296 // munge number to millisecond, to match stagger 6297 var duration = this.layout.options.transitionDuration; 6298 duration = typeof duration == 'number' ? duration + 'ms' : duration; 6299 // enable transition styles 6300 this.css({ 6301 transitionProperty: transitionProps, 6302 transitionDuration: duration, 6303 transitionDelay: this.staggerDelay || 0 6304 }); 6305 // listen for transition end event 6306 this.element.addEventListener( transitionEndEvent, this, false ); 6307}; 6308 6309// ----- events ----- // 6310 6311proto.onwebkitTransitionEnd = function( event ) { 6312 this.ontransitionend( event ); 6313}; 6314 6315proto.onotransitionend = function( event ) { 6316 this.ontransitionend( event ); 6317}; 6318 6319// properties that I munge to make my life easier 6320var dashedVendorProperties = { 6321 '-webkit-transform': 'transform' 6322}; 6323 6324proto.ontransitionend = function( event ) { 6325 // disregard bubbled events from children 6326 if ( event.target !== this.element ) { 6327 return; 6328 } 6329 var _transition = this._transn; 6330 // get property name of transitioned property, convert to prefix-free 6331 var propertyName = dashedVendorProperties[ event.propertyName ] || event.propertyName; 6332 6333 // remove property that has completed transitioning 6334 delete _transition.ingProperties[ propertyName ]; 6335 // check if any properties are still transitioning 6336 if ( isEmptyObj( _transition.ingProperties ) ) { 6337 // all properties have completed transitioning 6338 this.disableTransition(); 6339 } 6340 // clean style 6341 if ( propertyName in _transition.clean ) { 6342 // clean up style 6343 this.element.style[ event.propertyName ] = ''; 6344 delete _transition.clean[ propertyName ]; 6345 } 6346 // trigger onTransitionEnd callback 6347 if ( propertyName in _transition.onEnd ) { 6348 var onTransitionEnd = _transition.onEnd[ propertyName ]; 6349 onTransitionEnd.call( this ); 6350 delete _transition.onEnd[ propertyName ]; 6351 } 6352 6353 this.emitEvent( 'transitionEnd', [ this ] ); 6354}; 6355 6356proto.disableTransition = function() { 6357 this.removeTransitionStyles(); 6358 this.element.removeEventListener( transitionEndEvent, this, false ); 6359 this.isTransitioning = false; 6360}; 6361 6362/** 6363 * removes style property from element 6364 * @param {Object} style 6365**/ 6366proto._removeStyles = function( style ) { 6367 // clean up transition styles 6368 var cleanStyle = {}; 6369 for ( var prop in style ) { 6370 cleanStyle[ prop ] = ''; 6371 } 6372 this.css( cleanStyle ); 6373}; 6374 6375var cleanTransitionStyle = { 6376 transitionProperty: '', 6377 transitionDuration: '', 6378 transitionDelay: '' 6379}; 6380 6381proto.removeTransitionStyles = function() { 6382 // remove transition 6383 this.css( cleanTransitionStyle ); 6384}; 6385 6386// ----- stagger ----- // 6387 6388proto.stagger = function( delay ) { 6389 delay = isNaN( delay ) ? 0 : delay; 6390 this.staggerDelay = delay + 'ms'; 6391}; 6392 6393// ----- show/hide/remove ----- // 6394 6395// remove element from DOM 6396proto.removeElem = function() { 6397 this.element.parentNode.removeChild( this.element ); 6398 // remove display: none 6399 this.css({ display: '' }); 6400 this.emitEvent( 'remove', [ this ] ); 6401}; 6402 6403proto.remove = function() { 6404 // just remove element if no transition support or no transition 6405 if ( !transitionProperty || !parseFloat( this.layout.options.transitionDuration ) ) { 6406 this.removeElem(); 6407 return; 6408 } 6409 6410 // start transition 6411 this.once( 'transitionEnd', function() { 6412 this.removeElem(); 6413 }); 6414 this.hide(); 6415}; 6416 6417proto.reveal = function() { 6418 delete this.isHidden; 6419 // remove display: none 6420 this.css({ display: '' }); 6421 6422 var options = this.layout.options; 6423 6424 var onTransitionEnd = {}; 6425 var transitionEndProperty = this.getHideRevealTransitionEndProperty('visibleStyle'); 6426 onTransitionEnd[ transitionEndProperty ] = this.onRevealTransitionEnd; 6427 6428 this.transition({ 6429 from: options.hiddenStyle, 6430 to: options.visibleStyle, 6431 isCleaning: true, 6432 onTransitionEnd: onTransitionEnd 6433 }); 6434}; 6435 6436proto.onRevealTransitionEnd = function() { 6437 // check if still visible 6438 // during transition, item may have been hidden 6439 if ( !this.isHidden ) { 6440 this.emitEvent('reveal'); 6441 } 6442}; 6443 6444/** 6445 * get style property use for hide/reveal transition end 6446 * @param {String} styleProperty - hiddenStyle/visibleStyle 6447 * @returns {String} 6448 */ 6449proto.getHideRevealTransitionEndProperty = function( styleProperty ) { 6450 var optionStyle = this.layout.options[ styleProperty ]; 6451 // use opacity 6452 if ( optionStyle.opacity ) { 6453 return 'opacity'; 6454 } 6455 // get first property 6456 for ( var prop in optionStyle ) { 6457 return prop; 6458 } 6459}; 6460 6461proto.hide = function() { 6462 // set flag 6463 this.isHidden = true; 6464 // remove display: none 6465 this.css({ display: '' }); 6466 6467 var options = this.layout.options; 6468 6469 var onTransitionEnd = {}; 6470 var transitionEndProperty = this.getHideRevealTransitionEndProperty('hiddenStyle'); 6471 onTransitionEnd[ transitionEndProperty ] = this.onHideTransitionEnd; 6472 6473 this.transition({ 6474 from: options.visibleStyle, 6475 to: options.hiddenStyle, 6476 // keep hidden stuff hidden 6477 isCleaning: true, 6478 onTransitionEnd: onTransitionEnd 6479 }); 6480}; 6481 6482proto.onHideTransitionEnd = function() { 6483 // check if still hidden 6484 // during transition, item may have been un-hidden 6485 if ( this.isHidden ) { 6486 this.css({ display: 'none' }); 6487 this.emitEvent('hide'); 6488 } 6489}; 6490 6491proto.destroy = function() { 6492 this.css({ 6493 position: '', 6494 left: '', 6495 right: '', 6496 top: '', 6497 bottom: '', 6498 transition: '', 6499 transform: '' 6500 }); 6501}; 6502 6503return Item; 6504 6505})); 6506 6507/*! 6508 * Outlayer v2.1.1 6509 * the brains and guts of a layout library 6510 * MIT license 6511 */ 6512 6513( function( window, factory ) { 6514 'use strict'; 6515 // universal module definition 6516 /* jshint strict: false */ /* globals define, module, require */ 6517 if ( typeof define == 'function' && define.amd ) { 6518 // AMD - RequireJS 6519 define( 'outlayer/outlayer',[ 6520 'ev-emitter/ev-emitter', 6521 'get-size/get-size', 6522 'fizzy-ui-utils/utils', 6523 './item' 6524 ], 6525 function( EvEmitter, getSize, utils, Item ) { 6526 return factory( window, EvEmitter, getSize, utils, Item); 6527 } 6528 ); 6529 } else if ( typeof module == 'object' && module.exports ) { 6530 // CommonJS - Browserify, Webpack 6531 module.exports = factory( 6532 window, 6533 require('ev-emitter'), 6534 require('get-size'), 6535 require('fizzy-ui-utils'), 6536 require('./item') 6537 ); 6538 } else { 6539 // browser global 6540 window.Outlayer = factory( 6541 window, 6542 window.EvEmitter, 6543 window.getSize, 6544 window.fizzyUIUtils, 6545 window.Outlayer.Item 6546 ); 6547 } 6548 6549}( window, function factory( window, EvEmitter, getSize, utils, Item ) { 6550'use strict'; 6551 6552// ----- vars ----- // 6553 6554var console = window.console; 6555var jQuery = window.jQuery; 6556var noop = function() {}; 6557 6558// -------------------------- Outlayer -------------------------- // 6559 6560// globally unique identifiers 6561var GUID = 0; 6562// internal store of all Outlayer intances 6563var instances = {}; 6564 6565 6566/** 6567 * @param {Element, String} element 6568 * @param {Object} options 6569 * @constructor 6570 */ 6571function Outlayer( element, options ) { 6572 var queryElement = utils.getQueryElement( element ); 6573 if ( !queryElement ) { 6574 if ( console ) { 6575 console.error( 'Bad element for ' + this.constructor.namespace + 6576 ': ' + ( queryElement || element ) ); 6577 } 6578 return; 6579 } 6580 this.element = queryElement; 6581 // add jQuery 6582 if ( jQuery ) { 6583 this.$element = jQuery( this.element ); 6584 } 6585 6586 // options 6587 this.options = utils.extend( {}, this.constructor.defaults ); 6588 this.option( options ); 6589 6590 // add id for Outlayer.getFromElement 6591 var id = ++GUID; 6592 this.element.outlayerGUID = id; // expando 6593 instances[ id ] = this; // associate via id 6594 6595 // kick it off 6596 this._create(); 6597 6598 var isInitLayout = this._getOption('initLayout'); 6599 if ( isInitLayout ) { 6600 this.layout(); 6601 } 6602} 6603 6604// settings are for internal use only 6605Outlayer.namespace = 'outlayer'; 6606Outlayer.Item = Item; 6607 6608// default options 6609Outlayer.defaults = { 6610 containerStyle: { 6611 position: 'relative' 6612 }, 6613 initLayout: true, 6614 originLeft: true, 6615 originTop: true, 6616 resize: true, 6617 resizeContainer: true, 6618 // item options 6619 transitionDuration: '0.4s', 6620 hiddenStyle: { 6621 opacity: 0, 6622 transform: 'scale(0.001)' 6623 }, 6624 visibleStyle: { 6625 opacity: 1, 6626 transform: 'scale(1)' 6627 } 6628}; 6629 6630var proto = Outlayer.prototype; 6631// inherit EvEmitter 6632utils.extend( proto, EvEmitter.prototype ); 6633 6634/** 6635 * set options 6636 * @param {Object} opts 6637 */ 6638proto.option = function( opts ) { 6639 utils.extend( this.options, opts ); 6640}; 6641 6642/** 6643 * get backwards compatible option value, check old name 6644 */ 6645proto._getOption = function( option ) { 6646 var oldOption = this.constructor.compatOptions[ option ]; 6647 return oldOption && this.options[ oldOption ] !== undefined ? 6648 this.options[ oldOption ] : this.options[ option ]; 6649}; 6650 6651Outlayer.compatOptions = { 6652 // currentName: oldName 6653 initLayout: 'isInitLayout', 6654 horizontal: 'isHorizontal', 6655 layoutInstant: 'isLayoutInstant', 6656 originLeft: 'isOriginLeft', 6657 originTop: 'isOriginTop', 6658 resize: 'isResizeBound', 6659 resizeContainer: 'isResizingContainer' 6660}; 6661 6662proto._create = function() { 6663 // get items from children 6664 this.reloadItems(); 6665 // elements that affect layout, but are not laid out 6666 this.stamps = []; 6667 this.stamp( this.options.stamp ); 6668 // set container style 6669 utils.extend( this.element.style, this.options.containerStyle ); 6670 6671 // bind resize method 6672 var canBindResize = this._getOption('resize'); 6673 if ( canBindResize ) { 6674 this.bindResize(); 6675 } 6676}; 6677 6678// goes through all children again and gets bricks in proper order 6679proto.reloadItems = function() { 6680 // collection of item elements 6681 this.items = this._itemize( this.element.children ); 6682}; 6683 6684 6685/** 6686 * turn elements into Outlayer.Items to be used in layout 6687 * @param {Array or NodeList or HTMLElement} elems 6688 * @returns {Array} items - collection of new Outlayer Items 6689 */ 6690proto._itemize = function( elems ) { 6691 6692 var itemElems = this._filterFindItemElements( elems ); 6693 var Item = this.constructor.Item; 6694 6695 // create new Outlayer Items for collection 6696 var items = []; 6697 for ( var i=0; i < itemElems.length; i++ ) { 6698 var elem = itemElems[i]; 6699 var item = new Item( elem, this ); 6700 items.push( item ); 6701 } 6702 6703 return items; 6704}; 6705 6706/** 6707 * get item elements to be used in layout 6708 * @param {Array or NodeList or HTMLElement} elems 6709 * @returns {Array} items - item elements 6710 */ 6711proto._filterFindItemElements = function( elems ) { 6712 return utils.filterFindElements( elems, this.options.itemSelector ); 6713}; 6714 6715/** 6716 * getter method for getting item elements 6717 * @returns {Array} elems - collection of item elements 6718 */ 6719proto.getItemElements = function() { 6720 return this.items.map( function( item ) { 6721 return item.element; 6722 }); 6723}; 6724 6725// ----- init & layout ----- // 6726 6727/** 6728 * lays out all items 6729 */ 6730proto.layout = function() { 6731 this._resetLayout(); 6732 this._manageStamps(); 6733 6734 // don't animate first layout 6735 var layoutInstant = this._getOption('layoutInstant'); 6736 var isInstant = layoutInstant !== undefined ? 6737 layoutInstant : !this._isLayoutInited; 6738 this.layoutItems( this.items, isInstant ); 6739 6740 // flag for initalized 6741 this._isLayoutInited = true; 6742}; 6743 6744// _init is alias for layout 6745proto._init = proto.layout; 6746 6747/** 6748 * logic before any new layout 6749 */ 6750proto._resetLayout = function() {
vendor: 13,499 bytes, lines 6751-7319
6751 this.getSize(); 6752}; 6753 6754 6755proto.getSize = function() { 6756 this.size = getSize( this.element ); 6757}; 6758 6759/** 6760 * get measurement from option, for columnWidth, rowHeight, gutter 6761 * if option is String -> get element from selector string, & get size of element 6762 * if option is Element -> get size of element 6763 * else use option as a number 6764 * 6765 * @param {String} measurement 6766 * @param {String} size - width or height 6767 * @private 6768 */ 6769proto._getMeasurement = function( measurement, size ) { 6770 var option = this.options[ measurement ]; 6771 var elem; 6772 if ( !option ) { 6773 // default to 0 6774 this[ measurement ] = 0; 6775 } else { 6776 // use option as an element 6777 if ( typeof option == 'string' ) { 6778 elem = this.element.querySelector( option ); 6779 } else if ( option instanceof HTMLElement ) { 6780 elem = option; 6781 } 6782 // use size of element, if element 6783 this[ measurement ] = elem ? getSize( elem )[ size ] : option; 6784 } 6785}; 6786 6787/** 6788 * layout a collection of item elements 6789 * @api public 6790 */ 6791proto.layoutItems = function( items, isInstant ) { 6792 items = this._getItemsForLayout( items ); 6793 6794 this._layoutItems( items, isInstant ); 6795 6796 this._postLayout(); 6797}; 6798 6799/** 6800 * get the items to be laid out 6801 * you may want to skip over some items 6802 * @param {Array} items 6803 * @returns {Array} items 6804 */ 6805proto._getItemsForLayout = function( items ) { 6806 return items.filter( function( item ) { 6807 return !item.isIgnored; 6808 }); 6809}; 6810 6811/** 6812 * layout items 6813 * @param {Array} items 6814 * @param {Boolean} isInstant 6815 */ 6816proto._layoutItems = function( items, isInstant ) { 6817 this._emitCompleteOnItems( 'layout', items ); 6818 6819 if ( !items || !items.length ) { 6820 // no items, emit event with empty array 6821 return; 6822 } 6823 6824 var queue = []; 6825 6826 items.forEach( function( item ) { 6827 // get x/y object from method 6828 var position = this._getItemLayoutPosition( item ); 6829 // enqueue 6830 position.item = item; 6831 position.isInstant = isInstant || item.isLayoutInstant; 6832 queue.push( position ); 6833 }, this ); 6834 6835 this._processLayoutQueue( queue ); 6836}; 6837 6838/** 6839 * get item layout position 6840 * @param {Outlayer.Item} item 6841 * @returns {Object} x and y position 6842 */ 6843proto._getItemLayoutPosition = function( /* item */ ) { 6844 return { 6845 x: 0, 6846 y: 0 6847 }; 6848}; 6849 6850/** 6851 * iterate over array and position each item 6852 * Reason being - separating this logic prevents 'layout invalidation' 6853 * thx @paul_irish 6854 * @param {Array} queue 6855 */ 6856proto._processLayoutQueue = function( queue ) { 6857 this.updateStagger(); 6858 queue.forEach( function( obj, i ) { 6859 this._positionItem( obj.item, obj.x, obj.y, obj.isInstant, i ); 6860 }, this ); 6861}; 6862 6863// set stagger from option in milliseconds number 6864proto.updateStagger = function() { 6865 var stagger = this.options.stagger; 6866 if ( stagger === null || stagger === undefined ) { 6867 this.stagger = 0; 6868 return; 6869 } 6870 this.stagger = getMilliseconds( stagger ); 6871 return this.stagger; 6872}; 6873 6874/** 6875 * Sets position of item in DOM 6876 * @param {Outlayer.Item} item 6877 * @param {Number} x - horizontal position 6878 * @param {Number} y - vertical position 6879 * @param {Boolean} isInstant - disables transitions 6880 */ 6881proto._positionItem = function( item, x, y, isInstant, i ) { 6882 if ( isInstant ) { 6883 // if not transition, just set CSS 6884 item.goTo( x, y ); 6885 } else { 6886 item.stagger( i * this.stagger ); 6887 item.moveTo( x, y ); 6888 } 6889}; 6890 6891/** 6892 * Any logic you want to do after each layout, 6893 * i.e. size the container 6894 */ 6895proto._postLayout = function() { 6896 this.resizeContainer(); 6897}; 6898 6899proto.resizeContainer = function() { 6900 var isResizingContainer = this._getOption('resizeContainer'); 6901 if ( !isResizingContainer ) { 6902 return; 6903 } 6904 var size = this._getContainerSize(); 6905 if ( size ) { 6906 this._setContainerMeasure( size.width, true ); 6907 this._setContainerMeasure( size.height, false ); 6908 } 6909}; 6910 6911/** 6912 * Sets width or height of container if returned 6913 * @returns {Object} size 6914 * @param {Number} width 6915 * @param {Number} height 6916 */ 6917proto._getContainerSize = noop; 6918 6919/** 6920 * @param {Number} measure - size of width or height 6921 * @param {Boolean} isWidth 6922 */ 6923proto._setContainerMeasure = function( measure, isWidth ) { 6924 if ( measure === undefined ) { 6925 return; 6926 } 6927 6928 var elemSize = this.size; 6929 // add padding and border width if border box 6930 if ( elemSize.isBorderBox ) { 6931 measure += isWidth ? elemSize.paddingLeft + elemSize.paddingRight + 6932 elemSize.borderLeftWidth + elemSize.borderRightWidth : 6933 elemSize.paddingBottom + elemSize.paddingTop + 6934 elemSize.borderTopWidth + elemSize.borderBottomWidth; 6935 } 6936 6937 measure = Math.max( measure, 0 ); 6938 this.element.style[ isWidth ? 'width' : 'height' ] = measure + 'px'; 6939}; 6940 6941/** 6942 * emit eventComplete on a collection of items events 6943 * @param {String} eventName 6944 * @param {Array} items - Outlayer.Items 6945 */ 6946proto._emitCompleteOnItems = function( eventName, items ) { 6947 var _this = this; 6948 function onComplete() { 6949 _this.dispatchEvent( eventName + 'Complete', null, [ items ] ); 6950 } 6951 6952 var count = items.length; 6953 if ( !items || !count ) { 6954 onComplete(); 6955 return; 6956 } 6957 6958 var doneCount = 0; 6959 function tick() { 6960 doneCount++; 6961 if ( doneCount == count ) { 6962 onComplete(); 6963 } 6964 } 6965 6966 // bind callback 6967 items.forEach( function( item ) { 6968 item.once( eventName, tick ); 6969 }); 6970}; 6971 6972/** 6973 * emits events via EvEmitter and jQuery events 6974 * @param {String} type - name of event 6975 * @param {Event} event - original event 6976 * @param {Array} args - extra arguments 6977 */ 6978proto.dispatchEvent = function( type, event, args ) { 6979 // add original event to arguments 6980 var emitArgs = event ? [ event ].concat( args ) : args; 6981 this.emitEvent( type, emitArgs ); 6982 6983 if ( jQuery ) { 6984 // set this.$element 6985 this.$element = this.$element || jQuery( this.element ); 6986 if ( event ) { 6987 // create jQuery event 6988 var $event = jQuery.Event( event ); 6989 $event.type = type; 6990 this.$element.trigger( $event, args ); 6991 } else { 6992 // just trigger with type if no event available 6993 this.$element.trigger( type, args ); 6994 } 6995 } 6996}; 6997 6998// -------------------------- ignore & stamps -------------------------- // 6999 7000 7001/** 7002 * keep item in collection, but do not lay it out 7003 * ignored items do not get skipped in layout 7004 * @param {Element} elem 7005 */ 7006proto.ignore = function( elem ) { 7007 var item = this.getItem( elem ); 7008 if ( item ) { 7009 item.isIgnored = true; 7010 } 7011}; 7012 7013/** 7014 * return item to layout collection 7015 * @param {Element} elem 7016 */ 7017proto.unignore = function( elem ) { 7018 var item = this.getItem( elem ); 7019 if ( item ) { 7020 delete item.isIgnored; 7021 } 7022}; 7023 7024/** 7025 * adds elements to stamps 7026 * @param {NodeList, Array, Element, or String} elems 7027 */ 7028proto.stamp = function( elems ) { 7029 elems = this._find( elems ); 7030 if ( !elems ) { 7031 return; 7032 } 7033 7034 this.stamps = this.stamps.concat( elems ); 7035 // ignore 7036 elems.forEach( this.ignore, this ); 7037}; 7038 7039/** 7040 * removes elements to stamps 7041 * @param {NodeList, Array, or Element} elems 7042 */ 7043proto.unstamp = function( elems ) { 7044 elems = this._find( elems ); 7045 if ( !elems ){ 7046 return; 7047 } 7048 7049 elems.forEach( function( elem ) { 7050 // filter out removed stamp elements 7051 utils.removeFrom( this.stamps, elem ); 7052 this.unignore( elem ); 7053 }, this ); 7054}; 7055 7056/** 7057 * finds child elements 7058 * @param {NodeList, Array, Element, or String} elems 7059 * @returns {Array} elems 7060 */ 7061proto._find = function( elems ) { 7062 if ( !elems ) { 7063 return; 7064 } 7065 // if string, use argument as selector string 7066 if ( typeof elems == 'string' ) { 7067 elems = this.element.querySelectorAll( elems ); 7068 } 7069 elems = utils.makeArray( elems ); 7070 return elems; 7071}; 7072 7073proto._manageStamps = function() { 7074 if ( !this.stamps || !this.stamps.length ) { 7075 return; 7076 } 7077 7078 this._getBoundingRect(); 7079 7080 this.stamps.forEach( this._manageStamp, this ); 7081}; 7082 7083// update boundingLeft / Top 7084proto._getBoundingRect = function() { 7085 // get bounding rect for container element 7086 var boundingRect = this.element.getBoundingClientRect(); 7087 var size = this.size; 7088 this._boundingRect = { 7089 left: boundingRect.left + size.paddingLeft + size.borderLeftWidth, 7090 top: boundingRect.top + size.paddingTop + size.borderTopWidth, 7091 right: boundingRect.right - ( size.paddingRight + size.borderRightWidth ), 7092 bottom: boundingRect.bottom - ( size.paddingBottom + size.borderBottomWidth ) 7093 }; 7094}; 7095 7096/** 7097 * @param {Element} stamp 7098**/ 7099proto._manageStamp = noop; 7100 7101/** 7102 * get x/y position of element relative to container element 7103 * @param {Element} elem 7104 * @returns {Object} offset - has left, top, right, bottom 7105 */ 7106proto._getElementOffset = function( elem ) { 7107 var boundingRect = elem.getBoundingClientRect(); 7108 var thisRect = this._boundingRect; 7109 var size = getSize( elem ); 7110 var offset = { 7111 left: boundingRect.left - thisRect.left - size.marginLeft, 7112 top: boundingRect.top - thisRect.top - size.marginTop, 7113 right: thisRect.right - boundingRect.right - size.marginRight, 7114 bottom: thisRect.bottom - boundingRect.bottom - size.marginBottom 7115 }; 7116 return offset; 7117}; 7118 7119// -------------------------- resize -------------------------- // 7120 7121// enable event handlers for listeners 7122// i.e. resize -> onresize 7123proto.handleEvent = utils.handleEvent; 7124 7125/** 7126 * Bind layout to window resizing 7127 */ 7128proto.bindResize = function() { 7129 window.addEventListener( 'resize', this ); 7130 this.isResizeBound = true; 7131}; 7132 7133/** 7134 * Unbind layout to window resizing 7135 */ 7136proto.unbindResize = function() { 7137 window.removeEventListener( 'resize', this ); 7138 this.isResizeBound = false; 7139}; 7140 7141proto.onresize = function() { 7142 this.resize(); 7143}; 7144 7145utils.debounceMethod( Outlayer, 'onresize', 100 ); 7146 7147proto.resize = function() { 7148 // don't trigger if size did not change 7149 // or if resize was unbound. See #9 7150 if ( !this.isResizeBound || !this.needsResizeLayout() ) { 7151 return; 7152 } 7153 7154 this.layout(); 7155}; 7156 7157/** 7158 * check if layout is needed post layout 7159 * @returns Boolean 7160 */ 7161proto.needsResizeLayout = function() { 7162 var size = getSize( this.element ); 7163 // check that this.size and size are there 7164 // IE8 triggers resize on body size change, so they might not be 7165 var hasSizes = this.size && size; 7166 return hasSizes && size.innerWidth !== this.size.innerWidth; 7167}; 7168 7169// -------------------------- methods -------------------------- // 7170 7171/** 7172 * add items to Outlayer instance 7173 * @param {Array or NodeList or Element} elems 7174 * @returns {Array} items - Outlayer.Items 7175**/ 7176proto.addItems = function( elems ) { 7177 var items = this._itemize( elems ); 7178 // add items to collection 7179 if ( items.length ) { 7180 this.items = this.items.concat( items ); 7181 } 7182 return items; 7183}; 7184 7185/** 7186 * Layout newly-appended item elements 7187 * @param {Array or NodeList or Element} elems 7188 */ 7189proto.appended = function( elems ) { 7190 var items = this.addItems( elems ); 7191 if ( !items.length ) { 7192 return; 7193 } 7194 // layout and reveal just the new items 7195 this.layoutItems( items, true ); 7196 this.reveal( items ); 7197}; 7198 7199/** 7200 * Layout prepended elements 7201 * @param {Array or NodeList or Element} elems 7202 */ 7203proto.prepended = function( elems ) { 7204 var items = this._itemize( elems ); 7205 if ( !items.length ) { 7206 return; 7207 } 7208 // add items to beginning of collection 7209 var previousItems = this.items.slice(0); 7210 this.items = items.concat( previousItems ); 7211 // start new layout 7212 this._resetLayout(); 7213 this._manageStamps(); 7214 // layout new stuff without transition 7215 this.layoutItems( items, true ); 7216 this.reveal( items ); 7217 // layout previous items 7218 this.layoutItems( previousItems ); 7219}; 7220 7221/** 7222 * reveal a collection of items 7223 * @param {Array of Outlayer.Items} items 7224 */ 7225proto.reveal = function( items ) { 7226 this._emitCompleteOnItems( 'reveal', items ); 7227 if ( !items || !items.length ) { 7228 return; 7229 } 7230 var stagger = this.updateStagger(); 7231 items.forEach( function( item, i ) { 7232 item.stagger( i * stagger ); 7233 item.reveal(); 7234 }); 7235}; 7236 7237/** 7238 * hide a collection of items 7239 * @param {Array of Outlayer.Items} items 7240 */ 7241proto.hide = function( items ) { 7242 this._emitCompleteOnItems( 'hide', items ); 7243 if ( !items || !items.length ) { 7244 return; 7245 } 7246 var stagger = this.updateStagger(); 7247 items.forEach( function( item, i ) { 7248 item.stagger( i * stagger ); 7249 item.hide(); 7250 }); 7251}; 7252 7253/** 7254 * reveal item elements 7255 * @param {Array}, {Element}, {NodeList} items 7256 */ 7257proto.revealItemElements = function( elems ) { 7258 var items = this.getItems( elems ); 7259 this.reveal( items ); 7260}; 7261 7262/** 7263 * hide item elements 7264 * @param {Array}, {Element}, {NodeList} items 7265 */ 7266proto.hideItemElements = function( elems ) { 7267 var items = this.getItems( elems ); 7268 this.hide( items ); 7269}; 7270 7271/** 7272 * get Outlayer.Item, given an Element 7273 * @param {Element} elem 7274 * @param {Function} callback 7275 * @returns {Outlayer.Item} item 7276 */ 7277proto.getItem = function( elem ) { 7278 // loop through items to get the one that matches 7279 for ( var i=0; i < this.items.length; i++ ) { 7280 var item = this.items[i]; 7281 if ( item.element == elem ) { 7282 // return item 7283 return item; 7284 } 7285 } 7286}; 7287 7288/** 7289 * get collection of Outlayer.Items, given Elements 7290 * @param {Array} elems 7291 * @returns {Array} items - Outlayer.Items 7292 */ 7293proto.getItems = function( elems ) { 7294 elems = utils.makeArray( elems ); 7295 var items = []; 7296 elems.forEach( function( elem ) { 7297 var item = this.getItem( elem ); 7298 if ( item ) { 7299 items.push( item ); 7300 } 7301 }, this ); 7302 7303 return items; 7304}; 7305 7306/** 7307 * remove element(s) from instance and DOM 7308 * @param {Array or NodeList or Element} elems 7309 */ 7310proto.remove = function( elems ) { 7311 var removeItems = this.getItems( elems ); 7312 7313 this._emitCompleteOnItems( 'remove', removeItems ); 7314 7315 // bail if no items to remove 7316 if ( !removeItems || !removeItems.length ) { 7317 return; 7318 } 7319
vendor: 38,285 bytes, lines 7320-8743
7320 removeItems.forEach( function( item ) { 7321 item.remove(); 7322 // remove item from collection 7323 utils.removeFrom( this.items, item ); 7324 }, this ); 7325}; 7326 7327// ----- destroy ----- // 7328 7329// remove and disable Outlayer instance 7330proto.destroy = function() { 7331 // clean up dynamic styles 7332 var style = this.element.style; 7333 style.height = ''; 7334 style.position = ''; 7335 style.width = ''; 7336 // destroy items 7337 this.items.forEach( function( item ) { 7338 item.destroy(); 7339 }); 7340 7341 this.unbindResize(); 7342 7343 var id = this.element.outlayerGUID; 7344 delete instances[ id ]; // remove reference to instance by id 7345 delete this.element.outlayerGUID; 7346 // remove data for jQuery 7347 if ( jQuery ) { 7348 jQuery.removeData( this.element, this.constructor.namespace ); 7349 } 7350 7351}; 7352 7353// -------------------------- data -------------------------- // 7354 7355/** 7356 * get Outlayer instance from element 7357 * @param {Element} elem 7358 * @returns {Outlayer} 7359 */ 7360Outlayer.data = function( elem ) { 7361 elem = utils.getQueryElement( elem ); 7362 var id = elem && elem.outlayerGUID; 7363 return id && instances[ id ]; 7364}; 7365 7366 7367// -------------------------- create Outlayer class -------------------------- // 7368 7369/** 7370 * create a layout class 7371 * @param {String} namespace 7372 */ 7373Outlayer.create = function( namespace, options ) { 7374 // sub-class Outlayer 7375 var Layout = subclass( Outlayer ); 7376 // apply new options and compatOptions 7377 Layout.defaults = utils.extend( {}, Outlayer.defaults ); 7378 utils.extend( Layout.defaults, options ); 7379 Layout.compatOptions = utils.extend( {}, Outlayer.compatOptions ); 7380 7381 Layout.namespace = namespace; 7382 7383 Layout.data = Outlayer.data; 7384 7385 // sub-class Item 7386 Layout.Item = subclass( Item ); 7387 7388 // -------------------------- declarative -------------------------- // 7389 7390 utils.htmlInit( Layout, namespace ); 7391 7392 // -------------------------- jQuery bridge -------------------------- // 7393 7394 // make into jQuery plugin 7395 if ( jQuery && jQuery.bridget ) { 7396 jQuery.bridget( namespace, Layout ); 7397 } 7398 7399 return Layout; 7400}; 7401 7402function subclass( Parent ) { 7403 function SubClass() { 7404 Parent.apply( this, arguments ); 7405 } 7406 7407 SubClass.prototype = Object.create( Parent.prototype ); 7408 SubClass.prototype.constructor = SubClass; 7409 7410 return SubClass; 7411} 7412 7413// ----- helpers ----- // 7414 7415// how many milliseconds are in each unit 7416var msUnits = { 7417 ms: 1, 7418 s: 1000 7419}; 7420 7421// munge time-like parameter into millisecond number 7422// '0.4s' -> 40 7423function getMilliseconds( time ) { 7424 if ( typeof time == 'number' ) { 7425 return time; 7426 } 7427 var matches = time.match( /(^\d*\.?\d*)(\w*)/ ); 7428 var num = matches && matches[1]; 7429 var unit = matches && matches[2]; 7430 if ( !num.length ) { 7431 return 0; 7432 } 7433 num = parseFloat( num ); 7434 var mult = msUnits[ unit ] || 1; 7435 return num * mult; 7436} 7437 7438// ----- fin ----- // 7439 7440// back in global 7441Outlayer.Item = Item; 7442 7443return Outlayer; 7444 7445})); 7446 7447/** 7448 * Isotope Item 7449**/ 7450 7451( function( window, factory ) { 7452 // universal module definition 7453 /* jshint strict: false */ /*globals define, module, require */ 7454 if ( typeof define == 'function' && define.amd ) { 7455 // AMD 7456 define( 'isotope-layout/js/item',[ 7457 'outlayer/outlayer' 7458 ], 7459 factory ); 7460 } else if ( typeof module == 'object' && module.exports ) { 7461 // CommonJS 7462 module.exports = factory( 7463 require('outlayer') 7464 ); 7465 } else { 7466 // browser global 7467 window.Isotope = window.Isotope || {}; 7468 window.Isotope.Item = factory( 7469 window.Outlayer 7470 ); 7471 } 7472 7473}( window, function factory( Outlayer ) { 7474'use strict'; 7475 7476// -------------------------- Item -------------------------- // 7477 7478// sub-class Outlayer Item 7479function Item() { 7480 Outlayer.Item.apply( this, arguments ); 7481} 7482 7483var proto = Item.prototype = Object.create( Outlayer.Item.prototype ); 7484 7485var _create = proto._create; 7486proto._create = function() { 7487 // assign id, used for original-order sorting 7488 this.id = this.layout.itemGUID++; 7489 _create.call( this ); 7490 this.sortData = {}; 7491}; 7492 7493proto.updateSortData = function() { 7494 if ( this.isIgnored ) { 7495 return; 7496 } 7497 // default sorters 7498 this.sortData.id = this.id; 7499 // for backward compatibility 7500 this.sortData['original-order'] = this.id; 7501 this.sortData.random = Math.random(); 7502 // go thru getSortData obj and apply the sorters 7503 var getSortData = this.layout.options.getSortData; 7504 var sorters = this.layout._sorters; 7505 for ( var key in getSortData ) { 7506 var sorter = sorters[ key ]; 7507 this.sortData[ key ] = sorter( this.element, this ); 7508 } 7509}; 7510 7511var _destroy = proto.destroy; 7512proto.destroy = function() { 7513 // call super 7514 _destroy.apply( this, arguments ); 7515 // reset display, #741 7516 this.css({ 7517 display: '' 7518 }); 7519}; 7520 7521return Item; 7522 7523})); 7524 7525/** 7526 * Isotope LayoutMode 7527 */ 7528 7529( function( window, factory ) { 7530 // universal module definition 7531 /* jshint strict: false */ /*globals define, module, require */ 7532 if ( typeof define == 'function' && define.amd ) { 7533 // AMD 7534 define( 'isotope-layout/js/layout-mode',[ 7535 'get-size/get-size', 7536 'outlayer/outlayer' 7537 ], 7538 factory ); 7539 } else if ( typeof module == 'object' && module.exports ) { 7540 // CommonJS 7541 module.exports = factory( 7542 require('get-size'), 7543 require('outlayer') 7544 ); 7545 } else { 7546 // browser global 7547 window.Isotope = window.Isotope || {}; 7548 window.Isotope.LayoutMode = factory( 7549 window.getSize, 7550 window.Outlayer 7551 ); 7552 } 7553 7554}( window, function factory( getSize, Outlayer ) { 7555 'use strict'; 7556 7557 // layout mode class 7558 function LayoutMode( isotope ) { 7559 this.isotope = isotope; 7560 // link properties 7561 if ( isotope ) { 7562 this.options = isotope.options[ this.namespace ]; 7563 this.element = isotope.element; 7564 this.items = isotope.filteredItems; 7565 this.size = isotope.size; 7566 } 7567 } 7568 7569 var proto = LayoutMode.prototype; 7570 7571 /** 7572 * some methods should just defer to default Outlayer method 7573 * and reference the Isotope instance as `this` 7574 **/ 7575 var facadeMethods = [ 7576 '_resetLayout', 7577 '_getItemLayoutPosition', 7578 '_manageStamp', 7579 '_getContainerSize', 7580 '_getElementOffset', 7581 'needsResizeLayout', 7582 '_getOption' 7583 ]; 7584 7585 facadeMethods.forEach( function( methodName ) { 7586 proto[ methodName ] = function() { 7587 return Outlayer.prototype[ methodName ].apply( this.isotope, arguments ); 7588 }; 7589 }); 7590 7591 // ----- ----- // 7592 7593 // for horizontal layout modes, check vertical size 7594 proto.needsVerticalResizeLayout = function() { 7595 // don't trigger if size did not change 7596 var size = getSize( this.isotope.element ); 7597 // check that this.size and size are there 7598 // IE8 triggers resize on body size change, so they might not be 7599 var hasSizes = this.isotope.size && size; 7600 return hasSizes && size.innerHeight != this.isotope.size.innerHeight; 7601 }; 7602 7603 // ----- measurements ----- // 7604 7605 proto._getMeasurement = function() { 7606 this.isotope._getMeasurement.apply( this, arguments ); 7607 }; 7608 7609 proto.getColumnWidth = function() { 7610 this.getSegmentSize( 'column', 'Width' ); 7611 }; 7612 7613 proto.getRowHeight = function() { 7614 this.getSegmentSize( 'row', 'Height' ); 7615 }; 7616 7617 /** 7618 * get columnWidth or rowHeight 7619 * segment: 'column' or 'row' 7620 * size 'Width' or 'Height' 7621 **/ 7622 proto.getSegmentSize = function( segment, size ) { 7623 var segmentName = segment + size; 7624 var outerSize = 'outer' + size; 7625 // columnWidth / outerWidth // rowHeight / outerHeight 7626 this._getMeasurement( segmentName, outerSize ); 7627 // got rowHeight or columnWidth, we can chill 7628 if ( this[ segmentName ] ) { 7629 return; 7630 } 7631 // fall back to item of first element 7632 var firstItemSize = this.getFirstItemSize(); 7633 this[ segmentName ] = firstItemSize && firstItemSize[ outerSize ] || 7634 // or size of container 7635 this.isotope.size[ 'inner' + size ]; 7636 }; 7637 7638 proto.getFirstItemSize = function() { 7639 var firstItem = this.isotope.filteredItems[0]; 7640 return firstItem && firstItem.element && getSize( firstItem.element ); 7641 }; 7642 7643 // ----- methods that should reference isotope ----- // 7644 7645 proto.layout = function() { 7646 this.isotope.layout.apply( this.isotope, arguments ); 7647 }; 7648 7649 proto.getSize = function() { 7650 this.isotope.getSize(); 7651 this.size = this.isotope.size; 7652 }; 7653 7654 // -------------------------- create -------------------------- // 7655 7656 LayoutMode.modes = {}; 7657 7658 LayoutMode.create = function( namespace, options ) { 7659 7660 function Mode() { 7661 LayoutMode.apply( this, arguments ); 7662 } 7663 7664 Mode.prototype = Object.create( proto ); 7665 Mode.prototype.constructor = Mode; 7666 7667 // default options 7668 if ( options ) { 7669 Mode.options = options; 7670 } 7671 7672 Mode.prototype.namespace = namespace; 7673 // register in Isotope 7674 LayoutMode.modes[ namespace ] = Mode; 7675 7676 return Mode; 7677 }; 7678 7679 return LayoutMode; 7680 7681})); 7682 7683/*! 7684 * Masonry v4.2.1 7685 * Cascading grid layout library 7686 * https://masonry.desandro.com 7687 * MIT License 7688 * by David DeSandro 7689 */ 7690 7691( function( window, factory ) { 7692 // universal module definition 7693 /* jshint strict: false */ /*globals define, module, require */ 7694 if ( typeof define == 'function' && define.amd ) { 7695 // AMD 7696 define( 'masonry-layout/masonry',[ 7697 'outlayer/outlayer', 7698 'get-size/get-size' 7699 ], 7700 factory ); 7701 } else if ( typeof module == 'object' && module.exports ) { 7702 // CommonJS 7703 module.exports = factory( 7704 require('outlayer'), 7705 require('get-size') 7706 ); 7707 } else { 7708 // browser global 7709 window.Masonry = factory( 7710 window.Outlayer, 7711 window.getSize 7712 ); 7713 } 7714 7715}( window, function factory( Outlayer, getSize ) { 7716 7717 7718 7719// -------------------------- masonryDefinition -------------------------- // 7720 7721 // create an Outlayer layout class 7722 var Masonry = Outlayer.create('masonry'); 7723 // isFitWidth -> fitWidth 7724 Masonry.compatOptions.fitWidth = 'isFitWidth'; 7725 7726 var proto = Masonry.prototype; 7727 7728 proto._resetLayout = function() { 7729 this.getSize(); 7730 this._getMeasurement( 'columnWidth', 'outerWidth' ); 7731 this._getMeasurement( 'gutter', 'outerWidth' ); 7732 this.measureColumns(); 7733 7734 // reset column Y 7735 this.colYs = []; 7736 for ( var i=0; i < this.cols; i++ ) { 7737 this.colYs.push( 0 ); 7738 } 7739 7740 this.maxY = 0; 7741 this.horizontalColIndex = 0; 7742 }; 7743 7744 proto.measureColumns = function() { 7745 this.getContainerWidth(); 7746 // if columnWidth is 0, default to outerWidth of first item 7747 if ( !this.columnWidth ) { 7748 var firstItem = this.items[0]; 7749 var firstItemElem = firstItem && firstItem.element; 7750 // columnWidth fall back to item of first element 7751 this.columnWidth = firstItemElem && getSize( firstItemElem ).outerWidth || 7752 // if first elem has no width, default to size of container 7753 this.containerWidth; 7754 } 7755 7756 var columnWidth = this.columnWidth += this.gutter; 7757 7758 // calculate columns 7759 var containerWidth = this.containerWidth + this.gutter; 7760 var cols = containerWidth / columnWidth; 7761 // fix rounding errors, typically with gutters 7762 var excess = columnWidth - containerWidth % columnWidth; 7763 // if overshoot is less than a pixel, round up, otherwise floor it 7764 var mathMethod = excess && excess < 1 ? 'round' : 'floor'; 7765 cols = Math[ mathMethod ]( cols ); 7766 this.cols = Math.max( cols, 1 ); 7767 }; 7768 7769 proto.getContainerWidth = function() { 7770 // container is parent if fit width 7771 var isFitWidth = this._getOption('fitWidth'); 7772 var container = isFitWidth ? this.element.parentNode : this.element; 7773 // check that this.size and size are there 7774 // IE8 triggers resize on body size change, so they might not be 7775 var size = getSize( container ); 7776 this.containerWidth = size && size.innerWidth; 7777 }; 7778 7779 proto._getItemLayoutPosition = function( item ) { 7780 item.getSize(); 7781 // how many columns does this brick span 7782 var remainder = item.size.outerWidth % this.columnWidth; 7783 var mathMethod = remainder && remainder < 1 ? 'round' : 'ceil'; 7784 // round if off by 1 pixel, otherwise use ceil 7785 var colSpan = Math[ mathMethod ]( item.size.outerWidth / this.columnWidth ); 7786 colSpan = Math.min( colSpan, this.cols ); 7787 // use horizontal or top column position 7788 var colPosMethod = this.options.horizontalOrder ? 7789 '_getHorizontalColPosition' : '_getTopColPosition'; 7790 var colPosition = this[ colPosMethod ]( colSpan, item ); 7791 // position the brick 7792 var position = { 7793 x: this.columnWidth * colPosition.col, 7794 y: colPosition.y 7795 }; 7796 // apply setHeight to necessary columns 7797 var setHeight = colPosition.y + item.size.outerHeight; 7798 var setMax = colSpan + colPosition.col; 7799 for ( var i = colPosition.col; i < setMax; i++ ) { 7800 this.colYs[i] = setHeight; 7801 } 7802 7803 return position; 7804 }; 7805 7806 proto._getTopColPosition = function( colSpan ) { 7807 var colGroup = this._getTopColGroup( colSpan ); 7808 // get the minimum Y value from the columns 7809 var minimumY = Math.min.apply( Math, colGroup ); 7810 7811 return { 7812 col: colGroup.indexOf( minimumY ), 7813 y: minimumY, 7814 }; 7815 }; 7816 7817 /** 7818 * @param {Number} colSpan - number of columns the element spans 7819 * @returns {Array} colGroup 7820 */ 7821 proto._getTopColGroup = function( colSpan ) { 7822 if ( colSpan < 2 ) { 7823 // if brick spans only one column, use all the column Ys 7824 return this.colYs; 7825 } 7826 7827 var colGroup = []; 7828 // how many different places could this brick fit horizontally 7829 var groupCount = this.cols + 1 - colSpan; 7830 // for each group potential horizontal position 7831 for ( var i = 0; i < groupCount; i++ ) { 7832 colGroup[i] = this._getColGroupY( i, colSpan ); 7833 } 7834 return colGroup; 7835 }; 7836 7837 proto._getColGroupY = function( col, colSpan ) { 7838 if ( colSpan < 2 ) { 7839 return this.colYs[ col ]; 7840 } 7841 // make an array of colY values for that one group 7842 var groupColYs = this.colYs.slice( col, col + colSpan ); 7843 // and get the max value of the array 7844 return Math.max.apply( Math, groupColYs ); 7845 }; 7846 7847 // get column position based on horizontal index. #873 7848 proto._getHorizontalColPosition = function( colSpan, item ) { 7849 var col = this.horizontalColIndex % this.cols; 7850 var isOver = colSpan > 1 && col + colSpan > this.cols; 7851 // shift to next row if item can't fit on current row 7852 col = isOver ? 0 : col; 7853 // don't let zero-size items take up space 7854 var hasSize = item.size.outerWidth && item.size.outerHeight; 7855 this.horizontalColIndex = hasSize ? col + colSpan : this.horizontalColIndex; 7856 7857 return { 7858 col: col, 7859 y: this._getColGroupY( col, colSpan ), 7860 }; 7861 }; 7862 7863 proto._manageStamp = function( stamp ) { 7864 var stampSize = getSize( stamp ); 7865 var offset = this._getElementOffset( stamp ); 7866 // get the columns that this stamp affects 7867 var isOriginLeft = this._getOption('originLeft'); 7868 var firstX = isOriginLeft ? offset.left : offset.right; 7869 var lastX = firstX + stampSize.outerWidth; 7870 var firstCol = Math.floor( firstX / this.columnWidth ); 7871 firstCol = Math.max( 0, firstCol ); 7872 var lastCol = Math.floor( lastX / this.columnWidth ); 7873 // lastCol should not go over if multiple of columnWidth #425 7874 lastCol -= lastX % this.columnWidth ? 0 : 1; 7875 lastCol = Math.min( this.cols - 1, lastCol ); 7876 // set colYs to bottom of the stamp 7877 7878 var isOriginTop = this._getOption('originTop'); 7879 var stampMaxY = ( isOriginTop ? offset.top : offset.bottom ) + 7880 stampSize.outerHeight; 7881 for ( var i = firstCol; i <= lastCol; i++ ) { 7882 this.colYs[i] = Math.max( stampMaxY, this.colYs[i] ); 7883 } 7884 }; 7885 7886 proto._getContainerSize = function() { 7887 this.maxY = Math.max.apply( Math, this.colYs ); 7888 var size = { 7889 height: this.maxY 7890 }; 7891 7892 if ( this._getOption('fitWidth') ) { 7893 size.width = this._getContainerFitWidth(); 7894 } 7895 7896 return size; 7897 }; 7898 7899 proto._getContainerFitWidth = function() { 7900 var unusedCols = 0; 7901 // count unused columns 7902 var i = this.cols; 7903 while ( --i ) { 7904 if ( this.colYs[i] !== 0 ) { 7905 break; 7906 } 7907 unusedCols++; 7908 } 7909 // fit container to columns that have been used 7910 return ( this.cols - unusedCols ) * this.columnWidth - this.gutter; 7911 }; 7912 7913 proto.needsResizeLayout = function() { 7914 var previousWidth = this.containerWidth; 7915 this.getContainerWidth(); 7916 return previousWidth != this.containerWidth; 7917 }; 7918 7919 return Masonry; 7920 7921})); 7922 7923/*! 7924 * Masonry layout mode 7925 * sub-classes Masonry 7926 * https://masonry.desandro.com 7927 */ 7928 7929( function( window, factory ) { 7930 // universal module definition 7931 /* jshint strict: false */ /*globals define, module, require */ 7932 if ( typeof define == 'function' && define.amd ) { 7933 // AMD 7934 define( 'isotope-layout/js/layout-modes/masonry',[ 7935 '../layout-mode', 7936 'masonry-layout/masonry' 7937 ], 7938 factory ); 7939 } else if ( typeof module == 'object' && module.exports ) { 7940 // CommonJS 7941 module.exports = factory( 7942 require('../layout-mode'), 7943 require('masonry-layout') 7944 ); 7945 } else { 7946 // browser global 7947 factory( 7948 window.Isotope.LayoutMode, 7949 window.Masonry 7950 ); 7951 } 7952 7953}( window, function factory( LayoutMode, Masonry ) { 7954'use strict'; 7955 7956// -------------------------- masonryDefinition -------------------------- // 7957 7958 // create an Outlayer layout class 7959 var MasonryMode = LayoutMode.create('masonry'); 7960 7961 var proto = MasonryMode.prototype; 7962 7963 var keepModeMethods = { 7964 _getElementOffset: true, 7965 layout: true, 7966 _getMeasurement: true 7967 }; 7968 7969 // inherit Masonry prototype 7970 for ( var method in Masonry.prototype ) { 7971 // do not inherit mode methods 7972 if ( !keepModeMethods[ method ] ) { 7973 proto[ method ] = Masonry.prototype[ method ]; 7974 } 7975 } 7976 7977 var measureColumns = proto.measureColumns; 7978 proto.measureColumns = function() { 7979 // set items, used if measuring first item 7980 this.items = this.isotope.filteredItems; 7981 measureColumns.call( this ); 7982 }; 7983 7984 // point to mode options for fitWidth 7985 var _getOption = proto._getOption; 7986 proto._getOption = function( option ) { 7987 if ( option == 'fitWidth' ) { 7988 return this.options.isFitWidth !== undefined ? 7989 this.options.isFitWidth : this.options.fitWidth; 7990 } 7991 return _getOption.apply( this.isotope, arguments ); 7992 }; 7993 7994 return MasonryMode; 7995 7996})); 7997 7998/** 7999 * fitRows layout mode 8000 */ 8001 8002( function( window, factory ) { 8003 // universal module definition 8004 /* jshint strict: false */ /*globals define, module, require */ 8005 if ( typeof define == 'function' && define.amd ) { 8006 // AMD 8007 define( 'isotope-layout/js/layout-modes/fit-rows',[ 8008 '../layout-mode' 8009 ], 8010 factory ); 8011 } else if ( typeof exports == 'object' ) { 8012 // CommonJS 8013 module.exports = factory( 8014 require('../layout-mode') 8015 ); 8016 } else { 8017 // browser global 8018 factory( 8019 window.Isotope.LayoutMode 8020 ); 8021 } 8022 8023}( window, function factory( LayoutMode ) { 8024'use strict'; 8025 8026var FitRows = LayoutMode.create('fitRows'); 8027 8028var proto = FitRows.prototype; 8029 8030proto._resetLayout = function() { 8031 this.x = 0; 8032 this.y = 0; 8033 this.maxY = 0; 8034 this._getMeasurement( 'gutter', 'outerWidth' ); 8035}; 8036 8037proto._getItemLayoutPosition = function( item ) { 8038 item.getSize(); 8039 8040 var itemWidth = item.size.outerWidth + this.gutter; 8041 // if this element cannot fit in the current row 8042 var containerWidth = this.isotope.size.innerWidth + this.gutter; 8043 if ( this.x !== 0 && itemWidth + this.x > containerWidth ) { 8044 this.x = 0; 8045 this.y = this.maxY; 8046 } 8047 8048 var position = { 8049 x: this.x, 8050 y: this.y 8051 }; 8052 8053 this.maxY = Math.max( this.maxY, this.y + item.size.outerHeight ); 8054 this.x += itemWidth; 8055 8056 return position; 8057}; 8058 8059proto._getContainerSize = function() { 8060 return { height: this.maxY }; 8061}; 8062 8063return FitRows; 8064 8065})); 8066 8067/** 8068 * vertical layout mode 8069 */ 8070 8071( function( window, factory ) { 8072 // universal module definition 8073 /* jshint strict: false */ /*globals define, module, require */ 8074 if ( typeof define == 'function' && define.amd ) { 8075 // AMD 8076 define( 'isotope-layout/js/layout-modes/vertical',[ 8077 '../layout-mode' 8078 ], 8079 factory ); 8080 } else if ( typeof module == 'object' && module.exports ) { 8081 // CommonJS 8082 module.exports = factory( 8083 require('../layout-mode') 8084 ); 8085 } else { 8086 // browser global 8087 factory( 8088 window.Isotope.LayoutMode 8089 ); 8090 } 8091 8092}( window, function factory( LayoutMode ) { 8093'use strict'; 8094 8095var Vertical = LayoutMode.create( 'vertical', { 8096 horizontalAlignment: 0 8097}); 8098 8099var proto = Vertical.prototype; 8100 8101proto._resetLayout = function() { 8102 this.y = 0; 8103}; 8104 8105proto._getItemLayoutPosition = function( item ) { 8106 item.getSize(); 8107 var x = ( this.isotope.size.innerWidth - item.size.outerWidth ) * 8108 this.options.horizontalAlignment; 8109 var y = this.y; 8110 this.y += item.size.outerHeight; 8111 return { x: x, y: y }; 8112}; 8113 8114proto._getContainerSize = function() { 8115 return { height: this.y }; 8116}; 8117 8118return Vertical; 8119 8120})); 8121 8122/*! 8123 * Isotope v3.0.6 8124 * 8125 * Licensed GPLv3 for open source use 8126 * or Isotope Commercial License for commercial use 8127 * 8128 * https://isotope.metafizzy.co 8129 * Copyright 2010-2018 Metafizzy 8130 */ 8131 8132( function( window, factory ) { 8133 // universal module definition 8134 /* jshint strict: false */ /*globals define, module, require */ 8135 if ( typeof define == 'function' && define.amd ) { 8136 // AMD 8137 define( [ 8138 'outlayer/outlayer', 8139 'get-size/get-size', 8140 'desandro-matches-selector/matches-selector', 8141 'fizzy-ui-utils/utils', 8142 'isotope-layout/js/item', 8143 'isotope-layout/js/layout-mode', 8144 // include default layout modes 8145 'isotope-layout/js/layout-modes/masonry', 8146 'isotope-layout/js/layout-modes/fit-rows', 8147 'isotope-layout/js/layout-modes/vertical' 8148 ], 8149 function( Outlayer, getSize, matchesSelector, utils, Item, LayoutMode ) { 8150 return factory( window, Outlayer, getSize, matchesSelector, utils, Item, LayoutMode ); 8151 }); 8152 } else if ( typeof module == 'object' && module.exports ) { 8153 // CommonJS 8154 module.exports = factory( 8155 window, 8156 require('outlayer'), 8157 require('get-size'), 8158 require('desandro-matches-selector'), 8159 require('fizzy-ui-utils'), 8160 require('isotope-layout/js/item'), 8161 require('isotope-layout/js/layout-mode'), 8162 // include default layout modes 8163 require('isotope-layout/js/layout-modes/masonry'), 8164 require('isotope-layout/js/layout-modes/fit-rows'), 8165 require('isotope-layout/js/layout-modes/vertical') 8166 ); 8167 } else { 8168 // browser global 8169 window.Isotope = factory( 8170 window, 8171 window.Outlayer, 8172 window.getSize, 8173 window.matchesSelector, 8174 window.fizzyUIUtils, 8175 window.Isotope.Item, 8176 window.Isotope.LayoutMode 8177 ); 8178 } 8179 8180}( window, function factory( window, Outlayer, getSize, matchesSelector, utils, 8181 Item, LayoutMode ) { 8182 8183 8184 8185// -------------------------- vars -------------------------- // 8186 8187var jQuery = window.jQuery; 8188 8189// -------------------------- helpers -------------------------- // 8190 8191var trim = String.prototype.trim ? 8192 function( str ) { 8193 return str.trim(); 8194 } : 8195 function( str ) { 8196 return str.replace( /^\s+|\s+$/g, '' ); 8197 }; 8198 8199// -------------------------- isotopeDefinition -------------------------- // 8200 8201 // create an Outlayer layout class 8202 var Isotope = Outlayer.create( 'isotope', { 8203 layoutMode: 'masonry', 8204 isJQueryFiltering: true, 8205 sortAscending: true 8206 }); 8207 8208 Isotope.Item = Item; 8209 Isotope.LayoutMode = LayoutMode; 8210 8211 var proto = Isotope.prototype; 8212 8213 proto._create = function() { 8214 this.itemGUID = 0; 8215 // functions that sort items 8216 this._sorters = {}; 8217 this._getSorters(); 8218 // call super 8219 Outlayer.prototype._create.call( this ); 8220 8221 // create layout modes 8222 this.modes = {}; 8223 // start filteredItems with all items 8224 this.filteredItems = this.items; 8225 // keep of track of sortBys 8226 this.sortHistory = [ 'original-order' ]; 8227 // create from registered layout modes 8228 for ( var name in LayoutMode.modes ) { 8229 this._initLayoutMode( name ); 8230 } 8231 }; 8232 8233 proto.reloadItems = function() { 8234 // reset item ID counter 8235 this.itemGUID = 0; 8236 // call super 8237 Outlayer.prototype.reloadItems.call( this ); 8238 }; 8239 8240 proto._itemize = function() { 8241 var items = Outlayer.prototype._itemize.apply( this, arguments ); 8242 // assign ID for original-order 8243 for ( var i=0; i < items.length; i++ ) { 8244 var item = items[i]; 8245 item.id = this.itemGUID++; 8246 } 8247 this._updateItemsSortData( items ); 8248 return items; 8249 }; 8250 8251 8252 // -------------------------- layout -------------------------- // 8253 8254 proto._initLayoutMode = function( name ) { 8255 var Mode = LayoutMode.modes[ name ]; 8256 // set mode options 8257 // HACK extend initial options, back-fill in default options 8258 var initialOpts = this.options[ name ] || {}; 8259 this.options[ name ] = Mode.options ? 8260 utils.extend( Mode.options, initialOpts ) : initialOpts; 8261 // init layout mode instance 8262 this.modes[ name ] = new Mode( this ); 8263 }; 8264 8265 8266 proto.layout = function() { 8267 // if first time doing layout, do all magic 8268 if ( !this._isLayoutInited && this._getOption('initLayout') ) { 8269 this.arrange(); 8270 return; 8271 } 8272 this._layout(); 8273 }; 8274 8275 // private method to be used in layout() & magic() 8276 proto._layout = function() { 8277 // don't animate first layout 8278 var isInstant = this._getIsInstant(); 8279 // layout flow 8280 this._resetLayout(); 8281 this._manageStamps(); 8282 this.layoutItems( this.filteredItems, isInstant ); 8283 8284 // flag for initalized 8285 this._isLayoutInited = true; 8286 }; 8287 8288 // filter + sort + layout 8289 proto.arrange = function( opts ) { 8290 // set any options pass 8291 this.option( opts ); 8292 this._getIsInstant(); 8293 // filter, sort, and layout 8294 8295 // filter 8296 var filtered = this._filter( this.items ); 8297 this.filteredItems = filtered.matches; 8298 8299 this._bindArrangeComplete(); 8300 8301 if ( this._isInstant ) { 8302 this._noTransition( this._hideReveal, [ filtered ] ); 8303 } else { 8304 this._hideReveal( filtered ); 8305 } 8306 8307 this._sort(); 8308 this._layout(); 8309 }; 8310 // alias to _init for main plugin method 8311 proto._init = proto.arrange; 8312 8313 proto._hideReveal = function( filtered ) { 8314 this.reveal( filtered.needReveal ); 8315 this.hide( filtered.needHide ); 8316 }; 8317 8318 // HACK 8319 // Don't animate/transition first layout 8320 // Or don't animate/transition other layouts 8321 proto._getIsInstant = function() { 8322 var isLayoutInstant = this._getOption('layoutInstant'); 8323 var isInstant = isLayoutInstant !== undefined ? isLayoutInstant : 8324 !this._isLayoutInited; 8325 this._isInstant = isInstant; 8326 return isInstant; 8327 }; 8328 8329 // listen for layoutComplete, hideComplete and revealComplete 8330 // to trigger arrangeComplete 8331 proto._bindArrangeComplete = function() { 8332 // listen for 3 events to trigger arrangeComplete 8333 var isLayoutComplete, isHideComplete, isRevealComplete; 8334 var _this = this; 8335 function arrangeParallelCallback() { 8336 if ( isLayoutComplete && isHideComplete && isRevealComplete ) { 8337 _this.dispatchEvent( 'arrangeComplete', null, [ _this.filteredItems ] ); 8338 } 8339 } 8340 this.once( 'layoutComplete', function() { 8341 isLayoutComplete = true; 8342 arrangeParallelCallback(); 8343 }); 8344 this.once( 'hideComplete', function() { 8345 isHideComplete = true; 8346 arrangeParallelCallback(); 8347 }); 8348 this.once( 'revealComplete', function() { 8349 isRevealComplete = true; 8350 arrangeParallelCallback(); 8351 }); 8352 }; 8353 8354 // -------------------------- filter -------------------------- // 8355 8356 proto._filter = function( items ) { 8357 var filter = this.options.filter; 8358 filter = filter || '*'; 8359 var matches = []; 8360 var hiddenMatched = []; 8361 var visibleUnmatched = []; 8362 8363 var test = this._getFilterTest( filter ); 8364 8365 // test each item 8366 for ( var i=0; i < items.length; i++ ) { 8367 var item = items[i]; 8368 if ( item.isIgnored ) { 8369 continue; 8370 } 8371 // add item to either matched or unmatched group 8372 var isMatched = test( item ); 8373 // item.isFilterMatched = isMatched; 8374 // add to matches if its a match 8375 if ( isMatched ) { 8376 matches.push( item ); 8377 } 8378 // add to additional group if item needs to be hidden or revealed 8379 if ( isMatched && item.isHidden ) { 8380 hiddenMatched.push( item ); 8381 } else if ( !isMatched && !item.isHidden ) { 8382 visibleUnmatched.push( item ); 8383 } 8384 } 8385 8386 // return collections of items to be manipulated 8387 return { 8388 matches: matches, 8389 needReveal: hiddenMatched, 8390 needHide: visibleUnmatched 8391 }; 8392 }; 8393 8394 // get a jQuery, function, or a matchesSelector test given the filter 8395 proto._getFilterTest = function( filter ) { 8396 if ( jQuery && this.options.isJQueryFiltering ) { 8397 // use jQuery 8398 return function( item ) { 8399 return jQuery( item.element ).is( filter ); 8400 }; 8401 } 8402 if ( typeof filter == 'function' ) { 8403 // use filter as function 8404 return function( item ) { 8405 return filter( item.element ); 8406 }; 8407 } 8408 // default, use filter as selector string 8409 return function( item ) { 8410 return matchesSelector( item.element, filter ); 8411 }; 8412 }; 8413 8414 // -------------------------- sorting -------------------------- // 8415 8416 /** 8417 * @params {Array} elems 8418 * @public 8419 */ 8420 proto.updateSortData = function( elems ) { 8421 // get items 8422 var items; 8423 if ( elems ) { 8424 elems = utils.makeArray( elems ); 8425 items = this.getItems( elems ); 8426 } else { 8427 // update all items if no elems provided 8428 items = this.items; 8429 } 8430 8431 this._getSorters(); 8432 this._updateItemsSortData( items ); 8433 }; 8434 8435 proto._getSorters = function() { 8436 var getSortData = this.options.getSortData; 8437 for ( var key in getSortData ) { 8438 var sorter = getSortData[ key ]; 8439 this._sorters[ key ] = mungeSorter( sorter ); 8440 } 8441 }; 8442 8443 /** 8444 * @params {Array} items - of Isotope.Items 8445 * @private 8446 */ 8447 proto._updateItemsSortData = function( items ) { 8448 // do not update if no items 8449 var len = items && items.length; 8450 8451 for ( var i=0; len && i < len; i++ ) { 8452 var item = items[i]; 8453 item.updateSortData(); 8454 } 8455 }; 8456 8457 // ----- munge sorter ----- // 8458 8459 // encapsulate this, as we just need mungeSorter 8460 // other functions in here are just for munging 8461 var mungeSorter = ( function() { 8462 // add a magic layer to sorters for convienent shorthands 8463 // `.foo-bar` will use the text of .foo-bar querySelector 8464 // `[foo-bar]` will use attribute 8465 // you can also add parser 8466 // `.foo-bar parseInt` will parse that as a number 8467 function mungeSorter( sorter ) { 8468 // if not a string, return function or whatever it is 8469 if ( typeof sorter != 'string' ) { 8470 return sorter; 8471 } 8472 // parse the sorter string 8473 var args = trim( sorter ).split(' '); 8474 var query = args[0]; 8475 // check if query looks like [an-attribute] 8476 var attrMatch = query.match( /^\[(.+)\]$/ ); 8477 var attr = attrMatch && attrMatch[1]; 8478 var getValue = getValueGetter( attr, query ); 8479 // use second argument as a parser 8480 var parser = Isotope.sortDataParsers[ args[1] ]; 8481 // parse the value, if there was a parser 8482 sorter = parser ? function( elem ) { 8483 return elem && parser( getValue( elem ) ); 8484 } : 8485 // otherwise just return value 8486 function( elem ) { 8487 return elem && getValue( elem ); 8488 }; 8489 8490 return sorter; 8491 } 8492 8493 // get an attribute getter, or get text of the querySelector 8494 function getValueGetter( attr, query ) { 8495 // if query looks like [foo-bar], get attribute 8496 if ( attr ) { 8497 return function getAttribute( elem ) { 8498 return elem.getAttribute( attr ); 8499 }; 8500 } 8501 8502 // otherwise, assume its a querySelector, and get its text 8503 return function getChildText( elem ) { 8504 var child = elem.querySelector( query ); 8505 return child && child.textContent; 8506 }; 8507 } 8508 8509 return mungeSorter; 8510 })(); 8511 8512 // parsers used in getSortData shortcut strings 8513 Isotope.sortDataParsers = { 8514 'parseInt': function( val ) { 8515 return parseInt( val, 10 ); 8516 }, 8517 'parseFloat': function( val ) { 8518 return parseFloat( val ); 8519 } 8520 }; 8521 8522 // ----- sort method ----- // 8523 8524 // sort filteredItem order 8525 proto._sort = function() { 8526 if ( !this.options.sortBy ) { 8527 return; 8528 } 8529 // keep track of sortBy History 8530 var sortBys = utils.makeArray( this.options.sortBy ); 8531 if ( !this._getIsSameSortBy( sortBys ) ) { 8532 // concat all sortBy and sortHistory, add to front, oldest goes in last 8533 this.sortHistory = sortBys.concat( this.sortHistory ); 8534 } 8535 // sort magic 8536 var itemSorter = getItemSorter( this.sortHistory, this.options.sortAscending ); 8537 this.filteredItems.sort( itemSorter ); 8538 }; 8539 8540 // check if sortBys is same as start of sortHistory 8541 proto._getIsSameSortBy = function( sortBys ) { 8542 for ( var i=0; i < sortBys.length; i++ ) { 8543 if ( sortBys[i] != this.sortHistory[i] ) { 8544 return false; 8545 } 8546 } 8547 return true; 8548 }; 8549 8550 // returns a function used for sorting 8551 function getItemSorter( sortBys, sortAsc ) { 8552 return function sorter( itemA, itemB ) { 8553 // cycle through all sortKeys 8554 for ( var i = 0; i < sortBys.length; i++ ) { 8555 var sortBy = sortBys[i]; 8556 var a = itemA.sortData[ sortBy ]; 8557 var b = itemB.sortData[ sortBy ]; 8558 if ( a > b || a < b ) { 8559 // if sortAsc is an object, use the value given the sortBy key 8560 var isAscending = sortAsc[ sortBy ] !== undefined ? sortAsc[ sortBy ] : sortAsc; 8561 var direction = isAscending ? 1 : -1; 8562 return ( a > b ? 1 : -1 ) * direction; 8563 } 8564 } 8565 return 0; 8566 }; 8567 } 8568 8569 // -------------------------- methods -------------------------- // 8570 8571 // get layout mode 8572 proto._mode = function() { 8573 var layoutMode = this.options.layoutMode; 8574 var mode = this.modes[ layoutMode ]; 8575 if ( !mode ) { 8576 // TODO console.error 8577 throw new Error( 'No layout mode: ' + layoutMode ); 8578 } 8579 // HACK sync mode's options 8580 // any options set after init for layout mode need to be synced 8581 mode.options = this.options[ layoutMode ]; 8582 return mode; 8583 }; 8584 8585 proto._resetLayout = function() { 8586 // trigger original reset layout 8587 Outlayer.prototype._resetLayout.call( this ); 8588 this._mode()._resetLayout(); 8589 }; 8590 8591 proto._getItemLayoutPosition = function( item ) { 8592 return this._mode()._getItemLayoutPosition( item ); 8593 }; 8594 8595 proto._manageStamp = function( stamp ) { 8596 this._mode()._manageStamp( stamp ); 8597 }; 8598 8599 proto._getContainerSize = function() { 8600 return this._mode()._getContainerSize(); 8601 }; 8602 8603 proto.needsResizeLayout = function() { 8604 return this._mode().needsResizeLayout(); 8605 }; 8606 8607 // -------------------------- adding & removing -------------------------- // 8608 8609 // HEADS UP overwrites default Outlayer appended 8610 proto.appended = function( elems ) { 8611 var items = this.addItems( elems ); 8612 if ( !items.length ) { 8613 return; 8614 } 8615 // filter, layout, reveal new items 8616 var filteredItems = this._filterRevealAdded( items ); 8617 // add to filteredItems 8618 this.filteredItems = this.filteredItems.concat( filteredItems ); 8619 }; 8620 8621 // HEADS UP overwrites default Outlayer prepended 8622 proto.prepended = function( elems ) { 8623 var items = this._itemize( elems ); 8624 if ( !items.length ) { 8625 return; 8626 } 8627 // start new layout 8628 this._resetLayout(); 8629 this._manageStamps(); 8630 // filter, layout, reveal new items 8631 var filteredItems = this._filterRevealAdded( items ); 8632 // layout previous items 8633 this.layoutItems( this.filteredItems ); 8634 // add to items and filteredItems 8635 this.filteredItems = filteredItems.concat( this.filteredItems ); 8636 this.items = items.concat( this.items ); 8637 }; 8638 8639 proto._filterRevealAdded = function( items ) { 8640 var filtered = this._filter( items ); 8641 this.hide( filtered.needHide ); 8642 // reveal all new items 8643 this.reveal( filtered.matches ); 8644 // layout new items, no transition 8645 this.layoutItems( filtered.matches, true ); 8646 return filtered.matches; 8647 }; 8648 8649 /** 8650 * Filter, sort, and layout newly-appended item elements 8651 * @param {Array or NodeList or Element} elems 8652 */ 8653 proto.insert = function( elems ) { 8654 var items = this.addItems( elems ); 8655 if ( !items.length ) { 8656 return; 8657 } 8658 // append item elements 8659 var i, item; 8660 var len = items.length; 8661 for ( i=0; i < len; i++ ) { 8662 item = items[i]; 8663 this.element.appendChild( item.element ); 8664 } 8665 // filter new stuff 8666 var filteredInsertItems = this._filter( items ).matches; 8667 // set flag 8668 for ( i=0; i < len; i++ ) { 8669 items[i].isLayoutInstant = true; 8670 } 8671 this.arrange(); 8672 // reset flag 8673 for ( i=0; i < len; i++ ) { 8674 delete items[i].isLayoutInstant; 8675 } 8676 this.reveal( filteredInsertItems ); 8677 }; 8678 8679 var _remove = proto.remove; 8680 proto.remove = function( elems ) { 8681 elems = utils.makeArray( elems ); 8682 var removeItems = this.getItems( elems ); 8683 // do regular thing 8684 _remove.call( this, elems ); 8685 // bail if no items to remove 8686 var len = removeItems && removeItems.length; 8687 // remove elems from filteredItems 8688 for ( var i=0; len && i < len; i++ ) { 8689 var item = removeItems[i]; 8690 // remove item from collection 8691 utils.removeFrom( this.filteredItems, item ); 8692 } 8693 }; 8694 8695 proto.shuffle = function() { 8696 // update random sortData 8697 for ( var i=0; i < this.items.length; i++ ) { 8698 var item = this.items[i]; 8699 item.sortData.random = Math.random(); 8700 } 8701 this.options.sortBy = 'random'; 8702 this._sort(); 8703 this._layout(); 8704 }; 8705 8706 /** 8707 * trigger fn without transition 8708 * kind of hacky to have this in the first place 8709 * @param {Function} fn 8710 * @param {Array} args 8711 * @returns ret 8712 * @private 8713 */ 8714 proto._noTransition = function( fn, args ) { 8715 // save transitionDuration before disabling 8716 var transitionDuration = this.options.transitionDuration; 8717 // disable transition 8718 this.options.transitionDuration = 0; 8719 // do it 8720 var returnValue = fn.apply( this, args ); 8721 // re-enable transition for reveal 8722 this.options.transitionDuration = transitionDuration; 8723 return returnValue; 8724 }; 8725 8726 // ----- helper methods ----- // 8727 8728 /** 8729 * getter method for getting filtered item elements 8730 * @returns {Array} elems - collection of item elements 8731 */ 8732 proto.getFilteredItemElements = function() { 8733 return this.filteredItems.map( function( item ) { 8734 return item.element; 8735 }); 8736 }; 8737 8738 // ----- ----- // 8739 8740 return Isotope; 8741 8742})); 8743
vendor: 29,252 bytes, lines 8744-9900
8744/*! 8745 * Packery layout mode PACKAGED v2.0.1 8746 * sub-classes Packery 8747 */ 8748 8749/** 8750 * Rect 8751 * low-level utility class for basic geometry 8752 */ 8753 8754( function( window, factory ) { 8755 // universal module definition 8756 /* jshint strict: false */ /* globals define, module */ 8757 if ( typeof define == 'function' && define.amd ) { 8758 // AMD 8759 define( 'packery/js/rect',factory ); 8760 } else if ( typeof module == 'object' && module.exports ) { 8761 // CommonJS 8762 module.exports = factory(); 8763 } else { 8764 // browser global 8765 window.Packery = window.Packery || {}; 8766 window.Packery.Rect = factory(); 8767 } 8768 8769}( window, function factory() { 8770 8771 8772// -------------------------- Rect -------------------------- // 8773 8774function Rect( props ) { 8775 // extend properties from defaults 8776 for ( var prop in Rect.defaults ) { 8777 this[ prop ] = Rect.defaults[ prop ]; 8778 } 8779 8780 for ( prop in props ) { 8781 this[ prop ] = props[ prop ]; 8782 } 8783 8784} 8785 8786Rect.defaults = { 8787 x: 0, 8788 y: 0, 8789 width: 0, 8790 height: 0 8791}; 8792 8793var proto = Rect.prototype; 8794 8795/** 8796 * Determines whether or not this rectangle wholly encloses another rectangle or point. 8797 * @param {Rect} rect 8798 * @returns {Boolean} 8799**/ 8800proto.contains = function( rect ) { 8801 // points don't have width or height 8802 var otherWidth = rect.width || 0; 8803 var otherHeight = rect.height || 0; 8804 return this.x <= rect.x && 8805 this.y <= rect.y && 8806 this.x + this.width >= rect.x + otherWidth && 8807 this.y + this.height >= rect.y + otherHeight; 8808}; 8809 8810/** 8811 * Determines whether or not the rectangle intersects with another. 8812 * @param {Rect} rect 8813 * @returns {Boolean} 8814**/ 8815proto.overlaps = function( rect ) { 8816 var thisRight = this.x + this.width; 8817 var thisBottom = this.y + this.height; 8818 var rectRight = rect.x + rect.width; 8819 var rectBottom = rect.y + rect.height; 8820 8821 // http://stackoverflow.com/a/306332 8822 return this.x < rectRight && 8823 thisRight > rect.x && 8824 this.y < rectBottom && 8825 thisBottom > rect.y; 8826}; 8827 8828/** 8829 * @param {Rect} rect - the overlapping rect 8830 * @returns {Array} freeRects - rects representing the area around the rect 8831**/ 8832proto.getMaximalFreeRects = function( rect ) { 8833 8834 // if no intersection, return false 8835 if ( !this.overlaps( rect ) ) { 8836 return false; 8837 } 8838 8839 var freeRects = []; 8840 var freeRect; 8841 8842 var thisRight = this.x + this.width; 8843 var thisBottom = this.y + this.height; 8844 var rectRight = rect.x + rect.width; 8845 var rectBottom = rect.y + rect.height; 8846 8847 // top 8848 if ( this.y < rect.y ) { 8849 freeRect = new Rect({ 8850 x: this.x, 8851 y: this.y, 8852 width: this.width, 8853 height: rect.y - this.y 8854 }); 8855 freeRects.push( freeRect ); 8856 } 8857 8858 // right 8859 if ( thisRight > rectRight ) { 8860 freeRect = new Rect({ 8861 x: rectRight, 8862 y: this.y, 8863 width: thisRight - rectRight, 8864 height: this.height 8865 }); 8866 freeRects.push( freeRect ); 8867 } 8868 8869 // bottom 8870 if ( thisBottom > rectBottom ) { 8871 freeRect = new Rect({ 8872 x: this.x, 8873 y: rectBottom, 8874 width: this.width, 8875 height: thisBottom - rectBottom 8876 }); 8877 freeRects.push( freeRect ); 8878 } 8879 8880 // left 8881 if ( this.x < rect.x ) { 8882 freeRect = new Rect({ 8883 x: this.x, 8884 y: this.y, 8885 width: rect.x - this.x, 8886 height: this.height 8887 }); 8888 freeRects.push( freeRect ); 8889 } 8890 8891 return freeRects; 8892}; 8893 8894proto.canFit = function( rect ) { 8895 return this.width >= rect.width && this.height >= rect.height; 8896}; 8897 8898return Rect; 8899 8900})); 8901 8902/** 8903 * Packer 8904 * bin-packing algorithm 8905 */ 8906 8907( function( window, factory ) { 8908 // universal module definition 8909 /* jshint strict: false */ /* globals define, module, require */ 8910 if ( typeof define == 'function' && define.amd ) { 8911 // AMD 8912 define( 'packery/js/packer',[ './rect' ], factory ); 8913 } else if ( typeof module == 'object' && module.exports ) { 8914 // CommonJS 8915 module.exports = factory( 8916 require('./rect') 8917 ); 8918 } else { 8919 // browser global 8920 var Packery = window.Packery = window.Packery || {}; 8921 Packery.Packer = factory( Packery.Rect ); 8922 } 8923 8924}( window, function factory( Rect ) { 8925 8926 8927// -------------------------- Packer -------------------------- // 8928 8929/** 8930 * @param {Number} width 8931 * @param {Number} height 8932 * @param {String} sortDirection 8933 * topLeft for vertical, leftTop for horizontal 8934 */ 8935function Packer( width, height, sortDirection ) { 8936 this.width = width || 0; 8937 this.height = height || 0; 8938 this.sortDirection = sortDirection || 'downwardLeftToRight'; 8939 8940 this.reset(); 8941} 8942 8943var proto = Packer.prototype; 8944 8945proto.reset = function() { 8946 this.spaces = []; 8947 8948 var initialSpace = new Rect({ 8949 x: 0, 8950 y: 0, 8951 width: this.width, 8952 height: this.height 8953 }); 8954 8955 this.spaces.push( initialSpace ); 8956 // set sorter 8957 this.sorter = sorters[ this.sortDirection ] || sorters.downwardLeftToRight; 8958}; 8959 8960// change x and y of rect to fit with in Packer's available spaces 8961proto.pack = function( rect ) { 8962 for ( var i=0; i < this.spaces.length; i++ ) { 8963 var space = this.spaces[i]; 8964 if ( space.canFit( rect ) ) { 8965 this.placeInSpace( rect, space ); 8966 break; 8967 } 8968 } 8969}; 8970 8971proto.columnPack = function( rect ) { 8972 for ( var i=0; i < this.spaces.length; i++ ) { 8973 var space = this.spaces[i]; 8974 var canFitInSpaceColumn = space.x <= rect.x && 8975 space.x + space.width >= rect.x + rect.width && 8976 space.height >= rect.height - 0.01; // fudge number for rounding error 8977 if ( canFitInSpaceColumn ) { 8978 rect.y = space.y; 8979 this.placed( rect ); 8980 break; 8981 } 8982 } 8983}; 8984 8985proto.rowPack = function( rect ) { 8986 for ( var i=0; i < this.spaces.length; i++ ) { 8987 var space = this.spaces[i]; 8988 var canFitInSpaceRow = space.y <= rect.y && 8989 space.y + space.height >= rect.y + rect.height && 8990 space.width >= rect.width - 0.01; // fudge number for rounding error 8991 if ( canFitInSpaceRow ) { 8992 rect.x = space.x; 8993 this.placed( rect ); 8994 break; 8995 } 8996 } 8997}; 8998 8999proto.placeInSpace = function( rect, space ) { 9000 // place rect in space 9001 rect.x = space.x; 9002 rect.y = space.y; 9003 9004 this.placed( rect ); 9005}; 9006 9007// update spaces with placed rect 9008proto.placed = function( rect ) { 9009 // update spaces 9010 var revisedSpaces = []; 9011 for ( var i=0; i < this.spaces.length; i++ ) { 9012 var space = this.spaces[i]; 9013 var newSpaces = space.getMaximalFreeRects( rect ); 9014 // add either the original space or the new spaces to the revised spaces 9015 if ( newSpaces ) { 9016 revisedSpaces.push.apply( revisedSpaces, newSpaces ); 9017 } else { 9018 revisedSpaces.push( space ); 9019 } 9020 } 9021 9022 this.spaces = revisedSpaces; 9023 9024 this.mergeSortSpaces(); 9025}; 9026 9027proto.mergeSortSpaces = function() { 9028 // remove redundant spaces 9029 Packer.mergeRects( this.spaces ); 9030 this.spaces.sort( this.sorter ); 9031}; 9032 9033// add a space back 9034proto.addSpace = function( rect ) { 9035 this.spaces.push( rect ); 9036 this.mergeSortSpaces(); 9037}; 9038 9039// -------------------------- utility functions -------------------------- // 9040 9041/** 9042 * Remove redundant rectangle from array of rectangles 9043 * @param {Array} rects: an array of Rects 9044 * @returns {Array} rects: an array of Rects 9045**/ 9046Packer.mergeRects = function( rects ) { 9047 var i = 0; 9048 var rect = rects[i]; 9049 9050 rectLoop: 9051 while ( rect ) { 9052 var j = 0; 9053 var compareRect = rects[ i + j ]; 9054 9055 while ( compareRect ) { 9056 if ( compareRect == rect ) { 9057 j++; // next 9058 } else if ( compareRect.contains( rect ) ) { 9059 // remove rect 9060 rects.splice( i, 1 ); 9061 rect = rects[i]; // set next rect 9062 continue rectLoop; // bail on compareLoop 9063 } else if ( rect.contains( compareRect ) ) { 9064 // remove compareRect 9065 rects.splice( i + j, 1 ); 9066 } else { 9067 j++; 9068 } 9069 compareRect = rects[ i + j ]; // set next compareRect 9070 } 9071 i++; 9072 rect = rects[i]; 9073 } 9074 9075 return rects; 9076}; 9077 9078 9079// -------------------------- sorters -------------------------- // 9080 9081// functions for sorting rects in order 9082var sorters = { 9083 // top down, then left to right 9084 downwardLeftToRight: function( a, b ) { 9085 return a.y - b.y || a.x - b.x; 9086 }, 9087 // left to right, then top down 9088 rightwardTopToBottom: function( a, b ) { 9089 return a.x - b.x || a.y - b.y; 9090 } 9091}; 9092 9093 9094// -------------------------- -------------------------- // 9095 9096return Packer; 9097 9098})); 9099 9100/** 9101 * Packery Item Element 9102**/ 9103 9104( function( window, factory ) { 9105 // universal module definition 9106 /* jshint strict: false */ /* globals define, module, require */ 9107 if ( typeof define == 'function' && define.amd ) { 9108 // AMD 9109 define( 'packery/js/item',[ 9110 'outlayer/outlayer', 9111 './rect' 9112 ], 9113 factory ); 9114 } else if ( typeof module == 'object' && module.exports ) { 9115 // CommonJS 9116 module.exports = factory( 9117 require('outlayer'), 9118 require('./rect') 9119 ); 9120 } else { 9121 // browser global 9122 window.Packery.Item = factory( 9123 window.Outlayer, 9124 window.Packery.Rect 9125 ); 9126 } 9127 9128}( window, function factory( Outlayer, Rect ) { 9129 9130 9131// -------------------------- Item -------------------------- // 9132 9133var docElemStyle = document.documentElement.style; 9134 9135var transformProperty = typeof docElemStyle.transform == 'string' ? 9136 'transform' : 'WebkitTransform'; 9137 9138// sub-class Item 9139var Item = function PackeryItem() { 9140 Outlayer.Item.apply( this, arguments ); 9141}; 9142 9143var proto = Item.prototype = Object.create( Outlayer.Item.prototype ); 9144 9145var __create = proto._create; 9146proto._create = function() { 9147 // call default _create logic 9148 __create.call( this ); 9149 this.rect = new Rect(); 9150}; 9151 9152var _moveTo = proto.moveTo; 9153proto.moveTo = function( x, y ) { 9154 // don't shift 1px while dragging 9155 var dx = Math.abs( this.position.x - x ); 9156 var dy = Math.abs( this.position.y - y ); 9157 9158 var canHackGoTo = this.layout.dragItemCount && !this.isPlacing && 9159 !this.isTransitioning && dx < 1 && dy < 1; 9160 if ( canHackGoTo ) { 9161 this.goTo( x, y ); 9162 return; 9163 } 9164 _moveTo.apply( this, arguments ); 9165}; 9166 9167// -------------------------- placing -------------------------- // 9168 9169proto.enablePlacing = function() { 9170 this.removeTransitionStyles(); 9171 // remove transform property from transition 9172 if ( this.isTransitioning && transformProperty ) { 9173 this.element.style[ transformProperty ] = 'none'; 9174 } 9175 this.isTransitioning = false; 9176 this.getSize(); 9177 this.layout._setRectSize( this.element, this.rect ); 9178 this.isPlacing = true; 9179}; 9180 9181proto.disablePlacing = function() { 9182 this.isPlacing = false; 9183}; 9184 9185// ----- ----- // 9186 9187// remove element from DOM 9188proto.removeElem = function() { 9189 this.element.parentNode.removeChild( this.element ); 9190 // add space back to packer 9191 this.layout.packer.addSpace( this.rect ); 9192 this.emitEvent( 'remove', [ this ] ); 9193}; 9194 9195// ----- dropPlaceholder ----- // 9196 9197proto.showDropPlaceholder = function() { 9198 var dropPlaceholder = this.dropPlaceholder; 9199 if ( !dropPlaceholder ) { 9200 // create dropPlaceholder 9201 dropPlaceholder = this.dropPlaceholder = document.createElement('div'); 9202 dropPlaceholder.className = 'packery-drop-placeholder'; 9203 dropPlaceholder.style.position = 'absolute'; 9204 } 9205 9206 dropPlaceholder.style.width = this.size.width + 'px'; 9207 dropPlaceholder.style.height = this.size.height + 'px'; 9208 this.positionDropPlaceholder(); 9209 this.layout.element.appendChild( dropPlaceholder ); 9210}; 9211 9212proto.positionDropPlaceholder = function() { 9213 this.dropPlaceholder.style[ transformProperty ] = 'translate(' + 9214 this.rect.x + 'px, ' + this.rect.y + 'px)'; 9215}; 9216 9217proto.hideDropPlaceholder = function() { 9218 this.layout.element.removeChild( this.dropPlaceholder ); 9219}; 9220 9221// ----- ----- // 9222 9223return Item; 9224 9225})); 9226 9227/*! 9228 * Packery v2.0.0 9229 * Gapless, draggable grid layouts 9230 * 9231 * Licensed GPLv3 for open source use 9232 * or Packery Commercial License for commercial use 9233 * 9234 * http://packery.metafizzy.co 9235 * Copyright 2016 Metafizzy 9236 */ 9237 9238( function( window, factory ) { 9239 // universal module definition 9240 /* jshint strict: false */ /* globals define, module, require */ 9241 if ( typeof define == 'function' && define.amd ) { 9242 // AMD 9243 define( 'packery/js/packery',[ 9244 'get-size/get-size', 9245 'outlayer/outlayer', 9246 './rect', 9247 './packer', 9248 './item' 9249 ], 9250 factory ); 9251 } else if ( typeof module == 'object' && module.exports ) { 9252 // CommonJS 9253 module.exports = factory( 9254 require('get-size'), 9255 require('outlayer'), 9256 require('./rect'), 9257 require('./packer'), 9258 require('./item') 9259 ); 9260 } else { 9261 // browser global 9262 window.Packery = factory( 9263 window.getSize, 9264 window.Outlayer, 9265 window.Packery.Rect, 9266 window.Packery.Packer, 9267 window.Packery.Item 9268 ); 9269 } 9270 9271}( window, function factory( getSize, Outlayer, Rect, Packer, Item ) { 9272 9273 9274// ----- Rect ----- // 9275 9276// allow for pixel rounding errors IE8-IE11 & Firefox; #227 9277Rect.prototype.canFit = function( rect ) { 9278 return this.width >= rect.width - 1 && this.height >= rect.height - 1; 9279}; 9280 9281// -------------------------- Packery -------------------------- // 9282 9283// create an Outlayer layout class 9284var Packery = Outlayer.create('packery'); 9285Packery.Item = Item; 9286 9287var proto = Packery.prototype; 9288 9289proto._create = function() { 9290 // call super 9291 Outlayer.prototype._create.call( this ); 9292 9293 // initial properties 9294 this.packer = new Packer(); 9295 // packer for drop targets 9296 this.shiftPacker = new Packer(); 9297 this.isEnabled = true; 9298 9299 this.dragItemCount = 0; 9300 9301 // create drag handlers 9302 var _this = this; 9303 this.handleDraggabilly = { 9304 dragStart: function() { 9305 _this.itemDragStart( this.element ); 9306 }, 9307 dragMove: function() { 9308 _this.itemDragMove( this.element, this.position.x, this.position.y ); 9309 }, 9310 dragEnd: function() { 9311 _this.itemDragEnd( this.element ); 9312 } 9313 }; 9314 9315 this.handleUIDraggable = { 9316 start: function handleUIDraggableStart( event, ui ) { 9317 // HTML5 may trigger dragstart, dismiss HTML5 dragging 9318 if ( !ui ) { 9319 return; 9320 } 9321 _this.itemDragStart( event.currentTarget ); 9322 }, 9323 drag: function handleUIDraggableDrag( event, ui ) { 9324 if ( !ui ) { 9325 return; 9326 } 9327 _this.itemDragMove( event.currentTarget, ui.position.left, ui.position.top ); 9328 }, 9329 stop: function handleUIDraggableStop( event, ui ) { 9330 if ( !ui ) { 9331 return; 9332 } 9333 _this.itemDragEnd( event.currentTarget ); 9334 } 9335 }; 9336 9337}; 9338 9339 9340// ----- init & layout ----- // 9341 9342/** 9343 * logic before any new layout 9344 */ 9345proto._resetLayout = function() { 9346 this.getSize(); 9347 9348 this._getMeasurements(); 9349 9350 // reset packer 9351 var width, height, sortDirection; 9352 // packer settings, if horizontal or vertical 9353 if ( this._getOption('horizontal') ) { 9354 width = Infinity; 9355 height = this.size.innerHeight + this.gutter; 9356 sortDirection = 'rightwardTopToBottom'; 9357 } else { 9358 width = this.size.innerWidth + this.gutter; 9359 height = Infinity; 9360 sortDirection = 'downwardLeftToRight'; 9361 } 9362 9363 this.packer.width = this.shiftPacker.width = width; 9364 this.packer.height = this.shiftPacker.height = height; 9365 this.packer.sortDirection = this.shiftPacker.sortDirection = sortDirection; 9366 9367 this.packer.reset(); 9368 9369 // layout 9370 this.maxY = 0; 9371 this.maxX = 0; 9372}; 9373 9374/** 9375 * update columnWidth, rowHeight, & gutter 9376 * @private 9377 */ 9378proto._getMeasurements = function() { 9379 this._getMeasurement( 'columnWidth', 'width' ); 9380 this._getMeasurement( 'rowHeight', 'height' ); 9381 this._getMeasurement( 'gutter', 'width' ); 9382}; 9383 9384proto._getItemLayoutPosition = function( item ) { 9385 this._setRectSize( item.element, item.rect ); 9386 if ( this.isShifting || this.dragItemCount > 0 ) { 9387 var packMethod = this._getPackMethod(); 9388 this.packer[ packMethod ]( item.rect ); 9389 } else { 9390 this.packer.pack( item.rect ); 9391 } 9392 9393 this._setMaxXY( item.rect ); 9394 return item.rect; 9395}; 9396 9397proto.shiftLayout = function() { 9398 this.isShifting = true; 9399 this.layout(); 9400 delete this.isShifting; 9401}; 9402 9403proto._getPackMethod = function() { 9404 return this._getOption('horizontal') ? 'rowPack' : 'columnPack'; 9405}; 9406 9407 9408/** 9409 * set max X and Y value, for size of container 9410 * @param {Packery.Rect} rect 9411 * @private 9412 */ 9413proto._setMaxXY = function( rect ) { 9414 this.maxX = Math.max( rect.x + rect.width, this.maxX ); 9415 this.maxY = Math.max( rect.y + rect.height, this.maxY ); 9416}; 9417 9418/** 9419 * set the width and height of a rect, applying columnWidth and rowHeight 9420 * @param {Element} elem 9421 * @param {Packery.Rect} rect 9422 */ 9423proto._setRectSize = function( elem, rect ) { 9424 var size = getSize( elem ); 9425 var w = size.outerWidth; 9426 var h = size.outerHeight; 9427 // size for columnWidth and rowHeight, if available 9428 // only check if size is non-zero, #177 9429 if ( w || h ) { 9430 w = this._applyGridGutter( w, this.columnWidth ); 9431 h = this._applyGridGutter( h, this.rowHeight ); 9432 } 9433 // rect must fit in packer 9434 rect.width = Math.min( w, this.packer.width ); 9435 rect.height = Math.min( h, this.packer.height ); 9436}; 9437 9438/** 9439 * fits item to columnWidth/rowHeight and adds gutter 9440 * @param {Number} measurement - item width or height 9441 * @param {Number} gridSize - columnWidth or rowHeight 9442 * @returns measurement 9443 */ 9444proto._applyGridGutter = function( measurement, gridSize ) { 9445 // just add gutter if no gridSize 9446 if ( !gridSize ) { 9447 return measurement + this.gutter; 9448 } 9449 gridSize += this.gutter; 9450 // fit item to columnWidth/rowHeight 9451 var remainder = measurement % gridSize; 9452 var mathMethod = remainder && remainder < 1 ? 'round' : 'ceil'; 9453 measurement = Math[ mathMethod ]( measurement / gridSize ) * gridSize; 9454 return measurement; 9455}; 9456 9457proto._getContainerSize = function() { 9458 if ( this._getOption('horizontal') ) { 9459 return { 9460 width: this.maxX - this.gutter 9461 }; 9462 } else { 9463 return { 9464 height: this.maxY - this.gutter 9465 }; 9466 } 9467}; 9468 9469 9470// -------------------------- stamp -------------------------- // 9471 9472/** 9473 * makes space for element 9474 * @param {Element} elem 9475 */ 9476proto._manageStamp = function( elem ) { 9477 9478 var item = this.getItem( elem ); 9479 var rect; 9480 if ( item && item.isPlacing ) { 9481 rect = item.rect; 9482 } else { 9483 var offset = this._getElementOffset( elem ); 9484 rect = new Rect({ 9485 x: this._getOption('originLeft') ? offset.left : offset.right, 9486 y: this._getOption('originTop') ? offset.top : offset.bottom 9487 }); 9488 } 9489 9490 this._setRectSize( elem, rect ); 9491 // save its space in the packer 9492 this.packer.placed( rect ); 9493 this._setMaxXY( rect ); 9494}; 9495 9496// -------------------------- methods -------------------------- // 9497 9498function verticalSorter( a, b ) { 9499 return a.position.y - b.position.y || a.position.x - b.position.x; 9500} 9501 9502function horizontalSorter( a, b ) { 9503 return a.position.x - b.position.x || a.position.y - b.position.y; 9504} 9505 9506proto.sortItemsByPosition = function() { 9507 var sorter = this._getOption('horizontal') ? horizontalSorter : verticalSorter; 9508 this.items.sort( sorter ); 9509}; 9510 9511/** 9512 * Fit item element in its current position 9513 * Packery will position elements around it 9514 * useful for expanding elements 9515 * 9516 * @param {Element} elem 9517 * @param {Number} x - horizontal destination position, optional 9518 * @param {Number} y - vertical destination position, optional 9519 */ 9520proto.fit = function( elem, x, y ) { 9521 var item = this.getItem( elem ); 9522 if ( !item ) { 9523 return; 9524 } 9525 9526 // stamp item to get it out of layout 9527 this.stamp( item.element ); 9528 // set placing flag 9529 item.enablePlacing(); 9530 this.updateShiftTargets( item ); 9531 // fall back to current position for fitting 9532 x = x === undefined ? item.rect.x: x; 9533 y = y === undefined ? item.rect.y: y; 9534 // position it best at its destination 9535 this.shift( item, x, y ); 9536 this._bindFitEvents( item ); 9537 item.moveTo( item.rect.x, item.rect.y ); 9538 // layout everything else 9539 this.shiftLayout(); 9540 // return back to regularly scheduled programming 9541 this.unstamp( item.element ); 9542 this.sortItemsByPosition(); 9543 item.disablePlacing(); 9544}; 9545 9546/** 9547 * emit event when item is fit and other items are laid out 9548 * @param {Packery.Item} item 9549 * @private 9550 */ 9551proto._bindFitEvents = function( item ) { 9552 var _this = this; 9553 var ticks = 0; 9554 function onLayout() { 9555 ticks++; 9556 if ( ticks != 2 ) { 9557 return; 9558 } 9559 _this.dispatchEvent( 'fitComplete', null, [ item ] ); 9560 } 9561 // when item is laid out 9562 item.once( 'layout', onLayout ); 9563 // when all items are laid out 9564 this.once( 'layoutComplete', onLayout ); 9565}; 9566 9567// -------------------------- resize -------------------------- // 9568 9569// debounced, layout on resize 9570proto.resize = function() { 9571 // don't trigger if size did not change 9572 // or if resize was unbound. See #285, outlayer#9 9573 if ( !this.isResizeBound || !this.needsResizeLayout() ) { 9574 return; 9575 } 9576 9577 if ( this.options.shiftPercentResize ) { 9578 this.resizeShiftPercentLayout(); 9579 } else { 9580 this.layout(); 9581 } 9582}; 9583 9584/** 9585 * check if layout is needed post layout 9586 * @returns Boolean 9587 */ 9588proto.needsResizeLayout = function() { 9589 var size = getSize( this.element ); 9590 var innerSize = this._getOption('horizontal') ? 'innerHeight' : 'innerWidth'; 9591 return size[ innerSize ] != this.size[ innerSize ]; 9592}; 9593 9594proto.resizeShiftPercentLayout = function() { 9595 var items = this._getItemsForLayout( this.items ); 9596 9597 var isHorizontal = this._getOption('horizontal'); 9598 var coord = isHorizontal ? 'y' : 'x'; 9599 var measure = isHorizontal ? 'height' : 'width'; 9600 var segmentName = isHorizontal ? 'rowHeight' : 'columnWidth'; 9601 var innerSize = isHorizontal ? 'innerHeight' : 'innerWidth'; 9602 9603 // proportional re-align items 9604 var previousSegment = this[ segmentName ]; 9605 previousSegment = previousSegment && previousSegment + this.gutter; 9606 9607 if ( previousSegment ) { 9608 this._getMeasurements(); 9609 var currentSegment = this[ segmentName ] + this.gutter; 9610 items.forEach( function( item ) { 9611 var seg = Math.round( item.rect[ coord ] / previousSegment ); 9612 item.rect[ coord ] = seg * currentSegment; 9613 }); 9614 } else { 9615 var currentSize = getSize( this.element )[ innerSize ] + this.gutter; 9616 var previousSize = this.packer[ measure ]; 9617 items.forEach( function( item ) { 9618 item.rect[ coord ] = ( item.rect[ coord ] / previousSize ) * currentSize; 9619 }); 9620 } 9621 9622 this.shiftLayout(); 9623}; 9624 9625// -------------------------- drag -------------------------- // 9626 9627/** 9628 * handle an item drag start event 9629 * @param {Element} elem 9630 */ 9631proto.itemDragStart = function( elem ) { 9632 if ( !this.isEnabled ) { 9633 return; 9634 } 9635 this.stamp( elem ); 9636 // this.ignore( elem ); 9637 var item = this.getItem( elem ); 9638 if ( !item ) { 9639 return; 9640 } 9641 9642 item.enablePlacing(); 9643 item.showDropPlaceholder(); 9644 this.dragItemCount++; 9645 this.updateShiftTargets( item ); 9646}; 9647 9648proto.updateShiftTargets = function( dropItem ) { 9649 this.shiftPacker.reset(); 9650 9651 // pack stamps 9652 this._getBoundingRect(); 9653 var isOriginLeft = this._getOption('originLeft'); 9654 var isOriginTop = this._getOption('originTop'); 9655 this.stamps.forEach( function( stamp ) { 9656 // ignore dragged item 9657 var item = this.getItem( stamp ); 9658 if ( item && item.isPlacing ) { 9659 return; 9660 } 9661 var offset = this._getElementOffset( stamp ); 9662 var rect = new Rect({ 9663 x: isOriginLeft ? offset.left : offset.right, 9664 y: isOriginTop ? offset.top : offset.bottom 9665 }); 9666 this._setRectSize( stamp, rect ); 9667 // save its space in the packer 9668 this.shiftPacker.placed( rect ); 9669 }, this ); 9670 9671 // reset shiftTargets 9672 var isHorizontal = this._getOption('horizontal'); 9673 var segmentName = isHorizontal ? 'rowHeight' : 'columnWidth'; 9674 var measure = isHorizontal ? 'height' : 'width'; 9675 9676 this.shiftTargetKeys = []; 9677 this.shiftTargets = []; 9678 var boundsSize; 9679 var segment = this[ segmentName ]; 9680 segment = segment && segment + this.gutter; 9681 9682 if ( segment ) { 9683 var segmentSpan = Math.ceil( dropItem.rect[ measure ] / segment ); 9684 var segs = Math.floor( ( this.shiftPacker[ measure ] + this.gutter ) / segment ); 9685 boundsSize = ( segs - segmentSpan ) * segment; 9686 // add targets on top 9687 for ( var i=0; i < segs; i++ ) { 9688 this._addShiftTarget( i * segment, 0, boundsSize ); 9689 } 9690 } else { 9691 boundsSize = ( this.shiftPacker[ measure ] + this.gutter ) - dropItem.rect[ measure ]; 9692 this._addShiftTarget( 0, 0, boundsSize ); 9693 } 9694 9695 // pack each item to measure where shiftTargets are 9696 var items = this._getItemsForLayout( this.items ); 9697 var packMethod = this._getPackMethod(); 9698 items.forEach( function( item ) { 9699 var rect = item.rect; 9700 this._setRectSize( item.element, rect ); 9701 this.shiftPacker[ packMethod ]( rect ); 9702 9703 // add top left corner 9704 this._addShiftTarget( rect.x, rect.y, boundsSize ); 9705 // add bottom left / top right corner 9706 var cornerX = isHorizontal ? rect.x + rect.width : rect.x; 9707 var cornerY = isHorizontal ? rect.y : rect.y + rect.height; 9708 this._addShiftTarget( cornerX, cornerY, boundsSize ); 9709 9710 if ( segment ) { 9711 // add targets for each column on bottom / row on right 9712 var segSpan = Math.round( rect[ measure ] / segment ); 9713 for ( var i=1; i < segSpan; i++ ) { 9714 var segX = isHorizontal ? cornerX : rect.x + segment * i; 9715 var segY = isHorizontal ? rect.y + segment * i : cornerY; 9716 this._addShiftTarget( segX, segY, boundsSize ); 9717 } 9718 } 9719 }, this ); 9720 9721}; 9722 9723proto._addShiftTarget = function( x, y, boundsSize ) { 9724 var checkCoord = this._getOption('horizontal') ? y : x; 9725 if ( checkCoord !== 0 && checkCoord > boundsSize ) { 9726 return; 9727 } 9728 // create string for a key, easier to keep track of what targets 9729 var key = x + ',' + y; 9730 var hasKey = this.shiftTargetKeys.indexOf( key ) != -1; 9731 if ( hasKey ) { 9732 return; 9733 } 9734 this.shiftTargetKeys.push( key ); 9735 this.shiftTargets.push({ x: x, y: y }); 9736}; 9737 9738// -------------------------- drop -------------------------- // 9739 9740proto.shift = function( item, x, y ) { 9741 var shiftPosition; 9742 var minDistance = Infinity; 9743 var position = { x: x, y: y }; 9744 this.shiftTargets.forEach( function( target ) { 9745 var distance = getDistance( target, position ); 9746 if ( distance < minDistance ) { 9747 shiftPosition = target; 9748 minDistance = distance; 9749 } 9750 }); 9751 item.rect.x = shiftPosition.x; 9752 item.rect.y = shiftPosition.y; 9753}; 9754 9755function getDistance( a, b ) { 9756 var dx = b.x - a.x; 9757 var dy = b.y - a.y; 9758 return Math.sqrt( dx * dx + dy * dy ); 9759} 9760 9761// -------------------------- drag move -------------------------- // 9762 9763var DRAG_THROTTLE_TIME = 120; 9764 9765/** 9766 * handle an item drag move event 9767 * @param {Element} elem 9768 * @param {Number} x - horizontal change in position 9769 * @param {Number} y - vertical change in position 9770 */ 9771proto.itemDragMove = function( elem, x, y ) { 9772 var item = this.isEnabled && this.getItem( elem ); 9773 if ( !item ) { 9774 return; 9775 } 9776 9777 x -= this.size.paddingLeft; 9778 y -= this.size.paddingTop; 9779 9780 var _this = this; 9781 function onDrag() { 9782 _this.shift( item, x, y ); 9783 item.positionDropPlaceholder(); 9784 _this.layout(); 9785 } 9786 9787 // throttle 9788 var now = new Date(); 9789 if ( this._itemDragTime && now - this._itemDragTime < DRAG_THROTTLE_TIME ) { 9790 clearTimeout( this.dragTimeout ); 9791 this.dragTimeout = setTimeout( onDrag, DRAG_THROTTLE_TIME ); 9792 } else { 9793 onDrag(); 9794 this._itemDragTime = now; 9795 } 9796}; 9797 9798// -------------------------- drag end -------------------------- // 9799 9800/** 9801 * handle an item drag end event 9802 * @param {Element} elem 9803 */ 9804proto.itemDragEnd = function( elem ) { 9805 var item = this.isEnabled && this.getItem( elem ); 9806 if ( !item ) { 9807 return; 9808 } 9809 9810 clearTimeout( this.dragTimeout ); 9811 item.element.classList.add('is-positioning-post-drag'); 9812 9813 var completeCount = 0; 9814 var _this = this; 9815 function onDragEndLayoutComplete() { 9816 completeCount++; 9817 if ( completeCount != 2 ) { 9818 return; 9819 } 9820 // reset drag item 9821 item.element.classList.remove('is-positioning-post-drag'); 9822 item.hideDropPlaceholder(); 9823 _this.dispatchEvent( 'dragItemPositioned', null, [ item ] ); 9824 } 9825 9826 item.once( 'layout', onDragEndLayoutComplete ); 9827 this.once( 'layoutComplete', onDragEndLayoutComplete ); 9828 item.moveTo( item.rect.x, item.rect.y ); 9829 this.layout(); 9830 this.dragItemCount = Math.max( 0, this.dragItemCount - 1 ); 9831 this.sortItemsByPosition(); 9832 item.disablePlacing(); 9833 this.unstamp( item.element ); 9834}; 9835 9836/** 9837 * binds Draggabilly events 9838 * @param {Draggabilly} draggie 9839 */ 9840proto.bindDraggabillyEvents = function( draggie ) { 9841 this._bindDraggabillyEvents( draggie, 'on' ); 9842}; 9843 9844proto.unbindDraggabillyEvents = function( draggie ) { 9845 this._bindDraggabillyEvents( draggie, 'off' ); 9846}; 9847 9848proto._bindDraggabillyEvents = function( draggie, method ) { 9849 var handlers = this.handleDraggabilly; 9850 draggie[ method ]( 'dragStart', handlers.dragStart ); 9851 draggie[ method ]( 'dragMove', handlers.dragMove ); 9852 draggie[ method ]( 'dragEnd', handlers.dragEnd ); 9853}; 9854 9855/** 9856 * binds jQuery UI Draggable events 9857 * @param {jQuery} $elems 9858 */ 9859proto.bindUIDraggableEvents = function( $elems ) { 9860 this._bindUIDraggableEvents( $elems, 'on' ); 9861}; 9862 9863proto.unbindUIDraggableEvents = function( $elems ) { 9864 this._bindUIDraggableEvents( $elems, 'off' ); 9865}; 9866 9867proto._bindUIDraggableEvents = function( $elems, method ) { 9868 var handlers = this.handleUIDraggable; 9869 $elems 9870 [ method ]( 'dragstart', handlers.start ) 9871 [ method ]( 'drag', handlers.drag ) 9872 [ method ]( 'dragstop', handlers.stop ); 9873}; 9874 9875// ----- destroy ----- // 9876 9877var _destroy = proto.destroy; 9878proto.destroy = function() { 9879 _destroy.apply( this, arguments ); 9880 // disable flag; prevent drag events from triggering. #72 9881 this.isEnabled = false; 9882}; 9883 9884// ----- ----- // 9885 9886Packery.Rect = Rect; 9887Packery.Packer = Packer; 9888 9889return Packery; 9890 9891})); 9892 9893/*! 9894 * Packery layout mode v2.0.1 9895 * sub-classes Packery 9896 */ 9897 9898/*jshint browser: true, strict: true, undef: true, unused: true */ 9899 9900( function( window, factory ) {
9901 9902 // universal module definition 9903 if ( typeof define == 'function' && define.amd ) { 9904 // AMD 9905 define( [ 9906 'isotope-layout/js/layout-mode', 9907 'packery/js/packery' 9908 ], 9909 factory ); 9910 } else if ( typeof module == 'object' && module.exports ) { 9911 // CommonJS 9912 module.exports = factory( 9913 require('isotope-layout/js/layout-mode'), 9914 require('packery') 9915 ); 9916 } else { 9917 // browser global 9918 factory( 9919 window.Isotope.LayoutMode, 9920 window.Packery 9921 ); 9922 } 9923 9924}( window, function factor( LayoutMode, Packery ) { 9925 9926 9927 // create an Outlayer layout class 9928 var PackeryMode = LayoutMode.create('packery'); 9929 var proto = PackeryMode.prototype; 9930 9931 var keepModeMethods = { 9932 _getElementOffset: true, 9933 _getMeasurement: true 9934 }; 9935 9936 // inherit Packery prototype 9937 for ( var method in Packery.prototype ) { 9938 // do not inherit mode methods 9939 if ( !keepModeMethods[ method ] ) { 9940 proto[ method ] = Packery.prototype[ method ]; 9941 } 9942 } 9943 9944 // set packer in _resetLayout 9945 var _resetLayout = proto._resetLayout; 9946 proto._resetLayout = function() { 9947 this.packer = this.packer || new Packery.Packer(); 9948 this.shiftPacker = this.shiftPacker || new Packery.Packer(); 9949 _resetLayout.apply( this, arguments ); 9950 }; 9951 9952 var _getItemLayoutPosition = proto._getItemLayoutPosition; 9953 proto._getItemLayoutPosition = function( item ) { 9954 // set packery rect 9955 item.rect = item.rect || new Packery.Rect(); 9956 return _getItemLayoutPosition.call( this, item ); 9957 }; 9958 9959 // needsResizeLayout for vertical or horizontal 9960 var _needsResizeLayout = proto.needsResizeLayout; 9961 proto.needsResizeLayout = function() { 9962 if ( this._getOption('horizontal') ) { 9963 return this.needsVerticalResizeLayout(); 9964 } else { 9965 return _needsResizeLayout.call( this ); 9966 } 9967 }; 9968 9969 // point to mode options for horizontal 9970 var _getOption = proto._getOption; 9971 proto._getOption = function( option ) { 9972 if ( option == 'horizontal' ) { 9973 return this.options.isHorizontal !== undefined ? 9974 this.options.isHorizontal : this.options.horizontal; 9975 } 9976 return _getOption.apply( this.isotope, arguments ); 9977 }; 9978 9979 return PackeryMode; 9980 9981})); 9982 9983/*! 9984 * cellsByRows layout mode for Isotope 9985 * v1.1.3 9986 * http://isotope.metafizzy.co/layout-modes/cellsbyrow.html 9987 */ 9988 9989/*jshint browser: true, devel: false, strict: true, undef: true, unused: true */ 9990 9991( function( window, factory ) { 9992 // universal module definition 9993 /* jshint strict: false */ /*globals define, module, require */ 9994 if ( typeof define === 'function' && define.amd ) { 9995 // AMD 9996 define( [ 9997 'isotope/js/layout-mode' 9998 ], 9999 factory ); 10000 } else if ( typeof exports === 'object' ) { 10001 // CommonJS 10002 module.exports = factory( 10003 require('isotope-layout/js/layout-mode') 10004 ); 10005 } else { 10006 // browser global 10007 factory( 10008 window.Isotope.LayoutMode 10009 ); 10010 } 10011 10012}( window, function factory( LayoutMode ) { 10013 'use strict'; 10014 10015 var CellsByRow = LayoutMode.create( 'cellsByRow' ); 10016 var proto = CellsByRow.prototype; 10017 10018 proto._resetLayout = function() { 10019 // reset properties 10020 this.itemIndex = 0; 10021 // measurements 10022 this.getColumnWidth(); 10023 this.getRowHeight(); 10024 // set cols 10025 this.cols = Math.floor( this.isotope.size.innerWidth / this.columnWidth ); 10026 this.cols = Math.max( this.cols, 1 ); 10027 }; 10028 10029 proto._getItemLayoutPosition = function( item ) { 10030 item.getSize(); 10031 var col = this.itemIndex % this.cols; 10032 var row = Math.floor( this.itemIndex / this.cols ); 10033 // center item within cell 10034 var x = ( col + 0.5 ) * this.columnWidth - item.size.outerWidth / 2; 10035 var y = ( row + 0.5 ) * this.rowHeight - item.size.outerHeight / 2; 10036 this.itemIndex++; 10037 return { x: x, y: y }; 10038 }; 10039 10040 proto._getContainerSize = function() { 10041 return { 10042 height: Math.ceil( this.itemIndex / this.cols ) * this.rowHeight 10043 }; 10044 }; 10045 10046 return CellsByRow; 10047 10048})); 10049/*global jQuery: true */ 10050 10051/*! 10052 -------------------------------- 10053 Infinite Scroll 10054 -------------------------------- 10055 + https://github.com/paulirish/infinite-scroll 10056 + version 2.1.0 10057 + Copyright 2011/12 Paul Irish & Luke Shumard 10058 + Licensed under the MIT license 10059 10060 + Documentation: http://infinite-scroll.com/ 10061*/ 10062 10063// Uses AMD or browser globals to create a jQuery plugin. 10064(function (factory) { 10065 if (typeof define === 'function' && define.amd) { 10066 // AMD. Register as an anonymous module. 10067 define(['jquery'], factory); 10068 } else { 10069 // Browser globals 10070 factory(jQuery); 10071 } 10072}(function ($, undefined) { 10073 'use strict'; 10074
10075 $.infinitescroll = function infscr(options, callback, element) { 10076 this.element = $(element); 10077 10078 // Flag the object in the event of a failed creation 10079 if (!this._create(options, callback)) { 10080 this.failed = true; 10081 } 10082 }; 10083 10084 $.infinitescroll.defaults = { 10085 loading: { 10086 finished: undefined, 10087 finishedMsg: "<em>Congratulations, you've reached the end of the internet.</em>", 10088 img: 'data:image/gif;base64,R0lGODlh3AATAPQeAPDy+MnQ6LW/4N3h8MzT6rjC4sTM5r/I5NHX7N7j8c7U6tvg8OLl8uXo9Ojr9b3G5MfP6Ovu9tPZ7PT1+vX2+tbb7vf4+8/W69jd7rC73vn5/O/x+K243ai02////wAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQECgD/ACwAAAAA3AATAAAF/6AnjmRpnmiqrmzrvnAsz3Rt33iu73zv/8CgcEj0BAScpHLJbDqf0Kh0Sq1ar9isdioItAKGw+MAKYMFhbF63CW438f0mg1R2O8EuXj/aOPtaHx7fn96goR4hmuId4qDdX95c4+RBIGCB4yAjpmQhZN0YGYGXitdZBIVGAsLoq4BBKQDswm1CQRkcG6ytrYKubq8vbfAcMK9v7q7EMO1ycrHvsW6zcTKsczNz8HZw9vG3cjTsMIYqQkCLBwHCgsMDQ4RDAYIqfYSFxDxEfz88/X38Onr16+Bp4ADCco7eC8hQYMAEe57yNCew4IVBU7EGNDiRn8Z831cGLHhSIgdFf9chIeBg7oA7gjaWUWTVQAGE3LqBDCTlc9WOHfm7PkTqNCh54rePDqB6M+lR536hCpUqs2gVZM+xbrTqtGoWqdy1emValeXKzggYBBB5y1acFNZmEvXAoN2cGfJrTv3bl69Ffj2xZt3L1+/fw3XRVw4sGDGcR0fJhxZsF3KtBTThZxZ8mLMgC3fRatCbYMNFCzwLEqLgE4NsDWs/tvqdezZf13Hvk2A9Szdu2X3pg18N+68xXn7rh1c+PLksI/Dhe6cuO3ow3NfV92bdArTqC2Ebd3A8vjf5QWfH6Bg7Nz17c2fj69+fnq+8N2Lty+fuP78/eV2X13neIcCeBRwxorbZrA1ANoCDGrgoG8RTshahQ9iSKEEzUmYIYfNWViUhheCGJyIP5E4oom7WWjgCeBFAJNv1DVV01MAdJhhjdkplWNzO/5oXI846njjVEIqR2OS2B1pE5PVscajkxhMycqLJghQSwT40PgfAl4GqNSXYdZXJn5gSkmmmmJu1aZYb14V51do+pTOCmA40AqVCIhG5IJ9PvYnhIFOxmdqhpaI6GeHCtpooisuutmg+Eg62KOMKuqoTaXgicQWoIYq6qiklmoqFV0UoeqqrLbq6quwxirrrLTWauutJ4QAACH5BAUKABwALAcABADOAAsAAAX/IPd0D2dyRCoUp/k8gpHOKtseR9yiSmGbuBykler9XLAhkbDavXTL5k2oqFqNOxzUZPU5YYZd1XsD72rZpBjbeh52mSNnMSC8lwblKZGwi+0QfIJ8CncnCoCDgoVnBHmKfByGJimPkIwtiAeBkH6ZHJaKmCeVnKKTHIihg5KNq4uoqmEtcRUtEREMBggtEr4QDrjCuRC8h7/BwxENeicSF8DKy82pyNLMOxzWygzFmdvD2L3P0dze4+Xh1Arkyepi7dfFvvTtLQkZBC0T/FX3CRgCMOBHsJ+EHYQY7OinAGECgQsB+Lu3AOK+CewcWjwxQeJBihtNGHSoQOE+iQ3//4XkwBBhRZMcUS6YSXOAwIL8PGqEaSJCiYt9SNoCmnJPAgUVLChdaoFBURN8MAzl2PQphwQLfDFd6lTowglHve6rKpbjhK7/pG5VinZP1qkiz1rl4+tr2LRwWU64cFEihwEtZgbgR1UiHaMVvxpOSwBA37kzGz9e8G+B5MIEKLutOGEsAH2ATQwYfTmuX8aETWdGPZmiZcccNSzeTCA1Sw0bdiitC7LBWgu8jQr8HRzqgpK6gX88QbrB14z/kF+ELpwB8eVQj/JkqdylAudji/+ts3039vEEfK8Vz2dlvxZKG0CmbkKDBvllRd6fCzDvBLKBDSCeffhRJEFebFk1k/Mv9jVIoIJZSeBggwUaNeB+Qk34IE0cXlihcfRxkOAJFFhwGmKlmWDiakZhUJtnLBpnWWcnKaAZcxI0piFGGLBm1mc90kajSCveeBVWKeYEoU2wqeaQi0PetoE+rr14EpVC7oAbAUHqhYExbn2XHHsVqbcVew9tx8+XJKk5AZsqqdlddGpqAKdbAYBn1pcczmSTdWvdmZ17c1b3FZ99vnTdCRFM8OEcAhLwm1NdXnWcBBSMRWmfkWZqVlsmLIiAp/o1gGV2vpS4lalGYsUOqXrddcKCmK61aZ8SjEpUpVFVoCpTj4r661Km7kBHjrDyc1RAIQAAIfkEBQoAGwAsBwAEAM4ACwAABf/gtmUCd4goQQgFKj6PYKi0yrrbc8i4ohQt12EHcal+MNSQiCP8gigdz7iCioaCIvUmZLp8QBzW0EN2vSlCuDtFKaq4RyHzQLEKZNdiQDhRDVooCwkbfm59EAmKi4SGIm+AjIsKjhsqB4mSjT2IOIOUnICeCaB/mZKFNTSRmqVpmJqklSqskq6PfYYCDwYHDC4REQwGCBLGxxIQDsHMwhAIX8bKzcENgSLGF9PU1j3Sy9zX2NrgzQziChLk1BHWxcjf7N046tvN82715czn9Pryz6Ilc4ACj4EBOCZM8KEnAYYADBRKnACAYUMFv1wotIhCEcaJCisqwJFgAUSQGyX/kCSVUUTIdKMwJlyo0oXHlhskwrTJciZHEXsgaqS4s6PJiCAr1uzYU8kBBSgnWFqpoMJMUjGtDmUwkmfVmVypakWhEKvXsS4nhLW5wNjVroJIoc05wSzTr0PtiigpYe4EC2vj4iWrFu5euWIMRBhacaVJhYQBEFjA9jHjyQ0xEABwGceGAZYjY0YBOrRLCxUp29QM+bRkx5s7ZyYgVbTqwwti2ybJ+vLtDYpycyZbYOlptxdx0kV+V7lC5iJAyyRrwYKxAdiz82ng0/jnAdMJFz0cPi104Ec1Vj9/M6F173vKL/feXv156dw11tlqeMMnv4V5Ap53GmjQQH97nFfg+IFiucfgRX5Z8KAgbUlQ4IULIlghhhdOSB6AgX0IVn8eReghen3NRIBsRgnH4l4LuEidZBjwRpt6NM5WGwoW0KSjCwX6yJSMab2GwwAPDXfaBCtWpluRTQqC5JM5oUZAjUNS+VeOLWpJEQ7VYQANW0INJSZVDFSnZphjSikfmzE5N4EEbQI1QJmnWXCmHulRp2edwDXF43txukenJwvI9xyg9Q26Z3MzGUcBYFEChZh6DVTq34AU8Iflh51Sd+CnKFYQ6mmZkhqfBKfSxZWqA9DZanWjxmhrWwi0qtCrt/43K6WqVjjpmhIqgEGvculaGKklKstAACEAACH5BAUKABwALAcABADOAAsAAAX/ICdyQmaMYyAUqPgIBiHPxNpy79kqRXH8wAPsRmDdXpAWgWdEIYm2llCHqjVHU+jjJkwqBTecwItShMXkEfNWSh8e1NGAcLgpDGlRgk7EJ/6Ae3VKfoF/fDuFhohVeDeCfXkcCQqDVQcQhn+VNDOYmpSWaoqBlUSfmowjEA+iEAEGDRGztAwGCDcXEA60tXEiCrq8vREMEBLIyRLCxMWSH
10088MzExnbRvQ2Sy7vN0zvVtNfU2tLY3rPgLdnDvca4VQS/Cpk3ABwSLQkYAQwT/P309vcI7OvXr94jBQMJ/nskkGA/BQBRLNDncAIAiDcG6LsxAWOLiQzmeURBKWSLCQbv/1F0eDGinJUKR47YY1IEgQASKk7Yc7ACRwZm7mHweRJoz59BJUogisKCUaFMR0x4SlJBVBFTk8pZivTR0K73rN5wqlXEAq5Fy3IYgHbEzQ0nLy4QSoCjXLoom96VOJEeCosK5n4kkFfqXjl94wa+l1gvAcGICbewAOAxY8l/Ky/QhAGz4cUkGxu2HNozhwMGBnCUqUdBg9UuW9eUynqSwLHIBujePef1ZGQZXcM+OFuEBeBhi3OYgLyqcuaxbT9vLkf4SeqyWxSQpKGB2gQpm1KdWbu72rPRzR9Ne2Nu9Kzr/1Jqj0yD/fvqP4aXOt5sW/5qsXXVcv1Nsp8IBUAmgswGF3llGgeU1YVXXKTN1FlhWFXW3gIE+DVChApysACHHo7Q4A35lLichh+ROBmLKAzgYmYEYDAhCgxKGOOMn4WR4kkDaoBBOxJtdNKQxFmg5JIWIBnQc07GaORfUY4AEkdV6jHlCEISSZ5yTXpp1pbGZbkWmcuZmQCaE6iJ0FhjMaDjTMsgZaNEHFRAQVp3bqXnZED1qYcECOz5V6BhSWCoVJQIKuKQi2KFKEkEFAqoAo7uYSmO3jk61wUUMKmknJ4SGimBmAa0qVQBhAAAIfkEBQoAGwAsBwAEAM4ACwAABf/gJm5FmRlEqhJC+bywgK5pO4rHI0D3pii22+Mg6/0Ej96weCMAk7cDkXf7lZTTnrMl7eaYoy10JN0ZFdco0XAuvKI6qkgVFJXYNwjkIBcNBgR8TQoGfRsJCRuCYYQQiI+ICosiCoGOkIiKfSl8mJkHZ4U9kZMbKaI3pKGXmJKrngmug4WwkhA0lrCBWgYFCCMQFwoQDRHGxwwGCBLMzRLEx8iGzMMO0cYNeCMKzBDW19lnF9DXDIY/48Xg093f0Q3s1dcR8OLe8+Y91OTv5wrj7o7B+7VNQqABIoRVCMBggsOHE36kSoCBIcSH3EbFangxogJYFi8CkJhqQciLJEf/LDDJEeJIBT0GsOwYUYJGBS0fjpQAMidGmyVP6sx4Y6VQhzs9VUwkwqaCCh0tmKoFtSMDmBOf9phg4SrVrROuasRQAaxXpVUhdsU6IsECZlvX3kwLUWzRt0BHOLTbNlbZG3vZinArge5Dvn7wbqtQkSYAAgtKmnSsYKVKo2AfW048uaPmG386i4Q8EQMBAIAnfB7xBxBqvapJ9zX9WgRS2YMpnvYMGdPK3aMjt/3dUcNI4blpj7iwkMFWDXDvSmgAlijrt9RTR78+PS6z1uAJZIe93Q8g5zcsWCi/4Y+C8bah5zUv3vv89uft30QP23punGCx5954oBBwnwYaNCDY/wYrsYeggnM9B2Fpf8GG2CEUVWhbWAtGouEGDy7Y4IEJVrbSiXghqGKIo7z1IVcXIkKWWR361QOLWWnIhwERpLaaCCee5iMBGJQmJGyPFTnbkfHVZGRtIGrg5HALEJAZbu39BuUEUmq1JJQIPtZilY5hGeSWsSk52G9XqsmgljdIcABytq13HyIM6RcUA+r1qZ4EBF3WHWB29tBgAzRhEGhig8KmqKFv8SeCeo+mgsF7YFXa1qWSbkDpom/mqR1PmHCqJ3fwNRVXjC7S6CZhFVCQ2lWvZiirhQq42SACt25IK2hv8TprriUV1usGgeka7LFcNmCldMLi6qZMgFLgpw16Cipb7bC1knXsBiEAACH5BAUKABsALAcABADOAAsAAAX/4FZsJPkUmUGsLCEUTywXglFuSg7fW1xAvNWLF6sFFcPb42C8EZCj24EJdCp2yoegWsolS0Uu6fmamg8n8YYcLU2bXSiRaXMGvqV6/KAeJAh8VgZqCX+BexCFioWAYgqNi4qAR4ORhRuHY408jAeUhAmYYiuVlpiflqGZa5CWkzc5fKmbbhIpsAoQDRG8vQwQCBLCwxK6vb5qwhfGxxENahvCEA7NzskSy7vNzzzK09W/PNHF1NvX2dXcN8K55cfh69Luveol3vO8zwi4Yhj+AQwmCBw4IYclDAAJDlQggVOChAoLKkgFkSCAHDwWLKhIEOONARsDKryogFPIiAUb/95gJNIiw4wnI778GFPhzBKFOAq8qLJEhQpiNArjMcHCmlTCUDIouTKBhApELSxFWiGiVKY4E2CAekPgUphDu0742nRrVLJZnyrFSqKQ2ohoSYAMW6IoDpNJ4bLdILTnAj8KUF7UeENjAKuDyxIgOuGiOI0EBBMgLNew5AUrDTMGsFixwBIaNCQuAXJB57qNJ2OWm2Aj4skwCQCIyNkhhtMkdsIuodE0AN4LJDRgfLPtn5YDLdBlraAByuUbBgxQwICxMOnYpVOPej074OFdlfc0TqC62OIbcppHjV4o+LrieWhfT8JC/I/T6W8oCl29vQ0XjLdBaA3s1RcPBO7lFvpX8BVoG4O5jTXRQRDuJ6FDTzEWF1/BCZhgbyAKE9qICYLloQYOFtahVRsWYlZ4KQJHlwHS/IYaZ6sZd9tmu5HQm2xi1UaTbzxYwJk/wBF5g5EEYOBZeEfGZmNdFyFZmZIR4jikbLThlh5kUUVJGmRT7sekkziRWUIACABk3T4qCsedgO4xhgGcY7q5pHJ4klBBTQRJ0CeHcoYHHUh6wgfdn9uJdSdMiebGJ0zUPTcoS286FCkrZxnYoYYKWLkBowhQoBeaOlZAgVhLidrXqg2G
10088iqpQpZ4apwSwRtjqrB3muoF9BboaXKmshlqWqsWiGt2wphJkQbAU5hoCACH5BAUKABsALAcABADOAAsAAAX/oGFw2WZuT5oZROsSQnGaKjRvilI893MItlNOJ5v5gDcFrHhKIWcEYu/xFEqNv6B1N62aclysF7fsZYe5aOx2yL5aAUGSaT1oTYMBwQ5VGCAJgYIJCnx1gIOBhXdwiIl7d0p2iYGQUAQBjoOFSQR/lIQHnZ+Ue6OagqYzSqSJi5eTpTxGcjcSChANEbu8DBAIEsHBChe5vL13G7fFuscRDcnKuM3H0La3EA7Oz8kKEsXazr7Cw9/Gztar5uHHvte47MjktznZ2w0G1+D3BgirAqJmJMAQgMGEgwgn5Ei0gKDBhBMALGRYEOJBb5QcWlQo4cbAihZz3GgIMqFEBSM1/4ZEOWPAgpIIJXYU+PIhRG8ja1qU6VHlzZknJNQ6UanCjQkWCIGSUGEjAwVLjc44+DTqUQtPPS5gejUrTa5TJ3g9sWCr1BNUWZI161StiQUDmLYdGfesibQ3XMq1OPYthrwuA2yU2LBs2cBHIypYQPPlYAKFD5cVvNPtW8eVGbdcQADATsiNO4cFAPkvHpedPzc8kUcPgNGgZ5RNDZG05reoE9s2vSEP79MEGiQGy1qP8LA4ZcdtsJE48ONoLTBtTV0B9LsTnPceoIDBDQvS7W7vfjVY3q3eZ4A339J4eaAmKqU/sV58HvJh2RcnIBsDUw0ABqhBA5aV5V9XUFGiHfVeAiWwoFgJJrIXRH1tEMiDFV4oHoAEGlaWhgIGSGBO2nFomYY3mKjVglidaNYJGJDkWW2xxTfbjCbVaOGNqoX2GloR8ZeTaECS9pthRGJH2g0b3Agbk6hNANtteHD2GJUucfajCQBy5OOTQ25ZgUPvaVVQmbKh9510/qQpwXx3SQdfk8tZJOd5b6JJFplT3ZnmmX3qd5l1eg5q00HrtUkUn0AKaiGjClSAgKLYZcgWXwocGRcCFGCKwSB6ceqphwmYRUFYT/1WKlOdUpipmxW0mlCqHjYkAaeoZlqrqZ4qd+upQKaapn/AmgAegZ8KUtYtFAQQAgAh+QQFCgAbACwHAAQAzgALAAAF/+C2PUcmiCiZGUTrEkKBis8jQEquKwU5HyXIbEPgyX7BYa5wTNmEMwWsSXsqFbEh8DYs9mrgGjdK6GkPY5GOeU6ryz7UFopSQEzygOGhJBjoIgMDBAcBM0V/CYqLCQqFOwobiYyKjn2TlI6GKC2YjJZknouaZAcQlJUHl6eooJwKooobqoewrJSEmyKdt59NhRKFMxLEEA4RyMkMEAjDEhfGycqAG8TQx9IRDRDE3d3R2ctD1RLg0ttKEnbY5wZD3+zJ6M7X2RHi9Oby7u/r9g38UFjTh2xZJBEBMDAboogAgwkQI07IMUORwocSJwCgWDFBAIwZOaJIsOBjRogKJP8wTODw5ESVHVtm3AhzpEeQElOuNDlTZ0ycEUWKWFASqEahGwYUPbnxoAgEdlYSqDBkgoUNClAlIHbSAoOsqCRQnQHxq1axVb06FWFxLIqyaze0Tft1JVqyE+pWXMD1pF6bYl3+HTqAWNW8cRUFzmih0ZAAB2oGKukSAAGGRHWJgLiR6AylBLpuHKKUMlMCngMpDSAa9QIUggZVVvDaJobLeC3XZpvgNgCmtPcuwP3WgmXSq4do0DC6o2/guzcseECtUoO0hmcsGKDgOt7ssBd07wqesAIGZC1YIBa7PQHvb1+SFo+++HrJSQfB33xfav3i5eX3Hnb4CTJgegEq8tH/YQEOcIJzbm2G2EoYRLgBXFpVmFYDcREV4HIcnmUhiGBRouEMJGJGzHIspqgdXxK0yCKHRNXoIX4uorCdTyjkyNtdPWrA4Up82EbAbzMRxxZRR54WXVLDIRmRcag5d2R6ugl3ZXzNhTecchpMhIGVAKAYpgJjjsSklBEd99maZoo535ZvdamjBEpusJyctg3h4X8XqodBMx0tiNeg/oGJaKGABpogS40KSqiaEgBqlQWLUtqoVQnytekEjzo0hHqhRorppOZt2p923M2AAV+oBtpAnnPNoB6HaU6mAAIU+IXmi3j2mtFXuUoHKwXpzVrsjcgGOauKEjQrwq157hitGq2NoWmjh7z6Wmxb0m5w66+2VRAuXN/yFUAIACH5BAUKABsALAcABADOAAsAAAX/4CZuRiaM45MZqBgIRbs9AqTcuFLE7VHLOh7KB5ERdjJaEaU4ClO/lgKWjKKcMiJQ8KgumcieVdQMD8cbBeuAkkC6LYLhOxoQ2PF5Ys9PKPBMen17f0CCg4VSh32JV4t8jSNqEIOEgJKPlkYBlJWRInKdiJdkmQlvKAsLBxdABA4RsbIMBggtEhcQsLKxDBC2TAS6vLENdJLDxMZAubu8vjIbzcQRtMzJz79S08oQEt/guNiyy7fcvMbh4OezdAvGrakLAQwyABsELQkY9BP+//ckyPDD4J9BfAMh1GsBoImMeQUN+lMgUJ9CiRMa5msxoB9Gh/o8GmxYMZXIgxtR/yQ46S/gQAURR0pDwYDfywoyLPip5AdnCwsMFPBU4BPFhKBDi444quCmDKZOfwZ9KEGpCKgcN1jdALSpPqIYsabS+nSqvqplvYqQYAeDPgwKwjaMtiDl0oaqUAyo+3TuWwUAMPpVCfee0cEjVBGQq2ABx7oTWmQk4FglZMGN9fGVDMCuiH2AOVOu/PmyxM630gwM0CCn6q8LjVJ8GXvpa5Uwn95OTC/nNxkda1/dLSK475IjCD6dHbK1ZOa4hXP9DXs5chJ00UpVm5xo2qRpoxptwF2E4/IbJpB/SDz9+q9b1aNfQH08+p4a8uvX8B53fLP+ycAfemjsRUBgp1H20K+BghHgVgt1GXZXZpZ5lt4ECjxYR4ScUWiShEtZqBiIInRGWnERNnjiBglw+JyGnxUmGowsyiiZg189lNtPGACjV2+S9UjbU0JWF6SPvEk3QZEqsZYTk3UAaRSUnznJI5LmESCdBVSyaOWUWLK4I5gDUYVeV1T9l+FZClCAUVA09uSmRHBCKAECFEhW51ht6rnmWBXkaR+NjuHpJ40D3DmnQXt2F+ihZxlqVKOfQRACACH5BAUKABwALAcABADOAAsAAAX/ICdyUCkUo/g8mUG8MCGkKgspeC6j6XEIEBpBUeCNfECaglBcOVfJFK7YQwZHQ6JRZBUqTrSuVEuD3nI45pYjFuWKvjjSkCoRaBUMWxkwBGgJCXspQ36Bh4EEB0oKhoiBgyNLjo8Ki4QElIiWfJqHnISNEI+Ql5J9o6SgkqKkgqYihamPkW6oNBgSfiMMDQkGCBLCwxIQDhHIyQwQCGMKxsnKVyPCF9DREQ3MxMPX0cu4wt7J2uHWx9jlKd3o39MiuefYEcvNkuLt5O8c1ePI2tyELXGQwoGDAQf+iEC2xByDCRAjTlAgIUWCBRgCPJQ4AQBFXAs0coT40WLIjRxL/47AcHLkxIomRXL0CHPERZkpa4q4iVKiyp0tR/7kwHMkTUBBJR5dOCEBAVcKKtCAyOHpowXCpk7goABqBZdcvWploACpBKkpIJI1q5OD2rIWE0R1uTZu1LFwbWL9OlKuWb4c6+o9i3dEgw0RCGDUG9KlRw56gDY2qmCByZBaASi+TACA0TucAaTteCcy0ZuOK3N2vJlx58+LRQyY3Xm0ZsgjZg+oPQLi7dUcNXi0LOJw1pgNtB7XG6CBy+U75SYfPTSQAgZTNUDnQHt67wnbZyvwLgKiMN3oCZB3C76tdewpLFgIP2C88rbi4Y+QT3+8S5USMICZXWj1pkEDeUU3lOYGB3alSoEiMIjgX4WlgNF2EibIwQIXauWXSRg2SAOHIU5IIIMoZkhhWiJaiFVbKo6AQEgQXrTAazO1JhkBrBG3Y2Y6EsUhaGn95hprSN0oWpFE7rhkeaQBchGOEWnwEmc0uKWZj0LeuNV3W4Y2lZHFlQCSRjTIl8uZ+kG5HU/3sRlnTG2ytyadytnD3HrmuRcSn+0h1dycexIK1KCjYaCnjCCVqOFFJTZ5GkUUjESWaUIKU2lgCmAKKQIUjHapXRKE+t2og1VgankNYnohqKJ2CmKplso6GKz7WYCgqxeuyoF8u9IQAgA7', 10089 msg: null, 10090 msgText: '<em>Loading the next set of posts...</em>', 10091 selector: null, 10092 speed: 'fast', 10093 start: undefined 10094 }, 10095 state: { 10096 isDuringAjax: false, 10097 isInvalidPage: false,
10098 isDestroyed: false, 10099 isDone: false, // For when it goes all the way through the archive. 10100 isPaused: false, 10101 isBeyondMaxPage: false, 10102 currPage: 1 10103 }, 10104 debug: false, 10105 behavior: undefined, 10106 binder: $(window), // used to cache the selector 10107 nextSelector: 'div.navigation a:first', 10108 navSelector: 'div.navigation', 10109 contentSelector: null, // rename to pageFragment 10110 extraScrollPx: 150, 10111 itemSelector: 'div.post', 10112 animate: false, 10113 pathParse: undefined, 10114 dataType: 'html', 10115 appendCallback: true, 10116 bufferPx: 40, 10117 errorCallback: function () { }, 10118 infid: 0, //Instance ID 10119 pixelsFromNavToBottom: undefined, 10120 path: undefined, // Either parts of a URL as an array (e.g. ["/page/", "/"] or a function that takes in the page number and returns a URL 10121 prefill: false, // When the document is smaller than the window, load data until the document is larger or links are exhausted 10122 maxPage: undefined // to manually control maximum page (when maxPage is undefined, maximum page limitation is not work) 10123 }; 10124 10125 $.infinitescroll.prototype = { 10126 10127 /* 10128 ---------------------------- 10129 Private methods 10130 ---------------------------- 10131 */ 10132 10133 // Bind or unbind from scroll 10134 _binding: function infscr_binding(binding) { 10135 10136 var instance = this, 10137 opts = instance.options; 10138 10139 opts.v = '2.0b2.120520'; 10140 10141 // if behavior is defined and this function is extended, call that instead of default 10142 if (!!opts.behavior && this['_binding_'+opts.behavior] !== undefined) { 10143 this['_binding_'+opts.behavior].call(this); 10144 return; 10145 } 10146 10147 if (binding !== 'bind' && binding !== 'unbind') { 10148 this._debug('Binding value ' + binding + ' not valid'); 10149 return false; 10150 } 10151 10152 if (binding === 'unbind') { 10153 (this.options.binder).unbind('smartscroll.infscr.' + instance.options.infid); 10154 } else { 10155 (this.options.binder)[binding]('smartscroll.infscr.' + instance.options.infid, function () { 10156 instance.scroll(); 10157 }); 10158 } 10159 10160 this._debug('Binding', binding); 10161 }, 10162 10163 // Fundamental aspects of the plugin are initialized 10164 _create: function infscr_create(options, callback) { 10165 10166 // Add custom options to defaults 10167 var opts = $.extend(true, {}, $.infinitescroll.defaults, options); 10168 this.options = opts; 10169 var $window = $(window); 10170 var instance = this; 10171 10172 // Validate selectors 10173 if (!instance._validate(options)) { 10174 return false; 10175 } 10176 10177 // Validate page fragment path 10178 var path = $(opts.nextSelector).attr('href'); 10179 if (!path) { 10180 this._debug('Navigation selector not found'); 10181 return false; 10182 } 10183 10184 // Set the path to be a relative URL from root. 10185 opts.path = opts.path || this._determinepath(path); 10186 10187 // contentSelector is 'page fragment' option for .load() / .ajax() calls 10188 opts.contentSelector = opts.contentSelector || this.element; 10189 10190 // loading.selector - if we want to place the load message in a specific selector, defaulted to the contentSelector 10191 opts.loading.selector = opts.loading.selector || opts.contentSelector; 10192 10193 // Define loading.msg 10194 opts.loading.msg = opts.loading.msg || $('<div id="infscr-loading"><img alt="Loading..." src="' + opts.loading.img + '" /><div>' + opts.loading.msgText + '</div></div>'); 10195 10196 // Preload loading.img 10197 (new Image()).src = opts.loading.img; 10198 10199 // distance from nav links to bottom 10200 // computed as: height of the document + top offset of container - top offset of nav link 10201 if(opts.pixelsFromNavToBottom === undefined) { 10202 opts.pixelsFromNavToBottom = $(document).height() - $(opts.navSelector).offset().top; 10203 this._debug('pixelsFromNavToBottom: ' + opts.pixelsFromNavToBottom); 10204 } 10205 10206 var self = this; 10207 10208 // determine loading.start actions 10209 opts.loading.start = opts.loading.start || function() { 10210 $(opts.navSelector).hide(); 10211 opts.loading.msg 10212 .appendTo(opts.loading.selector) 10213 .show(opts.loading.speed, $.proxy(function() { 10214 this.beginAjax(opts); 10215 }, self)); 10216 }; 10217 10218 // determine loading.finished actions 10219 opts.loading.finished = opts.loading.finished || function() { 10220 if (!opts.state.isBeyondMaxPage) 10221 opts.loading.msg.fadeOut(opts.loading.speed); 10222 }; 10223 10224 // callback loading 10225 opts.callback = function(instance, data, url) { 10226 if (!!opts.behavior && instance['_callback_'+opts.behavior] !== undefined) { 10227 instance['_callback_'+opts.behavior].call($(opts.contentSelector)[0], data, url); 10228 } 10229 10230 if (callback) { 10231 callback.call($(opts.contentSelector)[0], data, opts, url); 10232 } 10233 10234 if (opts.prefill) { 10235 $window.bind('resize.infinite-scroll', instance._prefill); 10236 } 10237 }; 10238 10239 if (options.debug) { 10240 // Tell IE9 to use its built-in console 10241 if (Function.prototype.bind && (typeof console === 'object' || typeof console === 'function') && typeof console.log === 'object') { 10242 ['log','info','warn','error','assert','dir','clear','profile','profileEnd'] 10243 .forEach(function (method) { 10244 console[method] = this.call(console[method], console); 10245 }, Function.prototype.bind); 10246 } 10247 } 10248 10249 this._setup(); 10250 10251 // Setups the prefill method for use 10252 if (opts.prefill) { 10253 this._prefill(); 10254 } 10255 10256 // Return true to indicate successful creation 10257 return true; 10258 }, 10259 10260 _prefill: function infscr_prefill() { 10261 var instance = this; 10262 var $window = $(window); 10263 10264 function needsPrefill() { 10265 return ( $(instance.options.contentSelector).height() <= $window.height() ); 10266 } 10267 10268 this._prefill = function() { 10269 if (needsPrefill()) { 10270 instance.scroll(); 10271 } 10272 10273 $window.bind('resize.infinite-scroll', function() { 10274 if (needsPrefill()) { 10275 $window.unbind('resize.infinite-scroll'); 10276 instance.scroll(); 10277 } 10278 }); 10279 }; 10280 10281 // Call self after setting up the new function 10282 this._prefill(); 10283 }, 10284 10285 // Console log wrapper 10286 _debug: function infscr_debug() { 10287 if (true !== this.options.debug) { 10288 return; 10289 } 10290 10291 if (typeof console !== 'undefined' && typeof console.log === 'function') { 10292 // Modern browsers 10293 // Single argument, which is a string 10294 if ((Array.prototype.slice.call(arguments)).length === 1 && typeof Array.prototype.slice.call(arguments)[0] === 'string') { 10295 console.log( (Array.prototype.slice.call(arguments)).toString() ); 10296 } else { 10297 console.log( Array.prototype.slice.call(arguments) ); 10298 } 10299 } else if (!Function.prototype.bind && typeof console !== 'undefined' && typeof console.log === 'object') { 10300 // IE8 10301 Function.prototype.call.call(console.log, console, Array.prototype.slice.call(arguments)); 10302 } 10303 }, 10304 10305 // find the number to increment in the path.
10306 _determinepath: function infscr_determinepath(path) { 10307 10308 var opts = this.options; 10309 10310 // if behavior is defined and this function is extended, call that instead of default 10311 if (!!opts.behavior && this['_determinepath_'+opts.behavior] !== undefined) { 10312 return this['_determinepath_'+opts.behavior].call(this,path); 10313 } 10314 10315 if (!!opts.pathParse) { 10316 10317 this._debug('pathParse manual'); 10318 return opts.pathParse(path, this.options.state.currPage+1); 10319 10320 } else if (path.match(/^(.*?)\b2\b(.*?$)/)) { 10321 path = path.match(/^(.*?)\b2\b(.*?$)/).slice(1); 10322 10323 // if there is any 2 in the url at all. 10324 } else if (path.match(/^(.*?)2(.*?$)/)) { 10325 10326 // page= is used in django: 10327 // http://www.infinite-scroll.com/changelog/comment-page-1/#comment-127 10328 if (path.match(/^(.*?page=)2(\/.*|$)/)) { 10329 path = path.match(/^(.*?page=)2(\/.*|$)/).slice(1); 10330 return path; 10331 } 10332 10333 path = path.match(/^(.*?)2(.*?$)/).slice(1); 10334 10335 } else { 10336 10337 // page= is used in drupal too but second page is page=1 not page=2: 10338 // thx Jerod Fritz, vladikoff 10339 if (path.match(/^(.*?page=)1(\/.*|$)/)) { 10340 path = path.match(/^(.*?page=)1(\/.*|$)/).slice(1); 10341 return path; 10342 } else { 10343 this._debug("Sorry, we couldn't parse your Next (Previous Posts) URL. Verify your the css selector points to the correct A tag. If you still get this error: yell, scream, and kindly ask for help at infinite-scroll.com."); 10344 // Get rid of isInvalidPage to allow permalink to state 10345 opts.state.isInvalidPage = true; //prevent it from running on this page. 10346 } 10347 } 10348 this._debug('determinePath', path); 10349 return path; 10350 10351 }, 10352 10353 // Custom error 10354 _error: function infscr_error(xhr) { 10355 10356 var opts = this.options; 10357 10358 // if behavior is defined and this function is extended, call that instead of default 10359 if (!!opts.behavior && this['_error_'+opts.behavior] !== undefined) { 10360 this['_error_'+opts.behavior].call(this,xhr); 10361 return; 10362 } 10363 10364 if (xhr !== 'destroy' && xhr !== 'end') { 10365 xhr = 'unknown'; 10366 } 10367 10368 this._debug('Error', xhr); 10369 10370 if (xhr === 'end' || opts.state.isBeyondMaxPage) { 10371 this._showdonemsg(); 10372 } 10373 10374 opts.state.isDone = true; 10375 opts.state.currPage = 1; // if you need to go back to this instance 10376 opts.state.isPaused = false; 10377 opts.state.isBeyondMaxPage = false; 10378 this._binding('unbind'); 10379 10380 }, 10381 10382 // Load Callback 10383 _loadcallback: function infscr_loadcallback(box, data, url) { 10384 var opts = this.options, 10385 callback = this.options.callback, // GLOBAL OBJECT FOR CALLBACK 10386 result = (opts.state.isDone) ? 'done' : (!opts.appendCallback) ? 'no-append' : 'append', 10387 frag; 10388 10389 // if behavior is defined and this function is extended, call that instead of default 10390 if (!!opts.behavior && this['_loadcallback_'+opts.behavior] !== undefined) { 10391 this['_loadcallback_'+opts.behavior].call(this,box,data); 10392 return; 10393 } 10394 10395 switch (result) { 10396 case 'done': 10397 this._showdonemsg(); 10398 return false; 10399 10400 case 'no-append': 10401 if (opts.dataType === 'html') { 10402 data = '<div>' + data + '</div>'; 10403 data = $(data).find(opts.itemSelector); 10404 } 10405 10406 // if it didn't return anything 10407 if (data.length === 0) { 10408 return this._error('end'); 10409 } 10410 10411 break; 10412 10413 case 'append': 10414 var children = box.children(); 10415 // if it didn't return anything 10416 if (children.length === 0) { 10417 return this._error('end'); 10418 } 10419 10420 // use a documentFragment because it works when content is going into a table or UL 10421 frag = document.createDocumentFragment(); 10422 while (box[0].firstChild) { 10423 frag.appendChild(box[0].firstChild); 10424 } 10425 10426 this._debug('contentSelector', $(opts.contentSelector)[0]); 10427 $(opts.contentSelector)[0].appendChild(frag); 10428 // previously, we would pass in the new DOM element as context for the callback 10429 // however we're now using a documentfragment, which doesn't have parents or children, 10430 // so the context is the contentContainer guy, and we pass in an array 10431 // of the elements collected as the first argument. 10432 10433 data = children.get(); 10434 break; 10435 } 10436 10437 // loadingEnd function 10438 opts.loading.finished.call($(opts.contentSelector)[0],opts); 10439 10440 // smooth scroll to ease in the new content 10441 if (opts.animate) { 10442 var scrollTo = $(window).scrollTop() + $(opts.loading.msg).height() + opts.extraScrollPx + 'px'; 10443 $('html,body').animate({ scrollTop: scrollTo }, 800, function () { opts.state.isDuringAjax = false; }); 10444 } 10445 10446 if (!opts.animate) { 10447 // once the call is done, we can allow it again. 10448 opts.state.isDuringAjax = false;
10449 } 10450 10451 callback(this, data, url); 10452 10453 if (opts.prefill) { 10454 this._prefill(); 10455 } 10456 }, 10457 10458 _nearbottom: function infscr_nearbottom() { 10459 10460 var opts = this.options, 10461 pixelsFromWindowBottomToBottom = 0 + $(document).height() - (opts.binder.scrollTop()) - $(window).height(); 10462 10463 // if behavior is defined and this function is extended, call that instead of default 10464 if (!!opts.behavior && this['_nearbottom_'+opts.behavior] !== undefined) { 10465 return this['_nearbottom_'+opts.behavior].call(this); 10466 } 10467 10468 this._debug('math:', pixelsFromWindowBottomToBottom, opts.pixelsFromNavToBottom); 10469 10470 // if distance remaining in the scroll (including buffer) is less than the orignal nav to bottom.... 10471 return (pixelsFromWindowBottomToBottom - opts.bufferPx < opts.pixelsFromNavToBottom); 10472 10473 }, 10474 10475 // Pause / temporarily disable plugin from firing 10476 _pausing: function infscr_pausing(pause) { 10477 10478 var opts = this.options; 10479 10480 // if behavior is defined and this function is extended, call that instead of default 10481 if (!!opts.behavior && this['_pausing_'+opts.behavior] !== undefined) { 10482 this['_pausing_'+opts.behavior].call(this,pause); 10483 return; 10484 } 10485 10486 // If pause is not 'pause' or 'resume', toggle it's value 10487 if (pause !== 'pause' && pause !== 'resume' && pause !== null) { 10488 this._debug('Invalid argument. Toggling pause value instead'); 10489 } 10490 10491 pause = (pause && (pause === 'pause' || pause === 'resume')) ? pause : 'toggle'; 10492 10493 switch (pause) { 10494 case 'pause': 10495 opts.state.isPaused = true; 10496 break; 10497 10498 case 'resume': 10499 opts.state.isPaused = false; 10500 break; 10501 10502 case 'toggle': 10503 opts.state.isPaused = !opts.state.isPaused; 10504 break; 10505 } 10506 10507 this._debug('Paused', opts.state.isPaused); 10508 return false; 10509 10510 }, 10511 10512 // Behavior is determined 10513 // If the behavior option is undefined, it will set to default and bind to scroll 10514 _setup: function infscr_setup() { 10515 10516 var opts = this.options; 10517 10518 // if behavior is defined and this function is extended, call that instead of default 10519 if (!!opts.behavior && this['_setup_'+opts.behavior] !== undefined) { 10520 this['_setup_'+opts.behavior].call(this); 10521 return; 10522 } 10523 10524 this._binding('bind'); 10525 10526 return false; 10527 10528 }, 10529 10530 // Show done message 10531 _showdonemsg: function infscr_showdonemsg() { 10532 10533 var opts = this.options; 10534 10535 // if behavior is defined and this function is extended, call that instead of default 10536 if (!!opts.behavior && this['_showdonemsg_'+opts.behavior] !== undefined) { 10537 this['_showdonemsg_'+opts.behavior].call(this); 10538 return; 10539 } 10540 10541 opts.loading.msg 10542 .find('img') 10543 .hide() 10544 .parent() 10545 .find('div').html(opts.loading.finishedMsg).animate({ opacity: 1 }, 2000, function () { 10546 $(this).parent().fadeOut(opts.loading.speed); 10547 }); 10548 10549 // user provided callback when done 10550 opts.errorCallback.call($(opts.contentSelector)[0],'done'); 10551 }, 10552 10553 // grab each selector option and see if any fail 10554 _validate: function infscr_validate(opts) { 10555 for (var key in opts) { 10556 if (key.indexOf && key.indexOf('Selector') > -1 && $(opts[key]).length === 0) { 10557 this._debug('Your ' + key + ' found no elements.'); 10558 return false; 10559 } 10560 } 10561 10562 return true; 10563 }, 10564 10565 /* 10566 ---------------------------- 10567 Public methods 10568 ---------------------------- 10569 */ 10570 10571 // Bind to scroll 10572 bind: function infscr_bind() { 10573 this._binding('bind'); 10574 }, 10575 10576 // Destroy current instance of plugin 10577 destroy: function infscr_destroy() { 10578 this.options.state.isDestroyed = true; 10579 this.options.loading.finished(); 10580 return this._error('destroy'); 10581 }, 10582 10583 // Set pause value to false 10584 pause: function infscr_pause() { 10585 this._pausing('pause'); 10586 }, 10587 10588 // Set pause value to false 10589 resume: function infscr_resume() { 10590 this._pausing('resume'); 10591 }, 10592 10593 beginAjax: function infscr_ajax(opts) { 10594 var instance = this, 10595 path = opts.path, 10596 box, desturl, method, condition; 10597 10598 // increment the URL bit. e.g. /page/3/ 10599 opts.state.currPage++; 10600 10601 // Manually control maximum page 10602 if ( opts.maxPage !== undefined && opts.state.currPage > opts.maxPage ){ 10603 opts.state.isBeyondMaxPage = true; 10604 this.destroy(); 10605 return; 10606 } 10607 10608 // if we're dealing with a table we can't use DIVs 10609 box = $(opts.contentSelector).is('table, tbody') ? $('<tbody/>') : $('<div/>'); 10610 10611 desturl = (typeof path === 'function') ? path(opts.state.currPage) : path.join(opts.state.currPage); 10612 instance._debug('heading into ajax', desturl); 10613 10614 method = (opts.dataType === 'html' || opts.dataType === 'json' ) ? opts.dataType : 'html+callback'; 10615 if (opts.appendCallback && opts.dataType === 'html') { 10616 method += '+callback'; 10617 } 10618 10619 switch (method) { 10620 case 'html+callback': 10621 instance._debug('Using HTML via .load() method'); 10622 box.load(desturl + ' ' + opts.itemSelector, undefined, function infscr_ajax_callback(responseText) { 10623 instance._loadcallback(box, responseText, desturl); 10624 }); 10625 10626 break; 10627 10628 case 'html': 10629 instance._debug('Using ' + (method.toUpperCase()) + ' via $.ajax() method'); 10630 $.ajax({ 10631 // params 10632 url: desturl, 10633 dataType: opts.dataType, 10634 complete: function infscr_ajax_callback(jqXHR, textStatus) { 10635 condition = (typeof (jqXHR.isResolved) !== 'undefined') ? (jqXHR.isResolved()) : (textStatus === 'success' || textStatus === 'notmodified'); 10636 if (condition) { 10637 instance._loadcallback(box, jqXHR.responseText, desturl); 10638 } else { 10639 instance._error('end'); 10640 } 10641 } 10642 }); 10643 10644 break; 10645 case 'json': 10646 instance._debug('Using ' + (method.toUpperCase()) + ' via $.ajax() method'); 10647 $.ajax({ 10648 dataType: 'json', 10649 type: 'GET', 10650 url: desturl, 10651 success: function (data, textStatus, jqXHR) { 10652 condition = (typeof (jqXHR.isResolved) !== 'undefined') ? (jqXHR.isResolved()) : (textStatus === 'success' || textStatus === 'notmodified'); 10653 if (opts.appendCallback) { 10654 // if appendCallback is true, you must defined template in options. 10655 // note that data passed into _loadcallback is already an html (after processed in opts.template(data)). 10656 if (opts.template !== undefined) { 10657 var theData = opts.template(data); 10658 box.append(theData); 10659 if (condition) { 10660 instance._loadcallback(box, theData); 10661 } else { 10662 instance._error('end'); 10663 } 10664 } else { 10665 instance._debug('template must be defined.'); 10666 instance._error('end'); 10667 } 10668 } else { 10669 // if appendCallback is false, we will pass in the JSON object. you should handle it yourself in your callback. 10670 if (condition) { 10671 instance._loadcallback(box, data, desturl); 10672 } else { 10673 instance._error('end'); 10674 } 10675 } 10676 }, 10677 error: function() { 10678 instance._debug('JSON ajax request failed.'); 10679 instance._error('end'); 10680 } 10681 }); 10682 10683 break; 10684 } 10685 }, 10686 10687 // Retrieve next set of content items 10688 retrieve: function infscr_retrieve(pageNum) { 10689 pageNum = pageNum || null; 10690 10691 var instance = this, 10692 opts = instance.options; 10693 10694 // if behavior is defined and this function is extended, call that instead of default 10695 if (!!opts.behavior && this['retrieve_'+opts.behavior] !== undefined) { 10696 this['retrieve_'+opts.behavior].call(this,pageNum); 10697 return; 10698 } 10699 10700 // for manual triggers, if destroyed, get out of here 10701 if (opts.state.isDestroyed) { 10702 this._debug('Instance is destroyed'); 10703 return false;
10704 } 10705 10706 // we dont want to fire the ajax multiple times 10707 opts.state.isDuringAjax = true; 10708 10709 opts.loading.start.call($(opts.contentSelector)[0],opts); 10710 }, 10711 10712 // Check to see next page is needed 10713 scroll: function infscr_scroll() { 10714 10715 var opts = this.options, 10716 state = opts.state; 10717 10718 // if behavior is defined and this function is extended, call that instead of default 10719 if (!!opts.behavior && this['scroll_'+opts.behavior] !== undefined) { 10720 this['scroll_'+opts.behavior].call(this); 10721 return; 10722 } 10723 10724 if (state.isDuringAjax || state.isInvalidPage || state.isDone || state.isDestroyed || state.isPaused) { 10725 return; 10726 } 10727 10728 if (!this._nearbottom()) { 10729 return; 10730 } 10731 10732 this.retrieve(); 10733 10734 }, 10735 10736 // Toggle pause value 10737 toggle: function infscr_toggle() { 10738 this._pausing(); 10739 }, 10740 10741 // Unbind from scroll 10742 unbind: function infscr_unbind() { 10743 this._binding('unbind'); 10744 }, 10745 10746 // update options 10747 update: function infscr_options(key) { 10748 if ($.isPlainObject(key)) { 10749 this.options = $.extend(true,this.options,key); 10750 } 10751 } 10752 }; 10753 10754 10755 /* 10756 ---------------------------- 10757 Infinite Scroll function 10758 ---------------------------- 10759 10760 Borrowed logic from the following... 10761 10762 jQuery UI 10763 - https://github.com/jquery/jquery-ui/blob/master/ui/jquery.ui.widget.js 10764 10765 jCarousel 10766 - https://github.com/jsor/jcarousel/blob/master/lib/jquery.jcarousel.js 10767 10768 Masonry 10769 - https://github.com/desandro/masonry/blob/master/jquery.masonry.js 10770 10771*/ 10772 10773 $.fn.infinitescroll = function infscr_init(options, callback) { 10774 10775 10776 var thisCall = typeof options; 10777 10778 switch (thisCall) { 10779 10780 // method 10781 case 'string': 10782 var args = Array.prototype.slice.call(arguments, 1); 10783 10784 this.each(function () { 10785 var instance = $.data(this, 'infinitescroll'); 10786 10787 if (!instance) { 10788 // not setup yet 10789 // return $.error('Method ' + options + ' cannot be called until Infinite Scroll is setup'); 10790 return false; 10791 } 10792 10793 if (!$.isFunction(instance[options]) || options.charAt(0) === '_') { 10794 // return $.error('No such method ' + options + ' for Infinite Scroll'); 10795 return false; 10796 } 10797 10798 // no errors! 10799 instance[options].apply(instance, args); 10800 }); 10801 10802 break; 10803 10804 // creation 10805 case 'object': 10806 10807 this.each(function () { 10808 10809 var instance = $.data(this, 'infinitescroll'); 10810 10811 if (instance) { 10812 10813 // update options of current instance 10814 instance.update(options); 10815 10816 } else { 10817 10818 // initialize new instance 10819 instance = new $.infinitescroll(options, callback, this); 10820 10821 // don't attach if instantiation failed 10822 if (!instance.failed) { 10823 $.data(this, 'infinitescroll', instance); 10824 } 10825 10826 } 10827 10828 }); 10829 10830 break; 10831 10832 } 10833 10834 return this; 10835 }; 10836 10837 10838 10839 /* 10840 * smartscroll: debounced scroll event for jQuery * 10841 * https://github.com/lukeshumard/smartscroll 10842 * Based on smartresize by @louis_remi: https://github.com/lrbabe/jquery.smartresize.js * 10843 * Copyright 2011 Louis-Remi & Luke Shumard * Licensed under the MIT license. * 10844 */ 10845 10846 var event = $.event, 10847 scrollTimeout; 10848 10849 event.special.smartscroll = { 10850 setup: function () { 10851 $(this).bind('scroll', event.special.smartscroll.handler); 10852 }, 10853 teardown: function () { 10854 $(this).unbind('scroll', event.special.smartscroll.handler); 10855 }, 10856 handler: function (event, execAsap) { 10857 // Save the context 10858 var context = this, 10859 args = arguments; 10860 10861 // set correct event type 10862 event.type = 'smartscroll'; 10863 10864 if (scrollTimeout) { clearTimeout(scrollTimeout); } 10865 scrollTimeout = setTimeout(function () { 10866 $(context).trigger('smartscroll', args); 10867 }, execAsap === 'execAsap' ? 0 : 100); 10868 } 10869 }; 10870 10871 $.fn.smartscroll = function (fn) {
10872 return fn ? this.bind('smartscroll', fn) : this.trigger('smartscroll', ['execAsap']); 10873 }; 10874 10875})); 10876 10877/*! 10878Waypoints - 4.0.1 10879Copyright © 2011-2016 Caleb Troughton 10880Licensed under the MIT license. 10881https://github.com/imakewebthings/waypoints/blob/master/licenses.txt 10882*/ 10883(function() { 10884 'use strict' 10885 10886 var keyCounter = 0 10887 var allWaypoints = {} 10888 10889 /* http://imakewebthings.com/waypoints/api/waypoint */ 10890 function Waypoint(options) { 10891 if (!options) { 10892 throw new Error('No options passed to Waypoint constructor') 10893 } 10894 if (!options.element) { 10895 throw new Error('No element option passed to Waypoint constructor') 10896 } 10897 if (!options.handler) { 10898 throw new Error('No handler option passed to Waypoint constructor') 10899 } 10900 10901 this.key = 'waypoint-' + keyCounter 10902 this.options = Waypoint.Adapter.extend({}, Waypoint.defaults, options) 10903 this.element = this.options.element 10904 this.adapter = new Waypoint.Adapter(this.element) 10905 this.callback = options.handler 10906 this.axis = this.options.horizontal ? 'horizontal' : 'vertical' 10907 this.enabled = this.options.enabled 10908 this.triggerPoint = null 10909 this.group = Waypoint.Group.findOrCreate({ 10910 name: this.options.group, 10911 axis: this.axis 10912 }) 10913 this.context = Waypoint.Context.findOrCreateByElement(this.options.context) 10914 10915 if (Waypoint.offsetAliases[this.options.offset]) { 10916 this.options.offset = Waypoint.offsetAliases[this.options.offset] 10917 } 10918 this.group.add(this) 10919 this.context.add(this) 10920 allWaypoints[this.key] = this 10921 keyCounter += 1 10922 } 10923 10924 /* Private */ 10925 Waypoint.prototype.queueTrigger = function(direction) { 10926 this.group.queueTrigger(this, direction) 10927 } 10928 10929 /* Private */ 10930 Waypoint.prototype.trigger = function(args) { 10931 if (!this.enabled) { 10932 return 10933 } 10934 if (this.callback) { 10935 this.callback.apply(this, args) 10936 } 10937 } 10938 10939 /* Public */ 10940 /* http://imakewebthings.com/waypoints/api/destroy */ 10941 Waypoint.prototype.destroy = function() { 10942 this.context.remove(this) 10943 this.group.remove(this) 10944 delete allWaypoints[this.key] 10945 } 10946 10947 /* Public */ 10948 /* http://imakewebthings.com/waypoints/api/disable */ 10949 Waypoint.prototype.disable = function() { 10950 this.enabled = false 10951 return this 10952 } 10953 10954 /* Public */ 10955 /* http://imakewebthings.com/waypoints/api/enable */ 10956 Waypoint.prototype.enable = function() { 10957 this.context.refresh() 10958 this.enabled = true 10959 return this 10960 } 10961 10962 /* Public */ 10963 /* http://imakewebthings.com/waypoints/api/next */ 10964 Waypoint.prototype.next = function() { 10965 return this.group.next(this) 10966 } 10967 10968 /* Public */ 10969 /* http://imakewebthings.com/waypoints/api/previous */ 10970 Waypoint.prototype.previous = function() { 10971 return this.group.previous(this) 10972 } 10973 10974 /* Private */ 10975 Waypoint.invokeAll = function(method) { 10976 var allWaypointsArray = []
10977 for (var waypointKey in allWaypoints) { 10978 allWaypointsArray.push(allWaypoints[waypointKey]) 10979 } 10980 for (var i = 0, end = allWaypointsArray.length; i < end; i++) { 10981 allWaypointsArray[i][method]() 10982 } 10983 } 10984 10985 /* Public */ 10986 /* http://imakewebthings.com/waypoints/api/destroy-all */ 10987 Waypoint.destroyAll = function() { 10988 Waypoint.invokeAll('destroy') 10989 } 10990 10991 /* Public */ 10992 /* http://imakewebthings.com/waypoints/api/disable-all */ 10993 Waypoint.disableAll = function() { 10994 Waypoint.invokeAll('disable') 10995 } 10996 10997 /* Public */ 10998 /* http://imakewebthings.com/waypoints/api/enable-all */ 10999 Waypoint.enableAll = function() { 11000 Waypoint.Context.refreshAll() 11001 for (var waypointKey in allWaypoints) { 11002 allWaypoints[waypointKey].enabled = true 11003 } 11004 return this 11005 } 11006 11007 /* Public */ 11008 /* http://imakewebthings.com/waypoints/api/refresh-all */ 11009 Waypoint.refreshAll = function() { 11010 Waypoint.Context.refreshAll() 11011 } 11012 11013 /* Public */ 11014 /* http://imakewebthings.com/waypoints/api/viewport-height */ 11015 Waypoint.viewportHeight = function() { 11016 return window.innerHeight || document.documentElement.clientHeight 11017 } 11018 11019 /* Public */ 11020 /* http://imakewebthings.com/waypoints/api/viewport-width */ 11021 Waypoint.viewportWidth = function() { 11022 return document.documentElement.clientWidth 11023 } 11024 11025 Waypoint.adapters = [] 11026 11027 Waypoint.defaults = { 11028 context: window, 11029 continuous: true, 11030 enabled: true, 11031 group: 'default', 11032 horizontal: false, 11033 offset: 0 11034 } 11035 11036 Waypoint.offsetAliases = { 11037 'bottom-in-view': function() { 11038 return this.context.innerHeight() - this.adapter.outerHeight() 11039 }, 11040 'right-in-view': function() { 11041 return this.context.innerWidth() - this.adapter.outerWidth() 11042 } 11043 } 11044 11045 window.Waypoint = Waypoint 11046}()) 11047;(function() { 11048 'use strict' 11049 11050 function requestAnimationFrameShim(callback) { 11051 window.setTimeout(callback, 1000 / 60) 11052 } 11053 11054 var keyCounter = 0 11055 var contexts = {} 11056 var Waypoint = window.Waypoint 11057 var oldWindowLoad = window.onload 11058 11059 /* http://imakewebthings.com/waypoints/api/context */ 11060 function Context(element) { 11061 this.element = element 11062 this.Adapter = Waypoint.Adapter 11063 this.adapter = new this.Adapter(element) 11064 this.key = 'waypoint-context-' + keyCounter 11065 this.didScroll = false 11066 this.didResize = false 11067 this.oldScroll = { 11068 x: this.adapter.scrollLeft(), 11069 y: this.adapter.scrollTop() 11070 } 11071 this.waypoints = { 11072 vertical: {}, 11073 horizontal: {} 11074 } 11075 11076 element.waypointContextKey = this.key 11077 contexts[element.waypointContextKey] = this 11078 keyCounter += 1 11079 if (!Waypoint.windowContext) { 11080 Waypoint.windowContext = true 11081 Waypoint.windowContext = new Context(window) 11082 } 11083 11084 this.createThrottledScrollHandler() 11085 this.createThrottledResizeHandler() 11086 } 11087 11088 /* Private */ 11089 Context.prototype.add = function(waypoint) { 11090 var axis = waypoint.options.horizontal ? 'horizontal' : 'vertical' 11091 this.waypoints[axis][waypoint.key] = waypoint 11092 this.refresh() 11093 } 11094 11095 /* Private */ 11096 Context.prototype.checkEmpty = function() { 11097 var horizontalEmpty = this.Adapter.isEmptyObject(this.waypoints.horizontal) 11098 var verticalEmpty = this.Adapter.isEmptyObject(this.waypoints.vertical) 11099 var isWindow = this.element == this.element.window 11100 if (horizontalEmpty && verticalEmpty && !isWindow) { 11101 this.adapter.off('.waypoints') 11102 delete contexts[this.key] 11103 } 11104 } 11105 11106 /* Private */ 11107 Context.prototype.createThrottledResizeHandler = function() { 11108 var self = this 11109 11110 function resizeHandler() { 11111 self.handleResize() 11112 self.didResize = false 11113 } 11114 11115 this.adapter.on('resize.waypoints', function() { 11116 if (!self.didResize) { 11117 self.didResize = true 11118 Waypoint.requestAnimationFrame(resizeHandler) 11119 } 11120 }) 11121 } 11122 11123 /* Private */ 11124 Context.prototype.createThrottledScrollHandler = function() { 11125 var self = this 11126 function scrollHandler() { 11127 self.handleScroll() 11128 self.didScroll = false 11129 } 11130 11131 this.adapter.on('scroll.waypoints', function() { 11132 if (!self.didScroll || Waypoint.isTouch) { 11133 self.didScroll = true 11134 Waypoint.requestAnimationFrame(scrollHandler) 11135 } 11136 }) 11137 } 11138 11139 /* Private */ 11140 Context.prototype.handleResize = function() { 11141 Waypoint.Context.refreshAll() 11142 } 11143 11144 /* Private */ 11145 Context.prototype.handleScroll = function() { 11146 var triggeredGroups = {} 11147 var axes = { 11148 horizontal: { 11149 newScroll: this.adapter.scrollLeft(), 11150 oldScroll: this.oldScroll.x, 11151 forward: 'right', 11152 backward: 'left' 11153 }, 11154 vertical: { 11155 newScroll: this.adapter.scrollTop(), 11156 oldScroll: this.oldScroll.y, 11157 forward: 'down', 11158 backward: 'up' 11159 } 11160 } 11161 11162 for (var axisKey in axes) { 11163 var axis = axes[axisKey] 11164 var isForward = axis.newScroll > axis.oldScroll 11165 var direction = isForward ? axis.forward : axis.backward 11166
11167 for (var waypointKey in this.waypoints[axisKey]) { 11168 var waypoint = this.waypoints[axisKey][waypointKey] 11169 if (waypoint.triggerPoint === null) { 11170 continue 11171 } 11172 var wasBeforeTriggerPoint = axis.oldScroll < waypoint.triggerPoint 11173 var nowAfterTriggerPoint = axis.newScroll >= waypoint.triggerPoint 11174 var crossedForward = wasBeforeTriggerPoint && nowAfterTriggerPoint 11175 var crossedBackward = !wasBeforeTriggerPoint && !nowAfterTriggerPoint 11176 if (crossedForward || crossedBackward) { 11177 waypoint.queueTrigger(direction) 11178 triggeredGroups[waypoint.group.id] = waypoint.group 11179 } 11180 } 11181 } 11182 11183 for (var groupKey in triggeredGroups) { 11184 triggeredGroups[groupKey].flushTriggers() 11185 } 11186 11187 this.oldScroll = { 11188 x: axes.horizontal.newScroll, 11189 y: axes.vertical.newScroll 11190 } 11191 } 11192 11193 /* Private */ 11194 Context.prototype.innerHeight = function() { 11195 /*eslint-disable eqeqeq */ 11196 if (this.element == this.element.window) { 11197 return Waypoint.viewportHeight() 11198 } 11199 /*eslint-enable eqeqeq */ 11200 return this.adapter.innerHeight() 11201 } 11202 11203 /* Private */ 11204 Context.prototype.remove = function(waypoint) { 11205 delete this.waypoints[waypoint.axis][waypoint.key] 11206 this.checkEmpty() 11207 } 11208 11209 /* Private */ 11210 Context.prototype.innerWidth = function() { 11211 /*eslint-disable eqeqeq */ 11212 if (this.element == this.element.window) { 11213 return Waypoint.viewportWidth() 11214 } 11215 /*eslint-enable eqeqeq */ 11216 return this.adapter.innerWidth() 11217 } 11218 11219 /* Public */ 11220 /* http://imakewebthings.com/waypoints/api/context-destroy */ 11221 Context.prototype.destroy = function() { 11222 var allWaypoints = [] 11223 for (var axis in this.waypoints) {
11224 for (var waypointKey in this.waypoints[axis]) { 11225 allWaypoints.push(this.waypoints[axis][waypointKey]) 11226 } 11227 } 11228 for (var i = 0, end = allWaypoints.length; i < end; i++) { 11229 allWaypoints[i].destroy() 11230 } 11231 } 11232 11233 /* Public */ 11234 /* http://imakewebthings.com/waypoints/api/context-refresh */ 11235 Context.prototype.refresh = function() { 11236 /*eslint-disable eqeqeq */ 11237 var isWindow = this.element == this.element.window 11238 /*eslint-enable eqeqeq */ 11239 var contextOffset = isWindow ? undefined : this.adapter.offset() 11240 var triggeredGroups = {} 11241 var axes 11242 11243 this.handleScroll() 11244 axes = { 11245 horizontal: { 11246 contextOffset: isWindow ? 0 : contextOffset.left, 11247 contextScroll: isWindow ? 0 : this.oldScroll.x, 11248 contextDimension: this.innerWidth(), 11249 oldScroll: this.oldScroll.x, 11250 forward: 'right', 11251 backward: 'left', 11252 offsetProp: 'left' 11253 }, 11254 vertical: { 11255 contextOffset: isWindow ? 0 : contextOffset.top, 11256 contextScroll: isWindow ? 0 : this.oldScroll.y, 11257 contextDimension: this.innerHeight(), 11258 oldScroll: this.oldScroll.y, 11259 forward: 'down', 11260 backward: 'up', 11261 offsetProp: 'top' 11262 } 11263 } 11264 11265 for (var axisKey in axes) { 11266 var axis = axes[axisKey]
11267 for (var waypointKey in this.waypoints[axisKey]) { 11268 var waypoint = this.waypoints[axisKey][waypointKey] 11269 var adjustment = waypoint.options.offset 11270 var oldTriggerPoint = waypoint.triggerPoint 11271 var elementOffset = 0 11272 var freshWaypoint = oldTriggerPoint == null 11273 var contextModifier, wasBeforeScroll, nowAfterScroll 11274 var triggeredBackward, triggeredForward 11275 11276 if (waypoint.element !== waypoint.element.window) { 11277 elementOffset = waypoint.adapter.offset()[axis.offsetProp] 11278 } 11279 11280 if (typeof adjustment === 'function') { 11281 adjustment = adjustment.apply(waypoint) 11282 } 11283 else if (typeof adjustment === 'string') { 11284 adjustment = parseFloat(adjustment) 11285 if (waypoint.options.offset.indexOf('%') > - 1) { 11286 adjustment = Math.ceil(axis.contextDimension * adjustment / 100) 11287 } 11288 } 11289 11290 contextModifier = axis.contextScroll - axis.contextOffset 11291 waypoint.triggerPoint = Math.floor(elementOffset + contextModifier - adjustment) 11292 wasBeforeScroll = oldTriggerPoint < axis.oldScroll 11293 nowAfterScroll = waypoint.triggerPoint >= axis.oldScroll 11294 triggeredBackward = wasBeforeScroll && nowAfterScroll 11295 triggeredForward = !wasBeforeScroll && !nowAfterScroll 11296 11297 if (!freshWaypoint && triggeredBackward) { 11298 waypoint.queueTrigger(axis.backward) 11299 triggeredGroups[waypoint.group.id] = waypoint.group 11300 } 11301 else if (!freshWaypoint && triggeredForward) { 11302 waypoint.queueTrigger(axis.forward) 11303 triggeredGroups[waypoint.group.id] = waypoint.group 11304 } 11305 else if (freshWaypoint && axis.oldScroll >= waypoint.triggerPoint) { 11306 waypoint.queueTrigger(axis.forward) 11307 triggeredGroups[waypoint.group.id] = waypoint.group 11308 } 11309 } 11310 } 11311 11312 Waypoint.requestAnimationFrame(function() { 11313 for (var groupKey in triggeredGroups) { 11314 triggeredGroups[groupKey].flushTriggers() 11315 } 11316 }) 11317 11318 return this 11319 } 11320 11321 /* Private */ 11322 Context.findOrCreateByElement = function(element) { 11323 return Context.findByElement(element) || new Context(element) 11324 } 11325 11326 /* Private */ 11327 Context.refreshAll = function() { 11328 for (var contextId in contexts) { 11329 contexts[contextId].refresh() 11330 } 11331 } 11332 11333 /* Public */ 11334 /* http://imakewebthings.com/waypoints/api/context-find-by-element */ 11335 Context.findByElement = function(element) { 11336 return contexts[element.waypointContextKey] 11337 } 11338 11339 window.onload = function() { 11340 if (oldWindowLoad) { 11341 oldWindowLoad() 11342 } 11343 Context.refreshAll() 11344 } 11345 11346 11347 Waypoint.requestAnimationFrame = function(callback) { 11348 var requestFn = window.requestAnimationFrame || 11349 window.mozRequestAnimationFrame || 11350 window.webkitRequestAnimationFrame || 11351 requestAnimationFrameShim 11352 requestFn.call(window, callback) 11353 } 11354 Waypoint.Context = Context 11355}()) 11356;(function() { 11357 'use strict' 11358 11359 function byTriggerPoint(a, b) { 11360 return a.triggerPoint - b.triggerPoint 11361 } 11362 11363 function byReverseTriggerPoint(a, b) { 11364 return b.triggerPoint - a.triggerPoint 11365 } 11366 11367 var groups = { 11368 vertical: {}, 11369 horizontal: {} 11370 } 11371 var Waypoint = window.Waypoint 11372 11373 /* http://imakewebthings.com/waypoints/api/group */ 11374 function Group(options) { 11375 this.name = options.name 11376 this.axis = options.axis 11377 this.id = this.name + '-' + this.axis 11378 this.waypoints = [] 11379 this.clearTriggerQueues() 11380 groups[this.axis][this.name] = this 11381 } 11382 11383 /* Private */ 11384 Group.prototype.add = function(waypoint) { 11385 this.waypoints.push(waypoint) 11386 } 11387 11388 /* Private */ 11389 Group.prototype.clearTriggerQueues = function() { 11390 this.triggerQueues = { 11391 up: [], 11392 down: [], 11393 left: [], 11394 right: [] 11395 } 11396 } 11397 11398 /* Private */ 11399 Group.prototype.flushTriggers = function() { 11400 for (var direction in this.triggerQueues) { 11401 var waypoints = this.triggerQueues[direction] 11402 var reverse = direction === 'up' || direction === 'left' 11403 waypoints.sort(reverse ? byReverseTriggerPoint : byTriggerPoint) 11404 for (var i = 0, end = waypoints.length; i < end; i += 1) { 11405 var waypoint = waypoints[i] 11406 if (waypoint.options.continuous || i === waypoints.length - 1) { 11407 waypoint.trigger([direction]) 11408 } 11409 } 11410 } 11411 this.clearTriggerQueues() 11412 } 11413 11414 /* Private */ 11415 Group.prototype.next = function(waypoint) { 11416 this.waypoints.sort(byTriggerPoint) 11417 var index = Waypoint.Adapter.inArray(waypoint, this.waypoints) 11418 var isLast = index === this.waypoints.length - 1 11419 return isLast ? null : this.waypoints[index + 1] 11420 } 11421 11422 /* Private */ 11423 Group.prototype.previous = function(waypoint) { 11424 this.waypoints.sort(byTriggerPoint) 11425 var index = Waypoint.Adapter.inArray(waypoint, this.waypoints) 11426 return index ? this.waypoints[index - 1] : null 11427 } 11428 11429 /* Private */ 11430 Group.prototype.queueTrigger = function(waypoint, direction) { 11431 this.triggerQueues[direction].push(waypoint) 11432 } 11433 11434 /* Private */ 11435 Group.prototype.remove = function(waypoint) { 11436 var index = Waypoint.Adapter.inArray(waypoint, this.waypoints) 11437 if (index > -1) { 11438 this.waypoints.splice(index, 1) 11439 } 11440 } 11441 11442 /* Public */ 11443 /* http://imakewebthings.com/waypoints/api/first */ 11444 Group.prototype.first = function() { 11445 return this.waypoints[0] 11446 } 11447 11448 /* Public */ 11449 /* http://imakewebthings.com/waypoints/api/last */ 11450 Group.prototype.last = function() { 11451 return this.waypoints[this.waypoints.length - 1] 11452 } 11453 11454 /* Private */ 11455 Group.findOrCreate = function(options) { 11456 return groups[options.axis][options.name] || new Group(options) 11457 } 11458 11459 Waypoint.Group = Group 11460}()) 11461;(function() { 11462 'use strict' 11463 11464 var $ = window.jQuery 11465 var Waypoint = window.Waypoint 11466 11467 function JQueryAdapter(element) { 11468 this.$element = $(element) 11469 } 11470 11471 $.each([
11472 'innerHeight', 11473 'innerWidth', 11474 'off', 11475 'offset', 11476 'on', 11477 'outerHeight', 11478 'outerWidth', 11479 'scrollLeft', 11480 'scrollTop' 11481 ], function(i, method) { 11482 JQueryAdapter.prototype[method] = function() { 11483 var args = Array.prototype.slice.call(arguments) 11484 return this.$element[method].apply(this.$element, args) 11485 } 11486 }) 11487 11488 $.each([ 11489 'extend', 11490 'inArray', 11491 'isEmptyObject' 11492 ], function(i, method) { 11493 JQueryAdapter[method] = $[method] 11494 }) 11495 11496 Waypoint.adapters.push({ 11497 name: 'jquery', 11498 Adapter: JQueryAdapter 11499 }) 11500 Waypoint.Adapter = JQueryAdapter 11501}()) 11502;(function() { 11503 'use strict' 11504 11505 var Waypoint = window.Waypoint 11506 11507 function createExtension(framework) { 11508 return function() { 11509 var waypoints = [] 11510 var overrides = arguments[0] 11511 11512 if (framework.isFunction(arguments[0])) { 11513 overrides = framework.extend({}, arguments[1]) 11514 overrides.handler = arguments[0] 11515 } 11516 11517 this.each(function() { 11518 var options = framework.extend({}, overrides, { 11519 element: this 11520 }) 11521 if (typeof options.context === 'string') { 11522 options.context = framework(this).closest(options.context)[0] 11523 } 11524 waypoints.push(new Waypoint(options)) 11525 }) 11526 11527 return waypoints 11528 } 11529 } 11530 11531 if (window.jQuery) { 11532 window.jQuery.fn.waypoint = createExtension(window.jQuery) 11533 } 11534 if (window.Zepto) { 11535 window.Zepto.fn.waypoint = createExtension(window.Zepto) 11536 } 11537}()) 11538; 11539/*! 11540Waypoints Inview Shortcut - 4.0.1 11541Copyright © 2011-2016 Caleb Troughton 11542Licensed under the MIT license. 11543https://github.com/imakewebthings/waypoints/blob/master/licenses.txt 11544*/ 11545(function() { 11546 'use strict' 11547 11548 function noop() {} 11549 11550 var Waypoint = window.Waypoint 11551 11552 /* http://imakewebthings.com/waypoints/shortcuts/inview */ 11553 function Inview(options) { 11554 this.options = Waypoint.Adapter.extend({}, Inview.defaults, options) 11555 this.axis = this.options.horizontal ? 'horizontal' : 'vertical' 11556 this.waypoints = [] 11557 this.element = this.options.element 11558 this.createWaypoints() 11559 } 11560 11561 /* Private */ 11562 Inview.prototype.createWaypoints = function() { 11563 var configs = { 11564 vertical: [{ 11565 down: 'enter', 11566 up: 'exited', 11567 offset: '100%' 11568 }, { 11569 down: 'entered', 11570 up: 'exit', 11571 offset: 'bottom-in-view' 11572 }, { 11573 down: 'exit', 11574 up: 'entered', 11575 offset: 0 11576 }, { 11577 down: 'exited', 11578 up: 'enter', 11579 offset: function() { 11580 return -this.adapter.outerHeight() 11581 } 11582 }], 11583 horizontal: [{ 11584 right: 'enter', 11585 left: 'exited', 11586 offset: '100%' 11587 }, { 11588 right: 'entered', 11589 left: 'exit', 11590 offset: 'right-in-view' 11591 }, { 11592 right: 'exit', 11593 left: 'entered', 11594 offset: 0 11595 }, { 11596 right: 'exited', 11597 left: 'enter', 11598 offset: function() { 11599 return -this.adapter.outerWidth() 11600 } 11601 }] 11602 } 11603 11604 for (var i = 0, end = configs[this.axis].length; i < end; i++) { 11605 var config = configs[this.axis][i] 11606 this.createWaypoint(config) 11607 } 11608 } 11609 11610 /* Private */ 11611 Inview.prototype.createWaypoint = function(config) { 11612 var self = this 11613 this.waypoints.push(new Waypoint({ 11614 context: this.options.context, 11615 element: this.options.element, 11616 enabled: this.options.enabled, 11617 handler: (function(config) { 11618 return function(direction) { 11619 self.options[config[direction]].call(self, direction) 11620 } 11621 }(config)), 11622 offset: config.offset, 11623 horizontal: this.options.horizontal 11624 })) 11625 } 11626 11627 /* Public */ 11628 Inview.prototype.destroy = function() { 11629 for (var i = 0, end = this.waypoints.length; i < end; i++) { 11630 this.waypoints[i].destroy() 11631 } 11632 this.waypoints = [] 11633 } 11634 11635 Inview.prototype.disable = function() { 11636 for (var i = 0, end = this.waypoints.length; i < end; i++) { 11637 this.waypoints[i].disable() 11638 } 11639 } 11640 11641 Inview.prototype.enable = function() { 11642 for (var i = 0, end = this.waypoints.length; i < end; i++) { 11643 this.waypoints[i].enable() 11644 } 11645 } 11646 11647 Inview.defaults = { 11648 context: window, 11649 enabled: true, 11650 enter: noop, 11651 entered: noop,
11652 exit: noop, 11653 exited: noop 11654 } 11655 11656 Waypoint.Inview = Inview 11657}()) 11658; 11659 11660/* 11661 * SmartMenus jQuery v0.9.6 11662 * http://www.smartmenus.org/ 11663 * 11664 * Copyright 2014 Vasil Dinkov, Vadikom Web Ltd. 11665 * http://vadikom.com/ 11666 * 11667 * Released under the MIT license: 11668 * http://www.opensource.org/licenses/MIT 11669 */ 11670 11671(function($) { 11672 11673 var menuTrees = [], 11674 IE = !!window.createPopup, // we need to detect it, unfortunately 11675 IElt9 = IE && !document.defaultView, 11676 IElt8 = IE && !document.querySelector, 11677 IE6 = IE && typeof document.documentElement.currentStyle.minWidth == 'undefined', 11678 mouse = false, // optimize for touch by default - we will detect for mouse input 11679 mouseDetectionEnabled = false; 11680 11681 // Handle detection for mouse input (i.e. desktop browsers, tablets with a mouse, etc.) 11682 function initMouseDetection(disable) { 11683 if (!mouseDetectionEnabled && !disable) { 11684 // if we get two consecutive mousemoves within 2 pixels from each other and within 300ms, we assume a real mouse/cursor is present 11685 // in practice, this seems like impossible to trick unintentianally with a real mouse and a pretty safe detection on touch devices (even with older browsers that do not support touch events) 11686 var firstTime = true, 11687 lastMove = null; 11688 $(document).bind({ 11689 'mousemove.smartmenus_mouse': function(e) { 11690 var thisMove = { x: e.pageX, y: e.pageY, timeStamp: new Date().getTime() }; 11691 if (lastMove) { 11692 var deltaX = Math.abs(lastMove.x - thisMove.x), 11693 deltaY = Math.abs(lastMove.y - thisMove.y); 11694 if ((deltaX > 0 || deltaY > 0) && deltaX <= 2 && deltaY <= 2 && thisMove.timeStamp - lastMove.timeStamp <= 300) { 11695 mouse = true; 11696 // if this is the first check after page load, check if we are not over some item by chance and call the mouseenter handler if yes 11697 if (firstTime) { 11698 var $a = $(e.target).closest('a'); 11699 if ($a.is('a')) { 11700 $.each(menuTrees, function() { 11701 if ($.contains(this.$root[0], $a[0])) { 11702 this.itemEnter({ currentTarget: $a[0] }); 11703 return false; 11704 } 11705 }); 11706 } 11707 firstTime = false; 11708 } 11709 } 11710 } 11711 lastMove = thisMove; 11712 }, 11713 'touchstart.smartmenus_mouse pointerover.smartmenus_mouse MSPointerOver.smartmenus_mouse': function(e) { 11714 if (!/^(4|mouse)$/.test(e.originalEvent.pointerType)) { 11715 mouse = false; 11716 } 11717 } 11718 }); 11719 mouseDetectionEnabled = true; 11720 } else if (mouseDetectionEnabled && disable) { 11721 $(document).unbind('.smartmenus_mouse'); 11722 mouseDetectionEnabled = false; 11723 } 11724 }; 11725 11726 $.SmartMenus = function(elm, options) { 11727 this.$root = $(elm); 11728 this.opts = options; 11729 this.rootId = ''; // internal 11730 this.$subArrow = null; 11731 this.subMenus = []; // all sub menus in the tree (UL elms) in no particular order (only real - e.g. UL's in mega sub menus won't be counted) 11732 this.activatedItems = []; // stores last activated A's for each level 11733 this.visibleSubMenus = []; // stores visible sub menus UL's 11734 this.showTimeout = 0; 11735 this.hideTimeout = 0; 11736 this.scrollTimeout = 0; 11737 this.clickActivated = false; 11738 this.zIndexInc = 0; 11739 this.$firstLink = null; // we'll use these for some tests 11740 this.$firstSub = null; // at runtime so we'll cache them 11741 this.disabled = false; 11742 this.$disableOverlay = null; 11743 this.init(); 11744 }; 11745 11746 $.extend($.SmartMenus, { 11747 hideAll: function() { 11748 $.each(menuTrees, function() { 11749 this.menuHideAll(); 11750 }); 11751 }, 11752 destroy: function() { 11753 while (menuTrees.length) { 11754 menuTrees[0].destroy(); 11755 } 11756 initMouseDetection(true); 11757 }, 11758 prototype: { 11759 init: function(refresh) { 11760 var self = this; 11761 11762 if (!refresh) { 11763 menuTrees.push(this); 11764 11765 this.rootId = (new Date().getTime() + Math.random() + '').replace(/\D/g, ''); 11766 11767 if (this.$root.hasClass('sm-rtl')) { 11768 this.opts.rightToLeftSubMenus = true; 11769 } 11770 11771 // init root (main menu) 11772 this.$root 11773 .data('smartmenus', this) 11774 .attr('data-smartmenus-id', this.rootId) 11775 .dataSM('level', 1) 11776 .bind({ 11777 'mouseover.smartmenus focusin.smartmenus': $.proxy(this.rootOver, this),
11778 'mouseout.smartmenus focusout.smartmenus': $.proxy(this.rootOut, this) 11779 }) 11780 .delegate('a, div.logo-container', { 11781 'mouseenter.smartmenus': $.proxy(this.itemEnter, this), 11782 'mouseleave.smartmenus': $.proxy(this.itemLeave, this), 11783 'mousedown.smartmenus': $.proxy(this.itemDown, this), 11784 'focus.smartmenus': $.proxy(this.itemFocus, this), 11785 'blur.smartmenus': $.proxy(this.itemBlur, this), 11786 'click.smartmenus': $.proxy(this.itemClick, this), 11787 'touchend.smartmenus': $.proxy(this.itemTouchEnd, this) 11788 }); 11789 11790 var eNamespace = '.smartmenus' + this.rootId; 11791 // hide menus on tap or click outside the root UL 11792 if (this.opts.hideOnClick) { 11793 $(document).bind('touchstart' + eNamespace, $.proxy(this.docTouchStart, this)) 11794 .bind('touchmove' + eNamespace, $.proxy(this.docTouchMove, this)) 11795 .bind('touchend' + eNamespace, $.proxy(this.docTouchEnd, this)) 11796 // for Opera Mobile < 11.5, webOS browser, etc. we'll check click too 11797 .bind('click' + eNamespace, $.proxy(this.docClick, this)); 11798 } 11799 // hide sub menus on resize 11800 $(window).bind('resize' + eNamespace + ' orientationchange' + eNamespace, $.proxy(this.winResize, this)); 11801 $(window).bind('scroll' + eNamespace + ' orientationchange' + eNamespace, $.proxy(this.winResize, this)); 11802 11803 if (this.opts.subIndicators) { 11804 this.$subArrow = $('<span/>').addClass('sub-arrow'); 11805 if (this.opts.subIndicatorsText) { 11806 this.$subArrow.html(this.opts.subIndicatorsText); 11807 } 11808 } 11809 11810 // make sure mouse detection is enabled 11811 initMouseDetection(); 11812 } 11813 11814 // init sub menus 11815 this.$firstSub = this.$root.find('ul').each(function() { self.menuInit($(this)); }).eq(0); 11816 11817 this.$firstLink = this.$root.find('a').eq(0); 11818 11819 // find current item 11820 if (this.opts.markCurrentItem) { 11821 var reDefaultDoc = /(index|default)\.[^#\?\/]*/i, 11822 reHash = /#.*/, 11823 locHref = window.location.href.replace(reDefaultDoc, ''), 11824 locHrefNoHash = locHref.replace(reHash, ''); 11825 this.$root.find('a').each(function() { 11826 var href = this.href.replace(reDefaultDoc, ''), 11827 $this = $(this); 11828 if (href == locHref || href == locHrefNoHash) { 11829 $this.addClass('current'); 11830 if (self.opts.markCurrentTree) { 11831 $this.parents('li').each(function() { 11832 var $this = $(this); 11833 if ($this.dataSM('sub')) { 11834 $this.children('a').addClass('current'); 11835 } 11836 }); 11837 } 11838 } 11839 }); 11840 } 11841 }, 11842 destroy: function() { 11843 this.menuHideAll(); 11844 this.$root 11845 .removeData('smartmenus') 11846 .removeAttr('data-smartmenus-id') 11847 .removeDataSM('level') 11848 .unbind('.smartmenus') 11849 .undelegate('.smartmenus'); 11850 var eNamespace = '.smartmenus' + this.rootId; 11851 $(document).unbind(eNamespace); 11852 $(window).unbind(eNamespace); 11853 if (this.opts.subIndicators) { 11854 this.$subArrow = null; 11855 } 11856 var self = this; 11857 $.each(this.subMenus, function() { 11858 if (this.hasClass('mega-menu')) { 11859 this.find('ul').removeDataSM('in-mega'); 11860 } 11861 if (this.dataSM('shown-before')) { 11862 if (IElt8) { 11863 this.children().css({ styleFloat: '', width: '' }); 11864 } 11865 if (self.opts.subMenusMinWidth || self.opts.subMenusMaxWidth) { 11866 if (!IE6) { 11867 this.css({ width: '', minWidth: '', maxWidth: '' }).removeClass('sm-nowrap'); 11868 } else { 11869 this.css({ width: '', overflowX: '', overflowY: '' }).children().children('a').css('white-space', ''); 11870 } 11871 } 11872 if (this.dataSM('scroll-arrows')) { 11873 this.dataSM('scroll-arrows').remove(); 11874 } 11875 this.css({ zIndex: '', top: '', left: '', marginLeft: '', marginTop: '', display: '' }); 11876 } 11877 if (self.opts.subIndicators) { 11878 this.dataSM('parent-a').removeClass('has-submenu').children('span.sub-arrow').remove(); 11879 } 11880 this.removeDataSM('shown-before') 11881 .removeDataSM('ie-shim') 11882 .removeDataSM('scroll-arrows') 11883 .removeDataSM('parent-a') 11884 .removeDataSM('level') 11885 .removeDataSM('beforefirstshowfired') 11886 .parent().removeDataSM('sub'); 11887 }); 11888 if (this.opts.markCurrentItem) { 11889 this.$root.find('a.current').removeClass('current'); 11890 } 11891 this.$root = null; 11892 this.$firstLink = null; 11893 this.$firstSub = null; 11894 if (this.$disableOverlay) { 11895 this.$disableOverlay.remove(); 11896 this.$disableOverlay = null; 11897 } 11898 menuTrees.splice($.inArray(this, menuTrees), 1); 11899 }, 11900 disable: function(noOverlay) { 11901 if (!this.disabled) { 11902 this.menuHideAll(); 11903 // display overlay over the menu to prevent interaction 11904 if (!noOverlay && !this.opts.isPopup && this.$root.is(':visible')) { 11905 var pos = this.$root.offset(); 11906 this.$disableOverlay = $('<div class="sm-jquery-disable-overlay"/>').css({ 11907 position: 'absolute', 11908 top: pos.top, 11909 left: pos.left, 11910 width: this.$root.outerWidth(), 11911 height: this.$root.outerHeight(),
11912 zIndex: this.getStartZIndex() + 1, 11913 opacity: 0 11914 }).appendTo(document.body); 11915 } 11916 this.disabled = true; 11917 } 11918 }, 11919 docClick: function(e) { 11920 // hide on any click outside the menu or on a menu link 11921 if (this.visibleSubMenus.length && !$.contains(this.$root[0], e.target) || $(e.target).is('a')) { 11922 this.menuHideAll($(e.target)); 11923 } 11924 }, 11925 docTouchEnd: function(e) { 11926 if (!this.lastTouch) { 11927 return; 11928 } 11929 if (this.visibleSubMenus.length && (this.lastTouch.x2 === undefined || this.lastTouch.x1 == this.lastTouch.x2) && (this.lastTouch.y2 === undefined || this.lastTouch.y1 == this.lastTouch.y2) && (!this.lastTouch.target || !$.contains(this.$root[0], this.lastTouch.target))) { 11930 if (this.hideTimeout) { 11931 clearTimeout(this.hideTimeout); 11932 this.hideTimeout = 0; 11933 } 11934 // hide with a delay to prevent triggering accidental unwanted click on some page element 11935 var self = this; 11936 this.hideTimeout = setTimeout(function() { self.menuHideAll($(e.target)); }, 350); 11937 } 11938 this.lastTouch = null; 11939 }, 11940 docTouchMove: function(e) { 11941 if (!this.lastTouch) { 11942 return; 11943 } 11944 var touchPoint = e.originalEvent.touches[0]; 11945 this.lastTouch.x2 = touchPoint.pageX; 11946 this.lastTouch.y2 = touchPoint.pageY; 11947 }, 11948 docTouchStart: function(e) { 11949 var touchPoint = e.originalEvent.touches[0]; 11950 this.lastTouch = { x1: touchPoint.pageX, y1: touchPoint.pageY, target: touchPoint.target }; 11951 }, 11952 enable: function() { 11953 if (this.disabled) { 11954 if (this.$disableOverlay) { 11955 this.$disableOverlay.remove(); 11956 this.$disableOverlay = null; 11957 } 11958 this.disabled = false; 11959 } 11960 }, 11961 getHeight: function($elm) { 11962 return this.getOffset($elm, true); 11963 }, 11964 // returns precise width/height float values in IE9+, FF4+, recent WebKit 11965 // http://vadikom.com/dailies/offsetwidth-offsetheight-useless-in-ie9-firefox4/ 11966 getOffset: function($elm, height) { 11967 var old; 11968 if ($elm.css('display') == 'none') { 11969 old = { position: $elm[0].style.position, visibility: $elm[0].style.visibility }; 11970 $elm.css({ position: 'absolute', visibility: 'hidden' }).show(); 11971 } 11972 var defaultView = $elm[0].ownerDocument.defaultView, 11973 compStyle = defaultView && defaultView.getComputedStyle && defaultView.getComputedStyle($elm[0], null), 11974 val = compStyle && parseFloat(compStyle[height ? 'height' : 'width']); 11975 if (val) { 11976 val += parseFloat(compStyle[height ? 'paddingTop' : 'paddingLeft']) 11977 + parseFloat(compStyle[height ? 'paddingBottom' : 'paddingRight']) 11978 + parseInt(compStyle[height ? 'borderTopWidth' : 'borderLeftWidth']) 11979 + parseInt(compStyle[height ? 'borderBottomWidth' : 'borderRightWidth']); 11980 } else { 11981 val = height ? $elm[0].offsetHeight : $elm[0].offsetWidth; 11982 } 11983 if (old) { 11984 $elm.hide().css(old); 11985 } 11986 return val; 11987 }, 11988 getWidth: function($elm) { 11989 return this.getOffset($elm); 11990 }, 11991 getStartZIndex: function() { 11992 var zIndex = parseInt(this.$root.css('z-index')); 11993 return !isNaN(zIndex) ? zIndex : 1; 11994 }, 11995 handleEvents: function() { 11996 return !this.disabled && this.isCSSOn(); 11997 }, 11998 handleItemEvents: function($a) { 11999 return this.handleEvents() && !this.isLinkInMegaMenu($a); 12000 }, 12001 isCollapsible: function() { 12002 return this.$firstSub.css('position') == 'static'; 12003 }, 12004 isCSSOn: function() { 12005 return this.$firstLink.css('display') == 'block' || this.$firstLink.css('display') == 'flex' || this.$firstLink.css('display') == 'inline-flex' || this.$firstLink.css('display') == 'table-cell' || this.$firstLink.css('display') == 'inline'; 12006 }, 12007 isFixed: function() { 12008 return this.$root.css('position') == 'fixed'; 12009 }, 12010 isLinkInMegaMenu: function($a) { 12011 return !$a.parent().parent().dataSM('level'); 12012 }, 12013 isTouchMode: function() { 12014 return !mouse || this.isCollapsible(); 12015 }, 12016 itemActivate: function($a) { 12017 var $li = $a.parent(), 12018 $ul = $li.parent(), 12019 level = $ul.dataSM('level'); 12020 // if for some reason the parent item is not activated (e.g. this is an API call to activate the item), activate all parent items first 12021 if (level > 1 && (!this.activatedItems[level - 2] || this.activatedItems[level - 2][0] != $ul.dataSM('parent-a')[0])) { 12022 var self = this; 12023 $($ul.parentsUntil('[data-smartmenus-id]', 'ul').get().reverse()).add($ul).each(function() { 12024 self.itemActivate($(this).dataSM('parent-a')); 12025 }); 12026 } 12027 // hide any visible deeper level sub menus 12028 if (this.visibleSubMenus.length > level) { 12029 for (var i = this.visibleSubMenus.length - 1, l = !this.activatedItems[level - 1] || this.activatedItems[level - 1][0] != $a[0] ? level - 1 : level; i > l; i--) { 12030 this.menuHide(this.visibleSubMenus[i]); 12031 } 12032 } 12033 // save new active item and sub menu for this level 12034 this.activatedItems[level - 1] = $a; 12035 this.visibleSubMenus[level - 1] = $ul; 12036 if (this.$root.triggerHandler('activate.smapi', $a[0]) === false) { 12037 return; 12038 } 12039 // show the sub menu if this item has one 12040 var $sub = $li.dataSM('sub'); 12041 if ($sub && (this.isTouchMode() || (!this.opts.showOnClick || this.clickActivated))) { 12042 this.menuShow($sub); 12043 } 12044 }, 12045 itemBlur: function(e) { 12046 var $a = $(e.currentTarget); 12047 if (!this.handleItemEvents($a)) { 12048 return; 12049 } 12050 this.$root.triggerHandler('blur.smapi', $a[0]); 12051 }, 12052 itemClick: function(e) { 12053 var $a = $(e.currentTarget); 12054 12055 if (!this.handleItemEvents($a)) { 12056 return; 12057 } 12058 $a.removeDataSM('mousedown'); 12059 if (this.$root.triggerHandler('click.smapi', $a[0]) === false) { 12060 return false;
12061 } 12062 var $sub = $a.parent().dataSM('sub'); 12063 if (this.isTouchMode()) { 12064 // undo fix: prevent the address bar on iPhone from sliding down when expanding a sub menu 12065 if ($a.dataSM('href')) { 12066 $a.attr('href', $a.dataSM('href')).removeDataSM('href'); 12067 } 12068 // if the sub is not visible 12069 if ($sub && (!$sub.dataSM('shown-before') || !$sub.is(':visible'))) { 12070 // try to activate the item and show the sub 12071 this.itemActivate($a); 12072 // if "itemActivate" showed the sub, prevent the click so that the link is not loaded 12073 // if it couldn't show it, then the sub menus are disabled with an !important declaration (e.g. via mobile styles) so let the link get loaded 12074 if ($sub.is(':visible')) { 12075 return false; 12076 } 12077 } 12078 } else if (this.opts.showOnClick && $a.parent().parent().dataSM('level') == 1 && $sub) { 12079 this.clickActivated = true; 12080 this.menuShow($sub); 12081 return false; 12082 } 12083 if ($a.hasClass('disabled')) { 12084 return false; 12085 } 12086 if (this.$root.triggerHandler('select.smapi', $a[0]) === false) { 12087 return false; 12088 } 12089 }, 12090 itemDown: function(e) { 12091 var $a = $(e.currentTarget); 12092 if (!this.handleItemEvents($a)) { 12093 return; 12094 } 12095 $a.dataSM('mousedown', true); 12096 }, 12097 itemEnter: function(e) { 12098 var $a = $(e.currentTarget); 12099 if (!this.handleItemEvents($a)) { 12100 return; 12101 } 12102 if (!this.isTouchMode()) { 12103 if (this.showTimeout) { 12104 clearTimeout(this.showTimeout); 12105 this.showTimeout = 0; 12106 } 12107 var self = this; 12108 this.showTimeout = setTimeout(function() { self.itemActivate($a); }, this.opts.showOnClick && $a.parent().parent().dataSM('level') == 1 ? 1 : this.opts.showTimeout); 12109 } 12110 this.$root.triggerHandler('mouseenter.smapi', $a[0]); 12111 }, 12112 itemFocus: function(e) { 12113 var $a = $(e.currentTarget); 12114 if (!this.handleItemEvents($a)) { 12115 return; 12116 } 12117 // fix (the mousedown check): in some browsers a tap/click produces consecutive focus + click events so we don't need to activate the item on focus 12118 if ((!this.isTouchMode() || !$a.dataSM('mousedown')) && (!this.activatedItems.length || this.activatedItems[this.activatedItems.length - 1][0] != $a[0])) { 12119 this.itemActivate($a); 12120 } 12121 this.$root.triggerHandler('focus.smapi', $a[0]); 12122 }, 12123 itemLeave: function(e) { 12124 var $a = $(e.currentTarget); 12125 if (!this.handleItemEvents($a)) { 12126 return; 12127 } 12128 if (!this.isTouchMode()) { 12129 if ($a[0].blur) { 12130 $a[0].blur(); 12131 } 12132 if (this.showTimeout) { 12133 clearTimeout(this.showTimeout); 12134 this.showTimeout = 0; 12135 } 12136 } 12137 $a.removeDataSM('mousedown'); 12138 this.$root.triggerHandler('mouseleave.smapi', $a[0]); 12139 }, 12140 itemTouchEnd: function(e) { 12141 var $a = $(e.currentTarget); 12142 if (!this.handleItemEvents($a)) { 12143 return; 12144 } 12145 // prevent the address bar on iPhone from sliding down when expanding a sub menu 12146 var $sub = $a.parent().dataSM('sub'); 12147 if ($a.attr('href').charAt(0) !== '#' && $sub && (!$sub.dataSM('shown-before') || !$sub.is(':visible'))) { 12148 $a.dataSM('href', $a.attr('href')); 12149 $a.attr('href', '#'); 12150 } 12151 }, 12152 menuFixLayout: function($ul) { 12153 // fixes a menu that is being shown for the first time 12154 if (!$ul.dataSM('shown-before')) { 12155 $ul.hide().dataSM('shown-before', true); 12156 // fix the layout of the items in IE<8 12157 if (IElt8) { 12158 $ul.children().css({ styleFloat: 'left', width: '100%' }); 12159 } 12160 } 12161 }, 12162 menuHide: function($sub) { 12163 if (this.$root.triggerHandler('beforehide.smapi', $sub[0]) === false) { 12164 return; 12165 } 12166 $sub.stop(true, true); 12167 if ($sub.is(':visible')) { 12168 var complete = function() { 12169 // unset z-index 12170 if (IElt9) { 12171 $sub.parent().css('z-index', ''); 12172 } else { 12173 $sub.css('z-index', ''); 12174 } 12175 }; 12176 // if sub is collapsible (mobile view) 12177 if (this.isCollapsible()) { 12178 if (this.opts.collapsibleHideFunction) { 12179 this.opts.collapsibleHideFunction.call(this, $sub, complete); 12180 } else { 12181 $sub.hide(this.opts.collapsibleHideDuration, complete); 12182 } 12183 } else { 12184 if (this.opts.hideFunction) { 12185 this.opts.hideFunction.call(this, $sub, complete); 12186 } else { 12187 $sub.hide(this.opts.hideDuration, complete); 12188 } 12189 } 12190 // remove IE iframe shim 12191 if ($sub.dataSM('ie-shim')) { 12192 $sub.dataSM('ie-shim').remove(); 12193 } 12194 // deactivate scrolling if it is activated for this sub 12195 if ($sub.dataSM('scroll')) { 12196 $sub.unbind('.smartmenus_scroll').removeDataSM('scroll').dataSM('scroll-arrows').hide(); 12197 } 12198 // unhighlight parent item 12199 $sub.dataSM('parent-a').removeClass('highlighted'); 12200 var level = $sub.dataSM('level'); 12201 this.activatedItems.splice(level - 1, 1); 12202 this.visibleSubMenus.splice(level - 1, 1); 12203 this.$root.triggerHandler('hide.smapi', $sub[0]); 12204 } 12205 }, 12206 menuHideAll: function($item) { 12207 if ($item != undefined && $item.parent().hasClass('menu-item') && !$item.parent().hasClass('menu-item-has-children')) return; 12208 var $win = $(window), 12209 winW = $win.width(); 12210 if ( $('body').hasClass('vmenu') && winW >= 560 ) { 12211 return; 12212 } 12213 if (this.showTimeout) { 12214 clearTimeout(this.showTimeout); 12215 this.showTimeout = 0; 12216 } 12217 // hide all subs 12218 for (var i = this.visibleSubMenus.length - 1; i > 0; i--) { 12219 this.menuHide(this.visibleSubMenus[i]); 12220 } 12221 // hide root if it's popup 12222 if (this.opts.isPopup) { 12223 this.$root.stop(true, true); 12224 if (this.$root.is(':visible')) { 12225 if (this.opts.hideFunction) { 12226 this.opts.hideFunction.call(this, this.$root); 12227 } else { 12228 this.$root.hide(this.opts.hideDuration); 12229 } 12230 // remove IE iframe shim 12231 if (this.$root.dataSM('ie-shim')) { 12232 this.$root.dataSM('ie-shim').remove(); 12233 } 12234 } 12235 } 12236 this.activatedItems = []; 12237 this.visibleSubMenus = []; 12238 this.clickActivated = false;
12239 // reset z-index increment 12240 this.zIndexInc = 0; 12241 }, 12242 menuIframeShim: function($ul) { 12243 // create iframe shim for the menu 12244 if (IE && this.opts.overlapControlsInIE && !$ul.dataSM('ie-shim')) { 12245 $ul.dataSM('ie-shim', $('<iframe/>').attr({ src: 'javascript:0', tabindex: -9 }) 12246 .css({ position: 'absolute', top: 'auto', left: '0', opacity: 0, border: '0' }) 12247 ); 12248 } 12249 }, 12250 menuInit: function($ul) { 12251 if (!$ul.dataSM('in-mega')) { 12252 this.subMenus.push($ul); 12253 // mark UL's in mega drop downs (if any) so we can neglect them 12254 if ($ul.hasClass('mega-menu')) { 12255 $ul.find('ul').dataSM('in-mega', true); 12256 } 12257 // get level (much faster than, for example, using parentsUntil) 12258 var level = 2, 12259 par = $ul[0]; 12260 while (par != null && par.parentNode != null && ( par = par.parentNode.parentNode) != this.$root[0]) { 12261 level++; 12262 } 12263 // cache stuff 12264 $ul.dataSM('parent-a', $ul.prevAll('a').eq(-1)) 12265 .dataSM('level', level) 12266 .parent().dataSM('sub', $ul); 12267 // add sub indicator to parent item 12268 if (this.opts.subIndicators) { 12269 $ul.dataSM('parent-a').addClass('has-submenu')[this.opts.subIndicatorsPos](this.$subArrow.clone()); 12270 } 12271 } 12272 }, 12273 menuPosition: function($sub) { 12274 var fixIE = $('html.ie').length; 12275 // if (fixIE) { 12276 // var $rowParent = $($sub).closest('.main-menu-container'); 12277 // $rowParent.height($rowParent.height()); 12278 // } 12279 var $a = $sub.dataSM('parent-a'), 12280 $li = $sub.parent(), 12281 $ul = $sub.parent().parent(), 12282 // $container = $ul.closest('.row-menu-inner').length ? ( $('body').hasClass('megamenu-side-to-side') ? ( $('body').hasClass('boxed-width') ? $ul.closest('.row-menu') : $(window) ) : $ul.closest('.row-menu-inner') ) : $ul.closest('.uncol'), 12283 $container = $ul.closest('.row-menu-inner').length ? ( $('body').hasClass('megamenu-side-to-side') ? $ul.closest('.row-menu') : $ul.closest('.row-menu-inner') ) : $ul.closest('.uncol'), 12284 level = $sub.dataSM('level'), 12285 subW = this.getWidth($sub), 12286 subH = this.getHeight($sub), 12287 itemOffset = $a.offset(), 12288 itemX = itemOffset.left, 12289 itemY = itemOffset.top, 12290 itemW = this.getWidth($a), 12291 itemH = this.getHeight($a), 12292 $win = $(window), 12293 winX = $win.scrollLeft(), 12294 winY = $win.scrollTop(), 12295 winW = $win.width(), 12296 winH = $win.height(), 12297 containerW = $container.width(), 12298 containerOffsetX = containerW + ((winW - containerW) / 2), 12299 horizontalParent = $ul.hasClass('sm') && !$ul.hasClass('sm-vertical'), 12300 subOffsetX = level == 2 ? this.opts.mainMenuSubOffsetX : this.opts.subMenusSubOffsetX, 12301 subOffsetY = level == 2 ? this.opts.mainMenuSubOffsetY : this.opts.subMenusSubOffsetY, 12302 x, y, leftPos; 12303 12304 if (horizontalParent) { 12305 x = this.opts.rightToLeftSubMenus ? itemW - subW - subOffsetX : subOffsetX; 12306 y = this.opts.bottomToTopSubMenus ? -subH - subOffsetY : itemH + subOffsetY; 12307 } else { 12308 x = this.opts.rightToLeftSubMenus ? subOffsetX - subW : subW - subOffsetX; 12309 y = this.opts.bottomToTopSubMenus ? itemH - subOffsetY - subH : subOffsetY; 12310 } 12311 if (this.opts.keepInViewport && !this.isCollapsible()) { 12312 if (this.isFixed()) { 12313 itemX -= winX; 12314 itemY -= winY; 12315 winX = winY = 0; 12316 } 12317 var absX = itemX + x, 12318 absY = itemY + y; 12319 if (this.opts.rightToLeftSubMenus && absX < winX) { 12320 x = horizontalParent ? winX - absX + x : itemW - subOffsetX; 12321 } else if (!this.opts.rightToLeftSubMenus && absX + subW > winX + containerOffsetX ) { 12322 x = horizontalParent ? winX + containerOffsetX - subW - absX + x : subOffsetX - subW; 12323 } 12324 if (!horizontalParent) { 12325 if (subH < winH && absY + subH > winY + winH) { 12326 y += winY + winH - subH - absY; 12327 } else if (subH >= winH || absY < winY) { 12328 y += winY - absY; 12329 } 12330 } 12331 // do we need scrolling? 12332 // 0.49 added for the sake of IE9/FF4+ where we might be dealing with float numbers for "subH" 12333 if (mouse && (horizontalParent && (absY + subH > winY + winH + 0.49 || absY < winY) || !horizontalParent && subH > winH + 0.49)) { 12334 var self = this; 12335 if (!$sub.dataSM('scroll-arrows')) { 12336 $sub.dataSM('scroll-arrows', $([$('<span class="scroll-up"><span class="scroll-up-arrow"></span></span>')[0], $('<span class="scroll-down"><span class="scroll-down-arrow"></span></span>')[0]]) 12337 .bind({ 12338 mouseenter: function() { self.menuScroll($sub, $(this).hasClass('scroll-up')); }, 12339 mouseleave: function(e) { 12340 self.menuScrollStop($sub); 12341 self.menuScrollOut($sub, e); 12342 }, 12343 'mousewheel DOMMouseScroll': function(e) { e.preventDefault(); } 12344 }) 12345 .insertAfter($sub) 12346 ); 12347 } 12348 // bind events to show/hide arrows on hover and save scrolling data for this sub 12349 var vportY = winY - (itemY + itemH); 12350 $sub.dataSM('scroll', { 12351 vportY: vportY, 12352 subH: subH, 12353 winH: winH, 12354 step: 1 12355 }) 12356 .bind({ 12357 'mouseover.smartmenus_scroll': function(e) { self.menuScrollOver($sub, e); }, 12358 'mouseout.smartmenus_scroll': function(e) { self.menuScrollOut($sub, e); }, 12359 'mousewheel.smartmenus_scroll DOMMouseScroll.smartmenus_scroll': function(e) { self.menuScrollMousewheel($sub, e); } 12360 }) 12361 .dataSM('scroll-arrows').css({ top: 'auto', left: '0', marginLeft: x + (parseInt($sub.css('border-left-width')) || 0), width: this.getWidth($sub) - (parseInt($sub.css('border-left-width')) || 0) - (parseInt($sub.css('border-right-width')) || 0), zIndex: this.get
12361StartZIndex() + this.zIndexInc }) 12362 .eq(0).css('margin-top', vportY).end() 12363 .eq(1).css('margin-top', vportY + winH - this.getHeight($sub.dataSM('scroll-arrows').eq(1))).end() 12364 .eq(horizontalParent && this.opts.bottomToTopSubMenus ? 0 : 1).show(); 12365 } 12366 } 12367 if ( !$sub.closest('.menu-accordion').length ) { 12368 var rightPos = 'auto'; 12369 if ( $sub.parents('.isotope-filters').length ) { 12370 if ( $sub.parents('.text-right').eq(0).length ) { 12371 leftPos = '0px'; 12372 rightPos = 'auto'; 12373 } else { 12374 leftPos = 'auto'; 12375 rightPos = '0px'; 12376 } 12377 x = 0; 12378 } else { 12379 if ( $sub.hasClass('mega-menu-inner') ) { 12380 $sub.css({ width: containerW}); 12381 leftPos = -1 * (parseFloat($sub.closest('ul.menu-smart').offset().left) - parseFloat($sub.closest('.row-menu').offset().left)); 12382 if ( ! $('body').hasClass('megamenu-side-to-side') ) { 12383 leftPos += parseFloat($sub.closest('.row-menu-inner').css('paddingLeft')); 12384 } 12385 x = 0; 12386 } else { 12387 leftPos = (level > 2 ? $li.position().left - parseFloat($li.closest('ul').css('paddingLeft')) : $li.position().left ) + 'px'; 12388 x = (level > 2 && x >= 0) ? x + 1 : x - 1; 12389 } 12390 } 12391 } 12392 12393 // $sub.css({ top: (level > 2) ? $a[0].offsetTop : (fixIE ? itemH : '100%'), left: leftPos, right: rightPos, marginLeft: x, marginTop: (level > 2) ? 0 : y - itemH + ($sub.closest('.menu-borders').length ? 1 : 0) }); 12394 $sub.css({ top: (level > 2) ? $a[0].offsetTop : (fixIE ? itemH : '100%'), left: leftPos, right: rightPos, marginLeft: x, marginTop: (level > 2) ? 0 : y - itemH + ($sub.closest('.menu-borders').length && !$sub.closest('.menu-borders.needs-after').length ? 1 : 0) }); 12395 // IE iframe shim 12396 this.menuIframeShim($sub); 12397 if ($sub.dataSM('ie-shim')) { 12398 $sub.dataSM('ie-shim').css({ zIndex: $sub.css('z-index'), width: subW, height: subH, marginLeft: x, marginTop: y - itemH + ($sub.closest('.menu-mini').length ? 0 : 1) }); 12399 } 12400 }, 12401 menuScroll: function($sub, up, wheel) { 12402 var y = parseFloat($sub.css('margin-top')), 12403 scroll = $sub.dataSM('scroll'), 12404 end = scroll.vportY + (up ? 0 : scroll.winH - scroll.subH), 12405 step = wheel || !this.opts.scrollAccelerate ? this.opts.scrollStep : Math.floor($sub.dataSM('scroll').step); 12406 $sub.add($sub.dataSM('ie-shim')).css('margin-top', Math.abs(end - y) > step ? y + (up ? step : -step) : end); 12407 y = parseFloat($sub.css('margin-top')); 12408 // show opposite arrow if appropriate 12409 if (up && y + scroll.subH > scroll.vportY + scroll.winH || !up && y < scroll.vportY) { 12410 $sub.dataSM('scroll-arrows').eq(up ? 1 : 0).show(); 12411 } 12412 // accelerate when not using mousewheel to scroll 12413 if (!wheel && this.opts.scrollAccelerate && $sub.dataSM('scroll').step < this.opts.scrollStep) { 12414 $sub.dataSM('scroll').step += 0.5; 12415 } 12416 // "y" and "end" might be float numbers in IE9/FF4+ so this weird way to check is used 12417 if (Math.abs(y - end) < 1) { 12418 $sub.dataSM('scroll-arrows').eq(up ? 0 : 1).hide(); 12419 $sub.dataSM('scroll').step = 1; 12420 } else if (!wheel) { 12421 var self = this; 12422 this.scrollTimeout = setTimeout(function() { self.menuScroll($sub, up); }, this.opts.scrollInterval); 12423 } 12424 }, 12425 menuScrollMousewheel: function($sub, e) { 12426 var $closestSub = $(e.target).closest('ul'); 12427 while ($closestSub.dataSM('in-mega')) { 12428 $closestSub = $closestSub.parent().closest('ul'); 12429 } 12430 if ($closestSub[0] == $sub[0]) { 12431 var up = (e.originalEvent.wheelDelta || -e.originalEvent.detail) > 0; 12432 if ($sub.dataSM('scroll-arrows').eq(up ? 0 : 1).is(':visible')) { 12433 this.menuScroll($sub, up, true); 12434 } 12435 } 12436 e.preventDefault(); 12437 }, 12438 menuScrollOut: function($sub, e) { 12439 var reClass = /^scroll-(up|down)/, 12440 $closestSub = $(e.relatedTarget).closest('ul'); 12441 while ($closestSub.dataSM('in-mega')) { 12442 $closestSub = $closestSub.parent().closest('ul'); 12443 } 12444 if (!reClass.test((e.relatedTarget || '').className) && ($sub[0] != e.relatedTarget && !$.contains($sub[0], e.relatedTarget) || $closestSub[0] != $sub[0])) { 12445 $sub.dataSM('scroll-arrows').css('visibility', 'hidden'); 12446 } 12447 }, 12448 menuScrollOver: function($sub, e) { 12449 var reClass = /^scroll-(up|down)/, 12450 $closestSub = $(e.target).closest('ul'); 12451 while ($closestSub.dataSM('in-mega')) { 12452 $closestSub = $closestSub.parent().closest('ul'); 12453 } 12454 if (!reClass.test(e.target.className) && $closestSub[0] == $sub[0]) { 12455 $sub.dataSM('scroll-arrows').css('visibility', 'visible'); 12456 } 12457 }, 12458 menuScrollStop: function($sub) { 12459 if (this.scrollTimeout) { 12460 clearTimeout(this.scrollTimeout); 12461 this.scrollTimeout = 0; 12462 $sub.dataSM('scroll').step = 1; 12463 } 12464 }, 12465 menuShow: function($sub) { 12466 if (!$sub.dataSM('beforefirstshowfired')) { 12467 $sub.dataSM('beforefirstshowfired', true); 12468 if (this.$root.triggerHandler('beforefirstshow.smapi', $sub[0]) === false) { 12469 return; 12470 } 12471 } 12472 if (this.$root.triggerHandler('beforeshow.smapi', $sub[0]) === false) { 12473 return; 12474 } 12475 this.menuFixLayout($sub); 12476 $sub.stop(true, true); 12477 if (!$sub.is(':visible')) { 12478 $sub.css({ 12479 'visibility': 'visible', 12480 'pointer-events': 'auto', 12481 }); 12482 // set z-index - for IE < 9 set it to the parent LI
12483 var zIndex = this.getStartZIndex() + (++this.zIndexInc); 12484 if (IElt9) { 12485 $sub.parent().css('z-index', zIndex); 12486 } else { 12487 $sub.css('z-index', zIndex); 12488 } 12489 // highlight parent item 12490 if (this.opts.keepHighlighted || this.isCollapsible()) { 12491 if ($sub.dataSM('parent-a').attr('data-type') != 'title') 12492 $sub.dataSM('parent-a').addClass('highlighted'); 12493 } 12494 // min/max-width fix - no way to rely purely on CSS as all UL's are nested 12495 if (this.opts.subMenusMinWidth || this.opts.subMenusMaxWidth) { 12496 if (!IElt8) { 12497 $sub.css({ width: ($sub.hasClass('mega-menu-inner')) ? $('.box-container').outerWidth() + 'px' : 'auto', minWidth: '', maxWidth: '' }).addClass('sm-nowrap'); 12498 if (this.opts.subMenusMinWidth) { 12499 $sub.css('min-width', this.opts.subMenusMinWidth); 12500 } 12501 if (this.opts.subMenusMaxWidth) { 12502 var noMaxWidth = this.getWidth($sub); 12503 if ( ! $sub.hasClass('mega-menu-inner') ) { 12504 $sub.css('max-width', this.opts.subMenusMaxWidth); 12505 } 12506 if (noMaxWidth > this.getWidth($sub)) { 12507 $sub.removeClass('sm-nowrap').css('width', this.opts.subMenusMaxWidth); 12508 } 12509 } 12510 // IE6,7 12511 } else { 12512 $sub.children().css('styleFloat', 'none'); 12513 if (IE6) { 12514 $sub.width(this.opts.subMenusMinWidth ? this.opts.subMenusMinWidth : 1) 12515 .children().children('a').css('white-space', 'nowrap'); 12516 } else { // IE7 12517 $sub.css({ width: ($sub.hasClass('mega-menu-inner')) ? $('.box-container').outerWidth() + 'px' : 'auto', minWidth: '', maxWidth: '' }).addClass('sm-nowrap'); 12518 if (this.opts.subMenusMinWidth) { 12519 $sub.css('min-width', this.opts.subMenusMinWidth); 12520 } 12521 } 12522 if (this.opts.subMenusMaxWidth) { 12523 var noMaxWidth = $sub.width(); 12524 if (IE6) { 12525 var maxWidth = $sub.css({ width: this.opts.subMenusMaxWidth, overflowX: 'hidden', overflowY: 'hidden' }).width(); 12526 if (noMaxWidth > maxWidth) { 12527 $sub.css({ width: maxWidth, overflowX: 'visible', overflowY: 'visible' }).children().children('a').css('white-space', ''); 12528 } else { 12529 $sub.css({ width: noMaxWidth, overflowX: 'visible', overflowY: 'visible' }); 12530 } 12531 } else { // IE7 12532 if ( ! $sub.hasClass('mega-menu-inner') ) { 12533 $sub.css('max-width', this.opts.subMenusMaxWidth); 12534 } 12535 if (noMaxWidth > $sub.width()) { 12536 $sub.removeClass('sm-nowrap').css('width', this.opts.subMenusMaxWidth); 12537 } else { 12538 $sub.width(noMaxWidth); 12539 } 12540 } 12541 } else { 12542 $sub.width($sub.width()); 12543 } 12544 $sub.children().css('styleFloat', 'left'); 12545 } 12546 } 12547 this.menuPosition($sub); 12548 // insert IE iframe shim 12549 if ($sub.dataSM('ie-shim')) { 12550 $sub.dataSM('ie-shim').insertBefore($sub); 12551 } 12552 var complete = function() { 12553 // fix: "overflow: hidden;" is not reset on animation complete in jQuery < 1.9.0 in Chrome when global "box-sizing: border-box;" is used 12554 $sub.css('overflow', ''); 12555 }; 12556 // if sub is collapsible (mobile view) 12557 if (this.isCollapsible()) { 12558 if (this.opts.collapsibleShowFunction) { 12559 this.opts.collapsibleShowFunction.call(this, $sub, complete); 12560 } else { 12561 $sub.show(this.opts.collapsibleShowDuration, complete); 12562 } 12563 } else { 12564 if (this.opts.showFunction) { 12565 this.opts.showFunction.call(this, $sub, complete); 12566 } else { 12567 $sub.show(this.opts.showDuration, complete); 12568 } 12569 } 12570 // save new sub menu for this level 12571 this.visibleSubMenus[$sub.dataSM('level') - 1] = $sub; 12572 this.$root.triggerHandler('show.smapi', $sub[0]); 12573 } 12574 }, 12575 popupHide: function(noHideTimeout) { 12576 if (this.hideTimeout) { 12577 clearTimeout(this.hideTimeout); 12578 this.hideTimeout = 0; 12579 } 12580 var self = this; 12581 this.hideTimeout = setTimeout(function() { 12582 self.menuHideAll(); 12583 }, noHideTimeout ? 1 : this.opts.hideTimeout); 12584 }, 12585 popupShow: function(left, top) { 12586 if (!this.opts.isPopup) { 12587 alert('SmartMenus jQuery Error:\n\nIf you want to show this menu via the "popupShow" method, set the isPopup:true option.'); 12588 return; 12589 } 12590 if (this.hideTimeout) { 12591 clearTimeout(this.hideTimeout); 12592 this.hideTimeout = 0; 12593 } 12594 this.menuFixLayout(this.$root); 12595 this.$root.stop(true, true); 12596 if (!this.$root.is(':visible')) { 12597 this.$root.css({ left: left, top: top }); 12598 // IE iframe shim 12599 this.menuIframeShim(this.$root); 12600 if (this.$root.dataSM('ie-shim')) { 12601 this.$root.dataSM('ie-shim').css({ zIndex: this.$root.css('z-index'), width: this.getWidth(this.$root), height: this.getHeight(this.$root), left
12601: left, top: top }).insertBefore(this.$root); 12602 } 12603 // show menu 12604 if (this.opts.showFunction) { 12605 this.opts.showFunction.call(this, this.$root); 12606 } else { 12607 this.$root.show(this.opts.showDuration); 12608 } 12609 this.visibleSubMenus[0] = this.$root; 12610 } 12611 }, 12612 refresh: function() { 12613 this.menuHideAll(); 12614 this.$root.find('ul').each(function() { 12615 var $this = $(this); 12616 if ($this.dataSM('scroll-arrows')) { 12617 $this.dataSM('scroll-arrows').remove(); 12618 } 12619 }) 12620 .removeDataSM('in-mega') 12621 .removeDataSM('shown-before') 12622 .removeDataSM('ie-shim') 12623 .removeDataSM('scroll-arrows') 12624 .removeDataSM('parent-a') 12625 .removeDataSM('level') 12626 .removeDataSM('beforefirstshowfired'); 12627 this.$root.find('a.has-submenu').removeClass('has-submenu') 12628 .parent().removeDataSM('sub'); 12629 if (this.opts.subIndicators) { 12630 this.$root.find('span.sub-arrow').remove(); 12631 } 12632 if (this.opts.markCurrentItem) { 12633 this.$root.find('a.current').removeClass('current'); 12634 } 12635 this.subMenus = []; 12636 this.init(true); 12637 }, 12638 rootOut: function(e) { 12639 if (!this.handleEvents() || this.isTouchMode() || e.target == this.$root[0]) { 12640 return; 12641 } 12642 if (this.hideTimeout) { 12643 clearTimeout(this.hideTimeout); 12644 this.hideTimeout = 0; 12645 } 12646 if (!this.opts.showOnClick || !this.opts.hideOnClick) { 12647 var self = this; 12648 this.hideTimeout = setTimeout(function() { self.menuHideAll(); }, this.opts.hideTimeout); 12649 } 12650 }, 12651 rootOver: function(e) { 12652 if (!this.handleEvents() || this.isTouchMode() || e.target == this.$root[0]) { 12653 return; 12654 } 12655 if (this.hideTimeout) { 12656 clearTimeout(this.hideTimeout); 12657 this.hideTimeout = 0; 12658 } 12659 }, 12660 winResize: function(e) { 12661 if (!this.handleEvents()) { 12662 // we still need to resize the disable overlay if it's visible 12663 if (this.$disableOverlay) { 12664 var pos = this.$root.offset(); 12665 this.$disableOverlay.css({ 12666 top: pos.top, 12667 left: pos.left, 12668 width: this.$root.outerWidth(), 12669 height: this.$root.outerHeight() 12670 }); 12671 } 12672 return; 12673 } 12674 // hide sub menus on resize - on mobile do it only on orientation change 12675 if (!this.isCollapsible() && (!('onorientationchange' in window) || e.type == 'orientationchange')) { 12676 if (this.activatedItems.length) { 12677 this.activatedItems[this.activatedItems.length - 1][0].blur(); 12678 } 12679 this.menuHideAll(); 12680 } 12681 } 12682 } 12683 }); 12684 12685 $.fn.dataSM = function(key, val) { 12686 if (val) { 12687 return this.data(key + '_smartmenus', val); 12688 } 12689 return this.data(key + '_smartmenus'); 12690 } 12691 12692 $.fn.removeDataSM = function(key) { 12693 return this.removeData(key + '_smartmenus'); 12694 } 12695 12696 $.fn.smartmenus = function(options) { 12697 if (typeof options == 'string') { 12698 var args = arguments, 12699 method = options; 12700 Array.prototype.shift.call(args); 12701 return this.each(function() { 12702 var smartmenus = $(this).data('smartmenus'); 12703 if (smartmenus && smartmenus[method]) { 12704 smartmenus[method].apply(smartmenus, args); 12705 } 12706 }); 12707 } 12708 var opts = $.extend({}, $.fn.smartmenus.defaults, options); 12709 return this.each(function() { 12710 new $.SmartMenus(this, opts); 12711 }); 12712 } 12713 12714 // default settings 12715 $.fn.smartmenus.defaults = { 12716 isPopup: false, // is this a popup menu (can be shown via the popupShow/popupHide methods) or a permanent menu bar 12717 mainMenuSubOffsetX: 0, // pixels offset from default position
12718 mainMenuSubOffsetY: 0, // pixels offset from default position 12719 subMenusSubOffsetX: 0, // pixels offset from default position 12720 subMenusSubOffsetY: 0, // pixels offset from default position 12721 subMenusMinWidth: '10em', // min-width for the sub menus (any CSS unit) - if set, the fixed width set in CSS will be ignored 12722 subMenusMaxWidth: '20em', // max-width for the sub menus (any CSS unit) - if set, the fixed width set in CSS will be ignored 12723 subIndicators: true, // create sub menu indicators - creates a SPAN and inserts it in the A 12724 subIndicatorsPos: 'prepend', // position of the SPAN relative to the menu item content ('prepend', 'append') 12725 subIndicatorsText: '+', // [optionally] add text in the SPAN (e.g. '+') (you may want to check the CSS for the sub indicators too) 12726 scrollStep: 30, // pixels step when scrolling long sub menus that do not fit in the viewport height 12727 scrollInterval: 30, // interval between each scrolling step 12728 scrollAccelerate: true, // accelerate scrolling or use a fixed step 12729 showTimeout: 250, // timeout before showing the sub menus 12730 hideTimeout: 500, // timeout before hiding the sub menus 12731 showDuration: 0, // duration for show animation - set to 0 for no animation - matters only if showFunction:null 12732 showFunction: null, // custom function to use when showing a sub menu (the default is the jQuery 'show') 12733 // don't forget to call complete() at the end of whatever you do 12734 // e.g.: function($ul, complete) { $ul.fadeIn(250, complete); } 12735 hideDuration: 0, // duration for hide animation - set to 0 for no animation - matters only if hideFunction:null 12736 hideFunction: function($ul, complete) { $ul.fadeOut(200, complete); }, // custom function to use when hiding a sub menu (the default is the jQuery 'hide') 12737 // don't forget to call complete() at the end of whatever you do 12738 // e.g.: function($ul, complete) { $ul.fadeOut(250, complete); } 12739 collapsibleShowDuration:0, // duration for show animation for collapsible sub menus - matters only if collapsibleShowFunction:null 12740 collapsibleShowFunction:function($ul, complete) { $ul.slideDown(200, complete); }, // custom function to use when showing a collapsible sub menu 12741 // (i.e. when mobile styles are used to make the sub menus collapsible) 12742 collapsibleHideDuration:0, // duration for hide animation for collapsible sub menus - matters only if collapsibleHideFunction:null 12743 collapsibleHideFunction:function($ul, complete) { $ul.slideUp(200, complete); }, // custom function to use when hiding a collapsible sub menu 12744 // (i.e. when mobile styles are used to make the sub menus collapsible) 12745 showOnClick: false, // show the first-level sub menus onclick instead of onmouseover (matters only for mouse input) 12746 hideOnClick: true, // hide the sub menus on click/tap anywhere on the page 12747 keepInViewport: true, // reposition the sub menus if needed to make sure they always appear inside the viewport 12748 keepHighlighted: true, // keep all ancestor items of the current sub menu highlighted (adds the 'highlighted' class to the A's) 12749 markCurrentItem: false, // automatically add the 'current' class to the A element of the item linking to the current URL 12750 markCurrentTree: true, // add the 'current' class also to the A elements of all ancestor items of the current item 12751 rightToLeftSubMenus: false, // right to left display of the sub menus (check the CSS for the sub indicators' position) 12752 bottomToTopSubMenus: false, // bottom to top display of the sub menus 12753 overlapControlsInIE: true // make sure sub menus appear on top of special OS controls in IE (i.e. SELECT, OBJECT, EMBED, etc.) 12754 }; 12755 12756})(jQuery); 12757 12758/* 12759 * jQuery Easing v1.4.1 - http://gsgd.co.uk/sandbox/jquery/easing/ 12760 * Open source under the BSD License. 12761 * Copyright © 2008 George McGinley Smith 12762 * All rights reserved. 12763 * https://raw.github.com/gdsmith/jquery.easing/master/LICENSE 12764*/ 12765 12766/* globals jQuery, define, module, require */ 12767(function (factory) { 12768 if (typeof define === "function" && define.amd) { 12769 define(['jquery'], function ($) { 12770 return factory($); 12771 }); 12772 } else if (typeof module === "object" && typeof module.exports === "object") { 12773 module.exports = factory(require('jquery')); 12774 } else { 12775 factory(jQuery); 12776 } 12777})(function($){ 12778 12779 // Preserve the original jQuery "swing" easing as "jswing" 12780 if (typeof $.easing !== 'undefined') { 12781 $.easing['jswing'] = $.easing['swing']; 12782 } 12783 12784 var pow = Math.pow, 12785 sqrt = Math.sqrt, 12786 sin = Math.sin, 12787 cos = Math.cos, 12788 PI = Math.PI,
12789 c1 = 1.70158, 12790 c2 = c1 * 1.525, 12791 c3 = c1 + 1, 12792 c4 = ( 2 * PI ) / 3, 12793 c5 = ( 2 * PI ) / 4.5; 12794 12795 // x is the fraction of animation progress, in the range 0..1 12796 function bounceOut(x) { 12797 var n1 = 7.5625, 12798 d1 = 2.75; 12799 if ( x < 1/d1 ) { 12800 return n1*x*x; 12801 } else if ( x < 2/d1 ) { 12802 return n1*(x-=(1.5/d1))*x + .75; 12803 } else if ( x < 2.5/d1 ) { 12804 return n1*(x-=(2.25/d1))*x + .9375; 12805 } else { 12806 return n1*(x-=(2.625/d1))*x + .984375; 12807 } 12808 } 12809 12810 $.extend( $.easing, { 12811 def: 'easeOutQuad', 12812 swing: function (x) { 12813 return $.easing[$.easing.def](x); 12814 }, 12815 easeInQuad: function (x) { 12816 return x * x; 12817 }, 12818 easeOutQuad: function (x) { 12819 return 1 - ( 1 - x ) * ( 1 - x ); 12820 }, 12821 easeInOutQuad: function (x) { 12822 return x < 0.5 ? 12823 2 * x * x : 12824 1 - pow( -2 * x + 2, 2 ) / 2; 12825 }, 12826 easeInCubic: function (x) { 12827 return x * x * x; 12828 }, 12829 easeOutCubic: function (x) { 12830 return 1 - pow( 1 - x, 3 ); 12831 }, 12832 easeInOutCubic: function (x) { 12833 return x < 0.5 ? 12834 4 * x * x * x : 12835 1 - pow( -2 * x + 2, 3 ) / 2; 12836 }, 12837 easeInQuart: function (x) { 12838 return x * x * x * x; 12839 }, 12840 easeOutQuart: function (x) { 12841 return 1 - pow( 1 - x, 4 ); 12842 }, 12843 easeInOutQuart: function (x) { 12844 return x < 0.5 ? 12845 8 * x * x * x * x : 12846 1 - pow( -2 * x + 2, 4 ) / 2; 12847 }, 12848 easeInQuint: function (x) { 12849 return x * x * x * x * x; 12850 }, 12851 easeOutQuint: function (x) { 12852 return 1 - pow( 1 - x, 5 ); 12853 }, 12854 easeInOutQuint: function (x) { 12855 return x < 0.5 ? 12856 16 * x * x * x * x * x : 12857 1 - pow( -2 * x + 2, 5 ) / 2; 12858 }, 12859 easeInSine: function (x) { 12860 return 1 - cos( x * PI/2 ); 12861 }, 12862 easeOutSine: function (x) { 12863 return sin( x * PI/2 ); 12864 }, 12865 easeInOutSine: function (x) { 12866 return -( cos( PI * x ) - 1 ) / 2; 12867 }, 12868 easeInExpo: function (x) { 12869 return x === 0 ? 0 : pow( 2, 10 * x - 10 ); 12870 }, 12871 easeOutExpo: function (x) { 12872 return x === 1 ? 1 : 1 - pow( 2, -10 * x ); 12873 }, 12874 easeInOutExpo: function (x) { 12875 return x === 0 ? 0 : x === 1 ? 1 : x < 0.5 ? 12876 pow( 2, 20 * x - 10 ) / 2 : 12877 ( 2 - pow( 2, -20 * x + 10 ) ) / 2; 12878 }, 12879 easeInCirc: function (x) { 12880 return 1 - sqrt( 1 - pow( x, 2 ) ); 12881 }, 12882 easeOutCirc: function (x) { 12883 return sqrt( 1 - pow( x - 1, 2 ) ); 12884 }, 12885 easeInOutCirc: function (x) { 12886 return x < 0.5 ? 12887 ( 1 - sqrt( 1 - pow( 2 * x, 2 ) ) ) / 2 : 12888 ( sqrt( 1 - pow( -2 * x + 2, 2 ) ) + 1 ) / 2; 12889 }, 12890 easeInElastic: function (x) { 12891 return x === 0 ? 0 : x === 1 ? 1 : 12892 -pow( 2, 10 * x - 10 ) * sin( ( x * 10 - 10.75 ) * c4 ); 12893 }, 12894 easeOutElastic: function (x) { 12895 return x === 0 ? 0 : x === 1 ? 1 : 12896 pow( 2, -10 * x ) * sin( ( x * 10 - 0.75 ) * c4 ) + 1; 12897 }, 12898 easeInOutElastic: function (x) { 12899 return x === 0 ? 0 : x === 1 ? 1 : x < 0.5 ? 12900 -( pow( 2, 20 * x - 10 ) * sin( ( 20 * x - 11.125 ) * c5 )) / 2 : 12901 pow( 2, -20 * x + 10 ) * sin( ( 20 * x - 11.125 ) * c5 ) / 2 + 1; 12902 }, 12903 easeInBack: function (x) { 12904 return c3 * x * x * x - c1 * x * x; 12905 }, 12906 easeOutBack: function (x) { 12907 return 1 + c3 * pow( x - 1, 3 ) + c1 * pow( x - 1, 2 ); 12908 }, 12909 easeInOutBack: function (x) { 12910 return x < 0.5 ? 12911 ( pow( 2 * x, 2 ) * ( ( c2 + 1 ) * 2 * x - c2 ) ) / 2 : 12912 ( pow( 2 * x - 2, 2 ) *( ( c2 + 1 ) * ( x * 2 - 2 ) + c2 ) + 2 ) / 2; 12913 }, 12914 easeInBounce: function (x) { 12915 return 1 - bounceOut( 1 - x ); 12916 }, 12917 easeOutBounce: bounceOut, 12918 easeInOutBounce: function (x) { 12919 return x < 0.5 ? 12920 ( 1 - bounceOut( 1 - 2 * x ) ) / 2 : 12921 ( 1 + bounceOut( 2 * x - 1 ) ) / 2; 12922 } 12923 }); 12924 return $; 12925}); 12926 12927/*! Copyright (c) 2011 Brandon Aaron (http://brandonaaron.net) 12928 * Licensed under the MIT License (LICENSE.txt). 12929 * 12930 * Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers. 12931 * Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix. 12932 * Thanks to: Seamus Leahy for adding deltaX and deltaY 12933 * 12934 * Version: 3.0.6 12935 * 12936 * Requires: 1.2.2+ 12937 */ 12938(function($) { 12939 var types = ['DOMMouseScroll', 'mousewheel']; 12940 if ($.event.fixHooks) { 12941 for (var i = types.length; i;) { 12942 $.event.fixHooks[types[--i]] = $.event.mouseHooks; 12943 } 12944 } 12945 $.event.special.mousewheel = { 12946 setup: function() { 12947 if (this.addEventListener) { 12948 for (var i = types.length; i;) { 12949 this.addEventListener(types[--i], handler, false); 12950 } 12951 } else { 12952 this.onmousewheel = handler; 12953 } 12954 }, 12955 teardown: function() { 12956 if (this.removeEventListener) { 12957 for (var i = types.length; i;) { 12958 this.removeEventListener(types[--i], handler, false); 12959 } 12960 } else { 12961 this.onmousewheel = null; 12962 } 12963 } 12964 }; 12965 $.fn.extend({ 12966 mousewheel: function(fn) { 12967 return fn ? this.bind("mousewheel", fn) : this.trigger("mousewheel"); 12968 }, 12969 unmousewheel: function(fn) { 12970 return this.unbind("mousewheel", fn); 12971 } 12972 }); 12973 12974 function handler(event) { 12975 var orgEvent = event || window.event, 12976 args = [].slice.call(arguments, 1), 12977 delta = 0, 12978 returnValue = true, 12979 deltaX = 0, 12980 deltaY = 0; 12981 event = $.event.fix(orgEvent); 12982 event.type = "mousewheel"; 12983 // Old school scrollwheel delta 12984 if (orgEvent.wheelDelta) { 12985 delta = orgEvent.wheelDelta / 120; 12986 } 12987 if (orgEvent.detail) { 12988 delta = -orgEvent.detail / 3; 12989 } 12990 // New school multidimensional scroll (touchpads) deltas 12991 deltaY = delta; 12992 // Gecko 12993 if (orgEvent.axis !== undefined && orgEvent.axis === orgEvent.HORIZONTAL_AXIS) { 12994 deltaY = 0; 12995 deltaX = -1 * delta; 12996 } 12997 // Webkit 12998 if (orgEvent.wheelDeltaY !== undefined) { 12999 deltaY = orgEvent.wheelDeltaY / 120; 13000 } 13001 if (orgEvent.wheelDeltaX !== undefined) { 13002 deltaX = -1 * orgEvent.wheelDeltaX / 120; 13003 } 13004 // Add event and delta to the front of the arguments 13005 args.unshift(event, delta, deltaX, deltaY); 13006 return ($.event.dispatch || $.event.handle).apply(this, args); 13007 } 13008})(jQuery); 13009/** 13010 * jQuery iLightBox - Revolutionary Lightbox Plugin 13011 * http://www.ilightbox.net/ 13012 * 13013 * @version: 2.2.4 - October 14, 2017 13014 * 13015 * @author: iProDev (Hemn Chawroka) 13016 * http://www.iprodev.com/ 13017 * 13018 */ 13019(function($, window, undefined) { 13020 13021 var extensions = { 13022 flash: ['swf'], 13023 image: ['bmp', 'gif', 'jpeg', 'jpg', 'png', 'tiff', 'tif', 'jfif', 'jpe', 'webp'], 13024 iframe: ['asp', 'aspx', 'cgi', 'cfm', 'htm', 'html', 'jsp', 'php', 'pl', 'php3', 'php4', 'php5', 'phtml', 'rb', 'rhtml', 'shtml', 'txt'], 13025 video: ['avi', 'mov', 'mpg', 'mpeg', 'movie', 'mp4', 'webm', 'ogv', 'ogg', '3gp', 'm4v'] 13026 }, 13027 13028 // Global DOM elements 13029 $win = $(window), 13030 $doc = $(document), 13031
13032 // Support indicators 13033 browser, 13034 transform, 13035 gpuAcceleration, 13036 fullScreenApi = '', 13037 userAgent = navigator.userAgent || navigator.vendor || window.opera, 13038 supportTouch = "ontouchstart" in window || navigator.msMaxTouchPoints || (navigator.maxTouchPoints && navigator.userAgent.indexOf('Windows') > -1), 13039 ishybrid = navigator.maxTouchPoints && navigator.userAgent.indexOf('Windows') > -1, 13040 isMobile = /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(userAgent) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(userAgent.substr(0, 4)), 13041 13042 // Events 13043 clickEvent = ishybrid ? "itap.iLightBox click.iLightBox" : supportTouch ? "itap.iLightBox" : "click.iLightBox", 13044 touchStartEvent = ishybrid ? "touchstart.iLightBox mousedown.iLightBox" : supportTouch ? "touchstart.iLightBox" : "mousedown.iLightBox", 13045 touchStopEvent = ishybrid ? "touchend.iLightBox mouseup.iLightBox" : supportTouch ? "touchend.iLightBox" : "mouseup.iLightBox", 13046 touchMoveEvent = ishybrid ? "touchmove.iLightBox mousemove.iLightBox" : supportTouch ? "touchmove.iLightBox" : "mousemove.iLightBox", 13047 13048 // Math shorthands 13049 abs = Math.abs, 13050 sqrt = Math.sqrt, 13051 round = Math.round, 13052 max = Math.max, 13053 min = Math.min, 13054 floor = Math.floor, 13055 random = Math.random, 13056 13057 pluginspages = { 13058 quicktime: 'http://www.apple.com/quicktime/download', 13059 flash: 'http://www.adobe.com/go/getflash' 13060 }, 13061 13062 iLightBox = function(el, options, items, instant) { 13063 var iL = this; 13064 13065 iL.options = options, 13066 iL.selector = options.selector || el, 13067 iL.context = document, 13068 iL.instant = instant; 13069 13070 if (items.length < 1) iL.attachItems(); 13071 else iL.items = items; 13072 13073 iL.vars = { 13074 total: iL.items.length, 13075 start: 0, 13076 current: null, 13077 next: null, 13078 prev: null, 13079 BODY: $('body'), 13080 loadRequests: 0, 13081 overlay: $('<div class="ilightbox-overlay"></div>'), 13082 loader: $('<div class="ilightbox-loader"><div></div></div>'), 13083 toolbar: $('<div class="ilightbox-toolbar"></div>'), 13084 innerToolbar: $('<div class="ilightbox-inner-toolbar"></div>'), 13085 title: $('<div class="ilightbox-title"></div>'), 13086 closeButton: $('<a class="ilightbox-close" title="' + iL.options.text.close + '"></a>'), 13087 fullScreenButton: $('<a class="ilightbox-fullscreen" title="' + iL.options.text.enterFullscreen + '"></a>'), 13088 innerPlayButton: $('<a class="ilightbox-play" title="' + iL.options.text.slideShow + '"></a>'), 13089 innerNextButton: $('<a class="ilightbox-next-button" title="' + iL.options.text.next + '"></a>'), 13090 innerPrevButton: $('<a class="ilightbox-prev-button" title="' + iL.options.text.previous + '"></a>'), 13091 holder: $('<div class="ilightbox-holder' + (supportTouch ? ' supportTouch' : '') + '" ondragstart="return false;"><div class="ilightbox-container"></div></div>'), 13092 nextPhoto: $('<div class="ilightbox-holder' + (supportTouch ? ' supportTouch' : '') + ' ilightbox-next" ondragstart="return false;"><div class="ilightbox-container"></div></div>'), 13093 prevPhoto: $('<div class="ilightbox-holder' + (supportTouch ? ' supportTouch' : '') + ' ilightbox-prev" ondragstart="return false;"><div class="ilightbox-container"></div></div>'), 13094 nextButton: $('<a class="ilightbox-button ilightbox-next-button" ondragstart="return false;" title="' + iL.options.text.next + '"><span></span></a>'), 13095 prevButton: $('<a class="ilightbox-button ilightbox-prev-button" ondragstart="return false;" title="' + iL.options.text.previous + '"><span></span></a>'),
13096 thumbnails: $('<div class="ilightbox-thumbnails" ondragstart="return false;"><div class="ilightbox-thumbnails-container"><a class="ilightbox-thumbnails-dragger"></a><div class="ilightbox-thumbnails-grid"></div></div></div>'), 13097 thumbs: false, 13098 nextLock: false, 13099 prevLock: false, 13100 hashLock: false, 13101 isMobile: false, 13102 mobileMaxWidth: 980, 13103 isInFullScreen: false, 13104 isSwipe: false, 13105 mouseID: 0, 13106 cycleID: 0, 13107 isPaused: 0, 13108 captionHeight: 39, 13109 }; 13110 13111 // Hideable elements with mousemove event 13112 iL.vars.hideableElements = iL.vars.nextButton.add(iL.vars.prevButton); 13113 13114 iL.normalizeItems(); 13115 13116 //Check necessary plugins 13117 iL.availPlugins(); 13118 13119 //Set startFrom 13120 iL.options.startFrom = (iL.options.startFrom > 0 && iL.options.startFrom >= iL.vars.total) ? iL.vars.total - 1 : iL.options.startFrom; 13121 13122 //If randomStart 13123 iL.options.startFrom = (iL.options.randomStart) ? floor(random() * iL.vars.total) : iL.options.startFrom; 13124 iL.vars.start = iL.options.startFrom; 13125 13126 if (instant) iL.instantCall(); 13127 else iL.patchItemsEvents(); 13128 13129 if (iL.options.linkId) { 13130 iL.hashChangeHandler(); 13131 $win.iLightBoxHashChange(function() { 13132 iL.hashChangeHandler(); 13133 }); 13134 } 13135 13136 if (supportTouch) { 13137 var RegExp = /(click|mouseenter|mouseleave|mouseover|mouseout)/ig, 13138 replace = "itap"; 13139 iL.options.caption.show = iL.options.caption.show.replace(RegExp, replace), 13140 iL.options.caption.hide = iL.options.caption.hide.replace(RegExp, replace), 13141 iL.options.social.show = iL.options.social.show.replace(RegExp, replace), 13142 iL.options.social.hide = iL.options.social.hide.replace(RegExp, replace); 13143 } 13144 13145 if (iL.options.controls.arrows || $(window).width() < UNCODE.mediaQuery) { 13146 $.extend(iL.options.styles, { 13147 nextOffsetX: ($(window).width() > UNCODE.mediaQuery) ? 36 : 4, 13148 prevOffsetX: ($(window).width() > UNCODE.mediaQuery) ? 36 : 4, 13149 nextOpacity: 0, 13150 prevOpacity: 0 13151 }); 13152 } 13153 }; 13154 13155 //iLightBox helpers 13156 iLightBox.prototype = { 13157 showLoader: function() { 13158 var iL = this; 13159 iL.vars.loadRequests += 1; 13160 if (iL.options.path.toLowerCase() == "horizontal") iL.vars.loader.addClass('ilightbox-show').stop().animate({ 13161 //top: '-30px' 13162 opacity: '1' 13163 }, iL.options.show.speed, 'easeOutCirc'); 13164 else iL.vars.loader.addClass('ilightbox-show').stop().animate({ 13165 //left: '-30px' 13166 opacity: '1' 13167 }, iL.options.show.speed, 'easeOutCirc'); 13168 }, 13169 13170 hideLoader: function() { 13171 var iL = this; 13172 iL.vars.loadRequests -= 1; 13173 iL.vars.loadRequests = (iL.vars.loadRequests < 0) ? 0 : iL.vars.loadRequests; 13174 if (iL.options.path.toLowerCase() == "horizontal") { 13175 if (iL.vars.loadRequests <= 0) iL.vars.loader.removeClass('ilightbox-show').stop().animate({ 13176 //top: '-192px' 13177 opacity: '0' 13178 }, iL.options.show.speed, 'easeInCirc'); 13179 } else { 13180 if (iL.vars.loadRequests <= 0) iL.vars.loader.removeClass('ilightbox-show').stop().animate({ 13181 //left: '-192px' 13182 opacity: '0' 13183 }, iL.options.show.speed, 'easeInCirc'); 13184 } 13185 }, 13186 13187 createUI: function() { 13188 var iL = this; 13189 13190 iL.ui = { 13191 currentElement: iL.vars.holder, 13192 nextElement: iL.vars.nextPhoto, 13193 prevElement: iL.vars.prevPhoto, 13194 currentItem: iL.vars.current, 13195 nextItem: iL.vars.next, 13196 prevItem: iL.vars.prev, 13197 hide: function() { 13198 iL.closeAction(); 13199 }, 13200 refresh: function() { 13201 (arguments.length > 0) ? iL.repositionPhoto(true): iL.repositionPhoto(); 13202 }, 13203 fullscreen: function() { 13204 iL.fullScreenAction(); 13205 } 13206 }; 13207 }, 13208 13209 attachItems: function() { 13210 var iL = this, 13211 itemsObject = new Array(), 13212 items = new Array(); 13213 13214 $(iL.selector, iL.context).each(function() { 13215 var t = $(this), 13216 URL = t.attr(iL.options.attr) || null, 13217 options = t.data("options") && eval("({" + t.data("options") + "})") || {}, 13218 caption = t.data('caption'), 13219 title = t.data('title'), 13220 type = t.data('type') || getTypeByExtension(URL), 13221 clone = t.data('lbox-clone') || false; 13222 13223 //Uncode addition ##START## 13224 if (type === false) { 13225 return; 13226 } 13227 //Uncode addition ##END## 13228 13229 if (t.data('lbox-clone') != undefined) return; 13230 13231 //Uncode addition ##START## 13232 if ( typeof t.attr('data-album') != 'undefined' && t.attr('data-album') != '' ) { 13233 var ALBUM_URLS = JSON.parse(t.attr('data-album')), 13234 URL_i, 13235 URLS_LENGHT = ALBUM_URLS.length; 13236 13237 for (URL_i = 0; URL_i < URLS_LENGHT; URL_i++) { 13238 if ( typeof ALBUM_URLS[URL_i].url !== 'undefined' && ALBUM_URLS[URL_i].url != '' ) { 13239 var item_opts = 'width:' + ALBUM_URLS[URL_i].width + ',height:' + ALBUM_URLS[URL_i].height + ',thumbnail: \'' + ALBUM_URLS[URL_i].thumbnail + '\''; 13240 item_opts = item_opts && eval("({" + item_opts + "})") || {}, 13241 items.push({ 13242 URL: ALBUM_URLS[URL_i].url, 13243 caption: ALBUM_URLS[URL_i].caption, 13244 title: ALBUM_URLS[URL_i].title, 13245 type: getTypeByExtension(ALBUM_URLS[URL_i].url), 13246 options: item_opts, 13247 clone: clone 13248 }); 13249 var newT = t; 13250 newT.attr('href',ALBUM_URLS[URL_i].url); 13251 if (!iL.instant) itemsObject.push(newT); 13252 } 13253 } 13254 } else { 13255 //Uncode addition ##END## 13256 items.push({ 13257 URL: URL, 13258 caption: caption, 13259 title: title, 13260 type: type, 13261 options: options, 13262 clone: clone 13263 }); 13264 } 13265 13266 13267 if (iL.vars != undefined) iL.vars.total = items.length; 13268 13269 if (!iL.instant) itemsObject.push(t); 13270 }); 13271 13272 iL.items = items, 13273 iL.itemsObject = itemsObject; 13274 13275 }, 13276 13277 normalizeItems: function() { 13278 var iL = this, 13279 newItems = new Array(); 13280 13281 $.each(iL.items, function(key, val) { 13282 13283 if (typeof val == "string") val = { 13284 url: val 13285 }; 13286 13287 var URL = val.url || val.URL || null, 13288 options = val.options || {}, 13289 caption = val.caption || null, 13290 title = val.title || null, 13291 type = (val.type) ? val.type.toLowerCase() : getTypeByExtension(URL), 13292 ext = (typeof URL != 'object') ? getExtension(URL) : ''; 13293 13294 options.thumbnail = options.thumbnail || ((type == "image") ? URL : null),
13295 options.videoType = options.videoType || null, 13296 options.skin = options.skin || iL.options.skin, 13297 options.width = options.width || null, 13298 options.height = options.height || null, 13299 options.mousewheel = (typeof options.mousewheel != 'undefined') ? options.mousewheel : true, 13300 options.swipe = (typeof options.swipe != 'undefined') ? options.swipe : true, 13301 options.social = (typeof options.social != 'undefined') ? options.social : iL.options.social.buttons && $.extend({}, {}, iL.options.social.buttons); 13302 13303 if (type == "video") { 13304 options.html5video = (typeof options.html5video != 'undefined') ? options.html5video : {}; 13305 13306 options.html5video.webm = options.html5video.webm || options.html5video.WEBM || null; 13307 options.html5video.controls = (typeof options.html5video.controls != 'undefined') ? options.html5video.controls : "controls"; 13308 options.html5video.preload = options.html5video.preload || "metadata"; 13309 options.html5video.autoplay = (typeof options.html5video.autoplay != 'undefined') ? options.html5video.autoplay : false; 13310 //UNCODE addition 13311 options.html5video.loop = (typeof options.html5video.loop != 'undefined') ? options.html5video.loop : false; 13312 } 13313 13314 if (!options.width || !options.height) { 13315 if (type == "video") options.width = 1280, options.height = 720; 13316 else if (type == "iframe") options.width = '100%', options.height = '90%'; 13317 else if (type == "flash") options.width = 1280, options.height = 720; 13318 } 13319 13320 delete val.url; 13321 val.index = key; 13322 val.URL = URL; 13323 val.caption = caption; 13324 val.title = title; 13325 val.type = type; 13326 val.options = options; 13327 val.ext = ext; 13328 13329 newItems.push(val); 13330 }); 13331 13332 iL.items = newItems; 13333 }, 13334 13335 instantCall: function() { 13336 var iL = this, 13337 key = iL.vars.start; 13338 13339 iL.vars.current = key; 13340 iL.vars.next = (iL.items[key + 1]) ? key + 1 : null; 13341 iL.vars.prev = (iL.items[key - 1]) ? key - 1 : null; 13342 13343 iL.addContents(); 13344 iL.patchEvents(); 13345 }, 13346 13347 addContents: function() { 13348 var iL = this, 13349 vars = iL.vars, 13350 opts = iL.options, 13351 viewport = getViewport(), 13352 path = opts.path.toLowerCase(), 13353 recognizingItems = vars.total > 0 && iL.items.filter(function(e, i, arr) { 13354 return ['image', 'flash', 'video'].indexOf(e.type) === -1 && typeof e.recognized === 'undefined' && (opts.smartRecognition || e.options.smartRecognition); 13355 }), 13356 needRecognition = recognizingItems.length > 0; 13357 13358 if (opts.mobileOptimizer && !opts.innerToolbar) 13359 vars.isMobile = viewport.width <= vars.mobileMaxWidth; 13360 13361 vars.overlay.addClass(opts.skin).hide().css('opacity', opts.overlay.opacity); 13362 13363 if (opts.linkId) 13364 vars.overlay[0].setAttribute('linkid', opts.linkId); 13365 13366 //Add Toolbar Buttons 13367 if (opts.controls.toolbar) { 13368 vars.toolbar.addClass(opts.skin).append(vars.closeButton); 13369 if (opts.controls.fullscreen) 13370 vars.toolbar.append(vars.fullScreenButton); 13371 if (opts.controls.slideshow) 13372 vars.toolbar.append(vars.innerPlayButton); 13373 if (vars.total > 1) 13374 vars.toolbar.append(vars.innerPrevButton).append(vars.innerNextButton); 13375 } 13376 13377 //Append elements to body 13378 vars.BODY.addClass('ilightbox-noscroll').append(vars.overlay).append(vars.loader).append(vars.holder).append(vars.nextPhoto).append(vars.prevPhoto); 13379 13380 if (!opts.innerToolbar) 13381 vars.BODY.append(vars.toolbar); 13382 if (opts.controls.arrows) 13383 vars.BODY.append(vars.nextButton).append(vars.prevButton); 13384 13385 if (opts.controls.thumbnail && vars.total > 1) { 13386 vars.BODY.append(vars.thumbnails); 13387 vars.thumbnails.addClass(opts.skin).addClass('ilightbox-' + path); 13388 $('div.ilightbox-thumbnails-grid', vars.thumbnails).empty(); 13389 vars.thumbs = true; 13390 } 13391 13392 //Configure loader and arrows 13393 var loaderCss = (opts.path.toLowerCase() == "horizontal") ? { 13394 left: parseInt((viewport.width / 2) - (vars.loader.outerWidth() / 2)) 13395 } : { 13396 top: parseInt((viewport.height / 2) - (vars.loader.outerHeight() / 2)) 13397 }; 13398 vars.loader.addClass(opts.skin).css(loaderCss); 13399 vars.nextButton.add(vars.prevButton).addClass(opts.skin); 13400 if (path == "horizontal") 13401 vars.loader.add(vars.nextButton).add(vars.prevButton).addClass('horizontal'); 13402 13403 // Configure arrow buttons 13404 vars.BODY[vars.isMobile ? 'addClass' : 'removeClass']('isMobile'); 13405 13406 if (!opts.infinite) { 13407 vars.prevButton.add(vars.prevButton).add(vars.innerPrevButton).add(vars.innerNextButton).removeClass('disabled'); 13408 13409 if (vars.current == 0) 13410 vars.prevButton.add(vars.innerPrevButton).addClass('disabled'); 13411 if (vars.current >= vars.total - 1) 13412 vars.nextButton.add(vars.innerNextButton).addClass('disabled'); 13413 } 13414 13415 if (opts.show.effect) { 13416 vars.overlay.stop().fadeIn(opts.show.speed); 13417 vars.toolbar.stop().fadeIn(opts.show.speed); 13418 } else { 13419 vars.overlay.show(); 13420 vars.toolbar.show(); 13421 } 13422 13423 var length = recognizingItems.length; 13424 if (needRecognition) { 13425 iL.showLoader(); 13426 13427 $.each(recognizingItems, function(key, val) { 13428 var resultFnc = function(result) { 13429 var key = -1, 13430 filter = iL.items.filter(function(e, i, arr) { 13431 if (e.URL == result.url) 13432 key = i; 13433 13434 return e.URL == result.url; 13435 }), 13436 self = iL.items[key]; 13437 13438 if (result) 13439 $.extend(true, self, { 13440 URL: result.source, 13441 type: result.type, 13442 recognized: true, 13443 options: { 13444 html5video: result.html5video, 13445 width: (result.type == "image") ? 0 : (result.width || self.width), 13446 height: (result.type == "image") ? 0 : (result.height || self.height), 13447 thumbnail: self.options.thumbnail || result.thumbnail 13448 } 13449 }); 13450 13451 length--; 13452 13453 if (length == 0) { 13454 iL.hideLoader(); 13455 13456 vars.dontGenerateThumbs = false;
13457 iL.generateThumbnails(); 13458 13459 if (opts.show.effect) 13460 setTimeout(function() { 13461 iL.generateBoxes(); 13462 }, opts.show.speed); 13463 else 13464 iL.generateBoxes(); 13465 } 13466 }; 13467 13468 iL.ogpRecognition(this, resultFnc); 13469 }); 13470 } 13471 else { 13472 if (opts.show.effect) 13473 setTimeout(function() { 13474 iL.generateBoxes(); 13475 }, opts.show.speed); 13476 else 13477 iL.generateBoxes(); 13478 } 13479 13480 iL.createUI(); 13481 13482 window.iLightBox = { 13483 close: function() { 13484 iL.closeAction(); 13485 }, 13486 fullscreen: function() { 13487 iL.fullScreenAction(); 13488 }, 13489 moveNext: function() { 13490 iL.moveTo('next'); 13491 }, 13492 movePrev: function() { 13493 iL.moveTo('prev'); 13494 }, 13495 goTo: function(index) { 13496 iL.goTo(index); 13497 }, 13498 refresh: function() { 13499 iL.refresh(); 13500 }, 13501 reposition: function() { 13502 (arguments.length > 0) ? iL.repositionPhoto(true): iL.repositionPhoto(); 13503 }, 13504 setOption: function(options) { 13505 iL.setOption(options); 13506 }, 13507 destroy: function() { 13508 iL.closeAction(); 13509 iL.dispatchItemsEvents(); 13510 } 13511 }; 13512 13513 if (opts.linkId) { 13514 vars.hashLock = true; 13515 window.location.hash = opts.linkId + '/' + vars.current; 13516 setTimeout(function() { 13517 vars.hashLock = false; 13518 }, 55); 13519 } 13520 13521 if (!opts.slideshow.startPaused) { 13522 iL.resume(); 13523 vars.innerPlayButton.removeClass('ilightbox-play').addClass('ilightbox-pause'); 13524 } 13525 13526 //Trigger the onOpen callback 13527 if (typeof iL.options.callback.onOpen == 'function') iL.options.callback.onOpen.call(iL); 13528 }, 13529 13530 loadContent: function(obj, opt, speed) { 13531 var iL = this, 13532 holder, item; 13533 13534 iL.createUI(); 13535 13536 obj.speed = speed || iL.options.effects.loadedFadeSpeed; 13537 13538 if (opt == 'current') { 13539 if (!obj.options.mousewheel) iL.vars.lockWheel = true; 13540 else iL.vars.lockWheel = false; 13541 13542 if (!obj.options.swipe) iL.vars.lockSwipe = true; 13543 else iL.vars.lockSwipe = false; 13544 } 13545 13546 switch (opt) { 13547 case 'current': 13548 holder = iL.vars.holder, item = iL.vars.current; 13549 break; 13550 case 'next': 13551 holder = iL.vars.nextPhoto, item = iL.vars.next; 13552 break; 13553 case 'prev': 13554 holder = iL.vars.prevPhoto, item = iL.vars.prev; 13555 break; 13556 } 13557 13558 holder.removeAttr('style class').addClass('ilightbox-holder' + (supportTouch ? ' supportTouch' : '')).addClass(obj.options.skin); 13559 $('div.ilightbox-inner-toolbar', holder).remove(); 13560 13561 if (obj.title || iL.options.innerToolbar) { 13562 var innerToolbar = iL.vars.innerToolbar.clone(); 13563 if (obj.title && iL.options.show.title) { 13564 var title = iL.vars.title.clone(); 13565 title.empty().html(obj.title); 13566 innerToolbar.append(title); 13567 } 13568 if (iL.options.innerToolbar) { 13569 innerToolbar.append((iL.vars.total > 1) ? iL.vars.toolbar.clone() : iL.vars.toolbar); 13570 } 13571 holder.prepend(innerToolbar); 13572 } 13573 13574 //console.warn('loadContent', arguments); 13575 13576 iL.loadSwitcher(obj, holder, item, opt); 13577 }, 13578 13579 loadSwitcher: function(obj, holder, item, opt) { 13580 var iL = this, 13581 opts = iL.options, 13582 api = { 13583 element: holder, 13584 position: item 13585 }; 13586 13587 switch (obj.type) { 13588 case 'image': 13589 //Trigger the onBeforeLoad callback 13590 if (typeof opts.callback.onBeforeLoad == 'function') opts.callback.onBeforeLoad.call(iL, iL.ui, item); 13591 if (typeof obj.options.onBeforeLoad == 'function') obj.options.onBeforeLoad.call(iL, api); 13592 13593 iL.loadImage(obj.URL, function(img) { 13594 //Trigger the onAfterLoad callback 13595 if (typeof opts.callback.onAfterLoad == 'function') opts.callback.onAfterLoad.call(iL, iL.ui, item); 13596 if (typeof obj.options.onAfterLoad == 'function') obj.options.onAfterLoad.call(iL, api); 13597 13598 var width = (img) ? img.width : 400, 13599 height = (img) ? img.height : 200; 13600 13601 holder.data({ 13602 naturalWidth: width, 13603 naturalHeight: height 13604 }); 13605 13606 $('div.ilightbox-container', holder).empty().append((img) ? '<img src="' + obj.URL + '" class="ilightbox-image" />' : '<span class="ilightbox-alert">' + opts.errors.loadImage + '</span>'); 13607 13608 //Trigger the onRender callback 13609 if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item); 13610 if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api); 13611 13612 iL.configureHolder(obj, opt, holder); 13613 }); 13614 13615 break; 13616
13617 case 'video': 13618 holder.data({ 13619 naturalWidth: obj.options.width, 13620 naturalHeight: obj.options.height 13621 }); 13622 13623 if (opt === 'current') { 13624 iL.addContent(holder, obj); 13625 13626 //Trigger the onRender callback 13627 if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item); 13628 if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api); 13629 } else { 13630 $('div.ilightbox-container', holder).empty(); 13631 } 13632 13633 iL.configureHolder(obj, opt, holder); 13634 13635 break; 13636 13637 case 'iframe': 13638 //iL.showLoader(); 13639 holder.data({ 13640 naturalWidth: obj.options.width, 13641 naturalHeight: obj.options.height 13642 }); 13643 13644 iL.configureHolder(obj, opt, holder); 13645 13646 if (opt === 'current') { 13647 var el = iL.addContent(holder, obj); 13648 13649 //Trigger the onRender callback 13650 if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item); 13651 if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api); 13652 13653 //Trigger the onBeforeLoad callback 13654 if (typeof opts.callback.onBeforeLoad == 'function') opts.callback.onBeforeLoad.call(iL, iL.ui, item); 13655 if (typeof obj.options.onBeforeLoad == 'function') obj.options.onBeforeLoad.call(iL, api); 13656 13657 el.bind('load', function() { 13658 //Trigger the onAfterLoad callback 13659 if (typeof opts.callback.onAfterLoad == 'function') opts.callback.onAfterLoad.call(iL, iL.ui, item); 13660 if (typeof obj.options.onAfterLoad == 'function') obj.options.onAfterLoad.call(iL, api); 13661 13662 //iL.hideLoader(); 13663 el.unbind('load'); 13664 }); 13665 } else { 13666 $('div.ilightbox-container', holder).empty(); 13667 } 13668 13669 break; 13670 13671 case 'inline': 13672 var el = $(obj.URL), 13673 content = iL.addContent(holder, obj), 13674 images = findImageInElement(holder); 13675 13676 holder.data({ 13677 naturalWidth: (iL.items[item].options.width || el.outerWidth()), 13678 naturalHeight: (iL.items[item].options.height || el.outerHeight()) 13679 }); 13680 content.children().eq(0).show(); 13681 13682 //Trigger the onRender callback 13683 if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item); 13684 if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api); 13685 13686 //Trigger the onBeforeLoad callback 13687 if (typeof opts.callback.onBeforeLoad == 'function') opts.callback.onBeforeLoad.call(iL, iL.ui, item); 13688 if (typeof obj.options.onBeforeLoad == 'function') obj.options.onBeforeLoad.call(iL, api); 13689 13690 iL.loadImage(images, function() { 13691 //Trigger the onAfterLoad callback 13692 if (typeof opts.callback.onAfterLoad == 'function') opts.callback.onAfterLoad.call(iL, iL.ui, item); 13693 if (typeof obj.options.onAfterLoad == 'function') obj.options.onAfterLoad.call(iL, api); 13694 13695 iL.configureHolder(obj, opt, holder); 13696 }); 13697 13698 break; 13699 13700 case 'flash': 13701 var el = iL.addContent(holder, obj); 13702 13703 holder.data({ 13704 naturalWidth: (iL.items[item].options.width || el.outerWidth()), 13705 naturalHeight: (iL.items[item].options.height || el.outerHeight()) 13706 }); 13707 13708 //Trigger the onRender callback 13709 if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item); 13710 if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api); 13711 13712 iL.configureHolder(obj, opt, holder); 13713 13714 break; 13715 13716 case 'ajax': 13717 var ajax = obj.options.ajax || {}; 13718 //Trigger the onBeforeLoad callback 13719 if (typeof opts.callback.onBeforeLoad == 'function') opts.callback.onBeforeLoad.call(iL, iL.ui, item); 13720 if (typeof obj.options.onBeforeLoad == 'function') obj.options.onBeforeLoad.call(iL, api); 13721 13722 iL.showLoader(); 13723 $.ajax({ 13724 url: obj.URL || opts.ajaxSetup.url, 13725 data: ajax.data || null, 13726 dataType: ajax.dataType || "html", 13727 type: ajax.type || opts.ajaxSetup.type, 13728 cache: ajax.cache || opts.ajaxSetup.cache, 13729 crossDomain: ajax.crossDomain || opts.ajaxSetup.crossDomain, 13730 global: ajax.global || opts.ajaxSetup.global, 13731 ifModified: ajax.ifModified || opts.ajaxSetup.ifModified, 13732 username: ajax.username || opts.ajaxSetup.username, 13733 password: ajax.password || opts.ajaxSetup.password, 13734 beforeSend: ajax.beforeSend || opts.ajaxSetup.beforeSend, 13735 complete: ajax.complete || opts.ajaxSetup.complete, 13736 success: function(data, textStatus, jqXHR) { 13737 iL.hideLoader(); 13738 13739 var el = $(data), 13740 container = $('div.ilightbox-container', holder), 13741 elWidth = iL.items[item].options.width || parseInt(el[0].getAttribute('width')), 13742 elHeight = iL.items[item].options.height || parseInt(el[0].getAttribute('height')), 13743 css = (el[0].getAttribute('width') && el[0].getAttribute('height')) ? { 13744 'overflow': 'hidden' 13745 } : {}; 13746 13747 container.empty().append($('<div class="ilightbox-wrapper"></div>').css(css).html(el)); 13748 holder.show().data({
13749 naturalWidth: (elWidth || container.outerWidth()), 13750 naturalHeight: (elHeight || container.outerHeight()) 13751 }).hide(); 13752 13753 //Trigger the onRender callback 13754 if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item); 13755 if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api); 13756 13757 var images = findImageInElement(holder); 13758 iL.loadImage(images, function() { 13759 //Trigger the onAfterLoad callback 13760 if (typeof opts.callback.onAfterLoad == 'function') opts.callback.onAfterLoad.call(iL, iL.ui, item); 13761 if (typeof obj.options.onAfterLoad == 'function') obj.options.onAfterLoad.call(iL, api); 13762 13763 iL.configureHolder(obj, opt, holder); 13764 }); 13765 13766 opts.ajaxSetup.success(data, textStatus, jqXHR); 13767 if (typeof ajax.success == 'function') ajax.success(data, textStatus, jqXHR); 13768 }, 13769 error: function(jqXHR, textStatus, errorThrown) { 13770 //Trigger the onAfterLoad callback 13771 if (typeof opts.callback.onAfterLoad == 'function') opts.callback.onAfterLoad.call(iL, iL.ui, item); 13772 if (typeof obj.options.onAfterLoad == 'function') obj.options.onAfterLoad.call(iL, api); 13773 13774 iL.hideLoader(); 13775 $('div.ilightbox-container', holder).empty().append('<span class="ilightbox-alert">' + opts.errors.loadContents + '</span>'); 13776 iL.configureHolder(obj, opt, holder); 13777 13778 opts.ajaxSetup.error(jqXHR, textStatus, errorThrown); 13779 if (typeof ajax.error == 'function') ajax.error(jqXHR, textStatus, errorThrown); 13780 } 13781 }); 13782 13783 break; 13784 13785 case 'html': 13786 var object = obj.URL, 13787 el 13788 container = $('div.ilightbox-container', holder); 13789 13790 if (object[0].nodeName) el = object.clone(); 13791 else { 13792 var dom = $(object); 13793 if (dom.selector) el = $('<div>' + dom + '</div>'); 13794 else el = dom; 13795 } 13796 13797 var elWidth = iL.items[item].options.width || parseInt(el.attr('width')), 13798 elHeight = iL.items[item].options.height || parseInt(el.attr('height')); 13799 13800 iL.addContent(holder, obj); 13801 13802 el.appendTo(document.documentElement).hide(); 13803 13804 //Trigger the onRender callback 13805 if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item); 13806 if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api); 13807 13808 var images = findImageInElement(holder); 13809 13810 //Trigger the onBeforeLoad callback 13811 if (typeof opts.callback.onBeforeLoad == 'function') opts.callback.onBeforeLoad.call(iL, iL.ui, item); 13812 if (typeof obj.options.onBeforeLoad == 'function') obj.options.onBeforeLoad.call(iL, api); 13813 13814 iL.loadImage(images, function() { 13815 //Trigger the onAfterLoad callback 13816 if (typeof opts.callback.onAfterLoad == 'function') opts.callback.onAfterLoad.call(iL, iL.ui, item); 13817 if (typeof obj.options.onAfterLoad == 'function') obj.options.onAfterLoad.call(iL, api); 13818 13819 holder.show().data({ 13820 naturalWidth: (elWidth || container.outerWidth()), 13821 naturalHeight: (elHeight || container.outerHeight()) 13822 }).hide(); 13823 el.remove(); 13824 13825 iL.configureHolder(obj, opt, holder); 13826 }); 13827 13828 break; 13829 } 13830 }, 13831 13832 configureHolder: function(obj, opt, holder) { 13833 var iL = this, 13834 vars = iL.vars, 13835 opts = iL.options; 13836 13837 if (opt != "current")(opt == "next") ? holder.addClass('ilightbox-next') : holder.addClass('ilightbox-prev'); 13838 13839 if (opt == "current") 13840 var item = vars.current; 13841 else if (opt == "next") 13842 var opacity = opts.styles.nextOpacity, 13843 item = vars.next; 13844 else 13845 var opacity = opts.styles.prevOpacity, 13846 item = vars.prev; 13847 13848 var api = { 13849 element: holder, 13850 position: item 13851 }; 13852 13853 iL.items[item].options.width = iL.items[item].options.width || 0, 13854 iL.items[item].options.height = iL.items[item].options.height || 0; 13855 13856 if (opt == "current") { 13857 if (opts.show.effect) holder.css(transform, gpuAcceleration).fadeIn(obj.speed, function() { 13858 holder.css(transform, ''); 13859 if (obj.caption) { 13860 iL.setCaption(obj, holder); 13861 var caption = $('div.ilightbox-caption', holder), 13862 percent = parseInt((caption.outerHeight() / holder.outerHeight()) * 100); 13863 if (opts.caption.start & percent <= 50) caption.fadeIn(opts.effects.fade
13863Speed); 13864 } 13865 13866 var social = obj.options.social; 13867 if (social) { 13868 iL.setSocial(social, obj.URL, holder); 13869 if (opts.social.start) $('div.ilightbox-social', holder).fadeIn(opts.effects.fadeSpeed); 13870 } 13871 13872 //Generate thumbnails 13873 iL.generateThumbnails(); 13874 13875 //Trigger the onShow callback 13876 if (typeof opts.callback.onShow == 'function') opts.callback.onShow.call(iL, iL.ui, item); 13877 if (typeof obj.options.onShow == 'function') obj.options.onShow.call(iL, api); 13878 }); 13879 else { 13880 holder.show(); 13881 13882 //Generate thumbnails 13883 iL.generateThumbnails(); 13884 13885 //Trigger the onShow callback 13886 if (typeof opts.callback.onShow == 'function') opts.callback.onShow.call(iL, iL.ui, item); 13887 if (typeof obj.options.onShow == 'function') obj.options.onShow.call(iL, api); 13888 } 13889 } else { 13890 if (opts.show.effect) holder.fadeTo(obj.speed, opacity, function() { 13891 if (opt == "next") vars.nextLock = false; 13892 else vars.prevLock = false; 13893 13894 //Generate thumbnails 13895 iL.generateThumbnails(); 13896 13897 //Trigger the onShow callback 13898 if (typeof opts.callback.onShow == 'function') opts.callback.onShow.call(iL, iL.ui, item); 13899 if (typeof obj.options.onShow == 'function') obj.options.onShow.call(iL, api); 13900 }); 13901 else { 13902 holder.css({ 13903 opacity: opacity 13904 }).show(); 13905 if (opt == "next") vars.nextLock = false; 13906 else vars.prevLock = false; 13907 13908 //Generate thumbnails 13909 iL.generateThumbnails(); 13910 13911 //Trigger the onShow callback 13912 if (typeof opts.callback.onShow == 'function') opts.callback.onShow.call(iL, iL.ui, item); 13913 if (typeof obj.options.onShow == 'function') obj.options.onShow.call(iL, api); 13914 } 13915 } 13916 13917 setTimeout(function() { 13918 iL.repositionPhoto(); 13919 }, 0); 13920 }, 13921 13922 generateBoxes: function() { 13923 var iL = this, 13924 vars = iL.vars, 13925 opts = iL.options; 13926 13927 if (opts.infinite && vars.total >= 3) { 13928 if (vars.current == vars.total - 1) vars.next = 0; 13929 if (vars.current == 0) vars.prev = vars.total - 1; 13930 } else opts.infinite = false; 13931 13932 //UNCODE addition 13933 if ( typeof iL.items[vars.current] == 'undefined' ) 13934 vars.current = 0; 13935 13936 iL.loadContent(iL.items[vars.current], 'current', opts.show.speed); 13937 13938 if (iL.items[vars.next]) iL.loadContent(iL.items[vars.next], 'next', opts.show.speed); 13939 if (iL.items[vars.prev]) iL.loadContent(iL.items[vars.prev], 'prev', opts.show.speed); 13940 }, 13941 13942 generateThumbnails: function() { 13943 var iL = this, 13944 vars = iL.vars, 13945 opts = iL.options, 13946 timeOut = null; 13947 13948 if (vars.thumbs && !iL.vars.dontGenerateThumbs) { 13949 var thumbnails = vars.thumbnails, 13950 container = $('div.ilightbox-thumbnails-container', thumbnails), 13951 grid = $('div.ilightbox-thumbnails-grid', container), 13952 i = 0; 13953 13954 grid.removeAttr('style').empty(); 13955 13956 $.each(iL.items, function(key, val) { 13957 var isActive = (vars.current == key) ? 'ilightbox-active' : '', 13958 opacity = (vars.current == key) ? opts.thumbnails.activeOpacity : opts.thumbnails.normalOpacity, 13959 thumb = val.options.thumbnail, 13960 thumbnail = $('<div class="ilightbox-thumbnail"></div>'), 13961 icon = $('<div class="ilightbox-thumbnail-icon"></div>'); 13962 13963 thumbnail.css({ 13964 opacity: 0 13965 }).addClass(isActive); 13966 13967 if ((val.type == "video" || val.type == "flash") && typeof val.options.icon == 'undefined') { 13968 icon.addClass('ilightbox-thumbnail-video'); 13969 thumbnail.append(icon); 13970 } else if (val.options.icon) { 13971 icon.addClass('ilightbox-thumbnail-' + val.options.icon); 13972 thumbnail.append(icon); 13973 } 13974 13975 if (thumb) iL.loadImage(thumb, function(img) { 13976 i++; 13977 if (img) thumbnail.data({ 13978 naturalWidth: img.width, 13979 naturalHeight: img.height 13980 }).append('<img src="' + thumb + '" border="0" />'); 13981 else thumbnail.data({ 13982 naturalWidth: opts.thumbnails.maxWidth, 13983 naturalHeight: opts.thumbnails.maxHeight 13984 }); 13985 13986 clearTimeout(timeOut); 13987 timeOut = setTimeout(function() { 13988 iL.positionThumbnails(thumbnails, container, grid); 13989 }, 20); 13990 setTimeout(function() { 13991 thumbnail.fadeTo(opts.effects.loadedFadeSpeed, opacity); 13992 }, i * 20); 13993 }); 13994 13995 grid.append(thumbnail); 13996 }); 13997 iL.vars.dontGenerateThumbs = true; 13998 } 13999 }, 14000
14001 positionThumbnails: function(thumbnails, container, grid) { 14002 var iL = this, 14003 vars = iL.vars, 14004 opts = iL.options, 14005 viewport = getViewport(), 14006 path = opts.path.toLowerCase(); 14007 14008 if (!thumbnails) thumbnails = vars.thumbnails; 14009 if (!container) container = $('div.ilightbox-thumbnails-container', thumbnails); 14010 if (!grid) grid = $('div.ilightbox-thumbnails-grid', container); 14011 14012 var thumbs = $('.ilightbox-thumbnail', grid), 14013 widthAvail = (path == 'horizontal') ? viewport.width - opts.styles.pageOffsetX : thumbs.eq(0).outerWidth() - opts.styles.pageOffsetX, 14014 heightAvail = (path == 'horizontal') ? thumbs.eq(0).outerHeight() - opts.styles.pageOffsetY : viewport.height - opts.styles.pageOffsetY, 14015 gridWidth = (path == 'horizontal') ? 0 : widthAvail, 14016 gridHeight = (path == 'horizontal') ? heightAvail : 0, 14017 active = $('.ilightbox-active', grid), 14018 gridCss = {}, 14019 css = {}; 14020 14021 if (arguments.length < 3) { 14022 thumbs.css({ 14023 opacity: opts.thumbnails.normalOpacity 14024 }); 14025 active.css({ 14026 opacity: opts.thumbnails.activeOpacity 14027 }); 14028 } 14029 14030 thumbs.each(function(i) { 14031 var t = $(this), 14032 data = t.data(), 14033 width = (path == 'horizontal') ? 0 : opts.thumbnails.maxWidth; 14034 height = (path == 'horizontal') ? opts.thumbnails.maxHeight : 0; 14035 dims = iL.getNewDimenstions(width, height, data.naturalWidth, data.naturalHeight, true); 14036 14037 t.css({ 14038 width: dims.width, 14039 height: dims.height 14040 }); 14041 if (path == 'horizontal') t.css({ 14042 'float': 'left' 14043 }); 14044 14045 (path == 'horizontal') ? ( 14046 gridWidth += t.outerWidth() 14047 ) : ( 14048 gridHeight += t.outerHeight() 14049 ); 14050 }); 14051 14052 gridCss = { 14053 width: gridWidth, 14054 height: gridHeight 14055 }; 14056 14057 grid.css(gridCss); 14058 14059 gridCss = {}; 14060 14061 var gridOffset = grid.offset(), 14062 activeOffset = (active.length) ? active.offset() : { 14063 top: parseInt(heightAvail / 2), 14064 left: parseInt(widthAvail / 2) 14065 }; 14066 14067 gridOffset.top = (gridOffset.top - $doc.scrollTop()), 14068 gridOffset.left = (gridOffset.left - $doc.scrollLeft()), 14069 activeOffset.top = (activeOffset.top - gridOffset.top - $doc.scrollTop()), 14070 activeOffset.left = (activeOffset.left - gridOffset.left - $doc.scrollLeft()); 14071 14072 (path == 'horizontal') ? ( 14073 gridCss.top = 0, 14074 gridCss.left = parseInt((widthAvail / 2) - activeOffset.left - (active.outerWidth() / 2)) 14075 ) : ( 14076 gridCss.top = parseInt(((heightAvail / 2) - activeOffset.top - (active.outerHeight() / 2))), 14077 gridCss.left = 0 14078 ); 14079 14080 if (arguments.length < 3) grid.stop().animate(gridCss, opts.effects.repositionSpeed, 'easeOutCirc'); 14081 else grid.css(gridCss); 14082 }, 14083 14084 loadImage: function(image, callback) { 14085 if (!$.isArray(image)) image = [image]; 14086 14087 var iL = this, 14088 length = image.length; 14089 14090 if (length > 0) { 14091 iL.showLoader(); 14092 $.each(image, function(index, value) { 14093 var img = new Image(); 14094 img.onload = function() { 14095 length -= 1; 14096 if (length == 0) { 14097 iL.hideLoader(); 14098 callback(img); 14099 } 14100 }; 14101 img.onerror = img.onabort = function() { 14102 length -= 1; 14103 if (length == 0) { 14104 iL.hideLoader(); 14105 callback(false); 14106 } 14107 }; 14108 img.src = image[index]; 14109 }); 14110 } else callback(false); 14111 }, 14112 14113 patchItemsEvents: function() { 14114 var iL = this, 14115 vars = iL.vars, 14116 clickEvent = ishybrid ? "itap.iL click.iL" : supportTouch ? "itap.iL" : "click.iL", 14117 vEvent = ishybrid ? "click.iL itap.iL" : supportTouch ? "click.iL" : "itap.iL"; 14118 14119 if (iL.context && iL.selector) { 14120 var $items = $(iL.selector, iL.context); 14121 14122 $(iL.context).on(clickEvent, iL.selector, function() { 14123 var $this = $(this), 14124 //UNCODE addition 14125 key = typeof $(this).data('lb-index') !== '' && $(this).closest('.owl-item').length ? $(this).data('lb-index') : $items.index($this); 14126 if (UNCODE.isMobile) { 14127 var isCarousel = $this.closest('.owl-carousel'); 14128 if (isCarousel.length) { 14129 if (isCarousel.hasClass('owl-translating')) return false; 14130 } 14131 } 14132 14133 vars.current = key; 14134 vars.next = iL.items[key + 1] ? key + 1 : null; 14135 vars.prev = iL.items[key - 1] ? key - 1 : null; 14136 14137 //UNCODE addition 14138 if ( vars.BODY.hasClass('fp-slide-scrolling') ) 14139 return false;
14140 14141 iL.addContents(); 14142 iL.patchEvents(); 14143 14144 return false; 14145 }).on(vEvent, iL.selector, function() { 14146 return false; 14147 }); 14148 } else 14149 $.each(iL.itemsObject, function(key, val) { 14150 val.on(clickEvent, function() { 14151 vars.current = key; 14152 vars.next = iL.items[key + 1] ? key + 1 : null; 14153 vars.prev = iL.items[key - 1] ? key - 1 : null; 14154 14155 iL.addContents(); 14156 iL.patchEvents(); 14157 14158 return false; 14159 }).on(vEvent, function() { 14160 return false; 14161 }); 14162 }); 14163 }, 14164 14165 dispatchItemsEvents: function() { 14166 var iL = this, 14167 vars = iL.vars, 14168 opts = iL.options; 14169 14170 if (iL.context && iL.selector) 14171 $(iL.context).off('.iL', iL.selector); 14172 else 14173 $.each(iL.itemsObject, function(key, val) { 14174 val.off('.iL'); 14175 }); 14176 }, 14177 14178 refresh: function() { 14179 var iL = this; 14180 14181 iL.dispatchItemsEvents(); 14182 iL.attachItems(); 14183 iL.normalizeItems(); 14184 iL.patchItemsEvents(); 14185 }, 14186 14187 patchEvents: function() { 14188 var iL = this, 14189 vars = iL.vars, 14190 opts = iL.options, 14191 path = opts.path.toLowerCase(), 14192 holders = $('.ilightbox-holder'), 14193 fullscreenEvent = fullScreenApi.fullScreenEventName + '.iLightBox', 14194 durationThreshold = 1000, 14195 horizontalDistanceThreshold = 14196 verticalDistanceThreshold = 100, 14197 buttonsArray = [vars.nextButton[0], vars.prevButton[0], vars.nextButton[0].firstChild, vars.prevButton[0].firstChild]; 14198 14199 $win.bind('resize.iLightBox', function() { 14200 var viewport = getViewport(); 14201 14202 if (opts.mobileOptimizer && !opts.innerToolbar) vars.isMobile = viewport.width <= vars.mobileMaxWidth; 14203 vars.BODY[vars.isMobile ? 'addClass' : 'removeClass']('isMobile'); 14204 14205 iL.repositionPhoto(null); 14206 if (supportTouch) { 14207 clearTimeout(vars.setTime); 14208 vars.setTime = setTimeout(function() { 14209 var scrollTop = getScrollXY().y; 14210 window.scrollTo(0, scrollTop - 30); 14211 window.scrollTo(0, scrollTop + 30); 14212 window.scrollTo(0, scrollTop); 14213 }, 2000); 14214 } 14215 if (vars.thumbs) iL.positionThumbnails(); 14216 }).bind('keydown.iLightBox', function(event) { 14217 if (opts.controls.keyboard) { 14218 switch (event.keyCode) { 14219 case 13: 14220 if (event.shiftKey && opts.keyboard.shift_enter) iL.fullScreenAction(); 14221 break; 14222 case 27: 14223 if (opts.keyboard.esc) iL.closeAction(); 14224 break; 14225 case 37: 14226 if (opts.keyboard.left && !vars.lockKey) iL.moveTo('prev'); 14227 break; 14228 case 38: 14229 if (opts.keyboard.up && !vars.lockKey) iL.moveTo('prev'); 14230 break; 14231 case 39: 14232 if (opts.keyboard.right && !vars.lockKey) iL.moveTo('next'); 14233 break; 14234 case 40: 14235 if (opts.keyboard.down && !vars.lockKey) iL.moveTo('next'); 14236 break; 14237 } 14238 } 14239 }); 14240 14241 if (fullScreenApi.supportsFullScreen) $win.bind(fullscreenEvent, function() { 14242 iL.doFullscreen(); 14243 }); 14244 14245 var holderEventsArr = [opts.caption.show + '.iLightBox', opts.caption.hide + '.iLightBox', opts.social.show + '.iLightBox', opts.social.hide + '.iLightBox'].filter(function(e, i, arr) { 14246 return arr.lastIndexOf(e) === i; 14247 }), 14248 holderEvents = ""; 14249 14250 $.each(holderEventsArr, function(key, val) { 14251 if (key != 0) holderEvents += ' '; 14252 holderEvents += val; 14253 }); 14254 14255 $doc.on(clickEvent, '.ilightbox-overlay', function() { 14256 if (opts.overlay.blur) iL.closeAction(); 14257 }).on(clickEvent, '.ilightbox-next, .ilightbox-next-button', function() { 14258 iL.moveTo('next'); 14259 }).on(clickEvent, '.ilightbox-prev, .ilightbox-prev-button', function() { 14260 iL.moveTo('prev'); 14261 }).on(clickEvent, '.ilightbox-thumbnail', function() { 14262 var t = $(this), 14263 thumbs = $('.ilightbox-thumbnail', vars.thumbnails), 14264 index = thumbs.index(t); 14265 14266 if (index != vars.current) iL.goTo(index); 14267 }).on(holderEvents, '.ilightbox-holder:not(.ilightbox-next, .ilightbox-prev)', function(e) { 14268 var caption = $('div.ilightbox-caption', vars.holder), 14269 social = $('div.ilightbox-social', vars.holder), 14270 fadeSpeed = opts.effects.fadeSpeed; 14271 14272 if (vars.nextLock || vars.prevLock) { 14273 if (e.type == opts.caption.show && !caption.is(':visible')) caption.fadeIn(fadeSpeed); 14274 else if (e.type == opts.caption.hide && caption.is(':visible')) caption.fadeOut(fadeSpeed); 14275 14276 if (e.type == opts.social.show && !social.is(':visible')) social.fadeIn(fadeSpeed); 14277 else if (e.type == opts.social.hide && social.is(':visible')) social.fadeOut(fadeSpeed); 14278 } else { 14279 if (e.type == opts.caption.show && !caption.is(':visible')) caption.stop().fadeIn(fadeSpeed); 14280 else if (e.type == opts.caption.hide && caption.is(':visible')) caption.stop().fadeOut(fadeSpeed); 14281 14282 if (e.type == opts.social.show && !social.is(':visible')) social.stop().fadeIn(fadeSpeed); 14283 else if (e.type == opts.social.hide && social.is(':visible')) social.stop().fadeOut(fadeSpeed); 14284 } 14285 }).on('mouseenter.iLightBox mouseleave.iLightBox', '.ilightbox-wrapper', function(e) { 14286 if (e.type == 'mouseenter') vars.lockWheel = true; 14287 else vars.lockWheel = false;
14288 }).on(clickEvent, '.ilightbox-toolbar a.ilightbox-close, .ilightbox-toolbar a.ilightbox-fullscreen, .ilightbox-toolbar a.ilightbox-play, .ilightbox-toolbar a.ilightbox-pause', function() { 14289 var t = $(this); 14290 14291 if (t.hasClass('ilightbox-fullscreen')) iL.fullScreenAction(); 14292 else if (t.hasClass('ilightbox-play')) { 14293 iL.resume(); 14294 t.addClass('ilightbox-pause').removeClass('ilightbox-play'); 14295 } else if (t.hasClass('ilightbox-pause')) { 14296 iL.pause(); 14297 t.addClass('ilightbox-play').removeClass('ilightbox-pause'); 14298 } else iL.closeAction(); 14299 }).on(touchMoveEvent, '.ilightbox-overlay, .ilightbox-thumbnails-container', function(e) { 14300 // prevent scrolling 14301 e.preventDefault(); 14302 }); 14303 14304 function mouseMoveHandler(e) { 14305 if (!vars.isMobile) { 14306 if (!vars.mouseID) { 14307 vars.hideableElements.show(); 14308 } 14309 14310 vars.mouseID = clearTimeout(vars.mouseID); 14311 14312 if (buttonsArray.indexOf(e.target) === -1) 14313 vars.mouseID = setTimeout(function() { 14314 vars.hideableElements.hide(); 14315 vars.mouseID = clearTimeout(vars.mouseID); 14316 }, 3000); 14317 } 14318 } 14319 14320 if (opts.controls.arrows && !supportTouch) $doc.on('mousemove.iLightBox', mouseMoveHandler); 14321 14322 if (opts.controls.slideshow && opts.slideshow.pauseOnHover) $doc.on('mouseenter.iLightBox mouseleave.iLightBox', '.ilightbox-holder:not(.ilightbox-next, .ilightbox-prev)', function(e) { 14323 if (e.type == 'mouseenter' && vars.cycleID) iL.pause(); 14324 else if (e.type == 'mouseleave' && vars.isPaused) iL.resume(); 14325 }); 14326 14327 var switchers = $('.ilightbox-overlay, .ilightbox-holder, .ilightbox-thumbnails'), 14328 delay = false; 14329 14330 if (opts.controls.mousewheel) switchers.on('mousewheel.iLightBox', function(event, delta) { 14331 event.preventDefault(); 14332 if (delay) return; 14333 delay = true; 14334 if (!vars.lockWheel) { 14335 event.preventDefault(); 14336 if (delta < 0) { 14337 iL.moveTo('next'); 14338 } else if (delta > 0) { 14339 iL.moveTo('prev'); 14340 } 14341 } 14342 setTimeout(function(){
14343 delay = false; 14344 }, 2000); 14345 }); 14346 14347 if (opts.controls.swipe) holders.on(touchStartEvent, function(event) { 14348 if (vars.nextLock || vars.prevLock || vars.total == 1 || vars.lockSwipe) return; 14349 14350 vars.BODY.addClass('ilightbox-closedhand'); 14351 14352 var data = event.originalEvent.touches ? event.originalEvent.touches[0] : event, 14353 scrollTop = $doc.scrollTop(), 14354 scrollLeft = $doc.scrollLeft(), 14355 offsets = [ 14356 holders.eq(0).offset(), 14357 holders.eq(1).offset(), 14358 holders.eq(2).offset() 14359 ], 14360 offSet = [{ 14361 top: offsets[0].top - scrollTop, 14362 left: offsets[0].left - scrollLeft 14363 }, { 14364 top: offsets[1].top - scrollTop, 14365 left: offsets[1].left - scrollLeft 14366 }, { 14367 top: offsets[2].top - scrollTop, 14368 left: offsets[2].left - scrollLeft 14369 }], 14370 start = { 14371 time: (new Date()).getTime(), 14372 coords: [data.pageX - scrollLeft, data.pageY - scrollTop] 14373 }, 14374 stop; 14375 14376 function moveEachHandler(i) { 14377 var t = $(this), 14378 offset = offSet[i], 14379 scroll = [(start.coords[0] - stop.coords[0]), (start.coords[1] - stop.coords[1])]; 14380 14381 t[0].style[path == "horizontal" ? 'left' : 'top'] = (path == "horizontal" ? offset.left - scroll[0] : offset.top - scroll[1]) + 'px'; 14382 } 14383 14384 function moveHandler(event) { 14385 14386 if (!start) return; 14387 14388 var data = event.originalEvent.touches ? event.originalEvent.touches[0] : event; 14389 14390 stop = { 14391 time: (new Date()).getTime(), 14392 coords: [data.pageX - scrollLeft, data.pageY - scrollTop] 14393 }; 14394 14395 holders.each(moveEachHandler); 14396 14397 // prevent scrolling 14398 event.preventDefault(); 14399 } 14400 14401 function repositionHolders() { 14402 holders.each(function() { 14403 var t = $(this), 14404 offset = t.data('offset') || { 14405 top: t.offset().top - scrollTop, 14406 left: t.offset().left - scrollLeft 14407 }, 14408 top = offset.top, 14409 left = offset.left; 14410 14411 t.css(transform, gpuAcceleration).stop().animate({ 14412 top: top, 14413 left: left 14414 }, 500, 'easeOutCirc', function() { 14415 t.css(transform, ''); 14416 }); 14417 }); 14418 } 14419 14420 holders.bind(touchMoveEvent, moveHandler); 14421 $doc.one(touchStopEvent, function(event) { 14422 holders.unbind(touchMoveEvent, moveHandler); 14423 14424 vars.BODY.removeClass('ilightbox-closedhand'); 14425 14426 if (start && stop) { 14427 if (path == "horizontal" && stop.time - start.time < durationThreshold && abs(start.coords[0] - stop.coords[0]) > horizontalDistanceThreshold && abs(start.coords[1] - stop.coords[1]) < verticalDistanceThreshold) { 14428 if (start.coords[0] > stop.coords[0]) { 14429 if (vars.current == vars.total - 1 && !opts.infinite) repositionHolders(); 14430 else { 14431 vars.isSwipe = true; 14432 iL.moveTo('next'); 14433 } 14434 } else { 14435 if (vars.current == 0 && !opts.infinite) repositionHolders(); 14436 else { 14437 vars.isSwipe = true; 14438 iL.moveTo('prev'); 14439 } 14440 } 14441 } else if (path == "vertical" && stop.time - start.time < durationThreshold && abs(start.coords[1] - stop.coords[1]) > horizontalDistanceThreshold && abs(start.coords[0] - stop.coords[0]) < verticalDistanceThreshold) { 14442 if (start.coords[1] > stop.coords[1]) { 14443 if (vars.current == vars.total - 1 && !opts.infinite) repositionHolders(); 14444 else { 14445 vars.isSwipe = true; 14446 iL.moveTo('next'); 14447 } 14448 } else { 14449 if (vars.current == 0 && !opts.infinite) repositionHolders(); 14450 else { 14451 vars.isSwipe = true; 14452 iL.moveTo('prev'); 14453 } 14454 } 14455 } else repositionHolders(); 14456 } 14457 start = stop = undefined; 14458 }); 14459 }); 14460 14461 }, 14462 14463 goTo: function(index) { 14464 var iL = this, 14465 vars = iL.vars, 14466 opts = iL.options, 14467 diff = (index - vars.current); 14468 14469 if (opts.infinite) { 14470 if (index == vars.total - 1 && vars.current == 0) diff = -1; 14471 if (vars.current == vars.total - 1 && index == 0) diff = 1; 14472 } 14473 14474 if (diff == 1) iL.moveTo('next'); 14475 else if (diff == -1) iL.moveTo('prev'); 14476 else { 14477 14478 if (vars.nextLock || vars.prevLock) return false; 14479 14480 //Trigger the onBeforeChange callback 14481 if (typeof opts.callback.onBeforeChange == 'function') opts.callback.onBeforeChange.call(iL, iL.ui); 14482 14483 if (opts.linkId) { 14484 vars.hashLock = true; 14485 window.location.hash = opts.linkId + '/' + index; 14486 } 14487 14488 if (iL.items[index]) { 14489 if (!iL.items[index].options.mousewheel) vars.lockWheel = true; 14490 else iL.vars.lockWheel = false;
14491 14492 if (!iL.items[index].options.swipe) vars.lockSwipe = true; 14493 else vars.lockSwipe = false; 14494 } 14495 14496 $.each([vars.holder, vars.nextPhoto, vars.prevPhoto], function(key, val) { 14497 val.css(transform, gpuAcceleration).fadeOut(opts.effects.loadedFadeSpeed); 14498 }); 14499 14500 vars.current = index; 14501 vars.next = index + 1; 14502 vars.prev = index - 1; 14503 14504 iL.createUI(); 14505 14506 setTimeout(function() { 14507 iL.generateBoxes(); 14508 }, opts.effects.loadedFadeSpeed + 50); 14509 14510 $('.ilightbox-thumbnail', vars.thumbnails).removeClass('ilightbox-active').eq(index).addClass('ilightbox-active'); 14511 iL.positionThumbnails(); 14512 14513 if (opts.linkId) setTimeout(function() { 14514 vars.hashLock = false; 14515 }, 55); 14516 14517 // Configure arrow buttons 14518 if (!opts.infinite) { 14519 vars.nextButton.add(vars.prevButton).add(vars.innerPrevButton).add(vars.innerNextButton).removeClass('disabled'); 14520 14521 if (vars.current == 0) { 14522 vars.prevButton.add(vars.innerPrevButton).addClass('disabled'); 14523 } 14524 if (vars.current >= vars.total - 1) { 14525 vars.nextButton.add(vars.innerNextButton).addClass('disabled'); 14526 } 14527 } 14528 14529 // Reset next cycle timeout 14530 iL.resetCycle(); 14531 14532 //Trigger the onAfterChange callback 14533 if (typeof opts.callback.onAfterChange == 'function') opts.callback.onAfterChange.call(iL, iL.ui); 14534 } 14535 }, 14536 14537 moveTo: function(side) { 14538 var iL = this, 14539 vars = iL.vars, 14540 opts = iL.options, 14541 path = opts.path.toLowerCase(), 14542 viewport = getViewport(), 14543 switchSpeed = opts.effects.switchSpeed; 14544 14545 if (vars.nextLock || vars.prevLock) return false; 14546 else { 14547 14548 var item = (side == "next") ? vars.next : vars.prev; 14549 14550 if (opts.linkId) { 14551 vars.hashLock = true; 14552 window.location.hash = opts.linkId + '/' + item; 14553 } 14554 14555 if (side == "next") { 14556 if (!iL.items[item]) return false; 14557 var firstHolder = vars.nextPhoto, 14558 secondHolder = vars.holder, 14559 lastHolder = vars.prevPhoto, 14560 firstClass = 'ilightbox-prev', 14561 secondClass = 'ilightbox-next'; 14562 } else if (side == "prev") { 14563 if (!iL.items[item]) return false; 14564 var firstHolder = vars.prevPhoto, 14565 secondHolder = vars.holder, 14566 lastHolder = vars.nextPhoto, 14567 firstClass = 'ilightbox-next', 14568 secondClass = 'ilightbox-prev'; 14569 } 14570 14571 //Trigger the onBeforeChange callback 14572 if (typeof opts.callback.onBeforeChange == 'function') 14573 opts.callback.onBeforeChange.call(iL, iL.ui); 14574 14575 (side == "next") ? vars.nextLock = true: vars.prevLock = true; 14576 14577 var captionFirst = $('div.ilightbox-caption', secondHolder), 14578 socialFirst = $('div.ilightbox-social', secondHolder); 14579 14580 if (captionFirst.length) 14581 captionFirst.stop().fadeOut(switchSpeed, function() { 14582 $(this).remove(); 14583 }); 14584 if (socialFirst.length) 14585 socialFirst.stop().fadeOut(switchSpeed, function() { 14586 $(this).remove(); 14587 }); 14588 14589 if (iL.items[item].caption) { 14590 iL.setCaption(iL.items[item], firstHolder); 14591 var caption = $('div.ilightbox-caption', firstHolder), 14592 percent = parseInt((caption.outerHeight() / firstHolder.outerHeight()) * 100); 14593 if (opts.caption.start && percent <= 50) caption.fadeIn(switchSpeed); 14594 } 14595 14596 var social = iL.items[item].options.social; 14597 if (social) { 14598 iL.setSocial(social, iL.items[item].URL, firstHolder); 14599 if (opts.social.start) $('div.ilightbox-social', firstHolder).fadeIn(opts.effects.fadeSpeed); 14600 } 14601 14602 $.each([firstHolder, secondHolder, lastHolder], function(key, val) { 14603 val.removeClass('ilightbox-next ilightbox-prev'); 14604 }); 14605 14606 var firstOffset = firstHolder.data('offset'), 14607 winW = (viewport.width - (opts.styles.pageOffsetX)), 14608 winH = (viewport.height - (opts.styles.pageOffsetY)), 14609 width = firstOffset.newDims.width, 14610 height = firstOffset.newDims.height, 14611 thumbsOffset = firstOffset.thumbsOffset, 14612 diff = firstOffset.diff, 14613 top = parseInt((winH / 2) - (height / 2) - diff.H - (thumbsOffset.H / 2)), 14614 left = parseInt((winW / 2) - (width / 2) - diff.W - (thumbsOffset.W / 2)); 14615 14616 var secondOffset = secondHolder.data('offset'), 14617 object = secondOffset.object; 14618 14619 /*if (object.item.caption && !isNaN(width) && !isNaN(height) && UNCODE.wwidth > UNCODE.mediaQuery) { 14620 var objRatio = width / height; 14621 height = height - vars.captionHeight; 14622 width = height * objRatio; 14623 top = path == 'horizontal' ? parseInt((winH / 2) - (height / 2) - diff.H - (thumbsOffset.H / 2)) : top, 14624 left = parseInt((winW / 2) - (width / 2) - diff.W - (thumbsOffset.W / 2)); 14625 }*/ 14626 14627 firstHolder.show().css(transform, gpuAcceleration).animate({ 14628 top: top, 14629 left: left, 14630 opacity: 1 14631 }, switchSpeed, (vars.isSwipe) ? 'easeOutCirc' : 'easeInOutCirc', function() { 14632 firstHolder.css(transform, ''); 14633 }); 14634 14635 $('div.ilightbox-container', firstHolder).animate({ 14636 width: width, 14637 height: height 14638 }, switchSpeed, (vars.isSwipe) ? 'easeOutCirc' : 'easeInOutCirc'); 14639 14640 diff = secondOffset.diff; 14641 14642 width = secondOffset.newDims.width, 14643 height = secondOffset.newDims.height; 14644 14645 width = parseInt(width * opts.styles[side == 'next' ? 'prevScale' : 'nextScale']), 14646 height = parseInt(height * opts.styles[side == 'next' ? 'prevScale' : 'nextScale']), 14647 top = (path == 'horizontal') ? parseInt((winH / 2) - object.offsetY - (height / 2) - diff.H - (thumbsOffset.H / 2)) : parseInt(winH - object.offsetX - diff.H - (thumbsOffset.H / 2)); 14648 14649 if (side == 'prev') 14650 left = (path == 'horizontal') ? parseInt(winW - object.offsetX - diff.W - (thumbsOffset.W / 2)) : parseInt((winW / 2) - (width / 2) - diff.W - object.offsetY - (thumbsOffset.W / 2)); 14651 else { 14652 top = (path == 'horizontal') ? top : parseInt(object.offsetX - diff.H - height - (thumbsOffset.H / 2)), 14653 left = (path == 'horizontal') ? parseInt(object.offsetX - diff.W - width - (thumbsOffset.W / 2)) : parseInt((winW / 2) - object.offsetY - (width / 2) - diff.W - (thumbsOffset.W / 2)); 14654 } 14655 14656 /*if (object.item.caption && !isNaN(width) && !isNaN(height) && UNCODE.wwidth > UNCODE.mediaQuery) { 14657 var objRatio = width / height; 14658 height = height - vars.captionHeight; 14659 width = height * objRatio; 14660 top = path == 'horizontal' ? parseInt((winH / 2) - (height / 2) - diff.H - (thumbsOffset.H / 2)) : top; 14661 }*/ 14662 14663 $('div.ilightbox-container', secondHolder).animate({ 14664 width: width, 14665 height: height 14666 }, switchSpeed, (vars.isSwipe) ? 'easeOutCirc' : 'easeInOutCirc'); 14667 14668 secondHolder.addClass(firstClass).css(transform, gpuAcceleration).animate({ 14669 top: top, 14670 left: left, 14671 opacity: opts.styles.prevOpacity, 14672 }, switchSpeed, (vars.isSwipe) ? 'easeOutCirc' : 'easeInOutCirc', function() { 14673 secondHolder.css(transform, ''); 14674
14675 $('.ilightbox-thumbnail', vars.thumbnails).removeClass('ilightbox-active').eq(item).addClass('ilightbox-active'); 14676 iL.positionThumbnails(); 14677 14678 if (iL.items[item]) { 14679 if (!iL.items[item].options.mousewheel) vars.lockWheel = true; 14680 else vars.lockWheel = false; 14681 14682 if (!iL.items[item].options.swipe) vars.lockSwipe = true; 14683 else vars.lockSwipe = false; 14684 } 14685 14686 vars.isSwipe = false; 14687 14688 // Remove iframe & video from previous slide 14689 if (['iframe', 'video'].indexOf(iL.items[vars.current].type) !== -1) { 14690 $('div.ilightbox-container', secondHolder).empty(); 14691 } 14692 14693 if (side == "next") { 14694 vars.nextPhoto = lastHolder, 14695 vars.prevPhoto = secondHolder, 14696 vars.holder = firstHolder; 14697 14698 vars.nextPhoto.hide(); 14699 14700 vars.next = vars.next + 1, 14701 vars.prev = vars.current, 14702 vars.current = vars.current + 1; 14703 14704 if (opts.infinite) { 14705 if (vars.current > vars.total - 1) vars.current = 0; 14706 if (vars.current == vars.total - 1) vars.next = 0; 14707 if (vars.current == 0) vars.prev = vars.total - 1; 14708 } 14709 14710 iL.createUI(); 14711 14712 if (!iL.items[vars.next]) 14713 vars.nextLock = false; 14714 else 14715 iL.loadContent(iL.items[vars.next], 'next'); 14716 } else { 14717 vars.prevPhoto = lastHolder; 14718 vars.nextPhoto = secondHolder; 14719 vars.holder = firstHolder; 14720 14721 vars.prevPhoto.hide(); 14722 14723 vars.next = vars.current; 14724 vars.current = vars.prev; 14725 vars.prev = vars.current - 1; 14726 14727 if (opts.infinite) { 14728 if (vars.current == vars.total - 1) vars.next = 0; 14729 if (vars.current == 0) vars.prev = vars.total - 1; 14730 } 14731 14732 iL.createUI(); 14733 14734 if (!iL.items[vars.prev]) 14735 vars.prevLock = false; 14736 else 14737 iL.loadContent(iL.items[vars.prev], 'prev'); 14738 } 14739 14740 // Add iframe & video content for current slide 14741 if (['iframe', 'video'].indexOf(iL.items[vars.current].type) !== -1) { 14742 iL.loadContent(iL.items[vars.current], 'current'); 14743 } 14744 14745 if (opts.linkId) setTimeout(function() { 14746 vars.hashLock = false; 14747 }, 55); 14748 14749 // Configure arrow buttons 14750 if (!opts.infinite) { 14751 vars.nextButton.add(vars.prevButton).add(vars.innerPrevButton).add(vars.innerNextButton).removeClass('disabled'); 14752 14753 if (vars.current == 0) 14754 vars.prevButton.add(vars.innerPrevButton).addClass('disabled'); 14755 if (vars.current >= vars.total - 1) 14756 vars.nextButton.add(vars.innerNextButton).addClass('disabled'); 14757 } 14758 14759 iL.repositionPhoto(); 14760 14761 // Reset next cycle timeout 14762 iL.resetCycle(); 14763 14764 //Trigger the onAfterChange callback 14765 if (typeof opts.callback.onAfterChange == 'function') 14766 opts.callback.onAfterChange.call(iL, iL.ui); 14767 }); 14768 14769 top = (path == 'horizontal') ? getPixel(lastHolder, 'top') : ((side == "next") ? parseInt(-(winH / 2) - lastHolder.outerHeight()) : parseInt(top * 2)), 14770 left = (path == 'horizontal') ? ((side == "next") ? parseInt(-(winW / 2) - lastHolder.outerWidth()) : parseInt(left * 2)) : getPixel(lastHolder, 'left'); 14771 14772 lastHolder.css(transform, gpuAcceleration).animate({ 14773 top: top, 14774 left: left, 14775 opacity: opts.styles.nextOpacity 14776 }, switchSpeed, (vars.isSwipe) ? 'easeOutCirc' : 'easeInOutCirc', function() { 14777 lastHolder.css(transform, ''); 14778 }).addClass(secondClass); 14779 } 14780 }, 14781 14782 setCaption: function(obj, target) { 14783 var iL = this, 14784 caption = $('<div class="ilightbox-caption"></div>'); 14785 14786 if (obj.caption) { 14787 caption.html(obj.caption); 14788 $('div.ilightbox-container', target).append(caption); 14789 } 14790 }, 14791 14792 normalizeSocial: function(obj, url) { 14793 var iL = this, 14794 vars = iL.vars, 14795 opts = iL.options, 14796 baseURL = window.location.href; 14797 14798 $.each(obj, function(key, value) { 14799 if (!value) 14800 return true; 14801 14802 var item = key.toLowerCase(), 14803 source, text; 14804 14805 switch (item) { 14806 case 'facebook': 14807 source = "http://www.facebook.com/share.php?v=4&src=bm&u={URL}", 14808 text = "Share on Facebook"; 14809 break; 14810 case 'twitter': 14811 source = "http://twitter.com/home?status={URL}", 14812 text = "Share on Twitter"; 14813 break; 14814 case 'digg': 14815 source = "http://digg.com/submit?phase=2&url={URL}", 14816 text = "Share on Digg"; 14817 break; 14818 case 'reddit': 14819 source = "http://reddit.com/submit?url={URL}", 14820 text = "Share on reddit"; 14821 break; 14822 } 14823 14824 obj[key] = { 14825 URL: value.URL && absolutizeURI(baseURL, value.URL) || opts.linkId && window.location.href || typeof url !== 'string' && baseURL || url && absolutizeURI(baseURL, url) || baseURL, 14826 source: value.source || source || value.URL && absolutizeURI(baseURL, value.URL) || url && absolutizeURI(baseURL, url), 14827 text: value.text || text || "Share on " + key, 14828 width: (typeof(value.width) != 'undefined' && !isNaN(value.width)) ? parseInt(value.width) : 640, 14829 height: value.height || 360 14830 }; 14831 14832 }); 14833 14834 return obj; 14835 }, 14836 14837 setSocial: function(obj, url, target) { 14838 var iL = this, 14839 socialBar = $('<div class="ilightbox-social"></div>'), 14840 buttons = '<ul>'; 14841 14842 obj = iL.normalizeSocial(obj, url); 14843 14844 $.each(obj, function(key, value) { 14845 var item = key.toLowerCase(), 14846 source = value.source.replace(/\{URL\}/g, encodeURIComponent(value.URL).replace(/!/g, '%21').replace(/'/g, '%27').replace(/\(/g, '%28').replace(/\)/g, '%29').replace(/\*/g, '%2A').replace(/%20/g, '+')); 14847 buttons += '<li class="' + key + '"><a href="' + source + '" onclick="javascript:window.open(this.href' + ((value.width <= 0 || value.height <= 0) ? '' : ', \'\', \'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=' + value.height + ',width=' + value.width + ',left=40,top=40\'') + ');return false;" title="' + value.text + '" target="_blank"></a></li>'; 14848 }); 14849 14850 buttons += '</ul>'; 14851 14852 socialBar.html(buttons); 14853 $('div.ilightbox-container', target).append(socialBar); 14854 }, 14855 14856 fullScreenAction: function() { 14857 var iL = this, 14858 vars = iL.vars; 14859 14860 if (fullScreenApi.supportsFullScreen) { 14861 if (fullScreenApi.isFullScreen()) fullScreenApi.cancelFullScreen(document.documentElement); 14862 else fullScreenApi.requestFullScreen(document.documentElement); 14863 } else { 14864 iL.doFullscreen(); 14865 } 14866 }, 14867 14868 doFullscreen: function() { 14869 var iL = this, 14870 vars = iL.vars, 14871 viewport = getViewport(), 14872 opts = iL.options; 14873 14874 if (opts.fullAlone) { 14875 var currentHolder = vars.holder, 14876 current = iL.items[vars.current], 14877 windowWidth = viewport.width, 14878 windowHeight = viewport.height, 14879 elements = [currentHolder, vars.nextPhoto, vars.prevPhoto, vars.nextButton, vars.prevButton, vars.overlay, vars.toolbar, vars.thumbnails, vars.loader], 14880 hideElements = [vars.nextPhoto, vars.prevPhoto, vars.nextButton, vars.prevButton, vars.loader, vars.thumbnails]; 14881 14882 if (!vars.isInFullScreen) { 14883 vars.isInFullScreen = vars.lockKey = vars.lockWheel = vars.lockSwipe = true; 14884 vars.overlay.css({ 14885 opacity: 1 14886 }); 14887 14888 $.each(hideElements, function(i, element) { 14889 element.hide(); 14890 }); 14891 14892 vars.fullScreenButton.attr('title', opts.text.exitFullscreen); 14893 14894 if (opts.fullStretchTypes.indexOf(current.type) != -1) currentHolder.data({
14895 naturalWidthOld: currentHolder.data('naturalWidth'), 14896 naturalHeightOld: currentHolder.data('naturalHeight'), 14897 naturalWidth: windowWidth, 14898 naturalHeight: windowHeight 14899 }); 14900 else { 14901 var viewport = current.options.fullViewPort || opts.fullViewPort || '', 14902 newWidth = windowWidth, 14903 newHeight = windowHeight, 14904 width = currentHolder.data('naturalWidth'), 14905 height = currentHolder.data('naturalHeight'); 14906 14907 if (viewport.toLowerCase() == 'fill') { 14908 newHeight = (newWidth / width) * height; 14909 14910 if (newHeight < windowHeight) { 14911 newWidth = (windowHeight / height) * width, 14912 newHeight = windowHeight; 14913 } 14914 } else if (viewport.toLowerCase() == 'fit') { 14915 var dims = iL.getNewDimenstions(newWidth, newHeight, width, height, true); 14916 14917 newWidth = dims.width, 14918 newHeight = dims.height; 14919 } else if (viewport.toLowerCase() == 'stretch') { 14920 newWidth = newWidth, 14921 newHeight = newHeight; 14922 } else { 14923 var scale = (width > newWidth || height > newHeight) ? true : false, 14924 dims = iL.getNewDimenstions(newWidth, newHeight, width, height, scale); 14925 newWidth = dims.width, 14926 newHeight = dims.height; 14927 } 14928 14929 currentHolder.data({ 14930 naturalWidthOld: currentHolder.data('naturalWidth'), 14931 naturalHeightOld: currentHolder.data('naturalHeight'), 14932 naturalWidth: newWidth, 14933 naturalHeight: newHeight 14934 }); 14935 } 14936 14937 $.each(elements, function(key, val) { 14938 val.addClass('ilightbox-fullscreen'); 14939 }); 14940 14941 //Trigger the onEnterFullScreen callback 14942 if (typeof opts.callback.onEnterFullScreen == 'function') opts.callback.onEnterFullScreen.call(iL, iL.ui); 14943 } else { 14944 vars.isInFullScreen = vars.lockKey = vars.lockWheel = vars.lockSwipe = false; 14945 vars.overlay.css({ 14946 opacity: iL.options.overlay.opacity 14947 }); 14948 14949 $.each(hideElements, function(i, element) { 14950 element.show(); 14951 }); 14952 14953 vars.fullScreenButton.attr('title', opts.text.enterFullscreen); 14954 14955 currentHolder.data({ 14956 naturalWidth: currentHolder.data('naturalWidthOld'), 14957 naturalHeight: currentHolder.data('naturalHeightOld'), 14958 naturalWidthOld: null, 14959 naturalHeightOld: null 14960 }); 14961 14962 $.each(elements, function(key, val) { 14963 val.removeClass('ilightbox-fullscreen'); 14964 }); 14965 14966 //Trigger the onExitFullScreen callback 14967 if (typeof opts.callback.onExitFullScreen == 'function') opts.callback.onExitFullScreen.call(iL, iL.ui); 14968 } 14969 } else { 14970 if (!vars.isInFullScreen) vars.isInFullScreen = true; 14971 else vars.isInFullScreen = false; 14972 } 14973 iL.repositionPhoto(true); 14974 }, 14975 14976 closeAction: function() { 14977 var iL = this, 14978 vars = iL.vars, 14979 opts = iL.options; 14980 14981 $win.unbind('.iLightBox'); 14982 $doc.off('.iLightBox'); 14983 14984 if (vars.isInFullScreen) fullScreenApi.cancelFullScreen(document.documentElement); 14985 14986 $('.ilightbox-overlay, .ilightbox-holder, .ilightbox-thumbnails').off('.iLightBox'); 14987 14988 if (opts.hide.effect) vars.overlay.stop().fadeOut(opts.hide.speed, function() { 14989 vars.overlay.remove(); 14990 vars.BODY.removeClass('ilightbox-noscroll').off('.iLightBox'); 14991 }); 14992 else { 14993 vars.overlay.remove(); 14994 vars.BODY.removeClass('ilightbox-noscroll').off('.iLightBox'); 14995 } 14996 14997 var fadeOuts = [vars.toolbar, vars.holder, vars.nextPhoto, vars.prevPhoto, vars.nextButton, vars.prevButton, vars.loader, vars.thumbnails]; 14998 14999 $.each(fadeOuts, function(i, element) { 15000 element.removeAttr('style').remove(); 15001 }); 15002 15003 vars.dontGenerateThumbs = vars.isInFullScreen = false; 15004 15005 window.iLightBox = null; 15006 15007 if (opts.linkId) { 15008 vars.hashLock = true; 15009 removeHash(); 15010 setTimeout(function() { 15011 vars.hashLock = false; 15012 }, 55); 15013 } 15014 15015 vars.nextButton.add(vars.prevButton).add(vars.innerPrevButton).add(vars.innerNextButton).removeClass('disabled'); 15016 15017 //Trigger the onHide callback 15018 if (typeof opts.callback.onHide == 'function') opts.callback.onHide.call(iL, iL.ui); 15019 }, 15020 15021 repositionPhoto: function() { 15022 var iL = this, 15023 vars = iL.vars, 15024 opts = iL.options, 15025 path = opts.path.toLowerCase(), 15026 viewport = getViewport(), 15027 winWidth = viewport.width, 15028 winHeight = viewport.height; 15029 15030 if (viewport.width < UNCODE.mediaQuery) opts.styles.nextOffsetX = 0; 15031 15032 var thumbsOffsetW = (vars.isInFullScreen && opts.fullAlone || vars.isMobile) ? 0 : ((path == 'horizontal') ? 0 : vars.thumbnails.outerWidth()), 15033 thumbsOffsetH = vars.isMobile ? vars.toolbar.outerHeight() : ((vars.isInFullScreen && opts.fullAlone) ? 0 : ((path == 'horizontal') ? vars.thumbnails.outerHeight() : 0)), 15034 width = (vars.isInFullScreen && opts.fullAlone) ? winWidth : (winWidth - (opts.styles.pageOffsetX)), 15035 height = (vars.isInFullScreen && opts.fullAlone) ? winHeight : (winHeight - (opts.styles.pageOffsetY)), 15036 offsetW = (path == 'horizontal') ? parseInt((iL.items[vars.next] || iL.items[vars.prev]) ? ((opts.styles.nextOffsetX + opts.styles.prevOffsetX)) * 2 : (((width / 10) <= 30) ? 30 : (width / 10))) : parseInt(((width / 10) <= 30) ? 30 : (width / 10)) + thumbsOffsetW, 15037 offsetH = (path == 'horizontal') ? parseInt(((height / 10) <= 30) ? 30 : (height / 10)) + thumbsOffsetH : parseInt((iL.items[vars.next] || iL.items[vars.prev]) ? ((opts.styles.nextOffsetX + opts.styles.prevOffsetX)) * 2 : (((height / 10) <= 30) ? 30 : (height / 10))); 15038 15039 var elObject = { 15040 type: 'current', 15041 width: width, 15042 height: height, 15043 item: iL.items[vars.current], 15044 offsetW: offsetW, 15045 offsetH: offsetH,
15046 thumbsOffsetW: thumbsOffsetW, 15047 thumbsOffsetH: thumbsOffsetH, 15048 animate: arguments.length, 15049 holder: vars.holder 15050 }; 15051 15052 iL.repositionEl(elObject); 15053 15054 if (iL.items[vars.next]) { 15055 elObject = $.extend(elObject, { 15056 type: 'next', 15057 item: iL.items[vars.next], 15058 offsetX: opts.styles.nextOffsetX, 15059 offsetY: opts.styles.nextOffsetY, 15060 holder: vars.nextPhoto 15061 }); 15062 15063 iL.repositionEl(elObject); 15064 } 15065 15066 if (iL.items[vars.prev]) { 15067 elObject = $.extend(elObject, { 15068 type: 'prev', 15069 item: iL.items[vars.prev], 15070 offsetX: opts.styles.nextOffsetX, 15071 offsetY: opts.styles.prevOffsetY, 15072 holder: vars.prevPhoto 15073 }); 15074 15075 iL.repositionEl(elObject); 15076 } 15077 15078 var loaderCss = (path == "horizontal") ? { 15079 left: parseInt((width / 2) - (vars.loader.outerWidth() / 2)) 15080 } : { 15081 top: parseInt((height / 2) - (vars.loader.outerHeight() / 2)) 15082 }; 15083 vars.loader.css(loaderCss); 15084 }, 15085 15086 repositionEl: function(obj) { 15087 var iL = this, 15088 vars = iL.vars, 15089 opts = iL.options, 15090 path = opts.path.toLowerCase(), 15091 widthAvail = (obj.type == 'current') ? ((vars.isInFullScreen && opts.fullAlone) ? obj.width : (obj.width - obj.offsetW)) : (obj.width - obj.offsetW), 15092 heightAvail = (obj.type == 'current') ? ((vars.isInFullScreen && opts.fullAlone) ? obj.height : (obj.height - obj.offsetH)) : (obj.height - obj.offsetH), 15093 itemParent = obj.item, 15094 item = obj.item.options, 15095 holder = obj.holder, 15096 offsetX = obj.offsetX || 0, 15097 offsetY = obj.offsetY || 0, 15098 //Uncode change ##START## 15099 toolbarHeight = $('.ilightbox-inner-toolbar', holder).length ? parseInt( $('.ilightbox-inner-toolbar', holder).outerHeight() ) : 0, 15100 //Uncode change ##END## 15101 thumbsOffsetW = obj.thumbsOffsetW, 15102 thumbsOffsetH = obj.thumbsOffsetH; 15103 15104 if (obj.type == 'current') { 15105 if (typeof item.width == 'number' && item.width) widthAvail = ((vars.isInFullScreen && opts.fullAlone) && (opts.fullStretchTypes.indexOf(itemParent.type) != -1 || item.fullViewPort || opts.fullViewPort)) ? widthAvail : ((item.width > widthAvail) ? widthAvail : item.width); 15106 if (typeof item.height == 'number' && item.height) heightAvail = ((vars.isInFullScreen && opts.fullAlone) && (opts.fullStretchTypes.indexOf(itemParent.type) != -1 || item.fullViewPort || opts.fullViewPort)) ? heightAvail : ((item.height > heightAvail) ? heightAvail : item.height); 15107 } else { 15108 if (typeof item.width == 'number' && item.width) widthAvail = (item.width > widthAvail) ? widthAvail : item.width; 15109 if (typeof item.height == 'number' && item.height) heightAvail = (item.height > heightAvail) ? heightAvail : item.height; 15110 } 15111 15112 15113 //Uncode change ##START## 15114 heightAvail = parseInt(heightAvail - toolbarHeight); 15115 // heightAvail = parseInt(heightAvail - $('.ilightbox-inner-toolbar', holder).outerHeight()); 15116 //Uncode change ##END## 15117 15118 var width = (typeof item.width == 'string' && item.width.indexOf('%') != -1) ? percentToValue(parseInt(item.width.replace('%', '')), obj.width) : holder.data('naturalWidth'), 15119 height = (typeof item.height == 'string' && item.height.indexOf('%') != -1) ? percentToValue(parseInt(item.height.replace('%', '')), obj.height) : holder.data('naturalHeight'); 15120 15121 var dims = ((typeof item.width == 'string' && item.width.indexOf('%') != -1 || typeof item.height == 'string' && item.height.indexOf('%') != -1) ? { 15122 width: width, 15123 height: height 15124 } : iL.getNewDimenstions(widthAvail, heightAvail, width, height)), 15125 newDims = $.extend({}, dims, {}); 15126 15127 if (obj.type == 'prev' || obj.type == 'next') 15128 width = parseInt(dims.width * ((obj.type == 'next') ? opts.styles.nextScale : opts.styles.prevScale)), 15129 height = parseInt(dims.height * ((obj.type == 'next') ? opts.styles.nextScale : opts.styles.prevScale)); 15130 else 15131 width = dims.width, 15132 height = dims.height; 15133 15134 var widthDiff = parseInt((getPixel(holder, 'padding-left') + getPixel(holder, 'padding-right') + getPixel(holder, 'border-left-width') + getPixel(holder, 'border-right-width')) / 2), 15135 heightDiff = parseInt((getPixel(holder, 'padding-top') + getPixel(holder, 'padding-bottom') + getPixel(holder, 'border-top-width') + getPixel(holder, 'border-bottom-width') + ($('.ilightbox-inner-toolbar', holder).outerHeight() || 0)) / 2); 15136 15137 switch (obj.type) { 15138 case 'current': 15139 var top = parseInt((obj.height / 2) - (height / 2) - heightDiff - (thumbsOffsetH / 2)), 15140 left = parseInt((obj.width / 2) - (width / 2) - widthDiff - (thumbsOffsetW / 2)); 15141 break; 15142
15143 case 'next': 15144 var top = (path == 'horizontal') ? parseInt((obj.height / 2) - offsetY - (height / 2) - heightDiff - (thumbsOffsetH / 2)) : parseInt(obj.height - offsetX - heightDiff - (thumbsOffsetH / 2)), 15145 left = (path == 'horizontal') ? parseInt(obj.width - offsetX - widthDiff - (thumbsOffsetW / 2)) : parseInt((obj.width / 2) - (width / 2) - widthDiff - offsetY - (thumbsOffsetW / 2)); 15146 break; 15147 15148 case 'prev': 15149 var top = (path == 'horizontal') ? parseInt((obj.height / 2) - offsetY - (height / 2) - heightDiff - (thumbsOffsetH / 2)) : parseInt(offsetX - heightDiff - height - (thumbsOffsetH / 2)), 15150 left = (path == 'horizontal') ? parseInt(offsetX - widthDiff - width - (thumbsOffsetW / 2)) : parseInt((obj.width / 2) - offsetY - (width / 2) - widthDiff - (thumbsOffsetW / 2)); 15151 break; 15152 } 15153 15154 holder.data('offset', { 15155 top: top, 15156 left: left, 15157 newDims: newDims, 15158 diff: { 15159 W: widthDiff, 15160 H: heightDiff 15161 }, 15162 thumbsOffset: { 15163 W: thumbsOffsetW, 15164 H: thumbsOffsetH 15165 }, 15166 object: obj 15167 }); 15168 15169 var opacityMobile; 15170 if ( isMobile ) { 15171 opacityMobile = { 15172 opacity: 1, 15173 top: top, 15174 left: left 15175 }; 15176 } else { 15177 opacityMobile = { 15178 top: top, 15179 left: left 15180 }; 15181 } 15182 15183 if (obj.animate > 0 && opts.effects.reposition) { 15184 holder.css(transform, gpuAcceleration).stop().animate( 15185 opacityMobile, 15186 opts.effects.repositionSpeed, 'easeOutCirc', function() { 15187 holder.css(transform, ''); 15188 }); 15189 $('div.ilightbox-container', holder).stop().animate({ 15190 width: width, 15191 height: height 15192 }, opts.effects.repositionSpeed, 'easeOutCirc'); 15193 $('div.ilightbox-inner-toolbar', holder).stop().animate({ 15194 width: width 15195 }, opts.effects.repositionSpeed, 'easeOutCirc', function() { 15196 $(this).css('overflow', 'visible'); 15197 }); 15198 } else { 15199 holder.css(opacityMobile); 15200 $('div.ilightbox-container', holder).css({ 15201 width: width, 15202 height: height 15203 }); 15204 $('div.ilightbox-inner-toolbar', holder).css({ 15205 width: width 15206 }); 15207 } 15208 }, 15209 15210 15211 resume: function(priority) { 15212 var iL = this, 15213 vars = iL.vars, 15214 opts = iL.options; 15215 15216 if (!opts.slideshow.pauseTime || opts.controls.slideshow && vars.total <= 1 || priority < vars.isPaused) { 15217 return; 15218 } 15219 15220 vars.isPaused = 0; 15221 15222 if (vars.cycleID) { 15223 vars.cycleID = clearTimeout(vars.cycleID); 15224 } 15225 15226 vars.cycleID = setTimeout(function() { 15227 if (vars.current == vars.total - 1) iL.goTo(0); 15228 else iL.moveTo('next'); 15229 }, opts.slideshow.pauseTime); 15230 }, 15231 15232 pause: function(priority) { 15233 var iL = this, 15234 vars = iL.vars, 15235 opts = iL.options; 15236 15237 if (priority < vars.isPaused) { 15238 return; 15239 } 15240 15241 vars.isPaused = priority || 100; 15242 15243 if (vars.cycleID) { 15244 vars.cycleID = clearTimeout(vars.cycleID); 15245 } 15246 }, 15247 15248 resetCycle: function() { 15249 var iL = this, 15250 vars = iL.vars, 15251 opts = iL.options; 15252 15253 if (opts.controls.slideshow && vars.cycleID && !vars.isPaused) { 15254 iL.resume(); 15255 } 15256 }, 15257 15258 getNewDimenstions: function(width, height, width_old, height_old, thumb) { 15259 var iL = this; 15260 15261 if (!width) factor = height / height_old; 15262 else if (!height) factor = width / width_old; 15263 else factor = min(width / width_old, height / height_old); 15264 15265 if (!thumb) { 15266 if (factor > iL.options.maxScale) factor = iL.options.maxScale; 15267 else if (factor < iL.options.minScale) factor = iL.options.minScale; 15268 } 15269 15270 var final_width = (iL.options.keepAspectRatio) ? round(width_old * factor) : width, 15271 final_height = (iL.options.keepAspectRatio) ? round(height_old * factor) : height; 15272 15273 return { 15274 width: final_width, 15275 height: final_height, 15276 ratio: factor 15277 }; 15278 }, 15279 15280 setOption: function(options) { 15281 var iL = this; 15282 15283 iL.options = $.extend(true, iL.options, options || {}); 15284 iL.refresh(); 15285 }, 15286 15287 availPlugins: function() { 15288 var iL = this, 15289 testEl = document.createElement("video"); 15290 15291 iL.plugins = { 15292 flash: !isMobile, 15293 quicktime: (parseInt(PluginDetect.getVersion("QuickTime")) >= 0) ? true : false, 15294 html5H264: !!(testEl.canPlayType && testEl.canPlayType('video/mp4').replace(/no/, '')), 15295 html5WebM: !!(testEl.canPlayType && testEl.canPlayType('video/webm').replace(/no/, '')), 15296 html5Vorbis: !!(testEl.canPlayType && testEl.canPlayType('video/ogg').replace(/no/, '')), 15297 html5QuickTime: !!(testEl.canPlayType && testEl.canPlayType('video/quicktime').replace(/no/, '')) 15298 }; 15299 }, 15300 15301 addContent: function(element, obj) { 15302 var iL = this, 15303 el; 15304 15305 switch (obj.type) { 15306 case 'video': 15307 var HTML5 = false, 15308 videoType = obj.videoType, 15309 html5video = obj.options.html5video; 15310 15311 if (((videoType == 'video/mp4' || obj.ext == 'mp4' || obj.ext == 'm4v') || html5video.h264) && iL.plugins.html5H264) 15312 obj.ext = 'mp4', 15313 obj.URL = html5video.h264 || obj.URL; 15314 else if (html5video.webm && iL.plugins.html5WebM) 15315 obj.ext = 'webm', 15316 obj.URL = html5video.webm || obj.URL; 15317 else if (html5video.ogg && iL.plugins.html5Vorbis) 15318 obj.ext = 'ogv', 15319 obj.URL = html5video.ogg || obj.URL; 15320 15321 if (iL.plugins.html5H264 && (videoType == 'video/mp4' || obj.ext == 'mp4' || obj.ext == 'm4v')) HTML5 = true, videoType = "video/mp4"; 15322 else if (iL.plugins.html5WebM && (videoType == 'video/webm' || obj.ext == 'webm')) HTML5 = true, videoType = "video/webm"; 15323 else if (iL.plugins.html5Vorbis && (videoType == 'video/ogg' || obj.ext == 'ogv')) HTML5 = true, videoType = "video/ogg"; 15324 else if (iL.plugins.html5QuickTime && (videoType == 'video/quicktime' || obj.ext == 'mov' || obj.ext == 'qt')) HTML5 = true, videoType = "video/quicktime"; 15325 15326 if (HTML5) { 15327 el = $('<video />
15327', { 15328 "width": "100%", 15329 "height": "100%", 15330 "preload": html5video.preload, 15331 "autoplay": html5video.autoplay, 15332 "loop": html5video.loop, 15333 "poster": html5video.poster, 15334 "controls": html5video.controls, 15335 "controlslist": "nodownload" 15336 }).append($('<source />', { 15337 "src": obj.URL, 15338 "type": videoType 15339 })); 15340 } else { 15341 if (!iL.plugins.quicktime) el = $('<span />', { 15342 "class": "ilightbox-alert", 15343 html: iL.options.errors.missingPlugin.replace('{pluginspage}', pluginspages.quicktime).replace('{type}', 'QuickTime') 15344 }); 15345 else { 15346 15347 el = $('<object />', { 15348 "type": "video/quicktime", 15349 "pluginspage": pluginspages.quicktime 15350 }).attr({ 15351 "data": obj.URL, 15352 "width": "100%", 15353 "height": "100%" 15354 }).append($('<param />', { 15355 "name": "src", 15356 "value": obj.URL 15357 })).append($('<param />', { 15358 "name": "autoplay", 15359 "value": "false" 15360 })).append($('<param />', { 15361 "name": "loop", 15362 "value": "false" 15363 })).append($('<param />', { 15364 "name": "scale", 15365 "value": "tofit" 15366 })); 15367 15368 if (browser.msie) el = QT_GenerateOBJECTText(obj.URL, '100%', '100%', '', 'SCALE', 'tofit', 'AUTOPLAY', 'false', 'LOOP', 'false'); 15369 } 15370 } 15371 15372 break; 15373 15374 case 'flash': 15375 if (!iL.plugins.flash) el = $('<span />', { 15376 "class": "ilightbox-alert", 15377 html: iL.options.errors.missingPlugin.replace('{pluginspage}', pluginspages.flash).replace('{type}', 'Adobe Flash player') 15378 }); 15379 else { 15380 var flashvars = "", 15381 i = 0; 15382 15383 if (obj.options.flashvars) $.each(obj.options.flashvars, function(k, v) { 15384 if (i != 0) flashvars += "&"; 15385 flashvars += k + "=" + encodeURIComponent(v); 15386 i++; 15387 }); 15388 else flashvars = null; 15389 15390 el = $('<embed />').attr({ 15391 "type": "application/x-shockwave-flash", 15392 "src": obj.URL, 15393 "width": (typeof obj.options.width == 'number' && obj.options.width && iL.options.minScale == '1' && iL.options.maxScale == '1') ? obj.options.width : "100%", 15394 "height": (typeof obj.options.height == 'number' && obj.options.height && iL.options.minScale == '1' && iL.options.maxScale == '1') ? obj.options.height : "100%", 15395 "quality": "high", 15396 "bgcolor": "#000000", 15397 "play": "true", 15398 "loop": "true", 15399 "menu": "true", 15400 "wmode": "transparent", 15401 "scale": "showall", 15402 "allowScriptAccess": "always", 15403 "allowFullScreen": "true", 15404 "flashvars": flashvars, 15405 "fullscreen": "yes" 15406 }); 15407 } 15408 15409 break; 15410 15411 case 'iframe': 15412 el = $('<iframe />').attr({ 15413 "width": (typeof obj.options.width == 'number' && obj.options.width && iL.options.minScale == '1' && iL.options.maxScale == '1') ? obj.options.width : "100%", 15414 "height": (typeof obj.options.height == 'number' && obj.options.height && iL.options.minScale == '1' && iL.options.maxScale == '1') ? obj.options.height : "100%", 15415 src: obj.URL, 15416 frameborder: 0, 15417 'hspace': 0, 15418 'vspace': 0, 15419 'scrolling': supportTouch ? 'auto' : 'scroll', 15420 'webkitAllowFullScreen': '', 15421 'mozallowfullscreen': '', 15422 'allowFullScreen': '' 15423 }); 15424 15425 break; 15426 15427 case 'inline': 15428 el = $('<div class="ilightbox-wrapper"></div>').html($(obj.URL).clone(true)); 15429 15430 break; 15431 15432 case 'html': 15433 var object = obj.URL, 15434 el; 15435 15436 if (object[0].nodeName) { 15437 el = $('<div class="ilightbox-wrapper"></div>').html(object); 15438 } else { 15439 var dom = $(obj.URL), 15440 html = (dom.selector) ? $('<div>' + dom + '</div>') : dom; 15441 el = $('<div class="ilightbox-wrapper"></div>').html(html); 15442 } 15443 15444 break; 15445 } 15446 15447 $('div.ilightbox-container', element).empty().html(el); 15448 15449 // For fixing Chrome about just playing the video for first time 15450 if (el[0].tagName.toLowerCase() === 'video' && browser.webkit) setTimeout(function() { 15451 var src = el[0].currentSrc + '?' + floor(random() * 30000); 15452 el[0].currentSrc = src; 15453 el[0].src = src; 15454 }); 15455 15456 return el; 15457 }, 15458 15459 ogpRecognition: function(obj, callback) { 15460 var iL = this, 15461 url = obj.URL; 15462 15463 iL.showLoader(); 15464 doAjax(url, function(data) { 15465 iL.hideLoader(); 15466 if (data) { 15467 var object = new Object(); 15468 15469 object.length = false, 15470 object.url = data.url; 15471 15472 if (data.status == 200) { 15473 var result = data.results, 15474 type = result.type, 15475 source = result.source; 15476 15477 object.source = source.src, 15478 object.width = source.width && parseInt(source.width) || 0, 15479 object.height = source.height && parseInt(source.height) || 0, 15480 object.type = type, 15481 object.thumbnail = source.thumbnail || result.images && result.images[0], 15482 object.html5video = result.html5video || {}, 15483 object.length = true; 15484 15485 if (source.type == 'application/x-shockwave-flash') object.type = "flash"; 15486 else if (source.type.indexOf("video/") != -1) object.type = "video"; 15487 else if (source.type.indexOf("/html") != -1) object.type = "iframe"; 15488 else if (source.type.indexOf("image/") != -1) object.type = "image"; 15489 15490 } else if (typeof data.response != 'undefined') 15491 throw data.response; 15492 15493 callback.call(this, object.length ? object : false); 15494 } 15495 }); 15496 }, 15497 15498 hashChangeHandler: function(url) { 15499 var iL = this, 15500 vars = iL.vars, 15501 opts = iL.options, 15502 URL = url || window.location.href, 15503 hash = parseURI(URL).hash, 15504 split = hash.split('/'), 15505 index = split[1]; 15506 15507 if (vars.hashLock || ('#' + opts.linkId != split[0] && hash.length > 1)) return; 15508 15509 if (index) { 15510 var target = split[1] || 0; 15511 if (iL.items[target]) {
15512 var overlay = $('.ilightbox-overlay'); 15513 if (overlay.length && overlay.attr('linkid') == opts.linkId) { 15514 iL.goTo(target); 15515 } else { 15516 iL.itemsObject[target].trigger(ishybrid ? "itap click" : supportTouch ? 'itap' : 'click'); 15517 //iL.goTo(target); 15518 } 15519 } else { 15520 var overlay = $('.ilightbox-overlay'); 15521 if (overlay.length) iL.closeAction(); 15522 } 15523 } else { 15524 var overlay = $('.ilightbox-overlay'); 15525 if (overlay.length) iL.closeAction(); 15526 } 15527 } 15528 }; 15529 15530 /** 15531 * Parse style to pixels. 15532 * 15533 * @param {Object} $element jQuery object with element. 15534 * @param {Property} property CSS property to get the pixels from. 15535 * 15536 * @return {Int} 15537 */ 15538 function getPixel($element, property) { 15539 return parseInt($element.css(property), 10) || 0; 15540 } 15541 15542 /** 15543 * Make sure that number is within the limits. 15544 * 15545 * @param {Number} number 15546 * @param {Number} min 15547 * @param {Number} max 15548 * 15549 * @return {Number} 15550 */ 15551 function within(number, min, max) { 15552 return number < min ? min : number > max ? max : number; 15553 } 15554 15555 /** 15556 * Get viewport/window size (width and height). 15557 * 15558 * @return {Object} 15559 */ 15560 function getViewport() { 15561 var e = window, 15562 a = 'inner'; 15563 if (!('innerWidth' in window)) { 15564 a = 'client'; 15565 e = document.documentElement || document.body; 15566 } 15567 return { 15568 width: e[a + 'Width'], 15569 height: e[a + 'Height'] 15570 } 15571 } 15572 15573 /** 15574 * Remove hash tag from the URL 15575 * 15576 * @return {Void} 15577 */ 15578 function removeHash() { 15579 var scroll = getScrollXY(); 15580 15581 //UNCODE change 15582 //window.location.hash = ""; 15583 history.pushState("", document.title, window.location.pathname + window.location.search); 15584 15585 // Restore the scroll offset, should be flicker free 15586 window.scrollTo(scroll.x, scroll.y); 15587 } 15588 15589 /** 15590 * Do the ajax requests with callback. 15591 * 15592 * @param {String} url 15593 * @param {Function} callback 15594 * 15595 * @return {Void} 15596 */ 15597 function doAjax(url, callback) { 15598 var url = "//ilightbox.net/getSource/jsonp.php?url=" + encodeURIComponent(url).replace(/!/g, '%21').replace(/'/g, '%27').replace(/\(/g, '%28').replace(/\)/g, '%29').replace(/\*/g, '%2A'); 15599 $.ajax({ 15600 url: url, 15601 dataType: 'jsonp' 15602 }); 15603 15604 iLCallback = function(data) { 15605 callback.call(this, data); 15606 }; 15607 } 15608 15609 /** 15610 * Find image from DOM elements 15611 * 15612 * @param {Element} element 15613 * 15614 * @return {Void} 15615 */ 15616 function findImageInElement(element) { 15617 var elements = $('*', element), 15618 imagesArr = new Array(); 15619 15620 elements.each(function() { 15621 var url = "", 15622 element = this; 15623 15624 if ($(element).css("background-image") != "none") { 15625 url = $(element).css("background-image"); 15626 } else if (typeof($(element).attr("src")) != "undefined" && element.nodeName.toLowerCase() == "img") { 15627 url = $(element).attr("src"); 15628 } 15629 15630 if (url.indexOf("gradient") == -1) { 15631 url = url.replace(/url\(\"/g, ""); 15632 url = url.replace(/url\(/g, ""); 15633 url = url.replace(/\"\)/g, ""); 15634 url = url.replace(/\)/g, ""); 15635 15636 var urls = url.split(","); 15637 15638 for (var i = 0; i < urls.length; i++) { 15639 if (urls[i].length > 0 && $.inArray(urls[i], imagesArr) == -1) { 15640 var extra = ""; 15641 if (browser.msie && browser.version < 9) { 15642 extra = "?" + floor(random() * 3000); 15643 } 15644 imagesArr.push(urls[i] + extra); 15645 } 15646 } 15647 } 15648 }); 15649 15650 return imagesArr; 15651 } 15652 15653 /** 15654 * Get file extension. 15655 * 15656 * @param {String} URL 15657 * 15658 * @return {String} 15659 */ 15660 function getExtension(URL) { 15661 if (URL !== null) { 15662 //UNCODE: fix issue to detect media type with query strings 15663 var ext = URL.indexOf('?') !== -1 ? URL.split('?')[0] : URL; 15664 ext = ext.split('.').pop().toLowerCase(); 15665 15666 return ext; 15667 } 15668 } 15669 15670 /** 15671 * Get type via extension. 15672 * 15673 * @param {String} URL 15674 * 15675 * @return {String} 15676 */ 15677 function getTypeByExtension(URL) { 15678 var type, 15679 ext = getExtension(URL); 15680 15681 //Uncode addition ##START## 15682 if (URL == undefined) { 15683 return false; 15684 } 15685 //Uncode addition ##END## 15686 15687 if (extensions.image.indexOf(ext) !== -1) type = 'image'; 15688 else if (extensions.flash.indexOf(ext) !== -1) type = 'flash'; 15689 else if (extensions.video.indexOf(ext) !== -1) type = 'video'; 15690 else if (ext.substring(0, 1) == "#") type = 'inline'; //Uncode addition 15691 else type = 'iframe'; 15692 15693 return type; 15694 } 15695 15696 /** 15697 * Return value from percent of a number. 15698 * 15699 * @param {Number} percent 15700 * @param {Number} total 15701 * 15702 * @return {Number} 15703 */ 15704 function percentToValue(percent, total) { 15705 return parseInt((total / 100) * percent); 15706 } 15707 15708 /** 15709 * A JavaScript equivalent of PHP’s parse_url. 15710 * 15711 * @param {String} url The URL to parse. 15712 * 15713 * @return {Mixed} 15714 */ 15715 function parseURI(url) { 15716 var m = String(url).replace(/^\s+|\s+$/g, '').match(/^([^:\/?#]+:)?(\/\/(?:[^:@]*(?::[^:@]*)?@)?(([^:\/?#]*)(?::(\d*))?))?([^?#]*)(\?[^#]*)?(#[\s\S]*)?/); 15717 // authority = '//' + user + ':' + pass '@' + hostname + ':' port 15718 return (m ? { 15719 href: m[0] || '', 15720 protocol: m[1] || '', 15721 authority: m[2] || '', 15722 host: m[3] || '', 15723 hostname: m[4] || '', 15724 port: m[5] || '', 15725 pathname: m[6] || '', 15726 search: m[7] || '', 15727 hash: m[8] || '' 15728 } : null); 15729 } 15730 15731 /** 15732 * Gets the absolute URI. 15733 * 15734 * @param {String} href The relative URL. 15735 * @param {String} base The base URL. 15736 * 15737 * @return {String} The absolute URL. 15738 */ 15739 function absolutizeURI(base, href) { // RFC 3986 15740 var iL = this; 15741 15742 function removeDotSegments(input) { 15743 var output = []; 15744 input.replace(/^(\.\.?(\/|$))+/, '') 15745 .replace(/\/(\.(\/|$))+/g, '/') 15746 .replace(/\/\.\.$/, '/../') 15747 .replace(/\/?[^\/]*/g, function(p) { 15748 if (p === '/..') { 15749 output.pop(); 15750 } else { 15751 output.push(p); 15752 } 15753 }); 15754 return output.join('').replace(/^\//, input.charAt(0) === '/' ? '/' : ''); 15755 } 15756 15757 href = parseURI(href || ''); 15758 base = parseURI(base || ''); 15759 15760 return !href || !base ? null : (href.protocol || base.protocol) + 15761 (href.protocol || href.authority ? href.authority : base.authority) + 15762 removeDotSegments(href.protocol || href.authority || href.pathname.charAt(0) === '/' ? href.pathname : (href.pathname ? ((base.authority && !base.pathname ? '/' : '') + base.pathname.slice(0, base.pathname.lastIndexOf('/') + 1) + href.pathname) : base.pathname)) + 15763 (href.protocol || href.authority || href.pathname ? href.search : (href.search || base.search)) + 15764 href.hash; 15765 } 15766 15767 /** 15768 * A JavaScript equivalent of PHP’s version_compare. 15769 * 15770 * @param {String} v1 15771 * @param {String} v2 15772 * @param {String} operator
15773 * 15774 * @return {Boolean} 15775 */ 15776 function version_compare(v1, v2, operator) { 15777 this.php_js = this.php_js || {}; 15778 this.php_js.ENV = this.php_js.ENV || {}; 15779 var i = 0, 15780 x = 0, 15781 compare = 0, 15782 vm = { 15783 'dev': -6, 15784 'alpha': -5, 15785 'a': -5, 15786 'beta': -4, 15787 'b': -4, 15788 'RC': -3, 15789 'rc': -3, 15790 '#': -2, 15791 'p': 1, 15792 'pl': 1 15793 }, 15794 prepVersion = function(v) { 15795 v = ('' + v).replace(/[_\-+]/g, '.'); 15796 v = v.replace(/([^.\d]+)/g, '.$1.').replace(/\.{2,}/g, '.'); 15797 return (!v.length ? [-8] : v.split('.')); 15798 }, 15799 numVersion = function(v) { 15800 return !v ? 0 : (isNaN(v) ? vm[v] || -7 : parseInt(v, 10)); 15801 }; 15802 v1 = prepVersion(v1); 15803 v2 = prepVersion(v2); 15804 x = max(v1.length, v2.length); 15805 for (i = 0; i < x; i++) { 15806 if (v1[i] == v2[i]) { 15807 continue; 15808 } 15809 v1[i] = numVersion(v1[i]); 15810 v2[i] = numVersion(v2[i]); 15811 if (v1[i] < v2[i]) { 15812 compare = -1; 15813 break; 15814 } else if (v1[i] > v2[i]) { 15815 compare = 1; 15816 break; 15817 } 15818 } 15819 if (!operator) { 15820 return compare; 15821 } 15822 15823 switch (operator) { 15824 case '>': 15825 case 'gt': 15826 return (compare > 0); 15827 case '>=': 15828 case 'ge': 15829 return (compare >= 0); 15830 case '<=': 15831 case 'le': 15832 return (compare <= 0); 15833 case '==': 15834 case '=': 15835 case 'eq': 15836 return (compare === 0); 15837 case '<>': 15838 case '!=': 15839 case 'ne': 15840 return (compare !== 0); 15841 case '': 15842 case '<': 15843 case 'lt': 15844 return (compare < 0); 15845 default: 15846 return null; 15847 } 15848 } 15849 15850 15851 // Begin the iLightBox plugin 15852 $.fn.iLightBox = function() { 15853 15854 var args = arguments, 15855 opt = ($.isPlainObject(args[0])) ? args[0] : args[1], 15856 items = ($.isArray(args[0]) || typeof args[0] == 'string') ? args[0] : args[1]; 15857 15858 if (!opt) opt = {}; 15859 15860 // Default options. Play carefully. 15861 var options = $.extend(true, { 15862 attr: 'href', 15863 path: 'vertical', 15864 skin: 'dark', 15865 linkId: false, 15866 infinite: false, 15867 startFrom: 0, 15868 randomStart: false, 15869 keepAspectRatio: true, 15870 maxScale: 1, 15871 minScale: .2, 15872 innerToolbar: false, 15873 smartRecognition: false, 15874 mobileOptimizer: true, 15875 fullAlone: true, 15876 fullViewPort: null, 15877 fullStretchTypes: 'flash, video', 15878 overlay: { 15879 blur: true, 15880 opacity: .85 15881 }, 15882 controls: { 15883 arrows: false, 15884 slideshow: false, 15885 toolbar: true, 15886 fullscreen: true, 15887 thumbnail: true, 15888 keyboard: true, 15889 mousewheel: true, 15890 swipe: true 15891 }, 15892 keyboard: { 15893 left: true, // previous 15894 right: true, // next 15895 up: true, // previous 15896 down: true, // next 15897 esc: true, // close 15898 shift_enter: true // fullscreen 15899 }, 15900 show: { 15901 effect: true, 15902 speed: 300, 15903 title: true 15904 }, 15905 hide: { 15906 effect: true, 15907 speed: 300 15908 }, 15909 caption: { 15910 start: true, 15911 show: 'mouseenter', 15912 hide: 'mouseleave' 15913 }, 15914 social: { 15915 start: true, 15916 show: 'mouseenter', 15917 hide: 'mouseleave',
15918 buttons: false 15919 }, 15920 styles: { 15921 pageOffsetX: 0, 15922 pageOffsetY: 0, 15923 nextOffsetX: 45, 15924 nextOffsetY: 0, 15925 nextOpacity: 1, 15926 nextScale: 1, 15927 prevOffsetX: 45, 15928 prevOffsetY: 0, 15929 prevOpacity: 1, 15930 prevScale: 1 15931 }, 15932 thumbnails: { 15933 maxWidth: 120, 15934 maxHeight: 80, 15935 normalOpacity: 1, 15936 activeOpacity: .6 15937 }, 15938 effects: { 15939 reposition: true, 15940 repositionSpeed: 200, 15941 switchSpeed: 500, 15942 loadedFadeSpeed: 180, 15943 fadeSpeed: 200 15944 }, 15945 slideshow: { 15946 pauseTime: 5000, 15947 pauseOnHover: false, 15948 startPaused: true 15949 }, 15950 text: { 15951 close: "Press Esc to close", 15952 enterFullscreen: "Enter Fullscreen (Shift+Enter)", 15953 exitFullscreen: "Exit Fullscreen (Shift+Enter)", 15954 slideShow: "Slideshow", 15955 next: "Next", 15956 previous: "Previous" 15957 }, 15958 errors: { 15959 loadImage: "An error occurred when trying to load photo.", 15960 loadContents: "An error occurred when trying to load contents.", 15961 missingPlugin: "The content your are attempting to view requires the <a href='{pluginspage}' target='_blank'>{type} plugin<\/a>." 15962 }, 15963 ajaxSetup: { 15964 url: '', 15965 beforeSend: function(jqXHR, settings) {}, 15966 cache: false, 15967 complete: function(jqXHR, textStatus) {}, 15968 crossDomain: false, 15969 error: function(jqXHR, textStatus, errorThrown) {}, 15970 success: function(data, textStatus, jqXHR) {}, 15971 global: true, 15972 ifModified: false, 15973 username: null, 15974 password: null, 15975 type: 'GET' 15976 }, 15977 callback: {} 15978 }, opt); 15979 15980 var instant = ($.isArray(items) || typeof items == 'string') ? true : false; 15981 15982 items = $.isArray(items) ? items : new Array(); 15983 15984 if (typeof args[0] == 'string') items[0] = args[0]; 15985 15986 if (version_compare($.fn.jquery, '1.8', '>=')) { 15987 var iLB = new iLightBox($(this), options, items, instant); 15988 return { 15989 close: function() { 15990 iLB.closeAction(); 15991 }, 15992 fullscreen: function() { 15993 iLB.fullScreenAction(); 15994 }, 15995 moveNext: function() { 15996 iLB.moveTo('next'); 15997 }, 15998 movePrev: function() { 15999 iLB.moveTo('prev'); 16000 }, 16001 goTo: function(index) { 16002 iLB.goTo(index); 16003 }, 16004 refresh: function() { 16005 iLB.refresh(); 16006 }, 16007 reposition: function() { 16008 (arguments.length > 0) ? iLB.repositionPhoto(true): iLB.repositionPhoto(); 16009 }, 16010 setOption: function(options) { 16011 iLB.setOption(options); 16012 }, 16013 destroy: function() { 16014 iLB.closeAction(); 16015 iLB.dispatchItemsEvents(); 16016 } 16017 }; 16018 } else { 16019 throw "The jQuery version that was loaded is too old. iLightBox requires jQuery 1.8+"; 16020 } 16021 16022 }; 16023 16024 16025 $.iLightBox = function() { 16026 return $.fn.iLightBox(arguments[0], arguments[1]); 16027 }; 16028 16029 function getScrollXY() { 16030 var scrOfX = 0, 16031 scrOfY = 0; 16032 if (typeof(window.pageYOffset) == 'number') { 16033 //Netscape compliant 16034 scrOfY = window.pageYOffset; 16035 scrOfX = window.pageXOffset; 16036 } else if (document.body && (document.body.scrollLeft || document.body.scrollTop)) { 16037 //DOM compliant 16038 scrOfY = document.body.scrollTop; 16039 scrOfX = document.body.scrollLeft; 16040 } else if (document.documentElement && (document.documentElement.scrollLeft || document.documentElement.scrollTop)) { 16041 //IE6 standards compliant mode 16042 scrOfY = document.documentElement.scrollTop; 16043 scrOfX = document.documentElement.scrollLeft; 16044 } 16045 return { 16046 x: scrOfX, 16047 y: scrOfY 16048 }; 16049 } 16050 16051 (function() { 16052 // add new event shortcuts 16053 $.each(("touchstart touchmove touchend " + 16054 "tap taphold " + 16055 "swipe swipeleft swiperight " + 16056 "scrollstart scrollstop").split(" "), function(i, name) { 16057 16058 $.fn[name] = function(fn) { 16059 return fn ? this.bind(name, fn) : this.trigger(name); 16060 }; 16061 16062 // jQuery < 1.8 16063 // if ($.attrFn) { 16064 // $.attrFn[name] = true; 16065 // } 16066 }); 16067 16068 var tapSettings = { 16069 startEvent: 'touchstart.iTap', 16070 endEvent: 'touchend.iTap' 16071 }; 16072 16073 // tap Event: 16074 $.event.special.itap = { 16075 setup: function() { 16076 16077 var self = this, 16078 $self = $(this), 16079 start, stop; 16080 16081 $self.bind(tapSettings.startEvent, function(event) { 16082 start = getScrollXY(); 16083 16084 $self.one(tapSettings.endEvent, function(event) { 16085 stop = getScrollXY(); 16086 16087 var orgEvent = event || window.event; 16088 event = $.event.fix(orgEvent); 16089 event.type = "itap"; 16090 16091 if ((start && stop) && (start.x == stop.x && start.y == stop.y))($.event.dispatch || $.event.handle).call(self, event); 16092 16093 start = stop = undefined; 16094 }); 16095 }); 16096 }, 16097 16098 teardown: function() { 16099 $(this).unbind(tapSettings.startEvent); 16100 } 16101 }; 16102 }()); 16103 16104 16105 //Fullscreen API 16106 (function() { 16107 fullScreenApi = { 16108 supportsFullScreen: false, 16109 isFullScreen: function() { 16110 return false;
16111 }, 16112 requestFullScreen: function() {}, 16113 cancelFullScreen: function() {}, 16114 fullScreenEventName: '', 16115 prefix: '' 16116 }, 16117 browserPrefixes = 'webkit moz o ms khtml'.split(' '); 16118 16119 // check for native support 16120 if (typeof document.cancelFullScreen != 'undefined') { 16121 fullScreenApi.supportsFullScreen = true; 16122 } else { 16123 // check for fullscreen support by vendor prefix 16124 for (var i = 0, il = browserPrefixes.length; i < il; i++) { 16125 fullScreenApi.prefix = browserPrefixes[i]; 16126 16127 if (typeof document[fullScreenApi.prefix + 'CancelFullScreen'] != 'undefined') { 16128 fullScreenApi.supportsFullScreen = true; 16129 16130 break; 16131 } 16132 } 16133 } 16134 16135 // update methods to do something useful 16136 if (fullScreenApi.supportsFullScreen) { 16137 fullScreenApi.fullScreenEventName = fullScreenApi.prefix + 'fullscreenchange'; 16138 16139 fullScreenApi.isFullScreen = function() { 16140 switch (this.prefix) { 16141 case '': 16142 return document.fullScreen; 16143 case 'webkit': 16144 return document.webkitIsFullScreen; 16145 default: 16146 return document[this.prefix + 'FullScreen']; 16147 } 16148 } 16149 fullScreenApi.requestFullScreen = function(el) { 16150 return (this.prefix === '') ? el.requestFullScreen() : el[this.prefix + 'RequestFullScreen'](); 16151 } 16152 fullScreenApi.cancelFullScreen = function(el) { 16153 return (this.prefix === '') ? document.cancelFullScreen() : document[this.prefix + 'CancelFullScreen'](); 16154 } 16155 } 16156 }()); 16157 16158 // Browser detect 16159 (function() { 16160 function uaMatch(ua) { 16161 ua = ua.toLowerCase(); 16162 16163 var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || 16164 /(webkit)[ \/]([\w.]+)/.exec(ua) || 16165 /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || 16166 /(msie) ([\w.]+)/.exec(ua) || 16167 ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || []; 16168 16169 return { 16170 browser: match[1] || "", 16171 version: match[2] || "0" 16172 }; 16173 } 16174 16175 var matched = uaMatch(navigator.userAgent); 16176 browser = {}; 16177 16178 if (matched.browser) { 16179 browser[matched.browser] = true; 16180 browser.version = matched.version; 16181 } 16182 16183 // Chrome is Webkit, but Webkit is also Safari. 16184 if (browser.chrome) { 16185 browser.webkit = true; 16186 } else if (browser.webkit) { 16187 browser.safari = true; 16188 } 16189 }()); 16190 16191 // Feature detects 16192 (function() { 16193 var prefixes = ['', 'webkit', 'moz', 'ms', 'o']; 16194 var el = document.createElement('div'); 16195 16196 function testProp(prop) { 16197 for (var p = 0, pl = prefixes.length; p < pl; p++) { 16198 var prefixedProp = prefixes[p] ? prefixes[p] + prop.charAt(0).toUpperCase() + prop.slice(1) : prop; 16199 if (el.style[prefixedProp] !== undefined) { 16200 return prefixedProp; 16201 } 16202 } 16203 } 16204 16205 // Global support indicators 16206 transform = testProp('transform') || ''; 16207 gpuAcceleration = testProp('perspective') ? 'translateZ(0) ' : ''; 16208 }()); 16209 16210 16211 /* 16212 PluginDetect v0.7.9 16213 www.pinlady.net/PluginDetect/license/ 16214 [ getVersion onWindowLoaded BetterIE ] 16215 [ Flash QuickTime Shockwave ] 16216 */ 16217 var PluginDetect={version:"0.7.9",name:"PluginDetect",handler:function(c,b,a){return function(){c(b,a)}},openTag:"<",isDefined:function(b){return typeof b!="undefined"},isArray:function(b){return(/array/i).test(Object.prototype.toString.call(b))},isFunc:function(b){return typeof b=="function"},isString:function(b){return typeof b=="string"},isNum:function(b){return typeof b=="number"},isStrNum:function(b){return(typeof b=="string"&&(/\d/).test(b))},getNumRegx:/[\d][\d\.\_,-]*/,splitNumRegx:/[\.\_,-]/g,getNum:function(b,c){var d=this,a=d.isStrNum(b)?(d.isDefined(c)?new RegExp(c):d.getNumRegx).exec(b):null;return a?a[0]:null},compareNums:function(h,f,d){var e=this,c,b,a,g=parseInt;if(e.isStrNum(h)&&e.isStrNum(f)){if(e.isDefined(d)&&d.compareNums){return d.compareNums(h,f)}c=h.split(e.splitNumRegx);b=f.split(e.splitNumRegx);for(a=0;a<min(c.length,b.length);a++){if(g(c[a],10)>g(b[a],10)){return 1}if(g(c[a],10)<g(b[a],10)){return -1}}}return 0},formatNum:function(b,c){var d=this,a,e;if(!d.isStrNum(b)){return null}if(!d.isNum(c)){c=4}c--;e=b.replace(/\s/g,"").split(d.splitNumRegx).concat(["0","0","0","0"]);for(a=0;a<4;a++){if(/^(0+)(.+)$/.test(e[a])){e[a]=RegExp.$2}if(a>c||!(/\d/).test(e[a])){e[a]="0"}}return e.slice(0,4).join(",")},$$hasMimeType:function(a){return function(c){if(!a.isIE&&c){var f,e,b,d=a.isArray(c)?c:(a.isString(c)?[c]:[]);for(b=0;b<d.length;b++){if(a.isString(d[b])&&/[^\s]/.test(d[b])){f=navigator.mimeTypes[d[b]];e=f?f.enabledPlugin:0;if(e&&(e.name||e.description)){return f}}}}return null}},findNavPlugin:function(l,e,c){var j=this,h=new RegExp(l,"i"),d=(!j.isDefined(e)||e)?/\d/:0,k=c?new RegExp(c,"i"):0,a=navigator.plugins,g="",f,b,m;for(f=0;f<a.length;f++){m=a[f].description||g;b=a[f].name||g;if((h.test(m)&&(!d||d.test(RegExp.leftContext+RegExp.rightContext)))||(h.test(b)&&(!d||d.test(RegExp.leftContext+RegExp.rightContext)))){if(!k||!(k.test(m)||k.test(b))){return a[f]}}}return null},getMimeEnabledPlugin:function(k,m,c){var e=this,f,b=new RegExp(m,"i"),h="",g=c?new RegExp(c,"i"):0,a,l,d,j=e.isString(k)?[k]:k;for(d=0;d<j.length;
16217d++){if((f=e.hasMimeType(j[d]))&&(f=f.enabledPlugin)){l=f.description||h;a=f.name||h;if(b.test(l)||b.test(a)){if(!g||!(g.test(l)||g.test(a))){return f}}}}return 0},getPluginFileVersion:function(f,b){var h=this,e,d,g,a,c=-1;if(h.OS>2||!f||!f.version||!(e=h.getNum(f.version))){return b}if(!b){return e}e=h.formatNum(e);b=h.formatNum(b);d=b.split(h.splitNumRegx);g=e.split(h.splitNumRegx);for(a=0;a<d.length;a++){if(c>-1&&a>c&&d[a]!="0"){return b}if(g[a]!=d[a]){if(c==-1){c=a}if(d[a]!="0"){return b}}}return e},AXO:window.ActiveXObject,getAXO:function(a){var f=null,d,b=this,c={};try{f=new b.AXO(a)}catch(d){}return f},convertFuncs:function(f){var a,g,d,b=/^[\$][\$]/,c=this;for(a in f){if(b.test(a)){try{g=a.slice(2);if(g.length>0&&!f[g]){f[g]=f[a](f);delete f[a]}}catch(d){}}}},initObj:function(e,b,d){var a,c;if(e){if(e[b[0]]==1||d){for(a=0;a<b.length;a=a+2){e[b[a]]=b[a+1]}}for(a in e){c=e[a];if(c&&c[b[0]]==1){this.initObj(c,b)}}}},initScript:function(){var d=this,a=navigator,h,i=document,l=a.userAgent||"",j=a.vendor||"",b=a.platform||"",k=a.product||"";d.initObj(d,["$",d]);for(h in d.Plugins){if(d.Plugins[h]){d.initObj(d.Plugins[h],["$",d,"$$",d.Plugins[h]],1)}}d.convertFuncs(d);d.OS=100;if(b){var g=["Win",1,"Mac",2,"Linux",3,"FreeBSD",4,"iPhone",21.1,"iPod",21.2,"iPad",21.3,"Win.*CE",22.1,"Win.*Mobile",22.2,"Pocket\\s*PC",22.3,"",100];for(h=g.length-2;h>=0;h=h-2){if(g[h]&&new RegExp(g[h],"i").test(b)){d.OS=g[h+1];break}}};d.head=i.getElementsByTagName("head")[0]||i.getElementsByTagName("body")[0]||i.body||null;d.isIE=new Function("return/*@cc_on!@*/!1")();d.verIE=d.isIE&&(/MSIE\s*(\d+\.?\d*)/i).test(l)?parseFloat(RegExp.$1,10):null;d.verIEfull=null;d.docModeIE=null;if(d.isIE){var f,n,c=document.createElement("div");try{c.style.behavior="url(#default#clientcaps)";d.verIEfull=(c.getComponentVersion("{89820200-ECBD-11CF-8B85-00AA005B4383}","componentid")).replace(/,/g,".")}catch(f){}n=parseFloat(d.verIEfull||"0",10);d.docModeIE=i.documentMode||((/back/i).test(i.compatMode||"")?5:n)||d.verIE;d.verIE=n||d.docModeIE};d.ActiveXEnabled=false;if(d.isIE){var h,m=["Msxml2.XMLHTTP","Msxml2.DOMDocument","Microsoft.XMLDOM","ShockwaveFlash.ShockwaveFlash","TDCCtl.TDCCtl","Shell.UIHelper","Scripting.Dictionary","wmplayer.ocx"];for(h=0;h<m.length;h++){if(d.getAXO(m[h])){d.ActiveXEnabled=true;break}}};d.isGecko=(/Gecko/i).test(k)&&(/Gecko\s*\/\s*\d/i).test(l);
16217d.verGecko=d.isGecko?d.formatNum((/rv\s*\:\s*([\.\,\d]+)/i).test(l)?RegExp.$1:"0.9"):null;d.isChrome=(/Chrome\s*\/\s*(\d[\d\.]*)/i).test(l);d.verChrome=d.isChrome?d.formatNum(RegExp.$1):null;d.isSafari=((/Apple/i).test(j)||(!j&&!d.isChrome))&&(/Safari\s*\/\s*(\d[\d\.]*)/i).test(l);d.verSafari=d.isSafari&&(/Version\s*\/\s*(\d[\d\.]*)/i).test(l)?d.formatNum(RegExp.$1):null;d.isOpera=(/Opera\s*[\/]?\s*(\d+\.?\d*)/i).test(l);d.verOpera=d.isOpera&&((/Version\s*\/\s*(\d+\.?\d*)/i).test(l)||1)?parseFloat(RegExp.$1,10):null;d.addWinEvent("load",d.handler(d.runWLfuncs,d))},init:function(d){var c=this,b,d,a={status:-3,plugin:0};if(!c.isString(d)){return a}if(d.length==1){c.getVersionDelimiter=d;return a}d=d.toLowerCase().replace(/\s/g,"");b=c.Plugins[d];if(!b||!b.getVersion){return a}a.plugin=b;if(!c.isDefined(b.installed)){b.installed=null;b.version=null;b.version0=null;b.getVersionDone=null;b.pluginName=d}c.garbage=false;if(c.isIE&&!c.ActiveXEnabled&&d!=="java"){a.status=-2;return a}a.status=1;return a},fPush:function(b,a){var c=this;if(c.isArray(a)&&(c.isFunc(b)||(c.isArray(b)&&b.length>0&&c.isFunc(b[0])))){a.push(b)}},callArray:function(b){var c=this,a;if(c.isArray(b)){for(a=0;a<b.length;a++){if(b[a]===null){return}c.call(b[a]);b[a]=null}}},call:function(c){var b=this,a=b.isArray(c)?c.length:-1;if(a>0&&b.isFunc(c[0])){c[0](b,a>1?c[1]:0,a>2?c[2]:0,a>3?c[3]:0)}else{if(b.isFunc(c)){c(b)}}},getVersionDelimiter:",",$$getVersion:function(a){return function(g,d,c){var e=a.init(g),f,b,h={};if(e.status<0){return null};f=e.plugin;if(f.getVersionDone!=1){f.getVersion(null,d,c);if(f.getVersionDone===null){f.getVersionDone=1}}a.cleanup();b=(f.version||f.version0);b=b?b.replace(a.splitNumRegx,a.getVersionDelimiter):b;return b}},cleanup:function(){var a=this;if(a.garbage&&a.isDefined(window.CollectGarbage)){window.CollectGarbage()}},isActiveXObject:function(d,b){var f=this,a=false,g,c='<object width="1" height="1" style="display:none" '+d.getCodeBaseVersion(b)+">"+d.HTML+f.openTag+"/object>";if(!f.head){return a}f.head.insertBefore(document.createElement("object"),f.head.firstChild);f.head.firstChild.outerHTML=c;try{f.head.firstChild.classid=d.classID}catch(g){}try{if(f.head.firstChild.object){a=true}}catch(g){}try{if(a&&f.head.firstChild.readyState<4){f.garbage=true}}catch(g){}f.head.removeChild(f.head.firstChild);return a},codebaseSearch:function(f,b){var c=this;if(!c.ActiveXEnabled||!f){return null}if(f.BIfuncs&&f.BIfuncs.length&&f.BIfuncs[f.BIfuncs.length-1]!==null){c.callArray(f.BIfuncs)}var d,o=f.SEARCH,k={};if(c.isStrNum(b)){if(o.match&&o.min&&c.compareNums(b,o.min)<=0){return true}if(o.match&&o.max&&c.compareNums(b,o.max)>=0){return false}d=c.isActiveXObject(f,b);if(d&&(!o.min||c.compareNums(b,o.min)>0)){o.min=b}if(!d&&(!o.max||c.compareNums(b,o.max)<0)){o.max=b}return d};var e=[0,0,0,0],l=[].concat(o.digits),a=o.min?1:0,j,i,h,g,m,n=function(p,r){var q=[].concat(e);q[p]=r;return c.isActiveXObject(f,q.join(","))};if(o.max){g=o.max.split(c.splitNumRegx);for(j=0;j<g.length;j++){g[j]=parseInt(g[j],10)}if(g[0]<l[0]){l[0]=g[0]}}if(o.min){m=o.min.split(c.splitNumRegx);for(j=0;j<m.length;j++){m[j]=parseInt(m[j],10)}if(m[0]>e[0]){e[0]=m[0]}}if(m&&g){for(j=1;j<m.length;j++){if(m[j-1]!=g[j-1]){break}if(g[j]<l[j]){l[j]=g[j]}if(m[j]>e[j]){e[j]=m[j]}}}if(o.max){for(j=1;j<l.length;j++){if(g[j]>0&&l[j]==0&&l[j-1]<o.digits[j-1]){l[j-1]+=1;break}}};for(j=0;j<l.length;j++){h={};for(i=0;i<20;i++){if(l[j]-e[j]<1){break}d=round((l[j]+e[j])/2);if(h["a"+d]){break}h["a"+d]=1;if(n(j,d)){e[j]=d;a=1}else{l[j]=d}}l[j]=e[j];if(!a&&n(j,e[j])){a=1};if(!a){break}};return a?e.join(","):null},addWinEvent:function(d,c){var e=this,a=window,b;if(e.isFunc(c)){if(a.addEventListener){a.addEventListener(d,c,false)}else{if(a.attachEvent){a.attachEvent("on"+d,c)}else{b=a["on"+d];a["on"+d]=e.winHandler(c,b)}}}},winHandler:function(d,c){return function(){d();if(typeof c=="function"){c()}}},WLfuncs0:[],WLfuncs:[],runWLfuncs:function(a){var b={};a.winLoaded=true;a.callArray(a.WLfuncs0);a.callArray(a.WLfuncs);if(a.onDoneEmptyDiv){a.onDoneEmptyDiv()}},winLoaded:false,$$onWindowLoaded:function(a){return function(b){if(a.winLoaded){a.call(b)}else{a.fPush(b,a.WLfuncs)}}},div:null,divID:"plugindetect",divWidth:50,pluginSize:1,emptyDiv:function(){var d=this,b,h,c,a,f,g;if(d.div&&d.div.childNodes){for(b=d.div.childNodes.length-1;b>=0;b--){c=d.div.childNodes[b];if(c&&c.childNodes){for(h=c.childNodes.length-1;h>=0;h--){g=c.childNodes[h];try{c.removeChild(g)}catch(f){}}}if(c){try{d.div.removeChild(c)}catch(f){}}}}if(!d.div){a=document.getElementById(d.divID);if(a){d.div=a}}if(d.div&&d.div.parentNode){try{d.div.parentNode.removeChild(d.div)}catch(f){}d.div=null}},DONEfuncs:[],onDoneEmptyDiv:function(){var c=this,a,b;if(!c.winLoaded){return}if(c.WLfuncs&&c.WLfuncs.length&&c.WLfuncs[c.WLfuncs.length-1]!==null){return}for(a in c){b=c[a];if(b&&b.funcs){if(b.OTF==3){return}if(b.funcs.length&&b.funcs[b.funcs.length-1]!==null){return}}}for(a=0;a<c.DONEfuncs.length;a++){c.callArray(c.DONEfuncs)}
16217c.emptyDiv()},getWidth:function(c){if(c){var a=c.scrollWidth||c.offsetWidth,b=this;if(b.isNum(a)){return a}}return -1},getTagStatus:function(m,g,a,b){var c=this,f,k=m.span,l=c.getWidth(k),h=a.span,j=c.getWidth(h),d=g.span,i=c.getWidth(d);if(!k||!h||!d||!c.getDOMobj(m)){return -2}if(j<i||l<0||j<0||i<0||i<=c.pluginSize||c.pluginSize<1){return 0}if(l>=i){return -1}try{if(l==c.pluginSize&&(!c.isIE||c.getDOMobj(m).readyState==4)){if(!m.winLoaded&&c.winLoaded){return 1}if(m.winLoaded&&c.isNum(b)){if(!c.isNum(m.count)){m.count=b}if(b-m.count>=10){return 1}}}}catch(f){}return 0},getDOMobj:function(g,a){var f,d=this,c=g?g.span:0,b=c&&c.firstChild?1:0;try{if(b&&a){d.div.focus()}}catch(f){}return b?c.firstChild:null},setStyle:function(b,g){var f=b.style,a,d,c=this;if(f&&g){for(a=0;a<g.length;a=a+2){try{f[g[a]]=g[a+1]}catch(d){}}}},insertDivInBody:function(i,g){var f,c=this,h="pd33993399",b=null,d=g?window.top.document:window.document,a=d.getElementsByTagName("body")[0]||d.body;if(!a){try{d.write('<div id="'+h+'">.'+c.openTag+"/div>");b=d.getElementById(h)}catch(f){}}a=d.getElementsByTagName("body")[0]||d.body;if(a){a.insertBefore(i,a.firstChild);if(b){a.removeChild(b)}}},insertHTML:function(f,b,g,a,k){var l,m=document,j=this,p,o=m.createElement("span"),n,i;var c=["outlineStyle","none","borderStyle","none","padding","0px","margin","0px","visibility","visible"];var h="outline-style:none;border-style:none;padding:0px;margin:0px;visibility:visible;";if(!j.isDefined(a)){a=""}if(j.isString(f)&&(/[^\s]/).test(f)){f=f.toLowerCase().replace(/\s/g,"");p=j.openTag+f+' width="'+j.pluginSize+'" height="'+j.pluginSize+'" ';p+='style="'+h+'display:inline;" ';for(n=0;n<b.length;n=n+2){if(/[^\s]/.test(b[n+1])){p+=b[n]+'="'+b[n+1]+'" '}}p+=">";for(n=0;n<g.length;n=n+2){if(/[^\s]/.test(g[n+1])){p+=j.openTag+'param name="'+g[n]+'" value="'+g[n+1]+'" />'}}p+=a+j.openTag+"/"+f+">"}else{p=a}if(!j.div){i=m.getElementById(j.divID);if(i){j.div=i}else{j.div=m.createElement("div");j.div.id=j.divID}j.setStyle(j.div,c.concat(["width",j.divWidth+"px","height",(j.pluginSize+3)+"px","fontSize",(j.pluginSize+3)+"px","lineHeight",(j.pluginSize+3)+"px","verticalAlign","baseline","display","block"]));if(!i){j.setStyle(j.div,["position","absolute","right","0px","top","0px"]);j.insertDivInBody(j.div)}}if(j.div&&j.div.parentNode){j.setStyle(o,c.concat(["fontSize",(j.pluginSize+3)+"px","lineHeight",(j.pluginSize+3)+"px","verticalAlign","baseline","display","inline"]));try{o.innerHTML=p}catch(l){};try{j.div.appendChild(o)}catch(l){};return{span:o,winLoaded:j.winLoaded,tagName:f,outerHTML:p}}return{span:null,winLoaded:j.winLoaded,tagName:"",outerHTML:p}},Plugins:{quicktime:{mimeType:["video/quicktime","application/x-quicktimeplayer","image/x-macpaint","image/x-quicktime"],progID:"QuickTimeCheckObject.QuickTimeCheck.1",progID0:"QuickTime.QuickTime",classID:"clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B",minIEver:7,HTML:'<param name="src" value="" /><param name="controller" value="false" />',getCodeBaseVersion:function(a){return'codebase="#version='+a+'"'},SEARCH:{min:0,max:0,match:0,digits:[16,128,128,0]},getVersion:function(c){var f=this,d=f.$,a=null,e=null,b;if(!d.isIE){if(d.hasMimeType(f.mimeType)){e=d.OS!=3?d.findNavPlugin("QuickTime.*Plug-?in",0):null;if(e&&e.name){a=d.getNum(e.name)}}}else{if(d.isStrNum(c)){b=c.split(d.splitNumRegx);if(b.length>3&&parseInt(b[3],10)>0){b[3]="9999"}c=b.join(",")}if(d.isStrNum(c)&&d.verIE>=f.minIEver&&f.canUseIsMin()>0){f.installed=f.isMin(c);f.getVersionDone=0;return}f.getVersionDone=1;if(!a&&d.verIE>=f.minIEver){a=f.CDBASE2VER(d.codebaseSearch(f))}if(!a){e=d.getAXO(f.progID);if(e&&e.QuickTimeVersion){a=e.QuickTimeVersion.toString(16);a=parseInt(a.charAt(0),16)+"."+parseInt(a.charAt(1),16)+"."+parseInt(a.charAt(2),16)}}}f.installed=a?1:(e?0:-1);f.version=d.formatNum(a,3)},cdbaseUpper:["7,60,0,0","0,0,0,0"],cdbaseLower:["7,50,0,0",null],cdbase2ver:[function(c,b){var a=b.split(c.$.splitNumRegx);return[a[0],a[1].charAt(0),a[1].charAt(1),a[2]].join(",")},null],CDBASE2VER:function(f){var e=this,c=e.$,b,a=e.cdbaseUpper,d=e.cdbaseLower;
16217if(f){f=c.formatNum(f);for(b=0;b<a.length;b++){if(a[b]&&c.compareNums(f,a[b])<0&&d[b]&&c.compareNums(f,d[b])>=0&&e.cdbase2ver[b]){return e.cdbase2ver[b](e,f)}}}return f},canUseIsMin:function(){var f=this,d=f.$,b,c=f.canUseIsMin,a=f.cdbaseUpper,e=f.cdbaseLower;if(!c.value){c.value=-1;for(b=0;b<a.length;b++){if(a[b]&&d.codebaseSearch(f,a[b])){c.value=1;break}if(e[b]&&d.codebaseSearch(f,e[b])){c.value=-1;break}}}f.SEARCH.match=c.value==1?1:0;return c.value},isMin:function(c){var b=this,a=b.$;return a.codebaseSearch(b,c)?0.7:-1}},flash:{mimeType:"application/x-shockwave-flash",progID:"ShockwaveFlash.ShockwaveFlash",classID:"clsid:D27CDB6E-AE6D-11CF-96B8-444553540000",getVersion:function(){var b=function(i){if(!i){return null}var e=/[\d][\d\,\.\s]*[rRdD]{0,1}[\d\,]*/.exec(i);return e?e[0].replace(/[rRdD\.]/g,",").replace(/\s/g,""):null};var j=this,g=j.$,k,h,l=null,c=null,a=null,f,m,d;if(!g.isIE){m=g.hasMimeType(j.mimeType);if(m){f=g.getDOMobj(g.insertHTML("object",["type",j.mimeType],[],"",j));try{l=g.getNum(f.GetVariable("$version"))}catch(k){}}if(!l){d=m?m.enabledPlugin:null;if(d&&d.description){l=b(d.description)}if(l){l=g.getPluginFileVersion(d,l)}}}else{for(h=15;h>2;h--){c=g.getAXO(j.progID+"."+h);if(c){a=h.toString();break}}if(!c){c=g.getAXO(j.progID)}if(a=="6"){try{c.AllowScriptAccess="always"}catch(k){return"6,0,21,0"}}try{l=b(c.GetVariable("$version"))}catch(k){}if(!l&&a){l=a}}j.installed=l?1:-1;j.version=g.formatNum(l);return true}},shockwave:{mimeType:"application/x-director",progID:"SWCtl.SWCtl",classID:"clsid:166B1BCA-3F9C-11CF-8075-444553540000",getVersion:function(){var a=null,b=null,g,f,d=this,c=d.$;if(!c.isIE){f=c.findNavPlugin("Shockwave\\s*for\\s*Director");if(f&&f.description&&c.hasMimeType(d.mimeType)){a=c.getNum(f.description)}if(a){a=c.getPluginFileVersion(f,a)}}else{try{b=c.getAXO(d.progID).ShockwaveVersion("")}catch(g){}if(c.isString(b)&&b.length>0){a=c.getNum(b)}else{if(c.getAXO(d.progID+".8")){a="8"}else{if(c.getAXO(d.progID+".7")){a="7"}else{if(c.getAXO(d.progID+".1")){a="6"}}}}}d.installed=a?1:-1;d.version=c.formatNum(a)}},zz:0}};PluginDetect.initScript(); 16218 16219 var gArgCountErr='The "%%" function requires an even number of arguments.\nArguments should be in the form "atttributeName", "attributeValue", ...',gTagAttrs=null,gQTGeneratorVersion=1;function AC_QuickTimeVersion(){return gQTGeneratorVersion}function _QTComplain(a,b){b=b.replace("%%",a);alert(b)}function _QTAddAttribute(a,b,c){var d;d=gTagAttrs[a+b];null==d&&(d=gTagAttrs[b]);return null!=d?(0==b.indexOf(a)&&null==c&&(c=b.substring(a.length)),null==c&&(c=b),c+'="'+d+'" '):""}function _QTAddObjectAttr(a,b){if(0==a.indexOf("emb#"))return"";0==a.indexOf("obj#")&&null==b&&(b=a.substring(4));return _QTAddAttribute("obj#",a,b)}function _QTAddEmbedAttr(a,b){if(0==a.indexOf("obj#"))return"";0==a.indexOf("emb#")&&null==b&&(b=a.substring(4));return _QTAddAttribute("emb#",a,b)}function _QTAddObjectParam(a,b){var c,d="",e=b?" />":">";-1==a.indexOf("emb#")&&(c=gTagAttrs["obj#"+a],null==c&&(c=gTagAttrs[a]),0==a.indexOf("obj#")&&(a=a.substring(4)),null!=c&&(d=' <param name="'+a+'" value="'+c+'"'+e+"\n"));return d}function _QTDeleteTagAttrs(){for(var a=0;a<arguments.length;a++){var b=arguments[a];delete gTagAttrs[b];delete gTagAttrs["emb#"+b];delete gTagAttrs["obj#"+b]}}function _QTGenerate(a,b,c){if(4>c.length||0!=c.length%2)return _QTComplain(a,gArgCountErr),"";gTagAttrs=[];gTagAttrs.src=c[0];gTagAttrs.width=c[1];gTagAttrs.height=c[2];gTagAttrs.classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B";gTagAttrs.pluginspage="http://www.apple.com/quicktime/download/";a=c[3];if(null==a||""==a)a="6,0,2,0";gTagAttrs.codebase="http://www.apple.com/qtactivex/qtplugin.cab#version="+a;for(var d,e=4;e<c.length;e+=2)d=c[e].toLowerCase(),a=c[e+1],"name"==d||"id"==d?gTagAttrs.name=a:gTagAttrs[d]=a;c="<object "+_QTAddObjectAttr("classid")+_QTAddObjectAttr("width")+_QTAddObjectAttr("height")+_QTAddObjectAttr("codebase")+_QTAddObjectAttr("name","id")+_QTAddObjectAttr("tabindex")+_QTAddObjectAttr("hspace")+_QTAddObjectAttr("vspace")+_QTAddObjectAttr("border")+_QTAddObjectAttr("align")+_QTAddObjectAttr("class")+_QTAddObjectAttr("title")+_QTAddObjectAttr("accesskey")+_QTAddObjectAttr("noexternaldata")+">\n"+_QTAddObjectParam("src",b);e=" <embed "+_QTAddEmbedAttr("src")+_QTAddEmbedAttr("width")+_QTAddEmbedAttr("height")+_QTAddEmbedAttr("pluginspage")+_QTAddEmbedAttr("name")+_QTAddEmbedAttr("align")+_QTAddEmbedAttr("tabindex");_QTDeleteTagAttrs("src","width","height","pluginspage","classid","codebase","name","tabindex","hspace","vspace","border","align","noexternaldata","class","title","accesskey");for(d in gTagAttrs)a=gTagAttrs[d],null!=a&&(e+=_QTAddEmbedAttr(d),c+=_QTAddObjectParam(d,b));return c+e+"> </embed>\n</object>"}function QT_GenerateOBJECTText(){return _QTGenerate("QT_GenerateOBJECTText",!1,arguments)}; 16220 16221 16222 /* 16223 jQuery hashchange event v1.3 16224 https://github.com/cowboy/jquery-hashchange 16225 Copyright (c) 2010 "Cowboy" Ben Alman 16226 Dual licensed under the MIT and GPL licenses. 16227 */ 16228 (function(){function e(a){a=a||location.href;return"#"+a.replace(/^[^#]*#?(.*)$/,"$1")}var k=document,b,f=$.event.special,p=k.documentMode,m="oniLightBoxHashChange"in window&&(void 0===p||7<p);$.fn.iLightBoxHashChange=function(a){return a?this.bind("iLightBoxHashChange",a):this.trigger("iLightBoxHashChange")};$.fn.iLightBoxHashChange.delay=50;f.iLightBoxHashChange=$.extend(f.iLightBoxHashChange,{setup:function(){if(m)return!1;$(b.start)},teardown:function(){if(m)return!1;$(b.stop)}});b=function(){function a(){var c= 16229 e(),d=f(l);c!==l?(n(l=c,d),$(window).trigger("iLightBoxHashChange")):d!==l&&(location.href=location.href.replace(/#.*/,"")+d);g=setTimeout(a,$.fn.iLightBoxHashChange.delay)}var h={},g,l=e(),b=function(c){return c},n=b,f=b;h.start=function(){g||a()};h.stop=function(){g&&clearTimeout(g);g=void 0};browser.msie&&!m&&function(){var c,d;h.start=function(){c||(d=(d=$.fn.iLightBoxHashChange.src)&&d+e(),c=$('<iframe tabindex="-1" title="empty"/>').hide().one("load",function(){d||n(e());a()}).attr("src",d|| 16230 "javascript:0").insertAfter("body")[0].contentWindow,k.onpropertychange=function(){try{"title"===event.propertyName&&(c.document.title=k.title)}catch(a){}})};h.stop=b;f=function(){return e(c.location.href)};n=function(a,d){var b=c.document,e=$.fn.iLightBoxHashChange.domain;
16230a!==d&&(b.title=k.title,b.open(),e&&b.write('<script>document.domain="'+e+'"\x3c/script>'),b.close(),c.location.hash=a)}}();return h}()})(); 16231 16232 if (!Array.prototype.filter) { 16233 Array.prototype.filter = function(fun /*, thisp */ ) { 16234 "use strict"; 16235 16236 if (this == null) 16237 throw new TypeError(); 16238 16239 var t = Object(this); 16240 var len = t.length >>> 0; 16241 if (typeof fun != "function") 16242 throw new TypeError(); 16243 16244 var res = []; 16245 var thisp = arguments[1]; 16246 for (var i = 0; i < len; i++) { 16247 if (i in t) { 16248 var val = t[i]; // in case fun mutates this 16249 if (fun.call(thisp, val, i, t)) 16250 res.push(val); 16251 } 16252 } 16253 16254 return res; 16255 }; 16256 } 16257 16258 if (!Array.prototype.indexOf) { 16259 Array.prototype.indexOf = function(searchElement, fromIndex) { 16260 var k; 16261 16262 if (this == null) { 16263 throw new TypeError('"this" is null or not defined'); 16264 } 16265 16266 var O = Object(this); 16267 16268 var len = O.length >>> 0; 16269 16270 if (len === 0) { 16271 return -1; 16272 } 16273 16274 var n = +fromIndex || 0; 16275 16276 if (abs(n) === Infinity) { 16277 n = 0; 16278 } 16279 16280 if (n >= len) { 16281 return -1; 16282 } 16283 16284 k = max(n >= 0 ? n : len - abs(n), 0); 16285 16286 while (k < len) { 16287 var kValue; 16288 if (k in O && O[k] === searchElement) { 16289 return k; 16290 } 16291 k++; 16292 } 16293 return -1; 16294 }; 16295 } 16296 16297 if (!Array.prototype.lastIndexOf) { 16298 Array.prototype.lastIndexOf = function(searchElement /*, fromIndex*/ ) { 16299 "use strict"; 16300 16301 if (this == null) 16302 throw new TypeError(); 16303 16304 var t = Object(this); 16305 var len = t.length >>> 0; 16306 if (len === 0) 16307 return -1; 16308 16309 var n = len; 16310 if (arguments.length > 1) { 16311 n = Number(arguments[1]); 16312 if (n != n) 16313 n = 0; 16314 else if (n != 0 && n != (1 / 0) && n != -(1 / 0)) 16315 n = (n > 0 || -1) * floor(abs(n)); 16316 } 16317 16318 var k = n >= 0 ? min(n, len - 1) : len - abs(n); 16319 16320 for (; k >= 0; k--) { 16321 if (k in t && t[k] === searchElement) 16322 return k; 16323 } 16324 return -1; 16325 }; 16326 } 16327})(jQuery, this); 16328 16329/** 16330 * Owl carousel
vendor: 31,483 bytes, lines 16331-17534
16331 * @version 2.0.0-beta.3 16332 * @author Bartosz Wojciechowski 16333 * @license The MIT License (MIT) 16334 * @todo Lazy Load Icon 16335 * @todo prevent animationend bubling 16336 * @todo itemsScaleUp 16337 * @todo Test Zepto 16338 * @todo stagePadding calculate wrong active classes 16339 */ 16340;(function($, window, document, undefined) { 16341 16342 /** 16343 * Creates a carousel. 16344 * @class The Owl Carousel. 16345 * @public 16346 * @param {HTMLElement|jQuery} element - The element to create the carousel for. 16347 * @param {Object} [options] - The options 16348 */ 16349 function Owl(element, options) { 16350 16351 /** 16352 * Current settings for the carousel. 16353 * @public 16354 */ 16355 this.settings = null; 16356 16357 /** 16358 * Current options set by the caller including defaults. 16359 * @public 16360 */ 16361 this.options = $.extend({}, Owl.Defaults, options); 16362 16363 /** 16364 * Plugin element. 16365 * @public 16366 */ 16367 this.$element = $(element); 16368 16369 /** 16370 * Proxied event handlers. 16371 * @protected 16372 */ 16373 this._handlers = {}; 16374 16375 /** 16376 * References to the running plugins of this carousel. 16377 * @protected 16378 */ 16379 this._plugins = {}; 16380 16381 /** 16382 * Currently suppressed events to prevent them from beeing retriggered. 16383 * @protected 16384 */ 16385 this._supress = {}; 16386 16387 /** 16388 * Absolute current position. 16389 * @protected 16390 */ 16391 this._current = null; 16392 16393 /** 16394 * Animation speed in milliseconds. 16395 * @protected 16396 */ 16397 this._speed = null; 16398 16399 /** 16400 * Coordinates of all items in pixel. 16401 * @todo The name of this member is missleading. 16402 * @protected 16403 */ 16404 this._coordinates = []; 16405 16406 /** 16407 * Current breakpoint. 16408 * @todo Real media queries would be nice. 16409 * @protected 16410 */ 16411 this._breakpoint = null; 16412 16413 /** 16414 * Current width of the plugin element. 16415 */ 16416 this._width = null; 16417 16418 /** 16419 * All real items. 16420 * @protected 16421 */ 16422 this._items = []; 16423 16424 /** 16425 * All cloned items. 16426 * @protected 16427 */ 16428 this._clones = []; 16429 16430 /** 16431 * Merge values of all items. 16432 * @todo Maybe this could be part of a plugin. 16433 * @protected 16434 */ 16435 this._mergers = []; 16436 16437 /** 16438 * Widths of all items. 16439 */ 16440 this._widths = []; 16441 16442 /** 16443 * Invalidated parts within the update process. 16444 * @protected 16445 */ 16446 this._invalidated = {}; 16447 16448 /** 16449 * Ordered list of workers for the update process. 16450 * @protected 16451 */ 16452 this._pipe = []; 16453 16454 /** 16455 * Current state information for the drag operation. 16456 * @todo #261 16457 * @protected 16458 */ 16459 this._drag = { 16460 time: null, 16461 target: null, 16462 pointer: null, 16463 stage: { 16464 start: null, 16465 current: null 16466 }, 16467 direction: null 16468 }; 16469 16470 /** 16471 * Current state information and their tags. 16472 * @type {Object} 16473 * @protected 16474 */ 16475 this._states = { 16476 current: {}, 16477 tags: { 16478 'initializing': [ 'busy' ], 16479 'animating': [ 'busy' ], 16480 'dragging': [ 'interacting' ] 16481 } 16482 }; 16483 16484 $.each([ 'onResize', 'onThrottledResize' ], $.proxy(function(i, handler) { 16485 this._handlers[handler] = $.proxy(this[handler], this); 16486 }, this)); 16487 16488 $.each(Owl.Plugins, $.proxy(function(key, plugin) { 16489 this._plugins[key.charAt(0).toLowerCase() + key.slice(1)] 16490 = new plugin(this); 16491 }, this)); 16492 16493 $.each(Owl.Workers, $.proxy(function(priority, worker) { 16494 this._pipe.push({ 16495 'filter': worker.filter, 16496 'run': $.proxy(worker.run, this) 16497 }); 16498 }, this)); 16499 16500 this.setup(); 16501 this.initialize(); 16502 } 16503 16504 /** 16505 * Default options for the carousel. 16506 * @public 16507 */ 16508 Owl.Defaults = { 16509 items: 3, 16510 loop: false, 16511 center: false, 16512 rewind: false, 16513 16514 mouseDrag: true, 16515 touchDrag: true, 16516 pullDrag: true, 16517 freeDrag: false, 16518 16519 margin: 0, 16520 stagePadding: 0, 16521 16522 merge: false, 16523 mergeFit: true, 16524 autoWidth: false, 16525 16526 startPosition: 0, 16527 rtl: false, 16528 16529 smartSpeed: 250, 16530 fluidSpeed: false, 16531 dragEndSpeed: false, 16532 16533 responsive: {}, 16534 responsiveRefreshRate: 200, 16535 responsiveBaseElement: window, 16536 16537 fallbackEasing: 'swing', 16538 16539 info: false, 16540 16541 nestedItemSelector: false, 16542 itemElement: 'div', 16543 stageElement: 'div', 16544 16545 refreshClass: 'owl-refresh', 16546 loadedClass: 'owl-loaded', 16547 loadingClass: 'owl-loading', 16548 rtlClass: 'owl-rtl', 16549 responsiveClass: 'owl-responsive', 16550 dragClass: 'owl-drag', 16551 itemClass: 'owl-item', 16552 stageClass: 'owl-stage', 16553 stageOuterClass: 'owl-stage-outer', 16554 grabClass: 'owl-grab' 16555 }; 16556 16557 /** 16558 * Enumeration for width. 16559 * @public 16560 * @readonly 16561 * @enum {String} 16562 */ 16563 Owl.Width = { 16564 Default: 'default', 16565 Inner: 'inner', 16566 Outer: 'outer' 16567 }; 16568 16569 /** 16570 * Enumeration for types. 16571 * @public 16572 * @readonly 16573 * @enum {String} 16574 */ 16575 Owl.Type = { 16576 Event: 'event', 16577 State: 'state' 16578 }; 16579 16580 /** 16581 * Contains all registered plugins. 16582 * @public 16583 */ 16584 Owl.Plugins = {}; 16585 16586 /** 16587 * List of workers involved in the update process. 16588 */ 16589 Owl.Workers = [ { 16590 filter: [ 'width', 'settings' ], 16591 run: function() { 16592 this._width = (this.$element.closest('.px-gutter').length) ? 12 * Math.ceil(this.$element.width() / 12) : this.$element.width(); 16593 //this._width = (UNCODE.isMobile) ? this.$element.width() : 12 * Math.ceil(this.$element.width() / 12); 16594 } 16595 }, { 16596 filter: [ 'width', 'items', 'settings' ], 16597 run: function(cache) { 16598 cache.current = this._items && this._items[this.relative(this._current)]; 16599 } 16600 }, { 16601 filter: [ 'items', 'settings' ], 16602 run: function() { 16603 this.$stage.children('.cloned').remove(); 16604 } 16605 }, { 16606 filter: [ 'width', 'items', 'settings' ], 16607 run: function(cache) { 16608 var margin = this.settings.margin || '', 16609 grid = !this.settings.autoWidth, 16610 rtl = this.settings.rtl, 16611 css = { 16612 'width': 'auto', 16613 'margin-left': rtl ? margin : '', 16614 'margin-right': rtl ? '' : margin 16615 }; 16616 16617 !grid && this.$stage.children().css(css); 16618 16619 cache.css = css; 16620 } 16621 }, { 16622 filter: [ 'width', 'items', 'settings' ], 16623 run: function(cache) { 16624 //UNCODE edit to fix Chrome stage padding issue 16625 var width = Math.round((this.width() / this.settings.items).toFixed(3) - this.settings.margin), 16626 merge = null, 16627 iterator = this._items.length, 16628 grid = !this.settings.autoWidth, 16629 widths = []; 16630 16631 cache.items = { 16632 merge: false, 16633 width: width 16634 }; 16635 16636 while (iterator--) { 16637 merge = this._mergers[iterator]; 16638 merge = this.settings.mergeFit && Math.min(merge, this.settings.items) || merge; 16639 16640 cache.items.merge = merge > 1 || cache.items.merge; 16641 16642 widths[iterator] = !grid ? this._items[iterator].width() : width * merge; 16643 } 16644 16645 this._widths = widths; 16646 } 16647 }, { 16648 filter: [ 'items', 'settings' ], 16649 run: function() { 16650 var clones = [], 16651 items = this._items, 16652 settings = this.settings, 16653 view = Math.max(settings.items * 2, 4), 16654 size = Math.ceil(items.length / 2) * 2, 16655 repeat = settings.loop && items.length ? settings.rewind ? view : Math.max(view, size) : 0, 16656 append = '', 16657 prepend = ''; 16658 16659 repeat /= 2; 16660 16661 while (repeat--) { 16662 clones.push(this.normalize(clones.length / 2, true)); 16663 append = append + items[clones[clones.length - 1]][0].outerHTML; 16664 clones.push(this.normalize(items.length - 1 - (clones.length - 1) / 2, true)); 16665 prepend = items[clones[clones.length - 1]][0].outerHTML + prepend; 16666 } 16667 16668 this._clones = clones; 16669 16670 // var appendVideo = $(append).find('.uncode-video-container'); 16671 // if (appendVideo.length) { 16672 // appendVideo.attr('data-id', Math.round(Math.random() * 100000)); 16673 // } 16674 // var prependVideo = $(prepend).find('.uncode-video-container'); 16675 // if (prependVideo.length) { 16676 // prependVideo.attr('data-id', Math.round(Math.random() * 100000)); 16677 // } 16678 $(append).addClass('cloned').appendTo(this.$stage); 16679 $(prepend).addClass('cloned').prependTo(this.$stage); 16680 } 16681 }, { 16682 filter: [ 'width', 'items', 'settings' ], 16683 run: function() { 16684 var rtl = this.settings.rtl ? 1 : -1, 16685 size = this._clones.length + this._items.length, 16686 iterator = -1, 16687 previous = 0, 16688 current = 0, 16689 coordinates = []; 16690 16691 while (++iterator < size) { 16692 previous = coordinates[iterator - 1] || 0; 16693 current = this._widths[this.relative(iterator)] + this.settings.margin; 16694 coordinates.push(previous + current * rtl); 16695 } 16696 16697 this._coordinates = coordinates; 16698 } 16699 }, { 16700 filter: [ 'width', 'items', 'settings' ], 16701 run: function() { 16702 var stagePadding = (this._width < 480 && this.settings.stagePadding > 0) ? 41 : (this._width * this.settings.stagePadding) / 200, 16703 padding = stagePadding, 16704 coordinates = this._coordinates, 16705 css = { 16706 'width': Math.ceil(Math.abs(coordinates[coordinates.length - 1])) + padding * 2, 16707 'padding-left': padding || '', 16708 'padding-right': padding || '' 16709 }; 16710 16711 this.$stage.css(css); 16712 } 16713 }, { 16714 filter: [ 'width', 'items', 'settings' ], 16715 run: function(cache) { 16716 var iterator = this._coordinates.length, 16717 grid = !this.settings.autoWidth, 16718 items = this.$stage.children(); 16719 16720 if (grid && cache.items.merge) { 16721 while (iterator--) { 16722 cache.css.width = this._widths[this.relative(iterator)]; 16723 items.eq(iterator).css(cache.css); 16724 } 16725 } else if (grid) { 16726 cache.css.width = cache.items.width; 16727 items.css(cache.css); 16728 } 16729 } 16730 }, { 16731 filter: [ 'items' ], 16732 run: function() { 16733 this._coordinates.length < 1 && this.$stage.removeAttr('style'); 16734 } 16735 }, { 16736 filter: [ 'width', 'items', 'settings' ], 16737 run: function(cache) { 16738 cache.current = cache.current ? this.$stage.children().index(cache.current) : 0; 16739 cache.current = Math.max(this.minimum(), Math.min(this.maximum(), cache.current)); 16740 this.reset(cache.current); 16741 } 16742 }, { 16743 filter: [ 'position' ], 16744 run: function() { 16745 this.animate(this.coordinates(this._current)); 16746 } 16747 }, { 16748 filter: [ 'width', 'position', 'items', 'settings' ], 16749 run: function() { 16750 var stagePadding = (this._width < 480 && this.settings.stagePadding > 0) ? 41 : (this._width * this.settings.stagePadding) / 200, 16751 rtl = this.settings.rtl ? 1 : -1, 16752 padding = this.settings.stagePadding * 2, 16753 begin = this.coordinates(this.current()) + padding, 16754 end = begin + this.width() * rtl, 16755 inner, outer, matches = [], i, n; 16756 16757 for (i = 0, n = this._coordinates.length; i < n; i++) { 16758 inner = this._coordinates[i - 1] || 0; 16759 outer = Math.abs(this._coordinates[i]) + padding * rtl; 16760 16761 if ((this.op(inner, '<=', begin) && (this.op(inner, '>', end))) 16762 || (this.op(outer, '<', begin) && this.op(outer, '>', end))) { 16763 matches.push(i); 16764 } 16765 } 16766 16767 this.$stage.children('.active').removeClass('active'); 16768 this.$stage.children(':eq(' + matches.join('), :eq(') + ')').addClass('active'); 16769 16770 if (this.settings.center) { 16771 this.$stage.children('.center').removeClass('center'); 16772 this.$stage.children().eq(this.current()).addClass('center'); 16773 } 16774 } 16775 } ]; 16776 16777 /** 16778 * Initializes the carousel. 16779 * @protected 16780 */ 16781 Owl.prototype.initialize = function() { 16782 this.enter('initializing'); 16783 this.trigger('initialize'); 16784 16785 this.$element.toggleClass(this.settings.rtlClass, this.settings.rtl); 16786 16787 if (this.settings.autoWidth && !this.is('pre-loading')) { 16788 var imgs, nestedSelector, width; 16789 imgs = this.$element.find('img'); 16790 nestedSelector = this.settings.nestedItemSelector ? '.' + this.settings.nestedItemSelector : undefined; 16791 width = this.$element.children(nestedSelector).width(); 16792 16793 if (imgs.length && width <= 0) { 16794 this.preloadAutoWidthImages(imgs); 16795 } 16796 } 16797 16798 this.$element.addClass(this.options.loadingClass); 16799 16800 // create stage 16801 this.$stage = $('<' + this.settings.stageElement + ' class="' + this.settings.stageClass + '"/>') 16802 .wrap('<div class="' + this.settings.stageOuterClass + '"/>'); 16803 16804 // append stage 16805 this.$element.append(this.$stage.parent()); 16806 16807 // append content 16808 this.replace(this.$element.children().not(this.$stage.parent())); 16809 16810 // check visibility 16811 if (this.$element.is(':visible')) { 16812 // update view 16813 this.refresh(); 16814 } else { 16815 // invalidate width 16816 this.invalidate('width'); 16817 } 16818 16819 this.$element 16820 .removeClass(this.options.loadingClass) 16821 .addClass(this.options.loadedClass); 16822 16823 // register event handlers 16824 this.registerEventHandlers(); 16825 16826 this.leave('initializing'); 16827 this.trigger('initialized'); 16828 }; 16829 16830 /** 16831 * Setups the current settings. 16832 * @todo Remove responsive classes. Why should adaptive designs be brought into IE8? 16833 * @todo Support for media queries by using `matchMedia` would be nice. 16834 * @public 16835 */ 16836 Owl.prototype.setup = function() { 16837 var viewport = this.viewport(), 16838 overwrites = this.options.responsive, 16839 match = -1, 16840 settings = null; 16841 16842 if (!overwrites) { 16843 settings = $.extend({}, this.options); 16844 } else { 16845 $.each(overwrites, function(breakpoint) { 16846 if (breakpoint <= viewport && breakpoint > match) { 16847 match = Number(breakpoint); 16848 } 16849 }); 16850 16851 settings = $.extend({}, this.options, overwrites[match]); 16852 delete settings.responsive; 16853 16854 // responsive class 16855 if (settings.responsiveClass) { 16856 this.$element.attr('class', 16857 this.$element.attr('class').replace(new RegExp('(' + this.options.responsiveClass + '-)\\S+\\s', 'g'), '$1' + match) 16858 ); 16859 } 16860 } 16861 16862 if (this.settings === null || this._breakpoint !== match) { 16863 this.trigger('change', { property: { name: 'settings', value: settings } }); 16864 this._breakpoint = match; 16865 this.settings = settings; 16866 this.invalidate('settings'); 16867 this.trigger('changed', { property: { name: 'settings', value: this.settings } }); 16868 } 16869 }; 16870 16871 /** 16872 * Updates option logic if necessery. 16873 * @protected 16874 */ 16875 Owl.prototype.optionsLogic = function() { 16876 if (this.settings.autoWidth) { 16877 this.settings.stagePadding = false; 16878 this.settings.merge = false; 16879 } 16880 }; 16881 16882 /** 16883 * Prepares an item before add. 16884 * @todo Rename event parameter `content` to `item`. 16885 * @protected 16886 * @returns {jQuery|HTMLElement} - The item container. 16887 */ 16888 Owl.prototype.prepare = function(item, index) { 16889 var event = this.trigger('prepare', { content: item }); 16890 if (!event.data) { 16891 event.data = $('<' + this.settings.itemElement + '/>') 16892 .addClass(this.options.itemClass).attr('data-index', index + 1).append(item) 16893 } 16894 16895 this.trigger('prepared', { content: event.data }); 16896 16897 return event.data; 16898 }; 16899 16900 /** 16901 * Updates the view. 16902 * @public 16903 */ 16904 Owl.prototype.update = function() { 16905 var i = 0, 16906 n = this._pipe.length, 16907 filter = $.proxy(function(p) { return this[p] }, this._invalidated), 16908 cache = {}; 16909 16910 while (i < n) { 16911 if (this._invalidated.all || $.grep(this._pipe[i].filter, filter).length > 0) { 16912 this._pipe[i].run(cache); 16913 } 16914 i++; 16915 } 16916 16917 this._invalidated = {}; 16918 16919 !this.is('valid') && this.enter('valid'); 16920 }; 16921 16922 /** 16923 * Gets the width of the view. 16924 * @public 16925 * @param {Owl.Width} [dimension=Owl.Width.Default] - The dimension to return. 16926 * @returns {Number} - The width of the view in pixel. 16927 */ 16928 Owl.prototype.width = function(dimension) { 16929 dimension = dimension || Owl.Width.Default; 16930 var stagePadding = (this._width < 480 && this.settings.stagePadding > 0) ? 41 : (this._width * this.settings.stagePadding) / 200; 16931 switch (dimension) { 16932 case Owl.Width.Inner: 16933 case Owl.Width.Outer: 16934 return this._width; 16935 default: 16936 return this._width - stagePadding * 2 + this.settings.margin; 16937 } 16938 }; 16939 16940 /** 16941 * Refreshes the carousel primarily for adaptive purposes. 16942 * @public 16943 */ 16944 Owl.prototype.refresh = function() { 16945 this.enter('refreshing'); 16946 this.trigger('refresh'); 16947 16948 this.setup(); 16949 16950 this.optionsLogic(); 16951 16952 this.$element.addClass(this.options.refreshClass); 16953 16954 this.update(); 16955 16956 this.$element.removeClass(this.options.refreshClass); 16957 16958 this.leave('refreshing'); 16959 this.trigger('refreshed'); 16960 }; 16961 16962 /** 16963 * Checks window `resize` event. 16964 * @protected 16965 */ 16966 Owl.prototype.onThrottledResize = function() { 16967 window.clearTimeout(this.resizeTimer); 16968 this.resizeTimer = window.setTimeout(this._handlers.onResize, this.settings.responsiveRefreshRate); 16969 }; 16970 16971 /** 16972 * Checks window `resize` event. 16973 * @protected 16974 */ 16975 Owl.prototype.onResize = function() { 16976 if (!this._items.length) { 16977 return false; 16978 } 16979 16980 if (this._width === this.$element.width()) { 16981 return false; 16982 } 16983 16984 if (!this.$element.is(':visible')) { 16985 return false; 16986 } 16987 16988 this.enter('resizing'); 16989 16990 if (this.trigger('resize').isDefaultPrevented()) { 16991 this.leave('resizing'); 16992 return false; 16993 } 16994 16995 this.invalidate('width'); 16996 16997 this.refresh(); 16998 16999 this.leave('resizing'); 17000 this.trigger('resized'); 17001 }; 17002 17003 /** 17004 * Registers event handlers. 17005 * @todo Check `msPointerEnabled` 17006 * @todo #261 17007 * @protected 17008 */ 17009 Owl.prototype.registerEventHandlers = function() { 17010 if ($.support.transition) { 17011 this.$stage.on($.support.transition.end + '.owl.core', $.proxy(this.onTransitionEnd, this)); 17012 } 17013 17014 if (this.settings.responsive !== false) { 17015 this.on(window, 'resize', this._handlers.onThrottledResize); 17016 } 17017 17018 if (this.settings.mouseDrag) { 17019 this.$element.addClass(this.options.dragClass); 17020 this.$stage.on('mousedown.owl.core', $.proxy(this.onDragStart, this)); 17021 this.$stage.on('dragstart.owl.core selectstart.owl.core', function() { return false }); 17022 } 17023 17024 if (this.settings.touchDrag){ 17025 this.$stage.on('touchstart.owl.core', $.proxy(this.onDragStart, this)); 17026 this.$stage.on('touchcancel.owl.core', $.proxy(this.onDragEnd, this)); 17027 } 17028 }; 17029 17030 /** 17031 * Handles `touchstart` and `mousedown` events. 17032 * @todo Horizontal swipe threshold as option 17033 * @todo #261 17034 * @protected 17035 * @param {Event} event - The event arguments. 17036 */ 17037 Owl.prototype.onDragStart = function(event) { 17038 var stage = null; 17039 17040 if (event.which === 3) { 17041 return; 17042 } 17043 17044 if ($.support.transform) { 17045 stage = this.$stage.css('transform').replace(/.*\(|\)| /g, '').split(','); 17046 stage = { 17047 x: stage[stage.length === 16 ? 12 : 4], 17048 y: stage[stage.length === 16 ? 13 : 5] 17049 }; 17050 } else { 17051 stage = this.$stage.position(); 17052 stage = { 17053 x: this.settings.rtl ? 17054 stage.left + this.$stage.width() - this.width() + this.settings.margin : 17055 stage.left, 17056 y: stage.top 17057 }; 17058 } 17059 17060 if (this.is('animating')) { 17061 $.support.transform ? this.animate(stage.x) : this.$stage.stop() 17062 this.invalidate('position'); 17063 } 17064 17065 this.$element.toggleClass(this.options.grabClass, event.type === 'mousedown'); 17066 17067 this.speed(0); 17068 17069 this._drag.time = new Date().getTime(); 17070 this._drag.target = $(event.target); 17071 this._drag.stage.start = stage; 17072 this._drag.stage.current = stage; 17073 this._drag.pointer = this.pointer(event); 17074 17075 $(document).on('mouseup.owl.core touchend.owl.core', $.proxy(this.onDragEnd, this)); 17076 17077 $(document).one('mousemove.owl.core touchmove.owl.core', $.proxy(function(event) { 17078 var delta = this.difference(this._drag.pointer, this.pointer(event)); 17079 17080 $(document).on('mousemove.owl.core touchmove.owl.core', $.proxy(this.onDragMove, this)); 17081 17082 if (Math.abs(delta.x) < Math.abs(delta.y) && this.is('valid')) { 17083 return; 17084 } 17085 17086 event.preventDefault(); 17087 17088 this.enter('dragging'); 17089 this.trigger('drag'); 17090 }, this)); 17091 }; 17092 17093 /** 17094 * Handles the `touchmove` and `mousemove` events. 17095 * @todo #261 17096 * @protected 17097 * @param {Event} event - The event arguments. 17098 */ 17099 Owl.prototype.onDragMove = function(event) { 17100 var minimum = null, 17101 maximum = null, 17102 pull = null, 17103 delta = this.difference(this._drag.pointer, this.pointer(event)), 17104 stage = this.difference(this._drag.stage.start, delta); 17105 17106 if (!this.is('dragging')) { 17107 return; 17108 } 17109 17110 event.preventDefault(); 17111 17112 if (this.settings.loop) { 17113 minimum = this.coordinates(this.minimum()); 17114 maximum = this.coordinates(this.maximum() + 1) - minimum; 17115 stage.x = (((stage.x - minimum) % maximum + maximum) % maximum) + minimum; 17116 } else { 17117 minimum = this.settings.rtl ? this.coordinates(this.maximum()) : this.coordinates(this.minimum()); 17118 maximum = this.settings.rtl ? this.coordinates(this.minimum()) : this.coordinates(this.maximum()); 17119 pull = this.settings.pullDrag ? -1 * delta.x / 5 : 0; 17120 stage.x = Math.max(Math.min(stage.x, minimum + pull), maximum + pull); 17121 } 17122 17123 this._drag.stage.current = stage; 17124 17125 this.animate(stage.x); 17126 }; 17127 17128 /** 17129 * Handles the `touchend` and `mouseup` events. 17130 * @todo #261 17131 * @todo Threshold for click event 17132 * @protected 17133 * @param {Event} event - The event arguments. 17134 */ 17135 Owl.prototype.onDragEnd = function(event) { 17136 var delta = this.difference(this._drag.pointer, this.pointer(event)), 17137 stage = this._drag.stage.current, 17138 direction = delta.x > 0 ^ this.settings.rtl ? 'left' : 'right'; 17139 17140 $(document).off('.owl.core'); 17141 17142 this.$element.removeClass(this.options.grabClass); 17143 17144 if (delta.x !== 0 && this.is('dragging') || !this.is('valid')) { 17145 this.speed(this.settings.dragEndSpeed || this.settings.smartSpeed); 17146 this.current(this.closest(stage.x, delta.x !== 0 ? direction : this._drag.direction)); 17147 this.invalidate('position'); 17148 this.update(); 17149 17150 this._drag.direction = direction; 17151 17152 if (Math.abs(delta.x) > 3 || new Date().getTime() - this._drag.time > 300) { 17153 this._drag.target.one('click.owl.core', function() { return false; }); 17154 } 17155 } 17156 17157 if (!this.is('dragging')) { 17158 return; 17159 } 17160 17161 this.leave('dragging'); 17162 this.trigger('dragged'); 17163 }; 17164 17165 /** 17166 * Gets absolute position of the closest item for a coordinate. 17167 * @todo Setting `freeDrag` makes `closest` not reusable. See #165. 17168 * @protected 17169 * @param {Number} coordinate - The coordinate in pixel. 17170 * @param {String} direction - The direction to check for the closest item. Ether `left` or `right`. 17171 * @return {Number} - The absolute position of the closest item. 17172 */ 17173 Owl.prototype.closest = function(coordinate, direction) { 17174 var position = -1, 17175 pull = 30, 17176 width = this.width(), 17177 coordinates = this.coordinates(); 17178 17179 if (!this.settings.freeDrag) { 17180 // check closest item 17181 $.each(coordinates, $.proxy(function(index, value) { 17182 if (coordinate > value - pull && coordinate < value + pull) { 17183 position = index; 17184 } else if (this.op(coordinate, '<', value) 17185 && this.op(coordinate, '>', coordinates[index + 1] || value - width)) { 17186 position = direction === 'left' ? index + 1 : index; 17187 } 17188 return position === -1; 17189 }, this)); 17190 } 17191 17192 if (!this.settings.loop) { 17193 // non loop boundries 17194 if (this.op(coordinate, '>', coordinates[this.minimum()])) { 17195 position = coordinate = this.minimum(); 17196 } else if (this.op(coordinate, '<', coordinates[this.maximum()])) { 17197 position = coordinate = this.maximum(); 17198 } 17199 } 17200 17201 return position; 17202 }; 17203 17204 /** 17205 * Animates the stage. 17206 * @todo #270 17207 * @public 17208 * @param {Number} coordinate - The coordinate in pixels. 17209 */ 17210 Owl.prototype.animate = function(coordinate) { 17211 var animate = this.speed() > 0; 17212 17213 this.is('animating') && this.onTransitionEnd(); 17214 17215 if (animate) { 17216 this.enter('animating'); 17217 this.trigger('translate'); 17218 } 17219 17220 if ($.support.transform3d && $.support.transition) { 17221 this.$stage.css({ 17222 transform: 'translate3d(' + coordinate + 'px,0px,0px)', 17223 transition: (this.speed() / 1000) + 's' 17224 }); 17225 } else if (animate) { 17226 this.$stage.animate({ 17227 left: coordinate + 'px' 17228 }, this.speed(), this.settings.fallbackEasing, $.proxy(this.onTransitionEnd, this)); 17229 } else { 17230 this.$stage.css({ 17231 left: coordinate + 'px' 17232 }); 17233 } 17234 }; 17235 17236 /** 17237 * Checks whether the carousel is in a specific state or not. 17238 * @param {String} state - The state to check. 17239 * @returns {Boolean} - The flag which indicates if the carousel is busy. 17240 */ 17241 Owl.prototype.is = function(state) { 17242 return this._states.current[state] && this._states.current[state] > 0; 17243 }; 17244 17245 /** 17246 * Sets the absolute position of the current item. 17247 * @public 17248 * @param {Number} [position] - The new absolute position or nothing to leave it unchanged. 17249 * @returns {Number} - The absolute position of the current item. 17250 */ 17251 Owl.prototype.current = function(position) { 17252 if (position === undefined) { 17253 return this._current; 17254 } 17255 17256 if (this._items.length === 0) { 17257 return undefined; 17258 } 17259 17260 position = this.normalize(position); 17261 17262 if (this._current !== position) { 17263 var event = this.trigger('change', { property: { name: 'position', value: position } }); 17264 17265 if (event.data !== undefined) { 17266 position = this.normalize(event.data); 17267 } 17268 17269 this._current = position; 17270 17271 this.invalidate('position'); 17272 17273 this.trigger('changed', { property: { name: 'position', value: this._current } }); 17274 } 17275 17276 return this._current; 17277 }; 17278 17279 /** 17280 * Invalidates the given part of the update routine. 17281 * @param {String} [part] - The part to invalidate. 17282 * @returns {Array.<String>} - The invalidated parts. 17283 */ 17284 Owl.prototype.invalidate = function(part) { 17285 if ($.type(part) === 'string') { 17286 this._invalidated[part] = true; 17287 this.is('valid') && this.leave('valid'); 17288 } 17289 return $.map(this._invalidated, function(v, i) { return i }); 17290 }; 17291 17292 /** 17293 * Resets the absolute position of the current item. 17294 * @public 17295 * @param {Number} position - The absolute position of the new item. 17296 */ 17297 Owl.prototype.reset = function(position) { 17298 position = this.normalize(position); 17299 17300 if (position === undefined) { 17301 return; 17302 } 17303 17304 this._speed = 0; 17305 this._current = position; 17306 17307 this.suppress([ 'translate', 'translated' ]); 17308 17309 this.animate(this.coordinates(position)); 17310 17311 this.release([ 'translate', 'translated' ]); 17312 }; 17313 17314 /** 17315 * Normalizes an absolute or a relative position of an item. 17316 * @public 17317 * @param {Number} position - The absolute or relative position to normalize. 17318 * @param {Boolean} [relative=false] - Whether the given position is relative or not. 17319 * @returns {Number} - The normalized position. 17320 */ 17321 Owl.prototype.normalize = function(position, relative) { 17322 var n = this._items.length, 17323 m = relative ? 0 : this._clones.length; 17324 17325 if (!$.isNumeric(position) || n < 1) { 17326 position = undefined; 17327 } else if (position < 0 || position >= n + m) { 17328 position = ((position - m / 2) % n + n) % n + m / 2; 17329 } 17330 17331 return position; 17332 }; 17333 17334 /** 17335 * Converts an absolute position of an item into a relative one. 17336 * @public 17337 * @param {Number} position - The absolute position to convert. 17338 * @returns {Number} - The converted position. 17339 */ 17340 Owl.prototype.relative = function(position) { 17341 position -= this._clones.length / 2; 17342 return this.normalize(position, true); 17343 }; 17344 17345 /** 17346 * Gets the maximum position for the current item. 17347 * @public 17348 * @param {Boolean} [relative=false] - Whether to return an absolute position or a relative position. 17349 * @returns {Number} 17350 */ 17351 Owl.prototype.maximum = function(relative) { 17352 var settings = this.settings, 17353 maximum = this._coordinates.length, 17354 boundary = Math.abs(this._coordinates[maximum - 1]) - this._width, 17355 i = -1, j; 17356 17357 if (settings.loop) { 17358 maximum = this._clones.length / 2 + this._items.length - 1; 17359 } else if (settings.autoWidth || settings.merge) { 17360 // binary search 17361 while (maximum - i > 1) { 17362 Math.abs(this._coordinates[j = maximum + i >> 1]) < boundary 17363 ? i = j : maximum = j; 17364 } 17365 } else if (settings.center) { 17366 maximum = this._items.length - 1; 17367 } else { 17368 maximum = this._items.length - settings.items; 17369 } 17370 17371 if (relative) { 17372 maximum -= this._clones.length / 2; 17373 } 17374 17375 return Math.max(maximum, 0); 17376 }; 17377 17378 /** 17379 * Gets the minimum position for the current item. 17380 * @public 17381 * @param {Boolean} [relative=false] - Whether to return an absolute position or a relative position. 17382 * @returns {Number} 17383 */ 17384 Owl.prototype.minimum = function(relative) { 17385 return relative ? 0 : this._clones.length / 2; 17386 }; 17387 17388 /** 17389 * Gets an item at the specified relative position. 17390 * @public 17391 * @param {Number} [position] - The relative position of the item. 17392 * @return {jQuery|Array.<jQuery>} - The item at the given position or all items if no position was given. 17393 */ 17394 Owl.prototype.items = function(position) { 17395 if (position === undefined) { 17396 return this._items.slice(); 17397 } 17398 17399 position = this.normalize(position, true); 17400 return this._items[position]; 17401 }; 17402 17403 /** 17404 * Gets an item at the specified relative position. 17405 * @public 17406 * @param {Number} [position] - The relative position of the item. 17407 * @return {jQuery|Array.<jQuery>} - The item at the given position or all items if no position was given. 17408 */ 17409 Owl.prototype.mergers = function(position) { 17410 if (position === undefined) { 17411 return this._mergers.slice(); 17412 } 17413 17414 position = this.normalize(position, true); 17415 return this._mergers[position]; 17416 }; 17417 17418 /** 17419 * Gets the absolute positions of clones for an item. 17420 * @public 17421 * @param {Number} [position] - The relative position of the item. 17422 * @returns {Array.<Number>} - The absolute positions of clones for the item or all if no position was given. 17423 */ 17424 Owl.prototype.clones = function(position) { 17425 var odd = this._clones.length / 2, 17426 even = odd + this._items.length, 17427 map = function(index) { return index % 2 === 0 ? even + index / 2 : odd - (index + 1) / 2 }; 17428 17429 if (position === undefined) { 17430 return $.map(this._clones, function(v, i) { return map(i) }); 17431 } 17432 17433 return $.map(this._clones, function(v, i) { return v === position ? map(i) : null }); 17434 }; 17435 17436 /** 17437 * Sets the current animation speed. 17438 * @public 17439 * @param {Number} [speed] - The animation speed in milliseconds or nothing to leave it unchanged. 17440 * @returns {Number} - The current animation speed in milliseconds. 17441 */ 17442 Owl.prototype.speed = function(speed) { 17443 if (speed !== undefined) { 17444 this._speed = speed; 17445 } 17446 17447 return this._speed; 17448 }; 17449 17450 /** 17451 * Gets the coordinate of an item. 17452 * @todo The name of this method is missleanding. 17453 * @public 17454 * @param {Number} position - The absolute position of the item within `minimum()` and `maximum()`. 17455 * @returns {Number|Array.<Number>} - The coordinate of the item in pixel or all coordinates. 17456 */ 17457 Owl.prototype.coordinates = function(position) { 17458 var coordinate = null; 17459 17460 if (position === undefined) { 17461 return $.map(this._coordinates, $.proxy(function(coordinate, index) { 17462 return this.coordinates(index); 17463 }, this)); 17464 } 17465 17466 if (this.settings.center) { 17467 coordinate = this._coordinates[position]; 17468 coordinate += (this.width() - coordinate + (this._coordinates[position - 1] || 0)) / 2 * (this.settings.rtl ? -1 : 1); 17469 } else { 17470 coordinate = this._coordinates[position - 1] || 0; 17471 } 17472 17473 return coordinate; 17474 }; 17475 17476 /** 17477 * Calculates the speed for a translation. 17478 * @protected 17479 * @param {Number} from - The absolute position of the start item. 17480 * @param {Number} to - The absolute position of the target item. 17481 * @param {Number} [factor=undefined] - The time factor in milliseconds. 17482 * @returns {Number} - The time in milliseconds for the translation. 17483 */ 17484 Owl.prototype.duration = function(from, to, factor) { 17485 return Math.min(Math.max(Math.abs(to - from), 1), 6) * Math.abs((factor || this.settings.smartSpeed)); 17486 }; 17487 17488 /** 17489 * Slides to the specified item. 17490 * @public 17491 * @param {Number} position - The position of the item. 17492 * @param {Number} [speed] - The time in milliseconds for the transition. 17493 */ 17494 Owl.prototype.to = function(position, speed) { 17495 var current = this.current(), 17496 revert = null, 17497 distance = position - this.relative(current), 17498 direction = (distance > 0) - (distance < 0), 17499 items = this._items.length, 17500 minimum = this.minimum(), 17501 maximum = this.maximum(); 17502 17503 if (this.settings.loop) { 17504 if (!this.settings.rewind && Math.abs(distance) > items / 2) { 17505 distance += direction * -1 * items; 17506 } 17507 17508 position = current + distance; 17509 revert = ((position - minimum) % items + items) % items + minimum; 17510 17511 if (revert !== position && revert - distance <= maximum && revert - distance > 0) { 17512 current = revert - distance; 17513 position = revert; 17514 this.reset(current); 17515 } 17516 } else if (this.settings.rewind) { 17517 maximum += 1; 17518 position = (position % maximum + maximum) % maximum; 17519 } else { 17520 position = Math.max(minimum, Math.min(maximum, position)); 17521 } 17522 17523 this.speed(this.duration(current, position, speed)); 17524 this.current(position); 17525 17526 if (this.$element.is(':visible')) { 17527 this.update(); 17528 } 17529 }; 17530 17531 /** 17532 * Slides to the next item. 17533 * @public 17534 * @param {Number}
vendor: 12,284 bytes, lines 17534-17954
17534 [speed] - The time in milliseconds for the transition. 17535 */ 17536 Owl.prototype.next = function(speed) { 17537 speed = speed || false; 17538 this.to(this.relative(this.current()) + 1, speed); 17539 }; 17540 17541 /** 17542 * Slides to the previous item. 17543 * @public 17544 * @param {Number} [speed] - The time in milliseconds for the transition. 17545 */ 17546 Owl.prototype.prev = function(speed) { 17547 speed = speed || false; 17548 this.to(this.relative(this.current()) - 1, speed); 17549 }; 17550 17551 /** 17552 * Handles the end of an animation. 17553 * @protected 17554 * @param {Event} event - The event arguments. 17555 */ 17556 Owl.prototype.onTransitionEnd = function(event) { 17557 17558 // if css2 animation then event object is undefined 17559 if (event !== undefined) { 17560 event.stopPropagation(); 17561 17562 // Catch only owl-stage transitionEnd event 17563 if ((event.target || event.srcElement || event.originalTarget) !== this.$stage.get(0)) { 17564 return false; 17565 } 17566 } 17567 17568 this.leave('animating'); 17569 this.trigger('translated'); 17570 }; 17571 17572 /** 17573 * Gets viewport width. 17574 * @protected 17575 * @return {Number} - The width in pixel. 17576 */ 17577 Owl.prototype.viewport = function() { 17578 var width; 17579 if (this.options.responsiveBaseElement !== window) { 17580 width = $(this.options.responsiveBaseElement).width(); 17581 } else if (window.innerWidth) { 17582 width = window.innerWidth; 17583 } else if (document.documentElement && document.documentElement.clientWidth) { 17584 width = document.documentElement.clientWidth; 17585 } else { 17586 throw 'Can not detect viewport width.'; 17587 } 17588 17589 return width; 17590 }; 17591 17592 /** 17593 * Replaces the current content. 17594 * @public 17595 * @param {HTMLElement|jQuery|String} content - The new content. 17596 */ 17597 Owl.prototype.replace = function(content) { 17598 this.$stage.empty(); 17599 this._items = []; 17600 17601 if (content) { 17602 content = (content instanceof jQuery) ? content : $(content); 17603 } 17604 17605 if (this.settings.nestedItemSelector) { 17606 content = content.find('.' + this.settings.nestedItemSelector); 17607 } 17608 17609 content.filter(function() { 17610 return this.nodeType === 1; 17611 }).each($.proxy(function(index, item) { 17612 item = this.prepare(item, index); 17613 this.$stage.append(item); 17614 this._items.push(item); 17615 this._mergers.push(item.find('[data-merge]').addBack('[data-merge]').attr('data-merge') * 1 || 1); 17616 }, this)); 17617 17618 this.reset($.isNumeric(this.settings.startPosition) ? this.settings.startPosition : 0); 17619 17620 this.invalidate('items'); 17621 }; 17622 17623 /** 17624 * Adds an item. 17625 * @todo Use `item` instead of `content` for the event arguments. 17626 * @public 17627 * @param {HTMLElement|jQuery|String} content - The item content to add. 17628 * @param {Number} [position] - The relative position at which to insert the item otherwise the item will be added to the end. 17629 */ 17630 Owl.prototype.add = function(content, position) { 17631 var current = this.relative(this._current); 17632 17633 position = position === undefined ? this._items.length : this.normalize(position, true); 17634 content = content instanceof jQuery ? content : $(content); 17635 17636 this.trigger('add', { content: content, position: position }); 17637 17638 content = this.prepare(content, this._items[current].index()); 17639 17640 if (this._items.length === 0 || position === this._items.length) { 17641 this._items.length === 0 && this.$stage.append(content); 17642 this._items.length !== 0 && this._items[position - 1].after(content); 17643 this._items.push(content); 17644 this._mergers.push(content.find('[data-merge]').andSelf('[data-merge]').attr('data-merge') * 1 || 1); 17645 } else { 17646 this._items[position].before(content); 17647 this._items.splice(position, 0, content); 17648 this._mergers.splice(position, 0, content.find('[data-merge]').andSelf('[data-merge]').attr('data-merge') * 1 || 1); 17649 } 17650 17651 this._items[current] && this.reset(this._items[current].index()); 17652 17653 this.invalidate('items'); 17654 17655 this.trigger('added', { content: content, position: position }); 17656 }; 17657 17658 /** 17659 * Removes an item by its position. 17660 * @todo Use `item` instead of `content` for the event arguments. 17661 * @public 17662 * @param {Number} position - The relative position of the item to remove. 17663 */ 17664 Owl.prototype.remove = function(position) { 17665 position = this.normalize(position, true); 17666 17667 if (position === undefined) { 17668 return; 17669 } 17670 17671 this.trigger('remove', { content: this._items[position], position: position }); 17672 17673 this._items[position].remove(); 17674 this._items.splice(position, 1); 17675 this._mergers.splice(position, 1); 17676 17677 this.invalidate('items'); 17678 17679 this.trigger('removed', { content: null, position: position }); 17680 }; 17681 17682 /** 17683 * Preloads images with auto width. 17684 * @todo Replace by a more generic approach 17685 * @protected 17686 */ 17687 Owl.prototype.preloadAutoWidthImages = function(images) { 17688 images.each($.proxy(function(i, element) { 17689 this.enter('pre-loading'); 17690 element = $(element); 17691 $(new Image()).one('load', $.proxy(function(e) { 17692 element.attr('src', e.target.src); 17693 element.css('opacity', 1); 17694 this.leave('pre-loading'); 17695 !this.is('pre-loading') && !this.is('initializing') && this.refresh(); 17696 }, this)).attr('src', element.attr('src') || element.attr('data-src') || element.attr('data-src-retina')); 17697 }, this)); 17698 }; 17699 17700 /** 17701 * Destroys the carousel. 17702 * @public 17703 */ 17704 Owl.prototype.destroy = function() { 17705 17706 this.$element.off('.owl.core'); 17707 this.$stage.off('.owl.core'); 17708 $(document).off('.owl.core'); 17709 17710 if (this.settings.responsive !== false) { 17711 window.clearTimeout(this.resizeTimer); 17712 this.off(window, 'resize', this._handlers.onThrottledResize); 17713 } 17714 17715 for (var i in this._plugins) { 17716 this._plugins[i].destroy(); 17717 } 17718 17719 this.$stage.children('.cloned').remove(); 17720 17721 this.$stage.unwrap(); 17722 this.$stage.children().contents().unwrap(); 17723 this.$stage.children().unwrap(); 17724 17725 this.$element 17726 .removeClass(this.options.refreshClass) 17727 .removeClass(this.options.loadingClass) 17728 .removeClass(this.options.loadedClass) 17729 .removeClass(this.options.rtlClass) 17730 .removeClass(this.options.dragClass) 17731 .removeClass(this.options.grabClass) 17732 .attr('class', this.$element.attr('class').replace(new RegExp(this.options.responsiveClass + '-\\S+\\s', 'g'), '')) 17733 .removeData('owl.carousel'); 17734 }; 17735 17736 /** 17737 * Operators to calculate right-to-left and left-to-right. 17738 * @protected 17739 * @param {Number} [a] - The left side operand. 17740 * @param {String} [o] - The operator. 17741 * @param {Number} [b] - The right side operand. 17742 */ 17743 Owl.prototype.op = function(a, o, b) { 17744 var rtl = this.settings.rtl; 17745 switch (o) { 17746 case '<': 17747 return rtl ? a > b : a < b; 17748 case '>': 17749 return rtl ? a < b : a > b; 17750 case '>=': 17751 return rtl ? a <= b : a >= b; 17752 case '<=': 17753 return rtl ? a >= b : a <= b; 17754 default: 17755 break; 17756 } 17757 }; 17758 17759 /** 17760 * Attaches to an internal event. 17761 * @protected 17762 * @param {HTMLElement} element - The event source. 17763 * @param {String} event - The event name. 17764 * @param {Function} listener - The event handler to attach. 17765 * @param {Boolean} capture - Wether the event should be handled at the capturing phase or not. 17766 */ 17767 Owl.prototype.on = function(element, event, listener, capture) { 17768 if (element.addEventListener) { 17769 element.addEventListener(event, listener, capture); 17770 } else if (element.attachEvent) { 17771 element.attachEvent('on' + event, listener); 17772 } 17773 }; 17774 17775 /** 17776 * Detaches from an internal event. 17777 * @protected 17778 * @param {HTMLElement} element - The event source. 17779 * @param {String} event - The event name. 17780 * @param {Function} listener - The attached event handler to detach. 17781 * @param {Boolean} capture - Wether the attached event handler was registered as a capturing listener or not. 17782 */ 17783 Owl.prototype.off = function(element, event, listener, capture) { 17784 if (element.removeEventListener) { 17785 element.removeEventListener(event, listener, capture); 17786 } else if (element.detachEvent) { 17787 element.detachEvent('on' + event, listener); 17788 } 17789 }; 17790 17791 /** 17792 * Triggers a public event. 17793 * @todo Remove `status`, `relatedTarget` should be used instead. 17794 * @protected 17795 * @param {String} name - The event name. 17796 * @param {*} [data=null] - The event data. 17797 * @param {String} [namespace=carousel] - The event namespace. 17798 * @param {String} [state] - The state which is associated with the event. 17799 * @param {Boolean} [enter=false] - Indicates if the call enters the specified state or not. 17800 * @returns {Event} - The event arguments. 17801 */ 17802 Owl.prototype.trigger = function(name, data, namespace, state, enter) { 17803 var status = { 17804 item: { count: this._items.length, index: this.current() } 17805 }, handler = $.camelCase( 17806 $.grep([ 'on', name, namespace ], function(v) { return v }) 17807 .join('-').toLowerCase() 17808 ), event = $.Event( 17809 [ name, 'owl', namespace || 'carousel' ].join('.').toLowerCase(), 17810 $.extend({ relatedTarget: this }, status, data) 17811 ); 17812 17813 if (!this._supress[name]) { 17814 $.each(this._plugins, function(name, plugin) { 17815 if (plugin.onTrigger) { 17816 plugin.onTrigger(event); 17817 } 17818 }); 17819 17820 this.register({ type: Owl.Type.Event, name: name }); 17821 this.$element.trigger(event); 17822 17823 if (this.settings && typeof this.settings[handler] === 'function') { 17824 this.settings[handler].call(this, event); 17825 } 17826 } 17827 17828 return event; 17829 }; 17830 17831 /** 17832 * Enters a state. 17833 * @param name - The state name. 17834 */ 17835 Owl.prototype.enter = function(name) { 17836 $.each([ name ].concat(this._states.tags[name] || []), $.proxy(function(i, name) { 17837 if (this._states.current[name] === undefined) { 17838 this._states.current[name] = 0; 17839 } 17840 17841 this._states.current[name]++; 17842 }, this)); 17843 }; 17844 17845 /** 17846 * Leaves a state. 17847 * @param name - The state name. 17848 */ 17849 Owl.prototype.leave = function(name) { 17850 $.each([ name ].concat(this._states.tags[name] || []), $.proxy(function(i, name) { 17851 this._states.current[name]--; 17852 }, this)); 17853 }; 17854 17855 /** 17856 * Registers an event or state. 17857 * @public 17858 * @param {Object} object - The event or state to register. 17859 */ 17860 Owl.prototype.register = function(object) { 17861 if (object.type === Owl.Type.Event) { 17862 if (!$.event.special[object.name]) { 17863 $.event.special[object.name] = {}; 17864 } 17865 17866 if (!$.event.special[object.name].owl) { 17867 var _default = $.event.special[object.name]._default; 17868 $.event.special[object.name]._default = function(e) { 17869 if (_default && _default.apply && (!e.namespace || e.namespace.indexOf('owl') === -1)) { 17870 return _default.apply(this, arguments); 17871 } 17872 return e.namespace && e.namespace.indexOf('owl') > -1; 17873 }; 17874 $.event.special[object.name].owl = true; 17875 } 17876 } else if (object.type === Owl.Type.State) { 17877 if (!this._states.tags[object.name]) { 17878 this._states.tags[object.name] = object.tags; 17879 } else { 17880 this._states.tags[object.name] = this._states.tags[object.name].concat(object.tags); 17881 } 17882 17883 this._states.tags[object.name] = $.grep(this._states.tags[object.name], $.proxy(function(tag, i) { 17884 return $.inArray(tag, this._states.tags[object.name]) === i; 17885 }, this)); 17886 } 17887 }; 17888 17889 /** 17890 * Suppresses events. 17891 * @protected 17892 * @param {Array.<String>} events - The events to suppress. 17893 */ 17894 Owl.prototype.suppress = function(events) { 17895 $.each(events, $.proxy(function(index, event) { 17896 this._supress[event] = true; 17897 }, this)); 17898 }; 17899 17900 /** 17901 * Releases suppressed events. 17902 * @protected 17903 * @param {Array.<String>} events - The events to release. 17904 */ 17905 Owl.prototype.release = function(events) { 17906 $.each(events, $.proxy(function(index, event) { 17907 delete this._supress[event]; 17908 }, this)); 17909 }; 17910 17911 /** 17912 * Gets unified pointer coordinates from event. 17913 * @todo #261 17914 * @protected 17915 * @param {Event} - The `mousedown` or `touchstart` event. 17916 * @returns {Object} - Contains `x` and `y` coordinates of current pointer position. 17917 */ 17918 Owl.prototype.pointer = function(event) { 17919 var result = { x: null, y: null }; 17920 17921 event = event.originalEvent || event || window.event; 17922 17923 event = event.touches && event.touches.length ? 17924 event.touches[0] : event.changedTouches && event.changedTouches.length ? 17925 event.changedTouches[0] : event; 17926 17927 if (event.pageX) { 17928 result.x = event.pageX; 17929 result.y = event.pageY; 17930 } else { 17931 result.x = event.clientX; 17932 result.y = event.clientY; 17933 } 17934 17935 return result; 17936 }; 17937 17938 /** 17939 * Gets the difference of two vectors. 17940 * @todo #261 17941 * @protected 17942 * @param {Object} - The first vector. 17943 * @param {Object} - The second vector. 17944 * @returns {Object} - The difference. 17945 */ 17946 Owl.prototype.difference = function(first, second) { 17947 return { 17948 x: first.x - second.x, 17949 y: first.y - second.y 17950 }; 17951 }; 17952 17953 /** 17954 * The jQuery Plugin for the Owl Carousel
vendor: 32,216 bytes, lines 17955-19237
17955 * @todo Navigation plugin `next` and `prev` 17956 * @public 17957 */ 17958 $.fn.owlCarousel = function(option) { 17959 var args = Array.prototype.slice.call(arguments, 1); 17960 17961 return this.each(function() { 17962 var $this = $(this), 17963 data = $this.data('owl.carousel'); 17964 17965 if (!data) { 17966 data = new Owl(this, typeof option == 'object' && option); 17967 $this.data('owl.carousel', data); 17968 17969 $.each([ 17970 'next', 'prev', 'to', 'destroy', 'refresh', 'replace', 'add', 'remove' 17971 ], function(i, event) { 17972 data.register({ type: Owl.Type.Event, name: event }); 17973 data.$element.on(event + '.owl.carousel.core', $.proxy(function(e) { 17974 if (e.namespace && e.relatedTarget !== this) { 17975 this.suppress([ event ]); 17976 data[event].apply(this, [].slice.call(arguments, 1)); 17977 this.release([ event ]); 17978 } 17979 }, data)); 17980 }); 17981 } 17982 17983 if (typeof option == 'string' && option.charAt(0) !== '_') { 17984 data[option].apply(data, args); 17985 } 17986 }); 17987 }; 17988 17989 /** 17990 * The constructor for the jQuery Plugin 17991 * @public 17992 */ 17993 $.fn.owlCarousel.Constructor = Owl; 17994 17995})(window.Zepto || window.jQuery, window, document); 17996 17997/** 17998 * AutoRefresh Plugin 17999 * @version 2.0.0-beta.3 18000 * @author Artus Kolanowski 18001 * @license The MIT License (MIT) 18002 */ 18003;(function($, window, document, undefined) { 18004 18005 /** 18006 * Creates the auto refresh plugin. 18007 * @class The Auto Refresh Plugin 18008 * @param {Owl} carousel - The Owl Carousel 18009 */ 18010 var AutoRefresh = function(carousel) { 18011 /** 18012 * Reference to the core. 18013 * @protected 18014 * @type {Owl} 18015 */ 18016 this._core = carousel; 18017 18018 /** 18019 * Refresh interval. 18020 * @protected 18021 * @type {number} 18022 */ 18023 this._interval = null; 18024 18025 /** 18026 * Whether the element is currently visible or not. 18027 * @protected 18028 * @type {Boolean} 18029 */ 18030 this._visible = null; 18031 18032 /** 18033 * All event handlers. 18034 * @protected 18035 * @type {Object} 18036 */ 18037 this._handlers = { 18038 'initialized.owl.carousel': $.proxy(function(e) { 18039 if (e.namespace && this._core.settings.autoRefresh) { 18040 this.watch(); 18041 } 18042 }, this) 18043 }; 18044 18045 // set default options 18046 this._core.options = $.extend({}, AutoRefresh.Defaults, this._core.options); 18047 18048 // register event handlers 18049 this._core.$element.on(this._handlers); 18050 }; 18051 18052 /** 18053 * Default options. 18054 * @public 18055 */ 18056 AutoRefresh.Defaults = { 18057 autoRefresh: true, 18058 autoRefreshInterval: 500 18059 }; 18060 18061 /** 18062 * Watches the element. 18063 */ 18064 AutoRefresh.prototype.watch = function() { 18065 if (this._interval) { 18066 return; 18067 } 18068 18069 this._visible = this._core.$element.is(':visible'); 18070 this._interval = window.setInterval($.proxy(this.refresh, this), this._core.settings.autoRefreshInterval); 18071 }; 18072 18073 /** 18074 * Refreshes the element. 18075 */ 18076 AutoRefresh.prototype.refresh = function() { 18077 if (this._core.$element.is(':visible') === this._visible) { 18078 return; 18079 } 18080 18081 this._visible = !this._visible; 18082 18083 this._core.$element.toggleClass('owl-hidden', !this._visible); 18084 18085 this._visible && (this._core.invalidate('width') && this._core.refresh()); 18086 }; 18087 18088 /** 18089 * Destroys the plugin. 18090 */ 18091 AutoRefresh.prototype.destroy = function() { 18092 var handler, property; 18093 18094 window.clearInterval(this._interval); 18095 18096 for (handler in this._handlers) { 18097 this._core.$element.off(handler, this._handlers[handler]); 18098 } 18099 for (property in Object.getOwnPropertyNames(this)) { 18100 typeof this[property] != 'function' && (this[property] = null); 18101 } 18102 }; 18103 18104 $.fn.owlCarousel.Constructor.Plugins.AutoRefresh = AutoRefresh; 18105 18106})(window.Zepto || window.jQuery, window, document); 18107 18108/** 18109 * Lazy Plugin 18110 * @version 2.0.0-beta.3 18111 * @author Bartosz Wojciechowski 18112 * @license The MIT License (MIT) 18113 */ 18114;(function($, window, document, undefined) { 18115 18116 /** 18117 * Creates the lazy plugin. 18118 * @class The Lazy Plugin 18119 * @param {Owl} carousel - The Owl Carousel 18120 */ 18121 var Lazy = function(carousel) { 18122 18123 /** 18124 * Reference to the core. 18125 * @protected 18126 * @type {Owl} 18127 */ 18128 this._core = carousel; 18129 18130 /** 18131 * Already loaded items. 18132 * @protected 18133 * @type {Array.<jQuery>} 18134 */ 18135 this._loaded = []; 18136 18137 /** 18138 * Event handlers. 18139 * @protected 18140 * @type {Object} 18141 */ 18142 this._handlers = { 18143 'initialized.owl.carousel change.owl.carousel': $.proxy(function(e) { 18144 if (!e.namespace) { 18145 return; 18146 } 18147 18148 if (!this._core.settings || !this._core.settings.lazyLoad) { 18149 return; 18150 } 18151 18152 if ((e.property && e.property.name == 'position') || e.type == 'initialized') { 18153 var settings = this._core.settings, 18154 n = (settings.center && Math.ceil(settings.items / 2) || settings.items), 18155 i = ((settings.center && n * -1) || 0), 18156 position = ((e.property && e.property.value) || this._core.current()) + i, 18157 clones = this._core.clones().length, 18158 load = $.proxy(function(i, v) { this.load(v) }, this); 18159 18160 while (i++ < n) { 18161 this.load(clones / 2 + this._core.relative(position)); 18162 clones && $.each(this._core.clones(this._core.relative(position)), load); 18163 position++; 18164 } 18165 } 18166 }, this) 18167 }; 18168 18169 // set the default options 18170 this._core.options = $.extend({}, Lazy.Defaults, this._core.options); 18171 18172 // register event handler 18173 this._core.$element.on(this._handlers); 18174 } 18175 18176 /** 18177 * Default options. 18178 * @public 18179 */ 18180 Lazy.Defaults = { 18181 lazyLoad: false 18182 } 18183 18184 /** 18185 * Loads all resources of an item at the specified position. 18186 * @param {Number} position - The absolute position of the item. 18187 * @protected 18188 */ 18189 Lazy.prototype.load = function(position) { 18190 var $item = this._core.$stage.children().eq(position), 18191 $elements = $item && $item.find('.owl-lazy'); 18192 18193 if (!$elements || $.inArray($item.get(0), this._loaded) > -1) { 18194 return; 18195 } 18196 18197 $elements.each($.proxy(function(index, element) { 18198 var $element = $(element), image, 18199 url = (window.devicePixelRatio > 1 && $element.attr('data-src-retina')) || $element.attr('data-src'); 18200 18201 this._core.trigger('load', { element: $element, url: url }, 'lazy'); 18202 18203 if ($element.is('img')) { 18204 $element.one('load.owl.lazy', $.proxy(function() { 18205 $element.css('opacity', 1); 18206 this._core.trigger('loaded', { element: $element, url: url }, 'lazy'); 18207 }, this)).attr('src', url); 18208 } else { 18209 image = new Image(); 18210 image.onload = $.proxy(function() { 18211 $element.css({ 18212 'background-image': 'url(' + url + ')', 18213 'opacity': '1' 18214 }); 18215 this._core.trigger('loaded', { element: $element, url: url }, 'lazy'); 18216 }, this); 18217 image.src = url; 18218 } 18219 }, this)); 18220 18221 this._loaded.push($item.get(0)); 18222 } 18223 18224 /** 18225 * Destroys the plugin. 18226 * @public 18227 */ 18228 Lazy.prototype.destroy = function() { 18229 var handler, property; 18230 18231 for (handler in this.handlers) { 18232 this._core.$element.off(handler, this.handlers[handler]); 18233 } 18234 for (property in Object.getOwnPropertyNames(this)) { 18235 typeof this[property] != 'function' && (this[property] = null); 18236 } 18237 }; 18238 18239 $.fn.owlCarousel.Constructor.Plugins.Lazy = Lazy; 18240 18241})(window.Zepto || window.jQuery, window, document); 18242 18243/** 18244 * AutoHeight Plugin 18245 * @version 2.0.0-beta.3 18246 * @author Bartosz Wojciechowski 18247 * @license The MIT License (MIT) 18248 */ 18249;(function($, window, document, undefined) { 18250 18251 /** 18252 * Creates the auto height plugin. 18253 * @class The Auto Height Plugin 18254 * @param {Owl} carousel - The Owl Carousel 18255 */ 18256 var AutoHeight = function(carousel) { 18257 /** 18258 * Reference to the core. 18259 * @protected 18260 * @type {Owl} 18261 */ 18262 this._core = carousel; 18263 18264 /** 18265 * All event handlers. 18266 * @protected 18267 * @type {Object} 18268 */ 18269 this._handlers = { 18270 'initialized.owl.carousel refreshed.owl.carousel': $.proxy(function(e) { 18271 if (e.namespace && this._core.settings.autoHeight) { 18272 this.update(); 18273 } 18274 }, this), 18275 'changed.owl.carousel': $.proxy(function(e) { 18276 if (e.namespace && this._core.settings.autoHeight && e.property.name == 'position'){ 18277 this.update(); 18278 } 18279 }, this), 18280 'loaded.owl.lazy': $.proxy(function(e) { 18281 if (e.namespace && this._core.settings.autoHeight 18282 && e.element.closest('.' + this._core.settings.itemClass).index() === this._core.current()) { 18283 this.update(); 18284 } 18285 }, this) 18286 }; 18287 18288 // set default options 18289 this._core.options = $.extend({}, AutoHeight.Defaults, this._core.options); 18290 18291 // register event handlers 18292 this._core.$element.on(this._handlers); 18293 }; 18294 18295 /** 18296 * Default options. 18297 * @public 18298 */ 18299 AutoHeight.Defaults = { 18300 autoHeight: false, 18301 autoHeightClass: 'owl-height' 18302 }; 18303 18304 /** 18305 * Updates the view. 18306 */ 18307 AutoHeight.prototype.update = function() { 18308 var start = this._core._current, 18309 end = start + this._core.settings.items, 18310 visible = this._core.$stage.children().toArray().slice(start, end); 18311 heights = [], 18312 maxheight = 0; 18313 18314 $.each(visible, function(index, item) { 18315 heights.push($(item).height()); 18316 }); 18317 18318 maxheight = Math.max.apply(null, heights); 18319 18320 this._core.$stage.parent() 18321 .height(maxheight) 18322 .addClass(this._core.settings.autoHeightClass); 18323 }; 18324 18325 AutoHeight.prototype.destroy = function() { 18326 var handler, property; 18327 18328 for (handler in this._handlers) { 18329 this._core.$element.off(handler, this._handlers[handler]); 18330 } 18331 for (property in Object.getOwnPropertyNames(this)) { 18332 typeof this[property] != 'function' && (this[property] = null); 18333 } 18334 }; 18335 18336 $.fn.owlCarousel.Constructor.Plugins.AutoHeight = AutoHeight; 18337 18338})(window.Zepto || window.jQuery, window, document); 18339 18340/** 18341 * Video Plugin 18342 * @version 2.0.0-beta.3 18343 * @author Bartosz Wojciechowski 18344 * @license The MIT License (MIT) 18345 */ 18346;(function($, window, document, undefined) { 18347 18348 /** 18349 * Creates the video plugin. 18350 * @class The Video Plugin 18351 * @param {Owl} carousel - The Owl Carousel 18352 */ 18353 var Video = function(carousel) { 18354 /** 18355 * Reference to the core. 18356 * @protected 18357 * @type {Owl} 18358 */ 18359 this._core = carousel; 18360 18361 /** 18362 * Cache all video URLs. 18363 * @protected 18364 * @type {Object} 18365 */ 18366 this._videos = {}; 18367 18368 /** 18369 * Current playing item. 18370 * @protected 18371 * @type {jQuery} 18372 */ 18373 this._playing = null; 18374 18375 /** 18376 * All event handlers. 18377 * @todo The cloned content removale is too late 18378 * @protected 18379 * @type {Object} 18380 */ 18381 this._handlers = { 18382 'initialized.owl.carousel': $.proxy(function(e) { 18383 if (e.namespace) { 18384 this._core.register({ type: 'state', name: 'playing', tags: [ 'interacting' ] }); 18385 } 18386 }, this), 18387 'resize.owl.carousel': $.proxy(function(e) { 18388 if (e.namespace && this._core.settings.video && this.isInFullScreen()) { 18389 e.preventDefault(); 18390 } 18391 }, this), 18392 'refreshed.owl.carousel': $.proxy(function(e) { 18393 if (e.namespace && this._core.is('resizing')) { 18394 this._core.$stage.find('.cloned .owl-video-frame').remove(); 18395 } 18396 }, this), 18397 'changed.owl.carousel': $.proxy(function(e) { 18398 if (e.namespace && e.property.name === 'position' && this._playing) { 18399 this.stop(); 18400 } 18401 }, this), 18402 'prepared.owl.carousel': $.proxy(function(e) { 18403 if (!e.namespace) { 18404 return; 18405 } 18406 18407 var $element = $(e.content).find('.owl-video'); 18408 18409 if ($element.length) { 18410 $element.css('display', 'none'); 18411 this.fetch($element, $(e.content)); 18412 } 18413 }, this) 18414 }; 18415 18416 // set default options 18417 this._core.options = $.extend({}, Video.Defaults, this._core.options); 18418 18419 // register event handlers 18420 this._core.$element.on(this._handlers); 18421 18422 this._core.$element.on('click.owl.video', '.owl-video-play-icon', $.proxy(function(e) { 18423 this.play(e); 18424 }, this)); 18425 }; 18426 18427 /** 18428 * Default options. 18429 * @public 18430 */ 18431 Video.Defaults = { 18432 video: false, 18433 videoHeight: false, 18434 videoWidth: false 18435 }; 18436 18437 /** 18438 * Gets the video ID and the type (YouTube/Vimeo only). 18439 * @protected 18440 * @param {jQuery} target - The target containing the video data. 18441 * @param {jQuery} item - The item containing the video. 18442 */ 18443 Video.prototype.fetch = function(target, item) { 18444 var type = target.attr('data-vimeo-id') ? 'vimeo' : 'youtube', 18445 id = target.attr('data-vimeo-id') || target.attr('data-youtube-id'), 18446 width = target.attr('data-width') || this._core.settings.videoWidth, 18447 height = target.attr('data-height') || this._core.settings.videoHeight, 18448 url = target.attr('href'); 18449 18450 if (url) { 18451 id = url.match(/(http:|https:|)\/\/(player.|www.)?(vimeo\.com|youtu(be\.com|\.be|be\.googleapis\.com))\/(video\/|embed\/|watch\?v=|v\/)?([A-Za-z0-9._%-]*)(\&\S+)?/); 18452 18453 if (id[3].indexOf('youtu') > -1) { 18454 type = 'youtube'; 18455 } else if (id[3].indexOf('vimeo') > -1) { 18456 type = 'vimeo'; 18457 } else { 18458 throw new Error('Video URL not supported.'); 18459 } 18460 id = id[6]; 18461 } else { 18462 throw new Error('Missing video URL.'); 18463 } 18464 18465 this._videos[url] = { 18466 type: type, 18467 id: id, 18468 width: width, 18469 height: height 18470 }; 18471 18472 item.attr('data-video', url); 18473 18474 this.thumbnail(target, this._videos[url]); 18475 }; 18476 18477 /** 18478 * Creates video thumbnail. 18479 * @protected 18480 * @param {jQuery} target - The target containing the video data. 18481 * @param {Object} info - The video info object. 18482 * @see `fetch` 18483 */ 18484 Video.prototype.thumbnail = function(target, video) { 18485 var tnLink, 18486 icon, 18487 path, 18488 dimensions = video.width && video.height ? 'style="width:' + video.width + 'px;height:' + video.height + 'px;"' : '', 18489 customTn = target.find('img'), 18490 srcType = 'src', 18491 lazyClass = '', 18492 settings = this._core.settings, 18493 create = function(path) { 18494 icon = '<div class="owl-video-play-icon"></div>'; 18495 18496 if (settings.lazyLoad) { 18497 tnLink = '<div class="owl-video-tn ' + lazyClass + '" ' + srcType + '="' + path + '"></div>'; 18498 } else { 18499 tnLink = '<div class="owl-video-tn" style="opacity:1;background-image:url(' + path + ')"></div>'; 18500 } 18501 target.after(tnLink); 18502 target.after(icon); 18503 }; 18504 18505 // wrap video content into owl-video-wrapper div 18506 target.wrap('<div class="owl-video-wrapper"' + dimensions + '></div>'); 18507 18508 if (this._core.settings.lazyLoad) { 18509 srcType = 'data-src'; 18510 lazyClass = 'owl-lazy'; 18511 } 18512 18513 // custom thumbnail 18514 if (customTn.length) { 18515 create(customTn.attr(srcType)); 18516 customTn.remove(); 18517 return false; 18518 } 18519 18520 if (video.type === 'youtube') { 18521 path = "//img.youtube.com/vi/" + video.id + "/hqdefault.jpg"; 18522 create(path); 18523 } else if (video.type === 'vimeo') { 18524 $.ajax({ 18525 type: 'GET', 18526 url: '//vimeo.com/api/v2/video/' + video.id + '.json', 18527 jsonp: 'callback', 18528 dataType: 'jsonp', 18529 success: function(data) { 18530 path = data[0].thumbnail_large; 18531 create(path); 18532 } 18533 }); 18534 } 18535 }; 18536 18537 /** 18538 * Stops the current video. 18539 * @public 18540 */ 18541 Video.prototype.stop = function() { 18542 this._core.trigger('stop', null, 'video'); 18543 this._playing.find('.owl-video-frame').remove(); 18544 this._playing.removeClass('owl-video-playing'); 18545 this._playing = null; 18546 this._core.leave('playing'); 18547 this._core.trigger('stopped', null, 'video'); 18548 }; 18549 18550 /** 18551 * Starts the current video. 18552 * @public 18553 * @param {Event} event - The event arguments. 18554 */ 18555 Video.prototype.play = function(event) { 18556 var target = $(event.target), 18557 item = target.closest('.' + this._core.settings.itemClass), 18558 video = this._videos[item.attr('data-video')], 18559 width = video.width || '100%', 18560 height = video.height || this._core.$stage.height(), 18561 html; 18562 18563 if (this._playing) { 18564 return; 18565 } 18566 18567 this._core.enter('playing'); 18568 this._core.trigger('play', null, 'video'); 18569 18570 item = this._core.items(this._core.relative(item.index())); 18571 18572 this._core.reset(item.index()); 18573 18574 if (video.type === 'youtube') { 18575 html = '<iframe width="' + width + '" height="' + height + '" src="//www.youtube.com/embed/' + 18576 video.id + '?autoplay=1&v=' + video.id + '" frameborder="0" allowfullscreen></iframe>'; 18577 } else if (video.type === 'vimeo') { 18578 html = '<iframe src="//player.vimeo.com/video/' + video.id + 18579 '?autoplay=1" width="' + width + '" height="' + height + 18580 '" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>'; 18581 } 18582 18583 $('<div class="owl-video-frame">' + html + '</div>').insertAfter(item.find('.owl-video')); 18584 18585 this._playing = item.addClass('owl-video-playing'); 18586 }; 18587 18588 /** 18589 * Checks whether an video is currently in full screen mode or not. 18590 * @todo Bad style because looks like a readonly method but changes members. 18591 * @protected 18592 * @returns {Boolean} 18593 */ 18594 Video.prototype.isInFullScreen = function() { 18595 var element = document.fullscreenElement || document.mozFullScreenElement || 18596 document.webkitFullscreenElement; 18597 18598 return element && $(element).parent().hasClass('owl-video-frame'); 18599 }; 18600 18601 /** 18602 * Destroys the plugin. 18603 */ 18604 Video.prototype.destroy = function() { 18605 var handler, property; 18606 18607 this._core.$element.off('click.owl.video'); 18608 18609 for (handler in this._handlers) { 18610 this._core.$element.off(handler, this._handlers[handler]); 18611 } 18612 for (property in Object.getOwnPropertyNames(this)) { 18613 typeof this[property] != 'function' && (this[property] = null); 18614 } 18615 }; 18616 18617 $.fn.owlCarousel.Constructor.Plugins.Video = Video; 18618 18619})(window.Zepto || window.jQuery, window, document); 18620 18621/** 18622 * Animate Plugin 18623 * @version 2.0.0-beta.3 18624 * @author Bartosz Wojciechowski 18625 * @license The MIT License (MIT) 18626 */ 18627;(function($, window, document, undefined) { 18628 18629 /** 18630 * Creates the animate plugin. 18631 * @class The Navigation Plugin 18632 * @param {Owl} scope - The Owl Carousel 18633 */ 18634 var Animate = function(scope) { 18635 this.core = scope; 18636 this.core.options = $.extend({}, Animate.Defaults, this.core.options); 18637 this.swapping = true; 18638 this.previous = undefined; 18639 this.next = undefined; 18640 18641 this.handlers = { 18642 'change.owl.carousel': $.proxy(function(e) { 18643 if (e.namespace && e.property.name == 'position') { 18644 this.previous = this.core.current(); 18645 this.next = e.property.value; 18646 } 18647 }, this), 18648 'drag.owl.carousel dragged.owl.carousel translated.owl.carousel': $.proxy(function(e) { 18649 if (e.namespace) { 18650 this.swapping = e.type == 'translated'; 18651 } 18652 }, this), 18653 'translate.owl.carousel': $.proxy(function(e) { 18654 if (e.namespace && this.swapping && (this.core.options.animateOut || this.core.options.animateIn)) { 18655 this.swap(); 18656 } 18657 }, this) 18658 }; 18659 18660 this.core.$element.on(this.handlers); 18661 }; 18662 18663 /** 18664 * Default options. 18665 * @public 18666 */ 18667 Animate.Defaults = { 18668 animateOut: false, 18669 animateIn: false 18670 }; 18671 18672 /** 18673 * Toggles the animation classes whenever an translations starts. 18674 * @protected 18675 * @returns {Boolean|undefined} 18676 */ 18677 Animate.prototype.swap = function() { 18678 18679 if (this.core.settings.items !== 1) { 18680 return; 18681 } 18682 18683 if (!$.support.animation || !$.support.transition) { 18684 return; 18685 } 18686 18687 this.core.speed(0); 18688 18689 var left, 18690 clear = $.proxy(this.clear, this), 18691 previous = this.core.$stage.children().eq(this.previous), 18692 next = this.core.$stage.children().eq(this.next), 18693 incoming = this.core.settings.animateIn, 18694 outgoing = this.core.settings.animateOut; 18695 18696 if (this.core.current() === this.previous) { 18697 return; 18698 } 18699 18700 if (outgoing) { 18701 left = this.core.coordinates(this.previous) - this.core.coordinates(this.next); 18702 previous.css( { 'left': left + 'px' } ) 18703 .addClass('animated owl-animated-out') 18704 .addClass(outgoing) 18705 .on($.support.animation.end, clear); 18706 } 18707 18708 if (incoming) { 18709 next.addClass('animated owl-animated-in') 18710 .addClass(incoming) 18711 .on($.support.animation.end, clear); 18712 } 18713 }; 18714 18715 Animate.prototype.clear = function(e) { 18716 if ($(e.target).hasClass('animated')) { 18717 $(e.target).css( { 'left': '' } ) 18718 .removeClass('animated owl-animated-out owl-animated-in') 18719 .removeClass(this.core.settings.animateIn) 18720 .removeClass(this.core.settings.animateOut); 18721 this.core.onTransitionEnd(); 18722 } 18723 }; 18724 18725 /** 18726 * Destroys the plugin. 18727 * @public 18728 */ 18729 Animate.prototype.destroy = function() { 18730 var handler, property; 18731 18732 for (handler in this.handlers) { 18733 this.core.$element.off(handler, this.handlers[handler]); 18734 } 18735 for (property in Object.getOwnPropertyNames(this)) { 18736 typeof this[property] != 'function' && (this[property] = null); 18737 } 18738 }; 18739 18740 $.fn.owlCarousel.Constructor.Plugins.Animate = Animate; 18741 18742})(window.Zepto || window.jQuery, window, document); 18743 18744/** 18745 * Autoplay Plugin 18746 * @version 2.0.0-beta.3 18747 * @author Bartosz Wojciechowski 18748 * @author Artus Kolanowski 18749 * @license The MIT License (MIT) 18750 */ 18751;(function($, window, document, undefined) { 18752 18753 /** 18754 * Creates the autoplay plugin. 18755 * @class The Autoplay Plugin 18756 * @param {Owl} scope - The Owl Carousel 18757 */ 18758 var Autoplay = function(carousel) { 18759 /** 18760 * Reference to the core. 18761 * @protected 18762 * @type {Owl} 18763 */ 18764 this._core = carousel; 18765 18766 /** 18767 * The autoplay interval. 18768 * @type {Number} 18769 */ 18770 this._interval = null; 18771 18772 /** 18773 * Indicates whenever the autoplay is paused. 18774 * @type {Boolean} 18775 */ 18776 this._paused = false; 18777 18778 /** 18779 * All event handlers. 18780 * @protected 18781 * @type {Object} 18782 */ 18783 this._handlers = { 18784 'changed.owl.carousel': $.proxy(function(e) { 18785 if (e.namespace && e.property.name === 'settings') { 18786 if (this._core.settings.autoplay) { 18787 this.play(); 18788 } else { 18789 this.stop(); 18790 } 18791 } 18792 }, this), 18793 'initialized.owl.carousel': $.proxy(function(e) { 18794 if (e.namespace && this._core.settings.autoplay) { 18795 this.play(); 18796 } 18797 }, this), 18798 'play.owl.autoplay': $.proxy(function(e, t, s) { 18799 if (e.namespace) { 18800 this.play(t, s); 18801 } 18802 }, this), 18803 'stop.owl.autoplay': $.proxy(function(e) { 18804 if (e.namespace) { 18805 this.stop(); 18806 } 18807 }, this), 18808 'mouseover.owl.autoplay': $.proxy(function() { 18809 if (this._core.settings.autoplayHoverPause && this._core.is('rotating')) { 18810 this.pause(); 18811 } 18812 }, this), 18813 'mouseleave.owl.autoplay': $.proxy(function() { 18814 if (this._core.settings.autoplayHoverPause && this._core.is('rotating')) { 18815 this.play(); 18816 } 18817 }, this) 18818 }; 18819 18820 // register event handlers 18821 this._core.$element.on(this._handlers); 18822 18823 // set default options 18824 this._core.options = $.extend({}, Autoplay.Defaults, this._core.options); 18825 }; 18826 18827 /** 18828 * Default options. 18829 * @public 18830 */ 18831 Autoplay.Defaults = { 18832 autoplay: false, 18833 autoplayTimeout: 5000, 18834 autoplayHoverPause: false, 18835 autoplaySpeed: false 18836 }; 18837 18838 /** 18839 * Starts the autoplay. 18840 * @public 18841 * @param {Number} [timeout] - The interval before the next animation starts. 18842 * @param {Number} [speed] - The animation speed for the animations. 18843 */ 18844 Autoplay.prototype.play = function(timeout, speed) { 18845 this._paused = false; 18846 18847 if (this._core.is('rotating')) { 18848 return; 18849 } 18850 18851 this._core.enter('rotating'); 18852 18853 this._interval = window.setInterval($.proxy(function() { 18854 if (this._paused || this._core.is('busy') || this._core.is('interacting') || document.hidden) { 18855 return; 18856 } 18857 this._core.next(speed || this._core.settings.autoplaySpeed); 18858 }, this), timeout || this._core.settings.autoplayTimeout); 18859 }; 18860 18861 /** 18862 * Stops the autoplay. 18863 * @public 18864 */ 18865 Autoplay.prototype.stop = function() { 18866 if (!this._core.is('rotating')) { 18867 return; 18868 } 18869 18870 window.clearInterval(this._interval); 18871 this._core.leave('rotating'); 18872 }; 18873 18874 /** 18875 * Stops the autoplay. 18876 * @public 18877 */ 18878 Autoplay.prototype.pause = function() { 18879 if (!this._core.is('rotating')) { 18880 return; 18881 } 18882 18883 this._paused = true; 18884 }; 18885 18886 /** 18887 * Destroys the plugin. 18888 */ 18889 Autoplay.prototype.destroy = function() { 18890 var handler, property; 18891 18892 this.stop(); 18893 18894 for (handler in this._handlers) { 18895 this._core.$element.off(handler, this._handlers[handler]); 18896 } 18897 for (property in Object.getOwnPropertyNames(this)) { 18898 typeof this[property] != 'function' && (this[property] = null); 18899 } 18900 }; 18901 18902 $.fn.owlCarousel.Constructor.Plugins.autoplay = Autoplay; 18903 18904})(window.Zepto || window.jQuery, window, document); 18905 18906/** 18907 * Navigation Plugin 18908 * @version 2.0.0-beta.3 18909 * @author Artus Kolanowski 18910 * @license The MIT License (MIT) 18911 */ 18912;(function($, window, document, undefined) { 18913 'use strict'; 18914 18915 /** 18916 * Creates the navigation plugin. 18917 * @class The Navigation Plugin 18918 * @param {Owl} carousel - The Owl Carousel. 18919 */ 18920 var Navigation = function(carousel) { 18921 /** 18922 * Reference to the core. 18923 * @protected 18924 * @type {Owl} 18925 */ 18926 this._core = carousel; 18927 18928 /** 18929 * Indicates whether the plugin is initialized or not. 18930 * @protected 18931 * @type {Boolean} 18932 */ 18933 this._initialized = false; 18934 18935 /** 18936 * The current paging indexes. 18937 * @protected 18938 * @type {Array} 18939 */ 18940 this._pages = []; 18941 18942 /** 18943 * All DOM elements of the user interface. 18944 * @protected 18945 * @type {Object} 18946 */ 18947 this._controls = {}; 18948 18949 /** 18950 * Markup for an indicator. 18951 * @protected 18952 * @type {Array.<String>} 18953 */ 18954 this._templates = []; 18955 18956 /** 18957 * The carousel element. 18958 * @type {jQuery} 18959 */ 18960 this.$element = this._core.$element; 18961 18962 /** 18963 * Overridden methods of the carousel. 18964 * @protected 18965 * @type {Object} 18966 */ 18967 this._overrides = { 18968 next: this._core.next, 18969 prev: this._core.prev, 18970 to: this._core.to 18971 }; 18972 18973 /** 18974 * All event handlers. 18975 * @protected 18976 * @type {Object} 18977 */ 18978 this._handlers = { 18979 'prepared.owl.carousel': $.proxy(function(e) { 18980 if (e.namespace && this._core.settings.dotsData) { 18981 this._templates.push('<div class="' + this._core.settings.dotClass + '">' + 18982 $(e.content).find('[data-dot]').andSelf('[data-dot]').attr('data-dot') + '</div>'); 18983 } 18984 }, this), 18985 'added.owl.carousel': $.proxy(function(e) { 18986 if (e.namespace && this._core.settings.dotsData) { 18987 this._templates.splice(e.position, 0, this._templates.pop()); 18988 } 18989 }, this), 18990 'remove.owl.carousel': $.proxy(function(e) { 18991 if (e.namespace && this._core.settings.dotsData) { 18992 this._templates.splice(e.position, 1); 18993 } 18994 }, this), 18995 'changed.owl.carousel': $.proxy(function(e) { 18996 if (e.namespace && e.property.name == 'position') { 18997 this.draw(); 18998 } 18999 }, this), 19000 'initialized.owl.carousel': $.proxy(function(e) { 19001 if (e.namespace && !this._initialized) { 19002 this._core.trigger('initialize', null, 'navigation'); 19003 this.initialize(); 19004 this.update(); 19005 this.draw(); 19006 this._initialized = true; 19007 this._core.trigger('initialized', null, 'navigation'); 19008 } 19009 }, this), 19010 'refreshed.owl.carousel': $.proxy(function(e) { 19011 if (e.namespace && this._initialized) { 19012 this._core.trigger('refresh', null, 'navigation'); 19013 this.update(); 19014 this.draw(); 19015 this._core.trigger('refreshed', null, 'navigation'); 19016 } 19017 }, this) 19018 }; 19019 19020 // set default options 19021 this._core.options = $.extend({}, Navigation.Defaults, this._core.options); 19022 19023 // register event handlers 19024 this.$element.on(this._handlers); 19025 }; 19026 19027 /** 19028 * Default options. 19029 * @public 19030 * @todo Rename `slideBy` to `navBy` 19031 */ 19032 Navigation.Defaults = { 19033 nav: false, 19034 navText: [ 'prev', 'next' ], 19035 navSpeed: false, 19036 navElement: 'div', 19037 navContainer: false, 19038 navContainerClass: 'owl-nav', 19039 navClass: [ 'owl-prev', 'owl-next' ], 19040 slideBy: 1, 19041 dotClass: 'owl-dot', 19042 dotsClass: 'owl-dots', 19043 dots: true, 19044 dotsEach: false, 19045 dotsData: false, 19046 dotsSpeed: false, 19047 dotsContainer: false 19048 }; 19049 19050 /** 19051 * Initializes the layout of the plugin and extends the carousel. 19052 * @protected 19053 */ 19054 Navigation.prototype.initialize = function() { 19055 var override, 19056 settings = this._core.settings; 19057 19058 // create DOM structure for relative navigation 19059 this._controls.$relative = (settings.navContainer ? $(settings.navContainer) 19060 : $('<div>').addClass(settings.navContainerClass).appendTo(this.$element)).addClass('disabled'); 19061 19062 this._controls.$previous = $('<' + settings.navElement + '>') 19063 .addClass(settings.navClass[0]) 19064 .html(settings.navText[0]) 19065 .prependTo(this._controls.$relative) 19066 .on('click', $.proxy(function(e) { 19067 this.prev(settings.navSpeed); 19068 }, this)); 19069 this._controls.$next = $('<' + settings.navElement + '>') 19070 .addClass(settings.navClass[1]) 19071 .html(settings.navText[1]) 19072 .appendTo(this._controls.$relative) 19073 .on('click', $.proxy(function(e) { 19074 this.next(settings.navSpeed); 19075 }, this)); 19076 19077 // create DOM structure for absolute navigation 19078 if (!settings.dotsData) { 19079 this._templates = [ $('<div>') 19080 .addClass(settings.dotClass) 19081 .append($('<span>')) 19082 .prop('outerHTML') ]; 19083 } 19084 19085 this._controls.$absolute = (settings.dotsContainer ? $(settings.dotsContainer) 19086 : $('<div>').addClass(settings.dotsClass).appendTo(this.$element)).addClass('disabled'); 19087 19088 this._controls.$absolute.on('click', 'div', $.proxy(function(e) { 19089 var index = $(e.target).parent().is(this._controls.$absolute) 19090 ? $(e.target).index() : $(e.target).parent().index(); 19091 19092 e.preventDefault(); 19093 19094 this.to(index, settings.dotsSpeed); 19095 }, this)); 19096 19097 // override public methods of the carousel 19098 for (override in this._overrides) { 19099 this._core[override] = $.proxy(this[override], this); 19100 } 19101 }; 19102 19103 /** 19104 * Destroys the plugin. 19105 * @protected 19106 */ 19107 Navigation.prototype.destroy = function() { 19108 var handler, control, property, override; 19109 19110 for (handler in this._handlers) { 19111 this.$element.off(handler, this._handlers[handler]); 19112 } 19113 for (control in this._controls) { 19114 this._controls[control].remove(); 19115 } 19116 for (override in this.overides) { 19117 this._core[override] = this._overrides[override]; 19118 } 19119 for (property in Object.getOwnPropertyNames(this)) { 19120 typeof this[property] != 'function' && (this[property] = null); 19121 } 19122 }; 19123 19124 /** 19125 * Updates the internal state. 19126 * @protected 19127 */ 19128 Navigation.prototype.update = function() { 19129 var i, j, k, 19130 lower = this._core.clones().length / 2, 19131 upper = lower + this._core.items().length, 19132 maximum = this._core.maximum(true), 19133 settings = this._core.settings, 19134 size = settings.center || settings.autoWidth || settings.dotsData 19135 ? 1 : settings.dotsEach || settings.items; 19136 19137 if (settings.slideBy !== 'page') { 19138 settings.slideBy = Math.min(settings.slideBy, settings.items); 19139 } 19140 19141 if (settings.dots || settings.slideBy == 'page') { 19142 this._pages = []; 19143 19144 for (i = lower, j = 0, k = 0; i < upper; i++) { 19145 if (j >= size || j === 0) { 19146 this._pages.push({ 19147 start: Math.min(maximum, i - lower), 19148 end: i - lower + size - 1 19149 }); 19150 if (Math.min(maximum, i - lower) === maximum) { 19151 break; 19152 } 19153 j = 0, ++k; 19154 } 19155 j += this._core.mergers(this._core.relative(i)); 19156 } 19157 } 19158 }; 19159 19160 /** 19161 * Draws the user interface. 19162 * @todo The option `dotsData` wont work. 19163 * @protected 19164 */ 19165 Navigation.prototype.draw = function() { 19166 var difference, 19167 settings = this._core.settings, 19168 disabled = this._core.items().length <= settings.items, 19169 index = this._core.relative(this._core.current()), 19170 loop = settings.loop || settings.rewind; 19171 19172 this._controls.$relative.toggleClass('disabled', !settings.nav || disabled); 19173 19174 if (settings.nav) { 19175 this._controls.$previous.toggleClass('disabled', !loop && index <= this._core.minimum(true)); 19176 this._controls.$next.toggleClass('disabled', !loop && index >= this._core.maximum(true)); 19177 } 19178 19179 this._controls.$absolute.toggleClass('disabled', !settings.dots || disabled); 19180 19181 if (settings.dots) { 19182 difference = this._pages.length - this._controls.$absolute.children().length; 19183 19184 if (settings.dotsData && difference !== 0) { 19185 this._controls.$absolute.html(this._templates.join('')); 19186 } else if (difference > 0) { 19187 this._controls.$absolute.append(new Array(difference + 1).join(this._templates[0])); 19188 } else if (difference < 0) { 19189 this._controls.$absolute.children().slice(difference).remove(); 19190 } 19191 19192 this._controls.$absolute.find('.active').removeClass('active'); 19193 this._controls.$absolute.children().eq($.inArray(this.current(), this._pages)).addClass('active'); 19194 } 19195 }; 19196 19197 /** 19198 * Extends event data. 19199 * @protected 19200 * @param {Event} event - The event object which gets thrown. 19201 */ 19202 Navigation.prototype.onTrigger = function(event) { 19203 var settings = this._core.settings; 19204 19205 event.page = { 19206 index: $.inArray(this.current(), this._pages), 19207 count: this._pages.length, 19208 size: settings && (settings.center || settings.autoWidth || settings.dotsData 19209 ? 1 : settings.dotsEach || settings.items) 19210 }; 19211 }; 19212 19213 /** 19214 * Gets the current page position of the carousel. 19215 * @protected 19216 * @returns {Number} 19217 */ 19218 Navigation.prototype.current = function() { 19219 var current = this._core.relative(this._core.current()); 19220 return $.grep(this._pages, $.proxy(function(page, index) { 19221 return page.start <= current && page.end >= current; 19222 }, this)).pop(); 19223 }; 19224 19225 /** 19226 * Gets the current succesor/predecessor position. 19227 * @protected 19228 * @returns {Number} 19229 */ 19230 Navigation.prototype.getPosition = function(successor) { 19231 var position, length, 19232 settings = this._core.settings; 19233 19234 if (settings.slideBy == 'page') { 19235 position = $.inArray(this.current(), this._pages); 19236 length = this._pages.length; 19237 successor ? ++position : --position;
vendor: 5,678 bytes, lines 19238-19462
19238 position = this._pages[((position % length) + length) % length].start; 19239 } else { 19240 position = this._core.relative(this._core.current()); 19241 length = this._core.items().length; 19242 successor ? position += settings.slideBy : position -= settings.slideBy; 19243 } 19244 19245 return position; 19246 }; 19247 19248 /** 19249 * Slides to the next item or page. 19250 * @public 19251 * @param {Number} [speed=false] - The time in milliseconds for the transition. 19252 */ 19253 Navigation.prototype.next = function(speed) { 19254 $.proxy(this._overrides.to, this._core)(this.getPosition(true), speed); 19255 }; 19256 19257 /** 19258 * Slides to the previous item or page. 19259 * @public 19260 * @param {Number} [speed=false] - The time in milliseconds for the transition. 19261 */ 19262 Navigation.prototype.prev = function(speed) { 19263 $.proxy(this._overrides.to, this._core)(this.getPosition(false), speed); 19264 }; 19265 19266 /** 19267 * Slides to the specified item or page. 19268 * @public 19269 * @param {Number} position - The position of the item or page. 19270 * @param {Number} [speed] - The time in milliseconds for the transition. 19271 * @param {Boolean} [standard=false] - Whether to use the standard behaviour or not. 19272 */ 19273 Navigation.prototype.to = function(position, speed, standard) { 19274 var length; 19275 19276 if (!standard) { 19277 length = this._pages.length; 19278 $.proxy(this._overrides.to, this._core)(this._pages[((position % length) + length) % length].start, speed); 19279 } else { 19280 $.proxy(this._overrides.to, this._core)(position, speed); 19281 } 19282 }; 19283 19284 $.fn.owlCarousel.Constructor.Plugins.Navigation = Navigation; 19285 19286})(window.Zepto || window.jQuery, window, document); 19287 19288/** 19289 * Hash Plugin 19290 * @version 2.0.0-beta.3 19291 * @author Artus Kolanowski 19292 * @license The MIT License (MIT) 19293 */ 19294;(function($, window, document, undefined) { 19295 'use strict'; 19296 19297 /** 19298 * Creates the hash plugin. 19299 * @class The Hash Plugin 19300 * @param {Owl} carousel - The Owl Carousel 19301 */ 19302 var Hash = function(carousel) { 19303 /** 19304 * Reference to the core. 19305 * @protected 19306 * @type {Owl} 19307 */ 19308 this._core = carousel; 19309 19310 /** 19311 * Hash index for the items. 19312 * @protected 19313 * @type {Object} 19314 */ 19315 this._hashes = {}; 19316 19317 /** 19318 * The carousel element. 19319 * @type {jQuery} 19320 */ 19321 this.$element = this._core.$element; 19322 19323 /** 19324 * All event handlers. 19325 * @protected 19326 * @type {Object} 19327 */ 19328 this._handlers = { 19329 /*'initialized.owl.carousel': $.proxy(function(e) { 19330 if (e.namespace && this._core.settings.startPosition === 'URLHash') { 19331 $(window).trigger('hashchange.owl.navigation'); 19332 } 19333 }, this),*/ 19334 'prepared.owl.carousel': $.proxy(function(e) { 19335 if (e.namespace) { 19336 var hash = $(e.content).find('[data-hash]').addBack('[data-hash]').attr('data-hash'); 19337 19338 if (!hash) { 19339 return; 19340 } 19341 19342 this._hashes[hash] = e.content; 19343 } 19344 }, this), 19345 'changed.owl.carousel': $.proxy(function(e) { 19346 if (e.namespace && e.property.name === 'position') { 19347 var current = this._core.items(this._core.relative(this._core.current())), 19348 hash = $.map(this._hashes, function(item, hash) { 19349 return item === current ? hash : null; 19350 }).join(); 19351 19352 if (!hash || window.location.hash.slice(1) === hash) { 19353 return; 19354 } 19355 19356 window.location.hash = hash; 19357 } 19358 }, this) 19359 }; 19360 19361 // set default options 19362 this._core.options = $.extend({}, Hash.Defaults, this._core.options); 19363 19364 // register the event handlers 19365 this.$element.on(this._handlers); 19366 19367 // register event listener for hash navigation 19368 /*$(window).on('hashchange.owl.navigation', $.proxy(function(e) { 19369 var hash = window.location.hash.substring(1), 19370 items = this._core.$stage.children(), 19371 position = this._hashes[hash] && items.index(this._hashes[hash]); 19372 19373 if (position === undefined || position === this._core.current()) { 19374 return; 19375 } 19376 19377 this._core.to(this._core.relative(position), false, true); 19378 }, this));*/ 19379 }; 19380 19381 /** 19382 * Default options. 19383 * @public 19384 */ 19385 Hash.Defaults = { 19386 URLhashListener: false 19387 }; 19388 19389 /** 19390 * Destroys the plugin. 19391 * @public 19392 */ 19393 Hash.prototype.destroy = function() { 19394 var handler, property; 19395 19396 $(window).off('hashchange.owl.navigation'); 19397 19398 for (handler in this._handlers) { 19399 this._core.$element.off(handler, this._handlers[handler]); 19400 } 19401 for (property in Object.getOwnPropertyNames(this)) { 19402 typeof this[property] != 'function' && (this[property] = null); 19403 } 19404 }; 19405 19406 $.fn.owlCarousel.Constructor.Plugins.Hash = Hash; 19407 19408})(window.Zepto || window.jQuery, window, document); 19409 19410/** 19411 * Support Plugin 19412 * 19413 * @version 2.0.0-beta.3 19414 * @author Vivid Planet Software GmbH 19415 * @author Artus Kolanowski 19416 * @license The MIT License (MIT) 19417 */ 19418;(function($, window, document, undefined) { 19419 19420 var style = $('<support>').get(0).style, 19421 prefixes = 'Webkit Moz O ms'.split(' '), 19422 events = { 19423 transition: { 19424 end: { 19425 WebkitTransition: 'webkitTransitionEnd', 19426 MozTransition: 'transitionend', 19427 OTransition: 'oTransitionEnd', 19428 transition: 'transitionend' 19429 } 19430 }, 19431 animation: { 19432 end: { 19433 WebkitAnimation: 'webkitAnimationEnd', 19434 MozAnimation: 'animationend', 19435 OAnimation: 'oAnimationEnd', 19436 animation: 'animationend' 19437 } 19438 } 19439 }, 19440 tests = { 19441 csstransforms: function() { 19442 return !!test('transform'); 19443 }, 19444 csstransforms3d: function() { 19445 return !!test('perspective'); 19446 }, 19447 csstransitions: function() { 19448 return !!test('transition'); 19449 }, 19450 cssanimations: function() { 19451 return !!test('animation'); 19452 } 19453 }; 19454 19455 function test(property, prefixed) { 19456 var result = false, 19457 upper = property.charAt(0).toUpperCase() + property.slice(1); 19458 19459 $.each((property + ' ' + prefixes.join(upper + ' ') + upper).split(' '), function(i, property) { 19460 if (style[property] !== undefined) { 19461 result = prefixed ? property : true; 19462 return false;
19463 } 19464 }); 19465 19466 return result; 19467 } 19468 19469 function prefixed(property) { 19470 return test(property, true); 19471 } 19472 19473 if (tests.csstransitions()) { 19474 /* jshint -W053 */ 19475 $.support.transition = new String(prefixed('transition')) 19476 $.support.transition.end = events.transition.end[ $.support.transition ]; 19477 } 19478 19479 if (tests.cssanimations()) { 19480 /* jshint -W053 */ 19481 $.support.animation = new String(prefixed('animation')) 19482 $.support.animation.end = events.animation.end[ $.support.animation ]; 19483 } 19484 19485 if (tests.csstransforms()) { 19486 /* jshint -W053 */ 19487 $.support.transform = new String(prefixed('transform')); 19488 $.support.transform3d = tests.csstransforms3d(); 19489 } 19490 19491})(window.Zepto || window.jQuery, window, document); 19492 19493(function(window, document, undefined) { 19494 19495 /** 19496 * Find the absolute position of an element 19497 */ 19498 var absPos = function(element) { 19499 var offsetLeft, offsetTop; 19500 offsetLeft = offsetTop = 0; 19501 if (element.offsetParent) { 19502 do { 19503 offsetLeft += element.offsetLeft; 19504 offsetTop += element.offsetTop; 19505 } while (element = element.offsetParent); 19506 } 19507 return [offsetLeft, offsetTop]; 19508 }; 19509 19510 /** 19511 * @constructor Progress Circle class 19512 * @param params.canvas Canvas on which the circles will be drawn. 19513 * @param params.minRadius Inner radius of the innermost circle, in px. 19514 * @param params.arcWidth Width of each circle(to be more accurate, ring). 19515 * @param params.gapWidth Space between each circle. 19516 * @param params.centerX X coordinate of the center of circles. 19517 * @param params.centerY Y coordinate of the center of circles. 19518 * @param params.infoLineBaseAngle Base angle of the info line. 19519 * @param params.infoLineAngleInterval Angles between the info lines. 19520 */ 19521 var ProgressCircle = function(params) { 19522 this.canvas = params.canvas; 19523 this.minRadius = params.minRadius || 15; 19524 this.arcWidth = params.arcWidth || 5; 19525 this.gapWidth = params.gapWidth || 3; 19526 this.centerX = params.centerX || this.canvas.width / 2; 19527 this.centerY = params.centerY || this.canvas.height / 2;
19528 this.infoLineLength = params.infoLineLength || 60; 19529 this.horizLineLength = params.horizLineLength || 10; 19530 this.infoLineAngleInterval = params.infoLineAngleInterval || Math.PI / 8; 19531 this.infoLineBaseAngle = params.infoLineBaseAngle || Math.PI / 6; 19532 19533 this.context = this.canvas.getContext('2d'); 19534 19535 this.width = this.canvas.width; 19536 this.height = this.canvas.height; 19537 19538 this.circles = []; 19539 this.runningCount = 0; 19540 }; 19541 19542 ProgressCircle.prototype = { 19543 constructor: ProgressCircle, 19544 19545 /** 19546 * @method Adds an progress monitor entry. 19547 * @param params.fillColor Color to fill in the circle. 19548 * @param params.outlineColor Color to outline the circle. 19549 * @param params.progressListener Callback function to fetch the progress. 19550 * @param params.infoListener Callback function to fetch the info. 19551 * @returns this 19552 */ 19553 addEntry: function(params) { 19554 this.circles.push(new Circle({ 19555 canvas: this.canvas, 19556 context: this.context, 19557 centerX: this.centerX, 19558 centerY: this.centerY, 19559 innerRadius: this.minRadius + this.circles.length * 19560 (this.gapWidth + this.arcWidth), 19561 arcWidth: this.arcWidth,
19562 infoLineLength: this.infoLineLength, 19563 horizLineLength: this.horizLineLength, 19564 19565 id: this.circles.length, 19566 fillColor: params.fillColor, 19567 outlineColor: params.outlineColor, 19568 progressListener: params.progressListener, 19569 infoListener: params.infoListener, 19570 infoLineAngle: this.infoLineBaseAngle + 19571 this.circles.length * this.infoLineAngleInterval, 19572 })); 19573 19574 return this; 19575 }, 19576 19577 /** 19578 * @method Starts the monitor and updates with the given interval. 19579 * @param interval Interval between updates, in millisecond. 19580 * @returns this 19581 */ 19582 start: function(interval) { 19583 var self = this; 19584 this.timer = setInterval(function() { 19585 self._update(); 19586 }, interval || 33); 19587 19588 return this; 19589 }, 19590 19591 /** 19592 * @method Stop the animation. 19593 */ 19594 stop: function() { 19595 clearTimeout(this.timer); 19596 }, 19597 19598 /** 19599 * @private 19600 * @method Call update on each circle and redraw them. 19601 * @returns this 19602 */ 19603 _update: function() { 19604 this._clear(); 19605 this.circles.forEach(function(circle, idx, array) { 19606 circle.update(); 19607 }); 19608 19609 return this; 19610 }, 19611 19612 /** 19613 * @private 19614 * @method Clear the canvas. 19615 * @returns this 19616 */ 19617 _clear: function() { 19618 this.context.clearRect(0, 0, this.canvas.width, this.canvas.height); 19619 19620 return this; 19621 }, 19622 19623 }; 19624 19625 /** 19626 * @private 19627 * @class Individual progress circle. 19628 * @param params.canvas Canvas on which the circle will be drawn. 19629 * @param params.context Context of the canvas. 19630 * @param params.innerRadius Inner radius of the circle, in px. 19631 * @param params.arcWidth Width of each arc(circle). 19632 * @param params.gapWidth Distance between each arc. 19633 * @param params.centerX X coordinate of the center of circles. 19634 * @param params.centerY Y coordinate of the center of circles. 19635 * @param params.fillColor Color to fill in the circle. 19636 * @param params.outlineColor Color to outline the circle. 19637 * @param params.progressListener Callback function to fetch the progress. 19638 * @param params.infoListener Callback function to fetch the info. 19639 * @param params.infoLineAngle Angle of info line. 19640 */ 19641 var Circle = function(params) { 19642 this.id = params.id; 19643 this.canvas = params.canvas; 19644 this.context = params.context; 19645 this.centerX = params.centerX; 19646 this.centerY = params.centerY; 19647 this.arcWidth = params.arcWidth; 19648 this.innerRadius = params.innerRadius || 0; 19649 this.fillColor = params.fillColor || '#fff'; 19650 this.outlineColor = params.outlineColor || this.fillColor; 19651 this.progressListener = params.progressListener;
19652 this.infoLineLength = params.infoLineLength || 250; 19653 this.horizLineLength = params.horizLineLength || 50; 19654 this.infoListener = params.infoListener; 19655 this.infoLineAngle = params.infoLineAngle; 19656 19657 this.outerRadius = this.innerRadius + this.arcWidth; 19658 19659 // If the info listener is not registered, then don't calculate 19660 // the related coordinates 19661 if (!this.infoListener) return; 19662 19663 // calculate the info-line turning points 19664 var angle = this.infoLineAngle, 19665 arcDistance = (this.innerRadius + this.outerRadius) / 2, 19666 19667 sinA = Math.sin(angle), 19668 cosA = Math.cos(angle); 19669 19670 this.infoLineStartX = this.centerX + sinA * arcDistance; 19671 this.infoLineStartY = this.centerY - cosA * arcDistance; 19672 19673 this.infoLineMidX = this.centerX + sinA * this.infoLineLength; 19674 this.infoLineMidY = this.centerY - cosA * this.infoLineLength; 19675 19676 this.infoLineEndX = this.infoLineMidX + 19677 (sinA < 0 ? -this.horizLineLength : this.horizLineLength); 19678 this.infoLineEndY = this.infoLineMidY; 19679 19680 var infoText = document.createElement('div'), 19681 style = infoText.style; 19682 19683 style.color = this.fillColor; 19684 style.position = 'absolute'; 19685 style.left = this.infoLineEndX + absPos(this.canvas)[0] + 'px'; 19686 // style.top will be calculated in the `drawInfo` method. Since 19687 // user may want to change the size of the font, so the top offset 19688 // must be updated in each loop. 19689 infoText.className = 'ProgressCircleInfo'; // For css styling 19690 infoText.id = 'progress_circle_info_' + this.id; 19691 document.body.appendChild(infoText); 19692 this.infoText = infoText; 19693 }; 19694 19695 Circle.prototype = { 19696 constructor: Circle, 19697 19698 update: function() { 19699 this.progress = this.progressListener(); 19700 this._draw(); 19701 19702 if (this.infoListener) { 19703 this.info = this.infoListener(); 19704 this._drawInfo(); 19705 } 19706 }, 19707 19708 /** 19709 * @private 19710 * @method Draw the circle on the canvas. 19711 * @returns this 19712 */ 19713 _draw: function() { 19714 var ctx = this.context, 19715 19716 ANGLE_OFFSET = -Math.PI / 2, 19717 19718 startAngle = 0 + ANGLE_OFFSET, 19719 endAngle= startAngle + this.progress * Math.PI * 2, 19720 19721 x = this.centerX, 19722 y = this.centerY, 19723 19724 innerRadius = this.innerRadius - this.arcWidth - 1, 19725 outerRadius = this.outerRadius - this.arcWidth - 1; 19726 19727 if ( innerRadius < 0 ) 19728 return; 19729 19730 ctx.fillStyle = this.fillColor; 19731 ctx.strokeStyle = this.outlineColor; 19732 19733 ctx.beginPath(); 19734 ctx.arc(x, y, innerRadius, startAngle, endAngle, false); 19735 ctx.arc(x, y, outerRadius, endAngle, startAngle, true); 19736 ctx.closePath(); 19737 ctx.stroke(); 19738 ctx.fill(); 19739 19740 return this; 19741 }, 19742 19743 /** 19744 * @private 19745 * @method Draw the info lines and info text. 19746 * @returns this 19747 */ 19748 _drawInfo: function() { 19749 19750 var pointList, lineHeight; 19751 19752 pointList = [ 19753 [this.infoLineStartX, this.infoLineStartY], 19754 [this.infoLineMidX, this.infoLineMidY], 19755 [this.infoLineEndX, this.infoLineEndY], 19756 ]; 19757 this._drawSegments(pointList, false); 19758 19759 this.infoText.innerHTML = this.info; 19760 19761 lineHeight = this.infoText.offsetHeight; 19762 this.infoText.style.top = this.infoLineEndY + 19763 absPos(this.canvas)[1] - lineHeight / 2 + 'px'; 19764 19765 return this; 19766 }, 19767 19768 /** 19769 * @private 19770 * @method Helper function to draw the segments 19771 * @param pointList An array of points in the form of [x, y]. 19772 * @param close Whether to connect the first and last point. 19773 */ 19774 _drawSegments: function(pointList, close) { 19775 var ctx = this.context; 19776 19777 ctx.beginPath(); 19778 ctx.moveTo(pointList[0][0], pointList[0][1]); 19779 for (var i = 1; i < pointList.length; ++i) { 19780 ctx.lineTo(pointList[i][0], pointList[i][1]); 19781 } 19782 19783 if (close) { 19784 ctx.closePath(); 19785 } 19786 ctx.stroke(); 19787 }, 19788 }; 19789 19790 window.ProgressCircle = ProgressCircle; 19791 19792})(window, document); 19793 19794 19795 19796 19797/* ========================================================= 19798 * jquery.vc_chart.js v1.0 19799 * ========================================================= 19800 * Copyright 2013 Wpbakery 19801 * 19802 * Jquery chart plugin for the Visual Composer. 19803 * ========================================================= */ 19804(function($){ 19805 /** 19806 * Pie chart animated. 19807 * @param element - DOM element 19808 * @param options - settings object. 19809 * @constructor 19810 */ 19811 var VcChart = function(element, options) { 19812 this.el = element; 19813 this.$el = $(this.el); 19814 var $this = this; 19815 $this.options = $.extend({ 19816 color: 'wpb_button', 19817 units: '', 19818 width: '', 19819 label_selector: '.vc_pie_chart_value', 19820 back_selector: '.vc_pie_chart_back', 19821 responsive: true 19822 }, options); 19823 $this.init(); 19824 }; 19825 VcChart.prototype = { 19826 constructor: VcChart, 19827 _progress_v: 0, 19828 animated: false, 19829 colors: { 19830 'wpb_button': 'rgba(247, 247, 247, 1)', 19831 'btn-primary': 'rgba(0, 136, 204, 1)', 19832 'btn-info': 'rgba(88, 185, 218, 1)', 19833 'btn-success': 'rgba(106, 177, 101, 1)', 19834 'btn-warning': 'rgba(255, 153, 0, 1)', 19835 'btn-danger': 'rgba(255, 103, 91, 1)', 19836 'btn-inverse': 'rgba(85, 85, 85, 1)' 19837 }, 19838 init: function() { 19839 this.setupColor(); 19840 this.value = this.$el.data('pie-value')/100; 19841 this.label_value = this.$el.data('pie-label-value') || this.$el.data('pie-value'); 19842 this.$wrapper = $('.vc_pie_wrapper', this.$el); 19843 this.$label = $(this.options.label_selector, this.$el); 19844 this.$back = $(this.options.back_selector, this.$el); 19845 this.$canvas = this.$el.find('canvas'); 19846 this.arcWidth = this.$el.data('pie-width') * 2; 19847 this.draw(); 19848 this.setWayPoint(); 19849 if(this.options.responsive === true) this.setResponsive(); 19850 if (UNCODE.isMobile) this._progress_v = this.value; 19851 }, 19852 setupColor: function() { 19853 // if(typeof this.colors[this.options.color] !== 'undefined') { 19854 // this.color = this.colors[this.options.color]; 19855 // } else if(typeof this.options.color === 'string' && this.options.color.match(/^rgba?\([^\)]+\)/)) { 19856 // this.color = this.options.color; 19857 // } else { 19858 // this.color = 'rgba(247, 247, 247, 0.2)'; 19859 // } 19860 if(typeof this.options.color !== 'undefined') { 19861 this.color = this.options.color; 19862 } else this.color = 'rgba(247, 247, 247, 0.2)'; 19863 19864 }, 19865 setResponsive: function() { 19866 var that = this; 19867 if (!UNCODE.isMobile) { 19868 $(window).resize(function(){ 19869 if(that.animated === true) that.circle.stop(); 19870 that.draw(true); 19871 }); 19872 } 19873 }, 19874 draw: function(redraw) { 19875 var w = this.$el.addClass('vc_ready').width() * 2, 19876 border_w = this.arcWidth, 19877 radius; 19878 if(!w) w = this.$el.parents(':visible').first().width()-2; 19879 //w = Math.round(w/100*80); 19880 //if (w < 250) w = 250; 19881 radius = w/2; 19882 this.$wrapper.css({"width" : (w / 2) + "px"}); 19883 this.$label.css({"width" : (w / 2), "height" : (w / 2), "line-height" : (w / 2)+"px"}); 19884 this.$back.css({"width" : (w / 2), "height" : (w / 2)}); 19885 this.$canvas.attr({"width" : w + "px", "height" : w + "px"}); 19886 this.$el.addClass('vc_ready'); 19887 this.circle = new ProgressCircle({ 19888 canvas: this.$canvas.get(0), 19889 minRadius: radius, 19890 arcWidth: border_w 19891 }); 19892 if(redraw === true && this.animated === true) { 19893 this._progress_v = this.value; 19894 this.circle.addEntry({ 19895 fillColor: this.color, 19896 progressListener: $.proxy(this.setProgress, this) 19897 }).start(); 19898 } 19899 }, 19900 setProgress: function() { 19901 if (this._progress_v >= this.value) { 19902 this.circle.stop(); 19903 this.animated = true; 19904 this.$label.html(this.label_value + this.options.units); 19905 return this._progress_v; 19906 } 19907 this._progress_v += 0.01; 19908 if (!isNaN(this.label_value)) { 19909 var label_value = this._progress_v/this.value*this.label_value; 19910 var val = Math.round(label_value) + this.options.units; 19911 this.$label.html(val); 19912 } else this.$label.html(this.label_value + this.options.units); 19913 return this._progress_v; 19914 }, 19915 animate: function() { 19916 if(this.animated !== true) { 19917 this.circle.addEntry({ 19918 fillColor: this.color, 19919 progressListener: $.proxy(this.setProgress, this) 19920 }).start(10); 19921 } 19922 }, 19923 setWayPoint: function() { 19924 if (typeof $.fn.waypoint !== 'undefined' && !UNCODE.isMobile) { 19925 this.$el.waypoint($.proxy(this.animate, this), { offset: '85%' }); 19926 } else { 19927 this.animate(); 19928 } 19929 } 19930 }; 19931 /** 19932 * jQuery plugin 19933 * @param option - object with settings 19934 * @return {*} 19935 */ 19936 $.fn.vcChat = function(option, value) { 19937 return this.each(function () { 19938 var $this = $(this), 19939 data = $this.data('vc_chart'), 19940 options = typeof option === 'object' ? option : { 19941 color: $this.data('pie-color'), 19942 units: $this.data('pie-units') 19943 }; 19944 if (typeof option == 'undefined') $this.data('vc_chart', (data = new VcChart(this, options))); 19945 if (typeof option == 'string') data[option](value); 19946 }); 19947 }; 19948 /** 19949 * Allows users to rewrite function inside theme. 19950 */ 19951 if ( typeof window['vc_pieChart'] !== 'function' ) { 19952 window.vc_pieChart = function() { 19953 $('.vc_pie_chart:visible:not(.vc_ready)').vcChat(); 19954 } 19955 } 19956 $(document).ready(function(){ 19957 !window.vc_iframe && vc_pieChart(); 19958 19959 /** 19960 * Tab and collapse integration. 19961 */ 19962 $('.nav-tabs a').on('shown.bs.tab', function(e){ 19963 var $cont = $(e.target).closest('.tab-container'), 19964 $active = $('.tab-pane.active', $cont); 19965 $('.vc_pie_chart:not(.vc_ready)', $active).vcChat(); 19966 }); 19967 19968 $('.panel-collapse').on('shown.bs.collapse', function (e) { 19969 $('.vc_pie_chart:not(.vc_ready)', e.target).vcChat(); 19970 }) 19971 }); 19972 19973})(window.jQuery); 19974 19975/* Progress bar 19976 ---------------------------------------------------------- */ 19977function uncode_progress_bar() { 19978 jQuery.each(jQuery('.vc_progress_bar'), function(index, val) { 19979 if (UNCODE.isUnmodalOpen && !val.closest('#unmodal-content')) { 19980 return; 19981 } 19982 if (!UNCODE.isMobile) { 19983 new Waypoint({ 19984 context: UNCODE.isUnmodalOpen ? document.getElementById('unmodal-content') : window, 19985 element: val, 19986 handler: function() { 19987 var element = jQuery(this.element); 19988 element.find('.vc_single_bar').each(function(index) { 19989 var $this = jQuery(this), 19990 bar = $this.find('.vc_bar'), 19991 val = bar.data('percentage-value'); 19992 setTimeout(function() { 19993 bar.css({ 19994 "width": val + '%' 19995 }); 19996 }, index * 200); 19997 }); 19998 }, 19999 offset: '80%' 20000 }); 20001 } else { 20002 var element = jQuery(val); 20003 element.find('.vc_single_bar').each(function(index) { 20004 var $this = jQuery(this), 20005 bar = $this.find('.vc_bar'), 20006 val = bar.data('percentage-value'); 20007 setTimeout(function() { 20008 bar.css({ 20009 "width": val + '%' 20010 }); 20011 }, index * 200); 20012 }); 20013 } 20014 }); 20015}; 20016uncode_progress_bar(); 20017 20018/*! 20019 * jquery.counterup.js 1.0 20020 * 20021 * Copyright 2013, Benjamin Intal http://gambit.ph @bfintal 20022 * Released under the GPL v2 License 20023 * 20024 * Date: Nov 26, 2013 20025 */ 20026(function($) { 20027 "use strict"; 20028 $.fn.counterUp = function(options) { 20029 // Defaults 20030 var settings = $.extend({ 20031 'time': 400, 20032 'delay': 10 20033 }, options); 20034 return this.each(function() { 20035 // Store the object 20036 var $this = $(this); 20037 var $settings = settings; 20038 var counterUpper = function() { 20039 var nums = []; 20040 var divisions = $settings.time / $settings.delay; 20041 var numReal = $this.attr('data-val'), 20042 num = numReal; 20043 var isComma = /[0-9]+,[0-9]+/.test(num); 20044 num = num.replace(/,/g, ''); 20045 var isInt = /^[0-9]+$/.test(num); 20046 var isFloat = /^[0-9]+\.[0-9]+$/.test(num); 20047 var decimalPlaces = isFloat ? (num.split('.')[1] || []).length : 0; 20048 // Generate list of incremental numbers to display 20049 for (var i = divisions; i >= 1; i--) { 20050 // Preserve as int if input was int 20051 var newNum = parseInt(num / divisions * i); 20052 // Preserve float if input was float 20053 if (isFloat) { 20054 newNum = parseFloat(num / divisions * i).toFixed(decimalPlaces); 20055 } 20056 // Preserve commas if input had commas 20057 if (isComma) { 20058 while (/(\d+)(\d{3})/.test(newNum.toString())) { 20059 newNum = newNum.toString().replace(/(\d+)(\d{3})/, '$1' + ',' + '$2'); 20060 } 20061 } 20062 nums.unshift(newNum); 20063 } 20064 nums.push(numReal); 20065 $this.data('counterup-nums', nums); 20066 $this.text('0'); 20067 // Updates the number until we're done 20068 var f = function() { 20069 if ($this.data('counterup-nums') != null) { 20070 $this.text($this.data('counterup-nums').shift()); 20071 if ($this.data('counterup-nums').length) { 20072 setTimeout($this.data('counterup-func'), $settings.delay); 20073 } else { 20074 delete $this.data('counterup-nums'); 20075 $this.data('counterup-nums', null); 20076 $this.data('counterup-func', null); 20077 } 20078 } 20079 }; 20080 $this.data('counterup-func', f); 20081 // Start the count up 20082 setTimeout($this.data('counterup-func'), $settings.delay); 20083 }; 20084 // Perform counts when the element gets into view 20085 new Waypoint({ 20086 context: UNCODE.isUnmodalOpen ? document.getElementById('unmodal-content') : window, 20087 element: this, 20088 handler: function() { 20089 counterUpper(); 20090 if (!UNCODE.isUnmodalOpen) { 20091 this.destroy(); 20092 } 20093 }, 20094 offset: '100%' 20095 }); 20096 }); 20097 }; 20098})(jQuery); 20099 20100/*! 20101 * The Final Countdown for jQuery v2.2.0 (http://hilios.github.io/jQuery.countdown/) 20102 * Copyright (c) 2016 Edson Hilios 20103 * 20104 * Permission is hereby granted, free of charge, to any person obtaining a copy of 20105 * this software and associated documentation files (the "Software"), to deal in 20106 * the Software without restriction, including without limitation the rights to 20107 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 20108 * the Software, and to permit persons to whom the Software is furnished to do so, 20109 * subject to the following conditions: 20110 * 20111 * The above copyright notice and this permission notice shall be included in all 20112 * copies or substantial portions of the Software. 20113 * 20114 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20115 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 20116 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 20117 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20118 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20119 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20120 */ 20121(function(factory) { 20122 "use strict"; 20123 if (typeof define === "function" && define.amd) { 20124 define([ "jquery" ], factory); 20125 } else { 20126 factory(jQuery); 20127 } 20128})(function($) { 20129 "use strict"; 20130 var instances = [], matchers = [], defaultOptions = { 20131 precision: 100, 20132 elapse: false, 20133 defer: false 20134 }; 20135 matchers.push(/^[0-9]*$/.source); 20136 matchers.push(/([0-9]{1,2}\/){2}[0-9]{4}( [0-9]{1,2}(:[0-9]{2}){2})?/.source); 20137 matchers.push(/[0-9]{4}([\/\-][0-9]{1,2}){2}( [0-9]{1,2}(:[0-9]{2}){2})?/.source); 20138 matchers = new RegExp(matchers.join("|")); 20139 function parseDateString(dateString) { 20140 if (dateString instanceof Date) { 20141 return dateString; 20142 } 20143 if (String(dateString).match(matchers)) { 20144 if (String(dateString).match(/^[0-9]*$/)) { 20145 dateString = Number(dateString); 20146 } 20147 if (String(dateString).match(/\-/)) { 20148 dateString = String(dateString).replace(/\-/g, "/"); 20149 } 20150 return new Date(dateString); 20151 } else { 20152 throw new Error("Couldn't cast `" + dateString + "` to a date object."); 20153 } 20154 } 20155 var DIRECTIVE_KEY_MAP = { 20156 Y: "years", 20157 m: "months", 20158 n: "daysToMonth", 20159 d: "daysToWeek", 20160 w: "weeks", 20161 W: "weeksToMonth", 20162 H: "hours", 20163 M: "minutes", 20164 S: "seconds", 20165 D: "totalDays", 20166 I: "totalHours", 20167 N: "totalMinutes", 20168 T: "totalSeconds" 20169 }; 20170 function escapedRegExp(str) { 20171 var sanitize = str.toString().replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1"); 20172 return new RegExp(sanitize); 20173 } 20174 function strftime(offsetObject) { 20175 return function(format) { 20176 var directives = format.match(/%(-|!)?[A-Z]{1}(:[^;]+;)?/gi); 20177 if (directives) { 20178 for (var i = 0, len = directives.length; i < len; ++i) { 20179 var directive = directives[i].match(/%(-|!)?([a-zA-Z]{1})(:[^;]+;)?/), regexp = escapedRegExp(directive[0]), modifier = directive[1] || "", plural = directive[3] || "", value = null; 20180 directive = directive[2]; 20181 if (DIRECTIVE_KEY_MAP.hasOwnProperty(directive)) { 20182 value = DIRECTIVE_KEY_MAP[directive]; 20183 value = Number(offsetObject[value]); 20184 } 20185 if (value !== null) { 20186 if (modifier === "!") { 20187 value = pluralize(plural, value); 20188 } 20189 if (modifier === "") { 20190 if (value < 10) { 20191 value = "0" + value.toString(); 20192 } 20193 } 20194 format = format.replace(regexp, value.toString()); 20195 } 20196 } 20197 } 20198 format = format.replace(/%%/, "%"); 20199 return format; 20200 }; 20201 } 20202 function pluralize(format, count) { 20203 var plural = "s", singular = ""; 20204 if (format) { 20205 format = format.rep
vendor: 8,618 bytes, lines 20205-20349
20205lace(/(:|;|\s)/gi, "").split(/\,/); 20206 if (format.length === 1) { 20207 plural = format[0]; 20208 } else { 20209 singular = format[0]; 20210 plural = format[1]; 20211 } 20212 } 20213 if (Math.abs(count) > 1) { 20214 return plural; 20215 } else { 20216 return singular; 20217 } 20218 } 20219 var Countdown = function(el, finalDate, options) { 20220 this.el = el; 20221 this.$el = $(el); 20222 this.interval = null; 20223 this.offset = {}; 20224 this.options = $.extend({}, defaultOptions); 20225 this.instanceNumber = instances.length; 20226 instances.push(this); 20227 this.$el.data("countdown-instance", this.instanceNumber); 20228 if (options) { 20229 if (typeof options === "function") { 20230 this.$el.on("update.countdown", options); 20231 this.$el.on("stoped.countdown", options); 20232 this.$el.on("finish.countdown", options); 20233 } else { 20234 this.options = $.extend({}, defaultOptions, options); 20235 } 20236 } 20237 this.setFinalDate(finalDate); 20238 if (this.options.defer === false) { 20239 this.start(); 20240 } 20241 }; 20242 $.extend(Countdown.prototype, { 20243 start: function() { 20244 if (this.interval !== null) { 20245 clearInterval(this.interval); 20246 } 20247 var self = this; 20248 this.update(); 20249 this.interval = setInterval(function() { 20250 self.update.call(self); 20251 }, this.options.precision); 20252 }, 20253 stop: function() { 20254 clearInterval(this.interval); 20255 this.interval = null; 20256 this.dispatchEvent("stoped"); 20257 }, 20258 toggle: function() { 20259 if (this.interval) { 20260 this.stop(); 20261 } else { 20262 this.start(); 20263 } 20264 }, 20265 pause: function() { 20266 this.stop(); 20267 }, 20268 resume: function() { 20269 this.start(); 20270 }, 20271 remove: function() { 20272 this.stop.call(this); 20273 instances[this.instanceNumber] = null; 20274 delete this.$el.data().countdownInstance; 20275 }, 20276 setFinalDate: function(value) { 20277 this.finalDate = parseDateString(value); 20278 }, 20279 update: function() { 20280 if (this.$el.closest("html").length === 0) { 20281 this.remove(); 20282 return; 20283 } 20284 var hasEventsAttached = $._data(this.el, "events") !== undefined, now = new Date(), newTotalSecsLeft; 20285 newTotalSecsLeft = this.finalDate.getTime() - now.getTime(); 20286 newTotalSecsLeft = Math.ceil(newTotalSecsLeft / 1e3); 20287 newTotalSecsLeft = !this.options.elapse && newTotalSecsLeft < 0 ? 0 : Math.abs(newTotalSecsLeft); 20288 if (this.totalSecsLeft === newTotalSecsLeft || !hasEventsAttached) { 20289 return; 20290 } else { 20291 this.totalSecsLeft = newTotalSecsLeft; 20292 } 20293 this.elapsed = now >= this.finalDate; 20294 this.offset = { 20295 seconds: this.totalSecsLeft % 60, 20296 minutes: Math.floor(this.totalSecsLeft / 60) % 60, 20297 hours: Math.floor(this.totalSecsLeft / 60 / 60) % 24, 20298 days: Math.floor(this.totalSecsLeft / 60 / 60 / 24) % 7, 20299 daysToWeek: Math.floor(this.totalSecsLeft / 60 / 60 / 24) % 7, 20300 daysToMonth: Math.floor(this.totalSecsLeft / 60 / 60 / 24 % 30.4368), 20301 weeks: Math.floor(this.totalSecsLeft / 60 / 60 / 24 / 7), 20302 weeksToMonth: Math.floor(this.totalSecsLeft / 60 / 60 / 24 / 7) % 4, 20303 months: Math.floor(this.totalSecsLeft / 60 / 60 / 24 / 30.4368), 20304 years: Math.abs(this.finalDate.getFullYear() - now.getFullYear()), 20305 totalDays: Math.floor(this.totalSecsLeft / 60 / 60 / 24), 20306 totalHours: Math.floor(this.totalSecsLeft / 60 / 60), 20307 totalMinutes: Math.floor(this.totalSecsLeft / 60), 20308 totalSeconds: this.totalSecsLeft 20309 }; 20310 if (!this.options.elapse && this.totalSecsLeft === 0) { 20311 this.stop(); 20312 this.dispatchEvent("finish"); 20313 } else { 20314 this.dispatchEvent("update"); 20315 } 20316 }, 20317 dispatchEvent: function(eventName) { 20318 var event = $.Event(eventName + ".countdown"); 20319 event.finalDate = this.finalDate; 20320 event.elapsed = this.elapsed; 20321 event.offset = $.extend({}, this.offset); 20322 event.strftime = strftime(this.offset); 20323 this.$el.trigger(event); 20324 } 20325 }); 20326 $.fn.countdown = function() { 20327 var argumentsArray = Array.prototype.slice.call(arguments, 0); 20328 return this.each(function() { 20329 var instanceNumber = $(this).data("countdown-instance"); 20330 if (instanceNumber !== undefined) { 20331 var instance = instances[instanceNumber], method = argumentsArray[0]; 20332 if (Countdown.prototype.hasOwnProperty(method)) { 20333 instance[method].apply(instance, argumentsArray.slice(1)); 20334 } else if (String(method).match(/^[$A-Z_][0-9A-Z_$]*$/i) === null) { 20335 instance.setFinalDate.call(instance, method); 20336 instance.start(); 20337 } else { 20338 $.error("Method %s does not exist on jQuery.countdown".replace(/\%s/gi, method)); 20339 } 20340 } else { 20341 new Countdown(this, argumentsArray[0], argumentsArray[1]); 20342 } 20343 }); 20344 }; 20345}); 20346 20347!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.Share=e()}}(function(){var define,module,exports; 20348function getStyles(config){ 20349 // return ""+config.selector+"{width:92px;height:20px;-webkit-touch-callout:none;-khtml-user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}"+config.selector+" [class*=social-]:before{font-family:'uncodeicon'}"+config.selector+" label{font-size:16px;cursor:pointer;margin:0;padding:5px 10px;border-radius:5px;background:#a29baa;-webkit-transition:all .3s ease-in-out;transition:all .3s ease-in-out}"+config.selector+" label:hover{opacity:.8}"+config.selector+" label span{text-transform:uppercase;font-size:.9em;font-family:Lato,sans-serif;font-weight:700;-webkit-font-smoothing:antialiased;padding-left:6px}"+config.selector+" .social{opacity:0;-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out;margin-left:-15px;visibility:hidden}"+config.selector+" .social.top{-webkit-transform-origin:0 0;-ms-transform-origin:0 0;transform-origin:0 0;margin-top:-80px}"+config.selector+" .social.bottom{-webkit-transform-origin:0 0;-ms-transform-origin:0 0;transform-origin:0 0;margin-top:5px}"+config.selector+" .social.middle{margin-top:-34px}"+config.selector+" .social.middle.right{-webkit-transform-origin:5% 50%;-ms-transform-origin:5% 50%;transform-origin:5% 50%;margin-left:105px}"+config.selector+" .social.middle.left{-webkit-transform-origin:5% 50%;-ms-transform-origin:5% 50%;transform-origin:5% 50%}"+config.selector+" .social.right{margin-left:14px}"+config.selector+" .social.load{-webkit-transition:none!important;transition:none!important}"+config.selector+" .social.networks-1{width:60px}"+config.selector+" .social.networks-1.center,"+config.selector+" .social.networks-1.left{margin-left:14px}"+config.selector+" .social.networks-1.middle.left{margin-left:-70px}"+config.selector+" .social.networks-1 ul{width:60px}"+config.selector+" .social.networks-2{width:120px}"+config.selector+" .social.networks-2.center{margin-left:-13px}"+config.selector+" .social.networks-2.left{margin-left:-44px}"+config.selector+" .social.networks-2.middle.left{margin-left:-130px}"+config.selector+" .social.networks-2 ul{width:120px}"+config.selector+" .social.networks-3{width:180px}"+config.selector+" .social.networks-3.center{margin-left:-45px}"+config.selector+" .social.networks-3.left{margin-left:-102px}"+config.selector+" .social.networks-3.middle.left{margin-left:-190px}"+config.selector+" .social.networks-3 ul{width:180px}"+config.selector+" .social.networks-4{width:240px}"+config.selector+" .social.networks-4.center{margin-left:-75px}"+config.selector+" .social.networks-4.left{margin-left:162px}"+config.selector+" .social.networks-4.middle.left{margin-left:-250px}"+config.selector+" .social.networks-4 ul{width:240px}"+config.selector+" .social.networks-5{width:300px}"+config.selector+" .social.networks-5.center{margin-left:-105px}"+config.selector+" .social.networks-5.left{margin-left:-225px}"+config.selector+" .social.networks-5.middle.left{margin-left:-320px}"+config.selector+" .social.networks-5 ul{width:300px}"+config.selector+" .social.active{opacity:1;-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out;visibility:visible}"+config.selector+" .social.active.top{-webkit-transform:scale(1) translateY(-20px);-ms-transform:scale(1) translateY(-20px);transform:scale(1) translateY(-20px)}"+config.selector+" .social.active.bottom{-webkit-transform:scale(1) translateY(15px);-ms-transform:scale(1) translateY(15px);transform:scale(1) translateY(15px)}"+config.selector+" .social.active.middle.right{-webkit-transform:scale(1) translateX(10px);-ms-transform:scale(1) translateX(10px);transform:scale(1) translateX(10px)}"+config.selector+" .social.active.middle.left{-webkit-transform:scale(1) translateX(-20px);-ms-transform:scale(1) translateX(-20px);transform:scale(1) translateX(-20px)}"+config.selector+" .social ul{position:relative;
20349left:0;right:0;height:46px;color:#fff;margin:auto;padding:0;list-style:none}"+config.selector+" .social ul li{font-size:20px;cursor:pointer;width:60px;margin:0;padding:12px 0;text-align:center;float:left;display:none;height:22px;position:relative;z-index:2;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-transition:all .3s ease-in-out;transition:all .3s ease-in-out}"+config.selector+" .social ul li:hover{}"+config.selector+" .social li[class*=facebook]{display:"+config.networks.facebook.display+"}"+config.selector+" .social li[class*=twitter]{display:"+config.networks.twitter.display+"}"+config.selector+" .social li[class*=gplus]{display:"+config.networks.google_plus.display+"}"+config.selector+" .social li[class*=pinterest]{display:"+config.networks.pinterest.display+"}"+config.selector+" .social li[class*=paper-plane]{display:"+config.networks.email.display+"}" 20350}; 20351 var ShareUtils; 20352 20353if ((!("classList" in document.documentElement)) && Object.defineProperty && typeof HTMLElement !== "undefined") { 20354 Object.defineProperty(HTMLElement.prototype, "classList", { 20355 get: function() { 20356 var ret, self, update; 20357 update = function(fn) { 20358 return function(value) { 20359 var classes, index; 20360 classes = self.className.split(/\s+/); 20361 index = classes.indexOf(value); 20362 fn(classes, index, value); 20363 self.className = classes.join(" "); 20364 }; 20365 }; 20366 self = this; 20367 ret = { 20368 add: update(function(classes, index, value) { 20369 ~index || classes.push(value); 20370 }), 20371 remove: update(function(classes, index) { 20372 ~index && classes.splice(index, 1); 20373 }), 20374 toggle: update(function(classes, index, value) { 20375 if (~index) { 20376 classes.splice(index, 1); 20377 } else { 20378 classes.push(value); 20379 } 20380 }), 20381 contains: function(value) { 20382 return !!~self.className.split(/\s+/).indexOf(value); 20383 }, 20384 item: function(i) { 20385 return self.className.split(/\s+/)[i] || null; 20386 } 20387 }; 20388 Object.defineProperty(ret, "length", { 20389 get: function() { 20390 return self.className.split(/\s+/).length; 20391 } 20392 }); 20393 return ret; 20394 } 20395 }); 20396} 20397 20398String.prototype.to_rfc3986 = function() { 20399 var tmp; 20400 tmp = encodeURIComponent(this); 20401 return tmp.replace(/[!'()*]/g, function(c) { 20402 return "%" + c.charCodeAt(0).toString(16); 20403 }); 20404}; 20405 20406ShareUtils = (function() { 20407 function ShareUtils() {} 20408 20409 ShareUtils.prototype.extend = function(to, from, overwrite) { 20410 var hasProp, prop; 20411 for (prop in from) { 20412 hasProp = to[prop] !== undefined; 20413 if (hasProp && typeof from[prop] === "object") { 20414 this.extend(to[prop], from[prop], overwrite); 20415 } else { 20416 if (overwrite || !hasProp) { 20417 to[prop] = from[prop]; 20418 } 20419 } 20420 } 20421 }; 20422 20423 ShareUtils.prototype.hide = function(el) { 20424 return el.style.display = "none"; 20425 }; 20426 20427 ShareUtils.prototype.show = function(el) { 20428 return el.style.display = "block"; 20429 }; 20430 20431 ShareUtils.prototype.has_class = function(el, class_name) { 20432 return el.classList.contains(class_name); 20433 }; 20434 20435 ShareUtils.prototype.add_class = function(el, class_name) { 20436 return el.classList.add(class_name); 20437 }; 20438 20439 ShareUtils.prototype.remove_class = function(el, class_name) { 20440 return el.classList.remove(class_name); 20441 }; 20442 20443 ShareUtils.prototype.is_encoded = function(str) { 20444 str = str.to_rfc3986(); 20445 return decodeURIComponent(str) !== str; 20446 }; 20447 20448 ShareUtils.prototype.encode = function(str) { 20449 if (typeof str === "undefined" || this.is_encoded(str)) { 20450 return str; 20451 } else { 20452 return str.to_rfc3986(); 20453 } 20454 }; 20455 20456 ShareUtils.prototype.popup = function(url, params) { 20457 var k, popup, qs, v; 20458 if (params == null) { 20459 params = {}; 20460 } 20461 popup = { 20462 width: 500, 20463 height: 350 20464 }; 20465 popup.top = (screen.height / 2) - (popup.height / 2); 20466 popup.left = (screen.width / 2) - (popup.width / 2); 20467 qs = ((function() { 20468 var _results; 20469 _results = []; 20470 for (k in params) { 20471 v = params[k]; 20472 _results.push("" + k + "=" + (this.encode(v))); 20473 } 20474 return _results; 20475 }).call(this)).join('&'); 20476 if (qs) { 20477 qs = "?" + qs; 20478 } 20479 return window.open(url + qs, 'targetWindow', "toolbar=no,location=no,status=no,menubar=no,scrollbars=yes,resizable=yes,left=" + popup.left + ",top=" + popup.top + ",width="
20479+ popup.width + ",height=" + popup.height); 20480 }; 20481 20482 return ShareUtils; 20483 20484})(); 20485var Share, 20486 __hasProp = {}.hasOwnProperty, 20487 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; 20488 20489Share = (function(_super) { 20490 __extends(Share, _super); 20491 20492 function Share(element, options) { 20493 this.element = element; 20494 this.el = { 20495 head: document.getElementsByTagName('head')[0], 20496 body: document.getElementsByTagName('body')[0] 20497 }; 20498 this.config = { 20499 enabled_networks: 0, 20500 protocol: ['http', 'https'].indexOf(window.location.href.split(':')[0]) === -1 ? 'https://' : '//', 20501 url: window.location.href.replace("&", "%26"), 20502 caption: null, 20503 title: this.default_title(), 20504 image: this.default_image(), 20505 description: this.default_description(), 20506 ui: { 20507 flyout: 'top center', 20508 button_text: 'Share', 20509 button_font: true, 20510 icon_font: true 20511 }, 20512 networks: { 20513 twitter: { 20514 enabled: true, 20515 url: null, 20516 title: null, 20517 description: null 20518 }, 20519 facebook: { 20520 enabled: true, 20521 load_sdk: true, 20522 url: null, 20523 app_id: null, 20524 title: null, 20525 caption: null, 20526 description: null, 20527 image: null 20528 }, 20529 pinterest: { 20530 enabled: true, 20531 url: null, 20532 image: null, 20533 description: null 20534 }, 20535 reddit: { 20536 enabled: true, 20537 url: null, 20538 title: null 20539 }, 20540 linkedin: { 20541 enabled: true, 20542 url: null, 20543 title: null, 20544 description: null 20545 }, 20546 xing: { 20547 enabled: true, 20548 url: null, 20549 title: null, 20550 image: null, 20551 description: null 20552 }, 20553 whatsapp: { 20554 enabled: true, 20555 description: null, 20556 url: null 20557 }, 20558 email: { 20559 enabled: true, 20560 title: null, 20561 description: null, 20562 url: null 20563 } 20564 } 20565 }; 20566 this.setup(element, options); 20567 return this; 20568 } 20569 20570 Share.prototype.setup = function(element, opts) { 20571 var index, instance, instances, _i, _len; 20572 instances = document.querySelectorAll(element); 20573 this.extend(this.config, opts, true); 20574 this.set_global_configuration(); 20575 this.normalize_network_configuration(); 20576 if (this.config.ui.icon_font) { 20577 this.inject_icons(); 20578 } 20579 if (this.config.ui.button_font) { 20580 this.inject_fonts(); 20581 } 20582 if (this.config.networks.facebook.enabled && this.config.networks.facebook.load_sdk) { 20583 this.inject_facebook_sdk(); 20584 } 20585 for (index = _i = 0, _len = instances.length; _i < _len; index = ++_i) { 20586 instance = instances[index]; 20587 this.setup_instance(element, index); 20588 } 20589 }; 20590 20591 Share.prototype.setup_instance = function(element, index) { 20592 var button, instance, label, network, networks, _i, _len, _results, 20593 _this = this; 20594 instance = document.querySelectorAll(element)[index]; 20595 this.hide(instance); 20596 this.add_class(instance, "sharer-" + index); 20597 instance = document.querySelectorAll(element)[index]; 20598 this.inject_css(instance); 20599 this.inject_html(instance); 20600 this.show(instance); 20601 label = instance.getElementsByTagName("label")[0]; 20602 button = instance.getElementsByClassName("social")[0]; 20603 networks = instance.getElementsByTagName('li'); 20604 this.add_class(button, "networks-" + this.config.enabled_networks); 20605 label.addEventListener("click", function() { 20606 return _this.event_toggle(button); 20607 }); 20608 _this = this; 20609 _results = []; 20610 for (index = _i = 0, _len = networks.length; _i < _len; index = ++_i) { 20611 network = networks[index]; 20612 _results.push(network.addEventListener("click", function() { 20613 _this.event_network(instance, this); 20614 return _this.event_close(button); 20615 })); 20616 } 20617 return _results; 20618 }; 20619 20620 Share.prototype.event_toggle = function(button) { 20621 if (this.has_class(button, "active")) { 20622 return this.event_close(button); 20623 } else { 20624 return this.event_open(button); 20625 } 20626 }; 20627 20628 Share.prototype.event_open = function(button) { 20629 if (this.has_class(button, "load")) { 20630 this.remove_class(button, "load"); 20631 } 20632 return this.add_class(button, "active"); 20633 }; 20634 20635 Share.prototype.event_close = function(button) { 20636 return this.remove_class(button, "active"); 20637 }; 20638 20639 Share.prototype.event_network = function(instance, network) { 20640 var name; 20641 name = network.getAttribute("data-network"); 20642 this.hook("before", name, instance);
20643 this["network_" + name](); 20644 return this.hook("after", name, instance); 20645 }; 20646 20647 Share.prototype.open = function() { 20648 return this["public"]("open"); 20649 }; 20650 20651 Share.prototype.close = function() { 20652 return this["public"]("close"); 20653 }; 20654 20655 Share.prototype.toggle = function() { 20656 return this["public"]("toggle"); 20657 }; 20658 20659 Share.prototype["public"] = function(action) { 20660 var button, index, instance, _i, _len, _ref, _results; 20661 _ref = document.querySelectorAll(this.element); 20662 _results = []; 20663 for (index = _i = 0, _len = _ref.length; _i < _len; index = ++_i) { 20664 instance = _ref[index]; 20665 button = instance.getElementsByClassName("social")[0]; 20666 _results.push(this["event_" + action](button)); 20667 } 20668 return _results; 20669 }; 20670 20671 Share.prototype.network_facebook = function() { 20672 if (this.config.networks.facebook.load_sdk) { 20673 if (!window.FB) { 20674 return console.error("The Facebook JS SDK hasn't loaded yet."); 20675 } 20676 return FB.ui({ 20677 method: 'feed', 20678 name: this.config.networks.facebook.title, 20679 link: this.config.networks.facebook.url, 20680 picture: this.config.networks.facebook.image, 20681 caption: this.config.networks.facebook.caption, 20682 description: this.config.networks.facebook.description 20683 }); 20684 } else { 20685 return this.popup('https://www.facebook.com/sharer/sharer.php', { 20686 u: this.config.networks.facebook.url 20687 }); 20688 } 20689 }; 20690 20691 Share.prototype.network_twitter = function() { 20692 return this.popup('https://twitter.com/intent/tweet', { 20693 text: this.config.networks.twitter.title, 20694 url: this.config.networks.twitter.url 20695 }); 20696 }; 20697 20698 Share.prototype.network_pinterest = function() { 20699 return this.popup('https://www.pinterest.com/pin/create/button', { 20700 url: this.config.networks.pinterest.url, 20701 media: this.config.networks.pinterest.image, 20702 description: this.config.networks.pinterest.description 20703 }); 20704 }; 20705 20706 Share.prototype.network_linkedin = function() { 20707 return this.popup('https://www.linkedin.com/shareArticle', { 20708 url: this.config.networks.linkedin.url, 20709 title: this.config.networks.linkedin.title, 20710 summary: this.config.networks.linkedin.description 20711 }); 20712 } 20713 20714 Share.prototype.network_xing = function() { 20715 return this.popup('https://www.xing.com/spi/shares/new', { 20716 url: this.config.networks.xing.url, 20717 image: this.config.networks.xing.image, 20718 title: this.config.networks.xing.title, 20719 summary: this.config.networks.xing.description 20720 }); 20721 } 20722 20723 Share.prototype.network_email = function() { 20724 return this.popup('mailto:', { 20725 subject: this.config.networks.email.title, 20726 body: this.config.networks.email.url + '%0A%0A' + this.config.networks.email.description, 20727 }); 20728 }; 20729 20730 Share.prototype.inject_icons = function() { 20731 // return this.inject_stylesheet("https://www.sharebutton.co/fonts/v2/entypo.min.css"); 20732 }; 20733 20734 Share.prototype.inject_fonts = function() { 20735 // return this.inject_stylesheet("http://fonts.googleapis.com/css?family=Lato:900&text=" + this.config.ui.button_text); 20736 }; 20737 20738 Share.prototype.inject_stylesheet = function(url) { 20739 var link; 20740 if (!this.el.head.querySelector("link[href=\"" + url + "\"]")) { 20741 link = document.createElement("link"); 20742 link.setAttribute("rel", "stylesheet"); 20743 link.setAttribute("href", url); 20744 return this.el.head.appendChild(link); 20745 } 20746 }; 20747 20748 Share.prototype.inject_css = function(instance) { 20749 var css, meta, selector, style; 20750 selector = "." + (instance.getAttribute('class').split(" ").join(".")); 20751 if (!this.el.head.querySelector("meta[name='sharer" + selector + "']")) { 20752 this.config.selector = selector; 20753 css = getStyles(this.config); 20754 style = document.createElement("style"); 20755 style.type = "text/css"; 20756 if (style.styleSheet) { 20757 style.styleSheet.cssText = css; 20758 } else { 20759 style.appendChild(document.createTextNode(css)); 20760 } 20761 this.el.head.appendChild(style); 20762 delete this.config.selector; 20763 meta = document.createElement("meta"); 20764 meta.setAttribute("name", "sharer" + selector); 20765 return this.el.head.appendChild(meta); 20766 } 20767 }; 20768 20769 Share.prototype.inject_html = function(instance) { 20770 //return instance.innerHTML = "<label class='social-export'><span>" + this.config.ui.button_text + "</span></label><div class='social load " + this.config.ui.flyout + "'><ul><li class='social-facebook' data-network='facebook' tabindex='0'></li><li class='social-twitter' data-network='twitter' tabindex='0'></li><li class='social-gplus' data-network='google_plus' tabindex='0'></li><li class='social-pinterest' data-network='pinterest' tabindex='0'></li><li class='social-linkedin' data-network='linkedin' tabindex='0'></li><li class='social-xing' data-network='xing' tabindex='0'></li><li class='social-paper-plane' data-network='email' tabindex='0'></li></ul></div>"; 20771 return instance.innerHTML = "<label class='social-export'><span>" + this.config.ui.button_text + "</span></label><div class='social load " + this.config.ui.flyout + "'><ul><li class='social-facebook' data-network='facebook' tabindex='0'></li><li class='social-twitter' data-network='twitter' tabindex='0'></li><li class='social-pinterest' data-network='pinterest' tabindex='0'></li><li class='social-linkedin' data-network='linkedin' tabindex='0'></li><li class='social-xing' data-network='xing' tabindex='0'></li><li class='social-paper-plane' data-network='email' tabindex='0'></li></ul></div>"; 20772 }; 20773 20774 Share.prototype.inject_facebook_sdk = function() { 20775 var fb_root, script; 20776 if (!window.FB && this.config.networks.facebook.app_id && !this.el.body.querySelector('#fb-root')) { 20777 script = document.createElement("script"); 20778 script.text = "window.fbAsyncInit=function(){FB.init({appId:'" + this.config.networks.facebook.app_id + "',status:true,xfbml:true})};(function(e,t,n){var r,i=e.getElementsByTagName(t)[0];if(e.getElementById(n)){return}r=e.createElement(t);r.id=n;r.src='" + this.config.protocol + "connect.facebook.net/en_US/all.js';i.parentNode.insertBefore(r,i)})(document,'script','facebook-jssdk')"; 20779 fb_root = document.createElement("div"); 20780 fb_root.id = "fb-root"; 20781 this.el.body.appendChild(fb_root); 20782 return this.el.body.appendChild(script); 20783 } 20784 }; 20785 20786 Share.prototype.hook = function(type, network, instance) { 20787 var fn, opts; 20788 fn = this.config.networks[network][type]; 20789 if (typeof fn === "function") { 20790 opts = fn.call(this.config.networks[network], instance); 20791 if (opts !== void 0) { 20792 opts = this.normalize_filter_config_updates(opts); 20793 this.extend(this.config.networks[network], opts, true); 20794 this.normalize_network_configuration(); 20795 } 20796 } 20797 }; 20798 20799 Share.prototype.default_title = function() { 20800 var content; 20801 if (content = document.querySelector('meta[property="og:title"]') || document.querySelector('meta[name="twitter:title"]')) { 20802 return encodeURIComponent(content.getAttribute('content')); 20803 } else if (content = document.querySelector('title')) { 20804 return encodeURIComponent(content.innerText); 20805 } 20806 }; 20807 20808 Share.prototype.default_image = function() { 20809 var content; 20810 if (content = document.querySelector('meta[property="og:image"]') || document.querySelector('meta[name="twitter:image"]')) { 20811 return content.getAttribute('content'); 20812 } 20813 }; 20814 20815 Share.prototype.default_description = function() { 20816 var content; 20817 if (content = document.querySelector('meta[property="og:description"]') || document.querySelector('meta[name="twitter:description"]') || document.querySelector('meta[name="description"]')) { 20818 return encodeURIComponent(content.getAttribute('content')); 20819 } else { 20820 return ''; 20821 } 20822 }; 20823 20824 Share.prototype.set_global_configuration = function() { 20825 var display, network, option, options, _ref, _results; 20826 _ref = this.config.networks; 20827 _results = []; 20828 for (network in _ref) { 20829 options = _ref[network]; 20830 for (option in options) { 20831 if (this.config.networks[network][option] == null) { 20832 this.config.networks[network][option] = this.config[option]; 20833 } 20834 } 20835 if (this.config.networks[network].enabled) { 20836 display = 'block'; 20837 this.config.enabled_networks += 1; 20838 } else { 20839 display = 'none'; 20840 } 20841 _results.push(this.config.networks[network].display = display); 20842 } 20843 return _results; 20844 }; 20845 20846 Share.prototype.normalize_network_configuration = function() { 20847 if (!this.config.networks.facebook.app_id) { 20848 this.config.networks.facebook.load_sdk = false;
20849 } 20850 if (!this.is_encoded(this.config.networks.twitter.description)) { 20851 this.config.networks.twitter.description = encodeURIComponent(this.config.networks.twitter.description); 20852 } 20853 if (typeof this.config.networks.facebook.app_id === 'number') { 20854 return this.config.networks.facebook.app_id = this.config.networks.facebook.app_id.toString(); 20855 } 20856 }; 20857 20858 Share.prototype.normalize_filter_config_updates = function(opts) { 20859 if (this.config.networks.facebook.app_id !== opts.app_id) { 20860 console.warn("You are unable to change the Facebook app_id after the button has been initialized. Please-in-out update your Facebook filters accordingly."); 20861 delete opts.app_id; 20862 } 20863 if (this.config.networks.facebook.load_sdk !== opts.load_sdk) { 20864 console.warn("You are unable to change the Facebook load_sdk option after the button has been initialized. Please-in-out update your Facebook filters accordingly."); 20865 delete opts.app_id; 20866 } 20867 return opts; 20868 }; 20869 20870 return Share; 20871 20872})(ShareUtils); 20873 return Share; 20874}); 20875 20876// Generated by CoffeeScript 1.9.2 20877 20878// @license Sticky-kit v1.1.2 | WTFPL | Leaf Corcoran 2015 | http://leafo.net 20879 20880(function() { 20881 var $, win; 20882 20883 $ = this.jQuery || window.jQuery; 20884 20885 win = $(window); 20886 20887 $.fn.stick_in_parent = function(opts) { 20888 var doc, elm, enable_bottoming, fn, i, inner_scrolling, len, manual_spacer, offset_top, outer_width, parent_selector, recalc_every, sticky_class; 20889 if (opts == null) { 20890 opts = {}; 20891 } 20892 sticky_class = opts.sticky_class, inner_scrolling = opts.inner_scrolling, recalc_every = opts.recalc_every, parent_selector = opts.parent, offset_top = opts.offset_top, manual_spacer = opts.spacer, enable_bottoming = opts.bottoming; 20893 if (offset_top == null) { 20894 offset_top = 0; 20895 } 20896 if (parent_selector == null) { 20897 parent_selector = void 0; 20898 } 20899 if (inner_scrolling == null) { 20900 inner_scrolling = true; 20901 } 20902 if (sticky_class == null) { 20903 sticky_class = "is_stuck"; 20904 } 20905 doc = $(document); 20906 if (enable_bottoming == null) { 20907 enable_bottoming = true; 20908 } 20909 outer_width = function(el) { 20910 var _el, computed, w; 20911 if (window.getComputedStyle) { 20912 _el = el[0]; 20913 computed = window.getComputedStyle(el[0]); 20914 w = parseFloat(computed.getPropertyValue("width")) + parseFloat(computed.getPropertyValue("margin-left")) + parseFloat(computed.getPropertyValue("margin-right")); 20915 if (computed.getPropertyValue("box-sizing") !== "border-box") { 20916 w += parseFloat(computed.getPropertyValue("border-left-width")) + parseFloat(computed.getPropertyValue("border-right-width")) + parseFloat(computed.getPropertyValue("padding-left")) + parseFloat(computed.getPropertyValue("padding-right")); 20917 } 20918 return w; 20919 } else { 20920 return el.outerWidth(true); 20921 } 20922 }; 20923 fn = function(elm, padding_bottom, parent_top, parent_height, top, height, el_float, detached) { 20924 var bottomed, detach, fixed, last_pos, last_scroll_height, offset, parent, recalc, recalc_and_tick, recalc_counter, spacer, tick; 20925 if (elm.data("sticky_kit")) { 20926 return; 20927 } 20928 elm.data("sticky_kit", true); 20929 last_scroll_height = doc.height(); 20930 parent = elm.parent(); 20931 if (parent_selector != null) { 20932 parent = parent.closest(parent_selector); 20933 } 20934 if (!parent.length) { 20935 throw "failed to find stick parent"; 20936 } 20937 fixed = false; 20938 bottomed = false; 20939 spacer = manual_spacer != null ? manual_spacer && elm.closest(manual_spacer) : $("<div />"); 20940 if (spacer) { 20941 spacer.css('position', elm.css('position')); 20942 } 20943 recalc = function() { 20944 var border_top, padding_top, restore; 20945 if (detached) { 20946 return; 20947 } 20948 last_scroll_height = doc.height(); 20949 border_top = parseInt(parent.css("border-top-width"), 10); 20950 padding_top = parseInt(parent.css("padding-top"), 10); 20951 padding_bottom = parseInt(parent.css("padding-bottom"), 10); 20952 parent_top = parent.offset().top + border_top + padding_top; 20953 parent_height = parent.height(); 20954 if (fixed) { 20955 fixed = false;
vendor: 6,068 bytes, lines 20956-21150
20956 bottomed = false; 20957 if (manual_spacer == null) { 20958 elm.insertAfter(spacer); 20959 spacer.detach(); 20960 } 20961 elm.css({ 20962 position: "", 20963 top: "", 20964 width: "", 20965 bottom: "" 20966 }).removeClass(sticky_class); 20967 restore = true; 20968 } 20969 top = elm.offset().top - (parseInt(elm.css("margin-top"), 10) || 0) - offset_top; 20970 height = elm.outerHeight(true); 20971 el_float = elm.css("float"); 20972 if (spacer) { 20973 spacer.css({ 20974 width: outer_width(elm), 20975 height: height, 20976 display: elm.css("display"), 20977 "vertical-align": elm.css("vertical-align"), 20978 "float": el_float 20979 }); 20980 } 20981 if (restore) { 20982 return tick(); 20983 } 20984 }; 20985 recalc(); 20986 if (height === parent_height) { 20987 return; 20988 } 20989 last_pos = void 0; 20990 offset = offset_top; 20991 recalc_counter = recalc_every; 20992 tick = function() { 20993 var css, delta, recalced, scroll, will_bottom, win_height; 20994 if (detached) { 20995 return; 20996 } 20997 recalced = false; 20998 if (recalc_counter != null) { 20999 recalc_counter -= 1; 21000 if (recalc_counter <= 0) { 21001 recalc_counter = recalc_every; 21002 recalc(); 21003 recalced = true; 21004 } 21005 } 21006 if (!recalced && doc.height() !== last_scroll_height) { 21007 recalc(); 21008 recalced = true; 21009 } 21010 scroll = win.scrollTop(); 21011 if (last_pos != null) { 21012 delta = scroll - last_pos; 21013 } 21014 last_pos = scroll; 21015 if (fixed) { 21016 if (enable_bottoming) { 21017 will_bottom = scroll + height + offset > parent_height + parent_top; 21018 if (bottomed && !will_bottom) { 21019 bottomed = false; 21020 elm.css({ 21021 position: "fixed", 21022 bottom: "", 21023 top: offset 21024 }).trigger("sticky_kit:unbottom"); 21025 } 21026 } 21027 if (scroll < top) { 21028 fixed = false; 21029 offset = offset_top; 21030 if (manual_spacer == null) { 21031 if (el_float === "left" || el_float === "right") { 21032 elm.insertAfter(spacer); 21033 } 21034 spacer.detach(); 21035 } 21036 css = { 21037 position: "", 21038 width: "", 21039 top: "" 21040 }; 21041 elm.css(css).removeClass(sticky_class).trigger("sticky_kit:unstick"); 21042 } 21043 if (inner_scrolling) { 21044 win_height = win.height(); 21045 if (height + offset_top > win_height) { 21046 if (!bottomed) { 21047 offset -= delta; 21048 offset = Math.max(win_height - height, offset); 21049 offset = Math.min(offset_top, offset); 21050 if (fixed) { 21051 elm.css({ 21052 top: offset + "px" 21053 }); 21054 } 21055 } 21056 } 21057 } 21058 } else { 21059 if (scroll > top) { 21060 fixed = true; 21061 css = { 21062 position: "fixed", 21063 top: offset 21064 }; 21065 css.width = elm.css("box-sizing") === "border-box" ? elm.outerWidth() + "px" : elm.width() + "px"; 21066 elm.css(css).addClass(sticky_class); 21067 if (manual_spacer == null) { 21068 elm.after(spacer); 21069 if (el_float === "left" || el_float === "right") { 21070 spacer.append(elm); 21071 } 21072 } 21073 elm.trigger("sticky_kit:stick"); 21074 } 21075 } 21076 if (fixed && enable_bottoming) { 21077 if (will_bottom == null) { 21078 will_bottom = scroll + height + offset > parent_height + parent_top; 21079 } 21080 if (!bottomed && will_bottom) { 21081 bottomed = true; 21082 if (parent.css("position") === "static") { 21083 parent.css({ 21084 position: "relative" 21085 }); 21086 } 21087 return elm.css({ 21088 position: "absolute", 21089 bottom: padding_bottom, 21090 top: "auto" 21091 }).trigger("sticky_kit:bottom"); 21092 } 21093 } 21094 }; 21095 recalc_and_tick = function() { 21096 recalc(); 21097 return tick(); 21098 }; 21099 detach = function() { 21100 detached = true; 21101 win.off("touchmove", tick); 21102 win.off("scroll", tick); 21103 win.off("resize", recalc_and_tick); 21104 $(document.body).off("sticky_kit:recalc", recalc_and_tick); 21105 elm.off("sticky_kit:detach", detach); 21106 elm.removeData("sticky_kit"); 21107 elm.css({ 21108 position: "", 21109 bottom: "", 21110 top: "", 21111 width: "" 21112 }); 21113 parent.position("position", ""); 21114 if (fixed) { 21115 if (manual_spacer == null) { 21116 if (el_float === "left" || el_float === "right") { 21117 elm.insertAfter(spacer); 21118 } 21119 spacer.remove(); 21120 } 21121 return elm.removeClass(sticky_class); 21122 } 21123 }; 21124 win.on("touchmove", tick); 21125 win.on("scroll", tick); 21126 win.on("resize", recalc_and_tick); 21127 $(document.body).on("sticky_kit:recalc", recalc_and_tick); 21128 elm.on("sticky_kit:detach", detach); 21129 return setTimeout(tick, 0); 21130 }; 21131 for (i = 0, len = this.length; i < len; i++) { 21132 elm = this[i]; 21133 fn($(elm)); 21134 } 21135 return this; 21136 }; 21137 21138}).call(this); 21139/* ========================================================================== 21140 * bootstrap-tab-history.js 21141 * Author: Michael Narayan <[email protected]> 21142 * Repository: https://github.com/mnarayan01/bootstrap-tab-history/ 21143 * ========================================================================== 21144 * Licensed under the Apache License, Version 2.0 (the "License"); you may 21145 * not use this file except in compliance with the License. You may obtain a 21146 * copy of the License at 21147 * 21148 * http://www.apache.org/licenses/LICENSE-2.0 21149 * 21150 * Unless required by applicable law or agreed to in writing, softw
21150are 21151 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 21152 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 21153 * License for the specific language governing permissions and limitations 21154 * under the License. 21155 * ========================================================================== */ 21156 21157/* ========================================================================== */ 21158/* JSHint directives */ 21159/* */ 21160/* global BootstrapTabHistory: true */ 21161/* */ 21162/* global document */ 21163/* global jQuery */ 21164/* global history */ 21165/* global window */ 21166/* ========================================================================== */ 21167 21168/** 21169 * Integrate [HTML5 history state tracking](https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Manipulating_the_browser_history) 21170 * with [`bootstrap/tab.js`](http://getbootstrap.com/javascript/#tabs). To enable tracking on a tab element, simply set 21171 * the `data-tab-history` attribute to true (or a string denoting a tab grouping). 21172 * 21173 * See the README for additional information. 21174 * 21175 * Functionality based upon bootstrap/tab.js v3.1.0; reference it when making any changes. 21176 */ 21177 21178BootstrapTabHistory = { 21179 options: { 21180 /** 21181 * When the anchor portion of the URI is used to activate a tab, scroll down to the given offset, rather than the 21182 * element with the given `id` attribute. Set to null to disable. Only relevant if showTabsBasedOnAnchor is true. 21183 * 21184 * May be overriden on a per-element basis by the attribute `data-tab-history-anchor-y-offset`. 21185 * 21186 * @public 21187 * @type {?number} 21188 */ 21189 defaultAnchorYOffset: 0, 21190 /** 21191 * Either 'push' or 'replace', for whether to use `history.pushState` or `history.replaceState`, resp. 21192 * 21193 * May be overriden on a per-element basis by the attribute `data-tab-history-changer`. 21194 * 21195 * @public 21196 * @type {string} 21197 */ 21198 defaultChanger: 'replace', 21199 /** 21200 * If true, update the URL in onShownTab in the calls to `history.pushState` and `history.replaceState`. Otherwise, 21201 * `null` is passed as the third parameter to these calls. 21202 * 21203 * May be overriden on a per-element basis by the attribute `data-tab-history-update-url`. 21204 * 21205 * @public 21206 * @type {boolean} 21207 */ 21208 defaultUpdateURL: false, 21209 /** 21210 * Should the anchor portion of the loaded URI be used to activate a single tab if no history was present on page 21211 * load. 21212 * 21213 * @public 21214 * @type {boolean} 21215 */ 21216 showTabsBasedOnAnchor: true 21217 } 21218}; 21219 21220(function () { 21221 'use strict'; 21222 21223 jQuery(function () { 21224 if(history && history.pushState && history.replaceState) { 21225 var bootstrapTabHistory = history.state && history.state.bootstrapTabHistory; 21226 21227 if(bootstrapTabHistory) { 21228 showTabsBasedOnState(bootstrapTabHistory); 21229 } else { 21230 showTabsBasedOnAnchor(); 21231 } 21232 21233 backfillHistoryState(); 21234 21235 jQuery(document).on('shown.bs.tab show.bs.collapse', onShownTab); 21236 jQuery(window).on('popstate', onPopState); 21237 } else { 21238 showTabsBasedOnAnchor(); 21239 } 21240 }); 21241 21242 /** 21243 * Used to prevent onShownTab from registering shown events that we triggered via showTabsBasedOnState. 21244 * 21245 * @type {boolean} 21246 */ 21247 var showingTabsBasedOnState = false; 21248 21249 /** 21250 * Used to update `history.state` to reflect the default active tabs on initial page load. This supports proper 21251 * `history.back` handling when `data-tab-history-update-url` is true. 21252 */ 21253 function backfillHistoryState() { 21254 var newState = null; 21255 21256 jQuery('li.active > [data-tab-history], .panel-title.active [data-tab-history]').each(function () {//edited by Uncode 21257 var $activeTabElement = jQuery(this); 21258 var selector = getTabSelector($activeTabElement); 21259 21260 if(selector) { 21261 var tabGroup = getTabGroup($activeTabElement); 21262 21263 if(tabGroup) { 21264 newState = createNewHistoryState(newState || history.state, tabGroup, selector); 21265 } 21266 } 21267 }); 21268 21269 if(newState) { 21270 history.replaceState(newState, '', null); 21271 } 21272 } 21273 21274 /** 21275 * Clone the existing state, ensure its bootstrapTabHistory attribute is an Object, and add the provided tabGroup to 21276 * said bootstrapTabHistory attribute. 21277 * 21278 * @param {?object} existingState 21279 * @param {!string} tabGroup 21280 * @param {!string} selector 21281 * @returns {!object} 21282 */ 21283 function createNewHistoryState(existingState, tabGroup, selector) { 21284 // Clone history.state and ensure it has a bootstrapTabHistory entry. 21285 var newState = jQuery.extend(true, {}, existingState, { 21286 bootstrapTabHistory: {} 21287 }); 21288 21289 newState.bootstrapTabHistory[tabGroup] = selector; 21290 21291 return newState; 21292 } 21293 21294 /** 21295 * @param {jQuery} $tab
21296 * @returns {?string} 21297 */ 21298 function getTabGroup($tab) { 21299 return parseTruthyAttributeValue($tab.data('tab-history')); 21300 } 21301 21302 /** 21303 * @param {jQuery} $tab 21304 * @returns {?string} 21305 */ 21306 function getTabSelector($tab) { 21307 return $tab.data('target') || $tab.attr('href'); 21308 } 21309 21310 /** 21311 * Receives the `shown.bs.tab` event. Updates `history.state` as appropriate. 21312 * 21313 * @param {jQuery.Event} shownEvt 21314 */ 21315 function onShownTab(shownEvt) { 21316 if(!showingTabsBasedOnState) { 21317 var $activatedTab = jQuery(shownEvt.target); 21318 if ( $activatedTab.hasClass('panel-collapse') ) 21319 $activatedTab = $activatedTab.closest('.panel').find('a'); 21320 var selector = getTabSelector($activatedTab); 21321 21322 if(selector) { 21323 var tabGroup = getTabGroup($activatedTab); 21324 21325 if(tabGroup) { 21326 var historyChanger = $activatedTab.data('tab-history-changer') || BootstrapTabHistory.options.defaultChanger; 21327 var newState = createNewHistoryState(history.state, tabGroup, selector); 21328 var updateURL = (function ($activatedTab) { 21329 if(selector[0] === '#') { 21330 var elementUpdateURLOption = parseTruthyAttributeValue($activatedTab.data('tab-history-update-url')); 21331 21332 if(elementUpdateURLOption === undefined) { 21333 return BootstrapTabHistory.options.defaultUpdateURL; 21334 } else { 21335 return elementUpdateURLOption; 21336 } 21337 } else { 21338 return false; 21339 } 21340 })($activatedTab); 21341 21342 switch(historyChanger) { 21343 case 'push': 21344 history.pushState(newState, '', updateURL ? selector : null); 21345 break; 21346 case 'replace': 21347 history.replaceState(newState, '', updateURL ? selector : null); 21348 break; 21349 default: 21350 throw new Error('Unknown tab-history-changer: ' + historyChanger); 21351 } 21352 } 21353 } 21354 } 21355 } 21356 21357 /** 21358 * Receives the `popstate` event. Shows tabs based on the value of `history.state` as appropriate. 21359 */ 21360 function onPopState() { 21361 var bootstrapTabHistory = history.state && history.state.bootstrapTabHistory; 21362 21363 if(bootstrapTabHistory) { 21364 showTabsBasedOnState(bootstrapTabHistory); 21365 } 21366 } 21367 21368 /** 21369 * Returns the given value, _unless_ that value is an empty string, in which case `true` is returned. 21370 * 21371 * Rationale: HAML data attributes which are set to `true` are rendered as a blank string. 21372 * 21373 * @param {*} value 21374 * @returns {*} 21375 */ 21376 function parseTruthyAttributeValue(value) { 21377 if(value) { 21378 return value; 21379 } else if(value === '') { 21380 return true; 21381 } else { 21382 return value; 21383 } 21384 } 21385 21386 /** 21387 * Show tabs based upon the anchor component of `window.location`. 21388 */ 21389 function showTabsBasedOnAnchor() { 21390 if(BootstrapTabHistory.options.showTabsBasedOnAnchor) { 21391 var anchor = window.location && window.location.hash; 21392 21393 if(anchor) { 21394 var $tabElement = showTabForSelector(anchor); 21395 21396 if($tabElement && window.addEventListener && window.removeEventListener) { 21397 var anchorYOffset = (function ($tabElement) { 21398 var elementSetting = $tabElement.data('tab-history-anchor-y-offset'); 21399 21400 if(elementSetting === undefined) { 21401 return BootstrapTabHistory.options.defaultAnchorYOffset; 21402 } else { 21403 return elementSetting; 21404 } 21405 })($tabElement); 21406 21407 // HACK: This prevents scrolling to the tab on page load. This relies on the fact that we should never get 21408 // here on `history.forward`, `history.back`, or `location.reload`, since in all those situations the 21409 // `history.state` object should have been used (unless the browser did not support the modern History API). 21410 if(anchorYOffset || anchorYOffset === 0) { 21411 var scrollListener = function resetAnchorScroll () { 21412 window.removeEventListener('scroll', scrollListener); 21413 window.scrollTo(0, anchorYOffset); 21414 }; 21415 21416 window.addEventListener('scroll', scrollListener); 21417 } 21418 } 21419 } 21420 } 21421 } 21422 21423 /** 21424 * Show a tab which corresponds to the provided selector. 21425 * 21426 * @param {string} selector - A CSS selector. 21427 * @returns {?jQuery} - The tab which was found to show (even if said tab was already active). 21428 */ 21429 function showTabForSelector(selector) { 21430 var $tabElement = (function (selector) { 21431 var $ret = null; 21432 21433 jQuery('[data-toggle="tab"], [data-toggle="pill"], [data-toggle="collapse"]').each(function () { 21434 var $potentialTab = jQuery(this); 21435 21436 if(($potentialTab.attr('href') === selector || $potentialTab.data('target') === selector ) && getTabGroup($potentialTab)) { 21437 $ret = $potentialTab; 21438 return false;
vendor: 43,417 bytes, lines 21439-22653
21439 } else { 21440 return null; 21441 } 21442 }); 21443 21444 return $ret; 21445 })(selector); 21446 21447 if($tabElement) { 21448 $tabElement.trigger('click'); 21449 //$tabElement.tab('show'); 21450 } 21451 21452 return $tabElement; 21453 } 21454 21455 /** 21456 * Iterate through the provided set of tab tab groups, showing the tabs based on the stored selectors. 21457 * 21458 * @param {object} bootstrapTabHistory - Each of the values is passed to showTabForSelector; the keys are actually irrelevant. 21459 */ 21460 function showTabsBasedOnState(bootstrapTabHistory) { 21461 showingTabsBasedOnState = true; 21462 21463 try { 21464 for(var k in bootstrapTabHistory) { 21465 if(bootstrapTabHistory.hasOwnProperty(k)) { 21466 showTabForSelector(bootstrapTabHistory[k]); 21467 } 21468 } 21469 } finally { 21470 showingTabsBasedOnState = false; 21471 } 21472 } 21473})(); 21474 21475/*! 21476 * justifiedGallery - v3.8.1 21477 * http://miromannino.github.io/Justified-Gallery/ 21478 * Copyright (c) 2020 Miro Mannino 21479 * Licensed under the MIT license. 21480 */ 21481(function (factory) { 21482 if (typeof define === 'function' && define.amd) { 21483 // AMD. Register as an anonymous module. 21484 define(['jquery'], factory); 21485 } else if (typeof module === 'object' && module.exports) { 21486 // Node/CommonJS 21487 module.exports = function (root, jQuery) { 21488 if (jQuery === undefined) { 21489 // require('jQuery') returns a factory that requires window to 21490 // build a jQuery instance, we normalize how we use modules 21491 // that require this pattern but the window provided is a noop 21492 // if it's defined (how jquery works) 21493 if (typeof window !== 'undefined') { 21494 jQuery = require('jquery'); 21495 } 21496 else { 21497 jQuery = require('jquery')(root); 21498 } 21499 } 21500 factory(jQuery); 21501 return jQuery; 21502 }; 21503 } else { 21504 // Browser globals 21505 factory(jQuery); 21506 } 21507}(function ($) { 21508 21509 /** 21510 * Justified Gallery controller constructor 21511 * 21512 * @param $gallery the gallery to build 21513 * @param settings the settings (the defaults are in JustifiedGallery.defaults) 21514 * @constructor 21515 */ 21516 var JustifiedGallery = function ($gallery, settings) { 21517 21518 this.settings = settings; 21519 this.checkSettings(); 21520 21521 this.imgAnalyzerTimeout = null; 21522 this.entries = null; 21523 this.buildingRow = { 21524 entriesBuff: [], 21525 width: 0, 21526 height: 0, 21527 aspectRatio: 0 21528 }; 21529 this.lastFetchedEntry = null; 21530 this.lastAnalyzedIndex = -1; 21531 this.yield = { 21532 every: 2, // do a flush every n flushes (must be greater than 1) 21533 flushed: 0 // flushed rows without a yield 21534 }; 21535 this.border = settings.border >= 0 ? settings.border : settings.margins; 21536 this.maxRowHeight = this.retrieveMaxRowHeight(); 21537 this.suffixRanges = this.retrieveSuffixRanges(); 21538 this.offY = this.border; 21539 this.rows = 0; 21540 this.spinner = { 21541 phase: 0, 21542 timeSlot: 150, 21543 $el: $('<div class="jg-spinner"><span></span><span></span><span></span></div>'), 21544 intervalId: null 21545 }; 21546 this.scrollBarOn = false; 21547 this.checkWidthIntervalId = null; 21548 this.galleryWidth = $gallery.width(); 21549 this.$gallery = $gallery; 21550 21551 }; 21552 21553 /** @returns {String} the best suffix given the width and the height */ 21554 JustifiedGallery.prototype.getSuffix = function (width, height) { 21555 var longestSide, i; 21556 longestSide = (width > height) ? width : height; 21557 for (i = 0; i < this.suffixRanges.length; i++) { 21558 if (longestSide <= this.suffixRanges[i]) { 21559 return this.settings.sizeRangeSuffixes[this.suffixRanges[i]]; 21560 } 21561 } 21562 return this.settings.sizeRangeSuffixes[this.suffixRanges[i - 1]]; 21563 }; 21564 21565 /** 21566 * Remove the suffix from the string 21567 * 21568 * @returns {string} a new string without the suffix 21569 */ 21570 JustifiedGallery.prototype.removeSuffix = function (str, suffix) { 21571 return str.substring(0, str.length - suffix.length); 21572 }; 21573 21574 /** 21575 * @returns {boolean} a boolean to say if the suffix is contained in the str or not 21576 */ 21577 JustifiedGallery.prototype.endsWith = function (str, suffix) { 21578 return str.indexOf(suffix, str.length - suffix.length) !== -1; 21579 }; 21580 21581 /** 21582 * Get the used suffix of a particular url 21583 * 21584 * @param str 21585 * @returns {String} return the used suffix 21586 */ 21587 JustifiedGallery.prototype.getUsedSuffix = function (str) { 21588 for (var si in this.settings.sizeRangeSuffixes) { 21589 if (this.settings.sizeRangeSuffixes.hasOwnProperty(si)) { 21590 if (this.settings.sizeRangeSuffixes[si].length === 0) continue; 21591 if (this.endsWith(str, this.settings.sizeRangeSuffixes[si])) return this.settings.sizeRangeSuffixes[si]; 21592 } 21593 } 21594 return ''; 21595 }; 21596 21597 /** 21598 * Given an image src, with the width and the height, returns the new image src with the 21599 * best suffix to show the best quality thumbnail. 21600 * 21601 * @returns {String} the suffix to use 21602 */ 21603 JustifiedGallery.prototype.newSrc = function (imageSrc, imgWidth, imgHeight, image) { 21604 var newImageSrc; 21605 21606 if (this.settings.thumbnailPath) { 21607 newImageSrc = this.settings.thumbnailPath(imageSrc, imgWidth, imgHeight, image); 21608 } else { 21609 var matchRes = imageSrc.match(this.settings.extension); 21610 var ext = (matchRes !== null) ? matchRes[0] : ''; 21611 newImageSrc = imageSrc.replace(this.settings.extension, ''); 21612 newImageSrc = this.removeSuffix(newImageSrc, this.getUsedSuffix(newImageSrc)); 21613 newImageSrc += this.getSuffix(imgWidth, imgHeight) + ext; 21614 } 21615 21616 return newImageSrc; 21617 }; 21618 21619 /** 21620 * Shows the images that is in the given entry 21621 * 21622 * @param $entry the entry 21623 * @param callback the callback that is called when the show animation is finished 21624 */ 21625 JustifiedGallery.prototype.showImg = function ($entry, callback) { 21626 if (this.settings.cssAnimation) { 21627 $entry.addClass('jg-entry-visible'); 21628 if (callback) callback(); 21629 } else { 21630 $entry.stop().fadeTo(this.settings.imagesAnimationDuration, 1.0, callback); 21631 $entry.find(this.settings.imgSelector).stop().fadeTo(this.settings.imagesAnimationDuration, 1.0, callback); 21632 } 21633 }; 21634 21635 /** 21636 * Extract the image src form the image, looking from the 'safe-src', and if it can't be found, from the 21637 * 'src' attribute. It saves in the image data the 'jg.originalSrc' field, with the extracted src. 21638 * 21639 * @param $image the image to analyze 21640 * @returns {String} the extracted src 21641 */ 21642 JustifiedGallery.prototype.extractImgSrcFromImage = function ($image) { 21643 var imageSrc = $image.data('safe-src'); 21644 var imageSrcLoc = 'data-safe-src'; 21645 // Begin Uncode edit 21646 if (typeof imageSrc === 'undefined') { 21647 var imageCurrentSrc = $image[0].currentSrc; 21648 if (imageCurrentSrc) { 21649 imageSrc = imageCurrentSrc; 21650 } else { 21651 imageSrc = $image.attr('src'); 21652 } 21653 imageSrcLoc = 'src'; 21654 } 21655 // End Uncode edit 21656 $image.data('jg.originalSrc', imageSrc); // this is saved for the destroy method 21657 $image.data('jg.src', imageSrc); // this will change overtime 21658 $image.data('jg.originalSrcLoc', imageSrcLoc); // this is saved for the destroy method 21659 return imageSrc; 21660 }; 21661 21662 /** @returns {jQuery} the image in the given entry */ 21663 JustifiedGallery.prototype.imgFromEntry = function ($entry) { 21664 var $img = $entry.find(this.settings.imgSelector); 21665 if ($img.length === 0) $img = $entry.find('.t-entry-visual-cont img');//hacked by Uncode 21666 return $img.length === 0 ? null : $img; 21667 }; 21668 21669 /** @returns {jQuery} the caption in the given entry */ 21670 JustifiedGallery.prototype.captionFromEntry = function ($entry) { 21671 var $caption = $entry.find('> .jg-caption'); 21672 return $caption.length === 0 ? null : $caption; 21673 }; 21674 21675 /** 21676 * Display the entry 21677 * 21678 * @param {jQuery} $entry the entry to display 21679 * @param {int} x the x position where the entry must be positioned 21680 * @param y the y position where the entry must be positioned 21681 * @param imgWidth the image width 21682 * @param imgHeight the image height 21683 * @param rowHeight the row height of the row that owns the entry 21684 */ 21685 JustifiedGallery.prototype.displayEntry = function ($entry, x, y, imgWidth, imgHeight, rowHeight) { 21686 $entry.width(imgWidth); 21687 $entry.height(Math.floor(rowHeight));//hacked by Uncode 21688 $entry.css('top', Math.floor(y));//hacked by Uncode 21689 $entry.css('left', x); 21690 21691 var $image = this.imgFromEntry($entry); 21692 if ($image !== null) { 21693 $image.css('width', imgWidth); 21694 $image.css('height', imgHeight); 21695 $image.css('margin-left', - imgWidth / 2); 21696 $image.css('margin-top', - imgHeight / 2); 21697 21698 // Image reloading for an high quality of thumbnails 21699 var imageSrc = $image.data('jg.src'); 21700 if (imageSrc) { 21701 imageSrc = this.newSrc(imageSrc, imgWidth, imgHeight, $image[0]); 21702 21703 $image.one('error', function () { 21704 this.resetImgSrc($image); //revert to the original thumbnail 21705 }); 21706 21707 var loadNewImage = function () { 21708 // if (imageSrc !== newImageSrc) { 21709 $image.attr('src', imageSrc); 21710 // } 21711 }; 21712 21713 if ($entry.data('jg.loaded') === 'skipped' && imageSrc) { 21714 this.onImageEvent(imageSrc, (function() { 21715 this.showImg($entry, loadNewImage); //load the new image after the fadeIn 21716 $entry.data('jg.loaded', true); 21717 }).bind(this)); 21718 } else { 21719 this.showImg($entry, loadNewImage); //load the new image after the fadeIn 21720 } 21721 21722 } 21723 21724 } else { 21725 this.showImg($entry); 21726 } 21727 21728 this.displayEntryCaption($entry); 21729 }; 21730 21731 /** 21732 * Display the entry caption. If the caption element doesn't exists, it creates the caption using the 'alt' 21733 * or the 'title' attributes. 21734 * 21735 * @param {jQuery} $entry the entry to process 21736 */ 21737 JustifiedGallery.prototype.displayEntryCaption = function ($entry) { 21738 var $image = this.imgFromEntry($entry); 21739 if ($image !== null && this.settings.captions) { 21740 var $imgCaption = this.captionFromEntry($entry); 21741 21742 // Create it if it doesn't exists 21743 if ($imgCaption === null) { 21744 var caption = $image.attr('alt'); 21745 if (!this.isValidCaption(caption)) caption = $entry.attr('title'); 21746 if (this.isValidCaption(caption)) { // Create only we found something 21747 $imgCaption = $('<div class="jg-caption">' + caption + '</div>'); 21748 $entry.append($imgCaption); 21749 $entry.data('jg.createdCaption', true); 21750 } 21751 } 21752 21753 // Create events (we check again the $imgCaption because it can be still inexistent) 21754 if ($imgCaption !== null) { 21755 if (!this.settings.cssAnimation) $imgCaption.stop().fadeTo(0, this.settings.captionSettings.nonVisibleOpacity); 21756 this.addCaptionEventsHandlers($entry); 21757 } 21758 } else { 21759 this.removeCaptionEventsHandlers($entry); 21760 } 21761 }; 21762 21763 /** 21764 * Validates the caption 21765 * 21766 * @param caption The caption that should be validated 21767 * @return {boolean} Validation result 21768 */ 21769 JustifiedGallery.prototype.isValidCaption = function (caption) { 21770 return (typeof caption !== 'undefined' && caption.length > 0); 21771 }; 21772 21773 /** 21774 * The callback for the event 'mouseenter'. It assumes that the event currentTarget is an entry. 21775 * It shows the caption using jQuery (or using CSS if it is configured so) 21776 * 21777 * @param {Event} eventObject the event object 21778 */ 21779 JustifiedGallery.prototype.onEntryMouseEnterForCaption = function (eventObject) { 21780 var $caption = this.captionFromEntry($(eventObject.currentTarget)); 21781 if (this.settings.cssAnimation) { 21782 $caption.addClass('jg-caption-visible').removeClass('jg-caption-hidden'); 21783 } else { 21784 $caption.stop().fadeTo(this.settings.captionSettings.animationDuration, 21785 this.settings.captionSettings.visibleOpacity); 21786 } 21787 }; 21788 21789 /** 21790 * The callback for the event 'mouseleave'. It assumes that the event currentTarget is an entry. 21791 * It hides the caption using jQuery (or using CSS if it is configured so) 21792 * 21793 * @param {Event} eventObject the event object 21794 */ 21795 JustifiedGallery.prototype.onEntryMouseLeaveForCaption = function (eventObject) { 21796 var $caption = this.captionFromEntry($(eventObject.currentTarget)); 21797 if (this.settings.cssAnimation) { 21798 $caption.removeClass('jg-caption-visible').removeClass('jg-caption-hidden'); 21799 } else { 21800 $caption.stop().fadeTo(this.settings.captionSettings.animationDuration, 21801 this.settings.captionSettings.nonVisibleOpacity); 21802 } 21803 }; 21804 21805 /** 21806 * Add the handlers of the entry for the caption 21807 * 21808 * @param $entry the entry to modify 21809 */ 21810 JustifiedGallery.prototype.addCaptionEventsHandlers = function ($entry) { 21811 var captionMouseEvents = $entry.data('jg.captionMouseEvents'); 21812 if (typeof captionMouseEvents === 'undefined') { 21813 captionMouseEvents = { 21814 mouseenter: $.proxy(this.onEntryMouseEnterForCaption, this), 21815 mouseleave: $.proxy(this.onEntryMouseLeaveForCaption, this) 21816 }; 21817 $entry.on('mouseenter', undefined, undefined, captionMouseEvents.mouseenter); 21818 $entry.on('mouseleave', undefined, undefined, captionMouseEvents.mouseleave); 21819 $entry.data('jg.captionMouseEvents', captionMouseEvents); 21820 } 21821 }; 21822 21823 /** 21824 * Remove the handlers of the entry for the caption 21825 * 21826 * @param $entry the entry to modify 21827 */ 21828 JustifiedGallery.prototype.removeCaptionEventsHandlers = function ($entry) { 21829 var captionMouseEvents = $entry.data('jg.captionMouseEvents'); 21830 if (typeof captionMouseEvents !== 'undefined') { 21831 $entry.off('mouseenter', undefined, captionMouseEvents.mouseenter); 21832 $entry.off('mouseleave', undefined, captionMouseEvents.mouseleave); 21833 $entry.removeData('jg.captionMouseEvents'); 21834 } 21835 }; 21836 21837 /** 21838 * Clear the building row data to be used for a new row 21839 */ 21840 JustifiedGallery.prototype.clearBuildingRow = function () { 21841 this.buildingRow.entriesBuff = []; 21842 this.buildingRow.aspectRatio = 0; 21843 this.buildingRow.width = 0; 21844 }; 21845 21846 /** 21847 * Justify the building row, preparing it to 21848 * 21849 * @param isLastRow 21850 * @param hiddenRow undefined or false for normal behavior. hiddenRow = true to hide the row. 21851 * @returns a boolean to know if the row has been justified or not 21852 */ 21853 JustifiedGallery.prototype.prepareBuildingRow = function (isLastRow, hiddenRow) { 21854 var i, $entry, imgAspectRatio, newImgW, newImgH, justify = true; 21855 var minHeight = 0; 21856 var availableWidth = this.galleryWidth - 2 * this.border - ( 21857 (this.buildingRow.entriesBuff.length - 1) * this.settings.margins); 21858 var rowHeight = Math.floor( availableWidth / this.buildingRow.aspectRatio );//hacked by Uncode 21859 var defaultRowHeight = this.settings.rowHeight; 21860 var justifiable = this.buildingRow.width / availableWidth > this.settings.justifyThreshold; 21861 21862 //Skip the last row if we can't justify it and the lastRow == 'hide' 21863 if (hiddenRow || (isLastRow && this.settings.lastRow === 'hide' && !justifiable)) { 21864 for (i = 0; i < this.buildingRow.entriesBuff.length; i++) { 21865 $entry = this.buildingRow.entriesBuff[i]; 21866 if (this.settings.cssAnimation) 21867 $entry.removeClass('jg-entry-visible'); 21868 else { 21869 $entry.stop().fadeTo(0, 0.1); 21870 $entry.find('> img, > a > img').fadeTo(0, 0); 21871 } 21872 } 21873 return -1; 21874 } 21875 21876 // With lastRow = nojustify, justify if is justificable (the images will not become too big) 21877 if (isLastRow && !justifiable && this.settings.lastRow !== 'justify' && this.settings.lastRow !== 'hide') { 21878 justify = false; 21879 21880 if (this.rows > 0) { 21881 defaultRowHeight = (this.offY - this.border - this.settings.margins * this.rows) / this.rows; 21882 justify = defaultRowHeight * this.buildingRow.aspectRatio / availableWidth > this.settings.justifyThreshold; 21883 } 21884 } 21885 21886 for (i = 0; i < this.buildingRow.entriesBuff.length; i++) { 21887 $entry = this.buildingRow.entriesBuff[i]; 21888 imgAspectRatio = $entry.data('jg.width') / $entry.data('jg.height'); 21889 21890 if (justify) { 21891 newImgW = (i === this.buildingRow.entriesBuff.length - 1) ? availableWidth : rowHeight * imgAspectRatio; 21892 newImgH = rowHeight; 21893 } else { 21894 newImgW = defaultRowHeight * imgAspectRatio; 21895 newImgH = defaultRowHeight; 21896 } 21897 21898 availableWidth -= Math.round(newImgW); 21899 $entry.data('jg.jwidth', Math.round(newImgW)); 21900 $entry.data('jg.jheight', Math.ceil(newImgH)); 21901 if (i === 0 || minHeight > newImgH) minHeight = newImgH; 21902 } 21903 21904 this.buildingRow.height = minHeight; 21905 return justify; 21906 }; 21907 21908 /** 21909 * Flush a row: justify it, modify the gallery height accordingly to the row height 21910 * 21911 * @param isLastRow 21912 * @param hiddenRow undefined or false for normal behavior. hiddenRow = true to hide the row. 21913 */ 21914 JustifiedGallery.prototype.flushRow = function (isLastRow, hiddenRow) { 21915 var settings = this.settings; 21916 var $entry, buildingRowRes, offX = this.border, i; 21917 21918 buildingRowRes = this.prepareBuildingRow(isLastRow, hiddenRow); 21919 if (hiddenRow || (isLastRow && settings.lastRow === 'hide' && buildingRowRes === -1)) { 21920 this.clearBuildingRow(); 21921 return; 21922 } 21923 21924 if (this.maxRowHeight) { 21925 if (this.maxRowHeight < this.buildingRow.height) this.buildingRow.height = this.maxRowHeight; 21926 } 21927 21928 //Align last (unjustified) row 21929 if (isLastRow && (settings.lastRow === 'center' || settings.lastRow === 'right')) { 21930 var availableWidth = this.galleryWidth - 2 * this.border - (this.buildingRow.entriesBuff.length - 1) * settings.margins; 21931 21932 for (i = 0; i < this.buildingRow.entriesBuff.length; i++) { 21933 $entry = this.buildingRow.entriesBuff[i]; 21934 availableWidth -= $entry.data('jg.jwidth'); 21935 } 21936 21937 if (settings.lastRow === 'center') 21938 offX += Math.round(availableWidth / 2); 21939 else if (settings.lastRow === 'right') 21940 offX += availableWidth; 21941 } 21942 21943 var lastEntryIdx = this.buildingRow.entriesBuff.length - 1; 21944 for (i = 0; i <= lastEntryIdx; i++) { 21945 $entry = this.buildingRow.entriesBuff[this.settings.rtl ? lastEntryIdx - i : i]; 21946 this.displayEntry($entry, offX, this.offY, $entry.data('jg.jwidth'), $entry.data('jg.jheight'), this.buildingRow.height); 21947 offX += $entry.data('jg.jwidth') + settings.margins; 21948 } 21949 21950 //Gallery Height 21951 this.galleryHeightToSet = this.offY + this.buildingRow.height + this.border; 21952 this.setGalleryTempHeight(this.galleryHeightToSet + this.getSpinnerHeight()); 21953 21954 if (!isLastRow || (this.buildingRow.height <= settings.rowHeight && buildingRowRes)) { 21955 //Ready for a new row 21956 this.offY += this.buildingRow.height + settings.margins; 21957 this.rows += 1; 21958 this.clearBuildingRow(); 21959 this.settings.triggerEvent.call(this, 'jg.rowflush'); 21960 } 21961 }; 21962 21963 21964 // Scroll position not restoring: https://github.com/miromannino/Justified-Gallery/issues/221 21965 var galleryPrevStaticHeight = 0; 21966 21967 JustifiedGallery.prototype.rememberGalleryHeight = function () { 21968 galleryPrevStaticHeight = this.$gallery.height(); 21969 this.$gallery.height(galleryPrevStaticHeight); 21970 }; 21971 21972 // grow only 21973 JustifiedGallery.prototype.setGalleryTempHeight = function (height) { 21974 galleryPrevStaticHeight = Math.max(height, galleryPrevStaticHeight); 21975 this.$gallery.height(galleryPrevStaticHeight); 21976 }; 21977 21978 JustifiedGallery.prototype.setGalleryFinalHeight = function (height) { 21979 galleryPrevStaticHeight = height; 21980 this.$gallery.height(height); 21981 }; 21982 21983 /** 21984 * Checks the width of the gallery container, to know if a new justification is needed 21985 */ 21986 JustifiedGallery.prototype.checkWidth = function () { 21987 this.checkWidthIntervalId = setInterval($.proxy(function () { 21988 21989 // if the gallery is not currently visible, abort. 21990 if (!this.$gallery.is(":visible")) return; 21991 21992 var galleryWidth = parseFloat(this.$gallery.width()); 21993 if (Math.abs(galleryWidth - this.galleryWidth) > this.settings.refreshSensitivity) { 21994 this.galleryWidth = galleryWidth; 21995 this.rewind(); 21996 21997 this.rememberGalleryHeight(); 21998 21999 // Restart to analyze 22000 this.startImgAnalyzer(true); 22001 } 22002 }, this), this.settings.refreshTime); 22003 }; 22004 22005 /** 22006 * @returns {boolean} a boolean saying if the spinner is active or not 22007 */ 22008 JustifiedGallery.prototype.isSpinnerActive = function () { 22009 return this.spinner.intervalId !== null; 22010 }; 22011 22012 /** 22013 * @returns {int} the spinner height 22014 */ 22015 JustifiedGallery.prototype.getSpinnerHeight = function () { 22016 return this.spinner.$el.innerHeight(); 22017 }; 22018 22019 /** 22020 * Stops the spinner animation and modify the gallery height to exclude the spinner 22021 */ 22022 JustifiedGallery.prototype.stopLoadingSpinnerAnimation = function () { 22023 clearInterval(this.spinner.intervalId); 22024 this.spinner.intervalId = null; 22025 this.setGalleryTempHeight(this.$gallery.height() - this.getSpinnerHeight()); 22026 this.spinner.$el.detach(); 22027 }; 22028 22029 /** 22030 * Starts the spinner animation 22031 */ 22032 JustifiedGallery.prototype.startLoadingSpinnerAnimation = function () { 22033 var spinnerContext = this.spinner; 22034 var $spinnerPoints = spinnerContext.$el.find('span'); 22035 clearInterval(spinnerContext.intervalId); 22036 this.$gallery.append(spinnerContext.$el); 22037 this.setGalleryTempHeight(this.offY + this.buildingRow.height + this.getSpinnerHeight()); 22038 spinnerContext.intervalId = setInterval(function () { 22039 if (spinnerContext.phase < $spinnerPoints.length) { 22040 $spinnerPoints.eq(spinnerContext.phase).fadeTo(spinnerContext.timeSlot, 1); 22041 } else { 22042 $spinnerPoints.eq(spinnerContext.phase - $spinnerPoints.length).fadeTo(spinnerContext.timeSlot, 0); 22043 } 22044 spinnerContext.phase = (spinnerContext.phase + 1) % ($spinnerPoints.length * 2); 22045 }, spinnerContext.timeSlot); 22046 }; 22047 22048 /** 22049 * Rewind the image analysis to start from the first entry. 22050 */ 22051 JustifiedGallery.prototype.rewind = function () { 22052 this.lastFetchedEntry = null; 22053 this.lastAnalyzedIndex = -1; 22054 this.offY = this.border; 22055 this.rows = 0; 22056 this.clearBuildingRow(); 22057 }; 22058 22059 /** 22060 * @returns {String} `settings.selector` rejecting spinner element 22061 */ 22062 JustifiedGallery.prototype.getSelectorWithoutSpinner = function () { 22063 return this.settings.selector + ', div:not(.jg-spinner)'; 22064 }; 22065 22066 /** 22067 * @returns {Array} all entries matched by `settings.selector` 22068 */ 22069 JustifiedGallery.prototype.getAllEntries = function () { 22070 var selector = this.getSelectorWithoutSpinner(); 22071 return this.$gallery.children(selector).toArray(); 22072 }; 22073 22074 /** 22075 * Update the entries searching it from the justified gallery HTML element 22076 * 22077 * @param norewind if norewind only the new entries will be changed (i.e. randomized, sorted or filtered) 22078 * @returns {boolean} true if some entries has been founded 22079 */ 22080 JustifiedGallery.prototype.updateEntries = function (norewind) { 22081 var newEntries; 22082 22083 if (norewind && this.lastFetchedEntry != null) { 22084 var selector = this.getSelectorWithoutSpinner(); 22085 newEntries = $(this.lastFetchedEntry).nextAll(selector).toArray(); 22086 } else { 22087 this.entries = []; 22088 newEntries = this.getAllEntries(); 22089 } 22090 22091 if (newEntries.length > 0) { 22092 22093 // Sort or randomize 22094 if ($.isFunction(this.settings.sort)) { 22095 newEntries = this.sortArray(newEntries); 22096 } else if (this.settings.randomize) { 22097 newEntries = this.shuffleArray(newEntries); 22098 } 22099 this.lastFetchedEntry = newEntries[newEntries.length - 1]; 22100 22101 // Filter 22102 if (this.settings.filter) { 22103 newEntries = this.filterArray(newEntries); 22104 } else { 22105 this.resetFilters(newEntries); 22106 } 22107 22108 } 22109 22110 this.entries = this.entries.concat(newEntries); 22111 return true; 22112 }; 22113 22114 /** 22115 * Apply the entries order to the DOM, iterating the entries and appending the images 22116 * 22117 * @param entries the entries that has been modified and that must be re-ordered in the DOM 22118 */ 22119 JustifiedGallery.prototype.insertToGallery = function (entries) { 22120 var that = this; 22121 $.each(entries, function () { 22122 $(this).appendTo(that.$gallery); 22123 }); 22124 }; 22125 22126 /** 22127 * Shuffle the array using the Fisher-Yates shuffle algorithm 22128 * 22129 * @param a the array to shuffle 22130 * @return the shuffled array 22131 */ 22132 JustifiedGallery.prototype.shuffleArray = function (a) { 22133 var i, j, temp; 22134 for (i = a.length - 1; i > 0; i--) { 22135 j = Math.floor(Math.random() * (i + 1)); 22136 temp = a[i]; 22137 a[i] = a[j]; 22138 a[j] = temp; 22139 } 22140 this.insertToGallery(a); 22141 return a; 22142 }; 22143 22144 /** 22145 * Sort the array using settings.comparator as comparator 22146 * 22147 * @param a the array to sort (it is sorted) 22148 * @return the sorted array 22149 */ 22150 JustifiedGallery.prototype.sortArray = function (a) { 22151 a.sort(this.settings.sort); 22152 this.insertToGallery(a); 22153 return a; 22154 }; 22155 22156 /** 22157 * Reset the filters removing the 'jg-filtered' class from all the entries 22158 * 22159 * @param a the array to reset 22160 */ 22161 JustifiedGallery.prototype.resetFilters = function (a) { 22162 for (var i = 0; i < a.length; i++) $(a[i]).removeClass('jg-filtered'); 22163 }; 22164 22165 /** 22166 * Filter the entries considering theirs classes (if a string has been passed) or using a function for filtering. 22167 * 22168 * @param a the array to filter 22169 * @return the filtered array 22170 */ 22171 JustifiedGallery.prototype.filterArray = function (a) { 22172 var settings = this.settings; 22173 if ($.type(settings.filter) === 'string') { 22174 // Filter only keeping the entries passed in the string 22175 return a.filter(function (el) { 22176 var $el = $(el); 22177 if ($el.is(settings.filter)) { 22178 $el.removeClass('jg-filtered'); 22179 return true; 22180 } else { 22181 $el.addClass('jg-filtered').removeClass('jg-visible'); 22182 return false; 22183 } 22184 }); 22185 } else if ($.isFunction(settings.filter)) { 22186 // Filter using the passed function 22187 var filteredArr = a.filter(settings.filter); 22188 for (var i = 0; i < a.length; i++) { 22189 if (filteredArr.indexOf(a[i]) === -1) { 22190 $(a[i]).addClass('jg-filtered').removeClass('jg-visible'); 22191 } else { 22192 $(a[i]).removeClass('jg-filtered'); 22193 } 22194 } 22195 return filteredArr; 22196 } 22197 }; 22198 22199 /** 22200 * Revert the image src to the default value. 22201 */ 22202 JustifiedGallery.prototype.resetImgSrc = function ($img) { 22203 if ($img.data('jg.originalSrcLoc') === 'src') { 22204 $img.attr('src', $img.data('jg.originalSrc')); 22205 } else { 22206 $img.attr('src', ''); 22207 } 22208 }; 22209 22210 /** 22211 * Destroy the Justified Gallery instance. 22212 * 22213 * It clears all the css properties added in the style attributes. We doesn't backup the original 22214 * values for those css attributes, because it costs (performance) and because in general one 22215 * shouldn't use the style attribute for an uniform set of images (where we suppose the use of 22216 * classes). Creating a backup is also difficult because JG could be called multiple times and 22217 * with different style attributes. 22218 */ 22219 JustifiedGallery.prototype.destroy = function () { 22220 clearInterval(this.checkWidthIntervalId); 22221 this.stopImgAnalyzerStarter(); 22222 22223 // Get fresh entries list since filtered entries are absent in `this.entries` 22224 $.each(this.getAllEntries(), $.proxy(function (_, entry) { 22225 var $entry = $(entry); 22226 22227 // Reset entry style 22228 $entry.css('width', ''); 22229 $entry.css('height', ''); 22230 $entry.css('top', ''); 22231 $entry.css('left', ''); 22232 $entry.data('jg.loaded', undefined); 22233 $entry.removeClass('jg-entry jg-filtered jg-entry-visible'); 22234 22235 // Reset image style 22236 var $img = this.imgFromEntry($entry); 22237 if ($img) { 22238 $img.css('width', ''); 22239 $img.css('height', ''); 22240 $img.css('margin-left', ''); 22241 $img.css('margin-top', ''); 22242 this.resetImgSrc($img); 22243 $img.data('jg.originalSrc', undefined); 22244 $img.data('jg.originalSrcLoc', undefined); 22245 $img.data('jg.src', undefined); 22246 } 22247 22248 // Remove caption 22249 this.removeCaptionEventsHandlers($entry); 22250 var $caption = this.captionFromEntry($entry); 22251 if ($entry.data('jg.createdCaption')) { 22252 // remove also the caption element (if created by jg) 22253 $entry.data('jg.createdCaption', undefined); 22254 if ($caption !== null) $caption.remove(); 22255 } else { 22256 if ($caption !== null) $caption.fadeTo(0, 1); 22257 } 22258 22259 }, this)); 22260 22261 this.$gallery.css('height', ''); 22262 this.$gallery.removeClass('justified-gallery'); 22263 this.$gallery.data('jg.controller', undefined); 22264 this.settings.triggerEvent.call(this, 'jg.destroy'); 22265 }; 22266 22267 /** 22268 * Analyze the images and builds the rows. It returns if it found an image that is not loaded. 22269 * 22270 * @param isForResize if the image analyzer is called for resizing or not, to call a different callback at the end 22271 */ 22272 JustifiedGallery.prototype.analyzeImages = function (isForResize) { 22273 for (var i = this.lastAnalyzedIndex + 1; i < this.entries.length; i++) { 22274 var $entry = $(this.entries[i]); 22275 if ($entry.data('jg.loaded') === true || $entry.data('jg.loaded') === 'skipped') { 22276 var availableWidth = this.galleryWidth - 2 * this.border - ( 22277 (this.buildingRow.entriesBuff.length - 1) * this.settings.margins); 22278 var imgAspectRatio = $entry.data('jg.width') / $entry.data('jg.height'); 22279 22280 this.buildingRow.entriesBuff.push($entry); 22281 this.buildingRow.aspectRatio += imgAspectRatio; 22282 this.buildingRow.width += imgAspectRatio * this.settings.rowHeight; 22283 this.lastAnalyzedIndex = i; 22284 22285 if (availableWidth / (this.buildingRow.aspectRatio + imgAspectRatio) < this.settings.rowHeight) { 22286 this.flushRow(false, this.settings.maxRowsCount > 0 && this.rows === this.settings.maxRowsCount); 22287 22288 if (++this.yield.flushed >= this.yield.every) { 22289 this.startImgAnalyzer(isForResize); 22290 return; 22291 } 22292 } 22293 } else if ($entry.data('jg.loaded') !== 'error') { 22294 return; 22295 } 22296 } 22297 22298 // Last row flush (the row is not full) 22299 if (this.buildingRow.entriesBuff.length > 0) { 22300 this.flushRow(true, this.settings.maxRowsCount > 0 && this.rows === this.settings.maxRowsCount); 22301 } 22302 22303 if (this.isSpinnerActive()) { 22304 this.stopLoadingSpinnerAnimation(); 22305 } 22306 22307 /* Stop, if there is, the timeout to start the analyzeImages. 22308 This is because an image can be set loaded, and the timeout can be set, 22309 but this image can be analyzed yet. 22310 */ 22311 this.stopImgAnalyzerStarter(); 22312 22313 this.setGalleryFinalHeight(this.galleryHeightToSet); 22314 22315 //On complete callback 22316 this.settings.triggerEvent.call(this, isForResize ? 'jg.resize' : 'jg.complete'); 22317 }; 22318 22319 /** 22320 * Stops any ImgAnalyzer starter (that has an assigned timeout) 22321 */ 22322 JustifiedGallery.prototype.stopImgAnalyzerStarter = function () { 22323 this.yield.flushed = 0; 22324 if (this.imgAnalyzerTimeout !== null) { 22325 clearTimeout(this.imgAnalyzerTimeout); 22326 this.imgAnalyzerTimeout = null; 22327 } 22328 }; 22329 22330 /** 22331 * Starts the image analyzer. It is not immediately called to let the browser to update the view 22332 * 22333 * @param isForResize specifies if the image analyzer must be called for resizing or not 22334 */ 22335 JustifiedGallery.prototype.startImgAnalyzer = function (isForResize) { 22336 var that = this; 22337 this.stopImgAnalyzerStarter(); 22338 this.imgAnalyzerTimeout = setTimeout(function () { 22339 that.analyzeImages(isForResize); 22340 }, 0.001); // we can't start it immediately due to a IE different behaviour 22341 }; 22342 22343 /** 22344 * Checks if the image is loaded or not using another image object. We cannot use the 'complete' image property, 22345 * because some browsers, with a 404 set complete = true. 22346 * 22347 * @param imageSrc the image src to load 22348 * @param onLoad callback that is called when the image has been loaded 22349 * @param onError callback that is called in case of an error 22350 */ 22351 JustifiedGallery.prototype.onImageEvent = function (imageSrc, onLoad, onError) { 22352 if (!onLoad && !onError) return; 22353 22354 var memImage = new Image(); 22355 var $memImage = $(memImage); 22356 if (onLoad) { 22357 $memImage.one('load', function () { 22358 $memImage.off('load error'); 22359 onLoad(memImage); 22360 }); 22361 } 22362 if (onError) { 22363 $memImage.one('error', function () { 22364 $memImage.off('load error'); 22365 onError(memImage); 22366 }); 22367 } 22368 memImage.src = imageSrc; 22369 }; 22370 22371 /** 22372 * Init of Justified Gallery controlled 22373 * It analyzes all the entries starting theirs loading and calling the image analyzer (that works with loaded images) 22374 */ 22375 JustifiedGallery.prototype.init = function () { 22376 var imagesToLoad = false, skippedImages = false, that = this; 22377 $.each(this.entries, function (index, entry) { 22378 var $entry = $(entry); 22379 var $image = that.imgFromEntry($entry); 22380 22381 $entry.addClass('jg-entry'); 22382 22383 if ($entry.data('jg.loaded') !== true && $entry.data('jg.loaded') !== 'skipped') { 22384 22385 // Link Rel global overwrite 22386 if (that.settings.rel !== null) $entry.attr('rel', that.settings.rel); 22387 22388 // Link Target global overwrite 22389 if (that.settings.target !== null) $entry.attr('target', that.settings.target); 22390 22391 if ($image !== null) { 22392 22393 // Image src 22394 var imageSrc = that.extractImgSrcFromImage($image); 22395 22396 /* If we have the height and the width, we don't wait that the image is loaded, 22397 but we start directly with the justification */ 22398 if (that.settings.waitThumbnailsLoad === false || !imageSrc) { 22399 var width = parseFloat($image.attr('width')); 22400 var height = parseFloat($image.attr('height')); 22401 if ($image.prop('tagName') === 'svg') { 22402 width = parseFloat($image[0].getBBox().width); 22403 height = parseFloat($image[0].getBBox().height); 22404 } 22405 if (!isNaN(width) && !isNaN(height)) { 22406 $entry.data('jg.width', width); 22407 $entry.data('jg.height', height); 22408 $entry.data('jg.loaded', 'skipped'); 22409 skippedImages = true; 22410 that.startImgAnalyzer(false); 22411 return true; // continue 22412 } 22413 } 22414 22415 $entry.data('jg.loaded', false); 22416 imagesToLoad = true; 22417 22418 // Spinner start 22419 if (!that.isSpinnerActive()) that.startLoadingSpinnerAnimation(); 22420 22421 that.onImageEvent(imageSrc, function (loadImg) { // image loaded 22422 $entry.data('jg.width', loadImg.width); 22423 $entry.data('jg.height', loadImg.height); 22424 $entry.data('jg.loaded', true); 22425 that.startImgAnalyzer(false); 22426 }, function () { // image load error 22427 $entry.data('jg.loaded', 'error'); 22428 that.startImgAnalyzer(false); 22429 }); 22430 22431 } else { 22432 $entry.data('jg.loaded', true); 22433 $entry.data('jg.width', $entry.width() | parseFloat($entry.css('width')) | 1); 22434 $entry.data('jg.height', $entry.height() | parseFloat($entry.css('height')) | 1); 22435 } 22436 22437 } 22438 22439 }); 22440 22441 if (!imagesToLoad && !skippedImages) this.startImgAnalyzer(false); 22442 this.checkWidth(); 22443 }; 22444 22445 /** 22446 * Checks that it is a valid number. If a string is passed it is converted to a number 22447 * 22448 * @param settingContainer the object that contains the setting (to allow the conversion) 22449 * @param settingName the setting name 22450 */ 22451 JustifiedGallery.prototype.checkOrConvertNumber = function (settingContainer, settingName) { 22452 if ($.type(settingContainer[settingName]) === 'string') { 22453 settingContainer[settingName] = parseFloat(settingContainer[settingName]); 22454 } 22455 22456 if ($.type(settingContainer[settingName]) === 'number') { 22457 if (isNaN(settingContainer[settingName])) throw 'invalid number for ' + settingName; 22458 } else { 22459 throw settingName + ' must be a number'; 22460 } 22461 }; 22462 22463 /** 22464 * Checks the sizeRangeSuffixes and, if necessary, converts 22465 * its keys from string (e.g. old settings with 'lt100') to int. 22466 */ 22467 JustifiedGallery.prototype.checkSizeRangesSuffixes = function () { 22468 if ($.type(this.settings.sizeRangeSuffixes) !== 'object') { 22469 throw 'sizeRangeSuffixes must be defined and must be an object'; 22470 } 22471 22472 var suffixRanges = []; 22473 for (var rangeIdx in this.settings.sizeRangeSuffixes) { 22474 if (this.settings.sizeRangeSuffixes.hasOwnProperty(rangeIdx)) suffixRanges.push(rangeIdx); 22475 } 22476 22477 var newSizeRngSuffixes = { 0: '' }; 22478 for (var i = 0; i < suffixRanges.length; i++) { 22479 if ($.type(suffixRanges[i]) === 'string') { 22480 try { 22481 var numIdx = parseInt(suffixRanges[i].replace(/^[a-z]+/, ''), 10); 22482 newSizeRngSuffixes[numIdx] = this.settings.sizeRangeSuffixes[suffixRanges[i]]; 22483 } catch (e) { 22484 throw 'sizeRangeSuffixes keys must contains correct numbers (' + e + ')'; 22485 } 22486 } else { 22487 newSizeRngSuffixes[suffixRanges[i]] = this.settings.sizeRangeSuffixes[suffixRanges[i]]; 22488 } 22489 } 22490 22491 this.settings.sizeRangeSuffixes = newSizeRngSuffixes; 22492 }; 22493 22494 /** 22495 * check and convert the maxRowHeight setting 22496 * requires rowHeight to be already set 22497 * TODO: should be always called when only rowHeight is changed 22498 * @return number or null 22499 */ 22500 JustifiedGallery.prototype.retrieveMaxRowHeight = function () { 22501 var newMaxRowHeight = null; 22502 var rowHeight = this.settings.rowHeight; 22503 22504 if ($.type(this.settings.maxRowHeight) === 'string') { 22505 if (this.settings.maxRowHeight.match(/^[0-9]+%$/)) { 22506 newMaxRowHeight = rowHeight * parseFloat(this.settings.maxRowHeight.match(/^([0-9]+)%$/)[1]) / 100; 22507 } else { 22508 newMaxRowHeight = parseFloat(this.settings.maxRowHeight); 22509 } 22510 } else if ($.type(this.settings.maxRowHeight) === 'number') { 22511 newMaxRowHeight = this.settings.maxRowHeight; 22512 } else if (this.settings.maxRowHeight === false || this.settings.maxRowHeight == null) { 22513 return null; 22514 } else { 22515 throw 'maxRowHeight must be a number or a percentage'; 22516 } 22517 22518 // check if the converted value is not a number 22519 if (isNaN(newMaxRowHeight)) throw 'invalid number for maxRowHeight'; 22520 22521 // check values, maxRowHeight must be >= rowHeight 22522 if (newMaxRowHeight < rowHeight) newMaxRowHeight = rowHeight; 22523 22524 return newMaxRowHeight; 22525 }; 22526 22527 /** 22528 * Checks the settings 22529 */ 22530 JustifiedGallery.prototype.checkSettings = function () { 22531 this.checkSizeRangesSuffixes(); 22532 22533 this.checkOrConvertNumber(this.settings, 'rowHeight'); 22534 this.checkOrConvertNumber(this.settings, 'margins'); 22535 this.checkOrConvertNumber(this.settings, 'border'); 22536 this.checkOrConvertNumber(this.settings, 'maxRowsCount'); 22537 22538 var lastRowModes = [ 22539 'justify', 22540 'nojustify', 22541 'left', 22542 'center', 22543 'right', 22544 'hide' 22545 ]; 22546 if (lastRowModes.indexOf(this.settings.lastRow) === -1) { 22547 throw 'lastRow must be one of: ' + lastRowModes.join(', '); 22548 } 22549 22550 this.checkOrConvertNumber(this.settings, 'justifyThreshold'); 22551 if (this.settings.justifyThreshold < 0 || this.settings.justifyThreshold > 1) { 22552 throw 'justifyThreshold must be in the interval [0,1]'; 22553 } 22554 if ($.type(this.settings.cssAnimation) !== 'boolean') { 22555 throw 'cssAnimation must be a boolean'; 22556 } 22557 22558 if ($.type(this.settings.captions) !== 'boolean') throw 'captions must be a boolean'; 22559 this.checkOrConvertNumber(this.settings.captionSettings, 'animationDuration'); 22560 22561 this.checkOrConvertNumber(this.settings.captionSettings, 'visibleOpacity'); 22562 if (this.settings.captionSettings.visibleOpacity < 0 || 22563 this.settings.captionSettings.visibleOpacity > 1) { 22564 throw 'captionSettings.visibleOpacity must be in the interval [0, 1]'; 22565 } 22566 22567 this.checkOrConvertNumber(this.settings.captionSettings, 'nonVisibleOpacity'); 22568 if (this.settings.captionSettings.nonVisibleOpacity < 0 || 22569 this.settings.captionSettings.nonVisibleOpacity > 1) { 22570 throw 'captionSettings.nonVisibleOpacity must be in the interval [0, 1]'; 22571 } 22572 22573 this.checkOrConvertNumber(this.settings, 'imagesAnimationDuration'); 22574 this.checkOrConvertNumber(this.settings, 'refreshTime'); 22575 this.checkOrConvertNumber(this.settings, 'refreshSensitivity'); 22576 if ($.type(this.settings.randomize) !== 'boolean') throw 'randomize must be a boolean'; 22577 if ($.type(this.settings.selector) !== 'string') throw 'selector must be a string'; 22578 22579 if (this.settings.sort !== false && !$.isFunction(this.settings.sort)) { 22580 throw 'sort must be false or a comparison function'; 22581 } 22582 22583 if (this.settings.filter !== false && !$.isFunction(this.settings.filter) && 22584 $.type(this.settings.filter) !== 'string') { 22585 throw 'filter must be false, a string or a filter function'; 22586 } 22587 }; 22588 22589 /** 22590 * It brings all the indexes from the sizeRangeSuffixes and it orders them. They are then sorted and returned. 22591 * @returns {Array} sorted suffix ranges 22592 */ 22593 JustifiedGallery.prototype.retrieveSuffixRanges = function () { 22594 var suffixRanges = []; 22595 for (var rangeIdx in this.settings.sizeRangeSuffixes) { 22596 if (this.settings.sizeRangeSuffixes.hasOwnProperty(rangeIdx)) suffixRanges.push(parseInt(rangeIdx, 10)); 22597 } 22598 suffixRanges.sort(function (a, b) { return a > b ? 1 : a < b ? -1 : 0; }); 22599 return suffixRanges; 22600 }; 22601 22602 /** 22603 * Update the existing settings only changing some of them 22604 * 22605 * @param newSettings the new settings (or a subgroup of them) 22606 */ 22607 JustifiedGallery.prototype.updateSettings = function (newSettings) { 22608 // In this case Justified Gallery has been called again changing only some options 22609 this.settings = $.extend({}, this.settings, newSettings); 22610 this.checkSettings(); 22611 22612 // As reported in the settings: negative value = same as margins, 0 = disabled 22613 this.border = this.settings.border >= 0 ? this.settings.border : this.settings.margins; 22614 22615 this.maxRowHeight = this.retrieveMaxRowHeight(); 22616 this.suffixRanges = this.retrieveSuffixRanges(); 22617 }; 22618 22619 JustifiedGallery.prototype.defaults = { 22620 sizeRangeSuffixes: {}, /* e.g. Flickr configuration 22621 { 22622 100: '_t', // used when longest is less than 100px 22623 240: '_m', // used when longest is between 101px and 240px 22624 320: '_n', // ... 22625 500: '', 22626 640: '_z', 22627 1024: '_b' // used as else case because it is the last 22628 } 22629 */ 22630 thumbnailPath: undefined, /* If defined, sizeRangeSuffixes is not used, and this function is used to determine the 22631 path relative to a specific thumbnail size. The function should accept respectively three arguments: 22632 current path, width and height */ 22633 rowHeight: 120, // required? required to be > 0? 22634 maxRowHeight: false, // false or negative value to deactivate. Positive number to express the value in pixels, 22635 // A string '[0-9]+%' to express in percentage (e.g. 300% means that the row height 22636 // can't exceed 3 * rowHeight) 22637 maxRowsCount: 0, // maximum number of rows to be displayed (0 = disabled) 22638 margins: 1, 22639 border: -1, // negative value = same as margins, 0 = disabled, any other value to set the border 22640 22641 lastRow: 'nojustify', // … which is the same as 'left', or can be 'justify', 'center', 'right' or 'hide' 22642 22643 justifyThreshold: 0.90, /* if row width / available space > 0.90 it will be always justified 22644 * (i.e. lastRow setting is not considered) */ 22645 waitThumbnailsLoad: true, 22646 captions: true, 22647 cssAnimation: true, 22648 imagesAnimationDuration: 500, // ignored with css animations 22649 captionSettings: { // ignored with css animations 22650 animationDuration: 500, 22651 visibleOpacity: 0.7, 22652 nonVisibleOpacity: 0.0 22653 },
22654 rel: null, // rewrite the rel of each analyzed links 22655 target: null, // rewrite the target of all links 22656 extension: /\.[^.\\/]+$/, // regexp to capture the extension of an image 22657 refreshTime: 200, // time interval (in ms) to check if the page changes its width 22658 refreshSensitivity: 0, // change in width allowed (in px) without re-building the gallery 22659 randomize: false, 22660 rtl: false, // right-to-left mode 22661 sort: false, /* 22662 - false: to do not sort 22663 - function: to sort them using the function as comparator (see Array.prototype.sort()) 22664 */ 22665 filter: false, /* 22666 - false, null or undefined: for a disabled filter 22667 - a string: an entry is kept if entry.is(filter string) returns true 22668 see jQuery's .is() function for further information 22669 - a function: invoked with arguments (entry, index, array). Return true to keep the entry, false otherwise. 22670 It follows the specifications of the Array.prototype.filter() function of JavaScript. 22671 */ 22672 selector: 'a', // The selector that is used to know what are the entries of the gallery 22673 imgSelector: '> img, > a > img, > svg, > a > svg', // The selector that is used to know what are the images of each entry 22674 triggerEvent: function (event) { // This is called to trigger events, the default behavior is to call $.trigger 22675 this.$gallery.trigger(event); // Consider that 'this' is this set to the JustifiedGallery object, so it can 22676 } // access to fields such as $gallery, useful to trigger events with jQuery. 22677 }; 22678 22679 22680 /** 22681 * Justified Gallery plugin for jQuery 22682 * 22683 * Events 22684 * - jg.complete : called when all the gallery has been created 22685 * - jg.resize : called when the gallery has been resized 22686 * - jg.rowflush : when a new row appears 22687 * 22688 * @param arg the action (or the settings) passed when the plugin is called 22689 * @returns {*} the object itself 22690 */ 22691 $.fn.justifiedGallery = function (arg) { 22692 return this.each(function (index, gallery) { 22693 22694 var $gallery = $(gallery); 22695 $gallery.addClass('justified-gallery'); 22696 22697 var controller = $gallery.data('jg.controller'); 22698 if (typeof controller === 'undefined') { 22699 // Create controller and assign it to the object data 22700 if (typeof arg !== 'undefined' && arg !== null && $.type(arg) !== 'object') { 22701 if (arg === 'destroy') return; // Just a call to an unexisting object 22702 throw 'The argument must be an object'; 22703 } 22704 controller = new JustifiedGallery($gallery, $.extend({}, JustifiedGallery.prototype.defaults, arg)); 22705 $gallery.data('jg.controller', controller); 22706 } else if (arg === 'norewind') { 22707 // In this case we don't rewind: we analyze only the latest images (e.g. to complete the last unfinished row 22708 // ... left to be more readable 22709 } else if (arg === 'destroy') { 22710 controller.destroy(); 22711 return; 22712 } else { 22713 // In this case Justified Gallery has been called again changing only some options 22714 controller.updateSettings(arg); 22715 controller.rewind(); 22716 } 22717 22718 // Update the entries list 22719 if (!controller.updateEntries(arg === 'norewind')) return; 22720 22721 // Init justified gallery 22722 controller.init(); 22723 22724 }); 22725 }; 22726 22727})); 22728 22729/*! 22730* Customized version of iScroll.js 0.0.1 22731* It fixes bugs affecting its integration with fullpage.js 22732*/ 22733/*! iScroll v5.2.0 ~ (c) 2008-2016 Matteo Spinelli ~ http://cubiq.org/license */ 22734(function (window, document, Math) { 22735var rAF = window.requestAnimationFrame || 22736 window.webkitRequestAnimationFrame || 22737 window.mozRequestAnimationFrame || 22738 window.oRequestAnimationFrame || 22739 window.msRequestAnimationFrame || 22740 function (callback) { window.setTimeout(callback, 1000 / 60); }; 22741 22742var utils = (function () { 22743 var me = {}; 22744 22745 var _elementStyle = document.createElement('div').style; 22746 var _vendor = (function () { 22747 var vendors = ['t', 'webkitT', 'MozT', 'msT', 'OT'], 22748 transform, 22749 i = 0, 22750 l = vendors.length; 22751 22752 for ( ; i < l; i++ ) { 22753 transform = vendors[i] + 'ransform'; 22754 if ( transform in _elementStyle ) return vendors[i].substr(0, vendors[i].length-1); 22755 } 22756 22757 return false;
vendor: 5,154 bytes, lines 22758-22910
22758 })(); 22759 22760 function _prefixStyle (style) { 22761 if ( _vendor === false ) return false; 22762 if ( _vendor === '' ) return style; 22763 return _vendor + style.charAt(0).toUpperCase() + style.substr(1); 22764 } 22765 22766 me.getTime = Date.now || function getTime () { return new Date().getTime(); }; 22767 22768 me.extend = function (target, obj) { 22769 for ( var i in obj ) { 22770 target[i] = obj[i]; 22771 } 22772 }; 22773 22774 me.addEvent = function (el, type, fn, capture) { 22775 el.addEventListener(type, fn, !!capture); 22776 }; 22777 22778 me.removeEvent = function (el, type, fn, capture) { 22779 el.removeEventListener(type, fn, !!capture); 22780 }; 22781 22782 me.prefixPointerEvent = function (pointerEvent) { 22783 return window.MSPointerEvent ? 22784 'MSPointer' + pointerEvent.charAt(7).toUpperCase() + pointerEvent.substr(8): 22785 pointerEvent; 22786 }; 22787 22788 me.momentum = function (current, start, time, lowerMargin, wrapperSize, deceleration) { 22789 var distance = current - start, 22790 speed = Math.abs(distance) / time, 22791 destination, 22792 duration; 22793 22794 deceleration = deceleration === undefined ? 0.0006 : deceleration; 22795 22796 destination = current + ( speed * speed ) / ( 2 * deceleration ) * ( distance < 0 ? -1 : 1 ); 22797 duration = speed / deceleration; 22798 22799 if ( destination < lowerMargin ) { 22800 destination = wrapperSize ? lowerMargin - ( wrapperSize / 2.5 * ( speed / 8 ) ) : lowerMargin; 22801 distance = Math.abs(destination - current); 22802 duration = distance / speed; 22803 } else if ( destination > 0 ) { 22804 destination = wrapperSize ? wrapperSize / 2.5 * ( speed / 8 ) : 0; 22805 distance = Math.abs(current) + destination; 22806 duration = distance / speed; 22807 } 22808 22809 return { 22810 destination: Math.round(destination), 22811 duration: duration 22812 }; 22813 }; 22814 22815 var _transform = _prefixStyle('transform'); 22816 22817 me.extend(me, { 22818 hasTransform: _transform !== false, 22819 hasPerspective: _prefixStyle('perspective') in _elementStyle, 22820 hasTouch: 'ontouchstart' in window, 22821 hasPointer: !!(window.PointerEvent || window.MSPointerEvent), // IE10 is prefixed 22822 hasTransition: _prefixStyle('transition') in _elementStyle 22823 }); 22824 22825 /* 22826 This should find all Android browsers lower than build 535.19 (both stock browser and webview) 22827 - galaxy S2 is ok 22828 - 2.3.6 : `AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1` 22829 - 4.0.4 : `AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30` 22830 - galaxy S3 is badAndroid (stock brower, webview) 22831 `AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30` 22832 - galaxy S4 is badAndroid (stock brower, webview) 22833 `AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30` 22834 - galaxy S5 is OK 22835 `AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Mobile Safari/537.36 (Chrome/)` 22836 - galaxy S6 is OK 22837 `AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Mobile Safari/537.36 (Chrome/)` 22838 */ 22839 me.isBadAndroid = (function() { 22840 var appVersion = window.navigator.appVersion; 22841 // Android browser is not a chrome browser. 22842 if (/Android/.test(appVersion) && !(/Chrome\/\d/.test(appVersion))) { 22843 var safariVersion = appVersion.match(/Safari\/(\d+.\d)/); 22844 if(safariVersion && typeof safariVersion === "object" && safariVersion.length >= 2) { 22845 return parseFloat(safariVersion[1]) < 535.19; 22846 } else { 22847 return true; 22848 } 22849 } else { 22850 return false; 22851 } 22852 })(); 22853 22854 me.extend(me.style = {}, { 22855 transform: _transform, 22856 transitionTimingFunction: _prefixStyle('transitionTimingFunction'), 22857 transitionDuration: _prefixStyle('transitionDuration'), 22858 transitionDelay: _prefixStyle('transitionDelay'), 22859 transformOrigin: _prefixStyle('transformOrigin') 22860 }); 22861 22862 me.hasClass = function (e, c) { 22863 var re = new RegExp("(^|\\s)" + c + "(\\s|$)"); 22864 return re.test(e.className); 22865 }; 22866 22867 me.addClass = function (e, c) { 22868 if ( me.hasClass(e, c) ) { 22869 return; 22870 } 22871 22872 var newclass = e.className.split(' '); 22873 newclass.push(c); 22874 e.className = newclass.join(' '); 22875 }; 22876 22877 me.removeClass = function (e, c) { 22878 if ( !me.hasClass(e, c) ) { 22879 return; 22880 } 22881 22882 var re = new RegExp("(^|\\s)" + c + "(\\s|$)", 'g'); 22883 e.className = e.className.replace(re, ' '); 22884 }; 22885 22886 me.offset = function (el) { 22887 var left = -el.offsetLeft, 22888 top = -el.offsetTop; 22889 22890 // jshint -W084 22891 while (el = el.offsetParent) { 22892 left -= el.offsetLeft; 22893 top -= el.offsetTop; 22894 } 22895 // jshint +W084 22896 22897 return { 22898 left: left, 22899 top: top 22900 }; 22901 }; 22902 22903 me.preventDefaultException = function (el, exceptions) { 22904 for ( var i in exceptions ) { 22905 if ( exceptions[i].test(el[i]) ) { 22906 return true; 22907 } 22908 } 22909 22910 return false;
vendor: 5,660 bytes, lines 22911-23076
22911 }; 22912 22913 me.extend(me.eventType = {}, { 22914 touchstart: 1, 22915 touchmove: 1, 22916 touchend: 1, 22917 22918 mousedown: 2, 22919 mousemove: 2, 22920 mouseup: 2, 22921 22922 pointerdown: 3, 22923 pointermove: 3, 22924 pointerup: 3, 22925 22926 MSPointerDown: 3, 22927 MSPointerMove: 3, 22928 MSPointerUp: 3 22929 }); 22930 22931 me.extend(me.ease = {}, { 22932 quadratic: { 22933 style: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)', 22934 fn: function (k) { 22935 return k * ( 2 - k ); 22936 } 22937 }, 22938 circular: { 22939 style: 'cubic-bezier(0.1, 0.57, 0.1, 1)', // Not properly "circular" but this looks better, it should be (0.075, 0.82, 0.165, 1) 22940 fn: function (k) { 22941 return Math.sqrt( 1 - ( --k * k ) ); 22942 } 22943 }, 22944 back: { 22945 style: 'cubic-bezier(0.175, 0.885, 0.32, 1.275)', 22946 fn: function (k) { 22947 var b = 4; 22948 return ( k = k - 1 ) * k * ( ( b + 1 ) * k + b ) + 1; 22949 } 22950 }, 22951 bounce: { 22952 style: '', 22953 fn: function (k) { 22954 if ( ( k /= 1 ) < ( 1 / 2.75 ) ) { 22955 return 7.5625 * k * k; 22956 } else if ( k < ( 2 / 2.75 ) ) { 22957 return 7.5625 * ( k -= ( 1.5 / 2.75 ) ) * k + 0.75; 22958 } else if ( k < ( 2.5 / 2.75 ) ) { 22959 return 7.5625 * ( k -= ( 2.25 / 2.75 ) ) * k + 0.9375; 22960 } else { 22961 return 7.5625 * ( k -= ( 2.625 / 2.75 ) ) * k + 0.984375; 22962 } 22963 } 22964 }, 22965 elastic: { 22966 style: '', 22967 fn: function (k) { 22968 var f = 0.22, 22969 e = 0.4; 22970 22971 if ( k === 0 ) { return 0; } 22972 if ( k == 1 ) { return 1; } 22973 22974 return ( e * Math.pow( 2, - 10 * k ) * Math.sin( ( k - f / 4 ) * ( 2 * Math.PI ) / f ) + 1 ); 22975 } 22976 } 22977 }); 22978 22979 me.tap = function (e, eventName) { 22980 var ev = document.createEvent('Event'); 22981 ev.initEvent(eventName, true, true); 22982 ev.pageX = e.pageX; 22983 ev.pageY = e.pageY; 22984 e.target.dispatchEvent(ev); 22985 }; 22986 22987 me.click = function (e) { 22988 var target = e.target, 22989 ev; 22990 22991 if ( !(/(SELECT|INPUT|TEXTAREA)/i).test(target.tagName) ) { 22992 // https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/initMouseEvent 22993 // initMouseEvent is deprecated. 22994 ev = document.createEvent(window.MouseEvent ? 'MouseEvents' : 'Event'); 22995 ev.initEvent('click', true, true); 22996 ev.view = e.view || window; 22997 ev.detail = 1; 22998 ev.screenX = target.screenX || 0; 22999 ev.screenY = target.screenY || 0; 23000 ev.clientX = target.clientX || 0; 23001 ev.clientY = target.clientY || 0; 23002 ev.ctrlKey = !!e.ctrlKey; 23003 ev.altKey = !!e.altKey; 23004 ev.shiftKey = !!e.shiftKey; 23005 ev.metaKey = !!e.metaKey; 23006 ev.button = 0; 23007 ev.relatedTarget = null; 23008 ev._constructed = true; 23009 target.dispatchEvent(ev); 23010 } 23011 }; 23012 23013 return me; 23014})(); 23015function IScroll (el, options) { 23016 this.wrapper = typeof el == 'string' ? document.querySelector(el) : el; 23017 this.scroller = this.wrapper.children[0]; 23018 this.scrollerStyle = this.scroller.style; // cache style for better performance 23019 23020 this.options = { 23021 23022 resizeScrollbars: true, 23023 23024 mouseWheelSpeed: 20, 23025 23026 snapThreshold: 0.334, 23027 23028// INSERT POINT: OPTIONS 23029 disablePointer : !utils.hasPointer, 23030 disableTouch : utils.hasPointer || !utils.hasTouch, 23031 disableMouse : utils.hasPointer || utils.hasTouch, 23032 startX: 0, 23033 startY: 0, 23034 scrollY: true, 23035 directionLockThreshold: 5, 23036 momentum: true, 23037 23038 bounce: true, 23039 bounceTime: 600, 23040 bounceEasing: '', 23041 23042 preventDefault: true, 23043 preventDefaultException: { tagName: /^(INPUT|TEXTAREA|BUTTON|SELECT|LABEL)$/ }, 23044 23045 HWCompositing: true, 23046 useTransition: true, 23047 useTransform: true, 23048 bindToWrapper: typeof window.onmousedown === "undefined" 23049 }; 23050 23051 for ( var i in options ) { 23052 this.options[i] = options[i]; 23053 } 23054 23055 // Normalize options 23056 this.translateZ = this.options.HWCompositing && utils.hasPerspective ? ' translateZ(0)' : ''; 23057 23058 this.options.useTransition = utils.hasTransition && this.options.useTransition; 23059 this.options.useTransform = utils.hasTransform && this.options.useTransform; 23060 23061 this.options.eventPassthrough = this.options.eventPassthrough === true ? 'vertical' : this.options.eventPassthrough; 23062 this.options.preventDefault = !this.options.eventPassthrough && this.options.preventDefault; 23063 23064 // If you want eventPassthrough I have to lock one of the axes 23065 this.options.scrollY = this.options.eventPassthrough == 'vertical' ? false : this.options.scrollY; 23066 this.options.scrollX = this.options.eventPassthrough == 'horizontal' ? false : this.options.scrollX; 23067 23068 // With eventPassthrough we also need lockDirection mechanism 23069 this.options.freeScroll = this.options.freeScroll && !this.options.eventPassthrough; 23070 this.options.directionLockThreshold = this.options.eventPassthrough ? 0 : this.options.directionLockThreshold; 23071 23072 this.options.bounceEasing = typeof this.options.bounceEasing == 'string' ? utils.ease[this.options.bounceEasing] || utils.ease.circular : this.options.bounceEasing; 23073 23074 this.options.resizePolling = this.options.resizePolling === undefined ? 60 : this.options.resizePolling; 23075 23076 if ( this.options.tap === true ) {
vendor: 4,893 bytes, lines 23077-23248
23077 this.options.tap = 'tap'; 23078 } 23079 23080 // https://github.com/cubiq/iscroll/issues/1029 23081 if (!this.options.useTransition && !this.options.useTransform) { 23082 if(!(/relative|absolute/i).test(this.scrollerStyle.position)) { 23083 this.scrollerStyle.position = "relative"; 23084 } 23085 } 23086 23087 if ( this.options.shrinkScrollbars == 'scale' ) { 23088 this.options.useTransition = false; 23089 } 23090 23091 this.options.invertWheelDirection = this.options.invertWheelDirection ? -1 : 1; 23092 23093// INSERT POINT: NORMALIZATION 23094 23095 // Some defaults 23096 this.x = 0; 23097 this.y = 0; 23098 this.directionX = 0; 23099 this.directionY = 0; 23100 this._events = {}; 23101 23102// INSERT POINT: DEFAULTS 23103 23104 this._init(); 23105 this.refresh(); 23106 23107 this.scrollTo(this.options.startX, this.options.startY); 23108 this.enable(); 23109} 23110 23111IScroll.prototype = { 23112 version: '5.2.0', 23113 23114 _init: function () { 23115 this._initEvents(); 23116 23117 if ( this.options.scrollbars || this.options.indicators ) { 23118 this._initIndicators(); 23119 } 23120 23121 if ( this.options.mouseWheel ) { 23122 this._initWheel(); 23123 } 23124 23125 if ( this.options.snap ) { 23126 this._initSnap(); 23127 } 23128 23129 if ( this.options.keyBindings ) { 23130 this._initKeys(); 23131 } 23132 23133// INSERT POINT: _init 23134 23135 }, 23136 23137 destroy: function () { 23138 this._initEvents(true); 23139 clearTimeout(this.resizeTimeout); 23140 this.resizeTimeout = null; 23141 this._execEvent('destroy'); 23142 }, 23143 23144 _transitionEnd: function (e) { 23145 if ( e.target != this.scroller || !this.isInTransition ) { 23146 return; 23147 } 23148 23149 this._transitionTime(); 23150 if ( !this.resetPosition(this.options.bounceTime) ) { 23151 this.isInTransition = false; 23152 this._execEvent('scrollEnd'); 23153 } 23154 }, 23155 23156 _start: function (e) { 23157 // React to left mouse button only 23158 if ( utils.eventType[e.type] != 1 ) { 23159 // for button property 23160 // http://unixpapa.com/js/mouse.html 23161 var button; 23162 if (!e.which) { 23163 /* IE case */ 23164 button = (e.button < 2) ? 0 : 23165 ((e.button == 4) ? 1 : 2); 23166 } else { 23167 /* All others */ 23168 button = e.button; 23169 } 23170 if ( button !== 0 ) { 23171 return; 23172 } 23173 } 23174 23175 if ( !this.enabled || (this.initiated && utils.eventType[e.type] !== this.initiated) ) { 23176 return; 23177 } 23178 23179 if ( this.options.preventDefault && !utils.isBadAndroid && !utils.preventDefaultException(e.target, this.options.preventDefaultException) ) { 23180 e.preventDefault(); 23181 } 23182 23183 var point = e.touches ? e.touches[0] : e, 23184 pos; 23185 23186 this.initiated = utils.eventType[e.type]; 23187 this.moved = false; 23188 this.distX = 0; 23189 this.distY = 0; 23190 this.directionX = 0; 23191 this.directionY = 0; 23192 this.directionLocked = 0; 23193 23194 this.startTime = utils.getTime(); 23195 23196 if ( this.options.useTransition && this.isInTransition ) { 23197 this._transitionTime(); 23198 this.isInTransition = false; 23199 pos = this.getComputedPosition(); 23200 this._translate(Math.round(pos.x), Math.round(pos.y)); 23201 this._execEvent('scrollEnd'); 23202 } else if ( !this.options.useTransition && this.isAnimating ) { 23203 this.isAnimating = false; 23204 this._execEvent('scrollEnd'); 23205 } 23206 23207 this.startX = this.x; 23208 this.startY = this.y; 23209 this.absStartX = this.x; 23210 this.absStartY = this.y; 23211 this.pointX = point.pageX; 23212 this.pointY = point.pageY; 23213 23214 this._execEvent('beforeScrollStart'); 23215 }, 23216 23217 _move: function (e) { 23218 if ( !this.enabled || utils.eventType[e.type] !== this.initiated ) { 23219 return; 23220 } 23221 23222 if ( this.options.preventDefault ) { // increases performance on Android? TODO: check! 23223 e.preventDefault(); 23224 } 23225 23226 var point = e.touches ? e.touches[0] : e, 23227 deltaX = point.pageX - this.pointX, 23228 deltaY = point.pageY - this.pointY, 23229 timestamp = utils.getTime(), 23230 newX, newY, 23231 absDistX, absDistY; 23232 23233 this.pointX = point.pageX; 23234 this.pointY = point.pageY; 23235 23236 this.distX += deltaX; 23237 this.distY += deltaY; 23238 absDistX = Math.abs(this.distX); 23239 absDistY = Math.abs(this.distY); 23240 23241 // We need to move at least 10 pixels for the scrolling to initiate 23242 if ( timestamp - this.endTime > 300 && (absDistX < 10 && absDistY < 10) ) { 23243 return; 23244 } 23245 23246 // If you are scrolling in one direction lock the other 23247 if ( !this.directionLocked && !this.options.freeScroll ) { 23248 if ( absDistX > absDistY + this.options.directionLockThreshold ) {
vendor: 6,057 bytes, lines 23249-23435
23249 this.directionLocked = 'h'; // lock horizontally 23250 } else if ( absDistY >= absDistX + this.options.directionLockThreshold ) { 23251 this.directionLocked = 'v'; // lock vertically 23252 } else { 23253 this.directionLocked = 'n'; // no lock 23254 } 23255 } 23256 23257 if ( this.directionLocked == 'h' ) { 23258 if ( this.options.eventPassthrough == 'vertical' ) { 23259 e.preventDefault(); 23260 } else if ( this.options.eventPassthrough == 'horizontal' ) { 23261 this.initiated = false; 23262 return; 23263 } 23264 23265 deltaY = 0; 23266 } else if ( this.directionLocked == 'v' ) { 23267 if ( this.options.eventPassthrough == 'horizontal' ) { 23268 e.preventDefault(); 23269 } else if ( this.options.eventPassthrough == 'vertical' ) { 23270 this.initiated = false; 23271 return; 23272 } 23273 23274 deltaX = 0; 23275 } 23276 23277 deltaX = this.hasHorizontalScroll ? deltaX : 0; 23278 deltaY = this.hasVerticalScroll ? deltaY : 0; 23279 23280 newX = this.x + deltaX; 23281 newY = this.y + deltaY; 23282 23283 // Slow down if outside of the boundaries 23284 if ( newX > 0 || newX < this.maxScrollX ) { 23285 newX = this.options.bounce ? this.x + deltaX / 3 : newX > 0 ? 0 : this.maxScrollX; 23286 } 23287 if ( newY > 0 || newY < this.maxScrollY ) { 23288 newY = this.options.bounce ? this.y + deltaY / 3 : newY > 0 ? 0 : this.maxScrollY; 23289 } 23290 23291 this.directionX = deltaX > 0 ? -1 : deltaX < 0 ? 1 : 0; 23292 this.directionY = deltaY > 0 ? -1 : deltaY < 0 ? 1 : 0; 23293 23294 if ( !this.moved ) { 23295 this._execEvent('scrollStart'); 23296 } 23297 23298 this.moved = true; 23299 23300 this._translate(newX, newY); 23301 23302/* REPLACE START: _move */ 23303 23304 if ( timestamp - this.startTime > 300 ) { 23305 this.startTime = timestamp; 23306 this.startX = this.x; 23307 this.startY = this.y; 23308 } 23309 23310/* REPLACE END: _move */ 23311 23312 }, 23313 23314 _end: function (e) { 23315 if ( !this.enabled || utils.eventType[e.type] !== this.initiated ) { 23316 return; 23317 } 23318 23319 if ( this.options.preventDefault && !utils.preventDefaultException(e.target, this.options.preventDefaultException) ) { 23320 e.preventDefault(); 23321 } 23322 23323 var point = e.changedTouches ? e.changedTouches[0] : e, 23324 momentumX, 23325 momentumY, 23326 duration = utils.getTime() - this.startTime, 23327 newX = Math.round(this.x), 23328 newY = Math.round(this.y), 23329 distanceX = Math.abs(newX - this.startX), 23330 distanceY = Math.abs(newY - this.startY), 23331 time = 0, 23332 easing = ''; 23333 23334 this.isInTransition = 0; 23335 this.initiated = 0; 23336 this.endTime = utils.getTime(); 23337 23338 // reset if we are outside of the boundaries 23339 if ( this.resetPosition(this.options.bounceTime) ) { 23340 return; 23341 } 23342 23343 this.scrollTo(newX, newY); // ensures that the last position is rounded 23344 23345 // we scrolled less than 10 pixels 23346 if ( !this.moved ) { 23347 if ( this.options.tap ) { 23348 utils.tap(e, this.options.tap); 23349 } 23350 23351 if ( this.options.click ) { 23352 utils.click(e); 23353 } 23354 23355 this._execEvent('scrollCancel'); 23356 return; 23357 } 23358 23359 if ( this._events.flick && duration < 200 && distanceX < 100 && distanceY < 100 ) { 23360 this._execEvent('flick'); 23361 return; 23362 } 23363 23364 // start momentum animation if needed 23365 if ( this.options.momentum && duration < 300 ) { 23366 momentumX = this.hasHorizontalScroll ? utils.momentum(this.x, this.startX, duration, this.maxScrollX, this.options.bounce ? this.wrapperWidth : 0, this.options.deceleration) : { destination: newX, duration: 0 }; 23367 momentumY = this.hasVerticalScroll ? utils.momentum(this.y, this.startY, duration, this.maxScrollY, this.options.bounce ? this.wrapperHeight : 0, this.options.deceleration) : { destination: newY, duration: 0 }; 23368 newX = momentumX.destination; 23369 newY = momentumY.destination; 23370 time = Math.max(momentumX.duration, momentumY.duration); 23371 this.isInTransition = 1; 23372 } 23373 23374 23375 if ( this.options.snap ) { 23376 var snap = this._nearestSnap(newX, newY); 23377 this.currentPage = snap; 23378 time = this.options.snapSpeed || Math.max( 23379 Math.max( 23380 Math.min(Math.abs(newX - snap.x), 1000), 23381 Math.min(Math.abs(newY - snap.y), 1000) 23382 ), 300); 23383 newX = snap.x; 23384 newY = snap.y; 23385 23386 this.directionX = 0; 23387 this.directionY = 0; 23388 easing = this.options.bounceEasing; 23389 } 23390 23391// INSERT POINT: _end 23392 23393 if ( newX != this.x || newY != this.y ) { 23394 // change easing function when scroller goes out of the boundaries 23395 if ( newX > 0 || newX < this.maxScrollX || newY > 0 || newY < this.maxScrollY ) { 23396 easing = utils.ease.quadratic; 23397 } 23398 23399 this.scrollTo(newX, newY, time, easing); 23400 return; 23401 } 23402 23403 this._execEvent('scrollEnd'); 23404 }, 23405 23406 _resize: function () { 23407 var that = this; 23408 23409 clearTimeout(this.resizeTimeout); 23410 23411 this.resizeTimeout = setTimeout(function () { 23412 that.refresh(); 23413 }, this.options.resizePolling); 23414 }, 23415 23416 resetPosition: function (time) { 23417 var x = this.x, 23418 y = this.y; 23419 23420 time = time || 0; 23421 23422 if ( !this.hasHorizontalScroll || this.x > 0 ) { 23423 x = 0; 23424 } else if ( this.x < this.maxScrollX ) { 23425 x = this.maxScrollX; 23426 } 23427 23428 if ( !this.hasVerticalScroll || this.y > 0 ) { 23429 y = 0; 23430 } else if ( this.y < this.maxScrollY ) { 23431 y = this.maxScrollY; 23432 } 23433 23434 if ( x == this.x && y == this.y ) { 23435 return false;
vendor: 5,509 bytes, lines 23436-23640
23436 } 23437 23438 this.scrollTo(x, y, time, this.options.bounceEasing); 23439 23440 return true; 23441 }, 23442 23443 disable: function () { 23444 this.enabled = false; 23445 }, 23446 23447 enable: function () { 23448 this.enabled = true; 23449 }, 23450 23451 refresh: function () { 23452 var rf = this.wrapper.offsetHeight; // Force reflow 23453 23454 this.wrapperWidth = this.wrapper.clientWidth; 23455 this.wrapperHeight = this.wrapper.clientHeight; 23456 23457/* REPLACE START: refresh */ 23458 23459 this.scrollerWidth = this.scroller.offsetWidth; 23460 this.scrollerHeight = this.scroller.offsetHeight; 23461 23462 this.maxScrollX = this.wrapperWidth - this.scrollerWidth; 23463 this.maxScrollY = this.wrapperHeight - this.scrollerHeight; 23464 23465/* REPLACE END: refresh */ 23466 23467 this.hasHorizontalScroll = this.options.scrollX && this.maxScrollX < 0; 23468 this.hasVerticalScroll = this.options.scrollY && this.maxScrollY < 0; 23469 23470 if ( !this.hasHorizontalScroll ) { 23471 this.maxScrollX = 0; 23472 this.scrollerWidth = this.wrapperWidth; 23473 } 23474 23475 if ( !this.hasVerticalScroll ) { 23476 this.maxScrollY = 0; 23477 this.scrollerHeight = this.wrapperHeight; 23478 } 23479 23480 this.endTime = 0; 23481 this.directionX = 0; 23482 this.directionY = 0; 23483 23484 this.wrapperOffset = utils.offset(this.wrapper); 23485 23486 this._execEvent('refresh'); 23487 23488 this.resetPosition(); 23489 23490// INSERT POINT: _refresh 23491 23492 }, 23493 23494 23495 on: function (type, fn) { 23496 if ( !this._events[type] ) { 23497 this._events[type] = []; 23498 } 23499 23500 this._events[type].push(fn); 23501 }, 23502 23503 off: function (type, fn) { 23504 if ( !this._events[type] ) { 23505 return; 23506 } 23507 23508 var index = this._events[type].indexOf(fn); 23509 23510 if ( index > -1 ) { 23511 this._events[type].splice(index, 1); 23512 } 23513 }, 23514 23515 _execEvent: function (type) { 23516 if ( !this._events[type] ) { 23517 return; 23518 } 23519 23520 var i = 0, 23521 l = this._events[type].length; 23522 23523 if ( !l ) { 23524 return; 23525 } 23526 23527 for ( ; i < l; i++ ) { 23528 this._events[type][i].apply(this, [].slice.call(arguments, 1)); 23529 } 23530 }, 23531 23532 scrollBy: function (x, y, time, easing) { 23533 x = this.x + x; 23534 y = this.y + y; 23535 time = time || 0; 23536 23537 this.scrollTo(x, y, time, easing); 23538 }, 23539 23540 scrollTo: function (x, y, time, easing) { 23541 easing = easing || utils.ease.circular; 23542 23543 this.isInTransition = this.options.useTransition && time > 0; 23544 var transitionType = this.options.useTransition && easing.style; 23545 if ( !time || transitionType ) { 23546 if(transitionType) { 23547 this._transitionTimingFunction(easing.style); 23548 this._transitionTime(time); 23549 } 23550 this._translate(x, y); 23551 } else { 23552 this._animate(x, y, time, easing.fn); 23553 } 23554 }, 23555 23556 scrollToElement: function (el, time, offsetX, offsetY, easing) { 23557 el = el.nodeType ? el : this.scroller.querySelector(el); 23558 23559 if ( !el ) { 23560 return; 23561 } 23562 23563 var pos = utils.offset(el); 23564 23565 pos.left -= this.wrapperOffset.left; 23566 pos.top -= this.wrapperOffset.top; 23567 23568 // if offsetX/Y are true we center the element to the screen 23569 if ( offsetX === true ) { 23570 offsetX = Math.round(el.offsetWidth / 2 - this.wrapper.offsetWidth / 2); 23571 } 23572 if ( offsetY === true ) { 23573 offsetY = Math.round(el.offsetHeight / 2 - this.wrapper.offsetHeight / 2); 23574 } 23575 23576 pos.left -= offsetX || 0; 23577 pos.top -= offsetY || 0; 23578 23579 pos.left = pos.left > 0 ? 0 : pos.left < this.maxScrollX ? this.maxScrollX : pos.left; 23580 pos.top = pos.top > 0 ? 0 : pos.top < this.maxScrollY ? this.maxScrollY : pos.top; 23581 23582 time = time === undefined || time === null || time === 'auto' ? Math.max(Math.abs(this.x-pos.left), Math.abs(this.y-pos.top)) : time; 23583 23584 this.scrollTo(pos.left, pos.top, time, easing); 23585 }, 23586 23587 _transitionTime: function (time) { 23588 if (!this.options.useTransition) { 23589 return; 23590 } 23591 time = time || 0; 23592 var durationProp = utils.style.transitionDuration; 23593 if(!durationProp) { 23594 return; 23595 } 23596 23597 this.scrollerStyle[durationProp] = time + 'ms'; 23598 23599 if ( !time && utils.isBadAndroid ) { 23600 this.scrollerStyle[durationProp] = '0.0001ms'; 23601 // remove 0.0001ms 23602 var self = this; 23603 rAF(function() { 23604 if(self.scrollerStyle[durationProp] === '0.0001ms') { 23605 self.scrollerStyle[durationProp] = '0s'; 23606 } 23607 }); 23608 } 23609 23610 23611 if ( this.indicators ) { 23612 for ( var i = this.indicators.length; i--; ) { 23613 this.indicators[i].transitionTime(time); 23614 } 23615 } 23616 23617 23618// INSERT POINT: _transitionTime 23619 23620 }, 23621 23622 _transitionTimingFunction: function (easing) { 23623 this.scrollerStyle[utils.style.transitionTimingFunction] = easing; 23624 23625 23626 if ( this.indicators ) { 23627 for ( var i = this.indicators.length; i--; ) { 23628 this.indicators[i].transitionTimingFunction(easing); 23629 } 23630 } 23631 23632 23633// INSERT POINT: _transitionTimingFunction 23634 23635 }, 23636 23637 _translate: function (x, y) { 23638 //Uncode addition 23639 if ( (" " + this.wrapper.className + " ").replace(/[\n\t]/g, " ").indexOf(" no-scrolloverflow ") > -1 ) 23640 return false;
vendor: 9,939 bytes, lines 23641-23952
23641 23642 if ( this.options.useTransform ) { 23643 23644/* REPLACE START: _translate */ 23645 23646 this.scrollerStyle[utils.style.transform] = 'translate(' + x + 'px,' + y + 'px)' + this.translateZ; 23647 23648/* REPLACE END: _translate */ 23649 23650 } else { 23651 x = Math.round(x); 23652 y = Math.round(y); 23653 this.scrollerStyle.left = x + 'px'; 23654 this.scrollerStyle.top = y + 'px'; 23655 } 23656 23657 this.x = x; 23658 this.y = y; 23659 23660 23661 if ( this.indicators ) { 23662 for ( var i = this.indicators.length; i--; ) { 23663 this.indicators[i].updatePosition(); 23664 } 23665 } 23666 23667 //Uncode addition 23668 var uncodevent = new CustomEvent('fp-slide-scroll'); 23669 window.dispatchEvent(uncodevent); 23670 23671// INSERT POINT: _translate 23672 23673 }, 23674 23675 _initEvents: function (remove) { 23676 var eventType = remove ? utils.removeEvent : utils.addEvent, 23677 target = this.options.bindToWrapper ? this.wrapper : window; 23678 23679 eventType(window, 'orientationchange', this); 23680 eventType(window, 'resize', this); 23681 23682 if ( this.options.click ) { 23683 eventType(this.wrapper, 'click', this, true); 23684 } 23685 23686 if ( !this.options.disableMouse ) { 23687 eventType(this.wrapper, 'mousedown', this); 23688 eventType(target, 'mousemove', this); 23689 eventType(target, 'mousecancel', this); 23690 eventType(target, 'mouseup', this); 23691 } 23692 23693 if ( utils.hasPointer && !this.options.disablePointer ) { 23694 eventType(this.wrapper, utils.prefixPointerEvent('pointerdown'), this); 23695 eventType(target, utils.prefixPointerEvent('pointermove'), this); 23696 eventType(target, utils.prefixPointerEvent('pointercancel'), this); 23697 eventType(target, utils.prefixPointerEvent('pointerup'), this); 23698 } 23699 23700 if ( utils.hasTouch && !this.options.disableTouch ) { 23701 eventType(this.wrapper, 'touchstart', this); 23702 eventType(target, 'touchmove', this); 23703 eventType(target, 'touchcancel', this); 23704 eventType(target, 'touchend', this); 23705 } 23706 23707 eventType(this.scroller, 'transitionend', this); 23708 eventType(this.scroller, 'webkitTransitionEnd', this); 23709 eventType(this.scroller, 'oTransitionEnd', this); 23710 eventType(this.scroller, 'MSTransitionEnd', this); 23711 }, 23712 23713 getComputedPosition: function () { 23714 var matrix = window.getComputedStyle(this.scroller, null), 23715 x, y; 23716 23717 if ( this.options.useTransform ) { 23718 matrix = matrix[utils.style.transform].split(')')[0].split(', '); 23719 x = +(matrix[12] || matrix[4]); 23720 y = +(matrix[13] || matrix[5]); 23721 } else { 23722 x = +matrix.left.replace(/[^-\d.]/g, ''); 23723 y = +matrix.top.replace(/[^-\d.]/g, ''); 23724 } 23725 23726 return { x: x, y: y }; 23727 }, 23728 _initIndicators: function () { 23729 var interactive = this.options.interactiveScrollbars, 23730 customStyle = typeof this.options.scrollbars != 'string', 23731 indicators = [], 23732 indicator; 23733 23734 var that = this; 23735 23736 this.indicators = []; 23737 23738 if ( this.options.scrollbars ) { 23739 // Vertical scrollbar 23740 if ( this.options.scrollY ) { 23741 indicator = { 23742 el: createDefaultScrollbar('v', interactive, this.options.scrollbars), 23743 interactive: interactive, 23744 defaultScrollbars: true, 23745 customStyle: customStyle, 23746 resize: this.options.resizeScrollbars, 23747 shrink: this.options.shrinkScrollbars, 23748 fade: this.options.fadeScrollbars, 23749 listenX: false 23750 }; 23751 23752 this.wrapper.appendChild(indicator.el); 23753 indicators.push(indicator); 23754 } 23755 23756 // Horizontal scrollbar 23757 if ( this.options.scrollX ) { 23758 indicator = { 23759 el: createDefaultScrollbar('h', interactive, this.options.scrollbars), 23760 interactive: interactive, 23761 defaultScrollbars: true, 23762 customStyle: customStyle, 23763 resize: this.options.resizeScrollbars, 23764 shrink: this.options.shrinkScrollbars, 23765 fade: this.options.fadeScrollbars, 23766 listenY: false 23767 }; 23768 23769 this.wrapper.appendChild(indicator.el); 23770 indicators.push(indicator); 23771 } 23772 } 23773 23774 if ( this.options.indicators ) { 23775 // TODO: check concat compatibility 23776 indicators = indicators.concat(this.options.indicators); 23777 } 23778 23779 for ( var i = indicators.length; i--; ) { 23780 this.indicators.push( new Indicator(this, indicators[i]) ); 23781 } 23782 23783 // TODO: check if we can use array.map (wide compatibility and performance issues) 23784 function _indicatorsMap (fn) { 23785 if (that.indicators) { 23786 for ( var i = that.indicators.length; i--; ) { 23787 fn.call(that.indicators[i]); 23788 } 23789 } 23790 } 23791 23792 if ( this.options.fadeScrollbars ) { 23793 this.on('scrollEnd', function () { 23794 _indicatorsMap(function () { 23795 this.fade(); 23796 }); 23797 }); 23798 23799 this.on('scrollCancel', function () { 23800 _indicatorsMap(function () { 23801 this.fade(); 23802 }); 23803 }); 23804 23805 this.on('scrollStart', function () { 23806 _indicatorsMap(function () { 23807 this.fade(1); 23808 }); 23809 }); 23810 23811 this.on('beforeScrollStart', function () { 23812 _indicatorsMap(function () { 23813 this.fade(1, true); 23814 }); 23815 }); 23816 } 23817 23818 23819 this.on('refresh', function () { 23820 _indicatorsMap(function () { 23821 this.refresh(); 23822 }); 23823 }); 23824 23825 this.on('destroy', function () { 23826 _indicatorsMap(function () { 23827 this.destroy(); 23828 }); 23829 23830 delete this.indicators; 23831 }); 23832 }, 23833 23834 _initWheel: function () { 23835 utils.addEvent(this.wrapper, 'wheel', this); 23836 utils.addEvent(this.wrapper, 'mousewheel', this); 23837 utils.addEvent(this.wrapper, 'DOMMouseScroll', this); 23838 23839 this.on('destroy', function () { 23840 clearTimeout(this.wheelTimeout); 23841 this.wheelTimeout = null; 23842 utils.removeEvent(this.wrapper, 'wheel', this); 23843 utils.removeEvent(this.wrapper, 'mousewheel', this); 23844 utils.removeEvent(this.wrapper, 'DOMMouseScroll', this); 23845 }); 23846 }, 23847 23848 _wheel: function (e) { 23849 if ( !this.enabled ) { 23850 return; 23851 } 23852 23853 var wheelDeltaX, wheelDeltaY, 23854 newX, newY, 23855 that = this; 23856 23857 if ( this.wheelTimeout === undefined ) { 23858 that._execEvent('scrollStart'); 23859 } 23860 23861 // Execute the scrollEnd event after 400ms the wheel stopped scrolling 23862 clearTimeout(this.wheelTimeout); 23863 this.wheelTimeout = setTimeout(function () { 23864 if(!that.options.snap) { 23865 that._execEvent('scrollEnd'); 23866 } 23867 that.wheelTimeout = undefined; 23868 }, 400); 23869 23870 if ( 'deltaX' in e ) { 23871 if (e.deltaMode === 1) { 23872 wheelDeltaX = -e.deltaX * this.options.mouseWheelSpeed; 23873 wheelDeltaY = -e.deltaY * this.options.mouseWheelSpeed; 23874 } else { 23875 wheelDeltaX = -e.deltaX; 23876 wheelDeltaY = -e.deltaY; 23877 } 23878 } else if ( 'wheelDeltaX' in e ) { 23879 wheelDeltaX = e.wheelDeltaX / 120 * this.options.mouseWheelSpeed; 23880 wheelDeltaY = e.wheelDeltaY / 120 * this.options.mouseWheelSpeed; 23881 } else if ( 'wheelDelta' in e ) { 23882 wheelDeltaX = wheelDeltaY = e.wheelDelta / 120 * this.options.mouseWheelSpeed; 23883 } else if ( 'detail' in e ) { 23884 wheelDeltaX = wheelDeltaY = -e.detail / 3 * this.options.mouseWheelSpeed; 23885 } else { 23886 return; 23887 } 23888 23889 wheelDeltaX *= this.options.invertWheelDirection; 23890 wheelDeltaY *= this.options.invertWheelDirection; 23891 23892 if ( !this.hasVerticalScroll ) { 23893 wheelDeltaX = wheelDeltaY; 23894 wheelDeltaY = 0; 23895 } 23896 23897 if ( this.options.snap ) { 23898 newX = this.currentPage.pageX; 23899 newY = this.currentPage.pageY; 23900 23901 if ( wheelDeltaX > 0 ) { 23902 newX--; 23903 } else if ( wheelDeltaX < 0 ) { 23904 newX++; 23905 } 23906 23907 if ( wheelDeltaY > 0 ) { 23908 newY--; 23909 } else if ( wheelDeltaY < 0 ) { 23910 newY++; 23911 } 23912 23913 this.goToPage(newX, newY); 23914 23915 return; 23916 } 23917 23918 newX = this.x + Math.round(this.hasHorizontalScroll ? wheelDeltaX : 0); 23919 newY = this.y + Math.round(this.hasVerticalScroll ? wheelDeltaY : 0); 23920 23921 this.directionX = wheelDeltaX > 0 ? -1 : wheelDeltaX < 0 ? 1 : 0; 23922 this.directionY = wheelDeltaY > 0 ? -1 : wheelDeltaY < 0 ? 1 : 0; 23923 23924 if ( newX > 0 ) { 23925 newX = 0; 23926 } else if ( newX < this.maxScrollX ) { 23927 newX = this.maxScrollX; 23928 } 23929 23930 if ( newY > 0 ) { 23931 newY = 0; 23932 } else if ( newY < this.maxScrollY ) { 23933 newY = this.maxScrollY; 23934 } 23935 23936 this.scrollTo(newX, newY, 0); 23937 23938// INSERT POINT: _wheel 23939 }, 23940 23941 _initSnap: function () { 23942 this.currentPage = {}; 23943 23944 if ( typeof this.options.snap == 'string' ) { 23945 this.options.snap = this.scroller.querySelectorAll(this.options.snap); 23946 } 23947 23948 this.on('refresh', function () { 23949 var i = 0, l, 23950 m = 0, n, 23951 cx, cy, 23952 x = 0, y,
vendor: 7,339 bytes, lines 23953-24206
23953 stepX = this.options.snapStepX || this.wrapperWidth, 23954 stepY = this.options.snapStepY || this.wrapperHeight, 23955 el; 23956 23957 this.pages = []; 23958 23959 if ( !this.wrapperWidth || !this.wrapperHeight || !this.scrollerWidth || !this.scrollerHeight ) { 23960 return; 23961 } 23962 23963 if ( this.options.snap === true ) { 23964 cx = Math.round( stepX / 2 ); 23965 cy = Math.round( stepY / 2 ); 23966 23967 while ( x > -this.scrollerWidth ) { 23968 this.pages[i] = []; 23969 l = 0; 23970 y = 0; 23971 23972 while ( y > -this.scrollerHeight ) { 23973 this.pages[i][l] = { 23974 x: Math.max(x, this.maxScrollX), 23975 y: Math.max(y, this.maxScrollY), 23976 width: stepX, 23977 height: stepY, 23978 cx: x - cx, 23979 cy: y - cy 23980 }; 23981 23982 y -= stepY; 23983 l++; 23984 } 23985 23986 x -= stepX; 23987 i++; 23988 } 23989 } else { 23990 el = this.options.snap; 23991 l = el.length; 23992 n = -1; 23993 23994 for ( ; i < l; i++ ) { 23995 if ( i === 0 || el[i].offsetLeft <= el[i-1].offsetLeft ) { 23996 m = 0; 23997 n++; 23998 } 23999 24000 if ( !this.pages[m] ) { 24001 this.pages[m] = []; 24002 } 24003 24004 x = Math.max(-el[i].offsetLeft, this.maxScrollX); 24005 y = Math.max(-el[i].offsetTop, this.maxScrollY); 24006 cx = x - Math.round(el[i].offsetWidth / 2); 24007 cy = y - Math.round(el[i].offsetHeight / 2); 24008 24009 this.pages[m][n] = { 24010 x: x, 24011 y: y, 24012 width: el[i].offsetWidth, 24013 height: el[i].offsetHeight, 24014 cx: cx, 24015 cy: cy 24016 }; 24017 24018 if ( x > this.maxScrollX ) { 24019 m++; 24020 } 24021 } 24022 } 24023 24024 this.goToPage(this.currentPage.pageX || 0, this.currentPage.pageY || 0, 0); 24025 24026 // Update snap threshold if needed 24027 if ( this.options.snapThreshold % 1 === 0 ) { 24028 this.snapThresholdX = this.options.snapThreshold; 24029 this.snapThresholdY = this.options.snapThreshold; 24030 } else { 24031 this.snapThresholdX = Math.round(this.pages[this.currentPage.pageX][this.currentPage.pageY].width * this.options.snapThreshold); 24032 this.snapThresholdY = Math.round(this.pages[this.currentPage.pageX][this.currentPage.pageY].height * this.options.snapThreshold); 24033 } 24034 }); 24035 24036 this.on('flick', function () { 24037 var time = this.options.snapSpeed || Math.max( 24038 Math.max( 24039 Math.min(Math.abs(this.x - this.startX), 1000), 24040 Math.min(Math.abs(this.y - this.startY), 1000) 24041 ), 300); 24042 24043 this.goToPage( 24044 this.currentPage.pageX + this.directionX, 24045 this.currentPage.pageY + this.directionY, 24046 time 24047 ); 24048 }); 24049 }, 24050 24051 _nearestSnap: function (x, y) { 24052 if ( !this.pages.length ) { 24053 return { x: 0, y: 0, pageX: 0, pageY: 0 }; 24054 } 24055 24056 var i = 0, 24057 l = this.pages.length, 24058 m = 0; 24059 24060 // Check if we exceeded the snap threshold 24061 if ( Math.abs(x - this.absStartX) < this.snapThresholdX && 24062 Math.abs(y - this.absStartY) < this.snapThresholdY ) { 24063 return this.currentPage; 24064 } 24065 24066 if ( x > 0 ) { 24067 x = 0; 24068 } else if ( x < this.maxScrollX ) { 24069 x = this.maxScrollX; 24070 } 24071 24072 if ( y > 0 ) { 24073 y = 0; 24074 } else if ( y < this.maxScrollY ) { 24075 y = this.maxScrollY; 24076 } 24077 24078 for ( ; i < l; i++ ) { 24079 if ( x >= this.pages[i][0].cx ) { 24080 x = this.pages[i][0].x; 24081 break; 24082 } 24083 } 24084 24085 l = this.pages[i].length; 24086 24087 for ( ; m < l; m++ ) { 24088 if ( y >= this.pages[0][m].cy ) { 24089 y = this.pages[0][m].y; 24090 break; 24091 } 24092 } 24093 24094 if ( i == this.currentPage.pageX ) { 24095 i += this.directionX; 24096 24097 if ( i < 0 ) { 24098 i = 0; 24099 } else if ( i >= this.pages.length ) { 24100 i = this.pages.length - 1; 24101 } 24102 24103 x = this.pages[i][0].x; 24104 } 24105 24106 if ( m == this.currentPage.pageY ) { 24107 m += this.directionY; 24108 24109 if ( m < 0 ) { 24110 m = 0; 24111 } else if ( m >= this.pages[0].length ) { 24112 m = this.pages[0].length - 1; 24113 } 24114 24115 y = this.pages[0][m].y; 24116 } 24117 24118 return { 24119 x: x, 24120 y: y, 24121 pageX: i, 24122 pageY: m 24123 }; 24124 }, 24125 24126 goToPage: function (x, y, time, easing) { 24127 easing = easing || this.options.bounceEasing; 24128 24129 if ( x >= this.pages.length ) { 24130 x = this.pages.length - 1; 24131 } else if ( x < 0 ) { 24132 x = 0; 24133 } 24134 24135 if ( y >= this.pages[x].length ) { 24136 y = this.pages[x].length - 1; 24137 } else if ( y < 0 ) { 24138 y = 0; 24139 } 24140 24141 var posX = this.pages[x][y].x, 24142 posY = this.pages[x][y].y; 24143 24144 time = time === undefined ? this.options.snapSpeed || Math.max( 24145 Math.max( 24146 Math.min(Math.abs(posX - this.x), 1000), 24147 Math.min(Math.abs(posY - this.y), 1000) 24148 ), 300) : time; 24149 24150 this.currentPage = { 24151 x: posX, 24152 y: posY, 24153 pageX: x, 24154 pageY: y 24155 }; 24156 24157 this.scrollTo(posX, posY, time, easing); 24158 }, 24159 24160 next: function (time, easing) { 24161 var x = this.currentPage.pageX, 24162 y = this.currentPage.pageY; 24163 24164 x++; 24165 24166 if ( x >= this.pages.length && this.hasVerticalScroll ) { 24167 x = 0; 24168 y++; 24169 } 24170 24171 this.goToPage(x, y, time, easing); 24172 }, 24173 24174 prev: function (time, easing) { 24175 var x = this.currentPage.pageX, 24176 y = this.currentPage.pageY; 24177 24178 x--; 24179 24180 if ( x < 0 && this.hasVerticalScroll ) { 24181 x = 0; 24182 y--; 24183 } 24184 24185 this.goToPage(x, y, time, easing); 24186 }, 24187 24188 _initKeys: function (e) { 24189 // default key bindings 24190 var keys = { 24191 pageUp: 33, 24192 pageDown: 34, 24193 end: 35, 24194 home: 36, 24195 left: 37, 24196 up: 38, 24197 right: 39, 24198 down: 40 24199 }; 24200 var i; 24201 24202 // if you give me characters I give you keycode 24203 if ( typeof this.options.keyBindings == 'object' ) { 24204 for ( i in this.options.keyBindings ) { 24205 if ( typeof this.options.keyBindings[i] == 'string' ) { 24206 this.options.keyBindings[i] = this.options.keyBindings[i].toUpperCase().charCo
vendor: 11,097 bytes, lines 24206-24559
24206deAt(0); 24207 } 24208 } 24209 } else { 24210 this.options.keyBindings = {}; 24211 } 24212 24213 for ( i in keys ) { 24214 this.options.keyBindings[i] = this.options.keyBindings[i] || keys[i]; 24215 } 24216 24217 utils.addEvent(window, 'keydown', this); 24218 24219 this.on('destroy', function () { 24220 utils.removeEvent(window, 'keydown', this); 24221 }); 24222 }, 24223 24224 _key: function (e) { 24225 if ( !this.enabled ) { 24226 return; 24227 } 24228 24229 var snap = this.options.snap, // we are using this alot, better to cache it 24230 newX = snap ? this.currentPage.pageX : this.x, 24231 newY = snap ? this.currentPage.pageY : this.y, 24232 now = utils.getTime(), 24233 prevTime = this.keyTime || 0, 24234 acceleration = 0.250, 24235 pos; 24236 24237 if ( this.options.useTransition && this.isInTransition ) { 24238 pos = this.getComputedPosition(); 24239 24240 this._translate(Math.round(pos.x), Math.round(pos.y)); 24241 this.isInTransition = false; 24242 } 24243 24244 this.keyAcceleration = now - prevTime < 200 ? Math.min(this.keyAcceleration + acceleration, 50) : 0; 24245 24246 switch ( e.keyCode ) { 24247 case this.options.keyBindings.pageUp: 24248 if ( this.hasHorizontalScroll && !this.hasVerticalScroll ) { 24249 newX += snap ? 1 : this.wrapperWidth; 24250 } else { 24251 newY += snap ? 1 : this.wrapperHeight; 24252 } 24253 break; 24254 case this.options.keyBindings.pageDown: 24255 if ( this.hasHorizontalScroll && !this.hasVerticalScroll ) { 24256 newX -= snap ? 1 : this.wrapperWidth; 24257 } else { 24258 newY -= snap ? 1 : this.wrapperHeight; 24259 } 24260 break; 24261 case this.options.keyBindings.end: 24262 newX = snap ? this.pages.length-1 : this.maxScrollX; 24263 newY = snap ? this.pages[0].length-1 : this.maxScrollY; 24264 break; 24265 case this.options.keyBindings.home: 24266 newX = 0; 24267 newY = 0; 24268 break; 24269 case this.options.keyBindings.left: 24270 newX += snap ? -1 : 5 + this.keyAcceleration>>0; 24271 break; 24272 case this.options.keyBindings.up: 24273 newY += snap ? 1 : 5 + this.keyAcceleration>>0; 24274 break; 24275 case this.options.keyBindings.right: 24276 newX -= snap ? -1 : 5 + this.keyAcceleration>>0; 24277 break; 24278 case this.options.keyBindings.down: 24279 newY -= snap ? 1 : 5 + this.keyAcceleration>>0; 24280 break; 24281 default: 24282 return; 24283 } 24284 24285 if ( snap ) { 24286 this.goToPage(newX, newY); 24287 return; 24288 } 24289 24290 if ( newX > 0 ) { 24291 newX = 0; 24292 this.keyAcceleration = 0; 24293 } else if ( newX < this.maxScrollX ) { 24294 newX = this.maxScrollX; 24295 this.keyAcceleration = 0; 24296 } 24297 24298 if ( newY > 0 ) { 24299 newY = 0; 24300 this.keyAcceleration = 0; 24301 } else if ( newY < this.maxScrollY ) { 24302 newY = this.maxScrollY; 24303 this.keyAcceleration = 0; 24304 } 24305 24306 this.scrollTo(newX, newY, 0); 24307 24308 this.keyTime = now; 24309 }, 24310 24311 _animate: function (destX, destY, duration, easingFn) { 24312 var that = this, 24313 startX = this.x, 24314 startY = this.y, 24315 startTime = utils.getTime(), 24316 destTime = startTime + duration; 24317 24318 function step () { 24319 var now = utils.getTime(), 24320 newX, newY, 24321 easing; 24322 24323 if ( now >= destTime ) { 24324 that.isAnimating = false; 24325 that._translate(destX, destY); 24326 24327 if ( !that.resetPosition(that.options.bounceTime) ) { 24328 that._execEvent('scrollEnd'); 24329 } 24330 24331 return; 24332 } 24333 24334 now = ( now - startTime ) / duration; 24335 easing = easingFn(now); 24336 newX = ( destX - startX ) * easing + startX; 24337 newY = ( destY - startY ) * easing + startY; 24338 that._translate(newX, newY); 24339 24340 if ( that.isAnimating ) { 24341 rAF(step); 24342 } 24343 } 24344 24345 this.isAnimating = true; 24346 step(); 24347 }, 24348 handleEvent: function (e) { 24349 switch ( e.type ) { 24350 case 'touchstart': 24351 case 'pointerdown': 24352 case 'MSPointerDown': 24353 case 'mousedown': 24354 this._start(e); 24355 break; 24356 case 'touchmove': 24357 case 'pointermove': 24358 case 'MSPointerMove': 24359 case 'mousemove': 24360 this._move(e); 24361 break; 24362 case 'touchend': 24363 case 'pointerup': 24364 case 'MSPointerUp': 24365 case 'mouseup': 24366 case 'touchcancel': 24367 case 'pointercancel': 24368 case 'MSPointerCancel': 24369 case 'mousecancel': 24370 this._end(e); 24371 break; 24372 case 'orientationchange': 24373 case 'resize': 24374 this._resize(); 24375 break; 24376 case 'transitionend': 24377 case 'webkitTransitionEnd': 24378 case 'oTransitionEnd': 24379 case 'MSTransitionEnd': 24380 this._transitionEnd(e); 24381 break; 24382 case 'wheel': 24383 case 'DOMMouseScroll': 24384 case 'mousewheel': 24385 this._wheel(e); 24386 break; 24387 case 'keydown': 24388 this._key(e); 24389 break; 24390 case 'click': 24391 if ( this.enabled && !e._constructed ) { 24392 e.preventDefault(); 24393 e.stopPropagation(); 24394 } 24395 break; 24396 } 24397 } 24398}; 24399function createDefaultScrollbar (direction, interactive, type) { 24400 var scrollbar = document.createElement('div'), 24401 indicator = document.createElement('div'); 24402 24403 if ( type === true ) { 24404 scrollbar.style.cssText = 'position:absolute;z-index:9999'; 24405 indicator.style.cssText = '-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;position:absolute;background:rgba(0,0,0,0.5);border:1px solid rgba(255,255,255,0.9);border-radius:3px'; 24406 } 24407 24408 indicator.className = 'iScrollIndicator'; 24409 24410 if ( direction == 'h' ) { 24411 if ( type === true ) { 24412 scrollbar.style.cssText += ';height:7px;left:2px;right:2px;bottom:0'; 24413 indicator.style.height = '100%'; 24414 } 24415 scrollbar.className = 'iScrollHorizontalScrollbar'; 24416 } else { 24417 if ( type === true ) { 24418 scrollbar.style.cssText += ';width:7px;bottom:2px;top:2px;right:1px'; 24419 indicator.style.width = '100%'; 24420 } 24421 scrollbar.className = 'iScrollVerticalScrollbar'; 24422 } 24423 24424 scrollbar.style.cssText += ';overflow:hidden'; 24425 24426 if ( !interactive ) { 24427 scrollbar.style.pointerEvents = 'none'; 24428 } 24429 24430 scrollbar.appendChild(indicator); 24431 24432 return scrollbar; 24433} 24434 24435function Indicator (scroller, options) { 24436 this.wrapper = typeof options.el == 'string' ? document.querySelector(options.el) : options.el; 24437 this.wrapperStyle = this.wrapper.style; 24438 this.indicator = this.wrapper.children[0]; 24439 this.indicatorStyle = this.indicator.style; 24440 this.scroller = scroller; 24441 24442 this.options = { 24443 listenX: true, 24444 listenY: true, 24445 interactive: false, 24446 resize: true, 24447 defaultScrollbars: false, 24448 shrink: false, 24449 fade: false, 24450 speedRatioX: 0, 24451 speedRatioY: 0 24452 }; 24453 24454 for ( var i in options ) { 24455 this.options[i] = options[i]; 24456 } 24457 24458 this.sizeRatioX = 1; 24459 this.sizeRatioY = 1; 24460 this.maxPosX = 0; 24461 this.maxPosY = 0; 24462 24463 if ( this.options.interactive ) { 24464 if ( !this.options.disableTouch ) { 24465 utils.addEvent(this.indicator, 'touchstart', this); 24466 utils.addEvent(window, 'touchend', this); 24467 } 24468 if ( !this.options.disablePointer ) { 24469 utils.addEvent(this.indicator, utils.prefixPointerEvent('pointerdown'), this); 24470 utils.addEvent(window, utils.prefixPointerEvent('pointerup'), this); 24471 } 24472 if ( !this.options.disableMouse ) { 24473 utils.addEvent(this.indicator, 'mousedown', this); 24474 utils.addEvent(window, 'mouseup', this); 24475 } 24476 } 24477 24478 if ( this.options.fade ) { 24479 this.wrapperStyle[utils.style.transform] = this.scroller.translateZ; 24480 var durationProp = utils.style.transitionDuration; 24481 if(!durationProp) { 24482 return; 24483 } 24484 this.wrapperStyle[durationProp] = utils.isBadAndroid ? '0.0001ms' : '0ms'; 24485 // remove 0.0001ms 24486 var self = this; 24487 if(utils.isBadAndroid) { 24488 rAF(function() { 24489 if(self.wrapperStyle[durationProp] === '0.0001ms') { 24490 self.wrapperStyle[durationProp] = '0s'; 24491 } 24492 }); 24493 } 24494 this.wrapperStyle.opacity = '0'; 24495 } 24496} 24497 24498Indicator.prototype = { 24499 handleEvent: function (e) { 24500 switch ( e.type ) { 24501 case 'touchstart': 24502 case 'pointerdown': 24503 case 'MSPointerDown': 24504 case 'mousedown': 24505 this._start(e); 24506 break; 24507 case 'touchmove': 24508 case 'pointermove': 24509 case 'MSPointerMove': 24510 case 'mousemove': 24511 this._move(e); 24512 break; 24513 case 'touchend': 24514 case 'pointerup': 24515 case 'MSPointerUp': 24516 case 'mouseup': 24517 case 'touchcancel': 24518 case 'pointercancel': 24519 case 'MSPointerCancel': 24520 case 'mousecancel': 24521 this._end(e); 24522 break; 24523 } 24524 }, 24525 24526 destroy: function () { 24527 if ( this.options.fadeScrollbars ) { 24528 clearTimeout(this.fadeTimeout); 24529 this.fadeTimeout = null; 24530 } 24531 if ( this.options.interactive ) { 24532 utils.removeEvent(this.indicator, 'touchstart', this); 24533 utils.removeEvent(this.indicator, utils.prefixPointerEvent('pointerdown'), this); 24534 utils.removeEvent(this.indicator, 'mousedown', this); 24535 24536 utils.removeEvent(window, 'touchmove', this); 24537 utils.removeEvent(window, utils.prefixPointerEvent('pointermove'), this); 24538 utils.removeEvent(window, 'mousemove', this); 24539 24540 utils.removeEvent(window, 'touchend', this); 24541 utils.removeEvent(window, utils.prefixPointerEvent('pointerup'), this); 24542 utils.removeEvent(window, 'mouseup', this); 24543 } 24544 24545 if ( this.options.defaultScrollbars ) { 24546 this.wrapper.parentNode.removeChild(this.wrapper); 24547 } 24548 }, 24549 24550 _start: function (e) { 24551 var point = e.touches ? e.touches[0] : e; 24552 24553 e.preventDefault(); 24554 e.stopPropagation(); 24555 24556 this.transitionTime(); 24557 24558 this.initiated = true; 24559 this.moved = false;
vendor: 9,615 bytes, lines 24560-24818
24560 this.lastPointX = point.pageX; 24561 this.lastPointY = point.pageY; 24562 24563 this.startTime = utils.getTime(); 24564 24565 if ( !this.options.disableTouch ) { 24566 utils.addEvent(window, 'touchmove', this); 24567 } 24568 if ( !this.options.disablePointer ) { 24569 utils.addEvent(window, utils.prefixPointerEvent('pointermove'), this); 24570 } 24571 if ( !this.options.disableMouse ) { 24572 utils.addEvent(window, 'mousemove', this); 24573 } 24574 24575 this.scroller._execEvent('beforeScrollStart'); 24576 }, 24577 24578 _move: function (e) { 24579 var point = e.touches ? e.touches[0] : e, 24580 deltaX, deltaY, 24581 newX, newY, 24582 timestamp = utils.getTime(); 24583 24584 if ( !this.moved ) { 24585 this.scroller._execEvent('scrollStart'); 24586 } 24587 24588 this.moved = true; 24589 24590 deltaX = point.pageX - this.lastPointX; 24591 this.lastPointX = point.pageX; 24592 24593 deltaY = point.pageY - this.lastPointY; 24594 this.lastPointY = point.pageY; 24595 24596 newX = this.x + deltaX; 24597 newY = this.y + deltaY; 24598 24599 this._pos(newX, newY); 24600 24601// INSERT POINT: indicator._move 24602 24603 e.preventDefault(); 24604 e.stopPropagation(); 24605 }, 24606 24607 _end: function (e) { 24608 if ( !this.initiated ) { 24609 return; 24610 } 24611 24612 this.initiated = false; 24613 24614 e.preventDefault(); 24615 e.stopPropagation(); 24616 24617 utils.removeEvent(window, 'touchmove', this); 24618 utils.removeEvent(window, utils.prefixPointerEvent('pointermove'), this); 24619 utils.removeEvent(window, 'mousemove', this); 24620 24621 if ( this.scroller.options.snap ) { 24622 var snap = this.scroller._nearestSnap(this.scroller.x, this.scroller.y); 24623 24624 var time = this.options.snapSpeed || Math.max( 24625 Math.max( 24626 Math.min(Math.abs(this.scroller.x - snap.x), 1000), 24627 Math.min(Math.abs(this.scroller.y - snap.y), 1000) 24628 ), 300); 24629 24630 if ( this.scroller.x != snap.x || this.scroller.y != snap.y ) { 24631 this.scroller.directionX = 0; 24632 this.scroller.directionY = 0; 24633 this.scroller.currentPage = snap; 24634 this.scroller.scrollTo(snap.x, snap.y, time, this.scroller.options.bounceEasing); 24635 } 24636 } 24637 24638 if ( this.moved ) { 24639 this.scroller._execEvent('scrollEnd'); 24640 } 24641 }, 24642 24643 transitionTime: function (time) { 24644 time = time || 0; 24645 var durationProp = utils.style.transitionDuration; 24646 if(!durationProp) { 24647 return; 24648 } 24649 24650 this.indicatorStyle[durationProp] = time + 'ms'; 24651 24652 if ( !time && utils.isBadAndroid ) { 24653 this.indicatorStyle[durationProp] = '0.0001ms'; 24654 // remove 0.0001ms 24655 var self = this; 24656 rAF(function() { 24657 if(self.indicatorStyle[durationProp] === '0.0001ms') { 24658 self.indicatorStyle[durationProp] = '0s'; 24659 } 24660 }); 24661 } 24662 }, 24663 24664 transitionTimingFunction: function (easing) { 24665 this.indicatorStyle[utils.style.transitionTimingFunction] = easing; 24666 }, 24667 24668 refresh: function () { 24669 this.transitionTime(); 24670 24671 if ( this.options.listenX && !this.options.listenY ) { 24672 this.indicatorStyle.display = this.scroller.hasHorizontalScroll ? 'block' : 'none'; 24673 } else if ( this.options.listenY && !this.options.listenX ) { 24674 this.indicatorStyle.display = this.scroller.hasVerticalScroll ? 'block' : 'none'; 24675 } else { 24676 this.indicatorStyle.display = this.scroller.hasHorizontalScroll || this.scroller.hasVerticalScroll ? 'block' : 'none'; 24677 } 24678 24679 if ( this.scroller.hasHorizontalScroll && this.scroller.hasVerticalScroll ) { 24680 utils.addClass(this.wrapper, 'iScrollBothScrollbars'); 24681 utils.removeClass(this.wrapper, 'iScrollLoneScrollbar'); 24682 24683 if ( this.options.defaultScrollbars && this.options.customStyle ) { 24684 if ( this.options.listenX ) { 24685 this.wrapper.style.right = '8px'; 24686 } else { 24687 this.wrapper.style.bottom = '8px'; 24688 } 24689 } 24690 } else { 24691 utils.removeClass(this.wrapper, 'iScrollBothScrollbars'); 24692 utils.addClass(this.wrapper, 'iScrollLoneScrollbar'); 24693 24694 if ( this.options.defaultScrollbars && this.options.customStyle ) { 24695 if ( this.options.listenX ) { 24696 this.wrapper.style.right = '2px'; 24697 } else { 24698 this.wrapper.style.bottom = '2px'; 24699 } 24700 } 24701 } 24702 24703 var r = this.wrapper.offsetHeight; // force refresh 24704 24705 if ( this.options.listenX ) { 24706 this.wrapperWidth = this.wrapper.clientWidth; 24707 if ( this.options.resize ) { 24708 this.indicatorWidth = Math.max(Math.round(this.wrapperWidth * this.wrapperWidth / (this.scroller.scrollerWidth || this.wrapperWidth || 1)), 8); 24709 this.indicatorStyle.width = this.indicatorWidth + 'px'; 24710 } else { 24711 this.indicatorWidth = this.indicator.clientWidth; 24712 } 24713 24714 this.maxPosX = this.wrapperWidth - this.indicatorWidth; 24715 24716 if ( this.options.shrink == 'clip' ) { 24717 this.minBoundaryX = -this.indicatorWidth + 8; 24718 this.maxBoundaryX = this.wrapperWidth - 8; 24719 } else { 24720 this.minBoundaryX = 0; 24721 this.maxBoundaryX = this.maxPosX; 24722 } 24723 24724 this.sizeRatioX = this.options.speedRatioX || (this.scroller.maxScrollX && (this.maxPosX / this.scroller.maxScrollX)); 24725 } 24726 24727 if ( this.options.listenY ) { 24728 this.wrapperHeight = this.wrapper.clientHeight; 24729 if ( this.options.resize ) { 24730 this.indicatorHeight = Math.max(Math.round(this.wrapperHeight * this.wrapperHeight / (this.scroller.scrollerHeight || this.wrapperHeight || 1)), 8); 24731 this.indicatorStyle.height = this.indicatorHeight + 'px'; 24732 } else { 24733 this.indicatorHeight = this.indicator.clientHeight; 24734 } 24735 24736 this.maxPosY = this.wrapperHeight - this.indicatorHeight; 24737 24738 if ( this.options.shrink == 'clip' ) { 24739 this.minBoundaryY = -this.indicatorHeight + 8; 24740 this.maxBoundaryY = this.wrapperHeight - 8; 24741 } else { 24742 this.minBoundaryY = 0; 24743 this.maxBoundaryY = this.maxPosY; 24744 } 24745 24746 this.maxPosY = this.wrapperHeight - this.indicatorHeight; 24747 this.sizeRatioY = this.options.speedRatioY || (this.scroller.maxScrollY && (this.maxPosY / this.scroller.maxScrollY)); 24748 } 24749 24750 this.updatePosition(); 24751 }, 24752 24753 updatePosition: function () { 24754 var x = this.options.listenX && Math.round(this.sizeRatioX * this.scroller.x) || 0, 24755 y = this.options.listenY && Math.round(this.sizeRatioY * this.scroller.y) || 0; 24756 24757 if ( !this.options.ignoreBoundaries ) { 24758 if ( x < this.minBoundaryX ) { 24759 if ( this.options.shrink == 'scale' ) { 24760 this.width = Math.max(this.indicatorWidth + x, 8); 24761 this.indicatorStyle.width = this.width + 'px'; 24762 } 24763 x = this.minBoundaryX; 24764 } else if ( x > this.maxBoundaryX ) { 24765 if ( this.options.shrink == 'scale' ) { 24766 this.width = Math.max(this.indicatorWidth - (x - this.maxPosX), 8); 24767 this.indicatorStyle.width = this.width + 'px'; 24768 x = this.maxPosX + this.indicatorWidth - this.width; 24769 } else { 24770 x = this.maxBoundaryX; 24771 } 24772 } else if ( this.options.shrink == 'scale' && this.width != this.indicatorWidth ) { 24773 this.width = this.indicatorWidth; 24774 this.indicatorStyle.width = this.width + 'px'; 24775 } 24776 24777 if ( y < this.minBoundaryY ) { 24778 if ( this.options.shrink == 'scale' ) { 24779 this.height = Math.max(this.indicatorHeight + y * 3, 8); 24780 this.indicatorStyle.height = this.height + 'px'; 24781 } 24782 y = this.minBoundaryY; 24783 } else if ( y > this.maxBoundaryY ) { 24784 if ( this.options.shrink == 'scale' ) { 24785 this.height = Math.max(this.indicatorHeight - (y - this.maxPosY) * 3, 8); 24786 this.indicatorStyle.height = this.height + 'px'; 24787 y = this.maxPosY + this.indicatorHeight - this.height; 24788 } else { 24789 y = this.maxBoundaryY; 24790 } 24791 } else if ( this.options.shrink == 'scale' && this.height != this.indicatorHeight ) { 24792 this.height = this.indicatorHeight; 24793 this.indicatorStyle.height = this.height + 'px'; 24794 } 24795 } 24796 24797 this.x = x; 24798 this.y = y; 24799 24800 if ( this.scroller.options.useTransform ) { 24801 this.indicatorStyle[utils.style.transform] = 'translate(' + x + 'px,' + y + 'px)' + this.scroller.translateZ; 24802 } else { 24803 this.indicatorStyle.left = x + 'px'; 24804 this.indicatorStyle.top = y + 'px'; 24805 } 24806 }, 24807 24808 _pos: function (x, y) { 24809 if ( x < 0 ) { 24810 x = 0; 24811 } else if ( x > this.maxPosX ) { 24812 x = this.maxPosX; 24813 } 24814 24815 if ( y < 0 ) { 24816 y = 0; 24817 } else if ( y > this.maxPosY ) { 24818 y = this.maxPosY;
24819 } 24820 24821 x = this.options.listenX ? Math.round(x / this.sizeRatioX) : this.scroller.x; 24822 y = this.options.listenY ? Math.round(y / this.sizeRatioY) : this.scroller.y; 24823 24824 this.scroller.scrollTo(x, y); 24825 }, 24826 24827 fade: function (val, hold) { 24828 if ( hold && !this.visible ) { 24829 return; 24830 } 24831 24832 clearTimeout(this.fadeTimeout); 24833 this.fadeTimeout = null; 24834 24835 var time = val ? 250 : 500, 24836 delay = val ? 0 : 300; 24837 24838 val = val ? '1' : '0'; 24839 24840 this.wrapperStyle[utils.style.transitionDuration] = time + 'ms'; 24841 24842 this.fadeTimeout = setTimeout((function (val) { 24843 this.wrapperStyle.opacity = val; 24844 this.visible = +val; 24845 }).bind(this, val), delay); 24846 } 24847}; 24848 24849IScroll.utils = utils; 24850 24851if ( typeof module != 'undefined' && module.exports ) { 24852 module.exports = IScroll; 24853} else if ( typeof define == 'function' && define.amd ) { 24854 define( function () { return IScroll; } ); 24855} else { 24856 window.IScroll = IScroll; 24857} 24858 24859})(window, document, Math); 24860/*! 24861 * fullPage 2.9.4 24862 * https://github.com/alvarotrigo/fullPage.js 24863 * @license MIT licensed 24864 * 24865 * Copyright (C) 2015 alvarotrigo.com - A project by Alvaro Trigo 24866 */ 24867(function(global, factory) { 24868 'use strict'; 24869 if (typeof define === 'function' && define.amd) { 24870 define(['jquery'], function($) { 24871 return factory($, global, global.document, global.Math); 24872 }); 24873 } else if (typeof exports === "object" && exports) { 24874 module.exports = factory(require('jquery'), global, global.document, global.Math); 24875 } else { 24876 factory(jQuery, global, global.document, global.Math); 24877 } 24878})(typeof window !== 'undefined' ? window : this, function($, window, document, Math, undefined) { 24879 'use strict'; 24880 24881 // keeping central set of classnames and selectors 24882 var WRAPPER = 'fullpage-wrapper'; 24883 var WRAPPER_SEL = '.' + WRAPPER; 24884 24885 // slimscroll 24886 var SCROLLABLE = 'fp-scrollable'; 24887 var SCROLLABLE_SEL = '.' + SCROLLABLE; 24888 24889 // util 24890 var RESPONSIVE = 'fp-responsive'; 24891 var NO_TRANSITION = 'fp-notransition'; 24892 var DESTROYED = 'fp-destroyed'; 24893 var ENABLED = 'fp-enabled'; 24894 var VIEWING_PREFIX = 'fp-viewing'; 24895 var ACTIVE = 'active'; 24896 var ACTIVE_SEL = '.' + ACTIVE; 24897 var COMPLETELY = 'fp-completely'; 24898 var COMPLETELY_SEL = '.' + COMPLETELY; 24899 24900 // section 24901 var SECTION_DEFAULT_SEL = '.section'; 24902 var SECTION = 'fp-section'; 24903 var SECTION_SEL = '.' + SECTION; 24904 var SECTION_ACTIVE_SEL = SECTION_SEL + ACTIVE_SEL; 24905 var SECTION_FIRST_SEL = SECTION_SEL + ':first'; 24906 var SECTION_LAST_SEL = SECTION_SEL + ':last'; 24907 var TABLE_CELL = 'fp-tableCell'; 24908 var TABLE_CELL_SEL = '.' + TABLE_CELL; 24909 var AUTO_HEIGHT = 'fp-auto-height'; 24910 var AUTO_HEIGHT_SEL = '.fp-auto-height'; 24911 var NORMAL_SCROLL = 'fp-normal-scroll'; 24912 var NORMAL_SCROLL_SEL = '.fp-normal-scroll'; 24913 24914 // section nav 24915 var SECTION_NAV = 'fp-nav'; 24916 var SECTION_NAV_SEL = '#' + SECTION_NAV; 24917 var SECTION_NAV_TOOLTIP = 'fp-tooltip'; 24918 var SECTION_NAV_TOOLTIP_SEL='.'+SECTION_NAV_TOOLTIP; 24919 var SHOW_ACTIVE_TOOLTIP = 'fp-show-active'; 24920 24921 // slide 24922 var SLIDE_DEFAULT_SEL = '.slide'; 24923 var SLIDE = 'fp-slide'; 24924 var SLIDE_SEL = '.' + SLIDE; 24925 var SLIDE_ACTIVE_SEL = SLIDE_SEL + ACTIVE_SEL; 24926 var SLIDES_WRAPPER = 'fp-slides'; 24927 var SLIDES_WRAPPER_SEL = '.' + SLIDES_WRAPPER; 24928 var SLIDES_CONTAINER = 'fp-slidesContainer'; 24929 var SLIDES_CONTAINER_SEL = '.' + SLIDES_CONTAINER; 24930 var TABLE = 'fp-table'; 24931 24932 // slide nav 24933 var SLIDES_NAV = 'fp-slidesNav'; 24934 var SLIDES_NAV_SEL = '.' + SLIDES_NAV; 24935 var SLIDES_NAV_LINK_SEL = SLIDES_NAV_SEL + ' a'; 24936 var SLIDES_ARROW = 'fp-controlArrow'; 24937 var SLIDES_ARROW_SEL = '.' + SLIDES_ARROW; 24938 var SLIDES_PREV = 'fp-prev'; 24939 var SLIDES_PREV_SEL = '.' + SLIDES_PREV; 24940 var SLIDES_ARROW_PREV = SLIDES_ARROW + ' ' + SLIDES_PREV; 24941 var SLIDES_ARROW_PREV_SEL = SLIDES_ARROW_SEL + SLIDES_PREV_SEL; 24942 var SLIDES_NEXT = 'fp-next';
24943 var SLIDES_NEXT_SEL = '.' + SLIDES_NEXT; 24944 var SLIDES_ARROW_NEXT = SLIDES_ARROW + ' ' + SLIDES_NEXT; 24945 var SLIDES_ARROW_NEXT_SEL = SLIDES_ARROW_SEL + SLIDES_NEXT_SEL; 24946 24947 var $window = $(window); 24948 var $document = $(document); 24949 24950 // Default options for iScroll.js used when using scrollOverflow 24951 var iscrollOptions = { 24952 scrollbars: true, 24953 mouseWheel: true, 24954 hideScrollbars: false, 24955 fadeScrollbars: false, 24956 disableMouse: true, 24957 interactiveScrollbars: true, 24958 bounce: false, 24959 }; 24960 24961 $.fn.fullpage = function(options) { 24962 //only once my friend! 24963 if($('html').hasClass(ENABLED)){ displayWarnings(); return; } 24964 24965 // common jQuery objects 24966 var $htmlBody = $('html, body'); 24967 var $body = $('body'); 24968 24969 var FP = $.fn.fullpage; 24970 24971 // Creating some defaults, extending them with any options that were provided 24972 options = $.extend({ 24973 //navigation 24974 menu: false, 24975 anchors:[], 24976 lockAnchors: false, 24977 navigation: false, 24978 navigationPosition: 'right', 24979 navigationTooltips: [], 24980 showActiveTooltip: false, 24981 slidesNavigation: false, 24982 slidesNavPosition: 'bottom', 24983 scrollBar: false, 24984 hybrid: false, 24985 24986 //scrolling 24987 css3: true, 24988 scrollingSpeed: 700, 24989 autoScrolling: true, 24990 fitToSection: true, 24991 fitToSectionDelay: 1000, 24992 easing: 'easeInOutCubic', 24993 easingcss3: 'ease', 24994 loopBottom: false, 24995 loopTop: false, 24996 loopHorizontal: true, 24997 continuousVertical: false, 24998 continuousHorizontal: false, 24999 scrollHorizontally: false, 25000 interlockedSlides: false, 25001 dragAndMove: false, 25002 offsetSections: false, 25003 resetSliders: false, 25004 fadingEffect: false, 25005 normalScrollElements: null, 25006 scrollOverflow: false, 25007 scrollOverflowReset: false, 25008 scrollOverflowHandler: iscrollHandler, 25009 scrollOverflowOptions: null, 25010 touchSensitivity: 5, 25011 normalScrollElementTouchThreshold: 5, 25012 bigSectionsDestination: null, 25013 25014 //Accessibility 25015 keyboardScrolling: true, 25016 animateAnchor: true, 25017 recordHistory: true, 25018 25019 //design 25020 controlArrows: true, 25021 controlArrowColor: '#fff', 25022 verticalCentered: true, 25023 sectionsColor : [], 25024 paddingTop: 0, 25025 paddingBottom: 0, 25026 fixedElements: null, 25027 responsive: 0, //backwards compabitility with responsiveWiddth 25028 responsiveWidth: 0, 25029 responsiveHeight: 0, 25030 responsiveSlides: false, 25031 parallax: false, 25032 parallaxOptions: { 25033 type: 'reveal', 25034 percentage: 62, 25035 property: 'translate' 25036 }, 25037 25038 //Custom selectors 25039 sectionSelector: SECTION_DEFAULT_SEL, 25040 slideSelector: SLIDE_DEFAULT_SEL, 25041 25042 //events 25043 afterLoad: null, 25044 onLeave: null, 25045 afterRender: null, 25046 afterResize: null, 25047 afterReBuild: null, 25048 afterSlideLoad: null, 25049 onSlideLeave: null, 25050 afterResponsive: null, 25051 25052 lazyLoading: true 25053 }, options); 25054 25055 //flag to avoid very fast sliding for landscape sliders 25056 var slideMoving = false; 25057 25058 var isTouchDevice = navigator.userAgent.match(/(iPhone|iPod|iPad|Android|playbook|silk|BlackBerry|BB10|Windows Phone|Tizen|Bada|webOS|IEMobile|Opera Mini)/); 25059 var isTouch = (('ontouchstart' in window) || (navigator.msMaxTouchPoints > 0) || (navigator.maxTouchPoints)); 25060 var container = $(this); 25061 var windowsHeight = $window.height(); 25062 var isResizing = false; 25063 var isWindowFocused = true; 25064 var lastScrolledDestiny; 25065 var lastScrolledSlide; 25066 var canScroll = true; 25067 var scrollings = []; 25068 var controlPressed; 25069 var startingSection; 25070 var isScrollAllowed = {}; 25071 isScrollAllowed.m = { 'up':true, 'down':true, 'left':true, 'right':true }; 25072 isScrollAllowed.k = $.extend(true,{}, isScrollAllowed.m); 25073 var MSPointer = getMSPointer(); 25074 var events = { 25075 touchmove: 'ontouchmove' in window ? 'touchmove' : MSPointer.move, 25076 touchstart: 'ontouchstart' in window ? 'touchstart' : MSPointer.down 25077 }; 25078 25079 //cheks for passive event support 25080 //added by Uncode from new fullPage updates 25081 var g_supportsPassive = false;
25082 try { 25083 var opts = Object.defineProperty({}, 'passive', { 25084 get: function() { 25085 g_supportsPassive = true; 25086 } 25087 }); 25088 window.addEventListener("testPassive", null, opts); 25089 window.removeEventListener("testPassive", null, opts); 25090 } catch (e) {} 25091 25092 //timeouts 25093 var resizeId; 25094 var afterSectionLoadsId; 25095 var afterSlideLoadsId; 25096 var scrollId; 25097 var scrollId2; 25098 var keydownId; 25099 var originals = $.extend(true, {}, options); //deep copy 25100 25101 //Uncode addition 25102 var $masthead = $('#masthead'); 25103 var hideMenu = !$('body').hasClass('vmenu') && $('body').hasClass('uncode-fp-menu-hide') ? true : false; 25104 var menuHeight = $masthead.hasClass('menu-transparent') || hideMenu ? 0 : UNCODE.menuHeight; 25105 var bodyBorder = UNCODE.bodyBorder; 25106 var adminBarHeight = UNCODE.adminBarHeight; 25107 25108 displayWarnings(); 25109 25110 //fixing bug in iScroll with links: https://github.com/cubiq/iscroll/issues/783 25111 iscrollOptions.click = isTouch; // see #2035 25112 25113 //extending iScroll options with the user custom ones 25114 iscrollOptions = $.extend(iscrollOptions, options.scrollOverflowOptions); 25115 25116 //easeInOutCubic animation included in the plugin 25117 $.extend($.easing,{ easeInOutCubic: function (x, t, b, c, d) {if ((t/=d/2) < 1) return c/2*t*t*t + b;return c/2*((t-=2)*t*t + 2) + b;}}); 25118 25119 /** 25120 * Sets the autoScroll option. 25121 * It changes the scroll bar visibility and the history of the site as a result. 25122 */ 25123 function setAutoScrolling(value, type){ 25124 //removing the transformation 25125 if(!value){ 25126 silentScroll(0); 25127 } 25128 25129 setVariableState('autoScrolling', value, type); 25130 25131 var element = $(SECTION_ACTIVE_SEL); 25132 25133 if(options.autoScrolling && !options.scrollBar){ 25134 $htmlBody.css({ 25135 'overflow' : 'hidden !important', 25136 'height' : '100%' 25137 }); 25138 25139 //Uncode addition 25140 //setRecordHistory(originals.recordHistory, 'internal'); 25141 25142 //for IE touch devices 25143 container.css({ 25144 '-ms-touch-action': 'none', 25145 'touch-action': 'none' 25146 }); 25147 25148 if(element.length){ 25149 //moving the container up 25150 silentScroll(element.position().top); 25151 } 25152 25153 }else{ 25154 $htmlBody.css({ 25155 'overflow' : 'visible !important', 25156 'height' : 'initial' 25157 }); 25158 25159 //Uncode addition 25160 //setRecordHistory(false, 'internal'); 25161 25162 //for IE touch devices 25163 container.css({ 25164 '-ms-touch-action': '', 25165 'touch-action': '' 25166 }); 25167 25168 //scrolling the page to the section with no animation 25169 if (element.length) { 25170 $htmlBody.scrollTop(element.position().top); 25171 } 25172 } 25173 } 25174 25175 /** 25176 * Defines wheter to record the history for each hash change in the URL. 25177 */ 25178 function setRecordHistory(value, type){ 25179 setVariableState('recordHistory', value, type); 25180 } 25181 25182 /** 25183 * Defines the scrolling speed 25184 */ 25185 function setScrollingSpeed(value, type){ 25186 setVariableState('scrollingSpeed', value, type); 25187 } 25188 25189 /** 25190 * Sets fitToSection 25191 */ 25192 function setFitToSection(value, type){ 25193 setVariableState('fitToSection', value, type); 25194 } 25195 25196 /** 25197 * Sets lockAnchors 25198 */ 25199 function setLockAnchors(value){ 25200 options.lockAnchors = value; 25201 } 25202 25203 /** 25204 * Adds or remove the possiblity of scrolling through sections by using the mouse wheel or the trackpad. 25205 */ 25206 function setMouseWheelScrolling(value){ 25207 if(value){ 25208 addMouseWheelHandler(); 25209 addMiddleWheelHandler(); 25210 }else{ 25211 removeMouseWheelHandler(); 25212 removeMiddleWheelHandler(); 25213 } 25214 } 25215 25216 /** 25217 * Adds or remove the possibility of scrolling through sections by using the mouse wheel/trackpad or touch gestures. 25218 * Optionally a second parameter can be used to specify the direction for which the action will be applied. 25219 * 25220 * @param directions string containing the direction or directions separated by comma. 25221 */ 25222 function setAllowScrolling(value, directions){ 25223 if(typeof directions !== 'undefined'){ 25224 directions = directions.replace(/ /g,'').split(','); 25225 25226 $.each(directions, function (index, direction){ 25227 setIsScrollAllowed(value, direction, 'm'); 25228 }); 25229 } 25230 else if(value){ 25231 setMouseWheelScrolling(true); 25232 addTouchHandler(); 25233 }else{ 25234 setMouseWheelScrolling(false); 25235 removeTouchHandler(); 25236 } 25237 } 25238 25239 /** 25240 * Adds or remove the possibility of scrolling through sections by using the keyboard arrow keys 25241 */ 25242 function setKeyboardScrolling(value, directions){ 25243 if(typeof directions !== 'undefined'){ 25244 directions = directions.replace(/ /g,'').split(','); 25245 25246 $.each(directions, function (index, direction){ 25247 setIsScrollAllowed(value, direction, 'k'); 25248 }); 25249 }else{ 25250 options.keyboardScrolling = value; 25251 } 25252 } 25253 25254 /** 25255 * Moves the page up one section. 25256 */ 25257 function moveSectionUp(){ 25258 var prev = $(SECTION_ACTIVE_SEL).prev(SECTION_SEL); 25259 25260 //looping to the bottom if there's no more sections above 25261 if (!prev.length && (options.loopTop || options.continuousVertical)) {
25262 prev = $(SECTION_SEL).last(); 25263 } 25264 25265 if (prev.length) { 25266 scrollPage(prev, null, true); 25267 } 25268 } 25269 25270 /** 25271 * Moves the page down one section. 25272 */ 25273 function moveSectionDown(){ 25274 var next = $(SECTION_ACTIVE_SEL).next(SECTION_SEL); 25275 25276 //looping to the top if there's no more sections below 25277 if(!next.length && 25278 (options.loopBottom || options.continuousVertical)){ 25279 next = $(SECTION_SEL).first(); 25280 } 25281 25282 if(next.length){ 25283 scrollPage(next, null, false); 25284 } 25285 } 25286 25287 /** 25288 * Moves the page to the given section and slide with no animation. 25289 * Anchors or index positions can be used as params. 25290 */ 25291 function silentMoveTo(sectionAnchor, slideAnchor){ 25292 setScrollingSpeed (0, 'internal'); 25293 moveTo(sectionAnchor, slideAnchor); 25294 setScrollingSpeed (originals.scrollingSpeed, 'internal'); 25295 } 25296 25297 /** 25298 * Moves the page to the given section and slide. 25299 * Anchors or index positions can be used as params. 25300 */ 25301 function moveTo(sectionAnchor, slideAnchor){ 25302 var destiny = getSectionByAnchor(sectionAnchor); 25303 25304 if (typeof slideAnchor !== 'undefined'){ 25305 scrollPageAndSlide(sectionAnchor, slideAnchor); 25306 }else if(destiny.length > 0){ 25307 scrollPage(destiny); 25308 } 25309 } 25310 25311 /** 25312 * Slides right the slider of the active section. 25313 * Optional `section` param. 25314 */ 25315 function moveSlideRight(section){ 25316 moveSlide('right', section); 25317 } 25318 25319 /** 25320 * Slides left the slider of the active section. 25321 * Optional `section` param. 25322 */ 25323 function moveSlideLeft(section){ 25324 moveSlide('left', section); 25325 } 25326 25327 /** 25328 * When resizing is finished, we adjust the slides sizes and positions 25329 */ 25330 function reBuild(resizing){ 25331 if(container.hasClass(DESTROYED)){ return; } //nothing to do if the plugin was destroyed 25332 25333 isResizing = true; 25334 25335 windowsHeight = $window.height(); //updating global var 25336 25337 $(SECTION_SEL).each(function(){ 25338 var slidesWrap = $(this).find(SLIDES_WRAPPER_SEL); 25339 var slides = $(this).find(SLIDE_SEL); 25340 25341 //adjusting the height of the table-cell for IE and Firefox 25342 if(options.verticalCentered){ 25343 $(this).find(TABLE_CELL_SEL).css('height', getTableHeight($(this)) + 'px'); 25344 } 25345 25346 $(this).css('height', windowsHeight + 'px'); 25347 25348 //resizing the scrolling divs 25349 if(options.scrollOverflow){ 25350 if(slides.length){ 25351 slides.each(function(){ 25352 createScrollBar($(this)); 25353 }); 25354 }else{ 25355 createScrollBar($(this)); 25356 } 25357 } 25358 25359 //adjusting the position fo the FULL WIDTH slides... 25360 if (slides.length > 1) { 25361 landscapeScroll(slidesWrap, slidesWrap.find(SLIDE_ACTIVE_SEL)); 25362 } 25363 }); 25364 25365 var activeSection = $(SECTION_ACTIVE_SEL); 25366 var sectionIndex = activeSection.index(SECTION_SEL); 25367 25368 //isn't it the first section? 25369 if(sectionIndex){ 25370 //adjusting the position for the current section 25371 silentMoveTo(sectionIndex + 1); 25372 } 25373 25374 isResizing = false; 25375 // Uncode change 25376 // $.isFunction( options.afterResize ) && resizing && options.afterResize.call(container); 25377 $.isFunction( options.afterResize ) && resizing && options.afterResize.call(container, getTableHeight()); 25378 $.isFunction( options.afterReBuild ) && !resizing && options.afterReBuild.call(container); 25379 } 25380 25381 /** 25382 * Turns fullPage.js to normal scrolling mode when the viewport `width` or `height` 25383 * are smaller than the set limit values. 25384 */ 25385 function setResponsive(active){ 25386 var isResponsive = $body.hasClass(RESPONSIVE); 25387 25388 if(active){ 25389 if(!isResponsive){ 25390 setAutoScrolling(false, 'internal'); 25391 setFitToSection(false, 'internal'); 25392 $(SECTION_NAV_SEL).hide(); 25393 $body.addClass(RESPONSIVE); 25394 $.isFunction( options.afterResponsive ) && options.afterResponsive.call( container, active); 25395 } 25396 } 25397 else if(isResponsive){ 25398 setAutoScrolling(originals.autoScrolling, 'internal'); 25399 setFitToSection(originals.autoScrolling, 'internal'); 25400 $(SECTION_NAV_SEL).show(); 25401 $body.removeClass(RESPONSIVE); 25402 $.isFunction( options.afterResponsive ) && options.afterResponsive.call( container, active); 25403 } 25404 } 25405 25406 if($(this).length){ 25407 //public functions 25408 FP.setAutoScrolling = setAutoScrolling; 25409 FP.setRecordHistory = setRecordHistory; 25410 FP.setScrollingSpeed = setScrollingSpeed; 25411 FP.setFitToSection = setFitToSection; 25412 FP.setLockAnchors = setLockAnchors; 25413 FP.setMouseWheelScrolling = setMouseWheelScrolling; 25414 FP.setAllowScrolling = setAllowScrolling; 25415 FP.setKeyboardScrolling = setKeyboardScrolling; 25416 FP.moveSectionUp = moveSectionUp; 25417 FP.moveSectionDown = moveSectionDown; 25418 FP.silentMoveTo = silentMoveTo; 25419 FP.moveTo = moveTo; 25420 FP.moveSlideRight = moveSlideRight; 25421 FP.moveSlideLeft = moveSlideLeft; 25422 FP.fitToSection = fitToSection; 25423 FP.reBuild = reBuild; 25424 FP.setResponsive = setResponsive; 25425 FP.destroy = destroy; 25426 25427 init(); 25428 25429 bindEvents(); 25430 } 25431
25432 function init(){ 25433 //if css3 is not supported, it will use jQuery animations 25434 if(options.css3){ 25435 options.css3 = support3d(); 25436 } 25437 25438 options.scrollBar = options.scrollBar || options.hybrid; 25439 25440 setOptionsFromDOM(); 25441 prepareDom(); 25442 setAllowScrolling(true); 25443 setAutoScrolling(options.autoScrolling, 'internal'); 25444 responsive(); 25445 25446 //setting the class for the body element 25447 setBodyClass(); 25448 25449 //Uncode addition 25450 // if(document.readyState === 'complete'){ 25451 // scrollToAnchor(); 25452 // } 25453 // $window.on('load', scrollToAnchor); 25454 } 25455 25456 function bindEvents(){ 25457 $window 25458 //when scrolling... 25459 //.on('scroll', scrollHandler) 25460 25461 //detecting any change on the URL to scroll to the given anchor link 25462 //(a way to detect back history button as we play with the hashes on the URL) 25463 .on('hashchange', hashChangeHandler) 25464 25465 //when opening a new tab (ctrl + t), `control` won't be pressed when coming back. 25466 .blur(blurHandler) 25467 25468 //when resizing the site, we adjust the heights of the sections, slimScroll... 25469 .resize(resizeHandler); 25470 25471 $document 25472 //Sliding with arrow keys, both, vertical and horizontal 25473 .keydown(keydownHandler) 25474 25475 //to prevent scrolling while zooming 25476 .keyup(keyUpHandler) 25477 25478 //Scrolls to the section when clicking the navigation bullet 25479 .on('click touchstart', SECTION_NAV_SEL + ' a', sectionBulletHandler) 25480 25481 //Scrolls the slider to the given slide destination for the given section 25482 .on('click touchstart', SLIDES_NAV_LINK_SEL, slideBulletHandler) 25483 25484 .on('click', SECTION_NAV_TOOLTIP_SEL, tooltipTextHandler); 25485 25486 //Scrolling horizontally when clicking on the slider controls. 25487 $(SECTION_SEL).on('click touchstart', SLIDES_ARROW_SEL, slideArrowHandler); 25488 25489 /** 25490 * Applying normalScroll elements. 25491 * Ignoring the scrolls over the specified selectors. 25492 */ 25493 if(options.normalScrollElements){ 25494 $document.on('mouseenter', options.normalScrollElements, function () { 25495 setMouseWheelScrolling(false); 25496 }); 25497 25498 $document.on('mouseleave', options.normalScrollElements, function(){ 25499 setMouseWheelScrolling(true); 25500 }); 25501 } 25502 } 25503 25504 /** 25505 * Setting options from DOM elements if they are not provided. 25506 */ 25507 function setOptionsFromDOM(){ 25508 var sections = container.find(options.sectionSelector); 25509 25510 //no anchors option? Checking for them in the DOM attributes 25511 if(!options.anchors.length){ 25512 options.anchors = sections.filter('[data-anchor]').map(function(){ 25513 return $(this).data('anchor').toString(); 25514 }).get(); 25515 } 25516 25517 //no tooltips option? Checking for them in the DOM attributes 25518 if(!options.navigationTooltips.length){ 25519 options.navigationTooltips = sections.filter('[data-tooltip]').map(function(){ 25520 return $(this).data('tooltip').toString(); 25521 }).get(); 25522 } 25523 } 25524 25525 /** 25526 * Works over the DOM structure to set it up for the current fullpage options. 25527 */ 25528 function prepareDom(){ 25529 container.css({ 25530 'height': '100%', 25531 'position': 'relative' 25532 }); 25533 25534 //adding a class to recognize the container internally in the code 25535 container.addClass(WRAPPER); 25536 $('html').addClass(ENABLED); 25537 25538 windowsHeight = $window.height(); 25539 25540 container.removeClass(DESTROYED); //in case it was destroyed before initializing it again 25541 25542 addInternalSelectors(); 25543 25544 //styling the sections / slides / menu 25545 $(SECTION_SEL).each(function(index){ 25546 var section = $(this); 25547 var slides = section.find(SLIDE_SEL); 25548 var numSlides = slides.length; 25549 25550 styleSection(section, index); 25551 styleMenu(section, index); 25552 25553 // if there's any slide 25554 if (numSlides > 0) { 25555 styleSlides(section, slides, numSlides); 25556 }else{ 25557 if(options.verticalCentered){ 25558 addTableClass(section); 25559 } 25560 } 25561 }); 25562 25563 //fixed elements need to be moved out of the plugin container due to problems with CSS3. 25564 if(options.fixedElements && options.css3){ 25565 $(options.fixedElements).appendTo($body); 25566 } 25567 25568 //vertical centered of the navigation + active bullet 25569 if(options.navigation){ 25570 addVerticalNavigation(); 25571 } 25572 25573 enableYoutubeAPI(); 25574 25575 if(options.scrollOverflow){ 25576 if(document.readyState === 'complete'){ 25577 createScrollBarHandler(); 25578 } 25579 //after DOM and images are loaded 25580 $window.on('load', createScrollBarHandler); 25581 }else{ 25582 afterRenderActions(); 25583 } 25584 } 25585 25586 /** 25587 * Styles the horizontal slides for a section. 25588 */ 25589 function styleSlides(section, slides, numSlides){ 25590 var sliderWidth = numSlides * 100; 25591 var slideWidth = 100 / numSlides; 25592 25593 slides.wrapAll('<div class="' + SLIDES_CONTAINER + '" />'); 25594 slides.parent().wrap('<div class="' + SLIDES_WRAPPER + '" />'); 25595 25596 section.find(SLIDES_CONTAINER_SEL).css('width', sliderWidth + '%'); 25597 25598 if(numSlides > 1){ 25599 if(options.controlArrows){ 25600 createSlideArrows(section); 25601 } 25602 25603 if(options.slidesNavigation){ 25604 addSlidesNavigation(section, numSlides); 25605 } 25606 } 25607 25608 slides.each(function(index) { 25609 $(this).css('width', slideWidth + '%'); 25610 25611 if(options.verticalCentered){ 25612 addTableClass($(this)); 25613 } 25614 }); 25615 25616 var startingSlide = section.find(SLIDE_ACTIVE_SEL); 25617 25618 //if the slide won't be an starting point, the default will be the first one 25619 //the active section isn't the first one? Is not the first slide of the first section? Then we load that section/sl
25619ide by default. 25620 if( startingSlide.length && ($(SECTION_ACTIVE_SEL).index(SECTION_SEL) !== 0 || ($(SECTION_ACTIVE_SEL).index(SECTION_SEL) === 0 && startingSlide.index() !== 0))){ 25621 silentLandscapeScroll(startingSlide, 'internal'); 25622 }else{ 25623 slides.eq(0).addClass(ACTIVE); 25624 } 25625 } 25626 25627 /** 25628 * Styling vertical sections 25629 */ 25630 function styleSection(section, index){ 25631 //if no active section is defined, the 1st one will be the default one 25632 if(!index && $(SECTION_ACTIVE_SEL).length === 0) { 25633 section.addClass(ACTIVE); 25634 } 25635 startingSection = $(SECTION_ACTIVE_SEL); 25636 25637 section.css('height', windowsHeight + 'px'); 25638 25639 if(options.paddingTop){ 25640 section.css('padding-top', options.paddingTop); 25641 } 25642 25643 if(options.paddingBottom){ 25644 section.css('padding-bottom', options.paddingBottom); 25645 } 25646 25647 if (typeof options.sectionsColor[index] !== 'undefined') { 25648 section.css('background-color', options.sectionsColor[index]); 25649 } 25650 25651 if (typeof options.anchors[index] !== 'undefined') { 25652 section.attr('data-anchor', options.anchors[index]); 25653 } 25654 } 25655 25656 /** 25657 * Sets the data-anchor attributes to the menu elements and activates the current one. 25658 */ 25659 function styleMenu(section, index){ 25660 if (typeof options.anchors[index] !== 'undefined') { 25661 //activating the menu / nav element on load 25662 if(section.hasClass(ACTIVE)){ 25663 activateMenuAndNav(options.anchors[index], index); 25664 } 25665 } 25666 25667 //moving the menu outside the main container if it is inside (avoid problems with fixed positions when using CSS3 tranforms) 25668 if(options.menu && options.css3 && $(options.menu).closest(WRAPPER_SEL).length){ 25669 $(options.menu).appendTo($body); 25670 } 25671 } 25672 25673 /** 25674 * Adds internal classes to be able to provide customizable selectors 25675 * keeping the link with the style sheet. 25676 */ 25677 function addInternalSelectors(){ 25678 container.find(options.sectionSelector).addClass(SECTION); 25679 container.find(options.slideSelector).addClass(SLIDE); 25680 } 25681 25682 /** 25683 * Creates the control arrows for the given section 25684 */ 25685 function createSlideArrows(section){ 25686 section.find(SLIDES_WRAPPER_SEL).after('<div class="' + SLIDES_ARROW_PREV + '"></div><div class="' + SLIDES_ARROW_NEXT + '"></div>'); 25687 25688 if(options.controlArrowColor!='#fff'){ 25689 section.find(SLIDES_ARROW_NEXT_SEL).css('border-color', 'transparent transparent transparent '+options.controlArrowColor); 25690 section.find(SLIDES_ARROW_PREV_SEL).css('border-color', 'transparent '+ options.controlArrowColor + ' transparent transparent'); 25691 } 25692 25693 if(!options.loopHorizontal){ 25694 section.find(SLIDES_ARROW_PREV_SEL).hide(); 25695 } 25696 } 25697 25698 /** 25699 * Creates a vertical navigation bar. 25700 */ 25701 function addVerticalNavigation(){ 25702 $body.append('<div id="' + SECTION_NAV + '"><ul></ul></div>'); 25703 var nav = $(SECTION_NAV_SEL); 25704 25705 nav.addClass(function() { 25706 return options.showActiveTooltip ? SHOW_ACTIVE_TOOLTIP + ' ' + options.navigationPosition : options.navigationPosition; 25707 }); 25708 25709 for (var i = 0; i < $(SECTION_SEL).length; i++) { 25710 var link = ''; 25711 if (options.anchors.length) { 25712 link = options.anchors[i]; 25713 } 25714 25715 var li = '<li><a href="#' + link + '"><span></span></a>'; 25716 25717 // Only add tooltip if needed (defined by user) 25718 var tooltip = options.navigationTooltips[i]; 25719 25720 if (typeof tooltip !== 'undefined' && tooltip !== '') { 25721 li += '<div class="' + SECTION_NAV_TOOLTIP + ' ' + options.navigationPosition + '">' + tooltip + '</div>'; 25722 } 25723 25724 li += '</li>'; 25725 25726 nav.find('ul').append(li); 25727 } 25728 25729 //centering it vertically 25730 $(SECTION_NAV_SEL).css('margin-top', '-' + ($(SECTION_NAV_SEL).height()/2) + 'px'); 25731 25732 //activating the current active section 25733 $(SECTION_NAV_SEL).find('li').eq($(SECTION_ACTIVE_SEL).index(SECTION_SEL)).find('a').addClass(ACTIVE); 25734 } 25735 25736 /** 25737 * Creates the slim scroll scrollbar for the sections and slides inside them. 25738 */ 25739 function createScrollBarHandler(){ 25740 $(SECTION_SEL).each(function(){ 25741 var slides = $(this).find(SLIDE_SEL); 25742 25743 if(slides.length){ 25744 slides.each(function(){ 25745 createScrollBar($(this)); 25746 }); 25747 }else{ 25748 createScrollBar($(this)); 25749 } 25750 25751 }); 25752 afterRenderActions(); 25753 } 25754 25755 /*
25756 * Enables the Youtube videos API so we can control their flow if necessary. 25757 */ 25758 function enableYoutubeAPI(){ 25759 container.find('iframe[src*="youtube.com/embed/"]').each(function(){ 25760 addURLParam($(this), 'enablejsapi=1'); 25761 }); 25762 } 25763 25764 /** 25765 * Adds a new parameter and its value to the `src` of a given element 25766 */ 25767 function addURLParam(element, newParam){ 25768 var originalSrc = element.attr('src'); 25769 element.attr('src', originalSrc + getUrlParamSign(originalSrc) + newParam); 25770 } 25771 25772 /* 25773 * Returns the prefix sign to use for a new parameter in an existen URL. 25774 * 25775 * @return {String} ? | & 25776 */ 25777 function getUrlParamSign(url){ 25778 return ( !/\?/.test( url ) ) ? '?' : '&'; 25779 } 25780 25781 /** 25782 * Actions and callbacks to fire afterRender 25783 */ 25784 function afterRenderActions(){ 25785 var section = $(SECTION_ACTIVE_SEL); 25786 25787 section.addClass(COMPLETELY); 25788 25789 if(options.scrollOverflowHandler.afterRender){ 25790 options.scrollOverflowHandler.afterRender(section); 25791 } 25792 lazyLoad(section); 25793 playMedia(section); 25794 options.scrollOverflowHandler.afterLoad(); 25795 25796 if(isDestinyTheStartingSection()){ 25797 $.isFunction( options.afterLoad ) && options.afterLoad.call(section, section.data('anchor'), (section.index(SECTION_SEL) + 1)); 25798 } 25799 25800 // Uncode change 25801 // $.isFunction( options.afterRender ) && options.afterRender.call(container); 25802 $.isFunction( options.afterRender ) && options.afterRender.call(container, getTableHeight()); 25803 } 25804 25805 /** 25806 * Determines if the URL anchor destiny is the starting section (the one using 'active' class before initialization) 25807 */ 25808 function isDestinyTheStartingSection(){ 25809 var anchors = window.location.hash.replace('#', '').split('/'); 25810 var destinationSection = getSectionByAnchor(decodeURIComponent(anchors[0])); 25811 25812 return !destinationSection.length || destinationSection.length && destinationSection.index() === startingSection.index(); 25813 } 25814 25815 25816 var isScrolling = false; 25817 var lastScroll = 0; 25818 25819 //when scrolling... 25820 function scrollHandler(){ 25821 var currentSection; 25822 25823 if(!options.autoScrolling || options.scrollBar){ 25824 var currentScroll = $window.scrollTop(); 25825 var scrollDirection = getScrollDirection(currentScroll); 25826 var visibleSectionIndex = 0; 25827 var screen_mid = currentScroll + ($window.height() / 2.0); 25828 var isAtBottom = $body.height() - $window.height() === currentScroll; 25829 var sections = document.querySelectorAll(SECTION_SEL); 25830 25831 //when using `auto-height` for a small last section it won't be centered in the viewport 25832 if(isAtBottom){ 25833 visibleSectionIndex = sections.length - 1; 25834 } 25835 //is at top? when using `auto-height` for a small first section it won't be centered in the viewport 25836 else if(!currentScroll){ 25837 visibleSectionIndex = 0; 25838 } 25839 25840 //taking the section which is showing more content in the viewport 25841 else{ 25842 for (var i = 0; i < sections.length; ++i) { 25843 var section = sections[i]; 25844 25845 // Pick the the last section which passes the middle line of the screen. 25846 if (section.offsetTop <= screen_mid) 25847 { 25848 visibleSectionIndex = i; 25849 } 25850 } 25851 } 25852 25853 if(isCompletelyInViewPort(scrollDirection)){ 25854 if(!$(SECTION_ACTIVE_SEL).hasClass(COMPLETELY)){ 25855 $(SECTION_ACTIVE_SEL).addClass(COMPLETELY).siblings().removeClass(COMPLETELY); 25856 } 25857 } 25858 25859 //geting the last one, the current one on the screen 25860 currentSection = $(sections).eq(visibleSectionIndex); 25861 25862 //setting the visible section as active when manually scrolling 25863 //executing only once the first time we reach the section 25864 if(!currentSection.hasClass(ACTIVE)){ 25865 isScrolling = true; 25866 var leavingSection = $(SECTION_ACTIVE_SEL); 25867 var leavingSectionIndex = leavingSection.index(SECTION_SEL) + 1; 25868 var yMovement = getYmovement(currentSection); 25869 var anchorLink = currentSection.data('anchor'); 25870 var sectionIndex = currentSection.index(SECTION_SEL) + 1; 25871 var activeSlide = currentSection.find(SLIDE_ACTIVE_SEL); 25872 var slideIndex; 25873 var slideAnchorLink; 25874 25875 if(activeSlide.length){ 25876 slideAnchorLink = activeSlide.data('anchor'); 25877 slideIndex = activeSlide.index(); 25878 } 25879 25880 if(canScroll){ 25881 currentSection.addClass(ACTIVE).siblings().removeClass(ACTIVE); 25882 25883 $.isFunction( options.onLeave ) && options.onLeave.call( leavingSection, leavingSectionIndex, sectionIndex, yMovement); 25884 $.isFunction( options.afterLoad ) && options.afterLoad.call( currentSection, anchorLink, sectionIndex); 25885 25886 stopMedia(leavingSection); 25887 lazyLoad(currentSection); 25888 playMedia(currentSection); 25889 25890 activateMenuAndNav(anchorLink, sectionIndex - 1); 25891 25892 if(options.anchors.length){ 25893 //needed to enter in hashChange event when using the menu with anchor links 25894 lastScrolledDestiny = anchorLink; 25895 } 25896 setState(slideIndex, slideAnchorLink, anchorLink, sectionIndex); 25897 } 25898 25899 //small timeout in order to avoid entering in hashChange event when scrolling is not finished yet 25900 clearTimeout(scrollId); 25901 scrollId = setTimeout(function(){ 25902 isScrolling = false;
25903 }, 100); 25904 } 25905 25906 if(options.fitToSection){ 25907 //for the auto adjust of the viewport to fit a whole section 25908 clearTimeout(scrollId2); 25909 25910 scrollId2 = setTimeout(function(){ 25911 //checking it again in case it changed during the delay 25912 if(options.fitToSection){ 25913 fitToSection(); 25914 } 25915 }, options.fitToSectionDelay); 25916 } 25917 } 25918 } 25919 25920 /** 25921 * Fits the site to the nearest active section 25922 */ 25923 function fitToSection(){ 25924 //checking fitToSection again in case it was set to false before the timeout delay 25925 if(canScroll){ 25926 //allows to scroll to an active section and 25927 //if the section is already active, we prevent firing callbacks 25928 isResizing = true; 25929 25930 scrollPage($(SECTION_ACTIVE_SEL)); 25931 isResizing = false; 25932 } 25933 } 25934 25935 /** 25936 * Determines whether the active section has seen in its whole or not. 25937 */ 25938 function isCompletelyInViewPort(movement){ 25939 var top = $(SECTION_ACTIVE_SEL).position().top; 25940 var bottom = top + $window.height(); 25941 25942 if(movement == 'up'){ 25943 return bottom >= ($window.scrollTop() + $window.height()); 25944 } 25945 return top <= $window.scrollTop(); 25946 } 25947 25948 /** 25949 * Gets the directon of the the scrolling fired by the scroll event. 25950 */ 25951 function getScrollDirection(currentScroll){ 25952 var direction = currentScroll > lastScroll ? 'down' : 'up'; 25953 25954 lastScroll = currentScroll; 25955 25956 //needed for auto-height sections to determine if we want to scroll to the top or bottom of the destination 25957 previousDestTop = currentScroll; 25958 25959 return direction; 25960 } 25961 25962 /** 25963 * Determines the way of scrolling up or down: 25964 * by 'automatically' scrolling a section or by using the default and normal scrolling. 25965 */ 25966 function scrolling(type, scrollable){ 25967 if (!isScrollAllowed.m[type]){ 25968 return; 25969 } 25970 var check = (type === 'down') ? 'bottom' : 'top'; 25971 var scrollSection = (type === 'down') ? moveSectionDown : moveSectionUp; 25972 25973 if(scrollable.length > 0 ){ 25974 //is the scrollbar at the start/end of the scroll? 25975 if(options.scrollOverflowHandler.isScrolled(check, scrollable)){ 25976 scrollSection(); 25977 }else{ 25978 return true; 25979 } 25980 }else{ 25981 // moved up/down 25982 scrollSection(); 25983 } 25984 } 25985 25986 /* 25987 * Preventing bouncing in iOS #2285 25988 */ 25989 function preventBouncing(event){ 25990 var e = event.originalEvent; 25991 if(!checkParentForNormalScrollElement(event.target) && options.autoScrolling && isReallyTouch(e) && isScrollAllowed.m.up){ 25992 //preventing the easing on iOS devices 25993 event.preventDefault(); 25994 } 25995 } 25996 25997 var touchStartY = 0; 25998 var touchStartX = 0; 25999 var touchEndY = 0; 26000 var touchEndX = 0; 26001 26002 /* Detecting touch events 26003 26004 * As we are changing the top property of the page on scrolling, we can not use the traditional way to detect it. 26005 * This way, the touchstart and the touch moves shows an small difference between them which is the 26006 * used one to determine the direction. 26007 */ 26008 function touchMoveHandler(event){ 26009 var e = event.originalEvent; 26010 var activeSection = $(e.target).closest(SECTION_SEL); 26011 26012 // additional: if one of the normalScrollElements isn't within options.normalScrollElementTouchThreshold hops up the DOM chain 26013 if (!checkParentForNormalScrollElement(event.target) && isReallyTouch(e) ) { 26014 26015 if(options.autoScrolling){ 26016 //preventing the easing on iOS devices 26017 event.preventDefault(); 26018 } 26019 26020 var scrollable = options.scrollOverflowHandler.scrollable(activeSection); 26021 var touchEvents = getEventsPage(e); 26022 26023 touchEndY = touchEvents.y; 26024 touchEndX = touchEvents.x; 26025 26026 //if movement in the X axys is greater than in the Y and the currect section has slides... 26027 if (activeSection.find(SLIDES_WRAPPER_SEL).length && Math.abs(touchStartX - touchEndX) > (Math.abs(touchStartY - touchEndY))) { 26028 26029 //is the movement greater than the minimum resistance to scroll? 26030 if (!slideMoving && Math.abs(touchStartX - touchEndX) > ($window.outerWidth() / 100 * options.touchSensitivity)) { 26031 if (touchStartX > touchEndX) { 26032 if(isScrollAllowed.m.right){ 26033 moveSlideRight(activeSection); //next 26034 } 26035 } else { 26036 if(isScrollAllowed.m.left){ 26037 moveSlideLeft(activeSection); //prev 26038 } 26039 } 26040 } 26041 } 26042 26043 //vertical scrolling (only when autoScrolling is enabled) 26044 else if(options.autoScrolling && canScroll){ 26045 26046 //is the movement greater than the minimum resistance to scroll? 26047 if (Math.abs(touchStartY - touchEndY) > ($window.height() / 100 * options.touchSensitivity)) { 26048 if (touchStartY > touchEndY) { 26049 scrolling('down', scrollable); 26050 } else if (touchEndY > touchStartY) { 26051 scrolling('up', scrollable); 26052 } 26053 } 26054 } 26055 } 26056 } 26057 26058 /** 26059 * recursive function to loop up the parent nodes to check if one of them exists in options.normalScrollElements 26060 * Currently works well for iOS - Android might need some testing 26061 * @param {Element} el target element / jquery selector (in subsequent nodes) 26062 * @param {int} hop current hop compared to options.normalScrollElementTouchThreshold 26063 * @return {boolean} true if there is a match to options.normalScrollElements 26064 */ 26065 function checkParentForNormalScrollElement (el, hop) { 26066 hop = hop || 0; 26067 var parent = $(el).parent(); 26068 26069 if (hop < options.normalScrollElementTouchThreshold && 26070 parent.is(options.normalScrollElements) ) { 26071 return true; 26072 } else if (hop == options.normalScrollElementTouchThreshold) { 26073 return false;
26074 } else { 26075 return checkParentForNormalScrollElement(parent, ++hop); 26076 } 26077 } 26078 26079 /** 26080 * As IE >= 10 fires both touch and mouse events when using a mouse in a touchscreen 26081 * this way we make sure that is really a touch event what IE is detecting. 26082 */ 26083 function isReallyTouch(e){ 26084 //if is not IE || IE is detecting `touch` or `pen` 26085 return typeof e.pointerType === 'undefined' || e.pointerType != 'mouse'; 26086 } 26087 26088 /** 26089 * Handler for the touch start event. 26090 */ 26091 function touchStartHandler(event){ 26092 var e = event.originalEvent; 26093 26094 //stopping the auto scroll to adjust to a section 26095 if(options.fitToSection){ 26096 $htmlBody.stop(); 26097 } 26098 26099 if(isReallyTouch(e)){ 26100 var touchEvents = getEventsPage(e); 26101 touchStartY = touchEvents.y; 26102 touchStartX = touchEvents.x; 26103 } 26104 } 26105 26106 /** 26107 * Gets the average of the last `number` elements of the given array. 26108 */ 26109 function getAverage(elements, number){ 26110 var sum = 0; 26111 26112 //taking `number` elements from the end to make the average, if there are not enought, 1 26113 var lastElements = elements.slice(Math.max(elements.length - number, 1)); 26114 26115 for(var i = 0; i < lastElements.length; i++){ 26116 sum = sum + lastElements[i]; 26117 } 26118 26119 return Math.ceil(sum/number); 26120 } 26121 26122 /** 26123 * Detecting mousewheel scrolling 26124 * 26125 * http://blogs.sitepointstatic.com/examples/tech/mouse-wheel/index.html 26126 * http://www.sitepoint.com/html5-javascript-mouse-wheel/ 26127 */ 26128 var prevTime = new Date().getTime(); 26129 26130 function MouseWheelHandler(e) { 26131 var curTime = new Date().getTime(); 26132 var isNormalScroll = $(COMPLETELY_SEL).hasClass(NORMAL_SCROLL); 26133 26134 //autoscrolling and not zooming? 26135 if(options.autoScrolling && !controlPressed && !isNormalScroll){ 26136 // cross-browser wheel delta 26137 e = e || window.event; 26138 var value = e.wheelDelta || -e.deltaY || -e.detail; 26139 var delta = Math.max(-1, Math.min(1, value)); 26140 26141 var horizontalDetection = typeof e.wheelDeltaX !== 'undefined' || typeof e.deltaX !== 'undefined'; 26142 var isScrollingVertically = (Math.abs(e.wheelDeltaX) < Math.abs(e.wheelDelta)) || (Math.abs(e.deltaX ) < Math.abs(e.deltaY) || !horizontalDetection); 26143 26144 //Limiting the array to 150 (lets not waste memory!) 26145 if(scrollings.length > 149){ 26146 scrollings.shift(); 26147 } 26148 26149 //keeping record of the previous scrollings 26150 scrollings.push(Math.abs(value)); 26151 26152 //preventing to scroll the site on mouse wheel when scrollbar is present 26153 if(options.scrollBar){ 26154 e.preventDefault ? e.preventDefault() : e.returnValue = false; 26155 } 26156 26157 var activeSection = $(SECTION_ACTIVE_SEL); 26158 var scrollable = options.scrollOverflowHandler.scrollable(activeSection); 26159 26160 //time difference between the last scroll and the current one 26161 var timeDiff = curTime-prevTime; 26162 prevTime = curTime; 26163 26164 //haven't they scrolled in a while? 26165 //(enough to be consider a different scrolling action to scroll another section) 26166 if(timeDiff > 200){ 26167 //emptying the array, we dont care about old scrollings for our averages 26168 scrollings = []; 26169 } 26170 26171 if(canScroll){ 26172 var averageEnd = getAverage(scrollings, 10); 26173 var averageMiddle = getAverage(scrollings, 70); 26174 var isAccelerating = averageEnd >= averageMiddle; 26175 26176 //to avoid double swipes... 26177 if(isAccelerating && isScrollingVertically){ 26178 //scrolling down? 26179 if (delta < 0) { 26180 scrolling('down', scrollable); 26181 26182 //scrolling up? 26183 }else { 26184 scrolling('up', scrollable); 26185 } 26186 } 26187 } 26188 26189 return false;
26190 } 26191 26192 if(options.fitToSection){ 26193 //stopping the auto scroll to adjust to a section 26194 $htmlBody.stop(); 26195 } 26196 } 26197 26198 /** 26199 * Slides a slider to the given direction. 26200 * Optional `section` param. 26201 */ 26202 function moveSlide(direction, section){ 26203 var activeSection = typeof section === 'undefined' ? $(SECTION_ACTIVE_SEL) : section; 26204 var slides = activeSection.find(SLIDES_WRAPPER_SEL); 26205 var numSlides = slides.find(SLIDE_SEL).length; 26206 26207 // more than one slide needed and nothing should be sliding 26208 if (!slides.length || slideMoving || numSlides < 2) { 26209 return; 26210 } 26211 26212 var currentSlide = slides.find(SLIDE_ACTIVE_SEL); 26213 var destiny = null; 26214 26215 if(direction === 'left'){ 26216 destiny = currentSlide.prev(SLIDE_SEL); 26217 }else{ 26218 destiny = currentSlide.next(SLIDE_SEL); 26219 } 26220 26221 //isn't there a next slide in the secuence? 26222 if(!destiny.length){ 26223 //respect loopHorizontal settin 26224 if (!options.loopHorizontal) return; 26225 26226 if(direction === 'left'){ 26227 destiny = currentSlide.siblings(':last'); 26228 }else{ 26229 destiny = currentSlide.siblings(':first'); 26230 } 26231 } 26232 26233 slideMoving = true; 26234 26235 landscapeScroll(slides, destiny, direction); 26236 } 26237 26238 /** 26239 * Maintains the active slides in the viewport 26240 * (Because the `scroll` animation might get lost with some actions, such as when using continuousVertical) 26241 */ 26242 function keepSlidesPosition(){ 26243 $(SLIDE_ACTIVE_SEL).each(function(){ 26244 silentLandscapeScroll($(this), 'internal'); 26245 }); 26246 } 26247 26248 var previousDestTop = 0; 26249 /** 26250 * Returns the destination Y position based on the scrolling direction and 26251 * the height of the section. 26252 */ 26253 function getDestinationPosition(element){ 26254 var elemPosition = element.position(); 26255 26256 //top of the desination will be at the top of the viewport 26257 var position = elemPosition.top; 26258 var isScrollingDown = elemPosition.top > previousDestTop; 26259 var sectionBottom = position - windowsHeight + element.outerHeight(); 26260 var bigSectionsDestination = options.bigSectionsDestination; 26261 26262 //Uncode addition 26263 var containerH = container.outerHeight(); 26264 var containerPosition = container.offset(); 26265 26266 //########### Commented by Uncode - START ########### 26267 //is the destination element bigger than the viewport? 26268 // if(element.outerHeight() > windowsHeight){ 26269 // //scrolling up? 26270 // if(!isScrollingDown && !bigSectionsDestination || bigSectionsDestination === 'bottom' ){ 26271 // position = sectionBottom; 26272 // } 26273 // } 26274 26275 // //sections equal or smaller than the viewport height && scrolling down? || is resizing and its in the last section 26276 // else if(isScrollingDown || (isResizing && element.is(':last-child')) ){ 26277 // //The bottom of the destination will be at the bottom of the viewport 26278 // position = sectionBottom; 26279 // } 26280 //########### Commented by Uncode - END ########### 26281 26282 //Uncode addition 26283 if ( !$masthead.hasClass('menu-transparent') && $('body').hasClass('uncode-fp-menu-shrink') && !element.is(':first-child') ) 26284 position += 18; 26285 if ( ( containerH + menuHeight + bodyBorder + adminBarHeight - windowsHeight ) < position || ( isResizing && element.is(':last-child') ) ) { 26286 position = sectionBottom + menuHeight + bodyBorder*2 + adminBarHeight; 26287 } 26288 26289 /* 26290 Keeping record of the last scrolled position to determine the scrolling direction. 26291 No conventional methods can be used as the scroll bar might not be present 26292 AND the section might not be active if it is auto-height and didnt reach the middle 26293 of the viewport. 26294 */ 26295 previousDestTop = position; 26296 return position; 26297 } 26298 26299 /** 26300 * Scrolls the site to the given element and scrolls to the slide if a callback is given. 26301 */ 26302 function scrollPage(element, callback, isMovementUp){ 26303 if(typeof element === 'undefined'){ return; } //there's no element to scroll, leaving the function 26304 26305 var dtop = getDestinationPosition(element); 26306 var slideAnchorLink; 26307 var slideIndex; 26308 26309 //local variables 26310 var v = { 26311 element: element, 26312 callback: callback, 26313 isMovementUp: isMovementUp, 26314 dtop: dtop, 26315 yMovement: getYmovement(element), 26316 anchorLink: element.data('anchor'), 26317 sectionIndex: element.index(SECTION_SEL), 26318 activeSlide: element.find(SLIDE_ACTIVE_SEL), 26319 activeSection: $(SECTION_ACTIVE_SEL), 26320 leavingSection: $(SECTION_ACTIVE_SEL).index(SECTION_SEL) + 1, 26321 26322 //caching the value of isResizing at the momment the function is called 26323 //because it will be checked later inside a setTimeout and the value might change 26324 localIsResizing: isResizing 26325 }; 26326 26327 //quiting when destination scroll is the same as the current one 26328 if((v.activeSection.is(element) && !isResizing) || (options.scrollBar && $window.scrollTop() === v.dtop && !element.hasClass(AUTO_HEIGHT) )){ return; } 26329 26330 if(v.activeSlide.length){ 26331 slideAnchorLink = v.activeSlide.data('anchor'); 26332 slideIndex = v.activeSlide.index(); 26333 } 26334 26335 // If continuousVertical && we need to wrap around 26336 if (options.autoScrolling && options.continuousVertical && typeof (v.isMovementUp) !== "undefined" && 26337 ((!v.isMovementUp && v.yMovement == 'up') || // Intending to scroll down but about to go up or 26338 (v.isMovementUp && v.yMovement == 'down'))) { // intending to scroll up but about to go down 26339 26340 v = createInfiniteSections(v); 26341 } 26342 26343 //callback (onLeave) if the site is not just resizing and readjusting the slides 26344 if($.isFunction(options.onLeave) && !v.localIsResizing){ 26345 if(options.onLeave.call(v.activeSection, v.leavingSection, (v.sectionIndex + 1), v.yMovement) === false){ 26346 return; 26347 } 26348 } 26349 26350 //pausing media of the leaving section (if we are not just resizing, as destinatino will be the same one) 26351 if(!v.localIsResizing){ 26352 stopMedia(v.activeSection); 26353 } 26354 26355 options.scrollOverflowHandler.beforeLeave(); 26356 element.addClass(ACTIVE).siblings().removeClass(ACTIVE); 26357 lazyLoad(element); 26358 options.scrollOverflowHandler.onLeave(); 26359 26360 26361 //preventing from activating the MouseWheelHandler event 26362 //more than once if the page is scrolling 26363 canScroll = false;
26364 26365 setState(slideIndex, slideAnchorLink, v.anchorLink, v.sectionIndex); 26366 26367 performMovement(v); 26368 26369 //flag to avoid callingn `scrollPage()` twice in case of using anchor links 26370 lastScrolledDestiny = v.anchorLink; 26371 26372 //avoid firing it twice (as it does also on scroll) 26373 activateMenuAndNav(v.anchorLink, v.sectionIndex); 26374 } 26375 26376 /** 26377 * Performs the vertical movement (by CSS3 or by jQuery) 26378 */ 26379 function performMovement(v){ 26380 // using CSS3 translate functionality 26381 if (options.css3 && options.autoScrolling && !options.scrollBar) { 26382 26383 // The first section can have a negative value in iOS 10. Not quite sure why: -0.0142822265625 26384 // that's why we round it to 0. 26385 var translate3d = 'translate3d(0px, -' + Math.round(v.dtop) + 'px, 0px)'; 26386 transformContainer(translate3d, true); 26387 26388 //even when the scrollingSpeed is 0 there's a little delay, which might cause the 26389 //scrollingSpeed to change in case of using silentMoveTo(); 26390 if(options.scrollingSpeed){ 26391 clearTimeout(afterSectionLoadsId); 26392 afterSectionLoadsId = setTimeout(function () { 26393 afterSectionLoads(v); 26394 }, options.scrollingSpeed); 26395 }else{ 26396 afterSectionLoads(v); 26397 } 26398 } 26399 26400 // using jQuery animate 26401 else{ 26402 var scrollSettings = getScrollSettings(v); 26403 26404 $(scrollSettings.element).animate( 26405 scrollSettings.options, 26406 options.scrollingSpeed, options.easing).promise().done(function () { //only one single callback in case of animating `html, body` 26407 if(options.scrollBar){ 26408 26409 /* Hack! 26410 The timeout prevents setting the most dominant section in the viewport as "active" when the user 26411 scrolled to a smaller section by using the mousewheel (auto scrolling) rather than draging the scroll bar. 26412 26413 When using scrollBar:true It seems like the scroll events still getting propagated even after the scrolling animation has finished. 26414 */ 26415 setTimeout(function(){ 26416 afterSectionLoads(v); 26417 },30); 26418 }else{ 26419 afterSectionLoads(v); 26420 } 26421 }); 26422 } 26423 } 26424 26425 /** 26426 * Gets the scrolling settings depending on the plugin autoScrolling option 26427 */ 26428 function getScrollSettings(v){ 26429 var scroll = {}; 26430 26431 if(options.autoScrolling && !options.scrollBar){ 26432 scroll.options = { 'top': -v.dtop}; 26433 scroll.element = WRAPPER_SEL; 26434 }else{ 26435 scroll.options = { 'scrollTop': v.dtop}; 26436 scroll.element = 'html, body'; 26437 } 26438 26439 return scroll; 26440 } 26441 26442 /** 26443 * Adds sections before or after the current one to create the infinite effect. 26444 */ 26445 function createInfiniteSections(v){ 26446 // Scrolling down 26447 if (!v.isMovementUp) { 26448 // Move all previous sections to after the active section 26449 $(SECTION_ACTIVE_SEL).after(v.activeSection.prevAll(SECTION_SEL).get().reverse()); 26450 } 26451 else { // Scrolling up 26452 // Move all next sections to before the active section 26453 $(SECTION_ACTIVE_SEL).before(v.activeSection.nextAll(SECTION_SEL)); 26454 } 26455 26456 // Maintain the displayed position (now that we changed the element order) 26457 silentScroll($(SECTION_ACTIVE_SEL).position().top); 26458 26459 // Maintain the active slides visible in the viewport 26460 keepSlidesPosition(); 26461 26462 // save for later the elements that still need to be reordered 26463 v.wrapAroundElements = v.activeSection; 26464 26465 // Recalculate animation variables 26466 v.dtop = v.element.position().top; 26467 v.yMovement = getYmovement(v.element); 26468 26469 return v; 26470 } 26471 26472 /** 26473 * Fix section order after continuousVertical changes have been animated 26474 */ 26475 function continuousVerticalFixSectionOrder (v) {
26476 // If continuousVertical is in effect (and autoScrolling would also be in effect then), 26477 // finish moving the elements around so the direct navigation will function more simply 26478 if (!v.wrapAroundElements || !v.wrapAroundElements.length) { 26479 return; 26480 } 26481 26482 if (v.isMovementUp) { 26483 $(SECTION_FIRST_SEL).before(v.wrapAroundElements); 26484 } 26485 else { 26486 $(SECTION_LAST_SEL).after(v.wrapAroundElements); 26487 } 26488 26489 silentScroll($(SECTION_ACTIVE_SEL).position().top); 26490 26491 // Maintain the active slides visible in the viewport 26492 keepSlidesPosition(); 26493 } 26494 26495 26496 /** 26497 * Actions to do once the section is loaded. 26498 */ 26499 function afterSectionLoads (v){ 26500 continuousVerticalFixSectionOrder(v); 26501 26502 //callback (afterLoad) if the site is not just resizing and readjusting the slides 26503 $.isFunction(options.afterLoad) && !v.localIsResizing && options.afterLoad.call(v.element, v.anchorLink, (v.sectionIndex + 1)); 26504 options.scrollOverflowHandler.afterLoad(); 26505 26506 if(!v.localIsResizing){ 26507 playMedia(v.element); 26508 } 26509 26510 v.element.addClass(COMPLETELY).siblings().removeClass(COMPLETELY); 26511 26512 canScroll = true; 26513 26514 $.isFunction(v.callback) && v.callback.call(this); 26515 } 26516 26517 /** 26518 * Sets the value for the given attribute from the `data-` attribute with the same suffix 26519 * ie: data-srcset ==> srcset | data-src ==> src 26520 */ 26521 function setSrc(element, attribute){ 26522 element 26523 .attr(attribute, element.data(attribute)) 26524 .removeAttr('data-' + attribute); 26525 } 26526 26527 /** 26528 * Lazy loads image, video and audio elements. 26529 */ 26530 function lazyLoad(destiny){ 26531 if (!options.lazyLoading){ 26532 return; 26533 } 26534 26535 var panel = getSlideOrSection(destiny); 26536 var element; 26537 26538 panel.find('img[data-src], img[data-srcset], source[data-src], audio[data-src], iframe[data-src]').each(function(){ 26539 element = $(this); 26540 26541 $.each(['src', 'srcset'], function(index, type){ 26542 var attribute = element.attr('data-' + type); 26543 if(typeof attribute !== 'undefined' && attribute){ 26544 setSrc(element, type); 26545 } 26546 }); 26547 26548 if(element.is('source')){ 26549 element.closest('video').get(0).load(); 26550 } 26551 }); 26552 } 26553 26554 /** 26555 * Plays video and audio elements. 26556 */ 26557 function playMedia(destiny){ 26558 var panel = getSlideOrSection(destiny); 26559 26560 //playing HTML5 media elements 26561 panel.find('video, audio').each(function(){ 26562 var element = $(this).get(0); 26563 26564 if( element.hasAttribute('data-autoplay') && typeof element.play === 'function' ) { 26565 element.play(); 26566 } 26567 }); 26568 26569 //youtube videos 26570 panel.find('iframe[src*="youtube.com/embed/"]').each(function(){ 26571 var element = $(this).get(0); 26572 26573 if ( element.hasAttribute('data-autoplay') ){ 26574 playYoutube(element); 26575 } 26576 26577 //in case the URL was not loaded yet. On page load we need time for the new URL (with the API string) to load. 26578 element.onload = function() { 26579 if ( element.hasAttribute('data-autoplay') ){ 26580 playYoutube(element); 26581 } 26582 }; 26583 }); 26584 } 26585 26586 /** 26587 * Plays a youtube video 26588 */ 26589 function playYoutube(element){ 26590 element.contentWindow.postMessage('{"event":"command","func":"playVideo","args":""}', '*'); 26591 } 26592 26593 /** 26594 * Stops video and audio elements. 26595 */ 26596 function stopMedia(destiny){ 26597 var panel = getSlideOrSection(destiny); 26598 26599 //stopping HTML5 media elements 26600 panel.find('video, audio').each(function(){ 26601 var element = $(this).get(0); 26602 26603 if( !element.hasAttribute('data-keepplaying') && typeof element.pause === 'function' ) { 26604 element.pause(); 26605 } 26606 }); 26607 26608 //youtube videos 26609 panel.find('iframe[src*="youtube.com/embed/"]').each(function(){ 26610 var element = $(this).get(0); 26611 26612 if( /youtube\.com\/embed\//.test($(this).attr('src')) && !element.hasAttribute('data-keepplaying')){ 26613 $(this).get(0).contentWindow.postMessage('{"event":"command","func":"pauseVideo","args":""}','*'); 26614 } 26615 }); 26616 } 26617 26618 /** 26619 * Gets the active slide (or section) for the given section 26620 */ 26621 function getSlideOrSection(destiny){ 26622 var slide = destiny.find(SLIDE_ACTIVE_SEL); 26623 if( slide.length ) { 26624 destiny = $(slide); 26625 } 26626 26627 return destiny; 26628 } 26629 26630 /**
26631 * Scrolls to the anchor in the URL when loading the site 26632 */ 26633 function scrollToAnchor(){ 26634 //getting the anchor link in the URL and deleting the `#` 26635 var value = window.location.hash.replace('#', '').split('/'); 26636 var sectionAnchor = decodeURIComponent(value[0]); 26637 var slideAnchor = decodeURIComponent(value[1]); 26638 26639 if(sectionAnchor){ //if theres any # 26640 if(options.animateAnchor){ 26641 scrollPageAndSlide(sectionAnchor, slideAnchor); 26642 }else{ 26643 silentMoveTo(sectionAnchor, slideAnchor); 26644 } 26645 } 26646 } 26647 26648 /** 26649 * Detecting any change on the URL to scroll to the given anchor link 26650 * (a way to detect back history button as we play with the hashes on the URL) 26651 */ 26652 function hashChangeHandler(){ 26653 if(!isScrolling && !options.lockAnchors){ 26654 var value = window.location.hash.replace('#', '').split('/'); 26655 var sectionAnchor = decodeURIComponent(value[0]); 26656 var slideAnchor = decodeURIComponent(value[1]); 26657 26658 //when moving to a slide in the first section for the first time (first time to add an anchor to the URL) 26659 var isFirstSlideMove = (typeof lastScrolledDestiny === 'undefined'); 26660 var isFirstScrollMove = (typeof lastScrolledDestiny === 'undefined' && typeof slideAnchor === 'undefined' && !slideMoving); 26661 26662 26663 if(sectionAnchor.length){ 26664 /*in order to call scrollpage() only once for each destination at a time 26665 It is called twice for each scroll otherwise, as in case of using anchorlinks `hashChange` 26666 event is fired on every scroll too.*/ 26667 if ((sectionAnchor && sectionAnchor !== lastScrolledDestiny) && !isFirstSlideMove || isFirstScrollMove || (!slideMoving && lastScrolledSlide != slideAnchor )) { 26668 scrollPageAndSlide(sectionAnchor, slideAnchor); 26669 } 26670 } 26671 } 26672 } 26673 26674 //Sliding with arrow keys, both, vertical and horizontal 26675 function keydownHandler(e) { 26676 26677 clearTimeout(keydownId); 26678 26679 var activeElement = $(':focus'); 26680 26681 if(!activeElement.is('textarea') && !activeElement.is('input') && !activeElement.is('select') && 26682 activeElement.attr('contentEditable') !== "true" && activeElement.attr('contentEditable') !== '' && 26683 options.keyboardScrolling && options.autoScrolling){ 26684 var keyCode = e.which; 26685 26686 //preventing the scroll with arrow keys & spacebar & Page Up & Down keys 26687 var keyControls = [40, 38, 32, 33, 34]; 26688 if($.inArray(keyCode, keyControls) > -1){ 26689 e.preventDefault(); 26690 } 26691 26692 controlPressed = e.ctrlKey; 26693 26694 keydownId = setTimeout(function(){ 26695 onkeydown(e); 26696 },150); 26697 } 26698 } 26699 26700 function tooltipTextHandler(){ 26701 $(this).prev().trigger('click'); 26702 } 26703 26704 //to prevent scrolling while zooming 26705 function keyUpHandler(e){ 26706 if(isWindowFocused){ //the keyup gets fired on new tab ctrl + t in Firefox 26707 controlPressed = e.ctrlKey; 26708 } 26709 } 26710 26711 //binding the mousemove when the mouse's middle button is released 26712 function mouseDownHandler(e){ 26713 //middle button 26714 if (e.which == 2){ 26715 oldPageY = e.pageY; 26716 container.on('mousemove', mouseMoveHandler); 26717 } 26718 } 26719 26720 //unbinding the mousemove when the mouse's middle button is released 26721 function mouseUpHandler(e){ 26722 //middle button 26723 if (e.which == 2){ 26724 container.off('mousemove'); 26725 } 26726 } 26727 26728 //Scrolling horizontally when clicking on the slider controls. 26729 function slideArrowHandler(){ 26730 var section = $(this).closest(SECTION_SEL); 26731 26732 if ($(this).hasClass(SLIDES_PREV)) { 26733 if(isScrollAllowed.m.left){ 26734 moveSlideLeft(section); 26735 } 26736 } else { 26737 if(isScrollAllowed.m.right){ 26738 moveSlideRight(section); 26739 } 26740 } 26741 } 26742 26743 //when opening a new tab (ctrl + t), `control` won't be pressed when coming back. 26744 function blurHandler(){ 26745 isWindowFocused = false;
26746 controlPressed = false; 26747 } 26748 26749 //Scrolls to the section when clicking the navigation bullet 26750 function sectionBulletHandler(e){ 26751 e.preventDefault(); 26752 var index = $(this).parent().index(); 26753 scrollPage($(SECTION_SEL).eq(index)); 26754 } 26755 26756 //Scrolls the slider to the given slide destination for the given section 26757 function slideBulletHandler(e){ 26758 e.preventDefault(); 26759 var slides = $(this).closest(SECTION_SEL).find(SLIDES_WRAPPER_SEL); 26760 var destiny = slides.find(SLIDE_SEL).eq($(this).closest('li').index()); 26761 26762 landscapeScroll(slides, destiny); 26763 } 26764 26765 /** 26766 * Keydown event 26767 */ 26768 function onkeydown(e){ 26769 var shiftPressed = e.shiftKey; 26770 26771 //do nothing if we can not scroll or we are not using horizotnal key arrows. 26772 if(!canScroll && [37,39].indexOf(e.which) < 0){ 26773 return; 26774 } 26775 26776 switch (e.which) { 26777 //up 26778 case 38: 26779 case 33: 26780 if(isScrollAllowed.k.up){ 26781 moveSectionUp(); 26782 } 26783 break; 26784 26785 //down 26786 case 32: //spacebar 26787 if(shiftPressed && isScrollAllowed.k.up){ 26788 moveSectionUp(); 26789 break; 26790 } 26791 /* falls through */ 26792 case 40: 26793 case 34: 26794 if(isScrollAllowed.k.down){ 26795 moveSectionDown(); 26796 } 26797 break; 26798 26799 //Home 26800 case 36: 26801 if(isScrollAllowed.k.up){ 26802 moveTo(1); 26803 } 26804 break; 26805 26806 //End 26807 case 35: 26808 if(isScrollAllowed.k.down){ 26809 moveTo( $(SECTION_SEL).length ); 26810 } 26811 break; 26812 26813 //left 26814 case 37: 26815 if(isScrollAllowed.k.left){ 26816 moveSlideLeft(); 26817 } 26818 break; 26819 26820 //right 26821 case 39: 26822 if(isScrollAllowed.k.right){ 26823 moveSlideRight(); 26824 } 26825 break; 26826 26827 default: 26828 return; // exit this handler for other keys 26829 } 26830 } 26831 26832 /** 26833 * Detecting the direction of the mouse movement. 26834 * Used only for the middle button of the mouse. 26835 */ 26836 var oldPageY = 0; 26837 function mouseMoveHandler(e){ 26838 if(canScroll){ 26839 // moving up 26840 if (e.pageY < oldPageY && isScrollAllowed.m.up){ 26841 moveSectionUp(); 26842 } 26843 26844 // moving down 26845 else if(e.pageY > oldPageY && isScrollAllowed.m.down){ 26846 moveSectionDown(); 26847 } 26848 } 26849 oldPageY = e.pageY; 26850 } 26851 26852 /** 26853 * Scrolls horizontal sliders. 26854 */ 26855 function landscapeScroll(slides, destiny, direction){ 26856 var section = slides.closest(SECTION_SEL); 26857 var v = { 26858 slides: slides, 26859 destiny: destiny, 26860 direction: direction, 26861 destinyPos: destiny.position(), 26862 slideIndex: destiny.index(), 26863 section: section, 26864 sectionIndex: section.index(SECTION_SEL), 26865 anchorLink: section.data('anchor'), 26866 slidesNav: section.find(SLIDES_NAV_SEL), 26867 slideAnchor: getAnchor(destiny), 26868 prevSlide: section.find(SLIDE_ACTIVE_SEL), 26869 prevSlideIndex: section.find(SLIDE_ACTIVE_SEL).index(), 26870 26871 //caching the value of isResizing at the momment the function is called 26872 //because it will be checked later inside a setTimeout and the value might change 26873 localIsResizing: isResizing 26874 }; 26875 v.xMovement = getXmovement(v.prevSlideIndex, v.slideIndex); 26876 v.direction = v.direction ? v.direction : v.xMovement; 26877 26878 //important!! Only do it when not resizing 26879 if(!v.localIsResizing){ 26880 //preventing from scrolling to the next/prev section when using scrollHorizontally 26881 canScroll = false;
26882 } 26883 26884 if(options.onSlideLeave){ 26885 26886 //if the site is not just resizing and readjusting the slides 26887 if(!v.localIsResizing && v.xMovement!=='none'){ 26888 if($.isFunction( options.onSlideLeave )){ 26889 if(options.onSlideLeave.call( v.prevSlide, v.anchorLink, (v.sectionIndex + 1), v.prevSlideIndex, v.xMovement, v.slideIndex ) === false){ 26890 slideMoving = false; 26891 return; 26892 } 26893 } 26894 } 26895 } 26896 26897 destiny.addClass(ACTIVE).siblings().removeClass(ACTIVE); 26898 26899 if(!v.localIsResizing){ 26900 stopMedia(v.prevSlide); 26901 lazyLoad(destiny); 26902 } 26903 26904 if(!options.loopHorizontal && options.controlArrows){ 26905 //hidding it for the fist slide, showing for the rest 26906 section.find(SLIDES_ARROW_PREV_SEL).toggle(v.slideIndex!==0); 26907 26908 //hidding it for the last slide, showing for the rest 26909 section.find(SLIDES_ARROW_NEXT_SEL).toggle(!destiny.is(':last-child')); 26910 } 26911 26912 //only changing the URL if the slides are in the current section (not for resize re-adjusting) 26913 if(section.hasClass(ACTIVE) && !v.localIsResizing){ 26914 setState(v.slideIndex, v.slideAnchor, v.anchorLink, v.sectionIndex); 26915 } 26916 26917 performHorizontalMove(slides, v, true); 26918 } 26919 26920 26921 function afterSlideLoads(v){ 26922 activeSlidesNavigation(v.slidesNav, v.slideIndex); 26923 26924 //if the site is not just resizing and readjusting the slides 26925 if(!v.localIsResizing){ 26926 $.isFunction( options.afterSlideLoad ) && options.afterSlideLoad.call( v.destiny, v.anchorLink, (v.sectionIndex + 1), v.slideAnchor, v.slideIndex); 26927 26928 //needs to be inside the condition to prevent problems with continuousVertical and scrollHorizontally 26929 //and to prevent double scroll right after a windows resize 26930 canScroll = true; 26931 26932 playMedia(v.destiny); 26933 } 26934 26935 //letting them slide again 26936 slideMoving = false; 26937 } 26938 26939 /** 26940 * Performs the horizontal movement. (CSS3 or jQuery) 26941 * 26942 * @param fireCallback {Bool} - determines whether or not to fire the callback 26943 */ 26944 function performHorizontalMove(slides, v, fireCallback){ 26945 var destinyPos = v.destinyPos; 26946 26947 if(options.css3){ 26948 var translate3d = 'translate3d(-' + Math.round(destinyPos.left) + 'px, 0px, 0px)'; 26949 26950 addAnimation(slides.find(SLIDES_CONTAINER_SEL)).css(getTransforms(translate3d), v); 26951 26952 afterSlideLoadsId = setTimeout(function(){ 26953 fireCallback && afterSlideLoads(v); 26954 }, options.scrollingSpeed, options.easing); 26955 }else{ 26956 slides.animate({ 26957 scrollLeft : Math.round(destinyPos.left) 26958 }, options.scrollingSpeed, options.easing, function() { 26959 26960 fireCallback && afterSlideLoads(v); 26961 }); 26962 } 26963 } 26964 26965 /** 26966 * Sets the state for the horizontal bullet navigations. 26967 */ 26968 function activeSlidesNavigation(slidesNav, slideIndex){ 26969 slidesNav.find(ACTIVE_SEL).removeClass(ACTIVE); 26970 slidesNav.find('li').eq(slideIndex).find('a').addClass(ACTIVE); 26971 } 26972 26973 var previousHeight = windowsHeight; 26974 26975 //when resizing the site, we adjust the heights of the sections, slimScroll... 26976 function resizeHandler(){ 26977 //checking if it needs to get responsive 26978 responsive(); 26979 26980 // rebuild immediately on touch devices 26981 if (isTouchDevice) { 26982 var activeElement = $(document.activeElement); 26983 26984 //if the keyboard is NOT visible 26985 if (!activeElement.is('textarea') && !activeElement.is('input') && !activeElement.is('select')) { 26986 var currentHeight = $window.height(); 26987 26988 //making sure the change in the viewport size is enough to force a rebuild. (20 % of the window to avoid problems when hidding scroll bars) 26989 if( Math.abs(currentHeight - previousHeight) > (20 * Math.max(previousHeight, currentHeight) / 100) ){ 26990 reBuild(true); 26991 previousHeight = currentHeight; 26992 } 26993 } 26994 }else{ 26995 //in order to call the functions only when the resize is finished 26996 //http://stackoverflow.com/questions/4298612/jquery-how-to-call-resize-event-only-once-its-finished-resizing 26997 clearTimeout(resizeId); 26998 26999 resizeId = setTimeout(function(){ 27000 reBuild(true); 27001 }, 350); 27002 } 27003 } 27004 27005 /** 27006 * Checks if the site needs to get responsive and disables autoScrolling if so. 27007 * A class `fp-responsive` is added to the plugin's container in case the user wants to use it for his own responsive CSS. 27008 */ 27009 function responsive(){ 27010 var widthLimit = options.responsive || options.responsiveWidth; //backwards compatiblity 27011 var heightLimit = options.responsiveHeight; 27012 27013 //only calculating what we need. Remember its called on the resize event. 27014 var isBreakingPointWidth = widthLimit && $window.outerWidth() < widthLimit; 27015 var isBreakingPointHeight = heightLimit && $window.height() < heightLimit; 27016 27017 if(widthLimit && heightLimit){ 27018 setResponsive(isBreakingPointWidth || isBreakingPointHeight); 27019 } 27020 else if(widthLimit){ 27021 setResponsive(isBreakingPointWidth); 27022 } 27023 else if(heightLimit){ 27024 setResponsive(isBreakingPointHeight); 27025 } 27026 } 27027 27028 /** 27029 * Adds transition animations for the given element 27030 */ 27031 function addAnimation(container, element){ 27032 var transition = 'all ' + options.scrollingSpeed + 'ms ' + options.easingcss3; 27033 27034 container.removeClass(NO_TRANSITION); 27035 return container.css({
27036 '-webkit-transition': transition, 27037 'transition': transition 27038 }); 27039 } 27040 27041 /** 27042 * Remove transition animations for the given element 27043 */ 27044 function removeAnimation(element){ 27045 return element.addClass(NO_TRANSITION); 27046 } 27047 27048 /** 27049 * Activating the vertical navigation bullets according to the given slide name. 27050 */ 27051 function activateNavDots(name, sectionIndex){ 27052 if(options.navigation){ 27053 $(SECTION_NAV_SEL).find(ACTIVE_SEL).removeClass(ACTIVE); 27054 if(name){ 27055 $(SECTION_NAV_SEL).find('a[href="#' + name + '"]').addClass(ACTIVE); 27056 }else{ 27057 $(SECTION_NAV_SEL).find('li').eq(sectionIndex).find('a').addClass(ACTIVE); 27058 } 27059 } 27060 } 27061 27062 /** 27063 * Activating the website main menu elements according to the given slide name. 27064 */ 27065 function activateMenuElement(name){ 27066 if(options.menu){ 27067 $(options.menu).find(ACTIVE_SEL).removeClass(ACTIVE); 27068 $(options.menu).find('[data-menuanchor="'+name+'"]').addClass(ACTIVE); 27069 } 27070 } 27071 27072 /** 27073 * Sets to active the current menu and vertical nav items. 27074 */ 27075 function activateMenuAndNav(anchor, index){ 27076 activateMenuElement(anchor); 27077 activateNavDots(anchor, index); 27078 } 27079 27080 /** 27081 * Retuns `up` or `down` depending on the scrolling movement to reach its destination 27082 * from the current section. 27083 */ 27084 function getYmovement(destiny){ 27085 var fromIndex = $(SECTION_ACTIVE_SEL).index(SECTION_SEL); 27086 var toIndex = destiny.index(SECTION_SEL); 27087 if( fromIndex == toIndex){ 27088 return 'none'; 27089 } 27090 if(fromIndex > toIndex){ 27091 return 'up'; 27092 } 27093 return 'down'; 27094 } 27095 27096 /** 27097 * Retuns `right` or `left` depending on the scrolling movement to reach its destination 27098 * from the current slide. 27099 */ 27100 function getXmovement(fromIndex, toIndex){ 27101 if( fromIndex == toIndex){ 27102 return 'none'; 27103 } 27104 if(fromIndex > toIndex){ 27105 return 'left'; 27106 } 27107 return 'right'; 27108 } 27109 27110 /** 27111 * Checks if the element needs scrollbar and if the user wants to apply it. 27112 * If so it creates it. 27113 * 27114 * @param {Object} element jQuery object of the section or slide 27115 */ 27116 function createScrollBar(element){ 27117 //User doesn't want scrollbar here? Sayonara baby! 27118 if(element.hasClass('fp-noscroll')) return; 27119 27120 //needed to make `scrollHeight` work under Opera 12 27121 element.css('overflow', 'hidden'); 27122 27123 var scrollOverflowHandler = options.scrollOverflowHandler; 27124 var wrap = scrollOverflowHandler.wrapContent(); 27125 //in case element is a slide 27126 var section = element.closest(SECTION_SEL); 27127 var scrollable = scrollOverflowHandler.scrollable(element); 27128 var contentHeight; 27129 27130 //if there was scroll, the contentHeight will be the one in the scrollable section 27131 if(scrollable.length){ 27132 contentHeight = scrollOverflowHandler.scrollHeight(element); 27133 }else{ 27134 contentHeight = element.get(0).scrollHeight; 27135 if(options.verticalCentered){ 27136 contentHeight = element.find(TABLE_CELL_SEL).get(0).scrollHeight; 27137 } 27138 } 27139 27140 var scrollHeight = windowsHeight - parseInt(section.css('padding-bottom')) - parseInt(section.css('padding-top')); 27141 27142 //needs scroll? 27143 if ( contentHeight > scrollHeight) { 27144 //did we already have an scrollbar ? Updating it 27145 if(scrollable.length){ 27146 scrollOverflowHandler.update(element, scrollHeight); 27147 } 27148 //creating the scrolling 27149 else{ 27150 if(options.verticalCentered){ 27151 element.find(TABLE_CELL_SEL).wrapInner(wrap); 27152 }else{ 27153 element.wrapInner(wrap); 27154 } 27155 scrollOverflowHandler.create(element, scrollHeight); 27156 } 27157 } 27158 //removing the scrolling when it is not necessary anymore 27159 else{ 27160 scrollOverflowHandler.remove(element); 27161 } 27162 27163 //undo 27164 element.css('overflow', ''); 27165 } 27166 27167 function addTableClass(element){ 27168 //In case we are styling for the 2nd time as in with reponsiveSlides 27169 if(!element.hasClass(TABLE)){ 27170 element.addClass(TABLE).wrapInner('<div class="' + TABLE_CELL + '" style="height:' + getTableHeight(element) + 'px;" />'); 27171 } 27172 } 27173 27174 function getTableHeight(element){ 27175 var sectionHeight = windowsHeight; 27176 27177 if(options.paddingTop || options.paddingBottom){ 27178 var section = element; 27179 if(!section.hasClass(SECTION)){ 27180 section = element.closest(SECTION_SEL); 27181 } 27182 27183 var paddings = parseInt(section.css('padding-top')) + parseInt(section.css('padding-bottom')); 27184 sectionHeight = (windowsHeight - paddings); 27185 } 27186 27187 return sectionHeight; 27188 } 27189 27190 /** 27191 * Adds a css3 transform property to the container class with or without animation depending on the animated param. 27192 */ 27193 function transformContainer(translate3d, animated){ 27194 if(animated){ 27195 addAnimation(container); 27196 }else{ 27197 removeAnimation(container); 27198 } 27199 27200 container.css(getTransforms(translate3d)); 27201 27202 //syncronously removing the class after the animation has been applied. 27203 setTimeout(function(){ 27204 container.removeClass(NO_TRANSITION); 27205 },10); 27206 } 27207 27208 /** 27209 * Gets a section by its anchor / index 27210 */ 27211 function getSectionByAnchor(sectionAnchor){ 27212 if(!sectionAnchor) return []; 27213 27214 var section = container.find(SECTION_SEL + '[data-anchor="'+sectionAnchor+'"]'); 27215 if(!section.length){ 27216 section = $(SECTION_SEL).eq( sectionAnchor -1); 27217 } 27218 27219 return section; 27220 } 27221 27222 /** 27223 * Gets a slide inside a given section by its anchor / index 27224 */ 27225 function getSlideByAnchor(slideAnchor, section){ 27226 var slides = section.find(SLIDES_WRAPPER_SEL); 27227 var slide = slides.find(SLIDE_SEL + '[data-anchor="'+slideAnchor+'"]'); 27228
27229 if(!slide.length){ 27230 slide = slides.find(SLIDE_SEL).eq(slideAnchor); 27231 } 27232 27233 return slide; 27234 } 27235 27236 /** 27237 * Scrolls to the given section and slide anchors 27238 */ 27239 function scrollPageAndSlide(destiny, slide){ 27240 var section = getSectionByAnchor(destiny); 27241 27242 //do nothing if there's no section with the given anchor name 27243 if(!section.length) return; 27244 27245 //default slide 27246 if (typeof slide === 'undefined') { 27247 slide = 0; 27248 } 27249 27250 //we need to scroll to the section and then to the slide 27251 if (destiny !== lastScrolledDestiny && !section.hasClass(ACTIVE)){ 27252 scrollPage(section, function(){ 27253 scrollSlider(section, slide); 27254 }); 27255 } 27256 //if we were already in the section 27257 else{ 27258 scrollSlider(section, slide); 27259 } 27260 } 27261 27262 /** 27263 * Scrolls the slider to the given slide destination for the given section 27264 */ 27265 function scrollSlider(section, slideAnchor){ 27266 if(typeof slideAnchor !== 'undefined'){ 27267 var slides = section.find(SLIDES_WRAPPER_SEL); 27268 var destiny = getSlideByAnchor(slideAnchor, section); 27269 27270 if(destiny.length){ 27271 landscapeScroll(slides, destiny); 27272 } 27273 } 27274 } 27275 27276 /** 27277 * Creates a landscape navigation bar with dots for horizontal sliders. 27278 */ 27279 function addSlidesNavigation(section, numSlides){ 27280 section.append('<div class="' + SLIDES_NAV + '"><ul></ul></div>'); 27281 var nav = section.find(SLIDES_NAV_SEL); 27282 27283 //top or bottom 27284 nav.addClass(options.slidesNavPosition); 27285 27286 for(var i=0; i< numSlides; i++){ 27287 nav.find('ul').append('<li><a href="#"><span></span></a></li>'); 27288 } 27289 27290 //centering it 27291 nav.css('margin-left', '-' + (nav.width()/2) + 'px'); 27292 27293 nav.find('li').first().find('a').addClass(ACTIVE); 27294 } 27295 27296 27297 /** 27298 * Sets the state of the website depending on the active section/slide. 27299 * It changes the URL hash when needed and updates the body class. 27300 */ 27301 function setState(slideIndex, slideAnchor, anchorLink, sectionIndex){ 27302 var sectionHash = ''; 27303 27304 if(options.anchors.length && !options.lockAnchors){ 27305 27306 //isn't it the first slide? 27307 if(slideIndex){ 27308 if(typeof anchorLink !== 'undefined'){ 27309 sectionHash = anchorLink; 27310 } 27311 27312 //slide without anchor link? We take the index instead. 27313 if(typeof slideAnchor === 'undefined'){ 27314 slideAnchor = slideIndex; 27315 } 27316 27317 lastScrolledSlide = slideAnchor; 27318 setUrlHash(sectionHash + '/' + slideAnchor); 27319 27320 //first slide won't have slide anchor, just the section one 27321 }else if(typeof slideIndex !== 'undefined'){ 27322 lastScrolledSlide = slideAnchor; 27323 setUrlHash(anchorLink); 27324 } 27325 27326 //section without slides 27327 else{ 27328 setUrlHash(anchorLink); 27329 } 27330 } 27331 27332 setBodyClass(); 27333 } 27334 27335 /** 27336 * Sets the URL hash. 27337 */ 27338 function setUrlHash(url){ 27339 //Uncode addition 27340 if ( typeof SiteParameters.slide_footer != 'undefined' && url == SiteParameters.slide_footer ) 27341 return false; 27342 27343 if(options.recordHistory){ 27344 location.hash = url; 27345 }else{ 27346 //Uncode addition 27347 //Mobile Chrome doesn't work the normal way, so... lets use HTML5 for phones :) 27348 // if(isTouchDevice || isTouch){ 27349 // window.history.replaceState(undefined, undefined, '#' + url); 27350 // }else{ 27351 // var baseUrl = window.location.href.split('#')[0]; 27352 // window.location.replace( baseUrl + '#' + url ); 27353 // } 27354 return false;
27355 } 27356 } 27357 27358 /** 27359 * Gets the anchor for the given slide / section. Its index will be used if there's none. 27360 */ 27361 function getAnchor(element){ 27362 var anchor = element.data('anchor'); 27363 var index = element.index(); 27364 27365 //Slide without anchor link? We take the index instead. 27366 if(typeof anchor === 'undefined'){ 27367 anchor = index; 27368 } 27369 27370 return anchor; 27371 } 27372 27373 /** 27374 * Sets a class for the body of the page depending on the active section / slide 27375 */ 27376 function setBodyClass(){ 27377 var section = $(SECTION_ACTIVE_SEL); 27378 var slide = section.find(SLIDE_ACTIVE_SEL); 27379 27380 var sectionAnchor = getAnchor(section); 27381 var slideAnchor = getAnchor(slide); 27382 27383 var text = String(sectionAnchor); 27384 27385 if(slide.length){ 27386 text = text + '-' + slideAnchor; 27387 } 27388 27389 //changing slash for dash to make it a valid CSS style 27390 text = text.replace('/', '-').replace('#',''); 27391 27392 //removing previous anchor classes 27393 var classRe = new RegExp('\\b\\s?' + VIEWING_PREFIX + '-[^\\s]+\\b', "g"); 27394 $body[0].className = $body[0].className.replace(classRe, ''); 27395 27396 //adding the current anchor 27397 $body.addClass(VIEWING_PREFIX + '-' + text); 27398 } 27399 27400 /** 27401 * Checks for translate3d support 27402 * @return boolean 27403 * http://stackoverflow.com/questions/5661671/detecting-transform-translate3d-support 27404 */ 27405 function support3d() { 27406 var el = document.createElement('p'), 27407 has3d, 27408 transforms = { 27409 'webkitTransform':'-webkit-transform', 27410 'OTransform':'-o-transform', 27411 'msTransform':'-ms-transform', 27412 'MozTransform':'-moz-transform', 27413 'transform':'transform' 27414 }; 27415 27416 // Add it to the body to get the computed style. 27417 document.body.insertBefore(el, null); 27418 27419 for (var t in transforms) { 27420 if (el.style[t] !== undefined) { 27421 el.style[t] = 'translate3d(1px,1px,1px)'; 27422 has3d = window.getComputedStyle(el).getPropertyValue(transforms[t]); 27423 } 27424 } 27425 27426 document.body.removeChild(el); 27427 27428 return (has3d !== undefined && has3d.length > 0 && has3d !== 'none'); 27429 } 27430 27431 /** 27432 * Removes the auto scrolling action fired by the mouse wheel and trackpad. 27433 * After this function is called, the mousewheel and trackpad movements won't scroll through sections. 27434 */ 27435 function removeMouseWheelHandler(){ 27436 if (document.addEventListener) { 27437 document.removeEventListener('mousewheel', MouseWheelHandler, false); //IE9, Chrome, Safari, Oper 27438 document.removeEventListener('wheel', MouseWheelHandler, false); //Firefox 27439 document.removeEventListener('MozMousePixelScroll', MouseWheelHandler, false); //old Firefox 27440 } else { 27441 document.detachEvent('onmousewheel', MouseWheelHandler); //IE 6/7/8 27442 } 27443 } 27444 27445 /** 27446 * Adds the auto scrolling action for the mouse wheel and trackpad. 27447 * After this function is called, the mousewheel and trackpad movements will scroll through sections 27448 * https://developer.mozilla.org/en-US/docs/Web/Events/wheel 27449 */ 27450 function addMouseWheelHandler(){ 27451 var prefix = ''; 27452 var _addEventListener; 27453 27454 if (window.addEventListener){ 27455 _addEventListener = "addEventListener"; 27456 }else{ 27457 _addEventListener = "attachEvent"; 27458 prefix = 'on'; 27459 } 27460 27461 // detect available wheel event 27462 var support = 'onwheel' in document.createElement('div') ? 'wheel' : // Modern browsers support "wheel" 27463 document.onmousewheel !== undefined ? 'mousewheel' : // Webkit and IE support at least "mousewheel" 27464 'DOMMouseScroll'; // let's assume that remaining browsers are older Firefox 27465 var passiveEvent = g_supportsPassive ? {passive: false }
27465: false; 27466 27467 27468 if(support == 'DOMMouseScroll'){ 27469 document[ _addEventListener ](prefix + 'MozMousePixelScroll', MouseWheelHandler, passiveEvent); 27470 } 27471 27472 //handle MozMousePixelScroll in older Firefox 27473 else{ 27474 document[ _addEventListener ](prefix + support, MouseWheelHandler, passiveEvent); 27475 } 27476 } 27477 27478 /** 27479 * Binding the mousemove when the mouse's middle button is pressed 27480 */ 27481 function addMiddleWheelHandler(){ 27482 container 27483 .on('mousedown', mouseDownHandler) 27484 .on('mouseup', mouseUpHandler); 27485 } 27486 27487 /** 27488 * Unbinding the mousemove when the mouse's middle button is released 27489 */ 27490 function removeMiddleWheelHandler(){ 27491 container 27492 .off('mousedown', mouseDownHandler) 27493 .off('mouseup', mouseUpHandler); 27494 } 27495 27496 /** 27497 * Adds the possibility to auto scroll through sections on touch devices. 27498 */ 27499 function addTouchHandler(){ 27500 if(isTouchDevice || isTouch){ 27501 if(options.autoScrolling){ 27502 $body.off(events.touchmove).on(events.touchmove, preventBouncing); 27503 } 27504 27505 $(WRAPPER_SEL) 27506 .off(events.touchstart).on(events.touchstart, touchStartHandler) 27507 .off(events.touchmove).on(events.touchmove, touchMoveHandler); 27508 } 27509 } 27510 27511 /** 27512 * Removes the auto scrolling for touch devices. 27513 */ 27514 function removeTouchHandler(){ 27515 if(isTouchDevice || isTouch){ 27516 $(WRAPPER_SEL) 27517 .off(events.touchstart) 27518 .off(events.touchmove); 27519 } 27520 } 27521 27522 /* 27523 * Returns and object with Microsoft pointers (for IE<11 and for IE >= 11) 27524 * http://msdn.microsoft.com/en-us/library/ie/dn304886(v=vs.85).aspx 27525 */ 27526 function getMSPointer(){ 27527 var pointer; 27528 27529 //IE >= 11 & rest of browsers 27530 if(window.PointerEvent){ 27531 pointer = { down: 'pointerdown', move: 'pointermove'}; 27532 } 27533 27534 //IE < 11 27535 else{ 27536 pointer = { down: 'MSPointerDown', move: 'MSPointerMove'}; 27537 } 27538 27539 return pointer; 27540 } 27541 27542 /** 27543 * Gets the pageX and pageY properties depending on the browser. 27544 * https://github.com/alvarotrigo/fullPage.js/issues/194#issuecomment-34069854 27545 */ 27546 function getEventsPage(e){ 27547 var events = []; 27548 27549 events.y = (typeof e.pageY !== 'undefined' && (e.pageY || e.pageX) ? e.pageY : e.touches[0].pageY); 27550 events.x = (typeof e.pageX !== 'undefined' && (e.pageY || e.pageX) ? e.pageX : e.touches[0].pageX); 27551 27552 //in touch devices with scrollBar:true, e.pageY is detected, but we have to deal with touch events. #1008 27553 if(isTouch && isReallyTouch(e) && options.scrollBar){ 27554 events.y = e.touches[0].pageY; 27555 events.x = e.touches[0].pageX; 27556 } 27557 27558 return events; 27559 } 27560 27561 /** 27562 * Slides silently (with no animation) the active slider to the given slide. 27563 * @param noCallback {bool} true or defined -> no callbacks 27564 */ 27565 function silentLandscapeScroll(activeSlide, noCallbacks){ 27566 setScrollingSpeed (0, 'internal'); 27567 27568 if(typeof noCallbacks !== 'undefined'){ 27569 //preventing firing callbacks afterSlideLoad etc. 27570 isResizing = true; 27571 } 27572 27573 landscapeScroll(activeSlide.closest(SLIDES_WRAPPER_SEL), activeSlide); 27574 27575 if(typeof noCallbacks !== 'undefined'){ 27576 isResizing = false; 27577 } 27578 27579 setScrollingSpeed(originals.scrollingSpeed, 'internal'); 27580 } 27581 27582 /** 27583 * Scrolls silently (with no animation) the page to the given Y position. 27584 */ 27585 function silentScroll(top){ 27586 // The first section can have a negative value in iOS 10. Not quite sure why: -0.0142822265625 27587 // that's why we round it to 0. 27588 var roundedTop = Math.round(top); 27589 27590 if (options.css3 && options.autoScrolling && !options.scrollBar){ 27591 var translate3d = 'translate3d(0px, -' + roundedTop + 'px, 0px)'; 27592 transformContainer(translate3d, false); 27593 } 27594 else if(options.autoScrolling && !options.scrollBar){ 27595 container.css('top', -roundedTop); 27596 } 27597 else{ 27598 $htmlBody.scrollTop(roundedTop); 27599 } 27600 } 27601 27602 /** 27603 * Returns the cross-browser transform string. 27604 */ 27605 function getTransforms(translate3d){ 27606 return {
27607 '-webkit-transform': translate3d, 27608 '-moz-transform': translate3d, 27609 '-ms-transform':translate3d, 27610 'transform': translate3d 27611 }; 27612 } 27613 27614 /** 27615 * Allowing or disallowing the mouse/swipe scroll in a given direction. (not for keyboard) 27616 * @type m (mouse) or k (keyboard) 27617 */ 27618 function setIsScrollAllowed(value, direction, type){ 27619 switch (direction){ 27620 case 'up': isScrollAllowed[type].up = value; break; 27621 case 'down': isScrollAllowed[type].down = value; break; 27622 case 'left': isScrollAllowed[type].left = value; break; 27623 case 'right': isScrollAllowed[type].right = value; break; 27624 case 'all': 27625 if(type == 'm'){ 27626 setAllowScrolling(value); 27627 }else{ 27628 setKeyboardScrolling(value); 27629 } 27630 } 27631 } 27632 27633 /* 27634 * Destroys fullpage.js plugin events and optinally its html markup and styles 27635 */ 27636 function destroy(all){ 27637 setAutoScrolling(false, 'internal'); 27638 setAllowScrolling(false); 27639 setKeyboardScrolling(false); 27640 container.addClass(DESTROYED); 27641 27642 clearTimeout(afterSlideLoadsId); 27643 clearTimeout(afterSectionLoadsId); 27644 clearTimeout(resizeId); 27645 clearTimeout(scrollId); 27646 clearTimeout(scrollId2); 27647 27648 $window 27649 .off('scroll', scrollHandler) 27650 .off('hashchange', hashChangeHandler) 27651 .off('resize', resizeHandler); 27652 27653 $document 27654 .off('click touchstart', SECTION_NAV_SEL + ' a') 27655 .off('mouseenter', SECTION_NAV_SEL + ' li') 27656 .off('mouseleave', SECTION_NAV_SEL + ' li') 27657 .off('click touchstart', SLIDES_NAV_LINK_SEL) 27658 .off('mouseover', options.normalScrollElements) 27659 .off('mouseout', options.normalScrollElements); 27660 27661 $(SECTION_SEL) 27662 .off('click touchstart', SLIDES_ARROW_SEL); 27663 27664 clearTimeout(afterSlideLoadsId); 27665 clearTimeout(afterSectionLoadsId); 27666 27667 //lets make a mess! 27668 if(all){ 27669 destroyStructure(); 27670 } 27671 } 27672 27673 /* 27674 * Removes inline styles added by fullpage.js 27675 */ 27676 function destroyStructure(){ 27677 //reseting the `top` or `translate` properties to 0 27678 silentScroll(0); 27679 27680 //loading all the lazy load content 27681 container.find('img[data-src], source[data-src], audio[data-src], iframe[data-src]').each(function(){ 27682 setSrc($(this), 'src'); 27683 }); 27684 27685 container.find('img[data-srcset]').each(function(){ 27686 setSrc($(this), 'srcset'); 27687 }); 27688 27689 $(SECTION_NAV_SEL + ', ' + SLIDES_NAV_SEL + ', ' + SLIDES_ARROW_SEL).remove(); 27690 27691 //removing inline styles 27692 $(SECTION_SEL).css( { 27693 'height': '', 27694 'background-color' : '', 27695 'padding': '' 27696 }); 27697 27698 $(SLIDE_SEL).css( { 27699 'width': '' 27700 }); 27701 27702 container.css({ 27703 'height': '', 27704 'position': '', 27705 '-ms-touch-action': '', 27706 'touch-action': '' 27707 }); 27708 27709 $htmlBody.css({ 27710 'overflow': '', 27711 'height': '' 27712 }); 27713 27714 // remove .fp-enabled class 27715 $('html').removeClass(ENABLED); 27716 27717 // remove .fp-responsive class 27718 $body.removeClass(RESPONSIVE); 27719 27720 // remove all of the .fp-viewing- classes 27721 $.each($body.get(0).className.split(/\s+/), function (index, className) { 27722 if (className.indexOf(VIEWING_PREFIX) === 0) { 27723 $body.removeClass(className); 27724 } 27725 }); 27726 27727 //removing added classes 27728 $(SECTION_SEL + ', ' + SLIDE_SEL).each(function(){ 27729 options.scrollOverflowHandler.remove($(this)); 27730 $(this).removeClass(TABLE + ' ' + ACTIVE); 27731 }); 27732 27733 removeAnimation(container); 27734 27735 //Unwrapping content 27736 container.find(TABLE_CELL_SEL + ', ' + SLIDES_CONTAINER_SEL + ', ' + SLIDES_WRAPPER_SEL).each(function(){ 27737 //unwrap not being use in case there's no child element inside and its just text 27738 $(this).replaceWith(this.childNodes); 27739 }); 27740 27741 //removing the applied transition from the fullpage wrapper 27742 container.css({
27743 '-webkit-transition': 'none', 27744 'transition': 'none' 27745 }); 27746 27747 //scrolling the page to the top with no animation 27748 $htmlBody.scrollTop(0); 27749 27750 //removing selectors 27751 var usedSelectors = [SECTION, SLIDE, SLIDES_CONTAINER]; 27752 $.each(usedSelectors, function(index, value){ 27753 $('.' + value).removeClass(value); 27754 }); 27755 } 27756 27757 /* 27758 * Sets the state for a variable with multiple states (original, and temporal) 27759 * Some variables such as `autoScrolling` or `recordHistory` might change automatically its state when using `responsive` or `autoScrolling:false`. 27760 * This function is used to keep track of both states, the original and the temporal one. 27761 * If type is not 'internal', then we assume the user is globally changing the variable. 27762 */ 27763 function setVariableState(variable, value, type){ 27764 options[variable] = value; 27765 if(type !== 'internal'){ 27766 originals[variable] = value; 27767 } 27768 } 27769 27770 /** 27771 * Displays warnings 27772 */ 27773 function displayWarnings(){ 27774 var extensions = ['fadingEffect', 'continuousHorizontal', 'scrollHorizontally', 'interlockedSlides', 'resetSliders', 'responsiveSlides', 'offsetSections', 'dragAndMove', 'scrollOverflowReset', 'parallax']; 27775 //UNCODE.addition 27776 // if($('html').hasClass(ENABLED)){ 27777 // showError('error', 'Fullpage.js can only be initialized once and you are doing it multiple times!'); 27778 // return; 27779 // } 27780 27781 // Disable mutually exclusive settings 27782 //UNCODE.addition 27783 // if (options.continuousVertical && 27784 // (options.loopTop || options.loopBottom)) { 27785 // options.continuousVertical = false;
27786 // showError('warn', 'Option `loopTop/loopBottom` is mutually exclusive with `continuousVertical`; `continuousVertical` disabled'); 27787 // } 27788 27789 // if(options.scrollBar && options.scrollOverflow){ 27790 // showError('warn', 'Option `scrollBar` is mutually exclusive with `scrollOverflow`. Sections with scrollOverflow might not work well in Firefox'); 27791 // } 27792 27793 // if(options.continuousVertical && (options.scrollBar || !options.autoScrolling)){ 27794 // options.continuousVertical = false; 27795 // showError('warn', 'Scroll bars (`scrollBar:true` or `autoScrolling:false`) are mutually exclusive with `continuousVertical`; `continuousVertical` disabled'); 27796 // } 27797 27798 //using extensions? Wrong file! 27799 $.each(extensions, function(index, extension){ 27800 //is the option set to true? 27801 if(options[extension]){ 27802 showError('warn', 'fullpage.js extensions require jquery.fullpage.extensions.min.js file instead of the usual jquery.fullpage.js. Requested: '+ extension); 27803 } 27804 }); 27805 27806 //anchors can not have the same value as any element ID or NAME 27807 $.each(options.anchors, function(index, name){ 27808 27809 //case insensitive selectors (http://stackoverflow.com/a/19465187/1081396) 27810 var nameAttr = $document.find('[name]').filter(function() { 27811 return $(this).attr('name') && $(this).attr('name').toLowerCase() == name.toLowerCase(); 27812 }); 27813 27814 var idAttr = $document.find('[id]').filter(function() { 27815 return $(this).attr('id') && $(this).attr('id').toLowerCase() == name.toLowerCase(); 27816 }); 27817 27818 if(idAttr.length || nameAttr.length ){ 27819 showError('error', 'data-anchor tags can not have the same value as any `id` element on the site (or `name` element for IE).'); 27820 idAttr.length && showError('error', '"' + name + '" is is being used by another element `id` property'); 27821 nameAttr.length && showError('error', '"' + name + '" is is being used by another element `name` property'); 27822 } 27823 }); 27824 } 27825 27826 /** 27827 * Shows a message in the console of the given type. 27828 */ 27829 function showError(type, text){ 27830 console && console[type] && console[type]('fullPage: ' + text); 27831 } 27832 27833 }; //end of $.fn.fullpage 27834 27835 if(typeof IScroll !== 'undefined'){ 27836 /* 27837 * Turns iScroll `mousewheel` option off dynamically 27838 * https://github.com/cubiq/iscroll/issues/1036 27839 */ 27840 IScroll.prototype.wheelOn = function () { 27841 this.wrapper.addEventListener('wheel', this); 27842 this.wrapper.addEventListener('mousewheel', this); 27843 this.wrapper.addEventListener('DOMMouseScroll', this); 27844 }; 27845 27846 /* 27847 * Turns iScroll `mousewheel` option on dynamically 27848 * https://github.com/cubiq/iscroll/issues/1036 27849 */ 27850 IScroll.prototype.wheelOff = function () { 27851 this.wrapper.removeEventListener('wheel', this); 27852 this.wrapper.removeEventListener('mousewheel', this); 27853 this.wrapper.removeEventListener('DOMMouseScroll', this); 27854 }; 27855 } 27856 27857 /** 27858 * An object to handle overflow scrolling. 27859 * This uses jquery.slimScroll to accomplish overflow scrolling. 27860 * It is possible to pass in an alternate scrollOverflowHandler 27861 * to the fullpage.js option that implements the same functions 27862 * as this handler. 27863 * 27864 * @type {Object} 27865 */ 27866 var iscrollHandler = { 27867 refreshId: null, 27868 iScrollInstances: [], 27869 27870 // Enables or disables the mouse wheel for the active section or all slides in it 27871 toggleWheel: function(value){ 27872 var scrollable = $(SECTION_ACTIVE_SEL).find(SCROLLABLE_SEL); 27873 scrollable.each(function(){ 27874 var iScrollInstance = $(this).data('iscrollInstance'); 27875 if(typeof iScrollInstance !== 'undefined' && iScrollInstance){ 27876 if(value){ 27877 iScrollInstance.wheelOn(); 27878 } 27879 else{ 27880 iScrollInstance.wheelOff(); 27881 } 27882 } 27883 }); 27884 }, 27885 27886 /** 27887 * Turns off iScroll for the destination section. 27888 * When scrolling very fast on some trackpads (and Apple laptops) the inertial scrolling would
27889 * scroll the destination section/slide before the sections animations ends. 27890 */ 27891 onLeave: function(){ 27892 iscrollHandler.toggleWheel(false); 27893 }, 27894 27895 // Turns off iScroll for the leaving section 27896 beforeLeave: function(){ 27897 iscrollHandler.onLeave() 27898 }, 27899 27900 // Turns on iScroll on section load 27901 afterLoad: function(){ 27902 iscrollHandler.toggleWheel(true); 27903 }, 27904 27905 /** 27906 * Called when overflow scrolling is needed for a section. 27907 * 27908 * @param {Object} element jQuery object containing current section 27909 * @param {Number} scrollHeight Current window height in pixels 27910 */ 27911 create: function(element, scrollHeight) { 27912 var scrollable = element.find(SCROLLABLE_SEL); 27913 27914 scrollable.height(scrollHeight); 27915 scrollable.each(function() { 27916 var $this = $(this); 27917 var iScrollInstance = $this.data('iscrollInstance'); 27918 if (iScrollInstance) { 27919 $.each(iscrollHandler.iScrollInstances, function(){ 27920 $(this).destroy(); 27921 }); 27922 } 27923 27924 iScrollInstance = new IScroll($this.get(0), iscrollOptions); 27925 iscrollHandler.iScrollInstances.push(iScrollInstance); 27926 27927 //off by default until the section gets active 27928 iScrollInstance.wheelOff(); 27929 27930 $this.data('iscrollInstance', iScrollInstance); 27931 }); 27932 }, 27933 27934 /** 27935 * Return a boolean depending on whether the scrollable element is a 27936 * the end or at the start of the scrolling depending on the given type. 27937 * 27938 * @param {String} type Either 'top' or 'bottom' 27939 * @param {Object} scrollable jQuery object for the scrollable element 27940 * @return {Boolean} 27941 */ 27942 isScrolled: function(type, scrollable) { 27943 var scroller = scrollable.data('iscrollInstance'); 27944 27945 //no scroller? 27946 if (!scroller) { 27947 return true; 27948 } 27949 27950 if (type === 'top') { 27951 return scroller.y >= 0 && !scrollable.scrollTop(); 27952 } else if (type === 'bottom') { 27953 return (0 - scroller.y) + scrollable.scrollTop() + 1 + scrollable.innerHeight() >= scrollable[0].scrollHeight; 27954 } 27955 }, 27956 27957 /** 27958 * Returns the scrollable element for the given section. 27959 * If there are landscape slides, will only return a scrollable element 27960 * if it is in the active slide. 27961 * 27962 * @param {Object} activeSection jQuery object containing current section 27963 * @return {Boolean} 27964 */ 27965 scrollable: function(activeSection){ 27966 // if there are landscape slides, we check if the scrolling bar is in the current one or not 27967 if (activeSection.find(SLIDES_WRAPPER_SEL).length) { 27968 return activeSection.find(SLIDE_ACTIVE_SEL).find(SCROLLABLE_SEL); 27969 } 27970 return activeSection.find(SCROLLABLE_SEL); 27971 }, 27972 27973 /** 27974 * Returns the scroll height of the wrapped content. 27975 * If this is larger than the window height minus section padding, 27976 * overflow scrolling is needed. 27977 * 27978 * @param {Object} element jQuery object containing current section 27979 * @return {Number} 27980 */ 27981 scrollHeight: function(element) { 27982 return element.find(SCROLLABLE_SEL).children().first().get(0).scrollHeight; 27983 }, 27984 27985 /** 27986 * Called when overflow scrolling is no longer needed for a section. 27987 * 27988 * @param {Object} element jQuery object containing current section 27989 */ 27990 remove: function(element) { 27991 var scrollable = element.find(SCROLLABLE_SEL); 27992 if (scrollable.length) { 27993 var iScrollInstance = scrollable.data('iscrollInstance'); 27994 iScrollInstance.destroy(); 27995 27996 scrollable.data('iscrollInstance', null); 27997 } 27998 element.find(SCROLLABLE_SEL).children().first().children().first().unwrap().unwrap(); 27999 }, 28000 28001 /** 28002 * Called when overflow scrolling has already been setup but the 28003 * window height has potentially changed. 28004 * 28005 * @param {Object}
vendor: 16,384 bytes, lines 28005-28556
28005 element jQuery object containing current section 28006 * @param {Number} scrollHeight Current window height in pixels 28007 */ 28008 update: function(element, scrollHeight) { 28009 //using a timeout in order to execute the refresh function only once when `update` is called multiple times in a 28010 //short period of time. 28011 //it also comes on handy because iScroll requires the use of timeout when using `refresh`. 28012 clearTimeout(iscrollHandler.refreshId); 28013 iscrollHandler.refreshId = setTimeout(function(){ 28014 $.each(iscrollHandler.iScrollInstances, function(){ 28015 $(this).get(0).refresh(); 28016 }); 28017 }, 150); 28018 28019 //updating the wrappers height 28020 element.find(SCROLLABLE_SEL).css('height', scrollHeight + 'px').parent().css('height', scrollHeight + 'px'); 28021 }, 28022 28023 /** 28024 * Called to get any additional elements needed to wrap the section 28025 * content in order to facilitate overflow scrolling. 28026 * 28027 * @return {String|Object} Can be a string containing HTML, 28028 * a DOM element, or jQuery object. 28029 */ 28030 wrapContent: function() { 28031 return '<div class="' + SCROLLABLE + '"><div class="fp-scroller"></div></div>'; 28032 } 28033 }; 28034}); 28035 28036/* ======================================================================== 28037 * Bootstrap: collapse.js v3.1.1 28038 * http://getbootstrap.com/javascript/#collapse 28039 * ======================================================================== 28040 * Copyright 2011-2014 Twitter, Inc. 28041 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 28042 * ======================================================================== */ 28043 28044 28045+function ($) { 28046 'use strict'; 28047 28048 // COLLAPSE PUBLIC CLASS DEFINITION 28049 // ================================ 28050 28051 var Collapse = function (element, options) { 28052 this.$element = $(element) 28053 this.options = $.extend({}, Collapse.DEFAULTS, options) 28054 this.transitioning = null 28055 28056 if (this.options.parent) this.$parent = $(this.options.parent) 28057 if (this.options.toggle) this.toggle() 28058 } 28059 28060 Collapse.DEFAULTS = { 28061 toggle: true 28062 } 28063 28064 Collapse.prototype.dimension = function () { 28065 var hasWidth = this.$element.hasClass('width') 28066 return hasWidth ? 'width' : 'height' 28067 } 28068 28069 Collapse.prototype.show = function () { 28070 if (this.transitioning || this.$element.hasClass('in')) return 28071 28072 var startEvent = $.Event('show.bs.collapse') 28073 this.$element.trigger(startEvent) 28074 if (startEvent.isDefaultPrevented()) return 28075 28076 var actives = this.$parent && this.$parent.find('> .panel > .in') 28077 28078 if (actives && actives.length) { 28079 var hasData = actives.data('bs.collapse') 28080 if (hasData && hasData.transitioning) return 28081 actives.collapse('hide') 28082 hasData || actives.data('bs.collapse', null) 28083 } 28084 28085 var dimension = this.dimension() 28086 28087 this.$element 28088 .removeClass('collapse') 28089 .addClass('collapsing')[dimension](0) 28090 28091 this.transitioning = 1 28092 28093 var complete = function (e) { 28094 if (e && e.target != this.$element[0]) return 28095 this.$element 28096 .removeClass('collapsing') 28097 .addClass('collapse in')[dimension]('auto') 28098 this.transitioning = 0 28099 this.$element.trigger('shown.bs.collapse') 28100 } 28101 28102 if (!$.support.transition) return complete.call(this) 28103 28104 var scrollSize = $.camelCase(['scroll', dimension].join('-')) 28105 28106 this.$element 28107 .one($.support.transition.end, $.proxy(complete, this)) 28108 .emulateTransitionEnd(350)[dimension](this.$element[0][scrollSize]) 28109 } 28110 28111 Collapse.prototype.hide = function () { 28112 if (this.transitioning || !this.$element.hasClass('in')) return 28113 28114 var startEvent = $.Event('hide.bs.collapse') 28115 this.$element.trigger(startEvent) 28116 if (startEvent.isDefaultPrevented()) return 28117 28118 var dimension = this.dimension() 28119 28120 this.$element[dimension](this.$element[dimension]())[0].offsetHeight 28121 28122 this.$element 28123 .addClass('collapsing') 28124 .removeClass('collapse') 28125 .removeClass('in') 28126 28127 this.transitioning = 1 28128 28129 var complete = function (e) { 28130 if (e && e.target != this.$element[0]) return 28131 this.transitioning = 0 28132 this.$element 28133 .trigger('hidden.bs.collapse') 28134 .removeClass('collapsing') 28135 .addClass('collapse') 28136 } 28137 28138 if (!$.support.transition) return complete.call(this) 28139 28140 this.$element 28141 [dimension](0) 28142 .one($.support.transition.end, $.proxy(complete, this)) 28143 .emulateTransitionEnd(350) 28144 } 28145 28146 Collapse.prototype.toggle = function () { 28147 this[this.$element.hasClass('in') ? 'hide' : 'show']() 28148 } 28149 28150 28151 // COLLAPSE PLUGIN DEFINITION 28152 // ========================== 28153 28154 var old = $.fn.collapse 28155 28156 $.fn.collapse = function (option) { 28157 return this.each(function () { 28158 var $this = $(this) 28159 var data = $this.data('bs.collapse') 28160 var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option) 28161 28162 if (!data && options.toggle && option == 'show') option = !option 28163 if (!data) $this.data('bs.collapse', (data = new Collapse(this, options))) 28164 if (typeof option == 'string') data[option]() 28165 }) 28166 } 28167 28168 $.fn.collapse.Constructor = Collapse 28169 28170 28171 // COLLAPSE NO CONFLICT 28172 // ==================== 28173 28174 $.fn.collapse.noConflict = function () { 28175 $.fn.collapse = old 28176 return this 28177 } 28178 28179 28180 // COLLAPSE DATA-API 28181 // ================= 28182 28183 $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) { 28184 var $this = $(this), href 28185 var target = $this.attr('data-target') 28186 || e.preventDefault() 28187 || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7 28188 //Edited by Uncode to replace ID in panel [START] 28189 var _target = href.replace(/^#/, ""); 28190 if ( $('[data-id="' + _target + '"]').length ) { 28191 var $target = $('[data-id="' + _target + '"]') 28192 } else { 28193 var $target = $(target) 28194 } 28195 //Edited by Uncode to replace ID in panel [END] 28196 var data = $target.data('bs.collapse') 28197 var option = data ? 'toggle' : $this.data() 28198 var parent = $this.attr('data-parent') 28199 var $parent = parent && $(parent) 28200 28201 if (!data || !data.transitioning) { 28202 if ($parent) $parent.find('[data-toggle="collapse"][data-parent="' + parent + '"]').not($this).addClass('collapsed') 28203 $this[$target.hasClass('in') ? 'addClass' : 'removeClass']('collapsed') 28204 } 28205 28206 $target.collapse(option) 28207 }) 28208 28209}(jQuery); 28210 28211/* ======================================================================== 28212 * Bootstrap: tab.js v3.1.1 28213 * http://getbootstrap.com/javascript/#tabs 28214 * ======================================================================== 28215 * Copyright 2011-2014 Twitter, Inc. 28216 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 28217 * ======================================================================== */ 28218 28219 28220+function ($) { 28221 'use strict'; 28222 28223 // TAB CLASS DEFINITION 28224 // ==================== 28225 28226 var Tab = function (element) { 28227 this.element = $(element) 28228 } 28229 28230 Tab.prototype.show = function () { 28231 var $this = this.element 28232 var $ul = $this.closest('ul:not(.dropdown-menu)') 28233 var selector = $this.data('target') 28234 28235 if (!selector) { 28236 selector = $this.attr('href') 28237 selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7 28238 } 28239 28240 if ($this.parent('li').hasClass('active')) return 28241 28242 var previous = $ul.find('.active:last a')[0] 28243 var e = $.Event('show.bs.tab', { 28244 relatedTarget: previous 28245 }) 28246 28247 $this.trigger(e) 28248 28249 if (e.isDefaultPrevented()) return 28250 28251 //Edited by Uncode to replace ID in panel [START] 28252 var _target = selector.replace(/^#/, ""); 28253 if ( $('[data-id="' + _target + '"]').length ) 28254 var $target = $('[data-id="' + _target + '"]') 28255 else 28256 var $target = $(selector) 28257 //Edited by Uncode to replace ID in panel [END] 28258 28259 this.activate($this.parent('li'), $ul) 28260 this.activate($target, $target.parent(), function () { 28261 $this.trigger({ 28262 type: 'shown.bs.tab', 28263 relatedTarget: previous 28264 }) 28265 }) 28266 } 28267 28268 Tab.prototype.activate = function (element, container, callback) { 28269 var $active = container.find('> .active') 28270 var transition = callback 28271 && $.support.transition 28272 && $active.hasClass('fade') 28273 28274 function next() { 28275 $active 28276 .removeClass('active') 28277 .find('> .dropdown-menu > .active') 28278 .removeClass('active') 28279 28280 element.addClass('active') 28281 28282 if (transition) { 28283 element[0].offsetWidth // reflow for transition 28284 element.addClass('in') 28285 } else { 28286 element.removeClass('fade') 28287 } 28288 28289 if (element.parent('.dropdown-menu')) { 28290 element.closest('li.dropdown').addClass('active') 28291 } 28292 28293 callback && callback() 28294 } 28295 28296 transition ? 28297 $active 28298 .one($.support.transition.end, next) 28299 .emulateTransitionEnd(150) : 28300 next() 28301 28302 $active.removeClass('in') 28303 } 28304 28305 28306 // TAB PLUGIN DEFINITION 28307 // ===================== 28308 28309 var old = $.fn.tab 28310 28311 $.fn.tab = function ( option ) { 28312 return this.each(function () { 28313 var $this = $(this) 28314 var data = $this.data('bs.tab') 28315 28316 if (!data) $this.data('bs.tab', (data = new Tab(this))) 28317 if (typeof option == 'string') data[option]() 28318 }) 28319 } 28320 28321 $.fn.tab.Constructor = Tab 28322 28323 28324 // TAB NO CONFLICT 28325 // =============== 28326 28327 $.fn.tab.noConflict = function () { 28328 $.fn.tab = old 28329 return this 28330 } 28331 28332 28333 // TAB DATA-API 28334 // ============ 28335 28336 $(document).on('click.bs.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) { 28337 e.preventDefault() 28338 $(this).tab('show') 28339 }) 28340 28341}(jQuery); 28342 28343/* ======================================================================== 28344 * Bootstrap: tooltip.js v3.1.1 28345 * http://getbootstrap.com/javascript/#tooltip 28346 * Inspired by the original jQuery.tipsy by Jason Frame 28347 * ======================================================================== 28348 * Copyright 2011-2014 Twitter, Inc. 28349 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 28350 * ======================================================================== */ 28351 28352 28353+function ($) { 28354 'use strict'; 28355 28356 // TOOLTIP PUBLIC CLASS DEFINITION 28357 // =============================== 28358 28359 var Tooltip = function (element, options) { 28360 this.type = 28361 this.options = 28362 this.enabled = 28363 this.timeout = 28364 this.hoverState = 28365 this.$element = null 28366 28367 this.init('tooltip', element, options) 28368 } 28369 28370 Tooltip.DEFAULTS = { 28371 animation: true, 28372 placement: 'top', 28373 selector: false, 28374 template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>', 28375 trigger: 'hover focus', 28376 title: '', 28377 delay: 0, 28378 html: false, 28379 container: false, 28380 viewport: { 28381 selector: 'body', 28382 padding: 0 28383 } 28384 } 28385 28386 Tooltip.prototype.init = function (type, element, options) { 28387 this.enabled = true 28388 this.type = type 28389 this.$element = $(element) 28390 this.options = this.getOptions(options) 28391 this.$viewport = this.options.viewport && $(this.options.viewport.selector || this.options.viewport) 28392 28393 var triggers = this.options.trigger.split(' ') 28394 28395 for (var i = triggers.length; i--;) { 28396 var trigger = triggers[i] 28397 28398 if (trigger == 'click') { 28399 this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this)) 28400 } else if (trigger != 'manual') { 28401 var eventIn = trigger == 'hover' ? 'mouseenter' : 'focusin' 28402 var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout' 28403 28404 this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this)) 28405 this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this)) 28406 } 28407 } 28408 28409 this.options.selector ? 28410 (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) : 28411 this.fixTitle() 28412 } 28413 28414 Tooltip.prototype.getDefaults = function () { 28415 return Tooltip.DEFAULTS 28416 } 28417 28418 Tooltip.prototype.getOptions = function (options) { 28419 options = $.extend({}, this.getDefaults(), this.$element.data(), options) 28420 28421 if (options.delay && typeof options.delay == 'number') { 28422 options.delay = { 28423 show: options.delay, 28424 hide: options.delay 28425 } 28426 } 28427 28428 return options 28429 } 28430 28431 Tooltip.prototype.getDelegateOptions = function () { 28432 var options = {} 28433 var defaults = this.getDefaults() 28434 28435 this._options && $.each(this._options, function (key, value) { 28436 if (defaults[key] != value) options[key] = value 28437 }) 28438 28439 return options 28440 } 28441 28442 Tooltip.prototype.enter = function (obj) { 28443 var self = obj instanceof this.constructor ? 28444 obj : $(obj.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type) 28445 28446 clearTimeout(self.timeout) 28447 28448 self.hoverState = 'in' 28449 28450 if (!self.options.delay || !self.options.delay.show) return self.show() 28451 28452 self.timeout = setTimeout(function () { 28453 if (self.hoverState == 'in') self.show() 28454 }, self.options.delay.show) 28455 } 28456 28457 Tooltip.prototype.leave = function (obj) { 28458 var self = obj instanceof this.constructor ? 28459 obj : $(obj.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type) 28460 28461 clearTimeout(self.timeout) 28462 28463 self.hoverState = 'out' 28464 28465 if (!self.options.delay || !self.options.delay.hide) return self.hide() 28466 28467 self.timeout = setTimeout(function () { 28468 if (self.hoverState == 'out') self.hide() 28469 }, self.options.delay.hide) 28470 } 28471 28472 Tooltip.prototype.show = function () { 28473 var e = $.Event('show.bs.' + this.type) 28474 28475 if (this.hasContent() && this.enabled) { 28476 this.$element.trigger(e) 28477 28478 if (e.isDefaultPrevented()) return 28479 var that = this; 28480 28481 var $tip = this.tip() 28482 28483 this.setContent() 28484 28485 if (this.options.animation) $tip.addClass('fade') 28486 28487 var placement = typeof this.options.placement == 'function' ? 28488 this.options.placement.call(this, $tip[0], this.$element[0]) : 28489 this.options.placement 28490 28491 var autoToken = /\s?auto?\s?/i 28492 var autoPlace = autoToken.test(placement) 28493 if (autoPlace) placement = placement.replace(autoToken, '') || 'top' 28494 28495 $tip 28496 .detach() 28497 .css({ top: 0, left: 0, display: 'block' }) 28498 .addClass(placement) 28499 28500 this.options.container ? $tip.appendTo($(document).find(this.options.container)) : $tip.insertAfter(this.$element) 28501 28502 var pos = this.getPosition() 28503 var actualWidth = $tip[0].offsetWidth 28504 var actualHeight = $tip[0].offsetHeight 28505 28506 if (autoPlace) { 28507 var orgPlacement = placement 28508 var $parent = this.$element.parent() 28509 var parentDim = this.getPosition($parent) 28510 28511 placement = placement == 'bottom' && pos.top + pos.height + actualHeight - parentDim.scroll > parentDim.height ? 'top' : 28512 placement == 'top' && pos.top - parentDim.scroll - actualHeight < 0 ? 'bottom' : 28513 placement == 'right' && pos.right + actualWidth > parentDim.width ? 'left' : 28514 placement == 'left' && pos.left - actualWidth < parentDim.left ? 'right' : 28515 placement 28516 28517 $tip 28518 .removeClass(orgPlacement) 28519 .addClass(placement) 28520 } 28521 28522 var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight) 28523 28524 this.applyPlacement(calculatedOffset, placement) 28525 this.hoverState = null 28526 28527 var complete = function() { 28528 that.$element.trigger('shown.bs.' + that.type) 28529 } 28530 28531 $.support.transition && this.$tip.hasClass('fade') ? 28532 $tip 28533 .one($.support.transition.end, complete) 28534 .emulateTransitionEnd(150) : 28535 complete() 28536 } 28537 } 28538 28539 Tooltip.prototype.applyPlacement = function (offset, placement) { 28540 var $tip = this.tip() 28541 var width = $tip[0].offsetWidth 28542 var height = $tip[0].offsetHeight 28543 28544 // manually read margins because getBoundingClientRect includes difference 28545 var marginTop = parseInt($tip.css('margin-top'), 10) 28546 var marginLeft = parseInt($tip.css('margin-left'), 10) 28547 28548 // we must check for NaN for ie 8/9 28549 if (isNaN(marginTop)) marginTop = 0 28550 if (isNaN(marginLeft)) marginLeft = 0 28551 28552 offset.top = offset.top + marginTop 28553 offset.left = offset.left + marginLeft 28554 28555 // $.fn.offset doesn't round pixel values 28556 // so we use setOff
28556set directly with our own function B-0 28557 $.offset.setOffset($tip[0], $.extend({ 28558 using: function (props) { 28559 $tip.css({ 28560 top: Math.round(props.top), 28561 left: Math.round(props.left) 28562 }) 28563 } 28564 }, offset), 0) 28565 28566 $tip.addClass('in') 28567 28568 // check to see if placing tip in new offset caused the tip to resize itself 28569 var actualWidth = $tip[0].offsetWidth 28570 var actualHeight = $tip[0].offsetHeight 28571 28572 if (placement == 'top' && actualHeight != height) { 28573 offset.top = offset.top + height - actualHeight 28574 } 28575 28576 var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight) 28577 28578 if (delta.left) offset.left += delta.left 28579 else offset.top += delta.top 28580 28581 var arrowDelta = delta.left ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight 28582 var arrowPosition = delta.left ? 'left' : 'top' 28583 var arrowOffsetPosition = delta.left ? 'offsetWidth' : 'offsetHeight' 28584 28585 $tip.offset(offset) 28586 this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], arrowPosition) 28587 } 28588 28589 Tooltip.prototype.replaceArrow = function (delta, dimension, position) { 28590 this.arrow().css(position, delta ? (50 * (1 - delta / dimension) + '%') : '') 28591 } 28592 28593 Tooltip.prototype.setContent = function () { 28594 var $tip = this.tip() 28595 var title = this.getTitle() 28596 28597 $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title) 28598 $tip.removeClass('fade in top bottom left right') 28599 } 28600 28601 Tooltip.prototype.hide = function () { 28602 var that = this 28603 var $tip = this.tip() 28604 var e = $.Event('hide.bs.' + this.type) 28605 28606 function complete() { 28607 if (that.hoverState != 'in') $tip.detach() 28608 that.$element.trigger('hidden.bs.' + that.type) 28609 } 28610 28611 this.$element.trigger(e) 28612 28613 if (e.isDefaultPrevented()) return 28614 28615 $tip.removeClass('in') 28616 28617 $.support.transition && this.$tip.hasClass('fade') ? 28618 $tip 28619 .one($.support.transition.end, complete) 28620 .emulateTransitionEnd(150) : 28621 complete() 28622 28623 this.hoverState = null 28624 28625 return this 28626 } 28627 28628 Tooltip.prototype.fixTitle = function () { 28629 var $e = this.$element 28630 if ($e.attr('title') || typeof($e.attr('data-original-title')) != 'string') { 28631 $e.attr('data-original-title', $e.attr('title') || '').attr('title', '') 28632 } 28633 } 28634 28635 Tooltip.prototype.hasContent = function () { 28636 return this.getTitle() 28637 } 28638 28639 Tooltip.prototype.getPosition = function ($element) { 28640 $element = $element || this.$element 28641 var el = $element[0] 28642 var isBody = el.tagName == 'BODY' 28643 return $.extend({}, (typeof el.getBoundingClientRect == 'function') ? el.getBoundingClientRect() : null, { 28644 scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop(), 28645 width: isBody ? $(window).width() : $element.outerWidth(), 28646 height: isBody ? $(window).height() : $element.outerHeight() 28647 }, isBody ? {top: 0, left: 0} : $element.offset()) 28648 } 28649 28650 Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) { 28651 return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } : 28652 placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } : 28653 placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } : 28654 /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width } 28655 28656 } 28657 28658 Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) { 28659 var delta = { top: 0, left: 0 } 28660 if (!this.$viewport) return delta 28661 28662 var viewportPadding = this.options.viewport && this.options.viewport.padding || 0 28663 var viewportDimensions = this.getPosition(this.$viewport) 28664 28665 if (/right|left/.test(placement)) { 28666 var topEdgeOffset = pos.top - viewportPadding - viewportDimensions.scroll 28667 var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight 28668 if (topEdgeOffset < viewportDimensions.top) { // top overflow 28669 delta.top = viewportDimensions.top - topEdgeOffset 28670 } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow 28671 delta.top = viewportDimensions.top + viewportDimensions.height - bottom
28671EdgeOffset 28672 } 28673 } else { 28674 var leftEdgeOffset = pos.left - viewportPadding 28675 var rightEdgeOffset = pos.left + viewportPadding + actualWidth 28676 if (leftEdgeOffset < viewportDimensions.left) { // left overflow 28677 delta.left = viewportDimensions.left - leftEdgeOffset 28678 } else if (rightEdgeOffset > viewportDimensions.width) { // right overflow 28679 delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset 28680 } 28681 } 28682 28683 return delta 28684 } 28685 28686 Tooltip.prototype.getTitle = function () { 28687 var title 28688 var $e = this.$element 28689 var o = this.options 28690 28691 title = $e.attr('data-original-title') 28692 || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title) 28693 28694 return title 28695 } 28696 28697 Tooltip.prototype.tip = function () { 28698 return this.$tip = this.$tip || $(this.options.template) 28699 } 28700 28701 Tooltip.prototype.arrow = function () { 28702 return this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow') 28703 } 28704 28705 Tooltip.prototype.validate = function () { 28706 if (!this.$element[0].parentNode) { 28707 this.hide() 28708 this.$element = null 28709 this.options = null 28710 } 28711 } 28712 28713 Tooltip.prototype.enable = function () { 28714 this.enabled = true 28715 } 28716 28717 Tooltip.prototype.disable = function () { 28718 this.enabled = false 28719 } 28720 28721 Tooltip.prototype.toggleEnabled = function () { 28722 this.enabled = !this.enabled 28723 } 28724 28725 Tooltip.prototype.toggle = function (e) { 28726 var self = e ? $(e.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type) : this 28727 self.tip().hasClass('in') ? self.leave(self) : self.enter(self) 28728 } 28729 28730 Tooltip.prototype.destroy = function () { 28731 clearTimeout(this.timeout) 28732 this.hide().$element.off('.' + this.type).removeData('bs.' + this.type) 28733 } 28734 28735 28736 // TOOLTIP PLUGIN DEFINITION 28737 // ========================= 28738 28739 var old = $.fn.tooltip 28740 28741 $.fn.tooltip = function (option) { 28742 return this.each(function () { 28743 var $this = $(this) 28744 var data = $this.data('bs.tooltip') 28745 var options = typeof option == 'object' && option 28746 28747 if (!data && option == 'destroy') return 28748 if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options))) 28749 if (typeof option == 'string') data[option]() 28750 }) 28751 } 28752 28753 $.fn.tooltip.Constructor = Tooltip 28754 28755 28756 // TOOLTIP NO CONFLICT 28757 // =================== 28758 28759 $.fn.tooltip.noConflict = function () { 28760 $.fn.tooltip = old 28761 return this 28762 } 28763 28764}(jQuery); 28765 28766/* ======================================================================== 28767 * Bootstrap: transition.js v3.1.1 28768 * http://getbootstrap.com/javascript/#transitions 28769 * ======================================================================== 28770 * Copyright 2011-2014 Twitter, Inc. 28771 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 28772 * ======================================================================== */ 28773 28774 28775+function ($) { 28776 'use strict'; 28777 28778 // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/) 28779 // ============================================================ 28780 28781 function transitionEnd() { 28782 var el = document.createElement('bootstrap') 28783 28784 var transEndEventNames = { 28785 WebkitTransition : 'webkitTransitionEnd', 28786 MozTransition : 'transitionend', 28787 OTransition : 'oTransitionEnd otransitionend', 28788 transition : 'transitionend' 28789 } 28790 28791 for (var name in transEndEventNames) { 28792 if (el.style[name] !== undefined) { 28793 return { end: transEndEventNames[name] } 28794 } 28795 } 28796 28797 return false // explicit for ie8 ( ._.) 28798 } 28799 28800 // http://blog.alexmaccaw.com/css-transitions 28801 $.fn.emulateTransitionEnd = function (duration) { 28802 var called = false, $el = this 28803 $(this).one($.support.transition.end, function () { called = true }) 28804 var callback = function () { if (!called) $($el).trigger($.support.transition.end) } 28805 setTimeout(callback, duration) 28806 return this 28807 } 28808 28809 $(function () { 28810 $.support.transition = transitionEnd() 28811 }) 28812 28813}(jQuery); 28814 28815 28816// ------------------------------------------ 28817// Rellax.js 28818// Buttery smooth parallax library 28819// Copyright (c) 2016 Moe Amaya (@moeamaya) 28820// MIT license 28821// 28822// Thanks to Paraxify.js and Jaime Cabllero 28823// for parallax concepts 28824// ------------------------------------------ 28825 28826(function (root, factory) { 28827 if (typeof define === 'function' && define.amd) { 28828 // AMD. Register as an anonymous module. 28829 define([], factory); 28830 } else if (typeof module === 'object' && module.exports) { 28831 // Node. Does not work with strict CommonJS, but 28832 // only CommonJS-like environments that support module.exports, 28833 // like Node. 28834 module.exports = factory(); 28835 } else { 28836 // Browser globals (root is window) 28837 root.Rellax = factory(); 28838 } 28839}(typeof window !== "undefined" ? window : global, function () { 28840 var Rellax = function(el, options){ 28841 "use strict"; 28842 28843 var self = Object.create(Rellax.prototype); 28844 28845 var posY = 0; 28846 var screenY = 0; 28847 var posX = 0; 28848 var screenX = 0; 28849 var blocks = []; 28850 var pause = true; 28851 28852 // check what requestAnimationFrame to use, and if 28853 // it's not supported, use the onscroll event 28854 var loop = window.requestAnimationFrame || 28855 window.webkitRequestAnimationFrame || 28856 window.mozRequestAnimationFrame || 28857 window.msRequestAnimationFrame || 28858 window.oRequestAnimationFrame || 28859 function(callback){ return setTimeout(callback, 1000 / 60); }; 28860 28861 // store the id for later use 28862 var loopId = null; 28863 28864 // Test via a getter in the options object to see if the passive property is accessed 28865 var supportsPassive = false;
vendor: 16,286 bytes, lines 28866-29311
28866 try { 28867 var opts = Object.defineProperty({}, 'passive', { 28868 get: function() { 28869 supportsPassive = true; 28870 } 28871 }); 28872 window.addEventListener("testPassive", null, opts); 28873 window.removeEventListener("testPassive", null, opts); 28874 } catch (e) {} 28875 28876 // check what cancelAnimation method to use 28877 var clearLoop = window.cancelAnimationFrame || window.mozCancelAnimationFrame || clearTimeout; 28878 28879 // check which transform property to use 28880 var transformProp = window.transformProp || (function(){ 28881 var testEl = document.createElement('div'); 28882 if (testEl.style.transform === null) { 28883 var vendors = ['Webkit', 'Moz', 'ms']; 28884 for (var vendor in vendors) { 28885 if (testEl.style[ vendors[vendor] + 'Transform' ] !== undefined) { 28886 return vendors[vendor] + 'Transform'; 28887 } 28888 } 28889 } 28890 return 'transform'; 28891 })(); 28892 28893 // Default Settings 28894 self.options = { 28895 speed: -2, 28896 verticalSpeed: null, 28897 horizontalSpeed: null, 28898 breakpoints: [576, 768, 1201], 28899 center: false, 28900 wrapper: null, 28901 relativeToWrapper: false, 28902 round: true, 28903 vertical: true, 28904 horizontal: false, 28905 verticalScrollAxis: "y", 28906 horizontalScrollAxis: "x", 28907 callback: function() {}, 28908 }; 28909 28910 // User defined options (might have more in the future) 28911 if (options){ 28912 Object.keys(options).forEach(function(key){ 28913 self.options[key] = options[key]; 28914 }); 28915 } 28916 28917 function validateCustomBreakpoints () { 28918 if (self.options.breakpoints.length === 3 && Array.isArray(self.options.breakpoints)) { 28919 var isAscending = true; 28920 var isNumerical = true; 28921 var lastVal; 28922 self.options.breakpoints.forEach(function (i) { 28923 if (typeof i !== 'number') isNumerical = false; 28924 if (lastVal !== null) { 28925 if (i < lastVal) isAscending = false; 28926 } 28927 lastVal = i; 28928 }); 28929 if (isAscending && isNumerical) return; 28930 } 28931 // revert defaults if set incorrectly 28932 self.options.breakpoints = [576, 768, 1201]; 28933 console.warn("Rellax: You must pass an array of 3 numbers in ascending order to the breakpoints option. Defaults reverted"); 28934 } 28935 28936 if (options && options.breakpoints) { 28937 validateCustomBreakpoints(); 28938 } 28939 28940 // By default, rellax class 28941 if (!el) { 28942 el = '.rellax'; 28943 } 28944 28945 // check if el is a className or a node 28946 var elements = typeof el === 'string' ? document.querySelectorAll(el) : [el]; 28947 28948 // Now query selector 28949 if (elements.length > 0) { 28950 self.elems = elements; 28951 } 28952 28953 // The elements don't exist 28954 else { 28955 console.warn("Rellax: The elements you're trying to select don't exist."); 28956 return; 28957 } 28958 28959 // Has a wrapper and it exists 28960 if (self.options.wrapper) { 28961 if (!self.options.wrapper.nodeType) { 28962 var wrapper = document.querySelector(self.options.wrapper); 28963 28964 if (wrapper) { 28965 self.options.wrapper = wrapper; 28966 } else { 28967 console.warn("Rellax: The wrapper you're trying to use doesn't exist."); 28968 return; 28969 } 28970 } 28971 } 28972 28973 // set a placeholder for the current breakpoint 28974 var currentBreakpoint; 28975 28976 // helper to determine current breakpoint 28977 var getCurrentBreakpoint = function (w) { 28978 var bp = self.options.breakpoints; 28979 if (w < bp[0]) return 'xs'; 28980 if (w >= bp[0] && w < bp[1]) return 'sm'; 28981 if (w >= bp[1] && w < bp[2]) return 'md'; 28982 return 'lg'; 28983 }; 28984 28985 // Get and cache initial position of all elements 28986 var cacheBlocks = function() { 28987 for (var i = 0; i < self.elems.length; i++){ 28988 var block = createBlock(self.elems[i]); 28989 blocks.push(block); 28990 } 28991 }; 28992 28993 28994 // Let's kick this script off 28995 // Build array for cached element values 28996 var init = function() { 28997 for (var i = 0; i < blocks.length; i++){ 28998 self.elems[i].style.cssText = blocks[i].style; 28999 } 29000 29001 blocks = []; 29002 29003 screenY = window.innerHeight; 29004 screenX = window.innerWidth; 29005 currentBreakpoint = getCurrentBreakpoint(screenX); 29006 29007 setPosition(); 29008 29009 cacheBlocks(); 29010 29011 animate(); 29012 29013 // If paused, unpause and set listener for window resizing events 29014 if (pause) { 29015 window.addEventListener('resize', init); 29016 pause = false; 29017 // Start the loop 29018 update(); 29019 } 29020 }; 29021 29022 // We want to cache the parallax blocks' 29023 // values: base, top, height, speed 29024 // el: is dom object, return: el cache values 29025 var createBlock = function(el) { 29026 var dataPercentage = el.getAttribute( 'data-rellax-percentage' ); 29027 var dataSpeed = el.getAttribute( 'data-rellax-speed' ); 29028 var dataXsSpeed = el.getAttribute( 'data-rellax-xs-speed' ); 29029 var dataMobileSpeed = el.getAttribute( 'data-rellax-mobile-speed' ); 29030 var dataTabletSpeed = el.getAttribute( 'data-rellax-tablet-speed' ); 29031 var dataDesktopSpeed = el.getAttribute( 'data-rellax-desktop-speed' ); 29032 var dataVerticalSpeed = el.getAttribute('data-rellax-vertical-speed'); 29033 var dataHorizontalSpeed = el.getAttribute('data-rellax-horizontal-speed'); 29034 var dataVericalScrollAxis = el.getAttribute('data-rellax-vertical-scroll-axis'); 29035 var dataHorizontalScrollAxis = el.getAttribute('data-rellax-horizontal-scroll-axis'); 29036 var dataZindex = el.getAttribute( 'data-rellax-zindex' ) || 0; 29037 var dataMin = el.getAttribute( 'data-rellax-min' ); 29038 var dataMax = el.getAttribute( 'data-rellax-max' ); 29039 var dataMinX = el.getAttribute('data-rellax-min-x'); 29040 var dataMaxX = el.getAttribute('data-rellax-max-x'); 29041 var dataMinY = el.getAttribute('data-rellax-min-y'); 29042 var dataMaxY = el.getAttribute('data-rellax-max-y'); 29043 var mapBreakpoints; 29044 var breakpoints = true; 29045 29046 if (!dataXsSpeed && !dataMobileSpeed && !dataTabletSpeed && !dataDesktopSpeed) { 29047 breakpoints = false; 29048 } else { 29049 mapBreakpoints = { 29050 'xs': dataXsSpeed, 29051 'sm': dataMobileSpeed, 29052 'md': dataTabletSpeed, 29053 'lg': dataDesktopSpeed 29054 }; 29055 } 29056 29057 // initializing at scrollY = 0 (top of browser), scrollX = 0 (left of browser) 29058 // ensures elements are positioned based on HTML layout. 29059 // 29060 // If the element has the percentage attribute, the posY and posX needs to be 29061 // the current scroll position's value, so that the elements are still positioned based on HTML layout 29062 var wrapperPosY = self.options.wrapper ? self.options.wrapper.scrollTop : (window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop); 29063 // If the option relativeToWrapper is true, use the wrappers offset to top, subtracted from the current page scroll. 29064 if (self.options.relativeToWrapper) { 29065 var scrollPosY = (window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop); 29066 wrapperPosY = scrollPosY - self.options.wrapper.offsetTop; 29067 } 29068 var posY = self.options.vertical ? ( dataPercentage || self.options.center ? wrapperPosY : 0 ) : 0; 29069 var posX = self.options.horizontal ? ( dataPercentage || self.options.center ? self.options.wrapper ? self.options.wrapper.scrollLeft : (window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft) : 0 ) : 0; 29070 29071 var blockTop = posY + el.getBoundingClientRect().top; 29072 var blockHeight = el.clientHeight || el.offsetHeight || el.scrollHeight; 29073 29074 var blockLeft = posX + el.getBoundingClientRect().left; 29075 var blockWidth = el.clientWidth || el.offsetWidth || el.scrollWidth; 29076 29077 // apparently parallax equation everyone uses 29078 var percentageY = dataPercentage ? dataPercentage : (posY - blockTop + screenY) / (blockHeight + screenY); 29079 var percentageX = dataPercentage ? dataPercentage : (posX - blockLeft + screenX) / (blockWidth + screenX); 29080 if(self.options.center){ percentageX = 0.5; percentageY = 0.5; } 29081 29082 // Optional individual block speed as data attr, otherwise global speed 29083 var speed = (breakpoints && mapBreakpoints[currentBreakpoint] !== null) ? Number(mapBreakpoints[currentBreakpoint]) : (dataSpeed ? dataSpeed : self.options.speed); 29084 var verticalSpeed = dataVerticalSpeed ? dataVerticalSpeed : self.options.verticalSpeed; 29085 var horizontalSpeed = dataHorizontalSpeed ? dataHorizontalSpeed : self.options.horizontalSpeed; 29086 29087 // Optional individual block movement axis direction as data attr, otherwise global movement direction 29088 var verticalScrollAxis = dataVericalScrollAxis ? dataVericalScrollAxis : self.options.verticalScrollAxis; 29089 var horizontalScrollAxis = dataHorizontalScrollAxis ? dataHorizontalScrollAxis : self.options.horizontalScrollAxis; 29090 29091 var bases = updatePosition(percentageX, percentageY, speed, verticalSpeed, horizontalSpeed); 29092 29093 // ~~Store non-translate3d transforms~~ 29094 // Store inline styles and extract transforms 29095 var style = el.style.cssText; 29096 var transform = ''; 29097 29098 // Check if there's an inline styled transform 29099 var searchResult = /transform\s*:/i.exec(style); 29100 if (searchResult) { 29101 // Get the index of the transform 29102 var index = searchResult.index; 29103 29104 // Trim the style to the transform point and get the following semi-colon index 29105 var trimmedStyle = style.slice(index); 29106 var delimiter = trimmedStyle.indexOf(';'); 29107 29108 // Remove "transform" string and save the attribute 29109 if (delimiter) { 29110 transform = " " + trimmedStyle.slice(11, delimiter).replace(/\s/g,''); 29111 } else { 29112 transform = " " + trimmedStyle.slice(11).replace(/\s/g,''); 29113 } 29114 } 29115 29116 return { 29117 baseX: bases.x, 29118 baseY: bases.y, 29119 top: blockTop, 29120 left: blockLeft, 29121 height: blockHeight, 29122 width: blockWidth, 29123 speed: speed, 29124 verticalSpeed: verticalSpeed, 29125 horizontalSpeed: horizontalSpeed, 29126 verticalScrollAxis: verticalScrollAxis, 29127 horizontalScrollAxis: horizontalScrollAxis, 29128 style: style, 29129 transform: transform, 29130 zindex: dataZindex, 29131 min: dataMin, 29132 max: dataMax, 29133 minX: dataMinX, 29134 maxX: dataMaxX, 29135 minY: dataMinY, 29136 maxY: dataMaxY 29137 }; 29138 }; 29139 29140 // set scroll position (posY, posX) 29141 // side effect method is not ideal, but okay for now 29142 // returns true if the scroll changed, false if nothing happened 29143 var setPosition = function() { 29144 var oldY = posY; 29145 var oldX = posX; 29146 29147 posY = self.options.wrapper ? self.options.wrapper.scrollTop : (document.documentElement || document.body.parentNode || document.body).scrollTop || window.pageYOffset; 29148 posX = self.options.wrapper ? self.options.wrapper.scrollLeft : (document.documentElement || document.body.parentNode || document.body).scrollLeft || window.pageXOffset; 29149 // If option relativeToWrapper is true, use relative wrapper value instead. 29150 if (self.options.relativeToWrapper) { 29151 var scrollPosY = (document.documentElement || document.body.parentNode || document.body).scrollTop || window.pageYOffset; 29152 posY = scrollPosY - self.options.wrapper.offsetTop; 29153 } 29154 29155 29156 if (oldY != posY && self.options.vertical) { 29157 // scroll changed, return true 29158 return true; 29159 } 29160 29161 if (oldX != posX && self.options.horizontal) { 29162 // scroll changed, return true 29163 return true; 29164 } 29165 29166 // scroll did not change 29167 return false; 29168 }; 29169 29170 // Ahh a pure function, gets new transform value 29171 // based on scrollPosition and speed 29172 // Allow for decimal pixel values 29173 var updatePosition = function(percentageX, percentageY, speed, verticalSpeed, horizontalSpeed) { 29174 var result = {}; 29175 var valueX = ((horizontalSpeed ? horizontalSpeed : speed) * (100 * (1 - percentageX))); 29176 var valueY = ((verticalSpeed ? verticalSpeed : speed) * (100 * (1 - percentageY))); 29177 29178 result.x = self.options.round ? Math.round(valueX) : Math.round(valueX * 100) / 100; 29179 result.y = self.options.round ? Math.round(valueY) : Math.round(valueY * 100) / 100; 29180 29181 return result; 29182 }; 29183 29184 // Remove event listeners and loop again 29185 var deferredUpdate = function() { 29186 window.removeEventListener('resize', deferredUpdate); 29187 window.removeEventListener('orientationchange', deferredUpdate); 29188 (self.options.wrapper ? self.options.wrapper : window).removeEventListener('scroll', deferredUpdate); 29189 (self.options.wrapper ? self.options.wrapper : document).removeEventListener('touchmove', deferredUpdate); 29190 29191 // loop again 29192 loopId = loop(update); 29193 }; 29194 29195 // Loop 29196 var update = function() { 29197 if (setPosition() && pause === false) { 29198 animate(); 29199 29200 // loop again 29201 loopId = loop(update); 29202 } else { 29203 loopId = null; 29204 29205 // Don't animate until we get a position updating event 29206 window.addEventListener('resize', deferredUpdate); 29207 window.addEventListener('orientationchange', deferredUpdate); 29208 (self.options.wrapper ? self.options.wrapper : window).addEventListener('scroll', deferredUpdate, supportsPassive ? { passive: true } : false); 29209 (self.options.wrapper ? self.options.wrapper : document).addEventListener('touchmove', deferredUpdate, supportsPassive ? { passive: true } : false); 29210 } 29211 }; 29212 29213 // Transform3d on parallax element 29214 var animate = function() { 29215 var positions; 29216 for (var i = 0; i < self.elems.length; i++){ 29217 // Determine relevant movement directions 29218 var verticalScrollAxis = blocks[i].verticalScrollAxis.toLowerCase(); 29219 var horizontalScrollAxis = blocks[i].horizontalScrollAxis.toLowerCase(); 29220 var verticalScrollX = verticalScrollAxis.indexOf("x") != -1 ? posY : 0; 29221 var verticalScrollY = verticalScrollAxis.indexOf("y") != -1 ? posY : 0; 29222 var horizontalScrollX = horizontalScrollAxis.indexOf("x") != -1 ? posX : 0; 29223 var horizontalScrollY = horizontalScrollAxis.indexOf("y") != -1 ? posX : 0; 29224 29225 var percentageY = ((verticalScrollY + horizontalScrollY - blocks[i].top + screenY) / (blocks[i].height + screenY)); 29226 var percentageX = ((verticalScrollX + horizontalScrollX - blocks[i].left + screenX) / (blocks[i].width + screenX)); 29227 29228 // Subtracting initialize value, so element stays in same spot as HTML 29229 positions = updatePosition(percentageX, percentageY, blocks[i].speed, blocks[i].verticalSpeed, blocks[i].horizontalSpeed); 29230 var positionY = positions.y - blocks[i].baseY; 29231 var positionX = positions.x - blocks[i].baseX; 29232 29233 // The next two "if" blocks go like this: 29234 // Check if a limit is defined (first "min", then "max"); 29235 // Check if we need to change the Y or the X 29236 // (Currently working only if just one of the axes is enabled) 29237 // Then, check if the new position is inside the allowed limit 29238 // If so, use new position. If not, set position to limit. 29239 29240 // Check if a min limit is defined 29241 if (blocks[i].min !== null) { 29242 if (self.options.vertical && !self.options.horizontal) { 29243 positionY = positionY <= blocks[i].min ? blocks[i].min : positionY; 29244 } 29245 if (self.options.horizontal && !self.options.vertical) { 29246 positionX = positionX <= blocks[i].min ? blocks[i].min : positionX; 29247 } 29248 } 29249 29250 // Check if directional min limits are defined 29251 if (blocks[i].minY != null) { 29252 positionY = positionY <= blocks[i].minY ? blocks[i].minY : positionY; 29253 } 29254 if (blocks[i].minX != null) { 29255 positionX = positionX <= blocks[i].minX ? blocks[i].minX : positionX; 29256 } 29257 29258 // Check if a max limit is defined 29259 if (blocks[i].max !== null) { 29260 if (self.options.vertical && !self.options.horizontal) { 29261 positionY = positionY >= blocks[i].max ? blocks[i].max : positionY; 29262 } 29263 if (self.options.horizontal && !self.options.vertical) { 29264 positionX = positionX >= blocks[i].max ? blocks[i].max : positionX; 29265 } 29266 } 29267 29268 // Check if directional max limits are defined 29269 if (blocks[i].maxY != null) { 29270 positionY = positionY >= blocks[i].maxY ? blocks[i].maxY : positionY; 29271 } 29272 if (blocks[i].maxX != null) { 29273 positionX = positionX >= blocks[i].maxX ? blocks[i].maxX : positionX; 29274 } 29275 29276 var zindex = blocks[i].zindex; 29277 29278 // Move that element 29279 // (Set the new translation and append initial inline transforms.) 29280 var translate = 'translate3d(' + (self.options.horizontal ? positionX : '0') + 'px,' + (self.options.vertical ? positionY : '0') + 'px,' + zindex + 'px) ' + blocks[i].transform; 29281 self.elems[i].style[transformProp] = translate; 29282 } 29283 self.options.callback(positions); 29284 }; 29285 29286 self.destroy = function() { 29287 for (var i = 0; i < self.elems.length; i++){ 29288 self.elems[i].style.cssText = blocks[i].style; 29289 } 29290 29291 // Remove resize event listener if not pause, and pause 29292 if (!pause) { 29293 window.removeEventListener('resize', init); 29294 pause = true; 29295 } 29296 29297 // Clear the animation loop to prevent possible memory leak 29298 clearLoop(loopId); 29299 loopId = null; 29300 }; 29301 29302 // Init 29303 init(); 29304 29305 // Allow to recalculate the initial values whenever we want 29306 self.refresh = init; 29307 29308 return self; 29309 }; 29310 return Rellax; 29311}));
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.