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 && !$('body').hasClass('vmenu')) { 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|pen)$/.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.closest('.grid-filters').length ) { 12370 if ( $sub.closest('.text-right').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: false, //'10em', // min-width for the sub menus (any CSS unit) - if set, the fixed width set in CSS will be ignored 12722 subMenusMaxWidth: false, //'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 history.replaceState({}, document.title, window.location.pathname + window.location.search); 15585 15586 // Restore the scroll offset, should be flicker free 15587 window.scrollTo(scroll.x, scroll.y); 15588 } 15589 15590 /** 15591 * Do the ajax requests with callback. 15592 * 15593 * @param {String} url 15594 * @param {Function} callback 15595 * 15596 * @return {Void} 15597 */ 15598 function doAjax(url, callback) { 15599 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'); 15600 $.ajax({ 15601 url: url, 15602 dataType: 'jsonp' 15603 }); 15604 15605 iLCallback = function(data) { 15606 callback.call(this, data); 15607 }; 15608 } 15609 15610 /** 15611 * Find image from DOM elements 15612 * 15613 * @param {Element} element 15614 * 15615 * @return {Void} 15616 */ 15617 function findImageInElement(element) { 15618 var elements = $('*', element), 15619 imagesArr = new Array(); 15620 15621 elements.each(function() { 15622 var url = "", 15623 element = this; 15624 15625 if ($(element).css("background-image") != "none") { 15626 url = $(element).css("background-image"); 15627 } else if (typeof($(element).attr("src")) != "undefined" && element.nodeName.toLowerCase() == "img") { 15628 url = $(element).attr("src"); 15629 } 15630 15631 if (url.indexOf("gradient") == -1) { 15632 url = url.replace(/url\(\"/g, ""); 15633 url = url.replace(/url\(/g, ""); 15634 url = url.replace(/\"\)/g, ""); 15635 url = url.replace(/\)/g, ""); 15636 15637 var urls = url.split(","); 15638 15639 for (var i = 0; i < urls.length; i++) { 15640 if (urls[i].length > 0 && $.inArray(urls[i], imagesArr) == -1) { 15641 var extra = ""; 15642 if (browser.msie && browser.version < 9) { 15643 extra = "?" + floor(random() * 3000); 15644 } 15645 imagesArr.push(urls[i] + extra); 15646 } 15647 } 15648 } 15649 }); 15650 15651 return imagesArr; 15652 } 15653 15654 /** 15655 * Get file extension. 15656 * 15657 * @param {String} URL 15658 * 15659 * @return {String} 15660 */ 15661 function getExtension(URL) { 15662 if (URL !== null) { 15663 //UNCODE: fix issue to detect media type with query strings 15664 var ext = URL.indexOf('?') !== -1 ? URL.split('?')[0] : URL; 15665 ext = ext.split('.').pop().toLowerCase(); 15666 15667 return ext; 15668 } 15669 } 15670 15671 /** 15672 * Get type via extension. 15673 * 15674 * @param {String} URL 15675 * 15676 * @return {String} 15677 */ 15678 function getTypeByExtension(URL) { 15679 var type, 15680 ext = getExtension(URL); 15681 15682 //Uncode addition ##START## 15683 if (URL == undefined) { 15684 return false; 15685 } 15686 //Uncode addition ##END## 15687 15688 if (extensions.image.indexOf(ext) !== -1) type = 'image'; 15689 else if (extensions.flash.indexOf(ext) !== -1) type = 'flash'; 15690 else if (extensions.video.indexOf(ext) !== -1) type = 'video'; 15691 else if (ext.substring(0, 1) == "#") type = 'inline'; //Uncode addition 15692 else type = 'iframe'; 15693 15694 return type; 15695 } 15696 15697 /** 15698 * Return value from percent of a number. 15699 * 15700 * @param {Number} percent 15701 * @param {Number} total 15702 * 15703 * @return {Number} 15704 */ 15705 function percentToValue(percent, total) { 15706 return parseInt((total / 100) * percent); 15707 } 15708 15709 /** 15710 * A JavaScript equivalent of PHPâs parse_url. 15711 * 15712 * @param {String} url The URL to parse. 15713 * 15714 * @return {Mixed} 15715 */ 15716 function parseURI(url) { 15717 var m = String(url).replace(/^\s+|\s+$/g, '').match(/^([^:\/?#]+:)?(\/\/(?:[^:@]*(?::[^:@]*)?@)?(([^:\/?#]*)(?::(\d*))?))?([^?#]*)(\?[^#]*)?(#[\s\S]*)?/); 15718 // authority = '//' + user + ':' + pass '@' + hostname + ':' port 15719 return (m ? { 15720 href: m[0] || '', 15721 protocol: m[1] || '', 15722 authority: m[2] || '', 15723 host: m[3] || '', 15724 hostname: m[4] || '', 15725 port: m[5] || '', 15726 pathname: m[6] || '', 15727 search: m[7] || '', 15728 hash: m[8] || '' 15729 } : null); 15730 } 15731 15732 /** 15733 * Gets the absolute URI. 15734 * 15735 * @param {String} href The relative URL. 15736 * @param {String} base The base URL. 15737 * 15738 * @return {String} The absolute URL. 15739 */ 15740 function absolutizeURI(base, href) { // RFC 3986 15741 var iL = this; 15742 15743 function removeDotSegments(input) { 15744 var output = []; 15745 input.replace(/^(\.\.?(\/|$))+/, '') 15746 .replace(/\/(\.(\/|$))+/g, '/') 15747 .replace(/\/\.\.$/, '/../') 15748 .replace(/\/?[^\/]*/g, function(p) { 15749 if (p === '/..') { 15750 output.pop(); 15751 } else { 15752 output.push(p); 15753 } 15754 }); 15755 return output.join('').replace(/^\//, input.charAt(0) === '/' ? '/' : ''); 15756 } 15757 15758 href = parseURI(href || ''); 15759 base = parseURI(base || ''); 15760 15761 return !href || !base ? null : (href.protocol || base.protocol) + 15762 (href.protocol || href.authority ? href.authority : base.authority) + 15763 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)) + 15764 (href.protocol || href.authority || href.pathname ? href.search : (href.search || base.search)) + 15765 href.hash; 15766 } 15767 15768 /** 15769 * A JavaScript equivalent of PHPâs version_compare. 15770 * 15771 * @param {String} v1 15772 * @param {String} v2 15773 * @param {String} operator
15774 * 15775 * @return {Boolean} 15776 */ 15777 function version_compare(v1, v2, operator) { 15778 this.php_js = this.php_js || {}; 15779 this.php_js.ENV = this.php_js.ENV || {}; 15780 var i = 0, 15781 x = 0, 15782 compare = 0, 15783 vm = { 15784 'dev': -6, 15785 'alpha': -5, 15786 'a': -5, 15787 'beta': -4, 15788 'b': -4, 15789 'RC': -3, 15790 'rc': -3, 15791 '#': -2, 15792 'p': 1, 15793 'pl': 1 15794 }, 15795 prepVersion = function(v) { 15796 v = ('' + v).replace(/[_\-+]/g, '.'); 15797 v = v.replace(/([^.\d]+)/g, '.$1.').replace(/\.{2,}/g, '.'); 15798 return (!v.length ? [-8] : v.split('.')); 15799 }, 15800 numVersion = function(v) { 15801 return !v ? 0 : (isNaN(v) ? vm[v] || -7 : parseInt(v, 10)); 15802 }; 15803 v1 = prepVersion(v1); 15804 v2 = prepVersion(v2); 15805 x = max(v1.length, v2.length); 15806 for (i = 0; i < x; i++) { 15807 if (v1[i] == v2[i]) { 15808 continue; 15809 } 15810 v1[i] = numVersion(v1[i]); 15811 v2[i] = numVersion(v2[i]); 15812 if (v1[i] < v2[i]) { 15813 compare = -1; 15814 break; 15815 } else if (v1[i] > v2[i]) { 15816 compare = 1; 15817 break; 15818 } 15819 } 15820 if (!operator) { 15821 return compare; 15822 } 15823 15824 switch (operator) { 15825 case '>': 15826 case 'gt': 15827 return (compare > 0); 15828 case '>=': 15829 case 'ge': 15830 return (compare >= 0); 15831 case '<=': 15832 case 'le': 15833 return (compare <= 0); 15834 case '==': 15835 case '=': 15836 case 'eq': 15837 return (compare === 0); 15838 case '<>': 15839 case '!=': 15840 case 'ne': 15841 return (compare !== 0); 15842 case '': 15843 case '<': 15844 case 'lt': 15845 return (compare < 0); 15846 default: 15847 return null; 15848 } 15849 } 15850 15851 15852 // Begin the iLightBox plugin 15853 $.fn.iLightBox = function() { 15854 15855 var args = arguments, 15856 opt = ($.isPlainObject(args[0])) ? args[0] : args[1], 15857 items = ($.isArray(args[0]) || typeof args[0] == 'string') ? args[0] : args[1]; 15858 15859 if (!opt) opt = {}; 15860 15861 // Default options. Play carefully. 15862 var options = $.extend(true, { 15863 attr: 'href', 15864 path: 'vertical', 15865 skin: 'dark', 15866 linkId: false, 15867 infinite: false, 15868 startFrom: 0, 15869 randomStart: false, 15870 keepAspectRatio: true, 15871 maxScale: 1, 15872 minScale: .2, 15873 innerToolbar: false, 15874 smartRecognition: false, 15875 mobileOptimizer: true, 15876 fullAlone: true, 15877 fullViewPort: null, 15878 fullStretchTypes: 'flash, video', 15879 overlay: { 15880 blur: true, 15881 opacity: .85 15882 }, 15883 controls: { 15884 arrows: false, 15885 slideshow: false, 15886 toolbar: true, 15887 fullscreen: true, 15888 thumbnail: true, 15889 keyboard: true, 15890 mousewheel: true, 15891 swipe: true 15892 }, 15893 keyboard: { 15894 left: true, // previous 15895 right: true, // next 15896 up: true, // previous 15897 down: true, // next 15898 esc: true, // close 15899 shift_enter: true // fullscreen 15900 }, 15901 show: { 15902 effect: true, 15903 speed: 300, 15904 title: true 15905 }, 15906 hide: { 15907 effect: true, 15908 speed: 300 15909 }, 15910 caption: { 15911 start: true, 15912 show: 'mouseenter', 15913 hide: 'mouseleave' 15914 }, 15915 social: { 15916 start: true, 15917 show: 'mouseenter', 15918 hide: 'mouseleave',
15919 buttons: false 15920 }, 15921 styles: { 15922 pageOffsetX: 0, 15923 pageOffsetY: 0, 15924 nextOffsetX: 45, 15925 nextOffsetY: 0, 15926 nextOpacity: 1, 15927 nextScale: 1, 15928 prevOffsetX: 45, 15929 prevOffsetY: 0, 15930 prevOpacity: 1, 15931 prevScale: 1 15932 }, 15933 thumbnails: { 15934 maxWidth: 120, 15935 maxHeight: 80, 15936 normalOpacity: 1, 15937 activeOpacity: .6 15938 }, 15939 effects: { 15940 reposition: true, 15941 repositionSpeed: 200, 15942 switchSpeed: 500, 15943 loadedFadeSpeed: 180, 15944 fadeSpeed: 200 15945 }, 15946 slideshow: { 15947 pauseTime: 5000, 15948 pauseOnHover: false, 15949 startPaused: true 15950 }, 15951 text: { 15952 close: "Press Esc to close", 15953 enterFullscreen: "Enter Fullscreen (Shift+Enter)", 15954 exitFullscreen: "Exit Fullscreen (Shift+Enter)", 15955 slideShow: "Slideshow", 15956 next: "Next", 15957 previous: "Previous" 15958 }, 15959 errors: { 15960 loadImage: "An error occurred when trying to load photo.", 15961 loadContents: "An error occurred when trying to load contents.", 15962 missingPlugin: "The content your are attempting to view requires the <a href='{pluginspage}' target='_blank'>{type} plugin<\/a>." 15963 }, 15964 ajaxSetup: { 15965 url: '', 15966 beforeSend: function(jqXHR, settings) {}, 15967 cache: false, 15968 complete: function(jqXHR, textStatus) {}, 15969 crossDomain: false, 15970 error: function(jqXHR, textStatus, errorThrown) {}, 15971 success: function(data, textStatus, jqXHR) {}, 15972 global: true, 15973 ifModified: false, 15974 username: null, 15975 password: null, 15976 type: 'GET' 15977 }, 15978 callback: {} 15979 }, opt); 15980 15981 var instant = ($.isArray(items) || typeof items == 'string') ? true : false; 15982 15983 items = $.isArray(items) ? items : new Array(); 15984 15985 if (typeof args[0] == 'string') items[0] = args[0]; 15986 15987 if (version_compare($.fn.jquery, '1.8', '>=')) { 15988 var iLB = new iLightBox($(this), options, items, instant); 15989 return { 15990 close: function() { 15991 iLB.closeAction(); 15992 }, 15993 fullscreen: function() { 15994 iLB.fullScreenAction(); 15995 }, 15996 moveNext: function() { 15997 iLB.moveTo('next'); 15998 }, 15999 movePrev: function() { 16000 iLB.moveTo('prev'); 16001 }, 16002 goTo: function(index) { 16003 iLB.goTo(index); 16004 }, 16005 refresh: function() { 16006 iLB.refresh(); 16007 }, 16008 reposition: function() { 16009 (arguments.length > 0) ? iLB.repositionPhoto(true): iLB.repositionPhoto(); 16010 }, 16011 setOption: function(options) { 16012 iLB.setOption(options); 16013 }, 16014 destroy: function() { 16015 iLB.closeAction(); 16016 iLB.dispatchItemsEvents(); 16017 } 16018 }; 16019 } else { 16020 throw "The jQuery version that was loaded is too old. iLightBox requires jQuery 1.8+"; 16021 } 16022 16023 }; 16024 16025 16026 $.iLightBox = function() { 16027 return $.fn.iLightBox(arguments[0], arguments[1]); 16028 }; 16029 16030 function getScrollXY() { 16031 var scrOfX = 0, 16032 scrOfY = 0; 16033 if (typeof(window.pageYOffset) == 'number') { 16034 //Netscape compliant 16035 scrOfY = window.pageYOffset; 16036 scrOfX = window.pageXOffset; 16037 } else if (document.body && (document.body.scrollLeft || document.body.scrollTop)) { 16038 //DOM compliant 16039 scrOfY = document.body.scrollTop; 16040 scrOfX = document.body.scrollLeft; 16041 } else if (document.documentElement && (document.documentElement.scrollLeft || document.documentElement.scrollTop)) { 16042 //IE6 standards compliant mode 16043 scrOfY = document.documentElement.scrollTop; 16044 scrOfX = document.documentElement.scrollLeft; 16045 } 16046 return { 16047 x: scrOfX, 16048 y: scrOfY 16049 }; 16050 } 16051 16052 (function() { 16053 // add new event shortcuts 16054 $.each(("touchstart touchmove touchend " + 16055 "tap taphold " + 16056 "swipe swipeleft swiperight " + 16057 "scrollstart scrollstop").split(" "), function(i, name) { 16058 16059 $.fn[name] = function(fn) { 16060 return fn ? this.bind(name, fn) : this.trigger(name); 16061 }; 16062 16063 // jQuery < 1.8 16064 // if ($.attrFn) { 16065 // $.attrFn[name] = true; 16066 // } 16067 }); 16068 16069 var tapSettings = { 16070 startEvent: 'touchstart.iTap', 16071 endEvent: 'touchend.iTap' 16072 }; 16073 16074 // tap Event: 16075 $.event.special.itap = { 16076 setup: function() { 16077 16078 var self = this, 16079 $self = $(this), 16080 start, stop; 16081 16082 $self.bind(tapSettings.startEvent, function(event) { 16083 start = getScrollXY(); 16084 16085 $self.one(tapSettings.endEvent, function(event) { 16086 stop = getScrollXY(); 16087 16088 var orgEvent = event || window.event; 16089 event = $.event.fix(orgEvent); 16090 event.type = "itap"; 16091 16092 if ((start && stop) && (start.x == stop.x && start.y == stop.y))($.event.dispatch || $.event.handle).call(self, event); 16093 16094 start = stop = undefined; 16095 }); 16096 }); 16097 }, 16098 16099 teardown: function() { 16100 $(this).unbind(tapSettings.startEvent); 16101 } 16102 }; 16103 }()); 16104 16105 16106 //Fullscreen API 16107 (function() { 16108 fullScreenApi = { 16109 supportsFullScreen: false, 16110 isFullScreen: function() { 16111 return false;
16112 }, 16113 requestFullScreen: function() {}, 16114 cancelFullScreen: function() {}, 16115 fullScreenEventName: '', 16116 prefix: '' 16117 }, 16118 browserPrefixes = 'webkit moz o ms khtml'.split(' '); 16119 16120 // check for native support 16121 if (typeof document.cancelFullScreen != 'undefined') { 16122 fullScreenApi.supportsFullScreen = true; 16123 } else { 16124 // check for fullscreen support by vendor prefix 16125 for (var i = 0, il = browserPrefixes.length; i < il; i++) { 16126 fullScreenApi.prefix = browserPrefixes[i]; 16127 16128 if (typeof document[fullScreenApi.prefix + 'CancelFullScreen'] != 'undefined') { 16129 fullScreenApi.supportsFullScreen = true; 16130 16131 break; 16132 } 16133 } 16134 } 16135 16136 // update methods to do something useful 16137 if (fullScreenApi.supportsFullScreen) { 16138 fullScreenApi.fullScreenEventName = fullScreenApi.prefix + 'fullscreenchange'; 16139 16140 fullScreenApi.isFullScreen = function() { 16141 switch (this.prefix) { 16142 case '': 16143 return document.fullScreen; 16144 case 'webkit': 16145 return document.webkitIsFullScreen; 16146 default: 16147 return document[this.prefix + 'FullScreen']; 16148 } 16149 } 16150 fullScreenApi.requestFullScreen = function(el) { 16151 return (this.prefix === '') ? el.requestFullScreen() : el[this.prefix + 'RequestFullScreen'](); 16152 } 16153 fullScreenApi.cancelFullScreen = function(el) { 16154 return (this.prefix === '') ? document.cancelFullScreen() : document[this.prefix + 'CancelFullScreen'](); 16155 } 16156 } 16157 }()); 16158 16159 // Browser detect 16160 (function() { 16161 function uaMatch(ua) { 16162 ua = ua.toLowerCase(); 16163 16164 var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || 16165 /(webkit)[ \/]([\w.]+)/.exec(ua) || 16166 /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || 16167 /(msie) ([\w.]+)/.exec(ua) || 16168 ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || []; 16169 16170 return { 16171 browser: match[1] || "", 16172 version: match[2] || "0" 16173 }; 16174 } 16175 16176 var matched = uaMatch(navigator.userAgent); 16177 browser = {}; 16178 16179 if (matched.browser) { 16180 browser[matched.browser] = true; 16181 browser.version = matched.version; 16182 } 16183 16184 // Chrome is Webkit, but Webkit is also Safari. 16185 if (browser.chrome) { 16186 browser.webkit = true; 16187 } else if (browser.webkit) { 16188 browser.safari = true; 16189 } 16190 }()); 16191 16192 // Feature detects 16193 (function() { 16194 var prefixes = ['', 'webkit', 'moz', 'ms', 'o']; 16195 var el = document.createElement('div'); 16196 16197 function testProp(prop) { 16198 for (var p = 0, pl = prefixes.length; p < pl; p++) { 16199 var prefixedProp = prefixes[p] ? prefixes[p] + prop.charAt(0).toUpperCase() + prop.slice(1) : prop; 16200 if (el.style[prefixedProp] !== undefined) { 16201 return prefixedProp; 16202 } 16203 } 16204 } 16205 16206 // Global support indicators 16207 transform = testProp('transform') || ''; 16208 gpuAcceleration = testProp('perspective') ? 'translateZ(0) ' : ''; 16209 }()); 16210 16211 16212 /* 16213 PluginDetect v0.7.9 16214 www.pinlady.net/PluginDetect/license/ 16215 [ getVersion onWindowLoaded BetterIE ] 16216 [ Flash QuickTime Shockwave ] 16217 */ 16218 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;
16218d++){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);
16218d.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)}
16218c.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;
16218if(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(); 16219 16220 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)}; 16221 16222 16223 /* 16224 jQuery hashchange event v1.3 16225 https://github.com/cowboy/jquery-hashchange 16226 Copyright (c) 2010 "Cowboy" Ben Alman 16227 Dual licensed under the MIT and GPL licenses. 16228 */ 16229 (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= 16230 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|| 16231 "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;
16231a!==d&&(b.title=k.title,b.open(),e&&b.write('<script>document.domain="'+e+'"\x3c/script>'),b.close(),c.location.hash=a)}}();return h}()})(); 16232 16233 if (!Array.prototype.filter) { 16234 Array.prototype.filter = function(fun /*, thisp */ ) { 16235 "use strict"; 16236 16237 if (this == null) 16238 throw new TypeError(); 16239 16240 var t = Object(this); 16241 var len = t.length >>> 0; 16242 if (typeof fun != "function") 16243 throw new TypeError(); 16244 16245 var res = []; 16246 var thisp = arguments[1]; 16247 for (var i = 0; i < len; i++) { 16248 if (i in t) { 16249 var val = t[i]; // in case fun mutates this 16250 if (fun.call(thisp, val, i, t)) 16251 res.push(val); 16252 } 16253 } 16254 16255 return res; 16256 }; 16257 } 16258 16259 if (!Array.prototype.indexOf) { 16260 Array.prototype.indexOf = function(searchElement, fromIndex) { 16261 var k; 16262 16263 if (this == null) { 16264 throw new TypeError('"this" is null or not defined'); 16265 } 16266 16267 var O = Object(this); 16268 16269 var len = O.length >>> 0; 16270 16271 if (len === 0) { 16272 return -1; 16273 } 16274 16275 var n = +fromIndex || 0; 16276 16277 if (abs(n) === Infinity) { 16278 n = 0; 16279 } 16280 16281 if (n >= len) { 16282 return -1; 16283 } 16284 16285 k = max(n >= 0 ? n : len - abs(n), 0); 16286 16287 while (k < len) { 16288 var kValue; 16289 if (k in O && O[k] === searchElement) { 16290 return k; 16291 } 16292 k++; 16293 } 16294 return -1; 16295 }; 16296 } 16297 16298 if (!Array.prototype.lastIndexOf) { 16299 Array.prototype.lastIndexOf = function(searchElement /*, fromIndex*/ ) { 16300 "use strict"; 16301 16302 if (this == null) 16303 throw new TypeError(); 16304 16305 var t = Object(this); 16306 var len = t.length >>> 0; 16307 if (len === 0) 16308 return -1; 16309 16310 var n = len; 16311 if (arguments.length > 1) { 16312 n = Number(arguments[1]); 16313 if (n != n) 16314 n = 0; 16315 else if (n != 0 && n != (1 / 0) && n != -(1 / 0)) 16316 n = (n > 0 || -1) * floor(abs(n)); 16317 } 16318 16319 var k = n >= 0 ? min(n, len - 1) : len - abs(n); 16320 16321 for (; k >= 0; k--) { 16322 if (k in t && t[k] === searchElement) 16323 return k; 16324 } 16325 return -1; 16326 }; 16327 } 16328})(jQuery, this); 16329 16330/*! 16331 * lightgallery | 2.5.0 | June 13th 2022 16332 * http://www.lightgalleryjs.com/ 16333 * Copyright (c) 2020 Sachin Neravath; 16334 * @license GPLv3 16335 */ 16336 16337(function (global, factory) { 16338 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 16339 typeof define === 'function' && define.amd ? define(factory) : 16340 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lightGallery = factory()); 16341}(this, (function () { 'use strict'; 16342 16343 /*! ***************************************************************************** 16344 Copyright (c) Microsoft Corporation. 16345 16346 Permission to use, copy, modify, and/or distribute this software for any 16347 purpose with or without fee is hereby granted. 16348 16349 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 16350 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 16351 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 16352 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 16353 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 16354 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16355 PERFORMANCE OF THIS SOFTWARE. 16356 ***************************************************************************** */ 16357 16358 var __assign = function() { 16359 __assign = Object.assign || function __assign(t) { 16360 for (var s, i = 1, n = arguments.length; i < n; i++) { 16361 s = arguments[i]; 16362 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 16363 } 16364 return t; 16365 }; 16366 return __assign.apply(this, arguments); 16367 }; 16368 16369 function __spreadArrays() { 16370 for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; 16371 for (var r = Array(s), k = 0, i = 0; i < il; i++) 16372 for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) 16373 r[k] = a[j]; 16374 return r; 16375 } 16376 16377 /** 16378 * List of lightGallery events 16379 * All events should be documented here 16380 * Below interfaces are used to build the website documentations 16381 * */ 16382 var lGEvents = { 16383 afterAppendSlide: 'lgAfterAppendSlide', 16384 init: 'lgInit', 16385 hasVideo: 'lgHasVideo', 16386 containerResize: 'lgContainerResize', 16387 updateSlides: 'lgUpdateSlides', 16388 afterAppendSubHtml: 'lgAfterAppendSubHtml', 16389 beforeOpen: 'lgBeforeOpen', 16390 afterOpen: 'lgAfterOpen', 16391 slideItemLoad: 'lgSlideItemLoad', 16392 beforeSlide: 'lgBeforeSlide', 16393 afterSlide: 'lgAfterSlide', 16394 posterClick: 'lgPosterClick', 16395 dragStart: 'lgDragStart', 16396 dragMove: 'lgDragMove', 16397 dragEnd: 'lgDragEnd', 16398 beforeNextSlide: 'lgBeforeNextSlide', 16399 beforePrevSlide: 'lgBeforePrevSlide', 16400 beforeClose: 'lgBeforeClose', 16401 afterClose: 'lgAfterClose', 16402 rotateLeft: 'lgRotateLeft', 16403 rotateRight: 'lgRotateRight', 16404 flipHorizontal: 'lgFlipHorizontal', 16405 flipVertical: 'lgFlipVertical', 16406 autoplay: 'lgAutoplay', 16407 autoplayStart: 'lgAutoplayStart', 16408 autoplayStop: 'lgAutoplayStop', 16409 }; 16410 16411 var lightGalleryCoreSettings = { 16412 mode: 'lg-slide', 16413 easing: 'ease', 16414 speed: 400, 16415 licenseKey: '0000-0000-000-0000', 16416 height: '100%', 16417 width: '100%', 16418 addClass: '', 16419 startClass: 'lg-start-zoom', 16420 backdropDuration: 300, 16421 container: '', 16422 startAnimationDuration: 400, 16423 zoomFromOrigin: true, 16424 hideBarsDelay: 0, 16425 showBarsAfter: 10000, 16426 slideDelay: 0, 16427 supportLegacyBrowser: true, 16428 allowMediaOverlap: false, 16429 videoMaxSize: '1280-720', 16430 loadYouTubePoster: true, 16431 defaultCaptionHeight: 0, 16432 ariaLabelledby: '', 16433 ariaDescribedby: '', 16434 resetScrollPosition: true, 16435 hideScrollbar: false, 16436 closable: true, 16437 swipeToClose: true, 16438 closeOnTap: true, 16439 showCloseIcon: true, 16440 showMaximizeIcon: false, 16441 loop: true, 16442 escKey: true, 16443 keyPress: true, 16444 trapFocus: true, 16445 controls: true, 16446 slideEndAnimation: true, 16447 hideControlOnEnd: false,
vendor: 15,066 bytes, lines 16448-16995
16448 mousewheel: false, 16449 getCaptionFromTitleOrAlt: true, 16450 appendSubHtmlTo: '.lg-sub-html', 16451 subHtmlSelectorRelative: false, 16452 preload: 2, 16453 numberOfSlideItemsInDom: 10, 16454 selector: '', 16455 selectWithin: '', 16456 nextHtml: '', 16457 prevHtml: '', 16458 index: 0, 16459 iframeWidth: '100%', 16460 iframeHeight: '100%', 16461 iframeMaxWidth: '100%', 16462 iframeMaxHeight: '100%', 16463 download: true, 16464 counter: true, 16465 appendCounterTo: '.lg-toolbar', 16466 swipeThreshold: 50, 16467 enableSwipe: true, 16468 enableDrag: true, 16469 dynamic: false, 16470 dynamicEl: [], 16471 extraProps: [], 16472 exThumbImage: '', 16473 isMobile: undefined, 16474 mobileSettings: { 16475 controls: false, 16476 showCloseIcon: false, 16477 download: false, 16478 }, 16479 plugins: [], 16480 strings: { 16481 closeGallery: 'Close gallery', 16482 toggleMaximize: 'Toggle maximize', 16483 previousSlide: 'Previous slide', 16484 nextSlide: 'Next slide', 16485 download: 'Download', 16486 playVideo: 'Play video', 16487 }, 16488 }; 16489 16490 function initLgPolyfills() { 16491 (function () { 16492 if (typeof window.CustomEvent === 'function') 16493 return false; 16494 function CustomEvent(event, params) { 16495 params = params || { 16496 bubbles: false, 16497 cancelable: false, 16498 detail: null, 16499 }; 16500 var evt = document.createEvent('CustomEvent'); 16501 evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail); 16502 return evt; 16503 } 16504 window.CustomEvent = CustomEvent; 16505 })(); 16506 (function () { 16507 if (!Element.prototype.matches) { 16508 Element.prototype.matches = 16509 Element.prototype.msMatchesSelector || 16510 Element.prototype.webkitMatchesSelector; 16511 } 16512 })(); 16513 } 16514 var lgQuery = /** @class */ (function () { 16515 function lgQuery(selector) { 16516 this.cssVenderPrefixes = [ 16517 'TransitionDuration', 16518 'TransitionTimingFunction', 16519 'Transform', 16520 'Transition', 16521 ]; 16522 this.selector = this._getSelector(selector); 16523 this.firstElement = this._getFirstEl(); 16524 return this; 16525 } 16526 lgQuery.generateUUID = function () { 16527 return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { 16528 var r = (Math.random() * 16) | 0, v = c == 'x' ? r : (r & 0x3) | 0x8; 16529 return v.toString(16); 16530 }); 16531 }; 16532 lgQuery.prototype._getSelector = function (selector, context) { 16533 if (context === void 0) { context = document; } 16534 if (typeof selector !== 'string') { 16535 return selector; 16536 } 16537 context = context || document; 16538 var fl = selector.substring(0, 1); 16539 if (fl === '#') { 16540 return context.querySelector(selector); 16541 } 16542 else { 16543 return context.querySelectorAll(selector); 16544 } 16545 }; 16546 lgQuery.prototype._each = function (func) { 16547 if (!this.selector) { 16548 return this; 16549 } 16550 if (this.selector.length !== undefined) { 16551 [].forEach.call(this.selector, func); 16552 } 16553 else { 16554 func(this.selector, 0); 16555 } 16556 return this; 16557 }; 16558 lgQuery.prototype._setCssVendorPrefix = function (el, cssProperty, value) { 16559 // prettier-ignore 16560 var property = cssProperty.replace(/-([a-z])/gi, function (s, group1) { 16561 return group1.toUpperCase(); 16562 }); 16563 if (this.cssVenderPrefixes.indexOf(property) !== -1) { 16564 el.style[property.charAt(0).toLowerCase() + property.slice(1)] = value; 16565 el.style['webkit' + property] = value; 16566 el.style['moz' + property] = value; 16567 el.style['ms' + property] = value; 16568 el.style['o' + property] = value; 16569 } 16570 else { 16571 el.style[property] = value; 16572 } 16573 }; 16574 lgQuery.prototype._getFirstEl = function () { 16575 if (this.selector && this.selector.length !== undefined) { 16576 return this.selector[0]; 16577 } 16578 else { 16579 return this.selector; 16580 } 16581 }; 16582 lgQuery.prototype.isEventMatched = function (event, eventName) { 16583 var eventNamespace = eventName.split('.'); 16584 return event 16585 .split('.') 16586 .filter(function (e) { return e; }) 16587 .every(function (e) { 16588 return eventNamespace.indexOf(e) !== -1; 16589 }); 16590 }; 16591 lgQuery.prototype.attr = function (attr, value) { 16592 if (value === undefined) { 16593 if (!this.firstElement) { 16594 return ''; 16595 } 16596 return this.firstElement.getAttribute(attr); 16597 } 16598 this._each(function (el) { 16599 el.setAttribute(attr, value); 16600 }); 16601 return this; 16602 }; 16603 lgQuery.prototype.find = function (selector) { 16604 return $LG(this._getSelector(selector, this.selector)); 16605 }; 16606 lgQuery.prototype.first = function () { 16607 if (this.selector && this.selector.length !== undefined) { 16608 return $LG(this.selector[0]); 16609 } 16610 else { 16611 return $LG(this.selector); 16612 } 16613 }; 16614 lgQuery.prototype.eq = function (index) { 16615 return $LG(this.selector[index]); 16616 }; 16617 lgQuery.prototype.parent = function () { 16618 return $LG(this.selector.parentElement); 16619 }; 16620 lgQuery.prototype.get = function () { 16621 return this._getFirstEl(); 16622 }; 16623 lgQuery.prototype.removeAttr = function (attributes) { 16624 var attrs = attributes.split(' '); 16625 this._each(function (el) { 16626 attrs.forEach(function (attr) { return el.removeAttribute(attr); }); 16627 }); 16628 return this; 16629 }; 16630 lgQuery.prototype.wrap = function (className) { 16631 if (!this.firstElement) { 16632 return this; 16633 } 16634 var wrapper = document.createElement('div'); 16635 wrapper.className = className; 16636 this.firstElement.parentNode.insertBefore(wrapper, this.firstElement); 16637 this.firstElement.parentNode.removeChild(this.firstElement); 16638 wrapper.appendChild(this.firstElement); 16639 return this; 16640 }; 16641 lgQuery.prototype.addClass = function (classNames) { 16642 if (classNames === void 0) { classNames = ''; } 16643 this._each(function (el) { 16644 // IE doesn't support multiple arguments 16645 classNames.split(' ').forEach(function (className) { 16646 if (className) { 16647 el.classList.add(className); 16648 } 16649 }); 16650 }); 16651 return this; 16652 }; 16653 lgQuery.prototype.removeClass = function (classNames) { 16654 this._each(function (el) { 16655 // IE doesn't support multiple arguments 16656 classNames.split(' ').forEach(function (className) { 16657 if (className) { 16658 el.classList.remove(className); 16659 } 16660 }); 16661 }); 16662 return this; 16663 }; 16664 lgQuery.prototype.hasClass = function (className) { 16665 if (!this.firstElement) { 16666 return false; 16667 } 16668 return this.firstElement.classList.contains(className); 16669 }; 16670 lgQuery.prototype.hasAttribute = function (attribute) { 16671 if (!this.firstElement) { 16672 return false; 16673 } 16674 return this.firstElement.hasAttribute(attribute); 16675 }; 16676 lgQuery.prototype.toggleClass = function (className) { 16677 if (!this.firstElement) { 16678 return this; 16679 } 16680 if (this.hasClass(className)) { 16681 this.removeClass(className); 16682 } 16683 else { 16684 this.addClass(className); 16685 } 16686 return this; 16687 }; 16688 lgQuery.prototype.css = function (property, value) { 16689 var _this = this; 16690 this._each(function (el) { 16691 _this._setCssVendorPrefix(el, property, value); 16692 }); 16693 return this; 16694 }; 16695 // Need to pass separate namespaces for separate elements 16696 lgQuery.prototype.on = function (events, listener) { 16697 var _this = this; 16698 if (!this.selector) { 16699 return this; 16700 } 16701 events.split(' ').forEach(function (event) { 16702 if (!Array.isArray(lgQuery.eventListeners[event])) { 16703 lgQuery.eventListeners[event] = []; 16704 } 16705 lgQuery.eventListeners[event].push(listener); 16706 _this.selector.addEventListener(event.split('.')[0], listener); 16707 }); 16708 return this; 16709 }; 16710 // @todo - test this 16711 lgQuery.prototype.once = function (event, listener) { 16712 var _this = this; 16713 this.on(event, function () { 16714 _this.off(event); 16715 listener(event); 16716 }); 16717 return this; 16718 }; 16719 lgQuery.prototype.off = function (event) { 16720 var _this = this; 16721 if (!this.selector) { 16722 return this; 16723 } 16724 Object.keys(lgQuery.eventListeners).forEach(function (eventName) { 16725 if (_this.isEventMatched(event, eventName)) { 16726 lgQuery.eventListeners[eventName].forEach(function (listener) { 16727 _this.selector.removeEventListener(eventName.split('.')[0], listener); 16728 }); 16729 lgQuery.eventListeners[eventName] = []; 16730 } 16731 }); 16732 return this; 16733 }; 16734 lgQuery.prototype.trigger = function (event, detail) { 16735 if (!this.firstElement) { 16736 return this; 16737 } 16738 var customEvent = new CustomEvent(event.split('.')[0], { 16739 detail: detail || null, 16740 }); 16741 this.firstElement.dispatchEvent(customEvent); 16742 return this; 16743 }; 16744 // Does not support IE 16745 lgQuery.prototype.load = function (url) { 16746 var _this = this; 16747 fetch(url) 16748 .then(function (res) { return res.text(); }) 16749 .then(function (html) { 16750 _this.selector.innerHTML = html; 16751 }); 16752 return this; 16753 }; 16754 lgQuery.prototype.html = function (html) { 16755 if (html === undefined) { 16756 if (!this.firstElement) { 16757 return ''; 16758 } 16759 return this.firstElement.innerHTML; 16760 } 16761 this._each(function (el) { 16762 el.innerHTML = html; 16763 }); 16764 return this; 16765 }; 16766 lgQuery.prototype.append = function (html) { 16767 this._each(function (el) { 16768 if (typeof html === 'string') { 16769 el.insertAdjacentHTML('beforeend', html); 16770 } 16771 else { 16772 el.appendChild(html); 16773 } 16774 }); 16775 return this; 16776 }; 16777 lgQuery.prototype.prepend = function (html) { 16778 this._each(function (el) { 16779 el.insertAdjacentHTML('afterbegin', html); 16780 }); 16781 return this; 16782 }; 16783 lgQuery.prototype.remove = function () { 16784 this._each(function (el) { 16785 el.parentNode.removeChild(el); 16786 }); 16787 return this; 16788 }; 16789 lgQuery.prototype.empty = function () { 16790 this._each(function (el) { 16791 el.innerHTML = ''; 16792 }); 16793 return this; 16794 }; 16795 lgQuery.prototype.scrollTop = function (scrollTop) { 16796 if (scrollTop !== undefined) { 16797 document.body.scrollTop = scrollTop; 16798 document.documentElement.scrollTop = scrollTop; 16799 return this; 16800 } 16801 else { 16802 return (window.pageYOffset || 16803 document.documentElement.scrollTop || 16804 document.body.scrollTop || 16805 0); 16806 } 16807 }; 16808 lgQuery.prototype.scrollLeft = function (scrollLeft) { 16809 if (scrollLeft !== undefined) { 16810 document.body.scrollLeft = scrollLeft; 16811 document.documentElement.scrollLeft = scrollLeft; 16812 return this; 16813 } 16814 else { 16815 return (window.pageXOffset || 16816 document.documentElement.scrollLeft || 16817 document.body.scrollLeft || 16818 0); 16819 } 16820 }; 16821 lgQuery.prototype.offset = function () { 16822 if (!this.firstElement) { 16823 return { 16824 left: 0, 16825 top: 0, 16826 }; 16827 } 16828 var rect = this.firstElement.getBoundingClientRect(); 16829 var bodyMarginLeft = $LG('body').style().marginLeft; 16830 // Minus body margin - https://stackoverflow.com/questions/30711548/is-getboundingclientrect-left-returning-a-wrong-value 16831 return { 16832 left: rect.left - parseFloat(bodyMarginLeft) + this.scrollLeft(), 16833 top: rect.top + this.scrollTop(), 16834 }; 16835 }; 16836 lgQuery.prototype.style = function () { 16837 if (!this.firstElement) { 16838 return {}; 16839 } 16840 return (this.firstElement.currentStyle || 16841 window.getComputedStyle(this.firstElement)); 16842 }; 16843 // Width without padding and border even if box-sizing is used. 16844 lgQuery.prototype.width = function () { 16845 var style = this.style(); 16846 return (this.firstElement.clientWidth - 16847 parseFloat(style.paddingLeft) - 16848 parseFloat(style.paddingRight)); 16849 }; 16850 // Height without padding and border even if box-sizing is used. 16851 lgQuery.prototype.height = function () { 16852 var style = this.style(); 16853 return (this.firstElement.clientHeight - 16854 parseFloat(style.paddingTop) - 16855 parseFloat(style.paddingBottom)); 16856 }; 16857 lgQuery.eventListeners = {}; 16858 return lgQuery; 16859 }()); 16860 function $LG(selector) { 16861 initLgPolyfills(); 16862 return new lgQuery(selector); 16863 } 16864 16865 var defaultDynamicOptions = [ 16866 'src', 16867 'sources', 16868 'subHtml', 16869 'subHtmlUrl', 16870 'html', 16871 'video', 16872 'poster', 16873 'slideName', 16874 'responsive', 16875 'srcset', 16876 'sizes', 16877 'iframe', 16878 'downloadUrl', 16879 'download', 16880 'width', 16881 'facebookShareUrl', 16882 'tweetText', 16883 'iframeTitle', 16884 'twitterShareUrl', 16885 'pinterestShareUrl', 16886 'pinterestText', 16887 'fbHtml', 16888 'disqusIdentifier', 16889 'disqusUrl', 16890 ]; 16891 // Convert html data-attribute to camalcase 16892 function convertToData(attr) { 16893 // FInd a way for lgsize 16894 if (attr === 'href') { 16895 return 'src'; 16896 } 16897 attr = attr.replace('data-', ''); 16898 attr = attr.charAt(0).toLowerCase() + attr.slice(1); 16899 attr = attr.replace(/-([a-z])/g, function (g) { return g[1].toUpperCase(); }); 16900 return attr; 16901 } 16902 var utils = { 16903 /** 16904 * get possible width and height from the lgSize attribute. Used for ZoomFromOrigin option 16905 */ 16906 //Uncode edit ##START## 16907 getSize: function (el, container, spacing, defaultLgSize, galleryItem) { 16908 // getSize: function (el, container, spacing, defaultLgSize) { 16909 //Uncode edit ##END## 16910 if (spacing === void 0) { spacing = 0; } 16911 var LGel = $LG(el); 16912 var lgSize = LGel.attr('data-lg-size') || defaultLgSize; 16913 //Uncode edit ##START## 16914 if ( typeof galleryItem.size && galleryItem.size != null ) { 16915 lgSize = galleryItem.size; 16916 } 16917 //Uncode edit ##END## 16918 if (!lgSize) { 16919 return; 16920 } 16921 var isResponsiveSizes = lgSize.split(','); 16922 // if at-least two viewport sizes are available 16923 if (isResponsiveSizes[1]) { 16924 var wWidth = window.innerWidth; 16925 for (var i = 0; i < isResponsiveSizes.length; i++) { 16926 var size_1 = isResponsiveSizes[i]; 16927 var responsiveWidth = parseInt(size_1.split('-')[2], 10); 16928 if (responsiveWidth > wWidth) { 16929 lgSize = size_1; 16930 break; 16931 } 16932 // take last item as last option 16933 if (i === isResponsiveSizes.length - 1) { 16934 lgSize = size_1; 16935 } 16936 } 16937 } 16938 var size = lgSize.split('-'); 16939 var width = parseInt(size[0], 10); 16940 var height = parseInt(size[1], 10); 16941 var cWidth = container.width(); 16942 var cHeight = container.height() - spacing; 16943 var maxWidth = Math.min(cWidth, width); 16944 var maxHeight = Math.min(cHeight, height); 16945 var ratio = Math.min(maxWidth / width, maxHeight / height); 16946 return { width: width * ratio, height: height * ratio }; 16947 }, 16948 /** 16949 * @desc Get transform value based on the imageSize. Used for ZoomFromOrigin option 16950 * @param {jQuery Element} 16951 * @returns {String} Transform CSS string 16952 */ 16953 getTransform: function (el, container, top, bottom, imageSize) { 16954 if (!imageSize) { 16955 return; 16956 } 16957 var LGel = $LG(el).find('img').first(); 16958 if (!LGel.get()) { 16959 return; 16960 } 16961 var containerRect = container.get().getBoundingClientRect(); 16962 var wWidth = containerRect.width; 16963 // using innerWidth to include mobile safari bottom bar 16964 var wHeight = container.height() - (top + bottom); 16965 var elWidth = LGel.width(); 16966 var elHeight = LGel.height(); 16967 var elStyle = LGel.style(); 16968 var x = (wWidth - elWidth) / 2 - 16969 LGel.offset().left + 16970 (parseFloat(elStyle.paddingLeft) || 0) + 16971 (parseFloat(elStyle.borderLeft) || 0) + 16972 $LG(window).scrollLeft() + 16973 containerRect.left; 16974 var y = (wHeight - elHeight) / 2 - 16975 LGel.offset().top + 16976 (parseFloat(elStyle.paddingTop) || 0) + 16977 (parseFloat(elStyle.borderTop) || 0) + 16978 $LG(window).scrollTop() + 16979 top; 16980 var scX = elWidth / imageSize.width; 16981 var scY = elHeight / imageSize.height; 16982 var transform = 'translate3d(' + 16983 (x *= -1) + 16984 'px, ' + 16985 (y *= -1) + 16986 'px, 0) scale3d(' + 16987 scX + 16988 ', ' + 16989 scY + 16990 ', 1)'; 16991 return transform; 16992 }, 16993 getIframeMarkup: function (iframeWidth, iframeHeight, iframeMaxWidth, iframeMaxHeight, src, iframeTitle) { 16994 var title = iframeTitle ? 'title="' + iframeTitle + '"' : ''; 16995 return "<div class=\"lg-video-cont lg-has-iframe\" style=\"width:"
vendor: 2,803 bytes, lines 16995-17067
16995+ iframeWidth + "; max-width:" + iframeMaxWidth + "; height: " + iframeHeight + "; max-height:" + iframeMaxHeight + "\">\n <iframe class=\"lg-object\" frameborder=\"0\" " + title + " src=\"" + src + "\" allowfullscreen=\"true\"></iframe>\n </div>"; 16996 }, 16997 getImgMarkup: function (index, src, altAttr, srcset, sizes, sources) { 16998 var srcsetAttr = srcset ? "srcset=\"" + srcset + "\"" : ''; 16999 var sizesAttr = sizes ? "sizes=\"" + sizes + "\"" : ''; 17000 var imgMarkup = "<img " + altAttr + " " + srcsetAttr + " " + sizesAttr + " class=\"lg-object lg-image\" data-index=\"" + index + "\" src=\"" + src + "\" />"; 17001 var sourceTag = ''; 17002 if (sources) { 17003 var sourceObj = typeof sources === 'string' ? JSON.parse(sources) : sources; 17004 sourceTag = sourceObj.map(function (source) { 17005 var attrs = ''; 17006 Object.keys(source).forEach(function (key) { 17007 // Do not remove the first space as it is required to separate the attributes 17008 attrs += " " + key + "=\"" + source[key] + "\""; 17009 }); 17010 return "<source " + attrs + "></source>"; 17011 }); 17012 } 17013 return "" + sourceTag + imgMarkup; 17014 }, 17015 // Get src from responsive src 17016 getResponsiveSrc: function (srcItms) { 17017 var rsWidth = []; 17018 var rsSrc = []; 17019 var src = ''; 17020 for (var i = 0; i < srcItms.length; i++) { 17021 var _src = srcItms[i].split(' '); 17022 // Manage empty space 17023 if (_src[0] === '') { 17024 _src.splice(0, 1); 17025 } 17026 rsSrc.push(_src[0]); 17027 rsWidth.push(_src[1]); 17028 } 17029 var wWidth = window.innerWidth; 17030 for (var j = 0; j < rsWidth.length; j++) { 17031 if (parseInt(rsWidth[j], 10) > wWidth) { 17032 src = rsSrc[j]; 17033 break; 17034 } 17035 } 17036 return src; 17037 }, 17038 isImageLoaded: function (img) { 17039 if (!img) 17040 return false; 17041 // During the onload event, IE correctly identifies any images that 17042 // werenât downloaded as not complete. Others should too. Gecko-based 17043 // browsers act like NS4 in that they report this incorrectly. 17044 if (!img.complete) { 17045 return false; 17046 } 17047 // However, they do have two very useful properties: naturalWidth and 17048 // naturalHeight. These give the true size of the image. If it failed 17049 // to load, either of these should be zero. 17050 if (img.naturalWidth === 0) { 17051 return false; 17052 } 17053 // No other way of checking: assume itâs ok. 17054 return true; 17055 }, 17056 getVideoPosterMarkup: function (_poster, dummyImg, videoContStyle, playVideoString, _isVideo) { 17057 var videoClass = ''; 17058 if (_isVideo && _isVideo.youtube) { 17059 videoClass = 'lg-has-youtube'; 17060 } 17061 else if (_isVideo && _isVideo.vimeo) { 17062 videoClass = 'lg-has-vimeo'; 17063 } 17064 else { 17065 videoClass = 'lg-has-html5'; 17066 } 17067 return "<div class=\"lg-video-cont " + videoClass + "\" style=\"" + videoContStyle + "\">\n <div class=\"lg-video-play-button\">
vendor: 4,991 bytes, lines 17067-17178
17067\n <svg\n viewBox=\"0 0 20 20\"\n preserveAspectRatio=\"xMidYMid\"\n focusable=\"false\"\n aria-labelledby=\"" + playVideoString + "\"\n role=\"img\"\n class=\"lg-video-play-icon\"\n >\n <title>" + playVideoString + "</title>\n <polygon class=\"lg-video-play-icon-inner\" points=\"1,0 20,10 1,20\"></polygon>\n </svg>\n <svg class=\"lg-video-play-icon-bg\" viewBox=\"0 0 50 50\" focusable=\"false\">\n <circle cx=\"50%\" cy=\"50%\" r=\"20\"></circle></svg>\n <svg class=\"lg-video-play-icon-circle\" viewBox=\"0 0 50 50\" focusable=\"false\">\n <circle cx=\"50%\" cy=\"50%\" r=\"20\"></circle>\n </svg>\n </div>\n " + (dummyImg || '') + "\n <img class=\"lg-object lg-video-poster\" src=\"" + _poster + "\" />\n </div>"; 17068 }, 17069 getFocusableElements: function (container) { 17070 var elements = container.querySelectorAll('a[href]:not([disabled]), button:not([disabled]), textarea:not([disabled]), input[type="text"]:not([disabled]), input[type="radio"]:not([disabled]), input[type="checkbox"]:not([disabled]), select:not([disabled])'); 17071 var visibleElements = [].filter.call(elements, function (element) { 17072 var style = window.getComputedStyle(element); 17073 return style.display !== 'none' && style.visibility !== 'hidden'; 17074 }); 17075 return visibleElements; 17076 }, 17077 /** 17078 * @desc Create dynamic elements array from gallery items when dynamic option is false 17079 * It helps to avoid frequent DOM interaction 17080 * and avoid multiple checks for dynamic elments 17081 * 17082 * @returns {Array} dynamicEl 17083 */ 17084 getDynamicOptions: function (items, extraProps, getCaptionFromTitleOrAlt, exThumbImage) { 17085 var dynamicElements = []; 17086 var availableDynamicOptions = __spreadArrays(defaultDynamicOptions, extraProps); 17087 [].forEach.call(items, function (item) { 17088 var dynamicEl = {}; 17089 for (var i = 0; i < item.attributes.length; i++) { 17090 var attr = item.attributes[i]; 17091 if (attr.specified) { 17092 var dynamicAttr = convertToData(attr.name); 17093 var label = ''; 17094 if (availableDynamicOptions.indexOf(dynamicAttr) > -1) { 17095 label = dynamicAttr; 17096 } 17097 if (label) { 17098 dynamicEl[label] = attr.value; 17099 } 17100 } 17101 } 17102 var currentItem = $LG(item); 17103 var alt = currentItem.find('img').first().attr('alt'); 17104 var title = currentItem.attr('title'); 17105 //Uncode edit ##START## 17106 // var thumb = exThumbImage 17107 var thumb = exThumbImage && currentItem.attr(exThumbImage) 17108 //Uncode edit ##END## 17109 ? currentItem.attr(exThumbImage) 17110 : currentItem.find('img').first().attr('src'); 17111 dynamicEl.thumb = thumb; 17112 //Uncode edit ##START## 17113 if (getCaptionFromTitleOrAlt && !dynamicEl.subHtml) { 17114 // dynamicEl.subHtml = title || alt || ''; 17115 dynamicEl.subHtml = title || ''; 17116 } 17117 // dynamicEl.alt = alt || title || ''; 17118 dynamicEl.alt = title || ''; 17119 var inlineType = currentItem.attr('data-type'); 17120 dynamicEl.type = inlineType; 17121 //Uncode edit ##END## 17122 dynamicElements.push(dynamicEl); 17123 }); 17124 return dynamicElements; 17125 }, 17126 isMobile: function () { 17127 return /iPhone|iPad|iPod|Android/i.test(navigator.userAgent); 17128 }, 17129 /** 17130 * @desc Check the given src is video 17131 * @param {String} src 17132 * @return {Object} video type 17133 * Ex:{ youtube : ["//www.youtube.com/watch?v=c0asJgSyxcY", "c0asJgSyxcY"] } 17134 * 17135 * @todo - this information can be moved to dynamicEl to avoid frequent calls 17136 */ 17137 isVideo: function (src, isHTML5VIdeo, index) { 17138 if (!src) { 17139 if (isHTML5VIdeo) { 17140 return { 17141 html5: true, 17142 }; 17143 } 17144 else { 17145 console.warn('lightGallery :- data-src is not provided on slide item ' + 17146 (index + 1) + 17147 '. Please make sure the selector property is properly configured. More info - https://www.lightgalleryjs.com/demos/html-markup/'); 17148 return; 17149 } 17150 } 17151 var youtube = src.match(/\/\/(?:www\.)?youtu(?:\.be|be\.com|be-nocookie\.com)\/(?:watch\?v=|embed\/)?([a-z0-9\-\_\%]+)([\&|?][\S]*)*/i); 17152 var vimeo = src.match(/\/\/(?:www\.)?(?:player\.)?vimeo.com\/(?:video\/)?([0-9a-z\-_]+)(.*)?/i); 17153 var wistia = src.match(/https?:\/\/(.+)?(wistia\.com|wi\.st)\/(medias|embed)\/([0-9a-z\-_]+)(.*)/); 17154 if (youtube) { 17155 return { 17156 youtube: youtube, 17157 }; 17158 } 17159 else if (vimeo) { 17160 return { 17161 vimeo: vimeo, 17162 }; 17163 } 17164 else if (wistia) { 17165 return { 17166 wistia: wistia, 17167 }; 17168 } 17169 }, 17170 }; 17171 17172 // @ref - https://stackoverflow.com/questions/3971841/how-to-resize-images-proportionally-keeping-the-aspect-ratio 17173 // @ref - https://2ality.com/2017/04/setting-up-multi-platform-packages.html 17174 // Unique id for each gallery 17175 var lgId = 0; 17176 var LightGallery = /** @class */ (function () { 17177 function LightGallery(element, options) { 17178 this.lgOpened = false;
vendor: 4,563 bytes, lines 17179-17313
17179 this.index = 0; 17180 // lightGallery modules 17181 this.plugins = []; 17182 // false when lightGallery load first slide content; 17183 this.lGalleryOn = false; 17184 // True when a slide animation is in progress 17185 this.lgBusy = false; 17186 this.currentItemsInDom = []; 17187 // Scroll top value before lightGallery is opened 17188 this.prevScrollTop = 0; 17189 this.bodyPaddingRight = 0; 17190 this.isDummyImageRemoved = false; 17191 this.dragOrSwipeEnabled = false; 17192 this.mediaContainerPosition = { 17193 top: 0, 17194 bottom: 0, 17195 }; 17196 if (!element) { 17197 return this; 17198 } 17199 lgId++; 17200 this.lgId = lgId; 17201 this.el = element; 17202 this.LGel = $LG(element); 17203 this.generateSettings(options); 17204 this.buildModules(); 17205 // When using dynamic mode, ensure dynamicEl is an array 17206 if (this.settings.dynamic && 17207 this.settings.dynamicEl !== undefined && 17208 !Array.isArray(this.settings.dynamicEl)) { 17209 throw 'When using dynamic mode, you must also define dynamicEl as an Array.'; 17210 } 17211 this.galleryItems = this.getItems(); 17212 this.normalizeSettings(); 17213 // Gallery items 17214 this.init(); 17215 //Uncode edit ##START## 17216 // this.validateLicense(); 17217 //Uncode edit ##END## 17218 return this; 17219 } 17220 LightGallery.prototype.generateSettings = function (options) { 17221 // lightGallery settings 17222 this.settings = __assign(__assign({}, lightGalleryCoreSettings), options); 17223 if (this.settings.isMobile && 17224 typeof this.settings.isMobile === 'function' 17225 ? this.settings.isMobile() 17226 : utils.isMobile()) { 17227 var mobileSettings = __assign(__assign({}, this.settings.mobileSettings), this.settings.mobileSettings); 17228 this.settings = __assign(__assign({}, this.settings), mobileSettings); 17229 } 17230 }; 17231 LightGallery.prototype.normalizeSettings = function () { 17232 if (this.settings.slideEndAnimation) { 17233 this.settings.hideControlOnEnd = false; 17234 } 17235 if (!this.settings.closable) { 17236 this.settings.swipeToClose = false; 17237 } 17238 // And reset it on close to get the correct value next time 17239 this.zoomFromOrigin = this.settings.zoomFromOrigin; 17240 // At the moment, Zoom from image doesn't support dynamic options 17241 // @todo add zoomFromOrigin support for dynamic images 17242 if (this.settings.dynamic) { 17243 this.zoomFromOrigin = false; 17244 } 17245 if (!this.settings.container) { 17246 this.settings.container = document.body; 17247 } 17248 // settings.preload should not be grater than $item.length 17249 this.settings.preload = Math.min(this.settings.preload, this.galleryItems.length); 17250 }; 17251 LightGallery.prototype.init = function () { 17252 var _this = this; 17253 this.addSlideVideoInfo(this.galleryItems); 17254 this.buildStructure(); 17255 this.LGel.trigger(lGEvents.init, { 17256 instance: this, 17257 }); 17258 if (this.settings.keyPress) { 17259 this.keyPress(); 17260 } 17261 setTimeout(function () { 17262 _this.enableDrag(); 17263 _this.enableSwipe(); 17264 _this.triggerPosterClick(); 17265 }, 50); 17266 this.arrow(); 17267 if (this.settings.mousewheel) { 17268 this.mousewheel(); 17269 } 17270 if (!this.settings.dynamic) { 17271 this.openGalleryOnItemClick(); 17272 } 17273 }; 17274 LightGallery.prototype.openGalleryOnItemClick = function () { 17275 var _this = this; 17276 var _loop_1 = function (index) { 17277 var element = this_1.items[index]; 17278 var $element = $LG(element); 17279 // Using different namespace for click because click event should not unbind if selector is same object('this') 17280 // @todo manage all event listners - should have namespace that represent element 17281 var uuid = lgQuery.generateUUID(); 17282 $element 17283 .attr('data-lg-id', uuid) 17284 .on("click.lgcustom-item-" + uuid, function (e) { 17285 e.preventDefault(); 17286 var currentItemIndex = _this.settings.index || index; 17287 _this.openGallery(currentItemIndex, element); 17288 }); 17289 }; 17290 var this_1 = this; 17291 // Using for loop instead of using bubbling as the items can be any html element. 17292 for (var index = 0; index < this.items.length; index++) { 17293 _loop_1(index); 17294 } 17295 }; 17296 /** 17297 * Module constructor 17298 * Modules are build incrementally. 17299 * Gallery should be opened only once all the modules are initialized. 17300 * use moduleBuildTimeout to make sure this 17301 */ 17302 LightGallery.prototype.buildModules = function () { 17303 var _this = this; 17304 this.settings.plugins.forEach(function (plugin) { 17305 _this.plugins.push(new plugin(_this, $LG)); 17306 }); 17307 }; 17308 LightGallery.prototype.validateLicense = function () { 17309 if (!this.settings.licenseKey) { 17310 console.warn('Please provide a valid license key'); 17311 } 17312 else if (this.settings.licenseKey === '0000-0000-000-0000') { 17313 console.warn("lightGallery: " + this.settings.licenseKey + " license key is not val
vendor: 17,473 bytes, lines 17313-17727
17313id for production use"); 17314 } 17315 }; 17316 LightGallery.prototype.getSlideItem = function (index) { 17317 return $LG(this.getSlideItemId(index)); 17318 }; 17319 LightGallery.prototype.getSlideItemId = function (index) { 17320 return "#lg-item-" + this.lgId + "-" + index; 17321 }; 17322 LightGallery.prototype.getIdName = function (id) { 17323 return id + "-" + this.lgId; 17324 }; 17325 LightGallery.prototype.getElementById = function (id) { 17326 return $LG("#" + this.getIdName(id)); 17327 }; 17328 LightGallery.prototype.manageSingleSlideClassName = function () { 17329 if (this.galleryItems.length < 2) { 17330 this.outer.addClass('lg-single-item'); 17331 } 17332 else { 17333 this.outer.removeClass('lg-single-item'); 17334 } 17335 }; 17336 LightGallery.prototype.buildStructure = function () { 17337 var _this = this; 17338 var container = this.$container && this.$container.get(); 17339 if (container) { 17340 return; 17341 } 17342 var controls = ''; 17343 var subHtmlCont = ''; 17344 // Create controls 17345 if (this.settings.controls) { 17346 controls = "<button type=\"button\" id=\"" + this.getIdName('lg-prev') + "\" aria-label=\"" + this.settings.strings['previousSlide'] + "\" class=\"lg-prev lg-icon\"> " + this.settings.prevHtml + " </button>\n <button type=\"button\" id=\"" + this.getIdName('lg-next') + "\" aria-label=\"" + this.settings.strings['nextSlide'] + "\" class=\"lg-next lg-icon\"> " + this.settings.nextHtml + " </button>"; 17347 } 17348 if (this.settings.appendSubHtmlTo !== '.lg-item') { 17349 subHtmlCont = 17350 '<div class="lg-sub-html" role="status" aria-live="polite"></div>'; 17351 } 17352 var addClasses = ''; 17353 if (this.settings.allowMediaOverlap) { 17354 // Do not remove space before last single quote 17355 addClasses += 'lg-media-overlap '; 17356 } 17357 var ariaLabelledby = this.settings.ariaLabelledby 17358 ? 'aria-labelledby="' + this.settings.ariaLabelledby + '"' 17359 : ''; 17360 var ariaDescribedby = this.settings.ariaDescribedby 17361 ? 'aria-describedby="' + this.settings.ariaDescribedby + '"' 17362 : ''; 17363 var containerClassName = "lg-container " + this.settings.addClass + " " + (document.body !== this.settings.container ? 'lg-inline' : ''); 17364 var closeIcon = this.settings.closable && this.settings.showCloseIcon 17365 ? "<button type=\"button\" aria-label=\"" + this.settings.strings['closeGallery'] + "\" id=\"" + this.getIdName('lg-close') + "\" class=\"lg-close lg-icon\"></button>" 17366 : ''; 17367 var maximizeIcon = this.settings.showMaximizeIcon 17368 ? "<button type=\"button\" aria-label=\"" + this.settings.strings['toggleMaximize'] + "\" id=\"" + this.getIdName('lg-maximize') + "\" class=\"lg-maximize lg-icon\"></button>" 17369 : ''; 17370 var template = "\n <div class=\"" + containerClassName + "\" id=\"" + this.getIdName('lg-container') + "\" tabindex=\"-1\" aria-modal=\"true\" " + ariaLabelledby + " " + ariaDescribedby + " role=\"dialog\"\n >\n <div id=\"" + this.getIdName('lg-backdrop') + "\" class=\"lg-backdrop\"></div>\n\n <div id=\"" + this.getIdName('lg-outer') + "\" class=\"lg-outer lg-use-css3 lg-css3 lg-hide-items " + addClasses + " \">\n\n <div id=\"" + this.getIdName('lg-content') + "\" class=\"lg-content\">\n <div id=\"" + this.getIdName('lg-inner') + "\" class=\"lg-inner\">\n </div>\n " + controls + "\n </div>\n <div id=\"" + this.getIdName('lg-toolbar') + "\" class=\"lg-toolbar lg-group\">\n " + maximizeIcon + "\n " + closeIcon + "\n </div>\n " + (this.settings.appendSubHtmlTo === '.lg-outer' 17371 ? subHtmlCont 17372 : '') + "\n <div id=\"" + this.getIdName('lg-components') + "\" class=\"lg-components\">\n " + (this.settings.appendSubHtmlTo === '.lg-sub-html' 17373 ? subHtmlCont 17374 : '') + "\n </div>\n </div>\n </div>\n "; 17375 $LG(this.settings.container).append(template); 17376 if (document.body !== this.settings.container) { 17377 $LG(this.settings.container).css('position', 'relative'); 17378 } 17379 this.outer = this.getElementById('lg-outer'); 17380 this.$lgComponents = this.getElementById('lg-components'); 17381 this.$backdrop = this.getElementById('lg-backdrop'); 17382 this.$container = this.getElementById('lg-container'); 17383 this.$inner = this.getElementById('lg-inner'); 17384 this.$content = this.getElementById('lg-content'); 17385 this.$toolbar = this.getElementById('lg-toolbar'); 17386 this.$backdrop.css('transition-duration', this.settings.backdropDuration + 'ms'); 17387 var outerClassNames = this.settings.mode + " "; 17388 this.manageSingleSlideClassName(); 17389 if (this.settings.enableDrag) { 17390 outerClassNames += 'lg-grab '; 17391 } 17392 this.outer.addClass(outerClassNames); 17393 this.$inner.css('transition-timing-function', this.settings.easing); 17394 this.$inner.css('transition-duration', this.settings.speed + 'ms'); 17395 if (this.settings.download) { 17396 this.$toolbar.append("<a id=\"" + this.getIdName('lg-download') + "\" target=\"_blank\" rel=\"noopener\" aria-label=\"" + this.settings.strings['download'] + "\" download class=\"lg-download lg-icon\"></a>"); 17397 } 17398 this.counter(); 17399 $LG(window).on("resize.lg.global" + this.lgId + " orientationchange.lg.global" + this.lgId, function () { 17400 _this.refreshOnResize(); 17401 }); 17402 this.hideBars(); 17403 this.manageCloseGallery(); 17404 this.toggleMaximize(); 17405 this.initModules(); 17406 }; 17407 LightGallery.prototype.refreshOnResize = function () { 17408 if (this.lgOpened) { 17409 var currentGalleryItem = this.galleryItems[this.index]; 17410 var __slideVideoInfo = currentGalleryItem.__slideVideoInfo; 17411 this.mediaContainerPosition = this.getMediaContainerPosition(); 17412 var _a = this.mediaContainerPosition, top_1 = _a.top, bottom = _a.bottom; 17413 //Uncode edit ##START## 17414 this.currentImageSize = utils.getSize(this.items[this.index], this.outer, top_1 + bottom, __slideVideoInfo && this.settings.videoMaxSize, this.galleryItems[this.index]); 17415 // this.currentImageSize = utils.getSize(this.items[this.index], this.outer, top_1 + bottom, __slideVideoInfo && this.settings.videoMaxSize); 17416 //Uncode edit ##END## 17417 if (__slideVideoInfo) { 17418 this.resizeVideoSlide(this.index, this.currentImageSize); 17419 } 17420 if (this.zoomFromOrigin && !this.isDummyImageRemoved) { 17421 var imgStyle = this.getDummyImgStyles(this.currentImageSize); 17422 this.outer 17423 .find('.lg-current .lg-dummy-img') 17424 .first() 17425 .attr('style', imgStyle); 17426 } 17427 this.LGel.trigger(lGEvents.containerResize); 17428 } 17429 }; 17430 LightGallery.prototype.resizeVideoSlide = function (index, imageSize) { 17431 var lgVideoStyle = this.getVideoContStyle(imageSize); 17432 var currentSlide = this.getSlideItem(index); 17433 currentSlide.find('.lg-video-cont').attr('style', lgVideoStyle); 17434 }; 17435 /** 17436 * Update slides dynamically. 17437 * Add, edit or delete slides dynamically when lightGallery is opened. 17438 * Modify the current gallery items and pass it via updateSlides method 17439 * @note 17440 * - Do not mutate existing lightGallery items directly. 17441 * - Always pass new list of gallery items 17442 * - You need to take care of thumbnails outside the gallery if any 17443 * - user this method only if you want to update slides when the gallery is opened. Otherwise, use `refresh()` method. 17444 * @param items Gallery items 17445 * @param index After the update operation, which slide gallery should navigate to 17446 * @category lGPublicMethods 17447 * @example 17448 * const plugin = lightGallery(); 17449 * 17450 * // Adding slides dynamically 17451 * let galleryItems = [ 17452 * // Access existing lightGallery items 17453 * // galleryItems are automatically generated internally from the gallery HTML markup 17454 * // or directly from galleryItems when dynamic gallery is used 17455 * ...plugin.galleryItems, 17456 * ...[ 17457 * { 17458 * src: 'img/img-1.png', 17459 * thumb: 'img/thumb1.png', 17460 * }, 17461 * ], 17462 * ]; 17463 * plugin.updateSlides( 17464 * galleryItems, 17465 * plugin.index, 17466 * ); 17467 * 17468 * 17469 * // Remove slides dynamically 17470 * galleryItems = JSON.parse( 17471 * JSON.stringify(updateSlideInstance.galleryItems), 17472 * ); 17473 * galleryItems.shift(); 17474 * updateSlideInstance.updateSlides(galleryItems, 1); 17475 * @see <a href="/demos/update-slides/">Demo</a> 17476 */ 17477 LightGallery.prototype.updateSlides = function (items, index) { 17478 if (this.index > items.length - 1) { 17479 this.index = items.length - 1; 17480 } 17481 if (items.length === 1) { 17482 this.index = 0; 17483 } 17484 if (!items.length) { 17485 this.closeGallery(); 17486 return; 17487 } 17488 var currentSrc = this.galleryItems[index].src; 17489 this.galleryItems = items; 17490 this.updateControls(); 17491 this.$inner.empty(); 17492 this.currentItemsInDom = []; 17493 var _index = 0; 17494 // Find the current index based on source value of the slide 17495 this.galleryItems.some(function (galleryItem, itemIndex) { 17496 if (galleryItem.src === currentSrc) { 17497 _index = itemIndex; 17498 return true; 17499 } 17500 return false; 17501 }); 17502 this.currentItemsInDom = this.organizeSlideItems(_index, -1); 17503 this.loadContent(_index, true); 17504 this.getSlideItem(_index).addClass('lg-current'); 17505 this.index = _index; 17506 this.updateCurrentCounter(_index); 17507 this.LGel.trigger(lGEvents.updateSlides); 17508 }; 17509 // Get gallery items based on multiple conditions 17510 LightGallery.prototype.getItems = function () { 17511 // Gallery items 17512 this.items = []; 17513 if (!this.settings.dynamic) { 17514 if (this.settings.selector === 'this') { 17515 this.items.push(this.el); 17516 } 17517 else if (this.settings.selector) { 17518 if (typeof this.settings.selector === 'string') { 17519 if (this.settings.selectWithin) { 17520 var selectWithin = $LG(this.settings.selectWithin); 17521 this.items = selectWithin 17522 .find(this.settings.selector) 17523 .get(); 17524 } 17525 else { 17526 this.items = this.el.querySelectorAll(this.settings.selector); 17527 } 17528 } 17529 else { 17530 this.items = this.settings.selector; 17531 } 17532 } 17533 else { 17534 this.items = this.el.children; 17535 } 17536 return utils.getDynamicOptions(this.items, this.settings.extraProps, this.settings.getCaptionFromTitleOrAlt, this.settings.exThumbImage); 17537 } 17538 else { 17539 return this.settings.dynamicEl || []; 17540 } 17541 }; 17542 LightGallery.prototype.shouldHideScrollbar = function () { 17543 return (this.settings.hideScrollbar && 17544 document.body === this.settings.container); 17545 }; 17546 LightGallery.prototype.hideScrollbar = function () { 17547 if (!this.shouldHideScrollbar()) { 17548 return; 17549 } 17550 this.bodyPaddingRight = parseFloat($LG('body').style().paddingRight); 17551 var bodyRect = document.documentElement.getBoundingClientRect(); 17552 var scrollbarWidth = window.innerWidth - bodyRect.width; 17553 $LG(document.body).css('padding-right', scrollbarWidth + this.bodyPaddingRight + 'px'); 17554 $LG(document.body).addClass('lg-overlay-open'); 17555 }; 17556 LightGallery.prototype.resetScrollBar = function () { 17557 if (!this.shouldHideScrollbar()) { 17558 return; 17559 } 17560 $LG(document.body).css('padding-right', this.bodyPaddingRight + 'px'); 17561 $LG(document.body).removeClass('lg-overlay-open'); 17562 }; 17563 /** 17564 * Open lightGallery. 17565 * Open gallery with specific slide by passing index of the slide as parameter. 17566 * @category lGPublicMethods 17567 * @param {Number} index - index of the slide 17568 * @param {HTMLElement} element - Which image lightGallery should zoom from 17569 * 17570 * @example 17571 * const $dynamicGallery = document.getElementById('dynamic-gallery-demo'); 17572 * const dynamicGallery = lightGallery($dynamicGallery, { 17573 * dynamic: true, 17574 * dynamicEl: [ 17575 * { 17576 * src: 'img/1.jpg', 17577 * thumb: 'img/thumb-1.jpg', 17578 * subHtml: '<h4>Image 1 title</h4><p>Image 1 descriptions.</p>', 17579 * }, 17580 * ... 17581 * ], 17582 * }); 17583 * $dynamicGallery.addEventListener('click', function () { 17584 * // Starts with third item.(Optional). 17585 * // This is useful if you want use dynamic mode with 17586 * // custom thumbnails (thumbnails outside gallery), 17587 * dynamicGallery.openGallery(2); 17588 * }); 17589 * 17590 */ 17591 LightGallery.prototype.openGallery = function (index, element) { 17592 var _this = this; 17593 if (index === void 0) { index = this.settings.index; } 17594 // prevent accidental double execution 17595 if (this.lgOpened) 17596 return; 17597 this.lgOpened = true; 17598 this.outer.removeClass('lg-hide-items'); 17599 this.hideScrollbar(); 17600 // Add display block, but still has opacity 0 17601 this.$container.addClass('lg-show'); 17602 var itemsToBeInsertedToDom = this.getItemsToBeInsertedToDom(index, index); 17603 this.currentItemsInDom = itemsToBeInsertedToDom; 17604 var items = ''; 17605 itemsToBeInsertedToDom.forEach(function (item) { 17606 items = items + ("<div id=\"" + item + "\" class=\"lg-item\"></div>"); 17607 }); 17608 this.$inner.append(items); 17609 this.addHtml(index); 17610 var transform = ''; 17611 this.mediaContainerPosition = this.getMediaContainerPosition(); 17612 var _a = this.mediaContainerPosition, top = _a.top, bottom = _a.bottom; 17613 if (!this.settings.allowMediaOverlap) { 17614 this.setMediaContainerPosition(top, bottom); 17615 } 17616 var __slideVideoInfo = this.galleryItems[index].__slideVideoInfo; 17617 if (this.zoomFromOrigin && element) { 17618 //Uncode edit ##START## 17619 this.currentImageSize = utils.getSize(element, this.outer, top + bottom, __slideVideoInfo && this.settings.videoMaxSize, this.galleryItems[this.index]); 17620 // this.currentImageSize = utils.getSize(element, this.outer, top + bottom, __slideVideoInfo && this.settings.videoMaxSize); 17621 //Uncode edit ##END## 17622 transform = utils.getTransform(element, this.outer, top, bottom, this.currentImageSize); 17623 } 17624 if (!this.zoomFromOrigin || !transform) { 17625 this.outer.addClass(this.settings.startClass); 17626 this.getSlideItem(index).removeClass('lg-complete'); 17627 } 17628 var timeout = this.settings.zoomFromOrigin 17629 ? 100 17630 : this.settings.backdropDuration; 17631 setTimeout(function () { 17632 _this.outer.addClass('lg-components-open'); 17633 }, timeout); 17634 this.index = index; 17635 //Uncode edit ##START## 17636 // this.LGel.trigger(lGEvents.beforeOpen); 17637 this.LGel.trigger(lGEvents.beforeOpen, { 17638 galleryItems: this.galleryItems, 17639 items: this.items, 17640 outer: this.outer, 17641 }); 17642 //Uncode edit ##END## 17643 // add class lg-current to remove initial transition 17644 this.getSlideItem(index).addClass('lg-current'); 17645 this.lGalleryOn = false; 17646 // Store the current scroll top value to scroll back after closing the gallery.. 17647 this.prevScrollTop = $LG(window).scrollTop(); 17648 setTimeout(function () { 17649 // Need to check both zoomFromOrigin and transform values as we need to set set the 17650 // default opening animation if user missed to add the lg-size attribute 17651 if (_this.zoomFromOrigin && transform) { 17652 var currentSlide_1 = _this.getSlideItem(index); 17653 currentSlide_1.css('transform', transform); 17654 setTimeout(function () { 17655 currentSlide_1 17656 .addClass('lg-start-progress lg-start-end-progress') 17657 .css('transition-duration', _this.settings.startAnimationDuration + 'ms'); 17658 _this.outer.addClass('lg-zoom-from-image'); 17659 }); 17660 setTimeout(function () { 17661 currentSlide_1.css('transform', 'translate3d(0, 0, 0)'); 17662 }, 100); 17663 } 17664 setTimeout(function () { 17665 _this.$backdrop.addClass('in'); 17666 _this.$container.addClass('lg-show-in'); 17667 }, 10); 17668 setTimeout(function () { 17669 if (_this.settings.trapFocus && 17670 document.body === _this.settings.container) { 17671 _this.trapFocus(); 17672 } 17673 }, _this.settings.backdropDuration + 50); 17674 // lg-visible class resets gallery opacity to 1 17675 if (!_this.zoomFromOrigin || !transform) { 17676 setTimeout(function () { 17677 _this.outer.addClass('lg-visible'); 17678 }, _this.settings.backdropDuration); 17679 } 17680 // initiate slide function 17681 _this.slide(index, false, false, false); 17682 _this.LGel.trigger(lGEvents.afterOpen); 17683 }); 17684 if (document.body === this.settings.container) { 17685 $LG('html').addClass('lg-on'); 17686 } 17687 }; 17688 /** 17689 * Note - Changing the position of the media on every slide transition creates a flickering effect. 17690 * Therefore, The height of the caption is calculated dynamically, only once based on the first slide caption. 17691 * if you have dynamic captions for each media, 17692 * you can provide an appropriate height for the captions via allowMediaOverlap option 17693 */ 17694 LightGallery.prototype.getMediaContainerPosition = function () { 17695 if (this.settings.allowMediaOverlap) { 17696 return { 17697 top: 0, 17698 bottom: 0, 17699 }; 17700 } 17701 var top = this.$toolbar.get().clientHeight || 0; 17702 var subHtml = this.outer.find('.lg-components .lg-sub-html').get(); 17703 var captionHeight = this.settings.defaultCaptionHeight || 17704 (subHtml && subHtml.clientHeight) || 17705 0; 17706 var thumbContainer = this.outer.find('.lg-thumb-outer').get(); 17707 var thumbHeight = thumbContainer ? thumbContainer.clientHeight : 0; 17708 var bottom = thumbHeight + captionHeight; 17709 //Uncode edit ##START## 17710 bottom = bottom < 55 ? 55 : bottom; 17711 //Uncode edit ##END## 17712 return { 17713 top: top, 17714 bottom: bottom, 17715 }; 17716 }; 17717 LightGallery.prototype.setMediaContainerPosition = function (top, bottom) { 17718 if (top === void 0) { top = 0; } 17719 if (bottom === void 0) { bottom = 0; } 17720 this.$content.css('top', top + 'px').css('bottom', bottom + 'px'); 17721 }; 17722 LightGallery.prototype.hideBars = function () { 17723 var _this = this; 17724 // Hide controllers if mouse doesn't move for some period 17725 setTimeout(function () { 17726 _this.outer.removeClass('lg-hide-items'); 17727 if (_this.settings.hideBarsDelay > 0) {
vendor: 4,223 bytes, lines 17728-17858
17728 _this.outer.on('mousemove.lg click.lg touchstart.lg', function () { 17729 _this.outer.removeClass('lg-hide-items'); 17730 clearTimeout(_this.hideBarTimeout); 17731 // Timeout will be cleared on each slide movement also 17732 _this.hideBarTimeout = setTimeout(function () { 17733 _this.outer.addClass('lg-hide-items'); 17734 }, _this.settings.hideBarsDelay); 17735 }); 17736 _this.outer.trigger('mousemove.lg'); 17737 } 17738 }, this.settings.showBarsAfter); 17739 }; 17740 LightGallery.prototype.initPictureFill = function ($img) { 17741 if (this.settings.supportLegacyBrowser) { 17742 try { 17743 picturefill({ 17744 elements: [$img.get()], 17745 }); 17746 } 17747 catch (e) { 17748 console.warn('lightGallery :- If you want srcset or picture tag to be supported for older browser please include picturefil javascript library in your document.'); 17749 } 17750 } 17751 }; 17752 /** 17753 * @desc Create image counter 17754 * Ex: 1/10 17755 */ 17756 LightGallery.prototype.counter = function () { 17757 if (this.settings.counter) { 17758 var counterHtml = "<div class=\"lg-counter\" role=\"status\" aria-live=\"polite\">\n <span id=\"" + this.getIdName('lg-counter-current') + "\" class=\"lg-counter-current\">" + (this.index + 1) + " </span> /\n <span id=\"" + this.getIdName('lg-counter-all') + "\" class=\"lg-counter-all\">" + this.galleryItems.length + " </span></div>"; 17759 this.outer.find(this.settings.appendCounterTo).append(counterHtml); 17760 } 17761 }; 17762 /** 17763 * @desc add sub-html into the slide 17764 * @param {Number} index - index of the slide 17765 */ 17766 LightGallery.prototype.addHtml = function (index) { 17767 var subHtml; 17768 var subHtmlUrl; 17769 if (this.galleryItems[index].subHtmlUrl) { 17770 subHtmlUrl = this.galleryItems[index].subHtmlUrl; 17771 } 17772 else { 17773 subHtml = this.galleryItems[index].subHtml; 17774 } 17775 if (!subHtmlUrl) { 17776 if (subHtml) { 17777 // get first letter of sub-html 17778 // if first letter starts with . or # get the html form the jQuery object 17779 var fL = subHtml.substring(0, 1); 17780 if (fL === '.' || fL === '#') { 17781 if (this.settings.subHtmlSelectorRelative && 17782 !this.settings.dynamic) { 17783 subHtml = $LG(this.items) 17784 .eq(index) 17785 .find(subHtml) 17786 .first() 17787 .html(); 17788 } 17789 else { 17790 subHtml = $LG(subHtml).first().html(); 17791 } 17792 } 17793 } 17794 else { 17795 subHtml = ''; 17796 } 17797 } 17798 if (this.settings.appendSubHtmlTo !== '.lg-item') { 17799 if (subHtmlUrl) { 17800 this.outer.find('.lg-sub-html').load(subHtmlUrl); 17801 } 17802 else { 17803 this.outer.find('.lg-sub-html').html(subHtml); 17804 } 17805 } 17806 else { 17807 var currentSlide = $LG(this.getSlideItemId(index)); 17808 if (subHtmlUrl) { 17809 currentSlide.load(subHtmlUrl); 17810 } 17811 else { 17812 currentSlide.append("<div class=\"lg-sub-html\">" + subHtml + "</div>"); 17813 } 17814 } 17815 // Add lg-empty-html class if title doesn't exist 17816 if (typeof subHtml !== 'undefined' && subHtml !== null) { 17817 if (subHtml === '') { 17818 this.outer 17819 .find(this.settings.appendSubHtmlTo) 17820 .addClass('lg-empty-html'); 17821 } 17822 else { 17823 this.outer 17824 .find(this.settings.appendSubHtmlTo) 17825 .removeClass('lg-empty-html'); 17826 } 17827 } 17828 this.LGel.trigger(lGEvents.afterAppendSubHtml, { 17829 index: index, 17830 }); 17831 }; 17832 /** 17833 * @desc Preload slides 17834 * @param {Number} index - index of the slide 17835 * @todo preload not working for the first slide, Also, should work for the first and last slide as well 17836 */ 17837 LightGallery.prototype.preload = function (index) { 17838 for (var i = 1; i <= this.settings.preload; i++) { 17839 if (i >= this.galleryItems.length - index) { 17840 break; 17841 } 17842 this.loadContent(index + i, false); 17843 } 17844 for (var j = 1; j <= this.settings.preload; j++) { 17845 if (index - j < 0) { 17846 break; 17847 } 17848 this.loadContent(index - j, false); 17849 } 17850 }; 17851 LightGallery.prototype.getDummyImgStyles = function (imageSize) { 17852 if (!imageSize) 17853 return ''; 17854 return "width:" + imageSize.width + "px;\n margin-left: -" + imageSize.width / 2 + "px;\n margin-top: -" + imageSize.height / 2 + "px;\n height:" + imageSize.height + "px"; 17855 }; 17856 LightGallery.prototype.getVideoContStyle = function (imageSize) { 17857 if (!imageSize) 17858 return '';
17859 return "width:" + imageSize.width + "px;\n height:" + imageSize.height + "px"; 17860 }; 17861 LightGallery.prototype.getDummyImageContent = function ($currentSlide, index, alt) { 17862 var $currentItem; 17863 if (!this.settings.dynamic) { 17864 $currentItem = $LG(this.items).eq(index); 17865 } 17866 if ($currentItem) { 17867 var _dummyImgSrc = void 0; 17868 if (!this.settings.exThumbImage) { 17869 _dummyImgSrc = $currentItem.find('img').first().attr('src'); 17870 } 17871 else { 17872 _dummyImgSrc = $currentItem.attr(this.settings.exThumbImage); 17873 } 17874 if (!_dummyImgSrc) 17875 return ''; 17876 var imgStyle = this.getDummyImgStyles(this.currentImageSize); 17877 var dummyImgContent = "<img " + alt + " style=\"" + imgStyle + "\" class=\"lg-dummy-img\" src=\"" + _dummyImgSrc + "\" />"; 17878 $currentSlide.addClass('lg-first-slide'); 17879 this.outer.addClass('lg-first-slide-loading'); 17880 return dummyImgContent; 17881 } 17882 return ''; 17883 }; 17884 LightGallery.prototype.setImgMarkup = function (src, $currentSlide, index) { 17885 var currentGalleryItem = this.galleryItems[index]; 17886 var alt = currentGalleryItem.alt, srcset = currentGalleryItem.srcset, sizes = currentGalleryItem.sizes, sources = currentGalleryItem.sources; 17887 // Use the thumbnail as dummy image which will be resized to actual image size and 17888 // displayed on top of actual image 17889 var imgContent = ''; 17890 var altAttr = alt ? 'alt="' + alt + '"' : ''; 17891 if (this.isFirstSlideWithZoomAnimation()) { 17892 imgContent = this.getDummyImageContent($currentSlide, index, altAttr); 17893 } 17894 else { 17895 imgContent = utils.getImgMarkup(index, src, altAttr, srcset, sizes, sources); 17896 } 17897 var imgMarkup = "<picture class=\"lg-img-wrap\"> " + imgContent + "</picture>"; 17898 $currentSlide.prepend(imgMarkup); 17899 }; 17900 LightGallery.prototype.onSlideObjectLoad = function ($slide, isHTML5VideoWithoutPoster, onLoad, onError) { 17901 var mediaObject = $slide.find('.lg-object').first(); 17902 if (utils.isImageLoaded(mediaObject.get()) || 17903 isHTML5VideoWithoutPoster) { 17904 onLoad(); 17905 } 17906 else { 17907 mediaObject.on('load.lg error.lg', function () { 17908 onLoad && onLoad(); 17909 }); 17910 mediaObject.on('error.lg', function () { 17911 onError && onError(); 17912 }); 17913 } 17914 }; 17915 /** 17916 * 17917 * @param $el Current slide item 17918 * @param index 17919 * @param delay Delay is 0 except first time 17920 * @param speed Speed is same as delay, except it is 0 if gallery is opened via hash plugin 17921 * @param isFirstSlide 17922 */ 17923 LightGallery.prototype.onLgObjectLoad = function (currentSlide, index, delay, speed, isFirstSlide, isHTML5VideoWithoutPoster) { 17924 var _this = this; 17925 //Uncode edit ##START## 17926 var $item = _this.galleryItems[index], 17927 type = $item.type; 17928 17929 if ( typeof $item.src !== 'undefined' ) { 17930 var inline_id = $item.src.replace('#', ''), 17931 $inline = document.getElementById(inline_id), 17932 inline_html; 17933 17934 if ( type === 'inline' && inline_id != null && typeof $inline !== 'undefined' ) { 17935 inline_html = $inline.innerHTML; 17936 } else { 17937 inline_html = ''; 17938 } 17939 } 17940 //Uncode edit ##END## 17941 this.onSlideObjectLoad(currentSlide, true, function () { 17942 _this.triggerSlideItemLoad(currentSlide, index, delay, speed, isFirstSlide); 17943 }, function () { 17944 currentSlide.addClass('lg-complete lg-complete_'); 17945 //Uncode edit ##START## 17946 // currentSlide.html('<span class="lg-error-msg">Oops... Failed to load content...</span>'); 17947 if ( inline_html !== '' ) { 17948 currentSlide.html(inline_html); 17949 } else { 17950 currentSlide.html('<span class="lg-error-msg">Oops... Failed to load content...</span>'); 17951 } 17952 //Uncode edit ##END## 17953 }); 17954 }; 17955 LightGallery.prototype.triggerSlideItemLoad = function ($currentSlide, index, delay, speed, isFirstSlide) { 17956 var _this = this; 17957 var currentGalleryItem = this.galleryItems[index]; 17958 // Adding delay for video slides without poster for better performance and user experience 17959 // Videos should start playing once once the gallery is completely loaded 17960 var _speed = isFirstSlide &&
vendor: 37,617 bytes, lines 17961-19043
17961 this.getSlideType(currentGalleryItem) === 'video' && 17962 !currentGalleryItem.poster 17963 ? speed 17964 : 0; 17965 setTimeout(function () { 17966 $currentSlide.addClass('lg-complete lg-complete_'); 17967 _this.LGel.trigger(lGEvents.slideItemLoad, { 17968 index: index, 17969 delay: delay || 0, 17970 isFirstSlide: isFirstSlide, 17971 }); 17972 }, _speed); 17973 }; 17974 LightGallery.prototype.isFirstSlideWithZoomAnimation = function () { 17975 return !!(!this.lGalleryOn && 17976 this.zoomFromOrigin && 17977 this.currentImageSize); 17978 }; 17979 // Add video slideInfo 17980 LightGallery.prototype.addSlideVideoInfo = function (items) { 17981 var _this = this; 17982 items.forEach(function (element, index) { 17983 element.__slideVideoInfo = utils.isVideo(element.src, !!element.video, index); 17984 if (element.__slideVideoInfo && 17985 _this.settings.loadYouTubePoster && 17986 !element.poster && 17987 element.__slideVideoInfo.youtube) { 17988 element.poster = "//img.youtube.com/vi/" + element.__slideVideoInfo.youtube[1] + "/maxresdefault.jpg"; 17989 } 17990 }); 17991 }; 17992 /** 17993 * Load slide content into slide. 17994 * This is used to load content into slides that is not visible too 17995 * @param {Number} index - index of the slide. 17996 * @param {Boolean} rec - if true call loadcontent() function again. 17997 */ 17998 LightGallery.prototype.loadContent = function (index, rec) { 17999 var _this = this; 18000 var currentGalleryItem = this.galleryItems[index]; 18001 var $currentSlide = $LG(this.getSlideItemId(index)); 18002 var poster = currentGalleryItem.poster, srcset = currentGalleryItem.srcset, sizes = currentGalleryItem.sizes, sources = currentGalleryItem.sources; 18003 var src = currentGalleryItem.src; 18004 var video = currentGalleryItem.video; 18005 var _html5Video = video && typeof video === 'string' ? JSON.parse(video) : video; 18006 if (currentGalleryItem.responsive) { 18007 var srcDyItms = currentGalleryItem.responsive.split(','); 18008 src = utils.getResponsiveSrc(srcDyItms) || src; 18009 } 18010 var videoInfo = currentGalleryItem.__slideVideoInfo; 18011 var lgVideoStyle = ''; 18012 var iframe = !!currentGalleryItem.iframe; 18013 var isFirstSlide = !this.lGalleryOn; 18014 // delay for adding complete class. it is 0 except first time. 18015 var delay = 0; 18016 if (isFirstSlide) { 18017 if (this.zoomFromOrigin && this.currentImageSize) { 18018 delay = this.settings.startAnimationDuration + 10; 18019 } 18020 else { 18021 delay = this.settings.backdropDuration + 10; 18022 } 18023 } 18024 if (!$currentSlide.hasClass('lg-loaded')) { 18025 if (videoInfo) { 18026 var _a = this.mediaContainerPosition, top_2 = _a.top, bottom = _a.bottom; 18027 //Uncode edit ##START## 18028 var videoSize = utils.getSize(this.items[index], this.outer, top_2 + bottom, videoInfo && this.settings.videoMaxSize, this.galleryItems[this.index]); 18029 // var videoSize = utils.getSize(this.items[index], this.outer, top_2 + bottom, videoInfo && this.settings.videoMaxSize); 18030 //Uncode edit ##END## 18031 lgVideoStyle = this.getVideoContStyle(videoSize); 18032 } 18033 if (iframe) { 18034 var markup = utils.getIframeMarkup(this.settings.iframeWidth, this.settings.iframeHeight, this.settings.iframeMaxWidth, this.settings.iframeMaxHeight, src, currentGalleryItem.iframeTitle); 18035 $currentSlide.prepend(markup); 18036 } 18037 else if (poster) { 18038 var dummyImg = ''; 18039 var hasStartAnimation = isFirstSlide && 18040 this.zoomFromOrigin && 18041 this.currentImageSize; 18042 if (hasStartAnimation) { 18043 dummyImg = this.getDummyImageContent($currentSlide, index, ''); 18044 } 18045 var markup = utils.getVideoPosterMarkup(poster, dummyImg || '', lgVideoStyle, this.settings.strings['playVideo'], videoInfo); 18046 $currentSlide.prepend(markup); 18047 } 18048 //Uncode edit ##START## 18049 // else if (videoInfo) { 18050 else if (videoInfo || this.getSlideType(currentGalleryItem) === 'audio') { 18051 if (! _html5Video) { 18052 var markup = "<div class=\"lg-video-cont \" style=\"" + lgVideoStyle + "\"></div>"; 18053 } 18054 //Uncode edit ##END## 18055 $currentSlide.prepend(markup); 18056 } 18057 else { 18058 this.setImgMarkup(src, $currentSlide, index); 18059 if (srcset || sources) { 18060 var $img = $currentSlide.find('.lg-object'); 18061 this.initPictureFill($img); 18062 } 18063 } 18064 if (poster || videoInfo) { 18065 this.LGel.trigger(lGEvents.hasVideo, { 18066 index: index, 18067 src: src, 18068 html5Video: _html5Video, 18069 hasPoster: !!poster, 18070 }); 18071 } 18072 this.LGel.trigger(lGEvents.afterAppendSlide, { index: index }); 18073 if (this.lGalleryOn && 18074 this.settings.appendSubHtmlTo === '.lg-item') { 18075 this.addHtml(index); 18076 } 18077 } 18078 // For first time add some delay for displaying the start animation. 18079 var _speed = 0; 18080 // Do not change the delay value because it is required for zoom plugin. 18081 // If gallery opened from direct url (hash) speed value should be 0 18082 if (delay && !$LG(document.body).hasClass('lg-from-hash')) { 18083 _speed = delay; 18084 } 18085 // Only for first slide and zoomFromOrigin is enabled 18086 if (this.isFirstSlideWithZoomAnimation()) { 18087 setTimeout(function () { 18088 $currentSlide 18089 .removeClass('lg-start-end-progress lg-start-progress') 18090 .removeAttr('style'); 18091 }, this.settings.startAnimationDuration + 100); 18092 if (!$currentSlide.hasClass('lg-loaded')) { 18093 setTimeout(function () { 18094 if (_this.getSlideType(currentGalleryItem) === 'image') { 18095 var alt = currentGalleryItem.alt; 18096 var altAttr = alt ? 'alt="' + alt + '"' : ''; 18097 $currentSlide 18098 .find('.lg-img-wrap') 18099 .append(utils.getImgMarkup(index, src, altAttr, srcset, sizes, currentGalleryItem.sources)); 18100 if (srcset || sources) { 18101 var $img = $currentSlide.find('.lg-object'); 18102 _this.initPictureFill($img); 18103 } 18104 } 18105 if (_this.getSlideType(currentGalleryItem) === 'image' || 18106 (_this.getSlideType(currentGalleryItem) === 'video' && 18107 poster)) { 18108 _this.onLgObjectLoad($currentSlide, index, delay, _speed, true, false); 18109 // load remaining slides once the slide is completely loaded 18110 _this.onSlideObjectLoad($currentSlide, !!(videoInfo && videoInfo.html5 && !poster), function () { 18111 _this.loadContentOnFirstSlideLoad(index, $currentSlide, _speed); 18112 }, function () { 18113 _this.loadContentOnFirstSlideLoad(index, $currentSlide, _speed); 18114 }); 18115 } 18116 }, this.settings.startAnimationDuration + 100); 18117 } 18118 } 18119 // SLide content has been added to dom 18120 $currentSlide.addClass('lg-loaded'); 18121 if (!this.isFirstSlideWithZoomAnimation() || 18122 (this.getSlideType(currentGalleryItem) === 'video' && !poster)) { 18123 //Uncode edit ##START## 18124 // this.onLgObjectLoad($currentSlide, index, delay, _speed, isFirstSlide, !!(videoInfo && videoInfo.html5 && !poster)); 18125 this.onLgObjectLoad($currentSlide, index, delay, _speed, isFirstSlide, !!( (videoInfo && videoInfo.html5 && !poster) || this.getSlideType(currentGalleryItem) === 'audio')); 18126 //Uncode edit ##END## 18127 } 18128 // When gallery is opened once content is loaded (second time) need to add lg-complete class for css styling 18129 if ((!this.zoomFromOrigin || !this.currentImageSize) && 18130 $currentSlide.hasClass('lg-complete_') && 18131 !this.lGalleryOn) { 18132 setTimeout(function () { 18133 $currentSlide.addClass('lg-complete'); 18134 }, this.settings.backdropDuration); 18135 } 18136 // Content loaded 18137 // Need to set lGalleryOn before calling preload function 18138 this.lGalleryOn = true; 18139 if (rec === true) { 18140 if (!$currentSlide.hasClass('lg-complete_')) { 18141 $currentSlide 18142 .find('.lg-object') 18143 .first() 18144 .on('load.lg error.lg', function () { 18145 _this.preload(index); 18146 }); 18147 } 18148 else { 18149 this.preload(index); 18150 } 18151 } 18152 }; 18153 /** 18154 * @desc Remove dummy image content and load next slides 18155 * Called only for the first time if zoomFromOrigin animation is enabled 18156 * @param index 18157 * @param $currentSlide 18158 * @param speed 18159 */ 18160 LightGallery.prototype.loadContentOnFirstSlideLoad = function (index, $currentSlide, speed) { 18161 var _this = this; 18162 setTimeout(function () { 18163 $currentSlide.find('.lg-dummy-img').remove(); 18164 $currentSlide.removeClass('lg-first-slide'); 18165 _this.outer.removeClass('lg-first-slide-loading'); 18166 _this.isDummyImageRemoved = true; 18167 _this.preload(index); 18168 }, speed + 300); 18169 }; 18170 LightGallery.prototype.getItemsToBeInsertedToDom = function (index, prevIndex, numberOfItems) { 18171 var _this = this; 18172 if (numberOfItems === void 0) { numberOfItems = 0; } 18173 var itemsToBeInsertedToDom = []; 18174 // Minimum 2 items should be there 18175 var possibleNumberOfItems = Math.max(numberOfItems, 3); 18176 possibleNumberOfItems = Math.min(possibleNumberOfItems, this.galleryItems.length); 18177 var prevIndexItem = "lg-item-" + this.lgId + "-" + prevIndex; 18178 if (this.galleryItems.length <= 3) { 18179 this.galleryItems.forEach(function (_element, index) { 18180 itemsToBeInsertedToDom.push("lg-item-" + _this.lgId + "-" + index); 18181 }); 18182 return itemsToBeInsertedToDom; 18183 } 18184 if (index < (this.galleryItems.length - 1) / 2) { 18185 for (var idx = index; idx > index - possibleNumberOfItems / 2 && idx >= 0; idx--) { 18186 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + idx); 18187 } 18188 var numberOfExistingItems = itemsToBeInsertedToDom.length; 18189 for (var idx = 0; idx < possibleNumberOfItems - numberOfExistingItems; idx++) { 18190 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + (index + idx + 1)); 18191 } 18192 } 18193 else { 18194 for (var idx = index; idx <= this.galleryItems.length - 1 && 18195 idx < index + possibleNumberOfItems / 2; idx++) { 18196 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + idx); 18197 } 18198 var numberOfExistingItems = itemsToBeInsertedToDom.length; 18199 for (var idx = 0; idx < possibleNumberOfItems - numberOfExistingItems; idx++) { 18200 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + (index - idx - 1)); 18201 } 18202 } 18203 if (this.settings.loop) { 18204 if (index === this.galleryItems.length - 1) { 18205 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + 0); 18206 } 18207 else if (index === 0) { 18208 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + (this.galleryItems.length - 1)); 18209 } 18210 } 18211 if (itemsToBeInsertedToDom.indexOf(prevIndexItem) === -1) { 18212 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + prevIndex); 18213 } 18214 return itemsToBeInsertedToDom; 18215 }; 18216 LightGallery.prototype.organizeSlideItems = function (index, prevIndex) { 18217 var _this = this; 18218 var itemsToBeInsertedToDom = this.getItemsToBeInsertedToDom(index, prevIndex, this.settings.numberOfSlideItemsInDom); 18219 itemsToBeInsertedToDom.forEach(function (item) { 18220 if (_this.currentItemsInDom.indexOf(item) === -1) { 18221 _this.$inner.append("<div id=\"" + item + "\" class=\"lg-item\"></div>"); 18222 } 18223 }); 18224 this.currentItemsInDom.forEach(function (item) { 18225 if (itemsToBeInsertedToDom.indexOf(item) === -1) { 18226 $LG("#" + item).remove(); 18227 } 18228 }); 18229 return itemsToBeInsertedToDom; 18230 }; 18231 /** 18232 * Get previous index of the slide 18233 */ 18234 LightGallery.prototype.getPreviousSlideIndex = function () { 18235 var prevIndex = 0; 18236 try { 18237 var currentItemId = this.outer 18238 .find('.lg-current') 18239 .first() 18240 .attr('id'); 18241 prevIndex = parseInt(currentItemId.split('-')[3]) || 0; 18242 } 18243 catch (error) { 18244 prevIndex = 0; 18245 } 18246 return prevIndex; 18247 }; 18248 LightGallery.prototype.setDownloadValue = function (index) { 18249 if (this.settings.download) { 18250 var currentGalleryItem = this.galleryItems[index]; 18251 var hideDownloadBtn = currentGalleryItem.downloadUrl === false || 18252 currentGalleryItem.downloadUrl === 'false'; 18253 if (hideDownloadBtn) { 18254 this.outer.addClass('lg-hide-download'); 18255 } 18256 else { 18257 var $download = this.getElementById('lg-download'); 18258 this.outer.removeClass('lg-hide-download'); 18259 $download.attr('href', currentGalleryItem.downloadUrl || 18260 currentGalleryItem.src); 18261 if (currentGalleryItem.download) { 18262 //Uncode edit ##START## 18263 var download_url = currentGalleryItem.downloadUrl || currentGalleryItem.src, 18264 download_name = download_url.substring(download_url.lastIndexOf('/')+1); 18265 $download.attr('download', download_name); 18266 // $download.attr('download', currentGalleryItem.download); 18267 //Uncode edit ##END## 18268 } 18269 } 18270 } 18271 }; 18272 LightGallery.prototype.makeSlideAnimation = function (direction, currentSlideItem, previousSlideItem) { 18273 var _this = this; 18274 if (this.lGalleryOn) { 18275 previousSlideItem.addClass('lg-slide-progress'); 18276 } 18277 setTimeout(function () { 18278 // remove all transitions 18279 _this.outer.addClass('lg-no-trans'); 18280 _this.outer 18281 .find('.lg-item') 18282 .removeClass('lg-prev-slide lg-next-slide'); 18283 if (direction === 'prev') { 18284 //prevslide 18285 currentSlideItem.addClass('lg-prev-slide'); 18286 previousSlideItem.addClass('lg-next-slide'); 18287 } 18288 else { 18289 // next slide 18290 currentSlideItem.addClass('lg-next-slide'); 18291 previousSlideItem.addClass('lg-prev-slide'); 18292 } 18293 // give 50 ms for browser to add/remove class 18294 setTimeout(function () { 18295 _this.outer.find('.lg-item').removeClass('lg-current'); 18296 currentSlideItem.addClass('lg-current'); 18297 // reset all transitions 18298 _this.outer.removeClass('lg-no-trans'); 18299 }, 50); 18300 }, this.lGalleryOn ? this.settings.slideDelay : 0); 18301 }; 18302 /** 18303 * Goto a specific slide. 18304 * @param {Number} index - index of the slide 18305 * @param {Boolean} fromTouch - true if slide function called via touch event or mouse drag 18306 * @param {Boolean} fromThumb - true if slide function called via thumbnail click 18307 * @param {String} direction - Direction of the slide(next/prev) 18308 * @category lGPublicMethods 18309 * @example 18310 * const plugin = lightGallery(); 18311 * // to go to 3rd slide 18312 * plugin.slide(2); 18313 * 18314 */ 18315 LightGallery.prototype.slide = function (index, fromTouch, fromThumb, direction) { 18316 var _this = this; 18317 var prevIndex = this.getPreviousSlideIndex(); 18318 this.currentItemsInDom = this.organizeSlideItems(index, prevIndex); 18319 // Prevent multiple call, Required for hsh plugin 18320 if (this.lGalleryOn && prevIndex === index) { 18321 return; 18322 } 18323 var numberOfGalleryItems = this.galleryItems.length; 18324 if (!this.lgBusy) { 18325 if (this.settings.counter) { 18326 this.updateCurrentCounter(index); 18327 } 18328 var currentSlideItem = this.getSlideItem(index); 18329 var previousSlideItem_1 = this.getSlideItem(prevIndex); 18330 var currentGalleryItem = this.galleryItems[index]; 18331 var videoInfo = currentGalleryItem.__slideVideoInfo; 18332 this.outer.attr('data-lg-slide-type', this.getSlideType(currentGalleryItem)); 18333 this.setDownloadValue(index); 18334 if (videoInfo) { 18335 var _a = this.mediaContainerPosition, top_3 = _a.top, bottom = _a.bottom; 18336 //Uncode edit ##START## 18337 var videoSize = utils.getSize(this.items[index], this.outer, top_3 + bottom, videoInfo && this.settings.videoMaxSize, this.galleryItems[this.index]); 18338 // var videoSize = utils.getSize(this.items[index], this.outer, top_3 + bottom, videoInfo && this.settings.videoMaxSize); 18339 //Uncode edit ##END## 18340 this.resizeVideoSlide(index, videoSize); 18341 } 18342 this.LGel.trigger(lGEvents.beforeSlide, { 18343 prevIndex: prevIndex, 18344 index: index, 18345 fromTouch: !!fromTouch, 18346 fromThumb: !!fromThumb, 18347 //Uncode edit ##START## 18348 currentSlide: currentSlideItem, 18349 previousSlide: previousSlideItem_1, 18350 info: currentGalleryItem, 18351 item: this.items[index] 18352 //Uncode edit ##END## 18353 }); 18354 this.lgBusy = true; 18355 clearTimeout(this.hideBarTimeout); 18356 this.arrowDisable(index); 18357 if (!direction) { 18358 if (index < prevIndex) { 18359 direction = 'prev'; 18360 } 18361 else if (index > prevIndex) { 18362 direction = 'next'; 18363 } 18364 } 18365 if (!fromTouch) { 18366 this.makeSlideAnimation(direction, currentSlideItem, previousSlideItem_1); 18367 } 18368 else { 18369 this.outer 18370 .find('.lg-item') 18371 .removeClass('lg-prev-slide lg-current lg-next-slide'); 18372 var touchPrev = void 0; 18373 var touchNext = void 0; 18374 if (numberOfGalleryItems > 2) { 18375 touchPrev = index - 1; 18376 touchNext = index + 1; 18377 if (index === 0 && prevIndex === numberOfGalleryItems - 1) { 18378 // next slide 18379 touchNext = 0; 18380 touchPrev = numberOfGalleryItems - 1; 18381 } 18382 else if (index === numberOfGalleryItems - 1 && 18383 prevIndex === 0) { 18384 // prev slide 18385 touchNext = 0; 18386 touchPrev = numberOfGalleryItems - 1; 18387 } 18388 } 18389 else { 18390 touchPrev = 0; 18391 touchNext = 1; 18392 } 18393 if (direction === 'prev') { 18394 this.getSlideItem(touchNext).addClass('lg-next-slide'); 18395 } 18396 else { 18397 this.getSlideItem(touchPrev).addClass('lg-prev-slide'); 18398 } 18399 currentSlideItem.addClass('lg-current'); 18400 } 18401 // Do not put load content in set timeout as it needs to load immediately when the gallery is opened 18402 if (!this.lGalleryOn) { 18403 this.loadContent(index, true); 18404 } 18405 else { 18406 setTimeout(function () { 18407 _this.loadContent(index, true); 18408 // Add title if this.settings.appendSubHtmlTo === lg-sub-html 18409 if (_this.settings.appendSubHtmlTo !== '.lg-item') { 18410 _this.addHtml(index); 18411 } 18412 }, this.settings.speed + 50 + (fromTouch ? 0 : this.settings.slideDelay)); 18413 } 18414 setTimeout(function () { 18415 _this.lgBusy = false; 18416 previousSlideItem_1.removeClass('lg-slide-progress'); 18417 _this.LGel.trigger(lGEvents.afterSlide, { 18418 prevIndex: prevIndex, 18419 index: index, 18420 fromTouch: fromTouch, 18421 fromThumb: fromThumb, 18422 }); 18423 }, (this.lGalleryOn ? this.settings.speed + 100 : 100) + (fromTouch ? 0 : this.settings.slideDelay)); 18424 } 18425 this.index = index; 18426 }; 18427 LightGallery.prototype.updateCurrentCounter = function (index) { 18428 this.getElementById('lg-counter-current').html(index + 1 + ''); 18429 }; 18430 LightGallery.prototype.updateCounterTotal = function () { 18431 this.getElementById('lg-counter-all').html(this.galleryItems.length + ''); 18432 }; 18433 LightGallery.prototype.getSlideType = function (item) { 18434 if (item.__slideVideoInfo) { 18435 return 'video'; 18436 } 18437 else if (item.iframe) { 18438 return 'iframe'; 18439 } 18440 //Uncode edit ##START## 18441 else if (typeof item.src !== '' && item.src.search(/.mp3|.m4a/i) > -1) { 18442 return 'audio'; 18443 } 18444 //Uncode edit ##END## 18445 else { 18446 return 'image'; 18447 } 18448 }; 18449 LightGallery.prototype.touchMove = function (startCoords, endCoords, e) { 18450 var distanceX = endCoords.pageX - startCoords.pageX; 18451 var distanceY = endCoords.pageY - startCoords.pageY; 18452 var allowSwipe = false; 18453 if (this.swipeDirection) { 18454 allowSwipe = true; 18455 } 18456 else { 18457 if (Math.abs(distanceX) > 15) { 18458 this.swipeDirection = 'horizontal'; 18459 allowSwipe = true; 18460 } 18461 else if (Math.abs(distanceY) > 15) { 18462 this.swipeDirection = 'vertical'; 18463 allowSwipe = true; 18464 } 18465 } 18466 if (!allowSwipe) { 18467 return; 18468 } 18469 var $currentSlide = this.getSlideItem(this.index); 18470 if (this.swipeDirection === 'horizontal') { 18471 e === null || e === void 0 ? void 0 : e.preventDefault(); 18472 // reset opacity and transition duration 18473 this.outer.addClass('lg-dragging'); 18474 // move current slide 18475 this.setTranslate($currentSlide, distanceX, 0); 18476 // move next and prev slide with current slide 18477 var width = $currentSlide.get().offsetWidth; 18478 var slideWidthAmount = (width * 15) / 100; 18479 var gutter = slideWidthAmount - Math.abs((distanceX * 10) / 100); 18480 this.setTranslate(this.outer.find('.lg-prev-slide').first(), -width + distanceX - gutter, 0); 18481 this.setTranslate(this.outer.find('.lg-next-slide').first(), width + distanceX + gutter, 0); 18482 } 18483 else if (this.swipeDirection === 'vertical') { 18484 if (this.settings.swipeToClose) { 18485 e === null || e === void 0 ? void 0 : e.preventDefault(); 18486 this.$container.addClass('lg-dragging-vertical'); 18487 var opacity = 1 - Math.abs(distanceY) / window.innerHeight; 18488 this.$backdrop.css('opacity', opacity); 18489 var scale = 1 - Math.abs(distanceY) / (window.innerWidth * 2); 18490 this.setTranslate($currentSlide, 0, distanceY, scale, scale); 18491 if (Math.abs(distanceY) > 100) { 18492 this.outer 18493 .addClass('lg-hide-items') 18494 .removeClass('lg-components-open'); 18495 } 18496 } 18497 } 18498 }; 18499 LightGallery.prototype.touchEnd = function (endCoords, startCoords, event) { 18500 var _this = this; 18501 var distance; 18502 // keep slide animation for any mode while dragg/swipe 18503 if (this.settings.mode !== 'lg-slide') { 18504 this.outer.addClass('lg-slide'); 18505 } 18506 // set transition duration 18507 setTimeout(function () { 18508 _this.$container.removeClass('lg-dragging-vertical'); 18509 _this.outer 18510 .removeClass('lg-dragging lg-hide-items') 18511 .addClass('lg-components-open'); 18512 var triggerClick = true; 18513 if (_this.swipeDirection === 'horizontal') { 18514 distance = endCoords.pageX - startCoords.pageX; 18515 var distanceAbs = Math.abs(endCoords.pageX - startCoords.pageX); 18516 if (distance < 0 && 18517 distanceAbs > _this.settings.swipeThreshold) { 18518 _this.goToNextSlide(true); 18519 triggerClick = false; 18520 } 18521 else if (distance > 0 && 18522 distanceAbs > _this.settings.swipeThreshold) { 18523 _this.goToPrevSlide(true); 18524 triggerClick = false; 18525 } 18526 } 18527 else if (_this.swipeDirection === 'vertical') { 18528 distance = Math.abs(endCoords.pageY - startCoords.pageY); 18529 if (_this.settings.closable && 18530 _this.settings.swipeToClose && 18531 distance > 100) { 18532 _this.closeGallery(); 18533 return; 18534 } 18535 else { 18536 _this.$backdrop.css('opacity', 1); 18537 } 18538 } 18539 _this.outer.find('.lg-item').removeAttr('style'); 18540 if (triggerClick && 18541 Math.abs(endCoords.pageX - startCoords.pageX) < 5) { 18542 // Trigger click if distance is less than 5 pix 18543 var target = $LG(event.target); 18544 if (_this.isPosterElement(target)) { 18545 _this.LGel.trigger(lGEvents.posterClick); 18546 } 18547 } 18548 _this.swipeDirection = undefined; 18549 }); 18550 // remove slide class once drag/swipe is completed if mode is not slide 18551 setTimeout(function () { 18552 if (!_this.outer.hasClass('lg-dragging') && 18553 _this.settings.mode !== 'lg-slide') { 18554 _this.outer.removeClass('lg-slide'); 18555 } 18556 }, this.settings.speed + 100); 18557 }; 18558 LightGallery.prototype.enableSwipe = function () { 18559 var _this = this; 18560 var startCoords = {}; 18561 var endCoords = {}; 18562 var isMoved = false; 18563 var isSwiping = false; 18564 if (this.settings.enableSwipe) { 18565 this.$inner.on('touchstart.lg', function (e) { 18566 _this.dragOrSwipeEnabled = true; 18567 var $item = _this.getSlideItem(_this.index); 18568 if (($LG(e.target).hasClass('lg-item') || 18569 $item.get().contains(e.target)) && 18570 !_this.outer.hasClass('lg-zoomed') && 18571 !_this.lgBusy && 18572 e.targetTouches.length === 1) { 18573 isSwiping = true; 18574 _this.touchAction = 'swipe'; 18575 _this.manageSwipeClass(); 18576 startCoords = { 18577 pageX: e.targetTouches[0].pageX, 18578 pageY: e.targetTouches[0].pageY, 18579 }; 18580 } 18581 }); 18582 this.$inner.on('touchmove.lg', function (e) { 18583 if (isSwiping && 18584 _this.touchAction === 'swipe' && 18585 e.targetTouches.length === 1) { 18586 endCoords = { 18587 pageX: e.targetTouches[0].pageX, 18588 pageY: e.targetTouches[0].pageY, 18589 }; 18590 _this.touchMove(startCoords, endCoords, e); 18591 isMoved = true; 18592 } 18593 }); 18594 this.$inner.on('touchend.lg', function (event) { 18595 if (_this.touchAction === 'swipe') { 18596 if (isMoved) { 18597 isMoved = false; 18598 _this.touchEnd(endCoords, startCoords, event); 18599 } 18600 else if (isSwiping) { 18601 var target = $LG(event.target); 18602 if (_this.isPosterElement(target)) { 18603 _this.LGel.trigger(lGEvents.posterClick); 18604 } 18605 } 18606 _this.touchAction = undefined; 18607 isSwiping = false; 18608 } 18609 }); 18610 } 18611 }; 18612 LightGallery.prototype.enableDrag = function () { 18613 var _this = this; 18614 var startCoords = {}; 18615 var endCoords = {}; 18616 var isDraging = false; 18617 var isMoved = false; 18618 if (this.settings.enableDrag) { 18619 this.outer.on('mousedown.lg', function (e) { 18620 _this.dragOrSwipeEnabled = true; 18621 var $item = _this.getSlideItem(_this.index); 18622 if ($LG(e.target).hasClass('lg-item') || 18623 $item.get().contains(e.target)) { 18624 if (!_this.outer.hasClass('lg-zoomed') && !_this.lgBusy) { 18625 e.preventDefault(); 18626 if (!_this.lgBusy) { 18627 _this.manageSwipeClass(); 18628 startCoords = { 18629 pageX: e.pageX, 18630 pageY: e.pageY, 18631 }; 18632 isDraging = true; 18633 // ** Fix for webkit cursor issue https://code.google.com/p/chromium/issues/detail?id=26723 18634 _this.outer.get().scrollLeft += 1; 18635 _this.outer.get().scrollLeft -= 1; 18636 // * 18637 _this.outer 18638 .removeClass('lg-grab') 18639 .addClass('lg-grabbing'); 18640 _this.LGel.trigger(lGEvents.dragStart); 18641 } 18642 } 18643 } 18644 }); 18645 $LG(window).on("mousemove.lg.global" + this.lgId, function (e) { 18646 if (isDraging && _this.lgOpened) { 18647 isMoved = true; 18648 endCoords = { 18649 pageX: e.pageX, 18650 pageY: e.pageY, 18651 }; 18652 _this.touchMove(startCoords, endCoords); 18653 _this.LGel.trigger(lGEvents.dragMove); 18654 } 18655 }); 18656 $LG(window).on("mouseup.lg.global" + this.lgId, function (event) { 18657 if (!_this.lgOpened) { 18658 return; 18659 } 18660 var target = $LG(event.target); 18661 if (isMoved) { 18662 isMoved = false; 18663 _this.touchEnd(endCoords, startCoords, event); 18664 _this.LGel.trigger(lGEvents.dragEnd); 18665 } 18666 else if (_this.isPosterElement(target)) { 18667 _this.LGel.trigger(lGEvents.posterClick); 18668 } 18669 // Prevent execution on click 18670 if (isDraging) { 18671 isDraging = false; 18672 _this.outer.removeClass('lg-grabbing').addClass('lg-grab'); 18673 } 18674 }); 18675 } 18676 }; 18677 LightGallery.prototype.triggerPosterClick = function () { 18678 var _this = this; 18679 this.$inner.on('click.lg', function (event) { 18680 if (!_this.dragOrSwipeEnabled && 18681 _this.isPosterElement($LG(event.target))) { 18682 _this.LGel.trigger(lGEvents.posterClick); 18683 } 18684 }); 18685 }; 18686 LightGallery.prototype.manageSwipeClass = function () { 18687 var _touchNext = this.index + 1; 18688 var _touchPrev = this.index - 1; 18689 if (this.settings.loop && this.galleryItems.length > 2) { 18690 if (this.index === 0) { 18691 _touchPrev = this.galleryItems.length - 1; 18692 } 18693 else if (this.index === this.galleryItems.length - 1) { 18694 _touchNext = 0; 18695 } 18696 } 18697 this.outer.find('.lg-item').removeClass('lg-next-slide lg-prev-slide'); 18698 if (_touchPrev > -1) { 18699 this.getSlideItem(_touchPrev).addClass('lg-prev-slide'); 18700 } 18701 this.getSlideItem(_touchNext).addClass('lg-next-slide'); 18702 }; 18703 /** 18704 * Go to next slide 18705 * @param {Boolean} fromTouch - true if slide function called via touch event 18706 * @category lGPublicMethods 18707 * @example 18708 * const plugin = lightGallery(); 18709 * plugin.goToNextSlide(); 18710 * @see <a href="/demos/methods/">Demo</a> 18711 */ 18712 LightGallery.prototype.goToNextSlide = function (fromTouch) { 18713 var _this = this; 18714 var _loop = this.settings.loop; 18715 if (fromTouch && this.galleryItems.length < 3) { 18716 _loop = false; 18717 } 18718 if (!this.lgBusy) { 18719 if (this.index + 1 < this.galleryItems.length) { 18720 this.index++; 18721 this.LGel.trigger(lGEvents.beforeNextSlide, { 18722 index: this.index, 18723 }); 18724 this.slide(this.index, !!fromTouch, false, 'next'); 18725 } 18726 else { 18727 if (_loop) { 18728 this.index = 0; 18729 this.LGel.trigger(lGEvents.beforeNextSlide, { 18730 index: this.index, 18731 }); 18732 this.slide(this.index, !!fromTouch, false, 'next'); 18733 } 18734 else if (this.settings.slideEndAnimation && !fromTouch) { 18735 this.outer.addClass('lg-right-end'); 18736 setTimeout(function () { 18737 _this.outer.removeClass('lg-right-end'); 18738 }, 400); 18739 } 18740 } 18741 } 18742 }; 18743 /** 18744 * Go to previous slides 18745 * @param {Boolean} fromTouch - true if slide function called via touch event 18746 * @category lGPublicMethods 18747 * @example 18748 * const plugin = lightGallery({}); 18749 * plugin.goToPrevSlide(); 18750 * @see <a href="/demos/methods/">Demo</a> 18751 * 18752 */ 18753 LightGallery.prototype.goToPrevSlide = function (fromTouch) { 18754 var _this = this; 18755 var _loop = this.settings.loop; 18756 if (fromTouch && this.galleryItems.length < 3) { 18757 _loop = false; 18758 } 18759 if (!this.lgBusy) { 18760 if (this.index > 0) { 18761 this.index--; 18762 this.LGel.trigger(lGEvents.beforePrevSlide, { 18763 index: this.index, 18764 fromTouch: fromTouch, 18765 }); 18766 this.slide(this.index, !!fromTouch, false, 'prev'); 18767 } 18768 else { 18769 if (_loop) { 18770 this.index = this.galleryItems.length - 1; 18771 this.LGel.trigger(lGEvents.beforePrevSlide, { 18772 index: this.index, 18773 fromTouch: fromTouch, 18774 }); 18775 this.slide(this.index, !!fromTouch, false, 'prev'); 18776 } 18777 else if (this.settings.slideEndAnimation && !fromTouch) { 18778 this.outer.addClass('lg-left-end'); 18779 setTimeout(function () { 18780 _this.outer.removeClass('lg-left-end'); 18781 }, 400); 18782 } 18783 } 18784 } 18785 }; 18786 LightGallery.prototype.keyPress = function () { 18787 var _this = this; 18788 $LG(window).on("keydown.lg.global" + this.lgId, function (e) { 18789 if (_this.lgOpened && 18790 _this.settings.escKey === true && 18791 e.keyCode === 27) { 18792 e.preventDefault(); 18793 if (_this.settings.allowMediaOverlap && 18794 _this.outer.hasClass('lg-can-toggle') && 18795 _this.outer.hasClass('lg-components-open')) { 18796 _this.outer.removeClass('lg-components-open'); 18797 } 18798 else { 18799 _this.closeGallery(); 18800 } 18801 } 18802 if (_this.lgOpened && _this.galleryItems.length > 1) { 18803 if (e.keyCode === 37) { 18804 e.preventDefault(); 18805 _this.goToPrevSlide(); 18806 } 18807 if (e.keyCode === 39) { 18808 e.preventDefault(); 18809 _this.goToNextSlide(); 18810 } 18811 } 18812 }); 18813 }; 18814 LightGallery.prototype.arrow = function () { 18815 var _this = this; 18816 this.getElementById('lg-prev').on('click.lg', function () { 18817 _this.goToPrevSlide(); 18818 }); 18819 this.getElementById('lg-next').on('click.lg', function () { 18820 _this.goToNextSlide(); 18821 }); 18822 }; 18823 LightGallery.prototype.arrowDisable = function (index) { 18824 // Disable arrows if settings.hideControlOnEnd is true 18825 if (!this.settings.loop && this.settings.hideControlOnEnd) { 18826 var $prev = this.getElementById('lg-prev'); 18827 var $next = this.getElementById('lg-next'); 18828 if (index + 1 === this.galleryItems.length) { 18829 $next.attr('disabled', 'disabled').addClass('disabled'); 18830 } 18831 else { 18832 $next.removeAttr('disabled').removeClass('disabled'); 18833 } 18834 if (index === 0) { 18835 $prev.attr('disabled', 'disabled').addClass('disabled'); 18836 } 18837 else { 18838 $prev.removeAttr('disabled').removeClass('disabled'); 18839 } 18840 } 18841 }; 18842 LightGallery.prototype.setTranslate = function ($el, xValue, yValue, scaleX, scaleY) { 18843 if (scaleX === void 0) { scaleX = 1; } 18844 if (scaleY === void 0) { scaleY = 1; } 18845 $el.css('transform', 'translate3d(' + 18846 xValue + 18847 'px, ' + 18848 yValue + 18849 'px, 0px) scale3d(' + 18850 scaleX + 18851 ', ' + 18852 scaleY + 18853 ', 1)'); 18854 }; 18855 LightGallery.prototype.mousewheel = function () { 18856 var _this = this; 18857 var lastCall = 0; 18858 this.outer.on('wheel.lg', function (e) { 18859 if (!e.deltaY || _this.galleryItems.length < 2) { 18860 return; 18861 } 18862 e.preventDefault(); 18863 var now = new Date().getTime(); 18864 if (now - lastCall < 1000) { 18865 return; 18866 } 18867 lastCall = now; 18868 if (e.deltaY > 0) { 18869 _this.goToNextSlide(); 18870 } 18871 else if (e.deltaY < 0) { 18872 _this.goToPrevSlide(); 18873 } 18874 }); 18875 }; 18876 LightGallery.prototype.isSlideElement = function (target) { 18877 return (target.hasClass('lg-outer') || 18878 target.hasClass('lg-item') || 18879 target.hasClass('lg-img-wrap')); 18880 }; 18881 LightGallery.prototype.isPosterElement = function (target) { 18882 var playButton = this.getSlideItem(this.index) 18883 .find('.lg-video-play-button') 18884 .get(); 18885 return (target.hasClass('lg-video-poster') || 18886 target.hasClass('lg-video-play-button') || 18887 (playButton && playButton.contains(target.get()))); 18888 }; 18889 /** 18890 * Maximize minimize inline gallery. 18891 * @category lGPublicMethods 18892 */ 18893 LightGallery.prototype.toggleMaximize = function () { 18894 var _this = this; 18895 this.getElementById('lg-maximize').on('click.lg', function () { 18896 _this.$container.toggleClass('lg-inline'); 18897 _this.refreshOnResize(); 18898 }); 18899 }; 18900 LightGallery.prototype.invalidateItems = function () { 18901 for (var index = 0; index < this.items.length; index++) { 18902 var element = this.items[index]; 18903 var $element = $LG(element); 18904 $element.off("click.lgcustom-item-" + $element.attr('data-lg-id')); 18905 } 18906 }; 18907 LightGallery.prototype.trapFocus = function () { 18908 var _this = this; 18909 this.$container.get().focus({ 18910 preventScroll: true, 18911 }); 18912 $LG(window).on("keydown.lg.global" + this.lgId, function (e) { 18913 if (!_this.lgOpened) { 18914 return; 18915 } 18916 var isTabPressed = e.key === 'Tab' || e.keyCode === 9; 18917 if (!isTabPressed) { 18918 return; 18919 } 18920 var focusableEls = utils.getFocusableElements(_this.$container.get()); 18921 var firstFocusableEl = focusableEls[0]; 18922 var lastFocusableEl = focusableEls[focusableEls.length - 1]; 18923 if (e.shiftKey) { 18924 if (document.activeElement === firstFocusableEl) { 18925 lastFocusableEl.focus(); 18926 e.preventDefault(); 18927 } 18928 } 18929 else { 18930 if (document.activeElement === lastFocusableEl) { 18931 firstFocusableEl.focus(); 18932 e.preventDefault(); 18933 } 18934 } 18935 }); 18936 }; 18937 LightGallery.prototype.manageCloseGallery = function () { 18938 var _this = this; 18939 if (!this.settings.closable) 18940 return; 18941 var mousedown = false; 18942 this.getElementById('lg-close').on('click.lg', function () { 18943 _this.closeGallery(); 18944 }); 18945 if (this.settings.closeOnTap) { 18946 // If you drag the slide and release outside gallery gets close on chrome 18947 // for preventing this check mousedown and mouseup happened on .lg-item or lg-outer 18948 this.outer.on('mousedown.lg', function (e) { 18949 var target = $LG(e.target); 18950 if (_this.isSlideElement(target)) { 18951 mousedown = true; 18952 } 18953 else { 18954 mousedown = false; 18955 } 18956 }); 18957 this.outer.on('mousemove.lg', function () { 18958 mousedown = false; 18959 }); 18960 this.outer.on('mouseup.lg', function (e) { 18961 var target = $LG(e.target); 18962 if (_this.isSlideElement(target) && mousedown) { 18963 if (!_this.outer.hasClass('lg-dragging')) { 18964 _this.closeGallery(); 18965 } 18966 } 18967 }); 18968 } 18969 }; 18970 /** 18971 * Close lightGallery if it is opened. 18972 * 18973 * @description If closable is false in the settings, you need to pass true via closeGallery method to force close gallery 18974 * @return returns the estimated time to close gallery completely including the close animation duration 18975 * @category lGPublicMethods 18976 * @example 18977 * const plugin = lightGallery(); 18978 * plugin.closeGallery(); 18979 * 18980 */ 18981 LightGallery.prototype.closeGallery = function (force) { 18982 var _this = this; 18983 if (!this.lgOpened || (!this.settings.closable && !force)) { 18984 return 0; 18985 } 18986 this.LGel.trigger(lGEvents.beforeClose); 18987 if (this.settings.resetScrollPosition && !this.settings.hideScrollbar) { 18988 $LG(window).scrollTop(this.prevScrollTop); 18989 } 18990 var currentItem = this.items[this.index]; 18991 var transform; 18992 if (this.zoomFromOrigin && currentItem) { 18993 var _a = this.mediaContainerPosition, top_4 = _a.top, bottom = _a.bottom; 18994 var _b = this.galleryItems[this.index], __slideVideoInfo = _b.__slideVideoInfo, poster = _b.poster; 18995 //Uncode edit ##START## 18996 var imageSize = utils.getSize(currentItem, this.outer, top_4 + bottom, __slideVideoInfo && poster && this.settings.videoMaxSize, this.galleryItems[this.index]); 18997 // var imageSize = utils.getSize(currentItem, this.outer, top_4 + bottom, __slideVideoInfo && poster && this.settings.videoMaxSize); 18998 //Uncode edit ##END## 18999 transform = utils.getTransform(currentItem, this.outer, top_4, bottom, imageSize); 19000 } 19001 if (this.zoomFromOrigin && transform) { 19002 this.outer.addClass('lg-closing lg-zoom-from-image'); 19003 this.getSlideItem(this.index) 19004 .addClass('lg-start-end-progress') 19005 .css('transition-duration', this.settings.startAnimationDuration + 'ms') 19006 .css('transform', transform); 19007 } 19008 else { 19009 this.outer.addClass('lg-hide-items'); 19010 // lg-zoom-from-image is used for setting the opacity to 1 if zoomFromOrigin is true 19011 // If the closing item doesn't have the lg-size attribute, remove this class to avoid the closing css conflicts 19012 this.outer.removeClass('lg-zoom-from-image'); 19013 } 19014 // Unbind all events added by lightGallery 19015 // @todo 19016 //this.$el.off('.lg.tm'); 19017 this.destroyModules(); 19018 this.lGalleryOn = false; 19019 this.isDummyImageRemoved = false; 19020 this.zoomFromOrigin = this.settings.zoomFromOrigin; 19021 clearTimeout(this.hideBarTimeout); 19022 this.hideBarTimeout = false; 19023 $LG('html').removeClass('lg-on'); 19024 this.outer.removeClass('lg-visible lg-components-open'); 19025 // Resetting opacity to 0 isd required as vertical swipe to close function adds inline opacity. 19026 this.$backdrop.removeClass('in').css('opacity', 0); 19027 var removeTimeout = this.zoomFromOrigin && transform 19028 ? Math.max(this.settings.startAnimationDuration, this.settings.backdropDuration) 19029 : this.settings.backdropDuration; 19030 this.$container.removeClass('lg-show-in'); 19031 // Once the closign animation is completed and gallery is invisible 19032 setTimeout(function () { 19033 if (_this.zoomFromOrigin && transform) { 19034 _this.outer.removeClass('lg-zoom-from-image'); 19035 } 19036 _this.$container.removeClass('lg-show'); 19037 // Reset scrollbar 19038 _this.resetScrollBar(); 19039 // Need to remove inline opacity as it is used in the stylesheet as well 19040 _this.$backdrop 19041 .removeAttr('style') 19042 .css('transition-duration', _this.settings.backdropDuration + 'ms'); 19043 _this.outer.removeClass("lg-closing " + _this.settings.startClass);
vendor: 6,259 bytes, lines 19044-19247
19044 _this.getSlideItem(_this.index).removeClass('lg-start-end-progress'); 19045 _this.$inner.empty(); 19046 if (_this.lgOpened) { 19047 _this.LGel.trigger(lGEvents.afterClose, { 19048 instance: _this, 19049 }); 19050 } 19051 if (_this.$container.get()) { 19052 _this.$container.get().blur(); 19053 } 19054 _this.lgOpened = false; 19055 }, removeTimeout + 100); 19056 return removeTimeout + 100; 19057 }; 19058 LightGallery.prototype.initModules = function () { 19059 this.plugins.forEach(function (module) { 19060 try { 19061 module.init(); 19062 } 19063 catch (err) { 19064 console.warn("lightGallery:- make sure lightGallery module is properly initiated"); 19065 } 19066 }); 19067 }; 19068 LightGallery.prototype.destroyModules = function (destroy) { 19069 this.plugins.forEach(function (module) { 19070 try { 19071 if (destroy) { 19072 module.destroy(); 19073 } 19074 else { 19075 module.closeGallery && module.closeGallery(); 19076 } 19077 } 19078 catch (err) { 19079 console.warn("lightGallery:- make sure lightGallery module is properly destroyed"); 19080 } 19081 }); 19082 }; 19083 /** 19084 * Refresh lightGallery with new set of children. 19085 * 19086 * @description This is useful to update the gallery when the child elements are changed without calling destroy method. 19087 * 19088 * If you are using dynamic mode, you can pass the modified array of dynamicEl as the first parameter to refresh the dynamic gallery 19089 * @see <a href="/demos/dynamic-mode/">Demo</a> 19090 * @category lGPublicMethods 19091 * @example 19092 * const plugin = lightGallery(); 19093 * // Delete or add children, then call 19094 * plugin.refresh(); 19095 * 19096 */ 19097 LightGallery.prototype.refresh = function (galleryItems) { 19098 if (!this.settings.dynamic) { 19099 this.invalidateItems(); 19100 } 19101 if (galleryItems) { 19102 this.galleryItems = galleryItems; 19103 } 19104 else { 19105 this.galleryItems = this.getItems(); 19106 } 19107 this.updateControls(); 19108 this.openGalleryOnItemClick(); 19109 this.LGel.trigger(lGEvents.updateSlides); 19110 }; 19111 LightGallery.prototype.updateControls = function () { 19112 this.addSlideVideoInfo(this.galleryItems); 19113 this.updateCounterTotal(); 19114 this.manageSingleSlideClassName(); 19115 }; 19116 /** 19117 * Destroy lightGallery. 19118 * Destroy lightGallery and its plugin instances completely 19119 * 19120 * @description This method also calls CloseGallery function internally. Returns the time takes to completely close and destroy the instance. 19121 * In case if you want to re-initialize lightGallery right after destroying it, initialize it only once the destroy process is completed. 19122 * You can use refresh method most of the times. 19123 * @category lGPublicMethods 19124 * @example 19125 * const plugin = lightGallery(); 19126 * plugin.destroy(); 19127 * 19128 */ 19129 LightGallery.prototype.destroy = function () { 19130 var _this = this; 19131 var closeTimeout = this.closeGallery(true); 19132 setTimeout(function () { 19133 _this.destroyModules(true); 19134 if (!_this.settings.dynamic) { 19135 _this.invalidateItems(); 19136 } 19137 $LG(window).off(".lg.global" + _this.lgId); 19138 _this.LGel.off('.lg'); 19139 _this.$container.remove(); 19140 }, closeTimeout); 19141 return closeTimeout; 19142 }; 19143 return LightGallery; 19144 }()); 19145 19146 function lightGallery(el, options) { 19147 return new LightGallery(el, options); 19148 } 19149 19150 return lightGallery; 19151 19152}))); 19153 19154/*! 19155 * lightgallery | 2.5.0 | June 13th 2022 19156 * http://www.lightgalleryjs.com/ 19157 * Copyright (c) 2020 Sachin Neravath; 19158 * @license GPLv3 19159 */ 19160 19161(function (global, factory) { 19162 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 19163 typeof define === 'function' && define.amd ? define(factory) : 19164 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lgZoom = factory()); 19165}(this, (function () { 'use strict'; 19166 19167 /*! ***************************************************************************** 19168 Copyright (c) Microsoft Corporation. 19169 19170 Permission to use, copy, modify, and/or distribute this software for any 19171 purpose with or without fee is hereby granted. 19172 19173 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 19174 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 19175 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 19176 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 19177 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 19178 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 19179 PERFORMANCE OF THIS SOFTWARE. 19180 ***************************************************************************** */ 19181 19182 var __assign = function() { 19183 __assign = Object.assign || function __assign(t) { 19184 for (var s, i = 1, n = arguments.length; i < n; i++) { 19185 s = arguments[i]; 19186 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 19187 } 19188 return t; 19189 }; 19190 return __assign.apply(this, arguments); 19191 }; 19192 19193 var zoomSettings = { 19194 scale: 1, 19195 zoom: true, 19196 actualSize: true, 19197 showZoomInOutIcons: false, 19198 actualSizeIcons: { 19199 zoomIn: 'lg-zoom-in', 19200 zoomOut: 'lg-zoom-out', 19201 }, 19202 enableZoomAfter: 300, 19203 zoomPluginStrings: { 19204 zoomIn: 'Zoom in', 19205 zoomOut: 'Zoom out', 19206 viewActualSize: 'View actual size', 19207 }, 19208 }; 19209 19210 /** 19211 * List of lightGallery events 19212 * All events should be documented here 19213 * Below interfaces are used to build the website documentations 19214 * */ 19215 var lGEvents = { 19216 afterAppendSlide: 'lgAfterAppendSlide', 19217 init: 'lgInit', 19218 hasVideo: 'lgHasVideo', 19219 containerResize: 'lgContainerResize', 19220 updateSlides: 'lgUpdateSlides', 19221 afterAppendSubHtml: 'lgAfterAppendSubHtml', 19222 beforeOpen: 'lgBeforeOpen', 19223 afterOpen: 'lgAfterOpen', 19224 slideItemLoad: 'lgSlideItemLoad', 19225 beforeSlide: 'lgBeforeSlide', 19226 afterSlide: 'lgAfterSlide', 19227 posterClick: 'lgPosterClick', 19228 dragStart: 'lgDragStart', 19229 dragMove: 'lgDragMove', 19230 dragEnd: 'lgDragEnd', 19231 beforeNextSlide: 'lgBeforeNextSlide', 19232 beforePrevSlide: 'lgBeforePrevSlide', 19233 beforeClose: 'lgBeforeClose', 19234 afterClose: 'lgAfterClose', 19235 rotateLeft: 'lgRotateLeft', 19236 rotateRight: 'lgRotateRight', 19237 flipHorizontal: 'lgFlipHorizontal', 19238 flipVertical: 'lgFlipVertical', 19239 autoplay: 'lgAutoplay', 19240 autoplayStart: 'lgAutoplayStart', 19241 autoplayStop: 'lgAutoplayStop', 19242 }; 19243 19244 var Zoom = /** @class */ (function () { 19245 function Zoom(instance, $LG) { 19246 // get lightGallery core plugin instance 19247 this.core = instance;
19248 this.$LG = $LG; 19249 this.settings = __assign(__assign({}, zoomSettings), this.core.settings); 19250 return this; 19251 } 19252 // Append Zoom controls. Actual size, Zoom-in, Zoom-out 19253 Zoom.prototype.buildTemplates = function () { 19254 var zoomIcons = this.settings.showZoomInOutIcons 19255 ? "<button id=\"" + this.core.getIdName('lg-zoom-in') + "\" type=\"button\" aria-label=\"" + this.settings.zoomPluginStrings['zoomIn'] + "\" class=\"lg-zoom-in lg-icon\"></button><button id=\"" + this.core.getIdName('lg-zoom-out') + "\" type=\"button\" aria-label=\"" + this.settings.zoomPluginStrings['zoomIn'] + "\" class=\"lg-zoom-out lg-icon\"></button>" 19256 : ''; 19257 if (this.settings.actualSize) { 19258 zoomIcons += "<button id=\"" + this.core.getIdName('lg-actual-size') + "\" type=\"button\" aria-label=\"" + this.settings.zoomPluginStrings['viewActualSize'] + "\" class=\"" + this.settings.actualSizeIcons.zoomIn + " lg-icon\"></button>"; 19259 } 19260 this.core.outer.addClass('lg-use-transition-for-zoom'); 19261 this.core.$toolbar.first().append(zoomIcons); 19262 }; 19263 /** 19264 * @desc Enable zoom option only once the image is completely loaded 19265 * If zoomFromOrigin is true, Zoom is enabled once the dummy image has been inserted 19266 * 19267 * Zoom styles are defined under lg-zoomable CSS class. 19268 */ 19269 Zoom.prototype.enableZoom = function (event) { 19270 var _this = this; 19271 // delay will be 0 except first time 19272 var _speed = this.settings.enableZoomAfter + event.detail.delay; 19273 // set _speed value 0 if gallery opened from direct url and if it is first slide 19274 if (this.$LG('body').first().hasClass('lg-from-hash') && 19275 event.detail.delay) { 19276 // will execute only once 19277 _speed = 0; 19278 } 19279 else { 19280 // Remove lg-from-hash to enable starting animation. 19281 this.$LG('body').first().removeClass('lg-from-hash'); 19282 } 19283 this.zoomableTimeout = setTimeout(function () { 19284 if (!_this.isImageSlide()) { 19285 return; 19286 } 19287 _this.core.getSlideItem(event.detail.index).addClass('lg-zoomable'); 19288 if (event.detail.index === _this.core.index) { 19289 _this.setZoomEssentials(); 19290 } 19291 }, _speed + 30); 19292 }; 19293 Zoom.prototype.enableZoomOnSlideItemLoad = function () { 19294 // Add zoomable class 19295 this.core.LGel.on(lGEvents.slideItemLoad + ".zoom", this.enableZoom.bind(this)); 19296 }; 19297 Zoom.prototype.getModifier = function (rotateValue, axis, el) { 19298 var originalRotate = rotateValue; 19299 rotateValue = Math.abs(rotateValue); 19300 var transformValues = this.getCurrentTransform(el); 19301 if (!transformValues) { 19302 return 1; 19303 } 19304 var modifier = 1; 19305 if (axis === 'X') { 19306 var flipHorizontalValue = Math.sign(parseFloat(transformValues[0])); 19307 if (rotateValue === 0 || rotateValue === 180) { 19308 modifier = 1; 19309 } 19310 else if (rotateValue === 90) { 19311 if ((originalRotate === -90 && flipHorizontalValue === 1) || 19312 (originalRotate === 90 && flipHorizontalValue === -1)) { 19313 modifier = -1; 19314 } 19315 else { 19316 modifier = 1; 19317 } 19318 } 19319 modifier = modifier * flipHorizontalValue; 19320 } 19321 else { 19322 var flipVerticalValue = Math.sign(parseFloat(transformValues[3])); 19323 if (rotateValue === 0 || rotateValue === 180) { 19324 modifier = 1; 19325 } 19326 else if (rotateValue === 90) { 19327 var sinX = parseFloat(transformValues[1]); 19328 var sinMinusX = parseFloat(transformValues[2]); 19329 modifier = Math.sign(sinX * sinMinusX * originalRotate * flipVerticalValue); 19330 } 19331 modifier = modifier * flipVerticalValue; 19332 } 19333 return modifier; 19334 }; 19335 Zoom.prototype.getImageSize = function ($image, rotateValue, axis) { 19336 var imageSizes = { 19337 y: 'offsetHeight', 19338 x: 'offsetWidth', 19339 }; 19340 if (Math.abs(rotateValue) === 90) { 19341 // Swap axis 19342 if (axis === 'x') { 19343 axis = 'y'; 19344 } 19345 else { 19346 axis = 'x'; 19347 } 19348 } 19349 return $image[imageSizes[axis]]; 19350 }; 19351 Zoom.prototype.getDragCords = function (e, rotateValue) { 19352 if (rotateValue === 90) { 19353 return { 19354 x: e.pageY, 19355 y: e.pageX, 19356 }; 19357 } 19358 else { 19359 return { 19360 x: e.pageX, 19361 y: e.pageY, 19362 }; 19363 } 19364 }; 19365 Zoom.prototype.getSwipeCords = function (e, rotateValue) { 19366 var x = e.targetTouches[0].pageX; 19367 var y = e.targetTouches[0].pageY; 19368 if (rotateValue === 90) { 19369 return { 19370 x: y, 19371 y: x, 19372 }; 19373 } 19374 else { 19375 return { 19376 x: x, 19377 y: y, 19378 }; 19379 } 19380 }; 19381 Zoom.prototype.getDragAllowedAxises = function (rotateValue, scale) { 19382 scale = scale || this.scale || 1; 19383 var allowY = this.imageYSize * scale > this.containerRect.height; 19384 var allowX = this.imageXSize * scale > this.containerRect.width; 19385 if (rotateValue === 90) { 19386 return { 19387 allowX: allowY, 19388 allowY: allowX, 19389 }; 19390 } 19391 else { 19392 return { 19393 allowX: allowX, 19394 allowY: allowY, 19395 }; 19396 } 19397 }; 19398 /** 19399 * 19400 * @param {Element} el 19401 * @return matrix(cos(X), sin(X), -sin(X), cos(X), 0, 0); 19402 * Get the current transform value 19403 */ 19404 Zoom.prototype.getCurrentTransform = function (el) { 19405 if (!el) { 19406 return; 19407 } 19408 var st = window.getComputedStyle(el, null); 19409 var tm = st.getPropertyValue('-webkit-transform') || 19410 st.getPropertyValue('-moz-transform') || 19411 st.getPropertyValue('-ms-transform') || 19412 st.getPropertyValue('-o-transform') || 19413 st.getPropertyValue('transform') || 19414 'none'; 19415 if (tm !== 'none') { 19416 return tm.split('(')[1].split(')')[0].split(','); 19417 } 19418 return; 19419 }; 19420 Zoom.prototype.getCurrentRotation = function (el) { 19421 if (!el) { 19422 return 0; 19423 } 19424 var values = this.getCurrentTransform(el); 19425 if (values) { 19426 return Math.round(Math.atan2(parseFloat(values[1]), parseFloat(values[0])) * 19427 (180 / Math.PI)); 19428 // If you want rotate in 360 19429 //return (angle < 0 ? angle + 360 : angle); 19430 } 19431 return 0; 19432 }; 19433 Zoom.prototype.setZoomEssentials = function () { 19434 var $image = this.core 19435 .getSlideItem(this.core.index) 19436 .find('.lg-image') 19437 .first(); 19438 var rotateEl = this.core 19439 .getSlideItem(this.core.index) 19440 .find('.lg-img-rotate') 19441 .first() 19442 .get(); 19443 this.rotateValue = this.getCurrentRotation(rotateEl); 19444 this.imageYSize = this.getImageSize($image.get(), this.rotateValue, 'y'); 19445 this.imageXSize = this.getImageSize($image.get(), this.rotateValue, 'x'); 19446 this.containerRect = this.core.outer.get().getBoundingClientRect(); 19447 this.modifierX = this.getModifier(this.rotateValue, 'X', rotateEl); 19448 this.modifierY = this.getModifier(this.rotateValue, 'Y', rotateEl); 19449 }; 19450 /** 19451 * @desc Image zoom 19452 * Translate the wrap and scale the image to get better user experience 19453 * 19454 * @param {String} scale - Zoom decrement/increment value 19455 */ 19456 Zoom.prototype.zoomImage = function (scale) { 19457 // Find offset manually to avoid issue after zoom 19458 var offsetX = (this.containerRect.width - this.imageXSize) / 2 + 19459 this.containerRect.left; 19460 var _a = this.core.mediaContainerPosition, top = _a.top, bottom = _a.bottom; 19461 var topBottomSpacing = Math.abs(top - bottom) / 2; 19462 var offsetY = (this.containerRect.height - 19463 this.imageYSize - 19464 topBottomSpacing * this.modifierX) / 19465 2 + 19466 this.scrollTop + 19467 this.containerRect.top; 19468 var originalX; 19469 var originalY; 19470 if (scale === 1) { 19471 this.positionChanged = false;
19472 } 19473 var dragAllowedAxises = this.getDragAllowedAxises(Math.abs(this.rotateValue), scale); 19474 var allowY = dragAllowedAxises.allowY, allowX = dragAllowedAxises.allowX; 19475 if (this.positionChanged) { 19476 originalX = this.left / (this.scale - 1); 19477 originalY = this.top / (this.scale - 1); 19478 this.pageX = Math.abs(originalX) + offsetX; 19479 this.pageY = Math.abs(originalY) + offsetY; 19480 this.positionChanged = false; 19481 } 19482 var possibleSwipeCords = this.getPossibleSwipeDragCords(this.rotateValue, scale); 19483 var _x = offsetX - this.pageX; 19484 var _y = offsetY - this.pageY; 19485 var x = (scale - 1) * _x; 19486 var y = (scale - 1) * _y; 19487 if (allowX) { 19488 if (this.isBeyondPossibleLeft(x, possibleSwipeCords.minX)) { 19489 x = possibleSwipeCords.minX; 19490 } 19491 else if (this.isBeyondPossibleRight(x, possibleSwipeCords.maxX)) { 19492 x = possibleSwipeCords.maxX; 19493 } 19494 } 19495 else { 19496 if (scale > 1) { 19497 if (x < possibleSwipeCords.minX) { 19498 x = possibleSwipeCords.minX; 19499 } 19500 else if (x > possibleSwipeCords.maxX) { 19501 x = possibleSwipeCords.maxX; 19502 } 19503 } 19504 }
19505 if (allowY) { 19506 if (this.isBeyondPossibleTop(y, possibleSwipeCords.minY)) { 19507 y = possibleSwipeCords.minY; 19508 } 19509 else if (this.isBeyondPossibleBottom(y, possibleSwipeCords.maxY)) { 19510 y = possibleSwipeCords.maxY; 19511 } 19512 } 19513 else { 19514 // If the translate value based on index of beyond the viewport, utilize the available space to prevent image being cut out 19515 if (scale > 1) { 19516 //If image goes beyond viewport top, use the minim possible translate value 19517 if (y < possibleSwipeCords.minY) { 19518 y = possibleSwipeCords.minY; 19519 } 19520 else if (y > possibleSwipeCords.maxY) { 19521 y = possibleSwipeCords.maxY; 19522 } 19523 } 19524 } 19525 this.setZoomStyles({ 19526 x: x, 19527 y: y, 19528 scale: scale, 19529 }); 19530 }; 19531 /** 19532 * @desc apply scale3d to image and translate to image wrap 19533 * @param {style} X,Y and scale 19534 */ 19535 Zoom.prototype.setZoomStyles = function (style) { 19536 var $image = this.core 19537 .getSlideItem(this.core.index) 19538 .find('.lg-image') 19539 .first(); 19540 var $dummyImage = this.core.outer 19541 .find('.lg-current .lg-dummy-img') 19542 .first(); 19543 var $imageWrap = $image.parent(); 19544 this.scale = style.scale; 19545 $image.css('transform', 'scale3d(' + style.scale + ', ' + style.scale + ', 1)'); 19546 $dummyImage.css('transform', 'scale3d(' + style.scale + ', ' + style.scale + ', 1)'); 19547 var transform = 'translate3d(' + style.x + 'px, ' + style.y + 'px, 0)'; 19548 $imageWrap.css('transform', transform); 19549 this.left = style.x; 19550 this.top = style.y; 19551 }; 19552 /** 19553 * @param index - Index of the current slide 19554 * @param event - event will be available only if the function is called on clicking/taping the imags 19555 */ 19556 Zoom.prototype.setActualSize = function (index, event) { 19557 var _this = this; 19558 // Allow zoom only on image 19559 if (!this.isImageSlide() || 19560 this.core.outer.hasClass('lg-first-slide-loading')) { 19561 return; 19562 } 19563 var scale = this.getCurrentImageActualSizeScale(); 19564 if (this.core.outer.hasClass('lg-zoomed')) { 19565 this.scale = 1; 19566 } 19567 else { 19568 this.scale = this.getScale(scale); 19569 } 19570 this.setPageCords(event); 19571 this.beginZoom(this.scale); 19572 this.zoomImage(this.scale); 19573 setTimeout(function () { 19574 _this.core.outer.removeClass('lg-grabbing').addClass('lg-grab'); 19575 }, 10); 19576 }; 19577 Zoom.prototype.getNaturalWidth = function (index) { 19578 var $image = this.core.getSlideItem(index).find('.lg-image').first(); 19579 var naturalWidth = this.core.galleryItems[index].width; 19580 return naturalWidth 19581 ? parseFloat(naturalWidth) 19582 : $image.get().naturalWidth; 19583 }; 19584 Zoom.prototype.getActualSizeScale = function (naturalWidth, width) { 19585 var _scale; 19586 var scale;
19587 if (naturalWidth > width) { 19588 _scale = naturalWidth / width; 19589 scale = _scale || 2; 19590 } 19591 else { 19592 scale = 1; 19593 } 19594 return scale; 19595 }; 19596 Zoom.prototype.getCurrentImageActualSizeScale = function () { 19597 var $image = this.core 19598 .getSlideItem(this.core.index) 19599 .find('.lg-image') 19600 .first(); 19601 var width = $image.get().offsetWidth; 19602 var naturalWidth = this.getNaturalWidth(this.core.index) || width; 19603 return this.getActualSizeScale(naturalWidth, width); 19604 }; 19605 Zoom.prototype.getPageCords = function (event) { 19606 var cords = {}; 19607 if (event) { 19608 cords.x = event.pageX || event.targetTouches[0].pageX; 19609 cords.y = event.pageY || event.targetTouches[0].pageY; 19610 } 19611 else { 19612 var containerRect = this.core.outer.get().getBoundingClientRect(); 19613 cords.x = containerRect.width / 2 + containerRect.left; 19614 cords.y = 19615 containerRect.height / 2 + this.scrollTop + containerRect.top; 19616 } 19617 return cords; 19618 }; 19619 Zoom.prototype.setPageCords = function (event) { 19620 var pageCords = this.getPageCords(event); 19621 this.pageX = pageCords.x; 19622 this.pageY = pageCords.y; 19623 }; 19624 // If true, zoomed - in else zoomed out 19625 Zoom.prototype.beginZoom = function (scale) { 19626 this.core.outer.removeClass('lg-zoom-drag-transition lg-zoom-dragging'); 19627 if (scale > 1) { 19628 this.core.outer.addClass('lg-zoomed'); 19629 var $actualSize = this.core.getElementById('lg-actual-size'); 19630 $actualSize 19631 .removeClass(this.settings.actualSizeIcons.zoomIn) 19632 .addClass(this.settings.actualSizeIcons.zoomOut); 19633 } 19634 else { 19635 this.resetZoom(); 19636 } 19637 return scale > 1; 19638 }; 19639 Zoom.prototype.getScale = function (scale) { 19640 var actualSizeScale = this.getCurrentImageActualSizeScale(); 19641 if (scale < 1) { 19642 scale = 1; 19643 } 19644 else if (scale > actualSizeScale) { 19645 scale = actualSizeScale; 19646 } 19647 return scale; 19648 }; 19649 Zoom.prototype.init = function () { 19650 var _this = this; 19651 if (!this.settings.zoom) { 19652 return; 19653 } 19654 this.buildTemplates(); 19655 this.enableZoomOnSlideItemLoad(); 19656 var tapped = null; 19657 this.core.outer.on('dblclick.lg', function (event) { 19658 if (!_this.$LG(event.target).hasClass('lg-image')) { 19659 return; 19660 } 19661 _this.setActualSize(_this.core.index, event); 19662 }); 19663 this.core.outer.on('touchstart.lg', function (event) { 19664 var $target = _this.$LG(event.target); 19665 if (event.targetTouches.length === 1 && 19666 $target.hasClass('lg-image')) { 19667 if (!tapped) { 19668 tapped = setTimeout(function () { 19669 tapped = null; 19670 }, 300); 19671 } 19672 else { 19673 clearTimeout(tapped); 19674 tapped = null; 19675 event.preventDefault(); 19676 _this.setActualSize(_this.core.index, event); 19677 } 19678 } 19679 }); 19680 // Update zoom on resize and orientationchange 19681 this.core.LGel.on(lGEvents.containerResize + ".zoom " + lGEvents.rotateRight + ".zoom " + lGEvents.rotateLeft + ".zoom " + lGEvents.flipHorizontal + ".zoom " + lGEvents.flipVertical + ".zoom", function () { 19682 if (!_this.core.lgOpened || !_this.isImageSlide()) 19683 return; 19684 _this.setPageCords(); 19685 _this.setZoomEssentials(); 19686 _this.zoomImage(_this.scale); 19687 }); 19688 // Update zoom on resize and orientationchange 19689 this.$LG(window).on("scroll.lg.zoom.global" + this.core.lgId, function () { 19690 if (!_this.core.lgOpened) 19691 return; 19692 _this.scrollTop = _this.$LG(window).scrollTop(); 19693 }); 19694 this.core.getElementById('lg-zoom-out').on('click.lg', function () { 19695 if (_this.core.outer.find('.lg-current .lg-image').get()) { 19696 _this.scale -= _this.settings.scale; 19697 _this.scale = _this.getScale(_this.scale); 19698 _this.beginZoom(_this.scale); 19699 _this.zoomImage(_this.scale); 19700 } 19701 }); 19702 this.core.getElementById('lg-zoom-in').on('click.lg', function () { 19703 _this.zoomIn(); 19704 }); 19705 this.core.getElementById('lg-actual-size').on('click.lg', function () { 19706 _this.setActualSize(_this.core.index); 19707 }); 19708 this.core.LGel.on(lGEvents.beforeOpen + ".zoom", function () { 19709 _this.core.outer.find('.lg-item').removeClass('lg-zoomable'); 19710 }); 19711 this.core.LGel.on(lGEvents.afterOpen + ".zoom", function () { 19712 _this.scrollTop = _this.$LG(window).scrollTop(); 19713 // Set the initial value center 19714 _this.pageX = _this.core.outer.width() / 2;
19715 _this.pageY = _this.core.outer.height() / 2 + _this.scrollTop; 19716 _this.scale = 1; 19717 }); 19718 // Reset zoom on slide change 19719 this.core.LGel.on(lGEvents.afterSlide + ".zoom", function (event) { 19720 var prevIndex = event.detail.prevIndex; 19721 _this.scale = 1; 19722 _this.positionChanged = false; 19723 _this.resetZoom(prevIndex); 19724 if (_this.isImageSlide()) { 19725 _this.setZoomEssentials(); 19726 } 19727 }); 19728 // Drag option after zoom 19729 this.zoomDrag(); 19730 this.pinchZoom(); 19731 this.zoomSwipe(); 19732 // Store the zoomable timeout value just to clear it while closing 19733 this.zoomableTimeout = false; 19734 this.positionChanged = false; 19735 }; 19736 Zoom.prototype.zoomIn = function (scale) { 19737 // Allow zoom only on image 19738 if (!this.isImageSlide()) { 19739 return; 19740 } 19741 if (scale) { 19742 this.scale = scale; 19743 } 19744 else { 19745 this.scale += this.settings.scale; 19746 } 19747 this.scale = this.getScale(this.scale); 19748 this.beginZoom(this.scale); 19749 this.zoomImage(this.scale); 19750 }; 19751 // Reset zoom effect 19752 Zoom.prototype.resetZoom = function (index) { 19753 this.core.outer.removeClass('lg-zoomed lg-zoom-drag-transition'); 19754 var $actualSize = this.core.getElementById('lg-actual-size'); 19755 var $item = this.core.getSlideItem(index !== undefined ? index : this.core.index); 19756 $actualSize 19757 .removeClass(this.settings.actualSizeIcons.zoomOut) 19758 .addClass(this.settings.actualSizeIcons.zoomIn); 19759 $item.find('.lg-img-wrap').first().removeAttr('style'); 19760 $item.find('.lg-image').first().removeAttr('style'); 19761 this.scale = 1; 19762 this.left = 0; 19763 this.top = 0; 19764 // Reset pagx pagy values to center 19765 this.setPageCords(); 19766 }; 19767 Zoom.prototype.getTouchDistance = function (e) { 19768 return Math.sqrt((e.targetTouches[0].pageX - e.targetTouches[1].pageX) * 19769 (e.targetTouches[0].pageX - e.targetTouches[1].pageX) + 19770 (e.targetTouches[0].pageY - e.targetTouches[1].pageY) * 19771 (e.targetTouches[0].pageY - e.targetTouches[1].pageY)); 19772 }; 19773 Zoom.prototype.pinchZoom = function () { 19774 var _this = this; 19775 var startDist = 0; 19776 var pinchStarted = false; 19777 var initScale = 1; 19778 var $item = this.core.getSlideItem(this.core.index); 19779 this.core.$inner.on('touchstart.lg', function (e) { 19780 $item = _this.core.getSlideItem(_this.core.index); 19781 if (!_this.isImageSlide()) { 19782 return; 19783 } 19784 if (e.targetTouches.length === 2 && 19785 !_this.core.outer.hasClass('lg-first-slide-loading') && 19786 (_this.$LG(e.target).hasClass('lg-item') || 19787 $item.get().contains(e.target))) { 19788 initScale = _this.scale || 1; 19789 _this.core.outer.removeClass('lg-zoom-drag-transition lg-zoom-dragging'); 19790 _this.core.touchAction = 'pinch'; 19791 startDist = _this.getTouchDistance(e); 19792 } 19793 }); 19794 this.core.$inner.on('touchmove.lg', function (e) { 19795 if (e.targetTouches.length === 2 && 19796 _this.core.touchAction === 'pinch' && 19797 (_this.$LG(e.target).hasClass('lg-item') || 19798 $item.get().contains(e.target))) { 19799 e.preventDefault(); 19800 var endDist = _this.getTouchDistance(e); 19801 var distance = startDist - endDist; 19802 if (!pinchStarted && Math.abs(distance) > 5) { 19803 pinchStarted = true; 19804 } 19805 if (pinchStarted) { 19806 _this.scale = Math.max(1, initScale + -distance * 0.008); 19807 _this.zoomImage(_this.scale); 19808 } 19809 } 19810 }); 19811 this.core.$inner.on('touchend.lg', function (e) { 19812 if (_this.core.touchAction === 'pinch' && 19813 (_this.$LG(e.target).hasClass('lg-item') || 19814 $item.get().contains(e.target))) { 19815 pinchStarted = false; 19816 startDist = 0; 19817 if (_this.scale <= 1) { 19818 _this.resetZoom(); 19819 } 19820 else { 19821 _this.scale = _this.getScale(_this.scale); 19822 _this.zoomImage(_this.scale); 19823 _this.core.outer.addClass('lg-zoomed'); 19824 } 19825 _this.core.touchAction = undefined; 19826 } 19827 }); 19828 }; 19829 Zoom.prototype.touchendZoom = function (startCoords, endCoords, allowX, allowY, touchDuration, rotateValue) { 19830 var distanceXnew = endCoords.x - startCoords.x; 19831 var distanceYnew = endCoords.y - startCoords.y; 19832 var speedX = Math.abs(distanceXnew) / touchDuration + 1; 19833 var speedY = Math.abs(distanceYnew) / touchDuration + 1; 19834 if (speedX > 2) { 19835 speedX += 1; 19836 } 19837 if (speedY > 2) { 19838 speedY += 1; 19839 } 19840 distanceXnew = distanceXnew * speedX; 19841 distanceYnew = distanceYnew * speedY; 19842 var _LGel = this.core 19843 .getSlideItem(this.core.index) 19844 .find('.lg-img-wrap') 19845 .first(); 19846 var distance = {}; 19847 distance.x = this.left + distanceXnew * this.modifierX; 19848 distance.y = this.top + distanceYnew * this.modifierY; 19849 var possibleSwipeCords = this.getPossibleSwipeDragCords(rotateValue); 19850 if (Math.abs(distanceXnew) > 15 || Math.abs(distanceYnew) > 15) { 19851 if (allowY) { 19852 if (this.isBeyondPossibleTop(distance.y, possibleSwipeCords.minY)) { 19853 distance.y = possibleSwipeCords.minY; 19854 } 19855 else if (this.isBeyondPossibleBottom(distance.y, possibleSwipeCords.maxY)) { 19856 distance.y = possibleSwipeCords.maxY; 19857 } 19858 } 19859 if (allowX) { 19860 if (this.isBeyondPossibleLeft(distance.x, possibleSwipeCords.minX)) { 19861 distance.x = possibleSwipeCords.minX; 19862 } 19863 else if (this.isBeyondPossibleRight(distance.x, possibleSwipeCords.maxX)) { 19864 distance.x = possibleSwipeCords.maxX; 19865 } 19866 } 19867 if (allowY) { 19868 this.top = distance.y; 19869 } 19870 else { 19871 distance.y = this.top; 19872 } 19873 if (allowX) { 19874 this.left = distance.x; 19875 } 19876 else { 19877 distance.x = this.left; 19878 } 19879 this.setZoomSwipeStyles(_LGel, distance); 19880 this.positionChanged = true; 19881 } 19882 }; 19883 Zoom.prototype.getZoomSwipeCords = function (startCoords, endCoords, allowX, allowY, possibleSwipeCords) { 19884 var distance = {}; 19885 if (allowY) { 19886 distance.y = 19887 this.top + (endCoords.y - startCoords.y) * this.modifierY; 19888 if (this.isBeyondPossibleTop(distance.y, possibleSwipeCords.minY)) { 19889 var diffMinY = possibleSwipeCords.minY - distance.y; 19890 distance.y = possibleSwipeCords.minY - diffMinY / 6; 19891 } 19892 else if (this.isBeyondPossibleBottom(distance.y, possibleSwipeCords.maxY)) { 19893 var diffMaxY = distance.y - possibleSwipeCords.maxY; 19894 distance.y = possibleSwipeCords.maxY + diffMaxY / 6; 19895 } 19896 } 19897 else { 19898 distance.y = this.top; 19899 }
19900 if (allowX) { 19901 distance.x = 19902 this.left + (endCoords.x - startCoords.x) * this.modifierX; 19903 if (this.isBeyondPossibleLeft(distance.x, possibleSwipeCords.minX)) { 19904 var diffMinX = possibleSwipeCords.minX - distance.x; 19905 distance.x = possibleSwipeCords.minX - diffMinX / 6; 19906 } 19907 else if (this.isBeyondPossibleRight(distance.x, possibleSwipeCords.maxX)) { 19908 var difMaxX = distance.x - possibleSwipeCords.maxX; 19909 distance.x = possibleSwipeCords.maxX + difMaxX / 6; 19910 } 19911 } 19912 else { 19913 distance.x = this.left; 19914 } 19915 return distance; 19916 }; 19917 Zoom.prototype.isBeyondPossibleLeft = function (x, minX) { 19918 return x >= minX; 19919 }; 19920 Zoom.prototype.isBeyondPossibleRight = function (x, maxX) { 19921 return x <= maxX; 19922 }; 19923 Zoom.prototype.isBeyondPossibleTop = function (y, minY) { 19924 return y >= minY; 19925 }; 19926 Zoom.prototype.isBeyondPossibleBottom = function (y, maxY) { 19927 return y <= maxY; 19928 }; 19929 Zoom.prototype.isImageSlide = function () { 19930 var currentItem = this.core.galleryItems[this.core.index]; 19931 return this.core.getSlideType(currentItem) === 'image'; 19932 }; 19933 Zoom.prototype.getPossibleSwipeDragCords = function (rotateValue, scale) { 19934 var dataScale = scale || this.scale || 1; 19935 var elDataScale = Math.abs(dataScale); 19936 var _a = this.core.mediaContainerPosition, top = _a.top, bottom = _a.bottom; 19937 var topBottomSpacing = Math.abs(top - bottom) / 2; 19938 var minY = (this.imageYSize - this.containerRect.height) / 2 + 19939 topBottomSpacing * this.modifierX; 19940 var maxY = this.containerRect.height - this.imageYSize * elDataScale + minY; 19941 var minX = (this.imageXSize - this.containerRect.width) / 2; 19942 var maxX = this.containerRect.width - this.imageXSize * elDataScale + minX; 19943 var possibleSwipeCords = { 19944 minY: minY, 19945 maxY: maxY, 19946 minX: minX, 19947 maxX: maxX, 19948 }; 19949 if (Math.abs(rotateValue) === 90) { 19950 possibleSwipeCords = { 19951 minY: minX, 19952 maxY: maxX, 19953 minX: minY, 19954 maxX: maxY, 19955 }; 19956 } 19957 return possibleSwipeCords; 19958 }; 19959 Zoom.prototype.setZoomSwipeStyles = function (LGel, distance) { 19960 LGel.css('transform', 'translate3d(' + distance.x + 'px, ' + distance.y + 'px, 0)'); 19961 }; 19962 Zoom.prototype.zoomSwipe = function () { 19963 var _this = this; 19964 var startCoords = {}; 19965 var endCoords = {}; 19966 var isMoved = false; 19967 // Allow x direction drag 19968 var allowX = false; 19969 // Allow Y direction drag 19970 var allowY = false; 19971 var startTime = new Date(); 19972 var endTime = new Date(); 19973 var possibleSwipeCords; 19974 var _LGel; 19975 var $item = this.core.getSlideItem(this.core.index); 19976 this.core.$inner.on('touchstart.lg', function (e) { 19977 // Allow zoom only on image 19978 if (!_this.isImageSlide()) { 19979 return; 19980 } 19981 $item = _this.core.getSlideItem(_this.core.index); 19982 if ((_this.$LG(e.target).hasClass('lg-item') || 19983 $item.get().contains(e.target)) && 19984 e.targetTouches.length === 1 && 19985 _this.core.outer.hasClass('lg-zoomed')) { 19986 e.preventDefault(); 19987 startTime = new Date(); 19988 _this.core.touchAction = 'zoomSwipe'; 19989 _LGel = _this.core 19990 .getSlideItem(_this.core.index) 19991 .find('.lg-img-wrap') 19992 .first(); 19993 var dragAllowedAxises = _this.getDragAllowedAxises(Math.abs(_this.rotateValue)); 19994 allowY = dragAllowedAxises.allowY; 19995 allowX = dragAllowedAxises.allowX; 19996 if (allowX || allowY) { 19997 startCoords = _this.getSwipeCords(e, Math.abs(_this.rotateValue)); 19998 } 19999 possibleSwipeCords = _this.getPossibleSwipeDragCords(_this.rotateValue); 20000 // reset opacity and transition duration 20001 _this.core.outer.addClass('lg-zoom-dragging lg-zoom-drag-transition'); 20002 } 20003 }); 20004 this.core.$inner.on('touchmove.lg', function (e) { 20005 if (e.targetTouches.length === 1 && 20006 _this.core.touchAction === 'zoomSwipe' && 20007 (_this.$LG(e.target).hasClass('lg-item') || 20008 $item.get().contains(e.target))) { 20009 e.preventDefault(); 20010 _this.core.touchAction = 'zoomSwipe'; 20011 endCoords = _this.getSwipeCords(e, Math.abs(_this.rotateValue)); 20012 var distance = _this.getZoomSwipeCords(startCoords, endCoords, allowX, allowY, possibleSwipeCords); 20013 if (Math.abs(endCoords.x - startCoords.x) > 15 || 20014 Math.abs(endCoords.y - startCoords.y) > 15) { 20015 isMoved = true; 20016 _this.setZoomSwipeStyles(_LGel, distance); 20017 } 20018 } 20019 }); 20020 this.core.$inner.on('touchend.lg', function (e) { 20021 if (_this.core.touchAction === 'zoomSwipe' && 20022 (_this.$LG(e.target).hasClass('lg-item') || 20023 $item.get().contains(e.target))) { 20024 _this.core.touchAction = undefined; 20025 _this.core.outer.removeClass('lg-zoom-dragging'); 20026 if (!isMoved) { 20027 return; 20028 } 20029 isMoved = false;
20030 endTime = new Date(); 20031 var touchDuration = endTime.valueOf() - startTime.valueOf(); 20032 _this.touchendZoom(startCoords, endCoords, allowX, allowY, touchDuration, _this.rotateValue); 20033 } 20034 }); 20035 }; 20036 Zoom.prototype.zoomDrag = function () { 20037 var _this = this; 20038 var startCoords = {}; 20039 var endCoords = {}; 20040 var isDragging = false; 20041 var isMoved = false; 20042 // Allow x direction drag 20043 var allowX = false; 20044 // Allow Y direction drag 20045 var allowY = false; 20046 var startTime; 20047 var endTime; 20048 var possibleSwipeCords; 20049 var _LGel; 20050 this.core.outer.on('mousedown.lg.zoom', function (e) { 20051 // Allow zoom only on image 20052 if (!_this.isImageSlide()) { 20053 return; 20054 } 20055 var $item = _this.core.getSlideItem(_this.core.index); 20056 if (_this.$LG(e.target).hasClass('lg-item') || 20057 $item.get().contains(e.target)) { 20058 startTime = new Date(); 20059 _LGel = _this.core 20060 .getSlideItem(_this.core.index) 20061 .find('.lg-img-wrap') 20062 .first(); 20063 var dragAllowedAxises = _this.getDragAllowedAxises(Math.abs(_this.rotateValue)); 20064 allowY = dragAllowedAxises.allowY; 20065 allowX = dragAllowedAxises.allowX; 20066 if (_this.core.outer.hasClass('lg-zoomed')) { 20067 if (_this.$LG(e.target).hasClass('lg-object') && 20068 (allowX || allowY)) { 20069 e.preventDefault(); 20070 startCoords = _this.getDragCords(e, Math.abs(_this.rotateValue)); 20071 possibleSwipeCords = _this.getPossibleSwipeDragCords(_this.rotateValue); 20072 isDragging = true; 20073 // ** Fix for webkit cursor issue https://code.google.com/p/chromium/issues/detail?id=26723 20074 _this.core.outer.get().scrollLeft += 1; 20075 _this.core.outer.get().scrollLeft -= 1; 20076 _this.core.outer 20077 .removeClass('lg-grab') 20078 .addClass('lg-grabbing lg-zoom-drag-transition lg-zoom-dragging'); 20079 // reset opacity and transition duration 20080 } 20081 } 20082 } 20083 }); 20084 this.$LG(window).on("mousemove.lg.zoom.global" + this.core.lgId, function (e) { 20085 if (isDragging) { 20086 isMoved = true; 20087 endCoords = _this.getDragCords(e, Math.abs(_this.rotateValue)); 20088 var distance = _this.getZoomSwipeCords(startCoords, endCoords, allowX, allowY, possibleSwipeCords); 20089 _this.setZoomSwipeStyles(_LGel, distance); 20090 } 20091 }); 20092 this.$LG(window).on("mouseup.lg.zoom.global" + this.core.lgId, function (e) { 20093 if (isDragging) { 20094 endTime = new Date(); 20095 isDragging = false; 20096 _this.core.outer.removeClass('lg-zoom-dragging'); 20097 // Fix for chrome mouse move on click 20098 if (isMoved && 20099 (startCoords.x !== endCoords.x || 20100 startCoords.y !== endCoords.y)) { 20101 endCoords = _this.getDragCords(e, Math.abs(_this.rotateValue)); 20102 var touchDuration = endTime.valueOf() - startTime.valueOf(); 20103 _this.touchendZoom(startCoords, endCoords, allowX, allowY, touchDuration, _this.rotateValue); 20104 } 20105 isMoved = false; 20106 } 20107 _this.core.outer.removeClass('lg-grabbing').addClass('lg-grab'); 20108 }); 20109 }; 20110 Zoom.prototype.closeGallery = function () { 20111 this.resetZoom(); 20112 }; 20113 Zoom.prototype.destroy = function () { 20114 // Unbind all events added by lightGallery zoom plugin 20115 this.$LG(window).off(".lg.zoom.global" + this.core.lgId); 20116 this.core.LGel.off('.lg.zoom'); 20117 this.core.LGel.off('.zoom'); 20118 clearTimeout(this.zoomableTimeout); 20119 this.zoomableTimeout = false; 20120 }; 20121 return Zoom; 20122 }()); 20123 20124 return Zoom; 20125 20126}))); 20127/*! 20128 * lightgallery | 2.5.0 | June 13th 2022 20129 * http://www.lightgalleryjs.com/ 20130 * Copyright (c) 2020 Sachin Neravath; 20131 * @license GPLv3 20132 */ 20133 20134(function (global, factory) { 20135 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 20136 typeof define === 'function' && define.amd ? define(factory) : 20137 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lgFullscreen = factory()); 20138}(this, (function () { 'use strict'; 20139 20140 /*! ***************************************************************************** 20141 Copyright (c) Microsoft Corporation. 20142 20143 Permission to use, copy, modify, and/or distribute this software for any 20144 purpose with or without fee is hereby granted. 20145 20146 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 20147 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 20148 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 20149 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 20150 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 20151 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 20152 PERFORMANCE OF THIS SOFTWARE. 20153 ***************************************************************************** */ 20154 20155 var __assign = function() { 20156 __assign = Object.assign || function __assign(t) { 20157 for (var s, i = 1, n = arguments.length; i < n; i++) { 20158 s = arguments[i]; 20159 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 20160 } 20161 return t; 20162 }; 20163 return __assign.apply(this, arguments); 20164 }; 20165 20166 var fullscreenSettings = { 20167 fullScreen: true, 20168 fullscreenPluginStrings: { 20169 toggleFullscreen: 'Toggle Fullscreen', 20170 }, 20171 }; 20172 20173 var FullScreen = /** @class */ (function () { 20174 function FullScreen(instance, $LG) { 20175 // get lightGallery core plugin instance 20176 this.core = instance;
20177 this.$LG = $LG; 20178 // extend module default settings with lightGallery core settings 20179 this.settings = __assign(__assign({}, fullscreenSettings), this.core.settings); 20180 return this; 20181 } 20182 FullScreen.prototype.init = function () { 20183 var fullScreen = ''; 20184 if (this.settings.fullScreen) { 20185 // check for fullscreen browser support 20186 if (!document.fullscreenEnabled && 20187 !document.webkitFullscreenEnabled && 20188 !document.mozFullScreenEnabled && 20189 !document.msFullscreenEnabled) { 20190 return; 20191 } 20192 else { 20193 fullScreen = "<button type=\"button\" aria-label=\"" + this.settings.fullscreenPluginStrings['toggleFullscreen'] + "\" class=\"lg-fullscreen lg-icon\"></button>"; 20194 this.core.$toolbar.append(fullScreen); 20195 this.fullScreen(); 20196 } 20197 } 20198 }; 20199 FullScreen.prototype.isFullScreen = function () { 20200 return (document.fullscreenElement || 20201 document.mozFullScreenElement || 20202 document.webkitFullscreenElement || 20203 document.msFullscreenElement); 20204 }; 20205 FullScreen.prototype.requestFullscreen = function () { 20206 var el = document.documentElement; 20207 if (el.requestFullscreen) { 20208 el.requestFullscreen(); 20209 } 20210 else if (el.msRequestFullscreen) { 20211 el.msRequestFullscreen(); 20212 } 20213 else if (el.mozRequestFullScreen) { 20214 el.mozRequestFullScreen(); 20215 } 20216 else if (el.webkitRequestFullscreen) { 20217 el.webkitRequestFullscreen(); 20218 } 20219 }; 20220 FullScreen.prototype.exitFullscreen = function () { 20221 if (document.exitFullscreen) { 20222 document.exitFullscreen(); 20223 } 20224 else if (document.msExitFullscreen) { 20225 document.msExitFullscreen(); 20226 } 20227 else if (document.mozCancelFullScreen) { 20228 document.mozCancelFullScreen(); 20229 } 20230 else if (document.webkitExitFullscreen) { 20231 document.webkitExitFullscreen(); 20232 } 20233 }; 20234 // https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Using_full_screen_mode 20235 FullScreen.prototype.fullScreen = function () { 20236 var _this = this; 20237 this.$LG(document).on("fullscreenchange.lg.global" + this.core.lgId + " \n webkitfullscreenchange.lg.global" + this.core.lgId + " \n mozfullscreenchange.lg.global" + this.core.lgId + " \n MSFullscreenChange.lg.global" + this.core.lgId, function () { 20238 if (!_this.core.lgOpened) 20239 return; 20240 _this.core.outer.toggleClass('lg-fullscreen-on'); 20241 }); 20242 this.core.outer 20243 .find('.lg-fullscreen') 20244 .first() 20245 .on('click.lg', function () { 20246 if (_this.isFullScreen()) { 20247 _this.exitFullscreen(); 20248 } 20249 else { 20250 _this.requestFullscreen(); 20251 } 20252 }); 20253 }; 20254 FullScreen.prototype.closeGallery = function () { 20255 // exit from fullscreen if activated 20256 if (this.isFullScreen()) { 20257 this.exitFullscreen(); 20258 } 20259 }; 20260 FullScreen.prototype.destroy = function () { 20261 this.$LG(document).off("fullscreenchange.lg.global" + this.core.lgId + " \n webkitfullscreenchange.lg.global" + this.core.lgId + " \n mozfullscreenchange.lg.global" + this.core.lgId + " \n MSFullscreenChange.lg.global" + this.core.lgId); 20262 }; 20263 return FullScreen; 20264 }()); 20265 20266 return FullScreen; 20267 20268}))); 20269 20270/*! 20271 * lightgallery | 2.5.0 | June 13th 2022 20272 * http://www.lightgalleryjs.com/ 20273 * Copyright (c) 2020 Sachin Neravath; 20274 * @license GPLv3 20275 */ 20276 20277(function (global, factory) { 20278 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 20279 typeof define === 'function' && define.amd ? define(factory) : 20280 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lgHash = factory()); 20281}(this, (function () { 'use strict'; 20282 20283 /*! ***************************************************************************** 20284 Copyright (c) Microsoft Corporation. 20285 20286 Permission to use, copy, modify, and/or distribute this software for any 20287 purpose with or without fee is hereby granted. 20288 20289 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 20290 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 20291 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 20292 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 20293 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 20294 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 20295 PERFORMANCE OF THIS SOFTWARE. 20296 ***************************************************************************** */ 20297 20298 var __assign = function() { 20299 __assign = Object.assign || function __assign(t) { 20300 for (var s, i = 1, n = arguments.length; i < n; i++) { 20301 s = arguments[i]; 20302 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 20303 } 20304 return t; 20305 }; 20306 return __assign.apply(this, arguments); 20307 }; 20308 20309 /** 20310 * List of lightGallery events 20311 * All events should be documented here 20312 * Below interfaces are used to build the website documentations 20313 * */ 20314 var lGEvents = { 20315 afterAppendSlide: 'lgAfterAppendSlide', 20316 init: 'lgInit', 20317 hasVideo: 'lgHasVideo', 20318 containerResize: 'lgContainerResize', 20319 updateSlides: 'lgUpdateSlides', 20320 afterAppendSubHtml: 'lgAfterAppendSubHtml', 20321 beforeOpen: 'lgBeforeOpen', 20322 afterOpen: 'lgAfterOpen', 20323 slideItemLoad: 'lgSlideItemLoad', 20324 beforeSlide: 'lgBeforeSlide', 20325 afterSlide: 'lgAfterSlide', 20326 posterClick: 'lgPosterClick', 20327 dragStart: 'lgDragStart', 20328 dragMove: 'lgDragMove', 20329 dragEnd: 'lgDragEnd', 20330 beforeNextSlide: 'lgBeforeNextSlide', 20331 beforePrevSlide: 'lgBeforePrevSlide', 20332 beforeClose: 'lgBeforeClose', 20333 afterClose: 'lgAfterClose', 20334 rotateLeft: 'lgRotateLeft', 20335 rotateRight: 'lgRotateRight', 20336 flipHorizontal: 'lgFlipHorizontal', 20337 flipVertical: 'lgFlipVertical', 20338 autoplay: 'lgAutoplay', 20339 autoplayStart: 'lgAutoplayStart', 20340 autoplayStop: 'lgAutoplayStop', 20341 }; 20342 20343 var hashSettings = { 20344 hash: true, 20345 galleryId: '1', 20346 customSlideName: false, 20347 }; 20348 20349 var Hash = /** @class */ (function () { 20350 function Hash(instance, $LG) { 20351 // get lightGallery core plugin instance 20352 this.core = instance;
20353 this.$LG = $LG; 20354 // extend module default settings with lightGallery core settings 20355 this.settings = __assign(__assign({}, hashSettings), this.core.settings); 20356 return this; 20357 } 20358 Hash.prototype.init = function () { 20359 var _this = this; 20360 if (!this.settings.hash) { 20361 return; 20362 } 20363 this.oldHash = window.location.hash; 20364 setTimeout(function () { 20365 _this.buildFromHash(); 20366 }, 100); 20367 // Change hash value on after each slide transition 20368 this.core.LGel.on(lGEvents.afterSlide + ".hash", this.onAfterSlide.bind(this)); 20369 this.core.LGel.on(lGEvents.afterClose + ".hash", this.onCloseAfter.bind(this)); 20370 // Listen hash change and change the slide according to slide value 20371 this.$LG(window).on("hashchange.lg.hash.global" + this.core.lgId, this.onHashchange.bind(this)); 20372 }; 20373 Hash.prototype.onAfterSlide = function (event) { 20374 var slideName = this.core.galleryItems[event.detail.index].slideName; 20375 slideName = this.settings.customSlideName 20376 ? slideName || event.detail.index 20377 : event.detail.index; 20378 if (history.replaceState) { 20379 history.replaceState(null, '', window.location.pathname + 20380 window.location.search + 20381 '#lg=' + 20382 this.settings.galleryId + 20383 '&slide=' + 20384 slideName); 20385 } 20386 else { 20387 window.location.hash = 20388 'lg=' + this.settings.galleryId + '&slide=' + slideName; 20389 } 20390 }; 20391 /** 20392 * Get index of the slide from custom slideName. Has to be a public method. Used in hash plugin 20393 * @param {String} hash 20394 * @returns {Number} Index of the slide. 20395 */ 20396 Hash.prototype.getIndexFromUrl = function (hash) { 20397 if (hash === void 0) { hash = window.location.hash; } 20398 var slideName = hash.split('&slide=')[1]; 20399 var _idx = 0; 20400 if (this.settings.customSlideName) { 20401 for (var index = 0; index < this.core.galleryItems.length; index++) { 20402 var dynamicEl = this.core.galleryItems[index]; 20403 if (dynamicEl.slideName === slideName) { 20404 _idx = index; 20405 break; 20406 } 20407 } 20408 } 20409 else { 20410 _idx = parseInt(slideName, 10); 20411 } 20412 return isNaN(_idx) ? 0 : _idx; 20413 }; 20414 // Build Gallery if gallery id exist in the URL 20415 Hash.prototype.buildFromHash = function () { 20416 // if dynamic option is enabled execute immediately 20417 var _hash = window.location.hash; 20418 //Uncode edit ##START## 20419 // if (_hash.indexOf('lg=' + this.settings.galleryId) > 0) { 20420 if (_hash.indexOf('lg=' + this.settings.galleryId + '&') > 0) { 20421 //Uncode edit ##END## 20422 // This class is used to remove the initial animation if galleryId present in the URL 20423 this.$LG(document.body).addClass('lg-from-hash'); 20424 var index = this.getIndexFromUrl(_hash); 20425 this.core.openGallery(index); 20426 return true; 20427 } 20428 }; 20429 Hash.prototype.onCloseAfter = function () { 20430 // Reset to old hash value 20431 if (this.oldHash && 20432 this.oldHash.indexOf('lg=' + this.settings.galleryId) < 0) { 20433 if (history.replaceState) { 20434 history.replaceState(null, '', this.oldHash); 20435 } 20436 else { 20437 window.location.hash = this.oldHash; 20438 } 20439 } 20440 else { 20441 if (history.replaceState) { 20442 history.replaceState(null, document.title, window.location.pathname + window.location.search); 20443 } 20444 else { 20445 window.location.hash = ''; 20446 } 20447 } 20448 }; 20449 Hash.prototype.onHashchange = function () { 20450 if (!this.core.lgOpened) 20451 return; 20452 var _hash = window.location.hash; 20453 var index = this.getIndexFromUrl(_hash); 20454 // it galleryId doesn't exist in the url close the gallery 20455 if (_hash.indexOf('lg=' + this.settings.galleryId) > -1) { 20456 this.core.slide(index, false, false); 20457 } 20458 else if (this.core.lGalleryOn) { 20459 this.core.closeGallery(); 20460 } 20461 }; 20462 Hash.prototype.closeGallery = function () { 20463 if (this.settings.hash) { 20464 this.$LG(document.body).removeClass('lg-from-hash'); 20465 } 20466 }; 20467 Hash.prototype.destroy = function () { 20468 this.core.LGel.off('.lg.hash'); 20469 this.core.LGel.off('.hash'); 20470 this.$LG(window).off("hashchange.lg.hash.global" + this.core.lgId); 20471 }; 20472 return Hash; 20473 }()); 20474 20475 return Hash; 20476 20477}))); 20478/*! 20479 * lightgallery | 2.5.0 | June 13th 2022 20480 * http://www.lightgalleryjs.com/ 20481 * Copyright (c) 2020 Sachin Neravath; 20482 * @license GPLv3 20483 */ 20484 20485(function (global, factory) { 20486 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 20487 typeof define === 'function' && define.amd ? define(factory) : 20488 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lgShare = factory()); 20489}(this, (function () { 'use strict'; 20490 20491 /*! ***************************************************************************** 20492 Copyright (c) Microsoft Corporation. 20493 20494 Permission to use, copy, modify, and/or distribute this software for any 20495 purpose with or without fee is hereby granted. 20496 20497 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 20498 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 20499 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 20500 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 20501 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 20502 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 20503 PERFORMANCE OF THIS SOFTWARE. 20504 ***************************************************************************** */ 20505 20506 var __assign = function() { 20507 __assign = Object.assign || function __assign(t) { 20508 for (var s, i = 1, n = arguments.length; i < n; i++) { 20509 s = arguments[i]; 20510 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 20511 } 20512 return t; 20513 }; 20514 return __assign.apply(this, arguments); 20515 }; 20516 20517 function __spreadArrays() { 20518 for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; 20519 for (var r = Array(s), k = 0, i = 0; i < il; i++) 20520 for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) 20521 r[k] = a[j]; 20522 return r; 20523 } 20524 20525 var shareSettings = { 20526 share: true, 20527 facebook: true, 20528 facebookDropdownText: 'Facebook', 20529 twitter: true, 20530 twitterDropdownText: 'Twitter', 20531 pinterest: true, 20532 pinterestDropdownText: 'Pinterest', 20533 additionalShareOptions: [], 20534 sharePluginStrings: { share: 'Share' }, 20535 }; 20536 20537 function getFacebookShareLink(galleryItem) { 20538 var facebookBaseUrl = '//www.facebook.com/sharer/sharer.php?u='; 20539 return (facebookBaseUrl + 20540 encodeURIComponent(galleryItem.facebookShareUrl || window.location.href)); 20541 } 20542 20543 function getTwitterShareLink(galleryItem) { 20544 var twitterBaseUrl = '//twitter.com/intent/tweet?text='; 20545 var url = encodeURIComponent(galleryItem.twitterShareUrl || window.location.href); 20546 var text = galleryItem.tweetText;
20547 return twitterBaseUrl + text + '&url=' + url; 20548 } 20549 20550 function getPinterestShareLink(galleryItem) { 20551 var pinterestBaseUrl = 'http://www.pinterest.com/pin/create/button/?url='; 20552 var description = galleryItem.pinterestText; 20553 var media = encodeURIComponent(galleryItem.src); 20554 var url = encodeURIComponent(galleryItem.pinterestShareUrl || window.location.href); 20555 return (pinterestBaseUrl + 20556 url + 20557 '&media=' + 20558 media + 20559 '&description=' + 20560 description); 20561 } 20562 20563 /** 20564 * List of lightGallery events 20565 * All events should be documented here 20566 * Below interfaces are used to build the website documentations 20567 * */ 20568 var lGEvents = { 20569 afterAppendSlide: 'lgAfterAppendSlide', 20570 init: 'lgInit', 20571 hasVideo: 'lgHasVideo', 20572 containerResize: 'lgContainerResize', 20573 updateSlides: 'lgUpdateSlides', 20574 afterAppendSubHtml: 'lgAfterAppendSubHtml', 20575 beforeOpen: 'lgBeforeOpen', 20576 afterOpen: 'lgAfterOpen', 20577 slideItemLoad: 'lgSlideItemLoad', 20578 beforeSlide: 'lgBeforeSlide', 20579 afterSlide: 'lgAfterSlide', 20580 posterClick: 'lgPosterClick', 20581 dragStart: 'lgDragStart', 20582 dragMove: 'lgDragMove', 20583 dragEnd: 'lgDragEnd', 20584 beforeNextSlide: 'lgBeforeNextSlide', 20585 beforePrevSlide: 'lgBeforePrevSlide', 20586 beforeClose: 'lgBeforeClose', 20587 afterClose: 'lgAfterClose', 20588 rotateLeft: 'lgRotateLeft', 20589 rotateRight: 'lgRotateRight', 20590 flipHorizontal: 'lgFlipHorizontal', 20591 flipVertical: 'lgFlipVertical', 20592 autoplay: 'lgAutoplay', 20593 autoplayStart: 'lgAutoplayStart', 20594 autoplayStop: 'lgAutoplayStop', 20595 }; 20596 20597 var Share = /** @class */ (function () { 20598 function Share(instance) { 20599 this.shareOptions = []; 20600 // get lightGallery core plugin instance 20601 this.core = instance; 20602 // extend module default settings with lightGallery core settings 20603 this.settings = __assign(__assign({}, shareSettings), this.core.settings); 20604 return this; 20605 } 20606 Share.prototype.init = function () { 20607 if (!this.settings.share) { 20608 return; 20609 } 20610 this.shareOptions = __spreadArrays(this.getDefaultShareOptions(), this.settings.additionalShareOptions); 20611 this.setLgShareMarkup(); 20612 this.core.outer 20613 .find('.lg-share .lg-dropdown') 20614 .append(this.getShareListHtml()); 20615 this.core.LGel.on(lGEvents.afterSlide + ".share", this.onAfterSlide.bind(this)); 20616 }; 20617 Share.prototype.getShareListHtml = function () { 20618 var shareHtml = ''; 20619 this.shareOptions.forEach(function (shareOption) { 20620 shareHtml += shareOption.dropdownHTML; 20621 }); 20622 return shareHtml; 20623 }; 20624 Share.prototype.setLgShareMarkup = function () { 20625 var _this = this; 20626 this.core.$toolbar.append("<button type=\"button\" aria-label=\"" + this.settings.sharePluginStrings['share'] + "\" aria-haspopup=\"true\" aria-expanded=\"false\" class=\"lg-share lg-icon\">\n <ul class=\"lg-dropdown\" style=\"position: absolute;\"></ul></button>"); 20627 this.core.outer.append('<div class="lg-dropdown-overlay"></div>'); 20628 var $shareButton = this.core.outer.find('.lg-share'); 20629 $shareButton.first().on('click.lg', function () { 20630 _this.core.outer.toggleClass('lg-dropdown-active'); 20631 if (_this.core.outer.hasClass('lg-dropdown-active')) { 20632 _this.core.outer.attr('aria-expanded', true); 20633 } 20634 else { 20635 _this.core.outer.attr('aria-expanded', false); 20636 } 20637 }); 20638 this.core.outer 20639 .find('.lg-dropdown-overlay') 20640 .first() 20641 .on('click.lg', function () { 20642 _this.core.outer.removeClass('lg-dropdown-active'); 20643 _this.core.outer.attr('aria-expanded', false); 20644 }); 20645 }; 20646 Share.prototype.onAfterSlide = function (event) { 20647 var _this = this; 20648 var index = event.detail.index; 20649 var currentItem = this.core.galleryItems[index]; 20650 setTimeout(function () { 20651 _this.shareOptions.forEach(function (shareOption) { 20652 var selector = shareOption.selector; 20653 _this.core.outer 20654 .find(selector) 20655 .attr('href', shareOption.generateLink(currentItem)); 20656 }); 20657 }, 100); 20658 }; 20659 Share.prototype.getShareListItemHTML = function (type, text) { 20660 return "<li><a class=\"lg-share-" + type + "\" rel=\"noopener\" target=\"_blank\"><span class=\"lg-icon\"></span><span class=\"lg-dropdown-text\">" + text + "</span></a></li>"; 20661 }; 20662 Share.prototype.getDefaultShareOptions = function () { 20663 return __spreadArrays((this.settings.facebook 20664 ? [ 20665 { 20666 type: 'facebook', 20667 generateLink: getFacebookShareLink,
20668 dropdownHTML: this.getShareListItemHTML('facebook', this.settings.facebookDropdownText), 20669 selector: '.lg-share-facebook', 20670 }, 20671 ] 20672 : []), (this.settings.twitter 20673 ? [ 20674 { 20675 type: 'twitter', 20676 generateLink: getTwitterShareLink, 20677 dropdownHTML: this.getShareListItemHTML('twitter', this.settings.twitterDropdownText), 20678 selector: '.lg-share-twitter', 20679 }, 20680 ] 20681 : []), (this.settings.pinterest 20682 ? [ 20683 { 20684 type: 'pinterest', 20685 generateLink: getPinterestShareLink, 20686 dropdownHTML: this.getShareListItemHTML('pinterest', this.settings.pinterestDropdownText), 20687 selector: '.lg-share-pinterest', 20688 }, 20689 ] 20690 : [])); 20691 }; 20692 Share.prototype.destroy = function () { 20693 this.core.outer.find('.lg-dropdown-overlay').remove(); 20694 this.core.outer.find('.lg-share').remove(); 20695 this.core.LGel.off('.lg.share'); 20696 this.core.LGel.off('.share'); 20697 }; 20698 return Share; 20699 }()); 20700 20701 return Share; 20702 20703}))); 20704/*! 20705 * lightgallery | 2.5.0 | June 13th 2022 20706 * http://www.lightgalleryjs.com/ 20707 * Copyright (c) 2020 Sachin Neravath; 20708 * @license GPLv3 20709 */ 20710 20711(function (global, factory) { 20712 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 20713 typeof define === 'function' && define.amd ? define(factory) : 20714 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lgThumbnail = factory()); 20715}(this, (function () { 'use strict'; 20716 20717 /*! ***************************************************************************** 20718 Copyright (c) Microsoft Corporation. 20719 20720 Permission to use, copy, modify, and/or distribute this software for any 20721 purpose with or without fee is hereby granted. 20722 20723 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 20724 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 20725 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 20726 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 20727 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 20728 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 20729 PERFORMANCE OF THIS SOFTWARE. 20730 ***************************************************************************** */ 20731 20732 var __assign = function() { 20733 __assign = Object.assign || function __assign(t) { 20734 for (var s, i = 1, n = arguments.length; i < n; i++) { 20735 s = arguments[i]; 20736 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 20737 } 20738 return t; 20739 }; 20740 return __assign.apply(this, arguments); 20741 }; 20742 20743 var thumbnailsSettings = { 20744 thumbnail: true, 20745 animateThumb: true, 20746 currentPagerPosition: 'middle', 20747 alignThumbnails: 'middle', 20748 thumbWidth: 100, 20749 thumbHeight: '80px', 20750 thumbMargin: 5, 20751 appendThumbnailsTo: '.lg-components', 20752 toggleThumb: false, 20753 enableThumbDrag: true, 20754 enableThumbSwipe: true, 20755 thumbnailSwipeThreshold: 10, 20756 loadYouTubeThumbnail: true, 20757 youTubeThumbSize: 1, 20758 thumbnailPluginStrings: { 20759 toggleThumbnails: 'Toggle thumbnails', 20760 }, 20761 }; 20762 20763 /** 20764 * List of lightGallery events 20765 * All events should be documented here 20766 * Below interfaces are used to build the website documentations 20767 * */ 20768 var lGEvents = { 20769 afterAppendSlide: 'lgAfterAppendSlide', 20770 init: 'lgInit', 20771 hasVideo: 'lgHasVideo', 20772 containerResize: 'lgContainerResize', 20773 updateSlides: 'lgUpdateSlides', 20774 afterAppendSubHtml: 'lgAfterAppendSubHtml', 20775 beforeOpen: 'lgBeforeOpen', 20776 afterOpen: 'lgAfterOpen', 20777 slideItemLoad: 'lgSlideItemLoad', 20778 beforeSlide: 'lgBeforeSlide', 20779 afterSlide: 'lgAfterSlide', 20780 posterClick: 'lgPosterClick', 20781 dragStart: 'lgDragStart', 20782 dragMove: 'lgDragMove', 20783 dragEnd: 'lgDragEnd', 20784 beforeNextSlide: 'lgBeforeNextSlide', 20785 beforePrevSlide: 'lgBeforePrevSlide', 20786 beforeClose: 'lgBeforeClose', 20787 afterClose: 'lgAfterClose', 20788 rotateLeft: 'lgRotateLeft', 20789 rotateRight: 'lgRotateRight', 20790 flipHorizontal: 'lgFlipHorizontal', 20791 flipVertical: 'lgFlipVertical', 20792 autoplay: 'lgAutoplay', 20793 autoplayStart: 'lgAutoplayStart', 20794 autoplayStop: 'lgAutoplayStop', 20795 }; 20796 20797 var Thumbnail = /** @class */ (function () { 20798 function Thumbnail(instance, $LG) { 20799 this.thumbOuterWidth = 0; 20800 this.thumbTotalWidth = 0; 20801 this.translateX = 0; 20802 this.thumbClickable = false;
20803 // get lightGallery core plugin instance 20804 this.core = instance; 20805 this.$LG = $LG; 20806 return this; 20807 } 20808 Thumbnail.prototype.init = function () { 20809 // extend module default settings with lightGallery core settings 20810 this.settings = __assign(__assign({}, thumbnailsSettings), this.core.settings); 20811 this.thumbOuterWidth = 0; 20812 this.thumbTotalWidth = 20813 this.core.galleryItems.length * 20814 (this.settings.thumbWidth + this.settings.thumbMargin); 20815 // Thumbnail animation value 20816 this.translateX = 0; 20817 this.setAnimateThumbStyles(); 20818 if (!this.core.settings.allowMediaOverlap) { 20819 this.settings.toggleThumb = false; 20820 } 20821 if (this.settings.thumbnail) { 20822 this.build(); 20823 if (this.settings.animateThumb) { 20824 if (this.settings.enableThumbDrag) { 20825 this.enableThumbDrag(); 20826 } 20827 if (this.settings.enableThumbSwipe) { 20828 this.enableThumbSwipe(); 20829 } 20830 this.thumbClickable = false; 20831 } 20832 else { 20833 this.thumbClickable = true; 20834 } 20835 this.toggleThumbBar(); 20836 this.thumbKeyPress(); 20837 } 20838 }; 20839 Thumbnail.prototype.build = function () { 20840 var _this = this; 20841 this.setThumbMarkup(); 20842 this.manageActiveClassOnSlideChange(); 20843 this.$lgThumb.first().on('click.lg touchend.lg', function (e) { 20844 var $target = _this.$LG(e.target); 20845 if (!$target.hasAttribute('data-lg-item-id')) { 20846 return; 20847 } 20848 setTimeout(function () { 20849 // In IE9 and bellow touch does not support 20850 // Go to slide if browser does not support css transitions 20851 if (_this.thumbClickable && !_this.core.lgBusy) { 20852 var index = parseInt($target.attr('data-lg-item-id')); 20853 _this.core.slide(index, false, true, false); 20854 } 20855 }, 50); 20856 }); 20857 //Uncode edit ##START## 20858 // this.core.LGel.on(lGEvents.beforeSlide + ".thumb", function (event) { 20859 this.core.LGel.on(lGEvents.beforeSlide, function (event) { 20860 //Uncode edit ##END## 20861 var index = event.detail.index; 20862 _this.animateThumb(index); 20863 }); 20864 //Uncode edit ##START## 20865 // this.core.LGel.on(lGEvents.beforeOpen + ".thumb", function () { 20866 this.core.LGel.on(lGEvents.beforeOpen, function () { 20867 //Uncode edit ##END## 20868 _this.thumbOuterWidth = _this.core.outer.get().offsetWidth; 20869 }); 20870 //Uncode edit ##START## 20871 // this.core.LGel.on(lGEvents.updateSlides + ".thumb", function () { 20872 this.core.LGel.on(lGEvents.updateSlides, function () { 20873 //Uncode edit ##END## 20874 _this.rebuildThumbnails(); 20875 }); 20876 //Uncode edit ##START## 20877 // this.core.LGel.on(lGEvents.containerResize + ".thumb", function () { 20878 this.core.LGel.on(lGEvents.containerResize, function () { 20879 //Uncode edit ##END## 20880 if (!_this.core.lgOpened) 20881 return; 20882 setTimeout(function () { 20883 _this.thumbOuterWidth = _this.core.outer.get().offsetWidth; 20884 _this.animateThumb(_this.core.index); 20885 _this.thumbOuterWidth = _this.core.outer.get().offsetWidth; 20886 }, 50); 20887 }); 20888 }; 20889 Thumbnail.prototype.setThumbMarkup = function () { 20890 var thumbOuterClassNames = 'lg-thumb-outer '; 20891 if (this.settings.alignThumbnails) { 20892 thumbOuterClassNames += "lg-thumb-align-" + this.settings.alignThumbnails; 20893 } 20894 var html = "<div class=\"" + thumbOuterClassNames + "\">\n <div class=\"lg-thumb lg-group\">\n </div>\n </div>"; 20895 this.core.outer.addClass('lg-has-thumb'); 20896 if (this.settings.appendThumbnailsTo === '.lg-components') { 20897 this.core.$lgComponents.append(html); 20898 } 20899 else { 20900 this.core.outer.append(html); 20901 } 20902 this.$thumbOuter = this.core.outer.find('.lg-thumb-outer').first(); 20903 this.$lgThumb = this.core.outer.find('.lg-thumb').first(); 20904 if (this.settings.animateThumb) { 20905 this.core.outer 20906 .find('.lg-thumb') 20907 .css('transition-duration', this.core.settings.speed + 'ms') 20908 .css('width', this.thumbTotalWidth + 'px') 20909 .css('position', 'relative'); 20910 } 20911 this.setThumbItemHtml(this.core.galleryItems); 20912 }; 20913 Thumbnail.prototype.enableThumbDrag = function () { 20914 var _this = this; 20915 var thumbDragUtils = { 20916 cords: { 20917 startX: 0, 20918 endX: 0, 20919 }, 20920 isMoved: false, 20921 newTranslateX: 0, 20922 startTime: new Date(), 20923 endTime: new Date(), 20924 touchMoveTime: 0, 20925 }; 20926 var isDragging = false;
20927 this.$thumbOuter.addClass('lg-grab'); 20928 this.core.outer 20929 .find('.lg-thumb') 20930 .first() 20931 .on('mousedown.lg.thumb', function (e) { 20932 if (_this.thumbTotalWidth > _this.thumbOuterWidth) { 20933 // execute only on .lg-object 20934 e.preventDefault(); 20935 thumbDragUtils.cords.startX = e.pageX; 20936 thumbDragUtils.startTime = new Date(); 20937 _this.thumbClickable = false; 20938 isDragging = true; 20939 // ** Fix for webkit cursor issue https://code.google.com/p/chromium/issues/detail?id=26723 20940 _this.core.outer.get().scrollLeft += 1; 20941 _this.core.outer.get().scrollLeft -= 1; 20942 // * 20943 _this.$thumbOuter 20944 .removeClass('lg-grab') 20945 .addClass('lg-grabbing'); 20946 } 20947 }); 20948 this.$LG(window).on("mousemove.lg.thumb.global" + this.core.lgId, function (e) { 20949 if (!_this.core.lgOpened) 20950 return; 20951 if (isDragging) { 20952 thumbDragUtils.cords.endX = e.pageX; 20953 thumbDragUtils = _this.onThumbTouchMove(thumbDragUtils); 20954 } 20955 }); 20956 this.$LG(window).on("mouseup.lg.thumb.global" + this.core.lgId, function () { 20957 if (!_this.core.lgOpened) 20958 return; 20959 if (thumbDragUtils.isMoved) { 20960 thumbDragUtils = _this.onThumbTouchEnd(thumbDragUtils); 20961 } 20962 else { 20963 _this.thumbClickable = true; 20964 } 20965 if (isDragging) { 20966 isDragging = false; 20967 _this.$thumbOuter.removeClass('lg-grabbing').addClass('lg-grab'); 20968 } 20969 }); 20970 }; 20971 Thumbnail.prototype.enableThumbSwipe = function () { 20972 var _this = this; 20973 var thumbDragUtils = { 20974 cords: { 20975 startX: 0, 20976 endX: 0, 20977 }, 20978 isMoved: false, 20979 newTranslateX: 0, 20980 startTime: new Date(), 20981 endTime: new Date(), 20982 touchMoveTime: 0, 20983 }; 20984 this.$lgThumb.on('touchstart.lg', function (e) { 20985 if (_this.thumbTotalWidth > _this.thumbOuterWidth) { 20986 e.preventDefault(); 20987 thumbDragUtils.cords.startX = e.targetTouches[0].pageX; 20988 _this.thumbClickable = false; 20989 thumbDragUtils.startTime = new Date(); 20990 } 20991 }); 20992 this.$lgThumb.on('touchmove.lg', function (e) { 20993 if (_this.thumbTotalWidth > _this.thumbOuterWidth) { 20994 e.preventDefault(); 20995 thumbDragUtils.cords.endX = e.targetTouches[0].pageX; 20996 thumbDragUtils = _this.onThumbTouchMove(thumbDragUtils); 20997 } 20998 }); 20999 this.$lgThumb.on('touchend.lg', function () { 21000 if (thumbDragUtils.isMoved) { 21001 thumbDragUtils = _this.onThumbTouchEnd(thumbDragUtils); 21002 } 21003 else { 21004 _this.thumbClickable = true; 21005 } 21006 }); 21007 }; 21008 // Rebuild thumbnails 21009 Thumbnail.prototype.rebuildThumbnails = function () { 21010 var _this = this; 21011 // Remove transitions 21012 this.$thumbOuter.addClass('lg-rebuilding-thumbnails'); 21013 setTimeout(function () { 21014 _this.thumbTotalWidth = 21015 _this.core.galleryItems.length * 21016 (_this.settings.thumbWidth + _this.settings.thumbMargin); 21017 _this.$lgThumb.css('width', _this.thumbTotalWidth + 'px'); 21018 _this.$lgThumb.empty(); 21019 _this.setThumbItemHtml(_this.core.galleryItems); 21020 _this.animateThumb(_this.core.index); 21021 }, 50); 21022 setTimeout(function () { 21023 _this.$thumbOuter.removeClass('lg-rebuilding-thumbnails'); 21024 }, 200); 21025 }; 21026 // @ts-check 21027 Thumbnail.prototype.setTranslate = function (value) { 21028 this.$lgThumb.css('transform', 'translate3d(-' + value + 'px, 0px, 0px)'); 21029 }; 21030 Thumbnail.prototype.getPossibleTransformX = function (left) { 21031 if (left > this.thumbTotalWidth - this.thumbOuterWidth) { 21032 left = this.thumbTotalWidth - this.thumbOuterWidth; 21033 } 21034 if (left < 0) { 21035 left = 0; 21036 } 21037 return left; 21038 }; 21039 Thumbnail.prototype.animateThumb = function (index) { 21040 this.$lgThumb.css('transition-duration', this.core.settings.speed + 'ms'); 21041 if (this.settings.animateThumb) { 21042 var position = 0; 21043 switch (this.settings.currentPagerPosition) { 21044 case 'left': 21045 position = 0; 21046 break; 21047 case 'middle': 21048 position = 21049 this.thumbOuterWidth / 2 - this.settings.thumbWidth / 2; 21050 break; 21051 case 'right': 21052 position = this.thumbOuterWidth - this.settings.thumbWidth; 21053 } 21054 this.translateX = 21055 (this.settings.thumbWidth + this.settings.thumbMargin) * index - 21056 1 - 21057 position; 21058 if (this.translateX > this.thumbTotalWidth - this.thumbOuterWidth) { 21059 this.translateX = this.thumbTotalWidth - this.thumbOuterWidth; 21060 } 21061 if (this.translateX < 0) { 21062 this.translateX = 0; 21063 } 21064 this.setTranslate(this.translateX); 21065 } 21066 };
21067 Thumbnail.prototype.onThumbTouchMove = function (thumbDragUtils) { 21068 thumbDragUtils.newTranslateX = this.translateX; 21069 thumbDragUtils.isMoved = true; 21070 thumbDragUtils.touchMoveTime = new Date().valueOf(); 21071 thumbDragUtils.newTranslateX -= 21072 thumbDragUtils.cords.endX - thumbDragUtils.cords.startX; 21073 thumbDragUtils.newTranslateX = this.getPossibleTransformX(thumbDragUtils.newTranslateX); 21074 // move current slide 21075 this.setTranslate(thumbDragUtils.newTranslateX); 21076 this.$thumbOuter.addClass('lg-dragging'); 21077 return thumbDragUtils; 21078 }; 21079 Thumbnail.prototype.onThumbTouchEnd = function (thumbDragUtils) { 21080 thumbDragUtils.isMoved = false; 21081 thumbDragUtils.endTime = new Date(); 21082 this.$thumbOuter.removeClass('lg-dragging'); 21083 var touchDuration = thumbDragUtils.endTime.valueOf() - 21084 thumbDragUtils.startTime.valueOf(); 21085 var distanceXnew = thumbDragUtils.cords.endX - thumbDragUtils.cords.startX; 21086 var speedX = Math.abs(distanceXnew) / touchDuration; 21087 // Some magical numbers 21088 // Can be improved 21089 if (speedX > 0.15 && 21090 thumbDragUtils.endTime.valueOf() - thumbDragUtils.touchMoveTime < 30) { 21091 speedX += 1; 21092 if (speedX > 2) { 21093 speedX += 1; 21094 } 21095 speedX = 21096 speedX + 21097 speedX * (Math.abs(distanceXnew) / this.thumbOuterWidth); 21098 this.$lgThumb.css('transition-duration', Math.min(speedX - 1, 2) + 'settings'); 21099 distanceXnew = distanceXnew * speedX; 21100 this.translateX = this.getPossibleTransformX(this.translateX - distanceXnew); 21101 this.setTranslate(this.translateX); 21102 } 21103 else { 21104 this.translateX = thumbDragUtils.newTranslateX; 21105 } 21106 if (Math.abs(thumbDragUtils.cords.endX - thumbDragUtils.cords.startX) < 21107 this.settings.thumbnailSwipeThreshold) { 21108 this.thumbClickable = true; 21109 } 21110 return thumbDragUtils; 21111 }; 21112 Thumbnail.prototype.getThumbHtml = function (thumb, index) { 21113 var slideVideoInfo = this.core.galleryItems[index].__slideVideoInfo || {}; 21114 var thumbImg; 21115 if (slideVideoInfo.youtube) { 21116 if (this.settings.loadYouTubeThumbnail) { 21117 thumbImg = 21118 '//img.youtube.com/vi/' + 21119 slideVideoInfo.youtube[1] + 21120 '/' + 21121 this.settings.youTubeThumbSize + 21122 '.jpg'; 21123 } 21124 else { 21125 thumbImg = thumb; 21126 } 21127 } 21128 else { 21129 thumbImg = thumb; 21130 } 21131 return "<div data-lg-item-id=\"" + index + "\" class=\"lg-thumb-item " + (index === this.core.index ? ' active' : '') + "\" \n style=\"width:" + this.settings.thumbWidth + "px; height: " + this.settings.thumbHeight + ";\n margin-right: " + this.settings.thumbMargin + "px;\">\n <img data-lg-item-id=\"" + index + "\" src=\"" + thumbImg + "\" />\n </div>"; 21132 }; 21133 Thumbnail.prototype.getThumbItemHtml = function (items) { 21134 var thumbList = ''; 21135 for (var i = 0; i < items.length; i++) { 21136 thumbList += this.getThumbHtml(items[i].thumb, i); 21137 } 21138 return thumbList; 21139 }; 21140 Thumbnail.prototype.setThumbItemHtml = function (items) { 21141 var thumbList = this.getThumbItemHtml(items); 21142 this.$lgThumb.html(thumbList); 21143 }; 21144 Thumbnail.prototype.setAnimateThumbStyles = function () { 21145 if (this.settings.animateThumb) { 21146 this.core.outer.addClass('lg-animate-thumb'); 21147 } 21148 }; 21149 // Manage thumbnail active calss
21150 Thumbnail.prototype.manageActiveClassOnSlideChange = function () { 21151 var _this = this; 21152 // manage active class for thumbnail 21153 //Uncode edit ##START## 21154 // this.core.LGel.on(lGEvents.beforeSlide + ".thumb", function (event) { 21155 this.core.LGel.on(lGEvents.beforeSlide, function (event) { 21156 //Uncode edit ##END## 21157 var $thumb = _this.core.outer.find('.lg-thumb-item'); 21158 var index = event.detail.index; 21159 $thumb.removeClass('active'); 21160 $thumb.eq(index).addClass('active'); 21161 }); 21162 }; 21163 // Toggle thumbnail bar 21164 Thumbnail.prototype.toggleThumbBar = function () { 21165 var _this = this; 21166 if (this.settings.toggleThumb) { 21167 this.core.outer.addClass('lg-can-toggle'); 21168 this.core.$toolbar.append('<button type="button" aria-label="' + 21169 this.settings.thumbnailPluginStrings['toggleThumbnails'] + 21170 '" class="lg-toggle-thumb lg-icon"></button>'); 21171 this.core.outer 21172 .find('.lg-toggle-thumb') 21173 .first() 21174 .on('click.lg', function () { 21175 _this.core.outer.toggleClass('lg-components-open'); 21176 }); 21177 } 21178 }; 21179 Thumbnail.prototype.thumbKeyPress = function () { 21180 var _this = this; 21181 this.$LG(window).on("keydown.lg.thumb.global" + this.core.lgId, function (e) { 21182 if (!_this.core.lgOpened || !_this.settings.toggleThumb) 21183 return; 21184 if (e.keyCode === 38) { 21185 e.preventDefault(); 21186 _this.core.outer.addClass('lg-components-open'); 21187 } 21188 else if (e.keyCode === 40) { 21189 e.preventDefault(); 21190 _this.core.outer.removeClass('lg-components-open'); 21191 } 21192 }); 21193 }; 21194 Thumbnail.prototype.destroy = function () { 21195 if (this.settings.thumbnail) { 21196 this.$LG(window).off(".lg.thumb.global" + this.core.lgId); 21197 this.core.LGel.off('.lg.thumb'); 21198 this.core.LGel.off('.thumb'); 21199 this.$thumbOuter.remove(); 21200 this.core.outer.removeClass('lg-has-thumb'); 21201 } 21202 }; 21203 return Thumbnail; 21204 }()); 21205 21206 return Thumbnail; 21207 21208}))); 21209/*! 21210 * lightgallery | 2.5.0 | June 13th 2022 21211 * http://www.lightgalleryjs.com/ 21212 * Copyright (c) 2020 Sachin Neravath; 21213 * @license GPLv3 21214 */ 21215 21216(function (global, factory) { 21217 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 21218 typeof define === 'function' && define.amd ? define(factory) : 21219 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lgVideo = factory()); 21220}(this, (function () { 'use strict'; 21221 21222 /*! ***************************************************************************** 21223 Copyright (c) Microsoft Corporation. 21224 21225 Permission to use, copy, modify, and/or distribute this software for any 21226 purpose with or without fee is hereby granted. 21227 21228 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 21229 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 21230 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 21231 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 21232 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 21233 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 21234 PERFORMANCE OF THIS SOFTWARE. 21235 ***************************************************************************** */ 21236 21237 var __assign = function() { 21238 __assign = Object.assign || function __assign(t) { 21239 for (var s, i = 1, n = arguments.length; i < n; i++) { 21240 s = arguments[i]; 21241 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 21242 } 21243 return t; 21244 }; 21245 return __assign.apply(this, arguments); 21246 }; 21247 21248 var videoSettings = { 21249 autoplayFirstVideo: true, 21250 youTubePlayerParams: false, 21251 vimeoPlayerParams: false, 21252 wistiaPlayerParams: false, 21253 gotoNextSlideOnVideoEnd: true, 21254 autoplayVideoOnSlide: false, 21255 videojs: false, 21256 videojsTheme: '', 21257 videojsOptions: {}, 21258 }; 21259 21260 /** 21261 * List of lightGallery events 21262 * All events should be documented here 21263 * Below interfaces are used to build the website documentations 21264 * */ 21265 var lGEvents = { 21266 afterAppendSlide: 'lgAfterAppendSlide', 21267 init: 'lgInit', 21268 hasVideo: 'lgHasVideo', 21269 containerResize: 'lgContainerResize', 21270 updateSlides: 'lgUpdateSlides', 21271 afterAppendSubHtml: 'lgAfterAppendSubHtml', 21272 beforeOpen: 'lgBeforeOpen', 21273 afterOpen: 'lgAfterOpen', 21274 slideItemLoad: 'lgSlideItemLoad', 21275 beforeSlide: 'lgBeforeSlide', 21276 afterSlide: 'lgAfterSlide', 21277 posterClick: 'lgPosterClick', 21278 dragStart: 'lgDragStart', 21279 dragMove: 'lgDragMove', 21280 dragEnd: 'lgDragEnd', 21281 beforeNextSlide: 'lgBeforeNextSlide', 21282 beforePrevSlide: 'lgBeforePrevSlide', 21283 beforeClose: 'lgBeforeClose', 21284 afterClose: 'lgAfterClose', 21285 rotateLeft: 'lgRotateLeft', 21286 rotateRight: 'lgRotateRight', 21287 flipHorizontal: 'lgFlipHorizontal', 21288 flipVertical: 'lgFlipVertical', 21289 autoplay: 'lgAutoplay', 21290 autoplayStart: 'lgAutoplayStart', 21291 autoplayStop: 'lgAutoplayStop', 21292 }; 21293 21294 var param = function (obj) { 21295 return Object.keys(obj) 21296 .map(function (k) { 21297 return encodeURIComponent(k) + '=' + encodeURIComponent(obj[k]); 21298 }) 21299 .join('&'); 21300 }; 21301 var getVimeoURLParams = function (defaultParams, videoInfo) { 21302 if (!videoInfo || !videoInfo.vimeo) 21303 return '';
21304 var urlParams = videoInfo.vimeo[2] || ''; 21305 var defaultPlayerParams = defaultParams && Object.keys(defaultParams).length !== 0 21306 ? '&' + param(defaultParams) 21307 : ''; 21308 // Support private video 21309 var urlWithHash = videoInfo.vimeo[0].split('/').pop() || ''; 21310 var urlWithHashWithParams = urlWithHash.split('?')[0] || ''; 21311 var hash = urlWithHashWithParams.split('#')[0]; 21312 var isPrivate = videoInfo.vimeo[1] !== hash; 21313 if (isPrivate) { 21314 urlParams = urlParams.replace("/" + hash, ''); 21315 } 21316 urlParams = 21317 urlParams[0] == '?' ? '&' + urlParams.slice(1) : urlParams || ''; 21318 // For vimeo last params gets priority if duplicates found 21319 // Uncode edit ##START## 21320 var vimeoPlayerParams = '?autoplay=0'; 21321 if ( typeof SiteParameters !== 'undefined' && typeof SiteParameters.vimeoPlayerParams !== 'undefined' && SiteParameters.vimeoPlayerParams !== '' ) { 21322 vimeoPlayerParams = SiteParameters.vimeoPlayerParams; 21323 } 21324 if ( urlParams.indexOf('muted=') < 0 && vimeoPlayerParams.indexOf('muted=') < 0 ) { 21325 vimeoPlayerParams += '&muted=1'; 21326 } 21327 // var vimeoPlayerParams = "?autoplay=0&muted=1" + (isPrivate ? "&h=" + hash : '') + defaultPlayerParams + urlParams; 21328 vimeoPlayerParams += (isPrivate ? "&h=" + hash : '') + defaultPlayerParams + urlParams; 21329 // Uncode edit ##END## 21330 return vimeoPlayerParams; 21331 }; 21332 21333 /** 21334 * Video module for lightGallery 21335 * Supports HTML5, YouTube, Vimeo, wistia videos 21336 * 21337 * 21338 * @ref Wistia 21339 * https://wistia.com/support/integrations/wordpress(How to get url) 21340 * https://wistia.com/support/developers/embed-options#using-embed-options 21341 * https://wistia.com/support/developers/player-api 21342 * https://wistia.com/support/developers/construct-an-embed-code 21343 * http://jsfiddle.net/xvnm7xLm/ 21344 * https://developer.mozilla.org/en-US/docs/Web/HTML/Element/video 21345 * https://wistia.com/support/embed-and-share/sharing-videos 21346 * https://private-sharing.wistia.com/medias/mwhrulrucj 21347 * 21348 * @ref Youtube 21349 * https://developers.google.com/youtube/player_parameters#enablejsapi 21350 * https://developers.google.com/youtube/iframe_api_reference 21351 * https://developer.chrome.com/blog/autoplay/#iframe-delegation 21352 * 21353 * @ref Vimeo 21354 * https://stackoverflow.com/questions/10488943/easy-way-to-get-vimeo-id-from-a-vimeo-url 21355 * https://vimeo.zendesk.com/hc/en-us/articles/360000121668-Starting-playback-at-a-specific-timecode 21356 * https://vimeo.zendesk.com/hc/en-us/articles/360001494447-Using-Player-Parameters 21357 */ 21358 var Video = /** @class */ (function () { 21359 function Video(instance) { 21360 // get lightGallery core plugin instance 21361 this.core = instance; 21362 this.settings = __assign(__assign({}, videoSettings), this.core.settings); 21363 return this; 21364 } 21365 Video.prototype.init = function () { 21366 var _this = this; 21367 /** 21368 * Event triggered when video url found without poster 21369 * Append video HTML 21370 * Play if autoplayFirstVideo is true 21371 */ 21372 this.core.LGel.on(lGEvents.hasVideo + ".video", this.onHasVideo.bind(this)); 21373 this.core.LGel.on(lGEvents.posterClick + ".video", function () { 21374 var $el = _this.core.getSlideItem(_this.core.index); 21375 _this.loadVideoOnPosterClick($el); 21376 }); 21377 this.core.LGel.on(lGEvents.slideItemLoad + ".video", this.onSlideItemLoad.bind(this)); 21378 // @desc fired immediately before each slide transition. 21379 this.core.LGel.on(lGEvents.beforeSlide + ".video", this.onBeforeSlide.bind(this)); 21380 // @desc fired immediately after each slide transition. 21381 this.core.LGel.on(lGEvents.afterSlide + ".video", this.onAfterSlide.bind(this)); 21382 }; 21383 /** 21384 * @desc Event triggered when a slide is completely loaded 21385 * 21386 * @param {Event} event - lightGalley custom event 21387 */ 21388 Video.prototype.onSlideItemLoad = function (event) { 21389 var _this = this; 21390 var _a = event.detail, isFirstSlide = _a.isFirstSlide, index = _a.index; 21391 // Should check the active slide as well as user may have moved to different slide before the first slide is loaded 21392 if (this.settings.autoplayFirstVideo && 21393 isFirstSlide && 21394 index === this.core.index) { 21395 // Delay is just for the transition effect on video load 21396 setTimeout(function () { 21397 _this.loadAndPlayVideo(index); 21398 }, 200); 21399 } 21400 // Should not call on first slide. should check only if the slide is active 21401 if (!isFirstSlide && 21402 this.settings.autoplayVideoOnSlide && 21403 index === this.core.index) { 21404 this.loadAndPlayVideo(index); 21405 } 21406 }; 21407 /** 21408 * @desc Event triggered when video url or poster found 21409 * Append video HTML is poster is not given 21410 * Play if autoplayFirstVideo is true 21411 * 21412 * @param {Event} event - Javascript Event object. 21413 */ 21414 Video.prototype.onHasVideo = function (event) { 21415 var _a = event.detail, index = _a.index, src = _a.src, html5Video = _a.html5Video, hasPoster = _a.hasPoster; 21416 if (!hasPoster) { 21417 // All functions are called separately if poster exist in loadVideoOnPosterClick function 21418 this.appendVideos(this.core.getSlideItem(index), { 21419 src: src, 21420 addClass: 'lg-object', 21421 index: index, 21422 html5Video: html5Video, 21423 }); 21424 // Automatically navigate to next slide once video reaches the end. 21425 this.gotoNextSlideOnVideoEnd(src, index); 21426 } 21427 }; 21428 /** 21429 * @desc fired immediately before each slide transition. 21430 * Pause the previous video 21431 * Hide the download button if the slide contains YouTube, Vimeo, or Wistia videos. 21432 * 21433 * @param {Event} event - Javascript Event object. 21434 * @param {number} prevIndex - Previous index of the slide. 21435 * @param {number} index - Current index of the slide 21436 */ 21437 Video.prototype.onBeforeSlide = function (event) { 21438 if (this.core.lGalleryOn) { 21439 var prevIndex = event.detail.prevIndex; 21440 this.pauseVideo(prevIndex); 21441 } 21442 // Uncode edit ##START## 21443 var _a = event.detail, index = _a.index, src = _a.info.src; 21444 if ( typeof src !== 'undefined' && src.indexOf("autoplay") > -1 ) { 21445 this.loadAndPlayVideo(index); 21446 21447 var videoInfo = this.core.galleryItems[index].__slideVideoInfo || {}, 21448 $videoElement = this.core.getSlideItem(index).find('.lg-video-object').first(); 21449 if (videoInfo.vimeo) { 21450 var vimeoPlayer = new Vimeo.Player($videoElement.get()); 21451 vimeoPlayer.on('play', function () { 21452 vimeoPlayer.setCurrentTime(0); 21453 }); 21454 } else if ( videoInfo.youtube ) { 21455 try { 21456 $videoElement.get().contentWindow.postMessage("{\"event\":\"command\",\"func\":\"seekTo\",\"args\":[0, true]}", '*'); 21457 } 21458 catch (e) { 21459 console.warn(e); 21460 } 21461 } 21462 } 21463 // Uncode edit ##END## 21464 }; 21465 /** 21466 * @desc fired immediately after each slide transition. 21467 * Play video if autoplayVideoOnSlide option is enabled. 21468 * 21469 * @param {Event} event - Javascript Event object. 21470 * @param {number} prevIndex - Previous index of the slide. 21471 * @param {number} index - Current index of the slide 21472 * @todo should check on onSlideLoad as well if video is not loaded on after slide 21473 */ 21474 Video.prototype.onAfterSlide = function (event) { 21475 var _this = this; 21476 var _a = event.detail, index = _a.index, prevIndex = _a.prevIndex;
21477 // Do not call on first slide 21478 var $slide = this.core.getSlideItem(index); 21479 if (this.settings.autoplayVideoOnSlide && index !== prevIndex) { 21480 if ($slide.hasClass('lg-complete')) { 21481 setTimeout(function () { 21482 _this.loadAndPlayVideo(index); 21483 }, 100); 21484 } 21485 } 21486 }; 21487 Video.prototype.loadAndPlayVideo = function (index) { 21488 var $slide = this.core.getSlideItem(index); 21489 var currentGalleryItem = this.core.galleryItems[index]; 21490 if (currentGalleryItem.poster) { 21491 this.loadVideoOnPosterClick($slide, true); 21492 } 21493 else { 21494 //Uncode edit ##START## 21495 // this.playVideo(index); 21496 var src = currentGalleryItem.src; 21497 if ( typeof src !== 'undefined' && src.indexOf("autoplay") > -1) { 21498 if ( this.core.index == index ) { 21499 this.playVideo(index); 21500 } else { 21501 this.pauseVideo(index); 21502 } 21503 } 21504 //Uncode edit ##END## 21505 } 21506 }; 21507 /** 21508 * Play HTML5, Youtube, Vimeo or Wistia videos in a particular slide. 21509 * @param {number} index - Index of the slide 21510 */ 21511 Video.prototype.playVideo = function (index) { 21512 this.controlVideo(index, 'play'); 21513 }; 21514 /** 21515 * Pause HTML5, Youtube, Vimeo or Wistia videos in a particular slide. 21516 * @param {number} index - Index of the slide 21517 */ 21518 Video.prototype.pauseVideo = function (index) { 21519 this.controlVideo(index, 'pause'); 21520 }; 21521 Video.prototype.getVideoHtml = function (src, addClass, index, html5Video) { 21522 var video = ''; 21523 var videoInfo = this.core.galleryItems[index] 21524 .__slideVideoInfo || {}; 21525 var currentGalleryItem = this.core.galleryItems[index]; 21526 var videoTitle = currentGalleryItem.title || currentGalleryItem.alt; 21527 videoTitle = videoTitle ? 'title="' + videoTitle + '"' : ''; 21528 var commonIframeProps = "allowtransparency=\"true\"\n frameborder=\"0\"\n scrolling=\"no\"\n allowfullscreen\n mozallowfullscreen\n webkitallowfullscreen\n oallowfullscreen\n msallowfullscreen"; 21529 if (videoInfo.youtube) { 21530 var videoId = 'lg-youtube' + index; 21531 var slideUrlParams = videoInfo.youtube[2] 21532 ? videoInfo.youtube[2] + '&' 21533 : ''; 21534 // For youtube first parms gets priority if duplicates found 21535 // Uncode edit ##START## 21536 // var youTubePlayerParams = "?" + slideUrlParams + "wmode=opaque&autoplay=0&mute=1&enablejsapi=1"; 21537 var youTubePlayerParams = "?" + slideUrlParams + "wmode=opaque&enablejsapi=1"; 21538 if ( slideUrlParams.indexOf('autoplay=') < 0 && youTubePlayerParams.indexOf('autoplay=') < 0 ) { 21539 youTubePlayerParams += '&autoplay=0'; 21540 } 21541 if ( slideUrlParams.indexOf('mute=') < 0 && youTubePlayerParams.indexOf('mute=') < 0 ) { 21542 youTubePlayerParams += '&mute=1'; 21543 } 21544 // Uncode edit ##END## 21545 var playerParams = youTubePlayerParams + 21546 (this.settings.youTubePlayerParams 21547 ? '&' + param(this.settings.youTubePlayerParams) 21548 : ''); 21549 video = "<iframe allow=\"autoplay\" id=" + videoId + " class=\"lg-video-object lg-youtube " + addClass + "\" " + videoTitle + " src=\"//www.youtube.com/embed/" + (videoInfo.youtube[1] + playerParams) + "\" " + commonIframeProps + "></iframe>"; 21550 } 21551 else if (videoInfo.vimeo) { 21552 var videoId = 'lg-vimeo' + index; 21553 var playerParams = getVimeoURLParams(this.settings.vimeoPlayerParams, videoInfo); 21554 video = "<iframe allow=\"autoplay\" id=" + videoId + " class=\"lg-video-object lg-vimeo " + addClass + "\" " + videoTitle + " src=\"//player.vimeo.com/video/" + (videoInfo.vimeo[1] + playerParams) + "\" " + commonIframeProps + "></iframe>"; 21555 } 21556 else if (videoInfo.wistia) { 21557 var wistiaId = 'lg-wistia' + index; 21558 var playerParams = param(this.settings.wistiaPlayerParams); 21559 playerParams = playerParams ? '?' + playerParams : ''; 21560 video = "<iframe allow=\"autoplay\" id=\"" + wistiaId + "\" src=\"//fast.wistia.net/embed/iframe/" + (videoInfo.wistia[4] + playerParams) + "\" " + videoTitle + " class=\"wistia_embed lg-video-object lg-wistia " + addClass + "\" name=\"wistia_embed\" " + commonIframeProps + "></iframe>"; 21561 } 21562 else if (videoInfo.html5) { 21563 var html5VideoMarkup = ''; 21564 for (var i = 0; i < html5Video.source.length; i++) { 21565 html5VideoMarkup += "<source src=\"" + html5Video.source[i].src + "\" type=\"" + html5Video.source[i].type + "\">"; 21566 } 21567 if (html5Video.tracks) { 21568 var _loop_1 = function (i) { 21569 var trackAttributes = ''; 21570 var track = html5Video.tracks[i]; 21571 Object.keys(track || {}
21571).forEach(function (key) { 21572 trackAttributes += key + "=\"" + track[key] + "\" "; 21573 }); 21574 html5VideoMarkup += "<track " + trackAttributes + ">"; 21575 }; 21576 for (var i = 0; i < html5Video.tracks.length; i++) { 21577 _loop_1(i); 21578 } 21579 } 21580 var html5VideoAttrs_1 = ''; 21581 var videoAttributes_1 = html5Video.attributes || {}; 21582 Object.keys(videoAttributes_1 || {}).forEach(function (key) { 21583 html5VideoAttrs_1 += key + "=\"" + videoAttributes_1[key] + "\" "; 21584 }); 21585 video = "<video class=\"lg-video-object lg-html5 " + (this.settings.videojs && this.settings.videojsTheme 21586 ? this.settings.videojsTheme + ' ' 21587 : '') + " " + (this.settings.videojs ? ' video-js' : '') + "\" " + html5VideoAttrs_1 + ">\n " + html5VideoMarkup + "\n Your browser does not support HTML5 video.\n </video>"; 21588 } 21589 return video; 21590 }; 21591 /** 21592 * @desc - Append videos to the slide 21593 * 21594 * @param {HTMLElement} el - slide element 21595 * @param {Object} videoParams - Video parameters, Contains src, class, index, htmlVideo 21596 */ 21597 Video.prototype.appendVideos = function (el, videoParams) { 21598 var _a; 21599 var videoHtml = this.getVideoHtml(videoParams.src, videoParams.addClass, videoParams.index, videoParams.html5Video); 21600 el.find('.lg-video-cont').append(videoHtml); 21601 var $videoElement = el.find('.lg-video-object').first(); 21602 if (videoParams.html5Video) { 21603 $videoElement.on('mousedown.lg.video', function (e) { 21604 e.stopPropagation(); 21605 }); 21606 } 21607 if (this.settings.videojs && ((_a = this.core.galleryItems[videoParams.index].__slideVideoInfo) === null || _a === void 0 ? void 0 : _a.html5)) { 21608 try { 21609 return videojs($videoElement.get(), this.settings.videojsOptions); 21610 } 21611 catch (e) { 21612 console.warn('lightGallery:- Make sure you have included videojs'); 21613 } 21614 } 21615 }; 21616 Video.prototype.gotoNextSlideOnVideoEnd = function (src, index) { 21617 var _this = this; 21618 var $videoElement = this.core 21619 .getSlideItem(index) 21620 .find('.lg-video-object') 21621 .first(); 21622 var videoInfo = this.core.galleryItems[index].__slideVideoInfo || {}; 21623 if (this.settings.gotoNextSlideOnVideoEnd) { 21624 if (videoInfo.html5) { 21625 $videoElement.on('ended', function () { 21626 _this.core.goToNextSlide(); 21627 }); 21628 } 21629 else if (videoInfo.vimeo) { 21630 try { 21631 // https://github.com/vimeo/player.js/#ended 21632 new Vimeo.Player($videoElement.get()).on('ended', function () { 21633 _this.core.goToNextSlide(); 21634 }); 21635 } 21636 catch (e) { 21637 console.warn('lightGallery:- Make sure you have included //github.com/vimeo/player.js'); 21638 } 21639 } 21640 else if (videoInfo.wistia) { 21641 try { 21642 window._wq = window._wq || []; 21643 // @todo Event is gettign triggered multiple times 21644 window._wq.push({ 21645 id: $videoElement.attr('id'), 21646 onReady: function (video) { 21647 video.bind('end', function () { 21648 _this.core.goToNextSlide(); 21649 }); 21650 }, 21651 }); 21652 } 21653 catch (e) { 21654 console.warn('lightGallery:- Make sure you have included //fast.wistia.com/assets/external/E-v1.js'); 21655 } 21656 } 21657 } 21658 }; 21659 Video.prototype.controlVideo = function (index, action) { 21660 var $videoElement = this.core 21661 .getSlideItem(index) 21662 .find('.lg-video-object') 21663 .first(); 21664 var videoInfo = this.core.galleryItems[index].__slideVideoInfo || {}; 21665 if (!$videoElement.get()) 21666 return; 21667 if (videoInfo.youtube) { 21668 try { 21669 $videoElement.get().contentWindow.postMessage("{\"event\":\"command\",\"func\":\"" + action + "Video\",\"args\":\"\"}", '*'); 21670 } 21671 catch (e) { 21672 console.warn("lightGallery:- " + e); 21673 } 21674 } 21675 else if (videoInfo.vimeo) { 21676 try { 21677 new Vimeo.Player($videoElement.get())[action](); 21678 } 21679 catch (e) { 21680 console.warn('lightGallery:- Make sure you have included //github.com/vimeo/player.js'); 21681 } 21682 } 21683 else if (videoInfo.html5) { 21684 if (this.settings.videojs) { 21685 try { 21686 videojs($videoElement.get())[action](); 21687 } 21688 catch (e) { 21689 console.warn('lightGallery:- Make sure you have included videojs'); 21690 } 21691 } 21692 else { 21693 $videoElement.get()[action](); 21694 } 21695 } 21696 else if (videoInfo.wistia) { 21697 try { 21698 window._wq = window._wq || []; 21699 // @todo Find a way to destroy wistia player instance 21700 window._wq.push({ 21701 id: $videoElement.attr('id'), 21702 onReady: function (video) { 21703 video[action](); 21704 }, 21705 }); 21706 } 21707 catch (e) { 21708 console.warn('lightGallery:- Make sure you have included //fast.wistia.com/assets/external/E-v1.js'); 21709 } 21710 } 21711 }; 21712 Video.prototype.loadVideoOnPosterClick = function ($el, forcePlay) { 21713 var _this = this; 21714 // check slide has poster 21715 if (!$el.hasClass('lg-video-loaded')) { 21716 // check already video element present
21717 if (!$el.hasClass('lg-has-video')) { 21718 $el.addClass('lg-has-video'); 21719 var _html = void 0; 21720 var _src = this.core.galleryItems[this.core.index].src; 21721 var video = this.core.galleryItems[this.core.index].video; 21722 if (video) { 21723 _html = 21724 typeof video === 'string' ? JSON.parse(video) : video; 21725 } 21726 var videoJsPlayer_1 = this.appendVideos($el, { 21727 src: _src, 21728 addClass: '', 21729 index: this.core.index, 21730 html5Video: _html, 21731 }); 21732 this.gotoNextSlideOnVideoEnd(_src, this.core.index); 21733 var $tempImg = $el.find('.lg-object').first().get(); 21734 // @todo make sure it is working 21735 $el.find('.lg-video-cont').first().append($tempImg); 21736 $el.addClass('lg-video-loading'); 21737 videoJsPlayer_1 && 21738 videoJsPlayer_1.ready(function () { 21739 videoJsPlayer_1.on('loadedmetadata', function () { 21740 _this.onVideoLoadAfterPosterClick($el, _this.core.index); 21741 }); 21742 }); 21743 $el.find('.lg-video-object') 21744 .first() 21745 .on('load.lg error.lg loadedmetadata.lg', function () { 21746 setTimeout(function () { 21747 _this.onVideoLoadAfterPosterClick($el, _this.core.index); 21748 }, 50); 21749 }); 21750 } 21751 else { 21752 this.playVideo(this.core.index); 21753 } 21754 } 21755 else if (forcePlay) { 21756 this.playVideo(this.core.index); 21757 } 21758 }; 21759 Video.prototype.onVideoLoadAfterPosterClick = function ($el, index) { 21760 $el.addClass('lg-video-loaded'); 21761 this.playVideo(index); 21762 }; 21763 Video.prototype.destroy = function () { 21764 this.core.LGel.off('.lg.video'); 21765 this.core.LGel.off('.video'); 21766 }; 21767 return Video; 21768 }()); 21769 21770 return Video; 21771 21772}))); 21773 21774 21775/*! @vimeo/player v2.17.1 | (c) 2022 Vimeo | MIT License | https://github.com/vimeo/player.js */ 21776!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):((e="undefined"!=typeof globalThis?globalThis:e||self).Vimeo=e.Vimeo||{},e.Vimeo.Player=t())}(this,function(){"use strict";function r(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}var e="undefined"!=typeof global&&"[object global]"==={}.toString.call(global);function i(e,t){return 0===e.indexOf(t.toLowerCase())?e:"".concat(t.toLowerCase()).concat(e.substr(0,1).toUpperCase()).concat(e.substr(1))}function c(e){return/^(https?:)?\/\/((player|www)\.)?vimeo\.com(?=$|\/)/.test(e)}function s(e){var t,n=0<arguments.length&&void 0!==e?e:{},r=n.id,o=n.url,i=r||o;if(!i)throw new Error("An id or url must be passed, either in an options object or as a data-vimeo-id or data-vimeo-url attribute.");if(t=i,!isNaN(parseFloat(t))&&isFinite(t)&&Math.floor(t)==t)return"https://vimeo.com/".concat(i);if(c(i))return i.replace("http:","https:");if(r)throw new TypeError("â".concat(r,"â is not a valid video id."));throw new TypeError("â".concat(i,"â is not a vimeo.com url."))}var t=void 0!==Array.prototype.indexOf,n="undefined"!=typeof window&&void 0!==window.postMessage;if(!(e||t&&n))throw new Error("Sorry, the Vimeo Player API is not available in this browser.");var o,a,u,l,f="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function d(){if(void 0===this)throw new TypeError("Constructor WeakMap requires 'new'");if(l(this,"_id","_WeakMap_"+v()+"."+v()),0<arguments.length)throw new TypeError("WeakMap iterable is not supported")}function h(e,t){if(!m(e)||!a.call(e,"_id"))throw new TypeError(t+" method called on incompatible receiver "+typeof e)}function v(){return Math.random().toString().substring(2)}function m(e){return Object(e)===e}(o="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:"undefined"!=typeof window?window:f).WeakMap||(a=Object.prototype.hasOwnProperty,u=Object.defineProperty&&function(){try{return 1===Object.defineProperty({},"x",{value:1}).x}catch(e){}}(),l=function(e,t,n){u?Object.defineProperty(e,t,{configurable:!0,writable:!0,value:n}):e[t]=n},o.WeakMap=(l(d.prototype,"delete",function(e){if(h(this,"delete"),!m(e))return!1;var t=e[this._id];return!(!t||t[0]!==e)&&(delete e[this._id],!0)}),l(d.prototype,"get",function(e){if(h(this,"get"),m(e)){var t=e[this._id];return t&&t[0]===e?t[1]:void 0}}),l(d.prototype,"has",function(e){if(h(this,"has"),!m(e))return!1;var t=e[this._id];return!(!t||t[0]!==e)}),l(d.prototype,"set",function(e,t){if(h(this,"set"),!m(e))throw new TypeError("Invalid value used as weak map key");var n=e[this._id];return n&&n[0]===e?n[1]=t:l(e,this._id,[e,t]),this}),l(d,"_polyfill",!0),d));var p,y=(function(e){var t,n,r;r=function(){var t,n,r,o,i,a,e=Object.prototype.toString,u="undefined"!=typeof setImmediate?function(e){return setImmediate(e)}:setTimeout;try{Object.defineProperty({},"x",{}),t=function(e,t,n,r){return Object.defineProperty(e,t,{value:n,writable:!0,configurable:!1!==r})}}catch(e){t=function(e,t,n){return e[t]=n,e}}function l(e,t){this.fn=e,this.self=t,this.next=void 0}function c(e,t){r.add(e,t),n=n||u(r.drain)}function s(e){var t,n=typeof e;return null==e||"object"!=n&&"function"!=n||(t=e.then),"function"==typeof t&&t}function f(){for(var e=0;e<this.chain.length;e++)!function(e,t,n){var r,o;try{!1===t?n.reject(e.msg):(r=!0===t?e.msg:t.call(void 0,e.msg))===n.promise?n.reject(TypeError("Promise-chain cycle")):(o=s(r))?o.call(r,n.resolve,n.reject):n.resolve(r)}catch(e){n.reject(e)}}(this,1===this.state?this.chain[e].success:this.chain[e].failure,this.chain[e]);this.chain.length=0}function d(e){var n,r=this;if(!r.triggered){r.triggered=!0,r.def&&(r=r.def);try{(n=s(e))?c(function(){var t=new m(r);try{n.call(e,function(){d.apply(t,arguments)},function(){h.apply(t,arguments)})}catch(e){h.call(t,e)}}):(r.msg=e,r.state=1,0<r.chain.length&&c(f,r))}catch(e){h.call(new m(r),e)}}}function h(e){var t=this;t.triggered||(t.triggered=!0,t.def&&(t=t.def),t.msg=e,t.state=2,0<t.chain.length&&c(f,t))}function v(e,n,r,o){for(var t=0;t<n.length;t++)!function(t){e.resolve(n[t]).then(function(e){r(t,e)},o)}(t)}function m(e){this.def=e,this.triggered=!1}function p(e){this.promise=e,this.state=0,this.triggered=!1,this.chain=[],this.msg=void 0}function y(e){if("function"!=typeof e)throw TypeError("Not a function");if(0!==this.__NPO__)throw TypeError("Not a promise");this.__NPO__=1;var r=new p(this);this.then=function(e,t){var n={success:"function"!=typeof e||e,failure:"function"==typeof t&&t};return n.promise=new this.constructor(function(e,t){if("function"!=typeof e||"function"!=typeof t)throw TypeError("Not a function");n.resolve=e,n.reject=t}),r.chain.push(n),0!==r.state&&c(f,r),n.promise},this.catch=function(e){return this.then(void 0,e)};try{e.call(void 0,function(e){d.call(r,e)},function(e){h.call(r,e)})}catch(e){h.call(r,e)}}var g=t({},"constructor",y,!(r={add:function(e,t){a=new l(e,t),i?i.next=a:o=a,i=a,a=void 0},drain:function(){var e=o;for(o=i=n=void 0;e;)e.fn.call(e.self),e=e.next}}));return t(y.prototype=g,"__NPO__",0,!1),t(y,"resolve",function(n){return n&&"object"==typeof n&&1===n.__NPO__?n:new this(function(e,t){if("function"!=typeof e||"function"!=typeof t)throw TypeError("Not a function");e(n)})}),t(y,"reject",function(n){return new this(function(e,t){if("function"!=typeof e||"function"!=typeof t)throw TypeError("Not a function");t(n)})}),t(y,"all",function(t){var a=this;return"[object Array]"!=e.call(t)?a.reject(TypeError("Not an array")):0===t.length?a.resolve([]):new a(function(n,e){if("function"!=typeof n||"function"!=typeof e)throw TypeError("Not a function");var r=t.length,o=Array(r),i=0;v(a,t,function(e,t){o[e]=t,++i===r&&n(o)},e)})}),t(y,"race",function(t){var r=this;return"[object Array]"!=e.call(t)?r.reject(TypeError("Not an array")):new r(function(n,e){if("function"!=typeof n||"function"!=typeof e)throw TypeError("Not a function");v(r,t,function(e,t){n(t)},e)})}),y},(n=f)[t="Promise"]=n[t]||r(),e.exports&&(e.exports=n[t])}(p={exports:{}}
21776),p.exports),g=new WeakMap;function w(e,t,n){var r=g.get(e.element)||{};t in r||(r[t]=[]),r[t].push(n),g.set(e.element,r)}function b(e,t){return(g.get(e.element)||{})[t]||[]}function k(e,t,n){var r=g.get(e.element)||{};if(!r[t])return!0;if(!n)return r[t]=[],g.set(e.element,r),!0;var o=r[t].indexOf(n);return-1!==o&&r[t].splice(o,1),g.set(e.element,r),r[t]&&0===r[t].length}function E(e){if("string"==typeof e)try{e=JSON.parse(e)}catch(e){return console.warn(e),{}}return e}function T(e,t,n){var r,o;e.element.contentWindow&&e.element.contentWindow.postMessage&&(r={method:t},void 0!==n&&(r.value=n),8<=(o=parseFloat(navigator.userAgent.toLowerCase().replace(/^.*msie (\d+).*$/,"$1")))&&o<10&&(r=JSON.stringify(r)),e.element.contentWindow.postMessage(r,e.origin))}function P(n,r){var t,e,o=[];(r=E(r)).event?("error"===r.event&&b(n,r.data.method).forEach(function(e){var t=new Error(r.data.message);t.name=r.data.name,e.reject(t),k(n,r.data.method,e)}),o=b(n,"event:".concat(r.event)),t=r.data):!r.method||(e=function(e,t){var n=b(e,t);if(n.length<1)return!1;var r=n.shift();return k(e,t,r),r}(n,r.method))&&(o.push(e),t=r.value),o.forEach(function(e){try{if("function"==typeof e)return void e.call(n,t);e.resolve(t)}catch(e){}})}var M=["autopause","autoplay","background","byline","color","controls","dnt","height","id","interactive_params","keyboard","loop","maxheight","maxwidth","muted","playsinline","portrait","responsive","speed","texttrack","title","transparent","url","width"];function _(r,e){var t=1<arguments.length&&void 0!==e?e:{};return M.reduce(function(e,t){var n=r.getAttribute("data-vimeo-".concat(t));return!n&&""!==n||(e[t]=""===n?1:n),e},t)}function N(e,t){var n=e.html;if(!t)throw new TypeError("An element must be provided");if(null!==t.getAttribute("data-vimeo-initialized"))return t.querySelector("iframe");var r=document.createElement("div");return r.innerHTML=n,t.appendChild(r.firstChild),t.setAttribute("data-vimeo-initialized","true"),t.querySelector("iframe")}function F(i,e,t){var a=1<arguments.length&&void 0!==e?e:{},u=2<arguments.length?t:void 0;return new Promise(function(t,n){if(!c(i))throw new TypeError("â".concat(i,"â is not a vimeo.com url."));var e="https://vimeo.com/api/oembed.json?url=".concat(encodeURIComponent(i));for(var r in a)a.hasOwnProperty(r)&&(e+="&".concat(r,"=").concat(encodeURIComponent(a[r])));var o=new("XDomainRequest"in window?XDomainRequest:XMLHttpRequest);o.open("GET",e,!0),o.onload=function(){if(404!==o.status)if(403!==o.status)try{var e=JSON.parse(o.responseText);if(403===e.domain_status_code)return N(e,u),void n(new Error("â".concat(i,"â is not embeddable.")));t(e)}catch(e){n(e)}else n(new Error("â".concat(i,"â is not embeddable.")));else n(new Error("â".concat(i,"â was not found.")))},o.onerror=function(){var e=o.status?" (".concat(o.status,")"):"";n(new Error("There was an error fetching the embed code from Vimeo".concat(e,".")))},o.send()})}var x,C,j,A=new WeakMap,S=new WeakMap,q={},Player=function(){function Player(u){var e,t,l=this,n=1<arguments.length&&void 0!==arguments[1]?arguments[1]:{};if(!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,Player),window.jQuery&&u instanceof jQuery&&(1<u.length&&window.console&&console.warn&&console.warn("A jQuery object with multiple elements was passed, using the first element."),u=u[0]),"undefined"!=typeof document&&"string"==typeof u&&(u=document.getElementById(u)),e=u,!Boolean(e&&1===e.nodeType&&"nodeName"in e&&e.ownerDocument&&e.ownerDocument.defaultView))throw new TypeError("You must pass either a valid element or a valid id.");if("IFRAME"===u.nodeName||(t=u.querySelector("iframe"))&&(u=t),"IFRAME"===u.nodeName&&!c(u.getAttribute("src")||""))throw new Error("The player element passed isnât a Vimeo embed.");if(A.has(u))return A.get(u);this._window=u.ownerDocument.defaultView,this.element=u,this.origin="*";var r,o=new y(function(i,a){var e;l._onMessage=function(e){if(c(e.origin)&&l.element.contentWindow===e.source){"*"===l.origin&&(l.origin=e.origin);var t=E(e.data);if(t&&"error"===t.event&&t.data&&"ready"===t.data.method){var n=new Error(t.data.message);return n.name=t.data.name,void a(n)}
vendor: 5,252 bytes, line 21776
21776var r=t&&"ready"===t.event,o=t&&"ping"===t.method;if(r||o)return l.element.setAttribute("data-ready","true"),void i();P(l,t)}},l._window.addEventListener("message",l._onMessage),"IFRAME"!==l.element.nodeName&&F(s(e=_(u,n)),e,u).then(function(e){var t,n,r,o=N(e,u);return l.element=o,l._originalElement=u,t=u,n=o,r=g.get(t),g.set(n,r),g.delete(t),A.set(l.element,l),e}).catch(a)});return S.set(this,o),A.set(this.element,this),"IFRAME"===this.element.nodeName&&T(this,"ping"),q.isEnabled&&(r=function(){return q.exit()},this.fullscreenchangeHandler=function(){(q.isFullscreen?w:k)(l,"event:exitFullscreen",r),l.ready().then(function(){T(l,"fullscreenchange",q.isFullscreen)})},q.on("fullscreenchange",this.fullscreenchangeHandler)),this}var e,t,n;return e=Player,(t=[{key:"callMethod",value:function(n,e){var r=this,o=1<arguments.length&&void 0!==e?e:{};return new y(function(e,t){return r.ready().then(function(){w(r,n,{resolve:e,reject:t}),T(r,n,o)}).catch(t)})}},{key:"get",value:function(n){var r=this;return new y(function(e,t){return n=i(n,"get"),r.ready().then(function(){w(r,n,{resolve:e,reject:t}),T(r,n)}).catch(t)})}},{key:"set",value:function(n,r){var o=this;return new y(function(e,t){if(n=i(n,"set"),null==r)throw new TypeError("There must be a value to set.");return o.ready().then(function(){w(o,n,{resolve:e,reject:t}),T(o,n,r)}).catch(t)})}},{key:"on",value:function(e,t){if(!e)throw new TypeError("You must pass an event name.");if(!t)throw new TypeError("You must pass a callback function.");if("function"!=typeof t)throw new TypeError("The callback must be a function.");0===b(this,"event:".concat(e)).length&&this.callMethod("addEventListener",e).catch(function(){}),w(this,"event:".concat(e),t)}},{key:"off",value:function(e,t){if(!e)throw new TypeError("You must pass an event name.");if(t&&"function"!=typeof t)throw new TypeError("The callback must be a function.");k(this,"event:".concat(e),t)&&this.callMethod("removeEventListener",e).catch(function(e){})}},{key:"loadVideo",value:function(e){return this.callMethod("loadVideo",e)}},{key:"ready",value:function(){var e=S.get(this)||new y(function(e,t){t(new Error("Unknown player. Probably unloaded."))});return y.resolve(e)}},{key:"addCuePoint",value:function(e,t){var n=1<arguments.length&&void 0!==t?t:{};return this.callMethod("addCuePoint",{time:e,data:n})}},{key:"removeCuePoint",value:function(e){return this.callMethod("removeCuePoint",e)}},{key:"enableTextTrack",value:function(e,t){if(!e)throw new TypeError("You must pass a language.");return this.callMethod("enableTextTrack",{language:e,kind:t})}},{key:"disableTextTrack",value:function(){return this.callMethod("disableTextTrack")}},{key:"pause",value:function(){return this.callMethod("pause")}},{key:"play",value:function(){return this.callMethod("play")}},{key:"requestFullscreen",value:function(){return q.isEnabled?q.request(this.element):this.callMethod("requestFullscreen")}},{key:"exitFullscreen",value:function(){return q.isEnabled?q.exit():this.callMethod("exitFullscreen")}},{key:"getFullscreen",value:function(){return q.isEnabled?y.resolve(q.isFullscreen):this.get("fullscreen")}},{key:"requestPictureInPicture",value:function(){return this.callMethod("requestPictureInPicture")}},{key:"exitPictureInPicture",value:function(){return this.callMethod("exitPictureInPicture")}},{key:"getPictureInPicture",value:function(){return this.get("pictureInPicture")}},{key:"unload",value:function(){return this.callMethod("unload")}},{key:"destroy",value:function(){var n=this;return new y(function(e){var t;S.delete(n),A.delete(n.element),n._originalElement&&(A.delete(n._originalElement),n._originalElement.removeAttribute("data-vimeo-initialized")),n.element&&"IFRAME"===n.element.nodeName&&n.element.parentNode&&(n.element.parentNode.parentNode&&n._originalElement&&n._originalElement!==n.element.parentNode?n.element.parentNode.parentNode.removeChild(n.element.parentNode):n.element.parentNode.removeChild(n.element)),n.element&&"DIV"===n.element.nodeName&&n.element.parentNode&&(n.element.removeAttribute("data-vimeo-initialized"),(t=n.element.querySelector("iframe"))&&t.parentNode&&(t.parentNode.parentNode&&n._originalElement&&n._originalElement!==t.parentNode?t.parentNode.parentNode.removeChild(t.parentNode):t.parentNode.removeChild(t))),n._window.removeEventListener("message",n._onMessage),q.isEnabled&&q.off("fullscreenchange",n.fullscreenchangeHandler),e()})}},{key:"getAutopause",value:function(){return this.get("autopause")}},{key:"setAutopause",value:function(e){return this.set("autopause",e)}},{key:"getBuffered",value:function(){return this.get("buffered")}},{key:"getCameraProps",value:function(){return this.get("cameraProps")}},{key:"setCameraProps",value:function(e){return this.set("cameraProps",e)}},{key:"getChapters",value:function(){return this.get("chapters")}},{key:"getCurrentChapter",value:function(){return this.get("currentChapter")}},{key:"getColor",value:function(){return this.get("color")}},{key:"setColor",value:function(e){return this.set("color",e)}},{key:"getCuePoints",value:function(){return this.get("cuePoints")}},{key:"getCurrentTime",value:function(){return this.get("currentTime")}},{key:"setCurrentTime",value:function(e){return this.set("currentTime",e)}
21776},{key:"getDuration",value:function(){return this.get("duration")}},{key:"getEnded",value:function(){return this.get("ended")}},{key:"getLoop",value:function(){return this.get("loop")}},{key:"setLoop",value:function(e){return this.set("loop",e)}},{key:"setMuted",value:function(e){return this.set("muted",e)}},{key:"getMuted",value:function(){return this.get("muted")}},{key:"getPaused",value:function(){return this.get("paused")}},{key:"getPlaybackRate",value:function(){return this.get("playbackRate")}},{key:"setPlaybackRate",value:function(e){return this.set("playbackRate",e)}},{key:"getPlayed",value:function(){return this.get("played")}},{key:"getQualities",value:function(){return this.get("qualities")}},{key:"getQuality",value:function(){return this.get("quality")}},{key:"setQuality",value:function(e){return this.set("quality",e)}},{key:"getSeekable",value:function(){return this.get("seekable")}},{key:"getSeeking",value:function(){return this.get("seeking")}},{key:"getTextTracks",value:function(){return this.get("textTracks")}},{key:"getVideoEmbedCode",value:function(){return this.get("videoEmbedCode")}},{key:"getVideoId",value:function(){return this.get("videoId")}},{key:"getVideoTitle",value:function(){return this.get("videoTitle")}},{key:"getVideoWidth",value:function(){return this.get("videoWidth")}},{key:"getVideoHeight",value:function(){return this.get("videoHeight")}},{key:"getVideoUrl",value:function(){return this.get("videoUrl")}},{key:"getVolume",value:function(){return this.get("volume")}},{key:"setVolume",value:function(e){return this.set("volume",e)}}])&&r(e.prototype,t),n&&r(e,n),Player}();return e||(x=function(){for(var e,t=[["requestFullscreen","exitFullscreen","fullscreenElement","fullscreenEnabled","fullscreenchange","fullscreenerror"],["webkitRequestFullscreen","webkitExitFullscreen","webkitFullscreenElement","webkitFullscreenEnabled","webkitfullscreenchange","webkitfullscreenerror"],["webkitRequestFullScreen","webkitCancelFullScreen","webkitCurrentFullScreenElement","webkitCancelFullScreen","webkitfullscreenchange","webkitfullscreenerror"],["mozRequestFullScreen","mozCancelFullScreen","mozFullScreenElement","mozFullScreenEnabled","mozfullscreenchange","mozfullscreenerror"],["msRequestFullscreen","msExitFullscreen","msFullscreenElement","msFullscreenEnabled","MSFullscreenChange","MSFullscreenError"]],n=0,r=t.length,o={};n<r;n++)if((e=t[n])&&e[1]in document){for(n=0;n<e.length;n++)o[t[0][n]]=e[n];return o}return!1}(),C={fullscreenchange:x.fullscreenchange,fullscreenerror:x.fullscreenerror},j={request:function(o){return new Promise(function(e,t){function n(){j.off("fullscreenchange",n),e()}j.on("fullscreenchange",n);var r=(o=o||document.documentElement)[x.requestFullscreen]();r instanceof Promise&&r.then(n).catch(t)})},exit:function(){return new Promise(function(t,e){var n,r;j.isFullscreen?(n=function e(){j.off("fullscreenchange",e),t()},j.on("fullscreenchange",n),(r=document[x.exitFullscreen]())instanceof Promise&&r.then(n).catch(e)):t()})},on:function(e,t){var n=C[e];n&&document.addEventListener(n,t)},off:function(e,t){var n=C[e];n&&document.removeEventListener(n,t)}},Object.defineProperties(j,{isFullscreen:{get:function(){return Boolean(document[x.fullscreenElement])}},element:{enumerable:!0,get:function(){return document[x.fullscreenElement]}},isEnabled:{enumerable:!0,get:function(){return Boolean(document[x.fullscreenEnabled])}}}),q=j,function(e){function n(e){"console"in window&&console.error&&console.error("There was an error creating an embed: ".concat(e))}var t=0<arguments.length&&void 0!==e?e:document;[].slice.call(t.querySelectorAll("[data-vimeo-id], [data-vimeo-url]")).forEach(function(t){try{if(null!==t.getAttribute("data-vimeo-defer"))return;var e=_(t);F(s(e),e,t).then(function(e){return N(e,t)}).catch(n)}catch(e){n(e)}})}(),function(e){var r=0<arguments.length&&void 0!==e?e:document;window.VimeoPlayerResizeEmbeds_||(window.VimeoPlayerResizeEmbeds_=!0,window.addEventListener("message",function(e){if(c(e.origin)&&e.data&&"spacechange"===e.data.event)for(var t=r.querySelectorAll("iframe"),n=0;n<t.length;n++)if(t[n].contentWindow===e.source){t[n].parentElement.style.paddingBottom="".concat(e.data.data[0].bottom,"px");break}}
vendor: 31,994 bytes, lines 21776-22983
21776))}(),function(e){var u=0<arguments.length&&void 0!==e?e:document;window.VimeoSeoMetadataAppended||(window.VimeoSeoMetadataAppended=!0,window.addEventListener("message",function(e){if(c(e.origin)){var t=E(e.data);if(t&&"ready"===t.event)for(var n,r=u.querySelectorAll("iframe"),o=0;o<r.length;o++){var i=r[o],a=i.contentWindow===e.source;n=i.src,/^https:\/\/player\.vimeo\.com\/video\/\d+/.test(n)&&a&&new Player(i).callMethod("appendVideoMetadata",window.location.href)}}}))}()),Player}); 21777 21778/** 21779 * Owl carousel 21780 * @version 2.0.0-beta.3 21781 * @author Bartosz Wojciechowski 21782 * @license The MIT License (MIT) 21783 * @todo Lazy Load Icon 21784 * @todo prevent animationend bubling 21785 * @todo itemsScaleUp 21786 * @todo Test Zepto 21787 * @todo stagePadding calculate wrong active classes 21788 */ 21789;(function($, window, document, undefined) { 21790 21791 /** 21792 * Creates a carousel. 21793 * @class The Owl Carousel. 21794 * @public 21795 * @param {HTMLElement|jQuery} element - The element to create the carousel for. 21796 * @param {Object} [options] - The options 21797 */ 21798 function Owl(element, options) { 21799 21800 /** 21801 * Current settings for the carousel. 21802 * @public 21803 */ 21804 this.settings = null; 21805 21806 /** 21807 * Current options set by the caller including defaults. 21808 * @public 21809 */ 21810 this.options = $.extend({}, Owl.Defaults, options); 21811 21812 /** 21813 * Plugin element. 21814 * @public 21815 */ 21816 this.$element = $(element); 21817 21818 /** 21819 * Proxied event handlers. 21820 * @protected 21821 */ 21822 this._handlers = {}; 21823 21824 /** 21825 * References to the running plugins of this carousel. 21826 * @protected 21827 */ 21828 this._plugins = {}; 21829 21830 /** 21831 * Currently suppressed events to prevent them from beeing retriggered. 21832 * @protected 21833 */ 21834 this._supress = {}; 21835 21836 /** 21837 * Absolute current position. 21838 * @protected 21839 */ 21840 this._current = null; 21841 21842 /** 21843 * Animation speed in milliseconds. 21844 * @protected 21845 */ 21846 this._speed = null; 21847 21848 /** 21849 * Coordinates of all items in pixel. 21850 * @todo The name of this member is missleading. 21851 * @protected 21852 */ 21853 this._coordinates = []; 21854 21855 /** 21856 * Current breakpoint. 21857 * @todo Real media queries would be nice. 21858 * @protected 21859 */ 21860 this._breakpoint = null; 21861 21862 /** 21863 * Current width of the plugin element. 21864 */ 21865 this._width = null; 21866 21867 /** 21868 * All real items. 21869 * @protected 21870 */ 21871 this._items = []; 21872 21873 /** 21874 * All cloned items. 21875 * @protected 21876 */ 21877 this._clones = []; 21878 21879 /** 21880 * Merge values of all items. 21881 * @todo Maybe this could be part of a plugin. 21882 * @protected 21883 */ 21884 this._mergers = []; 21885 21886 /** 21887 * Widths of all items. 21888 */ 21889 this._widths = []; 21890 21891 /** 21892 * Invalidated parts within the update process. 21893 * @protected 21894 */ 21895 this._invalidated = {}; 21896 21897 /** 21898 * Ordered list of workers for the update process. 21899 * @protected 21900 */ 21901 this._pipe = []; 21902 21903 /** 21904 * Current state information for the drag operation. 21905 * @todo #261 21906 * @protected 21907 */ 21908 this._drag = { 21909 time: null, 21910 target: null, 21911 pointer: null, 21912 stage: { 21913 start: null, 21914 current: null 21915 }, 21916 direction: null 21917 }; 21918 21919 /** 21920 * Current state information and their tags. 21921 * @type {Object} 21922 * @protected 21923 */ 21924 this._states = { 21925 current: {}, 21926 tags: { 21927 'initializing': [ 'busy' ], 21928 'animating': [ 'busy' ], 21929 'dragging': [ 'interacting' ] 21930 } 21931 }; 21932 21933 $.each([ 'onResize', 'onThrottledResize' ], $.proxy(function(i, handler) { 21934 this._handlers[handler] = $.proxy(this[handler], this); 21935 }, this)); 21936 21937 $.each(Owl.Plugins, $.proxy(function(key, plugin) { 21938 this._plugins[key.charAt(0).toLowerCase() + key.slice(1)] 21939 = new plugin(this); 21940 }, this)); 21941 21942 $.each(Owl.Workers, $.proxy(function(priority, worker) { 21943 this._pipe.push({ 21944 'filter': worker.filter, 21945 'run': $.proxy(worker.run, this) 21946 }); 21947 }, this)); 21948 21949 this.setup(); 21950 this.initialize(); 21951 } 21952 21953 /** 21954 * Default options for the carousel. 21955 * @public 21956 */ 21957 Owl.Defaults = { 21958 items: 3, 21959 loop: false, 21960 center: false, 21961 rewind: false, 21962 21963 mouseDrag: true, 21964 touchDrag: true, 21965 pullDrag: true, 21966 freeDrag: false, 21967 21968 margin: 0, 21969 stagePadding: 0, 21970 21971 merge: false, 21972 mergeFit: true, 21973 autoWidth: false, 21974 21975 startPosition: 0, 21976 rtl: false, 21977 21978 smartSpeed: 250, 21979 fluidSpeed: false, 21980 dragEndSpeed: false, 21981 21982 responsive: {}, 21983 responsiveRefreshRate: 200, 21984 responsiveBaseElement: window, 21985 21986 fallbackEasing: 'swing', 21987 21988 info: false, 21989 21990 nestedItemSelector: false, 21991 itemElement: 'div', 21992 stageElement: 'div', 21993 21994 refreshClass: 'owl-refresh', 21995 loadedClass: 'owl-loaded', 21996 loadingClass: 'owl-loading', 21997 rtlClass: 'owl-rtl', 21998 responsiveClass: 'owl-responsive', 21999 dragClass: 'owl-drag', 22000 itemClass: 'owl-item', 22001 stageClass: 'owl-stage', 22002 stageOuterClass: 'owl-stage-outer', 22003 grabClass: 'owl-grab' 22004 }; 22005 22006 /** 22007 * Enumeration for width. 22008 * @public 22009 * @readonly 22010 * @enum {String} 22011 */ 22012 Owl.Width = { 22013 Default: 'default', 22014 Inner: 'inner', 22015 Outer: 'outer' 22016 }; 22017 22018 /** 22019 * Enumeration for types. 22020 * @public 22021 * @readonly 22022 * @enum {String} 22023 */ 22024 Owl.Type = { 22025 Event: 'event', 22026 State: 'state' 22027 }; 22028 22029 /** 22030 * Contains all registered plugins. 22031 * @public 22032 */ 22033 Owl.Plugins = {}; 22034 22035 /** 22036 * List of workers involved in the update process. 22037 */ 22038 Owl.Workers = [ { 22039 filter: [ 'width', 'settings' ], 22040 run: function() { 22041 this._width = (this.$element.closest('.px-gutter').length) ? 12 * Math.ceil(this.$element.width() / 12) : this.$element.width(); 22042 //this._width = (UNCODE.isMobile) ? this.$element.width() : 12 * Math.ceil(this.$element.width() / 12); 22043 } 22044 }, { 22045 filter: [ 'width', 'items', 'settings' ], 22046 run: function(cache) { 22047 cache.current = this._items && this._items[this.relative(this._current)]; 22048 } 22049 }, { 22050 filter: [ 'items', 'settings' ], 22051 run: function() { 22052 this.$stage.children('.cloned').remove(); 22053 } 22054 }, { 22055 filter: [ 'width', 'items', 'settings' ], 22056 run: function(cache) { 22057 var margin = this.settings.margin || '', 22058 grid = !this.settings.autoWidth, 22059 rtl = this.settings.rtl, 22060 css = { 22061 'width': 'auto', 22062 'margin-left': rtl ? margin : '', 22063 'margin-right': rtl ? '' : margin 22064 }; 22065 22066 !grid && this.$stage.children().css(css); 22067 22068 cache.css = css; 22069 } 22070 }, { 22071 filter: [ 'width', 'items', 'settings' ], 22072 run: function(cache) { 22073 //UNCODE edit to fix Chrome stage padding issue 22074 var width = Math.round((this.width() / this.settings.items).toFixed(3) - this.settings.margin), 22075 merge = null, 22076 iterator = this._items.length, 22077 grid = !this.settings.autoWidth, 22078 widths = []; 22079 22080 cache.items = { 22081 merge: false, 22082 width: width 22083 }; 22084 22085 while (iterator--) { 22086 merge = this._mergers[iterator]; 22087 merge = this.settings.mergeFit && Math.min(merge, this.settings.items) || merge; 22088 22089 cache.items.merge = merge > 1 || cache.items.merge; 22090 22091 widths[iterator] = !grid ? this._items[iterator].width() : width * merge; 22092 } 22093 22094 this._widths = widths; 22095 } 22096 }, { 22097 filter: [ 'items', 'settings' ], 22098 run: function() { 22099 var clones = [], 22100 items = this._items, 22101 settings = this.settings, 22102 view = Math.max(settings.items * 2, 4), 22103 size = Math.ceil(items.length / 2) * 2, 22104 repeat = settings.loop && items.length ? settings.rewind ? view : Math.max(view, size) : 0, 22105 append = '', 22106 prepend = ''; 22107 22108 repeat /= 2; 22109 22110 while (repeat--) { 22111 clones.push(this.normalize(clones.length / 2, true)); 22112 append = append + items[clones[clones.length - 1]][0].outerHTML; 22113 clones.push(this.normalize(items.length - 1 - (clones.length - 1) / 2, true)); 22114 prepend = items[clones[clones.length - 1]][0].outerHTML + prepend; 22115 } 22116 22117 this._clones = clones; 22118 22119 // var appendVideo = $(append).find('.uncode-video-container'); 22120 // if (appendVideo.length) { 22121 // appendVideo.attr('data-id', Math.round(Math.random() * 100000)); 22122 // } 22123 // var prependVideo = $(prepend).find('.uncode-video-container'); 22124 // if (prependVideo.length) { 22125 // prependVideo.attr('data-id', Math.round(Math.random() * 100000)); 22126 // } 22127 $(append).addClass('cloned').appendTo(this.$stage); 22128 $(prepend).addClass('cloned').prependTo(this.$stage); 22129 } 22130 }, { 22131 filter: [ 'width', 'items', 'settings' ], 22132 run: function() { 22133 var rtl = this.settings.rtl ? 1 : -1, 22134 size = this._clones.length + this._items.length, 22135 iterator = -1, 22136 previous = 0, 22137 current = 0, 22138 coordinates = []; 22139 22140 while (++iterator < size) { 22141 previous = coordinates[iterator - 1] || 0; 22142 current = this._widths[this.relative(iterator)] + this.settings.margin; 22143 coordinates.push(previous + current * rtl); 22144 } 22145 22146 this._coordinates = coordinates; 22147 } 22148 }, { 22149 filter: [ 'width', 'items', 'settings' ], 22150 run: function() { 22151 var stagePadding = (this._width < 480 && this.settings.stagePadding > 0) ? 41 : (this._width * this.settings.stagePadding) / 200, 22152 padding = stagePadding, 22153 coordinates = this._coordinates, 22154 css = { 22155 'width': Math.ceil(Math.abs(coordinates[coordinates.length - 1])) + padding * 2, 22156 'padding-left': padding || '', 22157 'padding-right': padding || '' 22158 }; 22159 22160 this.$stage.css(css); 22161 } 22162 }, { 22163 filter: [ 'width', 'items', 'settings' ], 22164 run: function(cache) { 22165 var iterator = this._coordinates.length, 22166 grid = !this.settings.autoWidth, 22167 items = this.$stage.children(); 22168 22169 if (grid && cache.items.merge) { 22170 while (iterator--) { 22171 cache.css.width = this._widths[this.relative(iterator)]; 22172 items.eq(iterator).css(cache.css); 22173 } 22174 } else if (grid) { 22175 cache.css.width = cache.items.width; 22176 items.css(cache.css); 22177 } 22178 } 22179 }, { 22180 filter: [ 'items' ], 22181 run: function() { 22182 this._coordinates.length < 1 && this.$stage.removeAttr('style'); 22183 } 22184 }, { 22185 filter: [ 'width', 'items', 'settings' ], 22186 run: function(cache) { 22187 cache.current = cache.current ? this.$stage.children().index(cache.current) : 0; 22188 cache.current = Math.max(this.minimum(), Math.min(this.maximum(), cache.current)); 22189 this.reset(cache.current); 22190 } 22191 }, { 22192 filter: [ 'position' ], 22193 run: function() { 22194 this.animate(this.coordinates(this._current)); 22195 } 22196 }, { 22197 filter: [ 'width', 'position', 'items', 'settings' ], 22198 run: function() { 22199 var stagePadding = (this._width < 480 && this.settings.stagePadding > 0) ? 41 : (this._width * this.settings.stagePadding) / 200, 22200 rtl = this.settings.rtl ? 1 : -1, 22201 padding = this.settings.stagePadding * 2, 22202 begin = this.coordinates(this.current()) + padding, 22203 end = begin + this.width() * rtl, 22204 inner, outer, matches = [], i, n; 22205 22206 for (i = 0, n = this._coordinates.length; i < n; i++) { 22207 inner = this._coordinates[i - 1] || 0; 22208 outer = Math.abs(this._coordinates[i]) + padding * rtl; 22209 22210 if ((this.op(inner, '<=', begin) && (this.op(inner, '>', end))) 22211 || (this.op(outer, '<', begin) && this.op(outer, '>', end))) { 22212 matches.push(i); 22213 } 22214 } 22215 22216 this.$stage.children('.active').removeClass('active'); 22217 this.$stage.children(':eq(' + matches.join('), :eq(') + ')').addClass('active'); 22218 22219 if (this.settings.center) { 22220 this.$stage.children('.center').removeClass('center'); 22221 this.$stage.children().eq(this.current()).addClass('center'); 22222 } 22223 } 22224 } ]; 22225 22226 /** 22227 * Initializes the carousel. 22228 * @protected 22229 */ 22230 Owl.prototype.initialize = function() { 22231 this.enter('initializing'); 22232 this.trigger('initialize'); 22233 22234 this.$element.toggleClass(this.settings.rtlClass, this.settings.rtl); 22235 22236 if (this.settings.autoWidth && !this.is('pre-loading')) { 22237 var imgs, nestedSelector, width; 22238 imgs = this.$element.find('img'); 22239 nestedSelector = this.settings.nestedItemSelector ? '.' + this.settings.nestedItemSelector : undefined; 22240 width = this.$element.children(nestedSelector).width(); 22241 22242 if (imgs.length && width <= 0) { 22243 this.preloadAutoWidthImages(imgs); 22244 } 22245 } 22246 22247 this.$element.addClass(this.options.loadingClass); 22248 22249 // create stage 22250 this.$stage = $('<' + this.settings.stageElement + ' class="' + this.settings.stageClass + '"/>') 22251 .wrap('<div class="' + this.settings.stageOuterClass + '"/>'); 22252 22253 // append stage 22254 this.$element.append(this.$stage.parent()); 22255 22256 // append content 22257 this.replace(this.$element.children().not(this.$stage.parent())); 22258 22259 // check visibility 22260 if (this.$element.is(':visible')) { 22261 // update view 22262 this.refresh(); 22263 } else { 22264 // invalidate width 22265 this.invalidate('width'); 22266 } 22267 22268 this.$element 22269 .removeClass(this.options.loadingClass) 22270 .addClass(this.options.loadedClass); 22271 22272 // register event handlers 22273 this.registerEventHandlers(); 22274 22275 this.leave('initializing'); 22276 this.trigger('initialized'); 22277 }; 22278 22279 /** 22280 * Setups the current settings. 22281 * @todo Remove responsive classes. Why should adaptive designs be brought into IE8? 22282 * @todo Support for media queries by using `matchMedia` would be nice. 22283 * @public 22284 */ 22285 Owl.prototype.setup = function() { 22286 var viewport = this.viewport(), 22287 overwrites = this.options.responsive, 22288 match = -1, 22289 settings = null; 22290 22291 if (!overwrites) { 22292 settings = $.extend({}, this.options); 22293 } else { 22294 $.each(overwrites, function(breakpoint) { 22295 if (breakpoint <= viewport && breakpoint > match) { 22296 match = Number(breakpoint); 22297 } 22298 }); 22299 22300 settings = $.extend({}, this.options, overwrites[match]); 22301 delete settings.responsive; 22302 22303 // responsive class 22304 if (settings.responsiveClass) { 22305 this.$element.attr('class', 22306 this.$element.attr('class').replace(new RegExp('(' + this.options.responsiveClass + '-)\\S+\\s', 'g'), '$1' + match) 22307 ); 22308 } 22309 } 22310 22311 if (this.settings === null || this._breakpoint !== match) { 22312 this.trigger('change', { property: { name: 'settings', value: settings } }); 22313 this._breakpoint = match; 22314 this.settings = settings; 22315 this.invalidate('settings'); 22316 this.trigger('changed', { property: { name: 'settings', value: this.settings } }); 22317 } 22318 }; 22319 22320 /** 22321 * Updates option logic if necessery. 22322 * @protected 22323 */ 22324 Owl.prototype.optionsLogic = function() { 22325 if (this.settings.autoWidth) { 22326 this.settings.stagePadding = false; 22327 this.settings.merge = false; 22328 } 22329 }; 22330 22331 /** 22332 * Prepares an item before add. 22333 * @todo Rename event parameter `content` to `item`. 22334 * @protected 22335 * @returns {jQuery|HTMLElement} - The item container. 22336 */ 22337 Owl.prototype.prepare = function(item, index) { 22338 var event = this.trigger('prepare', { content: item }); 22339 if (!event.data) { 22340 event.data = $('<' + this.settings.itemElement + '/>') 22341 .addClass(this.options.itemClass).attr('data-index', index + 1).append(item) 22342 } 22343 22344 this.trigger('prepared', { content: event.data }); 22345 22346 return event.data; 22347 }; 22348 22349 /** 22350 * Updates the view. 22351 * @public 22352 */ 22353 Owl.prototype.update = function() { 22354 var i = 0, 22355 n = this._pipe.length, 22356 filter = $.proxy(function(p) { return this[p] }, this._invalidated), 22357 cache = {}; 22358 22359 while (i < n) { 22360 if (this._invalidated.all || $.grep(this._pipe[i].filter, filter).length > 0) { 22361 this._pipe[i].run(cache); 22362 } 22363 i++; 22364 } 22365 22366 this._invalidated = {}; 22367 22368 !this.is('valid') && this.enter('valid'); 22369 }; 22370 22371 /** 22372 * Gets the width of the view. 22373 * @public 22374 * @param {Owl.Width} [dimension=Owl.Width.Default] - The dimension to return. 22375 * @returns {Number} - The width of the view in pixel. 22376 */ 22377 Owl.prototype.width = function(dimension) { 22378 dimension = dimension || Owl.Width.Default; 22379 var stagePadding = (this._width < 480 && this.settings.stagePadding > 0) ? 41 : (this._width * this.settings.stagePadding) / 200; 22380 switch (dimension) { 22381 case Owl.Width.Inner: 22382 case Owl.Width.Outer: 22383 return this._width; 22384 default: 22385 return this._width - stagePadding * 2 + this.settings.margin; 22386 } 22387 }; 22388 22389 /** 22390 * Refreshes the carousel primarily for adaptive purposes. 22391 * @public 22392 */ 22393 Owl.prototype.refresh = function() { 22394 this.enter('refreshing'); 22395 this.trigger('refresh'); 22396 22397 this.setup(); 22398 22399 this.optionsLogic(); 22400 22401 this.$element.addClass(this.options.refreshClass); 22402 22403 this.update(); 22404 22405 this.$element.removeClass(this.options.refreshClass); 22406 22407 this.leave('refreshing'); 22408 this.trigger('refreshed'); 22409 }; 22410 22411 /** 22412 * Checks window `resize` event. 22413 * @protected 22414 */ 22415 Owl.prototype.onThrottledResize = function() { 22416 window.clearTimeout(this.resizeTimer); 22417 this.resizeTimer = window.setTimeout(this._handlers.onResize, this.settings.responsiveRefreshRate); 22418 }; 22419 22420 /** 22421 * Checks window `resize` event. 22422 * @protected 22423 */ 22424 Owl.prototype.onResize = function() { 22425 if (!this._items.length) { 22426 return false; 22427 } 22428 22429 if (this._width === this.$element.width()) { 22430 return false; 22431 } 22432 22433 if (!this.$element.is(':visible')) { 22434 return false; 22435 } 22436 22437 this.enter('resizing'); 22438 22439 if (this.trigger('resize').isDefaultPrevented()) { 22440 this.leave('resizing'); 22441 return false; 22442 } 22443 22444 this.invalidate('width'); 22445 22446 this.refresh(); 22447 22448 this.leave('resizing'); 22449 this.trigger('resized'); 22450 }; 22451 22452 /** 22453 * Registers event handlers. 22454 * @todo Check `msPointerEnabled` 22455 * @todo #261 22456 * @protected 22457 */ 22458 Owl.prototype.registerEventHandlers = function() { 22459 if ($.support.transition) { 22460 this.$stage.on($.support.transition.end + '.owl.core', $.proxy(this.onTransitionEnd, this)); 22461 } 22462 22463 if (this.settings.responsive !== false) { 22464 this.on(window, 'resize', this._handlers.onThrottledResize); 22465 } 22466 22467 if (this.settings.mouseDrag) { 22468 this.$element.addClass(this.options.dragClass); 22469 this.$stage.on('mousedown.owl.core', $.proxy(this.onDragStart, this)); 22470 this.$stage.on('dragstart.owl.core selectstart.owl.core', function() { return false }); 22471 } 22472 22473 if (this.settings.touchDrag){ 22474 this.$stage.on('touchstart.owl.core', $.proxy(this.onDragStart, this)); 22475 this.$stage.on('touchcancel.owl.core', $.proxy(this.onDragEnd, this)); 22476 } 22477 }; 22478 22479 /** 22480 * Handles `touchstart` and `mousedown` events. 22481 * @todo Horizontal swipe threshold as option 22482 * @todo #261 22483 * @protected 22484 * @param {Event} event - The event arguments. 22485 */ 22486 Owl.prototype.onDragStart = function(event) { 22487 var stage = null; 22488 22489 if (event.which === 3) { 22490 return; 22491 } 22492 22493 if ($.support.transform) { 22494 stage = this.$stage.css('transform').replace(/.*\(|\)| /g, '').split(','); 22495 stage = { 22496 x: stage[stage.length === 16 ? 12 : 4], 22497 y: stage[stage.length === 16 ? 13 : 5] 22498 }; 22499 } else { 22500 stage = this.$stage.position(); 22501 stage = { 22502 x: this.settings.rtl ? 22503 stage.left + this.$stage.width() - this.width() + this.settings.margin : 22504 stage.left, 22505 y: stage.top 22506 }; 22507 } 22508 22509 if (this.is('animating')) { 22510 $.support.transform ? this.animate(stage.x) : this.$stage.stop() 22511 this.invalidate('position'); 22512 } 22513 22514 this.$element.toggleClass(this.options.grabClass, event.type === 'mousedown'); 22515 22516 this.speed(0); 22517 22518 this._drag.time = new Date().getTime(); 22519 this._drag.target = $(event.target); 22520 this._drag.stage.start = stage; 22521 this._drag.stage.current = stage; 22522 this._drag.pointer = this.pointer(event); 22523 22524 $(document).on('mouseup.owl.core touchend.owl.core', $.proxy(this.onDragEnd, this)); 22525 22526 $(document).one('mousemove.owl.core touchmove.owl.core', $.proxy(function(event) { 22527 var delta = this.difference(this._drag.pointer, this.pointer(event)); 22528 22529 $(document).on('mousemove.owl.core touchmove.owl.core', $.proxy(this.onDragMove, this)); 22530 22531 if (Math.abs(delta.x) < Math.abs(delta.y) && this.is('valid')) { 22532 return; 22533 } 22534 22535 event.preventDefault(); 22536 22537 this.enter('dragging'); 22538 this.trigger('drag'); 22539 }, this)); 22540 }; 22541 22542 /** 22543 * Handles the `touchmove` and `mousemove` events. 22544 * @todo #261 22545 * @protected 22546 * @param {Event} event - The event arguments. 22547 */ 22548 Owl.prototype.onDragMove = function(event) { 22549 var minimum = null, 22550 maximum = null, 22551 pull = null, 22552 delta = this.difference(this._drag.pointer, this.pointer(event)), 22553 stage = this.difference(this._drag.stage.start, delta); 22554 22555 if (!this.is('dragging')) { 22556 return; 22557 } 22558 22559 event.preventDefault(); 22560 22561 if (this.settings.loop) { 22562 minimum = this.coordinates(this.minimum()); 22563 maximum = this.coordinates(this.maximum() + 1) - minimum; 22564 stage.x = (((stage.x - minimum) % maximum + maximum) % maximum) + minimum; 22565 } else { 22566 minimum = this.settings.rtl ? this.coordinates(this.maximum()) : this.coordinates(this.minimum()); 22567 maximum = this.settings.rtl ? this.coordinates(this.minimum()) : this.coordinates(this.maximum()); 22568 pull = this.settings.pullDrag ? -1 * delta.x / 5 : 0; 22569 stage.x = Math.max(Math.min(stage.x, minimum + pull), maximum + pull); 22570 } 22571 22572 this._drag.stage.current = stage; 22573 22574 this.animate(stage.x); 22575 }; 22576 22577 /** 22578 * Handles the `touchend` and `mouseup` events. 22579 * @todo #261 22580 * @todo Threshold for click event 22581 * @protected 22582 * @param {Event} event - The event arguments. 22583 */ 22584 Owl.prototype.onDragEnd = function(event) { 22585 var delta = this.difference(this._drag.pointer, this.pointer(event)), 22586 stage = this._drag.stage.current, 22587 direction = delta.x > 0 ^ this.settings.rtl ? 'left' : 'right'; 22588 22589 $(document).off('.owl.core'); 22590 22591 this.$element.removeClass(this.options.grabClass); 22592 22593 if (delta.x !== 0 && this.is('dragging') || !this.is('valid')) { 22594 this.speed(this.settings.dragEndSpeed || this.settings.smartSpeed); 22595 this.current(this.closest(stage.x, delta.x !== 0 ? direction : this._drag.direction)); 22596 this.invalidate('position'); 22597 this.update(); 22598 22599 this._drag.direction = direction; 22600 22601 if (Math.abs(delta.x) > 3 || new Date().getTime() - this._drag.time > 300) { 22602 this._drag.target.one('click.owl.core', function() { return false; }); 22603 } 22604 } 22605 22606 if (!this.is('dragging')) { 22607 return; 22608 } 22609 22610 this.leave('dragging'); 22611 this.trigger('dragged'); 22612 }; 22613 22614 /** 22615 * Gets absolute position of the closest item for a coordinate. 22616 * @todo Setting `freeDrag` makes `closest` not reusable. See #165. 22617 * @protected 22618 * @param {Number} coordinate - The coordinate in pixel. 22619 * @param {String} direction - The direction to check for the closest item. Ether `left` or `right`. 22620 * @return {Number} - The absolute position of the closest item. 22621 */ 22622 Owl.prototype.closest = function(coordinate, direction) { 22623 var position = -1, 22624 pull = 30, 22625 width = this.width(), 22626 coordinates = this.coordinates(); 22627 22628 if (!this.settings.freeDrag) { 22629 // check closest item 22630 $.each(coordinates, $.proxy(function(index, value) { 22631 if (coordinate > value - pull && coordinate < value + pull) { 22632 position = index; 22633 } else if (this.op(coordinate, '<', value) 22634 && this.op(coordinate, '>', coordinates[index + 1] || value - width)) { 22635 position = direction === 'left' ? index + 1 : index; 22636 } 22637 return position === -1; 22638 }, this)); 22639 } 22640 22641 if (!this.settings.loop) { 22642 // non loop boundries 22643 if (this.op(coordinate, '>', coordinates[this.minimum()])) { 22644 position = coordinate = this.minimum(); 22645 } else if (this.op(coordinate, '<', coordinates[this.maximum()])) { 22646 position = coordinate = this.maximum(); 22647 } 22648 } 22649 22650 return position; 22651 }; 22652 22653 /** 22654 * Animates the stage. 22655 * @todo #270 22656 * @public 22657 * @param {Number} coordinate - The coordinate in pixels. 22658 */ 22659 Owl.prototype.animate = function(coordinate) { 22660 var animate = this.speed() > 0; 22661 22662 this.is('animating') && this.onTransitionEnd(); 22663 22664 if (animate) { 22665 this.enter('animating'); 22666 this.trigger('translate'); 22667 } 22668 22669 if ($.support.transform3d && $.support.transition) { 22670 this.$stage.css({ 22671 transform: 'translate3d(' + coordinate + 'px,0px,0px)', 22672 transition: (this.speed() / 1000) + 's' 22673 }); 22674 } else if (animate) { 22675 this.$stage.animate({ 22676 left: coordinate + 'px' 22677 }, this.speed(), this.settings.fallbackEasing, $.proxy(this.onTransitionEnd, this)); 22678 } else { 22679 this.$stage.css({ 22680 left: coordinate + 'px' 22681 }); 22682 } 22683 }; 22684 22685 /** 22686 * Checks whether the carousel is in a specific state or not. 22687 * @param {String} state - The state to check. 22688 * @returns {Boolean} - The flag which indicates if the carousel is busy. 22689 */ 22690 Owl.prototype.is = function(state) { 22691 return this._states.current[state] && this._states.current[state] > 0; 22692 }; 22693 22694 /** 22695 * Sets the absolute position of the current item. 22696 * @public 22697 * @param {Number} [position] - The new absolute position or nothing to leave it unchanged. 22698 * @returns {Number} - The absolute position of the current item. 22699 */ 22700 Owl.prototype.current = function(position) { 22701 if (position === undefined) { 22702 return this._current; 22703 } 22704 22705 if (this._items.length === 0) { 22706 return undefined; 22707 } 22708 22709 position = this.normalize(position); 22710 22711 if (this._current !== position) { 22712 var event = this.trigger('change', { property: { name: 'position', value: position } }); 22713 22714 if (event.data !== undefined) { 22715 position = this.normalize(event.data); 22716 } 22717 22718 this._current = position; 22719 22720 this.invalidate('position'); 22721 22722 this.trigger('changed', { property: { name: 'position', value: this._current } }); 22723 } 22724 22725 return this._current; 22726 }; 22727 22728 /** 22729 * Invalidates the given part of the update routine. 22730 * @param {String} [part] - The part to invalidate. 22731 * @returns {Array.<String>} - The invalidated parts. 22732 */ 22733 Owl.prototype.invalidate = function(part) { 22734 if ($.type(part) === 'string') { 22735 this._invalidated[part] = true; 22736 this.is('valid') && this.leave('valid'); 22737 } 22738 return $.map(this._invalidated, function(v, i) { return i }); 22739 }; 22740 22741 /** 22742 * Resets the absolute position of the current item. 22743 * @public 22744 * @param {Number} position - The absolute position of the new item. 22745 */ 22746 Owl.prototype.reset = function(position) { 22747 position = this.normalize(position); 22748 22749 if (position === undefined) { 22750 return; 22751 } 22752 22753 this._speed = 0; 22754 this._current = position; 22755 22756 this.suppress([ 'translate', 'translated' ]); 22757 22758 this.animate(this.coordinates(position)); 22759 22760 this.release([ 'translate', 'translated' ]); 22761 }; 22762 22763 /** 22764 * Normalizes an absolute or a relative position of an item. 22765 * @public 22766 * @param {Number} position - The absolute or relative position to normalize. 22767 * @param {Boolean} [relative=false] - Whether the given position is relative or not. 22768 * @returns {Number} - The normalized position. 22769 */ 22770 Owl.prototype.normalize = function(position, relative) { 22771 var n = this._items.length, 22772 m = relative ? 0 : this._clones.length; 22773 22774 if (!$.isNumeric(position) || n < 1) { 22775 position = undefined; 22776 } else if (position < 0 || position >= n + m) { 22777 position = ((position - m / 2) % n + n) % n + m / 2; 22778 } 22779 22780 return position; 22781 }; 22782 22783 /** 22784 * Converts an absolute position of an item into a relative one. 22785 * @public 22786 * @param {Number} position - The absolute position to convert. 22787 * @returns {Number} - The converted position. 22788 */ 22789 Owl.prototype.relative = function(position) { 22790 position -= this._clones.length / 2; 22791 return this.normalize(position, true); 22792 }; 22793 22794 /** 22795 * Gets the maximum position for the current item. 22796 * @public 22797 * @param {Boolean} [relative=false] - Whether to return an absolute position or a relative position. 22798 * @returns {Number} 22799 */ 22800 Owl.prototype.maximum = function(relative) { 22801 var settings = this.settings, 22802 maximum = this._coordinates.length, 22803 boundary = Math.abs(this._coordinates[maximum - 1]) - this._width, 22804 i = -1, j; 22805 22806 if (settings.loop) { 22807 maximum = this._clones.length / 2 + this._items.length - 1; 22808 } else if (settings.autoWidth || settings.merge) { 22809 // binary search 22810 while (maximum - i > 1) { 22811 Math.abs(this._coordinates[j = maximum + i >> 1]) < boundary 22812 ? i = j : maximum = j; 22813 } 22814 } else if (settings.center) { 22815 maximum = this._items.length - 1; 22816 } else { 22817 maximum = this._items.length - settings.items; 22818 } 22819 22820 if (relative) { 22821 maximum -= this._clones.length / 2; 22822 } 22823 22824 return Math.max(maximum, 0); 22825 }; 22826 22827 /** 22828 * Gets the minimum position for the current item. 22829 * @public 22830 * @param {Boolean} [relative=false] - Whether to return an absolute position or a relative position. 22831 * @returns {Number} 22832 */ 22833 Owl.prototype.minimum = function(relative) { 22834 return relative ? 0 : this._clones.length / 2; 22835 }; 22836 22837 /** 22838 * Gets an item at the specified relative position. 22839 * @public 22840 * @param {Number} [position] - The relative position of the item. 22841 * @return {jQuery|Array.<jQuery>} - The item at the given position or all items if no position was given. 22842 */ 22843 Owl.prototype.items = function(position) { 22844 if (position === undefined) { 22845 return this._items.slice(); 22846 } 22847 22848 position = this.normalize(position, true); 22849 return this._items[position]; 22850 }; 22851 22852 /** 22853 * Gets an item at the specified relative position. 22854 * @public 22855 * @param {Number} [position] - The relative position of the item. 22856 * @return {jQuery|Array.<jQuery>} - The item at the given position or all items if no position was given. 22857 */ 22858 Owl.prototype.mergers = function(position) { 22859 if (position === undefined) { 22860 return this._mergers.slice(); 22861 } 22862 22863 position = this.normalize(position, true); 22864 return this._mergers[position]; 22865 }; 22866 22867 /** 22868 * Gets the absolute positions of clones for an item. 22869 * @public 22870 * @param {Number} [position] - The relative position of the item. 22871 * @returns {Array.<Number>} - The absolute positions of clones for the item or all if no position was given. 22872 */ 22873 Owl.prototype.clones = function(position) { 22874 var odd = this._clones.length / 2, 22875 even = odd + this._items.length, 22876 map = function(index) { return index % 2 === 0 ? even + index / 2 : odd - (index + 1) / 2 }; 22877 22878 if (position === undefined) { 22879 return $.map(this._clones, function(v, i) { return map(i) }); 22880 } 22881 22882 return $.map(this._clones, function(v, i) { return v === position ? map(i) : null }); 22883 }; 22884 22885 /** 22886 * Sets the current animation speed. 22887 * @public 22888 * @param {Number} [speed] - The animation speed in milliseconds or nothing to leave it unchanged. 22889 * @returns {Number} - The current animation speed in milliseconds. 22890 */ 22891 Owl.prototype.speed = function(speed) { 22892 if (speed !== undefined) { 22893 this._speed = speed; 22894 } 22895 22896 return this._speed; 22897 }; 22898 22899 /** 22900 * Gets the coordinate of an item. 22901 * @todo The name of this method is missleanding. 22902 * @public 22903 * @param {Number} position - The absolute position of the item within `minimum()` and `maximum()`. 22904 * @returns {Number|Array.<Number>} - The coordinate of the item in pixel or all coordinates. 22905 */ 22906 Owl.prototype.coordinates = function(position) { 22907 var coordinate = null; 22908 22909 if (position === undefined) { 22910 return $.map(this._coordinates, $.proxy(function(coordinate, index) { 22911 return this.coordinates(index); 22912 }, this)); 22913 } 22914 22915 if (this.settings.center) { 22916 coordinate = this._coordinates[position]; 22917 coordinate += (this.width() - coordinate + (this._coordinates[position - 1] || 0)) / 2 * (this.settings.rtl ? -1 : 1); 22918 } else { 22919 coordinate = this._coordinates[position - 1] || 0; 22920 } 22921 22922 return coordinate; 22923 }; 22924 22925 /** 22926 * Calculates the speed for a translation. 22927 * @protected 22928 * @param {Number} from - The absolute position of the start item. 22929 * @param {Number} to - The absolute position of the target item. 22930 * @param {Number} [factor=undefined] - The time factor in milliseconds. 22931 * @returns {Number} - The time in milliseconds for the translation. 22932 */ 22933 Owl.prototype.duration = function(from, to, factor) { 22934 return Math.min(Math.max(Math.abs(to - from), 1), 6) * Math.abs((factor || this.settings.smartSpeed)); 22935 }; 22936 22937 /** 22938 * Slides to the specified item. 22939 * @public 22940 * @param {Number} position - The position of the item. 22941 * @param {Number} [speed] - The time in milliseconds for the transition. 22942 */ 22943 Owl.prototype.to = function(position, speed) { 22944 var current = this.current(), 22945 revert = null, 22946 distance = position - this.relative(current), 22947 direction = (distance > 0) - (distance < 0), 22948 items = this._items.length, 22949 minimum = this.minimum(), 22950 maximum = this.maximum(); 22951 22952 if (this.settings.loop) { 22953 if (!this.settings.rewind && Math.abs(distance) > items / 2) { 22954 distance += direction * -1 * items; 22955 } 22956 22957 position = current + distance; 22958 revert = ((position - minimum) % items + items) % items + minimum; 22959 22960 if (revert !== position && revert - distance <= maximum && revert - distance > 0) { 22961 current = revert - distance; 22962 position = revert; 22963 this.reset(current); 22964 } 22965 } else if (this.settings.rewind) { 22966 maximum += 1; 22967 position = (position % maximum + maximum) % maximum; 22968 } else { 22969 position = Math.max(minimum, Math.min(maximum, position)); 22970 } 22971 22972 this.speed(this.duration(current, position, speed)); 22973 this.current(position); 22974 22975 if (this.$element.is(':visible')) { 22976 this.update(); 22977 } 22978 }; 22979 22980 /** 22981 * Slides to the next item. 22982 * @public 22983 * @param {Number}
vendor: 12,284 bytes, lines 22983-23403
22983 [speed] - The time in milliseconds for the transition. 22984 */ 22985 Owl.prototype.next = function(speed) { 22986 speed = speed || false; 22987 this.to(this.relative(this.current()) + 1, speed); 22988 }; 22989 22990 /** 22991 * Slides to the previous item. 22992 * @public 22993 * @param {Number} [speed] - The time in milliseconds for the transition. 22994 */ 22995 Owl.prototype.prev = function(speed) { 22996 speed = speed || false; 22997 this.to(this.relative(this.current()) - 1, speed); 22998 }; 22999 23000 /** 23001 * Handles the end of an animation. 23002 * @protected 23003 * @param {Event} event - The event arguments. 23004 */ 23005 Owl.prototype.onTransitionEnd = function(event) { 23006 23007 // if css2 animation then event object is undefined 23008 if (event !== undefined) { 23009 event.stopPropagation(); 23010 23011 // Catch only owl-stage transitionEnd event 23012 if ((event.target || event.srcElement || event.originalTarget) !== this.$stage.get(0)) { 23013 return false; 23014 } 23015 } 23016 23017 this.leave('animating'); 23018 this.trigger('translated'); 23019 }; 23020 23021 /** 23022 * Gets viewport width. 23023 * @protected 23024 * @return {Number} - The width in pixel. 23025 */ 23026 Owl.prototype.viewport = function() { 23027 var width; 23028 if (this.options.responsiveBaseElement !== window) { 23029 width = $(this.options.responsiveBaseElement).width(); 23030 } else if (window.innerWidth) { 23031 width = window.innerWidth; 23032 } else if (document.documentElement && document.documentElement.clientWidth) { 23033 width = document.documentElement.clientWidth; 23034 } else { 23035 throw 'Can not detect viewport width.'; 23036 } 23037 23038 return width; 23039 }; 23040 23041 /** 23042 * Replaces the current content. 23043 * @public 23044 * @param {HTMLElement|jQuery|String} content - The new content. 23045 */ 23046 Owl.prototype.replace = function(content) { 23047 this.$stage.empty(); 23048 this._items = []; 23049 23050 if (content) { 23051 content = (content instanceof jQuery) ? content : $(content); 23052 } 23053 23054 if (this.settings.nestedItemSelector) { 23055 content = content.find('.' + this.settings.nestedItemSelector); 23056 } 23057 23058 content.filter(function() { 23059 return this.nodeType === 1; 23060 }).each($.proxy(function(index, item) { 23061 item = this.prepare(item, index); 23062 this.$stage.append(item); 23063 this._items.push(item); 23064 this._mergers.push(item.find('[data-merge]').addBack('[data-merge]').attr('data-merge') * 1 || 1); 23065 }, this)); 23066 23067 this.reset($.isNumeric(this.settings.startPosition) ? this.settings.startPosition : 0); 23068 23069 this.invalidate('items'); 23070 }; 23071 23072 /** 23073 * Adds an item. 23074 * @todo Use `item` instead of `content` for the event arguments. 23075 * @public 23076 * @param {HTMLElement|jQuery|String} content - The item content to add. 23077 * @param {Number} [position] - The relative position at which to insert the item otherwise the item will be added to the end. 23078 */ 23079 Owl.prototype.add = function(content, position) { 23080 var current = this.relative(this._current); 23081 23082 position = position === undefined ? this._items.length : this.normalize(position, true); 23083 content = content instanceof jQuery ? content : $(content); 23084 23085 this.trigger('add', { content: content, position: position }); 23086 23087 content = this.prepare(content, this._items[current].index()); 23088 23089 if (this._items.length === 0 || position === this._items.length) { 23090 this._items.length === 0 && this.$stage.append(content); 23091 this._items.length !== 0 && this._items[position - 1].after(content); 23092 this._items.push(content); 23093 this._mergers.push(content.find('[data-merge]').andSelf('[data-merge]').attr('data-merge') * 1 || 1); 23094 } else { 23095 this._items[position].before(content); 23096 this._items.splice(position, 0, content); 23097 this._mergers.splice(position, 0, content.find('[data-merge]').andSelf('[data-merge]').attr('data-merge') * 1 || 1); 23098 } 23099 23100 this._items[current] && this.reset(this._items[current].index()); 23101 23102 this.invalidate('items'); 23103 23104 this.trigger('added', { content: content, position: position }); 23105 }; 23106 23107 /** 23108 * Removes an item by its position. 23109 * @todo Use `item` instead of `content` for the event arguments. 23110 * @public 23111 * @param {Number} position - The relative position of the item to remove. 23112 */ 23113 Owl.prototype.remove = function(position) { 23114 position = this.normalize(position, true); 23115 23116 if (position === undefined) { 23117 return; 23118 } 23119 23120 this.trigger('remove', { content: this._items[position], position: position }); 23121 23122 this._items[position].remove(); 23123 this._items.splice(position, 1); 23124 this._mergers.splice(position, 1); 23125 23126 this.invalidate('items'); 23127 23128 this.trigger('removed', { content: null, position: position }); 23129 }; 23130 23131 /** 23132 * Preloads images with auto width. 23133 * @todo Replace by a more generic approach 23134 * @protected 23135 */ 23136 Owl.prototype.preloadAutoWidthImages = function(images) { 23137 images.each($.proxy(function(i, element) { 23138 this.enter('pre-loading'); 23139 element = $(element); 23140 $(new Image()).one('load', $.proxy(function(e) { 23141 element.attr('src', e.target.src); 23142 element.css('opacity', 1); 23143 this.leave('pre-loading'); 23144 !this.is('pre-loading') && !this.is('initializing') && this.refresh(); 23145 }, this)).attr('src', element.attr('src') || element.attr('data-src') || element.attr('data-src-retina')); 23146 }, this)); 23147 }; 23148 23149 /** 23150 * Destroys the carousel. 23151 * @public 23152 */ 23153 Owl.prototype.destroy = function() { 23154 23155 this.$element.off('.owl.core'); 23156 this.$stage.off('.owl.core'); 23157 $(document).off('.owl.core'); 23158 23159 if (this.settings.responsive !== false) { 23160 window.clearTimeout(this.resizeTimer); 23161 this.off(window, 'resize', this._handlers.onThrottledResize); 23162 } 23163 23164 for (var i in this._plugins) { 23165 this._plugins[i].destroy(); 23166 } 23167 23168 this.$stage.children('.cloned').remove(); 23169 23170 this.$stage.unwrap(); 23171 this.$stage.children().contents().unwrap(); 23172 this.$stage.children().unwrap(); 23173 23174 this.$element 23175 .removeClass(this.options.refreshClass) 23176 .removeClass(this.options.loadingClass) 23177 .removeClass(this.options.loadedClass) 23178 .removeClass(this.options.rtlClass) 23179 .removeClass(this.options.dragClass) 23180 .removeClass(this.options.grabClass) 23181 .attr('class', this.$element.attr('class').replace(new RegExp(this.options.responsiveClass + '-\\S+\\s', 'g'), '')) 23182 .removeData('owl.carousel'); 23183 }; 23184 23185 /** 23186 * Operators to calculate right-to-left and left-to-right. 23187 * @protected 23188 * @param {Number} [a] - The left side operand. 23189 * @param {String} [o] - The operator. 23190 * @param {Number} [b] - The right side operand. 23191 */ 23192 Owl.prototype.op = function(a, o, b) { 23193 var rtl = this.settings.rtl; 23194 switch (o) { 23195 case '<': 23196 return rtl ? a > b : a < b; 23197 case '>': 23198 return rtl ? a < b : a > b; 23199 case '>=': 23200 return rtl ? a <= b : a >= b; 23201 case '<=': 23202 return rtl ? a >= b : a <= b; 23203 default: 23204 break; 23205 } 23206 }; 23207 23208 /** 23209 * Attaches to an internal event. 23210 * @protected 23211 * @param {HTMLElement} element - The event source. 23212 * @param {String} event - The event name. 23213 * @param {Function} listener - The event handler to attach. 23214 * @param {Boolean} capture - Wether the event should be handled at the capturing phase or not. 23215 */ 23216 Owl.prototype.on = function(element, event, listener, capture) { 23217 if (element.addEventListener) { 23218 element.addEventListener(event, listener, capture); 23219 } else if (element.attachEvent) { 23220 element.attachEvent('on' + event, listener); 23221 } 23222 }; 23223 23224 /** 23225 * Detaches from an internal event. 23226 * @protected 23227 * @param {HTMLElement} element - The event source. 23228 * @param {String} event - The event name. 23229 * @param {Function} listener - The attached event handler to detach. 23230 * @param {Boolean} capture - Wether the attached event handler was registered as a capturing listener or not. 23231 */ 23232 Owl.prototype.off = function(element, event, listener, capture) { 23233 if (element.removeEventListener) { 23234 element.removeEventListener(event, listener, capture); 23235 } else if (element.detachEvent) { 23236 element.detachEvent('on' + event, listener); 23237 } 23238 }; 23239 23240 /** 23241 * Triggers a public event. 23242 * @todo Remove `status`, `relatedTarget` should be used instead. 23243 * @protected 23244 * @param {String} name - The event name. 23245 * @param {*} [data=null] - The event data. 23246 * @param {String} [namespace=carousel] - The event namespace. 23247 * @param {String} [state] - The state which is associated with the event. 23248 * @param {Boolean} [enter=false] - Indicates if the call enters the specified state or not. 23249 * @returns {Event} - The event arguments. 23250 */ 23251 Owl.prototype.trigger = function(name, data, namespace, state, enter) { 23252 var status = { 23253 item: { count: this._items.length, index: this.current() } 23254 }, handler = $.camelCase( 23255 $.grep([ 'on', name, namespace ], function(v) { return v }) 23256 .join('-').toLowerCase() 23257 ), event = $.Event( 23258 [ name, 'owl', namespace || 'carousel' ].join('.').toLowerCase(), 23259 $.extend({ relatedTarget: this }, status, data) 23260 ); 23261 23262 if (!this._supress[name]) { 23263 $.each(this._plugins, function(name, plugin) { 23264 if (plugin.onTrigger) { 23265 plugin.onTrigger(event); 23266 } 23267 }); 23268 23269 this.register({ type: Owl.Type.Event, name: name }); 23270 this.$element.trigger(event); 23271 23272 if (this.settings && typeof this.settings[handler] === 'function') { 23273 this.settings[handler].call(this, event); 23274 } 23275 } 23276 23277 return event; 23278 }; 23279 23280 /** 23281 * Enters a state. 23282 * @param name - The state name. 23283 */ 23284 Owl.prototype.enter = function(name) { 23285 $.each([ name ].concat(this._states.tags[name] || []), $.proxy(function(i, name) { 23286 if (this._states.current[name] === undefined) { 23287 this._states.current[name] = 0; 23288 } 23289 23290 this._states.current[name]++; 23291 }, this)); 23292 }; 23293 23294 /** 23295 * Leaves a state. 23296 * @param name - The state name. 23297 */ 23298 Owl.prototype.leave = function(name) { 23299 $.each([ name ].concat(this._states.tags[name] || []), $.proxy(function(i, name) { 23300 this._states.current[name]--; 23301 }, this)); 23302 }; 23303 23304 /** 23305 * Registers an event or state. 23306 * @public 23307 * @param {Object} object - The event or state to register. 23308 */ 23309 Owl.prototype.register = function(object) { 23310 if (object.type === Owl.Type.Event) { 23311 if (!$.event.special[object.name]) { 23312 $.event.special[object.name] = {}; 23313 } 23314 23315 if (!$.event.special[object.name].owl) { 23316 var _default = $.event.special[object.name]._default; 23317 $.event.special[object.name]._default = function(e) { 23318 if (_default && _default.apply && (!e.namespace || e.namespace.indexOf('owl') === -1)) { 23319 return _default.apply(this, arguments); 23320 } 23321 return e.namespace && e.namespace.indexOf('owl') > -1; 23322 }; 23323 $.event.special[object.name].owl = true; 23324 } 23325 } else if (object.type === Owl.Type.State) { 23326 if (!this._states.tags[object.name]) { 23327 this._states.tags[object.name] = object.tags; 23328 } else { 23329 this._states.tags[object.name] = this._states.tags[object.name].concat(object.tags); 23330 } 23331 23332 this._states.tags[object.name] = $.grep(this._states.tags[object.name], $.proxy(function(tag, i) { 23333 return $.inArray(tag, this._states.tags[object.name]) === i; 23334 }, this)); 23335 } 23336 }; 23337 23338 /** 23339 * Suppresses events. 23340 * @protected 23341 * @param {Array.<String>} events - The events to suppress. 23342 */ 23343 Owl.prototype.suppress = function(events) { 23344 $.each(events, $.proxy(function(index, event) { 23345 this._supress[event] = true; 23346 }, this)); 23347 }; 23348 23349 /** 23350 * Releases suppressed events. 23351 * @protected 23352 * @param {Array.<String>} events - The events to release. 23353 */ 23354 Owl.prototype.release = function(events) { 23355 $.each(events, $.proxy(function(index, event) { 23356 delete this._supress[event]; 23357 }, this)); 23358 }; 23359 23360 /** 23361 * Gets unified pointer coordinates from event. 23362 * @todo #261 23363 * @protected 23364 * @param {Event} - The `mousedown` or `touchstart` event. 23365 * @returns {Object} - Contains `x` and `y` coordinates of current pointer position. 23366 */ 23367 Owl.prototype.pointer = function(event) { 23368 var result = { x: null, y: null }; 23369 23370 event = event.originalEvent || event || window.event; 23371 23372 event = event.touches && event.touches.length ? 23373 event.touches[0] : event.changedTouches && event.changedTouches.length ? 23374 event.changedTouches[0] : event; 23375 23376 if (event.pageX) { 23377 result.x = event.pageX; 23378 result.y = event.pageY; 23379 } else { 23380 result.x = event.clientX; 23381 result.y = event.clientY; 23382 } 23383 23384 return result; 23385 }; 23386 23387 /** 23388 * Gets the difference of two vectors. 23389 * @todo #261 23390 * @protected 23391 * @param {Object} - The first vector. 23392 * @param {Object} - The second vector. 23393 * @returns {Object} - The difference. 23394 */ 23395 Owl.prototype.difference = function(first, second) { 23396 return { 23397 x: first.x - second.x, 23398 y: first.y - second.y 23399 }; 23400 }; 23401 23402 /** 23403 * The jQuery Plugin for the Owl Carousel
vendor: 32,216 bytes, lines 23404-24686
23404 * @todo Navigation plugin `next` and `prev` 23405 * @public 23406 */ 23407 $.fn.owlCarousel = function(option) { 23408 var args = Array.prototype.slice.call(arguments, 1); 23409 23410 return this.each(function() { 23411 var $this = $(this), 23412 data = $this.data('owl.carousel'); 23413 23414 if (!data) { 23415 data = new Owl(this, typeof option == 'object' && option); 23416 $this.data('owl.carousel', data); 23417 23418 $.each([ 23419 'next', 'prev', 'to', 'destroy', 'refresh', 'replace', 'add', 'remove' 23420 ], function(i, event) { 23421 data.register({ type: Owl.Type.Event, name: event }); 23422 data.$element.on(event + '.owl.carousel.core', $.proxy(function(e) { 23423 if (e.namespace && e.relatedTarget !== this) { 23424 this.suppress([ event ]); 23425 data[event].apply(this, [].slice.call(arguments, 1)); 23426 this.release([ event ]); 23427 } 23428 }, data)); 23429 }); 23430 } 23431 23432 if (typeof option == 'string' && option.charAt(0) !== '_') { 23433 data[option].apply(data, args); 23434 } 23435 }); 23436 }; 23437 23438 /** 23439 * The constructor for the jQuery Plugin 23440 * @public 23441 */ 23442 $.fn.owlCarousel.Constructor = Owl; 23443 23444})(window.Zepto || window.jQuery, window, document); 23445 23446/** 23447 * AutoRefresh Plugin 23448 * @version 2.0.0-beta.3 23449 * @author Artus Kolanowski 23450 * @license The MIT License (MIT) 23451 */ 23452;(function($, window, document, undefined) { 23453 23454 /** 23455 * Creates the auto refresh plugin. 23456 * @class The Auto Refresh Plugin 23457 * @param {Owl} carousel - The Owl Carousel 23458 */ 23459 var AutoRefresh = function(carousel) { 23460 /** 23461 * Reference to the core. 23462 * @protected 23463 * @type {Owl} 23464 */ 23465 this._core = carousel; 23466 23467 /** 23468 * Refresh interval. 23469 * @protected 23470 * @type {number} 23471 */ 23472 this._interval = null; 23473 23474 /** 23475 * Whether the element is currently visible or not. 23476 * @protected 23477 * @type {Boolean} 23478 */ 23479 this._visible = null; 23480 23481 /** 23482 * All event handlers. 23483 * @protected 23484 * @type {Object} 23485 */ 23486 this._handlers = { 23487 'initialized.owl.carousel': $.proxy(function(e) { 23488 if (e.namespace && this._core.settings.autoRefresh) { 23489 this.watch(); 23490 } 23491 }, this) 23492 }; 23493 23494 // set default options 23495 this._core.options = $.extend({}, AutoRefresh.Defaults, this._core.options); 23496 23497 // register event handlers 23498 this._core.$element.on(this._handlers); 23499 }; 23500 23501 /** 23502 * Default options. 23503 * @public 23504 */ 23505 AutoRefresh.Defaults = { 23506 autoRefresh: true, 23507 autoRefreshInterval: 500 23508 }; 23509 23510 /** 23511 * Watches the element. 23512 */ 23513 AutoRefresh.prototype.watch = function() { 23514 if (this._interval) { 23515 return; 23516 } 23517 23518 this._visible = this._core.$element.is(':visible'); 23519 this._interval = window.setInterval($.proxy(this.refresh, this), this._core.settings.autoRefreshInterval); 23520 }; 23521 23522 /** 23523 * Refreshes the element. 23524 */ 23525 AutoRefresh.prototype.refresh = function() { 23526 if (this._core.$element.is(':visible') === this._visible) { 23527 return; 23528 } 23529 23530 this._visible = !this._visible; 23531 23532 this._core.$element.toggleClass('owl-hidden', !this._visible); 23533 23534 this._visible && (this._core.invalidate('width') && this._core.refresh()); 23535 }; 23536 23537 /** 23538 * Destroys the plugin. 23539 */ 23540 AutoRefresh.prototype.destroy = function() { 23541 var handler, property; 23542 23543 window.clearInterval(this._interval); 23544 23545 for (handler in this._handlers) { 23546 this._core.$element.off(handler, this._handlers[handler]); 23547 } 23548 for (property in Object.getOwnPropertyNames(this)) { 23549 typeof this[property] != 'function' && (this[property] = null); 23550 } 23551 }; 23552 23553 $.fn.owlCarousel.Constructor.Plugins.AutoRefresh = AutoRefresh; 23554 23555})(window.Zepto || window.jQuery, window, document); 23556 23557/** 23558 * Lazy Plugin 23559 * @version 2.0.0-beta.3 23560 * @author Bartosz Wojciechowski 23561 * @license The MIT License (MIT) 23562 */ 23563;(function($, window, document, undefined) { 23564 23565 /** 23566 * Creates the lazy plugin. 23567 * @class The Lazy Plugin 23568 * @param {Owl} carousel - The Owl Carousel 23569 */ 23570 var Lazy = function(carousel) { 23571 23572 /** 23573 * Reference to the core. 23574 * @protected 23575 * @type {Owl} 23576 */ 23577 this._core = carousel; 23578 23579 /** 23580 * Already loaded items. 23581 * @protected 23582 * @type {Array.<jQuery>} 23583 */ 23584 this._loaded = []; 23585 23586 /** 23587 * Event handlers. 23588 * @protected 23589 * @type {Object} 23590 */ 23591 this._handlers = { 23592 'initialized.owl.carousel change.owl.carousel': $.proxy(function(e) { 23593 if (!e.namespace) { 23594 return; 23595 } 23596 23597 if (!this._core.settings || !this._core.settings.lazyLoad) { 23598 return; 23599 } 23600 23601 if ((e.property && e.property.name == 'position') || e.type == 'initialized') { 23602 var settings = this._core.settings, 23603 n = (settings.center && Math.ceil(settings.items / 2) || settings.items), 23604 i = ((settings.center && n * -1) || 0), 23605 position = ((e.property && e.property.value) || this._core.current()) + i, 23606 clones = this._core.clones().length, 23607 load = $.proxy(function(i, v) { this.load(v) }, this); 23608 23609 while (i++ < n) { 23610 this.load(clones / 2 + this._core.relative(position)); 23611 clones && $.each(this._core.clones(this._core.relative(position)), load); 23612 position++; 23613 } 23614 } 23615 }, this) 23616 }; 23617 23618 // set the default options 23619 this._core.options = $.extend({}, Lazy.Defaults, this._core.options); 23620 23621 // register event handler 23622 this._core.$element.on(this._handlers); 23623 } 23624 23625 /** 23626 * Default options. 23627 * @public 23628 */ 23629 Lazy.Defaults = { 23630 lazyLoad: false 23631 } 23632 23633 /** 23634 * Loads all resources of an item at the specified position. 23635 * @param {Number} position - The absolute position of the item. 23636 * @protected 23637 */ 23638 Lazy.prototype.load = function(position) { 23639 var $item = this._core.$stage.children().eq(position), 23640 $elements = $item && $item.find('.owl-lazy'); 23641 23642 if (!$elements || $.inArray($item.get(0), this._loaded) > -1) { 23643 return; 23644 } 23645 23646 $elements.each($.proxy(function(index, element) { 23647 var $element = $(element), image, 23648 url = (window.devicePixelRatio > 1 && $element.attr('data-src-retina')) || $element.attr('data-src'); 23649 23650 this._core.trigger('load', { element: $element, url: url }, 'lazy'); 23651 23652 if ($element.is('img')) { 23653 $element.one('load.owl.lazy', $.proxy(function() { 23654 $element.css('opacity', 1); 23655 this._core.trigger('loaded', { element: $element, url: url }, 'lazy'); 23656 }, this)).attr('src', url); 23657 } else { 23658 image = new Image(); 23659 image.onload = $.proxy(function() { 23660 $element.css({ 23661 'background-image': 'url(' + url + ')', 23662 'opacity': '1' 23663 }); 23664 this._core.trigger('loaded', { element: $element, url: url }, 'lazy'); 23665 }, this); 23666 image.src = url; 23667 } 23668 }, this)); 23669 23670 this._loaded.push($item.get(0)); 23671 } 23672 23673 /** 23674 * Destroys the plugin. 23675 * @public 23676 */ 23677 Lazy.prototype.destroy = function() { 23678 var handler, property; 23679 23680 for (handler in this.handlers) { 23681 this._core.$element.off(handler, this.handlers[handler]); 23682 } 23683 for (property in Object.getOwnPropertyNames(this)) { 23684 typeof this[property] != 'function' && (this[property] = null); 23685 } 23686 }; 23687 23688 $.fn.owlCarousel.Constructor.Plugins.Lazy = Lazy; 23689 23690})(window.Zepto || window.jQuery, window, document); 23691 23692/** 23693 * AutoHeight Plugin 23694 * @version 2.0.0-beta.3 23695 * @author Bartosz Wojciechowski 23696 * @license The MIT License (MIT) 23697 */ 23698;(function($, window, document, undefined) { 23699 23700 /** 23701 * Creates the auto height plugin. 23702 * @class The Auto Height Plugin 23703 * @param {Owl} carousel - The Owl Carousel 23704 */ 23705 var AutoHeight = function(carousel) { 23706 /** 23707 * Reference to the core. 23708 * @protected 23709 * @type {Owl} 23710 */ 23711 this._core = carousel; 23712 23713 /** 23714 * All event handlers. 23715 * @protected 23716 * @type {Object} 23717 */ 23718 this._handlers = { 23719 'initialized.owl.carousel refreshed.owl.carousel': $.proxy(function(e) { 23720 if (e.namespace && this._core.settings.autoHeight) { 23721 this.update(); 23722 } 23723 }, this), 23724 'changed.owl.carousel': $.proxy(function(e) { 23725 if (e.namespace && this._core.settings.autoHeight && e.property.name == 'position'){ 23726 this.update(); 23727 } 23728 }, this), 23729 'loaded.owl.lazy': $.proxy(function(e) { 23730 if (e.namespace && this._core.settings.autoHeight 23731 && e.element.closest('.' + this._core.settings.itemClass).index() === this._core.current()) { 23732 this.update(); 23733 } 23734 }, this) 23735 }; 23736 23737 // set default options 23738 this._core.options = $.extend({}, AutoHeight.Defaults, this._core.options); 23739 23740 // register event handlers 23741 this._core.$element.on(this._handlers); 23742 }; 23743 23744 /** 23745 * Default options. 23746 * @public 23747 */ 23748 AutoHeight.Defaults = { 23749 autoHeight: false, 23750 autoHeightClass: 'owl-height' 23751 }; 23752 23753 /** 23754 * Updates the view. 23755 */ 23756 AutoHeight.prototype.update = function() { 23757 var start = this._core._current, 23758 end = start + this._core.settings.items, 23759 visible = this._core.$stage.children().toArray().slice(start, end); 23760 heights = [], 23761 maxheight = 0; 23762 23763 $.each(visible, function(index, item) { 23764 heights.push($(item).height()); 23765 }); 23766 23767 maxheight = Math.max.apply(null, heights); 23768 23769 this._core.$stage.parent() 23770 .height(maxheight) 23771 .addClass(this._core.settings.autoHeightClass); 23772 }; 23773 23774 AutoHeight.prototype.destroy = function() { 23775 var handler, property; 23776 23777 for (handler in this._handlers) { 23778 this._core.$element.off(handler, this._handlers[handler]); 23779 } 23780 for (property in Object.getOwnPropertyNames(this)) { 23781 typeof this[property] != 'function' && (this[property] = null); 23782 } 23783 }; 23784 23785 $.fn.owlCarousel.Constructor.Plugins.AutoHeight = AutoHeight; 23786 23787})(window.Zepto || window.jQuery, window, document); 23788 23789/** 23790 * Video Plugin 23791 * @version 2.0.0-beta.3 23792 * @author Bartosz Wojciechowski 23793 * @license The MIT License (MIT) 23794 */ 23795;(function($, window, document, undefined) { 23796 23797 /** 23798 * Creates the video plugin. 23799 * @class The Video Plugin 23800 * @param {Owl} carousel - The Owl Carousel 23801 */ 23802 var Video = function(carousel) { 23803 /** 23804 * Reference to the core. 23805 * @protected 23806 * @type {Owl} 23807 */ 23808 this._core = carousel; 23809 23810 /** 23811 * Cache all video URLs. 23812 * @protected 23813 * @type {Object} 23814 */ 23815 this._videos = {}; 23816 23817 /** 23818 * Current playing item. 23819 * @protected 23820 * @type {jQuery} 23821 */ 23822 this._playing = null; 23823 23824 /** 23825 * All event handlers. 23826 * @todo The cloned content removale is too late 23827 * @protected 23828 * @type {Object} 23829 */ 23830 this._handlers = { 23831 'initialized.owl.carousel': $.proxy(function(e) { 23832 if (e.namespace) { 23833 this._core.register({ type: 'state', name: 'playing', tags: [ 'interacting' ] }); 23834 } 23835 }, this), 23836 'resize.owl.carousel': $.proxy(function(e) { 23837 if (e.namespace && this._core.settings.video && this.isInFullScreen()) { 23838 e.preventDefault(); 23839 } 23840 }, this), 23841 'refreshed.owl.carousel': $.proxy(function(e) { 23842 if (e.namespace && this._core.is('resizing')) { 23843 this._core.$stage.find('.cloned .owl-video-frame').remove(); 23844 } 23845 }, this), 23846 'changed.owl.carousel': $.proxy(function(e) { 23847 if (e.namespace && e.property.name === 'position' && this._playing) { 23848 this.stop(); 23849 } 23850 }, this), 23851 'prepared.owl.carousel': $.proxy(function(e) { 23852 if (!e.namespace) { 23853 return; 23854 } 23855 23856 var $element = $(e.content).find('.owl-video'); 23857 23858 if ($element.length) { 23859 $element.css('display', 'none'); 23860 this.fetch($element, $(e.content)); 23861 } 23862 }, this) 23863 }; 23864 23865 // set default options 23866 this._core.options = $.extend({}, Video.Defaults, this._core.options); 23867 23868 // register event handlers 23869 this._core.$element.on(this._handlers); 23870 23871 this._core.$element.on('click.owl.video', '.owl-video-play-icon', $.proxy(function(e) { 23872 this.play(e); 23873 }, this)); 23874 }; 23875 23876 /** 23877 * Default options. 23878 * @public 23879 */ 23880 Video.Defaults = { 23881 video: false, 23882 videoHeight: false, 23883 videoWidth: false 23884 }; 23885 23886 /** 23887 * Gets the video ID and the type (YouTube/Vimeo only). 23888 * @protected 23889 * @param {jQuery} target - The target containing the video data. 23890 * @param {jQuery} item - The item containing the video. 23891 */ 23892 Video.prototype.fetch = function(target, item) { 23893 var type = target.attr('data-vimeo-id') ? 'vimeo' : 'youtube', 23894 id = target.attr('data-vimeo-id') || target.attr('data-youtube-id'), 23895 width = target.attr('data-width') || this._core.settings.videoWidth, 23896 height = target.attr('data-height') || this._core.settings.videoHeight, 23897 url = target.attr('href'); 23898 23899 if (url) { 23900 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+)?/); 23901 23902 if (id[3].indexOf('youtu') > -1) { 23903 type = 'youtube'; 23904 } else if (id[3].indexOf('vimeo') > -1) { 23905 type = 'vimeo'; 23906 } else { 23907 throw new Error('Video URL not supported.'); 23908 } 23909 id = id[6]; 23910 } else { 23911 throw new Error('Missing video URL.'); 23912 } 23913 23914 this._videos[url] = { 23915 type: type, 23916 id: id, 23917 width: width, 23918 height: height 23919 }; 23920 23921 item.attr('data-video', url); 23922 23923 this.thumbnail(target, this._videos[url]); 23924 }; 23925 23926 /** 23927 * Creates video thumbnail. 23928 * @protected 23929 * @param {jQuery} target - The target containing the video data. 23930 * @param {Object} info - The video info object. 23931 * @see `fetch` 23932 */ 23933 Video.prototype.thumbnail = function(target, video) { 23934 var tnLink, 23935 icon, 23936 path, 23937 dimensions = video.width && video.height ? 'style="width:' + video.width + 'px;height:' + video.height + 'px;"' : '', 23938 customTn = target.find('img'), 23939 srcType = 'src', 23940 lazyClass = '', 23941 settings = this._core.settings, 23942 create = function(path) { 23943 icon = '<div class="owl-video-play-icon"></div>'; 23944 23945 if (settings.lazyLoad) { 23946 tnLink = '<div class="owl-video-tn ' + lazyClass + '" ' + srcType + '="' + path + '"></div>'; 23947 } else { 23948 tnLink = '<div class="owl-video-tn" style="opacity:1;background-image:url(' + path + ')"></div>'; 23949 } 23950 target.after(tnLink); 23951 target.after(icon); 23952 }; 23953 23954 // wrap video content into owl-video-wrapper div 23955 target.wrap('<div class="owl-video-wrapper"' + dimensions + '></div>'); 23956 23957 if (this._core.settings.lazyLoad) { 23958 srcType = 'data-src'; 23959 lazyClass = 'owl-lazy'; 23960 } 23961 23962 // custom thumbnail 23963 if (customTn.length) { 23964 create(customTn.attr(srcType)); 23965 customTn.remove(); 23966 return false; 23967 } 23968 23969 if (video.type === 'youtube') { 23970 path = "//img.youtube.com/vi/" + video.id + "/hqdefault.jpg"; 23971 create(path); 23972 } else if (video.type === 'vimeo') { 23973 $.ajax({ 23974 type: 'GET', 23975 url: '//vimeo.com/api/v2/video/' + video.id + '.json', 23976 jsonp: 'callback', 23977 dataType: 'jsonp', 23978 success: function(data) { 23979 path = data[0].thumbnail_large; 23980 create(path); 23981 } 23982 }); 23983 } 23984 }; 23985 23986 /** 23987 * Stops the current video. 23988 * @public 23989 */ 23990 Video.prototype.stop = function() { 23991 this._core.trigger('stop', null, 'video'); 23992 this._playing.find('.owl-video-frame').remove(); 23993 this._playing.removeClass('owl-video-playing'); 23994 this._playing = null; 23995 this._core.leave('playing'); 23996 this._core.trigger('stopped', null, 'video'); 23997 }; 23998 23999 /** 24000 * Starts the current video. 24001 * @public 24002 * @param {Event} event - The event arguments. 24003 */ 24004 Video.prototype.play = function(event) { 24005 var target = $(event.target), 24006 item = target.closest('.' + this._core.settings.itemClass), 24007 video = this._videos[item.attr('data-video')], 24008 width = video.width || '100%', 24009 height = video.height || this._core.$stage.height(), 24010 html; 24011 24012 if (this._playing) { 24013 return; 24014 } 24015 24016 this._core.enter('playing'); 24017 this._core.trigger('play', null, 'video'); 24018 24019 item = this._core.items(this._core.relative(item.index())); 24020 24021 this._core.reset(item.index()); 24022 24023 if (video.type === 'youtube') { 24024 html = '<iframe width="' + width + '" height="' + height + '" src="//www.youtube.com/embed/' + 24025 video.id + '?autoplay=1&v=' + video.id + '" frameborder="0" allowfullscreen></iframe>'; 24026 } else if (video.type === 'vimeo') { 24027 html = '<iframe src="//player.vimeo.com/video/' + video.id + 24028 '?autoplay=1" width="' + width + '" height="' + height + 24029 '" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>'; 24030 } 24031 24032 $('<div class="owl-video-frame">' + html + '</div>').insertAfter(item.find('.owl-video')); 24033 24034 this._playing = item.addClass('owl-video-playing'); 24035 }; 24036 24037 /** 24038 * Checks whether an video is currently in full screen mode or not. 24039 * @todo Bad style because looks like a readonly method but changes members. 24040 * @protected 24041 * @returns {Boolean} 24042 */ 24043 Video.prototype.isInFullScreen = function() { 24044 var element = document.fullscreenElement || document.mozFullScreenElement || 24045 document.webkitFullscreenElement; 24046 24047 return element && $(element).parent().hasClass('owl-video-frame'); 24048 }; 24049 24050 /** 24051 * Destroys the plugin. 24052 */ 24053 Video.prototype.destroy = function() { 24054 var handler, property; 24055 24056 this._core.$element.off('click.owl.video'); 24057 24058 for (handler in this._handlers) { 24059 this._core.$element.off(handler, this._handlers[handler]); 24060 } 24061 for (property in Object.getOwnPropertyNames(this)) { 24062 typeof this[property] != 'function' && (this[property] = null); 24063 } 24064 }; 24065 24066 $.fn.owlCarousel.Constructor.Plugins.Video = Video; 24067 24068})(window.Zepto || window.jQuery, window, document); 24069 24070/** 24071 * Animate Plugin 24072 * @version 2.0.0-beta.3 24073 * @author Bartosz Wojciechowski 24074 * @license The MIT License (MIT) 24075 */ 24076;(function($, window, document, undefined) { 24077 24078 /** 24079 * Creates the animate plugin. 24080 * @class The Navigation Plugin 24081 * @param {Owl} scope - The Owl Carousel 24082 */ 24083 var Animate = function(scope) { 24084 this.core = scope; 24085 this.core.options = $.extend({}, Animate.Defaults, this.core.options); 24086 this.swapping = true; 24087 this.previous = undefined; 24088 this.next = undefined; 24089 24090 this.handlers = { 24091 'change.owl.carousel': $.proxy(function(e) { 24092 if (e.namespace && e.property.name == 'position') { 24093 this.previous = this.core.current(); 24094 this.next = e.property.value; 24095 } 24096 }, this), 24097 'drag.owl.carousel dragged.owl.carousel translated.owl.carousel': $.proxy(function(e) { 24098 if (e.namespace) { 24099 this.swapping = e.type == 'translated'; 24100 } 24101 }, this), 24102 'translate.owl.carousel': $.proxy(function(e) { 24103 if (e.namespace && this.swapping && (this.core.options.animateOut || this.core.options.animateIn)) { 24104 this.swap(); 24105 } 24106 }, this) 24107 }; 24108 24109 this.core.$element.on(this.handlers); 24110 }; 24111 24112 /** 24113 * Default options. 24114 * @public 24115 */ 24116 Animate.Defaults = { 24117 animateOut: false, 24118 animateIn: false 24119 }; 24120 24121 /** 24122 * Toggles the animation classes whenever an translations starts. 24123 * @protected 24124 * @returns {Boolean|undefined} 24125 */ 24126 Animate.prototype.swap = function() { 24127 24128 if (this.core.settings.items !== 1) { 24129 return; 24130 } 24131 24132 if (!$.support.animation || !$.support.transition) { 24133 return; 24134 } 24135 24136 this.core.speed(0); 24137 24138 var left, 24139 clear = $.proxy(this.clear, this), 24140 previous = this.core.$stage.children().eq(this.previous), 24141 next = this.core.$stage.children().eq(this.next), 24142 incoming = this.core.settings.animateIn, 24143 outgoing = this.core.settings.animateOut; 24144 24145 if (this.core.current() === this.previous) { 24146 return; 24147 } 24148 24149 if (outgoing) { 24150 left = this.core.coordinates(this.previous) - this.core.coordinates(this.next); 24151 previous.css( { 'left': left + 'px' } ) 24152 .addClass('animated owl-animated-out') 24153 .addClass(outgoing) 24154 .on($.support.animation.end, clear); 24155 } 24156 24157 if (incoming) { 24158 next.addClass('animated owl-animated-in') 24159 .addClass(incoming) 24160 .on($.support.animation.end, clear); 24161 } 24162 }; 24163 24164 Animate.prototype.clear = function(e) { 24165 if ($(e.target).hasClass('animated')) { 24166 $(e.target).css( { 'left': '' } ) 24167 .removeClass('animated owl-animated-out owl-animated-in') 24168 .removeClass(this.core.settings.animateIn) 24169 .removeClass(this.core.settings.animateOut); 24170 this.core.onTransitionEnd(); 24171 } 24172 }; 24173 24174 /** 24175 * Destroys the plugin. 24176 * @public 24177 */ 24178 Animate.prototype.destroy = function() { 24179 var handler, property; 24180 24181 for (handler in this.handlers) { 24182 this.core.$element.off(handler, this.handlers[handler]); 24183 } 24184 for (property in Object.getOwnPropertyNames(this)) { 24185 typeof this[property] != 'function' && (this[property] = null); 24186 } 24187 }; 24188 24189 $.fn.owlCarousel.Constructor.Plugins.Animate = Animate; 24190 24191})(window.Zepto || window.jQuery, window, document); 24192 24193/** 24194 * Autoplay Plugin 24195 * @version 2.0.0-beta.3 24196 * @author Bartosz Wojciechowski 24197 * @author Artus Kolanowski 24198 * @license The MIT License (MIT) 24199 */ 24200;(function($, window, document, undefined) { 24201 24202 /** 24203 * Creates the autoplay plugin. 24204 * @class The Autoplay Plugin 24205 * @param {Owl} scope - The Owl Carousel 24206 */ 24207 var Autoplay = function(carousel) { 24208 /** 24209 * Reference to the core. 24210 * @protected 24211 * @type {Owl} 24212 */ 24213 this._core = carousel; 24214 24215 /** 24216 * The autoplay interval. 24217 * @type {Number} 24218 */ 24219 this._interval = null; 24220 24221 /** 24222 * Indicates whenever the autoplay is paused. 24223 * @type {Boolean} 24224 */ 24225 this._paused = false; 24226 24227 /** 24228 * All event handlers. 24229 * @protected 24230 * @type {Object} 24231 */ 24232 this._handlers = { 24233 'changed.owl.carousel': $.proxy(function(e) { 24234 if (e.namespace && e.property.name === 'settings') { 24235 if (this._core.settings.autoplay) { 24236 this.play(); 24237 } else { 24238 this.stop(); 24239 } 24240 } 24241 }, this), 24242 'initialized.owl.carousel': $.proxy(function(e) { 24243 if (e.namespace && this._core.settings.autoplay) { 24244 this.play(); 24245 } 24246 }, this), 24247 'play.owl.autoplay': $.proxy(function(e, t, s) { 24248 if (e.namespace) { 24249 this.play(t, s); 24250 } 24251 }, this), 24252 'stop.owl.autoplay': $.proxy(function(e) { 24253 if (e.namespace) { 24254 this.stop(); 24255 } 24256 }, this), 24257 'mouseover.owl.autoplay': $.proxy(function() { 24258 if (this._core.settings.autoplayHoverPause && this._core.is('rotating')) { 24259 this.pause(); 24260 } 24261 }, this), 24262 'mouseleave.owl.autoplay': $.proxy(function() { 24263 if (this._core.settings.autoplayHoverPause && this._core.is('rotating')) { 24264 this.play(); 24265 } 24266 }, this) 24267 }; 24268 24269 // register event handlers 24270 this._core.$element.on(this._handlers); 24271 24272 // set default options 24273 this._core.options = $.extend({}, Autoplay.Defaults, this._core.options); 24274 }; 24275 24276 /** 24277 * Default options. 24278 * @public 24279 */ 24280 Autoplay.Defaults = { 24281 autoplay: false, 24282 autoplayTimeout: 5000, 24283 autoplayHoverPause: false, 24284 autoplaySpeed: false 24285 }; 24286 24287 /** 24288 * Starts the autoplay. 24289 * @public 24290 * @param {Number} [timeout] - The interval before the next animation starts. 24291 * @param {Number} [speed] - The animation speed for the animations. 24292 */ 24293 Autoplay.prototype.play = function(timeout, speed) { 24294 this._paused = false; 24295 24296 if (this._core.is('rotating')) { 24297 return; 24298 } 24299 24300 this._core.enter('rotating'); 24301 24302 this._interval = window.setInterval($.proxy(function() { 24303 if (this._paused || this._core.is('busy') || this._core.is('interacting') || document.hidden) { 24304 return; 24305 } 24306 this._core.next(speed || this._core.settings.autoplaySpeed); 24307 }, this), timeout || this._core.settings.autoplayTimeout); 24308 }; 24309 24310 /** 24311 * Stops the autoplay. 24312 * @public 24313 */ 24314 Autoplay.prototype.stop = function() { 24315 if (!this._core.is('rotating')) { 24316 return; 24317 } 24318 24319 window.clearInterval(this._interval); 24320 this._core.leave('rotating'); 24321 }; 24322 24323 /** 24324 * Stops the autoplay. 24325 * @public 24326 */ 24327 Autoplay.prototype.pause = function() { 24328 if (!this._core.is('rotating')) { 24329 return; 24330 } 24331 24332 this._paused = true; 24333 }; 24334 24335 /** 24336 * Destroys the plugin. 24337 */ 24338 Autoplay.prototype.destroy = function() { 24339 var handler, property; 24340 24341 this.stop(); 24342 24343 for (handler in this._handlers) { 24344 this._core.$element.off(handler, this._handlers[handler]); 24345 } 24346 for (property in Object.getOwnPropertyNames(this)) { 24347 typeof this[property] != 'function' && (this[property] = null); 24348 } 24349 }; 24350 24351 $.fn.owlCarousel.Constructor.Plugins.autoplay = Autoplay; 24352 24353})(window.Zepto || window.jQuery, window, document); 24354 24355/** 24356 * Navigation Plugin 24357 * @version 2.0.0-beta.3 24358 * @author Artus Kolanowski 24359 * @license The MIT License (MIT) 24360 */ 24361;(function($, window, document, undefined) { 24362 'use strict'; 24363 24364 /** 24365 * Creates the navigation plugin. 24366 * @class The Navigation Plugin 24367 * @param {Owl} carousel - The Owl Carousel. 24368 */ 24369 var Navigation = function(carousel) { 24370 /** 24371 * Reference to the core. 24372 * @protected 24373 * @type {Owl} 24374 */ 24375 this._core = carousel; 24376 24377 /** 24378 * Indicates whether the plugin is initialized or not. 24379 * @protected 24380 * @type {Boolean} 24381 */ 24382 this._initialized = false; 24383 24384 /** 24385 * The current paging indexes. 24386 * @protected 24387 * @type {Array} 24388 */ 24389 this._pages = []; 24390 24391 /** 24392 * All DOM elements of the user interface. 24393 * @protected 24394 * @type {Object} 24395 */ 24396 this._controls = {}; 24397 24398 /** 24399 * Markup for an indicator. 24400 * @protected 24401 * @type {Array.<String>} 24402 */ 24403 this._templates = []; 24404 24405 /** 24406 * The carousel element. 24407 * @type {jQuery} 24408 */ 24409 this.$element = this._core.$element; 24410 24411 /** 24412 * Overridden methods of the carousel. 24413 * @protected 24414 * @type {Object} 24415 */ 24416 this._overrides = { 24417 next: this._core.next, 24418 prev: this._core.prev, 24419 to: this._core.to 24420 }; 24421 24422 /** 24423 * All event handlers. 24424 * @protected 24425 * @type {Object} 24426 */ 24427 this._handlers = { 24428 'prepared.owl.carousel': $.proxy(function(e) { 24429 if (e.namespace && this._core.settings.dotsData) { 24430 this._templates.push('<div class="' + this._core.settings.dotClass + '">' + 24431 $(e.content).find('[data-dot]').andSelf('[data-dot]').attr('data-dot') + '</div>'); 24432 } 24433 }, this), 24434 'added.owl.carousel': $.proxy(function(e) { 24435 if (e.namespace && this._core.settings.dotsData) { 24436 this._templates.splice(e.position, 0, this._templates.pop()); 24437 } 24438 }, this), 24439 'remove.owl.carousel': $.proxy(function(e) { 24440 if (e.namespace && this._core.settings.dotsData) { 24441 this._templates.splice(e.position, 1); 24442 } 24443 }, this), 24444 'changed.owl.carousel': $.proxy(function(e) { 24445 if (e.namespace && e.property.name == 'position') { 24446 this.draw(); 24447 } 24448 }, this), 24449 'initialized.owl.carousel': $.proxy(function(e) { 24450 if (e.namespace && !this._initialized) { 24451 this._core.trigger('initialize', null, 'navigation'); 24452 this.initialize(); 24453 this.update(); 24454 this.draw(); 24455 this._initialized = true; 24456 this._core.trigger('initialized', null, 'navigation'); 24457 } 24458 }, this), 24459 'refreshed.owl.carousel': $.proxy(function(e) { 24460 if (e.namespace && this._initialized) { 24461 this._core.trigger('refresh', null, 'navigation'); 24462 this.update(); 24463 this.draw(); 24464 this._core.trigger('refreshed', null, 'navigation'); 24465 } 24466 }, this) 24467 }; 24468 24469 // set default options 24470 this._core.options = $.extend({}, Navigation.Defaults, this._core.options); 24471 24472 // register event handlers 24473 this.$element.on(this._handlers); 24474 }; 24475 24476 /** 24477 * Default options. 24478 * @public 24479 * @todo Rename `slideBy` to `navBy` 24480 */ 24481 Navigation.Defaults = { 24482 nav: false, 24483 navText: [ 'prev', 'next' ], 24484 navSpeed: false, 24485 navElement: 'div', 24486 navContainer: false, 24487 navContainerClass: 'owl-nav', 24488 navClass: [ 'owl-prev', 'owl-next' ], 24489 slideBy: 1, 24490 dotClass: 'owl-dot', 24491 dotsClass: 'owl-dots', 24492 dots: true, 24493 dotsEach: false, 24494 dotsData: false, 24495 dotsSpeed: false, 24496 dotsContainer: false 24497 }; 24498 24499 /** 24500 * Initializes the layout of the plugin and extends the carousel. 24501 * @protected 24502 */ 24503 Navigation.prototype.initialize = function() { 24504 var override, 24505 settings = this._core.settings; 24506 24507 // create DOM structure for relative navigation 24508 this._controls.$relative = (settings.navContainer ? $(settings.navContainer) 24509 : $('<div>').addClass(settings.navContainerClass).appendTo(this.$element)).addClass('disabled'); 24510 24511 this._controls.$previous = $('<' + settings.navElement + '>') 24512 .addClass(settings.navClass[0]) 24513 .html(settings.navText[0]) 24514 .prependTo(this._controls.$relative) 24515 .on('click', $.proxy(function(e) { 24516 this.prev(settings.navSpeed); 24517 }, this)); 24518 this._controls.$next = $('<' + settings.navElement + '>') 24519 .addClass(settings.navClass[1]) 24520 .html(settings.navText[1]) 24521 .appendTo(this._controls.$relative) 24522 .on('click', $.proxy(function(e) { 24523 this.next(settings.navSpeed); 24524 }, this)); 24525 24526 // create DOM structure for absolute navigation 24527 if (!settings.dotsData) { 24528 this._templates = [ $('<div>') 24529 .addClass(settings.dotClass) 24530 .append($('<span>')) 24531 .prop('outerHTML') ]; 24532 } 24533 24534 this._controls.$absolute = (settings.dotsContainer ? $(settings.dotsContainer) 24535 : $('<div>').addClass(settings.dotsClass).appendTo(this.$element)).addClass('disabled'); 24536 24537 this._controls.$absolute.on('click', 'div', $.proxy(function(e) { 24538 var index = $(e.target).parent().is(this._controls.$absolute) 24539 ? $(e.target).index() : $(e.target).parent().index(); 24540 24541 e.preventDefault(); 24542 24543 this.to(index, settings.dotsSpeed); 24544 }, this)); 24545 24546 // override public methods of the carousel 24547 for (override in this._overrides) { 24548 this._core[override] = $.proxy(this[override], this); 24549 } 24550 }; 24551 24552 /** 24553 * Destroys the plugin. 24554 * @protected 24555 */ 24556 Navigation.prototype.destroy = function() { 24557 var handler, control, property, override; 24558 24559 for (handler in this._handlers) { 24560 this.$element.off(handler, this._handlers[handler]); 24561 } 24562 for (control in this._controls) { 24563 this._controls[control].remove(); 24564 } 24565 for (override in this.overides) { 24566 this._core[override] = this._overrides[override]; 24567 } 24568 for (property in Object.getOwnPropertyNames(this)) { 24569 typeof this[property] != 'function' && (this[property] = null); 24570 } 24571 }; 24572 24573 /** 24574 * Updates the internal state. 24575 * @protected 24576 */ 24577 Navigation.prototype.update = function() { 24578 var i, j, k, 24579 lower = this._core.clones().length / 2, 24580 upper = lower + this._core.items().length, 24581 maximum = this._core.maximum(true), 24582 settings = this._core.settings, 24583 size = settings.center || settings.autoWidth || settings.dotsData 24584 ? 1 : settings.dotsEach || settings.items; 24585 24586 if (settings.slideBy !== 'page') { 24587 settings.slideBy = Math.min(settings.slideBy, settings.items); 24588 } 24589 24590 if (settings.dots || settings.slideBy == 'page') { 24591 this._pages = []; 24592 24593 for (i = lower, j = 0, k = 0; i < upper; i++) { 24594 if (j >= size || j === 0) { 24595 this._pages.push({ 24596 start: Math.min(maximum, i - lower), 24597 end: i - lower + size - 1 24598 }); 24599 if (Math.min(maximum, i - lower) === maximum) { 24600 break; 24601 } 24602 j = 0, ++k; 24603 } 24604 j += this._core.mergers(this._core.relative(i)); 24605 } 24606 } 24607 }; 24608 24609 /** 24610 * Draws the user interface. 24611 * @todo The option `dotsData` wont work. 24612 * @protected 24613 */ 24614 Navigation.prototype.draw = function() { 24615 var difference, 24616 settings = this._core.settings, 24617 disabled = this._core.items().length <= settings.items, 24618 index = this._core.relative(this._core.current()), 24619 loop = settings.loop || settings.rewind; 24620 24621 this._controls.$relative.toggleClass('disabled', !settings.nav || disabled); 24622 24623 if (settings.nav) { 24624 this._controls.$previous.toggleClass('disabled', !loop && index <= this._core.minimum(true)); 24625 this._controls.$next.toggleClass('disabled', !loop && index >= this._core.maximum(true)); 24626 } 24627 24628 this._controls.$absolute.toggleClass('disabled', !settings.dots || disabled); 24629 24630 if (settings.dots) { 24631 difference = this._pages.length - this._controls.$absolute.children().length; 24632 24633 if (settings.dotsData && difference !== 0) { 24634 this._controls.$absolute.html(this._templates.join('')); 24635 } else if (difference > 0) { 24636 this._controls.$absolute.append(new Array(difference + 1).join(this._templates[0])); 24637 } else if (difference < 0) { 24638 this._controls.$absolute.children().slice(difference).remove(); 24639 } 24640 24641 this._controls.$absolute.find('.active').removeClass('active'); 24642 this._controls.$absolute.children().eq($.inArray(this.current(), this._pages)).addClass('active'); 24643 } 24644 }; 24645 24646 /** 24647 * Extends event data. 24648 * @protected 24649 * @param {Event} event - The event object which gets thrown. 24650 */ 24651 Navigation.prototype.onTrigger = function(event) { 24652 var settings = this._core.settings; 24653 24654 event.page = { 24655 index: $.inArray(this.current(), this._pages), 24656 count: this._pages.length, 24657 size: settings && (settings.center || settings.autoWidth || settings.dotsData 24658 ? 1 : settings.dotsEach || settings.items) 24659 }; 24660 }; 24661 24662 /** 24663 * Gets the current page position of the carousel. 24664 * @protected 24665 * @returns {Number} 24666 */ 24667 Navigation.prototype.current = function() { 24668 var current = this._core.relative(this._core.current()); 24669 return $.grep(this._pages, $.proxy(function(page, index) { 24670 return page.start <= current && page.end >= current; 24671 }, this)).pop(); 24672 }; 24673 24674 /** 24675 * Gets the current succesor/predecessor position. 24676 * @protected 24677 * @returns {Number} 24678 */ 24679 Navigation.prototype.getPosition = function(successor) { 24680 var position, length, 24681 settings = this._core.settings; 24682 24683 if (settings.slideBy == 'page') { 24684 position = $.inArray(this.current(), this._pages); 24685 length = this._pages.length; 24686 successor ? ++position : --position;
vendor: 5,678 bytes, lines 24687-24911
24687 position = this._pages[((position % length) + length) % length].start; 24688 } else { 24689 position = this._core.relative(this._core.current()); 24690 length = this._core.items().length; 24691 successor ? position += settings.slideBy : position -= settings.slideBy; 24692 } 24693 24694 return position; 24695 }; 24696 24697 /** 24698 * Slides to the next item or page. 24699 * @public 24700 * @param {Number} [speed=false] - The time in milliseconds for the transition. 24701 */ 24702 Navigation.prototype.next = function(speed) { 24703 $.proxy(this._overrides.to, this._core)(this.getPosition(true), speed); 24704 }; 24705 24706 /** 24707 * Slides to the previous item or page. 24708 * @public 24709 * @param {Number} [speed=false] - The time in milliseconds for the transition. 24710 */ 24711 Navigation.prototype.prev = function(speed) { 24712 $.proxy(this._overrides.to, this._core)(this.getPosition(false), speed); 24713 }; 24714 24715 /** 24716 * Slides to the specified item or page. 24717 * @public 24718 * @param {Number} position - The position of the item or page. 24719 * @param {Number} [speed] - The time in milliseconds for the transition. 24720 * @param {Boolean} [standard=false] - Whether to use the standard behaviour or not. 24721 */ 24722 Navigation.prototype.to = function(position, speed, standard) { 24723 var length; 24724 24725 if (!standard) { 24726 length = this._pages.length; 24727 $.proxy(this._overrides.to, this._core)(this._pages[((position % length) + length) % length].start, speed); 24728 } else { 24729 $.proxy(this._overrides.to, this._core)(position, speed); 24730 } 24731 }; 24732 24733 $.fn.owlCarousel.Constructor.Plugins.Navigation = Navigation; 24734 24735})(window.Zepto || window.jQuery, window, document); 24736 24737/** 24738 * Hash Plugin 24739 * @version 2.0.0-beta.3 24740 * @author Artus Kolanowski 24741 * @license The MIT License (MIT) 24742 */ 24743;(function($, window, document, undefined) { 24744 'use strict'; 24745 24746 /** 24747 * Creates the hash plugin. 24748 * @class The Hash Plugin 24749 * @param {Owl} carousel - The Owl Carousel 24750 */ 24751 var Hash = function(carousel) { 24752 /** 24753 * Reference to the core. 24754 * @protected 24755 * @type {Owl} 24756 */ 24757 this._core = carousel; 24758 24759 /** 24760 * Hash index for the items. 24761 * @protected 24762 * @type {Object} 24763 */ 24764 this._hashes = {}; 24765 24766 /** 24767 * The carousel element. 24768 * @type {jQuery} 24769 */ 24770 this.$element = this._core.$element; 24771 24772 /** 24773 * All event handlers. 24774 * @protected 24775 * @type {Object} 24776 */ 24777 this._handlers = { 24778 /*'initialized.owl.carousel': $.proxy(function(e) { 24779 if (e.namespace && this._core.settings.startPosition === 'URLHash') { 24780 $(window).trigger('hashchange.owl.navigation'); 24781 } 24782 }, this),*/ 24783 'prepared.owl.carousel': $.proxy(function(e) { 24784 if (e.namespace) { 24785 var hash = $(e.content).find('[data-hash]').addBack('[data-hash]').attr('data-hash'); 24786 24787 if (!hash) { 24788 return; 24789 } 24790 24791 this._hashes[hash] = e.content; 24792 } 24793 }, this), 24794 'changed.owl.carousel': $.proxy(function(e) { 24795 if (e.namespace && e.property.name === 'position') { 24796 var current = this._core.items(this._core.relative(this._core.current())), 24797 hash = $.map(this._hashes, function(item, hash) { 24798 return item === current ? hash : null; 24799 }).join(); 24800 24801 if (!hash || window.location.hash.slice(1) === hash) { 24802 return; 24803 } 24804 24805 window.location.hash = hash; 24806 } 24807 }, this) 24808 }; 24809 24810 // set default options 24811 this._core.options = $.extend({}, Hash.Defaults, this._core.options); 24812 24813 // register the event handlers 24814 this.$element.on(this._handlers); 24815 24816 // register event listener for hash navigation 24817 /*$(window).on('hashchange.owl.navigation', $.proxy(function(e) { 24818 var hash = window.location.hash.substring(1), 24819 items = this._core.$stage.children(), 24820 position = this._hashes[hash] && items.index(this._hashes[hash]); 24821 24822 if (position === undefined || position === this._core.current()) { 24823 return; 24824 } 24825 24826 this._core.to(this._core.relative(position), false, true); 24827 }, this));*/ 24828 }; 24829 24830 /** 24831 * Default options. 24832 * @public 24833 */ 24834 Hash.Defaults = { 24835 URLhashListener: false 24836 }; 24837 24838 /** 24839 * Destroys the plugin. 24840 * @public 24841 */ 24842 Hash.prototype.destroy = function() { 24843 var handler, property; 24844 24845 $(window).off('hashchange.owl.navigation'); 24846 24847 for (handler in this._handlers) { 24848 this._core.$element.off(handler, this._handlers[handler]); 24849 } 24850 for (property in Object.getOwnPropertyNames(this)) { 24851 typeof this[property] != 'function' && (this[property] = null); 24852 } 24853 }; 24854 24855 $.fn.owlCarousel.Constructor.Plugins.Hash = Hash; 24856 24857})(window.Zepto || window.jQuery, window, document); 24858 24859/** 24860 * Support Plugin 24861 * 24862 * @version 2.0.0-beta.3 24863 * @author Vivid Planet Software GmbH 24864 * @author Artus Kolanowski 24865 * @license The MIT License (MIT) 24866 */ 24867;(function($, window, document, undefined) { 24868 24869 var style = $('<support>').get(0).style, 24870 prefixes = 'Webkit Moz O ms'.split(' '), 24871 events = { 24872 transition: { 24873 end: { 24874 WebkitTransition: 'webkitTransitionEnd', 24875 MozTransition: 'transitionend', 24876 OTransition: 'oTransitionEnd', 24877 transition: 'transitionend' 24878 } 24879 }, 24880 animation: { 24881 end: { 24882 WebkitAnimation: 'webkitAnimationEnd', 24883 MozAnimation: 'animationend', 24884 OAnimation: 'oAnimationEnd', 24885 animation: 'animationend' 24886 } 24887 } 24888 }, 24889 tests = { 24890 csstransforms: function() { 24891 return !!test('transform'); 24892 }, 24893 csstransforms3d: function() { 24894 return !!test('perspective'); 24895 }, 24896 csstransitions: function() { 24897 return !!test('transition'); 24898 }, 24899 cssanimations: function() { 24900 return !!test('animation'); 24901 } 24902 }; 24903 24904 function test(property, prefixed) { 24905 var result = false, 24906 upper = property.charAt(0).toUpperCase() + property.slice(1); 24907 24908 $.each((property + ' ' + prefixes.join(upper + ' ') + upper).split(' '), function(i, property) { 24909 if (style[property] !== undefined) { 24910 result = prefixed ? property : true; 24911 return false;
24912 } 24913 }); 24914 24915 return result; 24916 } 24917 24918 function prefixed(property) { 24919 return test(property, true); 24920 } 24921 24922 if (tests.csstransitions()) { 24923 /* jshint -W053 */ 24924 $.support.transition = new String(prefixed('transition')) 24925 $.support.transition.end = events.transition.end[ $.support.transition ]; 24926 } 24927 24928 if (tests.cssanimations()) { 24929 /* jshint -W053 */ 24930 $.support.animation = new String(prefixed('animation')) 24931 $.support.animation.end = events.animation.end[ $.support.animation ]; 24932 } 24933 24934 if (tests.csstransforms()) { 24935 /* jshint -W053 */ 24936 $.support.transform = new String(prefixed('transform')); 24937 $.support.transform3d = tests.csstransforms3d(); 24938 } 24939 24940})(window.Zepto || window.jQuery, window, document); 24941 24942(function(window, document, undefined) { 24943 24944 /** 24945 * Find the absolute position of an element 24946 */ 24947 var absPos = function(element) { 24948 var offsetLeft, offsetTop; 24949 offsetLeft = offsetTop = 0; 24950 if (element.offsetParent) { 24951 do { 24952 offsetLeft += element.offsetLeft; 24953 offsetTop += element.offsetTop; 24954 } while (element = element.offsetParent); 24955 } 24956 return [offsetLeft, offsetTop]; 24957 }; 24958 24959 /** 24960 * @constructor Progress Circle class 24961 * @param params.canvas Canvas on which the circles will be drawn. 24962 * @param params.minRadius Inner radius of the innermost circle, in px. 24963 * @param params.arcWidth Width of each circle(to be more accurate, ring). 24964 * @param params.gapWidth Space between each circle. 24965 * @param params.centerX X coordinate of the center of circles. 24966 * @param params.centerY Y coordinate of the center of circles. 24967 * @param params.infoLineBaseAngle Base angle of the info line. 24968 * @param params.infoLineAngleInterval Angles between the info lines. 24969 */ 24970 var ProgressCircle = function(params) { 24971 this.canvas = params.canvas; 24972 this.minRadius = params.minRadius || 15; 24973 this.arcWidth = params.arcWidth || 5; 24974 this.gapWidth = params.gapWidth || 3; 24975 this.centerX = params.centerX || this.canvas.width / 2; 24976 this.centerY = params.centerY || this.canvas.height / 2;
24977 this.infoLineLength = params.infoLineLength || 60; 24978 this.horizLineLength = params.horizLineLength || 10; 24979 this.infoLineAngleInterval = params.infoLineAngleInterval || Math.PI / 8; 24980 this.infoLineBaseAngle = params.infoLineBaseAngle || Math.PI / 6; 24981 24982 this.context = this.canvas.getContext('2d'); 24983 24984 this.width = this.canvas.width; 24985 this.height = this.canvas.height; 24986 24987 this.circles = []; 24988 this.runningCount = 0; 24989 }; 24990 24991 ProgressCircle.prototype = { 24992 constructor: ProgressCircle, 24993 24994 /** 24995 * @method Adds an progress monitor entry. 24996 * @param params.fillColor Color to fill in the circle. 24997 * @param params.outlineColor Color to outline the circle. 24998 * @param params.progressListener Callback function to fetch the progress. 24999 * @param params.infoListener Callback function to fetch the info. 25000 * @returns this 25001 */ 25002 addEntry: function(params) { 25003 this.circles.push(new Circle({ 25004 canvas: this.canvas, 25005 context: this.context, 25006 centerX: this.centerX, 25007 centerY: this.centerY, 25008 innerRadius: this.minRadius + this.circles.length * 25009 (this.gapWidth + this.arcWidth), 25010 arcWidth: this.arcWidth,
25011 infoLineLength: this.infoLineLength, 25012 horizLineLength: this.horizLineLength, 25013 25014 id: this.circles.length, 25015 fillColor: params.fillColor, 25016 outlineColor: params.outlineColor, 25017 progressListener: params.progressListener, 25018 infoListener: params.infoListener, 25019 infoLineAngle: this.infoLineBaseAngle + 25020 this.circles.length * this.infoLineAngleInterval, 25021 })); 25022 25023 return this; 25024 }, 25025 25026 /** 25027 * @method Starts the monitor and updates with the given interval. 25028 * @param interval Interval between updates, in millisecond. 25029 * @returns this 25030 */ 25031 start: function(interval) { 25032 var self = this; 25033 this.timer = setInterval(function() { 25034 self._update(); 25035 }, interval || 33); 25036 25037 return this; 25038 }, 25039 25040 /** 25041 * @method Stop the animation. 25042 */ 25043 stop: function() { 25044 clearTimeout(this.timer); 25045 }, 25046 25047 /** 25048 * @private 25049 * @method Call update on each circle and redraw them. 25050 * @returns this 25051 */ 25052 _update: function() { 25053 this._clear(); 25054 this.circles.forEach(function(circle, idx, array) { 25055 circle.update(); 25056 }); 25057 25058 return this; 25059 }, 25060 25061 /** 25062 * @private 25063 * @method Clear the canvas. 25064 * @returns this 25065 */ 25066 _clear: function() { 25067 this.context.clearRect(0, 0, this.canvas.width, this.canvas.height); 25068 25069 return this; 25070 }, 25071 25072 }; 25073 25074 /** 25075 * @private 25076 * @class Individual progress circle. 25077 * @param params.canvas Canvas on which the circle will be drawn. 25078 * @param params.context Context of the canvas. 25079 * @param params.innerRadius Inner radius of the circle, in px. 25080 * @param params.arcWidth Width of each arc(circle). 25081 * @param params.gapWidth Distance between each arc. 25082 * @param params.centerX X coordinate of the center of circles. 25083 * @param params.centerY Y coordinate of the center of circles. 25084 * @param params.fillColor Color to fill in the circle. 25085 * @param params.outlineColor Color to outline the circle. 25086 * @param params.progressListener Callback function to fetch the progress. 25087 * @param params.infoListener Callback function to fetch the info. 25088 * @param params.infoLineAngle Angle of info line. 25089 */ 25090 var Circle = function(params) { 25091 this.id = params.id; 25092 this.canvas = params.canvas; 25093 this.context = params.context; 25094 this.centerX = params.centerX; 25095 this.centerY = params.centerY; 25096 this.arcWidth = params.arcWidth; 25097 this.innerRadius = params.innerRadius || 0; 25098 this.fillColor = params.fillColor || '#fff'; 25099 this.outlineColor = params.outlineColor || this.fillColor; 25100 this.progressListener = params.progressListener;
25101 this.infoLineLength = params.infoLineLength || 250; 25102 this.horizLineLength = params.horizLineLength || 50; 25103 this.infoListener = params.infoListener; 25104 this.infoLineAngle = params.infoLineAngle; 25105 25106 this.outerRadius = this.innerRadius + this.arcWidth; 25107 25108 // If the info listener is not registered, then don't calculate 25109 // the related coordinates 25110 if (!this.infoListener) return; 25111 25112 // calculate the info-line turning points 25113 var angle = this.infoLineAngle, 25114 arcDistance = (this.innerRadius + this.outerRadius) / 2, 25115 25116 sinA = Math.sin(angle), 25117 cosA = Math.cos(angle); 25118 25119 this.infoLineStartX = this.centerX + sinA * arcDistance; 25120 this.infoLineStartY = this.centerY - cosA * arcDistance; 25121 25122 this.infoLineMidX = this.centerX + sinA * this.infoLineLength; 25123 this.infoLineMidY = this.centerY - cosA * this.infoLineLength; 25124 25125 this.infoLineEndX = this.infoLineMidX + 25126 (sinA < 0 ? -this.horizLineLength : this.horizLineLength); 25127 this.infoLineEndY = this.infoLineMidY; 25128 25129 var infoText = document.createElement('div'), 25130 style = infoText.style; 25131 25132 style.color = this.fillColor; 25133 style.position = 'absolute'; 25134 style.left = this.infoLineEndX + absPos(this.canvas)[0] + 'px'; 25135 // style.top will be calculated in the `drawInfo` method. Since 25136 // user may want to change the size of the font, so the top offset 25137 // must be updated in each loop. 25138 infoText.className = 'ProgressCircleInfo'; // For css styling 25139 infoText.id = 'progress_circle_info_' + this.id; 25140 document.body.appendChild(infoText); 25141 this.infoText = infoText; 25142 }; 25143 25144 Circle.prototype = { 25145 constructor: Circle, 25146 25147 update: function() { 25148 this.progress = this.progressListener(); 25149 this._draw(); 25150 25151 if (this.infoListener) { 25152 this.info = this.infoListener(); 25153 this._drawInfo(); 25154 } 25155 }, 25156 25157 /** 25158 * @private 25159 * @method Draw the circle on the canvas. 25160 * @returns this 25161 */ 25162 _draw: function() { 25163 var ctx = this.context, 25164 25165 ANGLE_OFFSET = -Math.PI / 2, 25166 25167 startAngle = 0 + ANGLE_OFFSET, 25168 endAngle= startAngle + this.progress * Math.PI * 2, 25169 25170 x = this.centerX, 25171 y = this.centerY, 25172 25173 innerRadius = this.innerRadius - this.arcWidth - 1, 25174 outerRadius = this.outerRadius - this.arcWidth - 1; 25175 25176 if ( innerRadius < 0 ) 25177 return; 25178 25179 ctx.fillStyle = this.fillColor; 25180 ctx.strokeStyle = this.outlineColor; 25181 25182 ctx.beginPath(); 25183 ctx.arc(x, y, innerRadius, startAngle, endAngle, false); 25184 ctx.arc(x, y, outerRadius, endAngle, startAngle, true); 25185 ctx.closePath(); 25186 ctx.stroke(); 25187 ctx.fill(); 25188 25189 return this; 25190 }, 25191 25192 /** 25193 * @private 25194 * @method Draw the info lines and info text. 25195 * @returns this 25196 */ 25197 _drawInfo: function() { 25198 25199 var pointList, lineHeight; 25200 25201 pointList = [ 25202 [this.infoLineStartX, this.infoLineStartY], 25203 [this.infoLineMidX, this.infoLineMidY], 25204 [this.infoLineEndX, this.infoLineEndY], 25205 ]; 25206 this._drawSegments(pointList, false); 25207 25208 this.infoText.innerHTML = this.info; 25209 25210 lineHeight = this.infoText.offsetHeight; 25211 this.infoText.style.top = this.infoLineEndY + 25212 absPos(this.canvas)[1] - lineHeight / 2 + 'px'; 25213 25214 return this; 25215 }, 25216 25217 /** 25218 * @private 25219 * @method Helper function to draw the segments 25220 * @param pointList An array of points in the form of [x, y]. 25221 * @param close Whether to connect the first and last point. 25222 */ 25223 _drawSegments: function(pointList, close) { 25224 var ctx = this.context; 25225 25226 ctx.beginPath(); 25227 ctx.moveTo(pointList[0][0], pointList[0][1]); 25228 for (var i = 1; i < pointList.length; ++i) { 25229 ctx.lineTo(pointList[i][0], pointList[i][1]); 25230 } 25231 25232 if (close) { 25233 ctx.closePath(); 25234 } 25235 ctx.stroke(); 25236 }, 25237 }; 25238 25239 window.ProgressCircle = ProgressCircle; 25240 25241})(window, document); 25242 25243 25244 25245 25246/* ========================================================= 25247 * jquery.vc_chart.js v1.0 25248 * ========================================================= 25249 * Copyright 2013 Wpbakery 25250 * 25251 * Jquery chart plugin for the Visual Composer. 25252 * ========================================================= */ 25253(function($){ 25254 /** 25255 * Pie chart animated. 25256 * @param element - DOM element 25257 * @param options - settings object. 25258 * @constructor 25259 */ 25260 var VcChart = function(element, options) { 25261 this.el = element; 25262 this.$el = $(this.el); 25263 var $this = this; 25264 $this.options = $.extend({ 25265 color: 'wpb_button', 25266 units: '', 25267 width: '', 25268 label_selector: '.vc_pie_chart_value', 25269 back_selector: '.vc_pie_chart_back', 25270 responsive: true 25271 }, options); 25272 $this.init(); 25273 }; 25274 VcChart.prototype = { 25275 constructor: VcChart, 25276 _progress_v: 0, 25277 animated: false, 25278 colors: { 25279 'wpb_button': 'rgba(247, 247, 247, 1)', 25280 'btn-primary': 'rgba(0, 136, 204, 1)', 25281 'btn-info': 'rgba(88, 185, 218, 1)', 25282 'btn-success': 'rgba(106, 177, 101, 1)', 25283 'btn-warning': 'rgba(255, 153, 0, 1)', 25284 'btn-danger': 'rgba(255, 103, 91, 1)', 25285 'btn-inverse': 'rgba(85, 85, 85, 1)' 25286 }, 25287 init: function() { 25288 this.setupColor(); 25289 this.value = this.$el.data('pie-value')/100; 25290 this.label_value = this.$el.data('pie-label-value') || this.$el.data('pie-value'); 25291 this.$wrapper = $('.vc_pie_wrapper', this.$el); 25292 this.$label = $(this.options.label_selector, this.$el); 25293 this.$back = $(this.options.back_selector, this.$el); 25294 this.$canvas = this.$el.find('canvas'); 25295 this.arcWidth = this.$el.data('pie-width') * 2; 25296 this.draw(); 25297 this.setWayPoint(); 25298 if(this.options.responsive === true) this.setResponsive(); 25299 if (UNCODE.isMobile) this._progress_v = this.value; 25300 }, 25301 setupColor: function() { 25302 // if(typeof this.colors[this.options.color] !== 'undefined') { 25303 // this.color = this.colors[this.options.color]; 25304 // } else if(typeof this.options.color === 'string' && this.options.color.match(/^rgba?\([^\)]+\)/)) { 25305 // this.color = this.options.color; 25306 // } else { 25307 // this.color = 'rgba(247, 247, 247, 0.2)'; 25308 // } 25309 if(typeof this.options.color !== 'undefined') { 25310 this.color = this.options.color; 25311 } else this.color = 'rgba(247, 247, 247, 0.2)'; 25312 25313 }, 25314 setResponsive: function() { 25315 var that = this; 25316 if (!UNCODE.isMobile) { 25317 $(window).resize(function(){ 25318 if(that.animated === true) that.circle.stop(); 25319 that.draw(true); 25320 }); 25321 } 25322 }, 25323 draw: function(redraw) { 25324 var w = this.$el.addClass('vc_ready').width() * 2, 25325 border_w = this.arcWidth, 25326 radius; 25327 if(!w) w = this.$el.parents(':visible').first().width()-2; 25328 //w = Math.round(w/100*80); 25329 //if (w < 250) w = 250; 25330 radius = w/2; 25331 this.$wrapper.css({"width" : (w / 2) + "px"}); 25332 this.$label.css({"width" : (w / 2), "height" : (w / 2), "line-height" : (w / 2)+"px"}); 25333 this.$back.css({"width" : (w / 2), "height" : (w / 2)}); 25334 this.$canvas.attr({"width" : w + "px", "height" : w + "px"}); 25335 this.$el.addClass('vc_ready'); 25336 this.circle = new ProgressCircle({ 25337 canvas: this.$canvas.get(0), 25338 minRadius: radius, 25339 arcWidth: border_w 25340 }); 25341 if(redraw === true && this.animated === true) { 25342 this._progress_v = this.value; 25343 this.circle.addEntry({ 25344 fillColor: this.color, 25345 progressListener: $.proxy(this.setProgress, this) 25346 }).start(); 25347 } 25348 }, 25349 setProgress: function() { 25350 if (this._progress_v >= this.value) { 25351 this.circle.stop(); 25352 this.animated = true; 25353 this.$label.html(this.label_value + this.options.units); 25354 return this._progress_v; 25355 } 25356 this._progress_v += 0.01; 25357 if (!isNaN(this.label_value)) { 25358 var label_value = this._progress_v/this.value*this.label_value; 25359 var val = Math.round(label_value) + this.options.units; 25360 this.$label.html(val); 25361 } else this.$label.html(this.label_value + this.options.units); 25362 return this._progress_v; 25363 }, 25364 animate: function() { 25365 if(this.animated !== true) { 25366 this.circle.addEntry({ 25367 fillColor: this.color, 25368 progressListener: $.proxy(this.setProgress, this) 25369 }).start(10); 25370 } 25371 }, 25372 setWayPoint: function() { 25373 if (typeof $.fn.waypoint !== 'undefined' && !UNCODE.isMobile) { 25374 this.$el.waypoint($.proxy(this.animate, this), { offset: '85%' }); 25375 } else { 25376 this.animate(); 25377 } 25378 } 25379 }; 25380 /** 25381 * jQuery plugin 25382 * @param option - object with settings 25383 * @return {*} 25384 */ 25385 $.fn.vcChat = function(option, value) { 25386 return this.each(function () { 25387 var $this = $(this), 25388 data = $this.data('vc_chart'), 25389 options = typeof option === 'object' ? option : { 25390 color: $this.data('pie-color'), 25391 units: $this.data('pie-units') 25392 }; 25393 if (typeof option == 'undefined') $this.data('vc_chart', (data = new VcChart(this, options))); 25394 if (typeof option == 'string') data[option](value); 25395 }); 25396 }; 25397 /** 25398 * Allows users to rewrite function inside theme. 25399 */ 25400 if ( typeof window['vc_pieChart'] !== 'function' ) { 25401 window.vc_pieChart = function() { 25402 $('.vc_pie_chart:visible:not(.vc_ready)').vcChat(); 25403 } 25404 } 25405 $(document).ready(function(){ 25406 !window.vc_iframe && vc_pieChart(); 25407 25408 /** 25409 * Tab and collapse integration. 25410 */ 25411 $('.nav-tabs a').on('shown.bs.tab', function(e){ 25412 var $cont = $(e.target).closest('.tab-container'), 25413 $active = $('.tab-pane.active', $cont); 25414 $('.vc_pie_chart:not(.vc_ready)', $active).vcChat(); 25415 }); 25416 25417 $('.panel-collapse').on('shown.bs.collapse', function (e) { 25418 $('.vc_pie_chart:not(.vc_ready)', e.target).vcChat(); 25419 }) 25420 }); 25421 25422})(window.jQuery); 25423 25424/* Progress bar 25425 ---------------------------------------------------------- */ 25426function uncode_progress_bar() { 25427 jQuery.each(jQuery('.vc_progress_bar'), function(index, val) { 25428 if (UNCODE.isUnmodalOpen && !val.closest('#unmodal-content')) { 25429 return; 25430 } 25431 if (!UNCODE.isMobile) { 25432 new Waypoint({ 25433 context: UNCODE.isUnmodalOpen ? document.getElementById('unmodal-content') : window, 25434 element: val, 25435 handler: function() { 25436 var element = jQuery(this.element); 25437 element.find('.vc_single_bar').each(function(index) { 25438 var $this = jQuery(this), 25439 bar = $this.find('.vc_bar'), 25440 val = bar.data('percentage-value'); 25441 setTimeout(function() { 25442 bar.css({ 25443 "width": val + '%' 25444 }); 25445 }, index * 200); 25446 }); 25447 }, 25448 offset: '80%' 25449 }); 25450 } else { 25451 var element = jQuery(val); 25452 element.find('.vc_single_bar').each(function(index) { 25453 var $this = jQuery(this), 25454 bar = $this.find('.vc_bar'), 25455 val = bar.data('percentage-value'); 25456 setTimeout(function() { 25457 bar.css({ 25458 "width": val + '%' 25459 }); 25460 }, index * 200); 25461 }); 25462 } 25463 }); 25464}; 25465uncode_progress_bar(); 25466 25467/*! 25468 * jquery.counterup.js 1.0 25469 * 25470 * Copyright 2013, Benjamin Intal http://gambit.ph @bfintal 25471 * Released under the GPL v2 License 25472 * 25473 * Date: Nov 26, 2013 25474 */ 25475(function($) { 25476 "use strict"; 25477 $.fn.counterUp = function(options) { 25478 // Defaults 25479 var settings = $.extend({ 25480 'time': 400, 25481 'delay': 10 25482 }, options); 25483 return this.each(function() { 25484 // Store the object 25485 var $this = $(this); 25486 var $settings = settings; 25487 var counterUpper = function() { 25488 var nums = []; 25489 var divisions = $settings.time / $settings.delay; 25490 var numReal = $this.attr('data-val'), 25491 num = numReal; 25492 var isComma = /[0-9]+,[0-9]+/.test(num); 25493 num = num.replace(/,/g, ''); 25494 var isInt = /^[0-9]+$/.test(num); 25495 var isFloat = /^[0-9]+\.[0-9]+$/.test(num); 25496 var decimalPlaces = isFloat ? (num.split('.')[1] || []).length : 0; 25497 // Generate list of incremental numbers to display 25498 for (var i = divisions; i >= 1; i--) { 25499 // Preserve as int if input was int 25500 var newNum = parseInt(num / divisions * i); 25501 // Preserve float if input was float 25502 if (isFloat) { 25503 newNum = parseFloat(num / divisions * i).toFixed(decimalPlaces); 25504 } 25505 // Preserve commas if input had commas 25506 if (isComma) { 25507 while (/(\d+)(\d{3})/.test(newNum.toString())) { 25508 newNum = newNum.toString().replace(/(\d+)(\d{3})/, '$1' + ',' + '$2'); 25509 } 25510 } 25511 nums.unshift(newNum); 25512 } 25513 nums.push(numReal); 25514 $this.data('counterup-nums', nums); 25515 $this.text('0'); 25516 // Updates the number until we're done 25517 var f = function() { 25518 if ($this.data('counterup-nums') != null) { 25519 $this.text($this.data('counterup-nums').shift()); 25520 if ($this.data('counterup-nums').length) { 25521 setTimeout($this.data('counterup-func'), $settings.delay); 25522 } else { 25523 delete $this.data('counterup-nums'); 25524 $this.data('counterup-nums', null); 25525 $this.data('counterup-func', null); 25526 } 25527 } 25528 }; 25529 $this.data('counterup-func', f); 25530 // Start the count up 25531 setTimeout($this.data('counterup-func'), $settings.delay); 25532 }; 25533 // Perform counts when the element gets into view 25534 new Waypoint({ 25535 context: UNCODE.isUnmodalOpen ? document.getElementById('unmodal-content') : window, 25536 element: this, 25537 handler: function() { 25538 counterUpper(); 25539 if (!UNCODE.isUnmodalOpen) { 25540 this.destroy(); 25541 } 25542 }, 25543 offset: '100%' 25544 }); 25545 }); 25546 }; 25547})(jQuery); 25548 25549/*! 25550 * The Final Countdown for jQuery v2.2.0 (http://hilios.github.io/jQuery.countdown/) 25551 * Copyright (c) 2016 Edson Hilios 25552 * 25553 * Permission is hereby granted, free of charge, to any person obtaining a copy of 25554 * this software and associated documentation files (the "Software"), to deal in 25555 * the Software without restriction, including without limitation the rights to 25556 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 25557 * the Software, and to permit persons to whom the Software is furnished to do so, 25558 * subject to the following conditions: 25559 * 25560 * The above copyright notice and this permission notice shall be included in all 25561 * copies or substantial portions of the Software. 25562 * 25563 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 25564 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 25565 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 25566 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 25567 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 25568 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25569 */ 25570(function(factory) { 25571 "use strict"; 25572 if (typeof define === "function" && define.amd) { 25573 define([ "jquery" ], factory); 25574 } else { 25575 factory(jQuery); 25576 } 25577})(function($) { 25578 "use strict"; 25579 var instances = [], matchers = [], defaultOptions = { 25580 precision: 100, 25581 elapse: false, 25582 defer: false 25583 }; 25584 matchers.push(/^[0-9]*$/.source); 25585 matchers.push(/([0-9]{1,2}\/){2}[0-9]{4}( [0-9]{1,2}(:[0-9]{2}){2})?/.source); 25586 matchers.push(/[0-9]{4}([\/\-][0-9]{1,2}){2}( [0-9]{1,2}(:[0-9]{2}){2})?/.source); 25587 matchers = new RegExp(matchers.join("|")); 25588 function parseDateString(dateString) { 25589 if (dateString instanceof Date) { 25590 return dateString; 25591 } 25592 if (String(dateString).match(matchers)) { 25593 if (String(dateString).match(/^[0-9]*$/)) { 25594 dateString = Number(dateString); 25595 } 25596 if (String(dateString).match(/\-/)) { 25597 dateString = String(dateString).replace(/\-/g, "/"); 25598 } 25599 return new Date(dateString); 25600 } else { 25601 throw new Error("Couldn't cast `" + dateString + "` to a date object."); 25602 } 25603 } 25604 var DIRECTIVE_KEY_MAP = { 25605 Y: "years", 25606 m: "months", 25607 n: "daysToMonth", 25608 d: "daysToWeek", 25609 w: "weeks", 25610 W: "weeksToMonth", 25611 H: "hours", 25612 M: "minutes", 25613 S: "seconds", 25614 D: "totalDays", 25615 I: "totalHours", 25616 N: "totalMinutes", 25617 T: "totalSeconds" 25618 }; 25619 function escapedRegExp(str) { 25620 var sanitize = str.toString().replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1"); 25621 return new RegExp(sanitize); 25622 } 25623 function strftime(offsetObject) { 25624 return function(format) { 25625 var directives = format.match(/%(-|!)?[A-Z]{1}(:[^;]+;)?/gi); 25626 if (directives) { 25627 for (var i = 0, len = directives.length; i < len; ++i) { 25628 var directive = directives[i].match(/%(-|!)?([a-zA-Z]{1})(:[^;]+;)?/), regexp = escapedRegExp(directive[0]), modifier = directive[1] || "", plural = directive[3] || "", value = null; 25629 directive = directive[2]; 25630 if (DIRECTIVE_KEY_MAP.hasOwnProperty(directive)) { 25631 value = DIRECTIVE_KEY_MAP[directive]; 25632 value = Number(offsetObject[value]); 25633 } 25634 if (value !== null) { 25635 if (modifier === "!") { 25636 value = pluralize(plural, value); 25637 } 25638 if (modifier === "") { 25639 if (value < 10) { 25640 value = "0" + value.toString(); 25641 } 25642 } 25643 format = format.replace(regexp, value.toString()); 25644 } 25645 } 25646 } 25647 format = format.replace(/%%/, "%"); 25648 return format; 25649 }; 25650 } 25651 function pluralize(format, count) { 25652 var plural = "s", singular = ""; 25653 if (format) { 25654 format = format.rep
vendor: 8,618 bytes, lines 25654-25798
25654lace(/(:|;|\s)/gi, "").split(/\,/); 25655 if (format.length === 1) { 25656 plural = format[0]; 25657 } else { 25658 singular = format[0]; 25659 plural = format[1]; 25660 } 25661 } 25662 if (Math.abs(count) > 1) { 25663 return plural; 25664 } else { 25665 return singular; 25666 } 25667 } 25668 var Countdown = function(el, finalDate, options) { 25669 this.el = el; 25670 this.$el = $(el); 25671 this.interval = null; 25672 this.offset = {}; 25673 this.options = $.extend({}, defaultOptions); 25674 this.instanceNumber = instances.length; 25675 instances.push(this); 25676 this.$el.data("countdown-instance", this.instanceNumber); 25677 if (options) { 25678 if (typeof options === "function") { 25679 this.$el.on("update.countdown", options); 25680 this.$el.on("stoped.countdown", options); 25681 this.$el.on("finish.countdown", options); 25682 } else { 25683 this.options = $.extend({}, defaultOptions, options); 25684 } 25685 } 25686 this.setFinalDate(finalDate); 25687 if (this.options.defer === false) { 25688 this.start(); 25689 } 25690 }; 25691 $.extend(Countdown.prototype, { 25692 start: function() { 25693 if (this.interval !== null) { 25694 clearInterval(this.interval); 25695 } 25696 var self = this; 25697 this.update(); 25698 this.interval = setInterval(function() { 25699 self.update.call(self); 25700 }, this.options.precision); 25701 }, 25702 stop: function() { 25703 clearInterval(this.interval); 25704 this.interval = null; 25705 this.dispatchEvent("stoped"); 25706 }, 25707 toggle: function() { 25708 if (this.interval) { 25709 this.stop(); 25710 } else { 25711 this.start(); 25712 } 25713 }, 25714 pause: function() { 25715 this.stop(); 25716 }, 25717 resume: function() { 25718 this.start(); 25719 }, 25720 remove: function() { 25721 this.stop.call(this); 25722 instances[this.instanceNumber] = null; 25723 delete this.$el.data().countdownInstance; 25724 }, 25725 setFinalDate: function(value) { 25726 this.finalDate = parseDateString(value); 25727 }, 25728 update: function() { 25729 if (this.$el.closest("html").length === 0) { 25730 this.remove(); 25731 return; 25732 } 25733 var hasEventsAttached = $._data(this.el, "events") !== undefined, now = new Date(), newTotalSecsLeft; 25734 newTotalSecsLeft = this.finalDate.getTime() - now.getTime(); 25735 newTotalSecsLeft = Math.ceil(newTotalSecsLeft / 1e3); 25736 newTotalSecsLeft = !this.options.elapse && newTotalSecsLeft < 0 ? 0 : Math.abs(newTotalSecsLeft); 25737 if (this.totalSecsLeft === newTotalSecsLeft || !hasEventsAttached) { 25738 return; 25739 } else { 25740 this.totalSecsLeft = newTotalSecsLeft; 25741 } 25742 this.elapsed = now >= this.finalDate; 25743 this.offset = { 25744 seconds: this.totalSecsLeft % 60, 25745 minutes: Math.floor(this.totalSecsLeft / 60) % 60, 25746 hours: Math.floor(this.totalSecsLeft / 60 / 60) % 24, 25747 days: Math.floor(this.totalSecsLeft / 60 / 60 / 24) % 7, 25748 daysToWeek: Math.floor(this.totalSecsLeft / 60 / 60 / 24) % 7, 25749 daysToMonth: Math.floor(this.totalSecsLeft / 60 / 60 / 24 % 30.4368), 25750 weeks: Math.floor(this.totalSecsLeft / 60 / 60 / 24 / 7), 25751 weeksToMonth: Math.floor(this.totalSecsLeft / 60 / 60 / 24 / 7) % 4, 25752 months: Math.floor(this.totalSecsLeft / 60 / 60 / 24 / 30.4368), 25753 years: Math.abs(this.finalDate.getFullYear() - now.getFullYear()), 25754 totalDays: Math.floor(this.totalSecsLeft / 60 / 60 / 24), 25755 totalHours: Math.floor(this.totalSecsLeft / 60 / 60), 25756 totalMinutes: Math.floor(this.totalSecsLeft / 60), 25757 totalSeconds: this.totalSecsLeft 25758 }; 25759 if (!this.options.elapse && this.totalSecsLeft === 0) { 25760 this.stop(); 25761 this.dispatchEvent("finish"); 25762 } else { 25763 this.dispatchEvent("update"); 25764 } 25765 }, 25766 dispatchEvent: function(eventName) { 25767 var event = $.Event(eventName + ".countdown"); 25768 event.finalDate = this.finalDate; 25769 event.elapsed = this.elapsed; 25770 event.offset = $.extend({}, this.offset); 25771 event.strftime = strftime(this.offset); 25772 this.$el.trigger(event); 25773 } 25774 }); 25775 $.fn.countdown = function() { 25776 var argumentsArray = Array.prototype.slice.call(arguments, 0); 25777 return this.each(function() { 25778 var instanceNumber = $(this).data("countdown-instance"); 25779 if (instanceNumber !== undefined) { 25780 var instance = instances[instanceNumber], method = argumentsArray[0]; 25781 if (Countdown.prototype.hasOwnProperty(method)) { 25782 instance[method].apply(instance, argumentsArray.slice(1)); 25783 } else if (String(method).match(/^[$A-Z_][0-9A-Z_$]*$/i) === null) { 25784 instance.setFinalDate.call(instance, method); 25785 instance.start(); 25786 } else { 25787 $.error("Method %s does not exist on jQuery.countdown".replace(/\%s/gi, method)); 25788 } 25789 } else { 25790 new Countdown(this, argumentsArray[0], argumentsArray[1]); 25791 } 25792 }); 25793 }; 25794}); 25795 25796!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; 25797function getStyles(config){ 25798 // 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;
25798left: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+"}" 25799}; 25800 var ShareUtils; 25801 25802if ((!("classList" in document.documentElement)) && Object.defineProperty && typeof HTMLElement !== "undefined") { 25803 Object.defineProperty(HTMLElement.prototype, "classList", { 25804 get: function() { 25805 var ret, self, update; 25806 update = function(fn) { 25807 return function(value) { 25808 var classes, index; 25809 classes = self.className.split(/\s+/); 25810 index = classes.indexOf(value); 25811 fn(classes, index, value); 25812 self.className = classes.join(" "); 25813 }; 25814 }; 25815 self = this; 25816 ret = { 25817 add: update(function(classes, index, value) { 25818 ~index || classes.push(value); 25819 }), 25820 remove: update(function(classes, index) { 25821 ~index && classes.splice(index, 1); 25822 }), 25823 toggle: update(function(classes, index, value) { 25824 if (~index) { 25825 classes.splice(index, 1); 25826 } else { 25827 classes.push(value); 25828 } 25829 }), 25830 contains: function(value) { 25831 return !!~self.className.split(/\s+/).indexOf(value); 25832 }, 25833 item: function(i) { 25834 return self.className.split(/\s+/)[i] || null; 25835 } 25836 }; 25837 Object.defineProperty(ret, "length", { 25838 get: function() { 25839 return self.className.split(/\s+/).length; 25840 } 25841 }); 25842 return ret; 25843 } 25844 }); 25845} 25846 25847String.prototype.to_rfc3986 = function() { 25848 var tmp; 25849 tmp = encodeURIComponent(this); 25850 return tmp.replace(/[!'()*]/g, function(c) { 25851 return "%" + c.charCodeAt(0).toString(16); 25852 }); 25853}; 25854 25855ShareUtils = (function() { 25856 function ShareUtils() {} 25857 25858 ShareUtils.prototype.extend = function(to, from, overwrite) { 25859 var hasProp, prop; 25860 for (prop in from) { 25861 hasProp = to[prop] !== undefined; 25862 if (hasProp && typeof from[prop] === "object") { 25863 this.extend(to[prop], from[prop], overwrite); 25864 } else { 25865 if (overwrite || !hasProp) { 25866 to[prop] = from[prop]; 25867 } 25868 } 25869 } 25870 }; 25871 25872 ShareUtils.prototype.hide = function(el) { 25873 return el.style.display = "none"; 25874 }; 25875 25876 ShareUtils.prototype.show = function(el) { 25877 return el.style.display = "block"; 25878 }; 25879 25880 ShareUtils.prototype.has_class = function(el, class_name) { 25881 return el.classList.contains(class_name); 25882 }; 25883 25884 ShareUtils.prototype.add_class = function(el, class_name) { 25885 return el.classList.add(class_name); 25886 }; 25887 25888 ShareUtils.prototype.remove_class = function(el, class_name) { 25889 return el.classList.remove(class_name); 25890 }; 25891 25892 ShareUtils.prototype.is_encoded = function(str) { 25893 str = str.to_rfc3986(); 25894 return decodeURIComponent(str) !== str; 25895 }; 25896 25897 ShareUtils.prototype.encode = function(str) { 25898 if (typeof str === "undefined" || this.is_encoded(str)) { 25899 return str; 25900 } else { 25901 return str.to_rfc3986(); 25902 } 25903 }; 25904 25905 ShareUtils.prototype.popup = function(url, params) { 25906 var k, popup, qs, v; 25907 if (params == null) { 25908 params = {}; 25909 } 25910 popup = { 25911 width: 500, 25912 height: 350 25913 }; 25914 popup.top = (screen.height / 2) - (popup.height / 2); 25915 popup.left = (screen.width / 2) - (popup.width / 2); 25916 qs = ((function() { 25917 var _results; 25918 _results = []; 25919 for (k in params) { 25920 v = params[k]; 25921 _results.push("" + k + "=" + (this.encode(v))); 25922 } 25923 return _results; 25924 }).call(this)).join('&'); 25925 if (qs) { 25926 qs = "?" + qs; 25927 } 25928 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="
25928+ popup.width + ",height=" + popup.height); 25929 }; 25930 25931 return ShareUtils; 25932 25933})(); 25934var Share, 25935 __hasProp = {}.hasOwnProperty, 25936 __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; }; 25937 25938Share = (function(_super) { 25939 __extends(Share, _super); 25940 25941 function Share(element, options) { 25942 this.element = element; 25943 this.el = { 25944 head: document.getElementsByTagName('head')[0], 25945 body: document.getElementsByTagName('body')[0] 25946 }; 25947 this.config = { 25948 enabled_networks: 0, 25949 protocol: ['http', 'https'].indexOf(window.location.href.split(':')[0]) === -1 ? 'https://' : '//', 25950 url: window.location.href.replace("&", "%26"), 25951 caption: null, 25952 title: this.default_title(), 25953 image: this.default_image(), 25954 description: this.default_description(), 25955 ui: { 25956 flyout: 'top center', 25957 button_text: 'Share', 25958 button_font: true, 25959 icon_font: true 25960 }, 25961 networks: { 25962 twitter: { 25963 enabled: true, 25964 url: null, 25965 title: null, 25966 description: null 25967 }, 25968 facebook: { 25969 enabled: true, 25970 load_sdk: true, 25971 url: null, 25972 app_id: null, 25973 title: null, 25974 caption: null, 25975 description: null, 25976 image: null 25977 }, 25978 pinterest: { 25979 enabled: true, 25980 url: null, 25981 image: null, 25982 description: null 25983 }, 25984 reddit: { 25985 enabled: true, 25986 url: null, 25987 title: null 25988 }, 25989 linkedin: { 25990 enabled: true, 25991 url: null, 25992 title: null, 25993 description: null 25994 }, 25995 xing: { 25996 enabled: true, 25997 url: null, 25998 title: null, 25999 image: null, 26000 description: null 26001 }, 26002 whatsapp: { 26003 enabled: true, 26004 description: null, 26005 url: null 26006 }, 26007 email: { 26008 enabled: true, 26009 title: null, 26010 description: null, 26011 url: null 26012 } 26013 } 26014 }; 26015 this.setup(element, options); 26016 return this; 26017 } 26018 26019 Share.prototype.setup = function(element, opts) { 26020 var index, instance, instances, _i, _len; 26021 instances = document.querySelectorAll(element); 26022 this.extend(this.config, opts, true); 26023 this.set_global_configuration(); 26024 this.normalize_network_configuration(); 26025 if (this.config.ui.icon_font) { 26026 this.inject_icons(); 26027 } 26028 if (this.config.ui.button_font) { 26029 this.inject_fonts(); 26030 } 26031 if (this.config.networks.facebook.enabled && this.config.networks.facebook.load_sdk) { 26032 this.inject_facebook_sdk(); 26033 } 26034 for (index = _i = 0, _len = instances.length; _i < _len; index = ++_i) { 26035 instance = instances[index]; 26036 this.setup_instance(element, index); 26037 } 26038 }; 26039 26040 Share.prototype.setup_instance = function(element, index) { 26041 var button, instance, label, network, networks, _i, _len, _results, 26042 _this = this; 26043 instance = document.querySelectorAll(element)[index]; 26044 this.hide(instance); 26045 this.add_class(instance, "sharer-" + index); 26046 instance = document.querySelectorAll(element)[index]; 26047 this.inject_css(instance); 26048 this.inject_html(instance); 26049 this.show(instance); 26050 label = instance.getElementsByTagName("label")[0]; 26051 button = instance.getElementsByClassName("social")[0]; 26052 networks = instance.getElementsByTagName('li'); 26053 this.add_class(button, "networks-" + this.config.enabled_networks); 26054 label.addEventListener("click", function() { 26055 return _this.event_toggle(button); 26056 }); 26057 _this = this; 26058 _results = []; 26059 for (index = _i = 0, _len = networks.length; _i < _len; index = ++_i) { 26060 network = networks[index]; 26061 _results.push(network.addEventListener("click", function() { 26062 _this.event_network(instance, this); 26063 return _this.event_close(button); 26064 })); 26065 } 26066 return _results; 26067 }; 26068 26069 Share.prototype.event_toggle = function(button) { 26070 if (this.has_class(button, "active")) { 26071 return this.event_close(button); 26072 } else { 26073 return this.event_open(button); 26074 } 26075 }; 26076 26077 Share.prototype.event_open = function(button) { 26078 if (this.has_class(button, "load")) { 26079 this.remove_class(button, "load"); 26080 } 26081 return this.add_class(button, "active"); 26082 }; 26083 26084 Share.prototype.event_close = function(button) { 26085 return this.remove_class(button, "active"); 26086 }; 26087 26088 Share.prototype.event_network = function(instance, network) { 26089 var name; 26090 name = network.getAttribute("data-network"); 26091 this.hook("before", name, instance);
26092 this["network_" + name](); 26093 return this.hook("after", name, instance); 26094 }; 26095 26096 Share.prototype.open = function() { 26097 return this["public"]("open"); 26098 }; 26099 26100 Share.prototype.close = function() { 26101 return this["public"]("close"); 26102 }; 26103 26104 Share.prototype.toggle = function() { 26105 return this["public"]("toggle"); 26106 }; 26107 26108 Share.prototype["public"] = function(action) { 26109 var button, index, instance, _i, _len, _ref, _results; 26110 _ref = document.querySelectorAll(this.element); 26111 _results = []; 26112 for (index = _i = 0, _len = _ref.length; _i < _len; index = ++_i) { 26113 instance = _ref[index]; 26114 button = instance.getElementsByClassName("social")[0]; 26115 _results.push(this["event_" + action](button)); 26116 } 26117 return _results; 26118 }; 26119 26120 Share.prototype.network_facebook = function() { 26121 if (this.config.networks.facebook.load_sdk) { 26122 if (!window.FB) { 26123 return console.error("The Facebook JS SDK hasn't loaded yet."); 26124 } 26125 return FB.ui({ 26126 method: 'feed', 26127 name: this.config.networks.facebook.title, 26128 link: this.config.networks.facebook.url, 26129 picture: this.config.networks.facebook.image, 26130 caption: this.config.networks.facebook.caption, 26131 description: this.config.networks.facebook.description 26132 }); 26133 } else { 26134 return this.popup('https://www.facebook.com/sharer/sharer.php', { 26135 u: this.config.networks.facebook.url 26136 }); 26137 } 26138 }; 26139 26140 Share.prototype.network_twitter = function() { 26141 return this.popup('https://twitter.com/intent/tweet', { 26142 text: this.config.networks.twitter.title, 26143 url: this.config.networks.twitter.url 26144 }); 26145 }; 26146 26147 Share.prototype.network_pinterest = function() { 26148 return this.popup('https://www.pinterest.com/pin/create/button', { 26149 url: this.config.networks.pinterest.url, 26150 media: this.config.networks.pinterest.image, 26151 description: this.config.networks.pinterest.description 26152 }); 26153 }; 26154 26155 Share.prototype.network_linkedin = function() { 26156 return this.popup('https://www.linkedin.com/shareArticle', { 26157 url: this.config.networks.linkedin.url, 26158 title: this.config.networks.linkedin.title, 26159 summary: this.config.networks.linkedin.description 26160 }); 26161 } 26162 26163 Share.prototype.network_xing = function() { 26164 return this.popup('https://www.xing.com/spi/shares/new', { 26165 url: this.config.networks.xing.url, 26166 image: this.config.networks.xing.image, 26167 title: this.config.networks.xing.title, 26168 summary: this.config.networks.xing.description 26169 }); 26170 } 26171 26172 Share.prototype.network_email = function() { 26173 return this.popup('mailto:', { 26174 subject: this.config.networks.email.title, 26175 body: this.config.networks.email.url + '%0A%0A' + this.config.networks.email.description, 26176 }); 26177 }; 26178 26179 Share.prototype.inject_icons = function() { 26180 // return this.inject_stylesheet("https://www.sharebutton.co/fonts/v2/entypo.min.css"); 26181 }; 26182 26183 Share.prototype.inject_fonts = function() { 26184 // return this.inject_stylesheet("http://fonts.googleapis.com/css?family=Lato:900&text=" + this.config.ui.button_text); 26185 }; 26186 26187 Share.prototype.inject_stylesheet = function(url) { 26188 var link; 26189 if (!this.el.head.querySelector("link[href=\"" + url + "\"]")) { 26190 link = document.createElement("link"); 26191 link.setAttribute("rel", "stylesheet"); 26192 link.setAttribute("href", url); 26193 return this.el.head.appendChild(link); 26194 } 26195 }; 26196 26197 Share.prototype.inject_css = function(instance) { 26198 var css, meta, selector, style; 26199 selector = "." + (instance.getAttribute('class').split(" ").join(".")); 26200 if (!this.el.head.querySelector("meta[name='sharer" + selector + "']")) { 26201 this.config.selector = selector; 26202 css = getStyles(this.config); 26203 style = document.createElement("style"); 26204 style.type = "text/css"; 26205 if (style.styleSheet) { 26206 style.styleSheet.cssText = css; 26207 } else { 26208 style.appendChild(document.createTextNode(css)); 26209 } 26210 this.el.head.appendChild(style); 26211 delete this.config.selector; 26212 meta = document.createElement("meta"); 26213 meta.setAttribute("name", "sharer" + selector); 26214 return this.el.head.appendChild(meta); 26215 } 26216 }; 26217 26218 Share.prototype.inject_html = function(instance) { 26219 //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>"; 26220 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>"; 26221 }; 26222 26223 Share.prototype.inject_facebook_sdk = function() { 26224 var fb_root, script; 26225 if (!window.FB && this.config.networks.facebook.app_id && !this.el.body.querySelector('#fb-root')) { 26226 script = document.createElement("script"); 26227 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')"; 26228 fb_root = document.createElement("div"); 26229 fb_root.id = "fb-root"; 26230 this.el.body.appendChild(fb_root); 26231 return this.el.body.appendChild(script); 26232 } 26233 }; 26234 26235 Share.prototype.hook = function(type, network, instance) { 26236 var fn, opts; 26237 fn = this.config.networks[network][type]; 26238 if (typeof fn === "function") { 26239 opts = fn.call(this.config.networks[network], instance); 26240 if (opts !== void 0) { 26241 opts = this.normalize_filter_config_updates(opts); 26242 this.extend(this.config.networks[network], opts, true); 26243 this.normalize_network_configuration(); 26244 } 26245 } 26246 }; 26247 26248 Share.prototype.default_title = function() { 26249 var content; 26250 if (content = document.querySelector('meta[property="og:title"]') || document.querySelector('meta[name="twitter:title"]')) { 26251 return encodeURIComponent(content.getAttribute('content')); 26252 } else if (content = document.querySelector('title')) { 26253 return encodeURIComponent(content.innerText); 26254 } 26255 }; 26256 26257 Share.prototype.default_image = function() { 26258 var content; 26259 if (content = document.querySelector('meta[property="og:image"]') || document.querySelector('meta[name="twitter:image"]')) { 26260 return content.getAttribute('content'); 26261 } 26262 }; 26263 26264 Share.prototype.default_description = function() { 26265 var content; 26266 if (content = document.querySelector('meta[property="og:description"]') || document.querySelector('meta[name="twitter:description"]') || document.querySelector('meta[name="description"]')) { 26267 return encodeURIComponent(content.getAttribute('content')); 26268 } else { 26269 return ''; 26270 } 26271 }; 26272 26273 Share.prototype.set_global_configuration = function() { 26274 var display, network, option, options, _ref, _results; 26275 _ref = this.config.networks; 26276 _results = []; 26277 for (network in _ref) { 26278 options = _ref[network]; 26279 for (option in options) { 26280 if (this.config.networks[network][option] == null) { 26281 this.config.networks[network][option] = this.config[option]; 26282 } 26283 } 26284 if (this.config.networks[network].enabled) { 26285 display = 'block'; 26286 this.config.enabled_networks += 1; 26287 } else { 26288 display = 'none'; 26289 } 26290 _results.push(this.config.networks[network].display = display); 26291 } 26292 return _results; 26293 }; 26294 26295 Share.prototype.normalize_network_configuration = function() { 26296 if (!this.config.networks.facebook.app_id) { 26297 this.config.networks.facebook.load_sdk = false;
26298 } 26299 if (!this.is_encoded(this.config.networks.twitter.description)) { 26300 this.config.networks.twitter.description = encodeURIComponent(this.config.networks.twitter.description); 26301 } 26302 if (typeof this.config.networks.facebook.app_id === 'number') { 26303 return this.config.networks.facebook.app_id = this.config.networks.facebook.app_id.toString(); 26304 } 26305 }; 26306 26307 Share.prototype.normalize_filter_config_updates = function(opts) { 26308 if (this.config.networks.facebook.app_id !== opts.app_id) { 26309 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."); 26310 delete opts.app_id; 26311 } 26312 if (this.config.networks.facebook.load_sdk !== opts.load_sdk) { 26313 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."); 26314 delete opts.app_id; 26315 } 26316 return opts; 26317 }; 26318 26319 return Share; 26320 26321})(ShareUtils); 26322 return Share; 26323}); 26324 26325// Generated by CoffeeScript 1.9.2 26326 26327// @license Sticky-kit v1.1.2 | WTFPL | Leaf Corcoran 2015 | http://leafo.net 26328 26329(function() { 26330 var $, win; 26331 26332 $ = this.jQuery || window.jQuery; 26333 26334 win = $(window); 26335 26336 $.fn.stick_in_parent = function(opts) { 26337 var doc, elm, enable_bottoming, fn, i, inner_scrolling, len, manual_spacer, offset_top, outer_width, parent_selector, recalc_every, sticky_class; 26338 if (opts == null) { 26339 opts = {}; 26340 } 26341 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; 26342 if (offset_top == null) { 26343 offset_top = 0; 26344 } 26345 if (parent_selector == null) { 26346 parent_selector = void 0; 26347 } 26348 if (inner_scrolling == null) { 26349 inner_scrolling = true; 26350 } 26351 if (sticky_class == null) { 26352 sticky_class = "is_stuck"; 26353 } 26354 doc = $(document); 26355 if (enable_bottoming == null) { 26356 enable_bottoming = true; 26357 } 26358 outer_width = function(el) { 26359 var _el, computed, w; 26360 if (window.getComputedStyle) { 26361 _el = el[0]; 26362 computed = window.getComputedStyle(el[0]); 26363 w = parseFloat(computed.getPropertyValue("width")) + parseFloat(computed.getPropertyValue("margin-left")) + parseFloat(computed.getPropertyValue("margin-right")); 26364 if (computed.getPropertyValue("box-sizing") !== "border-box") { 26365 w += parseFloat(computed.getPropertyValue("border-left-width")) + parseFloat(computed.getPropertyValue("border-right-width")) + parseFloat(computed.getPropertyValue("padding-left")) + parseFloat(computed.getPropertyValue("padding-right")); 26366 } 26367 return w; 26368 } else { 26369 return el.outerWidth(true); 26370 } 26371 }; 26372 fn = function(elm, padding_bottom, parent_top, parent_height, top, height, el_float, detached) { 26373 var bottomed, detach, fixed, last_pos, last_scroll_height, offset, parent, recalc, recalc_and_tick, recalc_counter, spacer, tick; 26374 if (elm.data("sticky_kit")) { 26375 return; 26376 } 26377 elm.data("sticky_kit", true); 26378 last_scroll_height = doc.height(); 26379 parent = elm.parent(); 26380 if (parent_selector != null) { 26381 parent = parent.closest(parent_selector); 26382 } 26383 if (!parent.length) { 26384 throw "failed to find stick parent"; 26385 } 26386 fixed = false; 26387 bottomed = false; 26388 spacer = manual_spacer != null ? manual_spacer && elm.closest(manual_spacer) : $("<div />"); 26389 if (spacer) { 26390 spacer.css('position', elm.css('position')); 26391 } 26392 recalc = function() { 26393 var border_top, padding_top, restore; 26394 if (detached) { 26395 return; 26396 } 26397 last_scroll_height = doc.height(); 26398 border_top = parseInt(parent.css("border-top-width"), 10); 26399 padding_top = parseInt(parent.css("padding-top"), 10); 26400 padding_bottom = parseInt(parent.css("padding-bottom"), 10); 26401 parent_top = parent.offset().top + border_top + padding_top; 26402 parent_height = parent.height(); 26403 if (fixed) { 26404 fixed = false;
vendor: 6,068 bytes, lines 26405-26599
26405 bottomed = false; 26406 if (manual_spacer == null) { 26407 elm.insertAfter(spacer); 26408 spacer.detach(); 26409 } 26410 elm.css({ 26411 position: "", 26412 top: "", 26413 width: "", 26414 bottom: "" 26415 }).removeClass(sticky_class); 26416 restore = true; 26417 } 26418 top = elm.offset().top - (parseInt(elm.css("margin-top"), 10) || 0) - offset_top; 26419 height = elm.outerHeight(true); 26420 el_float = elm.css("float"); 26421 if (spacer) { 26422 spacer.css({ 26423 width: outer_width(elm), 26424 height: height, 26425 display: elm.css("display"), 26426 "vertical-align": elm.css("vertical-align"), 26427 "float": el_float 26428 }); 26429 } 26430 if (restore) { 26431 return tick(); 26432 } 26433 }; 26434 recalc(); 26435 if (height === parent_height) { 26436 return; 26437 } 26438 last_pos = void 0; 26439 offset = offset_top; 26440 recalc_counter = recalc_every; 26441 tick = function() { 26442 var css, delta, recalced, scroll, will_bottom, win_height; 26443 if (detached) { 26444 return; 26445 } 26446 recalced = false; 26447 if (recalc_counter != null) { 26448 recalc_counter -= 1; 26449 if (recalc_counter <= 0) { 26450 recalc_counter = recalc_every; 26451 recalc(); 26452 recalced = true; 26453 } 26454 } 26455 if (!recalced && doc.height() !== last_scroll_height) { 26456 recalc(); 26457 recalced = true; 26458 } 26459 scroll = win.scrollTop(); 26460 if (last_pos != null) { 26461 delta = scroll - last_pos; 26462 } 26463 last_pos = scroll; 26464 if (fixed) { 26465 if (enable_bottoming) { 26466 will_bottom = scroll + height + offset > parent_height + parent_top; 26467 if (bottomed && !will_bottom) { 26468 bottomed = false; 26469 elm.css({ 26470 position: "fixed", 26471 bottom: "", 26472 top: offset 26473 }).trigger("sticky_kit:unbottom"); 26474 } 26475 } 26476 if (scroll < top) { 26477 fixed = false; 26478 offset = offset_top; 26479 if (manual_spacer == null) { 26480 if (el_float === "left" || el_float === "right") { 26481 elm.insertAfter(spacer); 26482 } 26483 spacer.detach(); 26484 } 26485 css = { 26486 position: "", 26487 width: "", 26488 top: "" 26489 }; 26490 elm.css(css).removeClass(sticky_class).trigger("sticky_kit:unstick"); 26491 } 26492 if (inner_scrolling) { 26493 win_height = win.height(); 26494 if (height + offset_top > win_height) { 26495 if (!bottomed) { 26496 offset -= delta; 26497 offset = Math.max(win_height - height, offset); 26498 offset = Math.min(offset_top, offset); 26499 if (fixed) { 26500 elm.css({ 26501 top: offset + "px" 26502 }); 26503 } 26504 } 26505 } 26506 } 26507 } else { 26508 if (scroll > top) { 26509 fixed = true; 26510 css = { 26511 position: "fixed", 26512 top: offset 26513 }; 26514 css.width = elm.css("box-sizing") === "border-box" ? elm.outerWidth() + "px" : elm.width() + "px"; 26515 elm.css(css).addClass(sticky_class); 26516 if (manual_spacer == null) { 26517 elm.after(spacer); 26518 if (el_float === "left" || el_float === "right") { 26519 spacer.append(elm); 26520 } 26521 } 26522 elm.trigger("sticky_kit:stick"); 26523 } 26524 } 26525 if (fixed && enable_bottoming) { 26526 if (will_bottom == null) { 26527 will_bottom = scroll + height + offset > parent_height + parent_top; 26528 } 26529 if (!bottomed && will_bottom) { 26530 bottomed = true; 26531 if (parent.css("position") === "static") { 26532 parent.css({ 26533 position: "relative" 26534 }); 26535 } 26536 return elm.css({ 26537 position: "absolute", 26538 bottom: padding_bottom, 26539 top: "auto" 26540 }).trigger("sticky_kit:bottom"); 26541 } 26542 } 26543 }; 26544 recalc_and_tick = function() { 26545 recalc(); 26546 return tick(); 26547 }; 26548 detach = function() { 26549 detached = true; 26550 win.off("touchmove", tick); 26551 win.off("scroll", tick); 26552 win.off("resize", recalc_and_tick); 26553 $(document.body).off("sticky_kit:recalc", recalc_and_tick); 26554 elm.off("sticky_kit:detach", detach); 26555 elm.removeData("sticky_kit"); 26556 elm.css({ 26557 position: "", 26558 bottom: "", 26559 top: "", 26560 width: "" 26561 }); 26562 parent.position("position", ""); 26563 if (fixed) { 26564 if (manual_spacer == null) { 26565 if (el_float === "left" || el_float === "right") { 26566 elm.insertAfter(spacer); 26567 } 26568 spacer.remove(); 26569 } 26570 return elm.removeClass(sticky_class); 26571 } 26572 }; 26573 win.on("touchmove", tick); 26574 win.on("scroll", tick); 26575 win.on("resize", recalc_and_tick); 26576 $(document.body).on("sticky_kit:recalc", recalc_and_tick); 26577 elm.on("sticky_kit:detach", detach); 26578 return setTimeout(tick, 0); 26579 }; 26580 for (i = 0, len = this.length; i < len; i++) { 26581 elm = this[i]; 26582 fn($(elm)); 26583 } 26584 return this; 26585 }; 26586 26587}).call(this); 26588/* ========================================================================== 26589 * bootstrap-tab-history.js 26590 * Author: Michael Narayan <[email protected]> 26591 * Repository: https://github.com/mnarayan01/bootstrap-tab-history/ 26592 * ========================================================================== 26593 * Licensed under the Apache License, Version 2.0 (the "License"); you may 26594 * not use this file except in compliance with the License. You may obtain a 26595 * copy of the License at 26596 * 26597 * http://www.apache.org/licenses/LICENSE-2.0 26598 * 26599 * Unless required by applicable law or agreed to in writing, softw
26599are 26600 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 26601 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 26602 * License for the specific language governing permissions and limitations 26603 * under the License. 26604 * ========================================================================== */ 26605 26606/* ========================================================================== */ 26607/* JSHint directives */ 26608/* */ 26609/* global BootstrapTabHistory: true */ 26610/* */ 26611/* global document */ 26612/* global jQuery */ 26613/* global history */ 26614/* global window */ 26615/* ========================================================================== */ 26616 26617/** 26618 * Integrate [HTML5 history state tracking](https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Manipulating_the_browser_history) 26619 * with [`bootstrap/tab.js`](http://getbootstrap.com/javascript/#tabs). To enable tracking on a tab element, simply set 26620 * the `data-tab-history` attribute to true (or a string denoting a tab grouping). 26621 * 26622 * See the README for additional information. 26623 * 26624 * Functionality based upon bootstrap/tab.js v3.1.0; reference it when making any changes. 26625 */ 26626 26627BootstrapTabHistory = { 26628 options: { 26629 /** 26630 * When the anchor portion of the URI is used to activate a tab, scroll down to the given offset, rather than the 26631 * element with the given `id` attribute. Set to null to disable. Only relevant if showTabsBasedOnAnchor is true. 26632 * 26633 * May be overriden on a per-element basis by the attribute `data-tab-history-anchor-y-offset`. 26634 * 26635 * @public 26636 * @type {?number} 26637 */ 26638 defaultAnchorYOffset: 0, 26639 /** 26640 * Either 'push' or 'replace', for whether to use `history.pushState` or `history.replaceState`, resp. 26641 * 26642 * May be overriden on a per-element basis by the attribute `data-tab-history-changer`. 26643 * 26644 * @public 26645 * @type {string} 26646 */ 26647 defaultChanger: 'replace', 26648 /** 26649 * If true, update the URL in onShownTab in the calls to `history.pushState` and `history.replaceState`. Otherwise, 26650 * `null` is passed as the third parameter to these calls. 26651 * 26652 * May be overriden on a per-element basis by the attribute `data-tab-history-update-url`. 26653 * 26654 * @public 26655 * @type {boolean} 26656 */ 26657 defaultUpdateURL: false, 26658 /** 26659 * Should the anchor portion of the loaded URI be used to activate a single tab if no history was present on page 26660 * load. 26661 * 26662 * @public 26663 * @type {boolean} 26664 */ 26665 showTabsBasedOnAnchor: true 26666 } 26667}; 26668 26669(function () { 26670 'use strict'; 26671 26672 jQuery(function () { 26673 if(history && history.pushState && history.replaceState) { 26674 var bootstrapTabHistory = history.state && history.state.bootstrapTabHistory; 26675 26676 if(bootstrapTabHistory) { 26677 showTabsBasedOnState(bootstrapTabHistory); 26678 } else { 26679 showTabsBasedOnAnchor(); 26680 } 26681 26682 backfillHistoryState(); 26683 26684 jQuery(document).on('shown.bs.tab show.bs.collapse', onShownTab); 26685 jQuery(window).on('popstate', onPopState); 26686 } else { 26687 showTabsBasedOnAnchor(); 26688 } 26689 }); 26690 26691 /** 26692 * Used to prevent onShownTab from registering shown events that we triggered via showTabsBasedOnState. 26693 * 26694 * @type {boolean} 26695 */ 26696 var showingTabsBasedOnState = false; 26697 26698 /** 26699 * Used to update `history.state` to reflect the default active tabs on initial page load. This supports proper 26700 * `history.back` handling when `data-tab-history-update-url` is true. 26701 */ 26702 function backfillHistoryState() { 26703 var newState = null; 26704 26705 jQuery('li.active > [data-tab-history], .panel-title.active [data-tab-history]').each(function () {//edited by Uncode 26706 var $activeTabElement = jQuery(this); 26707 var selector = getTabSelector($activeTabElement); 26708 26709 if(selector) { 26710 var tabGroup = getTabGroup($activeTabElement); 26711 26712 if(tabGroup) { 26713 newState = createNewHistoryState(newState || history.state, tabGroup, selector); 26714 } 26715 } 26716 }); 26717 26718 if(newState) { 26719 history.replaceState(newState, '', null); 26720 } 26721 } 26722 26723 /** 26724 * Clone the existing state, ensure its bootstrapTabHistory attribute is an Object, and add the provided tabGroup to 26725 * said bootstrapTabHistory attribute. 26726 * 26727 * @param {?object} existingState 26728 * @param {!string} tabGroup 26729 * @param {!string} selector 26730 * @returns {!object} 26731 */ 26732 function createNewHistoryState(existingState, tabGroup, selector) { 26733 // Clone history.state and ensure it has a bootstrapTabHistory entry. 26734 var newState = jQuery.extend(true, {}, existingState, { 26735 bootstrapTabHistory: {} 26736 }); 26737 26738 newState.bootstrapTabHistory[tabGroup] = selector; 26739 26740 return newState; 26741 } 26742 26743 /** 26744 * @param {jQuery} $tab
26745 * @returns {?string} 26746 */ 26747 function getTabGroup($tab) { 26748 return parseTruthyAttributeValue($tab.data('tab-history')); 26749 } 26750 26751 /** 26752 * @param {jQuery} $tab 26753 * @returns {?string} 26754 */ 26755 function getTabSelector($tab) { 26756 return $tab.data('target') || $tab.attr('href'); 26757 } 26758 26759 /** 26760 * Receives the `shown.bs.tab` event. Updates `history.state` as appropriate. 26761 * 26762 * @param {jQuery.Event} shownEvt 26763 */ 26764 function onShownTab(shownEvt) { 26765 if(!showingTabsBasedOnState) { 26766 var $activatedTab = jQuery(shownEvt.target); 26767 if ( $activatedTab.hasClass('panel-collapse') ) 26768 $activatedTab = $activatedTab.closest('.panel').find('a'); 26769 var selector = getTabSelector($activatedTab); 26770 26771 if(selector) { 26772 var tabGroup = getTabGroup($activatedTab); 26773 26774 if(tabGroup) { 26775 var historyChanger = $activatedTab.data('tab-history-changer') || BootstrapTabHistory.options.defaultChanger; 26776 var newState = createNewHistoryState(history.state, tabGroup, selector); 26777 var updateURL = (function ($activatedTab) { 26778 if(selector[0] === '#') { 26779 var elementUpdateURLOption = parseTruthyAttributeValue($activatedTab.data('tab-history-update-url')); 26780 26781 if(elementUpdateURLOption === undefined) { 26782 return BootstrapTabHistory.options.defaultUpdateURL; 26783 } else { 26784 return elementUpdateURLOption; 26785 } 26786 } else { 26787 return false; 26788 } 26789 })($activatedTab); 26790 26791 switch(historyChanger) { 26792 case 'push': 26793 history.pushState(newState, '', updateURL ? selector : null); 26794 break; 26795 case 'replace': 26796 history.replaceState(newState, '', updateURL ? selector : null); 26797 break; 26798 default: 26799 throw new Error('Unknown tab-history-changer: ' + historyChanger); 26800 } 26801 } 26802 } 26803 } 26804 } 26805 26806 /** 26807 * Receives the `popstate` event. Shows tabs based on the value of `history.state` as appropriate. 26808 */ 26809 function onPopState() { 26810 var bootstrapTabHistory = history.state && history.state.bootstrapTabHistory; 26811 26812 if(bootstrapTabHistory) { 26813 showTabsBasedOnState(bootstrapTabHistory); 26814 } 26815 } 26816 26817 /** 26818 * Returns the given value, _unless_ that value is an empty string, in which case `true` is returned. 26819 * 26820 * Rationale: HAML data attributes which are set to `true` are rendered as a blank string. 26821 * 26822 * @param {*} value 26823 * @returns {*} 26824 */ 26825 function parseTruthyAttributeValue(value) { 26826 if(value) { 26827 return value; 26828 } else if(value === '') { 26829 return true; 26830 } else { 26831 return value; 26832 } 26833 } 26834 26835 /** 26836 * Show tabs based upon the anchor component of `window.location`. 26837 */ 26838 function showTabsBasedOnAnchor() { 26839 if(BootstrapTabHistory.options.showTabsBasedOnAnchor) { 26840 var anchor = window.location && window.location.hash; 26841 26842 if(anchor) { 26843 var $tabElement = showTabForSelector(anchor); 26844 26845 if($tabElement && window.addEventListener && window.removeEventListener) { 26846 var anchorYOffset = (function ($tabElement) { 26847 var elementSetting = $tabElement.data('tab-history-anchor-y-offset'); 26848 26849 if(elementSetting === undefined) { 26850 return BootstrapTabHistory.options.defaultAnchorYOffset; 26851 } else { 26852 return elementSetting; 26853 } 26854 })($tabElement); 26855 26856 // HACK: This prevents scrolling to the tab on page load. This relies on the fact that we should never get 26857 // here on `history.forward`, `history.back`, or `location.reload`, since in all those situations the 26858 // `history.state` object should have been used (unless the browser did not support the modern History API). 26859 if(anchorYOffset || anchorYOffset === 0) { 26860 var scrollListener = function resetAnchorScroll () { 26861 window.removeEventListener('scroll', scrollListener); 26862 window.scrollTo(0, anchorYOffset); 26863 }; 26864 26865 window.addEventListener('scroll', scrollListener); 26866 } 26867 } 26868 } 26869 } 26870 } 26871 26872 /** 26873 * Show a tab which corresponds to the provided selector. 26874 * 26875 * @param {string} selector - A CSS selector. 26876 * @returns {?jQuery} - The tab which was found to show (even if said tab was already active). 26877 */ 26878 function showTabForSelector(selector) { 26879 var $tabElement = (function (selector) { 26880 var $ret = null; 26881 26882 jQuery('[data-toggle="tab"], [data-toggle="pill"], [data-toggle="collapse"]').each(function () { 26883 var $potentialTab = jQuery(this); 26884 26885 if(($potentialTab.attr('href') === selector || $potentialTab.data('target') === selector ) && getTabGroup($potentialTab)) { 26886 $ret = $potentialTab; 26887 return false;
vendor: 43,417 bytes, lines 26888-28102
26888 } else { 26889 return null; 26890 } 26891 }); 26892 26893 return $ret; 26894 })(selector); 26895 26896 if($tabElement) { 26897 $tabElement.trigger('click'); 26898 //$tabElement.tab('show'); 26899 } 26900 26901 return $tabElement; 26902 } 26903 26904 /** 26905 * Iterate through the provided set of tab tab groups, showing the tabs based on the stored selectors. 26906 * 26907 * @param {object} bootstrapTabHistory - Each of the values is passed to showTabForSelector; the keys are actually irrelevant. 26908 */ 26909 function showTabsBasedOnState(bootstrapTabHistory) { 26910 showingTabsBasedOnState = true; 26911 26912 try { 26913 for(var k in bootstrapTabHistory) { 26914 if(bootstrapTabHistory.hasOwnProperty(k)) { 26915 showTabForSelector(bootstrapTabHistory[k]); 26916 } 26917 } 26918 } finally { 26919 showingTabsBasedOnState = false; 26920 } 26921 } 26922})(); 26923 26924/*! 26925 * justifiedGallery - v3.8.1 26926 * http://miromannino.github.io/Justified-Gallery/ 26927 * Copyright (c) 2020 Miro Mannino 26928 * Licensed under the MIT license. 26929 */ 26930(function (factory) { 26931 if (typeof define === 'function' && define.amd) { 26932 // AMD. Register as an anonymous module. 26933 define(['jquery'], factory); 26934 } else if (typeof module === 'object' && module.exports) { 26935 // Node/CommonJS 26936 module.exports = function (root, jQuery) { 26937 if (jQuery === undefined) { 26938 // require('jQuery') returns a factory that requires window to 26939 // build a jQuery instance, we normalize how we use modules 26940 // that require this pattern but the window provided is a noop 26941 // if it's defined (how jquery works) 26942 if (typeof window !== 'undefined') { 26943 jQuery = require('jquery'); 26944 } 26945 else { 26946 jQuery = require('jquery')(root); 26947 } 26948 } 26949 factory(jQuery); 26950 return jQuery; 26951 }; 26952 } else { 26953 // Browser globals 26954 factory(jQuery); 26955 } 26956}(function ($) { 26957 26958 /** 26959 * Justified Gallery controller constructor 26960 * 26961 * @param $gallery the gallery to build 26962 * @param settings the settings (the defaults are in JustifiedGallery.defaults) 26963 * @constructor 26964 */ 26965 var JustifiedGallery = function ($gallery, settings) { 26966 26967 this.settings = settings; 26968 this.checkSettings(); 26969 26970 this.imgAnalyzerTimeout = null; 26971 this.entries = null; 26972 this.buildingRow = { 26973 entriesBuff: [], 26974 width: 0, 26975 height: 0, 26976 aspectRatio: 0 26977 }; 26978 this.lastFetchedEntry = null; 26979 this.lastAnalyzedIndex = -1; 26980 this.yield = { 26981 every: 2, // do a flush every n flushes (must be greater than 1) 26982 flushed: 0 // flushed rows without a yield 26983 }; 26984 this.border = settings.border >= 0 ? settings.border : settings.margins; 26985 this.maxRowHeight = this.retrieveMaxRowHeight(); 26986 this.suffixRanges = this.retrieveSuffixRanges(); 26987 this.offY = this.border; 26988 this.rows = 0; 26989 this.spinner = { 26990 phase: 0, 26991 timeSlot: 150, 26992 $el: $('<div class="jg-spinner"><span></span><span></span><span></span></div>'), 26993 intervalId: null 26994 }; 26995 this.scrollBarOn = false; 26996 this.checkWidthIntervalId = null; 26997 this.galleryWidth = $gallery.width(); 26998 this.$gallery = $gallery; 26999 27000 }; 27001 27002 /** @returns {String} the best suffix given the width and the height */ 27003 JustifiedGallery.prototype.getSuffix = function (width, height) { 27004 var longestSide, i; 27005 longestSide = (width > height) ? width : height; 27006 for (i = 0; i < this.suffixRanges.length; i++) { 27007 if (longestSide <= this.suffixRanges[i]) { 27008 return this.settings.sizeRangeSuffixes[this.suffixRanges[i]]; 27009 } 27010 } 27011 return this.settings.sizeRangeSuffixes[this.suffixRanges[i - 1]]; 27012 }; 27013 27014 /** 27015 * Remove the suffix from the string 27016 * 27017 * @returns {string} a new string without the suffix 27018 */ 27019 JustifiedGallery.prototype.removeSuffix = function (str, suffix) { 27020 return str.substring(0, str.length - suffix.length); 27021 }; 27022 27023 /** 27024 * @returns {boolean} a boolean to say if the suffix is contained in the str or not 27025 */ 27026 JustifiedGallery.prototype.endsWith = function (str, suffix) { 27027 return str.indexOf(suffix, str.length - suffix.length) !== -1; 27028 }; 27029 27030 /** 27031 * Get the used suffix of a particular url 27032 * 27033 * @param str 27034 * @returns {String} return the used suffix 27035 */ 27036 JustifiedGallery.prototype.getUsedSuffix = function (str) { 27037 for (var si in this.settings.sizeRangeSuffixes) { 27038 if (this.settings.sizeRangeSuffixes.hasOwnProperty(si)) { 27039 if (this.settings.sizeRangeSuffixes[si].length === 0) continue; 27040 if (this.endsWith(str, this.settings.sizeRangeSuffixes[si])) return this.settings.sizeRangeSuffixes[si]; 27041 } 27042 } 27043 return ''; 27044 }; 27045 27046 /** 27047 * Given an image src, with the width and the height, returns the new image src with the 27048 * best suffix to show the best quality thumbnail. 27049 * 27050 * @returns {String} the suffix to use 27051 */ 27052 JustifiedGallery.prototype.newSrc = function (imageSrc, imgWidth, imgHeight, image) { 27053 var newImageSrc; 27054 27055 if (this.settings.thumbnailPath) { 27056 newImageSrc = this.settings.thumbnailPath(imageSrc, imgWidth, imgHeight, image); 27057 } else { 27058 var matchRes = imageSrc.match(this.settings.extension); 27059 var ext = (matchRes !== null) ? matchRes[0] : ''; 27060 newImageSrc = imageSrc.replace(this.settings.extension, ''); 27061 newImageSrc = this.removeSuffix(newImageSrc, this.getUsedSuffix(newImageSrc)); 27062 newImageSrc += this.getSuffix(imgWidth, imgHeight) + ext; 27063 } 27064 27065 return newImageSrc; 27066 }; 27067 27068 /** 27069 * Shows the images that is in the given entry 27070 * 27071 * @param $entry the entry 27072 * @param callback the callback that is called when the show animation is finished 27073 */ 27074 JustifiedGallery.prototype.showImg = function ($entry, callback) { 27075 if (this.settings.cssAnimation) { 27076 $entry.addClass('jg-entry-visible'); 27077 if (callback) callback(); 27078 } else { 27079 $entry.stop().fadeTo(this.settings.imagesAnimationDuration, 1.0, callback); 27080 $entry.find(this.settings.imgSelector).stop().fadeTo(this.settings.imagesAnimationDuration, 1.0, callback); 27081 } 27082 }; 27083 27084 /** 27085 * Extract the image src form the image, looking from the 'safe-src', and if it can't be found, from the 27086 * 'src' attribute. It saves in the image data the 'jg.originalSrc' field, with the extracted src. 27087 * 27088 * @param $image the image to analyze 27089 * @returns {String} the extracted src 27090 */ 27091 JustifiedGallery.prototype.extractImgSrcFromImage = function ($image) { 27092 var imageSrc = $image.data('safe-src'); 27093 var imageSrcLoc = 'data-safe-src'; 27094 // Begin Uncode edit 27095 if (typeof imageSrc === 'undefined') { 27096 var imageCurrentSrc = $image[0].currentSrc; 27097 if (imageCurrentSrc) { 27098 imageSrc = imageCurrentSrc; 27099 } else { 27100 imageSrc = $image.attr('src'); 27101 } 27102 imageSrcLoc = 'src'; 27103 } 27104 // End Uncode edit 27105 $image.data('jg.originalSrc', imageSrc); // this is saved for the destroy method 27106 $image.data('jg.src', imageSrc); // this will change overtime 27107 $image.data('jg.originalSrcLoc', imageSrcLoc); // this is saved for the destroy method 27108 return imageSrc; 27109 }; 27110 27111 /** @returns {jQuery} the image in the given entry */ 27112 JustifiedGallery.prototype.imgFromEntry = function ($entry) { 27113 var $img = $entry.find(this.settings.imgSelector); 27114 if ($img.length === 0) $img = $entry.find('.t-entry-visual-cont img');//hacked by Uncode 27115 return $img.length === 0 ? null : $img; 27116 }; 27117 27118 /** @returns {jQuery} the caption in the given entry */ 27119 JustifiedGallery.prototype.captionFromEntry = function ($entry) { 27120 var $caption = $entry.find('> .jg-caption'); 27121 return $caption.length === 0 ? null : $caption; 27122 }; 27123 27124 /** 27125 * Display the entry 27126 * 27127 * @param {jQuery} $entry the entry to display 27128 * @param {int} x the x position where the entry must be positioned 27129 * @param y the y position where the entry must be positioned 27130 * @param imgWidth the image width 27131 * @param imgHeight the image height 27132 * @param rowHeight the row height of the row that owns the entry 27133 */ 27134 JustifiedGallery.prototype.displayEntry = function ($entry, x, y, imgWidth, imgHeight, rowHeight) { 27135 $entry.width(imgWidth); 27136 $entry.height(Math.floor(rowHeight));//hacked by Uncode 27137 $entry.css('top', Math.floor(y));//hacked by Uncode 27138 $entry.css('left', x); 27139 27140 var $image = this.imgFromEntry($entry); 27141 if ($image !== null) { 27142 $image.css('width', imgWidth); 27143 $image.css('height', imgHeight); 27144 $image.css('margin-left', - imgWidth / 2); 27145 $image.css('margin-top', - imgHeight / 2); 27146 27147 // Image reloading for an high quality of thumbnails 27148 var imageSrc = $image.data('jg.src'); 27149 if (imageSrc) { 27150 imageSrc = this.newSrc(imageSrc, imgWidth, imgHeight, $image[0]); 27151 27152 $image.one('error', function () { 27153 this.resetImgSrc($image); //revert to the original thumbnail 27154 }); 27155 27156 var loadNewImage = function () { 27157 // if (imageSrc !== newImageSrc) { 27158 $image.attr('src', imageSrc); 27159 // } 27160 }; 27161 27162 if ($entry.data('jg.loaded') === 'skipped' && imageSrc) { 27163 this.onImageEvent(imageSrc, (function() { 27164 this.showImg($entry, loadNewImage); //load the new image after the fadeIn 27165 $entry.data('jg.loaded', true); 27166 }).bind(this)); 27167 } else { 27168 this.showImg($entry, loadNewImage); //load the new image after the fadeIn 27169 } 27170 27171 } 27172 27173 } else { 27174 this.showImg($entry); 27175 } 27176 27177 this.displayEntryCaption($entry); 27178 }; 27179 27180 /** 27181 * Display the entry caption. If the caption element doesn't exists, it creates the caption using the 'alt' 27182 * or the 'title' attributes. 27183 * 27184 * @param {jQuery} $entry the entry to process 27185 */ 27186 JustifiedGallery.prototype.displayEntryCaption = function ($entry) { 27187 var $image = this.imgFromEntry($entry); 27188 if ($image !== null && this.settings.captions) { 27189 var $imgCaption = this.captionFromEntry($entry); 27190 27191 // Create it if it doesn't exists 27192 if ($imgCaption === null) { 27193 var caption = $image.attr('alt'); 27194 if (!this.isValidCaption(caption)) caption = $entry.attr('title'); 27195 if (this.isValidCaption(caption)) { // Create only we found something 27196 $imgCaption = $('<div class="jg-caption">' + caption + '</div>'); 27197 $entry.append($imgCaption); 27198 $entry.data('jg.createdCaption', true); 27199 } 27200 } 27201 27202 // Create events (we check again the $imgCaption because it can be still inexistent) 27203 if ($imgCaption !== null) { 27204 if (!this.settings.cssAnimation) $imgCaption.stop().fadeTo(0, this.settings.captionSettings.nonVisibleOpacity); 27205 this.addCaptionEventsHandlers($entry); 27206 } 27207 } else { 27208 this.removeCaptionEventsHandlers($entry); 27209 } 27210 }; 27211 27212 /** 27213 * Validates the caption 27214 * 27215 * @param caption The caption that should be validated 27216 * @return {boolean} Validation result 27217 */ 27218 JustifiedGallery.prototype.isValidCaption = function (caption) { 27219 return (typeof caption !== 'undefined' && caption.length > 0); 27220 }; 27221 27222 /** 27223 * The callback for the event 'mouseenter'. It assumes that the event currentTarget is an entry. 27224 * It shows the caption using jQuery (or using CSS if it is configured so) 27225 * 27226 * @param {Event} eventObject the event object 27227 */ 27228 JustifiedGallery.prototype.onEntryMouseEnterForCaption = function (eventObject) { 27229 var $caption = this.captionFromEntry($(eventObject.currentTarget)); 27230 if (this.settings.cssAnimation) { 27231 $caption.addClass('jg-caption-visible').removeClass('jg-caption-hidden'); 27232 } else { 27233 $caption.stop().fadeTo(this.settings.captionSettings.animationDuration, 27234 this.settings.captionSettings.visibleOpacity); 27235 } 27236 }; 27237 27238 /** 27239 * The callback for the event 'mouseleave'. It assumes that the event currentTarget is an entry. 27240 * It hides the caption using jQuery (or using CSS if it is configured so) 27241 * 27242 * @param {Event} eventObject the event object 27243 */ 27244 JustifiedGallery.prototype.onEntryMouseLeaveForCaption = function (eventObject) { 27245 var $caption = this.captionFromEntry($(eventObject.currentTarget)); 27246 if (this.settings.cssAnimation) { 27247 $caption.removeClass('jg-caption-visible').removeClass('jg-caption-hidden'); 27248 } else { 27249 $caption.stop().fadeTo(this.settings.captionSettings.animationDuration, 27250 this.settings.captionSettings.nonVisibleOpacity); 27251 } 27252 }; 27253 27254 /** 27255 * Add the handlers of the entry for the caption 27256 * 27257 * @param $entry the entry to modify 27258 */ 27259 JustifiedGallery.prototype.addCaptionEventsHandlers = function ($entry) { 27260 var captionMouseEvents = $entry.data('jg.captionMouseEvents'); 27261 if (typeof captionMouseEvents === 'undefined') { 27262 captionMouseEvents = { 27263 mouseenter: $.proxy(this.onEntryMouseEnterForCaption, this), 27264 mouseleave: $.proxy(this.onEntryMouseLeaveForCaption, this) 27265 }; 27266 $entry.on('mouseenter', undefined, undefined, captionMouseEvents.mouseenter); 27267 $entry.on('mouseleave', undefined, undefined, captionMouseEvents.mouseleave); 27268 $entry.data('jg.captionMouseEvents', captionMouseEvents); 27269 } 27270 }; 27271 27272 /** 27273 * Remove the handlers of the entry for the caption 27274 * 27275 * @param $entry the entry to modify 27276 */ 27277 JustifiedGallery.prototype.removeCaptionEventsHandlers = function ($entry) { 27278 var captionMouseEvents = $entry.data('jg.captionMouseEvents'); 27279 if (typeof captionMouseEvents !== 'undefined') { 27280 $entry.off('mouseenter', undefined, captionMouseEvents.mouseenter); 27281 $entry.off('mouseleave', undefined, captionMouseEvents.mouseleave); 27282 $entry.removeData('jg.captionMouseEvents'); 27283 } 27284 }; 27285 27286 /** 27287 * Clear the building row data to be used for a new row 27288 */ 27289 JustifiedGallery.prototype.clearBuildingRow = function () { 27290 this.buildingRow.entriesBuff = []; 27291 this.buildingRow.aspectRatio = 0; 27292 this.buildingRow.width = 0; 27293 }; 27294 27295 /** 27296 * Justify the building row, preparing it to 27297 * 27298 * @param isLastRow 27299 * @param hiddenRow undefined or false for normal behavior. hiddenRow = true to hide the row. 27300 * @returns a boolean to know if the row has been justified or not 27301 */ 27302 JustifiedGallery.prototype.prepareBuildingRow = function (isLastRow, hiddenRow) { 27303 var i, $entry, imgAspectRatio, newImgW, newImgH, justify = true; 27304 var minHeight = 0; 27305 var availableWidth = this.galleryWidth - 2 * this.border - ( 27306 (this.buildingRow.entriesBuff.length - 1) * this.settings.margins); 27307 var rowHeight = Math.floor( availableWidth / this.buildingRow.aspectRatio );//hacked by Uncode 27308 var defaultRowHeight = this.settings.rowHeight; 27309 var justifiable = this.buildingRow.width / availableWidth > this.settings.justifyThreshold; 27310 27311 //Skip the last row if we can't justify it and the lastRow == 'hide' 27312 if (hiddenRow || (isLastRow && this.settings.lastRow === 'hide' && !justifiable)) { 27313 for (i = 0; i < this.buildingRow.entriesBuff.length; i++) { 27314 $entry = this.buildingRow.entriesBuff[i]; 27315 if (this.settings.cssAnimation) 27316 $entry.removeClass('jg-entry-visible'); 27317 else { 27318 $entry.stop().fadeTo(0, 0.1); 27319 $entry.find('> img, > a > img').fadeTo(0, 0); 27320 } 27321 } 27322 return -1; 27323 } 27324 27325 // With lastRow = nojustify, justify if is justificable (the images will not become too big) 27326 if (isLastRow && !justifiable && this.settings.lastRow !== 'justify' && this.settings.lastRow !== 'hide') { 27327 justify = false; 27328 27329 if (this.rows > 0) { 27330 defaultRowHeight = (this.offY - this.border - this.settings.margins * this.rows) / this.rows; 27331 justify = defaultRowHeight * this.buildingRow.aspectRatio / availableWidth > this.settings.justifyThreshold; 27332 } 27333 } 27334 27335 for (i = 0; i < this.buildingRow.entriesBuff.length; i++) { 27336 $entry = this.buildingRow.entriesBuff[i]; 27337 imgAspectRatio = $entry.data('jg.width') / $entry.data('jg.height'); 27338 27339 if (justify) { 27340 newImgW = (i === this.buildingRow.entriesBuff.length - 1) ? availableWidth : rowHeight * imgAspectRatio; 27341 newImgH = rowHeight; 27342 } else { 27343 newImgW = defaultRowHeight * imgAspectRatio; 27344 newImgH = defaultRowHeight; 27345 } 27346 27347 availableWidth -= Math.round(newImgW); 27348 $entry.data('jg.jwidth', Math.round(newImgW)); 27349 $entry.data('jg.jheight', Math.ceil(newImgH)); 27350 if (i === 0 || minHeight > newImgH) minHeight = newImgH; 27351 } 27352 27353 this.buildingRow.height = minHeight; 27354 return justify; 27355 }; 27356 27357 /** 27358 * Flush a row: justify it, modify the gallery height accordingly to the row height 27359 * 27360 * @param isLastRow 27361 * @param hiddenRow undefined or false for normal behavior. hiddenRow = true to hide the row. 27362 */ 27363 JustifiedGallery.prototype.flushRow = function (isLastRow, hiddenRow) { 27364 var settings = this.settings; 27365 var $entry, buildingRowRes, offX = this.border, i; 27366 27367 buildingRowRes = this.prepareBuildingRow(isLastRow, hiddenRow); 27368 if (hiddenRow || (isLastRow && settings.lastRow === 'hide' && buildingRowRes === -1)) { 27369 this.clearBuildingRow(); 27370 return; 27371 } 27372 27373 if (this.maxRowHeight) { 27374 if (this.maxRowHeight < this.buildingRow.height) this.buildingRow.height = this.maxRowHeight; 27375 } 27376 27377 //Align last (unjustified) row 27378 if (isLastRow && (settings.lastRow === 'center' || settings.lastRow === 'right')) { 27379 var availableWidth = this.galleryWidth - 2 * this.border - (this.buildingRow.entriesBuff.length - 1) * settings.margins; 27380 27381 for (i = 0; i < this.buildingRow.entriesBuff.length; i++) { 27382 $entry = this.buildingRow.entriesBuff[i]; 27383 availableWidth -= $entry.data('jg.jwidth'); 27384 } 27385 27386 if (settings.lastRow === 'center') 27387 offX += Math.round(availableWidth / 2); 27388 else if (settings.lastRow === 'right') 27389 offX += availableWidth; 27390 } 27391 27392 var lastEntryIdx = this.buildingRow.entriesBuff.length - 1; 27393 for (i = 0; i <= lastEntryIdx; i++) { 27394 $entry = this.buildingRow.entriesBuff[this.settings.rtl ? lastEntryIdx - i : i]; 27395 this.displayEntry($entry, offX, this.offY, $entry.data('jg.jwidth'), $entry.data('jg.jheight'), this.buildingRow.height); 27396 offX += $entry.data('jg.jwidth') + settings.margins; 27397 } 27398 27399 //Gallery Height 27400 this.galleryHeightToSet = this.offY + this.buildingRow.height + this.border; 27401 this.setGalleryTempHeight(this.galleryHeightToSet + this.getSpinnerHeight()); 27402 27403 if (!isLastRow || (this.buildingRow.height <= settings.rowHeight && buildingRowRes)) { 27404 //Ready for a new row 27405 this.offY += this.buildingRow.height + settings.margins; 27406 this.rows += 1; 27407 this.clearBuildingRow(); 27408 this.settings.triggerEvent.call(this, 'jg.rowflush'); 27409 } 27410 }; 27411 27412 27413 // Scroll position not restoring: https://github.com/miromannino/Justified-Gallery/issues/221 27414 var galleryPrevStaticHeight = 0; 27415 27416 JustifiedGallery.prototype.rememberGalleryHeight = function () { 27417 galleryPrevStaticHeight = this.$gallery.height(); 27418 this.$gallery.height(galleryPrevStaticHeight); 27419 }; 27420 27421 // grow only 27422 JustifiedGallery.prototype.setGalleryTempHeight = function (height) { 27423 galleryPrevStaticHeight = Math.max(height, galleryPrevStaticHeight); 27424 this.$gallery.height(galleryPrevStaticHeight); 27425 }; 27426 27427 JustifiedGallery.prototype.setGalleryFinalHeight = function (height) { 27428 galleryPrevStaticHeight = height; 27429 this.$gallery.height(height); 27430 }; 27431 27432 /** 27433 * Checks the width of the gallery container, to know if a new justification is needed 27434 */ 27435 JustifiedGallery.prototype.checkWidth = function () { 27436 this.checkWidthIntervalId = setInterval($.proxy(function () { 27437 27438 // if the gallery is not currently visible, abort. 27439 if (!this.$gallery.is(":visible")) return; 27440 27441 var galleryWidth = parseFloat(this.$gallery.width()); 27442 if (Math.abs(galleryWidth - this.galleryWidth) > this.settings.refreshSensitivity) { 27443 this.galleryWidth = galleryWidth; 27444 this.rewind(); 27445 27446 this.rememberGalleryHeight(); 27447 27448 // Restart to analyze 27449 this.startImgAnalyzer(true); 27450 } 27451 }, this), this.settings.refreshTime); 27452 }; 27453 27454 /** 27455 * @returns {boolean} a boolean saying if the spinner is active or not 27456 */ 27457 JustifiedGallery.prototype.isSpinnerActive = function () { 27458 return this.spinner.intervalId !== null; 27459 }; 27460 27461 /** 27462 * @returns {int} the spinner height 27463 */ 27464 JustifiedGallery.prototype.getSpinnerHeight = function () { 27465 return this.spinner.$el.innerHeight(); 27466 }; 27467 27468 /** 27469 * Stops the spinner animation and modify the gallery height to exclude the spinner 27470 */ 27471 JustifiedGallery.prototype.stopLoadingSpinnerAnimation = function () { 27472 clearInterval(this.spinner.intervalId); 27473 this.spinner.intervalId = null; 27474 this.setGalleryTempHeight(this.$gallery.height() - this.getSpinnerHeight()); 27475 this.spinner.$el.detach(); 27476 }; 27477 27478 /** 27479 * Starts the spinner animation 27480 */ 27481 JustifiedGallery.prototype.startLoadingSpinnerAnimation = function () { 27482 var spinnerContext = this.spinner; 27483 var $spinnerPoints = spinnerContext.$el.find('span'); 27484 clearInterval(spinnerContext.intervalId); 27485 this.$gallery.append(spinnerContext.$el); 27486 this.setGalleryTempHeight(this.offY + this.buildingRow.height + this.getSpinnerHeight()); 27487 spinnerContext.intervalId = setInterval(function () { 27488 if (spinnerContext.phase < $spinnerPoints.length) { 27489 $spinnerPoints.eq(spinnerContext.phase).fadeTo(spinnerContext.timeSlot, 1); 27490 } else { 27491 $spinnerPoints.eq(spinnerContext.phase - $spinnerPoints.length).fadeTo(spinnerContext.timeSlot, 0); 27492 } 27493 spinnerContext.phase = (spinnerContext.phase + 1) % ($spinnerPoints.length * 2); 27494 }, spinnerContext.timeSlot); 27495 }; 27496 27497 /** 27498 * Rewind the image analysis to start from the first entry. 27499 */ 27500 JustifiedGallery.prototype.rewind = function () { 27501 this.lastFetchedEntry = null; 27502 this.lastAnalyzedIndex = -1; 27503 this.offY = this.border; 27504 this.rows = 0; 27505 this.clearBuildingRow(); 27506 }; 27507 27508 /** 27509 * @returns {String} `settings.selector` rejecting spinner element 27510 */ 27511 JustifiedGallery.prototype.getSelectorWithoutSpinner = function () { 27512 return this.settings.selector + ', div:not(.jg-spinner)'; 27513 }; 27514 27515 /** 27516 * @returns {Array} all entries matched by `settings.selector` 27517 */ 27518 JustifiedGallery.prototype.getAllEntries = function () { 27519 var selector = this.getSelectorWithoutSpinner(); 27520 return this.$gallery.children(selector).toArray(); 27521 }; 27522 27523 /** 27524 * Update the entries searching it from the justified gallery HTML element 27525 * 27526 * @param norewind if norewind only the new entries will be changed (i.e. randomized, sorted or filtered) 27527 * @returns {boolean} true if some entries has been founded 27528 */ 27529 JustifiedGallery.prototype.updateEntries = function (norewind) { 27530 var newEntries; 27531 27532 if (norewind && this.lastFetchedEntry != null) { 27533 var selector = this.getSelectorWithoutSpinner(); 27534 newEntries = $(this.lastFetchedEntry).nextAll(selector).toArray(); 27535 } else { 27536 this.entries = []; 27537 newEntries = this.getAllEntries(); 27538 } 27539 27540 if (newEntries.length > 0) { 27541 27542 // Sort or randomize 27543 if ($.isFunction(this.settings.sort)) { 27544 newEntries = this.sortArray(newEntries); 27545 } else if (this.settings.randomize) { 27546 newEntries = this.shuffleArray(newEntries); 27547 } 27548 this.lastFetchedEntry = newEntries[newEntries.length - 1]; 27549 27550 // Filter 27551 if (this.settings.filter) { 27552 newEntries = this.filterArray(newEntries); 27553 } else { 27554 this.resetFilters(newEntries); 27555 } 27556 27557 } 27558 27559 this.entries = this.entries.concat(newEntries); 27560 return true; 27561 }; 27562 27563 /** 27564 * Apply the entries order to the DOM, iterating the entries and appending the images 27565 * 27566 * @param entries the entries that has been modified and that must be re-ordered in the DOM 27567 */ 27568 JustifiedGallery.prototype.insertToGallery = function (entries) { 27569 var that = this; 27570 $.each(entries, function () { 27571 $(this).appendTo(that.$gallery); 27572 }); 27573 }; 27574 27575 /** 27576 * Shuffle the array using the Fisher-Yates shuffle algorithm 27577 * 27578 * @param a the array to shuffle 27579 * @return the shuffled array 27580 */ 27581 JustifiedGallery.prototype.shuffleArray = function (a) { 27582 var i, j, temp; 27583 for (i = a.length - 1; i > 0; i--) { 27584 j = Math.floor(Math.random() * (i + 1)); 27585 temp = a[i]; 27586 a[i] = a[j]; 27587 a[j] = temp; 27588 } 27589 this.insertToGallery(a); 27590 return a; 27591 }; 27592 27593 /** 27594 * Sort the array using settings.comparator as comparator 27595 * 27596 * @param a the array to sort (it is sorted) 27597 * @return the sorted array 27598 */ 27599 JustifiedGallery.prototype.sortArray = function (a) { 27600 a.sort(this.settings.sort); 27601 this.insertToGallery(a); 27602 return a; 27603 }; 27604 27605 /** 27606 * Reset the filters removing the 'jg-filtered' class from all the entries 27607 * 27608 * @param a the array to reset 27609 */ 27610 JustifiedGallery.prototype.resetFilters = function (a) { 27611 for (var i = 0; i < a.length; i++) $(a[i]).removeClass('jg-filtered'); 27612 }; 27613 27614 /** 27615 * Filter the entries considering theirs classes (if a string has been passed) or using a function for filtering. 27616 * 27617 * @param a the array to filter 27618 * @return the filtered array 27619 */ 27620 JustifiedGallery.prototype.filterArray = function (a) { 27621 var settings = this.settings; 27622 if ($.type(settings.filter) === 'string') { 27623 // Filter only keeping the entries passed in the string 27624 return a.filter(function (el) { 27625 var $el = $(el); 27626 if ($el.is(settings.filter)) { 27627 $el.removeClass('jg-filtered'); 27628 return true; 27629 } else { 27630 $el.addClass('jg-filtered').removeClass('jg-visible'); 27631 return false; 27632 } 27633 }); 27634 } else if ($.isFunction(settings.filter)) { 27635 // Filter using the passed function 27636 var filteredArr = a.filter(settings.filter); 27637 for (var i = 0; i < a.length; i++) { 27638 if (filteredArr.indexOf(a[i]) === -1) { 27639 $(a[i]).addClass('jg-filtered').removeClass('jg-visible'); 27640 } else { 27641 $(a[i]).removeClass('jg-filtered'); 27642 } 27643 } 27644 return filteredArr; 27645 } 27646 }; 27647 27648 /** 27649 * Revert the image src to the default value. 27650 */ 27651 JustifiedGallery.prototype.resetImgSrc = function ($img) { 27652 if ($img.data('jg.originalSrcLoc') === 'src') { 27653 $img.attr('src', $img.data('jg.originalSrc')); 27654 } else { 27655 $img.attr('src', ''); 27656 } 27657 }; 27658 27659 /** 27660 * Destroy the Justified Gallery instance. 27661 * 27662 * It clears all the css properties added in the style attributes. We doesn't backup the original 27663 * values for those css attributes, because it costs (performance) and because in general one 27664 * shouldn't use the style attribute for an uniform set of images (where we suppose the use of 27665 * classes). Creating a backup is also difficult because JG could be called multiple times and 27666 * with different style attributes. 27667 */ 27668 JustifiedGallery.prototype.destroy = function () { 27669 clearInterval(this.checkWidthIntervalId); 27670 this.stopImgAnalyzerStarter(); 27671 27672 // Get fresh entries list since filtered entries are absent in `this.entries` 27673 $.each(this.getAllEntries(), $.proxy(function (_, entry) { 27674 var $entry = $(entry); 27675 27676 // Reset entry style 27677 $entry.css('width', ''); 27678 $entry.css('height', ''); 27679 $entry.css('top', ''); 27680 $entry.css('left', ''); 27681 $entry.data('jg.loaded', undefined); 27682 $entry.removeClass('jg-entry jg-filtered jg-entry-visible'); 27683 27684 // Reset image style 27685 var $img = this.imgFromEntry($entry); 27686 if ($img) { 27687 $img.css('width', ''); 27688 $img.css('height', ''); 27689 $img.css('margin-left', ''); 27690 $img.css('margin-top', ''); 27691 this.resetImgSrc($img); 27692 $img.data('jg.originalSrc', undefined); 27693 $img.data('jg.originalSrcLoc', undefined); 27694 $img.data('jg.src', undefined); 27695 } 27696 27697 // Remove caption 27698 this.removeCaptionEventsHandlers($entry); 27699 var $caption = this.captionFromEntry($entry); 27700 if ($entry.data('jg.createdCaption')) { 27701 // remove also the caption element (if created by jg) 27702 $entry.data('jg.createdCaption', undefined); 27703 if ($caption !== null) $caption.remove(); 27704 } else { 27705 if ($caption !== null) $caption.fadeTo(0, 1); 27706 } 27707 27708 }, this)); 27709 27710 this.$gallery.css('height', ''); 27711 this.$gallery.removeClass('justified-gallery'); 27712 this.$gallery.data('jg.controller', undefined); 27713 this.settings.triggerEvent.call(this, 'jg.destroy'); 27714 }; 27715 27716 /** 27717 * Analyze the images and builds the rows. It returns if it found an image that is not loaded. 27718 * 27719 * @param isForResize if the image analyzer is called for resizing or not, to call a different callback at the end 27720 */ 27721 JustifiedGallery.prototype.analyzeImages = function (isForResize) { 27722 for (var i = this.lastAnalyzedIndex + 1; i < this.entries.length; i++) { 27723 var $entry = $(this.entries[i]); 27724 if ($entry.data('jg.loaded') === true || $entry.data('jg.loaded') === 'skipped') { 27725 var availableWidth = this.galleryWidth - 2 * this.border - ( 27726 (this.buildingRow.entriesBuff.length - 1) * this.settings.margins); 27727 var imgAspectRatio = $entry.data('jg.width') / $entry.data('jg.height'); 27728 27729 this.buildingRow.entriesBuff.push($entry); 27730 this.buildingRow.aspectRatio += imgAspectRatio; 27731 this.buildingRow.width += imgAspectRatio * this.settings.rowHeight; 27732 this.lastAnalyzedIndex = i; 27733 27734 if (availableWidth / (this.buildingRow.aspectRatio + imgAspectRatio) < this.settings.rowHeight) { 27735 this.flushRow(false, this.settings.maxRowsCount > 0 && this.rows === this.settings.maxRowsCount); 27736 27737 if (++this.yield.flushed >= this.yield.every) { 27738 this.startImgAnalyzer(isForResize); 27739 return; 27740 } 27741 } 27742 } else if ($entry.data('jg.loaded') !== 'error') { 27743 return; 27744 } 27745 } 27746 27747 // Last row flush (the row is not full) 27748 if (this.buildingRow.entriesBuff.length > 0) { 27749 this.flushRow(true, this.settings.maxRowsCount > 0 && this.rows === this.settings.maxRowsCount); 27750 } 27751 27752 if (this.isSpinnerActive()) { 27753 this.stopLoadingSpinnerAnimation(); 27754 } 27755 27756 /* Stop, if there is, the timeout to start the analyzeImages. 27757 This is because an image can be set loaded, and the timeout can be set, 27758 but this image can be analyzed yet. 27759 */ 27760 this.stopImgAnalyzerStarter(); 27761 27762 this.setGalleryFinalHeight(this.galleryHeightToSet); 27763 27764 //On complete callback 27765 this.settings.triggerEvent.call(this, isForResize ? 'jg.resize' : 'jg.complete'); 27766 }; 27767 27768 /** 27769 * Stops any ImgAnalyzer starter (that has an assigned timeout) 27770 */ 27771 JustifiedGallery.prototype.stopImgAnalyzerStarter = function () { 27772 this.yield.flushed = 0; 27773 if (this.imgAnalyzerTimeout !== null) { 27774 clearTimeout(this.imgAnalyzerTimeout); 27775 this.imgAnalyzerTimeout = null; 27776 } 27777 }; 27778 27779 /** 27780 * Starts the image analyzer. It is not immediately called to let the browser to update the view 27781 * 27782 * @param isForResize specifies if the image analyzer must be called for resizing or not 27783 */ 27784 JustifiedGallery.prototype.startImgAnalyzer = function (isForResize) { 27785 var that = this; 27786 this.stopImgAnalyzerStarter(); 27787 this.imgAnalyzerTimeout = setTimeout(function () { 27788 that.analyzeImages(isForResize); 27789 }, 0.001); // we can't start it immediately due to a IE different behaviour 27790 }; 27791 27792 /** 27793 * Checks if the image is loaded or not using another image object. We cannot use the 'complete' image property, 27794 * because some browsers, with a 404 set complete = true. 27795 * 27796 * @param imageSrc the image src to load 27797 * @param onLoad callback that is called when the image has been loaded 27798 * @param onError callback that is called in case of an error 27799 */ 27800 JustifiedGallery.prototype.onImageEvent = function (imageSrc, onLoad, onError) { 27801 if (!onLoad && !onError) return; 27802 27803 var memImage = new Image(); 27804 var $memImage = $(memImage); 27805 if (onLoad) { 27806 $memImage.one('load', function () { 27807 $memImage.off('load error'); 27808 onLoad(memImage); 27809 }); 27810 } 27811 if (onError) { 27812 $memImage.one('error', function () { 27813 $memImage.off('load error'); 27814 onError(memImage); 27815 }); 27816 } 27817 memImage.src = imageSrc; 27818 }; 27819 27820 /** 27821 * Init of Justified Gallery controlled 27822 * It analyzes all the entries starting theirs loading and calling the image analyzer (that works with loaded images) 27823 */ 27824 JustifiedGallery.prototype.init = function () { 27825 var imagesToLoad = false, skippedImages = false, that = this; 27826 $.each(this.entries, function (index, entry) { 27827 var $entry = $(entry); 27828 var $image = that.imgFromEntry($entry); 27829 27830 $entry.addClass('jg-entry'); 27831 27832 if ($entry.data('jg.loaded') !== true && $entry.data('jg.loaded') !== 'skipped') { 27833 27834 // Link Rel global overwrite 27835 if (that.settings.rel !== null) $entry.attr('rel', that.settings.rel); 27836 27837 // Link Target global overwrite 27838 if (that.settings.target !== null) $entry.attr('target', that.settings.target); 27839 27840 if ($image !== null) { 27841 27842 // Image src 27843 var imageSrc = that.extractImgSrcFromImage($image); 27844 27845 /* If we have the height and the width, we don't wait that the image is loaded, 27846 but we start directly with the justification */ 27847 if (that.settings.waitThumbnailsLoad === false || !imageSrc) { 27848 var width = parseFloat($image.attr('width')); 27849 var height = parseFloat($image.attr('height')); 27850 if ($image.prop('tagName') === 'svg') { 27851 width = parseFloat($image[0].getBBox().width); 27852 height = parseFloat($image[0].getBBox().height); 27853 } 27854 if (!isNaN(width) && !isNaN(height)) { 27855 $entry.data('jg.width', width); 27856 $entry.data('jg.height', height); 27857 $entry.data('jg.loaded', 'skipped'); 27858 skippedImages = true; 27859 that.startImgAnalyzer(false); 27860 return true; // continue 27861 } 27862 } 27863 27864 $entry.data('jg.loaded', false); 27865 imagesToLoad = true; 27866 27867 // Spinner start 27868 if (!that.isSpinnerActive()) that.startLoadingSpinnerAnimation(); 27869 27870 that.onImageEvent(imageSrc, function (loadImg) { // image loaded 27871 $entry.data('jg.width', loadImg.width); 27872 $entry.data('jg.height', loadImg.height); 27873 $entry.data('jg.loaded', true); 27874 that.startImgAnalyzer(false); 27875 }, function () { // image load error 27876 $entry.data('jg.loaded', 'error'); 27877 that.startImgAnalyzer(false); 27878 }); 27879 27880 } else { 27881 $entry.data('jg.loaded', true); 27882 $entry.data('jg.width', $entry.width() | parseFloat($entry.css('width')) | 1); 27883 $entry.data('jg.height', $entry.height() | parseFloat($entry.css('height')) | 1); 27884 } 27885 27886 } 27887 27888 }); 27889 27890 if (!imagesToLoad && !skippedImages) this.startImgAnalyzer(false); 27891 this.checkWidth(); 27892 }; 27893 27894 /** 27895 * Checks that it is a valid number. If a string is passed it is converted to a number 27896 * 27897 * @param settingContainer the object that contains the setting (to allow the conversion) 27898 * @param settingName the setting name 27899 */ 27900 JustifiedGallery.prototype.checkOrConvertNumber = function (settingContainer, settingName) { 27901 if ($.type(settingContainer[settingName]) === 'string') { 27902 settingContainer[settingName] = parseFloat(settingContainer[settingName]); 27903 } 27904 27905 if ($.type(settingContainer[settingName]) === 'number') { 27906 if (isNaN(settingContainer[settingName])) throw 'invalid number for ' + settingName; 27907 } else { 27908 throw settingName + ' must be a number'; 27909 } 27910 }; 27911 27912 /** 27913 * Checks the sizeRangeSuffixes and, if necessary, converts 27914 * its keys from string (e.g. old settings with 'lt100') to int. 27915 */ 27916 JustifiedGallery.prototype.checkSizeRangesSuffixes = function () { 27917 if ($.type(this.settings.sizeRangeSuffixes) !== 'object') { 27918 throw 'sizeRangeSuffixes must be defined and must be an object'; 27919 } 27920 27921 var suffixRanges = []; 27922 for (var rangeIdx in this.settings.sizeRangeSuffixes) { 27923 if (this.settings.sizeRangeSuffixes.hasOwnProperty(rangeIdx)) suffixRanges.push(rangeIdx); 27924 } 27925 27926 var newSizeRngSuffixes = { 0: '' }; 27927 for (var i = 0; i < suffixRanges.length; i++) { 27928 if ($.type(suffixRanges[i]) === 'string') { 27929 try { 27930 var numIdx = parseInt(suffixRanges[i].replace(/^[a-z]+/, ''), 10); 27931 newSizeRngSuffixes[numIdx] = this.settings.sizeRangeSuffixes[suffixRanges[i]]; 27932 } catch (e) { 27933 throw 'sizeRangeSuffixes keys must contains correct numbers (' + e + ')'; 27934 } 27935 } else { 27936 newSizeRngSuffixes[suffixRanges[i]] = this.settings.sizeRangeSuffixes[suffixRanges[i]]; 27937 } 27938 } 27939 27940 this.settings.sizeRangeSuffixes = newSizeRngSuffixes; 27941 }; 27942 27943 /** 27944 * check and convert the maxRowHeight setting 27945 * requires rowHeight to be already set 27946 * TODO: should be always called when only rowHeight is changed 27947 * @return number or null 27948 */ 27949 JustifiedGallery.prototype.retrieveMaxRowHeight = function () { 27950 var newMaxRowHeight = null; 27951 var rowHeight = this.settings.rowHeight; 27952 27953 if ($.type(this.settings.maxRowHeight) === 'string') { 27954 if (this.settings.maxRowHeight.match(/^[0-9]+%$/)) { 27955 newMaxRowHeight = rowHeight * parseFloat(this.settings.maxRowHeight.match(/^([0-9]+)%$/)[1]) / 100; 27956 } else { 27957 newMaxRowHeight = parseFloat(this.settings.maxRowHeight); 27958 } 27959 } else if ($.type(this.settings.maxRowHeight) === 'number') { 27960 newMaxRowHeight = this.settings.maxRowHeight; 27961 } else if (this.settings.maxRowHeight === false || this.settings.maxRowHeight == null) { 27962 return null; 27963 } else { 27964 throw 'maxRowHeight must be a number or a percentage'; 27965 } 27966 27967 // check if the converted value is not a number 27968 if (isNaN(newMaxRowHeight)) throw 'invalid number for maxRowHeight'; 27969 27970 // check values, maxRowHeight must be >= rowHeight 27971 if (newMaxRowHeight < rowHeight) newMaxRowHeight = rowHeight; 27972 27973 return newMaxRowHeight; 27974 }; 27975 27976 /** 27977 * Checks the settings 27978 */ 27979 JustifiedGallery.prototype.checkSettings = function () { 27980 this.checkSizeRangesSuffixes(); 27981 27982 this.checkOrConvertNumber(this.settings, 'rowHeight'); 27983 this.checkOrConvertNumber(this.settings, 'margins'); 27984 this.checkOrConvertNumber(this.settings, 'border'); 27985 this.checkOrConvertNumber(this.settings, 'maxRowsCount'); 27986 27987 var lastRowModes = [ 27988 'justify', 27989 'nojustify', 27990 'left', 27991 'center', 27992 'right', 27993 'hide' 27994 ]; 27995 if (lastRowModes.indexOf(this.settings.lastRow) === -1) { 27996 throw 'lastRow must be one of: ' + lastRowModes.join(', '); 27997 } 27998 27999 this.checkOrConvertNumber(this.settings, 'justifyThreshold'); 28000 if (this.settings.justifyThreshold < 0 || this.settings.justifyThreshold > 1) { 28001 throw 'justifyThreshold must be in the interval [0,1]'; 28002 } 28003 if ($.type(this.settings.cssAnimation) !== 'boolean') { 28004 throw 'cssAnimation must be a boolean'; 28005 } 28006 28007 if ($.type(this.settings.captions) !== 'boolean') throw 'captions must be a boolean'; 28008 this.checkOrConvertNumber(this.settings.captionSettings, 'animationDuration'); 28009 28010 this.checkOrConvertNumber(this.settings.captionSettings, 'visibleOpacity'); 28011 if (this.settings.captionSettings.visibleOpacity < 0 || 28012 this.settings.captionSettings.visibleOpacity > 1) { 28013 throw 'captionSettings.visibleOpacity must be in the interval [0, 1]'; 28014 } 28015 28016 this.checkOrConvertNumber(this.settings.captionSettings, 'nonVisibleOpacity'); 28017 if (this.settings.captionSettings.nonVisibleOpacity < 0 || 28018 this.settings.captionSettings.nonVisibleOpacity > 1) { 28019 throw 'captionSettings.nonVisibleOpacity must be in the interval [0, 1]'; 28020 } 28021 28022 this.checkOrConvertNumber(this.settings, 'imagesAnimationDuration'); 28023 this.checkOrConvertNumber(this.settings, 'refreshTime'); 28024 this.checkOrConvertNumber(this.settings, 'refreshSensitivity'); 28025 if ($.type(this.settings.randomize) !== 'boolean') throw 'randomize must be a boolean'; 28026 if ($.type(this.settings.selector) !== 'string') throw 'selector must be a string'; 28027 28028 if (this.settings.sort !== false && !$.isFunction(this.settings.sort)) { 28029 throw 'sort must be false or a comparison function'; 28030 } 28031 28032 if (this.settings.filter !== false && !$.isFunction(this.settings.filter) && 28033 $.type(this.settings.filter) !== 'string') { 28034 throw 'filter must be false, a string or a filter function'; 28035 } 28036 }; 28037 28038 /** 28039 * It brings all the indexes from the sizeRangeSuffixes and it orders them. They are then sorted and returned. 28040 * @returns {Array} sorted suffix ranges 28041 */ 28042 JustifiedGallery.prototype.retrieveSuffixRanges = function () { 28043 var suffixRanges = []; 28044 for (var rangeIdx in this.settings.sizeRangeSuffixes) { 28045 if (this.settings.sizeRangeSuffixes.hasOwnProperty(rangeIdx)) suffixRanges.push(parseInt(rangeIdx, 10)); 28046 } 28047 suffixRanges.sort(function (a, b) { return a > b ? 1 : a < b ? -1 : 0; }); 28048 return suffixRanges; 28049 }; 28050 28051 /** 28052 * Update the existing settings only changing some of them 28053 * 28054 * @param newSettings the new settings (or a subgroup of them) 28055 */ 28056 JustifiedGallery.prototype.updateSettings = function (newSettings) { 28057 // In this case Justified Gallery has been called again changing only some options 28058 this.settings = $.extend({}, this.settings, newSettings); 28059 this.checkSettings(); 28060 28061 // As reported in the settings: negative value = same as margins, 0 = disabled 28062 this.border = this.settings.border >= 0 ? this.settings.border : this.settings.margins; 28063 28064 this.maxRowHeight = this.retrieveMaxRowHeight(); 28065 this.suffixRanges = this.retrieveSuffixRanges(); 28066 }; 28067 28068 JustifiedGallery.prototype.defaults = { 28069 sizeRangeSuffixes: {}, /* e.g. Flickr configuration 28070 { 28071 100: '_t', // used when longest is less than 100px 28072 240: '_m', // used when longest is between 101px and 240px 28073 320: '_n', // ... 28074 500: '', 28075 640: '_z', 28076 1024: '_b' // used as else case because it is the last 28077 } 28078 */ 28079 thumbnailPath: undefined, /* If defined, sizeRangeSuffixes is not used, and this function is used to determine the 28080 path relative to a specific thumbnail size. The function should accept respectively three arguments: 28081 current path, width and height */ 28082 rowHeight: 120, // required? required to be > 0? 28083 maxRowHeight: false, // false or negative value to deactivate. Positive number to express the value in pixels, 28084 // A string '[0-9]+%' to express in percentage (e.g. 300% means that the row height 28085 // can't exceed 3 * rowHeight) 28086 maxRowsCount: 0, // maximum number of rows to be displayed (0 = disabled) 28087 margins: 1, 28088 border: -1, // negative value = same as margins, 0 = disabled, any other value to set the border 28089 28090 lastRow: 'nojustify', // ⦠which is the same as 'left', or can be 'justify', 'center', 'right' or 'hide' 28091 28092 justifyThreshold: 0.90, /* if row width / available space > 0.90 it will be always justified 28093 * (i.e. lastRow setting is not considered) */ 28094 waitThumbnailsLoad: true, 28095 captions: true, 28096 cssAnimation: true, 28097 imagesAnimationDuration: 500, // ignored with css animations 28098 captionSettings: { // ignored with css animations 28099 animationDuration: 500, 28100 visibleOpacity: 0.7, 28101 nonVisibleOpacity: 0.0 28102 },
28103 rel: null, // rewrite the rel of each analyzed links 28104 target: null, // rewrite the target of all links 28105 extension: /\.[^.\\/]+$/, // regexp to capture the extension of an image 28106 refreshTime: 200, // time interval (in ms) to check if the page changes its width 28107 refreshSensitivity: 0, // change in width allowed (in px) without re-building the gallery 28108 randomize: false, 28109 rtl: false, // right-to-left mode 28110 sort: false, /* 28111 - false: to do not sort 28112 - function: to sort them using the function as comparator (see Array.prototype.sort()) 28113 */ 28114 filter: false, /* 28115 - false, null or undefined: for a disabled filter 28116 - a string: an entry is kept if entry.is(filter string) returns true 28117 see jQuery's .is() function for further information 28118 - a function: invoked with arguments (entry, index, array). Return true to keep the entry, false otherwise. 28119 It follows the specifications of the Array.prototype.filter() function of JavaScript. 28120 */ 28121 selector: 'a', // The selector that is used to know what are the entries of the gallery 28122 imgSelector: '> img, > a > img, > svg, > a > svg', // The selector that is used to know what are the images of each entry 28123 triggerEvent: function (event) { // This is called to trigger events, the default behavior is to call $.trigger 28124 this.$gallery.trigger(event); // Consider that 'this' is this set to the JustifiedGallery object, so it can 28125 } // access to fields such as $gallery, useful to trigger events with jQuery. 28126 }; 28127 28128 28129 /** 28130 * Justified Gallery plugin for jQuery 28131 * 28132 * Events 28133 * - jg.complete : called when all the gallery has been created 28134 * - jg.resize : called when the gallery has been resized 28135 * - jg.rowflush : when a new row appears 28136 * 28137 * @param arg the action (or the settings) passed when the plugin is called 28138 * @returns {*} the object itself 28139 */ 28140 $.fn.justifiedGallery = function (arg) { 28141 return this.each(function (index, gallery) { 28142 28143 var $gallery = $(gallery); 28144 $gallery.addClass('justified-gallery'); 28145 28146 var controller = $gallery.data('jg.controller'); 28147 if (typeof controller === 'undefined') { 28148 // Create controller and assign it to the object data 28149 if (typeof arg !== 'undefined' && arg !== null && $.type(arg) !== 'object') { 28150 if (arg === 'destroy') return; // Just a call to an unexisting object 28151 throw 'The argument must be an object'; 28152 } 28153 controller = new JustifiedGallery($gallery, $.extend({}, JustifiedGallery.prototype.defaults, arg)); 28154 $gallery.data('jg.controller', controller); 28155 } else if (arg === 'norewind') { 28156 // In this case we don't rewind: we analyze only the latest images (e.g. to complete the last unfinished row 28157 // ... left to be more readable 28158 } else if (arg === 'destroy') { 28159 controller.destroy(); 28160 return; 28161 } else { 28162 // In this case Justified Gallery has been called again changing only some options 28163 controller.updateSettings(arg); 28164 controller.rewind(); 28165 } 28166 28167 // Update the entries list 28168 if (!controller.updateEntries(arg === 'norewind')) return; 28169 28170 // Init justified gallery 28171 controller.init(); 28172 28173 }); 28174 }; 28175 28176})); 28177 28178/*! 28179* Customized version of iScroll.js 0.0.1 28180* It fixes bugs affecting its integration with fullpage.js 28181*/ 28182/*! iScroll v5.2.0 ~ (c) 2008-2016 Matteo Spinelli ~ http://cubiq.org/license */ 28183(function (window, document, Math) { 28184var rAF = window.requestAnimationFrame || 28185 window.webkitRequestAnimationFrame || 28186 window.mozRequestAnimationFrame || 28187 window.oRequestAnimationFrame || 28188 window.msRequestAnimationFrame || 28189 function (callback) { window.setTimeout(callback, 1000 / 60); }; 28190 28191var utils = (function () { 28192 var me = {}; 28193 28194 var _elementStyle = document.createElement('div').style; 28195 var _vendor = (function () { 28196 var vendors = ['t', 'webkitT', 'MozT', 'msT', 'OT'], 28197 transform, 28198 i = 0, 28199 l = vendors.length; 28200 28201 for ( ; i < l; i++ ) { 28202 transform = vendors[i] + 'ransform'; 28203 if ( transform in _elementStyle ) return vendors[i].substr(0, vendors[i].length-1); 28204 } 28205 28206 return false;
vendor: 5,154 bytes, lines 28207-28359
28207 })(); 28208 28209 function _prefixStyle (style) { 28210 if ( _vendor === false ) return false; 28211 if ( _vendor === '' ) return style; 28212 return _vendor + style.charAt(0).toUpperCase() + style.substr(1); 28213 } 28214 28215 me.getTime = Date.now || function getTime () { return new Date().getTime(); }; 28216 28217 me.extend = function (target, obj) { 28218 for ( var i in obj ) { 28219 target[i] = obj[i]; 28220 } 28221 }; 28222 28223 me.addEvent = function (el, type, fn, capture) { 28224 el.addEventListener(type, fn, !!capture); 28225 }; 28226 28227 me.removeEvent = function (el, type, fn, capture) { 28228 el.removeEventListener(type, fn, !!capture); 28229 }; 28230 28231 me.prefixPointerEvent = function (pointerEvent) { 28232 return window.MSPointerEvent ? 28233 'MSPointer' + pointerEvent.charAt(7).toUpperCase() + pointerEvent.substr(8): 28234 pointerEvent; 28235 }; 28236 28237 me.momentum = function (current, start, time, lowerMargin, wrapperSize, deceleration) { 28238 var distance = current - start, 28239 speed = Math.abs(distance) / time, 28240 destination, 28241 duration; 28242 28243 deceleration = deceleration === undefined ? 0.0006 : deceleration; 28244 28245 destination = current + ( speed * speed ) / ( 2 * deceleration ) * ( distance < 0 ? -1 : 1 ); 28246 duration = speed / deceleration; 28247 28248 if ( destination < lowerMargin ) { 28249 destination = wrapperSize ? lowerMargin - ( wrapperSize / 2.5 * ( speed / 8 ) ) : lowerMargin; 28250 distance = Math.abs(destination - current); 28251 duration = distance / speed; 28252 } else if ( destination > 0 ) { 28253 destination = wrapperSize ? wrapperSize / 2.5 * ( speed / 8 ) : 0; 28254 distance = Math.abs(current) + destination; 28255 duration = distance / speed; 28256 } 28257 28258 return { 28259 destination: Math.round(destination), 28260 duration: duration 28261 }; 28262 }; 28263 28264 var _transform = _prefixStyle('transform'); 28265 28266 me.extend(me, { 28267 hasTransform: _transform !== false, 28268 hasPerspective: _prefixStyle('perspective') in _elementStyle, 28269 hasTouch: 'ontouchstart' in window, 28270 hasPointer: !!(window.PointerEvent || window.MSPointerEvent), // IE10 is prefixed 28271 hasTransition: _prefixStyle('transition') in _elementStyle 28272 }); 28273 28274 /* 28275 This should find all Android browsers lower than build 535.19 (both stock browser and webview) 28276 - galaxy S2 is ok 28277 - 2.3.6 : `AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1` 28278 - 4.0.4 : `AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30` 28279 - galaxy S3 is badAndroid (stock brower, webview) 28280 `AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30` 28281 - galaxy S4 is badAndroid (stock brower, webview) 28282 `AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30` 28283 - galaxy S5 is OK 28284 `AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Mobile Safari/537.36 (Chrome/)` 28285 - galaxy S6 is OK 28286 `AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Mobile Safari/537.36 (Chrome/)` 28287 */ 28288 me.isBadAndroid = (function() { 28289 var appVersion = window.navigator.appVersion; 28290 // Android browser is not a chrome browser. 28291 if (/Android/.test(appVersion) && !(/Chrome\/\d/.test(appVersion))) { 28292 var safariVersion = appVersion.match(/Safari\/(\d+.\d)/); 28293 if(safariVersion && typeof safariVersion === "object" && safariVersion.length >= 2) { 28294 return parseFloat(safariVersion[1]) < 535.19; 28295 } else { 28296 return true; 28297 } 28298 } else { 28299 return false; 28300 } 28301 })(); 28302 28303 me.extend(me.style = {}, { 28304 transform: _transform, 28305 transitionTimingFunction: _prefixStyle('transitionTimingFunction'), 28306 transitionDuration: _prefixStyle('transitionDuration'), 28307 transitionDelay: _prefixStyle('transitionDelay'), 28308 transformOrigin: _prefixStyle('transformOrigin') 28309 }); 28310 28311 me.hasClass = function (e, c) { 28312 var re = new RegExp("(^|\\s)" + c + "(\\s|$)"); 28313 return re.test(e.className); 28314 }; 28315 28316 me.addClass = function (e, c) { 28317 if ( me.hasClass(e, c) ) { 28318 return; 28319 } 28320 28321 var newclass = e.className.split(' '); 28322 newclass.push(c); 28323 e.className = newclass.join(' '); 28324 }; 28325 28326 me.removeClass = function (e, c) { 28327 if ( !me.hasClass(e, c) ) { 28328 return; 28329 } 28330 28331 var re = new RegExp("(^|\\s)" + c + "(\\s|$)", 'g'); 28332 e.className = e.className.replace(re, ' '); 28333 }; 28334 28335 me.offset = function (el) { 28336 var left = -el.offsetLeft, 28337 top = -el.offsetTop; 28338 28339 // jshint -W084 28340 while (el = el.offsetParent) { 28341 left -= el.offsetLeft; 28342 top -= el.offsetTop; 28343 } 28344 // jshint +W084 28345 28346 return { 28347 left: left, 28348 top: top 28349 }; 28350 }; 28351 28352 me.preventDefaultException = function (el, exceptions) { 28353 for ( var i in exceptions ) { 28354 if ( exceptions[i].test(el[i]) ) { 28355 return true; 28356 } 28357 } 28358 28359 return false;
vendor: 5,660 bytes, lines 28360-28525
28360 }; 28361 28362 me.extend(me.eventType = {}, { 28363 touchstart: 1, 28364 touchmove: 1, 28365 touchend: 1, 28366 28367 mousedown: 2, 28368 mousemove: 2, 28369 mouseup: 2, 28370 28371 pointerdown: 3, 28372 pointermove: 3, 28373 pointerup: 3, 28374 28375 MSPointerDown: 3, 28376 MSPointerMove: 3, 28377 MSPointerUp: 3 28378 }); 28379 28380 me.extend(me.ease = {}, { 28381 quadratic: { 28382 style: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)', 28383 fn: function (k) { 28384 return k * ( 2 - k ); 28385 } 28386 }, 28387 circular: { 28388 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) 28389 fn: function (k) { 28390 return Math.sqrt( 1 - ( --k * k ) ); 28391 } 28392 }, 28393 back: { 28394 style: 'cubic-bezier(0.175, 0.885, 0.32, 1.275)', 28395 fn: function (k) { 28396 var b = 4; 28397 return ( k = k - 1 ) * k * ( ( b + 1 ) * k + b ) + 1; 28398 } 28399 }, 28400 bounce: { 28401 style: '', 28402 fn: function (k) { 28403 if ( ( k /= 1 ) < ( 1 / 2.75 ) ) { 28404 return 7.5625 * k * k; 28405 } else if ( k < ( 2 / 2.75 ) ) { 28406 return 7.5625 * ( k -= ( 1.5 / 2.75 ) ) * k + 0.75; 28407 } else if ( k < ( 2.5 / 2.75 ) ) { 28408 return 7.5625 * ( k -= ( 2.25 / 2.75 ) ) * k + 0.9375; 28409 } else { 28410 return 7.5625 * ( k -= ( 2.625 / 2.75 ) ) * k + 0.984375; 28411 } 28412 } 28413 }, 28414 elastic: { 28415 style: '', 28416 fn: function (k) { 28417 var f = 0.22, 28418 e = 0.4; 28419 28420 if ( k === 0 ) { return 0; } 28421 if ( k == 1 ) { return 1; } 28422 28423 return ( e * Math.pow( 2, - 10 * k ) * Math.sin( ( k - f / 4 ) * ( 2 * Math.PI ) / f ) + 1 ); 28424 } 28425 } 28426 }); 28427 28428 me.tap = function (e, eventName) { 28429 var ev = document.createEvent('Event'); 28430 ev.initEvent(eventName, true, true); 28431 ev.pageX = e.pageX; 28432 ev.pageY = e.pageY; 28433 e.target.dispatchEvent(ev); 28434 }; 28435 28436 me.click = function (e) { 28437 var target = e.target, 28438 ev; 28439 28440 if ( !(/(SELECT|INPUT|TEXTAREA)/i).test(target.tagName) ) { 28441 // https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/initMouseEvent 28442 // initMouseEvent is deprecated. 28443 ev = document.createEvent(window.MouseEvent ? 'MouseEvents' : 'Event'); 28444 ev.initEvent('click', true, true); 28445 ev.view = e.view || window; 28446 ev.detail = 1; 28447 ev.screenX = target.screenX || 0; 28448 ev.screenY = target.screenY || 0; 28449 ev.clientX = target.clientX || 0; 28450 ev.clientY = target.clientY || 0; 28451 ev.ctrlKey = !!e.ctrlKey; 28452 ev.altKey = !!e.altKey; 28453 ev.shiftKey = !!e.shiftKey; 28454 ev.metaKey = !!e.metaKey; 28455 ev.button = 0; 28456 ev.relatedTarget = null; 28457 ev._constructed = true; 28458 target.dispatchEvent(ev); 28459 } 28460 }; 28461 28462 return me; 28463})(); 28464function IScroll (el, options) { 28465 this.wrapper = typeof el == 'string' ? document.querySelector(el) : el; 28466 this.scroller = this.wrapper.children[0]; 28467 this.scrollerStyle = this.scroller.style; // cache style for better performance 28468 28469 this.options = { 28470 28471 resizeScrollbars: true, 28472 28473 mouseWheelSpeed: 20, 28474 28475 snapThreshold: 0.334, 28476 28477// INSERT POINT: OPTIONS 28478 disablePointer : !utils.hasPointer, 28479 disableTouch : utils.hasPointer || !utils.hasTouch, 28480 disableMouse : utils.hasPointer || utils.hasTouch, 28481 startX: 0, 28482 startY: 0, 28483 scrollY: true, 28484 directionLockThreshold: 5, 28485 momentum: true, 28486 28487 bounce: true, 28488 bounceTime: 600, 28489 bounceEasing: '', 28490 28491 preventDefault: true, 28492 preventDefaultException: { tagName: /^(INPUT|TEXTAREA|BUTTON|SELECT|LABEL)$/ }, 28493 28494 HWCompositing: true, 28495 useTransition: true, 28496 useTransform: true, 28497 bindToWrapper: typeof window.onmousedown === "undefined" 28498 }; 28499 28500 for ( var i in options ) { 28501 this.options[i] = options[i]; 28502 } 28503 28504 // Normalize options 28505 this.translateZ = this.options.HWCompositing && utils.hasPerspective ? ' translateZ(0)' : ''; 28506 28507 this.options.useTransition = utils.hasTransition && this.options.useTransition; 28508 this.options.useTransform = utils.hasTransform && this.options.useTransform; 28509 28510 this.options.eventPassthrough = this.options.eventPassthrough === true ? 'vertical' : this.options.eventPassthrough; 28511 this.options.preventDefault = !this.options.eventPassthrough && this.options.preventDefault; 28512 28513 // If you want eventPassthrough I have to lock one of the axes 28514 this.options.scrollY = this.options.eventPassthrough == 'vertical' ? false : this.options.scrollY; 28515 this.options.scrollX = this.options.eventPassthrough == 'horizontal' ? false : this.options.scrollX; 28516 28517 // With eventPassthrough we also need lockDirection mechanism 28518 this.options.freeScroll = this.options.freeScroll && !this.options.eventPassthrough; 28519 this.options.directionLockThreshold = this.options.eventPassthrough ? 0 : this.options.directionLockThreshold; 28520 28521 this.options.bounceEasing = typeof this.options.bounceEasing == 'string' ? utils.ease[this.options.bounceEasing] || utils.ease.circular : this.options.bounceEasing; 28522 28523 this.options.resizePolling = this.options.resizePolling === undefined ? 60 : this.options.resizePolling; 28524 28525 if ( this.options.tap === true ) {
vendor: 4,893 bytes, lines 28526-28697
28526 this.options.tap = 'tap'; 28527 } 28528 28529 // https://github.com/cubiq/iscroll/issues/1029 28530 if (!this.options.useTransition && !this.options.useTransform) { 28531 if(!(/relative|absolute/i).test(this.scrollerStyle.position)) { 28532 this.scrollerStyle.position = "relative"; 28533 } 28534 } 28535 28536 if ( this.options.shrinkScrollbars == 'scale' ) { 28537 this.options.useTransition = false; 28538 } 28539 28540 this.options.invertWheelDirection = this.options.invertWheelDirection ? -1 : 1; 28541 28542// INSERT POINT: NORMALIZATION 28543 28544 // Some defaults 28545 this.x = 0; 28546 this.y = 0; 28547 this.directionX = 0; 28548 this.directionY = 0; 28549 this._events = {}; 28550 28551// INSERT POINT: DEFAULTS 28552 28553 this._init(); 28554 this.refresh(); 28555 28556 this.scrollTo(this.options.startX, this.options.startY); 28557 this.enable(); 28558} 28559 28560IScroll.prototype = { 28561 version: '5.2.0', 28562 28563 _init: function () { 28564 this._initEvents(); 28565 28566 if ( this.options.scrollbars || this.options.indicators ) { 28567 this._initIndicators(); 28568 } 28569 28570 if ( this.options.mouseWheel ) { 28571 this._initWheel(); 28572 } 28573 28574 if ( this.options.snap ) { 28575 this._initSnap(); 28576 } 28577 28578 if ( this.options.keyBindings ) { 28579 this._initKeys(); 28580 } 28581 28582// INSERT POINT: _init 28583 28584 }, 28585 28586 destroy: function () { 28587 this._initEvents(true); 28588 clearTimeout(this.resizeTimeout); 28589 this.resizeTimeout = null; 28590 this._execEvent('destroy'); 28591 }, 28592 28593 _transitionEnd: function (e) { 28594 if ( e.target != this.scroller || !this.isInTransition ) { 28595 return; 28596 } 28597 28598 this._transitionTime(); 28599 if ( !this.resetPosition(this.options.bounceTime) ) { 28600 this.isInTransition = false; 28601 this._execEvent('scrollEnd'); 28602 } 28603 }, 28604 28605 _start: function (e) { 28606 // React to left mouse button only 28607 if ( utils.eventType[e.type] != 1 ) { 28608 // for button property 28609 // http://unixpapa.com/js/mouse.html 28610 var button; 28611 if (!e.which) { 28612 /* IE case */ 28613 button = (e.button < 2) ? 0 : 28614 ((e.button == 4) ? 1 : 2); 28615 } else { 28616 /* All others */ 28617 button = e.button; 28618 } 28619 if ( button !== 0 ) { 28620 return; 28621 } 28622 } 28623 28624 if ( !this.enabled || (this.initiated && utils.eventType[e.type] !== this.initiated) ) { 28625 return; 28626 } 28627 28628 if ( this.options.preventDefault && !utils.isBadAndroid && !utils.preventDefaultException(e.target, this.options.preventDefaultException) ) { 28629 e.preventDefault(); 28630 } 28631 28632 var point = e.touches ? e.touches[0] : e, 28633 pos; 28634 28635 this.initiated = utils.eventType[e.type]; 28636 this.moved = false; 28637 this.distX = 0; 28638 this.distY = 0; 28639 this.directionX = 0; 28640 this.directionY = 0; 28641 this.directionLocked = 0; 28642 28643 this.startTime = utils.getTime(); 28644 28645 if ( this.options.useTransition && this.isInTransition ) { 28646 this._transitionTime(); 28647 this.isInTransition = false; 28648 pos = this.getComputedPosition(); 28649 this._translate(Math.round(pos.x), Math.round(pos.y)); 28650 this._execEvent('scrollEnd'); 28651 } else if ( !this.options.useTransition && this.isAnimating ) { 28652 this.isAnimating = false; 28653 this._execEvent('scrollEnd'); 28654 } 28655 28656 this.startX = this.x; 28657 this.startY = this.y; 28658 this.absStartX = this.x; 28659 this.absStartY = this.y; 28660 this.pointX = point.pageX; 28661 this.pointY = point.pageY; 28662 28663 this._execEvent('beforeScrollStart'); 28664 }, 28665 28666 _move: function (e) { 28667 if ( !this.enabled || utils.eventType[e.type] !== this.initiated ) { 28668 return; 28669 } 28670 28671 if ( this.options.preventDefault ) { // increases performance on Android? TODO: check! 28672 e.preventDefault(); 28673 } 28674 28675 var point = e.touches ? e.touches[0] : e, 28676 deltaX = point.pageX - this.pointX, 28677 deltaY = point.pageY - this.pointY, 28678 timestamp = utils.getTime(), 28679 newX, newY, 28680 absDistX, absDistY; 28681 28682 this.pointX = point.pageX; 28683 this.pointY = point.pageY; 28684 28685 this.distX += deltaX; 28686 this.distY += deltaY; 28687 absDistX = Math.abs(this.distX); 28688 absDistY = Math.abs(this.distY); 28689 28690 // We need to move at least 10 pixels for the scrolling to initiate 28691 if ( timestamp - this.endTime > 300 && (absDistX < 10 && absDistY < 10) ) { 28692 return; 28693 } 28694 28695 // If you are scrolling in one direction lock the other 28696 if ( !this.directionLocked && !this.options.freeScroll ) { 28697 if ( absDistX > absDistY + this.options.directionLockThreshold ) {
vendor: 6,057 bytes, lines 28698-28884
28698 this.directionLocked = 'h'; // lock horizontally 28699 } else if ( absDistY >= absDistX + this.options.directionLockThreshold ) { 28700 this.directionLocked = 'v'; // lock vertically 28701 } else { 28702 this.directionLocked = 'n'; // no lock 28703 } 28704 } 28705 28706 if ( this.directionLocked == 'h' ) { 28707 if ( this.options.eventPassthrough == 'vertical' ) { 28708 e.preventDefault(); 28709 } else if ( this.options.eventPassthrough == 'horizontal' ) { 28710 this.initiated = false; 28711 return; 28712 } 28713 28714 deltaY = 0; 28715 } else if ( this.directionLocked == 'v' ) { 28716 if ( this.options.eventPassthrough == 'horizontal' ) { 28717 e.preventDefault(); 28718 } else if ( this.options.eventPassthrough == 'vertical' ) { 28719 this.initiated = false; 28720 return; 28721 } 28722 28723 deltaX = 0; 28724 } 28725 28726 deltaX = this.hasHorizontalScroll ? deltaX : 0; 28727 deltaY = this.hasVerticalScroll ? deltaY : 0; 28728 28729 newX = this.x + deltaX; 28730 newY = this.y + deltaY; 28731 28732 // Slow down if outside of the boundaries 28733 if ( newX > 0 || newX < this.maxScrollX ) { 28734 newX = this.options.bounce ? this.x + deltaX / 3 : newX > 0 ? 0 : this.maxScrollX; 28735 } 28736 if ( newY > 0 || newY < this.maxScrollY ) { 28737 newY = this.options.bounce ? this.y + deltaY / 3 : newY > 0 ? 0 : this.maxScrollY; 28738 } 28739 28740 this.directionX = deltaX > 0 ? -1 : deltaX < 0 ? 1 : 0; 28741 this.directionY = deltaY > 0 ? -1 : deltaY < 0 ? 1 : 0; 28742 28743 if ( !this.moved ) { 28744 this._execEvent('scrollStart'); 28745 } 28746 28747 this.moved = true; 28748 28749 this._translate(newX, newY); 28750 28751/* REPLACE START: _move */ 28752 28753 if ( timestamp - this.startTime > 300 ) { 28754 this.startTime = timestamp; 28755 this.startX = this.x; 28756 this.startY = this.y; 28757 } 28758 28759/* REPLACE END: _move */ 28760 28761 }, 28762 28763 _end: function (e) { 28764 if ( !this.enabled || utils.eventType[e.type] !== this.initiated ) { 28765 return; 28766 } 28767 28768 if ( this.options.preventDefault && !utils.preventDefaultException(e.target, this.options.preventDefaultException) ) { 28769 e.preventDefault(); 28770 } 28771 28772 var point = e.changedTouches ? e.changedTouches[0] : e, 28773 momentumX, 28774 momentumY, 28775 duration = utils.getTime() - this.startTime, 28776 newX = Math.round(this.x), 28777 newY = Math.round(this.y), 28778 distanceX = Math.abs(newX - this.startX), 28779 distanceY = Math.abs(newY - this.startY), 28780 time = 0, 28781 easing = ''; 28782 28783 this.isInTransition = 0; 28784 this.initiated = 0; 28785 this.endTime = utils.getTime(); 28786 28787 // reset if we are outside of the boundaries 28788 if ( this.resetPosition(this.options.bounceTime) ) { 28789 return; 28790 } 28791 28792 this.scrollTo(newX, newY); // ensures that the last position is rounded 28793 28794 // we scrolled less than 10 pixels 28795 if ( !this.moved ) { 28796 if ( this.options.tap ) { 28797 utils.tap(e, this.options.tap); 28798 } 28799 28800 if ( this.options.click ) { 28801 utils.click(e); 28802 } 28803 28804 this._execEvent('scrollCancel'); 28805 return; 28806 } 28807 28808 if ( this._events.flick && duration < 200 && distanceX < 100 && distanceY < 100 ) { 28809 this._execEvent('flick'); 28810 return; 28811 } 28812 28813 // start momentum animation if needed 28814 if ( this.options.momentum && duration < 300 ) { 28815 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 }; 28816 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 }; 28817 newX = momentumX.destination; 28818 newY = momentumY.destination; 28819 time = Math.max(momentumX.duration, momentumY.duration); 28820 this.isInTransition = 1; 28821 } 28822 28823 28824 if ( this.options.snap ) { 28825 var snap = this._nearestSnap(newX, newY); 28826 this.currentPage = snap; 28827 time = this.options.snapSpeed || Math.max( 28828 Math.max( 28829 Math.min(Math.abs(newX - snap.x), 1000), 28830 Math.min(Math.abs(newY - snap.y), 1000) 28831 ), 300); 28832 newX = snap.x; 28833 newY = snap.y; 28834 28835 this.directionX = 0; 28836 this.directionY = 0; 28837 easing = this.options.bounceEasing; 28838 } 28839 28840// INSERT POINT: _end 28841 28842 if ( newX != this.x || newY != this.y ) { 28843 // change easing function when scroller goes out of the boundaries 28844 if ( newX > 0 || newX < this.maxScrollX || newY > 0 || newY < this.maxScrollY ) { 28845 easing = utils.ease.quadratic; 28846 } 28847 28848 this.scrollTo(newX, newY, time, easing); 28849 return; 28850 } 28851 28852 this._execEvent('scrollEnd'); 28853 }, 28854 28855 _resize: function () { 28856 var that = this; 28857 28858 clearTimeout(this.resizeTimeout); 28859 28860 this.resizeTimeout = setTimeout(function () { 28861 that.refresh(); 28862 }, this.options.resizePolling); 28863 }, 28864 28865 resetPosition: function (time) { 28866 var x = this.x, 28867 y = this.y; 28868 28869 time = time || 0; 28870 28871 if ( !this.hasHorizontalScroll || this.x > 0 ) { 28872 x = 0; 28873 } else if ( this.x < this.maxScrollX ) { 28874 x = this.maxScrollX; 28875 } 28876 28877 if ( !this.hasVerticalScroll || this.y > 0 ) { 28878 y = 0; 28879 } else if ( this.y < this.maxScrollY ) { 28880 y = this.maxScrollY; 28881 } 28882 28883 if ( x == this.x && y == this.y ) { 28884 return false;
vendor: 5,509 bytes, lines 28885-29089
28885 } 28886 28887 this.scrollTo(x, y, time, this.options.bounceEasing); 28888 28889 return true; 28890 }, 28891 28892 disable: function () { 28893 this.enabled = false; 28894 }, 28895 28896 enable: function () { 28897 this.enabled = true; 28898 }, 28899 28900 refresh: function () { 28901 var rf = this.wrapper.offsetHeight; // Force reflow 28902 28903 this.wrapperWidth = this.wrapper.clientWidth; 28904 this.wrapperHeight = this.wrapper.clientHeight; 28905 28906/* REPLACE START: refresh */ 28907 28908 this.scrollerWidth = this.scroller.offsetWidth; 28909 this.scrollerHeight = this.scroller.offsetHeight; 28910 28911 this.maxScrollX = this.wrapperWidth - this.scrollerWidth; 28912 this.maxScrollY = this.wrapperHeight - this.scrollerHeight; 28913 28914/* REPLACE END: refresh */ 28915 28916 this.hasHorizontalScroll = this.options.scrollX && this.maxScrollX < 0; 28917 this.hasVerticalScroll = this.options.scrollY && this.maxScrollY < 0; 28918 28919 if ( !this.hasHorizontalScroll ) { 28920 this.maxScrollX = 0; 28921 this.scrollerWidth = this.wrapperWidth; 28922 } 28923 28924 if ( !this.hasVerticalScroll ) { 28925 this.maxScrollY = 0; 28926 this.scrollerHeight = this.wrapperHeight; 28927 } 28928 28929 this.endTime = 0; 28930 this.directionX = 0; 28931 this.directionY = 0; 28932 28933 this.wrapperOffset = utils.offset(this.wrapper); 28934 28935 this._execEvent('refresh'); 28936 28937 this.resetPosition(); 28938 28939// INSERT POINT: _refresh 28940 28941 }, 28942 28943 28944 on: function (type, fn) { 28945 if ( !this._events[type] ) { 28946 this._events[type] = []; 28947 } 28948 28949 this._events[type].push(fn); 28950 }, 28951 28952 off: function (type, fn) { 28953 if ( !this._events[type] ) { 28954 return; 28955 } 28956 28957 var index = this._events[type].indexOf(fn); 28958 28959 if ( index > -1 ) { 28960 this._events[type].splice(index, 1); 28961 } 28962 }, 28963 28964 _execEvent: function (type) { 28965 if ( !this._events[type] ) { 28966 return; 28967 } 28968 28969 var i = 0, 28970 l = this._events[type].length; 28971 28972 if ( !l ) { 28973 return; 28974 } 28975 28976 for ( ; i < l; i++ ) { 28977 this._events[type][i].apply(this, [].slice.call(arguments, 1)); 28978 } 28979 }, 28980 28981 scrollBy: function (x, y, time, easing) { 28982 x = this.x + x; 28983 y = this.y + y; 28984 time = time || 0; 28985 28986 this.scrollTo(x, y, time, easing); 28987 }, 28988 28989 scrollTo: function (x, y, time, easing) { 28990 easing = easing || utils.ease.circular; 28991 28992 this.isInTransition = this.options.useTransition && time > 0; 28993 var transitionType = this.options.useTransition && easing.style; 28994 if ( !time || transitionType ) { 28995 if(transitionType) { 28996 this._transitionTimingFunction(easing.style); 28997 this._transitionTime(time); 28998 } 28999 this._translate(x, y); 29000 } else { 29001 this._animate(x, y, time, easing.fn); 29002 } 29003 }, 29004 29005 scrollToElement: function (el, time, offsetX, offsetY, easing) { 29006 el = el.nodeType ? el : this.scroller.querySelector(el); 29007 29008 if ( !el ) { 29009 return; 29010 } 29011 29012 var pos = utils.offset(el); 29013 29014 pos.left -= this.wrapperOffset.left; 29015 pos.top -= this.wrapperOffset.top; 29016 29017 // if offsetX/Y are true we center the element to the screen 29018 if ( offsetX === true ) { 29019 offsetX = Math.round(el.offsetWidth / 2 - this.wrapper.offsetWidth / 2); 29020 } 29021 if ( offsetY === true ) { 29022 offsetY = Math.round(el.offsetHeight / 2 - this.wrapper.offsetHeight / 2); 29023 } 29024 29025 pos.left -= offsetX || 0; 29026 pos.top -= offsetY || 0; 29027 29028 pos.left = pos.left > 0 ? 0 : pos.left < this.maxScrollX ? this.maxScrollX : pos.left; 29029 pos.top = pos.top > 0 ? 0 : pos.top < this.maxScrollY ? this.maxScrollY : pos.top; 29030 29031 time = time === undefined || time === null || time === 'auto' ? Math.max(Math.abs(this.x-pos.left), Math.abs(this.y-pos.top)) : time; 29032 29033 this.scrollTo(pos.left, pos.top, time, easing); 29034 }, 29035 29036 _transitionTime: function (time) { 29037 if (!this.options.useTransition) { 29038 return; 29039 } 29040 time = time || 0; 29041 var durationProp = utils.style.transitionDuration; 29042 if(!durationProp) { 29043 return; 29044 } 29045 29046 this.scrollerStyle[durationProp] = time + 'ms'; 29047 29048 if ( !time && utils.isBadAndroid ) { 29049 this.scrollerStyle[durationProp] = '0.0001ms'; 29050 // remove 0.0001ms 29051 var self = this; 29052 rAF(function() { 29053 if(self.scrollerStyle[durationProp] === '0.0001ms') { 29054 self.scrollerStyle[durationProp] = '0s'; 29055 } 29056 }); 29057 } 29058 29059 29060 if ( this.indicators ) { 29061 for ( var i = this.indicators.length; i--; ) { 29062 this.indicators[i].transitionTime(time); 29063 } 29064 } 29065 29066 29067// INSERT POINT: _transitionTime 29068 29069 }, 29070 29071 _transitionTimingFunction: function (easing) { 29072 this.scrollerStyle[utils.style.transitionTimingFunction] = easing; 29073 29074 29075 if ( this.indicators ) { 29076 for ( var i = this.indicators.length; i--; ) { 29077 this.indicators[i].transitionTimingFunction(easing); 29078 } 29079 } 29080 29081 29082// INSERT POINT: _transitionTimingFunction 29083 29084 }, 29085 29086 _translate: function (x, y) { 29087 //Uncode addition 29088 if ( (" " + this.wrapper.className + " ").replace(/[\n\t]/g, " ").indexOf(" no-scrolloverflow ") > -1 ) 29089 return false;
vendor: 9,939 bytes, lines 29090-29401
29090 29091 if ( this.options.useTransform ) { 29092 29093/* REPLACE START: _translate */ 29094 29095 this.scrollerStyle[utils.style.transform] = 'translate(' + x + 'px,' + y + 'px)' + this.translateZ; 29096 29097/* REPLACE END: _translate */ 29098 29099 } else { 29100 x = Math.round(x); 29101 y = Math.round(y); 29102 this.scrollerStyle.left = x + 'px'; 29103 this.scrollerStyle.top = y + 'px'; 29104 } 29105 29106 this.x = x; 29107 this.y = y; 29108 29109 29110 if ( this.indicators ) { 29111 for ( var i = this.indicators.length; i--; ) { 29112 this.indicators[i].updatePosition(); 29113 } 29114 } 29115 29116 //Uncode addition 29117 var uncodevent = new CustomEvent('fp-slide-scroll'); 29118 window.dispatchEvent(uncodevent); 29119 29120// INSERT POINT: _translate 29121 29122 }, 29123 29124 _initEvents: function (remove) { 29125 var eventType = remove ? utils.removeEvent : utils.addEvent, 29126 target = this.options.bindToWrapper ? this.wrapper : window; 29127 29128 eventType(window, 'orientationchange', this); 29129 eventType(window, 'resize', this); 29130 29131 if ( this.options.click ) { 29132 eventType(this.wrapper, 'click', this, true); 29133 } 29134 29135 if ( !this.options.disableMouse ) { 29136 eventType(this.wrapper, 'mousedown', this); 29137 eventType(target, 'mousemove', this); 29138 eventType(target, 'mousecancel', this); 29139 eventType(target, 'mouseup', this); 29140 } 29141 29142 if ( utils.hasPointer && !this.options.disablePointer ) { 29143 eventType(this.wrapper, utils.prefixPointerEvent('pointerdown'), this); 29144 eventType(target, utils.prefixPointerEvent('pointermove'), this); 29145 eventType(target, utils.prefixPointerEvent('pointercancel'), this); 29146 eventType(target, utils.prefixPointerEvent('pointerup'), this); 29147 } 29148 29149 if ( utils.hasTouch && !this.options.disableTouch ) { 29150 eventType(this.wrapper, 'touchstart', this); 29151 eventType(target, 'touchmove', this); 29152 eventType(target, 'touchcancel', this); 29153 eventType(target, 'touchend', this); 29154 } 29155 29156 eventType(this.scroller, 'transitionend', this); 29157 eventType(this.scroller, 'webkitTransitionEnd', this); 29158 eventType(this.scroller, 'oTransitionEnd', this); 29159 eventType(this.scroller, 'MSTransitionEnd', this); 29160 }, 29161 29162 getComputedPosition: function () { 29163 var matrix = window.getComputedStyle(this.scroller, null), 29164 x, y; 29165 29166 if ( this.options.useTransform ) { 29167 matrix = matrix[utils.style.transform].split(')')[0].split(', '); 29168 x = +(matrix[12] || matrix[4]); 29169 y = +(matrix[13] || matrix[5]); 29170 } else { 29171 x = +matrix.left.replace(/[^-\d.]/g, ''); 29172 y = +matrix.top.replace(/[^-\d.]/g, ''); 29173 } 29174 29175 return { x: x, y: y }; 29176 }, 29177 _initIndicators: function () { 29178 var interactive = this.options.interactiveScrollbars, 29179 customStyle = typeof this.options.scrollbars != 'string', 29180 indicators = [], 29181 indicator; 29182 29183 var that = this; 29184 29185 this.indicators = []; 29186 29187 if ( this.options.scrollbars ) { 29188 // Vertical scrollbar 29189 if ( this.options.scrollY ) { 29190 indicator = { 29191 el: createDefaultScrollbar('v', interactive, this.options.scrollbars), 29192 interactive: interactive, 29193 defaultScrollbars: true, 29194 customStyle: customStyle, 29195 resize: this.options.resizeScrollbars, 29196 shrink: this.options.shrinkScrollbars, 29197 fade: this.options.fadeScrollbars, 29198 listenX: false 29199 }; 29200 29201 this.wrapper.appendChild(indicator.el); 29202 indicators.push(indicator); 29203 } 29204 29205 // Horizontal scrollbar 29206 if ( this.options.scrollX ) { 29207 indicator = { 29208 el: createDefaultScrollbar('h', interactive, this.options.scrollbars), 29209 interactive: interactive, 29210 defaultScrollbars: true, 29211 customStyle: customStyle, 29212 resize: this.options.resizeScrollbars, 29213 shrink: this.options.shrinkScrollbars, 29214 fade: this.options.fadeScrollbars, 29215 listenY: false 29216 }; 29217 29218 this.wrapper.appendChild(indicator.el); 29219 indicators.push(indicator); 29220 } 29221 } 29222 29223 if ( this.options.indicators ) { 29224 // TODO: check concat compatibility 29225 indicators = indicators.concat(this.options.indicators); 29226 } 29227 29228 for ( var i = indicators.length; i--; ) { 29229 this.indicators.push( new Indicator(this, indicators[i]) ); 29230 } 29231 29232 // TODO: check if we can use array.map (wide compatibility and performance issues) 29233 function _indicatorsMap (fn) { 29234 if (that.indicators) { 29235 for ( var i = that.indicators.length; i--; ) { 29236 fn.call(that.indicators[i]); 29237 } 29238 } 29239 } 29240 29241 if ( this.options.fadeScrollbars ) { 29242 this.on('scrollEnd', function () { 29243 _indicatorsMap(function () { 29244 this.fade(); 29245 }); 29246 }); 29247 29248 this.on('scrollCancel', function () { 29249 _indicatorsMap(function () { 29250 this.fade(); 29251 }); 29252 }); 29253 29254 this.on('scrollStart', function () { 29255 _indicatorsMap(function () { 29256 this.fade(1); 29257 }); 29258 }); 29259 29260 this.on('beforeScrollStart', function () { 29261 _indicatorsMap(function () { 29262 this.fade(1, true); 29263 }); 29264 }); 29265 } 29266 29267 29268 this.on('refresh', function () { 29269 _indicatorsMap(function () { 29270 this.refresh(); 29271 }); 29272 }); 29273 29274 this.on('destroy', function () { 29275 _indicatorsMap(function () { 29276 this.destroy(); 29277 }); 29278 29279 delete this.indicators; 29280 }); 29281 }, 29282 29283 _initWheel: function () { 29284 utils.addEvent(this.wrapper, 'wheel', this); 29285 utils.addEvent(this.wrapper, 'mousewheel', this); 29286 utils.addEvent(this.wrapper, 'DOMMouseScroll', this); 29287 29288 this.on('destroy', function () { 29289 clearTimeout(this.wheelTimeout); 29290 this.wheelTimeout = null; 29291 utils.removeEvent(this.wrapper, 'wheel', this); 29292 utils.removeEvent(this.wrapper, 'mousewheel', this); 29293 utils.removeEvent(this.wrapper, 'DOMMouseScroll', this); 29294 }); 29295 }, 29296 29297 _wheel: function (e) { 29298 if ( !this.enabled ) { 29299 return; 29300 } 29301 29302 var wheelDeltaX, wheelDeltaY, 29303 newX, newY, 29304 that = this; 29305 29306 if ( this.wheelTimeout === undefined ) { 29307 that._execEvent('scrollStart'); 29308 } 29309 29310 // Execute the scrollEnd event after 400ms the wheel stopped scrolling 29311 clearTimeout(this.wheelTimeout); 29312 this.wheelTimeout = setTimeout(function () { 29313 if(!that.options.snap) { 29314 that._execEvent('scrollEnd'); 29315 } 29316 that.wheelTimeout = undefined; 29317 }, 400); 29318 29319 if ( 'deltaX' in e ) { 29320 if (e.deltaMode === 1) { 29321 wheelDeltaX = -e.deltaX * this.options.mouseWheelSpeed; 29322 wheelDeltaY = -e.deltaY * this.options.mouseWheelSpeed; 29323 } else { 29324 wheelDeltaX = -e.deltaX; 29325 wheelDeltaY = -e.deltaY; 29326 } 29327 } else if ( 'wheelDeltaX' in e ) { 29328 wheelDeltaX = e.wheelDeltaX / 120 * this.options.mouseWheelSpeed; 29329 wheelDeltaY = e.wheelDeltaY / 120 * this.options.mouseWheelSpeed; 29330 } else if ( 'wheelDelta' in e ) { 29331 wheelDeltaX = wheelDeltaY = e.wheelDelta / 120 * this.options.mouseWheelSpeed; 29332 } else if ( 'detail' in e ) { 29333 wheelDeltaX = wheelDeltaY = -e.detail / 3 * this.options.mouseWheelSpeed; 29334 } else { 29335 return; 29336 } 29337 29338 wheelDeltaX *= this.options.invertWheelDirection; 29339 wheelDeltaY *= this.options.invertWheelDirection; 29340 29341 if ( !this.hasVerticalScroll ) { 29342 wheelDeltaX = wheelDeltaY; 29343 wheelDeltaY = 0; 29344 } 29345 29346 if ( this.options.snap ) { 29347 newX = this.currentPage.pageX; 29348 newY = this.currentPage.pageY; 29349 29350 if ( wheelDeltaX > 0 ) { 29351 newX--; 29352 } else if ( wheelDeltaX < 0 ) { 29353 newX++; 29354 } 29355 29356 if ( wheelDeltaY > 0 ) { 29357 newY--; 29358 } else if ( wheelDeltaY < 0 ) { 29359 newY++; 29360 } 29361 29362 this.goToPage(newX, newY); 29363 29364 return; 29365 } 29366 29367 newX = this.x + Math.round(this.hasHorizontalScroll ? wheelDeltaX : 0); 29368 newY = this.y + Math.round(this.hasVerticalScroll ? wheelDeltaY : 0); 29369 29370 this.directionX = wheelDeltaX > 0 ? -1 : wheelDeltaX < 0 ? 1 : 0; 29371 this.directionY = wheelDeltaY > 0 ? -1 : wheelDeltaY < 0 ? 1 : 0; 29372 29373 if ( newX > 0 ) { 29374 newX = 0; 29375 } else if ( newX < this.maxScrollX ) { 29376 newX = this.maxScrollX; 29377 } 29378 29379 if ( newY > 0 ) { 29380 newY = 0; 29381 } else if ( newY < this.maxScrollY ) { 29382 newY = this.maxScrollY; 29383 } 29384 29385 this.scrollTo(newX, newY, 0); 29386 29387// INSERT POINT: _wheel 29388 }, 29389 29390 _initSnap: function () { 29391 this.currentPage = {}; 29392 29393 if ( typeof this.options.snap == 'string' ) { 29394 this.options.snap = this.scroller.querySelectorAll(this.options.snap); 29395 } 29396 29397 this.on('refresh', function () { 29398 var i = 0, l, 29399 m = 0, n, 29400 cx, cy, 29401 x = 0, y,
vendor: 7,339 bytes, lines 29402-29655
29402 stepX = this.options.snapStepX || this.wrapperWidth, 29403 stepY = this.options.snapStepY || this.wrapperHeight, 29404 el; 29405 29406 this.pages = []; 29407 29408 if ( !this.wrapperWidth || !this.wrapperHeight || !this.scrollerWidth || !this.scrollerHeight ) { 29409 return; 29410 } 29411 29412 if ( this.options.snap === true ) { 29413 cx = Math.round( stepX / 2 ); 29414 cy = Math.round( stepY / 2 ); 29415 29416 while ( x > -this.scrollerWidth ) { 29417 this.pages[i] = []; 29418 l = 0; 29419 y = 0; 29420 29421 while ( y > -this.scrollerHeight ) { 29422 this.pages[i][l] = { 29423 x: Math.max(x, this.maxScrollX), 29424 y: Math.max(y, this.maxScrollY), 29425 width: stepX, 29426 height: stepY, 29427 cx: x - cx, 29428 cy: y - cy 29429 }; 29430 29431 y -= stepY; 29432 l++; 29433 } 29434 29435 x -= stepX; 29436 i++; 29437 } 29438 } else { 29439 el = this.options.snap; 29440 l = el.length; 29441 n = -1; 29442 29443 for ( ; i < l; i++ ) { 29444 if ( i === 0 || el[i].offsetLeft <= el[i-1].offsetLeft ) { 29445 m = 0; 29446 n++; 29447 } 29448 29449 if ( !this.pages[m] ) { 29450 this.pages[m] = []; 29451 } 29452 29453 x = Math.max(-el[i].offsetLeft, this.maxScrollX); 29454 y = Math.max(-el[i].offsetTop, this.maxScrollY); 29455 cx = x - Math.round(el[i].offsetWidth / 2); 29456 cy = y - Math.round(el[i].offsetHeight / 2); 29457 29458 this.pages[m][n] = { 29459 x: x, 29460 y: y, 29461 width: el[i].offsetWidth, 29462 height: el[i].offsetHeight, 29463 cx: cx, 29464 cy: cy 29465 }; 29466 29467 if ( x > this.maxScrollX ) { 29468 m++; 29469 } 29470 } 29471 } 29472 29473 this.goToPage(this.currentPage.pageX || 0, this.currentPage.pageY || 0, 0); 29474 29475 // Update snap threshold if needed 29476 if ( this.options.snapThreshold % 1 === 0 ) { 29477 this.snapThresholdX = this.options.snapThreshold; 29478 this.snapThresholdY = this.options.snapThreshold; 29479 } else { 29480 this.snapThresholdX = Math.round(this.pages[this.currentPage.pageX][this.currentPage.pageY].width * this.options.snapThreshold); 29481 this.snapThresholdY = Math.round(this.pages[this.currentPage.pageX][this.currentPage.pageY].height * this.options.snapThreshold); 29482 } 29483 }); 29484 29485 this.on('flick', function () { 29486 var time = this.options.snapSpeed || Math.max( 29487 Math.max( 29488 Math.min(Math.abs(this.x - this.startX), 1000), 29489 Math.min(Math.abs(this.y - this.startY), 1000) 29490 ), 300); 29491 29492 this.goToPage( 29493 this.currentPage.pageX + this.directionX, 29494 this.currentPage.pageY + this.directionY, 29495 time 29496 ); 29497 }); 29498 }, 29499 29500 _nearestSnap: function (x, y) { 29501 if ( !this.pages.length ) { 29502 return { x: 0, y: 0, pageX: 0, pageY: 0 }; 29503 } 29504 29505 var i = 0, 29506 l = this.pages.length, 29507 m = 0; 29508 29509 // Check if we exceeded the snap threshold 29510 if ( Math.abs(x - this.absStartX) < this.snapThresholdX && 29511 Math.abs(y - this.absStartY) < this.snapThresholdY ) { 29512 return this.currentPage; 29513 } 29514 29515 if ( x > 0 ) { 29516 x = 0; 29517 } else if ( x < this.maxScrollX ) { 29518 x = this.maxScrollX; 29519 } 29520 29521 if ( y > 0 ) { 29522 y = 0; 29523 } else if ( y < this.maxScrollY ) { 29524 y = this.maxScrollY; 29525 } 29526 29527 for ( ; i < l; i++ ) { 29528 if ( x >= this.pages[i][0].cx ) { 29529 x = this.pages[i][0].x; 29530 break; 29531 } 29532 } 29533 29534 l = this.pages[i].length; 29535 29536 for ( ; m < l; m++ ) { 29537 if ( y >= this.pages[0][m].cy ) { 29538 y = this.pages[0][m].y; 29539 break; 29540 } 29541 } 29542 29543 if ( i == this.currentPage.pageX ) { 29544 i += this.directionX; 29545 29546 if ( i < 0 ) { 29547 i = 0; 29548 } else if ( i >= this.pages.length ) { 29549 i = this.pages.length - 1; 29550 } 29551 29552 x = this.pages[i][0].x; 29553 } 29554 29555 if ( m == this.currentPage.pageY ) { 29556 m += this.directionY; 29557 29558 if ( m < 0 ) { 29559 m = 0; 29560 } else if ( m >= this.pages[0].length ) { 29561 m = this.pages[0].length - 1; 29562 } 29563 29564 y = this.pages[0][m].y; 29565 } 29566 29567 return { 29568 x: x, 29569 y: y, 29570 pageX: i, 29571 pageY: m 29572 }; 29573 }, 29574 29575 goToPage: function (x, y, time, easing) { 29576 easing = easing || this.options.bounceEasing; 29577 29578 if ( x >= this.pages.length ) { 29579 x = this.pages.length - 1; 29580 } else if ( x < 0 ) { 29581 x = 0; 29582 } 29583 29584 if ( y >= this.pages[x].length ) { 29585 y = this.pages[x].length - 1; 29586 } else if ( y < 0 ) { 29587 y = 0; 29588 } 29589 29590 var posX = this.pages[x][y].x, 29591 posY = this.pages[x][y].y; 29592 29593 time = time === undefined ? this.options.snapSpeed || Math.max( 29594 Math.max( 29595 Math.min(Math.abs(posX - this.x), 1000), 29596 Math.min(Math.abs(posY - this.y), 1000) 29597 ), 300) : time; 29598 29599 this.currentPage = { 29600 x: posX, 29601 y: posY, 29602 pageX: x, 29603 pageY: y 29604 }; 29605 29606 this.scrollTo(posX, posY, time, easing); 29607 }, 29608 29609 next: function (time, easing) { 29610 var x = this.currentPage.pageX, 29611 y = this.currentPage.pageY; 29612 29613 x++; 29614 29615 if ( x >= this.pages.length && this.hasVerticalScroll ) { 29616 x = 0; 29617 y++; 29618 } 29619 29620 this.goToPage(x, y, time, easing); 29621 }, 29622 29623 prev: function (time, easing) { 29624 var x = this.currentPage.pageX, 29625 y = this.currentPage.pageY; 29626 29627 x--; 29628 29629 if ( x < 0 && this.hasVerticalScroll ) { 29630 x = 0; 29631 y--; 29632 } 29633 29634 this.goToPage(x, y, time, easing); 29635 }, 29636 29637 _initKeys: function (e) { 29638 // default key bindings 29639 var keys = { 29640 pageUp: 33, 29641 pageDown: 34, 29642 end: 35, 29643 home: 36, 29644 left: 37, 29645 up: 38, 29646 right: 39, 29647 down: 40 29648 }; 29649 var i; 29650 29651 // if you give me characters I give you keycode 29652 if ( typeof this.options.keyBindings == 'object' ) { 29653 for ( i in this.options.keyBindings ) { 29654 if ( typeof this.options.keyBindings[i] == 'string' ) { 29655 this.options.keyBindings[i] = this.options.keyBindings[i].toUpperCase().charCo
vendor: 11,097 bytes, lines 29655-30008
29655deAt(0); 29656 } 29657 } 29658 } else { 29659 this.options.keyBindings = {}; 29660 } 29661 29662 for ( i in keys ) { 29663 this.options.keyBindings[i] = this.options.keyBindings[i] || keys[i]; 29664 } 29665 29666 utils.addEvent(window, 'keydown', this); 29667 29668 this.on('destroy', function () { 29669 utils.removeEvent(window, 'keydown', this); 29670 }); 29671 }, 29672 29673 _key: function (e) { 29674 if ( !this.enabled ) { 29675 return; 29676 } 29677 29678 var snap = this.options.snap, // we are using this alot, better to cache it 29679 newX = snap ? this.currentPage.pageX : this.x, 29680 newY = snap ? this.currentPage.pageY : this.y, 29681 now = utils.getTime(), 29682 prevTime = this.keyTime || 0, 29683 acceleration = 0.250, 29684 pos; 29685 29686 if ( this.options.useTransition && this.isInTransition ) { 29687 pos = this.getComputedPosition(); 29688 29689 this._translate(Math.round(pos.x), Math.round(pos.y)); 29690 this.isInTransition = false; 29691 } 29692 29693 this.keyAcceleration = now - prevTime < 200 ? Math.min(this.keyAcceleration + acceleration, 50) : 0; 29694 29695 switch ( e.keyCode ) { 29696 case this.options.keyBindings.pageUp: 29697 if ( this.hasHorizontalScroll && !this.hasVerticalScroll ) { 29698 newX += snap ? 1 : this.wrapperWidth; 29699 } else { 29700 newY += snap ? 1 : this.wrapperHeight; 29701 } 29702 break; 29703 case this.options.keyBindings.pageDown: 29704 if ( this.hasHorizontalScroll && !this.hasVerticalScroll ) { 29705 newX -= snap ? 1 : this.wrapperWidth; 29706 } else { 29707 newY -= snap ? 1 : this.wrapperHeight; 29708 } 29709 break; 29710 case this.options.keyBindings.end: 29711 newX = snap ? this.pages.length-1 : this.maxScrollX; 29712 newY = snap ? this.pages[0].length-1 : this.maxScrollY; 29713 break; 29714 case this.options.keyBindings.home: 29715 newX = 0; 29716 newY = 0; 29717 break; 29718 case this.options.keyBindings.left: 29719 newX += snap ? -1 : 5 + this.keyAcceleration>>0; 29720 break; 29721 case this.options.keyBindings.up: 29722 newY += snap ? 1 : 5 + this.keyAcceleration>>0; 29723 break; 29724 case this.options.keyBindings.right: 29725 newX -= snap ? -1 : 5 + this.keyAcceleration>>0; 29726 break; 29727 case this.options.keyBindings.down: 29728 newY -= snap ? 1 : 5 + this.keyAcceleration>>0; 29729 break; 29730 default: 29731 return; 29732 } 29733 29734 if ( snap ) { 29735 this.goToPage(newX, newY); 29736 return; 29737 } 29738 29739 if ( newX > 0 ) { 29740 newX = 0; 29741 this.keyAcceleration = 0; 29742 } else if ( newX < this.maxScrollX ) { 29743 newX = this.maxScrollX; 29744 this.keyAcceleration = 0; 29745 } 29746 29747 if ( newY > 0 ) { 29748 newY = 0; 29749 this.keyAcceleration = 0; 29750 } else if ( newY < this.maxScrollY ) { 29751 newY = this.maxScrollY; 29752 this.keyAcceleration = 0; 29753 } 29754 29755 this.scrollTo(newX, newY, 0); 29756 29757 this.keyTime = now; 29758 }, 29759 29760 _animate: function (destX, destY, duration, easingFn) { 29761 var that = this, 29762 startX = this.x, 29763 startY = this.y, 29764 startTime = utils.getTime(), 29765 destTime = startTime + duration; 29766 29767 function step () { 29768 var now = utils.getTime(), 29769 newX, newY, 29770 easing; 29771 29772 if ( now >= destTime ) { 29773 that.isAnimating = false; 29774 that._translate(destX, destY); 29775 29776 if ( !that.resetPosition(that.options.bounceTime) ) { 29777 that._execEvent('scrollEnd'); 29778 } 29779 29780 return; 29781 } 29782 29783 now = ( now - startTime ) / duration; 29784 easing = easingFn(now); 29785 newX = ( destX - startX ) * easing + startX; 29786 newY = ( destY - startY ) * easing + startY; 29787 that._translate(newX, newY); 29788 29789 if ( that.isAnimating ) { 29790 rAF(step); 29791 } 29792 } 29793 29794 this.isAnimating = true; 29795 step(); 29796 }, 29797 handleEvent: function (e) { 29798 switch ( e.type ) { 29799 case 'touchstart': 29800 case 'pointerdown': 29801 case 'MSPointerDown': 29802 case 'mousedown': 29803 this._start(e); 29804 break; 29805 case 'touchmove': 29806 case 'pointermove': 29807 case 'MSPointerMove': 29808 case 'mousemove': 29809 this._move(e); 29810 break; 29811 case 'touchend': 29812 case 'pointerup': 29813 case 'MSPointerUp': 29814 case 'mouseup': 29815 case 'touchcancel': 29816 case 'pointercancel': 29817 case 'MSPointerCancel': 29818 case 'mousecancel': 29819 this._end(e); 29820 break; 29821 case 'orientationchange': 29822 case 'resize': 29823 this._resize(); 29824 break; 29825 case 'transitionend': 29826 case 'webkitTransitionEnd': 29827 case 'oTransitionEnd': 29828 case 'MSTransitionEnd': 29829 this._transitionEnd(e); 29830 break; 29831 case 'wheel': 29832 case 'DOMMouseScroll': 29833 case 'mousewheel': 29834 this._wheel(e); 29835 break; 29836 case 'keydown': 29837 this._key(e); 29838 break; 29839 case 'click': 29840 if ( this.enabled && !e._constructed ) { 29841 e.preventDefault(); 29842 e.stopPropagation(); 29843 } 29844 break; 29845 } 29846 } 29847}; 29848function createDefaultScrollbar (direction, interactive, type) { 29849 var scrollbar = document.createElement('div'), 29850 indicator = document.createElement('div'); 29851 29852 if ( type === true ) { 29853 scrollbar.style.cssText = 'position:absolute;z-index:9999'; 29854 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'; 29855 } 29856 29857 indicator.className = 'iScrollIndicator'; 29858 29859 if ( direction == 'h' ) { 29860 if ( type === true ) { 29861 scrollbar.style.cssText += ';height:7px;left:2px;right:2px;bottom:0'; 29862 indicator.style.height = '100%'; 29863 } 29864 scrollbar.className = 'iScrollHorizontalScrollbar'; 29865 } else { 29866 if ( type === true ) { 29867 scrollbar.style.cssText += ';width:7px;bottom:2px;top:2px;right:1px'; 29868 indicator.style.width = '100%'; 29869 } 29870 scrollbar.className = 'iScrollVerticalScrollbar'; 29871 } 29872 29873 scrollbar.style.cssText += ';overflow:hidden'; 29874 29875 if ( !interactive ) { 29876 scrollbar.style.pointerEvents = 'none'; 29877 } 29878 29879 scrollbar.appendChild(indicator); 29880 29881 return scrollbar; 29882} 29883 29884function Indicator (scroller, options) { 29885 this.wrapper = typeof options.el == 'string' ? document.querySelector(options.el) : options.el; 29886 this.wrapperStyle = this.wrapper.style; 29887 this.indicator = this.wrapper.children[0]; 29888 this.indicatorStyle = this.indicator.style; 29889 this.scroller = scroller; 29890 29891 this.options = { 29892 listenX: true, 29893 listenY: true, 29894 interactive: false, 29895 resize: true, 29896 defaultScrollbars: false, 29897 shrink: false, 29898 fade: false, 29899 speedRatioX: 0, 29900 speedRatioY: 0 29901 }; 29902 29903 for ( var i in options ) { 29904 this.options[i] = options[i]; 29905 } 29906 29907 this.sizeRatioX = 1; 29908 this.sizeRatioY = 1; 29909 this.maxPosX = 0; 29910 this.maxPosY = 0; 29911 29912 if ( this.options.interactive ) { 29913 if ( !this.options.disableTouch ) { 29914 utils.addEvent(this.indicator, 'touchstart', this); 29915 utils.addEvent(window, 'touchend', this); 29916 } 29917 if ( !this.options.disablePointer ) { 29918 utils.addEvent(this.indicator, utils.prefixPointerEvent('pointerdown'), this); 29919 utils.addEvent(window, utils.prefixPointerEvent('pointerup'), this); 29920 } 29921 if ( !this.options.disableMouse ) { 29922 utils.addEvent(this.indicator, 'mousedown', this); 29923 utils.addEvent(window, 'mouseup', this); 29924 } 29925 } 29926 29927 if ( this.options.fade ) { 29928 this.wrapperStyle[utils.style.transform] = this.scroller.translateZ; 29929 var durationProp = utils.style.transitionDuration; 29930 if(!durationProp) { 29931 return; 29932 } 29933 this.wrapperStyle[durationProp] = utils.isBadAndroid ? '0.0001ms' : '0ms'; 29934 // remove 0.0001ms 29935 var self = this; 29936 if(utils.isBadAndroid) { 29937 rAF(function() { 29938 if(self.wrapperStyle[durationProp] === '0.0001ms') { 29939 self.wrapperStyle[durationProp] = '0s'; 29940 } 29941 }); 29942 } 29943 this.wrapperStyle.opacity = '0'; 29944 } 29945} 29946 29947Indicator.prototype = { 29948 handleEvent: function (e) { 29949 switch ( e.type ) { 29950 case 'touchstart': 29951 case 'pointerdown': 29952 case 'MSPointerDown': 29953 case 'mousedown': 29954 this._start(e); 29955 break; 29956 case 'touchmove': 29957 case 'pointermove': 29958 case 'MSPointerMove': 29959 case 'mousemove': 29960 this._move(e); 29961 break; 29962 case 'touchend': 29963 case 'pointerup': 29964 case 'MSPointerUp': 29965 case 'mouseup': 29966 case 'touchcancel': 29967 case 'pointercancel': 29968 case 'MSPointerCancel': 29969 case 'mousecancel': 29970 this._end(e); 29971 break; 29972 } 29973 }, 29974 29975 destroy: function () { 29976 if ( this.options.fadeScrollbars ) { 29977 clearTimeout(this.fadeTimeout); 29978 this.fadeTimeout = null; 29979 } 29980 if ( this.options.interactive ) { 29981 utils.removeEvent(this.indicator, 'touchstart', this); 29982 utils.removeEvent(this.indicator, utils.prefixPointerEvent('pointerdown'), this); 29983 utils.removeEvent(this.indicator, 'mousedown', this); 29984 29985 utils.removeEvent(window, 'touchmove', this); 29986 utils.removeEvent(window, utils.prefixPointerEvent('pointermove'), this); 29987 utils.removeEvent(window, 'mousemove', this); 29988 29989 utils.removeEvent(window, 'touchend', this); 29990 utils.removeEvent(window, utils.prefixPointerEvent('pointerup'), this); 29991 utils.removeEvent(window, 'mouseup', this); 29992 } 29993 29994 if ( this.options.defaultScrollbars ) { 29995 this.wrapper.parentNode.removeChild(this.wrapper); 29996 } 29997 }, 29998 29999 _start: function (e) { 30000 var point = e.touches ? e.touches[0] : e; 30001 30002 e.preventDefault(); 30003 e.stopPropagation(); 30004 30005 this.transitionTime(); 30006 30007 this.initiated = true; 30008 this.moved = false;
vendor: 9,615 bytes, lines 30009-30267
30009 this.lastPointX = point.pageX; 30010 this.lastPointY = point.pageY; 30011 30012 this.startTime = utils.getTime(); 30013 30014 if ( !this.options.disableTouch ) { 30015 utils.addEvent(window, 'touchmove', this); 30016 } 30017 if ( !this.options.disablePointer ) { 30018 utils.addEvent(window, utils.prefixPointerEvent('pointermove'), this); 30019 } 30020 if ( !this.options.disableMouse ) { 30021 utils.addEvent(window, 'mousemove', this); 30022 } 30023 30024 this.scroller._execEvent('beforeScrollStart'); 30025 }, 30026 30027 _move: function (e) { 30028 var point = e.touches ? e.touches[0] : e, 30029 deltaX, deltaY, 30030 newX, newY, 30031 timestamp = utils.getTime(); 30032 30033 if ( !this.moved ) { 30034 this.scroller._execEvent('scrollStart'); 30035 } 30036 30037 this.moved = true; 30038 30039 deltaX = point.pageX - this.lastPointX; 30040 this.lastPointX = point.pageX; 30041 30042 deltaY = point.pageY - this.lastPointY; 30043 this.lastPointY = point.pageY; 30044 30045 newX = this.x + deltaX; 30046 newY = this.y + deltaY; 30047 30048 this._pos(newX, newY); 30049 30050// INSERT POINT: indicator._move 30051 30052 e.preventDefault(); 30053 e.stopPropagation(); 30054 }, 30055 30056 _end: function (e) { 30057 if ( !this.initiated ) { 30058 return; 30059 } 30060 30061 this.initiated = false; 30062 30063 e.preventDefault(); 30064 e.stopPropagation(); 30065 30066 utils.removeEvent(window, 'touchmove', this); 30067 utils.removeEvent(window, utils.prefixPointerEvent('pointermove'), this); 30068 utils.removeEvent(window, 'mousemove', this); 30069 30070 if ( this.scroller.options.snap ) { 30071 var snap = this.scroller._nearestSnap(this.scroller.x, this.scroller.y); 30072 30073 var time = this.options.snapSpeed || Math.max( 30074 Math.max( 30075 Math.min(Math.abs(this.scroller.x - snap.x), 1000), 30076 Math.min(Math.abs(this.scroller.y - snap.y), 1000) 30077 ), 300); 30078 30079 if ( this.scroller.x != snap.x || this.scroller.y != snap.y ) { 30080 this.scroller.directionX = 0; 30081 this.scroller.directionY = 0; 30082 this.scroller.currentPage = snap; 30083 this.scroller.scrollTo(snap.x, snap.y, time, this.scroller.options.bounceEasing); 30084 } 30085 } 30086 30087 if ( this.moved ) { 30088 this.scroller._execEvent('scrollEnd'); 30089 } 30090 }, 30091 30092 transitionTime: function (time) { 30093 time = time || 0; 30094 var durationProp = utils.style.transitionDuration; 30095 if(!durationProp) { 30096 return; 30097 } 30098 30099 this.indicatorStyle[durationProp] = time + 'ms'; 30100 30101 if ( !time && utils.isBadAndroid ) { 30102 this.indicatorStyle[durationProp] = '0.0001ms'; 30103 // remove 0.0001ms 30104 var self = this; 30105 rAF(function() { 30106 if(self.indicatorStyle[durationProp] === '0.0001ms') { 30107 self.indicatorStyle[durationProp] = '0s'; 30108 } 30109 }); 30110 } 30111 }, 30112 30113 transitionTimingFunction: function (easing) { 30114 this.indicatorStyle[utils.style.transitionTimingFunction] = easing; 30115 }, 30116 30117 refresh: function () { 30118 this.transitionTime(); 30119 30120 if ( this.options.listenX && !this.options.listenY ) { 30121 this.indicatorStyle.display = this.scroller.hasHorizontalScroll ? 'block' : 'none'; 30122 } else if ( this.options.listenY && !this.options.listenX ) { 30123 this.indicatorStyle.display = this.scroller.hasVerticalScroll ? 'block' : 'none'; 30124 } else { 30125 this.indicatorStyle.display = this.scroller.hasHorizontalScroll || this.scroller.hasVerticalScroll ? 'block' : 'none'; 30126 } 30127 30128 if ( this.scroller.hasHorizontalScroll && this.scroller.hasVerticalScroll ) { 30129 utils.addClass(this.wrapper, 'iScrollBothScrollbars'); 30130 utils.removeClass(this.wrapper, 'iScrollLoneScrollbar'); 30131 30132 if ( this.options.defaultScrollbars && this.options.customStyle ) { 30133 if ( this.options.listenX ) { 30134 this.wrapper.style.right = '8px'; 30135 } else { 30136 this.wrapper.style.bottom = '8px'; 30137 } 30138 } 30139 } else { 30140 utils.removeClass(this.wrapper, 'iScrollBothScrollbars'); 30141 utils.addClass(this.wrapper, 'iScrollLoneScrollbar'); 30142 30143 if ( this.options.defaultScrollbars && this.options.customStyle ) { 30144 if ( this.options.listenX ) { 30145 this.wrapper.style.right = '2px'; 30146 } else { 30147 this.wrapper.style.bottom = '2px'; 30148 } 30149 } 30150 } 30151 30152 var r = this.wrapper.offsetHeight; // force refresh 30153 30154 if ( this.options.listenX ) { 30155 this.wrapperWidth = this.wrapper.clientWidth; 30156 if ( this.options.resize ) { 30157 this.indicatorWidth = Math.max(Math.round(this.wrapperWidth * this.wrapperWidth / (this.scroller.scrollerWidth || this.wrapperWidth || 1)), 8); 30158 this.indicatorStyle.width = this.indicatorWidth + 'px'; 30159 } else { 30160 this.indicatorWidth = this.indicator.clientWidth; 30161 } 30162 30163 this.maxPosX = this.wrapperWidth - this.indicatorWidth; 30164 30165 if ( this.options.shrink == 'clip' ) { 30166 this.minBoundaryX = -this.indicatorWidth + 8; 30167 this.maxBoundaryX = this.wrapperWidth - 8; 30168 } else { 30169 this.minBoundaryX = 0; 30170 this.maxBoundaryX = this.maxPosX; 30171 } 30172 30173 this.sizeRatioX = this.options.speedRatioX || (this.scroller.maxScrollX && (this.maxPosX / this.scroller.maxScrollX)); 30174 } 30175 30176 if ( this.options.listenY ) { 30177 this.wrapperHeight = this.wrapper.clientHeight; 30178 if ( this.options.resize ) { 30179 this.indicatorHeight = Math.max(Math.round(this.wrapperHeight * this.wrapperHeight / (this.scroller.scrollerHeight || this.wrapperHeight || 1)), 8); 30180 this.indicatorStyle.height = this.indicatorHeight + 'px'; 30181 } else { 30182 this.indicatorHeight = this.indicator.clientHeight; 30183 } 30184 30185 this.maxPosY = this.wrapperHeight - this.indicatorHeight; 30186 30187 if ( this.options.shrink == 'clip' ) { 30188 this.minBoundaryY = -this.indicatorHeight + 8; 30189 this.maxBoundaryY = this.wrapperHeight - 8; 30190 } else { 30191 this.minBoundaryY = 0; 30192 this.maxBoundaryY = this.maxPosY; 30193 } 30194 30195 this.maxPosY = this.wrapperHeight - this.indicatorHeight; 30196 this.sizeRatioY = this.options.speedRatioY || (this.scroller.maxScrollY && (this.maxPosY / this.scroller.maxScrollY)); 30197 } 30198 30199 this.updatePosition(); 30200 }, 30201 30202 updatePosition: function () { 30203 var x = this.options.listenX && Math.round(this.sizeRatioX * this.scroller.x) || 0, 30204 y = this.options.listenY && Math.round(this.sizeRatioY * this.scroller.y) || 0; 30205 30206 if ( !this.options.ignoreBoundaries ) { 30207 if ( x < this.minBoundaryX ) { 30208 if ( this.options.shrink == 'scale' ) { 30209 this.width = Math.max(this.indicatorWidth + x, 8); 30210 this.indicatorStyle.width = this.width + 'px'; 30211 } 30212 x = this.minBoundaryX; 30213 } else if ( x > this.maxBoundaryX ) { 30214 if ( this.options.shrink == 'scale' ) { 30215 this.width = Math.max(this.indicatorWidth - (x - this.maxPosX), 8); 30216 this.indicatorStyle.width = this.width + 'px'; 30217 x = this.maxPosX + this.indicatorWidth - this.width; 30218 } else { 30219 x = this.maxBoundaryX; 30220 } 30221 } else if ( this.options.shrink == 'scale' && this.width != this.indicatorWidth ) { 30222 this.width = this.indicatorWidth; 30223 this.indicatorStyle.width = this.width + 'px'; 30224 } 30225 30226 if ( y < this.minBoundaryY ) { 30227 if ( this.options.shrink == 'scale' ) { 30228 this.height = Math.max(this.indicatorHeight + y * 3, 8); 30229 this.indicatorStyle.height = this.height + 'px'; 30230 } 30231 y = this.minBoundaryY; 30232 } else if ( y > this.maxBoundaryY ) { 30233 if ( this.options.shrink == 'scale' ) { 30234 this.height = Math.max(this.indicatorHeight - (y - this.maxPosY) * 3, 8); 30235 this.indicatorStyle.height = this.height + 'px'; 30236 y = this.maxPosY + this.indicatorHeight - this.height; 30237 } else { 30238 y = this.maxBoundaryY; 30239 } 30240 } else if ( this.options.shrink == 'scale' && this.height != this.indicatorHeight ) { 30241 this.height = this.indicatorHeight; 30242 this.indicatorStyle.height = this.height + 'px'; 30243 } 30244 } 30245 30246 this.x = x; 30247 this.y = y; 30248 30249 if ( this.scroller.options.useTransform ) { 30250 this.indicatorStyle[utils.style.transform] = 'translate(' + x + 'px,' + y + 'px)' + this.scroller.translateZ; 30251 } else { 30252 this.indicatorStyle.left = x + 'px'; 30253 this.indicatorStyle.top = y + 'px'; 30254 } 30255 }, 30256 30257 _pos: function (x, y) { 30258 if ( x < 0 ) { 30259 x = 0; 30260 } else if ( x > this.maxPosX ) { 30261 x = this.maxPosX; 30262 } 30263 30264 if ( y < 0 ) { 30265 y = 0; 30266 } else if ( y > this.maxPosY ) { 30267 y = this.maxPosY;
30268 } 30269 30270 x = this.options.listenX ? Math.round(x / this.sizeRatioX) : this.scroller.x; 30271 y = this.options.listenY ? Math.round(y / this.sizeRatioY) : this.scroller.y; 30272 30273 this.scroller.scrollTo(x, y); 30274 }, 30275 30276 fade: function (val, hold) { 30277 if ( hold && !this.visible ) { 30278 return; 30279 } 30280 30281 clearTimeout(this.fadeTimeout); 30282 this.fadeTimeout = null; 30283 30284 var time = val ? 250 : 500, 30285 delay = val ? 0 : 300; 30286 30287 val = val ? '1' : '0'; 30288 30289 this.wrapperStyle[utils.style.transitionDuration] = time + 'ms'; 30290 30291 this.fadeTimeout = setTimeout((function (val) { 30292 this.wrapperStyle.opacity = val; 30293 this.visible = +val; 30294 }).bind(this, val), delay); 30295 } 30296}; 30297 30298IScroll.utils = utils; 30299 30300if ( typeof module != 'undefined' && module.exports ) { 30301 module.exports = IScroll; 30302} else if ( typeof define == 'function' && define.amd ) { 30303 define( function () { return IScroll; } ); 30304} else { 30305 window.IScroll = IScroll; 30306} 30307 30308})(window, document, Math); 30309/*! 30310 * fullPage 2.9.4 30311 * https://github.com/alvarotrigo/fullPage.js 30312 * @license MIT licensed 30313 * 30314 * Copyright (C) 2015 alvarotrigo.com - A project by Alvaro Trigo 30315 */ 30316(function(global, factory) { 30317 'use strict'; 30318 if (typeof define === 'function' && define.amd) { 30319 define(['jquery'], function($) { 30320 return factory($, global, global.document, global.Math); 30321 }); 30322 } else if (typeof exports === "object" && exports) { 30323 module.exports = factory(require('jquery'), global, global.document, global.Math); 30324 } else { 30325 factory(jQuery, global, global.document, global.Math); 30326 } 30327})(typeof window !== 'undefined' ? window : this, function($, window, document, Math, undefined) { 30328 'use strict'; 30329 30330 // keeping central set of classnames and selectors 30331 var WRAPPER = 'fullpage-wrapper'; 30332 var WRAPPER_SEL = '.' + WRAPPER; 30333 30334 // slimscroll 30335 var SCROLLABLE = 'fp-scrollable'; 30336 var SCROLLABLE_SEL = '.' + SCROLLABLE; 30337 30338 // util 30339 var RESPONSIVE = 'fp-responsive'; 30340 var NO_TRANSITION = 'fp-notransition'; 30341 var DESTROYED = 'fp-destroyed'; 30342 var ENABLED = 'fp-enabled'; 30343 var VIEWING_PREFIX = 'fp-viewing'; 30344 var ACTIVE = 'active'; 30345 var ACTIVE_SEL = '.' + ACTIVE; 30346 var COMPLETELY = 'fp-completely'; 30347 var COMPLETELY_SEL = '.' + COMPLETELY; 30348 30349 // section 30350 var SECTION_DEFAULT_SEL = '.section'; 30351 var SECTION = 'fp-section'; 30352 var SECTION_SEL = '.' + SECTION; 30353 var SECTION_ACTIVE_SEL = SECTION_SEL + ACTIVE_SEL; 30354 var SECTION_FIRST_SEL = SECTION_SEL + ':first'; 30355 var SECTION_LAST_SEL = SECTION_SEL + ':last'; 30356 var TABLE_CELL = 'fp-tableCell'; 30357 var TABLE_CELL_SEL = '.' + TABLE_CELL; 30358 var AUTO_HEIGHT = 'fp-auto-height'; 30359 var AUTO_HEIGHT_SEL = '.fp-auto-height'; 30360 var NORMAL_SCROLL = 'fp-normal-scroll'; 30361 var NORMAL_SCROLL_SEL = '.fp-normal-scroll'; 30362 30363 // section nav 30364 var SECTION_NAV = 'fp-nav'; 30365 var SECTION_NAV_SEL = '#' + SECTION_NAV; 30366 var SECTION_NAV_TOOLTIP = 'fp-tooltip'; 30367 var SECTION_NAV_TOOLTIP_SEL='.'+SECTION_NAV_TOOLTIP; 30368 var SHOW_ACTIVE_TOOLTIP = 'fp-show-active'; 30369 30370 // slide 30371 var SLIDE_DEFAULT_SEL = '.slide'; 30372 var SLIDE = 'fp-slide'; 30373 var SLIDE_SEL = '.' + SLIDE; 30374 var SLIDE_ACTIVE_SEL = SLIDE_SEL + ACTIVE_SEL; 30375 var SLIDES_WRAPPER = 'fp-slides'; 30376 var SLIDES_WRAPPER_SEL = '.' + SLIDES_WRAPPER; 30377 var SLIDES_CONTAINER = 'fp-slidesContainer'; 30378 var SLIDES_CONTAINER_SEL = '.' + SLIDES_CONTAINER; 30379 var TABLE = 'fp-table'; 30380 30381 // slide nav 30382 var SLIDES_NAV = 'fp-slidesNav'; 30383 var SLIDES_NAV_SEL = '.' + SLIDES_NAV; 30384 var SLIDES_NAV_LINK_SEL = SLIDES_NAV_SEL + ' a'; 30385 var SLIDES_ARROW = 'fp-controlArrow'; 30386 var SLIDES_ARROW_SEL = '.' + SLIDES_ARROW; 30387 var SLIDES_PREV = 'fp-prev'; 30388 var SLIDES_PREV_SEL = '.' + SLIDES_PREV; 30389 var SLIDES_ARROW_PREV = SLIDES_ARROW + ' ' + SLIDES_PREV; 30390 var SLIDES_ARROW_PREV_SEL = SLIDES_ARROW_SEL + SLIDES_PREV_SEL; 30391 var SLIDES_NEXT = 'fp-next';
30392 var SLIDES_NEXT_SEL = '.' + SLIDES_NEXT; 30393 var SLIDES_ARROW_NEXT = SLIDES_ARROW + ' ' + SLIDES_NEXT; 30394 var SLIDES_ARROW_NEXT_SEL = SLIDES_ARROW_SEL + SLIDES_NEXT_SEL; 30395 30396 var $window = $(window); 30397 var $document = $(document); 30398 30399 // Default options for iScroll.js used when using scrollOverflow 30400 var iscrollOptions = { 30401 scrollbars: true, 30402 mouseWheel: true, 30403 hideScrollbars: false, 30404 fadeScrollbars: false, 30405 disableMouse: true, 30406 interactiveScrollbars: true, 30407 bounce: false, 30408 }; 30409 30410 $.fn.fullpage = function(options) { 30411 //only once my friend! 30412 if($('html').hasClass(ENABLED)){ displayWarnings(); return; } 30413 30414 // common jQuery objects 30415 var $htmlBody = $('html, body'); 30416 var $body = $('body'); 30417 30418 var FP = $.fn.fullpage; 30419 30420 // Creating some defaults, extending them with any options that were provided 30421 options = $.extend({ 30422 //navigation 30423 menu: false, 30424 anchors:[], 30425 lockAnchors: false, 30426 navigation: false, 30427 navigationPosition: 'right', 30428 navigationTooltips: [], 30429 showActiveTooltip: false, 30430 slidesNavigation: false, 30431 slidesNavPosition: 'bottom', 30432 scrollBar: false, 30433 hybrid: false, 30434 30435 //scrolling 30436 css3: true, 30437 scrollingSpeed: 700, 30438 autoScrolling: true, 30439 fitToSection: true, 30440 fitToSectionDelay: 1000, 30441 easing: 'easeInOutCubic', 30442 easingcss3: 'ease', 30443 loopBottom: false, 30444 loopTop: false, 30445 loopHorizontal: true, 30446 continuousVertical: false, 30447 continuousHorizontal: false, 30448 scrollHorizontally: false, 30449 interlockedSlides: false, 30450 dragAndMove: false, 30451 offsetSections: false, 30452 resetSliders: false, 30453 fadingEffect: false, 30454 normalScrollElements: null, 30455 scrollOverflow: false, 30456 scrollOverflowReset: false, 30457 scrollOverflowHandler: iscrollHandler, 30458 scrollOverflowOptions: null, 30459 touchSensitivity: 5, 30460 normalScrollElementTouchThreshold: 5, 30461 bigSectionsDestination: null, 30462 30463 //Accessibility 30464 keyboardScrolling: true, 30465 animateAnchor: true, 30466 recordHistory: true, 30467 30468 //design 30469 controlArrows: true, 30470 controlArrowColor: '#fff', 30471 verticalCentered: true, 30472 sectionsColor : [], 30473 paddingTop: 0, 30474 paddingBottom: 0, 30475 fixedElements: null, 30476 responsive: 0, //backwards compabitility with responsiveWiddth 30477 responsiveWidth: 0, 30478 responsiveHeight: 0, 30479 responsiveSlides: false, 30480 parallax: false, 30481 parallaxOptions: { 30482 type: 'reveal', 30483 percentage: 62, 30484 property: 'translate' 30485 }, 30486 30487 //Custom selectors 30488 sectionSelector: SECTION_DEFAULT_SEL, 30489 slideSelector: SLIDE_DEFAULT_SEL, 30490 30491 //events 30492 afterLoad: null, 30493 onLeave: null, 30494 afterRender: null, 30495 afterResize: null, 30496 afterReBuild: null, 30497 afterSlideLoad: null, 30498 onSlideLeave: null, 30499 afterResponsive: null, 30500 30501 lazyLoading: true 30502 }, options); 30503 30504 //flag to avoid very fast sliding for landscape sliders 30505 var slideMoving = false; 30506 30507 var isTouchDevice = navigator.userAgent.match(/(iPhone|iPod|iPad|Android|playbook|silk|BlackBerry|BB10|Windows Phone|Tizen|Bada|webOS|IEMobile|Opera Mini)/); 30508 var isTouch = (('ontouchstart' in window) || (navigator.msMaxTouchPoints > 0) || (navigator.maxTouchPoints)); 30509 var container = $(this); 30510 var windowsHeight = $window.height(); 30511 var isResizing = false; 30512 var isWindowFocused = true; 30513 var lastScrolledDestiny; 30514 var lastScrolledSlide; 30515 var canScroll = true; 30516 var scrollings = []; 30517 var controlPressed; 30518 var startingSection; 30519 var isScrollAllowed = {}; 30520 isScrollAllowed.m = { 'up':true, 'down':true, 'left':true, 'right':true }; 30521 isScrollAllowed.k = $.extend(true,{}, isScrollAllowed.m); 30522 var MSPointer = getMSPointer(); 30523 var events = { 30524 touchmove: 'ontouchmove' in window ? 'touchmove' : MSPointer.move, 30525 touchstart: 'ontouchstart' in window ? 'touchstart' : MSPointer.down 30526 }; 30527 30528 //cheks for passive event support 30529 //added by Uncode from new fullPage updates 30530 var g_supportsPassive = false;
30531 try { 30532 var opts = Object.defineProperty({}, 'passive', { 30533 get: function() { 30534 g_supportsPassive = true; 30535 } 30536 }); 30537 window.addEventListener("testPassive", null, opts); 30538 window.removeEventListener("testPassive", null, opts); 30539 } catch (e) {} 30540 30541 //timeouts 30542 var resizeId; 30543 var afterSectionLoadsId; 30544 var afterSlideLoadsId; 30545 var scrollId; 30546 var scrollId2; 30547 var keydownId; 30548 var originals = $.extend(true, {}, options); //deep copy 30549 30550 //Uncode addition 30551 var $masthead = $('#masthead'); 30552 var hideMenu = !$('body').hasClass('vmenu') && $('body').hasClass('uncode-fp-menu-hide') ? true : false; 30553 var menuHeight = $masthead.hasClass('menu-transparent') || hideMenu ? 0 : UNCODE.menuHeight; 30554 var bodyBorder = UNCODE.bodyBorder; 30555 var adminBarHeight = UNCODE.adminBarHeight; 30556 30557 displayWarnings(); 30558 30559 //fixing bug in iScroll with links: https://github.com/cubiq/iscroll/issues/783 30560 iscrollOptions.click = isTouch; // see #2035 30561 30562 //extending iScroll options with the user custom ones 30563 iscrollOptions = $.extend(iscrollOptions, options.scrollOverflowOptions); 30564 30565 //easeInOutCubic animation included in the plugin 30566 $.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;}}); 30567 30568 /** 30569 * Sets the autoScroll option. 30570 * It changes the scroll bar visibility and the history of the site as a result. 30571 */ 30572 function setAutoScrolling(value, type){ 30573 //removing the transformation 30574 if(!value){ 30575 silentScroll(0); 30576 } 30577 30578 setVariableState('autoScrolling', value, type); 30579 30580 var element = $(SECTION_ACTIVE_SEL); 30581 30582 if(options.autoScrolling && !options.scrollBar){ 30583 $htmlBody.css({ 30584 'overflow' : 'hidden !important', 30585 'height' : '100%' 30586 }); 30587 30588 //Uncode addition 30589 //setRecordHistory(originals.recordHistory, 'internal'); 30590 30591 //for IE touch devices 30592 container.css({ 30593 '-ms-touch-action': 'none', 30594 'touch-action': 'none' 30595 }); 30596 30597 if(element.length){ 30598 //moving the container up 30599 silentScroll(element.position().top); 30600 } 30601 30602 }else{ 30603 $htmlBody.css({ 30604 'overflow' : 'visible !important', 30605 'height' : 'initial' 30606 }); 30607 30608 //Uncode addition 30609 //setRecordHistory(false, 'internal'); 30610 30611 //for IE touch devices 30612 container.css({ 30613 '-ms-touch-action': '', 30614 'touch-action': '' 30615 }); 30616 30617 //scrolling the page to the section with no animation 30618 if (element.length) { 30619 $htmlBody.scrollTop(element.position().top); 30620 } 30621 } 30622 } 30623 30624 /** 30625 * Defines wheter to record the history for each hash change in the URL. 30626 */ 30627 function setRecordHistory(value, type){ 30628 setVariableState('recordHistory', value, type); 30629 } 30630 30631 /** 30632 * Defines the scrolling speed 30633 */ 30634 function setScrollingSpeed(value, type){ 30635 setVariableState('scrollingSpeed', value, type); 30636 } 30637 30638 /** 30639 * Sets fitToSection 30640 */ 30641 function setFitToSection(value, type){ 30642 setVariableState('fitToSection', value, type); 30643 } 30644 30645 /** 30646 * Sets lockAnchors 30647 */ 30648 function setLockAnchors(value){ 30649 options.lockAnchors = value; 30650 } 30651 30652 /** 30653 * Adds or remove the possiblity of scrolling through sections by using the mouse wheel or the trackpad. 30654 */ 30655 function setMouseWheelScrolling(value){ 30656 if(value){ 30657 addMouseWheelHandler(); 30658 addMiddleWheelHandler(); 30659 }else{ 30660 removeMouseWheelHandler(); 30661 removeMiddleWheelHandler(); 30662 } 30663 } 30664 30665 /** 30666 * Adds or remove the possibility of scrolling through sections by using the mouse wheel/trackpad or touch gestures. 30667 * Optionally a second parameter can be used to specify the direction for which the action will be applied. 30668 * 30669 * @param directions string containing the direction or directions separated by comma. 30670 */ 30671 function setAllowScrolling(value, directions){ 30672 if(typeof directions !== 'undefined'){ 30673 directions = directions.replace(/ /g,'').split(','); 30674 30675 $.each(directions, function (index, direction){ 30676 setIsScrollAllowed(value, direction, 'm'); 30677 }); 30678 } 30679 else if(value){ 30680 setMouseWheelScrolling(true); 30681 addTouchHandler(); 30682 }else{ 30683 setMouseWheelScrolling(false); 30684 removeTouchHandler(); 30685 } 30686 } 30687 30688 /** 30689 * Adds or remove the possibility of scrolling through sections by using the keyboard arrow keys 30690 */ 30691 function setKeyboardScrolling(value, directions){ 30692 if(typeof directions !== 'undefined'){ 30693 directions = directions.replace(/ /g,'').split(','); 30694 30695 $.each(directions, function (index, direction){ 30696 setIsScrollAllowed(value, direction, 'k'); 30697 }); 30698 }else{ 30699 options.keyboardScrolling = value; 30700 } 30701 } 30702 30703 /** 30704 * Moves the page up one section. 30705 */ 30706 function moveSectionUp(){ 30707 var prev = $(SECTION_ACTIVE_SEL).prev(SECTION_SEL); 30708 30709 //looping to the bottom if there's no more sections above 30710 if (!prev.length && (options.loopTop || options.continuousVertical)) {
30711 prev = $(SECTION_SEL).last(); 30712 } 30713 30714 if (prev.length) { 30715 scrollPage(prev, null, true); 30716 } 30717 } 30718 30719 /** 30720 * Moves the page down one section. 30721 */ 30722 function moveSectionDown(){ 30723 var next = $(SECTION_ACTIVE_SEL).next(SECTION_SEL); 30724 30725 //looping to the top if there's no more sections below 30726 if(!next.length && 30727 (options.loopBottom || options.continuousVertical)){ 30728 next = $(SECTION_SEL).first(); 30729 } 30730 30731 if(next.length){ 30732 scrollPage(next, null, false); 30733 } 30734 } 30735 30736 /** 30737 * Moves the page to the given section and slide with no animation. 30738 * Anchors or index positions can be used as params. 30739 */ 30740 function silentMoveTo(sectionAnchor, slideAnchor){ 30741 setScrollingSpeed (0, 'internal'); 30742 moveTo(sectionAnchor, slideAnchor); 30743 setScrollingSpeed (originals.scrollingSpeed, 'internal'); 30744 } 30745 30746 /** 30747 * Moves the page to the given section and slide. 30748 * Anchors or index positions can be used as params. 30749 */ 30750 function moveTo(sectionAnchor, slideAnchor){ 30751 var destiny = getSectionByAnchor(sectionAnchor); 30752 30753 if (typeof slideAnchor !== 'undefined'){ 30754 scrollPageAndSlide(sectionAnchor, slideAnchor); 30755 }else if(destiny.length > 0){ 30756 scrollPage(destiny); 30757 } 30758 } 30759 30760 /** 30761 * Slides right the slider of the active section. 30762 * Optional `section` param. 30763 */ 30764 function moveSlideRight(section){ 30765 moveSlide('right', section); 30766 } 30767 30768 /** 30769 * Slides left the slider of the active section. 30770 * Optional `section` param. 30771 */ 30772 function moveSlideLeft(section){ 30773 moveSlide('left', section); 30774 } 30775 30776 /** 30777 * When resizing is finished, we adjust the slides sizes and positions 30778 */ 30779 function reBuild(resizing){ 30780 if(container.hasClass(DESTROYED)){ return; } //nothing to do if the plugin was destroyed 30781 30782 isResizing = true; 30783 30784 windowsHeight = $window.height(); //updating global var 30785 30786 $(SECTION_SEL).each(function(){ 30787 var slidesWrap = $(this).find(SLIDES_WRAPPER_SEL); 30788 var slides = $(this).find(SLIDE_SEL); 30789 30790 //adjusting the height of the table-cell for IE and Firefox 30791 if(options.verticalCentered){ 30792 $(this).find(TABLE_CELL_SEL).css('height', getTableHeight($(this)) + 'px'); 30793 } 30794 30795 $(this).css('height', windowsHeight + 'px'); 30796 30797 //resizing the scrolling divs 30798 if(options.scrollOverflow){ 30799 if(slides.length){ 30800 slides.each(function(){ 30801 createScrollBar($(this)); 30802 }); 30803 }else{ 30804 createScrollBar($(this)); 30805 } 30806 } 30807 30808 //adjusting the position fo the FULL WIDTH slides... 30809 if (slides.length > 1) { 30810 landscapeScroll(slidesWrap, slidesWrap.find(SLIDE_ACTIVE_SEL)); 30811 } 30812 }); 30813 30814 var activeSection = $(SECTION_ACTIVE_SEL); 30815 var sectionIndex = activeSection.index(SECTION_SEL); 30816 30817 //isn't it the first section? 30818 if(sectionIndex){ 30819 //adjusting the position for the current section 30820 silentMoveTo(sectionIndex + 1); 30821 } 30822 30823 isResizing = false; 30824 // Uncode change 30825 // $.isFunction( options.afterResize ) && resizing && options.afterResize.call(container); 30826 $.isFunction( options.afterResize ) && resizing && options.afterResize.call(container, getTableHeight()); 30827 $.isFunction( options.afterReBuild ) && !resizing && options.afterReBuild.call(container); 30828 } 30829 30830 /** 30831 * Turns fullPage.js to normal scrolling mode when the viewport `width` or `height` 30832 * are smaller than the set limit values. 30833 */ 30834 function setResponsive(active){ 30835 var isResponsive = $body.hasClass(RESPONSIVE); 30836 30837 if(active){ 30838 if(!isResponsive){ 30839 setAutoScrolling(false, 'internal'); 30840 setFitToSection(false, 'internal'); 30841 $(SECTION_NAV_SEL).hide(); 30842 $body.addClass(RESPONSIVE); 30843 $.isFunction( options.afterResponsive ) && options.afterResponsive.call( container, active); 30844 } 30845 } 30846 else if(isResponsive){ 30847 setAutoScrolling(originals.autoScrolling, 'internal'); 30848 setFitToSection(originals.autoScrolling, 'internal'); 30849 $(SECTION_NAV_SEL).show(); 30850 $body.removeClass(RESPONSIVE); 30851 $.isFunction( options.afterResponsive ) && options.afterResponsive.call( container, active); 30852 } 30853 } 30854 30855 if($(this).length){ 30856 //public functions 30857 FP.setAutoScrolling = setAutoScrolling; 30858 FP.setRecordHistory = setRecordHistory; 30859 FP.setScrollingSpeed = setScrollingSpeed; 30860 FP.setFitToSection = setFitToSection; 30861 FP.setLockAnchors = setLockAnchors; 30862 FP.setMouseWheelScrolling = setMouseWheelScrolling; 30863 FP.setAllowScrolling = setAllowScrolling; 30864 FP.setKeyboardScrolling = setKeyboardScrolling; 30865 FP.moveSectionUp = moveSectionUp; 30866 FP.moveSectionDown = moveSectionDown; 30867 FP.silentMoveTo = silentMoveTo; 30868 FP.moveTo = moveTo; 30869 FP.moveSlideRight = moveSlideRight; 30870 FP.moveSlideLeft = moveSlideLeft; 30871 FP.fitToSection = fitToSection; 30872 FP.reBuild = reBuild; 30873 FP.setResponsive = setResponsive; 30874 FP.destroy = destroy; 30875 30876 init(); 30877 30878 bindEvents(); 30879 } 30880
30881 function init(){ 30882 //if css3 is not supported, it will use jQuery animations 30883 if(options.css3){ 30884 options.css3 = support3d(); 30885 } 30886 30887 options.scrollBar = options.scrollBar || options.hybrid; 30888 30889 setOptionsFromDOM(); 30890 prepareDom(); 30891 setAllowScrolling(true); 30892 setAutoScrolling(options.autoScrolling, 'internal'); 30893 responsive(); 30894 30895 //setting the class for the body element 30896 setBodyClass(); 30897 30898 //Uncode addition 30899 // if(document.readyState === 'complete'){ 30900 // scrollToAnchor(); 30901 // } 30902 // $window.on('load', scrollToAnchor); 30903 } 30904 30905 function bindEvents(){ 30906 $window 30907 //when scrolling... 30908 //.on('scroll', scrollHandler) 30909 30910 //detecting any change on the URL to scroll to the given anchor link 30911 //(a way to detect back history button as we play with the hashes on the URL) 30912 .on('hashchange', hashChangeHandler) 30913 30914 //when opening a new tab (ctrl + t), `control` won't be pressed when coming back. 30915 .blur(blurHandler) 30916 30917 //when resizing the site, we adjust the heights of the sections, slimScroll... 30918 .resize(resizeHandler); 30919 30920 $document 30921 //Sliding with arrow keys, both, vertical and horizontal 30922 .keydown(keydownHandler) 30923 30924 //to prevent scrolling while zooming 30925 .keyup(keyUpHandler) 30926 30927 //Scrolls to the section when clicking the navigation bullet 30928 .on('click touchstart', SECTION_NAV_SEL + ' a', sectionBulletHandler) 30929 30930 //Scrolls the slider to the given slide destination for the given section 30931 .on('click touchstart', SLIDES_NAV_LINK_SEL, slideBulletHandler) 30932 30933 .on('click', SECTION_NAV_TOOLTIP_SEL, tooltipTextHandler); 30934 30935 //Scrolling horizontally when clicking on the slider controls. 30936 $(SECTION_SEL).on('click touchstart', SLIDES_ARROW_SEL, slideArrowHandler); 30937 30938 /** 30939 * Applying normalScroll elements. 30940 * Ignoring the scrolls over the specified selectors. 30941 */ 30942 if(options.normalScrollElements){ 30943 $document.on('mouseenter', options.normalScrollElements, function () { 30944 setMouseWheelScrolling(false); 30945 }); 30946 30947 $document.on('mouseleave', options.normalScrollElements, function(){ 30948 setMouseWheelScrolling(true); 30949 }); 30950 } 30951 } 30952 30953 /** 30954 * Setting options from DOM elements if they are not provided. 30955 */ 30956 function setOptionsFromDOM(){ 30957 var sections = container.find(options.sectionSelector); 30958 30959 //no anchors option? Checking for them in the DOM attributes 30960 if(!options.anchors.length){ 30961 options.anchors = sections.filter('[data-anchor]').map(function(){ 30962 return $(this).data('anchor').toString(); 30963 }).get(); 30964 } 30965 30966 //no tooltips option? Checking for them in the DOM attributes 30967 if(!options.navigationTooltips.length){ 30968 options.navigationTooltips = sections.filter('[data-tooltip]').map(function(){ 30969 return $(this).data('tooltip').toString(); 30970 }).get(); 30971 } 30972 } 30973 30974 /** 30975 * Works over the DOM structure to set it up for the current fullpage options. 30976 */ 30977 function prepareDom(){ 30978 container.css({ 30979 'height': '100%', 30980 'position': 'relative' 30981 }); 30982 30983 //adding a class to recognize the container internally in the code 30984 container.addClass(WRAPPER); 30985 $('html').addClass(ENABLED); 30986 30987 windowsHeight = $window.height(); 30988 30989 container.removeClass(DESTROYED); //in case it was destroyed before initializing it again 30990 30991 addInternalSelectors(); 30992 30993 //styling the sections / slides / menu 30994 $(SECTION_SEL).each(function(index){ 30995 var section = $(this); 30996 var slides = section.find(SLIDE_SEL); 30997 var numSlides = slides.length; 30998 30999 styleSection(section, index); 31000 styleMenu(section, index); 31001 31002 // if there's any slide 31003 if (numSlides > 0) { 31004 styleSlides(section, slides, numSlides); 31005 }else{ 31006 if(options.verticalCentered){ 31007 addTableClass(section); 31008 } 31009 } 31010 }); 31011 31012 //fixed elements need to be moved out of the plugin container due to problems with CSS3. 31013 if(options.fixedElements && options.css3){ 31014 $(options.fixedElements).appendTo($body); 31015 } 31016 31017 //vertical centered of the navigation + active bullet 31018 if(options.navigation){ 31019 addVerticalNavigation(); 31020 } 31021 31022 enableYoutubeAPI(); 31023 31024 if(options.scrollOverflow){ 31025 if(document.readyState === 'complete'){ 31026 createScrollBarHandler(); 31027 } 31028 //after DOM and images are loaded 31029 $window.on('load', createScrollBarHandler); 31030 }else{ 31031 afterRenderActions(); 31032 } 31033 } 31034 31035 /** 31036 * Styles the horizontal slides for a section. 31037 */ 31038 function styleSlides(section, slides, numSlides){ 31039 var sliderWidth = numSlides * 100; 31040 var slideWidth = 100 / numSlides; 31041 31042 slides.wrapAll('<div class="' + SLIDES_CONTAINER + '" />'); 31043 slides.parent().wrap('<div class="' + SLIDES_WRAPPER + '" />'); 31044 31045 section.find(SLIDES_CONTAINER_SEL).css('width', sliderWidth + '%'); 31046 31047 if(numSlides > 1){ 31048 if(options.controlArrows){ 31049 createSlideArrows(section); 31050 } 31051 31052 if(options.slidesNavigation){ 31053 addSlidesNavigation(section, numSlides); 31054 } 31055 } 31056 31057 slides.each(function(index) { 31058 $(this).css('width', slideWidth + '%'); 31059 31060 if(options.verticalCentered){ 31061 addTableClass($(this)); 31062 } 31063 }); 31064 31065 var startingSlide = section.find(SLIDE_ACTIVE_SEL); 31066 31067 //if the slide won't be an starting point, the default will be the first one 31068 //the active section isn't the first one? Is not the first slide of the first section? Then we load that section/sl
31068ide by default. 31069 if( startingSlide.length && ($(SECTION_ACTIVE_SEL).index(SECTION_SEL) !== 0 || ($(SECTION_ACTIVE_SEL).index(SECTION_SEL) === 0 && startingSlide.index() !== 0))){ 31070 silentLandscapeScroll(startingSlide, 'internal'); 31071 }else{ 31072 slides.eq(0).addClass(ACTIVE); 31073 } 31074 } 31075 31076 /** 31077 * Styling vertical sections 31078 */ 31079 function styleSection(section, index){ 31080 //if no active section is defined, the 1st one will be the default one 31081 if(!index && $(SECTION_ACTIVE_SEL).length === 0) { 31082 section.addClass(ACTIVE); 31083 } 31084 startingSection = $(SECTION_ACTIVE_SEL); 31085 31086 section.css('height', windowsHeight + 'px'); 31087 31088 if(options.paddingTop){ 31089 section.css('padding-top', options.paddingTop); 31090 } 31091 31092 if(options.paddingBottom){ 31093 section.css('padding-bottom', options.paddingBottom); 31094 } 31095 31096 if (typeof options.sectionsColor[index] !== 'undefined') { 31097 section.css('background-color', options.sectionsColor[index]); 31098 } 31099 31100 if (typeof options.anchors[index] !== 'undefined') { 31101 section.attr('data-anchor', options.anchors[index]); 31102 } 31103 } 31104 31105 /** 31106 * Sets the data-anchor attributes to the menu elements and activates the current one. 31107 */ 31108 function styleMenu(section, index){ 31109 if (typeof options.anchors[index] !== 'undefined') { 31110 //activating the menu / nav element on load 31111 if(section.hasClass(ACTIVE)){ 31112 activateMenuAndNav(options.anchors[index], index); 31113 } 31114 } 31115 31116 //moving the menu outside the main container if it is inside (avoid problems with fixed positions when using CSS3 tranforms) 31117 if(options.menu && options.css3 && $(options.menu).closest(WRAPPER_SEL).length){ 31118 $(options.menu).appendTo($body); 31119 } 31120 } 31121 31122 /** 31123 * Adds internal classes to be able to provide customizable selectors 31124 * keeping the link with the style sheet. 31125 */ 31126 function addInternalSelectors(){ 31127 container.find(options.sectionSelector).addClass(SECTION); 31128 container.find(options.slideSelector).addClass(SLIDE); 31129 } 31130 31131 /** 31132 * Creates the control arrows for the given section 31133 */ 31134 function createSlideArrows(section){ 31135 section.find(SLIDES_WRAPPER_SEL).after('<div class="' + SLIDES_ARROW_PREV + '"></div><div class="' + SLIDES_ARROW_NEXT + '"></div>'); 31136 31137 if(options.controlArrowColor!='#fff'){ 31138 section.find(SLIDES_ARROW_NEXT_SEL).css('border-color', 'transparent transparent transparent '+options.controlArrowColor); 31139 section.find(SLIDES_ARROW_PREV_SEL).css('border-color', 'transparent '+ options.controlArrowColor + ' transparent transparent'); 31140 } 31141 31142 if(!options.loopHorizontal){ 31143 section.find(SLIDES_ARROW_PREV_SEL).hide(); 31144 } 31145 } 31146 31147 /** 31148 * Creates a vertical navigation bar. 31149 */ 31150 function addVerticalNavigation(){ 31151 $body.append('<div id="' + SECTION_NAV + '"><ul></ul></div>'); 31152 var nav = $(SECTION_NAV_SEL); 31153 31154 nav.addClass(function() { 31155 return options.showActiveTooltip ? SHOW_ACTIVE_TOOLTIP + ' ' + options.navigationPosition : options.navigationPosition; 31156 }); 31157 31158 for (var i = 0; i < $(SECTION_SEL).length; i++) { 31159 var link = ''; 31160 if (options.anchors.length) { 31161 link = options.anchors[i]; 31162 } 31163 31164 var li = '<li><a href="#' + link + '"><span></span></a>'; 31165 31166 // Only add tooltip if needed (defined by user) 31167 var tooltip = options.navigationTooltips[i]; 31168 31169 if (typeof tooltip !== 'undefined' && tooltip !== '') { 31170 li += '<div class="' + SECTION_NAV_TOOLTIP + ' ' + options.navigationPosition + '">' + tooltip + '</div>'; 31171 } 31172 31173 li += '</li>'; 31174 31175 nav.find('ul').append(li); 31176 } 31177 31178 //centering it vertically 31179 $(SECTION_NAV_SEL).css('margin-top', '-' + ($(SECTION_NAV_SEL).height()/2) + 'px'); 31180 31181 //activating the current active section 31182 $(SECTION_NAV_SEL).find('li').eq($(SECTION_ACTIVE_SEL).index(SECTION_SEL)).find('a').addClass(ACTIVE); 31183 } 31184 31185 /** 31186 * Creates the slim scroll scrollbar for the sections and slides inside them. 31187 */ 31188 function createScrollBarHandler(){ 31189 $(SECTION_SEL).each(function(){ 31190 var slides = $(this).find(SLIDE_SEL); 31191 31192 if(slides.length){ 31193 slides.each(function(){ 31194 createScrollBar($(this)); 31195 }); 31196 }else{ 31197 createScrollBar($(this)); 31198 } 31199 31200 }); 31201 afterRenderActions(); 31202 } 31203 31204 /*
31205 * Enables the Youtube videos API so we can control their flow if necessary. 31206 */ 31207 function enableYoutubeAPI(){ 31208 container.find('iframe[src*="youtube.com/embed/"]').each(function(){ 31209 addURLParam($(this), 'enablejsapi=1'); 31210 }); 31211 } 31212 31213 /** 31214 * Adds a new parameter and its value to the `src` of a given element 31215 */ 31216 function addURLParam(element, newParam){ 31217 var originalSrc = element.attr('src'); 31218 element.attr('src', originalSrc + getUrlParamSign(originalSrc) + newParam); 31219 } 31220 31221 /* 31222 * Returns the prefix sign to use for a new parameter in an existen URL. 31223 * 31224 * @return {String} ? | & 31225 */ 31226 function getUrlParamSign(url){ 31227 return ( !/\?/.test( url ) ) ? '?' : '&'; 31228 } 31229 31230 /** 31231 * Actions and callbacks to fire afterRender 31232 */ 31233 function afterRenderActions(){ 31234 var section = $(SECTION_ACTIVE_SEL); 31235 31236 section.addClass(COMPLETELY); 31237 31238 if(options.scrollOverflowHandler.afterRender){ 31239 options.scrollOverflowHandler.afterRender(section); 31240 } 31241 lazyLoad(section); 31242 playMedia(section); 31243 options.scrollOverflowHandler.afterLoad(); 31244 31245 if(isDestinyTheStartingSection()){ 31246 $.isFunction( options.afterLoad ) && options.afterLoad.call(section, section.data('anchor'), (section.index(SECTION_SEL) + 1)); 31247 } 31248 31249 // Uncode change 31250 // $.isFunction( options.afterRender ) && options.afterRender.call(container); 31251 $.isFunction( options.afterRender ) && options.afterRender.call(container, getTableHeight()); 31252 } 31253 31254 /** 31255 * Determines if the URL anchor destiny is the starting section (the one using 'active' class before initialization) 31256 */ 31257 function isDestinyTheStartingSection(){ 31258 var anchors = window.location.hash.replace('#', '').split('/'); 31259 var destinationSection = getSectionByAnchor(decodeURIComponent(anchors[0])); 31260 31261 return !destinationSection.length || destinationSection.length && destinationSection.index() === startingSection.index(); 31262 } 31263 31264 31265 var isScrolling = false; 31266 var lastScroll = 0; 31267 31268 //when scrolling... 31269 function scrollHandler(){ 31270 var currentSection; 31271 31272 if(!options.autoScrolling || options.scrollBar){ 31273 var currentScroll = $window.scrollTop(); 31274 var scrollDirection = getScrollDirection(currentScroll); 31275 var visibleSectionIndex = 0; 31276 var screen_mid = currentScroll + ($window.height() / 2.0); 31277 var isAtBottom = $body.height() - $window.height() === currentScroll; 31278 var sections = document.querySelectorAll(SECTION_SEL); 31279 31280 //when using `auto-height` for a small last section it won't be centered in the viewport 31281 if(isAtBottom){ 31282 visibleSectionIndex = sections.length - 1; 31283 } 31284 //is at top? when using `auto-height` for a small first section it won't be centered in the viewport 31285 else if(!currentScroll){ 31286 visibleSectionIndex = 0; 31287 } 31288 31289 //taking the section which is showing more content in the viewport 31290 else{ 31291 for (var i = 0; i < sections.length; ++i) { 31292 var section = sections[i]; 31293 31294 // Pick the the last section which passes the middle line of the screen. 31295 if (section.offsetTop <= screen_mid) 31296 { 31297 visibleSectionIndex = i; 31298 } 31299 } 31300 } 31301 31302 if(isCompletelyInViewPort(scrollDirection)){ 31303 if(!$(SECTION_ACTIVE_SEL).hasClass(COMPLETELY)){ 31304 $(SECTION_ACTIVE_SEL).addClass(COMPLETELY).siblings().removeClass(COMPLETELY); 31305 } 31306 } 31307 31308 //geting the last one, the current one on the screen 31309 currentSection = $(sections).eq(visibleSectionIndex); 31310 31311 //setting the visible section as active when manually scrolling 31312 //executing only once the first time we reach the section 31313 if(!currentSection.hasClass(ACTIVE)){ 31314 isScrolling = true; 31315 var leavingSection = $(SECTION_ACTIVE_SEL); 31316 var leavingSectionIndex = leavingSection.index(SECTION_SEL) + 1; 31317 var yMovement = getYmovement(currentSection); 31318 var anchorLink = currentSection.data('anchor'); 31319 var sectionIndex = currentSection.index(SECTION_SEL) + 1; 31320 var activeSlide = currentSection.find(SLIDE_ACTIVE_SEL); 31321 var slideIndex; 31322 var slideAnchorLink; 31323 31324 if(activeSlide.length){ 31325 slideAnchorLink = activeSlide.data('anchor'); 31326 slideIndex = activeSlide.index(); 31327 } 31328 31329 if(canScroll){ 31330 currentSection.addClass(ACTIVE).siblings().removeClass(ACTIVE); 31331 31332 $.isFunction( options.onLeave ) && options.onLeave.call( leavingSection, leavingSectionIndex, sectionIndex, yMovement); 31333 $.isFunction( options.afterLoad ) && options.afterLoad.call( currentSection, anchorLink, sectionIndex); 31334 31335 stopMedia(leavingSection); 31336 lazyLoad(currentSection); 31337 playMedia(currentSection); 31338 31339 activateMenuAndNav(anchorLink, sectionIndex - 1); 31340 31341 if(options.anchors.length){ 31342 //needed to enter in hashChange event when using the menu with anchor links 31343 lastScrolledDestiny = anchorLink; 31344 } 31345 setState(slideIndex, slideAnchorLink, anchorLink, sectionIndex); 31346 } 31347 31348 //small timeout in order to avoid entering in hashChange event when scrolling is not finished yet 31349 clearTimeout(scrollId); 31350 scrollId = setTimeout(function(){ 31351 isScrolling = false;
31352 }, 100); 31353 } 31354 31355 if(options.fitToSection){ 31356 //for the auto adjust of the viewport to fit a whole section 31357 clearTimeout(scrollId2); 31358 31359 scrollId2 = setTimeout(function(){ 31360 //checking it again in case it changed during the delay 31361 if(options.fitToSection){ 31362 fitToSection(); 31363 } 31364 }, options.fitToSectionDelay); 31365 } 31366 } 31367 } 31368 31369 /** 31370 * Fits the site to the nearest active section 31371 */ 31372 function fitToSection(){ 31373 //checking fitToSection again in case it was set to false before the timeout delay 31374 if(canScroll){ 31375 //allows to scroll to an active section and 31376 //if the section is already active, we prevent firing callbacks 31377 isResizing = true; 31378 31379 scrollPage($(SECTION_ACTIVE_SEL)); 31380 isResizing = false; 31381 } 31382 } 31383 31384 /** 31385 * Determines whether the active section has seen in its whole or not. 31386 */ 31387 function isCompletelyInViewPort(movement){ 31388 var top = $(SECTION_ACTIVE_SEL).position().top; 31389 var bottom = top + $window.height(); 31390 31391 if(movement == 'up'){ 31392 return bottom >= ($window.scrollTop() + $window.height()); 31393 } 31394 return top <= $window.scrollTop(); 31395 } 31396 31397 /** 31398 * Gets the directon of the the scrolling fired by the scroll event. 31399 */ 31400 function getScrollDirection(currentScroll){ 31401 var direction = currentScroll > lastScroll ? 'down' : 'up'; 31402 31403 lastScroll = currentScroll; 31404 31405 //needed for auto-height sections to determine if we want to scroll to the top or bottom of the destination 31406 previousDestTop = currentScroll; 31407 31408 return direction; 31409 } 31410 31411 /** 31412 * Determines the way of scrolling up or down: 31413 * by 'automatically' scrolling a section or by using the default and normal scrolling. 31414 */ 31415 function scrolling(type, scrollable){ 31416 if (!isScrollAllowed.m[type]){ 31417 return; 31418 } 31419 var check = (type === 'down') ? 'bottom' : 'top'; 31420 var scrollSection = (type === 'down') ? moveSectionDown : moveSectionUp; 31421 31422 if(scrollable.length > 0 ){ 31423 //is the scrollbar at the start/end of the scroll? 31424 if(options.scrollOverflowHandler.isScrolled(check, scrollable)){ 31425 scrollSection(); 31426 }else{ 31427 return true; 31428 } 31429 }else{ 31430 // moved up/down 31431 scrollSection(); 31432 } 31433 } 31434 31435 /* 31436 * Preventing bouncing in iOS #2285 31437 */ 31438 function preventBouncing(event){ 31439 var e = event.originalEvent; 31440 if(!checkParentForNormalScrollElement(event.target) && options.autoScrolling && isReallyTouch(e) && isScrollAllowed.m.up){ 31441 //preventing the easing on iOS devices 31442 event.preventDefault(); 31443 } 31444 } 31445 31446 var touchStartY = 0; 31447 var touchStartX = 0; 31448 var touchEndY = 0; 31449 var touchEndX = 0; 31450 31451 /* Detecting touch events 31452 31453 * As we are changing the top property of the page on scrolling, we can not use the traditional way to detect it. 31454 * This way, the touchstart and the touch moves shows an small difference between them which is the 31455 * used one to determine the direction. 31456 */ 31457 function touchMoveHandler(event){ 31458 var e = event.originalEvent; 31459 var activeSection = $(e.target).closest(SECTION_SEL); 31460 31461 // additional: if one of the normalScrollElements isn't within options.normalScrollElementTouchThreshold hops up the DOM chain 31462 if (!checkParentForNormalScrollElement(event.target) && isReallyTouch(e) ) { 31463 31464 if(options.autoScrolling){ 31465 //preventing the easing on iOS devices 31466 event.preventDefault(); 31467 } 31468 31469 var scrollable = options.scrollOverflowHandler.scrollable(activeSection); 31470 var touchEvents = getEventsPage(e); 31471 31472 touchEndY = touchEvents.y; 31473 touchEndX = touchEvents.x; 31474 31475 //if movement in the X axys is greater than in the Y and the currect section has slides... 31476 if (activeSection.find(SLIDES_WRAPPER_SEL).length && Math.abs(touchStartX - touchEndX) > (Math.abs(touchStartY - touchEndY))) { 31477 31478 //is the movement greater than the minimum resistance to scroll? 31479 if (!slideMoving && Math.abs(touchStartX - touchEndX) > ($window.outerWidth() / 100 * options.touchSensitivity)) { 31480 if (touchStartX > touchEndX) { 31481 if(isScrollAllowed.m.right){ 31482 moveSlideRight(activeSection); //next 31483 } 31484 } else { 31485 if(isScrollAllowed.m.left){ 31486 moveSlideLeft(activeSection); //prev 31487 } 31488 } 31489 } 31490 } 31491 31492 //vertical scrolling (only when autoScrolling is enabled) 31493 else if(options.autoScrolling && canScroll){ 31494 31495 //is the movement greater than the minimum resistance to scroll? 31496 if (Math.abs(touchStartY - touchEndY) > ($window.height() / 100 * options.touchSensitivity)) { 31497 if (touchStartY > touchEndY) { 31498 scrolling('down', scrollable); 31499 } else if (touchEndY > touchStartY) { 31500 scrolling('up', scrollable); 31501 } 31502 } 31503 } 31504 } 31505 } 31506 31507 /** 31508 * recursive function to loop up the parent nodes to check if one of them exists in options.normalScrollElements 31509 * Currently works well for iOS - Android might need some testing 31510 * @param {Element} el target element / jquery selector (in subsequent nodes) 31511 * @param {int} hop current hop compared to options.normalScrollElementTouchThreshold 31512 * @return {boolean} true if there is a match to options.normalScrollElements 31513 */ 31514 function checkParentForNormalScrollElement (el, hop) { 31515 hop = hop || 0; 31516 var parent = $(el).parent(); 31517 31518 if (hop < options.normalScrollElementTouchThreshold && 31519 parent.is(options.normalScrollElements) ) { 31520 return true; 31521 } else if (hop == options.normalScrollElementTouchThreshold) { 31522 return false;
31523 } else { 31524 return checkParentForNormalScrollElement(parent, ++hop); 31525 } 31526 } 31527 31528 /** 31529 * As IE >= 10 fires both touch and mouse events when using a mouse in a touchscreen 31530 * this way we make sure that is really a touch event what IE is detecting. 31531 */ 31532 function isReallyTouch(e){ 31533 //if is not IE || IE is detecting `touch` or `pen` 31534 return typeof e.pointerType === 'undefined' || e.pointerType != 'mouse'; 31535 } 31536 31537 /** 31538 * Handler for the touch start event. 31539 */ 31540 function touchStartHandler(event){ 31541 var e = event.originalEvent; 31542 31543 //stopping the auto scroll to adjust to a section 31544 if(options.fitToSection){ 31545 $htmlBody.stop(); 31546 } 31547 31548 if(isReallyTouch(e)){ 31549 var touchEvents = getEventsPage(e); 31550 touchStartY = touchEvents.y; 31551 touchStartX = touchEvents.x; 31552 } 31553 } 31554 31555 /** 31556 * Gets the average of the last `number` elements of the given array. 31557 */ 31558 function getAverage(elements, number){ 31559 var sum = 0; 31560 31561 //taking `number` elements from the end to make the average, if there are not enought, 1 31562 var lastElements = elements.slice(Math.max(elements.length - number, 1)); 31563 31564 for(var i = 0; i < lastElements.length; i++){ 31565 sum = sum + lastElements[i]; 31566 } 31567 31568 return Math.ceil(sum/number); 31569 } 31570 31571 /** 31572 * Detecting mousewheel scrolling 31573 * 31574 * http://blogs.sitepointstatic.com/examples/tech/mouse-wheel/index.html 31575 * http://www.sitepoint.com/html5-javascript-mouse-wheel/ 31576 */ 31577 var prevTime = new Date().getTime(); 31578 31579 function MouseWheelHandler(e) { 31580 var curTime = new Date().getTime(); 31581 var isNormalScroll = $(COMPLETELY_SEL).hasClass(NORMAL_SCROLL); 31582 31583 //autoscrolling and not zooming? 31584 if(options.autoScrolling && !controlPressed && !isNormalScroll){ 31585 // cross-browser wheel delta 31586 e = e || window.event; 31587 var value = e.wheelDelta || -e.deltaY || -e.detail; 31588 var delta = Math.max(-1, Math.min(1, value)); 31589 31590 var horizontalDetection = typeof e.wheelDeltaX !== 'undefined' || typeof e.deltaX !== 'undefined'; 31591 var isScrollingVertically = (Math.abs(e.wheelDeltaX) < Math.abs(e.wheelDelta)) || (Math.abs(e.deltaX ) < Math.abs(e.deltaY) || !horizontalDetection); 31592 31593 //Limiting the array to 150 (lets not waste memory!) 31594 if(scrollings.length > 149){ 31595 scrollings.shift(); 31596 } 31597 31598 //keeping record of the previous scrollings 31599 scrollings.push(Math.abs(value)); 31600 31601 //preventing to scroll the site on mouse wheel when scrollbar is present 31602 if(options.scrollBar){ 31603 e.preventDefault ? e.preventDefault() : e.returnValue = false; 31604 } 31605 31606 var activeSection = $(SECTION_ACTIVE_SEL); 31607 var scrollable = options.scrollOverflowHandler.scrollable(activeSection); 31608 31609 //time difference between the last scroll and the current one 31610 var timeDiff = curTime-prevTime; 31611 prevTime = curTime; 31612 31613 //haven't they scrolled in a while? 31614 //(enough to be consider a different scrolling action to scroll another section) 31615 if(timeDiff > 200){ 31616 //emptying the array, we dont care about old scrollings for our averages 31617 scrollings = []; 31618 } 31619 31620 if(canScroll){ 31621 var averageEnd = getAverage(scrollings, 10); 31622 var averageMiddle = getAverage(scrollings, 70); 31623 var isAccelerating = averageEnd >= averageMiddle; 31624 31625 //to avoid double swipes... 31626 if(isAccelerating && isScrollingVertically){ 31627 //scrolling down? 31628 if (delta < 0) { 31629 scrolling('down', scrollable); 31630 31631 //scrolling up? 31632 }else { 31633 scrolling('up', scrollable); 31634 } 31635 } 31636 } 31637 31638 return false;
31639 } 31640 31641 if(options.fitToSection){ 31642 //stopping the auto scroll to adjust to a section 31643 $htmlBody.stop(); 31644 } 31645 } 31646 31647 /** 31648 * Slides a slider to the given direction. 31649 * Optional `section` param. 31650 */ 31651 function moveSlide(direction, section){ 31652 var activeSection = typeof section === 'undefined' ? $(SECTION_ACTIVE_SEL) : section; 31653 var slides = activeSection.find(SLIDES_WRAPPER_SEL); 31654 var numSlides = slides.find(SLIDE_SEL).length; 31655 31656 // more than one slide needed and nothing should be sliding 31657 if (!slides.length || slideMoving || numSlides < 2) { 31658 return; 31659 } 31660 31661 var currentSlide = slides.find(SLIDE_ACTIVE_SEL); 31662 var destiny = null; 31663 31664 if(direction === 'left'){ 31665 destiny = currentSlide.prev(SLIDE_SEL); 31666 }else{ 31667 destiny = currentSlide.next(SLIDE_SEL); 31668 } 31669 31670 //isn't there a next slide in the secuence? 31671 if(!destiny.length){ 31672 //respect loopHorizontal settin 31673 if (!options.loopHorizontal) return; 31674 31675 if(direction === 'left'){ 31676 destiny = currentSlide.siblings(':last'); 31677 }else{ 31678 destiny = currentSlide.siblings(':first'); 31679 } 31680 } 31681 31682 slideMoving = true; 31683 31684 landscapeScroll(slides, destiny, direction); 31685 } 31686 31687 /** 31688 * Maintains the active slides in the viewport 31689 * (Because the `scroll` animation might get lost with some actions, such as when using continuousVertical) 31690 */ 31691 function keepSlidesPosition(){ 31692 $(SLIDE_ACTIVE_SEL).each(function(){ 31693 silentLandscapeScroll($(this), 'internal'); 31694 }); 31695 } 31696 31697 var previousDestTop = 0; 31698 /** 31699 * Returns the destination Y position based on the scrolling direction and 31700 * the height of the section. 31701 */ 31702 function getDestinationPosition(element){ 31703 var elemPosition = element.position(); 31704 31705 //top of the desination will be at the top of the viewport 31706 var position = elemPosition.top; 31707 var isScrollingDown = elemPosition.top > previousDestTop; 31708 var sectionBottom = position - windowsHeight + element.outerHeight(); 31709 var bigSectionsDestination = options.bigSectionsDestination; 31710 31711 //Uncode addition 31712 var containerH = container.outerHeight(); 31713 var containerPosition = container.offset(); 31714 31715 //########### Commented by Uncode - START ########### 31716 //is the destination element bigger than the viewport? 31717 // if(element.outerHeight() > windowsHeight){ 31718 // //scrolling up? 31719 // if(!isScrollingDown && !bigSectionsDestination || bigSectionsDestination === 'bottom' ){ 31720 // position = sectionBottom; 31721 // } 31722 // } 31723 31724 // //sections equal or smaller than the viewport height && scrolling down? || is resizing and its in the last section 31725 // else if(isScrollingDown || (isResizing && element.is(':last-child')) ){ 31726 // //The bottom of the destination will be at the bottom of the viewport 31727 // position = sectionBottom; 31728 // } 31729 //########### Commented by Uncode - END ########### 31730 31731 //Uncode addition 31732 if ( !$masthead.hasClass('menu-transparent') && $('body').hasClass('uncode-fp-menu-shrink') && !element.is(':first-child') ) 31733 position += 18; 31734 if ( ( containerH + menuHeight + bodyBorder + adminBarHeight - windowsHeight ) < position || ( isResizing && element.is(':last-child') ) ) { 31735 position = sectionBottom + menuHeight + bodyBorder*2 + adminBarHeight; 31736 } 31737 31738 /* 31739 Keeping record of the last scrolled position to determine the scrolling direction. 31740 No conventional methods can be used as the scroll bar might not be present 31741 AND the section might not be active if it is auto-height and didnt reach the middle 31742 of the viewport. 31743 */ 31744 previousDestTop = position; 31745 return position; 31746 } 31747 31748 /** 31749 * Scrolls the site to the given element and scrolls to the slide if a callback is given. 31750 */ 31751 function scrollPage(element, callback, isMovementUp){ 31752 if(typeof element === 'undefined'){ return; } //there's no element to scroll, leaving the function 31753 31754 var dtop = getDestinationPosition(element); 31755 var slideAnchorLink; 31756 var slideIndex; 31757 31758 //local variables 31759 var v = { 31760 element: element, 31761 callback: callback, 31762 isMovementUp: isMovementUp, 31763 dtop: dtop, 31764 yMovement: getYmovement(element), 31765 anchorLink: element.data('anchor'), 31766 sectionIndex: element.index(SECTION_SEL), 31767 activeSlide: element.find(SLIDE_ACTIVE_SEL), 31768 activeSection: $(SECTION_ACTIVE_SEL), 31769 leavingSection: $(SECTION_ACTIVE_SEL).index(SECTION_SEL) + 1, 31770 31771 //caching the value of isResizing at the momment the function is called 31772 //because it will be checked later inside a setTimeout and the value might change 31773 localIsResizing: isResizing 31774 }; 31775 31776 //quiting when destination scroll is the same as the current one 31777 if((v.activeSection.is(element) && !isResizing) || (options.scrollBar && $window.scrollTop() === v.dtop && !element.hasClass(AUTO_HEIGHT) )){ return; } 31778 31779 if(v.activeSlide.length){ 31780 slideAnchorLink = v.activeSlide.data('anchor'); 31781 slideIndex = v.activeSlide.index(); 31782 } 31783 31784 // If continuousVertical && we need to wrap around 31785 if (options.autoScrolling && options.continuousVertical && typeof (v.isMovementUp) !== "undefined" && 31786 ((!v.isMovementUp && v.yMovement == 'up') || // Intending to scroll down but about to go up or 31787 (v.isMovementUp && v.yMovement == 'down'))) { // intending to scroll up but about to go down 31788 31789 v = createInfiniteSections(v); 31790 } 31791 31792 //callback (onLeave) if the site is not just resizing and readjusting the slides 31793 if($.isFunction(options.onLeave) && !v.localIsResizing){ 31794 if(options.onLeave.call(v.activeSection, v.leavingSection, (v.sectionIndex + 1), v.yMovement) === false){ 31795 return; 31796 } 31797 } 31798 31799 //pausing media of the leaving section (if we are not just resizing, as destinatino will be the same one) 31800 if(!v.localIsResizing){ 31801 stopMedia(v.activeSection); 31802 } 31803 31804 options.scrollOverflowHandler.beforeLeave(); 31805 element.addClass(ACTIVE).siblings().removeClass(ACTIVE); 31806 lazyLoad(element); 31807 options.scrollOverflowHandler.onLeave(); 31808 31809 31810 //preventing from activating the MouseWheelHandler event 31811 //more than once if the page is scrolling 31812 canScroll = false;
31813 31814 setState(slideIndex, slideAnchorLink, v.anchorLink, v.sectionIndex); 31815 31816 performMovement(v); 31817 31818 //flag to avoid callingn `scrollPage()` twice in case of using anchor links 31819 lastScrolledDestiny = v.anchorLink; 31820 31821 //avoid firing it twice (as it does also on scroll) 31822 activateMenuAndNav(v.anchorLink, v.sectionIndex); 31823 } 31824 31825 /** 31826 * Performs the vertical movement (by CSS3 or by jQuery) 31827 */ 31828 function performMovement(v){ 31829 // using CSS3 translate functionality 31830 if (options.css3 && options.autoScrolling && !options.scrollBar) { 31831 31832 // The first section can have a negative value in iOS 10. Not quite sure why: -0.0142822265625 31833 // that's why we round it to 0. 31834 var translate3d = 'translate3d(0px, -' + Math.round(v.dtop) + 'px, 0px)'; 31835 transformContainer(translate3d, true); 31836 31837 //even when the scrollingSpeed is 0 there's a little delay, which might cause the 31838 //scrollingSpeed to change in case of using silentMoveTo(); 31839 if(options.scrollingSpeed){ 31840 clearTimeout(afterSectionLoadsId); 31841 afterSectionLoadsId = setTimeout(function () { 31842 afterSectionLoads(v); 31843 }, options.scrollingSpeed); 31844 }else{ 31845 afterSectionLoads(v); 31846 } 31847 } 31848 31849 // using jQuery animate 31850 else{ 31851 var scrollSettings = getScrollSettings(v); 31852 31853 $(scrollSettings.element).animate( 31854 scrollSettings.options, 31855 options.scrollingSpeed, options.easing).promise().done(function () { //only one single callback in case of animating `html, body` 31856 if(options.scrollBar){ 31857 31858 /* Hack! 31859 The timeout prevents setting the most dominant section in the viewport as "active" when the user 31860 scrolled to a smaller section by using the mousewheel (auto scrolling) rather than draging the scroll bar. 31861 31862 When using scrollBar:true It seems like the scroll events still getting propagated even after the scrolling animation has finished. 31863 */ 31864 setTimeout(function(){ 31865 afterSectionLoads(v); 31866 },30); 31867 }else{ 31868 afterSectionLoads(v); 31869 } 31870 }); 31871 } 31872 } 31873 31874 /** 31875 * Gets the scrolling settings depending on the plugin autoScrolling option 31876 */ 31877 function getScrollSettings(v){ 31878 var scroll = {}; 31879 31880 if(options.autoScrolling && !options.scrollBar){ 31881 scroll.options = { 'top': -v.dtop}; 31882 scroll.element = WRAPPER_SEL; 31883 }else{ 31884 scroll.options = { 'scrollTop': v.dtop}; 31885 scroll.element = 'html, body'; 31886 } 31887 31888 return scroll; 31889 } 31890 31891 /** 31892 * Adds sections before or after the current one to create the infinite effect. 31893 */ 31894 function createInfiniteSections(v){ 31895 // Scrolling down 31896 if (!v.isMovementUp) { 31897 // Move all previous sections to after the active section 31898 $(SECTION_ACTIVE_SEL).after(v.activeSection.prevAll(SECTION_SEL).get().reverse()); 31899 } 31900 else { // Scrolling up 31901 // Move all next sections to before the active section 31902 $(SECTION_ACTIVE_SEL).before(v.activeSection.nextAll(SECTION_SEL)); 31903 } 31904 31905 // Maintain the displayed position (now that we changed the element order) 31906 silentScroll($(SECTION_ACTIVE_SEL).position().top); 31907 31908 // Maintain the active slides visible in the viewport 31909 keepSlidesPosition(); 31910 31911 // save for later the elements that still need to be reordered 31912 v.wrapAroundElements = v.activeSection; 31913 31914 // Recalculate animation variables 31915 v.dtop = v.element.position().top; 31916 v.yMovement = getYmovement(v.element); 31917 31918 return v; 31919 } 31920 31921 /** 31922 * Fix section order after continuousVertical changes have been animated 31923 */ 31924 function continuousVerticalFixSectionOrder (v) {
31925 // If continuousVertical is in effect (and autoScrolling would also be in effect then), 31926 // finish moving the elements around so the direct navigation will function more simply 31927 if (!v.wrapAroundElements || !v.wrapAroundElements.length) { 31928 return; 31929 } 31930 31931 if (v.isMovementUp) { 31932 $(SECTION_FIRST_SEL).before(v.wrapAroundElements); 31933 } 31934 else { 31935 $(SECTION_LAST_SEL).after(v.wrapAroundElements); 31936 } 31937 31938 silentScroll($(SECTION_ACTIVE_SEL).position().top); 31939 31940 // Maintain the active slides visible in the viewport 31941 keepSlidesPosition(); 31942 } 31943 31944 31945 /** 31946 * Actions to do once the section is loaded. 31947 */ 31948 function afterSectionLoads (v){ 31949 continuousVerticalFixSectionOrder(v); 31950 31951 //callback (afterLoad) if the site is not just resizing and readjusting the slides 31952 $.isFunction(options.afterLoad) && !v.localIsResizing && options.afterLoad.call(v.element, v.anchorLink, (v.sectionIndex + 1)); 31953 options.scrollOverflowHandler.afterLoad(); 31954 31955 if(!v.localIsResizing){ 31956 playMedia(v.element); 31957 } 31958 31959 v.element.addClass(COMPLETELY).siblings().removeClass(COMPLETELY); 31960 31961 canScroll = true; 31962 31963 $.isFunction(v.callback) && v.callback.call(this); 31964 } 31965 31966 /** 31967 * Sets the value for the given attribute from the `data-` attribute with the same suffix 31968 * ie: data-srcset ==> srcset | data-src ==> src 31969 */ 31970 function setSrc(element, attribute){ 31971 element 31972 .attr(attribute, element.data(attribute)) 31973 .removeAttr('data-' + attribute); 31974 } 31975 31976 /** 31977 * Lazy loads image, video and audio elements. 31978 */ 31979 function lazyLoad(destiny){ 31980 if (!options.lazyLoading){ 31981 return; 31982 } 31983 31984 var panel = getSlideOrSection(destiny); 31985 var element; 31986 31987 panel.find('img[data-src], img[data-srcset], source[data-src], audio[data-src], iframe[data-src]').each(function(){ 31988 element = $(this); 31989 31990 $.each(['src', 'srcset'], function(index, type){ 31991 var attribute = element.attr('data-' + type); 31992 if(typeof attribute !== 'undefined' && attribute){ 31993 setSrc(element, type); 31994 } 31995 }); 31996 31997 if(element.is('source')){ 31998 element.closest('video').get(0).load(); 31999 } 32000 }); 32001 } 32002 32003 /** 32004 * Plays video and audio elements. 32005 */ 32006 function playMedia(destiny){ 32007 var panel = getSlideOrSection(destiny); 32008 32009 //playing HTML5 media elements 32010 panel.find('video, audio').each(function(){ 32011 var element = $(this).get(0); 32012 32013 if( element.hasAttribute('data-autoplay') && typeof element.play === 'function' ) { 32014 element.play(); 32015 } 32016 }); 32017 32018 //youtube videos 32019 panel.find('iframe[src*="youtube.com/embed/"]').each(function(){ 32020 var element = $(this).get(0); 32021 32022 if ( element.hasAttribute('data-autoplay') ){ 32023 playYoutube(element); 32024 } 32025 32026 //in case the URL was not loaded yet. On page load we need time for the new URL (with the API string) to load. 32027 element.onload = function() { 32028 if ( element.hasAttribute('data-autoplay') ){ 32029 playYoutube(element); 32030 } 32031 }; 32032 }); 32033 } 32034 32035 /** 32036 * Plays a youtube video 32037 */ 32038 function playYoutube(element){ 32039 element.contentWindow.postMessage('{"event":"command","func":"playVideo","args":""}', '*'); 32040 } 32041 32042 /** 32043 * Stops video and audio elements. 32044 */ 32045 function stopMedia(destiny){ 32046 var panel = getSlideOrSection(destiny); 32047 32048 //stopping HTML5 media elements 32049 panel.find('video, audio').each(function(){ 32050 var element = $(this).get(0); 32051 32052 if( !element.hasAttribute('data-keepplaying') && typeof element.pause === 'function' ) { 32053 element.pause(); 32054 } 32055 }); 32056 32057 //youtube videos 32058 panel.find('iframe[src*="youtube.com/embed/"]').each(function(){ 32059 var element = $(this).get(0); 32060 32061 if( /youtube\.com\/embed\//.test($(this).attr('src')) && !element.hasAttribute('data-keepplaying')){ 32062 $(this).get(0).contentWindow.postMessage('{"event":"command","func":"pauseVideo","args":""}','*'); 32063 } 32064 }); 32065 } 32066 32067 /** 32068 * Gets the active slide (or section) for the given section 32069 */ 32070 function getSlideOrSection(destiny){ 32071 var slide = destiny.find(SLIDE_ACTIVE_SEL); 32072 if( slide.length ) { 32073 destiny = $(slide); 32074 } 32075 32076 return destiny; 32077 } 32078 32079 /**
32080 * Scrolls to the anchor in the URL when loading the site 32081 */ 32082 function scrollToAnchor(){ 32083 //getting the anchor link in the URL and deleting the `#` 32084 var value = window.location.hash.replace('#', '').split('/'); 32085 var sectionAnchor = decodeURIComponent(value[0]); 32086 var slideAnchor = decodeURIComponent(value[1]); 32087 32088 if(sectionAnchor){ //if theres any # 32089 if(options.animateAnchor){ 32090 scrollPageAndSlide(sectionAnchor, slideAnchor); 32091 }else{ 32092 silentMoveTo(sectionAnchor, slideAnchor); 32093 } 32094 } 32095 } 32096 32097 /** 32098 * Detecting any change on the URL to scroll to the given anchor link 32099 * (a way to detect back history button as we play with the hashes on the URL) 32100 */ 32101 function hashChangeHandler(){ 32102 if(!isScrolling && !options.lockAnchors){ 32103 var value = window.location.hash.replace('#', '').split('/'); 32104 var sectionAnchor = decodeURIComponent(value[0]); 32105 var slideAnchor = decodeURIComponent(value[1]); 32106 32107 //when moving to a slide in the first section for the first time (first time to add an anchor to the URL) 32108 var isFirstSlideMove = (typeof lastScrolledDestiny === 'undefined'); 32109 var isFirstScrollMove = (typeof lastScrolledDestiny === 'undefined' && typeof slideAnchor === 'undefined' && !slideMoving); 32110 32111 32112 if(sectionAnchor.length){ 32113 /*in order to call scrollpage() only once for each destination at a time 32114 It is called twice for each scroll otherwise, as in case of using anchorlinks `hashChange` 32115 event is fired on every scroll too.*/ 32116 if ((sectionAnchor && sectionAnchor !== lastScrolledDestiny) && !isFirstSlideMove || isFirstScrollMove || (!slideMoving && lastScrolledSlide != slideAnchor )) { 32117 scrollPageAndSlide(sectionAnchor, slideAnchor); 32118 } 32119 } 32120 } 32121 } 32122 32123 //Sliding with arrow keys, both, vertical and horizontal 32124 function keydownHandler(e) { 32125 32126 clearTimeout(keydownId); 32127 32128 var activeElement = $(':focus'); 32129 32130 if(!activeElement.is('textarea') && !activeElement.is('input') && !activeElement.is('select') && 32131 activeElement.attr('contentEditable') !== "true" && activeElement.attr('contentEditable') !== '' && 32132 options.keyboardScrolling && options.autoScrolling){ 32133 var keyCode = e.which; 32134 32135 //preventing the scroll with arrow keys & spacebar & Page Up & Down keys 32136 var keyControls = [40, 38, 32, 33, 34]; 32137 if($.inArray(keyCode, keyControls) > -1){ 32138 e.preventDefault(); 32139 } 32140 32141 controlPressed = e.ctrlKey; 32142 32143 keydownId = setTimeout(function(){ 32144 onkeydown(e); 32145 },150); 32146 } 32147 } 32148 32149 function tooltipTextHandler(){ 32150 $(this).prev().trigger('click'); 32151 } 32152 32153 //to prevent scrolling while zooming 32154 function keyUpHandler(e){ 32155 if(isWindowFocused){ //the keyup gets fired on new tab ctrl + t in Firefox 32156 controlPressed = e.ctrlKey; 32157 } 32158 } 32159 32160 //binding the mousemove when the mouse's middle button is released 32161 function mouseDownHandler(e){ 32162 //middle button 32163 if (e.which == 2){ 32164 oldPageY = e.pageY; 32165 container.on('mousemove', mouseMoveHandler); 32166 } 32167 } 32168 32169 //unbinding the mousemove when the mouse's middle button is released 32170 function mouseUpHandler(e){ 32171 //middle button 32172 if (e.which == 2){ 32173 container.off('mousemove'); 32174 } 32175 } 32176 32177 //Scrolling horizontally when clicking on the slider controls. 32178 function slideArrowHandler(){ 32179 var section = $(this).closest(SECTION_SEL); 32180 32181 if ($(this).hasClass(SLIDES_PREV)) { 32182 if(isScrollAllowed.m.left){ 32183 moveSlideLeft(section); 32184 } 32185 } else { 32186 if(isScrollAllowed.m.right){ 32187 moveSlideRight(section); 32188 } 32189 } 32190 } 32191 32192 //when opening a new tab (ctrl + t), `control` won't be pressed when coming back. 32193 function blurHandler(){ 32194 isWindowFocused = false;
32195 controlPressed = false; 32196 } 32197 32198 //Scrolls to the section when clicking the navigation bullet 32199 function sectionBulletHandler(e){ 32200 e.preventDefault(); 32201 var index = $(this).parent().index(); 32202 scrollPage($(SECTION_SEL).eq(index)); 32203 } 32204 32205 //Scrolls the slider to the given slide destination for the given section 32206 function slideBulletHandler(e){ 32207 e.preventDefault(); 32208 var slides = $(this).closest(SECTION_SEL).find(SLIDES_WRAPPER_SEL); 32209 var destiny = slides.find(SLIDE_SEL).eq($(this).closest('li').index()); 32210 32211 landscapeScroll(slides, destiny); 32212 } 32213 32214 /** 32215 * Keydown event 32216 */ 32217 function onkeydown(e){ 32218 var shiftPressed = e.shiftKey; 32219 32220 //do nothing if we can not scroll or we are not using horizotnal key arrows. 32221 if(!canScroll && [37,39].indexOf(e.which) < 0){ 32222 return; 32223 } 32224 32225 switch (e.which) { 32226 //up 32227 case 38: 32228 case 33: 32229 if(isScrollAllowed.k.up){ 32230 moveSectionUp(); 32231 } 32232 break; 32233 32234 //down 32235 case 32: //spacebar 32236 if(shiftPressed && isScrollAllowed.k.up){ 32237 moveSectionUp(); 32238 break; 32239 } 32240 /* falls through */ 32241 case 40: 32242 case 34: 32243 if(isScrollAllowed.k.down){ 32244 moveSectionDown(); 32245 } 32246 break; 32247 32248 //Home 32249 case 36: 32250 if(isScrollAllowed.k.up){ 32251 moveTo(1); 32252 } 32253 break; 32254 32255 //End 32256 case 35: 32257 if(isScrollAllowed.k.down){ 32258 moveTo( $(SECTION_SEL).length ); 32259 } 32260 break; 32261 32262 //left 32263 case 37: 32264 if(isScrollAllowed.k.left){ 32265 moveSlideLeft(); 32266 } 32267 break; 32268 32269 //right 32270 case 39: 32271 if(isScrollAllowed.k.right){ 32272 moveSlideRight(); 32273 } 32274 break; 32275 32276 default: 32277 return; // exit this handler for other keys 32278 } 32279 } 32280 32281 /** 32282 * Detecting the direction of the mouse movement. 32283 * Used only for the middle button of the mouse. 32284 */ 32285 var oldPageY = 0; 32286 function mouseMoveHandler(e){ 32287 if(canScroll){ 32288 // moving up 32289 if (e.pageY < oldPageY && isScrollAllowed.m.up){ 32290 moveSectionUp(); 32291 } 32292 32293 // moving down 32294 else if(e.pageY > oldPageY && isScrollAllowed.m.down){ 32295 moveSectionDown(); 32296 } 32297 } 32298 oldPageY = e.pageY; 32299 } 32300 32301 /** 32302 * Scrolls horizontal sliders. 32303 */ 32304 function landscapeScroll(slides, destiny, direction){ 32305 var section = slides.closest(SECTION_SEL); 32306 var v = { 32307 slides: slides, 32308 destiny: destiny, 32309 direction: direction, 32310 destinyPos: destiny.position(), 32311 slideIndex: destiny.index(), 32312 section: section, 32313 sectionIndex: section.index(SECTION_SEL), 32314 anchorLink: section.data('anchor'), 32315 slidesNav: section.find(SLIDES_NAV_SEL), 32316 slideAnchor: getAnchor(destiny), 32317 prevSlide: section.find(SLIDE_ACTIVE_SEL), 32318 prevSlideIndex: section.find(SLIDE_ACTIVE_SEL).index(), 32319 32320 //caching the value of isResizing at the momment the function is called 32321 //because it will be checked later inside a setTimeout and the value might change 32322 localIsResizing: isResizing 32323 }; 32324 v.xMovement = getXmovement(v.prevSlideIndex, v.slideIndex); 32325 v.direction = v.direction ? v.direction : v.xMovement; 32326 32327 //important!! Only do it when not resizing 32328 if(!v.localIsResizing){ 32329 //preventing from scrolling to the next/prev section when using scrollHorizontally 32330 canScroll = false;
32331 } 32332 32333 if(options.onSlideLeave){ 32334 32335 //if the site is not just resizing and readjusting the slides 32336 if(!v.localIsResizing && v.xMovement!=='none'){ 32337 if($.isFunction( options.onSlideLeave )){ 32338 if(options.onSlideLeave.call( v.prevSlide, v.anchorLink, (v.sectionIndex + 1), v.prevSlideIndex, v.xMovement, v.slideIndex ) === false){ 32339 slideMoving = false; 32340 return; 32341 } 32342 } 32343 } 32344 } 32345 32346 destiny.addClass(ACTIVE).siblings().removeClass(ACTIVE); 32347 32348 if(!v.localIsResizing){ 32349 stopMedia(v.prevSlide); 32350 lazyLoad(destiny); 32351 } 32352 32353 if(!options.loopHorizontal && options.controlArrows){ 32354 //hidding it for the fist slide, showing for the rest 32355 section.find(SLIDES_ARROW_PREV_SEL).toggle(v.slideIndex!==0); 32356 32357 //hidding it for the last slide, showing for the rest 32358 section.find(SLIDES_ARROW_NEXT_SEL).toggle(!destiny.is(':last-child')); 32359 } 32360 32361 //only changing the URL if the slides are in the current section (not for resize re-adjusting) 32362 if(section.hasClass(ACTIVE) && !v.localIsResizing){ 32363 setState(v.slideIndex, v.slideAnchor, v.anchorLink, v.sectionIndex); 32364 } 32365 32366 performHorizontalMove(slides, v, true); 32367 } 32368 32369 32370 function afterSlideLoads(v){ 32371 activeSlidesNavigation(v.slidesNav, v.slideIndex); 32372 32373 //if the site is not just resizing and readjusting the slides 32374 if(!v.localIsResizing){ 32375 $.isFunction( options.afterSlideLoad ) && options.afterSlideLoad.call( v.destiny, v.anchorLink, (v.sectionIndex + 1), v.slideAnchor, v.slideIndex); 32376 32377 //needs to be inside the condition to prevent problems with continuousVertical and scrollHorizontally 32378 //and to prevent double scroll right after a windows resize 32379 canScroll = true; 32380 32381 playMedia(v.destiny); 32382 } 32383 32384 //letting them slide again 32385 slideMoving = false; 32386 } 32387 32388 /** 32389 * Performs the horizontal movement. (CSS3 or jQuery) 32390 * 32391 * @param fireCallback {Bool} - determines whether or not to fire the callback 32392 */ 32393 function performHorizontalMove(slides, v, fireCallback){ 32394 var destinyPos = v.destinyPos; 32395 32396 if(options.css3){ 32397 var translate3d = 'translate3d(-' + Math.round(destinyPos.left) + 'px, 0px, 0px)'; 32398 32399 addAnimation(slides.find(SLIDES_CONTAINER_SEL)).css(getTransforms(translate3d), v); 32400 32401 afterSlideLoadsId = setTimeout(function(){ 32402 fireCallback && afterSlideLoads(v); 32403 }, options.scrollingSpeed, options.easing); 32404 }else{ 32405 slides.animate({ 32406 scrollLeft : Math.round(destinyPos.left) 32407 }, options.scrollingSpeed, options.easing, function() { 32408 32409 fireCallback && afterSlideLoads(v); 32410 }); 32411 } 32412 } 32413 32414 /** 32415 * Sets the state for the horizontal bullet navigations. 32416 */ 32417 function activeSlidesNavigation(slidesNav, slideIndex){ 32418 slidesNav.find(ACTIVE_SEL).removeClass(ACTIVE); 32419 slidesNav.find('li').eq(slideIndex).find('a').addClass(ACTIVE); 32420 } 32421 32422 var previousHeight = windowsHeight; 32423 32424 //when resizing the site, we adjust the heights of the sections, slimScroll... 32425 function resizeHandler(){ 32426 //checking if it needs to get responsive 32427 responsive(); 32428 32429 // rebuild immediately on touch devices 32430 if (isTouchDevice) { 32431 var activeElement = $(document.activeElement); 32432 32433 //if the keyboard is NOT visible 32434 if (!activeElement.is('textarea') && !activeElement.is('input') && !activeElement.is('select')) { 32435 var currentHeight = $window.height(); 32436 32437 //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) 32438 if( Math.abs(currentHeight - previousHeight) > (20 * Math.max(previousHeight, currentHeight) / 100) ){ 32439 reBuild(true); 32440 previousHeight = currentHeight; 32441 } 32442 } 32443 }else{ 32444 //in order to call the functions only when the resize is finished 32445 //http://stackoverflow.com/questions/4298612/jquery-how-to-call-resize-event-only-once-its-finished-resizing 32446 clearTimeout(resizeId); 32447 32448 resizeId = setTimeout(function(){ 32449 reBuild(true); 32450 }, 350); 32451 } 32452 } 32453 32454 /** 32455 * Checks if the site needs to get responsive and disables autoScrolling if so. 32456 * A class `fp-responsive` is added to the plugin's container in case the user wants to use it for his own responsive CSS. 32457 */ 32458 function responsive(){ 32459 var widthLimit = options.responsive || options.responsiveWidth; //backwards compatiblity 32460 var heightLimit = options.responsiveHeight; 32461 32462 //only calculating what we need. Remember its called on the resize event. 32463 var isBreakingPointWidth = widthLimit && $window.outerWidth() < widthLimit; 32464 var isBreakingPointHeight = heightLimit && $window.height() < heightLimit; 32465 32466 if(widthLimit && heightLimit){ 32467 setResponsive(isBreakingPointWidth || isBreakingPointHeight); 32468 } 32469 else if(widthLimit){ 32470 setResponsive(isBreakingPointWidth); 32471 } 32472 else if(heightLimit){ 32473 setResponsive(isBreakingPointHeight); 32474 } 32475 } 32476 32477 /** 32478 * Adds transition animations for the given element 32479 */ 32480 function addAnimation(container, element){ 32481 var transition = 'all ' + options.scrollingSpeed + 'ms ' + options.easingcss3; 32482 32483 container.removeClass(NO_TRANSITION); 32484 return container.css({
32485 '-webkit-transition': transition, 32486 'transition': transition 32487 }); 32488 } 32489 32490 /** 32491 * Remove transition animations for the given element 32492 */ 32493 function removeAnimation(element){ 32494 return element.addClass(NO_TRANSITION); 32495 } 32496 32497 /** 32498 * Activating the vertical navigation bullets according to the given slide name. 32499 */ 32500 function activateNavDots(name, sectionIndex){ 32501 if(options.navigation){ 32502 $(SECTION_NAV_SEL).find(ACTIVE_SEL).removeClass(ACTIVE); 32503 if(name){ 32504 $(SECTION_NAV_SEL).find('a[href="#' + name + '"]').addClass(ACTIVE); 32505 }else{ 32506 $(SECTION_NAV_SEL).find('li').eq(sectionIndex).find('a').addClass(ACTIVE); 32507 } 32508 } 32509 } 32510 32511 /** 32512 * Activating the website main menu elements according to the given slide name. 32513 */ 32514 function activateMenuElement(name){ 32515 if(options.menu){ 32516 $(options.menu).find(ACTIVE_SEL).removeClass(ACTIVE); 32517 $(options.menu).find('[data-menuanchor="'+name+'"]').addClass(ACTIVE); 32518 } 32519 } 32520 32521 /** 32522 * Sets to active the current menu and vertical nav items. 32523 */ 32524 function activateMenuAndNav(anchor, index){ 32525 activateMenuElement(anchor); 32526 activateNavDots(anchor, index); 32527 } 32528 32529 /** 32530 * Retuns `up` or `down` depending on the scrolling movement to reach its destination 32531 * from the current section. 32532 */ 32533 function getYmovement(destiny){ 32534 var fromIndex = $(SECTION_ACTIVE_SEL).index(SECTION_SEL); 32535 var toIndex = destiny.index(SECTION_SEL); 32536 if( fromIndex == toIndex){ 32537 return 'none'; 32538 } 32539 if(fromIndex > toIndex){ 32540 return 'up'; 32541 } 32542 return 'down'; 32543 } 32544 32545 /** 32546 * Retuns `right` or `left` depending on the scrolling movement to reach its destination 32547 * from the current slide. 32548 */ 32549 function getXmovement(fromIndex, toIndex){ 32550 if( fromIndex == toIndex){ 32551 return 'none'; 32552 } 32553 if(fromIndex > toIndex){ 32554 return 'left'; 32555 } 32556 return 'right'; 32557 } 32558 32559 /** 32560 * Checks if the element needs scrollbar and if the user wants to apply it. 32561 * If so it creates it. 32562 * 32563 * @param {Object} element jQuery object of the section or slide 32564 */ 32565 function createScrollBar(element){ 32566 //User doesn't want scrollbar here? Sayonara baby! 32567 if(element.hasClass('fp-noscroll')) return; 32568 32569 //needed to make `scrollHeight` work under Opera 12 32570 element.css('overflow', 'hidden'); 32571 32572 var scrollOverflowHandler = options.scrollOverflowHandler; 32573 var wrap = scrollOverflowHandler.wrapContent(); 32574 //in case element is a slide 32575 var section = element.closest(SECTION_SEL); 32576 var scrollable = scrollOverflowHandler.scrollable(element); 32577 var contentHeight; 32578 32579 //if there was scroll, the contentHeight will be the one in the scrollable section 32580 if(scrollable.length){ 32581 contentHeight = scrollOverflowHandler.scrollHeight(element); 32582 }else{ 32583 contentHeight = element.get(0).scrollHeight; 32584 if(options.verticalCentered){ 32585 contentHeight = element.find(TABLE_CELL_SEL).get(0).scrollHeight; 32586 } 32587 } 32588 32589 var scrollHeight = windowsHeight - parseInt(section.css('padding-bottom')) - parseInt(section.css('padding-top')); 32590 32591 //needs scroll? 32592 if ( contentHeight > scrollHeight) { 32593 //did we already have an scrollbar ? Updating it 32594 if(scrollable.length){ 32595 scrollOverflowHandler.update(element, scrollHeight); 32596 } 32597 //creating the scrolling 32598 else{ 32599 if(options.verticalCentered){ 32600 element.find(TABLE_CELL_SEL).wrapInner(wrap); 32601 }else{ 32602 element.wrapInner(wrap); 32603 } 32604 scrollOverflowHandler.create(element, scrollHeight); 32605 } 32606 } 32607 //removing the scrolling when it is not necessary anymore 32608 else{ 32609 scrollOverflowHandler.remove(element); 32610 } 32611 32612 //undo 32613 element.css('overflow', ''); 32614 } 32615 32616 function addTableClass(element){ 32617 //In case we are styling for the 2nd time as in with reponsiveSlides 32618 if(!element.hasClass(TABLE)){ 32619 element.addClass(TABLE).wrapInner('<div class="' + TABLE_CELL + '" style="height:' + getTableHeight(element) + 'px;" />'); 32620 } 32621 } 32622 32623 function getTableHeight(element){ 32624 var sectionHeight = windowsHeight; 32625 32626 if(options.paddingTop || options.paddingBottom){ 32627 var section = element; 32628 if(!section.hasClass(SECTION)){ 32629 section = element.closest(SECTION_SEL); 32630 } 32631 32632 var paddings = parseInt(section.css('padding-top')) + parseInt(section.css('padding-bottom')); 32633 sectionHeight = (windowsHeight - paddings); 32634 } 32635 32636 return sectionHeight; 32637 } 32638 32639 /** 32640 * Adds a css3 transform property to the container class with or without animation depending on the animated param. 32641 */ 32642 function transformContainer(translate3d, animated){ 32643 if(animated){ 32644 addAnimation(container); 32645 }else{ 32646 removeAnimation(container); 32647 } 32648 32649 container.css(getTransforms(translate3d)); 32650 32651 //syncronously removing the class after the animation has been applied. 32652 setTimeout(function(){ 32653 container.removeClass(NO_TRANSITION); 32654 },10); 32655 } 32656 32657 /** 32658 * Gets a section by its anchor / index 32659 */ 32660 function getSectionByAnchor(sectionAnchor){ 32661 if(!sectionAnchor) return []; 32662 32663 var section = container.find(SECTION_SEL + '[data-anchor="'+sectionAnchor+'"]'); 32664 if(!section.length){ 32665 section = $(SECTION_SEL).eq( sectionAnchor -1); 32666 } 32667 32668 return section; 32669 } 32670 32671 /** 32672 * Gets a slide inside a given section by its anchor / index 32673 */ 32674 function getSlideByAnchor(slideAnchor, section){ 32675 var slides = section.find(SLIDES_WRAPPER_SEL); 32676 var slide = slides.find(SLIDE_SEL + '[data-anchor="'+slideAnchor+'"]'); 32677
32678 if(!slide.length){ 32679 slide = slides.find(SLIDE_SEL).eq(slideAnchor); 32680 } 32681 32682 return slide; 32683 } 32684 32685 /** 32686 * Scrolls to the given section and slide anchors 32687 */ 32688 function scrollPageAndSlide(destiny, slide){ 32689 var section = getSectionByAnchor(destiny); 32690 32691 //do nothing if there's no section with the given anchor name 32692 if(!section.length) return; 32693 32694 //default slide 32695 if (typeof slide === 'undefined') { 32696 slide = 0; 32697 } 32698 32699 //we need to scroll to the section and then to the slide 32700 if (destiny !== lastScrolledDestiny && !section.hasClass(ACTIVE)){ 32701 scrollPage(section, function(){ 32702 scrollSlider(section, slide); 32703 }); 32704 } 32705 //if we were already in the section 32706 else{ 32707 scrollSlider(section, slide); 32708 } 32709 } 32710 32711 /** 32712 * Scrolls the slider to the given slide destination for the given section 32713 */ 32714 function scrollSlider(section, slideAnchor){ 32715 if(typeof slideAnchor !== 'undefined'){ 32716 var slides = section.find(SLIDES_WRAPPER_SEL); 32717 var destiny = getSlideByAnchor(slideAnchor, section); 32718 32719 if(destiny.length){ 32720 landscapeScroll(slides, destiny); 32721 } 32722 } 32723 } 32724 32725 /** 32726 * Creates a landscape navigation bar with dots for horizontal sliders. 32727 */ 32728 function addSlidesNavigation(section, numSlides){ 32729 section.append('<div class="' + SLIDES_NAV + '"><ul></ul></div>'); 32730 var nav = section.find(SLIDES_NAV_SEL); 32731 32732 //top or bottom 32733 nav.addClass(options.slidesNavPosition); 32734 32735 for(var i=0; i< numSlides; i++){ 32736 nav.find('ul').append('<li><a href="#"><span></span></a></li>'); 32737 } 32738 32739 //centering it 32740 nav.css('margin-left', '-' + (nav.width()/2) + 'px'); 32741 32742 nav.find('li').first().find('a').addClass(ACTIVE); 32743 } 32744 32745 32746 /** 32747 * Sets the state of the website depending on the active section/slide. 32748 * It changes the URL hash when needed and updates the body class. 32749 */ 32750 function setState(slideIndex, slideAnchor, anchorLink, sectionIndex){ 32751 var sectionHash = ''; 32752 32753 if(options.anchors.length && !options.lockAnchors){ 32754 32755 //isn't it the first slide? 32756 if(slideIndex){ 32757 if(typeof anchorLink !== 'undefined'){ 32758 sectionHash = anchorLink; 32759 } 32760 32761 //slide without anchor link? We take the index instead. 32762 if(typeof slideAnchor === 'undefined'){ 32763 slideAnchor = slideIndex; 32764 } 32765 32766 lastScrolledSlide = slideAnchor; 32767 setUrlHash(sectionHash + '/' + slideAnchor); 32768 32769 //first slide won't have slide anchor, just the section one 32770 }else if(typeof slideIndex !== 'undefined'){ 32771 lastScrolledSlide = slideAnchor; 32772 setUrlHash(anchorLink); 32773 } 32774 32775 //section without slides 32776 else{ 32777 setUrlHash(anchorLink); 32778 } 32779 } 32780 32781 setBodyClass(); 32782 } 32783 32784 /** 32785 * Sets the URL hash. 32786 */ 32787 function setUrlHash(url){ 32788 //Uncode addition 32789 if ( typeof SiteParameters.slide_footer != 'undefined' && url == SiteParameters.slide_footer ) 32790 return false; 32791 32792 if(options.recordHistory){ 32793 location.hash = url; 32794 }else{ 32795 //Uncode addition 32796 //Mobile Chrome doesn't work the normal way, so... lets use HTML5 for phones :) 32797 // if(isTouchDevice || isTouch){ 32798 // window.history.replaceState(undefined, undefined, '#' + url); 32799 // }else{ 32800 // var baseUrl = window.location.href.split('#')[0]; 32801 // window.location.replace( baseUrl + '#' + url ); 32802 // } 32803 return false;
32804 } 32805 } 32806 32807 /** 32808 * Gets the anchor for the given slide / section. Its index will be used if there's none. 32809 */ 32810 function getAnchor(element){ 32811 var anchor = element.data('anchor'); 32812 var index = element.index(); 32813 32814 //Slide without anchor link? We take the index instead. 32815 if(typeof anchor === 'undefined'){ 32816 anchor = index; 32817 } 32818 32819 return anchor; 32820 } 32821 32822 /** 32823 * Sets a class for the body of the page depending on the active section / slide 32824 */ 32825 function setBodyClass(){ 32826 var section = $(SECTION_ACTIVE_SEL); 32827 var slide = section.find(SLIDE_ACTIVE_SEL); 32828 32829 var sectionAnchor = getAnchor(section); 32830 var slideAnchor = getAnchor(slide); 32831 32832 var text = String(sectionAnchor); 32833 32834 if(slide.length){ 32835 text = text + '-' + slideAnchor; 32836 } 32837 32838 //changing slash for dash to make it a valid CSS style 32839 text = text.replace('/', '-').replace('#',''); 32840 32841 //removing previous anchor classes 32842 var classRe = new RegExp('\\b\\s?' + VIEWING_PREFIX + '-[^\\s]+\\b', "g"); 32843 $body[0].className = $body[0].className.replace(classRe, ''); 32844 32845 //adding the current anchor 32846 $body.addClass(VIEWING_PREFIX + '-' + text); 32847 } 32848 32849 /** 32850 * Checks for translate3d support 32851 * @return boolean 32852 * http://stackoverflow.com/questions/5661671/detecting-transform-translate3d-support 32853 */ 32854 function support3d() { 32855 var el = document.createElement('p'), 32856 has3d, 32857 transforms = { 32858 'webkitTransform':'-webkit-transform', 32859 'OTransform':'-o-transform', 32860 'msTransform':'-ms-transform', 32861 'MozTransform':'-moz-transform', 32862 'transform':'transform' 32863 }; 32864 32865 // Add it to the body to get the computed style. 32866 document.body.insertBefore(el, null); 32867 32868 for (var t in transforms) { 32869 if (el.style[t] !== undefined) { 32870 el.style[t] = 'translate3d(1px,1px,1px)'; 32871 has3d = window.getComputedStyle(el).getPropertyValue(transforms[t]); 32872 } 32873 } 32874 32875 document.body.removeChild(el); 32876 32877 return (has3d !== undefined && has3d.length > 0 && has3d !== 'none'); 32878 } 32879 32880 /** 32881 * Removes the auto scrolling action fired by the mouse wheel and trackpad. 32882 * After this function is called, the mousewheel and trackpad movements won't scroll through sections. 32883 */ 32884 function removeMouseWheelHandler(){ 32885 if (document.addEventListener) { 32886 document.removeEventListener('mousewheel', MouseWheelHandler, false); //IE9, Chrome, Safari, Oper 32887 document.removeEventListener('wheel', MouseWheelHandler, false); //Firefox 32888 document.removeEventListener('MozMousePixelScroll', MouseWheelHandler, false); //old Firefox 32889 } else { 32890 document.detachEvent('onmousewheel', MouseWheelHandler); //IE 6/7/8 32891 } 32892 } 32893 32894 /** 32895 * Adds the auto scrolling action for the mouse wheel and trackpad. 32896 * After this function is called, the mousewheel and trackpad movements will scroll through sections 32897 * https://developer.mozilla.org/en-US/docs/Web/Events/wheel 32898 */ 32899 function addMouseWheelHandler(){ 32900 var prefix = ''; 32901 var _addEventListener; 32902 32903 if (window.addEventListener){ 32904 _addEventListener = "addEventListener"; 32905 }else{ 32906 _addEventListener = "attachEvent"; 32907 prefix = 'on'; 32908 } 32909 32910 // detect available wheel event 32911 var support = 'onwheel' in document.createElement('div') ? 'wheel' : // Modern browsers support "wheel" 32912 document.onmousewheel !== undefined ? 'mousewheel' : // Webkit and IE support at least "mousewheel" 32913 'DOMMouseScroll'; // let's assume that remaining browsers are older Firefox 32914 var passiveEvent = g_supportsPassive ? {passive: false }
32914: false; 32915 32916 32917 if(support == 'DOMMouseScroll'){ 32918 document[ _addEventListener ](prefix + 'MozMousePixelScroll', MouseWheelHandler, passiveEvent); 32919 } 32920 32921 //handle MozMousePixelScroll in older Firefox 32922 else{ 32923 document[ _addEventListener ](prefix + support, MouseWheelHandler, passiveEvent); 32924 } 32925 } 32926 32927 /** 32928 * Binding the mousemove when the mouse's middle button is pressed 32929 */ 32930 function addMiddleWheelHandler(){ 32931 container 32932 .on('mousedown', mouseDownHandler) 32933 .on('mouseup', mouseUpHandler); 32934 } 32935 32936 /** 32937 * Unbinding the mousemove when the mouse's middle button is released 32938 */ 32939 function removeMiddleWheelHandler(){ 32940 container 32941 .off('mousedown', mouseDownHandler) 32942 .off('mouseup', mouseUpHandler); 32943 } 32944 32945 /** 32946 * Adds the possibility to auto scroll through sections on touch devices. 32947 */ 32948 function addTouchHandler(){ 32949 if(isTouchDevice || isTouch){ 32950 if(options.autoScrolling){ 32951 $body.off(events.touchmove).on(events.touchmove, preventBouncing); 32952 } 32953 32954 $(WRAPPER_SEL) 32955 .off(events.touchstart).on(events.touchstart, touchStartHandler) 32956 .off(events.touchmove).on(events.touchmove, touchMoveHandler); 32957 } 32958 } 32959 32960 /** 32961 * Removes the auto scrolling for touch devices. 32962 */ 32963 function removeTouchHandler(){ 32964 if(isTouchDevice || isTouch){ 32965 $(WRAPPER_SEL) 32966 .off(events.touchstart) 32967 .off(events.touchmove); 32968 } 32969 } 32970 32971 /* 32972 * Returns and object with Microsoft pointers (for IE<11 and for IE >= 11) 32973 * http://msdn.microsoft.com/en-us/library/ie/dn304886(v=vs.85).aspx 32974 */ 32975 function getMSPointer(){ 32976 var pointer; 32977 32978 //IE >= 11 & rest of browsers 32979 if(window.PointerEvent){ 32980 pointer = { down: 'pointerdown', move: 'pointermove'}; 32981 } 32982 32983 //IE < 11 32984 else{ 32985 pointer = { down: 'MSPointerDown', move: 'MSPointerMove'}; 32986 } 32987 32988 return pointer; 32989 } 32990 32991 /** 32992 * Gets the pageX and pageY properties depending on the browser. 32993 * https://github.com/alvarotrigo/fullPage.js/issues/194#issuecomment-34069854 32994 */ 32995 function getEventsPage(e){ 32996 var events = []; 32997 32998 events.y = (typeof e.pageY !== 'undefined' && (e.pageY || e.pageX) ? e.pageY : e.touches[0].pageY); 32999 events.x = (typeof e.pageX !== 'undefined' && (e.pageY || e.pageX) ? e.pageX : e.touches[0].pageX); 33000 33001 //in touch devices with scrollBar:true, e.pageY is detected, but we have to deal with touch events. #1008 33002 if(isTouch && isReallyTouch(e) && options.scrollBar){ 33003 events.y = e.touches[0].pageY; 33004 events.x = e.touches[0].pageX; 33005 } 33006 33007 return events; 33008 } 33009 33010 /** 33011 * Slides silently (with no animation) the active slider to the given slide. 33012 * @param noCallback {bool} true or defined -> no callbacks 33013 */ 33014 function silentLandscapeScroll(activeSlide, noCallbacks){ 33015 setScrollingSpeed (0, 'internal'); 33016 33017 if(typeof noCallbacks !== 'undefined'){ 33018 //preventing firing callbacks afterSlideLoad etc. 33019 isResizing = true; 33020 } 33021 33022 landscapeScroll(activeSlide.closest(SLIDES_WRAPPER_SEL), activeSlide); 33023 33024 if(typeof noCallbacks !== 'undefined'){ 33025 isResizing = false; 33026 } 33027 33028 setScrollingSpeed(originals.scrollingSpeed, 'internal'); 33029 } 33030 33031 /** 33032 * Scrolls silently (with no animation) the page to the given Y position. 33033 */ 33034 function silentScroll(top){ 33035 // The first section can have a negative value in iOS 10. Not quite sure why: -0.0142822265625 33036 // that's why we round it to 0. 33037 var roundedTop = Math.round(top); 33038 33039 if (options.css3 && options.autoScrolling && !options.scrollBar){ 33040 var translate3d = 'translate3d(0px, -' + roundedTop + 'px, 0px)'; 33041 transformContainer(translate3d, false); 33042 } 33043 else if(options.autoScrolling && !options.scrollBar){ 33044 container.css('top', -roundedTop); 33045 } 33046 else{ 33047 $htmlBody.scrollTop(roundedTop); 33048 } 33049 } 33050 33051 /** 33052 * Returns the cross-browser transform string. 33053 */ 33054 function getTransforms(translate3d){ 33055 return {
33056 '-webkit-transform': translate3d, 33057 '-moz-transform': translate3d, 33058 '-ms-transform':translate3d, 33059 'transform': translate3d 33060 }; 33061 } 33062 33063 /** 33064 * Allowing or disallowing the mouse/swipe scroll in a given direction. (not for keyboard) 33065 * @type m (mouse) or k (keyboard) 33066 */ 33067 function setIsScrollAllowed(value, direction, type){ 33068 switch (direction){ 33069 case 'up': isScrollAllowed[type].up = value; break; 33070 case 'down': isScrollAllowed[type].down = value; break; 33071 case 'left': isScrollAllowed[type].left = value; break; 33072 case 'right': isScrollAllowed[type].right = value; break; 33073 case 'all': 33074 if(type == 'm'){ 33075 setAllowScrolling(value); 33076 }else{ 33077 setKeyboardScrolling(value); 33078 } 33079 } 33080 } 33081 33082 /* 33083 * Destroys fullpage.js plugin events and optinally its html markup and styles 33084 */ 33085 function destroy(all){ 33086 setAutoScrolling(false, 'internal'); 33087 setAllowScrolling(false); 33088 setKeyboardScrolling(false); 33089 container.addClass(DESTROYED); 33090 33091 clearTimeout(afterSlideLoadsId); 33092 clearTimeout(afterSectionLoadsId); 33093 clearTimeout(resizeId); 33094 clearTimeout(scrollId); 33095 clearTimeout(scrollId2); 33096 33097 $window 33098 .off('scroll', scrollHandler) 33099 .off('hashchange', hashChangeHandler) 33100 .off('resize', resizeHandler); 33101 33102 $document 33103 .off('click touchstart', SECTION_NAV_SEL + ' a') 33104 .off('mouseenter', SECTION_NAV_SEL + ' li') 33105 .off('mouseleave', SECTION_NAV_SEL + ' li') 33106 .off('click touchstart', SLIDES_NAV_LINK_SEL) 33107 .off('mouseover', options.normalScrollElements) 33108 .off('mouseout', options.normalScrollElements); 33109 33110 $(SECTION_SEL) 33111 .off('click touchstart', SLIDES_ARROW_SEL); 33112 33113 clearTimeout(afterSlideLoadsId); 33114 clearTimeout(afterSectionLoadsId); 33115 33116 //lets make a mess! 33117 if(all){ 33118 destroyStructure(); 33119 } 33120 } 33121 33122 /* 33123 * Removes inline styles added by fullpage.js 33124 */ 33125 function destroyStructure(){ 33126 //reseting the `top` or `translate` properties to 0 33127 silentScroll(0); 33128 33129 //loading all the lazy load content 33130 container.find('img[data-src], source[data-src], audio[data-src], iframe[data-src]').each(function(){ 33131 setSrc($(this), 'src'); 33132 }); 33133 33134 container.find('img[data-srcset]').each(function(){ 33135 setSrc($(this), 'srcset'); 33136 }); 33137 33138 $(SECTION_NAV_SEL + ', ' + SLIDES_NAV_SEL + ', ' + SLIDES_ARROW_SEL).remove(); 33139 33140 //removing inline styles 33141 $(SECTION_SEL).css( { 33142 'height': '', 33143 'background-color' : '', 33144 'padding': '' 33145 }); 33146 33147 $(SLIDE_SEL).css( { 33148 'width': '' 33149 }); 33150 33151 container.css({ 33152 'height': '', 33153 'position': '', 33154 '-ms-touch-action': '', 33155 'touch-action': '' 33156 }); 33157 33158 $htmlBody.css({ 33159 'overflow': '', 33160 'height': '' 33161 }); 33162 33163 // remove .fp-enabled class 33164 $('html').removeClass(ENABLED); 33165 33166 // remove .fp-responsive class 33167 $body.removeClass(RESPONSIVE); 33168 33169 // remove all of the .fp-viewing- classes 33170 $.each($body.get(0).className.split(/\s+/), function (index, className) { 33171 if (className.indexOf(VIEWING_PREFIX) === 0) { 33172 $body.removeClass(className); 33173 } 33174 }); 33175 33176 //removing added classes 33177 $(SECTION_SEL + ', ' + SLIDE_SEL).each(function(){ 33178 options.scrollOverflowHandler.remove($(this)); 33179 $(this).removeClass(TABLE + ' ' + ACTIVE); 33180 }); 33181 33182 removeAnimation(container); 33183 33184 //Unwrapping content 33185 container.find(TABLE_CELL_SEL + ', ' + SLIDES_CONTAINER_SEL + ', ' + SLIDES_WRAPPER_SEL).each(function(){ 33186 //unwrap not being use in case there's no child element inside and its just text 33187 $(this).replaceWith(this.childNodes); 33188 }); 33189 33190 //removing the applied transition from the fullpage wrapper 33191 container.css({
33192 '-webkit-transition': 'none', 33193 'transition': 'none' 33194 }); 33195 33196 //scrolling the page to the top with no animation 33197 $htmlBody.scrollTop(0); 33198 33199 //removing selectors 33200 var usedSelectors = [SECTION, SLIDE, SLIDES_CONTAINER]; 33201 $.each(usedSelectors, function(index, value){ 33202 $('.' + value).removeClass(value); 33203 }); 33204 } 33205 33206 /* 33207 * Sets the state for a variable with multiple states (original, and temporal) 33208 * Some variables such as `autoScrolling` or `recordHistory` might change automatically its state when using `responsive` or `autoScrolling:false`. 33209 * This function is used to keep track of both states, the original and the temporal one. 33210 * If type is not 'internal', then we assume the user is globally changing the variable. 33211 */ 33212 function setVariableState(variable, value, type){ 33213 options[variable] = value; 33214 if(type !== 'internal'){ 33215 originals[variable] = value; 33216 } 33217 } 33218 33219 /** 33220 * Displays warnings 33221 */ 33222 function displayWarnings(){ 33223 var extensions = ['fadingEffect', 'continuousHorizontal', 'scrollHorizontally', 'interlockedSlides', 'resetSliders', 'responsiveSlides', 'offsetSections', 'dragAndMove', 'scrollOverflowReset', 'parallax']; 33224 //UNCODE.addition 33225 // if($('html').hasClass(ENABLED)){ 33226 // showError('error', 'Fullpage.js can only be initialized once and you are doing it multiple times!'); 33227 // return; 33228 // } 33229 33230 // Disable mutually exclusive settings 33231 //UNCODE.addition 33232 // if (options.continuousVertical && 33233 // (options.loopTop || options.loopBottom)) { 33234 // options.continuousVertical = false;
33235 // showError('warn', 'Option `loopTop/loopBottom` is mutually exclusive with `continuousVertical`; `continuousVertical` disabled'); 33236 // } 33237 33238 // if(options.scrollBar && options.scrollOverflow){ 33239 // showError('warn', 'Option `scrollBar` is mutually exclusive with `scrollOverflow`. Sections with scrollOverflow might not work well in Firefox'); 33240 // } 33241 33242 // if(options.continuousVertical && (options.scrollBar || !options.autoScrolling)){ 33243 // options.continuousVertical = false; 33244 // showError('warn', 'Scroll bars (`scrollBar:true` or `autoScrolling:false`) are mutually exclusive with `continuousVertical`; `continuousVertical` disabled'); 33245 // } 33246 33247 //using extensions? Wrong file! 33248 $.each(extensions, function(index, extension){ 33249 //is the option set to true? 33250 if(options[extension]){ 33251 showError('warn', 'fullpage.js extensions require jquery.fullpage.extensions.min.js file instead of the usual jquery.fullpage.js. Requested: '+ extension); 33252 } 33253 }); 33254 33255 //anchors can not have the same value as any element ID or NAME 33256 $.each(options.anchors, function(index, name){ 33257 33258 //case insensitive selectors (http://stackoverflow.com/a/19465187/1081396) 33259 var nameAttr = $document.find('[name]').filter(function() { 33260 return $(this).attr('name') && $(this).attr('name').toLowerCase() == name.toLowerCase(); 33261 }); 33262 33263 var idAttr = $document.find('[id]').filter(function() { 33264 return $(this).attr('id') && $(this).attr('id').toLowerCase() == name.toLowerCase(); 33265 }); 33266 33267 if(idAttr.length || nameAttr.length ){ 33268 showError('error', 'data-anchor tags can not have the same value as any `id` element on the site (or `name` element for IE).'); 33269 idAttr.length && showError('error', '"' + name + '" is is being used by another element `id` property'); 33270 nameAttr.length && showError('error', '"' + name + '" is is being used by another element `name` property'); 33271 } 33272 }); 33273 } 33274 33275 /** 33276 * Shows a message in the console of the given type. 33277 */ 33278 function showError(type, text){ 33279 console && console[type] && console[type]('fullPage: ' + text); 33280 } 33281 33282 }; //end of $.fn.fullpage 33283 33284 if(typeof IScroll !== 'undefined'){ 33285 /* 33286 * Turns iScroll `mousewheel` option off dynamically 33287 * https://github.com/cubiq/iscroll/issues/1036 33288 */ 33289 IScroll.prototype.wheelOn = function () { 33290 this.wrapper.addEventListener('wheel', this); 33291 this.wrapper.addEventListener('mousewheel', this); 33292 this.wrapper.addEventListener('DOMMouseScroll', this); 33293 }; 33294 33295 /* 33296 * Turns iScroll `mousewheel` option on dynamically 33297 * https://github.com/cubiq/iscroll/issues/1036 33298 */ 33299 IScroll.prototype.wheelOff = function () { 33300 this.wrapper.removeEventListener('wheel', this); 33301 this.wrapper.removeEventListener('mousewheel', this); 33302 this.wrapper.removeEventListener('DOMMouseScroll', this); 33303 }; 33304 } 33305 33306 /** 33307 * An object to handle overflow scrolling. 33308 * This uses jquery.slimScroll to accomplish overflow scrolling. 33309 * It is possible to pass in an alternate scrollOverflowHandler 33310 * to the fullpage.js option that implements the same functions 33311 * as this handler. 33312 * 33313 * @type {Object} 33314 */ 33315 var iscrollHandler = { 33316 refreshId: null, 33317 iScrollInstances: [], 33318 33319 // Enables or disables the mouse wheel for the active section or all slides in it 33320 toggleWheel: function(value){ 33321 var scrollable = $(SECTION_ACTIVE_SEL).find(SCROLLABLE_SEL); 33322 scrollable.each(function(){ 33323 var iScrollInstance = $(this).data('iscrollInstance'); 33324 if(typeof iScrollInstance !== 'undefined' && iScrollInstance){ 33325 if(value){ 33326 iScrollInstance.wheelOn(); 33327 } 33328 else{ 33329 iScrollInstance.wheelOff(); 33330 } 33331 } 33332 }); 33333 }, 33334 33335 /** 33336 * Turns off iScroll for the destination section. 33337 * When scrolling very fast on some trackpads (and Apple laptops) the inertial scrolling would
33338 * scroll the destination section/slide before the sections animations ends. 33339 */ 33340 onLeave: function(){ 33341 iscrollHandler.toggleWheel(false); 33342 }, 33343 33344 // Turns off iScroll for the leaving section 33345 beforeLeave: function(){ 33346 iscrollHandler.onLeave() 33347 }, 33348 33349 // Turns on iScroll on section load 33350 afterLoad: function(){ 33351 iscrollHandler.toggleWheel(true); 33352 }, 33353 33354 /** 33355 * Called when overflow scrolling is needed for a section. 33356 * 33357 * @param {Object} element jQuery object containing current section 33358 * @param {Number} scrollHeight Current window height in pixels 33359 */ 33360 create: function(element, scrollHeight) { 33361 var scrollable = element.find(SCROLLABLE_SEL); 33362 33363 scrollable.height(scrollHeight); 33364 scrollable.each(function() { 33365 var $this = $(this); 33366 var iScrollInstance = $this.data('iscrollInstance'); 33367 if (iScrollInstance) { 33368 $.each(iscrollHandler.iScrollInstances, function(){ 33369 $(this).destroy(); 33370 }); 33371 } 33372 33373 iScrollInstance = new IScroll($this.get(0), iscrollOptions); 33374 iscrollHandler.iScrollInstances.push(iScrollInstance); 33375 33376 //off by default until the section gets active 33377 iScrollInstance.wheelOff(); 33378 33379 $this.data('iscrollInstance', iScrollInstance); 33380 }); 33381 }, 33382 33383 /** 33384 * Return a boolean depending on whether the scrollable element is a 33385 * the end or at the start of the scrolling depending on the given type. 33386 * 33387 * @param {String} type Either 'top' or 'bottom' 33388 * @param {Object} scrollable jQuery object for the scrollable element 33389 * @return {Boolean} 33390 */ 33391 isScrolled: function(type, scrollable) { 33392 var scroller = scrollable.data('iscrollInstance'); 33393 33394 //no scroller? 33395 if (!scroller) { 33396 return true; 33397 } 33398 33399 //Uncode addition 33400 var uncode_body_borders = parseFloat($('.body-borders').attr('data-border')) || 0; 33401 //End Uncode addition 33402 33403 if (type === 'top') { 33404 return scroller.y >= 0 && !scrollable.scrollTop(); 33405 } else if (type === 'bottom') { 33406 //Uncode change 33407 // return (0 - scroller.y) + scrollable.scrollTop() + 1 + scrollable.innerHeight() >= scrollable[0].scrollHeight; 33408 return (0 - scroller.y) + scrollable.scrollTop() + 1 + ( uncode_body_borders * 2 ) + scrollable.innerHeight() >= scrollable[0].scrollHeight; 33409 //End Uncode change 33410 } 33411 }, 33412 33413 /** 33414 * Returns the scrollable element for the given section. 33415 * If there are landscape slides, will only return a scrollable element 33416 * if it is in the active slide. 33417 * 33418 * @param {Object} activeSection jQuery object containing current section 33419 * @return {Boolean} 33420 */ 33421 scrollable: function(activeSection){ 33422 // if there are landscape slides, we check if the scrolling bar is in the current one or not 33423 if (activeSection.find(SLIDES_WRAPPER_SEL).length) { 33424 return activeSection.find(SLIDE_ACTIVE_SEL).find(SCROLLABLE_SEL); 33425 } 33426 return activeSection.find(SCROLLABLE_SEL); 33427 }, 33428 33429 /** 33430 * Returns the scroll height of the wrapped content. 33431 * If this is larger than the window height minus section padding, 33432 * overflow scrolling is needed. 33433 * 33434 * @param {Object} element jQuery object containing current section 33435 * @return {Number} 33436 */ 33437 scrollHeight: function(element) { 33438 return element.find(SCROLLABLE_SEL).children().first().get(0).scrollHeight; 33439 }, 33440 33441 /** 33442 * Called when overflow scrolling is no longer needed for a section. 33443 * 33444 * @param {Object}
33444 element jQuery object containing current section 33445 */ 33446 remove: function(element) { 33447 var scrollable = element.find(SCROLLABLE_SEL); 33448 if (scrollable.length) { 33449 var iScrollInstance = scrollable.data('iscrollInstance'); 33450 iScrollInstance.destroy(); 33451 33452 scrollable.data('iscrollInstance', null); 33453 } 33454 element.find(SCROLLABLE_SEL).children().first().children().first().unwrap().unwrap(); 33455 }, 33456 33457 /** 33458 * Called when overflow scrolling has already been setup but the 33459 * window height has potentially changed. 33460 * 33461 * @param {Object} element jQuery object containing current section 33462 * @param {Number} scrollHeight Current window height in pixels 33463 */ 33464 update: function(element, scrollHeight) { 33465 //using a timeout in order to execute the refresh function only once when `update` is called multiple times in a 33466 //short period of time. 33467 //it also comes on handy because iScroll requires the use of timeout when using `refresh`. 33468 clearTimeout(iscrollHandler.refreshId); 33469 iscrollHandler.refreshId = setTimeout(function(){ 33470 $.each(iscrollHandler.iScrollInstances, function(){ 33471 $(this).get(0).refresh(); 33472 }); 33473 }, 150); 33474 33475 //updating the wrappers height 33476 element.find(SCROLLABLE_SEL).css('height', scrollHeight + 'px').parent().css('height', scrollHeight + 'px'); 33477 }, 33478 33479 /** 33480 * Called to get any additional elements needed to wrap the section 33481 * content in order to facilitate overflow scrolling. 33482 * 33483 * @return {String|Object} Can be a string containing HTML, 33484 * a DOM element, or jQuery object. 33485 */ 33486 wrapContent: function() { 33487 return '<div class="' + SCROLLABLE + '"><div class="fp-scroller"></div></div>'; 33488 } 33489 }; 33490}); 33491 33492(function (global, factory) { 33493 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : 33494 typeof define === 'function' && define.amd ? define(['exports'], factory) : 33495 (global = global || self, factory(global.window = global.window || {})); 33496}(this, (function (exports) { 'use strict'; 33497 33498 /*! 33499 * ScrollTrigger 3.8.0 33500 * https://greensock.com 33501 * 33502 * @license Copyright 2008-2021, GreenSock. All rights reserved. 33503 * Subject to the terms at https://greensock.com/standard-license or for 33504 * Club GreenSock members, the agreement issued with that membership. 33505 * @author: Jack Doyle, [email protected] 33506 */ 33507 var gsap, 33508 _coreInitted, 33509 _win, 33510 _doc, 33511 _docEl, 33512 _body, 33513 _root, 33514 _resizeDelay, 33515 _raf, 33516 _request, 33517 _toArray, 33518 _clamp, 33519 _time2, 33520 _syncInterval, 33521 _refreshing, 33522 _pointerIsDown, 33523 _transformProp, 33524 _i, 33525 _prevWidth, 33526 _prevHeight, 33527 _autoRefresh, 33528 _sort, 33529 _suppressOverwrites, 33530 _ignoreResize, 33531 _limitCallbacks, 33532 _startup = 1, 33533 _proxies = [], 33534 _scrollers = [], 33535 _getTime = Date.now, 33536 _time1 = _getTime(), 33537 _lastScrollTime = 0, 33538 _enabled = 1, 33539 _passThrough = function _passThrough(v) { 33540 return v; 33541 }, 33542 _getTarget = function _getTarget(t) { 33543 return _toArray(t)[0] || (_isString(t) ? console.warn("Element not found:", t) : null); 33544 }, 33545 _round = function _round(value) { 33546 return Math.round(value * 100000) / 100000 || 0; 33547 }, 33548 _windowExists = function _windowExists() { 33549 return typeof window !== "undefined"; 33550 }, 33551 _getGSAP = function _getGSAP() { 33552 return gsap || _windowExists() && (gsap = window.gsap) && gsap.registerPlugin && gsap; 33553 }, 33554 _isViewport = function _isViewport(e) { 33555 return !!~_root.indexOf(e); 33556 }, 33557 _getProxyProp = function _getProxyProp(element, property) { 33558 return ~_proxies.indexOf(element) && _proxies[_proxies.indexOf(element) + 1][property]; 33559 }, 33560 _getScrollFunc = function _getScrollFunc(element, _ref) { 33561 var s = _ref.s, 33562 sc = _ref.sc; 33563 33564 var i = _scrollers.indexOf(element), 33565 offset = sc === _vertical.sc ? 1 : 2; 33566 33567 !~i && (i = _scrollers.push(element) - 1); 33568 return _scrollers[i + offset] || (_scrollers[i + offset] = _getProxyProp(element, s) || (_isViewport(element) ? sc : function (value) { 33569 return arguments.length ? element[s] = value : element[s]; 33570 })); 33571 }, 33572 _getBoundsFunc = function _getBoundsFunc(element) { 33573 return _getProxyProp(element, "getBoundingClientRect") || (_isViewport(element) ? function () { 33574 _winOffsets.width = _win.innerWidth; 33575 _winOffsets.height = _win.innerHeight; 33576 return _winOffsets; 33577 } : function () { 33578 return _getBounds(element); 33579 }); 33580 }, 33581 _getSizeFunc = function _getSizeFunc(scroller, isViewport, _ref2) { 33582 var d = _ref2.d, 33583 d2 = _ref2.d2, 33584 a = _ref2.a; 33585 return (a = _getProxyProp(scroller, "getBoundingClientRect")) ? function () { 33586 return a()[d]; 33587 } : function () { 33588 return (isViewport ? _win["inner" + d2] : scroller["client" + d2]) || 0; 33589 }; 33590 }, 33591 _getOffsetsFunc = function _getOffsetsFunc(element, isViewport) { 33592 return !isViewport || ~_proxies.indexOf(element) ? _getBoundsFunc(element) : function () { 33593 return _winOffsets; 33594 }; 33595 }, 33596 _maxScroll = function _maxScroll(element, _ref3) { 33597 var s = _ref3.s, 33598 d2 = _ref3.d2, 33599 d = _ref3.d, 33600 a = _ref3.a; 33601 return (s = "scroll" + d2) && (a = _getProxyProp(element, s)) ? a() - _getBoundsFunc(element)()[d] : _isViewport(element) ? (_body[s] || _docEl[s]) - (_win["inner" + d2] || _docEl["client" + d2] || _body["client" + d2]) : element[s] - element["offset" + d2]; 33602 }, 33603 _iterateAutoRefresh = function _iterateAutoRefresh(func, events) { 33604 for (var i = 0; i < _autoRefresh.length; i += 3) {
vendor: 5,689 bytes, lines 33605-33809
33605 (!events || ~events.indexOf(_autoRefresh[i + 1])) && func(_autoRefresh[i], _autoRefresh[i + 1], _autoRefresh[i + 2]); 33606 } 33607 }, 33608 _isString = function _isString(value) { 33609 return typeof value === "string"; 33610 }, 33611 _isFunction = function _isFunction(value) { 33612 return typeof value === "function"; 33613 }, 33614 _isNumber = function _isNumber(value) { 33615 return typeof value === "number"; 33616 }, 33617 _isObject = function _isObject(value) { 33618 return typeof value === "object"; 33619 }, 33620 _callIfFunc = function _callIfFunc(value) { 33621 return _isFunction(value) && value(); 33622 }, 33623 _combineFunc = function _combineFunc(f1, f2) { 33624 return function () { 33625 var result1 = _callIfFunc(f1), 33626 result2 = _callIfFunc(f2); 33627 33628 return function () { 33629 _callIfFunc(result1); 33630 33631 _callIfFunc(result2); 33632 }; 33633 }; 33634 }, 33635 _endAnimation = function _endAnimation(animation, reversed, pause) { 33636 return animation && animation.progress(reversed ? 0 : 1) && pause && animation.pause(); 33637 }, 33638 _callback = function _callback(self, func) { 33639 var result = func(self); 33640 result && result.totalTime && (self.callbackAnimation = result); 33641 }, 33642 _abs = Math.abs, 33643 _scrollLeft = "scrollLeft", 33644 _scrollTop = "scrollTop", 33645 _left = "left", 33646 _top = "top", 33647 _right = "right", 33648 _bottom = "bottom", 33649 _width = "width", 33650 _height = "height", 33651 _Right = "Right", 33652 _Left = "Left", 33653 _Top = "Top", 33654 _Bottom = "Bottom", 33655 _padding = "padding", 33656 _margin = "margin", 33657 _Width = "Width", 33658 _Height = "Height", 33659 _px = "px", 33660 _horizontal = { 33661 s: _scrollLeft, 33662 p: _left, 33663 p2: _Left, 33664 os: _right, 33665 os2: _Right, 33666 d: _width, 33667 d2: _Width, 33668 a: "x", 33669 sc: function sc(value) { 33670 return arguments.length ? _win.scrollTo(value, _vertical.sc()) : _win.pageXOffset || _doc[_scrollLeft] || _docEl[_scrollLeft] || _body[_scrollLeft] || 0; 33671 } 33672 }, 33673 _vertical = { 33674 s: _scrollTop, 33675 p: _top, 33676 p2: _Top, 33677 os: _bottom, 33678 os2: _Bottom, 33679 d: _height, 33680 d2: _Height, 33681 a: "y", 33682 op: _horizontal, 33683 sc: function sc(value) { 33684 return arguments.length ? _win.scrollTo(_horizontal.sc(), value) : _win.pageYOffset || _doc[_scrollTop] || _docEl[_scrollTop] || _body[_scrollTop] || 0; 33685 } 33686 }, 33687 _getComputedStyle = function _getComputedStyle(element) { 33688 return _win.getComputedStyle(element); 33689 }, 33690 _makePositionable = function _makePositionable(element) { 33691 var position = _getComputedStyle(element).position; 33692 33693 element.style.position = position === "absolute" || position === "fixed" ? position : "relative"; 33694 }, 33695 _setDefaults = function _setDefaults(obj, defaults) { 33696 for (var p in defaults) { 33697 p in obj || (obj[p] = defaults[p]); 33698 } 33699 33700 return obj; 33701 }, 33702 _getBounds = function _getBounds(element, withoutTransforms) { 33703 var tween = withoutTransforms && _getComputedStyle(element)[_transformProp] !== "matrix(1, 0, 0, 1, 0, 0)" && gsap.to(element, { 33704 x: 0, 33705 y: 0, 33706 xPercent: 0, 33707 yPercent: 0, 33708 rotation: 0, 33709 rotationX: 0, 33710 rotationY: 0, 33711 scale: 1, 33712 skewX: 0, 33713 skewY: 0 33714 }).progress(1), 33715 bounds = element.getBoundingClientRect(); 33716 tween && tween.progress(0).kill(); 33717 return bounds; 33718 }, 33719 _getSize = function _getSize(element, _ref4) { 33720 var d2 = _ref4.d2; 33721 return element["offset" + d2] || element["client" + d2] || 0; 33722 }, 33723 _getLabelRatioArray = function _getLabelRatioArray(timeline) { 33724 var a = [], 33725 labels = timeline.labels, 33726 duration = timeline.duration(), 33727 p; 33728 33729 for (p in labels) { 33730 a.push(labels[p] / duration); 33731 } 33732 33733 return a; 33734 }, 33735 _getClosestLabel = function _getClosestLabel(animation) { 33736 return function (value) { 33737 return gsap.utils.snap(_getLabelRatioArray(animation), value); 33738 }; 33739 }, 33740 _snapDirectional = function _snapDirectional(snapIncrementOrArray) { 33741 var snap = gsap.utils.snap(snapIncrementOrArray), 33742 a = Array.isArray(snapIncrementOrArray) && snapIncrementOrArray.slice(0).sort(function (a, b) { 33743 return a - b; 33744 }); 33745 return a ? function (value, direction) { 33746 var i; 33747 33748 if (!direction) { 33749 return snap(value); 33750 } 33751 33752 if (direction > 0) { 33753 value -= 1e-4; 33754 33755 for (i = 0; i < a.length; i++) { 33756 if (a[i] >= value) { 33757 return a[i]; 33758 } 33759 } 33760 33761 return a[i - 1]; 33762 } else { 33763 i = a.length; 33764 value += 1e-4; 33765 33766 while (i--) { 33767 if (a[i] <= value) { 33768 return a[i]; 33769 } 33770 } 33771 } 33772 33773 return a[0]; 33774 } : function (value, direction) { 33775 var snapped = snap(value); 33776 return !direction || Math.abs(snapped - value) < 0.001 || snapped - value < 0 === direction < 0 ? snapped : snap(direction < 0 ? value - snapIncrementOrArray : value + snapIncrementOrArray); 33777 }; 33778 }, 33779 _getLabelAtDirection = function _getLabelAtDirection(timeline) { 33780 return function (value, st) { 33781 return _snapDirectional(_getLabelRatioArray(timeline))(value, st.direction); 33782 }; 33783 }, 33784 _multiListener = function _multiListener(func, element, types, callback) { 33785 return types.split(",").forEach(function (type) { 33786 return func(element, type, callback); 33787 }); 33788 }, 33789 _addListener = function _addListener(element, type, func) { 33790 return element.addEventListener(type, func, { 33791 passive: true 33792 }); 33793 }, 33794 _removeListener = function _removeListener(element, type, func) { 33795 return element.removeEventListener(type, func); 33796 }, 33797 _markerDefaults = { 33798 startColor: "green", 33799 endColor: "red", 33800 indent: 0, 33801 fontSize: "16px", 33802 fontWeight: "normal" 33803 }, 33804 _defaults = { 33805 toggleActions: "play", 33806 anticipatePin: 0 33807 }, 33808 _keywords = { 33809 top: 0,
33810 left: 0, 33811 center: 0.5, 33812 bottom: 1, 33813 right: 1 33814 }, 33815 _offsetToPx = function _offsetToPx(value, size) { 33816 if (_isString(value)) { 33817 var eqIndex = value.indexOf("="), 33818 relative = ~eqIndex ? +(value.charAt(eqIndex - 1) + 1) * parseFloat(value.substr(eqIndex + 1)) : 0; 33819 33820 if (~eqIndex) { 33821 value.indexOf("%") > eqIndex && (relative *= size / 100); 33822 value = value.substr(0, eqIndex - 1); 33823 } 33824 33825 value = relative + (value in _keywords ? _keywords[value] * size : ~value.indexOf("%") ? parseFloat(value) * size / 100 : parseFloat(value) || 0); 33826 } 33827 33828 return value; 33829 }, 33830 _createMarker = function _createMarker(type, name, container, direction, _ref5, offset, matchWidthEl, containerAnimation) { 33831 var startColor = _ref5.startColor, 33832 endColor = _ref5.endColor, 33833 fontSize = _ref5.fontSize, 33834 indent = _ref5.indent, 33835 fontWeight = _ref5.fontWeight; 33836 33837 var e = _doc.createElement("div"), 33838 useFixedPosition = _isViewport(container) || _getProxyProp(container, "pinType") === "fixed", 33839 isScroller = type.indexOf("scroller") !== -1, 33840 parent = useFixedPosition ? _body : container, 33841 isStart = type.indexOf("start") !== -1, 33842 color = isStart ? startColor : endColor, 33843 css = "border-color:" + color + ";font-size:" + fontSize + ";color:" + color + ";font-weight:" + fontWeight + ";pointer-events:none;white-space:nowrap;font-family:sans-serif,Arial;z-index:1000;padding:4px 8px;border-width:0;border-style:solid;"; 33844 33845 css += "position:" + ((isScroller || containerAnimation) && useFixedPosition ? "fixed;" : "absolute;"); 33846 (isScroller || containerAnimation || !useFixedPosition) && (css += (direction === _vertical ? _right : _bottom) + ":" + (offset + parseFloat(indent)) + "px;"); 33847 matchWidthEl && (css += "box-sizing:border-box;text-align:left;width:" + matchWidthEl.offsetWidth + "px;"); 33848 e._isStart = isStart; 33849 e.setAttribute("class", "gsap-marker-" + type + (name ? " marker-" + name : "")); 33850 e.style.cssText = css; 33851 e.innerText = name || name === 0 ? type + "-" + name : type; 33852 parent.children[0] ? parent.insertBefore(e, parent.children[0]) : parent.appendChild(e); 33853 e._offset = e["offset" + direction.op.d2]; 33854 33855 _positionMarker(e, 0, direction, isStart); 33856 33857 return e; 33858 }, 33859 _positionMarker = function _positionMarker(marker, start, direction, flipped) { 33860 var vars = { 33861 display: "block" 33862 }, 33863 side = direction[flipped ? "os2" : "p2"], 33864 oppositeSide = direction[flipped ? "p2" : "os2"]; 33865 marker._isFlipped = flipped; 33866 vars[direction.a + "Percent"] = flipped ? -100 : 0; 33867 vars[direction.a] = flipped ? "1px" : 0; 33868 vars["border" + side + _Width] = 1; 33869 vars["border" + oppositeSide + _Width] = 0; 33870 vars[direction.p] = start + "px"; 33871 gsap.set(marker, vars); 33872 }, 33873 _triggers = [], 33874 _ids = {}, 33875 _sync = function _sync() { 33876 return _getTime() - _lastScrollTime > 20 && _updateAll(); 33877 }, 33878 _onScroll = function _onScroll() { 33879 var time = _getTime(); 33880 33881 if (_lastScrollTime !== time) { 33882 _updateAll(); 33883 33884 _lastScrollTime || _dispatch("scrollStart"); 33885 _lastScrollTime = time; 33886 } else if (!_request) { 33887 _request = _raf(_updateAll); 33888 } 33889 }, 33890 _onResize = function _onResize() { 33891 return !_refreshing && !_ignoreResize && !_doc.fullscreenElement && _resizeDelay.restart(true); 33892 }, 33893 _listeners = {}, 33894 _emptyArray = [], 33895 _media = [], 33896 _creatingMedia, 33897 _lastMediaTick, 33898 _onMediaChange = function _onMediaChange(e) { 33899 var tick = gsap.ticker.frame, 33900 matches = [], 33901 i = 0, 33902 index; 33903 33904 if (_lastMediaTick !== tick || _startup) { 33905 _revertAll(); 33906 33907 for (; i < _media.length; i += 4) { 33908 index = _win.matchMedia(_media[i]).matches; 33909 33910 if (index !== _media[i + 3]) { 33911 _media[i + 3] = index; 33912 index ? matches.push(i) : _revertAll(1, _media[i]) || _isFunction(_media[i + 2]) && _media[i + 2](); 33913 } 33914 } 33915 33916 _revertRecorded(); 33917 33918 for (i = 0; i < matches.length; i++) { 33919 index = matches[i]; 33920 _creatingMedia = _media[index]; 33921 _media[index + 2] = _media[index + 1](e); 33922 } 33923 33924 _creatingMedia = 0; 33925 _coreInitted && _refreshAll(0, 1); 33926 _lastMediaTick = tick; 33927 33928 _dispatch("matchMedia"); 33929 } 33930 }, 33931 _softRefresh = function _softRefresh() { 33932 return _removeListener(ScrollTrigger, "scrollEnd", _softRefresh) || _refreshAll(true); 33933 }, 33934 _dispatch = function _dispatch(type) { 33935 return _listeners[type] && _listeners[type].map(function (f) { 33936 return f(); 33937 }) || _emptyArray; 33938 }, 33939 _savedStyles = [], 33940 _revertRecorded = function _revertRecorded(media) { 33941 for (var i = 0; i < _savedStyles.length; i += 5) { 33942 if (!media || _savedStyles[i + 4] === media) { 33943 _savedStyles[i].style.cssText = _savedStyles[i + 1]; 33944 _savedStyles[i].getBBox && _savedStyles[i].setAttribute("transform", _savedStyles[i + 2] || ""); 33945 _savedStyles[i + 3].uncache = 1; 33946 } 33947 } 33948 }, 33949 _revertAll = function _revertAll(kill, media) { 33950 var trigger; 33951 33952 for (_i = 0; _i < _triggers.length; _i++) { 33953 trigger = _triggers[_i]; 33954 33955 if (!media || trigger.media === media) { 33956 if (kill) { 33957 trigger.kill(1); 33958 } else { 33959 trigger.revert(); 33960 } 33961 } 33962 } 33963 33964 media && _revertRecorded(media); 33965 media || _dispatch("revert"); 33966 }, 33967 _clearScrollMemory = function _clearScrollMemory() {
vendor: 10,266 bytes, lines 33968-34302
33968 return _scrollers.forEach(function (obj) { 33969 return typeof obj === "function" && (obj.rec = 0); 33970 }); 33971 }, 33972 _refreshingAll, 33973 _refreshAll = function _refreshAll(force, skipRevert) { 33974 if (_lastScrollTime && !force) { 33975 _addListener(ScrollTrigger, "scrollEnd", _softRefresh); 33976 33977 return; 33978 } 33979 33980 _refreshingAll = true; 33981 33982 var refreshInits = _dispatch("refreshInit"); 33983 33984 _sort && ScrollTrigger.sort(); 33985 skipRevert || _revertAll(); 33986 33987 _triggers.forEach(function (t) { 33988 return t.refresh(); 33989 }); 33990 33991 refreshInits.forEach(function (result) { 33992 return result && result.render && result.render(-1); 33993 }); 33994 33995 _clearScrollMemory(); 33996 33997 _resizeDelay.pause(); 33998 33999 _refreshingAll = false; 34000 34001 _dispatch("refresh"); 34002 }, 34003 _lastScroll = 0, 34004 _direction = 1, 34005 _updateAll = function _updateAll() { 34006 if (!_refreshingAll) { 34007 var l = _triggers.length, 34008 time = _getTime(), 34009 recordVelocity = time - _time1 >= 50, 34010 scroll = l && _triggers[0].scroll(); 34011 34012 _direction = _lastScroll > scroll ? -1 : 1; 34013 _lastScroll = scroll; 34014 34015 if (recordVelocity) { 34016 if (_lastScrollTime && !_pointerIsDown && time - _lastScrollTime > 200) { 34017 _lastScrollTime = 0; 34018 34019 _dispatch("scrollEnd"); 34020 } 34021 34022 _time2 = _time1; 34023 _time1 = time; 34024 } 34025 34026 if (_direction < 0) { 34027 _i = l; 34028 34029 while (_i-- > 0) { 34030 _triggers[_i] && _triggers[_i].update(0, recordVelocity); 34031 } 34032 34033 _direction = 1; 34034 } else { 34035 for (_i = 0; _i < l; _i++) { 34036 _triggers[_i] && _triggers[_i].update(0, recordVelocity); 34037 } 34038 } 34039 34040 _request = 0; 34041 } 34042 }, 34043 _propNamesToCopy = [_left, _top, _bottom, _right, _margin + _Bottom, _margin + _Right, _margin + _Top, _margin + _Left, "display", "flexShrink", "float", "zIndex", "grid-column-start", "grid-column-end", "grid-row-start", "grid-row-end", "grid-area", "justify-self", "align-self", "place-self"], 34044 _stateProps = _propNamesToCopy.concat([_width, _height, "boxSizing", "max" + _Width, "max" + _Height, "position", _margin, _padding, _padding + _Top, _padding + _Right, _padding + _Bottom, _padding + _Left]), 34045 _swapPinOut = function _swapPinOut(pin, spacer, state) { 34046 _setState(state); 34047 34048 var cache = pin._gsap; 34049 34050 if (cache.spacerIsNative) { 34051 _setState(cache.spacerState); 34052 } else if (pin.parentNode === spacer) { 34053 var parent = spacer.parentNode; 34054 34055 if (parent) { 34056 parent.insertBefore(pin, spacer); 34057 parent.removeChild(spacer); 34058 } 34059 } 34060 }, 34061 _swapPinIn = function _swapPinIn(pin, spacer, cs, spacerState) { 34062 if (pin.parentNode !== spacer) { 34063 var i = _propNamesToCopy.length, 34064 spacerStyle = spacer.style, 34065 pinStyle = pin.style, 34066 p; 34067 34068 while (i--) { 34069 p = _propNamesToCopy[i]; 34070 spacerStyle[p] = cs[p]; 34071 } 34072 34073 spacerStyle.position = cs.position === "absolute" ? "absolute" : "relative"; 34074 cs.display === "inline" && (spacerStyle.display = "inline-block"); 34075 pinStyle[_bottom] = pinStyle[_right] = "auto"; 34076 spacerStyle.overflow = "visible"; 34077 spacerStyle.boxSizing = "border-box"; 34078 spacerStyle[_width] = _getSize(pin, _horizontal) + _px; 34079 spacerStyle[_height] = _getSize(pin, _vertical) + _px; 34080 spacerStyle[_padding] = pinStyle[_margin] = pinStyle[_top] = pinStyle[_left] = "0"; 34081 34082 _setState(spacerState); 34083 34084 pinStyle[_width] = pinStyle["max" + _Width] = cs[_width]; 34085 pinStyle[_height] = pinStyle["max" + _Height] = cs[_height]; 34086 pinStyle[_padding] = cs[_padding]; 34087 pin.parentNode.insertBefore(spacer, pin); 34088 spacer.appendChild(pin); 34089 } 34090 }, 34091 _capsExp = /([A-Z])/g, 34092 _setState = function _setState(state) { 34093 if (state) { 34094 var style = state.t.style, 34095 l = state.length, 34096 i = 0, 34097 p, 34098 value; 34099 (state.t._gsap || gsap.core.getCache(state.t)).uncache = 1; 34100 34101 for (; i < l; i += 2) { 34102 value = state[i + 1]; 34103 p = state[i]; 34104 34105 if (value) { 34106 style[p] = value; 34107 } else if (style[p]) { 34108 style.removeProperty(p.replace(_capsExp, "-$1").toLowerCase()); 34109 } 34110 } 34111 } 34112 }, 34113 _getState = function _getState(element) { 34114 var l = _stateProps.length, 34115 style = element.style, 34116 state = [], 34117 i = 0; 34118 34119 for (; i < l; i++) { 34120 state.push(_stateProps[i], style[_stateProps[i]]); 34121 } 34122 34123 state.t = element; 34124 return state; 34125 }, 34126 _copyState = function _copyState(state, override, omitOffsets) { 34127 var result = [], 34128 l = state.length, 34129 i = omitOffsets ? 8 : 0, 34130 p; 34131 34132 for (; i < l; i += 2) { 34133 p = state[i]; 34134 result.push(p, p in override ? override[p] : state[i + 1]); 34135 } 34136 34137 result.t = state.t; 34138 return result; 34139 }, 34140 _winOffsets = { 34141 left: 0, 34142 top: 0 34143 }, 34144 _parsePosition = function _parsePosition(value, trigger, scrollerSize, direction, scroll, marker, markerScroller, self, scrollerBounds, borderWidth, useFixedPosition, scrollerMax, containerAnimation) { 34145 _isFunction(value) && (value = value(self)); 34146 34147 if (_isString(value) && value.substr(0, 3) === "max") { 34148 value = scrollerMax + (value.charAt(4) === "=" ? _offsetToPx("0" + value.substr(3), scrollerSize) : 0); 34149 } 34150 34151 var time = containerAnimation ? containerAnimation.time() : 0, 34152 p1, 34153 p2, 34154 element; 34155 containerAnimation && containerAnimation.seek(0); 34156 34157 if (!_isNumber(value)) { 34158 _isFunction(trigger) && (trigger = trigger(self)); 34159 var offsets = value.split(" "), 34160 bounds, 34161 localOffset, 34162 globalOffset, 34163 display; 34164 element = _getTarget(trigger) || _body; 34165 bounds = _getBounds(element) || {}; 34166 34167 if ((!bounds || !bounds.left && !bounds.top) && _getComputedStyle(element).display === "none") { 34168 display = element.style.display; 34169 element.style.display = "block"; 34170 bounds = _getBounds(element); 34171 display ? element.style.display = display : element.style.removeProperty("display"); 34172 } 34173 34174 localOffset = _offsetToPx(offsets[0], bounds[direction.d]); 34175 globalOffset = _offsetToPx(offsets[1] || "0", scrollerSize); 34176 value = bounds[direction.p] - scrollerBounds[direction.p] - borderWidth + localOffset + scroll - globalOffset; 34177 markerScroller && _positionMarker(markerScroller, globalOffset, direction, scrollerSize - globalOffset < 20 || markerScroller._isStart && globalOffset > 20); 34178 scrollerSize -= scrollerSize - globalOffset; 34179 } else if (markerScroller) { 34180 _positionMarker(markerScroller, scrollerSize, direction, true); 34181 } 34182 34183 if (marker) { 34184 var position = value + scrollerSize, 34185 isStart = marker._isStart; 34186 p1 = "scroll" + direction.d2; 34187 34188 _positionMarker(marker, position, direction, isStart && position > 20 || !isStart && (useFixedPosition ? Math.max(_body[p1], _docEl[p1]) : marker.parentNode[p1]) <= position + 1); 34189 34190 if (useFixedPosition) { 34191 scrollerBounds = _getBounds(markerScroller); 34192 useFixedPosition && (marker.style[direction.op.p] = scrollerBounds[direction.op.p] - direction.op.m - marker._offset + _px); 34193 } 34194 } 34195 34196 if (containerAnimation && element) { 34197 p1 = _getBounds(element); 34198 containerAnimation.seek(scrollerMax); 34199 p2 = _getBounds(element); 34200 containerAnimation._caScrollDist = p1[direction.p] - p2[direction.p]; 34201 value = value / containerAnimation._caScrollDist * scrollerMax; 34202 } 34203 34204 containerAnimation && containerAnimation.seek(time); 34205 return containerAnimation ? value : Math.round(value); 34206 }, 34207 _prefixExp = /(?:webkit|moz|length|cssText|inset)/i, 34208 _reparent = function _reparent(element, parent, top, left) { 34209 if (element.parentNode !== parent) { 34210 var style = element.style, 34211 p, 34212 cs; 34213 34214 if (parent === _body) { 34215 element._stOrig = style.cssText; 34216 cs = _getComputedStyle(element); 34217 34218 for (p in cs) { 34219 if (!+p && !_prefixExp.test(p) && cs[p] && typeof style[p] === "string" && p !== "0") { 34220 style[p] = cs[p]; 34221 } 34222 } 34223 34224 style.top = top; 34225 style.left = left; 34226 } else { 34227 style.cssText = element._stOrig; 34228 } 34229 34230 gsap.core.getCache(element).uncache = 1; 34231 parent.appendChild(element); 34232 } 34233 }, 34234 _getTweenCreator = function _getTweenCreator(scroller, direction) { 34235 var getScroll = _getScrollFunc(scroller, direction), 34236 prop = "_scroll" + direction.p2, 34237 lastScroll1, 34238 lastScroll2, 34239 getTween = function getTween(scrollTo, vars, initialValue, change1, change2) { 34240 var tween = getTween.tween, 34241 onComplete = vars.onComplete, 34242 modifiers = {}; 34243 tween && tween.kill(); 34244 lastScroll1 = Math.round(initialValue); 34245 vars[prop] = scrollTo; 34246 vars.modifiers = modifiers; 34247 34248 modifiers[prop] = function (value) { 34249 value = _round(getScroll()); 34250 34251 if (value !== lastScroll1 && value !== lastScroll2 && Math.abs(value - lastScroll1) > 2) { 34252 tween.kill(); 34253 getTween.tween = 0; 34254 } else { 34255 value = initialValue + change1 * tween.ratio + change2 * tween.ratio * tween.ratio; 34256 } 34257 34258 lastScroll2 = lastScroll1; 34259 return lastScroll1 = _round(value); 34260 }; 34261 34262 vars.onComplete = function () { 34263 getTween.tween = 0; 34264 onComplete && onComplete.call(tween); 34265 }; 34266 34267 tween = getTween.tween = gsap.to(scroller, vars); 34268 return tween; 34269 }; 34270 34271 scroller[prop] = getScroll; 34272 scroller.addEventListener("wheel", function () { 34273 return getTween.tween && getTween.tween.kill() && (getTween.tween = 0); 34274 }, { 34275 passive: true 34276 }); 34277 return getTween; 34278 }; 34279 34280 _horizontal.op = _vertical; 34281 var ScrollTrigger = function () { 34282 function ScrollTrigger(vars, animation) { 34283 _coreInitted || ScrollTrigger.register(gsap) || console.warn("Please gsap.registerPlugin(ScrollTrigger)"); 34284 this.init(vars, animation); 34285 } 34286 34287 var _proto = ScrollTrigger.prototype; 34288 34289 _proto.init = function init(vars, animation) { 34290 this.progress = this.start = 0; 34291 this.vars && this.kill(1); 34292 34293 if (!_enabled) { 34294 this.update = this.refresh = this.kill = _passThrough; 34295 return; 34296 } 34297 34298 vars = _setDefaults(_isString(vars) || _isNumber(vars) || vars.nodeType ? { 34299 trigger: vars 34300 } : vars, _defaults); 34301 34302 var _vars = vars,
34303 onUpdate = _vars.onUpdate, 34304 toggleClass = _vars.toggleClass, 34305 id = _vars.id, 34306 onToggle = _vars.onToggle, 34307 onRefresh = _vars.onRefresh, 34308 scrub = _vars.scrub, 34309 trigger = _vars.trigger, 34310 pin = _vars.pin, 34311 pinSpacing = _vars.pinSpacing, 34312 invalidateOnRefresh = _vars.invalidateOnRefresh, 34313 anticipatePin = _vars.anticipatePin, 34314 onScrubComplete = _vars.onScrubComplete, 34315 onSnapComplete = _vars.onSnapComplete, 34316 once = _vars.once, 34317 snap = _vars.snap, 34318 pinReparent = _vars.pinReparent, 34319 pinSpacer = _vars.pinSpacer, 34320 containerAnimation = _vars.containerAnimation, 34321 fastScrollEnd = _vars.fastScrollEnd, 34322 preventOverlaps = _vars.preventOverlaps, 34323 direction = vars.horizontal || vars.containerAnimation && vars.horizontal !== false ? _horizontal : _vertical, 34324 isToggle = !scrub && scrub !== 0, 34325 scroller = _getTarget(vars.scroller || _win), 34326 scrollerCache = gsap.core.getCache(scroller), 34327 isViewport = _isViewport(scroller), 34328 useFixedPosition = ("pinType" in vars ? vars.pinType : _getProxyProp(scroller, "pinType") || isViewport && "fixed") === "fixed", 34329 callbacks = [vars.onEnter, vars.onLeave, vars.onEnterBack, vars.onLeaveBack], 34330 toggleActions = isToggle && vars.toggleActions.split(" "), 34331 markers = "markers" in vars ? vars.markers : _defaults.markers, 34332 borderWidth = isViewport ? 0 : parseFloat(_getComputedStyle(scroller)["border" + direction.p2 + _Width]) || 0, 34333 self = this, 34334 onRefreshInit = vars.onRefreshInit && function () { 34335 return vars.onRefreshInit(self); 34336 }, 34337 getScrollerSize = _getSizeFunc(scroller, isViewport, direction), 34338 getScrollerOffsets = _getOffsetsFunc(scroller, isViewport), 34339 lastSnap = 0, 34340 scrollFunc = _getScrollFunc(scroller, direction), 34341 tweenTo, 34342 pinCache, 34343 snapFunc, 34344 scroll1, 34345 scroll2, 34346 start, 34347 end, 34348 markerStart, 34349 markerEnd, 34350 markerStartTrigger, 34351 markerEndTrigger, 34352 markerVars, 34353 change, 34354 pinOriginalState, 34355 pinActiveState, 34356 pinState, 34357 spacer, 34358 offset, 34359 pinGetter, 34360 pinSetter, 34361 pinStart, 34362 pinChange, 34363 spacingStart, 34364 spacerState, 34365 markerStartSetter, 34366 markerEndSetter, 34367 cs, 34368 snap1, 34369 snap2, 34370 scrubTween, 34371 scrubSmooth, 34372 snapDurClamp, 34373 snapDelayedCall, 34374 prevProgress, 34375 prevScroll, 34376 prevAnimProgress, 34377 caMarkerSetter; 34378 34379 self.media = _creatingMedia; 34380 anticipatePin *= 45; 34381 self.scroller = scroller; 34382 self.scroll = containerAnimation ? containerAnimation.time.bind(containerAnimation) : scrollFunc; 34383 scroll1 = scrollFunc(); 34384 self.vars = vars; 34385 animation = animation || vars.animation; 34386 "refreshPriority" in vars && (_sort = 1); 34387 scrollerCache.tweenScroll = scrollerCache.tweenScroll || { 34388 top: _getTweenCreator(scroller, _vertical), 34389 left: _getTweenCreator(scroller, _horizontal) 34390 }; 34391 self.tweenTo = tweenTo = scrollerCache.tweenScroll[direction.p]; 34392 34393 if (animation) { 34394 animation.vars.lazy = false; 34395 animation._initted || animation.vars.immediateRender !== false && vars.immediateRender !== false && animation.render(0, true, true); 34396 self.animation = animation.pause(); 34397 animation.scrollTrigger = self; 34398 scrubSmooth = _isNumber(scrub) && scrub; 34399 scrubSmooth && (scrubTween = gsap.to(animation, { 34400 ease: "power3", 34401 duration: scrubSmooth, 34402 onComplete: function onComplete() { 34403 return onScrubComplete && onScrubComplete(self); 34404 } 34405 })); 34406 snap1 = 0; 34407 id || (id = animation.vars.id); 34408 } 34409 34410 _triggers.push(self); 34411 34412 if (snap) { 34413 if (!_isObject(snap) || snap.push) { 34414 snap = { 34415 snapTo: snap 34416 }; 34417 } 34418 34419 "scrollBehavior" in _body.style && gsap.set(isViewport ? [_body, _docEl] : scroller, { 34420 scrollBehavior: "auto" 34421 }); 34422 snapFunc = _isFunction(snap.snapTo) ? snap.snapTo : snap.snapTo === "labels" ? _getClosestLabel(animation) : snap.snapTo === "labelsDirectional" ? _getLabelAtDirection(animation) : snap.directional !== false ? function (value, st) { 34423 return _snapDirectional(snap.snapTo)(value, st.direction); 34424 } : gsap.utils.snap(snap.snapTo); 34425 snapDurClamp = snap.duration || { 34426 min: 0.1, 34427 max: 2 34428 }; 34429 snapDurClamp = _isObject(snapDurClamp) ? _clamp(snapDurClamp.min, snapDurClamp.max) : _clamp(snapDurClamp, snapDurClamp); 34430 snapDelayedCall = gsap.delayedCall(snap.delay || scrubSmooth / 2 || 0.1, function () { 34431 if (Math.abs(self.getVelocity()) < 10 && !_pointerIsDown && lastSnap !== scrollFunc()) { 34432 var totalProgress = animation && !isToggle ? animation.totalProgress() : self.progress, 34433 velocity = (totalProgress - snap2) / (_getTime() - _time2) * 1000 || 0, 34434 change1 = gsap.utils.clamp(-self.progress, 1 - self.progress, _abs(velocity / 2) * velocity / 0.185), 34435 naturalEnd = self.progress + (snap.inertia === false ? 0 : change1), 34436 endValue = _clamp(0, 1, snapFunc(naturalEnd, self)), 34437 scroll = scrollFunc(), 34438 endScroll = Math.round(start + endValue * change), 34439 _snap = snap, 34440 onStart = _snap.onStart, 34441 _onInterrupt = _snap.onInterrupt, 34442 _onComplete = _snap.onComplete, 34443 tween = tweenTo.tween; 34444 34445 if (scroll <= end && scroll >= start && endScroll !== scroll) { 34446 if (tween && !tween._initted && tween.data <= _abs(endScroll - scroll)) { 34447 return; 34448 } 34449 34450 if (snap.inertia === false) { 34451 change1 = endValue - self.progress; 34452 } 34453 34454 tweenTo(endScroll, { 34455 duration: snapDurClamp(_abs(Math.max(_abs(naturalEnd - totalProgress), _abs(endValue - totalProgress)) * 0.185 / velocity / 0.05 || 0)), 34456 ease: snap.ease || "power3", 34457 data: _abs(endScroll - scroll), 34458 onInterrupt: function onInterrupt() { 34459 return snapDelayedCall.restart(true) && _onInterrupt && _onInterrupt(self); 34460 }, 34461 onComplete: function onComplete() { 34462 lastSnap = scrollFunc(); 34463 snap1 = snap2 = animation && !isToggle ? animation.totalProgress() : self.progress; 34464 onSnapComplete && onSnapComplete(self); 34465 _onComplete && _onComplete(self); 34466 } 34467 }, scroll, change1 * change, endScroll - scroll - change1 * change); 34468 onStart && onStart(self, tweenTo.tween); 34469 } 34470 } else if (self.isActive) { 34471 snapDelayedCall.restart(true); 34472 } 34473 }).pause(); 34474 } 34475 34476 id && (_ids[id] = self); 34477 trigger = self.trigger = _getTarget(trigger || pin); 34478 pin = pin === true ? trigger : _getTarget(pin); 34479 _isString(toggleClass) && (toggleClass = { 34480 targets: trigger, 34481 className: toggleClass 34482 }); 34483 34484 if (pin) { 34485 pinSpacing === false || pinSpacing === _margin || (pinSpacing = !pinSpacing && _getComputedStyle(pin.parentNode).display === "flex" ? false : _padding); 34486 self.pin = pin; 34487 vars.force3D !== false && gsap.set(pin, {
34488 force3D: true 34489 }); 34490 pinCache = gsap.core.getCache(pin); 34491 34492 if (!pinCache.spacer) { 34493 if (pinSpacer) { 34494 pinSpacer = _getTarget(pinSpacer); 34495 pinSpacer && !pinSpacer.nodeType && (pinSpacer = pinSpacer.current || pinSpacer.nativeElement); 34496 pinCache.spacerIsNative = !!pinSpacer; 34497 pinSpacer && (pinCache.spacerState = _getState(pinSpacer)); 34498 } 34499 34500 pinCache.spacer = spacer = pinSpacer || _doc.createElement("div"); 34501 spacer.classList.add("pin-spacer"); 34502 id && spacer.classList.add("pin-spacer-" + id); 34503 pinCache.pinState = pinOriginalState = _getState(pin); 34504 } else { 34505 pinOriginalState = pinCache.pinState; 34506 } 34507 34508 self.spacer = spacer = pinCache.spacer; 34509 cs = _getComputedStyle(pin); 34510 spacingStart = cs[pinSpacing + direction.os2]; 34511 pinGetter = gsap.getProperty(pin); 34512 pinSetter = gsap.quickSetter(pin, direction.a, _px); 34513 34514 _swapPinIn(pin, spacer, cs); 34515 34516 pinState = _getState(pin); 34517 } 34518 34519 if (markers) { 34520 markerVars = _isObject(markers) ? _setDefaults(markers, _markerDefaults) : _markerDefaults; 34521 markerStartTrigger = _createMarker("scroller-start", id, scroller, direction, markerVars, 0); 34522 markerEndTrigger = _createMarker("scroller-end", id, scroller, direction, markerVars, 0, markerStartTrigger); 34523 offset = markerStartTrigger["offset" + direction.op.d2]; 34524 markerStart = _createMarker("start", id, scroller, direction, markerVars, offset, 0, containerAnimation); 34525 markerEnd = _createMarker("end", id, scroller, direction, markerVars, offset, 0, containerAnimation); 34526 containerAnimation && (caMarkerSetter = gsap.quickSetter([markerStart, markerEnd], direction.a, _px)); 34527 34528 if (!useFixedPosition && !(_proxies.length && _getProxyProp(scroller, "fixedMarkers") === true)) { 34529 _makePositionable(isViewport ? _body : scroller); 34530 34531 gsap.set([markerStartTrigger, markerEndTrigger], { 34532 force3D: true 34533 }); 34534 markerStartSetter = gsap.quickSetter(markerStartTrigger, direction.a, _px); 34535 markerEndSetter = gsap.quickSetter(markerEndTrigger, direction.a, _px); 34536 } 34537 } 34538 34539 if (containerAnimation) { 34540 var oldOnUpdate = containerAnimation.vars.onUpdate, 34541 oldParams = containerAnimation.vars.onUpdateParams; 34542 containerAnimation.eventCallback("onUpdate", function () { 34543 self.update(0, 0, 1); 34544 oldOnUpdate && oldOnUpdate.apply(oldParams || []); 34545 }); 34546 } 34547 34548 self.previous = function () { 34549 return _triggers[_triggers.indexOf(self) - 1]; 34550 }; 34551 34552 self.next = function () { 34553 return _triggers[_triggers.indexOf(self) + 1]; 34554 }; 34555 34556 self.revert = function (revert) { 34557 var r = revert !== false || !self.enabled, 34558 prevRefreshing = _refreshing; 34559 34560 if (r !== self.isReverted) { 34561 if (r) { 34562 self.scroll.rec || (self.scroll.rec = scrollFunc()); 34563 prevScroll = Math.max(scrollFunc(), self.scroll.rec || 0); 34564 prevProgress = self.progress; 34565 prevAnimProgress = animation && animation.progress(); 34566 } 34567 34568 markerStart && [markerStart, markerEnd, markerStartTrigger, markerEndTrigger].forEach(function (m) { 34569 return m.style.display = r ? "none" : "block"; 34570 }); 34571 r && (_refreshing = 1); 34572 self.update(r); 34573 _refreshing = prevRefreshing; 34574 pin && (r ? _swapPinOut(pin, spacer, pinOriginalState) : (!pinReparent || !self.isActive) && _swapPinIn(pin, spacer, _getComputedStyle(pin), spacerState)); 34575 self.isReverted = r; 34576 } 34577 }; 34578 34579 self.refresh = function (soft, force) { 34580 if ((_refreshing || !self.enabled) && !force) { 34581 return; 34582 } 34583 34584 if (pin && soft && _lastScrollTime) { 34585 _addListener(ScrollTrigger, "scrollEnd", _softRefresh); 34586 34587 return; 34588 } 34589 34590 _refreshing = 1; 34591 scrubTween && scrubTween.pause(); 34592 invalidateOnRefresh && animation && animation.progress(0).invalidate(); 34593 self.isReverted || self.revert(); 34594 34595 var size = getScrollerSize(), 34596 scrollerBounds = getScrollerOffsets(),
34597 max = containerAnimation ? containerAnimation.duration() : _maxScroll(scroller, direction), 34598 offset = 0, 34599 otherPinOffset = 0, 34600 parsedEnd = vars.end, 34601 parsedEndTrigger = vars.endTrigger || trigger, 34602 parsedStart = vars.start || (vars.start === 0 || !trigger ? 0 : pin ? "0 0" : "0 100%"), 34603 pinnedContainer = vars.pinnedContainer && _getTarget(vars.pinnedContainer), 34604 triggerIndex = trigger && Math.max(0, _triggers.indexOf(self)) || 0, 34605 i = triggerIndex, 34606 cs, 34607 bounds, 34608 scroll, 34609 isVertical, 34610 override, 34611 curTrigger, 34612 curPin, 34613 oppositeScroll, 34614 initted, 34615 revertedPins; 34616 34617 while (i--) { 34618 curTrigger = _triggers[i]; 34619 curTrigger.end || curTrigger.refresh(0, 1) || (_refreshing = 1); 34620 curPin = curTrigger.pin; 34621 34622 if (curPin && (curPin === trigger || curPin === pin) && !curTrigger.isReverted) { 34623 revertedPins || (revertedPins = []); 34624 revertedPins.unshift(curTrigger); 34625 curTrigger.revert(); 34626 } 34627 } 34628 34629 _isFunction(parsedStart) && (parsedStart = parsedStart(self)); 34630 start = _parsePosition(parsedStart, trigger, size, direction, scrollFunc(), markerStart, markerStartTrigger, self, scrollerBounds, borderWidth, useFixedPosition, max, containerAnimation) || (pin ? -0.001 : 0); 34631 _isFunction(parsedEnd) && (parsedEnd = parsedEnd(self)); 34632 34633 if (_isString(parsedEnd) && !parsedEnd.indexOf("+=")) { 34634 if (~parsedEnd.indexOf(" ")) { 34635 parsedEnd = (_isString(parsedStart) ? parsedStart.split(" ")[0] : "") + parsedEnd; 34636 } else { 34637 offset = _offsetToPx(parsedEnd.substr(2), size); 34638 parsedEnd = _isString(parsedStart) ? parsedStart : start + offset; 34639 parsedEndTrigger = trigger; 34640 } 34641 } 34642 34643 end = Math.max(start, _parsePosition(parsedEnd || (parsedEndTrigger ? "100% 0" : max), parsedEndTrigger, size, direction, scrollFunc() + offset, markerEnd, markerEndTrigger, self, scrollerBounds, borderWidth, useFixedPosition, max, containerAnimation)) || -0.001; 34644 change = end - start || (start -= 0.01) && 0.001; 34645 offset = 0; 34646 i = triggerIndex; 34647 34648 while (i--) { 34649 curTrigger = _triggers[i]; 34650 curPin = curTrigger.pin; 34651 34652 if (curPin && curTrigger.start - curTrigger._pinPush < start && !containerAnimation) { 34653 cs = curTrigger.end - curTrigger.start; 34654 (curPin === trigger || curPin === pinnedContainer) && !_isNumber(parsedStart) && (offset += cs); 34655 curPin === pin && (otherPinOffset += cs); 34656 } 34657 } 34658 34659 start += offset; 34660 end += offset; 34661 self._pinPush = otherPinOffset; 34662 34663 if (markerStart && offset) { 34664 cs = {}; 34665 cs[direction.a] = "+=" + offset; 34666 pinnedContainer && (cs[direction.p] = "-=" + scrollFunc()); 34667 gsap.set([markerStart, markerEnd], cs); 34668 } 34669 34670 if (pin) { 34671 cs = _getComputedStyle(pin); 34672 isVertical = direction === _vertical; 34673 scroll = scrollFunc(); 34674 pinStart = parseFloat(pinGetter(direction.a)) + otherPinOffset; 34675 !max && end > 1 && ((isViewport ? _body : scroller).style["overflow-" + direction.a] = "scroll"); 34676 34677 _swapPinIn(pin, spacer, cs); 34678 34679 pinState = _getState(pin); 34680 bounds = _getBounds(pin, true); 34681 oppositeScroll = useFixedPosition && _getScrollFunc(scroller, isVertical ? _horizontal : _vertical)(); 34682 34683 if (pinSpacing) { 34684 spacerState = [pinSpacing + direction.os2, change + otherPinOffset + _px]; 34685 spacerState.t = spacer; 34686 i = pinSpacing === _padding ? _getSize(pin, direction) + change + otherPinOffset : 0; 34687 i && spacerState.push(direction.d, i + _px); 34688 34689 _setState(spacerState); 34690 34691 useFixedPosition && scrollFunc(prevScroll); 34692 } 34693 34694 if (useFixedPosition) { 34695 override = { 34696 top: bounds.top + (isVertical ? scroll - start : oppositeScroll) + _px, 34697 left: bounds.left + (isVertical ? oppositeScroll : scroll - start) + _px, 34698 boxSizing: "border-box", 34699 position: "fixed" 34700 }; 34701 override[_width] = override["max" + _Width] = Math.ceil(bounds.width) + _px; 34702 override[_height] = override["max" + _Height] = Math.ceil(bounds.height) + _px; 34703 override[_margin] = override[_margin + _Top] = override[_margin + _Right] = override[_margin + _Bottom] = override[_margin + _Left] = "0"; 34704 override[_padding] = cs[_padding]; 34705 override[_padding + _Top] = cs[_padding + _Top]; 34706 override[_padding + _Right] = cs[_padding + _Right]; 34707 override[_padding + _Bottom] = cs[_padding + _Bottom]; 34708 override[_padding + _Left] = cs[_padding + _Left]; 34709 pinActiveState = _copyState(pinOriginalState, override, pinReparent); 34710 } 34711 34712 if (animation) { 34713 initted = animation._initted; 34714 34715 _suppressOverwrites(1); 34716 34717 animation.render(animation.duration(), true, true); 34718 pinChange = pinGetter(direction.a) - pinStart + change + otherPinOffset; 34719 change !== pinChange && pinActiveState.splice(pinActiveState.length - 2, 2); 34720 animation.render(0, true, true); 34721 initted || animation.invalidate(); 34722 34723 _suppressOverwrites(0); 34724 } else { 34725 pinChange = change; 34726 } 34727 } else if (trigger && scrollFunc() && !containerAnimation) { 34728 bounds = trigger.parentNode; 34729 34730 while (bounds && bounds !== _body) { 34731 if (bounds._pinOffset) { 34732 start -= bounds._pinOffset; 34733 end -= bounds._pinOffset; 34734 } 34735 34736 bounds = bounds.parentNode; 34737 } 34738 } 34739 34740 revertedPins && revertedPins.forEach(function (t) { 34741 return t.revert(false); 34742 }); 34743 self.start = start; 34744 self.end = end; 34745 scroll1 = scroll2 = scrollFunc(); 34746 34747 if (!containerAnimation) { 34748 scroll1 < prevScroll && scrollFunc(prevScroll); 34749 self.scroll.rec = 0; 34750 } 34751 34752 self.revert(false); 34753 _refreshing = 0; 34754 animation && isToggle && animation._initted && animation.progress() !== prevAnimProgress && animation.progress(prevAnimProgress, true).render(animation.time(), true, true); 34755 34756 if (prevProgress !== self.progress) { 34757 animation && !isToggle && animation.totalProgress(prevProgress, true); 34758 self.progress = prevProgress; 34759 self.update(0, 0, 1); 34760 } 34761 34762 pin && pinSpacing && (spacer._pinOffset = Math.round(self.progress * pinChange)); 34763 onRefresh && onRefresh(self); 34764 }; 34765 34766 self.getVelocity = function () { 34767 return (scrollFunc() - scroll2) / (_getTime() - _time2) * 1000 || 0; 34768 }; 34769 34770 self.endAnimation = function () {
vendor: 8,601 bytes, lines 34771-35009
34771 _endAnimation(self.callbackAnimation); 34772 34773 if (animation) { 34774 scrubTween ? scrubTween.progress(1) : !animation.paused() ? _endAnimation(animation, animation.reversed()) : isToggle || _endAnimation(animation, self.direction < 0, 1); 34775 } 34776 }; 34777 34778 self.getTrailing = function (name) { 34779 var i = _triggers.indexOf(self), 34780 a = self.direction > 0 ? _triggers.slice(0, i).reverse() : _triggers.slice(i + 1); 34781 34782 return _isString(name) ? a.filter(function (t) { 34783 return t.vars.preventOverlaps === name; 34784 }) : a; 34785 }; 34786 34787 self.update = function (reset, recordVelocity, forceFake) { 34788 if (containerAnimation && !forceFake && !reset) { 34789 return; 34790 } 34791 34792 var scroll = self.scroll(), 34793 p = reset ? 0 : (scroll - start) / change, 34794 clipped = p < 0 ? 0 : p > 1 ? 1 : p || 0, 34795 prevProgress = self.progress, 34796 isActive, 34797 wasActive, 34798 toggleState, 34799 action, 34800 stateChanged, 34801 toggled, 34802 isAtMax, 34803 isTakingAction; 34804 34805 if (recordVelocity) { 34806 scroll2 = scroll1; 34807 scroll1 = containerAnimation ? scrollFunc() : scroll; 34808 34809 if (snap) { 34810 snap2 = snap1; 34811 snap1 = animation && !isToggle ? animation.totalProgress() : clipped; 34812 } 34813 } 34814 34815 anticipatePin && !clipped && pin && !_refreshing && !_startup && _lastScrollTime && start < scroll + (scroll - scroll2) / (_getTime() - _time2) * anticipatePin && (clipped = 0.0001); 34816 34817 if (clipped !== prevProgress && self.enabled) { 34818 isActive = self.isActive = !!clipped && clipped < 1; 34819 wasActive = !!prevProgress && prevProgress < 1; 34820 toggled = isActive !== wasActive; 34821 stateChanged = toggled || !!clipped !== !!prevProgress; 34822 self.direction = clipped > prevProgress ? 1 : -1; 34823 self.progress = clipped; 34824 34825 if (stateChanged && !_refreshing) { 34826 toggleState = clipped && !prevProgress ? 0 : clipped === 1 ? 1 : prevProgress === 1 ? 2 : 3; 34827 34828 if (isToggle) { 34829 action = !toggled && toggleActions[toggleState + 1] !== "none" && toggleActions[toggleState + 1] || toggleActions[toggleState]; 34830 isTakingAction = animation && (action === "complete" || action === "reset" || action in animation); 34831 } 34832 } 34833 34834 preventOverlaps && toggled && (isTakingAction || scrub || !animation) && (_isFunction(preventOverlaps) ? preventOverlaps(self) : self.getTrailing(preventOverlaps).forEach(function (t) { 34835 return t.endAnimation(); 34836 })); 34837 34838 if (!isToggle) { 34839 if (scrubTween && !_refreshing && !_startup) { 34840 scrubTween.vars.totalProgress = clipped; 34841 scrubTween.invalidate().restart(); 34842 } else if (animation) { 34843 animation.totalProgress(clipped, !!_refreshing); 34844 } 34845 } 34846 34847 if (pin) { 34848 reset && pinSpacing && (spacer.style[pinSpacing + direction.os2] = spacingStart); 34849 34850 if (!useFixedPosition) { 34851 pinSetter(pinStart + pinChange * clipped); 34852 } else if (stateChanged) { 34853 isAtMax = !reset && clipped > prevProgress && end + 1 > scroll && scroll + 1 >= _maxScroll(scroller, direction); 34854 34855 if (pinReparent) { 34856 if (!reset && (isActive || isAtMax)) { 34857 var bounds = _getBounds(pin, true), 34858 _offset = scroll - start; 34859 34860 _reparent(pin, _body, bounds.top + (direction === _vertical ? _offset : 0) + _px, bounds.left + (direction === _vertical ? 0 : _offset) + _px); 34861 } else { 34862 _reparent(pin, spacer); 34863 } 34864 } 34865 34866 _setState(isActive || isAtMax ? pinActiveState : pinState); 34867 34868 pinChange !== change && clipped < 1 && isActive || pinSetter(pinStart + (clipped === 1 && !isAtMax ? pinChange : 0)); 34869 } 34870 } 34871 34872 snap && !tweenTo.tween && !_refreshing && !_startup && snapDelayedCall.restart(true); 34873 toggleClass && (toggled || once && clipped && (clipped < 1 || !_limitCallbacks)) && _toArray(toggleClass.targets).forEach(function (el) { 34874 return el.classList[isActive || once ? "add" : "remove"](toggleClass.className); 34875 }); 34876 onUpdate && !isToggle && !reset && onUpdate(self); 34877 34878 if (stateChanged && !_refreshing) { 34879 if (isToggle) { 34880 if (isTakingAction) { 34881 if (action === "complete") { 34882 animation.pause().totalProgress(1); 34883 } else if (action === "reset") { 34884 animation.restart(true).pause(); 34885 } else if (action === "restart") { 34886 animation.restart(true); 34887 } else { 34888 animation[action](); 34889 } 34890 } 34891 34892 onUpdate && onUpdate(self); 34893 } 34894 34895 if (toggled || !_limitCallbacks) { 34896 onToggle && toggled && _callback(self, onToggle); 34897 callbacks[toggleState] && _callback(self, callbacks[toggleState]); 34898 once && (clipped === 1 ? self.kill(false, 1) : callbacks[toggleState] = 0); 34899 34900 if (!toggled) { 34901 toggleState = clipped === 1 ? 1 : 3; 34902 callbacks[toggleState] && _callback(self, callbacks[toggleState]); 34903 } 34904 } 34905 34906 if (fastScrollEnd && !isActive && Math.abs(self.getVelocity()) > (_isNumber(fastScrollEnd) ? fastScrollEnd : 2500)) { 34907 _endAnimation(self.callbackAnimation); 34908 34909 scrubTween ? scrubTween.progress(1) : _endAnimation(animation, !clipped, 1); 34910 } 34911 } else if (isToggle && onUpdate && !_refreshing) { 34912 onUpdate(self); 34913 } 34914 } 34915 34916 if (markerEndSetter) { 34917 var n = containerAnimation ? scroll / containerAnimation.duration() * (containerAnimation._caScrollDist || 0) : scroll; 34918 markerStartSetter(n + (markerStartTrigger._isFlipped ? 1 : 0)); 34919 markerEndSetter(n); 34920 } 34921 34922 caMarkerSetter && caMarkerSetter(-scroll / containerAnimation.duration() * (containerAnimation._caScrollDist || 0)); 34923 }; 34924 34925 self.enable = function (reset, refresh) { 34926 if (!self.enabled) { 34927 self.enabled = true; 34928 34929 _addListener(scroller, "resize", _onResize); 34930 34931 _addListener(scroller, "scroll", _onScroll); 34932 34933 onRefreshInit && _addListener(ScrollTrigger, "refreshInit", onRefreshInit); 34934 34935 if (reset !== false) { 34936 self.progress = prevProgress = 0; 34937 scroll1 = scroll2 = lastSnap = scrollFunc(); 34938 } 34939 34940 refresh !== false && self.refresh(); 34941 } 34942 }; 34943 34944 self.getTween = function (snap) { 34945 return snap && tweenTo ? tweenTo.tween : scrubTween; 34946 }; 34947 34948 self.disable = function (reset, allowAnimation) { 34949 if (self.enabled) { 34950 reset !== false && self.revert(); 34951 self.enabled = self.isActive = false; 34952 allowAnimation || scrubTween && scrubTween.pause(); 34953 prevScroll = 0; 34954 pinCache && (pinCache.uncache = 1); 34955 onRefreshInit && _removeListener(ScrollTrigger, "refreshInit", onRefreshInit); 34956 34957 if (snapDelayedCall) { 34958 snapDelayedCall.pause(); 34959 tweenTo.tween && tweenTo.tween.kill() && (tweenTo.tween = 0); 34960 } 34961 34962 if (!isViewport) { 34963 var i = _triggers.length; 34964 34965 while (i--) { 34966 if (_triggers[i].scroller === scroller && _triggers[i] !== self) { 34967 return; 34968 } 34969 } 34970 34971 _removeListener(scroller, "resize", _onResize); 34972 34973 _removeListener(scroller, "scroll", _onScroll); 34974 } 34975 } 34976 }; 34977 34978 self.kill = function (revert, allowAnimation) { 34979 self.disable(revert, allowAnimation); 34980 scrubTween && scrubTween.kill(); 34981 id && delete _ids[id]; 34982 34983 var i = _triggers.indexOf(self); 34984 34985 _triggers.splice(i, 1); 34986 34987 i === _i && _direction > 0 && _i--; 34988 i = 0; 34989 34990 _triggers.forEach(function (t) { 34991 return t.scroller === self.scroller && (i = 1); 34992 }); 34993 34994 i || (self.scroll.rec = 0); 34995 34996 if (animation) { 34997 animation.scrollTrigger = null; 34998 revert && animation.render(-1); 34999 allowAnimation || animation.kill(); 35000 } 35001 35002 markerStart && [markerStart, markerEnd, markerStartTrigger, markerEndTrigger].forEach(function (m) { 35003 return m.parentNode && m.parentNode.removeChild(m); 35004 }); 35005 35006 if (pin) { 35007 pinCache && (pinCache.uncache = 1); 35008 i = 0; 35009
35010 _triggers.forEach(function (t) { 35011 return t.pin === pin && i++; 35012 }); 35013 35014 i || (pinCache.spacer = 0); 35015 } 35016 }; 35017 35018 self.enable(false, false); 35019 !animation || !animation.add || change ? self.refresh() : gsap.delayedCall(0.01, function () { 35020 return start || end || self.refresh(); 35021 }) && (change = 0.01) && (start = end = 0); 35022 }; 35023 35024 ScrollTrigger.register = function register(core) { 35025 if (!_coreInitted) { 35026 gsap = core || _getGSAP(); 35027 35028 if (_windowExists() && window.document) { 35029 _win = window; 35030 _doc = document; 35031 _docEl = _doc.documentElement; 35032 _body = _doc.body; 35033 } 35034 35035 if (gsap) { 35036 _toArray = gsap.utils.toArray; 35037 _clamp = gsap.utils.clamp; 35038 _suppressOverwrites = gsap.core.suppressOverwrites || _passThrough; 35039 gsap.core.globals("ScrollTrigger", ScrollTrigger); 35040 35041 if (_body) { 35042 _raf = _win.requestAnimationFrame || function (f) { 35043 return setTimeout(f, 16); 35044 }; 35045 35046 _addListener(_win, "wheel", _onScroll); 35047 35048 _root = [_win, _doc, _docEl, _body]; 35049 35050 _addListener(_doc, "scroll", _onScroll); 35051 35052 var bodyStyle = _body.style, 35053 border = bodyStyle.borderTopStyle, 35054 bounds; 35055 bodyStyle.borderTopStyle = "solid"; 35056 bounds = _getBounds(_body); 35057 _vertical.m = Math.round(bounds.top + _vertical.sc()) || 0; 35058 _horizontal.m = Math.round(bounds.left + _horizontal.sc()) || 0; 35059 border ? bodyStyle.borderTopStyle = border : bodyStyle.removeProperty("border-top-style"); 35060 _syncInterval = setInterval(_sync, 200); 35061 gsap.delayedCall(0.5, function () { 35062 return _startup = 0; 35063 }); 35064 35065 _addListener(_doc, "touchcancel", _passThrough); 35066 35067 _addListener(_body, "touchstart", _passThrough); 35068 35069 _multiListener(_addListener, _doc, "pointerdown,touchstart,mousedown", function () { 35070 return _pointerIsDown = 1; 35071 }); 35072 35073 _multiListener(_addListener, _doc, "pointerup,touchend,mouseup", function () { 35074 return _pointerIsDown = 0; 35075 }); 35076 35077 _transformProp = gsap.utils.checkPrefix("transform"); 35078 35079 _stateProps.push(_transformProp); 35080 35081 _coreInitted = _getTime(); 35082 _resizeDelay = gsap.delayedCall(0.2, _refreshAll).pause(); 35083 _autoRefresh = [_doc, "visibilitychange", function () { 35084 var w = _win.innerWidth, 35085 h = _win.innerHeight; 35086 35087 if (_doc.hidden) { 35088 _prevWidth = w; 35089 _prevHeight = h; 35090 } else if (_prevWidth !== w || _prevHeight !== h) { 35091 _onResize(); 35092 } 35093 }, _doc, "DOMContentLoaded", _refreshAll, _win, "load", function () { 35094 return _lastScrollTime || _refreshAll(); 35095 }, _win, "resize", _onResize]; 35096 35097 _iterateAutoRefresh(_addListener); 35098 } 35099 } 35100 } 35101 35102 return _coreInitted; 35103 }; 35104 35105 ScrollTrigger.defaults = function defaults(config) { 35106 for (var p in config) { 35107 _defaults[p] = config[p]; 35108 } 35109 }; 35110 35111 ScrollTrigger.kill = function kill() { 35112 _enabled = 0; 35113 35114 _triggers.slice(0).forEach(function (trigger) { 35115 return trigger.kill(1); 35116 }); 35117 }; 35118 35119 ScrollTrigger.config = function config(vars) { 35120 "limitCallbacks" in vars && (_limitCallbacks = !!vars.limitCallbacks); 35121 var ms = vars.syncInterval; 35122 ms && clearInterval(_syncInterval) || (_syncInterval = ms) && setInterval(_sync, ms); 35123 35124 if ("autoRefreshEvents" in vars) { 35125 _iterateAutoRefresh(_removeListener) || _iterateAutoRefresh(_addListener, vars.autoRefreshEvents || "none"); 35126 _ignoreResize = (vars.autoRefreshEvents + "").indexOf("resize") === -1; 35127 } 35128 }; 35129 35130 ScrollTrigger.scrollerProxy = function scrollerProxy(target, vars) { 35131 var t = _getTarget(target), 35132 i = _scrollers.indexOf(t), 35133 isViewport = _isViewport(t); 35134 35135 if (~i) { 35136 _scrollers.splice(i, isViewport ? 6 : 2); 35137 } 35138 35139 isViewport ? _proxies.unshift(_win, vars, _body, vars, _docEl, vars) : _proxies.unshift(t, vars); 35140 }; 35141 35142 ScrollTrigger.matchMedia = function matchMedia(vars) { 35143 var mq, p, i, func, result; 35144 35145 for (p in vars) { 35146 i = _media.indexOf(p); 35147 func = vars[p]; 35148 _creatingMedia = p; 35149 35150 if (p === "all") { 35151 func(); 35152 } else { 35153 mq = _win.matchMedia(p); 35154 35155 if (mq) { 35156 mq.matches && (result = func()); 35157 35158 if (~i) { 35159 _media[i + 1] = _combineFunc(_media[i + 1], func); 35160 _media[i + 2] = _combineFunc(_media[i + 2], result); 35161 } else { 35162 i = _media.length; 35163 35164 _media.push(p, func, result); 35165 35166 mq.addListener ? mq.addListener(_onMediaChange) : mq.addEventListener("change", _onMediaChange); 35167 } 35168 35169 _media[i + 3] = mq.matches; 35170 } 35171 } 35172 35173 _creatingMedia = 0; 35174 } 35175 35176 return _media; 35177 }; 35178 35179 ScrollTrigger.clearMatchMedia = function clearMatchMedia(query) { 35180 query || (_media.length = 0); 35181 query = _media.indexOf(query); 35182 query >= 0 && _media.splice(query, 4); 35183 }; 35184 35185 ScrollTrigger.isInViewport = function isInViewport(element, ratio, horizontal) { 35186 var bounds = (_isString(element) ? _getTarget(element) : element).getBoundingClientRect(), 35187 offset = bounds[horizontal ? _width : _height] * ratio || 0; 35188 return horizontal ? bounds.right - offset > 0 && bounds.left + offset < _win.innerWidth : bounds.bottom - offset > 0 && bounds.top + offset < _win.innerHeight; 35189 }; 35190 35191 ScrollTrigger.positionInViewport = function positionInViewport(element, referencePoint, horizontal) { 35192 _isString(element) && (element = _getTarget(element)); 35193 var bounds = element.getBoundingClientRect(), 35194 size = bounds[horizontal ? _width : _height], 35195 offset = referencePoint == null ? size / 2 : referencePoint in _keywords ? _keywords[referencePoint] * size : ~referencePoint.indexOf("%") ? parseFloat(referencePoint) * size / 100 : parseFloat(referencePoint) || 0; 35196 return horizontal ? (bounds.left + offset) / _win.innerWidth : (bounds.top + offset) / _win.innerHeight; 35197 }; 35198 35199 return ScrollTrigger; 35200 }(); 35201 ScrollTrigger.version = "3.8.0"; 35202 35203 ScrollTrigger.saveStyles = function (targets) {
35204 return targets ? _toArray(targets).forEach(function (target) { 35205 if (target && target.style) { 35206 var i = _savedStyles.indexOf(target); 35207 35208 i >= 0 && _savedStyles.splice(i, 5); 35209 35210 _savedStyles.push(target, target.style.cssText, target.getBBox && target.getAttribute("transform"), gsap.core.getCache(target), _creatingMedia); 35211 } 35212 }) : _savedStyles; 35213 }; 35214 35215 ScrollTrigger.revert = function (soft, media) { 35216 return _revertAll(!soft, media); 35217 }; 35218 35219 ScrollTrigger.create = function (vars, animation) { 35220 return new ScrollTrigger(vars, animation); 35221 }; 35222 35223 ScrollTrigger.refresh = function (safe) { 35224 return safe ? _onResize() : (_coreInitted || ScrollTrigger.register()) && _refreshAll(true); 35225 }; 35226 35227 ScrollTrigger.update = _updateAll; 35228 ScrollTrigger.clearScrollMemory = _clearScrollMemory; 35229 35230 ScrollTrigger.maxScroll = function (element, horizontal) { 35231 return _maxScroll(element, horizontal ? _horizontal : _vertical); 35232 }; 35233 35234 ScrollTrigger.getScrollFunc = function (element, horizontal) { 35235 return _getScrollFunc(_getTarget(element), horizontal ? _horizontal : _vertical); 35236 }; 35237 35238 ScrollTrigger.getById = function (id) { 35239 return _ids[id]; 35240 }; 35241 35242 ScrollTrigger.getAll = function () { 35243 return _triggers.slice(0); 35244 }; 35245 35246 ScrollTrigger.isScrolling = function () { 35247 return !!_lastScrollTime; 35248 }; 35249 35250 ScrollTrigger.snapDirectional = _snapDirectional; 35251 35252 ScrollTrigger.addEventListener = function (type, callback) { 35253 var a = _listeners[type] || (_listeners[type] = []); 35254 ~a.indexOf(callback) || a.push(callback); 35255 }; 35256 35257 ScrollTrigger.removeEventListener = function (type, callback) { 35258 var a = _listeners[type], 35259 i = a && a.indexOf(callback); 35260 i >= 0 && a.splice(i, 1); 35261 }; 35262 35263 ScrollTrigger.batch = function (targets, vars) { 35264 var result = [], 35265 varsCopy = {}, 35266 interval = vars.interval || 0.016, 35267 batchMax = vars.batchMax || 1e9, 35268 proxyCallback = function proxyCallback(type, callback) { 35269 var elements = [], 35270 triggers = [], 35271 delay = gsap.delayedCall(interval, function () { 35272 callback(elements, triggers); 35273 elements = []; 35274 triggers = []; 35275 }).pause(); 35276 return function (self) { 35277 elements.length || delay.restart(true); 35278 elements.push(self.trigger); 35279 triggers.push(self); 35280 batchMax <= elements.length && delay.progress(1); 35281 }; 35282 }, 35283 p; 35284 35285 for (p in vars) { 35286 varsCopy[p] = p.substr(0, 2) === "on" && _isFunction(vars[p]) && p !== "onRefreshInit" ? proxyCallback(p, vars[p]) : vars[p]; 35287 } 35288 35289 if (_isFunction(batchMax)) { 35290 batchMax = batchMax(); 35291 35292 _addListener(ScrollTrigger, "refresh", function () { 35293 return batchMax = vars.batchMax(); 35294 }); 35295 } 35296 35297 _toArray(targets).forEach(function (target) { 35298 var config = {}; 35299 35300 for (p in varsCopy) { 35301 config[p] = varsCopy[p]; 35302 } 35303 35304 config.trigger = target; 35305 result.push(ScrollTrigger.create(config)); 35306 }); 35307 35308 return result; 35309 }; 35310 35311 ScrollTrigger.sort = function (func) { 35312 return _triggers.sort(func || function (a, b) { 35313 return (a.vars.refreshPriority || 0) * -1e6 + a.start - (b.start + (b.vars.refreshPriority || 0) * -1e6); 35314 }); 35315 }; 35316 35317 _getGSAP() && gsap.registerPlugin(ScrollTrigger); 35318 35319 exports.ScrollTrigger = ScrollTrigger; 35320 exports.default = ScrollTrigger; 35321 35322 Object.defineProperty(exports, '__esModule', { value: true }); 35323 35324}))); 35325 35326/* ======================================================================== 35327 * Bootstrap: collapse.js v3.1.1 35328 * http://getbootstrap.com/javascript/#collapse 35329 * ======================================================================== 35330 * Copyright 2011-2014 Twitter, Inc. 35331 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 35332 * ======================================================================== */ 35333 35334 35335+function ($) { 35336 'use strict'; 35337 35338 // COLLAPSE PUBLIC CLASS DEFINITION 35339 // ================================ 35340 35341 var Collapse = function (element, options) { 35342 this.$element = $(element) 35343 this.options = $.extend({}, Collapse.DEFAULTS, options) 35344 this.transitioning = null 35345 35346 if (this.options.parent) this.$parent = $(this.options.parent) 35347 if (this.options.toggle) this.toggle() 35348 } 35349 35350 Collapse.DEFAULTS = { 35351 toggle: true 35352 } 35353 35354 Collapse.prototype.dimension = function () { 35355 var hasWidth = this.$element.hasClass('width') 35356 return hasWidth ? 'width' : 'height' 35357 } 35358 35359 Collapse.prototype.show = function () { 35360 if (this.transitioning || this.$element.hasClass('in')) return 35361 35362 var startEvent = $.Event('show.bs.collapse') 35363 this.$element.trigger(startEvent) 35364 if (startEvent.isDefaultPrevented()) return 35365 35366 var actives = this.$parent && this.$parent.find('> .panel > .in') 35367 35368 if (actives && actives.length) { 35369 var hasData = actives.data('bs.collapse') 35370 if (hasData && hasData.transitioning) return 35371 actives.collapse('hide') 35372 hasData || actives.data('bs.collapse', null) 35373 } 35374 35375 var dimension = this.dimension() 35376 35377 this.$element 35378 .removeClass('collapse') 35379 .addClass('collapsing')[dimension](0) 35380 35381 this.transitioning = 1 35382 35383 var complete = function (e) { 35384 if (e && e.target != this.$element[0]) return 35385 this.$element 35386 .removeClass('collapsing') 35387 .addClass('collapse in')[dimension]('auto') 35388 this.transitioning = 0 35389 this.$element.trigger('shown.bs.collapse') 35390 } 35391 35392 if (!$.support.transition) return complete.call(this) 35393 35394 var scrollSize = $.camelCase(['scroll', dimension].join('-')) 35395 35396 this.$element 35397 .one($.support.transition.end, $.proxy(complete, this)) 35398 .emulateTransitionEnd(350)[dimension](this.$element[0][scrollSize]) 35399 } 35400 35401 Collapse.prototype.hide = function () { 35402 if (this.transitioning || !this.$element.hasClass('in')) return 35403 35404 var startEvent = $.Event('hide.bs.collapse') 35405 this.$element.trigger(startEvent) 35406 if (startEvent.isDefaultPrevented()) return 35407 35408 var dimension = this.dimension() 35409 35410 this.$element[dimension](this.$element[dimension]())[0].offsetHeight 35411 35412 this.$element 35413 .addClass('collapsing') 35414 .removeClass('collapse') 35415 .removeClass('in') 35416 35417 this.transitioning = 1 35418 35419 var complete = function (e) { 35420 if (e && e.target != this.$element[0]) return 35421 this.transitioning = 0 35422 this.$element 35423 .trigger('hidden.bs.collapse') 35424 .removeClass('collapsing') 35425 .addClass('collapse') 35426 } 35427 35428 if (!$.support.transition) return complete.call(this) 35429 35430 this.$element 35431 [dimension](0) 35432 .one($.support.transition.end, $.proxy(complete, this)) 35433 .emulateTransitionEnd(350) 35434 } 35435 35436 Collapse.prototype.toggle = function () { 35437 this[this.$element.hasClass('in') ? 'hide' : 'show']() 35438 } 35439 35440 35441 // COLLAPSE PLUGIN DEFINITION 35442 // ========================== 35443 35444 var old = $.fn.collapse 35445 35446 $.fn.collapse = function (option) { 35447 return this.each(function () { 35448 var $this = $(this) 35449 var data = $this.data('bs.collapse') 35450 var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option) 35451 35452 if (!data && options.toggle && option == 'show') option = !option 35453 if (!data) $this.data('bs.collapse', (data = new Collapse(this, options))) 35454 if (typeof option == 'string') data[option]() 35455 }) 35456 } 35457 35458 $.fn.collapse.Constructor = Collapse 35459 35460 35461 // COLLAPSE NO CONFLICT 35462 // ==================== 35463 35464 $.fn.collapse.noConflict = function () { 35465 $.fn.collapse = old 35466 return this 35467 } 35468 35469 35470 // COLLAPSE DATA-API 35471 // ================= 35472 35473 $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) { 35474 var $this = $(this), href 35475 var target = $this.attr('data-target') 35476 || e.preventDefault() 35477 || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7 35478 //Edited by Uncode to replace ID in panel [START] 35479 var _target = href.replace(/^#/, ""); 35480 if ( $('[data-id="' + _target + '"]').length ) { 35481 var $target = $('[data-id="' + _target + '"]') 35482 } else { 35483 var $target = $(target) 35484 } 35485 //Edited by Uncode to replace ID in panel [END] 35486 var data = $target.data('bs.collapse') 35487 var option = data ? 'toggle' : $this.data() 35488 var parent = $this.attr('data-parent') 35489 var $parent = parent && $(parent) 35490 35491 if (!data || !data.transitioning) { 35492 if ($parent) $parent.find('[data-toggle="collapse"][data-parent="' + parent + '"]').not($this).addClass('collapsed') 35493 $this[$target.hasClass('in') ? 'addClass' : 'removeClass']('collapsed') 35494 } 35495 35496 $target.collapse(option) 35497 }) 35498 35499}(jQuery); 35500 35501/* ======================================================================== 35502 * Bootstrap: tab.js v3.1.1 35503 * http://getbootstrap.com/javascript/#tabs 35504 * ======================================================================== 35505 * Copyright 2011-2014 Twitter, Inc. 35506 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 35507 * ======================================================================== */ 35508 35509 35510+function ($) { 35511 'use strict'; 35512 35513 // TAB CLASS DEFINITION 35514 // ==================== 35515 35516 var Tab = function (element) { 35517 this.element = $(element) 35518 } 35519 35520 Tab.prototype.show = function () { 35521 var $this = this.element 35522 var $ul = $this.closest('ul:not(.dropdown-menu)') 35523 var selector = $this.data('target') 35524 35525 if (!selector) { 35526 selector = $this.attr('href') 35527 selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7 35528 } 35529 35530 if ($this.parent('li').hasClass('active')) return 35531 35532 var previous = $ul.find('.active:last a')[0] 35533 var e = $.Event('show.bs.tab', { 35534 relatedTarget: previous 35535 }) 35536 35537 $this.trigger(e) 35538 35539 if (e.isDefaultPrevented()) return 35540 35541 //Edited by Uncode to replace ID in panel [START] 35542 var _target = selector.replace(/^#/, ""); 35543 if ( $('[data-id="' + _target + '"]').length ) 35544 var $target = $('[data-id="' + _target + '"]') 35545 else 35546 var $target = $(selector) 35547 //Edited by Uncode to replace ID in panel [END] 35548 35549 this.activate($this.parent('li'), $ul) 35550 this.activate($target, $target.parent(), function () { 35551 $this.trigger({ 35552 type: 'shown.bs.tab', 35553 relatedTarget: previous 35554 }) 35555 }) 35556 } 35557 35558 Tab.prototype.activate = function (element, container, callback) { 35559 var $active = container.find('> .active') 35560 var transition = callback 35561 && $.support.transition 35562 && $active.hasClass('fade') 35563 35564 function next() { 35565 $active 35566 .removeClass('active') 35567 .find('> .dropdown-menu > .active') 35568 .removeClass('active') 35569 35570 element.addClass('active') 35571 35572 if (transition) { 35573 element[0].offsetWidth // reflow for transition 35574 element.addClass('in') 35575 } else { 35576 element.removeClass('fade') 35577 } 35578 35579 if (element.parent('.dropdown-menu')) { 35580 element.closest('li.dropdown').addClass('active') 35581 } 35582 35583 callback && callback() 35584 } 35585 35586 transition ? 35587 $active 35588 .one($.support.transition.end, next) 35589 .emulateTransitionEnd(150) : 35590 next() 35591 35592 $active.removeClass('in') 35593 } 35594 35595 35596 // TAB PLUGIN DEFINITION 35597 // ===================== 35598 35599 var old = $.fn.tab 35600 35601 $.fn.tab = function ( option ) { 35602 return this.each(function () { 35603 var $this = $(this) 35604 var data = $this.data('bs.tab') 35605 35606 if (!data) $this.data('bs.tab', (data = new Tab(this))) 35607 if (typeof option == 'string') data[option]() 35608 }) 35609 } 35610 35611 $.fn.tab.Constructor = Tab 35612 35613 35614 // TAB NO CONFLICT 35615 // =============== 35616 35617 $.fn.tab.noConflict = function () { 35618 $.fn.tab = old 35619 return this 35620 } 35621 35622 35623 // TAB DATA-API 35624 // ============ 35625 35626 $(document).on('click.bs.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) { 35627 e.preventDefault() 35628 $(this).tab('show') 35629 }) 35630 35631}(jQuery); 35632 35633/* ======================================================================== 35634 * Bootstrap: tooltip.js v3.1.1 35635 * http://getbootstrap.com/javascript/#tooltip 35636 * Inspired by the original jQuery.tipsy by Jason Frame 35637 * ======================================================================== 35638 * Copyright 2011-2014 Twitter, Inc. 35639 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 35640 * ======================================================================== */ 35641 35642 35643+function ($) { 35644 'use strict'; 35645 35646 // TOOLTIP PUBLIC CLASS DEFINITION 35647 // =============================== 35648 35649 var Tooltip = function (element, options) { 35650 this.type = 35651 this.options = 35652 this.enabled = 35653 this.timeout = 35654 this.hoverState = 35655 this.$element = null 35656 35657 this.init('tooltip', element, options) 35658 } 35659 35660 Tooltip.DEFAULTS = { 35661 animation: true, 35662 placement: 'top', 35663 selector: false, 35664 template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>', 35665 trigger: 'hover focus', 35666 title: '', 35667 delay: 0, 35668 html: false, 35669 container: false, 35670 viewport: { 35671 selector: 'body', 35672 padding: 0 35673 } 35674 } 35675 35676 Tooltip.prototype.init = function (type, element, options) { 35677 this.enabled = true 35678 this.type = type 35679 this.$element = $(element) 35680 this.options = this.getOptions(options) 35681 this.$viewport = this.options.viewport && $(this.options.viewport.selector || this.options.viewport) 35682 35683 var triggers = this.options.trigger.split(' ') 35684 35685 for (var i = triggers.length; i--;) { 35686 var trigger = triggers[i] 35687 35688 if (trigger == 'click') { 35689 this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this)) 35690 } else if (trigger != 'manual') { 35691 var eventIn = trigger == 'hover' ? 'mouseenter' : 'focusin' 35692 var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout' 35693 35694 this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this)) 35695 this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this)) 35696 } 35697 } 35698 35699 this.options.selector ? 35700 (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) : 35701 this.fixTitle() 35702 } 35703 35704 Tooltip.prototype.getDefaults = function () { 35705 return Tooltip.DEFAULTS 35706 } 35707 35708 Tooltip.prototype.getOptions = function (options) { 35709 options = $.extend({}, this.getDefaults(), this.$element.data(), options) 35710 35711 if (options.delay && typeof options.delay == 'number') { 35712 options.delay = { 35713 show: options.delay, 35714 hide: options.delay 35715 } 35716 } 35717 35718 return options 35719 } 35720 35721 Tooltip.prototype.getDelegateOptions = function () { 35722 var options = {} 35723 var defaults = this.getDefaults() 35724 35725 this._options && $.each(this._options, function (key, value) { 35726 if (defaults[key] != value) options[key] = value 35727 }) 35728 35729 return options 35730 } 35731 35732 Tooltip.prototype.enter = function (obj) { 35733 var self = obj instanceof this.constructor ? 35734 obj : $(obj.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type) 35735 35736 clearTimeout(self.timeout) 35737 35738 self.hoverState = 'in' 35739 35740 if (!self.options.delay || !self.options.delay.show) return self.show() 35741 35742 self.timeout = setTimeout(function () { 35743 if (self.hoverState == 'in') self.show() 35744 }, self.options.delay.show) 35745 } 35746 35747 Tooltip.prototype.leave = function (obj) { 35748 var self = obj instanceof this.constructor ? 35749 obj : $(obj.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type) 35750 35751 clearTimeout(self.timeout) 35752 35753 self.hoverState = 'out' 35754 35755 if (!self.options.delay || !self.options.delay.hide) return self.hide() 35756 35757 self.timeout = setTimeout(function () { 35758 if (self.hoverState == 'out') self.hide() 35759 }, self.options.delay.hide) 35760 } 35761 35762 Tooltip.prototype.show = function () { 35763 var e = $.Event('show.bs.' + this.type) 35764 35765 if (this.hasContent() && this.enabled) { 35766 this.$element.trigger(e) 35767 35768 if (e.isDefaultPrevented()) return 35769 var that = this; 35770 35771 var $tip = this.tip() 35772 35773 this.setContent() 35774 35775 if (this.options.animation) $tip.addClass('fade') 35776 35777 var placement = typeof this.options.placement == 'function' ? 35778 this.options.placement.call(this, $tip[0], this.$element[0]) : 35779 this.options.placement 35780 35781 var autoToken = /\s?auto?\s?/i 35782 var autoPlace = autoToken.test(placement) 35783 if (autoPlace) placement = placement.replace(autoToken, '') || 'top' 35784 35785 $tip 35786 .detach() 35787 .css({ top: 0, left: 0, display: 'block' }) 35788 .addClass(placement) 35789 35790 this.options.container ? $tip.appendTo($(document).find(this.options.container)) : $tip.insertAfter(this.$element) 35791 35792 var pos = this.getPosition() 35793 var actualWidth = $tip[0].offsetWidth 35794 var act
35794ualHeight = $tip[0].offsetHeight 35795 35796 if (autoPlace) { 35797 var orgPlacement = placement 35798 var $parent = this.$element.parent() 35799 var parentDim = this.getPosition($parent) 35800 35801 placement = placement == 'bottom' && pos.top + pos.height + actualHeight - parentDim.scroll > parentDim.height ? 'top' : 35802 placement == 'top' && pos.top - parentDim.scroll - actualHeight < 0 ? 'bottom' : 35803 placement == 'right' && pos.right + actualWidth > parentDim.width ? 'left' : 35804 placement == 'left' && pos.left - actualWidth < parentDim.left ? 'right' : 35805 placement 35806 35807 $tip 35808 .removeClass(orgPlacement) 35809 .addClass(placement) 35810 } 35811 35812 var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight) 35813 35814 this.applyPlacement(calculatedOffset, placement) 35815 this.hoverState = null 35816 35817 var complete = function() { 35818 that.$element.trigger('shown.bs.' + that.type) 35819 } 35820 35821 $.support.transition && this.$tip.hasClass('fade') ? 35822 $tip 35823 .one($.support.transition.end, complete) 35824 .emulateTransitionEnd(150) : 35825 complete() 35826 } 35827 } 35828 35829 Tooltip.prototype.applyPlacement = function (offset, placement) { 35830 var $tip = this.tip() 35831 var width = $tip[0].offsetWidth 35832 var height = $tip[0].offsetHeight 35833 35834 // manually read margins because getBoundingClientRect includes difference 35835 var marginTop = parseInt($tip.css('margin-top'), 10) 35836 var marginLeft = parseInt($tip.css('margin-left'), 10) 35837 35838 // we must check for NaN for ie 8/9 35839 if (isNaN(marginTop)) marginTop = 0 35840 if (isNaN(marginLeft)) marginLeft = 0 35841 35842 offset.top = offset.top + marginTop 35843 offset.left = offset.left + marginLeft 35844 35845 // $.fn.offset doesn't round pixel values 35846 // so we use setOffset directly with our own function B-0 35847 $.offset.setOffset($tip[0], $.extend({ 35848 using: function (props) { 35849 $tip.css({ 35850 top: Math.round(props.top), 35851 left: Math.round(props.left) 35852 }) 35853 } 35854 }, offset), 0) 35855 35856 $tip.addClass('in') 35857 35858 // check to see if placing tip in new offset caused the tip to resize itself 35859 var actualWidth = $tip[0].offsetWidth 35860 var actualHeight = $tip[0].offsetHeight 35861 35862 if (placement == 'top' && actualHeight != height) { 35863 offset.top = offset.top + height - actualHeight 35864 } 35865 35866 var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight) 35867 35868 if (delta.left) offset.left += delta.left 35869 else offset.top += delta.top 35870 35871 var arrowDelta = delta.left ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight 35872 var arrowPosition = delta.left ? 'left' : 'top' 35873 var arrowOffsetPosition = delta.left ? 'offsetWidth' : 'offsetHeight' 35874 35875 $tip.offset(offset) 35876 this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], arrowPosition) 35877 } 35878 35879 Tooltip.prototype.replaceArrow = function (delta, dimension, position) { 35880 this.arrow().css(position, delta ? (50 * (1 - delta / dimension) + '%') : '') 35881 } 35882 35883 Tooltip.prototype.setContent = function () { 35884 var $tip = this.tip() 35885 var title = this.getTitle() 35886 35887 $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title) 35888 $tip.removeClass('fade in top bottom left right') 35889 } 35890 35891 Tooltip.prototype.hide = function () { 35892 var that = this 35893 var $tip = this.tip() 35894 var e = $.Event('hide.bs.' + this.type) 35895 35896 function complete() { 35897 if (that.hoverState != 'in') $tip.detach() 35898 that.$element.trigger('hidden.bs.' + that.type) 35899 } 35900 35901 this.$element.trigger(e) 35902 35903 if (e.isDefaultPrevented()) return 35904 35905 $tip.removeClass('in') 35906 35907 $.support.transition && this.$tip.hasClass('fade') ? 35908 $tip 35909 .one($.support.transition.end, complete) 35910 .emulateTransitionEnd(150) : 35911 complete() 35912 35913 this.hoverState = null 35914 35915 return this 35916 } 35917 35918 Tooltip.prototype.fixTitle = function () { 35919 var $e = this.$element 35920 if ($e.attr('title') || typeof($e.attr('data-original-title')) != 'string') { 35921 $e.attr('data-original-title', $e.attr('title') || '').attr('title', '') 35922 } 35923 } 35924 35925 Tooltip.prototype.hasContent = function () { 35926 return this.getTitle() 35927 } 35928 35929 Tooltip.prototype.getPosition = function ($element) { 35930 $element = $element || this.$element 35931 var el = $element[0] 35932 var isBody = el.tagName == 'BODY' 35933 return $.extend({}, (typeof el.getBoundingClientRect == 'function') ? el.getBoundingClientRect() : null, { 35934 scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop(), 35935 width: isBody ? $(window).width() : $element.outerWidth(), 35936 height: isBody ? $(window).height() : $element.outerHeight() 35937 }, isBody ? {top: 0, left: 0} : $element.offset()) 35938 } 35939 35940 Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) { 35941 return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } : 35942 placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } : 35943 placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } : 35944 /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width } 35945 35946 } 35947 35948 Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) { 35949 var delta = { top: 0, left: 0 } 35950 if (!this.$viewport) return delta 35951 35952 var viewportPadding = this.options.viewport && this.options.viewport.padding || 0 35953 var viewportDimensions = this.getPosition(this.$viewport) 35954 35955 if (/right|left/.test(placement)) { 35956 var topEdgeOffset = pos.top - viewportPadding - viewportDimensions.scroll 35957 var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight 35958 if (topEdgeOffset < viewportDimensions.top) { // top overflow 35959 delta.top = viewportDimensions.top - topEdgeOffset 35960 } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow 35961 delta.top = viewportDimensions.top + viewportDimensions.height - bottom
35961EdgeOffset 35962 } 35963 } else { 35964 var leftEdgeOffset = pos.left - viewportPadding 35965 var rightEdgeOffset = pos.left + viewportPadding + actualWidth 35966 if (leftEdgeOffset < viewportDimensions.left) { // left overflow 35967 delta.left = viewportDimensions.left - leftEdgeOffset 35968 } else if (rightEdgeOffset > viewportDimensions.width) { // right overflow 35969 delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset 35970 } 35971 } 35972 35973 return delta 35974 } 35975 35976 Tooltip.prototype.getTitle = function () { 35977 var title 35978 var $e = this.$element 35979 var o = this.options 35980 35981 title = $e.attr('data-original-title') 35982 || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title) 35983 35984 return title 35985 } 35986 35987 Tooltip.prototype.tip = function () { 35988 return this.$tip = this.$tip || $(this.options.template) 35989 } 35990 35991 Tooltip.prototype.arrow = function () { 35992 return this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow') 35993 } 35994 35995 Tooltip.prototype.validate = function () { 35996 if (!this.$element[0].parentNode) { 35997 this.hide() 35998 this.$element = null 35999 this.options = null 36000 } 36001 } 36002 36003 Tooltip.prototype.enable = function () { 36004 this.enabled = true 36005 } 36006 36007 Tooltip.prototype.disable = function () { 36008 this.enabled = false 36009 } 36010 36011 Tooltip.prototype.toggleEnabled = function () { 36012 this.enabled = !this.enabled 36013 } 36014 36015 Tooltip.prototype.toggle = function (e) { 36016 var self = e ? $(e.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type) : this 36017 self.tip().hasClass('in') ? self.leave(self) : self.enter(self) 36018 } 36019 36020 Tooltip.prototype.destroy = function () { 36021 clearTimeout(this.timeout) 36022 this.hide().$element.off('.' + this.type).removeData('bs.' + this.type) 36023 } 36024 36025 36026 // TOOLTIP PLUGIN DEFINITION 36027 // ========================= 36028 36029 var old = $.fn.tooltip 36030 36031 $.fn.tooltip = function (option) { 36032 return this.each(function () { 36033 var $this = $(this) 36034 var data = $this.data('bs.tooltip') 36035 var options = typeof option == 'object' && option 36036 36037 if (!data && option == 'destroy') return 36038 if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options))) 36039 if (typeof option == 'string') data[option]() 36040 }) 36041 } 36042 36043 $.fn.tooltip.Constructor = Tooltip 36044 36045 36046 // TOOLTIP NO CONFLICT 36047 // =================== 36048 36049 $.fn.tooltip.noConflict = function () { 36050 $.fn.tooltip = old 36051 return this 36052 } 36053 36054}(jQuery); 36055 36056/* ======================================================================== 36057 * Bootstrap: transition.js v3.1.1 36058 * http://getbootstrap.com/javascript/#transitions 36059 * ======================================================================== 36060 * Copyright 2011-2014 Twitter, Inc. 36061 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 36062 * ======================================================================== */ 36063 36064 36065+function ($) { 36066 'use strict'; 36067 36068 // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/) 36069 // ============================================================ 36070 36071 function transitionEnd() { 36072 var el = document.createElement('bootstrap') 36073 36074 var transEndEventNames = { 36075 WebkitTransition : 'webkitTransitionEnd', 36076 MozTransition : 'transitionend', 36077 OTransition : 'oTransitionEnd otransitionend', 36078 transition : 'transitionend' 36079 } 36080 36081 for (var name in transEndEventNames) { 36082 if (el.style[name] !== undefined) { 36083 return { end: transEndEventNames[name] } 36084 } 36085 } 36086 36087 return false // explicit for ie8 ( ._.) 36088 } 36089 36090 // http://blog.alexmaccaw.com/css-transitions 36091 $.fn.emulateTransitionEnd = function (duration) { 36092 var called = false, $el = this 36093 $(this).one($.support.transition.end, function () { called = true }) 36094 var callback = function () { if (!called) $($el).trigger($.support.transition.end) } 36095 setTimeout(callback, duration) 36096 return this 36097 } 36098 36099 $(function () { 36100 $.support.transition = transitionEnd() 36101 }) 36102 36103}(jQuery); 36104 36105 36106// ------------------------------------------ 36107// Rellax.js 36108// Buttery smooth parallax library 36109// Copyright (c) 2016 Moe Amaya (@moeamaya) 36110// MIT license 36111// 36112// Thanks to Paraxify.js and Jaime Cabllero 36113// for parallax concepts 36114// ------------------------------------------ 36115 36116(function (root, factory) { 36117 if (typeof define === 'function' && define.amd) { 36118 // AMD. Register as an anonymous module. 36119 define([], factory); 36120 } else if (typeof module === 'object' && module.exports) { 36121 // Node. Does not work with strict CommonJS, but 36122 // only CommonJS-like environments that support module.exports, 36123 // like Node. 36124 module.exports = factory(); 36125 } else { 36126 // Browser globals (root is window) 36127 root.Rellax = factory(); 36128 } 36129}(typeof window !== "undefined" ? window : global, function () { 36130 var Rellax = function(el, options){ 36131 "use strict"; 36132 36133 var self = Object.create(Rellax.prototype); 36134 36135 var posY = 0; 36136 var screenY = 0; 36137 var posX = 0; 36138 var screenX = 0; 36139 var blocks = []; 36140 var pause = true; 36141 36142 // check what requestAnimationFrame to use, and if 36143 // it's not supported, use the onscroll event 36144 var loop = window.requestAnimationFrame || 36145 window.webkitRequestAnimationFrame || 36146 window.mozRequestAnimationFrame || 36147 window.msRequestAnimationFrame || 36148 window.oRequestAnimationFrame || 36149 function(callback){ return setTimeout(callback, 1000 / 60); }; 36150 36151 // store the id for later use 36152 var loopId = null; 36153 36154 // Test via a getter in the options object to see if the passive property is accessed 36155 var supportsPassive = false;
vendor: 10,724 bytes, lines 36156-36457
36156 try { 36157 var opts = Object.defineProperty({}, 'passive', { 36158 get: function() { 36159 supportsPassive = true; 36160 } 36161 }); 36162 window.addEventListener("testPassive", null, opts); 36163 window.removeEventListener("testPassive", null, opts); 36164 } catch (e) {} 36165 36166 // check what cancelAnimation method to use 36167 var clearLoop = window.cancelAnimationFrame || window.mozCancelAnimationFrame || clearTimeout; 36168 36169 // check which transform property to use 36170 var transformProp = window.transformProp || (function(){ 36171 var testEl = document.createElement('div'); 36172 if (testEl.style.transform === null) { 36173 var vendors = ['Webkit', 'Moz', 'ms']; 36174 for (var vendor in vendors) { 36175 if (testEl.style[ vendors[vendor] + 'Transform' ] !== undefined) { 36176 return vendors[vendor] + 'Transform'; 36177 } 36178 } 36179 } 36180 return 'transform'; 36181 })(); 36182 36183 // Default Settings 36184 self.options = { 36185 speed: -2, 36186 verticalSpeed: null, 36187 horizontalSpeed: null, 36188 breakpoints: [576, 768, 1201], 36189 center: false, 36190 wrapper: null, 36191 relativeToWrapper: false, 36192 round: true, 36193 vertical: true, 36194 horizontal: false, 36195 verticalScrollAxis: "y", 36196 horizontalScrollAxis: "x", 36197 callback: function() {}, 36198 }; 36199 36200 // User defined options (might have more in the future) 36201 if (options){ 36202 Object.keys(options).forEach(function(key){ 36203 self.options[key] = options[key]; 36204 }); 36205 } 36206 36207 function validateCustomBreakpoints () { 36208 if (self.options.breakpoints.length === 3 && Array.isArray(self.options.breakpoints)) { 36209 var isAscending = true; 36210 var isNumerical = true; 36211 var lastVal; 36212 self.options.breakpoints.forEach(function (i) { 36213 if (typeof i !== 'number') isNumerical = false; 36214 if (lastVal !== null) { 36215 if (i < lastVal) isAscending = false; 36216 } 36217 lastVal = i; 36218 }); 36219 if (isAscending && isNumerical) return; 36220 } 36221 // revert defaults if set incorrectly 36222 self.options.breakpoints = [576, 768, 1201]; 36223 console.warn("Rellax: You must pass an array of 3 numbers in ascending order to the breakpoints option. Defaults reverted"); 36224 } 36225 36226 if (options && options.breakpoints) { 36227 validateCustomBreakpoints(); 36228 } 36229 36230 // By default, rellax class 36231 if (!el) { 36232 el = '.rellax'; 36233 } 36234 36235 // check if el is a className or a node 36236 var elements = typeof el === 'string' ? document.querySelectorAll(el) : [el]; 36237 36238 // Now query selector 36239 if (elements.length > 0) { 36240 self.elems = elements; 36241 } 36242 36243 // The elements don't exist 36244 else { 36245 console.warn("Rellax: The elements you're trying to select don't exist."); 36246 return; 36247 } 36248 36249 // Has a wrapper and it exists 36250 if (self.options.wrapper) { 36251 if (!self.options.wrapper.nodeType) { 36252 var wrapper = document.querySelector(self.options.wrapper); 36253 36254 if (wrapper) { 36255 self.options.wrapper = wrapper; 36256 } else { 36257 console.warn("Rellax: The wrapper you're trying to use doesn't exist."); 36258 return; 36259 } 36260 } 36261 } 36262 36263 // set a placeholder for the current breakpoint 36264 var currentBreakpoint; 36265 36266 // helper to determine current breakpoint 36267 var getCurrentBreakpoint = function (w) { 36268 var bp = self.options.breakpoints; 36269 if (w < bp[0]) return 'xs'; 36270 if (w >= bp[0] && w < bp[1]) return 'sm'; 36271 if (w >= bp[1] && w < bp[2]) return 'md'; 36272 return 'lg'; 36273 }; 36274 36275 // Get and cache initial position of all elements 36276 var cacheBlocks = function() { 36277 for (var i = 0; i < self.elems.length; i++){ 36278 var block = createBlock(self.elems[i]); 36279 blocks.push(block); 36280 } 36281 }; 36282 36283 36284 // Let's kick this script off 36285 // Build array for cached element values 36286 var init = function() { 36287 for (var i = 0; i < blocks.length; i++){ 36288 self.elems[i].style.cssText = blocks[i].style; 36289 } 36290 36291 blocks = []; 36292 36293 screenY = window.innerHeight; 36294 screenX = window.innerWidth; 36295 currentBreakpoint = getCurrentBreakpoint(screenX); 36296 36297 setPosition(); 36298 36299 cacheBlocks(); 36300 36301 animate(); 36302 36303 // If paused, unpause and set listener for window resizing events 36304 if (pause) { 36305 window.addEventListener('resize', init); 36306 pause = false; 36307 // Start the loop 36308 update(); 36309 } 36310 }; 36311 36312 // We want to cache the parallax blocks' 36313 // values: base, top, height, speed 36314 // el: is dom object, return: el cache values 36315 var createBlock = function(el) { 36316 var dataPercentage = el.getAttribute( 'data-rellax-percentage' ); 36317 var dataSpeed = el.getAttribute( 'data-rellax-speed' ); 36318 var dataXsSpeed = el.getAttribute( 'data-rellax-xs-speed' ); 36319 var dataMobileSpeed = el.getAttribute( 'data-rellax-mobile-speed' ); 36320 var dataTabletSpeed = el.getAttribute( 'data-rellax-tablet-speed' ); 36321 var dataDesktopSpeed = el.getAttribute( 'data-rellax-desktop-speed' ); 36322 var dataVerticalSpeed = el.getAttribute('data-rellax-vertical-speed'); 36323 var dataHorizontalSpeed = el.getAttribute('data-rellax-horizontal-speed'); 36324 var dataVericalScrollAxis = el.getAttribute('data-rellax-vertical-scroll-axis'); 36325 var dataHorizontalScrollAxis = el.getAttribute('data-rellax-horizontal-scroll-axis'); 36326 var dataZindex = el.getAttribute( 'data-rellax-zindex' ) || 0; 36327 var dataMin = el.getAttribute( 'data-rellax-min' ); 36328 var dataMax = el.getAttribute( 'data-rellax-max' ); 36329 var dataMinX = el.getAttribute('data-rellax-min-x'); 36330 var dataMaxX = el.getAttribute('data-rellax-max-x'); 36331 var dataMinY = el.getAttribute('data-rellax-min-y'); 36332 var dataMaxY = el.getAttribute('data-rellax-max-y'); 36333 var mapBreakpoints; 36334 var breakpoints = true; 36335 36336 if (!dataXsSpeed && !dataMobileSpeed && !dataTabletSpeed && !dataDesktopSpeed) { 36337 breakpoints = false; 36338 } else { 36339 mapBreakpoints = { 36340 'xs': dataXsSpeed, 36341 'sm': dataMobileSpeed, 36342 'md': dataTabletSpeed, 36343 'lg': dataDesktopSpeed 36344 }; 36345 } 36346 36347 // initializing at scrollY = 0 (top of browser), scrollX = 0 (left of browser) 36348 // ensures elements are positioned based on HTML layout. 36349 // 36350 // If the element has the percentage attribute, the posY and posX needs to be 36351 // the current scroll position's value, so that the elements are still positioned based on HTML layout 36352 var wrapperPosY = self.options.wrapper ? self.options.wrapper.scrollTop : (window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop); 36353 // If the option relativeToWrapper is true, use the wrappers offset to top, subtracted from the current page scroll. 36354 if (self.options.relativeToWrapper) { 36355 var scrollPosY = (window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop); 36356 wrapperPosY = scrollPosY - self.options.wrapper.offsetTop; 36357 } 36358 var posY = self.options.vertical ? ( dataPercentage || self.options.center ? wrapperPosY : 0 ) : 0; 36359 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; 36360 36361 var blockTop = posY + el.getBoundingClientRect().top; 36362 var blockHeight = el.clientHeight || el.offsetHeight || el.scrollHeight; 36363 36364 var blockLeft = posX + el.getBoundingClientRect().left; 36365 var blockWidth = el.clientWidth || el.offsetWidth || el.scrollWidth; 36366 36367 // apparently parallax equation everyone uses 36368 var percentageY = dataPercentage ? dataPercentage : (posY - blockTop + screenY) / (blockHeight + screenY); 36369 var percentageX = dataPercentage ? dataPercentage : (posX - blockLeft + screenX) / (blockWidth + screenX); 36370 if(self.options.center){ percentageX = 0.5; percentageY = 0.5; } 36371 36372 // Optional individual block speed as data attr, otherwise global speed 36373 var speed = (breakpoints && mapBreakpoints[currentBreakpoint] !== null) ? Number(mapBreakpoints[currentBreakpoint]) : (dataSpeed ? dataSpeed : self.options.speed); 36374 var verticalSpeed = dataVerticalSpeed ? dataVerticalSpeed : self.options.verticalSpeed; 36375 var horizontalSpeed = dataHorizontalSpeed ? dataHorizontalSpeed : self.options.horizontalSpeed; 36376 36377 // Optional individual block movement axis direction as data attr, otherwise global movement direction 36378 var verticalScrollAxis = dataVericalScrollAxis ? dataVericalScrollAxis : self.options.verticalScrollAxis; 36379 var horizontalScrollAxis = dataHorizontalScrollAxis ? dataHorizontalScrollAxis : self.options.horizontalScrollAxis; 36380 36381 var bases = updatePosition(percentageX, percentageY, speed, verticalSpeed, horizontalSpeed); 36382 36383 // ~~Store non-translate3d transforms~~ 36384 // Store inline styles and extract transforms 36385 var style = el.style.cssText; 36386 var transform = ''; 36387 36388 // Check if there's an inline styled transform 36389 var searchResult = /transform\s*:/i.exec(style); 36390 if (searchResult) { 36391 // Get the index of the transform 36392 var index = searchResult.index; 36393 36394 // Trim the style to the transform point and get the following semi-colon index 36395 var trimmedStyle = style.slice(index); 36396 var delimiter = trimmedStyle.indexOf(';'); 36397 36398 // Remove "transform" string and save the attribute 36399 if (delimiter) { 36400 transform = " " + trimmedStyle.slice(11, delimiter).replace(/\s/g,''); 36401 } else { 36402 transform = " " + trimmedStyle.slice(11).replace(/\s/g,''); 36403 } 36404 } 36405 36406 return { 36407 baseX: bases.x, 36408 baseY: bases.y, 36409 top: blockTop, 36410 left: blockLeft, 36411 height: blockHeight, 36412 width: blockWidth, 36413 speed: speed, 36414 verticalSpeed: verticalSpeed, 36415 horizontalSpeed: horizontalSpeed, 36416 verticalScrollAxis: verticalScrollAxis, 36417 horizontalScrollAxis: horizontalScrollAxis, 36418 style: style, 36419 transform: transform, 36420 zindex: dataZindex, 36421 min: dataMin, 36422 max: dataMax, 36423 minX: dataMinX, 36424 maxX: dataMaxX, 36425 minY: dataMinY, 36426 maxY: dataMaxY 36427 }; 36428 }; 36429 36430 // set scroll position (posY, posX) 36431 // side effect method is not ideal, but okay for now 36432 // returns true if the scroll changed, false if nothing happened 36433 var setPosition = function() { 36434 var oldY = posY; 36435 var oldX = posX; 36436 36437 posY = self.options.wrapper ? self.options.wrapper.scrollTop : (document.documentElement || document.body.parentNode || document.body).scrollTop || window.pageYOffset; 36438 posX = self.options.wrapper ? self.options.wrapper.scrollLeft : (document.documentElement || document.body.parentNode || document.body).scrollLeft || window.pageXOffset; 36439 // If option relativeToWrapper is true, use relative wrapper value instead. 36440 if (self.options.relativeToWrapper) { 36441 var scrollPosY = (document.documentElement || document.body.parentNode || document.body).scrollTop || window.pageYOffset; 36442 posY = scrollPosY - self.options.wrapper.offsetTop; 36443 } 36444 36445 36446 if (oldY != posY && self.options.vertical) { 36447 // scroll changed, return true 36448 return true; 36449 } 36450 36451 if (oldX != posX && self.options.horizontal) { 36452 // scroll changed, return true 36453 return true; 36454 } 36455 36456 // scroll did not change 36457 return false;
36458 }; 36459 36460 // Ahh a pure function, gets new transform value 36461 // based on scrollPosition and speed 36462 // Allow for decimal pixel values 36463 var updatePosition = function(percentageX, percentageY, speed, verticalSpeed, horizontalSpeed) { 36464 var result = {}; 36465 var valueX = ((horizontalSpeed ? horizontalSpeed : speed) * (100 * (1 - percentageX))); 36466 var valueY = ((verticalSpeed ? verticalSpeed : speed) * (100 * (1 - percentageY))); 36467 36468 result.x = self.options.round ? Math.round(valueX) : Math.round(valueX * 100) / 100; 36469 result.y = self.options.round ? Math.round(valueY) : Math.round(valueY * 100) / 100; 36470 36471 return result; 36472 }; 36473 36474 // Remove event listeners and loop again 36475 var deferredUpdate = function() { 36476 window.removeEventListener('resize', deferredUpdate); 36477 window.removeEventListener('orientationchange', deferredUpdate); 36478 (self.options.wrapper ? self.options.wrapper : window).removeEventListener('scroll', deferredUpdate); 36479 (self.options.wrapper ? self.options.wrapper : document).removeEventListener('touchmove', deferredUpdate); 36480 36481 // loop again 36482 loopId = loop(update); 36483 }; 36484 36485 // Loop 36486 var update = function() { 36487 if (setPosition() && pause === false) { 36488 animate(); 36489 36490 // loop again 36491 loopId = loop(update); 36492 } else { 36493 loopId = null; 36494 36495 // Don't animate until we get a position updating event 36496 window.addEventListener('resize', deferredUpdate); 36497 window.addEventListener('orientationchange', deferredUpdate); 36498 (self.options.wrapper ? self.options.wrapper : window).addEventListener('scroll', deferredUpdate, supportsPassive ? { passive: true } : false); 36499 (self.options.wrapper ? self.options.wrapper : document).addEventListener('touchmove', deferredUpdate, supportsPassive ? { passive: true } : false); 36500 } 36501 }; 36502 36503 // Transform3d on parallax element 36504 var animate = function() { 36505 var positions; 36506 for (var i = 0; i < self.elems.length; i++){ 36507 // Determine relevant movement directions 36508 var verticalScrollAxis = blocks[i].verticalScrollAxis.toLowerCase(); 36509 var horizontalScrollAxis = blocks[i].horizontalScrollAxis.toLowerCase(); 36510 var verticalScrollX = verticalScrollAxis.indexOf("x") != -1 ? posY : 0; 36511 var verticalScrollY = verticalScrollAxis.indexOf("y") != -1 ? posY : 0; 36512 var horizontalScrollX = horizontalScrollAxis.indexOf("x") != -1 ? posX : 0; 36513 var horizontalScrollY = horizontalScrollAxis.indexOf("y") != -1 ? posX : 0; 36514 36515 var percentageY = ((verticalScrollY + horizontalScrollY - blocks[i].top + screenY) / (blocks[i].height + screenY)); 36516 var percentageX = ((verticalScrollX + horizontalScrollX - blocks[i].left + screenX) / (blocks[i].width + screenX)); 36517 36518 // Subtracting initialize value, so element stays in same spot as HTML 36519 positions = updatePosition(percentageX, percentageY, blocks[i].speed, blocks[i].verticalSpeed, blocks[i].horizontalSpeed); 36520 var positionY = positions.y - blocks[i].baseY; 36521 var positionX = positions.x - blocks[i].baseX; 36522 36523 // The next two "if" blocks go like this: 36524 // Check if a limit is defined (first "min", then "max"); 36525 // Check if we need to change the Y or the X 36526 // (Currently working only if just one of the axes is enabled) 36527 // Then, check if the new position is inside the allowed limit 36528 // If so, use new position. If not, set position to limit. 36529 36530 // Check if a min limit is defined 36531 if (blocks[i].min !== null) { 36532 if (self.options.vertical && !self.options.horizontal) { 36533 positionY = positionY <= blocks[i].min ? blocks[i].min : positionY; 36534 } 36535 if (self.options.horizontal && !self.options.vertical) { 36536 positionX = positionX <= blocks[i].min ? blocks[i].min : positionX; 36537 } 36538 } 36539 36540 // Check if directional min limits are defined 36541 if (blocks[i].minY != null) { 36542 positionY = positionY <= blocks[i].minY ? blocks[i].minY : positionY; 36543 } 36544 if (blocks[i].minX != null) { 36545 positionX = positionX <= blocks[i].minX ? blocks[i].minX : positionX; 36546 } 36547 36548 // Check if a max limit is defined 36549 if (blocks[i].max !== null) { 36550 if (self.options.vertical && !self.options.horizontal) { 36551 positionY = positionY >= blocks[i].max ? blocks[i].max : positionY; 36552 } 36553 if (self.options.horizontal && !self.options.vertical) { 36554 positionX = positionX >= blocks[i].max ? blocks[i].max : positionX; 36555 } 36556 } 36557 36558 // Check if directional max limits are defined 36559 if (blocks[i].maxY != null) { 36560 positionY = positionY >= blocks[i].maxY ? blocks[i].maxY : positionY; 36561 } 36562 if (blocks[i].maxX != null) { 36563 positionX = positionX >= blocks[i].maxX ? blocks[i].maxX : positionX; 36564 } 36565 36566 var zindex = blocks[i].zindex; 36567 36568 // Move that element 36569 // (Set the new translation and append initial inline transforms.) 36570 var translate = 'translate3d(' + (self.options.horizontal ? positionX : '0') + 'px,' + (self.options.vertical ? positionY : '0') + 'px,' + zindex + 'px) ' + blocks[i].transform; 36571 self.elems[i].style[transformProp] = translate; 36572 } 36573 self.options.callback(positions); 36574 }; 36575 36576 self.destroy = function() { 36577 for (var i = 0; i < self.elems.length; i++){ 36578 self.elems[i].style.cssText = blocks[i].style; 36579 } 36580 36581 // Remove resize event listener if not pause, and pause 36582 if (!pause) { 36583 window.removeEventListener('resize', init); 36584 pause = true; 36585 } 36586 36587 // Clear the animation loop to prevent possible memory leak 36588 clearLoop(loopId); 36589 loopId = null; 36590 }; 36591 36592 // Init 36593 init(); 36594 36595 // Allow to recalculate the initial values whenever we want 36596 self.refresh = init; 36597 36598 return self; 36599 }; 36600 return Rellax; 36601})); 36602 36603/* 36604 * OKVideo by OKFocus v2.3.2 36605 * http://okfoc.us 36606 * 36607 * Copyright 2014, OKFocus 36608 * Licensed under the MIT license. 36609 * 36610 */ 36611var player, OKEvents, options, videoWidth, videoHeight, YTplayers, youtubePlayers = new Array(); 36612// youtube player ready 36613function onYouTubeIframeAPIReady() { 36614 YTplayers = new Array(); 36615 jQuery('.no-touch .uncode-video-container.video').each(function() { 36616 var playerY; 36617 if (jQuery(this).attr('data-provider') == 'youtube') { 36618 var id = jQuery(this).attr('data-id'), 36619 start = jQuery(this).attr('data-start'), 36620 end = jQuery(this).attr('data-end'); 36621 start = typeof start && start !== null ? start : 0; 36622 end = typeof end && end !== null ? end : 0; 36623 options = jQuery(window).data('okoptions-' + id); 36624 options.time = jQuery(this).attr('data-t'); 36625 playerY = new YT.Player('okplayer-' + id, { 36626 videoId: options.video ? options.video.id : null, 36627 playerVars: { 36628 'autohide': 1, 36629 'autoplay': 0, //options.autoplay, 36630 'disablekb': 1, 36631 'cc_load_policy': options.captions, 36632 'controls': 0, 36633 'enablejsapi': 1, 36634 'fs': 0, 36635 'modestbranding': 1, 36636 'origin': window.location.origin || (window.location.protocol + '//' + window.location.hostname), 36637 'iv_load_policy': options.annotations, 36638 'loop': options.loop, 36639 'showinfo': 0, 36640 'rel': 0, 36641 'wmode': 'opaque', 36642 'hd': options.hd, 36643 'mute': 1, 36644 'start': start, 36645 'end': end 36646 }, 36647 events: { 36648 'onReady': OKEvents.yt.ready, 36649 'onStateChange': OKEvents.yt.onStateChange, 36650 'onError': OKEvents.yt.error 36651 } 36652 }); 36653 YTplayers[id] = playerY; 36654 playerY.videoId = id; 36655 } 36656 36657 }); 36658} 36659// vimeo player ready 36660function vimeoPlayerReady(id) { 36661 options = jQuery(window).data('okoptions-' + id); 36662 var jIframe = options.jobject, 36663 iframe = jIframe[0]; 36664 36665 jIframe.attr('src', jIframe.data('src')); 36666 var playerV = new Vimeo.Player(iframe); 36667 // hide player until Vimeo hides controls... 36668 playerV.on('loaded', function(e) { 36669 OKEvents.v.onReady(iframe); 36670 var carouselContainer = jQuery(iframe).closest('.owl-carousel'); 36671 if (carouselContainer.length) { 36672 UNCODE.owlPlayVideo(carouselContainer); 36673 } 36674 // "Do not try to add listeners or call functions before receiving this event." 36675 if (OKEvents.utils.isMobile()) { 36676 // mobile devices cannot listen for play event 36677 OKEvents.v.onPlay(playerV); 36678 } else { 36679 playerV.on('play', function(){ 36680 OKEvents.v.onPlay(playerV); 36681 }); 36682 playerV.on('pause', function(){ 36683 OKEvents.v.onPause;
36684 }); 36685 playerV.on('ended', function(){ 36686 OKEvents.v.onFinish 36687 }); 36688 } 36689 if (options.time != null) { 36690 var optsTimeStr = (options.time).replace('t=', ''), 36691 timeV = ''; 36692 36693 if ( /[a-zA-Z]/g.test(optsTimeStr) ) { 36694 var timeArr = optsTimeStr.split(/([^\d.-])/); 36695 for ( var i = 0; i < timeArr.length; i++ ) { 36696 if ( timeArr[i] === 'h' ) { 36697 timeV += parseFloat(timeArr[i-1]) * 3600; 36698 } else if ( timeArr[i] === 'm' ) { 36699 timeV += parseFloat(timeArr[i-1]) * 60; 36700 } else if ( timeArr[i] === 's' ) { 36701 timeV += parseFloat(timeArr[i-1]); 36702 } 36703 } 36704 } else { 36705 timeV = optsTimeStr; 36706 } 36707 36708 playerV.setCurrentTime(timeV); 36709 } 36710 36711 playerV.setVolume(0); 36712 playerV.play(); 36713 jQuery(iframe).css({ 36714 visibility: 'visible', 36715 opacity: 1 36716 }); 36717 jQuery(iframe).closest('.uncode-video-container:not(.t-entry-drop)').css('opacity', '1'); 36718 jQuery(iframe).closest('#page-header').addClass('video-started'); 36719 jQuery(iframe).closest('.background-wrapper').find('.block-bg-blend-mode.not-ie').css('opacity', '1'); 36720 36721 }); 36722} 36723OKEvents = { 36724 yt: { 36725 ready: function(event) { 36726 var id = event.target.videoId; 36727 youtubePlayers[id] = event.target; 36728 event.target.setVolume(options.volume); 36729 if (options.autoplay === 1) { 36730 if (options.playlist.list) { 36731 player.loadPlaylist(options.playlist.list, options.playlist.index, options.playlist.startSeconds, options.playlist.suggestedQuality); 36732 } else { 36733 var inCarousel = jQuery('#okplayer-' + id).closest('.owl-item'); 36734 if (!inCarousel.length || (inCarousel.length && inCarousel.hasClass('active'))) { 36735 if (options.time != null) { 36736 event.target.seekTo(parseInt(options.time)); 36737 } 36738 event.target.playVideo(); 36739 } else { 36740 event.target.pauseVideo(); 36741 } 36742 } 36743 } 36744 OKEvents.utils.isFunction(options.onReady) && options.onReady(event.target); 36745 36746 jQuery('#okplayer-' + id).closest('[data-provider]').on('uncode-resume', function(){ 36747 if (options.time != null) { 36748 event.target.seekTo(parseInt(options.time)).playVideo(); 36749 } else { 36750 event.target.seekTo(0).playVideo(); 36751 } 36752 }); 36753 36754 jQuery('#okplayer-' + id).closest('[data-provider]').on('uncode-pause', function(){ 36755 if (options.time != null) { 36756 event.target.seekTo(parseInt(options.time)).pauseVideo(); 36757 } else { 36758 event.target.seekTo(0).pauseVideo(); 36759 } 36760 }); 36761 }, 36762 onStateChange: function(event) { 36763 var id = event.target.videoId; 36764 switch (event.data) { 36765 case -1: 36766 OKEvents.utils.isFunction(options.unstarted) && options.unstarted(); 36767 break; 36768 case 0: 36769 OKEvents.utils.isFunction(options.onFinished) && options.onFinished(); 36770 options.loop && event.target.playVideo(); 36771 break; 36772 case 1: 36773 OKEvents.utils.isFunction(options.onPlay) && options.onPlay(); 36774 setTimeout(function() { 36775 UNCODE.initVideoComponent(document.body, '.uncode-video-container.video:not(.drop-move), .uncode-video-container.self-video:not(.drop-move)'); 36776 jQuery('#okplayer-' + id).closest('.uncode-video-container:not(.t-entry-drop)').css('opacity', '1'); 36777 jQuery('#okplayer-' + id).closest('#page-header').addClass('video-started'); 36778 jQuery('#okplayer-' + id).closest('.background-wrapper').find('.block-bg-blend-mode.not-ie').css('opacity', '1'); 36779 }, 300); 36780 break; 36781 case 2: 36782 OKEvents.utils.isFunction(options.onPause) && options.onPause(); 36783 break; 36784 case 3: 36785 OKEvents.utils.isFunction(options.buffering) && options.buffering(); 36786 break; 36787 case 5: 36788 OKEvents.utils.isFunction(options.cued) && options.cued(); 36789 break; 36790 default: 36791 throw "OKVideo: received invalid data from YT player."; 36792 } 36793 }, 36794 error: function(event) { 36795 throw event; 36796 } 36797 }, 36798 v: { 36799 onReady: function(target) { 36800 OKEvents.utils.isFunction(options.onReady) && options.onReady(target); 36801 }, 36802 onPlay: function(player) { 36803 if (!OKEvents.utils.isMobile()) player.setVolume(options.volume); 36804 OKEvents.utils.isFunction(options.onPlay) && options.onPlay(); 36805 jQuery(player.element).closest('.uncode-video-container:not(.t-entry-drop)').css('opacity', '1'); 36806 jQuery(player.element).closest('#page-header').addClass('video-started'); 36807 jQuery(player.element).closest('.background-wrapper').find('.block-bg-blend-mode.not-ie').css('opacity', '1'); 36808 }, 36809 onPause: function() { 36810 OKEvents.utils.isFunction(options.onPause) && options.onPause(); 36811 }, 36812 onFinish: function() { 36813 OKEvents.utils.isFunction(options.onFinish) && options.onFinish(); 36814 } 36815 }, 36816 utils: { 36817 isFunction: function(func) { 36818 if (typeof func === 'function') { 36819 return true; 36820 } else { 36821 return false;
36822 } 36823 }, 36824 isMobile: function() { 36825 if (navigator.userAgent.match(/(iPhone|iPod|iPad|Android|BlackBerry)/)) { 36826 return true; 36827 } else { 36828 return false; 36829 } 36830 } 36831 } 36832}; 36833 36834/** 36835 * vivus - JavaScript library to make drawing animation on SVG 36836 * @version v0.4.4 36837 * @link https://github.com/maxwellito/vivus 36838 * @license MIT 36839 */ 36840 36841'use strict'; 36842 36843(function () { 36844 36845 'use strict'; 36846 36847/** 36848 * Pathformer 36849 * Beta version 36850 * 36851 * Take any SVG version 1.1 and transform 36852 * child elements to 'path' elements 36853 * 36854 * This code is purely forked from 36855 * https://github.com/Waest/SVGPathConverter 36856 */ 36857 36858/** 36859 * Class constructor 36860 * 36861 * @param {DOM|String} element Dom element of the SVG or id of it 36862 */ 36863function Pathformer(element) { 36864 // Test params 36865 if (typeof element === 'undefined') { 36866 throw new Error('Pathformer [constructor]: "element" parameter is required'); 36867 } 36868 36869 // Set the element 36870 if (element.constructor === String) { 36871 element = document.getElementById(element); 36872 if (!element) { 36873 throw new Error('Pathformer [constructor]: "element" parameter is not related to an existing ID'); 36874 } 36875 } 36876 if (element instanceof window.SVGElement || 36877 element instanceof window.SVGGElement || 36878 /^svg$/i.test(element.nodeName)) { 36879 this.el = element; 36880 } else { 36881 throw new Error('Pathformer [constructor]: "element" parameter must be a string or a SVGelement'); 36882 } 36883 36884 // Start 36885 this.scan(element); 36886} 36887 36888/** 36889 * List of tags which can be transformed 36890 * to path elements 36891 * 36892 * @type {Array} 36893 */ 36894Pathformer.prototype.TYPES = ['line', 'ellipse', 'circle', 'polygon', 'polyline', 'rect']; 36895 36896/** 36897 * List of attribute names which contain 36898 * data. This array list them to check if 36899 * they contain bad values, like percentage. 36900 * 36901 * @type {Array} 36902 */ 36903Pathformer.prototype.ATTR_WATCH = ['cx', 'cy', 'points', 'r', 'rx', 'ry', 'x', 'x1', 'x2', 'y', '
vendor: 24,640 bytes, lines 36903-37701
36903y1', 'y2']; 36904 36905/** 36906 * Finds the elements compatible for transform 36907 * and apply the liked method 36908 * 36909 * @param {object} options Object from the constructor 36910 */ 36911Pathformer.prototype.scan = function (svg) { 36912 var fn, element, pathData, pathDom, 36913 elements = svg.querySelectorAll(this.TYPES.join(',')); 36914 36915 for (var i = 0; i < elements.length; i++) { 36916 element = elements[i]; 36917 fn = this[element.tagName.toLowerCase() + 'ToPath']; 36918 pathData = fn(this.parseAttr(element.attributes)); 36919 pathDom = this.pathMaker(element, pathData); 36920 element.parentNode.replaceChild(pathDom, element); 36921 } 36922}; 36923 36924 36925/** 36926 * Read `line` element to extract and transform 36927 * data, to make it ready for a `path` object. 36928 * 36929 * @param {DOMelement} element Line element to transform 36930 * @return {object} Data for a `path` element 36931 */ 36932Pathformer.prototype.lineToPath = function (element) { 36933 var newElement = {}, 36934 x1 = element.x1 || 0, 36935 y1 = element.y1 || 0, 36936 x2 = element.x2 || 0, 36937 y2 = element.y2 || 0; 36938 36939 newElement.d = 'M' + x1 + ',' + y1 + 'L' + x2 + ',' + y2; 36940 return newElement; 36941}; 36942 36943/** 36944 * Read `rect` element to extract and transform 36945 * data, to make it ready for a `path` object. 36946 * The radius-border is not taken in charge yet. 36947 * (your help is more than welcomed) 36948 * 36949 * @param {DOMelement} element Rect element to transform 36950 * @return {object} Data for a `path` element 36951 */ 36952Pathformer.prototype.rectToPath = function (element) { 36953 var newElement = {}, 36954 x = parseFloat(element.x) || 0, 36955 y = parseFloat(element.y) || 0, 36956 width = parseFloat(element.width) || 0, 36957 height = parseFloat(element.height) || 0; 36958 36959 if (element.rx || element.ry) { 36960 var rx = parseInt(element.rx, 10) || -1, 36961 ry = parseInt(element.ry, 10) || -1; 36962 rx = Math.min(Math.max(rx < 0 ? ry : rx, 0), width/2); 36963 ry = Math.min(Math.max(ry < 0 ? rx : ry, 0), height/2); 36964 36965 newElement.d = 'M ' + (x + rx) + ',' + y + ' ' + 36966 'L ' + (x + width - rx) + ',' + y + ' ' + 36967 'A ' + rx + ',' + ry + ',0,0,1,' + (x + width) + ',' + (y + ry) + ' ' + 36968 'L ' + (x + width) + ',' + (y + height - ry) + ' ' + 36969 'A ' + rx + ',' + ry + ',0,0,1,' + (x + width - rx) + ',' + (y + height) + ' ' + 36970 'L ' + (x + rx) + ',' + (y + height) + ' ' + 36971 'A ' + rx + ',' + ry + ',0,0,1,' + x + ',' + (y + height - ry) + ' ' + 36972 'L ' + x + ',' + (y + ry) + ' ' + 36973 'A ' + rx + ',' + ry + ',0,0,1,' + (x + rx) + ',' + y; 36974 } 36975 else { 36976 newElement.d = 'M' + x + ' ' + y + ' ' + 36977 'L' + (x + width) + ' ' + y + ' ' + 36978 'L' + (x + width) + ' ' + (y + height) + ' ' + 36979 'L' + x + ' ' + (y + height) + ' Z'; 36980 } 36981 return newElement; 36982}; 36983 36984/** 36985 * Read `polyline` element to extract and transform 36986 * data, to make it ready for a `path` object. 36987 * 36988 * @param {DOMelement} element Polyline element to transform 36989 * @return {object} Data for a `path` element 36990 */ 36991Pathformer.prototype.polylineToPath = function (element) { 36992 var newElement = {}, 36993 points = element.points.trim().split(' '), 36994 i, path; 36995 36996 // Reformatting if points are defined without commas 36997 if (element.points.indexOf(',') === -1) { 36998 var formattedPoints = []; 36999 for (i = 0; i < points.length; i+=2) { 37000 formattedPoints.push(points[i] + ',' + points[i+1]); 37001 } 37002 points = formattedPoints; 37003 } 37004 37005 // Generate the path.d value 37006 path = 'M' + points[0]; 37007 for(i = 1; i < points.length; i++) { 37008 if (points[i].indexOf(',') !== -1) { 37009 path += 'L' + points[i]; 37010 } 37011 } 37012 newElement.d = path; 37013 return newElement; 37014}; 37015 37016/** 37017 * Read `polygon` element to extract and transform 37018 * data, to make it ready for a `path` object. 37019 * This method rely on polylineToPath, because the 37020 * logic is similar. The path created is just closed, 37021 * so it needs an 'Z' at the end. 37022 * 37023 * @param {DOMelement} element Polygon element to transform 37024 * @return {object} Data for a `path` element 37025 */ 37026Pathformer.prototype.polygonToPath = function (element) { 37027 var newElement = Pathformer.prototype.polylineToPath(element); 37028 37029 newElement.d += 'Z'; 37030 return newElement; 37031}; 37032 37033/** 37034 * Read `ellipse` element to extract and transform 37035 * data, to make it ready for a `path` object. 37036 * 37037 * @param {DOMelement} element ellipse element to transform 37038 * @return {object} Data for a `path` element 37039 */ 37040Pathformer.prototype.ellipseToPath = function (element) { 37041 var newElement = {}, 37042 rx = parseFloat(element.rx) || 0, 37043 ry = parseFloat(element.ry) || 0, 37044 cx = parseFloat(element.cx) || 0, 37045 cy = parseFloat(element.cy) || 0, 37046 startX = cx - rx, 37047 startY = cy, 37048 endX = parseFloat(cx) + parseFloat(rx), 37049 endY = cy; 37050 37051 newElement.d = 'M' + startX + ',' + startY + 37052 'A' + rx + ',' + ry + ' 0,1,1 ' + endX + ',' + endY + 37053 'A' + rx + ',' + ry + ' 0,1,1 ' + startX + ',' + endY; 37054 return newElement; 37055}; 37056 37057/** 37058 * Read `circle` element to extract and transform 37059 * data, to make it ready for a `path` object. 37060 * 37061 * @param {DOMelement} element Circle element to transform 37062 * @return {object} Data for a `path` element 37063 */ 37064Pathformer.prototype.circleToPath = function (element) { 37065 var newElement = {}, 37066 r = parseFloat(element.r) || 0, 37067 cx = parseFloat(element.cx) || 0, 37068 cy = parseFloat(element.cy) || 0, 37069 startX = cx - r, 37070 startY = cy, 37071 endX = parseFloat(cx) + parseFloat(r), 37072 endY = cy; 37073 37074 newElement.d = 'M' + startX + ',' + startY + 37075 'A' + r + ',' + r + ' 0,1,1 ' + endX + ',' + endY + 37076 'A' + r + ',' + r + ' 0,1,1 ' + startX + ',' + endY; 37077 return newElement; 37078}; 37079 37080/** 37081 * Create `path` elements form original element 37082 * and prepared objects 37083 * 37084 * @param {DOMelement} element Original element to transform 37085 * @param {object} pathData Path data (from `toPath` methods) 37086 * @return {DOMelement} Path element 37087 */ 37088Pathformer.prototype.pathMaker = function (element, pathData) { 37089 var i, attr, pathTag = document.createElementNS('http://www.w3.org/2000/svg','path'); 37090 for(i = 0; i < element.attributes.length; i++) { 37091 attr = element.attributes[i]; 37092 if (this.ATTR_WATCH.indexOf(attr.name) === -1) { 37093 pathTag.setAttribute(attr.name, attr.value); 37094 } 37095 } 37096 for(i in pathData) { 37097 pathTag.setAttribute(i, pathData[i]); 37098 } 37099 return pathTag; 37100}; 37101 37102/** 37103 * Parse attributes of a DOM element to 37104 * get an object of attribute => value 37105 * 37106 * @param {NamedNodeMap} attributes Attributes object from DOM element to parse 37107 * @return {object} Object of attributes 37108 */ 37109Pathformer.prototype.parseAttr = function (element) { 37110 var attr, output = {}; 37111 for (var i = 0; i < element.length; i++) { 37112 attr = element[i]; 37113 // Check if no data attribute contains '%', or the transformation is impossible 37114 if (this.ATTR_WATCH.indexOf(attr.name) !== -1 && attr.value.indexOf('%') !== -1) { 37115 throw new Error('Pathformer [parseAttr]: a SVG shape got values in percentage. This cannot be transformed into \'path\' tags. Please use \'viewBox\'.'); 37116 } 37117 output[attr.name] = attr.value; 37118 } 37119 return output; 37120}; 37121 37122 'use strict'; 37123 37124var setupEnv, requestAnimFrame, cancelAnimFrame, parsePositiveInt; 37125 37126/** 37127 * Vivus 37128 * Beta version 37129 * 37130 * Take any SVG and make the animation 37131 * to give give the impression of live drawing 37132 * 37133 * This in more than just inspired from codrops 37134 * At that point, it's a pure fork. 37135 */ 37136 37137/** 37138 * Class constructor 37139 * option structure 37140 * type: 'delayed'|'sync'|'oneByOne'|'script' (to know if the items must be drawn synchronously or not, default: delayed) 37141 * duration: <int> (in frames) 37142 * start: 'inViewport'|'manual'|'autostart' (start automatically the animation, default: inViewport) 37143 * delay: <int> (delay between the drawing of first and last path) 37144 * dashGap <integer> whitespace extra margin between dashes 37145 * pathTimingFunction <function> timing animation function for each path element of the SVG 37146 * animTimingFunction <function> timing animation function for the complete SVG 37147 * forceRender <boolean> force the browser to re-render all updated path items 37148 * selfDestroy <boolean> removes all extra styling on the SVG, and leaves it as original 37149 * 37150 * The attribute 'type' is by default on 'delayed'. 37151 * - 'delayed' 37152 * all paths are draw at the same time but with a 37153 * little delay between them before start 37154 * - 'sync' 37155 * all path are start and finish at the same time 37156 * - 'oneByOne' 37157 * only one path is draw at the time 37158 * the end of the first one will trigger the draw 37159 * of the next one 37160 * 37161 * All these values can be overwritten individually 37162 * for each path item in the SVG 37163 * The value of frames will always take the advantage of 37164 * the duration value. 37165 * If you fail somewhere, an error will be thrown. 37166 * Good luck. 37167 * 37168 * @constructor 37169 * @this {Vivus} 37170 * @param {DOM|String} element Dom element of the SVG or id of it 37171 * @param {Object} options Options about the animation 37172 * @param {Function} callback Callback for the end of the animation 37173 */ 37174function Vivus (element, options, callback) { 37175 37176 setupEnv(); 37177 37178 // Setup 37179 this.isReady = false; 37180 this.setElement(element, options); 37181 this.setOptions(options); 37182 this.setCallback(callback); 37183 37184 if (this.isReady) { 37185 this.init(); 37186 } 37187} 37188 37189/** 37190 * Timing functions 37191 ************************************** 37192 * 37193 * Default functions to help developers. 37194 * It always take a number as parameter (between 0 to 1) then 37195 * return a number (between 0 and 1) 37196 */ 37197Vivus.LINEAR = function (x) {return x;}; 37198Vivus.EASE = function (x) {return -Math.cos(x * Math.PI) / 2 + 0.5;}; 37199Vivus.EASE_OUT = function (x) {return 1 - Math.pow(1-x, 3);}; 37200Vivus.EASE_IN = function (x) {return Math.pow(x, 3);}; 37201Vivus.EASE_OUT_BOUNCE = function (x) { 37202 var base = -Math.cos(x * (0.5 * Math.PI)) + 1, 37203 rate = Math.pow(base,1.5), 37204 rateR = Math.pow(1 - x, 2), 37205 progress = -Math.abs(Math.cos(rate * (2.5 * Math.PI) )) + 1; 37206 return (1- rateR) + (progress * rateR); 37207}; 37208 37209 37210/** 37211 * Setters 37212 ************************************** 37213 */ 37214 37215/** 37216 * Check and set the element in the instance 37217 * The method will not return anything, but will throw an 37218 * error if the parameter is invalid 37219 * 37220 * @param {DOM|String} element SVG Dom element or id of it 37221 */ 37222Vivus.prototype.setElement = function (element, options) { 37223 var onLoad, self; 37224 37225 // Basic check 37226 if (typeof element === 'undefined') { 37227 throw new Error('Vivus [constructor]: "element" parameter is required'); 37228 } 37229 37230 // Set the element 37231 if (element.constructor === String) { 37232 element = document.getElementById(element); 37233 if (!element) { 37234 throw new Error('Vivus [constructor]: "element" parameter is not related to an existing ID'); 37235 } 37236 } 37237 this.parentEl = element; 37238 37239 // Load the SVG with XMLHttpRequest and extract the SVG 37240 if (options && options.file) { 37241 var self = this; 37242 onLoad = function (e) { 37243 var domSandbox = document.createElement('div'); 37244 domSandbox.innerHTML = this.responseText; 37245 37246 var svgTag = domSandbox.querySelector('svg'); 37247 if (!svgTag) { 37248 throw new Error('Vivus [load]: Cannot find the SVG in the loaded file : ' + options.file); 37249 } 37250 37251 self.el = svgTag 37252 self.el.setAttribute('width', '100%'); 37253 self.el.setAttribute('height', '100%'); 37254 self.parentEl.appendChild(self.el) 37255 self.isReady = true; 37256 self.init(); 37257 self = null; 37258 } 37259 37260 var oReq = new window.XMLHttpRequest(); 37261 oReq.addEventListener('load', onLoad); 37262 oReq.open('GET', options.file); 37263 oReq.send(); 37264 return; 37265 } 37266 37267 switch (element.constructor) { 37268 case window.SVGSVGElement: 37269 case window.SVGElement: 37270 case window.SVGGElement: 37271 this.el = element; 37272 this.isReady = true; 37273 break; 37274 37275 case window.HTMLObjectElement: 37276 self = this; 37277 onLoad = function (e) { 37278 if (self.isReady) { 37279 return; 37280 } 37281 self.el = element.contentDocument && element.contentDocument.querySelector('svg'); 37282 if (!self.el && e) { 37283 throw new Error('Vivus [constructor]: object loaded does not contain any SVG'); 37284 } 37285 else if (self.el) { 37286 if (element.getAttribute('built-by-vivus')) { 37287 self.parentEl.insertBefore(self.el, element); 37288 self.parentEl.removeChild(element); 37289 self.el.setAttribute('width', '100%'); 37290 self.el.setAttribute('height', '100%'); 37291 } 37292 self.isReady = true; 37293 self.init(); 37294 self = null; 37295 } 37296 }; 37297 37298 if (!onLoad()) { 37299 element.addEventListener('load', onLoad); 37300 } 37301 break; 37302 37303 default: 37304 throw new Error('Vivus [constructor]: "element" parameter is not valid (or miss the "file" attribute)'); 37305 } 37306}; 37307 37308/** 37309 * Set up user option to the instance 37310 * The method will not return anything, but will throw an 37311 * error if the parameter is invalid 37312 * 37313 * @param {object} options Object from the constructor 37314 */ 37315Vivus.prototype.setOptions = function (options) { 37316 var allowedTypes = ['delayed', 'sync', 'async', 'nsync', 'oneByOne', 'scenario', 'scenario-sync']; 37317 var allowedStarts = ['inViewport', 'manual', 'autostart']; 37318 37319 // Basic check 37320 if (options !== undefined && options.constructor !== Object) { 37321 throw new Error('Vivus [constructor]: "options" parameter must be an object'); 37322 } 37323 else { 37324 options = options || {}; 37325 } 37326 37327 // Set the animation type 37328 if (options.type && allowedTypes.indexOf(options.type) === -1) { 37329 throw new Error('Vivus [constructor]: ' + options.type + ' is not an existing animation `type`'); 37330 } 37331 else { 37332 this.type = options.type || allowedTypes[0]; 37333 } 37334 37335 // Set the start type 37336 if (options.start && allowedStarts.indexOf(options.start) === -1) { 37337 throw new Error('Vivus [constructor]: ' + options.start + ' is not an existing `start` option'); 37338 } 37339 else { 37340 this.start = options.start || allowedStarts[0]; 37341 } 37342 37343 this.isIE = (window.navigator.userAgent.indexOf('MSIE') !== -1 || window.navigator.userAgent.indexOf('Trident/') !== -1 || window.navigator.userAgent.indexOf('Edge/') !== -1 ); 37344 this.duration = parsePositiveInt(options.duration, 120); 37345 this.delay = parsePositiveInt(options.delay, null); 37346 //Uncode addition 37347 this.delayStart = parsePositiveInt(options.delayStart, null); 37348 //#END 37349 this.dashGap = parsePositiveInt(options.dashGap, 1); 37350 this.forceRender = options.hasOwnProperty('forceRender') ? !!options.forceRender : this.isIE; 37351 this.reverseStack = !!options.reverseStack; 37352 this.selfDestroy = !!options.selfDestroy; 37353 this.onReady = options.onReady; 37354 this.map = []; 37355 this.frameLength = this.currentFrame = this.delayUnit = this.speed = this.handle = null; 37356 37357 this.ignoreInvisible = options.hasOwnProperty('ignoreInvisible') ? !!options.ignoreInvisible : false; 37358 37359 this.animTimingFunction = options.animTimingFunction || Vivus.LINEAR; 37360 this.pathTimingFunction = options.pathTimingFunction || Vivus.LINEAR; 37361 37362 if (this.delay >= this.duration) { 37363 throw new Error('Vivus [constructor]: delay must be shorter than duration'); 37364 } 37365}; 37366 37367/** 37368 * Set up callback to the instance 37369 * The method will not return enything, but will throw an 37370 * error if the parameter is invalid 37371 * 37372 * @param {Function} callback Callback for the animation end 37373 */ 37374Vivus.prototype.setCallback = function (callback) { 37375 // Basic check 37376 if (!!callback && callback.constructor !== Function) { 37377 throw new Error('Vivus [constructor]: "callback" parameter must be a function'); 37378 } 37379 this.callback = callback || function () {}; 37380}; 37381 37382 37383/** 37384 * Core 37385 ************************************** 37386 */ 37387 37388/** 37389 * Map the svg, path by path. 37390 * The method return nothing, it just fill the 37391 * `map` array. Each item in this array represent 37392 * a path element from the SVG, with informations for 37393 * the animation. 37394 * 37395 * ``` 37396 * [ 37397 * { 37398 * el: <DOMobj> the path element 37399 * length: <number> length of the path line 37400 * startAt: <number> time start of the path animation (in frames) 37401 * duration: <number> path animation duration (in frames) 37402 * }, 37403 * ... 37404 * ] 37405 * ``` 37406 * 37407 */ 37408Vivus.prototype.mapping = function () { 37409 var i, paths, path, pAttrs, pathObj, totalLength, lengthMeter, timePoint; 37410 timePoint = totalLength = lengthMeter = 0; 37411 paths = this.el.querySelectorAll('path'); 37412 37413 for (i = 0; i < paths.length; i++) { 37414 path = paths[i]; 37415 if (this.isInvisible(path)) { 37416 continue; 37417 } 37418 pathObj = { 37419 el: path, 37420 length: Math.ceil(path.getTotalLength()) 37421 }; 37422 // Test if the path length is correct 37423 if (isNaN(pathObj.length)) { 37424 if (window.console && console.warn) { 37425 console.warn('Vivus [mapping]: cannot retrieve a path element length', path); 37426 } 37427 continue; 37428 } 37429 this.map.push(pathObj); 37430 path.style.strokeDasharray = pathObj.length + ' ' + (pathObj.length + this.dashGap * 2); 37431 path.style.strokeDashoffset = pathObj.length + this.dashGap; 37432 pathObj.length += this.dashGap; 37433 totalLength += pathObj.length; 37434 37435 this.renderPath(i); 37436 } 37437 37438 totalLength = totalLength === 0 ? 1 : totalLength; 37439 this.delay = this.delay === null ? this.duration / 3 : this.delay; 37440 this.delayUnit = this.delay / (paths.length > 1 ? paths.length - 1 : 1); 37441 37442 // Reverse stack if asked 37443 if (this.reverseStack) { 37444 this.map.reverse(); 37445 } 37446 37447 for (i = 0; i < this.map.length; i++) { 37448 pathObj = this.map[i]; 37449 37450 switch (this.type) { 37451 case 'delayed': 37452 pathObj.startAt = this.delayUnit * i; 37453 pathObj.duration = this.duration - this.delay; 37454 break; 37455 37456 case 'oneByOne': 37457 pathObj.startAt = lengthMeter / totalLength * this.duration; 37458 pathObj.duration = pathObj.length / totalLength * this.duration; 37459 break; 37460 37461 case 'sync': 37462 case 'async': 37463 case 'nsync': 37464 pathObj.startAt = 0; 37465 pathObj.duration = this.duration; 37466 break; 37467 37468 case 'scenario-sync': 37469 path = pathObj.el; 37470 pAttrs = this.parseAttr(path); 37471 pathObj.startAt = timePoint + (parsePositiveInt(pAttrs['data-delay'], this.delayUnit) || 0); 37472 pathObj.duration = parsePositiveInt(pAttrs['data-duration'], this.duration); 37473 timePoint = pAttrs['data-async'] !== undefined ? pathObj.startAt : pathObj.startAt + pathObj.duration; 37474 this.frameLength = Math.max(this.frameLength, (pathObj.startAt + pathObj.duration)); 37475 break; 37476 37477 case 'scenario': 37478 path = pathObj.el; 37479 pAttrs = this.parseAttr(path); 37480 pathObj.startAt = parsePositiveInt(pAttrs['data-start'], this.delayUnit) || 0; 37481 pathObj.duration = parsePositiveInt(pAttrs['data-duration'], this.duration); 37482 this.frameLength = Math.max(this.frameLength, (pathObj.startAt + pathObj.duration)); 37483 break; 37484 } 37485 lengthMeter += pathObj.length; 37486 this.frameLength = this.frameLength || this.duration; 37487 } 37488}; 37489 37490/** 37491 * Interval method to draw the SVG from current 37492 * position of the animation. It update the value of 37493 * `currentFrame` and re-trace the SVG. 37494 * 37495 * It use this.handle to store the requestAnimationFrame 37496 * and clear it one the animation is stopped. So this 37497 * attribute can be used to know if the animation is 37498 * playing. 37499 * 37500 * Once the animation at the end, this method will 37501 * trigger the Vivus callback. 37502 * 37503 */ 37504Vivus.prototype.drawer = function () { 37505 var self = this; 37506 this.currentFrame += this.speed; 37507 37508 if (this.currentFrame <= 0) { 37509 this.stop(); 37510 this.reset(); 37511 } else if (this.currentFrame >= this.frameLength) { 37512 this.stop(); 37513 this.currentFrame = this.frameLength; 37514 this.trace(); 37515 if (this.selfDestroy) { 37516 this.destroy(); 37517 } 37518 } else { 37519 this.trace(); 37520 this.handle = requestAnimFrame(function () { 37521 self.drawer(); 37522 }); 37523 return; 37524 } 37525 37526 this.callback(this); 37527 if (this.instanceCallback) { 37528 this.instanceCallback(this); 37529 this.instanceCallback = null; 37530 } 37531}; 37532 37533/** 37534 * Draw the SVG at the current instant from the 37535 * `currentFrame` value. Here is where most of the magic is. 37536 * The trick is to use the `strokeDashoffset` style property. 37537 * 37538 * For optimisation reasons, a new property called `progress` 37539 * is added in each item of `map`. This one contain the current 37540 * progress of the path element. Only if the new value is different 37541 * the new value will be applied to the DOM element. This 37542 * method save a lot of resources to re-render the SVG. And could 37543 * be improved if the animation couldn't be played forward. 37544 * 37545 */ 37546Vivus.prototype.trace = function () { 37547 var i, progress, path, currentFrame; 37548 currentFrame = this.animTimingFunction(this.currentFrame / this.frameLength) * this.frameLength; 37549 for (i = 0; i < this.map.length; i++) { 37550 path = this.map[i]; 37551 progress = (currentFrame - path.startAt) / path.duration; 37552 progress = this.pathTimingFunction(Math.max(0, Math.min(1, progress))); 37553 if (path.progress !== progress) { 37554 path.progress = progress; 37555 path.el.style.strokeDashoffset = Math.floor(path.length * (1 - progress)); 37556 this.renderPath(i); 37557 } 37558 } 37559}; 37560 37561/** 37562 * Method forcing the browser to re-render a path element 37563 * from it's index in the map. Depending on the `forceRender` 37564 * value. 37565 * The trick is to replace the path element by it's clone. 37566 * This practice is not recommended because it's asking more 37567 * ressources, too much DOM manupulation.. 37568 * but it's the only way to let the magic happen on IE. 37569 * By default, this fallback is only applied on IE. 37570 * 37571 * @param {Number} index Path index 37572 */ 37573Vivus.prototype.renderPath = function (index) { 37574 if (this.forceRender && this.map && this.map[index]) { 37575 var pathObj = this.map[index], 37576 newPath = pathObj.el.cloneNode(true); 37577 pathObj.el.parentNode.replaceChild(newPath, pathObj.el); 37578 pathObj.el = newPath; 37579 } 37580}; 37581 37582/** 37583 * When the SVG object is loaded and ready, 37584 * this method will continue the initialisation. 37585 * 37586 * This this mainly due to the case of passing an 37587 * object tag in the constructor. It will wait 37588 * the end of the loading to initialise. 37589 * 37590 */ 37591Vivus.prototype.init = function () { 37592 // Set object variables 37593 this.frameLength = 0; 37594 this.currentFrame = 0; 37595 this.map = []; 37596 37597 // Start 37598 new Pathformer(this.el); 37599 this.mapping(); 37600 this.starter(); 37601 37602 if (this.onReady) { 37603 this.onReady(this); 37604 } 37605}; 37606 37607/** 37608 * Trigger to start of the animation. 37609 * Depending on the `start` value, a different script 37610 * will be applied. 37611 * 37612 * If the `start` value is not valid, an error will be thrown. 37613 * Even if technically, this is impossible. 37614 * 37615 */ 37616Vivus.prototype.starter = function () { 37617 switch (this.start) { 37618 case 'manual': 37619 return; 37620 37621 case 'autostart': 37622 this.play(); 37623 break; 37624 37625 case 'inViewport': 37626 var self = this, 37627 listener = function () { 37628 if (self.isInViewport(self.parentEl, 1)) { 37629 self.play(); 37630 window.removeEventListener('scroll', listener); 37631 //Uncode addition 37632 window.removeEventListener('fp-slide-changed', listener); 37633 window.removeEventListener('fp-slide-scroll', listener); 37634 //#END 37635 } 37636 }; 37637 window.addEventListener('scroll', listener); 37638 //Uncode addition 37639 window.addEventListener('fp-slide-changed', listener); 37640 window.addEventListener('fp-slide-scroll', listener); 37641 //#END 37642 listener(); 37643 break; 37644 } 37645}; 37646 37647 37648/** 37649 * Controls 37650 ************************************** 37651 */ 37652 37653/** 37654 * Get the current status of the animation between 37655 * three different states: 'start', 'progress', 'end'. 37656 * @return {string} Instance status 37657 */ 37658Vivus.prototype.getStatus = function () { 37659 return this.currentFrame === 0 ? 'start' : this.currentFrame === this.frameLength ? 'end' : 'progress'; 37660}; 37661 37662/** 37663 * Reset the instance to the initial state : undraw 37664 * Be careful, it just reset the animation, if you're 37665 * playing the animation, this won't stop it. But just 37666 * make it start from start. 37667 * 37668 */ 37669Vivus.prototype.reset = function () { 37670 return this.setFrameProgress(0); 37671}; 37672 37673/** 37674 * Set the instance to the final state : drawn 37675 * Be careful, it just set the animation, if you're 37676 * playing the animation on rewind, this won't stop it. 37677 * But just make it start from the end. 37678 * 37679 */ 37680Vivus.prototype.finish = function () { 37681 return this.setFrameProgress(1); 37682}; 37683 37684/** 37685 * Set the level of progress of the drawing. 37686 * 37687 * @param {number} progress Level of progress to set 37688 */ 37689Vivus.prototype.setFrameProgress = function (progress) { 37690 progress = Math.min(1, Math.max(0, progress)); 37691 this.currentFrame = Math.round(this.frameLength * progress); 37692 this.trace(); 37693 return this; 37694}; 37695 37696/** 37697 * Play the animation at the desired speed. 37698 * Speed must be a valid number (no zero). 37699 * By default, the speed value is 1. 37700 * But a negative value is accepted to go forward. 37701 *
37702 * And works with float too. 37703 * But don't forget we are in JavaScript, se be nice 37704 * with him and give him a 1/2^x value. 37705 * 37706 * @param {number} speed Animation speed [optional] 37707 */ 37708Vivus.prototype.play = function (speed, callback) { 37709 this.instanceCallback = null; 37710 37711 if (speed && typeof speed === 'function') { 37712 this.instanceCallback = speed; // first parameter is actually the callback function 37713 speed = null; 37714 } 37715 else if (speed && typeof speed !== 'number') { 37716 throw new Error('Vivus [play]: invalid speed'); 37717 } 37718 // if the first parameter wasn't the callback, check if the seconds was 37719 if (callback && typeof(callback) === 'function' && !this.instanceCallback) { 37720 this.instanceCallback = callback; 37721 } 37722 37723 37724 this.speed = speed || 1; 37725 //Uncode addition 37726 if (!this.handle) { 37727 var $this = this, 37728 delay = (this.delayStart != null) ? this.delayStart : 0; 37729 setTimeout(function() { 37730 $this.drawer(); 37731 }, delay); 37732 } 37733 //#END 37734 return this; 37735}; 37736 37737/** 37738 * Stop the current animation, if on progress. 37739 * Should not trigger any error. 37740 * 37741 */ 37742Vivus.prototype.stop = function () { 37743 if (this.handle) { 37744 cancelAnimFrame(this.handle); 37745 this.handle = null; 37746 } 37747 return this; 37748}; 37749 37750/** 37751 * Destroy the instance. 37752 * Remove all bad styling attributes on all 37753 * path tags 37754 * 37755 */ 37756Vivus.prototype.destroy = function () { 37757 this.stop(); 37758 var i, path; 37759 for (i = 0; i < this.map.length; i++) { 37760 path = this.map[i]; 37761 path.el.style.strokeDashoffset = null; 37762 path.el.style.strokeDasharray = null; 37763 this.renderPath(i); 37764 } 37765}; 37766 37767 37768/** 37769 * Utils methods 37770 * include methods from Codrops 37771 ************************************** 37772 */ 37773 37774/** 37775 * Method to best guess if a path should added into 37776 * the animation or not. 37777 * 37778 * 1. Use the `data-vivus-ignore` attribute if set 37779 * 2. Check if the instance must ignore invisible paths 37780 * 3. Check if the path is visible 37781 * 37782 * For now the visibility checking is unstable. 37783 * It will be used for a beta phase. 37784 * 37785 * Other improvments are planned. Like detecting 37786 * is the path got a stroke or a valid opacity. 37787 */ 37788Vivus.prototype.isInvisible = function (el) { 37789 var rect, 37790 ignoreAttr = el.getAttribute('data-ignore'); 37791 37792 if (ignoreAttr !== null) { 37793 return ignoreAttr !== 'false'; 37794 } 37795 37796 if (this.ignoreInvisible) { 37797 rect = el.getBoundingClientRect(); 37798 return !rect.width && !rect.height; 37799 } 37800 else { 37801 return false; 37802 } 37803}; 37804 37805/** 37806 * Parse attributes of a DOM element to 37807 * get an object of {attributeName => attributeValue} 37808 * 37809 * @param {object} element DOM element to parse 37810 * @return {object} Object of attributes 37811 */ 37812Vivus.prototype.parseAttr = function (element) { 37813 var attr, output = {}; 37814 if (element && element.attributes) { 37815 for (var i = 0; i < element.attributes.length; i++) { 37816 attr = element.attributes[i]; 37817 output[attr.name] = attr.value; 37818 } 37819 } 37820 return output; 37821}; 37822 37823/** 37824 * Reply if an element is in the page viewport 37825 * 37826 * @param {object} el Element to observe 37827 * @param {number} h Percentage of height 37828 * @return {boolean} 37829 */ 37830Vivus.prototype.isInViewport = function (el, h) { 37831 var scrolled = this.scrollY(), 37832 viewed = scrolled + this.getViewportH(), 37833 elBCR = el.getBoundingClientRect(), 37834 elHeight = elBCR.height, 37835 elTop = scrolled + elBCR.top, 37836 elBottom = elTop + elHeight; 37837 37838 // if 0, the element is considered in the viewport as soon as it enters. 37839 // if 1, the element is considered in the viewport only when it's fully inside 37840 // value in percentage (1 >= h >= 0) 37841 h = h || 0; 37842 37843 return (elTop + elHeight * h) <= viewed && (elBottom) >= scrolled; 37844}; 37845 37846 37847/** 37848 * Get the viewport height in pixels 37849 * 37850 * @return {integer} Viewport height 37851 */ 37852Vivus.prototype.getViewportH = function () { 37853 var client = this.docElem.clientHeight, 37854 inner = window.innerHeight; 37855 37856 if (client < inner) { 37857 return inner; 37858 } 37859 else { 37860 return client; 37861 } 37862}; 37863 37864/** 37865 * Get the page Y offset 37866 * 37867 * @return {integer} Page Y offset 37868 */ 37869Vivus.prototype.scrollY = function () { 37870 return window.pageYOffset || this.docElem.scrollTop; 37871}; 37872 37873setupEnv = function () { 37874 37875 if (Vivus.prototype.docElem) { 37876 return; 37877 } 37878 37879 /** 37880 * Alias for document element 37881 * 37882 * @type {DOMelement} 37883 */ 37884 Vivus.prototype.docElem = window.document.documentElement; 37885 37886 /** 37887 * Alias for `requestAnimationFrame` or 37888 * `setTimeout` function for deprecated browsers. 37889 * 37890 */ 37891 requestAnimFrame = (function () { 37892 return ( 37893 window.requestAnimationFrame || 37894 window.webkitRequestAnimationFrame || 37895 window.mozRequestAnimationFrame || 37896 window.oRequestAnimationFrame || 37897 window.msRequestAnimationFrame || 37898 function(/* function */ callback){ 37899 return window.setTimeout(callback, 1000 / 60); 37900 } 37901 ); 37902 })(); 37903 37904 /** 37905 * Alias for `cancelAnimationFrame` or 37906 * `cancelTimeout` function for deprecated browsers. 37907 * 37908 */ 37909 cancelAnimFrame = (function () { 37910 return ( 37911 window.cancelAnimationFrame || 37912 window.webkitCancelAnimationFrame || 37913 window.mozCancelAnimationFrame || 37914 window.oCancelAnimationFrame || 37915 window.msCancelAnimationFrame || 37916 function(id){ 37917 return window.clearTimeout(id); 37918 } 37919 ); 37920 })(); 37921}; 37922 37923/** 37924 * Parse string to integer. 37925 * If the number is not positive or null 37926 * the method will return the default value 37927 * or 0 if undefined 37928 * 37929 * @param {string} value String to parse 37930 * @param {*}
37930 defaultValue Value to return if the result parsed is invalid 37931 * @return {number} 37932 * 37933 */ 37934parsePositiveInt = function (value, defaultValue) { 37935 var output = parseInt(value, 10); 37936 return (output >= 0) ? output : defaultValue; 37937}; 37938 37939 37940 if (typeof define === 'function' && define.amd) { 37941 // AMD. Register as an anonymous module. 37942 define([], function() { 37943 return Vivus; 37944 }); 37945 } else if (typeof exports === 'object') { 37946 // Node. Does not work with strict CommonJS, but 37947 // only CommonJS-like environments that support module.exports, 37948 // like Node. 37949 module.exports = Vivus; 37950 } else { 37951 // Browser globals 37952 window.Vivus = Vivus; 37953 } 37954 37955}());
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.