vendor: 4,985 bytes, lines 1-161
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.11.3 27 * https://greensock.com 28 * 29 * @license Copyright 2008-2022, 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 _reverting, 49 _context, 50 _bigNum = 1e8, 51 _tinyNum = 1 / _bigNum, 52 _2PI = Math.PI * 2, 53 _HALF_PI = _2PI / 4, 54 _gsID = 0, 55 _sqrt = Math.sqrt, 56 _cos = Math.cos, 57 _sin = Math.sin, 58 _isString = function _isString(value) { 59 return typeof value === "string"; 60 }, 61 _isFunction = function _isFunction(value) { 62 return typeof value === "function"; 63 }, 64 _isNumber = function _isNumber(value) { 65 return typeof value === "number"; 66 }, 67 _isUndefined = function _isUndefined(value) { 68 return typeof value === "undefined"; 69 }, 70 _isObject = function _isObject(value) { 71 return typeof value === "object"; 72 }, 73 _isNotFalse = function _isNotFalse(value) { 74 return value !== false; 75 }, 76 _windowExists = function _windowExists() { 77 return typeof window !== "undefined"; 78 }, 79 _isFuncOrString = function _isFuncOrString(value) { 80 return _isFunction(value) || _isString(value); 81 }, 82 _isTypedArray = typeof ArrayBuffer === "function" && ArrayBuffer.isView || function () {}, 83 _isArray = Array.isArray, 84 _strictNumExp = /(?:-?\.?\d|\.)+/gi, 85 _numExp = /[-+=.]*\d+[.e\-+]*\d*[e\-+]*\d*/g, 86 _numWithUnitExp = /[-+=.]*\d+[.e-]*\d*[a-z%]*/g, 87 _complexStringNumExp = /[-+=.]*\d+\.?\d*(?:e-|e\+)?\d*/gi, 88 _relExp = /[+-]=-?[.\d]+/, 89 _delimitedValueExp = /[^,'"\[\]\s]+/gi, 90 _unitExp = /^[+\-=e\s\d]*\d+[.\d]*([a-z]*|%)\s*$/i, 91 _globalTimeline, 92 _win, 93 _coreInitted, 94 _doc, 95 _globals = {}, 96 _installScope = {}, 97 _coreReady, 98 _install = function _install(scope) { 99 return (_installScope = _merge(scope, _globals)) && gsap; 100 }, 101 _missingPlugin = function _missingPlugin(property, value) { 102 return console.warn("Invalid property", property, "set to", value, "Missing plugin? gsap.registerPlugin()"); 103 }, 104 _warn = function _warn(message, suppress) { 105 return !suppress && console.warn(message); 106 }, 107 _addGlobal = function _addGlobal(name, obj) { 108 return name && (_globals[name] = obj) && _installScope && (_installScope[name] = obj) || _globals; 109 }, 110 _emptyFunc = function _emptyFunc() { 111 return 0; 112 }, 113 _startAtRevertConfig = { 114 suppressEvents: true, 115 isStart: true, 116 kill: false 117 }, 118 _revertConfigNoKill = { 119 suppressEvents: true, 120 kill: false 121 }, 122 _revertConfig = { 123 suppressEvents: true 124 }, 125 _reservedProps = {}, 126 _lazyTweens = [], 127 _lazyLookup = {}, 128 _lastRenderedFrame, 129 _plugins = {}, 130 _effects = {}, 131 _nextGCFrame = 30, 132 _harnessPlugins = [], 133 _callbackNames = "", 134 _harness = function _harness(targets) { 135 var target = targets[0], 136 harnessPlugin, 137 i; 138 _isObject(target) || _isFunction(target) || (targets = [targets]); 139 140 if (!(harnessPlugin = (target._gsap || {}).harness)) { 141 i = _harnessPlugins.length; 142 143 while (i-- && !_harnessPlugins[i].targetTest(target)) {} 144 145 harnessPlugin = _harnessPlugins[i]; 146 } 147 148 i = targets.length; 149 150 while (i--) { 151 targets[i] && (targets[i]._gsap || (targets[i]._gsap = new GSCache(targets[i], harnessPlugin))) || targets.splice(i, 1); 152 } 153 154 return targets; 155 }, 156 _getCache = function _getCache(target) { 157 return target._gsap || _harness(toArray(target))[0]._gsap; 158 }, 159 _getProperty = function _getProperty(target, property, v) { 160 return (v = target[property]) && _isFunction(v) ? target[property]() : _isUndefined(v) && target.getAttribute && target.getAttribute(property) || v; 161 },
vendor: 7,375 bytes, lines 162-396
162 _forEachName = function _forEachName(names, func) { 163 return (names = names.split(",")).forEach(func) || names; 164 }, 165 _round = function _round(value) { 166 return Math.round(value * 100000) / 100000 || 0; 167 }, 168 _roundPrecise = function _roundPrecise(value) { 169 return Math.round(value * 10000000) / 10000000 || 0; 170 }, 171 _parseRelative = function _parseRelative(start, value) { 172 var operator = value.charAt(0), 173 end = parseFloat(value.substr(2)); 174 start = parseFloat(start); 175 return operator === "+" ? start + end : operator === "-" ? start - end : operator === "*" ? start * end : start / end; 176 }, 177 _arrayContainsAny = function _arrayContainsAny(toSearch, toFind) { 178 var l = toFind.length, 179 i = 0; 180 181 for (; toSearch.indexOf(toFind[i]) < 0 && ++i < l;) {} 182 183 return i < l; 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 || _reverting && time < 0 && (animation._initted || animation._startAt)); 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(excludeDuration) { 219 return function (obj, defaults) { 220 for (var p in defaults) { 221 p in obj || p === "duration" && excludeDuration || p === "ease" || (obj[p] = defaults[p]); 222 } 223 }; 224 }, 225 _merge = function _merge(base, toMerge) { 226 for (var p in toMerge) { 227 base[p] = toMerge[p]; 228 } 229 230 return base; 231 }, 232 _mergeDeep = function _mergeDeep(base, toMerge) { 233 for (var p in toMerge) { 234 p !== "__proto__" && p !== "constructor" && p !== "prototype" && (base[p] = _isObject(toMerge[p]) ? _mergeDeep(base[p] || (base[p] = {}), toMerge[p]) : toMerge[p]); 235 } 236 237 return base; 238 }, 239 _copyExcluding = function _copyExcluding(obj, excluding) { 240 var copy = {}, 241 p; 242 243 for (p in obj) { 244 p in excluding || (copy[p] = obj[p]); 245 } 246 247 return copy; 248 }, 249 _inheritDefaults = function _inheritDefaults(vars) { 250 var parent = vars.parent || _globalTimeline, 251 func = vars.keyframes ? _setKeyframeDefaults(_isArray(vars.keyframes)) : _setDefaults; 252 253 if (_isNotFalse(vars.inherit)) { 254 while (parent) { 255 func(vars, parent.vars.defaults); 256 parent = parent.parent || parent._dp; 257 } 258 } 259 260 return vars; 261 }, 262 _arraysMatch = function _arraysMatch(a1, a2) { 263 var i = a1.length, 264 match = i === a2.length; 265 266 while (match && i-- && a1[i] === a2[i]) {} 267 268 return i < 0; 269 }, 270 _addLinkedListItem = function _addLinkedListItem(parent, child, firstProp, lastProp, sortBy) { 271 if (firstProp === void 0) { 272 firstProp = "_first"; 273 } 274 275 if (lastProp === void 0) { 276 lastProp = "_last"; 277 } 278 279 var prev = parent[lastProp], 280 t; 281 282 if (sortBy) { 283 t = child[sortBy]; 284 285 while (prev && prev[sortBy] > t) { 286 prev = prev._prev; 287 } 288 } 289 290 if (prev) { 291 child._next = prev._next; 292 prev._next = child; 293 } else { 294 child._next = parent[firstProp]; 295 parent[firstProp] = child; 296 } 297 298 if (child._next) { 299 child._next._prev = child; 300 } else { 301 parent[lastProp] = child; 302 } 303 304 child._prev = prev; 305 child.parent = child._dp = parent; 306 return child; 307 }, 308 _removeLinkedListItem = function _removeLinkedListItem(parent, child, firstProp, lastProp) { 309 if (firstProp === void 0) { 310 firstProp = "_first"; 311 } 312 313 if (lastProp === void 0) { 314 lastProp = "_last"; 315 } 316 317 var prev = child._prev, 318 next = child._next; 319 320 if (prev) { 321 prev._next = next; 322 } else if (parent[firstProp] === child) { 323 parent[firstProp] = next; 324 } 325 326 if (next) { 327 next._prev = prev; 328 } else if (parent[lastProp] === child) { 329 parent[lastProp] = prev; 330 } 331 332 child._next = child._prev = child.parent = null; 333 }, 334 _removeFromParent = function _removeFromParent(child, onlyIfParentHasAutoRemove) { 335 child.parent && (!onlyIfParentHasAutoRemove || child.parent.autoRemoveChildren) && child.parent.remove(child); 336 child._act = 0; 337 }, 338 _uncache = function _uncache(animation, child) { 339 if (animation && (!child || child._end > animation._dur || child._start < 0)) { 340 var a = animation; 341 342 while (a) { 343 a._dirty = 1; 344 a = a.parent; 345 } 346 } 347 348 return animation; 349 }, 350 _recacheAncestors = function _recacheAncestors(animation) { 351 var parent = animation.parent; 352 353 while (parent && parent.parent) { 354 parent._dirty = 1; 355 parent.totalDuration(); 356 parent = parent.parent; 357 } 358 359 return animation; 360 }, 361 _rewindStartAt = function _rewindStartAt(tween, totalTime, suppressEvents, force) { 362 return tween._startAt && (_reverting ? tween._startAt.revert(_revertConfigNoKill) : tween.vars.immediateRender && !tween.vars.autoRevert || tween._startAt.render(totalTime, true, force)); 363 }, 364 _hasNoPausedAncestors = function _hasNoPausedAncestors(animation) { 365 return !animation || animation._ts && _hasNoPausedAncestors(animation.parent); 366 }, 367 _elapsedCycleDuration = function _elapsedCycleDuration(animation) { 368 return animation._repeat ? _animationCycle(animation._tTime, animation = animation.duration() + animation._rDelay) * animation : 0; 369 }, 370 _animationCycle = function _animationCycle(tTime, cycleDuration) { 371 var whole = Math.floor(tTime /= cycleDuration); 372 return tTime && whole === tTime ? whole - 1 : whole; 373 }, 374 _parentToChildTotalTime = function _parentToChildTotalTime(parentTime, child) { 375 return (parentTime - child._start) * child._ts + (child._ts >= 0 ? 0 : child._dirty ? child.totalDuration() : child._tDur); 376 }, 377 _setEnd = function _setEnd(animation) { 378 return animation._end = _roundPrecise(animation._start + (animation._tDur / Math.abs(animation._ts || animation._rts || _tinyNum) || 0)); 379 }, 380 _alignPlayhead = function _alignPlayhead(animation, totalTime) { 381 var parent = animation._dp; 382 383 if (parent && parent.smoothChildTiming && animation._ts) { 384 animation._start = _roundPrecise(parent._time - (animation._ts > 0 ? totalTime / animation._ts : ((animation._dirty ? animation.totalDuration() : animation._tDur) - totalTime) / -animation._ts)); 385 386 _setEnd(animation); 387 388 parent._dirty || _uncache(parent, animation); 389 } 390 391 return animation; 392 }, 393 _postAddChecks = function _postAddChecks(timeline, child) { 394 var t; 395 396 if (child._time || child._initted && !child._dur
vendor: 11,458 bytes, lines 396-708
396) { 397 t = _parentToChildTotalTime(timeline.rawTime(), child); 398 399 if (!child._dur || _clamp(0, child.totalDuration(), t) - child._tTime > _tinyNum) { 400 child.render(t, true); 401 } 402 } 403 404 if (_uncache(timeline, child)._dp && timeline._initted && timeline._time >= timeline._dur && timeline._ts) { 405 if (timeline._dur < timeline.duration()) { 406 t = timeline; 407 408 while (t._dp) { 409 t.rawTime() >= 0 && t.totalTime(t._tTime); 410 t = t._dp; 411 } 412 } 413 414 timeline._zTime = -_tinyNum; 415 } 416 }, 417 _addToTimeline = function _addToTimeline(timeline, child, position, skipChecks) { 418 child.parent && _removeFromParent(child); 419 child._start = _roundPrecise((_isNumber(position) ? position : position || timeline !== _globalTimeline ? _parsePosition(timeline, position, child) : timeline._time) + child._delay); 420 child._end = _roundPrecise(child._start + (child.totalDuration() / Math.abs(child.timeScale()) || 0)); 421 422 _addLinkedListItem(timeline, child, "_first", "_last", timeline._sort ? "_start" : 0); 423 424 _isFromOrFromStart(child) || (timeline._recent = child); 425 skipChecks || _postAddChecks(timeline, child); 426 timeline._ts < 0 && _alignPlayhead(timeline, timeline._tTime); 427 return timeline; 428 }, 429 _scrollTrigger = function _scrollTrigger(animation, trigger) { 430 return (_globals.ScrollTrigger || _missingPlugin("scrollTrigger", trigger)) && _globals.ScrollTrigger.create(trigger, animation); 431 }, 432 _attemptInitTween = function _attemptInitTween(tween, time, force, suppressEvents, tTime) { 433 _initTween(tween, time, tTime); 434 435 if (!tween._initted) { 436 return 1; 437 } 438 439 if (!force && tween._pt && !_reverting && (tween._dur && tween.vars.lazy !== false || !tween._dur && tween.vars.lazy) && _lastRenderedFrame !== _ticker.frame) { 440 _lazyTweens.push(tween); 441 442 tween._lazy = [tTime, suppressEvents]; 443 return 1; 444 } 445 }, 446 _parentPlayheadIsBeforeStart = function _parentPlayheadIsBeforeStart(_ref) { 447 var parent = _ref.parent; 448 return parent && parent._ts && parent._initted && !parent._lock && (parent.rawTime() < 0 || _parentPlayheadIsBeforeStart(parent)); 449 }, 450 _isFromOrFromStart = function _isFromOrFromStart(_ref2) { 451 var data = _ref2.data; 452 return data === "isFromStart" || data === "isStart"; 453 }, 454 _renderZeroDurationTween = function _renderZeroDurationTween(tween, totalTime, suppressEvents, force) { 455 var prevRatio = tween.ratio, 456 ratio = totalTime < 0 || !totalTime && (!tween._start && _parentPlayheadIsBeforeStart(tween) && !(!tween._initted && _isFromOrFromStart(tween)) || (tween._ts < 0 || tween._dp._ts < 0) && !_isFromOrFromStart(tween)) ? 0 : 1, 457 repeatDelay = tween._rDelay, 458 tTime = 0, 459 pt, 460 iteration, 461 prevIteration; 462 463 if (repeatDelay && tween._repeat) { 464 tTime = _clamp(0, tween._tDur, totalTime); 465 iteration = _animationCycle(tTime, repeatDelay); 466 tween._yoyo && iteration & 1 && (ratio = 1 - ratio); 467 468 if (iteration !== _animationCycle(tween._tTime, repeatDelay)) { 469 prevRatio = 1 - ratio; 470 tween.vars.repeatRefresh && tween._initted && tween.invalidate(); 471 } 472 } 473 474 if (ratio !== prevRatio || _reverting || force || tween._zTime === _tinyNum || !totalTime && tween._zTime) { 475 if (!tween._initted && _attemptInitTween(tween, totalTime, force, suppressEvents, tTime)) { 476 return; 477 } 478 479 prevIteration = tween._zTime; 480 tween._zTime = totalTime || (suppressEvents ? _tinyNum : 0); 481 suppressEvents || (suppressEvents = totalTime && !prevIteration); 482 tween.ratio = ratio; 483 tween._from && (ratio = 1 - ratio); 484 tween._time = 0; 485 tween._tTime = tTime; 486 pt = tween._pt; 487 488 while (pt) { 489 pt.r(ratio, pt.d); 490 pt = pt._next; 491 } 492 493 totalTime < 0 && _rewindStartAt(tween, totalTime, suppressEvents, true); 494 tween._onUpdate && !suppressEvents && _callback(tween, "onUpdate"); 495 tTime && tween._repeat && !suppressEvents && tween.parent && _callback(tween, "onRepeat"); 496 497 if ((totalTime >= tween._tDur || totalTime < 0) && tween.ratio === ratio) { 498 ratio && _removeFromParent(tween, 1); 499 500 if (!suppressEvents && !_reverting) { 501 _callback(tween, ratio ? "onComplete" : "onReverseComplete", true); 502 503 tween._prom && tween._prom(); 504 } 505 } 506 } else if (!tween._zTime) { 507 tween._zTime = totalTime; 508 } 509 }, 510 _findNextPauseTween = function _findNextPauseTween(animation, prevTime, time) { 511 var child; 512 513 if (time > prevTime) { 514 child = animation._first; 515 516 while (child && child._start <= time) { 517 if (child.data === "isPause" && child._start > prevTime) { 518 return child; 519 } 520 521 child = child._next; 522 } 523 } else { 524 child = animation._last; 525 526 while (child && child._start >= time) { 527 if (child.data === "isPause" && child._start < prevTime) { 528 return child; 529 } 530 531 child = child._prev; 532 } 533 } 534 }, 535 _setDuration = function _setDuration(animation, duration, skipUncache, leavePlayhead) { 536 var repeat = animation._repeat, 537 dur = _roundPrecise(duration) || 0, 538 totalProgress = animation._tTime / animation._tDur; 539 totalProgress && !leavePlayhead && (animation._time *= dur / animation._dur); 540 animation._dur = dur; 541 animation._tDur = !repeat ? dur : repeat < 0 ? 1e10 : _roundPrecise(dur * (repeat + 1) + animation._rDelay * repeat); 542 totalProgress > 0 && !leavePlayhead && _alignPlayhead(animation, animation._tTime = animation._tDur * totalProgress); 543 animation.parent && _setEnd(animation); 544 skipUncache || _uncache(animation.parent, animation); 545 return animation; 546 }, 547 _onUpdateTotalDuration = function _onUpdateTotalDuration(animation) { 548 return animation instanceof Timeline ? _uncache(animation) : _setDuration(animation, animation._dur); 549 }, 550 _zeroPosition = { 551 _start: 0, 552 endTime: _emptyFunc, 553 totalDuration: _emptyFunc 554 }, 555 _parsePosition = function _parsePosition(animation, position, percentAnimation) { 556 var labels = animation.labels, 557 recent = animation._recent || _zeroPosition, 558 clippedDuration = animation.duration() >= _bigNum ? recent.endTime(false) : animation._dur, 559 i, 560 offset, 561 isPercent; 562 563 if (_isString(position) && (isNaN(position) || position in labels)) { 564 offset = position.charAt(0); 565 isPercent = position.substr(-1) === "%"; 566 i = position.indexOf("="); 567 568 if (offset === "<" || offset === ">") { 569 i >= 0 && (position = position.replace(/=/, "")); 570 return (offset === "<" ? recent._start : recent.endTime(recent._repeat >= 0)) + (parseFloat(position.substr(1)) || 0) * (isPercent ? (i < 0 ? recent : percentAnimation).totalDuration() / 100 : 1); 571 } 572 573 if (i < 0) { 574 position in labels || (labels[position] = clippedDuration); 575 return labels[position]; 576 } 577 578 offset = parseFloat(position.charAt(i - 1) + position.substr(i + 1)); 579 580 if (isPercent && percentAnimation) { 581 offset = offset / 100 * (_isArray(percentAnimation) ? percentAnimation[0] : percentAnimation).totalDuration(); 582 } 583 584 return i > 1 ? _parsePosition(animation, position.substr(0, i - 1), percentAnimation) + offset : clippedDuration + offset; 585 } 586 587 return position == null ? clippedDuration : +position; 588 }, 589 _createTweenType = function _createTweenType(type, params, timeline) { 590 var isLegacy = _isNumber(params[1]), 591 varsIndex = (isLegacy ? 2 : 1) + (type < 2 ? 0 : 1), 592 vars = params[varsIndex], 593 irVars, 594 parent; 595 596 isLegacy && (vars.duration = params[1]); 597 vars.parent = timeline; 598 599 if (type) { 600 irVars = vars; 601 parent = timeline; 602 603 while (parent && !("immediateRender" in irVars)) { 604 irVars = parent.vars.defaults || {}; 605 parent = _isNotFalse(parent.vars.inherit) && parent.parent; 606 } 607 608 vars.immediateRender = _isNotFalse(irVars.immediateRender); 609 type < 2 ? vars.runBackwards = 1 : vars.startAt = params[varsIndex - 1]; 610 } 611 612 return new Tween(params[0], vars, params[varsIndex + 1]); 613 }, 614 _conditionalReturn = function _conditionalReturn(value, func) { 615 return value || value === 0 ? func(value) : func; 616 }, 617 _clamp = function _clamp(min, max, value) { 618 return value < min ? min : value > max ? max : value; 619 }, 620 getUnit = function getUnit(value, v) { 621 return !_isString(value) || !(v = _unitExp.exec(value)) ? "" : v[1]; 622 }, 623 clamp = function clamp(min, max, value) { 624 return _conditionalReturn(value, function (v) { 625 return _clamp(min, max, v); 626 }); 627 }, 628 _slice = [].slice, 629 _isArrayLike = function _isArrayLike(value, nonEmpty) { 630 return value && _isObject(value) && "length" in value && (!nonEmpty && !value.length || value.length - 1 in value && _isObject(value[0])) && !value.nodeType && value !== _win; 631 }, 632 _flatten = function _flatten(ar, leaveStrings, accumulator) { 633 if (accumulator === void 0) { 634 accumulator = []; 635 } 636 637 return ar.forEach(function (value) { 638 var _accumulator; 639 640 return _isString(value) && !leaveStrings || _isArrayLike(value, 1) ? (_accumulator = accumulator).push.apply(_accumulator, toArray(value)) : accumulator.push(value); 641 }) || accumulator; 642 }, 643 toArray = function toArray(value, scope, leaveStrings) { 644 return _context && !scope && _context.selector ? _context.selector(value) : _isString(value) && !leaveStrings && (_coreInitted || !_wake()) ? _slice.call((scope || _doc).querySelectorAll(value), 0) : _isArray(value) ? _flatten(value, leaveStrings) : _isArrayLike(value) ? _slice.call(value, 0) : value ? [value] : []; 645 }, 646 selector = function selector(value) { 647 value = toArray(value)[0] || _warn("Invalid scope") || {}; 648 return function (v) { 649 var el = value.current || value.nativeElement || value; 650 return toArray(v, el.querySelectorAll ? el : el === value ? _warn("Invalid scope") || _doc.createElement("div") : value); 651 }; 652 }, 653 shuffle = function shuffle(a) { 654 return a.sort(function () { 655 return .5 - Math.random(); 656 }); 657 }, 658 distribute = function distribute(v) { 659 if (_isFunction(v)) { 660 return v; 661 } 662 663 var vars = _isObject(v) ? v : { 664 each: v 665 }, 666 ease = _parseEase(vars.ease), 667 from = vars.from || 0, 668 base = parseFloat(vars.base) || 0, 669 cache = {}, 670 isDecimal = from > 0 && from < 1, 671 ratios = isNaN(from) || isDecimal, 672 axis = vars.axis, 673 ratioX = from, 674 ratioY = from; 675 676 if (_isString(from)) { 677 ratioX = ratioY = { 678 center: .5, 679 edges: .5, 680 end: 1 681 }[from] || 0; 682 } else if (!isDecimal && ratios) { 683 ratioX = from[0]; 684 ratioY = from[1]; 685 } 686 687 return function (i, target, a) { 688 var l = (a || vars).length, 689 distances = cache[l], 690 originX, 691 originY, 692 x, 693 y, 694 d, 695 j, 696 max, 697 min, 698 wrapAt; 699 700 if (!distances) { 701 wrapAt = vars.grid === "auto" ? 0 : (vars.grid || [1, _bigNum])[1]; 702 703 if (!wrapAt) { 704 max = -_bigNum; 705 706 while (max < (max = a[wrapAt++].getBoundingClientRect().left) && wrapAt < l) {} 707 708 wrapAt
vendor: 3,154 bytes, lines 708-798
708--; 709 } 710 711 distances = cache[l] = []; 712 originX = ratios ? Math.min(wrapAt, l) * ratioX - .5 : from % wrapAt; 713 originY = wrapAt === _bigNum ? 0 : ratios ? l * ratioY / wrapAt - .5 : from / wrapAt | 0; 714 max = 0; 715 min = _bigNum; 716 717 for (j = 0; j < l; j++) { 718 x = j % wrapAt - originX; 719 y = originY - (j / wrapAt | 0); 720 distances[j] = d = !axis ? _sqrt(x * x + y * y) : Math.abs(axis === "y" ? y : x); 721 d > max && (max = d); 722 d < min && (min = d); 723 } 724 725 from === "random" && shuffle(distances); 726 distances.max = max - min; 727 distances.min = min; 728 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); 729 distances.b = l < 0 ? base - l : base; 730 distances.u = getUnit(vars.amount || vars.each) || 0; 731 ease = ease && l < 0 ? _invertEase(ease) : ease; 732 } 733 734 l = (distances[i] - distances.min) / distances.max || 0; 735 return _roundPrecise(distances.b + (ease ? ease(l) : l) * distances.v) + distances.u; 736 }; 737 }, 738 _roundModifier = function _roundModifier(v) { 739 var p = Math.pow(10, ((v + "").split(".")[1] || "").length); 740 return function (raw) { 741 var n = _roundPrecise(Math.round(parseFloat(raw) / v) * v * p); 742 743 return (n - n % 1) / p + (_isNumber(raw) ? 0 : getUnit(raw)); 744 }; 745 }, 746 snap = function snap(snapTo, value) { 747 var isArray = _isArray(snapTo), 748 radius, 749 is2D; 750 751 if (!isArray && _isObject(snapTo)) { 752 radius = isArray = snapTo.radius || _bigNum; 753 754 if (snapTo.values) { 755 snapTo = toArray(snapTo.values); 756 757 if (is2D = !_isNumber(snapTo[0])) { 758 radius *= radius; 759 } 760 } else { 761 snapTo = _roundModifier(snapTo.increment); 762 } 763 } 764 765 return _conditionalReturn(value, !isArray ? _roundModifier(snapTo) : _isFunction(snapTo) ? function (raw) { 766 is2D = snapTo(raw); 767 return Math.abs(is2D - raw) <= radius ? is2D : raw; 768 } : function (raw) { 769 var x = parseFloat(is2D ? raw.x : raw), 770 y = parseFloat(is2D ? raw.y : 0), 771 min = _bigNum, 772 closest = 0, 773 i = snapTo.length, 774 dx, 775 dy; 776 777 while (i--) { 778 if (is2D) { 779 dx = snapTo[i].x - x; 780 dy = snapTo[i].y - y; 781 dx = dx * dx + dy * dy; 782 } else { 783 dx = Math.abs(snapTo[i] - x); 784 } 785 786 if (dx < min) { 787 min = dx; 788 closest = i; 789 } 790 } 791 792 closest = !radius || min <= radius ? snapTo[closest] : raw; 793 return is2D || closest === raw || _isNumber(raw) ? closest : closest + getUnit(raw); 794 }); 795 }, 796 random = function random(min, max, roundingIncrement, returnFunction) { 797 return _conditionalReturn(_isArray(min) ? !max : roundingIncrement === true ? !!(roundingIncrement = 0) : !returnFunction, function () { 798 return _isArray(min) ? min[~~(Math.random() * min.length)] : (roundingIncrement = roundingIncrement || 1e
vendor: 4,891 bytes, lines 798-960
798-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; 799 }); 800 }, 801 pipe = function pipe() { 802 for (var _len = arguments.length, functions = new Array(_len), _key = 0; _key < _len; _key++) { 803 functions[_key] = arguments[_key]; 804 } 805 806 return function (value) { 807 return functions.reduce(function (v, f) { 808 return f(v); 809 }, value); 810 }; 811 }, 812 unitize = function unitize(func, unit) { 813 return function (value) { 814 return func(parseFloat(value)) + (unit || getUnit(value)); 815 }; 816 }, 817 normalize = function normalize(min, max, value) { 818 return mapRange(min, max, 0, 1, value); 819 }, 820 _wrapArray = function _wrapArray(a, wrapper, value) { 821 return _conditionalReturn(value, function (index) { 822 return a[~~wrapper(index)]; 823 }); 824 }, 825 wrap = function wrap(min, max, value) { 826 var range = max - min; 827 return _isArray(min) ? _wrapArray(min, wrap(0, min.length), max) : _conditionalReturn(value, function (value) { 828 return (range + (value - min) % range) % range + min; 829 }); 830 }, 831 wrapYoyo = function wrapYoyo(min, max, value) { 832 var range = max - min, 833 total = range * 2; 834 return _isArray(min) ? _wrapArray(min, wrapYoyo(0, min.length - 1), max) : _conditionalReturn(value, function (value) { 835 value = (total + (value - min) % total) % total || 0; 836 return min + (value > range ? total - value : value); 837 }); 838 }, 839 _replaceRandom = function _replaceRandom(value) { 840 var prev = 0, 841 s = "", 842 i, 843 nums, 844 end, 845 isArray; 846 847 while (~(i = value.indexOf("random(", prev))) { 848 end = value.indexOf(")", i); 849 isArray = value.charAt(i + 7) === "["; 850 nums = value.substr(i + 7, end - i - 7).match(isArray ? _delimitedValueExp : _strictNumExp); 851 s += value.substr(prev, i - prev) + random(isArray ? nums : +nums[0], isArray ? 0 : +nums[1], +nums[2] || 1e-5); 852 prev = end + 1; 853 } 854 855 return s + value.substr(prev, value.length - prev); 856 }, 857 mapRange = function mapRange(inMin, inMax, outMin, outMax, value) { 858 var inRange = inMax - inMin, 859 outRange = outMax - outMin; 860 return _conditionalReturn(value, function (value) { 861 return outMin + ((value - inMin) / inRange * outRange || 0); 862 }); 863 }, 864 interpolate = function interpolate(start, end, progress, mutate) { 865 var func = isNaN(start + end) ? 0 : function (p) { 866 return (1 - p) * start + p * end; 867 }; 868 869 if (!func) { 870 var isString = _isString(start), 871 master = {}, 872 p, 873 i, 874 interpolators, 875 l, 876 il; 877 878 progress === true && (mutate = 1) && (progress = null); 879 880 if (isString) { 881 start = { 882 p: start 883 }; 884 end = { 885 p: end 886 }; 887 } else if (_isArray(start) && !_isArray(end)) { 888 interpolators = []; 889 l = start.length; 890 il = l - 2; 891 892 for (i = 1; i < l; i++) { 893 interpolators.push(interpolate(start[i - 1], start[i])); 894 } 895 896 l--; 897 898 func = function func(p) { 899 p *= l; 900 var i = Math.min(il, ~~p); 901 return interpolators[i](p - i); 902 }; 903 904 progress = end; 905 } else if (!mutate) { 906 start = _merge(_isArray(start) ? [] : {}, start); 907 } 908 909 if (!interpolators) { 910 for (p in end) { 911 _addPropTween.call(master, start, p, "get", end[p]); 912 } 913 914 func = function func(p) { 915 return _renderPropTweens(p, master) || (isString ? start.p : start); 916 }; 917 } 918 } 919 920 return _conditionalReturn(progress, func); 921 }, 922 _getLabelInDirection = function _getLabelInDirection(timeline, fromTime, backward) { 923 var labels = timeline.labels, 924 min = _bigNum, 925 p, 926 distance, 927 label; 928 929 for (p in labels) { 930 distance = labels[p] - fromTime; 931 932 if (distance < 0 === !!backward && distance && min > (distance = Math.abs(distance))) { 933 label = p; 934 min = distance; 935 } 936 } 937 938 return label; 939 }, 940 _callback = function _callback(animation, type, executeLazyFirst) { 941 var v = animation.vars, 942 callback = v[type], 943 prevContext = _context, 944 context = animation._ctx, 945 params, 946 scope, 947 result; 948 949 if (!callback) { 950 return; 951 } 952 953 params = v[type + "Params"]; 954 scope = v.callbackScope || animation; 955 executeLazyFirst && _lazyTweens.length && _lazyRender(); 956 context && (_context = context); 957 result = params ? callback.apply(scope, params) : callback.call(scope); 958 _context = prevContext; 959 return result; 960 },
vendor: 7,656 bytes, lines 961-1246
961 _interrupt = function _interrupt(animation) { 962 _removeFromParent(animation); 963 964 animation.scrollTrigger && animation.scrollTrigger.kill(!!_reverting); 965 animation.progress() < 1 && _callback(animation, "onInterrupt"); 966 return animation; 967 }, 968 _quickTween, 969 _createPlugin = function _createPlugin(config) { 970 config = !config.name && config["default"] || config; 971 972 var name = config.name, 973 isFunc = _isFunction(config), 974 Plugin = name && !isFunc && config.init ? function () { 975 this._props = []; 976 } : config, 977 instanceDefaults = { 978 init: _emptyFunc, 979 render: _renderPropTweens, 980 add: _addPropTween, 981 kill: _killPropTweensOf, 982 modifier: _addPluginModifier, 983 rawVars: 0 984 }, 985 statics = { 986 targetTest: 0, 987 get: 0, 988 getSetter: _getSetter, 989 aliases: {}, 990 register: 0 991 }; 992 993 _wake(); 994 995 if (config !== Plugin) { 996 if (_plugins[name]) { 997 return; 998 } 999 1000 _setDefaults(Plugin, _setDefaults(_copyExcluding(config, instanceDefaults), statics)); 1001 1002 _merge(Plugin.prototype, _merge(instanceDefaults, _copyExcluding(config, statics))); 1003 1004 _plugins[Plugin.prop = name] = Plugin; 1005 1006 if (config.targetTest) { 1007 _harnessPlugins.push(Plugin); 1008 1009 _reservedProps[name] = 1; 1010 } 1011 1012 name = (name === "css" ? "CSS" : name.charAt(0).toUpperCase() + name.substr(1)) + "Plugin"; 1013 } 1014 1015 _addGlobal(name, Plugin); 1016 1017 config.register && config.register(gsap, Plugin, PropTween); 1018 }, 1019 _255 = 255, 1020 _colorLookup = { 1021 aqua: [0, _255, _255], 1022 lime: [0, _255, 0], 1023 silver: [192, 192, 192], 1024 black: [0, 0, 0], 1025 maroon: [128, 0, 0], 1026 teal: [0, 128, 128], 1027 blue: [0, 0, _255], 1028 navy: [0, 0, 128], 1029 white: [_255, _255, _255], 1030 olive: [128, 128, 0], 1031 yellow: [_255, _255, 0], 1032 orange: [_255, 165, 0], 1033 gray: [128, 128, 128], 1034 purple: [128, 0, 128], 1035 green: [0, 128, 0], 1036 red: [_255, 0, 0], 1037 pink: [_255, 192, 203], 1038 cyan: [0, _255, _255], 1039 transparent: [_255, _255, _255, 0] 1040 }, 1041 _hue = function _hue(h, m1, m2) { 1042 h += h < 0 ? 1 : h > 1 ? -1 : 0; 1043 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; 1044 }, 1045 splitColor = function splitColor(v, toHSL, forceAlpha) { 1046 var a = !v ? _colorLookup.black : _isNumber(v) ? [v >> 16, v >> 8 & _255, v & _255] : 0, 1047 r, 1048 g, 1049 b, 1050 h, 1051 s, 1052 l, 1053 max, 1054 min, 1055 d, 1056 wasHSL; 1057 1058 if (!a) { 1059 if (v.substr(-1) === ",") { 1060 v = v.substr(0, v.length - 1); 1061 } 1062 1063 if (_colorLookup[v]) { 1064 a = _colorLookup[v]; 1065 } else if (v.charAt(0) === "#") { 1066 if (v.length < 6) { 1067 r = v.charAt(1); 1068 g = v.charAt(2); 1069 b = v.charAt(3); 1070 v = "#" + r + r + g + g + b + b + (v.length === 5 ? v.charAt(4) + v.charAt(4) : ""); 1071 } 1072 1073 if (v.length === 9) { 1074 a = parseInt(v.substr(1, 6), 16); 1075 return [a >> 16, a >> 8 & _255, a & _255, parseInt(v.substr(7), 16) / 255]; 1076 } 1077 1078 v = parseInt(v.substr(1), 16); 1079 a = [v >> 16, v >> 8 & _255, v & _255]; 1080 } else if (v.substr(0, 3) === "hsl") { 1081 a = wasHSL = v.match(_strictNumExp); 1082 1083 if (!toHSL) { 1084 h = +a[0] % 360 / 360; 1085 s = +a[1] / 100; 1086 l = +a[2] / 100; 1087 g = l <= .5 ? l * (s + 1) : l + s - l * s; 1088 r = l * 2 - g; 1089 a.length > 3 && (a[3] *= 1); 1090 a[0] = _hue(h + 1 / 3, r, g); 1091 a[1] = _hue(h, r, g); 1092 a[2] = _hue(h - 1 / 3, r, g); 1093 } else if (~v.indexOf("=")) { 1094 a = v.match(_numExp); 1095 forceAlpha && a.length < 4 && (a[3] = 1); 1096 return a; 1097 } 1098 } else { 1099 a = v.match(_strictNumExp) || _colorLookup.transparent; 1100 } 1101 1102 a = a.map(Number); 1103 } 1104 1105 if (toHSL && !wasHSL) { 1106 r = a[0] / _255; 1107 g = a[1] / _255; 1108 b = a[2] / _255; 1109 max = Math.max(r, g, b); 1110 min = Math.min(r, g, b); 1111 l = (max + min) / 2; 1112 1113 if (max === min) { 1114 h = s = 0; 1115 } else { 1116 d = max - min; 1117 s = l > 0.5 ? d / (2 - max - min) : d / (max + min); 1118 h = max === r ? (g - b) / d + (g < b ? 6 : 0) : max === g ? (b - r) / d + 2 : (r - g) / d + 4; 1119 h *= 60; 1120 } 1121 1122 a[0] = ~~(h + .5); 1123 a[1] = ~~(s * 100 + .5); 1124 a[2] = ~~(l * 100 + .5); 1125 } 1126 1127 forceAlpha && a.length < 4 && (a[3] = 1); 1128 return a; 1129 }, 1130 _colorOrderData = function _colorOrderData(v) { 1131 var values = [], 1132 c = [], 1133 i = -1; 1134 v.split(_colorExp).forEach(function (v) { 1135 var a = v.match(_numWithUnitExp) || []; 1136 values.push.apply(values, a); 1137 c.push(i += a.length + 1); 1138 }); 1139 values.c = c; 1140 return values; 1141 }, 1142 _formatColors = function _formatColors(s, toHSL, orderMatchData) { 1143 var result = "", 1144 colors = (s + result).match(_colorExp), 1145 type = toHSL ? "hsla(" : "rgba(", 1146 i = 0, 1147 c, 1148 shell, 1149 d, 1150 l; 1151 1152 if (!colors) { 1153 return s; 1154 } 1155 1156 colors = colors.map(function (color) { 1157 return (color = splitColor(color, toHSL, 1)) && type + (toHSL ? color[0] + "," + color[1] + "%," + color[2] + "%," + color[3] : color.join(",")) + ")"; 1158 }); 1159 1160 if (orderMatchData) { 1161 d = _colorOrderData(s); 1162 c = orderMatchData.c; 1163 1164 if (c.join(result) !== d.c.join(result)) { 1165 shell = s.replace(_colorExp, "1").split(_numWithUnitExp); 1166 l = shell.length - 1; 1167 1168 for (; i < l; i++) { 1169 result += shell[i] + (~c.indexOf(i) ? colors.shift() || type + "0,0,0,0)" : (d.length ? d : colors.length ? colors : orderMatchData).shift()); 1170 } 1171 } 1172 } 1173 1174 if (!shell) { 1175 shell = s.split(_colorExp); 1176 l = shell.length - 1; 1177 1178 for (; i < l; i++) { 1179 result += shell[i] + colors[i]; 1180 } 1181 } 1182 1183 return result + shell[l]; 1184 }, 1185 _colorExp = function () { 1186 var s = "(?:\\b(?:(?:rgb|rgba|hsl|hsla)\\(.+?\\))|\\B#(?:[0-9a-f]{3,4}){1,2}\\b", 1187 p; 1188 1189 for (p in _colorLookup) { 1190 s += "|" + p + "\\b"; 1191 } 1192 1193 return new RegExp(s + ")", "gi"); 1194 }(), 1195 _hslExp = /hsl[a]?\(/, 1196 _colorStringFilter = function _colorStringFilter(a) { 1197 var combined = a.join(" "), 1198 toHSL; 1199 _colorExp.lastIndex = 0; 1200 1201 if (_colorExp.test(combined)) { 1202 toHSL = _hslExp.test(combined); 1203 a[1] = _formatColors(a[1], toHSL); 1204 a[0] = _formatColors(a[0], toHSL, _colorOrderData(a[1])); 1205 return true; 1206 } 1207 }, 1208 _tickerActive, 1209 _ticker = function () { 1210 var _getTime = Date.now, 1211 _lagThreshold = 500, 1212 _adjustedLag = 33, 1213 _startTime = _getTime(), 1214 _lastUpdate = _startTime, 1215 _gap = 1000 / 240, 1216 _nextTime = _gap, 1217 _listeners = [], 1218 _id, 1219 _req, 1220 _raf, 1221 _self, 1222 _delta, 1223 _i, 1224 _tick = function _tick(v) { 1225 var elapsed = _getTime() - _lastUpdate, 1226 manual = v === true, 1227 overlap, 1228 dispatch, 1229 time, 1230 frame; 1231 1232 elapsed > _lagThreshold && (_startTime += elapsed - _adjustedLag); 1233 _lastUpdate += elapsed; 1234 time = _lastUpdate - _startTime; 1235 overlap = time - _nextTime; 1236 1237 if (overlap > 0 || manual) { 1238 frame = ++_self.frame; 1239 _delta = time - _self.time * 1000; 1240 _self.time = time = time / 1000; 1241 _nextTime += overlap + (overlap >= _gap ? 4 : _gap - overlap); 1242 dispatch = 1; 1243 } 1244 1245 manual || (_id = _req(_tick)); 1246
vendor: 4,239 bytes, lines 1247-1383
1247 if (dispatch) { 1248 for (_i = 0; _i < _listeners.length; _i++) { 1249 _listeners[_i](time, _delta, frame, v); 1250 } 1251 } 1252 }; 1253 1254 _self = { 1255 time: 0, 1256 frame: 0, 1257 tick: function tick() { 1258 _tick(true); 1259 }, 1260 deltaRatio: function deltaRatio(fps) { 1261 return _delta / (1000 / (fps || 60)); 1262 }, 1263 wake: function wake() { 1264 if (_coreReady) { 1265 if (!_coreInitted && _windowExists()) { 1266 _win = _coreInitted = window; 1267 _doc = _win.document || {}; 1268 _globals.gsap = gsap; 1269 (_win.gsapVersions || (_win.gsapVersions = [])).push(gsap.version); 1270 1271 _install(_installScope || _win.GreenSockGlobals || !_win.gsap && _win || {}); 1272 1273 _raf = _win.requestAnimationFrame; 1274 } 1275 1276 _id && _self.sleep(); 1277 1278 _req = _raf || function (f) { 1279 return setTimeout(f, _nextTime - _self.time * 1000 + 1 | 0); 1280 }; 1281 1282 _tickerActive = 1; 1283 1284 _tick(2); 1285 } 1286 }, 1287 sleep: function sleep() { 1288 (_raf ? _win.cancelAnimationFrame : clearTimeout)(_id); 1289 _tickerActive = 0; 1290 _req = _emptyFunc; 1291 }, 1292 lagSmoothing: function lagSmoothing(threshold, adjustedLag) { 1293 _lagThreshold = threshold || 1 / _tinyNum; 1294 _adjustedLag = Math.min(adjustedLag, _lagThreshold, 0); 1295 }, 1296 fps: function fps(_fps) { 1297 _gap = 1000 / (_fps || 240); 1298 _nextTime = _self.time * 1000 + _gap; 1299 }, 1300 add: function add(callback, once, prioritize) { 1301 var func = once ? function (t, d, f, v) { 1302 callback(t, d, f, v); 1303 1304 _self.remove(func); 1305 } : callback; 1306 1307 _self.remove(callback); 1308 1309 _listeners[prioritize ? "unshift" : "push"](func); 1310 1311 _wake(); 1312 1313 return func; 1314 }, 1315 remove: function remove(callback, i) { 1316 ~(i = _listeners.indexOf(callback)) && _listeners.splice(i, 1) && _i >= i && _i--; 1317 }, 1318 _listeners: _listeners 1319 }; 1320 return _self; 1321 }(), 1322 _wake = function _wake() { 1323 return !_tickerActive && _ticker.wake(); 1324 }, 1325 _easeMap = {}, 1326 _customEaseExp = /^[\d.\-M][\d.\-,\s]/, 1327 _quotesExp = /["']/g, 1328 _parseObjectInString = function _parseObjectInString(value) { 1329 var obj = {}, 1330 split = value.substr(1, value.length - 3).split(":"), 1331 key = split[0], 1332 i = 1, 1333 l = split.length, 1334 index, 1335 val, 1336 parsedVal; 1337 1338 for (; i < l; i++) { 1339 val = split[i]; 1340 index = i !== l - 1 ? val.lastIndexOf(",") : val.length; 1341 parsedVal = val.substr(0, index); 1342 obj[key] = isNaN(parsedVal) ? parsedVal.replace(_quotesExp, "").trim() : +parsedVal; 1343 key = val.substr(index + 1).trim(); 1344 } 1345 1346 return obj; 1347 }, 1348 _valueInParentheses = function _valueInParentheses(value) { 1349 var open = value.indexOf("(") + 1, 1350 close = value.indexOf(")"), 1351 nested = value.indexOf("(", open); 1352 return value.substring(open, ~nested && nested < close ? value.indexOf(")", close + 1) : close); 1353 }, 1354 _configEaseFromString = function _configEaseFromString(name) { 1355 var split = (name + "").split("("), 1356 ease = _easeMap[split[0]]; 1357 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; 1358 }, 1359 _invertEase = function _invertEase(ease) { 1360 return function (p) { 1361 return 1 - ease(1 - p); 1362 }; 1363 }, 1364 _propagateYoyoEase = function _propagateYoyoEase(timeline, isYoyo) { 1365 var child = timeline._first, 1366 ease; 1367 1368 while (child) { 1369 if (child instanceof Timeline) { 1370 _propagateYoyoEase(child, isYoyo); 1371 } else if (child.vars.yoyoEase && (!child._yoyo || !child._repeat) && child._yoyo !== isYoyo) { 1372 if (child.timeline) { 1373 _propagateYoyoEase(child.timeline, isYoyo); 1374 } else { 1375 ease = child._ease; 1376 child._ease = child._yEase; 1377 child._yEase = ease; 1378 child._yoyo = isYoyo; 1379 } 1380 } 1381 1382 child = child._next; 1383 }
vendor: 3,445 bytes, lines 1383-1494
1383 1384 }, 1385 _parseEase = function _parseEase(ease, defaultEase) { 1386 return !ease ? defaultEase : (_isFunction(ease) ? ease : _easeMap[ease] || _configEaseFromString(ease)) || defaultEase; 1387 }, 1388 _insertEase = function _insertEase(names, easeIn, easeOut, easeInOut) { 1389 if (easeOut === void 0) { 1390 easeOut = function easeOut(p) { 1391 return 1 - easeIn(1 - p); 1392 }; 1393 } 1394 1395 if (easeInOut === void 0) { 1396 easeInOut = function easeInOut(p) { 1397 return p < .5 ? easeIn(p * 2) / 2 : 1 - easeIn((1 - p) * 2) / 2; 1398 }; 1399 } 1400 1401 var ease = { 1402 easeIn: easeIn, 1403 easeOut: easeOut, 1404 easeInOut: easeInOut 1405 }, 1406 lowercaseName; 1407 1408 _forEachName(names, function (name) { 1409 _easeMap[name] = _globals[name] = ease; 1410 _easeMap[lowercaseName = name.toLowerCase()] = easeOut; 1411 1412 for (var p in ease) { 1413 _easeMap[lowercaseName + (p === "easeIn" ? ".in" : p === "easeOut" ? ".out" : ".inOut")] = _easeMap[name + "." + p] = ease[p]; 1414 } 1415 }); 1416 1417 return ease; 1418 }, 1419 _easeInOutFromOut = function _easeInOutFromOut(easeOut) { 1420 return function (p) { 1421 return p < .5 ? (1 - easeOut(1 - p * 2)) / 2 : .5 + easeOut((p - .5) * 2) / 2; 1422 }; 1423 }, 1424 _configElastic = function _configElastic(type, amplitude, period) { 1425 var p1 = amplitude >= 1 ? amplitude : 1, 1426 p2 = (period || (type ? .3 : .45)) / (amplitude < 1 ? amplitude : 1), 1427 p3 = p2 / _2PI * (Math.asin(1 / p1) || 0), 1428 easeOut = function easeOut(p) { 1429 return p === 1 ? 1 : p1 * Math.pow(2, -10 * p) * _sin((p - p3) * p2) + 1; 1430 }, 1431 ease = type === "out" ? easeOut : type === "in" ? function (p) { 1432 return 1 - easeOut(1 - p); 1433 } : _easeInOutFromOut(easeOut); 1434 1435 p2 = _2PI / p2; 1436 1437 ease.config = function (amplitude, period) { 1438 return _configElastic(type, amplitude, period); 1439 }; 1440 1441 return ease; 1442 }, 1443 _configBack = function _configBack(type, overshoot) { 1444 if (overshoot === void 0) { 1445 overshoot = 1.70158; 1446 } 1447 1448 var easeOut = function easeOut(p) { 1449 return p ? --p * p * ((overshoot + 1) * p + overshoot) + 1 : 0; 1450 }, 1451 ease = type === "out" ? easeOut : type === "in" ? function (p) { 1452 return 1 - easeOut(1 - p); 1453 } : _easeInOutFromOut(easeOut); 1454 1455 ease.config = function (overshoot) { 1456 return _configBack(type, overshoot); 1457 }; 1458 1459 return ease; 1460 }; 1461 1462 _forEachName("Linear,Quad,Cubic,Quart,Quint,Strong", function (name, i) { 1463 var power = i < 5 ? i + 1 : i; 1464 1465 _insertEase(name + ",Power" + (power - 1), i ? function (p) { 1466 return Math.pow(p, power); 1467 } : function (p) { 1468 return p; 1469 }, function (p) { 1470 return 1 - Math.pow(1 - p, power); 1471 }, function (p) { 1472 return p < .5 ? Math.pow(p * 2, power) / 2 : 1 - Math.pow((1 - p) * 2, power) / 2; 1473 }); 1474 }); 1475 1476 _easeMap.Linear.easeNone = _easeMap.none = _easeMap.Linear.easeIn; 1477 1478 _insertEase("Elastic", _configElastic("in"), _configElastic("out"), _configElastic()); 1479 1480 (function (n, c) { 1481 var n1 = 1 / c, 1482 n2 = 2 * n1, 1483 n3 = 2.5 * n1, 1484 easeOut = function easeOut(p) { 1485 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; 1486 }; 1487 1488 _insertEase("Bounce", function (p) { 1489 return 1 - easeOut(1 - p); 1490 }, easeOut); 1491 })(7.5625, 2.75); 1492 1493 _insertEase("Expo", function (p) { 1494 return
vendor: 6,314 bytes, lines 1494-1684
1494p ? Math.pow(2, 10 * (p - 1)) : 0; 1495 }); 1496 1497 _insertEase("Circ", function (p) { 1498 return -(_sqrt(1 - p * p) - 1); 1499 }); 1500 1501 _insertEase("Sine", function (p) { 1502 return p === 1 ? 1 : -_cos(p * _HALF_PI) + 1; 1503 }); 1504 1505 _insertEase("Back", _configBack("in"), _configBack("out"), _configBack()); 1506 1507 _easeMap.SteppedEase = _easeMap.steps = _globals.SteppedEase = { 1508 config: function config(steps, immediateStart) { 1509 if (steps === void 0) { 1510 steps = 1; 1511 } 1512 1513 var p1 = 1 / steps, 1514 p2 = steps + (immediateStart ? 0 : 1), 1515 p3 = immediateStart ? 1 : 0, 1516 max = 1 - _tinyNum; 1517 return function (p) { 1518 return ((p2 * _clamp(0, max, p) | 0) + p3) * p1; 1519 }; 1520 } 1521 }; 1522 _defaults.ease = _easeMap["quad.out"]; 1523 1524 _forEachName("onComplete,onUpdate,onStart,onRepeat,onReverseComplete,onInterrupt", function (name) { 1525 return _callbackNames += name + "," + name + "Params,"; 1526 }); 1527 1528 var GSCache = function GSCache(target, harness) { 1529 this.id = _gsID++; 1530 target._gsap = this; 1531 this.target = target; 1532 this.harness = harness; 1533 this.get = harness ? harness.get : _getProperty; 1534 this.set = harness ? harness.getSetter : _getSetter; 1535 }; 1536 var Animation = function () { 1537 function Animation(vars) { 1538 this.vars = vars; 1539 this._delay = +vars.delay || 0; 1540 1541 if (this._repeat = vars.repeat === Infinity ? -2 : vars.repeat || 0) { 1542 this._rDelay = vars.repeatDelay || 0; 1543 this._yoyo = !!vars.yoyo || !!vars.yoyoEase; 1544 } 1545 1546 this._ts = 1; 1547 1548 _setDuration(this, +vars.duration, 1, 1); 1549 1550 this.data = vars.data; 1551 1552 if (_context) { 1553 this._ctx = _context; 1554 1555 _context.data.push(this); 1556 } 1557 1558 _tickerActive || _ticker.wake(); 1559 } 1560 1561 var _proto = Animation.prototype; 1562 1563 _proto.delay = function delay(value) { 1564 if (value || value === 0) { 1565 this.parent && this.parent.smoothChildTiming && this.startTime(this._start + value - this._delay); 1566 this._delay = value; 1567 return this; 1568 } 1569 1570 return this._delay; 1571 }; 1572 1573 _proto.duration = function duration(value) { 1574 return arguments.length ? this.totalDuration(this._repeat > 0 ? value + (value + this._rDelay) * this._repeat : value) : this.totalDuration() && this._dur; 1575 }; 1576 1577 _proto.totalDuration = function totalDuration(value) { 1578 if (!arguments.length) { 1579 return this._tDur; 1580 } 1581 1582 this._dirty = 0; 1583 return _setDuration(this, this._repeat < 0 ? value : (value - this._repeat * this._rDelay) / (this._repeat + 1)); 1584 }; 1585 1586 _proto.totalTime = function totalTime(_totalTime, suppressEvents) { 1587 _wake(); 1588 1589 if (!arguments.length) { 1590 return this._tTime; 1591 } 1592 1593 var parent = this._dp; 1594 1595 if (parent && parent.smoothChildTiming && this._ts) { 1596 _alignPlayhead(this, _totalTime); 1597 1598 !parent._dp || parent.parent || _postAddChecks(parent, this); 1599 1600 while (parent && parent.parent) { 1601 if (parent.parent._time !== parent._start + (parent._ts >= 0 ? parent._tTime / parent._ts : (parent.totalDuration() - parent._tTime) / -parent._ts)) { 1602 parent.totalTime(parent._tTime, true); 1603 } 1604 1605 parent = parent.parent; 1606 } 1607 1608 if (!this.parent && this._dp.autoRemoveChildren && (this._ts > 0 && _totalTime < this._tDur || this._ts < 0 && _totalTime > 0 || !this._tDur && !_totalTime)) { 1609 _addToTimeline(this._dp, this, this._start - this._delay); 1610 } 1611 } 1612 1613 if (this._tTime !== _totalTime || !this._dur && !suppressEvents || this._initted && Math.abs(this._zTime) === _tinyNum || !_totalTime && !this._initted && (this.add || this._ptLookup)) { 1614 this._ts || (this._pTime = _totalTime); 1615 1616 _lazySafeRender(this, _totalTime, suppressEvents); 1617 } 1618 1619 return this; 1620 }; 1621 1622 _proto.time = function time(value, suppressEvents) { 1623 return arguments.length ? this.totalTime(Math.min(this.totalDuration(), value + _elapsedCycleDuration(this)) % (this._dur + this._rDelay) || (value ? this._dur : 0), suppressEvents) : this._time; 1624 }; 1625 1626 _proto.totalProgress = function totalProgress(value, suppressEvents) { 1627 return arguments.length ? this.totalTime(this.totalDuration() * value, suppressEvents) : this.totalDuration() ? Math.min(1, this._tTime / this._tDur) : this.ratio; 1628 }; 1629 1630 _proto.progress = function progress(value, suppressEvents) { 1631 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; 1632 }; 1633 1634 _proto.iteration = function iteration(value, suppressEvents) { 1635 var cycleDuration = this.duration() + this._rDelay; 1636 1637 return arguments.length ? this.totalTime(this._time + (value - 1) * cycleDuration, suppressEvents) : this._repeat ? _animationCycle(this._tTime, cycleDuration) + 1 : 1; 1638 }; 1639 1640 _proto.timeScale = function timeScale(value) { 1641 if (!arguments.length) { 1642 return this._rts === -_tinyNum ? 0 : this._rts; 1643 } 1644 1645 if (this._rts === value) { 1646 return this; 1647 } 1648 1649 var tTime = this.parent && this._ts ? _parentToChildTotalTime(this.parent._time, this) : this._tTime; 1650 this._rts = +value || 0; 1651 this._ts = this._ps || value === -_tinyNum ? 0 : this._rts; 1652 this.totalTime(_clamp(-this._delay, this._tDur, tTime), true); 1653 1654 _setEnd(this); 1655 1656 return _recacheAncestors(this); 1657 }; 1658 1659 _proto.paused = function paused(value) { 1660 if (!arguments.length) { 1661 return this._ps; 1662 } 1663 1664 if (this._ps !== value) { 1665 this._ps = value; 1666 1667 if (value) { 1668 this._pTime = this._tTime || Math.max(-this._delay, this.rawTime()); 1669 this._ts = this._act = 0; 1670 } else { 1671 _wake(); 1672 1673 this._ts = this._rts; 1674 this.totalTime(this.parent && !this.parent.smoothChildTiming ? this.rawTime() : this._tTime || this._pTime, this.progress() === 1 && Math.abs(this._zTime) !== _tinyNum && (this._tTime -= _tinyNum)); 1675 } 1676 } 1677 1678 return this; 1679 }; 1680 1681 _proto.startTime = function startTime(value) { 1682 if (arguments.length) { 1683 this._start = value; 1684 var parent = this.parent || this._dp;
vendor: 3,424 bytes, lines 1685-1797
1685 parent && (parent._sort || !this.parent) && _addToTimeline(parent, this, value - this._delay); 1686 return this; 1687 } 1688 1689 return this._start; 1690 }; 1691 1692 _proto.endTime = function endTime(includeRepeats) { 1693 return this._start + (_isNotFalse(includeRepeats) ? this.totalDuration() : this.duration()) / Math.abs(this._ts || 1); 1694 }; 1695 1696 _proto.rawTime = function rawTime(wrapRepeats) { 1697 var parent = this.parent || this._dp; 1698 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); 1699 }; 1700 1701 _proto.revert = function revert(config) { 1702 if (config === void 0) { 1703 config = _revertConfig; 1704 } 1705 1706 var prevIsReverting = _reverting; 1707 _reverting = config; 1708 1709 if (this._initted || this._startAt) { 1710 this.timeline && this.timeline.revert(config); 1711 this.totalTime(-0.01, config.suppressEvents); 1712 } 1713 1714 this.data !== "nested" && config.kill !== false && this.kill(); 1715 _reverting = prevIsReverting; 1716 return this; 1717 }; 1718 1719 _proto.globalTime = function globalTime(rawTime) { 1720 var animation = this, 1721 time = arguments.length ? rawTime : animation.rawTime(); 1722 1723 while (animation) { 1724 time = animation._start + time / (animation._ts || 1); 1725 animation = animation._dp; 1726 } 1727 1728 return !this.parent && this.vars.immediateRender ? -1 : time; 1729 }; 1730 1731 _proto.repeat = function repeat(value) { 1732 if (arguments.length) { 1733 this._repeat = value === Infinity ? -2 : value; 1734 return _onUpdateTotalDuration(this); 1735 } 1736 1737 return this._repeat === -2 ? Infinity : this._repeat; 1738 }; 1739 1740 _proto.repeatDelay = function repeatDelay(value) { 1741 if (arguments.length) { 1742 var time = this._time; 1743 this._rDelay = value; 1744 1745 _onUpdateTotalDuration(this); 1746 1747 return time ? this.time(time) : this; 1748 } 1749 1750 return this._rDelay; 1751 }; 1752 1753 _proto.yoyo = function yoyo(value) { 1754 if (arguments.length) { 1755 this._yoyo = value; 1756 return this; 1757 } 1758 1759 return this._yoyo; 1760 }; 1761 1762 _proto.seek = function seek(position, suppressEvents) { 1763 return this.totalTime(_parsePosition(this, position), _isNotFalse(suppressEvents)); 1764 }; 1765 1766 _proto.restart = function restart(includeDelay, suppressEvents) { 1767 return this.play().totalTime(includeDelay ? -this._delay : 0, _isNotFalse(suppressEvents)); 1768 }; 1769 1770 _proto.play = function play(from, suppressEvents) { 1771 from != null && this.seek(from, suppressEvents); 1772 return this.reversed(false).paused(false); 1773 }; 1774 1775 _proto.reverse = function reverse(from, suppressEvents) { 1776 from != null && this.seek(from || this.totalDuration(), suppressEvents); 1777 return this.reversed(true).paused(false); 1778 }; 1779 1780 _proto.pause = function pause(atTime, suppressEvents) { 1781 atTime != null && this.seek(atTime, suppressEvents); 1782 return this.paused(true); 1783 }; 1784 1785 _proto.resume = function resume() { 1786 return this.paused(false); 1787 }; 1788 1789 _proto.reversed = function reversed(value) { 1790 if (arguments.length) { 1791 !!value !== this.reversed() && this.timeScale(-this._rts || (value ? -_tinyNum : 0)); 1792 return this; 1793 } 1794 1795 return this._rts < 0; 1796 }; 1797
vendor: 8,586 bytes, lines 1798-2069
1798 _proto.invalidate = function invalidate() { 1799 this._initted = this._act = 0; 1800 this._zTime = -_tinyNum; 1801 return this; 1802 }; 1803 1804 _proto.isActive = function isActive() { 1805 var parent = this.parent || this._dp, 1806 start = this._start, 1807 rawTime; 1808 return !!(!parent || this._ts && this._initted && parent.isActive() && (rawTime = parent.rawTime(true)) >= start && rawTime < this.endTime(true) - _tinyNum); 1809 }; 1810 1811 _proto.eventCallback = function eventCallback(type, callback, params) { 1812 var vars = this.vars; 1813 1814 if (arguments.length > 1) { 1815 if (!callback) { 1816 delete vars[type]; 1817 } else { 1818 vars[type] = callback; 1819 params && (vars[type + "Params"] = params); 1820 type === "onUpdate" && (this._onUpdate = callback); 1821 } 1822 1823 return this; 1824 } 1825 1826 return vars[type]; 1827 }; 1828 1829 _proto.then = function then(onFulfilled) { 1830 var self = this; 1831 return new Promise(function (resolve) { 1832 var f = _isFunction(onFulfilled) ? onFulfilled : _passThrough, 1833 _resolve = function _resolve() { 1834 var _then = self.then; 1835 self.then = null; 1836 _isFunction(f) && (f = f(self)) && (f.then || f === self) && (self.then = _then); 1837 resolve(f); 1838 self.then = _then; 1839 }; 1840 1841 if (self._initted && self.totalProgress() === 1 && self._ts >= 0 || !self._tTime && self._ts < 0) { 1842 _resolve(); 1843 } else { 1844 self._prom = _resolve; 1845 } 1846 }); 1847 }; 1848 1849 _proto.kill = function kill() { 1850 _interrupt(this); 1851 }; 1852 1853 return Animation; 1854 }(); 1855 1856 _setDefaults(Animation.prototype, { 1857 _time: 0, 1858 _start: 0, 1859 _end: 0, 1860 _tTime: 0, 1861 _tDur: 0, 1862 _dirty: 0, 1863 _repeat: 0, 1864 _yoyo: false, 1865 parent: null, 1866 _initted: false, 1867 _rDelay: 0, 1868 _ts: 1, 1869 _dp: 0, 1870 ratio: 0, 1871 _zTime: -_tinyNum, 1872 _prom: 0, 1873 _ps: false, 1874 _rts: 1 1875 }); 1876 1877 var Timeline = function (_Animation) { 1878 _inheritsLoose(Timeline, _Animation); 1879 1880 function Timeline(vars, position) { 1881 var _this; 1882 1883 if (vars === void 0) { 1884 vars = {}; 1885 } 1886 1887 _this = _Animation.call(this, vars) || this; 1888 _this.labels = {}; 1889 _this.smoothChildTiming = !!vars.smoothChildTiming; 1890 _this.autoRemoveChildren = !!vars.autoRemoveChildren; 1891 _this._sort = _isNotFalse(vars.sortChildren); 1892 _globalTimeline && _addToTimeline(vars.parent || _globalTimeline, _assertThisInitialized(_this), position); 1893 vars.reversed && _this.reverse(); 1894 vars.paused && _this.paused(true); 1895 vars.scrollTrigger && _scrollTrigger(_assertThisInitialized(_this), vars.scrollTrigger); 1896 return _this; 1897 } 1898 1899 var _proto2 = Timeline.prototype; 1900 1901 _proto2.to = function to(targets, vars, position) { 1902 _createTweenType(0, arguments, this); 1903 1904 return this; 1905 }; 1906 1907 _proto2.from = function from(targets, vars, position) { 1908 _createTweenType(1, arguments, this); 1909 1910 return this; 1911 }; 1912 1913 _proto2.fromTo = function fromTo(targets, fromVars, toVars, position) { 1914 _createTweenType(2, arguments, this); 1915 1916 return this; 1917 }; 1918 1919 _proto2.set = function set(targets, vars, position) { 1920 vars.duration = 0; 1921 vars.parent = this; 1922 _inheritDefaults(vars).repeatDelay || (vars.repeat = 0); 1923 vars.immediateRender = !!vars.immediateRender; 1924 new Tween(targets, vars, _parsePosition(this, position), 1); 1925 return this; 1926 }; 1927 1928 _proto2.call = function call(callback, params, position) { 1929 return _addToTimeline(this, Tween.delayedCall(0, callback, params), position); 1930 }; 1931 1932 _proto2.staggerTo = function staggerTo(targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams) { 1933 vars.duration = duration; 1934 vars.stagger = vars.stagger || stagger; 1935 vars.onComplete = onCompleteAll; 1936 vars.onCompleteParams = onCompleteAllParams; 1937 vars.parent = this; 1938 new Tween(targets, vars, _parsePosition(this, position)); 1939 return this; 1940 }; 1941 1942 _proto2.staggerFrom = function staggerFrom(targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams) { 1943 vars.runBackwards = 1; 1944 _inheritDefaults(vars).immediateRender = _isNotFalse(vars.immediateRender); 1945 return this.staggerTo(targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams); 1946 }; 1947 1948 _proto2.staggerFromTo = function staggerFromTo(targets, duration, fromVars, toVars, stagger, position, onCompleteAll, onCompleteAllParams) { 1949 toVars.startAt = fromVars; 1950 _inheritDefaults(toVars).immediateRender = _isNotFalse(toVars.immediateRender); 1951 return this.staggerTo(targets, duration, toVars, stagger, position, onCompleteAll, onCompleteAllParams); 1952 }; 1953 1954 _proto2.render = function render(totalTime, suppressEvents, force) { 1955 var prevTime = this._time, 1956 tDur = this._dirty ? this.totalDuration() : this._tDur, 1957 dur = this._dur, 1958 tTime = totalTime <= 0 ? 0 : _roundPrecise(totalTime), 1959 crossingStart = this._zTime < 0 !== totalTime < 0 && (this._initted || !dur), 1960 time, 1961 child, 1962 next, 1963 iteration, 1964 cycleDuration, 1965 prevPaused, 1966 pauseTween, 1967 timeScale, 1968 prevStart, 1969 prevIteration, 1970 yoyo, 1971 isYoyo; 1972 this !== _globalTimeline && tTime > tDur && totalTime >= 0 && (tTime = tDur); 1973 1974 if (tTime !== this._tTime || force || crossingStart) { 1975 if (prevTime !== this._time && dur) { 1976 tTime += this._time - prevTime; 1977 totalTime += this._time - prevTime; 1978 } 1979 1980 time = tTime; 1981 prevStart = this._start; 1982 timeScale = this._ts; 1983 prevPaused = !timeScale; 1984 1985 if (crossingStart) { 1986 dur || (prevTime = this._zTime); 1987 (totalTime || !suppressEvents) && (this._zTime = totalTime); 1988 } 1989 1990 if (this._repeat) { 1991 yoyo = this._yoyo; 1992 cycleDuration = dur + this._rDelay; 1993 1994 if (this._repeat < -1 && totalTime < 0) { 1995 return this.totalTime(cycleDuration * 100 + totalTime, suppressEvents, force); 1996 } 1997 1998 time = _roundPrecise(tTime % cycleDuration); 1999 2000 if (tTime === tDur) { 2001 iteration = this._repeat; 2002 time = dur; 2003 } else { 2004 iteration = ~~(tTime / cycleDuration); 2005 2006 if (iteration && iteration === tTime / cycleDuration) { 2007 time = dur; 2008 iteration--; 2009 } 2010 2011 time > dur && (time = dur); 2012 } 2013 2014 prevIteration = _animationCycle(this._tTime, cycleDuration); 2015 !prevTime && this._tTime && prevIteration !== iteration && (prevIteration = iteration); 2016 2017 if (yoyo && iteration & 1) { 2018 time = dur - time; 2019 isYoyo = 1; 2020 } 2021 2022 if (iteration !== prevIteration && !this._lock) { 2023 var rewinding = yoyo && prevIteration & 1, 2024 doesWrap = rewinding === (yoyo && iteration & 1); 2025 iteration < prevIteration && (rewinding = !rewinding); 2026 prevTime = rewinding ? 0 : dur; 2027 this._lock = 1; 2028 this.render(prevTime || (isYoyo ? 0 : _roundPrecise(iteration * cycleDuration)), suppressEvents, !dur)._lock = 0; 2029 this._tTime = tTime; 2030 !suppressEvents && this.parent && _callback(this, "onRepeat"); 2031 this.vars.repeatRefresh && !isYoyo && (this.invalidate()._lock = 1); 2032 2033 if (prevTime && prevTime !== this._time || prevPaused !== !this._ts || this.vars.onRepeat && !this.parent && !this._act) { 2034 return this; 2035 } 2036 2037 dur = this._dur; 2038 tDur = this._tDur; 2039 2040 if (doesWrap) { 2041 this._lock = 2; 2042 prevTime = rewinding ? dur : -0.0001; 2043 this.render(prevTime, true); 2044 this.vars.repeatRefresh && !isYoyo && this.invalidate(); 2045 } 2046 2047 this._lock = 0; 2048 2049 if (!this._ts && !prevPaused) { 2050 return this; 2051 } 2052 2053 _propagateYoyoEase(this, isYoyo); 2054 } 2055 } 2056 2057 if (this._hasPause && !this._forcing && this._lock < 2) { 2058 pauseTween = _findNextPauseTween(this, _roundPrecise(prevTime), _roundPrecise(time)); 2059 2060 if (pauseTween) { 2061 tTime -= time - (time = pauseTween._start); 2062 } 2063 } 2064 2065 this._tTime = tTime; 2066 this._time = time; 2067 this._act = !timeScale; 2068 2069 if (!this._initted) {
vendor: 15,188 bytes, lines 2070-2602
2070 this._onUpdate = this.vars.onUpdate; 2071 this._initted = 1; 2072 this._zTime = totalTime; 2073 prevTime = 0; 2074 } 2075 2076 if (!prevTime && time && !suppressEvents) { 2077 _callback(this, "onStart"); 2078 2079 if (this._tTime !== tTime) { 2080 return this; 2081 } 2082 } 2083 2084 if (time >= prevTime && totalTime >= 0) { 2085 child = this._first; 2086 2087 while (child) { 2088 next = child._next; 2089 2090 if ((child._act || time >= child._start) && child._ts && pauseTween !== child) { 2091 if (child.parent !== this) { 2092 return this.render(totalTime, suppressEvents, force); 2093 } 2094 2095 child.render(child._ts > 0 ? (time - child._start) * child._ts : (child._dirty ? child.totalDuration() : child._tDur) + (time - child._start) * child._ts, suppressEvents, force); 2096 2097 if (time !== this._time || !this._ts && !prevPaused) { 2098 pauseTween = 0; 2099 next && (tTime += this._zTime = -_tinyNum); 2100 break; 2101 } 2102 } 2103 2104 child = next; 2105 } 2106 } else { 2107 child = this._last; 2108 var adjustedTime = totalTime < 0 ? totalTime : time; 2109 2110 while (child) { 2111 next = child._prev; 2112 2113 if ((child._act || adjustedTime <= child._end) && child._ts && pauseTween !== child) { 2114 if (child.parent !== this) { 2115 return this.render(totalTime, suppressEvents, force); 2116 } 2117 2118 child.render(child._ts > 0 ? (adjustedTime - child._start) * child._ts : (child._dirty ? child.totalDuration() : child._tDur) + (adjustedTime - child._start) * child._ts, suppressEvents, force || _reverting && (child._initted || child._startAt)); 2119 2120 if (time !== this._time || !this._ts && !prevPaused) { 2121 pauseTween = 0; 2122 next && (tTime += this._zTime = adjustedTime ? -_tinyNum : _tinyNum); 2123 break; 2124 } 2125 } 2126 2127 child = next; 2128 } 2129 } 2130 2131 if (pauseTween && !suppressEvents) { 2132 this.pause(); 2133 pauseTween.render(time >= prevTime ? 0 : -_tinyNum)._zTime = time >= prevTime ? 1 : -1; 2134 2135 if (this._ts) { 2136 this._start = prevStart; 2137 2138 _setEnd(this); 2139 2140 return this.render(totalTime, suppressEvents, force); 2141 } 2142 } 2143 2144 this._onUpdate && !suppressEvents && _callback(this, "onUpdate", true); 2145 if (tTime === tDur && this._tTime >= this.totalDuration() || !tTime && prevTime) if (prevStart === this._start || Math.abs(timeScale) !== Math.abs(this._ts)) if (!this._lock) { 2146 (totalTime || !dur) && (tTime === tDur && this._ts > 0 || !tTime && this._ts < 0) && _removeFromParent(this, 1); 2147 2148 if (!suppressEvents && !(totalTime < 0 && !prevTime) && (tTime || prevTime || !tDur)) { 2149 _callback(this, tTime === tDur && totalTime >= 0 ? "onComplete" : "onReverseComplete", true); 2150 2151 this._prom && !(tTime < tDur && this.timeScale() > 0) && this._prom(); 2152 } 2153 } 2154 } 2155 2156 return this; 2157 }; 2158 2159 _proto2.add = function add(child, position) { 2160 var _this2 = this; 2161 2162 _isNumber(position) || (position = _parsePosition(this, position, child)); 2163 2164 if (!(child instanceof Animation)) { 2165 if (_isArray(child)) { 2166 child.forEach(function (obj) { 2167 return _this2.add(obj, position); 2168 }); 2169 return this; 2170 } 2171 2172 if (_isString(child)) { 2173 return this.addLabel(child, position); 2174 } 2175 2176 if (_isFunction(child)) { 2177 child = Tween.delayedCall(0, child); 2178 } else { 2179 return this; 2180 } 2181 } 2182 2183 return this !== child ? _addToTimeline(this, child, position) : this; 2184 }; 2185 2186 _proto2.getChildren = function getChildren(nested, tweens, timelines, ignoreBeforeTime) { 2187 if (nested === void 0) { 2188 nested = true; 2189 } 2190 2191 if (tweens === void 0) { 2192 tweens = true; 2193 } 2194 2195 if (timelines === void 0) { 2196 timelines = true; 2197 } 2198 2199 if (ignoreBeforeTime === void 0) { 2200 ignoreBeforeTime = -_bigNum; 2201 } 2202 2203 var a = [], 2204 child = this._first; 2205 2206 while (child) { 2207 if (child._start >= ignoreBeforeTime) { 2208 if (child instanceof Tween) { 2209 tweens && a.push(child); 2210 } else { 2211 timelines && a.push(child); 2212 nested && a.push.apply(a, child.getChildren(true, tweens, timelines)); 2213 } 2214 } 2215 2216 child = child._next; 2217 } 2218 2219 return a; 2220 }; 2221 2222 _proto2.getById = function getById(id) { 2223 var animations = this.getChildren(1, 1, 1), 2224 i = animations.length; 2225 2226 while (i--) { 2227 if (animations[i].vars.id === id) { 2228 return animations[i]; 2229 } 2230 } 2231 }; 2232 2233 _proto2.remove = function remove(child) { 2234 if (_isString(child)) { 2235 return this.removeLabel(child); 2236 } 2237 2238 if (_isFunction(child)) { 2239 return this.killTweensOf(child); 2240 } 2241 2242 _removeLinkedListItem(this, child); 2243 2244 if (child === this._recent) { 2245 this._recent = this._last; 2246 } 2247 2248 return _uncache(this); 2249 }; 2250 2251 _proto2.totalTime = function totalTime(_totalTime2, suppressEvents) { 2252 if (!arguments.length) { 2253 return this._tTime; 2254 } 2255 2256 this._forcing = 1; 2257 2258 if (!this._dp && this._ts) { 2259 this._start = _roundPrecise(_ticker.time - (this._ts > 0 ? _totalTime2 / this._ts : (this.totalDuration() - _totalTime2) / -this._ts)); 2260 } 2261 2262 _Animation.prototype.totalTime.call(this, _totalTime2, suppressEvents); 2263 2264 this._forcing = 0; 2265 return this; 2266 }; 2267 2268 _proto2.addLabel = function addLabel(label, position) { 2269 this.labels[label] = _parsePosition(this, position); 2270 return this; 2271 }; 2272 2273 _proto2.removeLabel = function removeLabel(label) { 2274 delete this.labels[label]; 2275 return this; 2276 }; 2277 2278 _proto2.addPause = function addPause(position, callback, params) { 2279 var t = Tween.delayedCall(0, callback || _emptyFunc, params); 2280 t.data = "isPause"; 2281 this._hasPause = 1; 2282 return _addToTimeline(this, t, _parsePosition(this, position)); 2283 }; 2284 2285 _proto2.removePause = function removePause(position) { 2286 var child = this._first; 2287 position = _parsePosition(this, position); 2288 2289 while (child) { 2290 if (child._start === position && child.data === "isPause") { 2291 _removeFromParent(child); 2292 } 2293 2294 child = child._next; 2295 } 2296 }; 2297 2298 _proto2.killTweensOf = function killTweensOf(targets, props, onlyActive) { 2299 var tweens = this.getTweensOf(targets, onlyActive), 2300 i = tweens.length; 2301 2302 while (i--) { 2303 _overwritingTween !== tweens[i] && tweens[i].kill(targets, props); 2304 } 2305 2306 return this; 2307 }; 2308 2309 _proto2.getTweensOf = function getTweensOf(targets, onlyActive) { 2310 var a = [], 2311 parsedTargets = toArray(targets), 2312 child = this._first, 2313 isGlobalTime = _isNumber(onlyActive), 2314 children; 2315 2316 while (child) { 2317 if (child instanceof Tween) { 2318 if (_arrayContainsAny(child._targets, parsedTargets) && (isGlobalTime ? (!_overwritingTween || child._initted && child._ts) && child.globalTime(0) <= onlyActive && child.globalTime(child.totalDuration()) > onlyActive : !onlyActive || child.isActive())) { 2319 a.push(child); 2320 } 2321 } else if ((children = child.getTweensOf(parsedTargets, onlyActive)).length) { 2322 a.push.apply(a, children); 2323 } 2324 2325 child = child._next; 2326 } 2327 2328 return a; 2329 }; 2330 2331 _proto2.tweenTo = function tweenTo(position, vars) { 2332 vars = vars || {}; 2333 2334 var tl = this, 2335 endTime = _parsePosition(tl, position), 2336 _vars = vars, 2337 startAt = _vars.startAt, 2338 _onStart = _vars.onStart, 2339 onStartParams = _vars.onStartParams, 2340 immediateRender = _vars.immediateRender, 2341 initted, 2342 tween = Tween.to(tl, _setDefaults({ 2343 ease: vars.ease || "none", 2344 lazy: false, 2345 immediateRender: false, 2346 time: endTime, 2347 overwrite: "auto", 2348 duration: vars.duration || Math.abs((endTime - (startAt && "time" in startAt ? startAt.time : tl._time)) / tl.timeScale()) || _tinyNum, 2349 onStart: function onStart() { 2350 tl.pause(); 2351 2352 if (!initted) { 2353 var duration = vars.duration || Math.abs((endTime - (startAt && "time" in startAt ? startAt.time : tl._time)) / tl.timeScale()); 2354 tween._dur !== duration && _setDuration(tween, duration, 0, 1).render(tween._time, true, true); 2355 initted = 1; 2356 } 2357 2358 _onStart && _onStart.apply(tween, onStartParams || []); 2359 } 2360 }, vars)); 2361 2362 return immediateRender ? tween.render(0) : tween; 2363 }; 2364 2365 _proto2.tweenFromTo = function tweenFromTo(fromPosition, toPosition, vars) { 2366 return this.tweenTo(toPosition, _setDefaults({ 2367 startAt: { 2368 time: _parsePosition(this, fromPosition) 2369 } 2370 }, vars)); 2371 }; 2372 2373 _proto2.recent = function recent() { 2374 return this._recent; 2375 }; 2376 2377 _proto2.nextLabel = function nextLabel(afterTime) { 2378 if (afterTime === void 0) { 2379 afterTime = this._time; 2380 } 2381 2382 return _getLabelInDirection(this, _parsePosition(this, afterTime)); 2383 }; 2384 2385 _proto2.previousLabel = function previousLabel(beforeTime) { 2386 if (beforeTime === void 0) { 2387 beforeTime = this._time; 2388 } 2389 2390 return _getLabelInDirection(this, _parsePosition(this, beforeTime), 1); 2391 }; 2392 2393 _proto2.currentLabel = function currentLabel(value) { 2394 return arguments.length ? this.seek(value, true) : this.previousLabel(this._time + _tinyNum); 2395 }; 2396 2397 _proto2.shiftChildren = function shiftChildren(amount, adjustLabels, ignoreBeforeTime) { 2398 if (ignoreBeforeTime === void 0) { 2399 ignoreBeforeTime = 0; 2400 } 2401 2402 var child = this._first, 2403 labels = this.labels, 2404 p; 2405 2406 while (child) { 2407 if (child._start >= ignoreBeforeTime) { 2408 child._start += amount; 2409 child._end += amount; 2410 } 2411 2412 child = child._next; 2413 } 2414 2415 if (adjustLabels) { 2416 for (p in labels) { 2417 if (labels[p] >= ignoreBeforeTime) { 2418 labels[p] += amount; 2419 } 2420 } 2421 } 2422 2423 return _uncache(this); 2424 }; 2425 2426 _proto2.invalidate = function invalidate(soft) { 2427 var child = this._first; 2428 this._lock = 0; 2429 2430 while (child) { 2431 child.invalidate(soft); 2432 child = child._next; 2433 } 2434 2435 return _Animation.prototype.invalidate.call(this, soft); 2436 }; 2437 2438 _proto2.clear = function clear(includeLabels) { 2439 if (includeLabels === void 0) { 2440 includeLabels = true; 2441 } 2442 2443 var child = this._first, 2444 next; 2445 2446 while (child) { 2447 next = child._next; 2448 this.remove(child); 2449 child = next; 2450 } 2451 2452 this._dp && (this._time = this._tTime = this._pTime = 0); 2453 includeLabels && (this.labels = {}); 2454 return _uncache(this); 2455 }; 2456 2457 _proto2.totalDuration = function totalDuration(value) { 2458 var max = 0, 2459 self = this, 2460 child = self._last, 2461 prevStart = _bigNum, 2462 prev, 2463 start, 2464 parent; 2465 2466 if (arguments.length) { 2467 return self.timeScale((self._repeat < 0 ? self.duration() : self.totalDuration()) / (self.reversed() ? -value : value)); 2468 } 2469 2470 if (self._dirty) { 2471 parent = self.parent; 2472 2473 while (child) { 2474 prev = child._prev; 2475 child._dirty && child.totalDuration(); 2476 start = child._start; 2477 2478 if (start > prevStart && self._sort && child._ts && !self._lock) { 2479 self._lock = 1; 2480 _addToTimeline(self, child, start - child._delay, 1)._lock = 0; 2481 } else { 2482 prevStart = start; 2483 } 2484 2485 if (start < 0 && child._ts) { 2486 max -= start; 2487 2488 if (!parent && !self._dp || parent && parent.smoothChildTiming) { 2489 self._start += start / self._ts; 2490 self._time -= start; 2491 self._tTime -= start; 2492 } 2493 2494 self.shiftChildren(-start, false, -1e999); 2495 prevStart = 0; 2496 } 2497 2498 child._end > max && child._ts && (max = child._end); 2499 child = prev; 2500 } 2501 2502 _setDuration(self, self === _globalTimeline && self._time > max ? self._time : max, 1, 1); 2503 2504 self._dirty = 0; 2505 } 2506 2507 return self._tDur; 2508 }; 2509 2510 Timeline.updateRoot = function updateRoot(time) { 2511 if (_globalTimeline._ts) { 2512 _lazySafeRender(_globalTimeline, _parentToChildTotalTime(time, _globalTimeline)); 2513 2514 _lastRenderedFrame = _ticker.frame; 2515 } 2516 2517 if (_ticker.frame >= _nextGCFrame) { 2518 _nextGCFrame += _config.autoSleep || 120; 2519 var child = _globalTimeline._first; 2520 if (!child || !child._ts) if (_config.autoSleep && _ticker._listeners.length < 2) { 2521 while (child && !child._ts) { 2522 child = child._next; 2523 } 2524 2525 child || _ticker.sleep(); 2526 } 2527 } 2528 }; 2529 2530 return Timeline; 2531 }(Animation); 2532 2533 _setDefaults(Timeline.prototype, { 2534 _lock: 0, 2535 _hasPause: 0, 2536 _forcing: 0 2537 }); 2538 2539 var _addComplexStringPropTween = function _addComplexStringPropTween(target, prop, start, end, setter, stringFilter, funcParam) { 2540 var pt = new PropTween(this._pt, target, prop, 0, 1, _renderComplexString, null, setter), 2541 index = 0, 2542 matchIndex = 0, 2543 result, 2544 startNums, 2545 color, 2546 endNum, 2547 chunk, 2548 startNum, 2549 hasRandom, 2550 a; 2551 pt.b = start; 2552 pt.e = end; 2553 start += ""; 2554 end += ""; 2555 2556 if (hasRandom = ~end.indexOf("random(")) { 2557 end = _replaceRandom(end); 2558 } 2559 2560 if (stringFilter) { 2561 a = [start, end]; 2562 stringFilter(a, target, prop); 2563 start = a[0]; 2564 end = a[1]; 2565 } 2566 2567 startNums = start.match(_complexStringNumExp) || []; 2568 2569 while (result = _complexStringNumExp.exec(end)) { 2570 endNum = result[0]; 2571 chunk = end.substring(index, result.index); 2572 2573 if (color) { 2574 color = (color + 1) % 5; 2575 } else if (chunk.substr(-5) === "rgba(") { 2576 color = 1; 2577 } 2578 2579 if (endNum !== startNums[matchIndex++]) { 2580 startNum = parseFloat(startNums[matchIndex - 1]) || 0; 2581 pt._pt = { 2582 _next: pt._pt, 2583 p: chunk || matchIndex === 1 ? chunk : ",", 2584 s: startNum, 2585 c: endNum.charAt(1) === "=" ? _parseRelative(startNum, endNum) - startNum : parseFloat(endNum) - startNum, 2586 m: color && color < 4 ? Math.round : 0 2587 }; 2588 index = _complexStringNumExp.lastIndex; 2589 } 2590 } 2591 2592 pt.c = index < end.length ? end.substring(index, end.length) : ""; 2593 pt.fp = funcParam; 2594 2595 if (_relExp.test(end) || hasRandom) { 2596 pt.e = 0; 2597 } 2598 2599 this._pt = pt; 2600 return pt; 2601 }, 2602 _addPropTween = function _addPropTween(target, prop, start, end, index, targets, modifier, stringFilter, funcParam, optional) {
vendor: 9,749 bytes, lines 2603-2889
2603 _isFunction(end) && (end = end(index || 0, target, targets)); 2604 var currentValue = target[prop], 2605 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](), 2606 setter = !_isFunction(currentValue) ? _setterPlain : funcParam ? _setterFuncWithParam : _setterFunc, 2607 pt; 2608 2609 if (_isString(end)) { 2610 if (~end.indexOf("random(")) { 2611 end = _replaceRandom(end); 2612 } 2613 2614 if (end.charAt(1) === "=") { 2615 pt = _parseRelative(parsedStart, end) + (getUnit(parsedStart) || 0); 2616 2617 if (pt || pt === 0) { 2618 end = pt; 2619 } 2620 } 2621 } 2622 2623 if (!optional || parsedStart !== end || _forceAllPropTweens) { 2624 if (!isNaN(parsedStart * end) && end !== "") { 2625 pt = new PropTween(this._pt, target, prop, +parsedStart || 0, end - (parsedStart || 0), typeof currentValue === "boolean" ? _renderBoolean : _renderPlain, 0, setter); 2626 funcParam && (pt.fp = funcParam); 2627 modifier && pt.modifier(modifier, this, target); 2628 return this._pt = pt; 2629 } 2630 2631 !currentValue && !(prop in target) && _missingPlugin(prop, end); 2632 return _addComplexStringPropTween.call(this, target, prop, parsedStart, end, setter, stringFilter || _config.stringFilter, funcParam); 2633 } 2634 }, 2635 _processVars = function _processVars(vars, index, target, targets, tween) { 2636 _isFunction(vars) && (vars = _parseFuncOrString(vars, tween, index, target, targets)); 2637 2638 if (!_isObject(vars) || vars.style && vars.nodeType || _isArray(vars) || _isTypedArray(vars)) { 2639 return _isString(vars) ? _parseFuncOrString(vars, tween, index, target, targets) : vars; 2640 } 2641 2642 var copy = {}, 2643 p; 2644 2645 for (p in vars) { 2646 copy[p] = _parseFuncOrString(vars[p], tween, index, target, targets); 2647 } 2648 2649 return copy; 2650 }, 2651 _checkPlugin = function _checkPlugin(property, vars, tween, index, target, targets) { 2652 var plugin, pt, ptLookup, i; 2653 2654 if (_plugins[property] && (plugin = new _plugins[property]()).init(target, plugin.rawVars ? vars[property] : _processVars(vars[property], index, target, targets, tween), tween, index, targets) !== false) { 2655 tween._pt = pt = new PropTween(tween._pt, target, property, 0, 1, plugin.render, plugin, 0, plugin.priority); 2656 2657 if (tween !== _quickTween) { 2658 ptLookup = tween._ptLookup[tween._targets.indexOf(target)]; 2659 i = plugin._props.length; 2660 2661 while (i--) { 2662 ptLookup[plugin._props[i]] = pt; 2663 } 2664 } 2665 } 2666 2667 return plugin; 2668 }, 2669 _overwritingTween, 2670 _forceAllPropTweens, 2671 _initTween = function _initTween(tween, time, tTime) { 2672 var vars = tween.vars, 2673 ease = vars.ease, 2674 startAt = vars.startAt, 2675 immediateRender = vars.immediateRender, 2676 lazy = vars.lazy, 2677 onUpdate = vars.onUpdate, 2678 onUpdateParams = vars.onUpdateParams, 2679 callbackScope = vars.callbackScope, 2680 runBackwards = vars.runBackwards, 2681 yoyoEase = vars.yoyoEase, 2682 keyframes = vars.keyframes, 2683 autoRevert = vars.autoRevert, 2684 dur = tween._dur, 2685 prevStartAt = tween._startAt, 2686 targets = tween._targets, 2687 parent = tween.parent, 2688 fullTargets = parent && parent.data === "nested" ? parent.vars.targets : targets, 2689 autoOverwrite = tween._overwrite === "auto" && !_suppressOverwrites, 2690 tl = tween.timeline, 2691 cleanVars, 2692 i, 2693 p, 2694 pt, 2695 target, 2696 hasPriority, 2697 gsData, 2698 harness, 2699 plugin, 2700 ptLookup, 2701 index, 2702 harnessVars, 2703 overwritten; 2704 tl && (!keyframes || !ease) && (ease = "none"); 2705 tween._ease = _parseEase(ease, _defaults.ease); 2706 tween._yEase = yoyoEase ? _invertEase(_parseEase(yoyoEase === true ? ease : yoyoEase, _defaults.ease)) : 0; 2707 2708 if (yoyoEase && tween._yoyo && !tween._repeat) { 2709 yoyoEase = tween._yEase; 2710 tween._yEase = tween._ease; 2711 tween._ease = yoyoEase; 2712 } 2713 2714 tween._from = !tl && !!vars.runBackwards; 2715 2716 if (!tl || keyframes && !vars.stagger) { 2717 harness = targets[0] ? _getCache(targets[0]).harness : 0; 2718 harnessVars = harness && vars[harness.prop]; 2719 cleanVars = _copyExcluding(vars, _reservedProps); 2720 2721 if (prevStartAt) { 2722 prevStartAt._zTime < 0 && prevStartAt.progress(1); 2723 time < 0 && runBackwards && immediateRender && !autoRevert ? prevStartAt.render(-1, true) : prevStartAt.revert(runBackwards && dur ? _revertConfigNoKill : _startAtRevertConfig); 2724 prevStartAt._lazy = 0; 2725 } 2726 2727 if (startAt) { 2728 _removeFromParent(tween._startAt = Tween.set(targets, _setDefaults({ 2729 data: "isStart", 2730 overwrite: false, 2731 parent: parent, 2732 immediateRender: true, 2733 lazy: _isNotFalse(lazy), 2734 startAt: null, 2735 delay: 0, 2736 onUpdate: onUpdate, 2737 onUpdateParams: onUpdateParams, 2738 callbackScope: callbackScope, 2739 stagger: 0 2740 }, startAt))); 2741 2742 tween._startAt._dp = 0; 2743 time < 0 && (_reverting || !immediateRender && !autoRevert) && tween._startAt.revert(_revertConfigNoKill); 2744 2745 if (immediateRender) { 2746 if (dur && time <= 0 && tTime <= 0) { 2747 time && (tween._zTime = time); 2748 return; 2749 } 2750 } 2751 } else if (runBackwards && dur) { 2752 if (!prevStartAt) { 2753 time && (immediateRender = false); 2754 p = _setDefaults({ 2755 overwrite: false, 2756 data: "isFromStart", 2757 lazy: immediateRender && _isNotFalse(lazy), 2758 immediateRender: immediateRender, 2759 stagger: 0, 2760 parent: parent 2761 }, cleanVars); 2762 harnessVars && (p[harness.prop] = harnessVars); 2763 2764 _removeFromParent(tween._startAt = Tween.set(targets, p)); 2765 2766 tween._startAt._dp = 0; 2767 time < 0 && (_reverting ? tween._startAt.revert(_revertConfigNoKill) : tween._startAt.render(-1, true)); 2768 tween._zTime = time; 2769 2770 if (!immediateRender) { 2771 _initTween(tween._startAt, _tinyNum, _tinyNum); 2772 } else if (!time) { 2773 return; 2774 } 2775 } 2776 } 2777 2778 tween._pt = tween._ptCache = 0; 2779 lazy = dur && _isNotFalse(lazy) || lazy && !dur; 2780 2781 for (i = 0; i < targets.length; i++) { 2782 target = targets[i]; 2783 gsData = target._gsap || _harness(targets)[i]._gsap; 2784 tween._ptLookup[i] = ptLookup = {}; 2785 _lazyLookup[gsData.id] && _lazyTweens.length && _lazyRender(); 2786 index = fullTargets === targets ? i : fullTargets.indexOf(target); 2787 2788 if (harness && (plugin = new harness()).init(target, harnessVars || cleanVars, tween, index, fullTargets) !== false) { 2789 tween._pt = pt = new PropTween(tween._pt, target, plugin.name, 0, 1, plugin.render, plugin, 0, plugin.priority); 2790 2791 plugin._props.forEach(function (name) { 2792 ptLookup[name] = pt; 2793 }); 2794 2795 plugin.priority && (hasPriority = 1); 2796 } 2797 2798 if (!harness || harnessVars) { 2799 for (p in cleanVars) { 2800 if (_plugins[p] && (plugin = _checkPlugin(p, cleanVars, tween, index, target, fullTargets))) { 2801 plugin.priority && (hasPriority = 1); 2802 } else { 2803 ptLookup[p] = pt = _addPropTween.call(tween, target, p, "get", cleanVars[p], index, fullTargets, 0, vars.stringFilter); 2804 } 2805 } 2806 } 2807 2808 tween._op && tween._op[i] && tween.kill(target, tween._op[i]); 2809 2810 if (autoOverwrite && tween._pt) { 2811 _overwritingTween = tween; 2812 2813 _globalTimeline.killTweensOf(target, ptLookup, tween.globalTime(time)); 2814 2815 overwritten = !tween.parent; 2816 _overwritingTween = 0; 2817 } 2818 2819 tween._pt && lazy && (_lazyLookup[gsData.id] = 1); 2820 } 2821 2822 hasPriority && _sortPropTweensByPriority(tween); 2823 tween._onInit && tween._onInit(tween); 2824 } 2825 2826 tween._onUpdate = onUpdate; 2827 tween._initted = (!tween._op || tween._pt) && !overwritten; 2828 keyframes && time <= 0 && tl.render(_bigNum, true, true); 2829 }, 2830 _updatePropTweens = function _updatePropTweens(tween, property, value, start, startIsRelative, ratio, time) { 2831 var ptCache = (tween._pt && tween._ptCache || (tween._ptCache = {}))[property], 2832 pt, 2833 rootPT, 2834 lookup, 2835 i; 2836 2837 if (!ptCache) { 2838 ptCache = tween._ptCache[property] = []; 2839 lookup = tween._ptLookup; 2840 i = tween._targets.length; 2841 2842 while (i--) { 2843 pt = lookup[i][property]; 2844 2845 if (pt && pt.d && pt.d._pt) { 2846 pt = pt.d._pt; 2847 2848 while (pt && pt.p !== property && pt.fp !== property) { 2849 pt = pt._next; 2850 } 2851 } 2852 2853 if (!pt) { 2854 _forceAllPropTweens = 1; 2855 tween.vars[property] = "+=0"; 2856 2857 _initTween(tween, time); 2858 2859 _forceAllPropTweens = 0; 2860 return 1; 2861 } 2862 2863 ptCache.push(pt); 2864 } 2865 } 2866 2867 i = ptCache.length; 2868 2869 while (i--) { 2870 rootPT = ptCache[i]; 2871 pt = rootPT._pt || rootPT; 2872 pt.s = (start || start === 0) && !startIsRelative ? start : pt.s + (start || 0) + ratio * pt.c; 2873 pt.c = value - pt.s; 2874 rootPT.e && (rootPT.e = _round(value) + getUnit(rootPT.e)); 2875 rootPT.b && (rootPT.b = pt.s + getUnit(rootPT.b)); 2876 } 2877 }, 2878 _addAliasesToVars = function _addAliasesToVars(targets, vars) { 2879 var harness = targets[0] ? _getCache(targets[0]).harness : 0, 2880 propertyAliases = harness && harness.aliases, 2881 copy, 2882 p, 2883 i, 2884 aliases; 2885 2886 if (!propertyAliases) { 2887 return vars; 2888 } 2889
vendor: 4,989 bytes, lines 2890-3032
2890 copy = _merge({}, vars); 2891 2892 for (p in propertyAliases) { 2893 if (p in copy) { 2894 aliases = propertyAliases[p].split(","); 2895 i = aliases.length; 2896 2897 while (i--) { 2898 copy[aliases[i]] = copy[p]; 2899 } 2900 } 2901 } 2902 2903 return copy; 2904 }, 2905 _parseKeyframe = function _parseKeyframe(prop, obj, allProps, easeEach) { 2906 var ease = obj.ease || easeEach || "power1.inOut", 2907 p, 2908 a; 2909 2910 if (_isArray(obj)) { 2911 a = allProps[prop] || (allProps[prop] = []); 2912 obj.forEach(function (value, i) { 2913 return a.push({ 2914 t: i / (obj.length - 1) * 100, 2915 v: value, 2916 e: ease 2917 }); 2918 }); 2919 } else { 2920 for (p in obj) { 2921 a = allProps[p] || (allProps[p] = []); 2922 p === "ease" || a.push({ 2923 t: parseFloat(prop), 2924 v: obj[p], 2925 e: ease 2926 }); 2927 } 2928 } 2929 }, 2930 _parseFuncOrString = function _parseFuncOrString(value, tween, i, target, targets) { 2931 return _isFunction(value) ? value.call(tween, i, target, targets) : _isString(value) && ~value.indexOf("random(") ? _replaceRandom(value) : value; 2932 }, 2933 _staggerTweenProps = _callbackNames + "repeat,repeatDelay,yoyo,repeatRefresh,yoyoEase,autoRevert", 2934 _staggerPropsToSkip = {}; 2935 2936 _forEachName(_staggerTweenProps + ",id,stagger,delay,duration,paused,scrollTrigger", function (name) { 2937 return _staggerPropsToSkip[name] = 1; 2938 }); 2939 2940 var Tween = function (_Animation2) { 2941 _inheritsLoose(Tween, _Animation2); 2942 2943 function Tween(targets, vars, position, skipInherit) { 2944 var _this3; 2945 2946 if (typeof vars === "number") { 2947 position.duration = vars; 2948 vars = position; 2949 position = null; 2950 } 2951 2952 _this3 = _Animation2.call(this, skipInherit ? vars : _inheritDefaults(vars)) || this; 2953 var _this3$vars = _this3.vars, 2954 duration = _this3$vars.duration, 2955 delay = _this3$vars.delay, 2956 immediateRender = _this3$vars.immediateRender, 2957 stagger = _this3$vars.stagger, 2958 overwrite = _this3$vars.overwrite, 2959 keyframes = _this3$vars.keyframes, 2960 defaults = _this3$vars.defaults, 2961 scrollTrigger = _this3$vars.scrollTrigger, 2962 yoyoEase = _this3$vars.yoyoEase, 2963 parent = vars.parent || _globalTimeline, 2964 parsedTargets = (_isArray(targets) || _isTypedArray(targets) ? _isNumber(targets[0]) : "length" in vars) ? [targets] : toArray(targets), 2965 tl, 2966 i, 2967 copy, 2968 l, 2969 p, 2970 curTarget, 2971 staggerFunc, 2972 staggerVarsToMerge; 2973 _this3._targets = parsedTargets.length ? _harness(parsedTargets) : _warn("GSAP target " + targets + " not found. https://greensock.com", !_config.nullTargetWarn) || []; 2974 _this3._ptLookup = []; 2975 _this3._overwrite = overwrite; 2976 2977 if (keyframes || stagger || _isFuncOrString(duration) || _isFuncOrString(delay)) { 2978 vars = _this3.vars; 2979 tl = _this3.timeline = new Timeline({ 2980 data: "nested", 2981 defaults: defaults || {}, 2982 targets: parent && parent.data === "nested" ? parent.vars.targets : parsedTargets 2983 }); 2984 tl.kill(); 2985 tl.parent = tl._dp = _assertThisInitialized(_this3); 2986 tl._start = 0; 2987 2988 if (stagger || _isFuncOrString(duration) || _isFuncOrString(delay)) { 2989 l = parsedTargets.length; 2990 staggerFunc = stagger && distribute(stagger); 2991 2992 if (_isObject(stagger)) { 2993 for (p in stagger) { 2994 if (~_staggerTweenProps.indexOf(p)) { 2995 staggerVarsToMerge || (staggerVarsToMerge = {}); 2996 staggerVarsToMerge[p] = stagger[p]; 2997 } 2998 } 2999 } 3000 3001 for (i = 0; i < l; i++) { 3002 copy = _copyExcluding(vars, _staggerPropsToSkip); 3003 copy.stagger = 0; 3004 yoyoEase && (copy.yoyoEase = yoyoEase); 3005 staggerVarsToMerge && _merge(copy, staggerVarsToMerge); 3006 curTarget = parsedTargets[i]; 3007 copy.duration = +_parseFuncOrString(duration, _assertThisInitialized(_this3), i, curTarget, parsedTargets); 3008 copy.delay = (+_parseFuncOrString(delay, _assertThisInitialized(_this3), i, curTarget, parsedTargets) || 0) - _this3._delay; 3009 3010 if (!stagger && l === 1 && copy.delay) { 3011 _this3._delay = delay = copy.delay; 3012 _this3._start += delay; 3013 copy.delay = 0; 3014 } 3015 3016 tl.to(curTarget, copy, staggerFunc ? staggerFunc(i, curTarget, parsedTargets) : 0); 3017 tl._ease = _easeMap.none; 3018 } 3019 3020 tl.duration() ? duration = delay = 0 : _this3.timeline = 0; 3021 } else if (keyframes) { 3022 _inheritDefaults(_setDefaults(tl.vars.defaults, { 3023 ease: "none" 3024 })); 3025 3026 tl._ease = _parseEase(keyframes.ease || vars.ease || "none"); 3027 var time = 0, 3028 a, 3029 kf, 3030 v; 3031 3032 if (_isArray(keyframes)) {
vendor: 6,328 bytes, lines 3033-3239
3033 keyframes.forEach(function (frame) { 3034 return tl.to(parsedTargets, frame, ">"); 3035 }); 3036 tl.duration(); 3037 } else { 3038 copy = {}; 3039 3040 for (p in keyframes) { 3041 p === "ease" || p === "easeEach" || _parseKeyframe(p, keyframes[p], copy, keyframes.easeEach); 3042 } 3043 3044 for (p in copy) { 3045 a = copy[p].sort(function (a, b) { 3046 return a.t - b.t; 3047 }); 3048 time = 0; 3049 3050 for (i = 0; i < a.length; i++) { 3051 kf = a[i]; 3052 v = { 3053 ease: kf.e, 3054 duration: (kf.t - (i ? a[i - 1].t : 0)) / 100 * duration 3055 }; 3056 v[p] = kf.v; 3057 tl.to(parsedTargets, v, time); 3058 time += v.duration; 3059 } 3060 } 3061 3062 tl.duration() < duration && tl.to({}, { 3063 duration: duration - tl.duration() 3064 }); 3065 } 3066 } 3067 3068 duration || _this3.duration(duration = tl.duration()); 3069 } else { 3070 _this3.timeline = 0; 3071 } 3072 3073 if (overwrite === true && !_suppressOverwrites) { 3074 _overwritingTween = _assertThisInitialized(_this3); 3075 3076 _globalTimeline.killTweensOf(parsedTargets); 3077 3078 _overwritingTween = 0; 3079 } 3080 3081 _addToTimeline(parent, _assertThisInitialized(_this3), position); 3082 3083 vars.reversed && _this3.reverse(); 3084 vars.paused && _this3.paused(true); 3085 3086 if (immediateRender || !duration && !keyframes && _this3._start === _roundPrecise(parent._time) && _isNotFalse(immediateRender) && _hasNoPausedAncestors(_assertThisInitialized(_this3)) && parent.data !== "nested") { 3087 _this3._tTime = -_tinyNum; 3088 3089 _this3.render(Math.max(0, -delay) || 0); 3090 } 3091 3092 scrollTrigger && _scrollTrigger(_assertThisInitialized(_this3), scrollTrigger); 3093 return _this3; 3094 } 3095 3096 var _proto3 = Tween.prototype; 3097 3098 _proto3.render = function render(totalTime, suppressEvents, force) { 3099 var prevTime = this._time, 3100 tDur = this._tDur, 3101 dur = this._dur, 3102 isNegative = totalTime < 0, 3103 tTime = totalTime > tDur - _tinyNum && !isNegative ? tDur : totalTime < _tinyNum ? 0 : totalTime, 3104 time, 3105 pt, 3106 iteration, 3107 cycleDuration, 3108 prevIteration, 3109 isYoyo, 3110 ratio, 3111 timeline, 3112 yoyoEase; 3113 3114 if (!dur) { 3115 _renderZeroDurationTween(this, totalTime, suppressEvents, force); 3116 } else if (tTime !== this._tTime || !totalTime || force || !this._initted && this._tTime || this._startAt && this._zTime < 0 !== isNegative) { 3117 time = tTime; 3118 timeline = this.timeline; 3119 3120 if (this._repeat) { 3121 cycleDuration = dur + this._rDelay; 3122 3123 if (this._repeat < -1 && isNegative) { 3124 return this.totalTime(cycleDuration * 100 + totalTime, suppressEvents, force); 3125 } 3126 3127 time = _roundPrecise(tTime % cycleDuration); 3128 3129 if (tTime === tDur) { 3130 iteration = this._repeat; 3131 time = dur; 3132 } else { 3133 iteration = ~~(tTime / cycleDuration); 3134 3135 if (iteration && iteration === tTime / cycleDuration) { 3136 time = dur; 3137 iteration--; 3138 } 3139 3140 time > dur && (time = dur); 3141 } 3142 3143 isYoyo = this._yoyo && iteration & 1; 3144 3145 if (isYoyo) { 3146 yoyoEase = this._yEase; 3147 time = dur - time; 3148 } 3149 3150 prevIteration = _animationCycle(this._tTime, cycleDuration); 3151 3152 if (time === prevTime && !force && this._initted) { 3153 this._tTime = tTime; 3154 return this; 3155 } 3156 3157 if (iteration !== prevIteration) { 3158 timeline && this._yEase && _propagateYoyoEase(timeline, isYoyo); 3159 3160 if (this.vars.repeatRefresh && !isYoyo && !this._lock) { 3161 this._lock = force = 1; 3162 this.render(_roundPrecise(cycleDuration * iteration), true).invalidate()._lock = 0; 3163 } 3164 } 3165 } 3166 3167 if (!this._initted) { 3168 if (_attemptInitTween(this, isNegative ? totalTime : time, force, suppressEvents, tTime)) { 3169 this._tTime = 0; 3170 return this; 3171 } 3172 3173 if (prevTime !== this._time) { 3174 return this; 3175 } 3176 3177 if (dur !== this._dur) { 3178 return this.render(totalTime, suppressEvents, force); 3179 } 3180 } 3181 3182 this._tTime = tTime; 3183 this._time = time; 3184 3185 if (!this._act && this._ts) { 3186 this._act = 1; 3187 this._lazy = 0; 3188 } 3189 3190 this.ratio = ratio = (yoyoEase || this._ease)(time / dur); 3191 3192 if (this._from) { 3193 this.ratio = ratio = 1 - ratio; 3194 } 3195 3196 if (time && !prevTime && !suppressEvents) { 3197 _callback(this, "onStart"); 3198 3199 if (this._tTime !== tTime) { 3200 return this; 3201 } 3202 } 3203 3204 pt = this._pt; 3205 3206 while (pt) { 3207 pt.r(ratio, pt.d); 3208 pt = pt._next; 3209 } 3210 3211 timeline && timeline.render(totalTime < 0 ? totalTime : !time && isYoyo ? -_tinyNum : timeline._dur * timeline._ease(time / this._dur), suppressEvents, force) || this._startAt && (this._zTime = totalTime); 3212 3213 if (this._onUpdate && !suppressEvents) { 3214 isNegative && _rewindStartAt(this, totalTime, suppressEvents, force); 3215 3216 _callback(this, "onUpdate"); 3217 } 3218 3219 this._repeat && iteration !== prevIteration && this.vars.onRepeat && !suppressEvents && this.parent && _callback(this, "onRepeat"); 3220 3221 if ((tTime === this._tDur || !tTime) && this._tTime === tTime) { 3222 isNegative && !this._onUpdate && _rewindStartAt(this, totalTime, true, true); 3223 (totalTime || !dur) && (tTime === this._tDur && this._ts > 0 || !tTime && this._ts < 0) && _removeFromParent(this, 1); 3224 3225 if (!suppressEvents && !(isNegative && !prevTime) && (tTime || prevTime || isYoyo)) { 3226 _callback(this, tTime === tDur ? "onComplete" : "onReverseComplete", true); 3227 3228 this._prom && !(tTime < tDur && this.timeScale() > 0) && this._prom(); 3229 } 3230 } 3231 } 3232 3233 return this; 3234 }; 3235 3236 _proto3.targets = function targets() { 3237 return this._targets; 3238 }; 3239
vendor: 1,277 bytes, lines 3240-3273
3240 _proto3.invalidate = function invalidate(soft) { 3241 (!soft || !this.vars.runBackwards) && (this._startAt = 0); 3242 this._pt = this._op = this._onUpdate = this._lazy = this.ratio = 0; 3243 this._ptLookup = []; 3244 this.timeline && this.timeline.invalidate(soft); 3245 return _Animation2.prototype.invalidate.call(this, soft); 3246 }; 3247 3248 _proto3.resetTo = function resetTo(property, value, start, startIsRelative) { 3249 _tickerActive || _ticker.wake(); 3250 this._ts || this.play(); 3251 var time = Math.min(this._dur, (this._dp._time - this._start) * this._ts), 3252 ratio; 3253 this._initted || _initTween(this, time); 3254 ratio = this._ease(time / this._dur); 3255 3256 if (_updatePropTweens(this, property, value, start, startIsRelative, ratio, time)) { 3257 return this.resetTo(property, value, start, startIsRelative); 3258 } 3259 3260 _alignPlayhead(this, 0); 3261 3262 this.parent || _addLinkedListItem(this._dp, this, "_first", "_last", this._dp._sort ? "_start" : 0); 3263 return this.render(0); 3264 }; 3265 3266 _proto3.kill = function kill(targets, vars) { 3267 if (vars === void 0) { 3268 vars = "all"; 3269 } 3270 3271 if (!targets && (!vars || vars === "all")) { 3272 this._lazy = this._pt = 0; 3273 return this.parent ? _interrupt(this) :
vendor: 7,709 bytes, lines 3273-3553
3273 this; 3274 } 3275 3276 if (this.timeline) { 3277 var tDur = this.timeline.totalDuration(); 3278 this.timeline.killTweensOf(targets, vars, _overwritingTween && _overwritingTween.vars.overwrite !== true)._first || _interrupt(this); 3279 this.parent && tDur !== this.timeline.totalDuration() && _setDuration(this, this._dur * this.timeline._tDur / tDur, 0, 1); 3280 return this; 3281 } 3282 3283 var parsedTargets = this._targets, 3284 killingTargets = targets ? toArray(targets) : parsedTargets, 3285 propTweenLookup = this._ptLookup, 3286 firstPT = this._pt, 3287 overwrittenProps, 3288 curLookup, 3289 curOverwriteProps, 3290 props, 3291 p, 3292 pt, 3293 i; 3294 3295 if ((!vars || vars === "all") && _arraysMatch(parsedTargets, killingTargets)) { 3296 vars === "all" && (this._pt = 0); 3297 return _interrupt(this); 3298 } 3299 3300 overwrittenProps = this._op = this._op || []; 3301 3302 if (vars !== "all") { 3303 if (_isString(vars)) { 3304 p = {}; 3305 3306 _forEachName(vars, function (name) { 3307 return p[name] = 1; 3308 }); 3309 3310 vars = p; 3311 } 3312 3313 vars = _addAliasesToVars(parsedTargets, vars); 3314 } 3315 3316 i = parsedTargets.length; 3317 3318 while (i--) { 3319 if (~killingTargets.indexOf(parsedTargets[i])) { 3320 curLookup = propTweenLookup[i]; 3321 3322 if (vars === "all") { 3323 overwrittenProps[i] = vars; 3324 props = curLookup; 3325 curOverwriteProps = {}; 3326 } else { 3327 curOverwriteProps = overwrittenProps[i] = overwrittenProps[i] || {}; 3328 props = vars; 3329 } 3330 3331 for (p in props) { 3332 pt = curLookup && curLookup[p]; 3333 3334 if (pt) { 3335 if (!("kill" in pt.d) || pt.d.kill(p) === true) { 3336 _removeLinkedListItem(this, pt, "_pt"); 3337 } 3338 3339 delete curLookup[p]; 3340 } 3341 3342 if (curOverwriteProps !== "all") { 3343 curOverwriteProps[p] = 1; 3344 } 3345 } 3346 } 3347 } 3348 3349 this._initted && !this._pt && firstPT && _interrupt(this); 3350 return this; 3351 }; 3352 3353 Tween.to = function to(targets, vars) { 3354 return new Tween(targets, vars, arguments[2]); 3355 }; 3356 3357 Tween.from = function from(targets, vars) { 3358 return _createTweenType(1, arguments); 3359 }; 3360 3361 Tween.delayedCall = function delayedCall(delay, callback, params, scope) { 3362 return new Tween(callback, 0, { 3363 immediateRender: false, 3364 lazy: false, 3365 overwrite: false, 3366 delay: delay, 3367 onComplete: callback, 3368 onReverseComplete: callback, 3369 onCompleteParams: params, 3370 onReverseCompleteParams: params, 3371 callbackScope: scope 3372 }); 3373 }; 3374 3375 Tween.fromTo = function fromTo(targets, fromVars, toVars) { 3376 return _createTweenType(2, arguments); 3377 }; 3378 3379 Tween.set = function set(targets, vars) { 3380 vars.duration = 0; 3381 vars.repeatDelay || (vars.repeat = 0); 3382 return new Tween(targets, vars); 3383 }; 3384 3385 Tween.killTweensOf = function killTweensOf(targets, props, onlyActive) { 3386 return _globalTimeline.killTweensOf(targets, props, onlyActive); 3387 }; 3388 3389 return Tween; 3390 }(Animation); 3391 3392 _setDefaults(Tween.prototype, { 3393 _targets: [], 3394 _lazy: 0, 3395 _startAt: 0, 3396 _op: 0, 3397 _onInit: 0 3398 }); 3399 3400 _forEachName("staggerTo,staggerFrom,staggerFromTo", function (name) { 3401 Tween[name] = function () { 3402 var tl = new Timeline(), 3403 params = _slice.call(arguments, 0); 3404 3405 params.splice(name === "staggerFromTo" ? 5 : 4, 0, 0); 3406 return tl[name].apply(tl, params); 3407 }; 3408 }); 3409 3410 var _setterPlain = function _setterPlain(target, property, value) { 3411 return target[property] = value; 3412 }, 3413 _setterFunc = function _setterFunc(target, property, value) { 3414 return target[property](value); 3415 }, 3416 _setterFuncWithParam = function _setterFuncWithParam(target, property, value, data) { 3417 return target[property](data.fp, value); 3418 }, 3419 _setterAttribute = function _setterAttribute(target, property, value) { 3420 return target.setAttribute(property, value); 3421 }, 3422 _getSetter = function _getSetter(target, property) { 3423 return _isFunction(target[property]) ? _setterFunc : _isUndefined(target[property]) && target.setAttribute ? _setterAttribute : _setterPlain; 3424 }, 3425 _renderPlain = function _renderPlain(ratio, data) { 3426 return data.set(data.t, data.p, Math.round((data.s + data.c * ratio) * 1000000) / 1000000, data); 3427 }, 3428 _renderBoolean = function _renderBoolean(ratio, data) { 3429 return data.set(data.t, data.p, !!(data.s + data.c * ratio), data); 3430 }, 3431 _renderComplexString = function _renderComplexString(ratio, data) { 3432 var pt = data._pt, 3433 s = ""; 3434 3435 if (!ratio && data.b) { 3436 s = data.b; 3437 } else if (ratio === 1 && data.e) { 3438 s = data.e; 3439 } else { 3440 while (pt) { 3441 s = pt.p + (pt.m ? pt.m(pt.s + pt.c * ratio) : Math.round((pt.s + pt.c * ratio) * 10000) / 10000) + s; 3442 pt = pt._next; 3443 } 3444 3445 s += data.c; 3446 } 3447 3448 data.set(data.t, data.p, s, data); 3449 }, 3450 _renderPropTweens = function _renderPropTweens(ratio, data) { 3451 var pt = data._pt; 3452 3453 while (pt) { 3454 pt.r(ratio, pt.d); 3455 pt = pt._next; 3456 } 3457 }, 3458 _addPluginModifier = function _addPluginModifier(modifier, tween, target, property) { 3459 var pt = this._pt, 3460 next; 3461 3462 while (pt) { 3463 next = pt._next; 3464 pt.p === property && pt.modifier(modifier, tween, target); 3465 pt = next; 3466 } 3467 }, 3468 _killPropTweensOf = function _killPropTweensOf(property) { 3469 var pt = this._pt, 3470 hasNonDependentRemaining, 3471 next; 3472 3473 while (pt) { 3474 next = pt._next; 3475 3476 if (pt.p === property && !pt.op || pt.op === property) { 3477 _removeLinkedListItem(this, pt, "_pt"); 3478 } else if (!pt.dep) { 3479 hasNonDependentRemaining = 1; 3480 } 3481 3482 pt = next; 3483 } 3484 3485 return !hasNonDependentRemaining; 3486 }, 3487 _setterWithModifier = function _setterWithModifier(target, property, value, data) { 3488 data.mSet(target, property, data.m.call(data.tween, value, data.mt), data); 3489 }, 3490 _sortPropTweensByPriority = function _sortPropTweensByPriority(parent) { 3491 var pt = parent._pt, 3492 next, 3493 pt2, 3494 first, 3495 last; 3496 3497 while (pt) { 3498 next = pt._next; 3499 pt2 = first; 3500 3501 while (pt2 && pt2.pr > pt.pr) { 3502 pt2 = pt2._next; 3503 } 3504 3505 if (pt._prev = pt2 ? pt2._prev : last) { 3506 pt._prev._next = pt; 3507 } else { 3508 first = pt; 3509 } 3510 3511 if (pt._next = pt2) { 3512 pt2._prev = pt; 3513 } else { 3514 last = pt; 3515 } 3516 3517 pt = next; 3518 } 3519 3520 parent._pt = first; 3521 }; 3522 3523 var PropTween = function () { 3524 function PropTween(next, target, prop, start, change, renderer, data, setter, priority) { 3525 this.t = target; 3526 this.s = start; 3527 this.c = change; 3528 this.p = prop; 3529 this.r = renderer || _renderPlain; 3530 this.d = data || this; 3531 this.set = setter || _setterPlain; 3532 this.pr = priority || 0; 3533 this._next = next; 3534 3535 if (next) { 3536 next._prev = this; 3537 } 3538 } 3539 3540 var _proto4 = PropTween.prototype; 3541 3542 _proto4.modifier = function modifier(func, tween, target) { 3543 this.mSet = this.mSet || this.set; 3544 this.set = _setterWithModifier; 3545 this.m = func; 3546 this.mt = target; 3547 this.tween = tween; 3548 }; 3549 3550 return PropTween; 3551 }(); 3552 3553 _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
vendor: 3,674 bytes, lines 3553-3696
3553", function (name) { 3554 return _reservedProps[name] = 1; 3555 }); 3556 3557 _globals.TweenMax = _globals.TweenLite = Tween; 3558 _globals.TimelineLite = _globals.TimelineMax = Timeline; 3559 _globalTimeline = new Timeline({ 3560 sortChildren: false, 3561 defaults: _defaults, 3562 autoRemoveChildren: true, 3563 id: "root", 3564 smoothChildTiming: true 3565 }); 3566 _config.stringFilter = _colorStringFilter; 3567 3568 var _media = [], 3569 _listeners = {}, 3570 _emptyArray = [], 3571 _lastMediaTime = 0, 3572 _dispatch = function _dispatch(type) { 3573 return (_listeners[type] || _emptyArray).map(function (f) { 3574 return f(); 3575 }); 3576 }, 3577 _onMediaChange = function _onMediaChange() { 3578 var time = Date.now(), 3579 matches = []; 3580 3581 if (time - _lastMediaTime > 2) { 3582 _dispatch("matchMediaInit"); 3583 3584 _media.forEach(function (c) { 3585 var queries = c.queries, 3586 conditions = c.conditions, 3587 match, 3588 p, 3589 anyMatch, 3590 toggled; 3591 3592 for (p in queries) { 3593 match = _win.matchMedia(queries[p]).matches; 3594 match && (anyMatch = 1); 3595 3596 if (match !== conditions[p]) { 3597 conditions[p] = match; 3598 toggled = 1; 3599 } 3600 } 3601 3602 if (toggled) { 3603 c.revert(); 3604 anyMatch && matches.push(c); 3605 } 3606 }); 3607 3608 _dispatch("matchMediaRevert"); 3609 3610 matches.forEach(function (c) { 3611 return c.onMatch(c); 3612 }); 3613 _lastMediaTime = time; 3614 3615 _dispatch("matchMedia"); 3616 } 3617 }; 3618 3619 var Context = function () { 3620 function Context(func, scope) { 3621 this.selector = scope && selector(scope); 3622 this.data = []; 3623 this._r = []; 3624 this.isReverted = false; 3625 func && this.add(func); 3626 } 3627 3628 var _proto5 = Context.prototype; 3629 3630 _proto5.add = function add(name, func, scope) { 3631 if (_isFunction(name)) { 3632 scope = func; 3633 func = name; 3634 name = _isFunction; 3635 } 3636 3637 var self = this, 3638 f = function f() { 3639 var prev = _context, 3640 prevSelector = self.selector, 3641 result; 3642 prev && prev !== self && prev.data.push(self); 3643 scope && (self.selector = selector(scope)); 3644 _context = self; 3645 result = func.apply(self, arguments); 3646 _isFunction(result) && self._r.push(result); 3647 _context = prev; 3648 self.selector = prevSelector; 3649 self.isReverted = false; 3650 return result; 3651 }; 3652 3653 self.last = f; 3654 return name === _isFunction ? f(self) : name ? self[name] = f : f; 3655 }; 3656 3657 _proto5.ignore = function ignore(func) { 3658 var prev = _context; 3659 _context = null; 3660 func(this); 3661 _context = prev; 3662 }; 3663 3664 _proto5.getTweens = function getTweens() { 3665 var a = []; 3666 this.data.forEach(function (e) { 3667 return e instanceof Context ? a.push.apply(a, e.getTweens()) : e instanceof Tween && !(e.parent && e.parent.data === "nested") && a.push(e); 3668 }); 3669 return a; 3670 }; 3671 3672 _proto5.clear = function clear() { 3673 this._r.length = this.data.length = 0; 3674 }; 3675 3676 _proto5.kill = function kill(revert, matchMedia) { 3677 var _this4 = this; 3678 3679 if (revert) { 3680 var tweens = this.getTweens(); 3681 this.data.forEach(function (t) { 3682 if (t.data === "isFlip") { 3683 t.revert(); 3684 t.getChildren(true, true, false).forEach(function (tween) { 3685 return tweens.splice(tweens.indexOf(tween), 1); 3686 }); 3687 } 3688 }); 3689 tweens.map(function (t) { 3690 return { 3691 g: t.globalTime(0), 3692 t: t 3693 }; 3694 }).sort(function (a, b) { 3695 return b.g - a.g || -1; 3696 }
3696).forEach(function (o) { 3697 return o.t.revert(revert); 3698 }); 3699 this.data.forEach(function (e) { 3700 return !(e instanceof Animation) && e.revert && e.revert(revert); 3701 }); 3702 3703 this._r.forEach(function (f) { 3704 return f(revert, _this4); 3705 }); 3706 3707 this.isReverted = true; 3708 } else { 3709 this.data.forEach(function (e) { 3710 return e.kill && e.kill(); 3711 }); 3712 } 3713 3714 this.clear(); 3715 3716 if (matchMedia) { 3717 var i = _media.indexOf(this); 3718 3719 !!~i && _media.splice(i, 1); 3720 } 3721 }; 3722 3723 _proto5.revert = function revert(config) { 3724 this.kill(config || {}); 3725 }; 3726 3727 return Context; 3728 }(); 3729 3730 var MatchMedia = function () { 3731 function MatchMedia(scope) { 3732 this.contexts = []; 3733 this.scope = scope; 3734 } 3735 3736 var _proto6 = MatchMedia.prototype; 3737 3738 _proto6.add = function add(conditions, func, scope) { 3739 _isObject(conditions) || (conditions = { 3740 matches: conditions 3741 }); 3742 var context = new Context(0, scope || this.scope), 3743 cond = context.conditions = {}, 3744 mq, 3745 p, 3746 active; 3747 this.contexts.push(context); 3748 func = context.add("onMatch", func); 3749 context.queries = conditions; 3750 3751 for (p in conditions) { 3752 if (p === "all") { 3753 active = 1; 3754 } else { 3755 mq = _win.matchMedia(conditions[p]); 3756 3757 if (mq) { 3758 _media.indexOf(context) < 0 && _media.push(context); 3759 (cond[p] = mq.matches) && (active = 1); 3760 mq.addListener ? mq.addListener(_onMediaChange) : mq.addEventListener("change", _onMediaChange); 3761 } 3762 } 3763 } 3764 3765 active && func(context); 3766 return this; 3767 }; 3768 3769 _proto6.revert = function revert(config) { 3770 this.kill(config || {}); 3771 }; 3772 3773 _proto6.kill = function kill(revert) {
vendor: 2,486 bytes, lines 3774-3846
3774 this.contexts.forEach(function (c) { 3775 return c.kill(revert, true); 3776 }); 3777 }; 3778 3779 return MatchMedia; 3780 }(); 3781 3782 var _gsap = { 3783 registerPlugin: function registerPlugin() { 3784 for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { 3785 args[_key2] = arguments[_key2]; 3786 } 3787 3788 args.forEach(function (config) { 3789 return _createPlugin(config); 3790 }); 3791 }, 3792 timeline: function timeline(vars) { 3793 return new Timeline(vars); 3794 }, 3795 getTweensOf: function getTweensOf(targets, onlyActive) { 3796 return _globalTimeline.getTweensOf(targets, onlyActive); 3797 }, 3798 getProperty: function getProperty(target, property, unit, uncache) { 3799 _isString(target) && (target = toArray(target)[0]); 3800 3801 var getter = _getCache(target || {}).get, 3802 format = unit ? _passThrough : _numericIfPossible; 3803 3804 unit === "native" && (unit = ""); 3805 return !target ? target : !property ? function (property, unit, uncache) { 3806 return format((_plugins[property] && _plugins[property].get || getter)(target, property, unit, uncache)); 3807 } : format((_plugins[property] && _plugins[property].get || getter)(target, property, unit, uncache)); 3808 }, 3809 quickSetter: function quickSetter(target, property, unit) { 3810 target = toArray(target); 3811 3812 if (target.length > 1) { 3813 var setters = target.map(function (t) { 3814 return gsap.quickSetter(t, property, unit); 3815 }), 3816 l = setters.length; 3817 return function (value) { 3818 var i = l; 3819 3820 while (i--) { 3821 setters[i](value); 3822 } 3823 }; 3824 } 3825 3826 target = target[0] || {}; 3827 3828 var Plugin = _plugins[property], 3829 cache = _getCache(target), 3830 p = cache.harness && (cache.harness.aliases || {})[property] || property, 3831 setter = Plugin ? function (value) { 3832 var p = new Plugin(); 3833 _quickTween._pt = 0; 3834 p.init(target, unit ? value + unit : value, _quickTween, 0, [target]); 3835 p.render(1, p); 3836 _quickTween._pt && _renderPropTweens(1, _quickTween); 3837 } : cache.set(target, p); 3838 3839 return Plugin ? setter : function (value) { 3840 return setter(target, p, unit ? value + unit : value, cache, 1); 3841 }; 3842 }, 3843 quickTo: function quickTo(target, property, vars) { 3844 var _merge2; 3845 3846 var tween = gsap.to(target, _merge((_merge2 = {}, _merge2[property] = "+=0.1", _merge2.paused = true, _merge
vendor: 5,649 bytes, lines 3846-4048
38462), vars || {})), 3847 func = function func(value, start, startIsRelative) { 3848 return tween.resetTo(property, value, start, startIsRelative); 3849 }; 3850 3851 func.tween = tween; 3852 return func; 3853 }, 3854 isTweening: function isTweening(targets) { 3855 return _globalTimeline.getTweensOf(targets, true).length > 0; 3856 }, 3857 defaults: function defaults(value) { 3858 value && value.ease && (value.ease = _parseEase(value.ease, _defaults.ease)); 3859 return _mergeDeep(_defaults, value || {}); 3860 }, 3861 config: function config(value) { 3862 return _mergeDeep(_config, value || {}); 3863 }, 3864 registerEffect: function registerEffect(_ref3) { 3865 var name = _ref3.name, 3866 effect = _ref3.effect, 3867 plugins = _ref3.plugins, 3868 defaults = _ref3.defaults, 3869 extendTimeline = _ref3.extendTimeline; 3870 (plugins || "").split(",").forEach(function (pluginName) { 3871 return pluginName && !_plugins[pluginName] && !_globals[pluginName] && _warn(name + " effect requires " + pluginName + " plugin."); 3872 }); 3873 3874 _effects[name] = function (targets, vars, tl) { 3875 return effect(toArray(targets), _setDefaults(vars || {}, defaults), tl); 3876 }; 3877 3878 if (extendTimeline) { 3879 Timeline.prototype[name] = function (targets, vars, position) { 3880 return this.add(_effects[name](targets, _isObject(vars) ? vars : (position = vars) && {}, this), position); 3881 }; 3882 } 3883 }, 3884 registerEase: function registerEase(name, ease) { 3885 _easeMap[name] = _parseEase(ease); 3886 }, 3887 parseEase: function parseEase(ease, defaultEase) { 3888 return arguments.length ? _parseEase(ease, defaultEase) : _easeMap; 3889 }, 3890 getById: function getById(id) { 3891 return _globalTimeline.getById(id); 3892 }, 3893 exportRoot: function exportRoot(vars, includeDelayedCalls) { 3894 if (vars === void 0) { 3895 vars = {}; 3896 } 3897 3898 var tl = new Timeline(vars), 3899 child, 3900 next; 3901 tl.smoothChildTiming = _isNotFalse(vars.smoothChildTiming); 3902 3903 _globalTimeline.remove(tl); 3904 3905 tl._dp = 0; 3906 tl._time = tl._tTime = _globalTimeline._time; 3907 child = _globalTimeline._first; 3908 3909 while (child) { 3910 next = child._next; 3911 3912 if (includeDelayedCalls || !(!child._dur && child instanceof Tween && child.vars.onComplete === child._targets[0])) { 3913 _addToTimeline(tl, child, child._start - child._delay); 3914 } 3915 3916 child = next; 3917 } 3918 3919 _addToTimeline(_globalTimeline, tl, 0); 3920 3921 return tl; 3922 }, 3923 context: function context(func, scope) { 3924 return func ? new Context(func, scope) : _context; 3925 }, 3926 matchMedia: function matchMedia(scope) { 3927 return new MatchMedia(scope); 3928 }, 3929 matchMediaRefresh: function matchMediaRefresh() { 3930 return _media.forEach(function (c) { 3931 var cond = c.conditions, 3932 found, 3933 p; 3934 3935 for (p in cond) { 3936 if (cond[p]) { 3937 cond[p] = false; 3938 found = 1; 3939 } 3940 } 3941 3942 found && c.revert(); 3943 }) || _onMediaChange(); 3944 }, 3945 addEventListener: function addEventListener(type, callback) { 3946 var a = _listeners[type] || (_listeners[type] = []); 3947 ~a.indexOf(callback) || a.push(callback); 3948 }, 3949 removeEventListener: function removeEventListener(type, callback) { 3950 var a = _listeners[type], 3951 i = a && a.indexOf(callback); 3952 i >= 0 && a.splice(i, 1); 3953 }, 3954 utils: { 3955 wrap: wrap, 3956 wrapYoyo: wrapYoyo, 3957 distribute: distribute, 3958 random: random, 3959 snap: snap, 3960 normalize: normalize, 3961 getUnit: getUnit, 3962 clamp: clamp, 3963 splitColor: splitColor, 3964 toArray: toArray, 3965 selector: selector, 3966 mapRange: mapRange, 3967 pipe: pipe, 3968 unitize: unitize, 3969 interpolate: interpolate, 3970 shuffle: shuffle 3971 }, 3972 install: _install, 3973 effects: _effects, 3974 ticker: _ticker, 3975 updateRoot: Timeline.updateRoot, 3976 plugins: _plugins, 3977 globalTimeline: _globalTimeline, 3978 core: { 3979 PropTween: PropTween, 3980 globals: _addGlobal, 3981 Tween: Tween, 3982 Timeline: Timeline, 3983 Animation: Animation, 3984 getCache: _getCache, 3985 _removeLinkedListItem: _removeLinkedListItem, 3986 reverting: function reverting() { 3987 return _reverting; 3988 }, 3989 context: function context(toAdd) { 3990 if (toAdd && _context) { 3991 _context.data.push(toAdd); 3992 3993 toAdd._ctx = _context; 3994 } 3995 3996 return _context; 3997 }, 3998 suppressOverwrites: function suppressOverwrites(value) { 3999 return _suppressOverwrites = value; 4000 } 4001 } 4002 }; 4003 4004 _forEachName("to,from,fromTo,delayedCall,set,killTweensOf", function (name) { 4005 return _gsap[name] = Tween[name]; 4006 }); 4007 4008 _ticker.add(Timeline.updateRoot); 4009 4010 _quickTween = _gsap.to({}, { 4011 duration: 0 4012 }); 4013 4014 var _getPluginPropTween = function _getPluginPropTween(plugin, prop) { 4015 var pt = plugin._pt; 4016 4017 while (pt && pt.p !== prop && pt.op !== prop && pt.fp !== prop) { 4018 pt = pt._next; 4019 } 4020 4021 return pt; 4022 }, 4023 _addModifiers = function _addModifiers(tween, modifiers) { 4024 var targets = tween._targets, 4025 p, 4026 i, 4027 pt; 4028 4029 for (p in modifiers) { 4030 i = targets.length; 4031 4032 while (i--) { 4033 pt = tween._ptLookup[i][p]; 4034 4035 if (pt && (pt = pt.d)) { 4036 if (pt._pt) { 4037 pt = _getPluginPropTween(pt, p); 4038 } 4039 4040 pt && pt.modifier && pt.modifier(modifiers[p], tween, targets[i], p); 4041 } 4042 } 4043 } 4044 }, 4045 _buildModifierPlugin = function _buildModifierPlugin(name, modifier) { 4046 return { 4047 name: name, 4048
vendor: 20,072 bytes, lines 4048-4675
4048rawVars: 1, 4049 init: function init(target, vars, tween) { 4050 tween._onInit = function (tween) { 4051 var temp, p; 4052 4053 if (_isString(vars)) { 4054 temp = {}; 4055 4056 _forEachName(vars, function (name) { 4057 return temp[name] = 1; 4058 }); 4059 4060 vars = temp; 4061 } 4062 4063 if (modifier) { 4064 temp = {}; 4065 4066 for (p in vars) { 4067 temp[p] = modifier(vars[p]); 4068 } 4069 4070 vars = temp; 4071 } 4072 4073 _addModifiers(tween, vars); 4074 }; 4075 } 4076 }; 4077 }; 4078 4079 var gsap = _gsap.registerPlugin({ 4080 name: "attr", 4081 init: function init(target, vars, tween, index, targets) { 4082 var p, pt, v; 4083 this.tween = tween; 4084 4085 for (p in vars) { 4086 v = target.getAttribute(p) || ""; 4087 pt = this.add(target, "setAttribute", (v || 0) + "", vars[p], index, targets, 0, 0, p); 4088 pt.op = p; 4089 pt.b = v; 4090 4091 this._props.push(p); 4092 } 4093 }, 4094 render: function render(ratio, data) { 4095 var pt = data._pt; 4096 4097 while (pt) { 4098 _reverting ? pt.set(pt.t, pt.p, pt.b, pt) : pt.r(ratio, pt.d); 4099 pt = pt._next; 4100 } 4101 } 4102 }, { 4103 name: "endArray", 4104 init: function init(target, value) { 4105 var i = value.length; 4106 4107 while (i--) { 4108 this.add(target, i, target[i] || 0, value[i], 0, 0, 0, 0, 0, 1); 4109 } 4110 } 4111 }, _buildModifierPlugin("roundProps", _roundModifier), _buildModifierPlugin("modifiers"), _buildModifierPlugin("snap", snap)) || _gsap; 4112 Tween.version = Timeline.version = gsap.version = "3.11.3"; 4113 _coreReady = 1; 4114 _windowExists() && _wake(); 4115 var Power0 = _easeMap.Power0, 4116 Power1 = _easeMap.Power1, 4117 Power2 = _easeMap.Power2, 4118 Power3 = _easeMap.Power3, 4119 Power4 = _easeMap.Power4, 4120 Linear = _easeMap.Linear, 4121 Quad = _easeMap.Quad, 4122 Cubic = _easeMap.Cubic, 4123 Quart = _easeMap.Quart, 4124 Quint = _easeMap.Quint, 4125 Strong = _easeMap.Strong, 4126 Elastic = _easeMap.Elastic, 4127 Back = _easeMap.Back, 4128 SteppedEase = _easeMap.SteppedEase, 4129 Bounce = _easeMap.Bounce, 4130 Sine = _easeMap.Sine, 4131 Expo = _easeMap.Expo, 4132 Circ = _easeMap.Circ; 4133 4134 var _win$1, 4135 _doc$1, 4136 _docElement, 4137 _pluginInitted, 4138 _tempDiv, 4139 _tempDivStyler, 4140 _recentSetterPlugin, 4141 _reverting$1, 4142 _windowExists$1 = function _windowExists() { 4143 return typeof window !== "undefined"; 4144 }, 4145 _transformProps = {}, 4146 _RAD2DEG = 180 / Math.PI, 4147 _DEG2RAD = Math.PI / 180, 4148 _atan2 = Math.atan2, 4149 _bigNum$1 = 1e8, 4150 _capsExp = /([A-Z])/g, 4151 _horizontalExp = /(left|right|width|margin|padding|x)/i, 4152 _complexExp = /[\s,\(]\S/, 4153 _propertyAliases = { 4154 autoAlpha: "opacity,visibility", 4155 scale: "scaleX,scaleY", 4156 alpha: "opacity" 4157 }, 4158 _renderCSSProp = function _renderCSSProp(ratio, data) { 4159 return data.set(data.t, data.p, Math.round((data.s + data.c * ratio) * 10000) / 10000 + data.u, data); 4160 }, 4161 _renderPropWithEnd = function _renderPropWithEnd(ratio, data) { 4162 return data.set(data.t, data.p, ratio === 1 ? data.e : Math.round((data.s + data.c * ratio) * 10000) / 10000 + data.u, data); 4163 }, 4164 _renderCSSPropWithBeginning = function _renderCSSPropWithBeginning(ratio, data) { 4165 return data.set(data.t, data.p, ratio ? Math.round((data.s + data.c * ratio) * 10000) / 10000 + data.u : data.b, data); 4166 }, 4167 _renderRoundedCSSProp = function _renderRoundedCSSProp(ratio, data) { 4168 var value = data.s + data.c * ratio; 4169 data.set(data.t, data.p, ~~(value + (value < 0 ? -.5 : .5)) + data.u, data); 4170 }, 4171 _renderNonTweeningValue = function _renderNonTweeningValue(ratio, data) { 4172 return data.set(data.t, data.p, ratio ? data.e : data.b, data); 4173 }, 4174 _renderNonTweeningValueOnlyAtEnd = function _renderNonTweeningValueOnlyAtEnd(ratio, data) { 4175 return data.set(data.t, data.p, ratio !== 1 ? data.b : data.e, data); 4176 }, 4177 _setterCSSStyle = function _setterCSSStyle(target, property, value) { 4178 return target.style[property] = value; 4179 }, 4180 _setterCSSProp = function _setterCSSProp(target, property, value) { 4181 return target.style.setProperty(property, value); 4182 }, 4183 _setterTransform = function _setterTransform(target, property, value) { 4184 return target._gsap[property] = value; 4185 }, 4186 _setterScale = function _setterScale(target, property, value) { 4187 return target._gsap.scaleX = target._gsap.scaleY = value; 4188 }, 4189 _setterScaleWithRender = function _setterScaleWithRender(target, property, value, data, ratio) { 4190 var cache = target._gsap; 4191 cache.scaleX = cache.scaleY = value; 4192 cache.renderTransform(ratio, cache); 4193 }, 4194 _setterTransformWithRender = function _setterTransformWithRender(target, property, value, data, ratio) { 4195 var cache = target._gsap; 4196 cache[property] = value; 4197 cache.renderTransform(ratio, cache); 4198 }, 4199 _transformProp = "transform", 4200 _transformOriginProp = _transformProp + "Origin", 4201 _saveStyle = function _saveStyle(property, isNotCSS) { 4202 var _this = this; 4203 4204 var target = this.target, 4205 style = target.style; 4206 4207 if (property in _transformProps) { 4208 this.tfm = this.tfm || {}; 4209 4210 if (property !== "transform") { 4211 property = _propertyAliases[property] || property; 4212 ~property.indexOf(",") ? property.split(",").forEach(function (a) { 4213 return _this.tfm[a] = _get(target, a); 4214 }) : this.tfm[property] = target._gsap.x ? target._gsap[property] : _get(target, property); 4215 } 4216 4217 if (this.props.indexOf(_transformProp) >= 0) { 4218 return; 4219 } 4220 4221 if (target._gsap.svg) { 4222 this.svgo = target.getAttribute("data-svg-origin"); 4223 this.props.push(_transformOriginProp, isNotCSS, ""); 4224 } 4225 4226 property = _transformProp; 4227 } 4228 4229 (style || isNotCSS) && this.props.push(property, isNotCSS, style[property]); 4230 }, 4231 _removeIndependentTransforms = function _removeIndependentTransforms(style) { 4232 if (style.translate) { 4233 style.removeProperty("translate"); 4234 style.removeProperty("scale"); 4235 style.removeProperty("rotate"); 4236 } 4237 }, 4238 _revertStyle = function _revertStyle() { 4239 var props = this.props, 4240 target = this.target, 4241 style = target.style, 4242 cache = target._gsap, 4243 i, 4244 p; 4245 4246 for (i = 0; i < props.length; i += 3) { 4247 props[i + 1] ? target[props[i]] = props[i + 2] : props[i + 2] ? style[props[i]] = props[i + 2] : style.removeProperty(props[i].replace(_capsExp, "-$1").toLowerCase()); 4248 } 4249 4250 if (this.tfm) { 4251 for (p in this.tfm) { 4252 cache[p] = this.tfm[p]; 4253 } 4254 4255 if (cache.svg) { 4256 cache.renderTransform(); 4257 target.setAttribute("data-svg-origin", this.svgo || ""); 4258 } 4259 4260 i = _reverting$1(); 4261 4262 if (i && !i.isStart && !style[_transformProp]) { 4263 _removeIndependentTransforms(style); 4264 4265 cache.uncache = 1; 4266 } 4267 } 4268 }, 4269 _getStyleSaver = function _getStyleSaver(target, properties) { 4270 var saver = { 4271 target: target, 4272 props: [], 4273 revert: _revertStyle, 4274 save: _saveStyle 4275 }; 4276 properties && properties.split(",").forEach(function (p) { 4277 return saver.save(p); 4278 }); 4279 return saver; 4280 }, 4281 _supports3D, 4282 _createElement = function _createElement(type, ns) { 4283 var e = _doc$1.createElementNS ? _doc$1.createElementNS((ns || "http://www.w3.org/1999/xhtml").replace(/^https/, "http"), type) : _doc$1.createElement(type); 4284 return e.style ? e : _doc$1.createElement(type); 4285 }, 4286 _getComputedProperty = function _getComputedProperty(target, property, skipPrefixFallback) { 4287 var cs = getComputedStyle(target); 4288 return cs[property] || cs.getPropertyValue(property.replace(_capsExp, "-$1").toLowerCase()) || cs.getPropertyValue(property) || !skipPrefixFallback && _getComputedProperty(target, _checkPropPrefix(property) || property, 1) || ""; 4289 }, 4290 _prefixes = "O,Moz,ms,Ms,Webkit".split(","), 4291 _checkPropPrefix = function _checkPropPrefix(property, element, preferPrefix) { 4292 var e = element || _tempDiv, 4293 s = e.style, 4294 i = 5; 4295 4296 if (property in s && !preferPrefix) { 4297 return property; 4298 } 4299 4300 property = property.charAt(0).toUpperCase() + property.substr(1); 4301 4302 while (i-- && !(_prefixes[i] + property in s)) {} 4303 4304 return i < 0 ? null : (i === 3 ? "ms" : i >= 0 ? _prefixes[i] : "") + property; 4305 }, 4306 _initCore = function _initCore() { 4307 if (_windowExists$1() && window.document) { 4308 _win$1 = window; 4309 _doc$1 = _win$1.document; 4310 _docElement = _doc$1.documentElement; 4311 _tempDiv = _createElement("div") || { 4312 style: {} 4313 }; 4314 _tempDivStyler = _createElement("div"); 4315 _transformProp = _checkPropPrefix(_transformProp); 4316 _transformOriginProp = _transformProp + "Origin"; 4317 _tempDiv.style.cssText = "border-width:0;line-height:0;position:absolute;padding:0"; 4318 _supports3D = !!_checkPropPrefix("perspective"); 4319 _reverting$1 = gsap.core.reverting; 4320 _pluginInitted = 1; 4321 } 4322 }, 4323 _getBBoxHack = function _getBBoxHack(swapIfPossible) { 4324 var svg = _createElement("svg", this.ownerSVGElement && this.ownerSVGElement.getAttribute("xmlns") || "http://www.w3.org/2000/svg"), 4325 oldParent = this.parentNode, 4326 oldSibling = this.nextSibling, 4327 oldCSS = this.style.cssText, 4328 bbox; 4329 4330 _docElement.appendChild(svg); 4331 4332 svg.appendChild(this); 4333 this.style.display = "block"; 4334 4335 if (swapIfPossible) { 4336 try { 4337 bbox = this.getBBox(); 4338 this._gsapBBox = this.getBBox; 4339 this.getBBox = _getBBoxHack; 4340 } catch (e) {} 4341 } else if (this._gsapBBox) { 4342 bbox = this._gsapBBox(); 4343 } 4344 4345 if (oldParent) { 4346 if (oldSibling) { 4347 oldParent.insertBefore(this, oldSibling); 4348 } else { 4349 oldParent.appendChild(this); 4350 } 4351 } 4352 4353 _docElement.removeChild(svg); 4354 4355 this.style.cssText = oldCSS; 4356 return bbox; 4357 }, 4358 _getAttributeFallbacks = function _getAttributeFallbacks(target, attributesArray) { 4359 var i = attributesArray.length; 4360 4361 while (i--) { 4362 if (target.hasAttribute(attributesArray[i])) { 4363 return target.getAttribute(attributesArray[i]); 4364 } 4365 } 4366 }, 4367 _getBBox = function _getBBox(target) { 4368 var bounds; 4369 4370 try { 4371 bounds = target.getBBox(); 4372 } catch (error) { 4373 bounds = _getBBoxHack.call(target, true); 4374 } 4375 4376 bounds && (bounds.width || bounds.height) || target.getBBox === _getBBoxHack || (bounds = _getBBoxHack.call(target, true)); 4377 return bounds && !bounds.width && !bounds.x && !bounds.y ? { 4378 x: +_getAttributeFallbacks(target, ["x", "cx", "x1"]) || 0, 4379 y: +_getAttributeFallbacks(target, ["y", "cy", "y1"]) || 0, 4380 width: 0, 4381 height: 0 4382 } : bounds; 4383 }, 4384 _isSVG = function _isSVG(e) { 4385 return !!(e.getCTM && (!e.parentNode || e.ownerSVGElement) && _getBBox(e)); 4386 }, 4387 _removeProperty = function _removeProperty(target, property) { 4388 if (property) { 4389 var style = target.style; 4390 4391 if (property in _transformProps && property !== _transformOriginProp) { 4392 property = _transformProp; 4393 } 4394 4395 if (style.removeProperty) { 4396 if (property.substr(0, 2) === "ms" || property.substr(0, 6) === "webkit") { 4397 property = "-" + property; 4398 } 4399 4400 style.removeProperty(property.replace(_capsExp, "-$1").toLowerCase()); 4401 } else { 4402 style.removeAttribute(property); 4403 } 4404 } 4405 }, 4406 _addNonTweeningPT = function _addNonTweeningPT(plugin, target, property, beginning, end, onlySetAtEnd) { 4407 var pt = new PropTween(plugin._pt, target, property, 0, 1, onlySetAtEnd ? _renderNonTweeningValueOnlyAtEnd : _renderNonTweeningValue); 4408 plugin._pt = pt; 4409 pt.b = beginning; 4410 pt.e = end; 4411 4412 plugin._props.push(property); 4413 4414 return pt; 4415 }, 4416 _nonConvertibleUnits = { 4417 deg: 1, 4418 rad: 1, 4419 turn: 1 4420 }, 4421 _nonStandardLayouts = { 4422 grid: 1, 4423 flex: 1 4424 }, 4425 _convertToUnit = function _convertToUnit(target, property, value, unit) { 4426 var curValue = parseFloat(value) || 0, 4427 curUnit = (value + "").trim().substr((curValue + "").length) || "px", 4428 style = _tempDiv.style, 4429 horizontal = _horizontalExp.test(property), 4430 isRootSVG = target.tagName.toLowerCase() === "svg", 4431 measureProperty = (isRootSVG ? "client" : "offset") + (horizontal ? "Width" : "Height"), 4432 amount = 100, 4433 toPixels = unit === "px", 4434 toPercent = unit === "%", 4435 px, 4436 parent, 4437 cache, 4438 isSVG; 4439 4440 if (unit === curUnit || !curValue || _nonConvertibleUnits[unit] || _nonConvertibleUnits[curUnit]) { 4441 return curValue; 4442 } 4443 4444 curUnit !== "px" && !toPixels && (curValue = _convertToUnit(target, property, value, "px")); 4445 isSVG = target.getCTM && _isSVG(target); 4446 4447 if ((toPercent || curUnit === "%") && (_transformProps[property] || ~property.indexOf("adius"))) { 4448 px = isSVG ? target.getBBox()[horizontal ? "width" : "height"] : target[measureProperty]; 4449 return _round(toPercent ? curValue / px * amount : curValue / 100 * px); 4450 } 4451 4452 style[horizontal ? "width" : "height"] = amount + (toPixels ? curUnit : unit); 4453 parent = ~property.indexOf("adius") || unit === "em" && target.appendChild && !isRootSVG ? target : target.parentNode; 4454 4455 if (isSVG) { 4456 parent = (target.ownerSVGElement || {}).parentNode; 4457 } 4458 4459 if (!parent || parent === _doc$1 || !parent.appendChild) { 4460 parent = _doc$1.body; 4461 } 4462 4463 cache = parent._gsap; 4464 4465 if (cache && toPercent && cache.width && horizontal && cache.time === _ticker.time && !cache.uncache) { 4466 return _round(curValue / cache.width * amount); 4467 } else { 4468 (toPercent || curUnit === "%") && !_nonStandardLayouts[_getComputedProperty(parent, "display")] && (style.position = _getComputedProperty(target, "position")); 4469 parent === target && (style.position = "static"); 4470 parent.appendChild(_tempDiv); 4471 px = _tempDiv[measureProperty]; 4472 parent.removeChild(_tempDiv); 4473 style.position = "absolute"; 4474 4475 if (horizontal && toPercent) { 4476 cache = _getCache(parent); 4477 cache.time = _ticker.time; 4478 cache.width = parent[measureProperty]; 4479 } 4480 } 4481 4482 return _round(toPixels ? px * curValue / amount : px && curValue ? amount / px * curValue : 0); 4483 }, 4484 _get = function _get(target, property, unit, uncache) { 4485 var value; 4486 _pluginInitted || _initCore(); 4487 4488 if (property in _propertyAliases && property !== "transform") { 4489 property = _propertyAliases[property]; 4490 4491 if (~property.indexOf(",")) { 4492 property = property.split(",")[0]; 4493 } 4494 } 4495 4496 if (_transformProps[property] && property !== "transform") { 4497 value = _parseTransform(target, uncache); 4498 value = property !== "transformOrigin" ? value[property] : value.svg ? value.origin : _firstTwoOnly(_getComputedProperty(target, _transformOriginProp)) + " " + value.zOrigin + "px"; 4499 } else { 4500 value = target.style[property]; 4501 4502 if (!value || value === "auto" || uncache || ~(value + "").indexOf("calc(")) { 4503 value = _specialProps[property] && _specialProps[property](target, property, unit) || _getComputedProperty(target, property) || _getProperty(target, property) || (property === "opacity" ? 1 : 0); 4504 } 4505 } 4506 4507 return unit && !~(value + "").trim().indexOf(" ") ? _convertToUnit(target, property, value, unit) + unit : value; 4508 }, 4509 _tweenComplexCSSString = function _tweenComplexCSSString(target, prop, start, end) { 4510 if (!start || start === "none") { 4511 var p = _checkPropPrefix(prop, target, 1), 4512 s = p && _getComputedProperty(target, p, 1); 4513 4514 if (s && s !== start) { 4515 prop = p; 4516 start = s; 4517 } else if (prop === "borderColor") { 4518 start = _getComputedProperty(target, "borderTopColor"); 4519 } 4520 } 4521 4522 var pt = new PropTween(this._pt, target.style, prop, 0, 1, _renderComplexString), 4523 index = 0, 4524 matchIndex = 0, 4525 a, 4526 result, 4527 startValues, 4528 startNum, 4529 color, 4530 startValue, 4531 endValue, 4532 endNum, 4533 chunk, 4534 endUnit, 4535 startUnit, 4536 endValues; 4537 pt.b = start; 4538 pt.e = end; 4539 start += ""; 4540 end += ""; 4541 4542 if (end === "auto") { 4543 target.style[prop] = end; 4544 end = _getComputedProperty(target, prop) || end; 4545 target.style[prop] = start; 4546 } 4547 4548 a = [start, end]; 4549 4550 _colorStringFilter(a); 4551 4552 start = a[0]; 4553 end = a[1]; 4554 startValues = start.match(_numWithUnitExp) || []; 4555 endValues = end.match(_numWithUnitExp) || []; 4556 4557 if (endValues.length) { 4558 while (result = _numWithUnitExp.exec(end)) { 4559 endValue = result[0]; 4560 chunk = end.substring(index, result.index); 4561 4562 if (color) { 4563 color = (color + 1) % 5; 4564 } else if (chunk.substr(-5) === "rgba(" || chunk.substr(-5) === "hsla(") { 4565 color = 1; 4566 } 4567 4568 if (endValue !== (startValue = startValues[matchIndex++] || "")) { 4569 startNum = parseFloat(startValue) || 0; 4570 startUnit = startValue.substr((startNum + "").length); 4571 endValue.charAt(1) === "=" && (endValue = _parseRelative(startNum, endValue) + startUnit); 4572 endNum = parseFloat(endValue); 4573 endUnit = endValue.substr((endNum + "").length); 4574 index = _numWithUnitExp.lastIndex - endUnit.length; 4575 4576 if (!endUnit) { 4577 endUnit = endUnit || _config.units[prop] || startUnit; 4578 4579 if (index === end.length) { 4580 end += endUnit; 4581 pt.e += endUnit; 4582 } 4583 } 4584 4585 if (startUnit !== endUnit) { 4586 startNum = _convertToUnit(target, prop, startValue, endUnit) || 0; 4587 } 4588 4589 pt._pt = { 4590 _next: pt._pt, 4591 p: chunk || matchIndex === 1 ? chunk : ",", 4592 s: startNum, 4593 c: endNum - startNum, 4594 m: color && color < 4 || prop === "zIndex" ? Math.round : 0 4595 }; 4596 } 4597 } 4598 4599 pt.c = index < end.length ? end.substring(index, end.length) : ""; 4600 } else { 4601 pt.r = prop === "display" && end === "none" ? _renderNonTweeningValueOnlyAtEnd : _renderNonTweeningValue; 4602 } 4603 4604 _relExp.test(end) && (pt.e = 0); 4605 this._pt = pt; 4606 return pt; 4607 }, 4608 _keywordToPercent = { 4609 top: "0%", 4610 bottom: "100%", 4611 left: "0%", 4612 right: "100%", 4613 center: "50%" 4614 }, 4615 _convertKeywordsToPercentages = function _convertKeywordsToPercentages(value) { 4616 var split = value.split(" "), 4617 x = split[0], 4618 y = split[1] || "50%"; 4619 4620 if (x === "top" || x === "bottom" || y === "left" || y === "right") { 4621 value = x; 4622 x = y; 4623 y = value; 4624 } 4625 4626 split[0] = _keywordToPercent[x] || x; 4627 split[1] = _keywordToPercent[y] || y; 4628 return split.join(" "); 4629 }, 4630 _renderClearProps = function _renderClearProps(ratio, data) { 4631 if (data.tween && data.tween._time === data.tween._dur) { 4632 var target = data.t, 4633 style = target.style, 4634 props = data.u, 4635 cache = target._gsap, 4636 prop, 4637 clearTransforms, 4638 i; 4639 4640 if (props === "all" || props === true) { 4641 style.cssText = ""; 4642 clearTransforms = 1; 4643 } else { 4644 props = props.split(","); 4645 i = props.length; 4646 4647 while (--i > -1) { 4648 prop = props[i]; 4649 4650 if (_transformProps[prop]) { 4651 clearTransforms = 1; 4652 prop = prop === "transformOrigin" ? _transformOriginProp : _transformProp; 4653 } 4654 4655 _removeProperty(target, prop); 4656 } 4657 } 4658 4659 if (clearTransforms) { 4660 _removeProperty(target, _transformProp); 4661 4662 if (cache) { 4663 cache.svg && target.removeAttribute("transform"); 4664 4665 _parseTransform(target, 1); 4666 4667 cache.uncache = 1; 4668 4669 _removeIndependentTransforms(style); 4670 } 4671 } 4672 } 4673 }, 4674 _specialProps = { 4675 clearProps: function clearProps(plugin, target, property, endValue, tween) {
vendor: 1,580 bytes, lines 4676-4716
4676 if (tween.data !== "isFromStart") { 4677 var pt = plugin._pt = new PropTween(plugin._pt, target, property, 0, 0, _renderClearProps); 4678 pt.u = endValue; 4679 pt.pr = -10; 4680 pt.tween = tween; 4681 4682 plugin._props.push(property); 4683 4684 return 1; 4685 } 4686 } 4687 }, 4688 _identity2DMatrix = [1, 0, 0, 1, 0, 0], 4689 _rotationalProperties = {}, 4690 _isNullTransform = function _isNullTransform(value) { 4691 return value === "matrix(1, 0, 0, 1, 0, 0)" || value === "none" || !value; 4692 }, 4693 _getComputedTransformMatrixAsArray = function _getComputedTransformMatrixAsArray(target) { 4694 var matrixString = _getComputedProperty(target, _transformProp); 4695 4696 return _isNullTransform(matrixString) ? _identity2DMatrix : matrixString.substr(7).match(_numExp).map(_round); 4697 }, 4698 _getMatrix = function _getMatrix(target, force2D) { 4699 var cache = target._gsap || _getCache(target), 4700 style = target.style, 4701 matrix = _getComputedTransformMatrixAsArray(target), 4702 parent, 4703 nextSibling, 4704 temp, 4705 addedToDOM; 4706 4707 if (cache.svg && target.getAttribute("transform")) { 4708 temp = target.transform.baseVal.consolidate().matrix; 4709 matrix = [temp.a, temp.b, temp.c, temp.d, temp.e, temp.f]; 4710 return matrix.join(",") === "1,0,0,1,0,0" ? _identity2DMatrix : matrix; 4711 } else if (matrix === _identity2DMatrix && !target.offsetParent && target !== _docElement && !cache.svg) { 4712 temp = style.display; 4713 style.display = "block"; 4714 parent = target.parentNode; 4715 4716 if (!parent || !target.offsetParent
vendor: 18,897 bytes, lines 4716-5313
4716) { 4717 addedToDOM = 1; 4718 nextSibling = target.nextElementSibling; 4719 4720 _docElement.appendChild(target); 4721 } 4722 4723 matrix = _getComputedTransformMatrixAsArray(target); 4724 temp ? style.display = temp : _removeProperty(target, "display"); 4725 4726 if (addedToDOM) { 4727 nextSibling ? parent.insertBefore(target, nextSibling) : parent ? parent.appendChild(target) : _docElement.removeChild(target); 4728 } 4729 } 4730 4731 return force2D && matrix.length > 6 ? [matrix[0], matrix[1], matrix[4], matrix[5], matrix[12], matrix[13]] : matrix; 4732 }, 4733 _applySVGOrigin = function _applySVGOrigin(target, origin, originIsAbsolute, smooth, matrixArray, pluginToAddPropTweensTo) { 4734 var cache = target._gsap, 4735 matrix = matrixArray || _getMatrix(target, true), 4736 xOriginOld = cache.xOrigin || 0, 4737 yOriginOld = cache.yOrigin || 0, 4738 xOffsetOld = cache.xOffset || 0, 4739 yOffsetOld = cache.yOffset || 0, 4740 a = matrix[0], 4741 b = matrix[1], 4742 c = matrix[2], 4743 d = matrix[3], 4744 tx = matrix[4], 4745 ty = matrix[5], 4746 originSplit = origin.split(" "), 4747 xOrigin = parseFloat(originSplit[0]) || 0, 4748 yOrigin = parseFloat(originSplit[1]) || 0, 4749 bounds, 4750 determinant, 4751 x, 4752 y; 4753 4754 if (!originIsAbsolute) { 4755 bounds = _getBBox(target); 4756 xOrigin = bounds.x + (~originSplit[0].indexOf("%") ? xOrigin / 100 * bounds.width : xOrigin); 4757 yOrigin = bounds.y + (~(originSplit[1] || originSplit[0]).indexOf("%") ? yOrigin / 100 * bounds.height : yOrigin); 4758 } else if (matrix !== _identity2DMatrix && (determinant = a * d - b * c)) { 4759 x = xOrigin * (d / determinant) + yOrigin * (-c / determinant) + (c * ty - d * tx) / determinant; 4760 y = xOrigin * (-b / determinant) + yOrigin * (a / determinant) - (a * ty - b * tx) / determinant; 4761 xOrigin = x; 4762 yOrigin = y; 4763 } 4764 4765 if (smooth || smooth !== false && cache.smooth) { 4766 tx = xOrigin - xOriginOld; 4767 ty = yOrigin - yOriginOld; 4768 cache.xOffset = xOffsetOld + (tx * a + ty * c) - tx; 4769 cache.yOffset = yOffsetOld + (tx * b + ty * d) - ty; 4770 } else { 4771 cache.xOffset = cache.yOffset = 0; 4772 } 4773 4774 cache.xOrigin = xOrigin; 4775 cache.yOrigin = yOrigin; 4776 cache.smooth = !!smooth; 4777 cache.origin = origin; 4778 cache.originIsAbsolute = !!originIsAbsolute; 4779 target.style[_transformOriginProp] = "0px 0px"; 4780 4781 if (pluginToAddPropTweensTo) { 4782 _addNonTweeningPT(pluginToAddPropTweensTo, cache, "xOrigin", xOriginOld, xOrigin); 4783 4784 _addNonTweeningPT(pluginToAddPropTweensTo, cache, "yOrigin", yOriginOld, yOrigin); 4785 4786 _addNonTweeningPT(pluginToAddPropTweensTo, cache, "xOffset", xOffsetOld, cache.xOffset); 4787 4788 _addNonTweeningPT(pluginToAddPropTweensTo, cache, "yOffset", yOffsetOld, cache.yOffset); 4789 } 4790 4791 target.setAttribute("data-svg-origin", xOrigin + " " + yOrigin); 4792 }, 4793 _parseTransform = function _parseTransform(target, uncache) { 4794 var cache = target._gsap || new GSCache(target); 4795 4796 if ("x" in cache && !uncache && !cache.uncache) { 4797 return cache; 4798 } 4799 4800 var style = target.style, 4801 invertedScaleX = cache.scaleX < 0, 4802 px = "px", 4803 deg = "deg", 4804 cs = getComputedStyle(target), 4805 origin = _getComputedProperty(target, _transformOriginProp) || "0", 4806 x, 4807 y, 4808 z, 4809 scaleX, 4810 scaleY, 4811 rotation, 4812 rotationX, 4813 rotationY, 4814 skewX, 4815 skewY, 4816 perspective, 4817 xOrigin, 4818 yOrigin, 4819 matrix, 4820 angle, 4821 cos, 4822 sin, 4823 a, 4824 b, 4825 c, 4826 d, 4827 a12, 4828 a22, 4829 t1, 4830 t2, 4831 t3, 4832 a13, 4833 a23, 4834 a33, 4835 a42, 4836 a43, 4837 a32; 4838 x = y = z = rotation = rotationX = rotationY = skewX = skewY = perspective = 0; 4839 scaleX = scaleY = 1; 4840 cache.svg = !!(target.getCTM && _isSVG(target)); 4841 4842 if (cs.translate) { 4843 if (cs.translate !== "none" || cs.scale !== "none" || cs.rotate !== "none") { 4844 style[_transformProp] = (cs.translate !== "none" ? "translate3d(" + (cs.translate + " 0 0").split(" ").slice(0, 3).join(", ") + ") " : "") + (cs.rotate !== "none" ? "rotate(" + cs.rotate + ") " : "") + (cs.scale !== "none" ? "scale(" + cs.scale.split(" ").join(",") + ") " : "") + (cs[_transformProp] !== "none" ? cs[_transformProp] : ""); 4845 } 4846 4847 style.scale = style.rotate = style.translate = "none"; 4848 } 4849 4850 matrix = _getMatrix(target, cache.svg); 4851 4852 if (cache.svg) { 4853 if (cache.uncache) { 4854 t2 = target.getBBox(); 4855 origin = cache.xOrigin - t2.x + "px " + (cache.yOrigin - t2.y) + "px"; 4856 t1 = ""; 4857 } else { 4858 t1 = !uncache && target.getAttribute("data-svg-origin"); 4859 } 4860 4861 _applySVGOrigin(target, t1 || origin, !!t1 || cache.originIsAbsolute, cache.smooth !== false, matrix); 4862 } 4863 4864 xOrigin = cache.xOrigin || 0; 4865 yOrigin = cache.yOrigin || 0; 4866 4867 if (matrix !== _identity2DMatrix) { 4868 a = matrix[0]; 4869 b = matrix[1]; 4870 c = matrix[2]; 4871 d = matrix[3]; 4872 x = a12 = matrix[4]; 4873 y = a22 = matrix[5]; 4874 4875 if (matrix.length === 6) { 4876 scaleX = Math.sqrt(a * a + b * b); 4877 scaleY = Math.sqrt(d * d + c * c); 4878 rotation = a || b ? _atan2(b, a) * _RAD2DEG : 0; 4879 skewX = c || d ? _atan2(c, d) * _RAD2DEG + rotation : 0; 4880 skewX && (scaleY *= Math.abs(Math.cos(skewX * _DEG2RAD))); 4881 4882 if (cache.svg) { 4883 x -= xOrigin - (xOrigin * a + yOrigin * c); 4884 y -= yOrigin - (xOrigin * b + yOrigin * d); 4885 } 4886 } else { 4887 a32 = matrix[6]; 4888 a42 = matrix[7]; 4889 a13 = matrix[8]; 4890 a23 = matrix[9]; 4891 a33 = matrix[10]; 4892 a43 = matrix[11]; 4893 x = matrix[12]; 4894 y = matrix[13]; 4895 z = matrix[14]; 4896 angle = _atan2(a32, a33); 4897 rotationX = angle * _RAD2DEG; 4898 4899 if (angle) { 4900 cos = Math.cos(-angle); 4901 sin = Math.sin(-angle); 4902 t1 = a12 * cos + a13 * sin; 4903 t2 = a22 * cos + a23 * sin; 4904 t3 = a32 * cos + a33 * sin; 4905 a13 = a12 * -sin + a13 * cos; 4906 a23 = a22 * -sin + a23 * cos; 4907 a33 = a32 * -sin + a33 * cos; 4908 a43 = a42 * -sin + a43 * cos; 4909 a12 = t1; 4910 a22 = t2; 4911 a32 = t3; 4912 } 4913 4914 angle = _atan2(-c, a33); 4915 rotationY = angle * _RAD2DEG; 4916 4917 if (angle) { 4918 cos = Math.cos(-angle); 4919 sin = Math.sin(-angle); 4920 t1 = a * cos - a13 * sin; 4921 t2 = b * cos - a23 * sin; 4922 t3 = c * cos - a33 * sin; 4923 a43 = d * sin + a43 * cos; 4924 a = t1; 4925 b = t2; 4926 c = t3; 4927 } 4928 4929 angle = _atan2(b, a); 4930 rotation = angle * _RAD2DEG; 4931 4932 if (angle) { 4933 cos = Math.cos(angle); 4934 sin = Math.sin(angle); 4935 t1 = a * cos + b * sin; 4936 t2 = a12 * cos + a22 * sin; 4937 b = b * cos - a * sin; 4938 a22 = a22 * cos - a12 * sin; 4939 a = t1; 4940 a12 = t2; 4941 } 4942 4943 if (rotationX && Math.abs(rotationX) + Math.abs(rotation) > 359.9) { 4944 rotationX = rotation = 0; 4945 rotationY = 180 - rotationY; 4946 } 4947 4948 scaleX = _round(Math.sqrt(a * a + b * b + c * c)); 4949 scaleY = _round(Math.sqrt(a22 * a22 + a32 * a32)); 4950 angle = _atan2(a12, a22); 4951 skewX = Math.abs(angle) > 0.0002 ? angle * _RAD2DEG : 0; 4952 perspective = a43 ? 1 / (a43 < 0 ? -a43 : a43) : 0; 4953 } 4954 4955 if (cache.svg) { 4956 t1 = target.getAttribute("transform"); 4957 cache.forceCSS = target.setAttribute("transform", "") || !_isNullTransform(_getComputedProperty(target, _transformProp)); 4958 t1 && target.setAttribute("transform", t1); 4959 } 4960 } 4961 4962 if (Math.abs(skewX) > 90 && Math.abs(skewX) < 270) { 4963 if (invertedScaleX) { 4964 scaleX *= -1; 4965 skewX += rotation <= 0 ? 180 : -180; 4966 rotation += rotation <= 0 ? 180 : -180; 4967 } else { 4968 scaleY *= -1; 4969 skewX += skewX <= 0 ? 180 : -180; 4970 } 4971 } 4972 4973 uncache = uncache || cache.uncache; 4974 cache.x = x - ((cache.xPercent = x && (!uncache && cache.xPercent || (Math.round(target.offsetWidth / 2) === Math.round(-x) ? -50 : 0))) ? target.offsetWidth * cache.xPercent / 100 : 0) + px; 4975 cache.y = y - ((cache.yPercent = y && (!uncache && cache.yPercent || (Math.round(target.offsetHeight / 2) === Math.round(-y) ? -50 : 0))) ? target.offsetHeight * cache.yPercent / 100 : 0) + px; 4976 cache.z = z + px; 4977 cache.scaleX = _round(scaleX); 4978 cache.scaleY = _round(scaleY); 4979 cache.rotation = _round(rotation) + deg; 4980 cache.rotationX = _round(rotationX) + deg; 4981 cache.rotationY = _round(rotationY) + deg; 4982 cache.skewX = skewX + deg; 4983 cache.skewY = skewY + deg; 4984 cache.transformPerspective = perspective + px; 4985 4986 if (cache.zOrigin = parseFloat(origin.split(" ")[2]) || 0) { 4987 style[_transformOriginProp] = _firstTwoOnly(origin); 4988 } 4989 4990 cache.xOffset = cache.yOffset = 0; 4991 cache.force3D = _config.force3D; 4992 cache.renderTransform = cache.svg ? _renderSVGTransforms : _supports3D ? _renderCSSTransforms : _renderNon3DTransforms; 4993 cache.uncache = 0; 4994 return cache; 4995 }, 4996 _firstTwoOnly = function _firstTwoOnly(value) { 4997 return (value = value.split(" "))[0] + " " + value[1]; 4998 }, 4999 _addPxTranslate = function _addPxTranslate(target, start, value) { 5000 var unit = getUnit(start); 5001 return _round(parseFloat(start) + parseFloat(_convertToUnit(target, "x", value + "px", unit))) + unit; 5002 }, 5003 _renderNon3DTransforms = function _renderNon3DTransforms(ratio, cache) { 5004 cache.z = "0px"; 5005 cache.rotationY = cache.rotationX = "0deg"; 5006 cache.force3D = 0; 5007 5008 _renderCSSTransforms(ratio, cache); 5009 }, 5010 _zeroDeg = "0deg", 5011 _zeroPx = "0px", 5012 _endParenthesis = ") ", 5013 _renderCSSTransforms = function _renderCSSTransforms(ratio, cache) { 5014 var _ref = cache || this, 5015 xPercent = _ref.xPercent, 5016 yPercent = _ref.yPercent, 5017 x = _ref.x, 5018 y = _ref.y, 5019 z = _ref.z, 5020 rotation = _ref.rotation, 5021 rotationY = _ref.rotationY, 5022 rotationX = _ref.rotationX, 5023 skewX = _ref.skewX, 5024 skewY = _ref.skewY, 5025 scaleX = _ref.scaleX, 5026 scaleY = _ref.scaleY, 5027 transformPerspective = _ref.transformPerspective, 5028 force3D = _ref.force3D, 5029 target = _ref.target, 5030 zOrigin = _ref.zOrigin, 5031 transforms = "", 5032 use3D = force3D === "auto" && ratio && ratio !== 1 || force3D === true; 5033 5034 if (zOrigin && (rotationX !== _zeroDeg || rotationY !== _zeroDeg)) { 5035 var angle = parseFloat(rotationY) * _DEG2RAD, 5036 a13 = Math.sin(angle), 5037 a33 = Math.cos(angle), 5038 cos; 5039 5040 angle = parseFloat(rotationX) * _DEG2RAD; 5041 cos = Math.cos(angle); 5042 x = _addPxTranslate(target, x, a13 * cos * -zOrigin); 5043 y = _addPxTranslate(target, y, -Math.sin(angle) * -zOrigin); 5044 z = _addPxTranslate(target, z, a33 * cos * -zOrigin + zOrigin); 5045 } 5046 5047 if (transformPerspective !== _zeroPx) { 5048 transforms += "perspective(" + transformPerspective + _endParenthesis; 5049 } 5050 5051 if (xPercent || yPercent) { 5052 transforms += "translate(" + xPercent + "%, " + yPercent + "%) "; 5053 } 5054 5055 if (use3D || x !== _zeroPx || y !== _zeroPx || z !== _zeroPx) { 5056 transforms += z !== _zeroPx || use3D ? "translate3d(" + x + ", " + y + ", " + z + ") " : "translate(" + x + ", " + y + _endParenthesis; 5057 } 5058 5059 if (rotation !== _zeroDeg) { 5060 transforms += "rotate(" + rotation + _endParenthesis; 5061 } 5062 5063 if (rotationY !== _zeroDeg) { 5064 transforms += "rotateY(" + rotationY + _endParenthesis; 5065 } 5066 5067 if (rotationX !== _zeroDeg) { 5068 transforms += "rotateX(" + rotationX + _endParenthesis; 5069 } 5070 5071 if (skewX !== _zeroDeg || skewY !== _zeroDeg) { 5072 transforms += "skew(" + skewX + ", " + skewY + _endParenthesis; 5073 } 5074 5075 if (scaleX !== 1 || scaleY !== 1) { 5076 transforms += "scale(" + scaleX + ", " + scaleY + _endParenthesis; 5077 } 5078 5079 target.style[_transformProp] = transforms || "translate(0, 0)"; 5080 }, 5081 _renderSVGTransforms = function _renderSVGTransforms(ratio, cache) { 5082 var _ref2 = cache || this, 5083 xPercent = _ref2.xPercent, 5084 yPercent = _ref2.yPercent, 5085 x = _ref2.x, 5086 y = _ref2.y, 5087 rotation = _ref2.rotation, 5088 skewX = _ref2.skewX, 5089 skewY = _ref2.skewY, 5090 scaleX = _ref2.scaleX, 5091 scaleY = _ref2.scaleY, 5092 target = _ref2.target, 5093 xOrigin = _ref2.xOrigin, 5094 yOrigin = _ref2.yOrigin, 5095 xOffset = _ref2.xOffset, 5096 yOffset = _ref2.yOffset, 5097 forceCSS = _ref2.forceCSS, 5098 tx = parseFloat(x), 5099 ty = parseFloat(y), 5100 a11, 5101 a21, 5102 a12, 5103 a22, 5104 temp; 5105 5106 rotation = parseFloat(rotation); 5107 skewX = parseFloat(skewX); 5108 skewY = parseFloat(skewY); 5109 5110 if (skewY) { 5111 skewY = parseFloat(skewY); 5112 skewX += skewY; 5113 rotation += skewY; 5114 } 5115 5116 if (rotation || skewX) { 5117 rotation *= _DEG2RAD; 5118 skewX *= _DEG2RAD; 5119 a11 = Math.cos(rotation) * scaleX; 5120 a21 = Math.sin(rotation) * scaleX; 5121 a12 = Math.sin(rotation - skewX) * -scaleY; 5122 a22 = Math.cos(rotation - skewX) * scaleY; 5123 5124 if (skewX) { 5125 skewY *= _DEG2RAD; 5126 temp = Math.tan(skewX - skewY); 5127 temp = Math.sqrt(1 + temp * temp); 5128 a12 *= temp; 5129 a22 *= temp; 5130 5131 if (skewY) { 5132 temp = Math.tan(skewY); 5133 temp = Math.sqrt(1 + temp * temp); 5134 a11 *= temp; 5135 a21 *= temp; 5136 } 5137 } 5138 5139 a11 = _round(a11); 5140 a21 = _round(a21); 5141 a12 = _round(a12); 5142 a22 = _round(a22); 5143 } else { 5144 a11 = scaleX; 5145 a22 = scaleY; 5146 a21 = a12 = 0; 5147 } 5148 5149 if (tx && !~(x + "").indexOf("px") || ty && !~(y + "").indexOf("px")) { 5150 tx = _convertToUnit(target, "x", x, "px"); 5151 ty = _convertToUnit(target, "y", y, "px"); 5152 } 5153 5154 if (xOrigin || yOrigin || xOffset || yOffset) { 5155 tx = _round(tx + xOrigin - (xOrigin * a11 + yOrigin * a12) + xOffset); 5156 ty = _round(ty + yOrigin - (xOrigin * a21 + yOrigin * a22) + yOffset); 5157 } 5158 5159 if (xPercent || yPercent) { 5160 temp = target.getBBox(); 5161 tx = _round(tx + xPercent / 100 * temp.width); 5162 ty = _round(ty + yPercent / 100 * temp.height); 5163 } 5164 5165 temp = "matrix(" + a11 + "," + a21 + "," + a12 + "," + a22 + "," + tx + "," + ty + ")"; 5166 target.setAttribute("transform", temp); 5167 forceCSS && (target.style[_transformProp] = temp); 5168 }, 5169 _addRotationalPropTween = function _addRotationalPropTween(plugin, target, property, startNum, endValue) { 5170 var cap = 360, 5171 isString = _isString(endValue), 5172 endNum = parseFloat(endValue) * (isString && ~endValue.indexOf("rad") ? _RAD2DEG : 1), 5173 change = endNum - startNum, 5174 finalValue = startNum + change + "deg", 5175 direction, 5176 pt; 5177 5178 if (isString) { 5179 direction = endValue.split("_")[1]; 5180 5181 if (direction === "short") { 5182 change %= cap; 5183 5184 if (change !== change % (cap / 2)) { 5185 change += change < 0 ? cap : -cap; 5186 } 5187 } 5188 5189 if (direction === "cw" && change < 0) { 5190 change = (change + cap * _bigNum$1) % cap - ~~(change / cap) * cap; 5191 } else if (direction === "ccw" && change > 0) { 5192 change = (change - cap * _bigNum$1) % cap - ~~(change / cap) * cap; 5193 } 5194 } 5195 5196 plugin._pt = pt = new PropTween(plugin._pt, target, property, startNum, change, _renderPropWithEnd); 5197 pt.e = finalValue; 5198 pt.u = "deg"; 5199 5200 plugin._props.push(property); 5201 5202 return pt; 5203 }, 5204 _assign = function _assign(target, source) { 5205 for (var p in source) { 5206 target[p] = source[p]; 5207 } 5208 5209 return target; 5210 }, 5211 _addRawTransformPTs = function _addRawTransformPTs(plugin, transforms, target) { 5212 var startCache = _assign({}, target._gsap), 5213 exclude = "perspective,force3D,transformOrigin,svgOrigin", 5214 style = target.style, 5215 endCache, 5216 p, 5217 startValue, 5218 endValue, 5219 startNum, 5220 endNum, 5221 startUnit, 5222 endUnit; 5223 5224 if (startCache.svg) { 5225 startValue = target.getAttribute("transform"); 5226 target.setAttribute("transform", ""); 5227 style[_transformProp] = transforms; 5228 endCache = _parseTransform(target, 1); 5229 5230 _removeProperty(target, _transformProp); 5231 5232 target.setAttribute("transform", startValue); 5233 } else { 5234 startValue = getComputedStyle(target)[_transformProp]; 5235 style[_transformProp] = transforms; 5236 endCache = _parseTransform(target, 1); 5237 style[_transformProp] = startValue; 5238 } 5239 5240 for (p in _transformProps) { 5241 startValue = startCache[p]; 5242 endValue = endCache[p]; 5243 5244 if (startValue !== endValue && exclude.indexOf(p) < 0) { 5245 startUnit = getUnit(startValue); 5246 endUnit = getUnit(endValue); 5247 startNum = startUnit !== endUnit ? _convertToUnit(target, p, startValue, endUnit) : parseFloat(startValue); 5248 endNum = parseFloat(endValue); 5249 plugin._pt = new PropTween(plugin._pt, endCache, p, startNum, endNum - startNum, _renderCSSProp); 5250 plugin._pt.u = endUnit || 0; 5251 5252 plugin._props.push(p); 5253 } 5254 } 5255 5256 _assign(endCache, startCache); 5257 }; 5258 5259 _forEachName("padding,margin,Width,Radius", function (name, index) { 5260 var t = "Top", 5261 r = "Right", 5262 b = "Bottom", 5263 l = "Left", 5264 props = (index < 3 ? [t, r, b, l] : [t + l, t + r, b + r, b + l]).map(function (side) { 5265 return index < 2 ? name + side : "border" + side + name; 5266 }); 5267 5268 _specialProps[index > 1 ? "border" + name : name] = function (plugin, target, property, endValue, tween) { 5269 var a, vars; 5270 5271 if (arguments.length < 4) { 5272 a = props.map(function (prop) { 5273 return _get(plugin, prop, property); 5274 }); 5275 vars = a.join(" "); 5276 return vars.split(a[0]).length === 5 ? a[0] : vars; 5277 } 5278 5279 a = (endValue + "").split(" "); 5280 vars = {}; 5281 props.forEach(function (prop, i) { 5282 return vars[prop] = a[i] = a[i] || a[(i - 1) / 2 | 0]; 5283 }); 5284 plugin.init(target, vars, tween); 5285 }; 5286 }); 5287 5288 var CSSPlugin = { 5289 name: "css", 5290 register: _initCore, 5291 targetTest: function targetTest(target) { 5292 return target.style && target.nodeType; 5293 }, 5294 init: function init(target, vars, tween, index, targets) { 5295 var props = this._props, 5296 style = target.style, 5297 startAt = tween.vars.startAt, 5298 startValue, 5299 endValue, 5300 endNum, 5301 startNum, 5302 type, 5303 specialProp, 5304 p, 5305 startUnit, 5306 endUnit, 5307 relative, 5308 isTransformRelated, 5309 transformPropTween, 5310 cache, 5311 smooth, 5312 hasPriority, 5313 inlineProps
vendor: 7,960 bytes, lines 5313-5500
5313; 5314 _pluginInitted || _initCore(); 5315 this.styles = this.styles || _getStyleSaver(target); 5316 inlineProps = this.styles.props; 5317 this.tween = tween; 5318 5319 for (p in vars) { 5320 if (p === "autoRound") { 5321 continue; 5322 } 5323 5324 endValue = vars[p]; 5325 5326 if (_plugins[p] && _checkPlugin(p, vars, tween, index, target, targets)) { 5327 continue; 5328 } 5329 5330 type = typeof endValue; 5331 specialProp = _specialProps[p]; 5332 5333 if (type === "function") { 5334 endValue = endValue.call(tween, index, target, targets); 5335 type = typeof endValue; 5336 } 5337 5338 if (type === "string" && ~endValue.indexOf("random(")) { 5339 endValue = _replaceRandom(endValue); 5340 } 5341 5342 if (specialProp) { 5343 specialProp(this, target, p, endValue, tween) && (hasPriority = 1); 5344 } else if (p.substr(0, 2) === "--") { 5345 startValue = (getComputedStyle(target).getPropertyValue(p) + "").trim(); 5346 endValue += ""; 5347 _colorExp.lastIndex = 0; 5348 5349 if (!_colorExp.test(startValue)) { 5350 startUnit = getUnit(startValue); 5351 endUnit = getUnit(endValue); 5352 } 5353 5354 endUnit ? startUnit !== endUnit && (startValue = _convertToUnit(target, p, startValue, endUnit) + endUnit) : startUnit && (endValue += startUnit); 5355 this.add(style, "setProperty", startValue, endValue, index, targets, 0, 0, p); 5356 props.push(p); 5357 inlineProps.push(p, 0, style[p]); 5358 } else if (type !== "undefined") { 5359 if (startAt && p in startAt) { 5360 startValue = typeof startAt[p] === "function" ? startAt[p].call(tween, index, target, targets) : startAt[p]; 5361 _isString(startValue) && ~startValue.indexOf("random(") && (startValue = _replaceRandom(startValue)); 5362 getUnit(startValue + "") || (startValue += _config.units[p] || getUnit(_get(target, p)) || ""); 5363 (startValue + "").charAt(1) === "=" && (startValue = _get(target, p)); 5364 } else { 5365 startValue = _get(target, p); 5366 } 5367 5368 startNum = parseFloat(startValue); 5369 relative = type === "string" && endValue.charAt(1) === "=" && endValue.substr(0, 2); 5370 relative && (endValue = endValue.substr(2)); 5371 endNum = parseFloat(endValue); 5372 5373 if (p in _propertyAliases) { 5374 if (p === "autoAlpha") { 5375 if (startNum === 1 && _get(target, "visibility") === "hidden" && endNum) { 5376 startNum = 0; 5377 } 5378 5379 inlineProps.push("visibility", 0, style.visibility); 5380 5381 _addNonTweeningPT(this, style, "visibility", startNum ? "inherit" : "hidden", endNum ? "inherit" : "hidden", !endNum); 5382 } 5383 5384 if (p !== "scale" && p !== "transform") { 5385 p = _propertyAliases[p]; 5386 ~p.indexOf(",") && (p = p.split(",")[0]); 5387 } 5388 } 5389 5390 isTransformRelated = p in _transformProps; 5391 5392 if (isTransformRelated) { 5393 this.styles.save(p); 5394 5395 if (!transformPropTween) { 5396 cache = target._gsap; 5397 cache.renderTransform && !vars.parseTransform || _parseTransform(target, vars.parseTransform); 5398 smooth = vars.smoothOrigin !== false && cache.smooth; 5399 transformPropTween = this._pt = new PropTween(this._pt, style, _transformProp, 0, 1, cache.renderTransform, cache, 0, -1); 5400 transformPropTween.dep = 1; 5401 } 5402 5403 if (p === "scale") { 5404 this._pt = new PropTween(this._pt, cache, "scaleY", startNum, (relative ? _parseRelative(startNum, relative + endNum) : endNum) - startNum || 0, _renderCSSProp); 5405 this._pt.u = 0; 5406 props.push("scaleY", p); 5407 p += "X"; 5408 } else if (p === "transformOrigin") { 5409 inlineProps.push(_transformOriginProp, 0, style[_transformOriginProp]); 5410 endValue = _convertKeywordsToPercentages(endValue); 5411 5412 if (cache.svg) { 5413 _applySVGOrigin(target, endValue, 0, smooth, 0, this); 5414 } else { 5415 endUnit = parseFloat(endValue.split(" ")[2]) || 0; 5416 endUnit !== cache.zOrigin && _addNonTweeningPT(this, cache, "zOrigin", cache.zOrigin, endUnit); 5417 5418 _addNonTweeningPT(this, style, p, _firstTwoOnly(startValue), _firstTwoOnly(endValue)); 5419 } 5420 5421 continue; 5422 } else if (p === "svgOrigin") { 5423 _applySVGOrigin(target, endValue, 1, smooth, 0, this); 5424 5425 continue; 5426 } else if (p in _rotationalProperties) { 5427 _addRotationalPropTween(this, cache, p, startNum, relative ? _parseRelative(startNum, relative + endValue) : endValue); 5428 5429 continue; 5430 } else if (p === "smoothOrigin") { 5431 _addNonTweeningPT(this, cache, "smooth", cache.smooth, endValue); 5432 5433 continue; 5434 } else if (p === "force3D") { 5435 cache[p] = endValue; 5436 continue; 5437 } else if (p === "transform") { 5438 _addRawTransformPTs(this, endValue, target); 5439 5440 continue; 5441 } 5442 } else if (!(p in style)) { 5443 p = _checkPropPrefix(p) || p; 5444 } 5445 5446 if (isTransformRelated || (endNum || endNum === 0) && (startNum || startNum === 0) && !_complexExp.test(endValue) && p in style) { 5447 startUnit = (startValue + "").substr((startNum + "").length); 5448 endNum || (endNum = 0); 5449 endUnit = getUnit(endValue) || (p in _config.units ? _config.units[p] : startUnit); 5450 startUnit !== endUnit && (startNum = _convertToUnit(target, p, startValue, endUnit)); 5451 this._pt = new PropTween(this._pt, isTransformRelated ? cache : style, p, startNum, (relative ? _parseRelative(startNum, relative + endNum) : endNum) - startNum, !isTransformRelated && (endUnit === "px" || p === "zIndex") && vars.autoRound !== false ? _renderRoundedCSSProp : _renderCSSProp); 5452 this._pt.u = endUnit || 0; 5453 5454 if (startUnit !== endUnit && endUnit !== "%") { 5455 this._pt.b = startValue; 5456 this._pt.r = _renderCSSPropWithBeginning; 5457 } 5458 } else if (!(p in style)) { 5459 if (p in target) { 5460 this.add(target, p, startValue || target[p], relative ? relative + endValue : endValue, index, targets); 5461 } else { 5462 _missingPlugin(p, endValue); 5463 5464 continue; 5465 } 5466 } else { 5467 _tweenComplexCSSString.call(this, target, p, startValue, relative ? relative + endValue : endValue); 5468 } 5469 5470 isTransformRelated || (p in style ? inlineProps.push(p, 0, style[p]) : inlineProps.push(p, 1, startValue || target[p])); 5471 props.push(p); 5472 } 5473 } 5474 5475 hasPriority && _sortPropTweensByPriority(this); 5476 }, 5477 render: function render(ratio, data) { 5478 if (data.tween._time || !_reverting$1()) { 5479 var pt = data._pt; 5480 5481 while (pt) { 5482 pt.r(ratio, pt.d); 5483 pt = pt._next; 5484 } 5485 } else { 5486 data.styles.revert(); 5487 } 5488 }, 5489 get: _get, 5490 aliases: _propertyAliases, 5491 getSetter: function getSetter(target, property, plugin) { 5492 var p = _propertyAliases[property]; 5493 p && p.indexOf(",") < 0 && (property = p); 5494 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); 5495 }, 5496 core: { 5497 _removeProperty: _removeProperty, 5498 _getMatrix: _getMatrix 5499 } 5500 };
5501 gsap.utils.checkPrefix = _checkPropPrefix; 5502 gsap.core.getStyleSaver = _getStyleSaver; 5503 5504 (function (positionAndScale, rotation, others, aliases) { 5505 var all = _forEachName(positionAndScale + "," + rotation + "," + others, function (name) { 5506 _transformProps[name] = 1; 5507 }); 5508 5509 _forEachName(rotation, function (name) { 5510 _config.units[name] = "deg"; 5511 _rotationalProperties[name] = 1; 5512 }); 5513 5514 _propertyAliases[all[13]] = positionAndScale + "," + rotation; 5515 5516 _forEachName(aliases, function (name) { 5517 var split = name.split(":"); 5518 _propertyAliases[split[1]] = all[split[0]]; 5519 }); 5520 })("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"); 5521 5522 _forEachName("x,y,z,top,right,bottom,left,width,height,fontSize,padding,margin,perspective", function (name) { 5523 _config.units[name] = "px"; 5524 }); 5525 5526 gsap.registerPlugin(CSSPlugin); 5527 5528 var gsapWithCSS = gsap.registerPlugin(CSSPlugin) || gsap, 5529 TweenMaxWithCSS = gsapWithCSS.core.Tween; 5530 5531 exports.Back = Back; 5532 exports.Bounce = Bounce; 5533 exports.CSSPlugin = CSSPlugin; 5534 exports.Circ = Circ; 5535 exports.Cubic = Cubic; 5536 exports.Elastic = Elastic; 5537 exports.Expo = Expo; 5538 exports.Linear = Linear; 5539 exports.Power0 = Power0; 5540 exports.Power1 = Power1; 5541 exports.Power2 = Power2; 5542 exports.Power3 = Power3; 5543 exports.Power4 = Power4; 5544 exports.Quad = Quad; 5545 exports.Quart = Quart; 5546 exports.Quint = Quint; 5547 exports.Sine = Sine; 5548 exports.SteppedEase = SteppedEase; 5549 exports.Strong = Strong; 5550 exports.TimelineLite = Timeline; 5551 exports.TimelineMax = Timeline; 5552 exports.TweenLite = Tween; 5553 exports.TweenMax = TweenMaxWithCSS; 5554 exports.default = gsapWithCSS; 5555 exports.gsap = gsapWithCSS; 5556 5557 if (typeof(window) === 'undefined' || window !== exports) {Object.defineProperty(exports, '__esModule', { value: true });} else {delete window.default;} 5558 5559}))); 5560 5561(function(window, $) { 5562 'use strict'; 5563 var counter = 0, 5564 $headCache = $('head'), 5565 oldBigText = window.BigText, 5566 oldjQueryMethod = $.fn.bigtext, 5567 BigText = { 5568 DEBUG_MODE: false, 5569 DEFAULT_MIN_FONT_SIZE_PX: null, 5570 DEFAULT_MAX_FONT_SIZE_PX: 528, 5571 GLOBAL_STYLE_ID: 'bigtext-style', 5572 STYLE_ID: 'bigtext-id', 5573 LINE_CLASS_PREFIX: 'bigtext-line', 5574 EXEMPT_CLASS: 'bigtext-exempt', 5575 noConflict: function(restore) 5576 { 5577 if(restore) { 5578 $.fn.bigtext = oldjQueryMethod; 5579 window.BigText = oldBigText; 5580 } 5581 return BigText; 5582 }, 5583 supports: { 5584 wholeNumberFontSizeOnly: (function() { 5585 if( !( 'getComputedStyle' in window ) ) { 5586 return true; 5587 } 5588 var test = $('<div/>').css({ 5589 position: 'absolute', 5590 'font-size': '14.1px' 5591 }).insertBefore( $('script').eq(0) ), 5592 computedStyle = window.getComputedStyle( test[0], null ); 5593 5594 var ret = computedStyle && computedStyle.getPropertyValue( 'font-size' ) === '14px'; 5595 test.remove(); 5596 return ret; 5597 })() 5598 }, 5599 init: function() { 5600 if(!$('#'+BigText.GLOBAL_STYLE_ID).length) { 5601 $headCache.append(BigText.generateStyleTag(BigText.GLOBAL_STYLE_ID, ['.bigtext * { white-space: nowrap; } .bigtext > * { display: block; }', 5602 '.bigtext .' + BigText.EXEMPT_CLASS + ', .bigtext .' + BigText.EXEMPT_CLASS + ' * { white-space: normal; }'])); 5603 } 5604 }, 5605 bindResize: function(eventName, resizeFunction) { 5606 var timeoutId; 5607 $(window).unbind(eventName).bind(eventName, function() { 5608 if( timeoutId ) { 5609 clearTimeout( timeoutId ); 5610 } 5611 timeoutId = setTimeout( resizeFunction, 300 ); 5612 }); 5613 }, 5614 getStyleId: function(id) 5615 { 5616 return BigText.STYLE_ID + '-' + id; 5617 }, 5618 generateStyleTag: function(id, css) 5619 { 5620 return $('<style>' + css.join('\n') + '</style>').attr('id', id); 5621 }, 5622 clearCss: function(id) 5623 { 5624 var styleId = BigText.getStyleId(id); 5625 $('#' + styleId).remove(); 5626 }, 5627 generateCss: function(id, linesFontSizes, lineWordSpacings, minFontSizes) 5628 { 5629 var css = []; 5630 5631 BigText.clearCss(id); 5632 5633 for(var j=0, k=linesFontSizes.length; j<k; j++) { 5634 css.push('#' + id + ' .' + BigText.LINE_CLASS_PREFIX + j + ' {' + 5635 (minFontSizes[j] ? ' white-space: normal;' : '') + 5636 (linesFontSizes[j] ? ' font-size: ' + linesFontSizes[j] + 'px;' : '') + 5637 (lineWordSpacings[j] ? ' word-spacing: ' + lineWordSpacings[j] + 'px;' : '') + 5638 '}'); 5639 } 5640 5641 return BigText.generateStyleTag(BigText.getStyleId(id), css); 5642 }, 5643 jQueryMethod: function(options) 5644 {
5645 BigText.init(); 5646 5647 options = $.extend({ 5648 minfontsize: BigText.DEFAULT_MIN_FONT_SIZE_PX, 5649 maxfontsize: BigText.DEFAULT_MAX_FONT_SIZE_PX, 5650 childSelector: '', 5651 resize: true 5652 }, options || {}); 5653 5654 this.each(function() 5655 { 5656 var $t = $(this).addClass('bigtext'), 5657 maxWidth = $t.width(), 5658 id = $t.attr('id'), 5659 $children = options.childSelector ? $t.find( options.childSelector ) : $t.children(); 5660 5661 if(!id) { 5662 id = 'bigtext-id' + (counter++); 5663 $t.attr('id', id); 5664 } 5665 5666 if(options.resize) { 5667 BigText.bindResize('resize.bigtext-event-' + id, function() 5668 { 5669 // TODO only call this if the width has changed. 5670 BigText.jQueryMethod.call($('#' + id), options); 5671 }); 5672 } 5673 5674 BigText.clearCss(id); 5675 5676 $children.addClass(function(lineNumber, className) 5677 { 5678 // remove existing line classes. 5679 return [className.replace(new RegExp('\\b' + BigText.LINE_CLASS_PREFIX + '\\d+\\b'), ''), 5680 BigText.LINE_CLASS_PREFIX + lineNumber].join(' '); 5681 }); 5682 5683 var sizes = calculateSizes($t, $children, maxWidth, options.maxfontsize, options.minfontsize); 5684 $headCache.append(BigText.generateCss(id, sizes.fontSizes, sizes.wordSpacings, sizes.minFontSizes)); 5685 }); 5686 5687 return this.trigger('bigtext:complete'); 5688 } 5689 }; 5690 5691 function testLineDimensions($line, maxWidth, property, size, interval, units, previousWidth) 5692 { 5693 var width; 5694 previousWidth = typeof previousWidth === 'number' ? previousWidth : 0; 5695 $line.css(property, size + units); 5696 5697 width = $line.width(); 5698 5699 if(width >= maxWidth) { 5700 5701 $line.css(property, ''); 5702 5703 if(width === maxWidth) { 5704 return { 5705 match: 'exact', 5706 size: parseFloat((parseFloat(size) - 0.1).toFixed(3)) 5707 }; 5708 } 5709 5710 // Since this is an estimate, we calculate how far over the width we went with the new value. 5711 // If this is word-spacing (our last resort guess) and the over is less than the under, we keep the higher value. 5712 // Otherwise, we revert to the underestimate. 5713 var under = maxWidth - previousWidth, 5714 over = width - maxWidth; 5715 5716 return { 5717 match: 'estimate', 5718 size: parseFloat((parseFloat(size) - (property === 'word-spacing' && previousWidth && ( over < under ) ? 0 : interval)).toFixed(3)) 5719 }; 5720 } 5721 5722 return width; 5723 } 5724 5725 function calculateSizes($t, $children, maxWidth, maxFontSize, minFontSize) 5726 { 5727 var $c = $t.clone(true) 5728 .addClass('bigtext-cloned') 5729 .css({ 5730 fontFamily: $t.css('font-family'), 5731 textTransform: $t.css('text-transform'), 5732 wordSpacing: $t.css('word-spacing'), 5733 letterSpacing: $t.css('letter-spacing'), 5734 position: 'absolute', 5735 left: BigText.DEBUG_MODE ? 0 : -9999, 5736 top: BigText.DEBUG_MODE ? 0 : -9999 5737 }) 5738 .appendTo(document.body); 5739 5740 // font-size isn't the only thing we can modify, we can also mess with: 5741 // word-spacing and letter-spacing. WebKit does not respect subpixel 5742 // letter-spacing, word-spacing, or font-size. 5743 // TODO try -webkit-transform: scale() as a workaround. 5744 var fontSizes = [], 5745 wordSpacings = [], 5746 minFontSizes = [], 5747 ratios = []; 5748 5749 $children.css('float', 'left').each(function() { 5750 var $line = $(this), 5751 // TODO replace 8, 4 with a proportional size to the calculated font-size. 5752 intervals = BigText.supports.wholeNumberFontSizeOnly ? [8, 4, 1] : [8, 4, 1, 0.1], 5753 lineMax, 5754 newFontSize; 5755 5756 if($line.hasClass(BigText.EXEMPT_CLASS)) { 5757 fontSizes.push(null); 5758 ratios.push(null); 5759 minFontSizes.push(false); 5760 return; 5761 } 5762 5763 // TODO we can cache this ratio? 5764 var autoGuessSubtraction = 32, // font size in px 5765 currentFontSize = parseFloat($line.css('font-size')), 5766 ratio = ( $line.width() / currentFontSize ).toFixed(6); 5767 5768 newFontSize = parseInt( maxWidth / ratio, 10 ) - autoGuessSubtraction; 5769 5770 outer: for(var m=0, n=intervals.length; m<n; m++) { 5771 inner: for(var j=1, k=10; j<=k; j++) { 5772 if(newFontSize + j*intervals[m] > maxFontSize) { 5773 newFontSize = maxFontSize; 5774 break outer; 5775 } 5776 5777 lineMax = testLineDimensions($line, maxWidth, 'font-size', newFontSize + j*intervals[m], intervals[m], 'px', lineMax); 5778 if(typeof lineMax !== 'number') { 5779 newFontSize = lineMax.size; 5780 5781 if(lineMax.match === 'exact') { 5782 break outer; 5783 } 5784 break inner; 5785 } 5786 } 5787 } 5788 5789 ratios.push(maxWidth / newFontSize); 5790 5791 if(newFontSize > maxFontSize) { 5792 fontSizes.push(maxFontSize); 5793 minFontSizes.push(false); 5794 } else if(!!minFontSize && newFontSize < minFontSize) { 5795 fontSizes.push(minFontSize); 5796 minFontSizes.push(true); 5797 } else { 5798 fontSizes.push(newFontSize); 5799 minFontSizes.push(false); 5800 } 5801 }).each(function(lineNumber) { 5802 var $line = $(this), 5803 wordSpacing = 0, 5804 interval = 1, 5805 maxWordSpacing; 5806 5807 if($line.hasClass(BigText.EXEMPT_CLASS)) { 5808 wordSpacings.push(null); 5809 return; 5810 } 5811 5812 // must re-use font-size, even though it was removed above. 5813 $line.css('font-size', fontSizes[lineNumber] + 'px'); 5814 5815 for(var m=1, n=3; m<n; m+=interval) { 5816 maxWordSpacing = testLineDimensions($line, maxWidth, 'word-spacing', m, interval, 'px', maxWordSpacing); 5817 if(typeof maxWordSpacing !== 'number') { 5818 wordSpacing = maxWordSpacing.size; 5819 break; 5820 } 5821 } 5822 5823 $line.css('font-size', ''); 5824 wordSpacings.push(wordSpacing); 5825 }).removeAttr('style'); 5826 5827 if( !BigText.DEBUG_MODE ) { 5828 $c.remove(); 5829 } else { 5830 $c.css({ 5831 'background-color': 'rgba(255,255,255,.4)' 5832 }); 5833 } 5834 5835 return { 5836 fontSizes: fontSizes, 5837 wordSpacings: wordSpacings, 5838 ratios: ratios, 5839 minFontSizes: minFontSizes 5840 }; 5841 } 5842 5843 $.fn.bigtext = BigText.jQueryMethod; 5844 window.BigText = BigText; 5845 5846})(this, jQuery); 5847/*! 5848 * Isotope PACKAGED v3.0.6 5849 * 5850 * Licensed GPLv3 for open source use 5851 * or Isotope Commercial License for commercial use 5852 * 5853 * https://isotope.metafizzy.co 5854 * Copyright 2010-2018 Metafizzy
vendor: 15,902 bytes, lines 5854-6504
5854 5855 */ 5856 5857/** 5858 * Bridget makes jQuery widgets 5859 * v2.0.1 5860 * MIT license 5861 */ 5862 5863/* jshint browser: true, strict: true, undef: true, unused: true */ 5864 5865( function( window, factory ) { 5866 // universal module definition 5867 /*jshint strict: false */ /* globals define, module, require */ 5868 if ( typeof define == 'function' && define.amd ) { 5869 // AMD 5870 define( 'jquery-bridget/jquery-bridget',[ 'jquery' ], function( jQuery ) { 5871 return factory( window, jQuery ); 5872 }); 5873 } else if ( typeof module == 'object' && module.exports ) { 5874 // CommonJS 5875 module.exports = factory( 5876 window, 5877 require('jquery') 5878 ); 5879 } else { 5880 // browser global 5881 window.jQueryBridget = factory( 5882 window, 5883 window.jQuery 5884 ); 5885 } 5886 5887}( window, function factory( window, jQuery ) { 5888'use strict'; 5889 5890// ----- utils ----- // 5891 5892var arraySlice = Array.prototype.slice; 5893 5894// helper function for logging errors 5895// $.error breaks jQuery chaining 5896var console = window.console; 5897var logError = typeof console == 'undefined' ? function() {} : 5898 function( message ) { 5899 console.error( message ); 5900 }; 5901 5902// ----- jQueryBridget ----- // 5903 5904function jQueryBridget( namespace, PluginClass, $ ) { 5905 $ = $ || jQuery || window.jQuery; 5906 if ( !$ ) { 5907 return; 5908 } 5909 5910 // add option method -> $().plugin('option', {...}) 5911 if ( !PluginClass.prototype.option ) { 5912 // option setter 5913 PluginClass.prototype.option = function( opts ) { 5914 // bail out if not an object 5915 if ( !$.isPlainObject( opts ) ){ 5916 return; 5917 } 5918 this.options = $.extend( true, this.options, opts ); 5919 }; 5920 } 5921 5922 // make jQuery plugin 5923 $.fn[ namespace ] = function( arg0 /*, arg1 */ ) { 5924 if ( typeof arg0 == 'string' ) { 5925 // method call $().plugin( 'methodName', { options } ) 5926 // shift arguments by 1 5927 var args = arraySlice.call( arguments, 1 ); 5928 return methodCall( this, arg0, args ); 5929 } 5930 // just $().plugin({ options }) 5931 plainCall( this, arg0 ); 5932 return this; 5933 }; 5934 5935 // $().plugin('methodName') 5936 function methodCall( $elems, methodName, args ) { 5937 var returnValue; 5938 var pluginMethodStr = '$().' + namespace + '("' + methodName + '")'; 5939 5940 $elems.each( function( i, elem ) { 5941 // get instance 5942 var instance = $.data( elem, namespace ); 5943 if ( !instance ) { 5944 logError( namespace + ' not initialized. Cannot call methods, i.e. ' + 5945 pluginMethodStr ); 5946 return; 5947 } 5948 5949 var method = instance[ methodName ]; 5950 if ( !method || methodName.charAt(0) == '_' ) { 5951 logError( pluginMethodStr + ' is not a valid method' ); 5952 return; 5953 } 5954 5955 // apply method, get return value 5956 var value = method.apply( instance, args ); 5957 // set return value if value is returned, use only first value 5958 returnValue = returnValue === undefined ? value : returnValue; 5959 }); 5960 5961 return returnValue !== undefined ? returnValue : $elems; 5962 } 5963 5964 function plainCall( $elems, options ) { 5965 $elems.each( function( i, elem ) { 5966 var instance = $.data( elem, namespace ); 5967 if ( instance ) { 5968 // set options & init 5969 instance.option( options ); 5970 instance._init(); 5971 } else { 5972 // initialize new instance 5973 instance = new PluginClass( elem, options ); 5974 $.data( elem, namespace, instance ); 5975 } 5976 }); 5977 } 5978 5979 updateJQuery( $ ); 5980 5981} 5982 5983// ----- updateJQuery ----- // 5984 5985// set $.bridget for v1 backwards compatibility 5986function updateJQuery( $ ) { 5987 if ( !$ || ( $ && $.bridget ) ) { 5988 return; 5989 } 5990 $.bridget = jQueryBridget; 5991} 5992 5993updateJQuery( jQuery || window.jQuery ); 5994 5995// ----- ----- // 5996 5997return jQueryBridget; 5998 5999})); 6000 6001/** 6002 * EvEmitter v1.1.0 6003 * Lil' event emitter 6004 * MIT License 6005 */ 6006 6007/* jshint unused: true, undef: true, strict: true */ 6008 6009( function( global, factory ) { 6010 // universal module definition 6011 /* jshint strict: false */ /* globals define, module, window */ 6012 if ( typeof define == 'function' && define.amd ) { 6013 // AMD - RequireJS 6014 define( 'ev-emitter/ev-emitter',factory ); 6015 } else if ( typeof module == 'object' && module.exports ) { 6016 // CommonJS - Browserify, Webpack 6017 module.exports = factory(); 6018 } else { 6019 // Browser globals 6020 global.EvEmitter = factory(); 6021 } 6022 6023}( typeof window != 'undefined' ? window : this, function() { 6024 6025 6026 6027function EvEmitter() {} 6028 6029var proto = EvEmitter.prototype; 6030 6031proto.on = function( eventName, listener ) { 6032 if ( !eventName || !listener ) { 6033 return; 6034 } 6035 // set events hash 6036 var events = this._events = this._events || {}; 6037 // set listeners array 6038 var listeners = events[ eventName ] = events[ eventName ] || []; 6039 // only add once 6040 if ( listeners.indexOf( listener ) == -1 ) { 6041 listeners.push( listener ); 6042 } 6043 6044 return this; 6045}; 6046 6047proto.once = function( eventName, listener ) { 6048 if ( !eventName || !listener ) { 6049 return; 6050 } 6051 // add event 6052 this.on( eventName, listener ); 6053 // set once flag 6054 // set onceEvents hash 6055 var onceEvents = this._onceEvents = this._onceEvents || {}; 6056 // set onceListeners object 6057 var onceListeners = onceEvents[ eventName ] = onceEvents[ eventName ] || {}; 6058 // set flag 6059 onceListeners[ listener ] = true; 6060 6061 return this; 6062}; 6063 6064proto.off = function( eventName, listener ) { 6065 var listeners = this._events && this._events[ eventName ]; 6066 if ( !listeners || !listeners.length ) { 6067 return; 6068 } 6069 var index = listeners.indexOf( listener ); 6070 if ( index != -1 ) { 6071 listeners.splice( index, 1 ); 6072 } 6073 6074 return this; 6075}; 6076 6077proto.emitEvent = function( eventName, args ) { 6078 var listeners = this._events && this._events[ eventName ]; 6079 if ( !listeners || !listeners.length ) { 6080 return; 6081 } 6082 // copy over to avoid interference if .off() in listener 6083 listeners = listeners.slice(0); 6084 args = args || []; 6085 // once stuff 6086 var onceListeners = this._onceEvents && this._onceEvents[ eventName ]; 6087 6088 for ( var i=0; i < listeners.length; i++ ) { 6089 var listener = listeners[i] 6090 var isOnce = onceListeners && onceListeners[ listener ]; 6091 if ( isOnce ) { 6092 // remove listener 6093 // remove before trigger to prevent recursion 6094 this.off( eventName, listener ); 6095 // unset once flag 6096 delete onceListeners[ listener ]; 6097 } 6098 // trigger listener 6099 listener.apply( this, args ); 6100 } 6101 6102 return this; 6103}; 6104 6105proto.allOff = function() { 6106 delete this._events; 6107 delete this._onceEvents; 6108}; 6109 6110return EvEmitter; 6111 6112})); 6113 6114/*! 6115 * getSize v2.0.3 6116 * measure size of elements 6117 * MIT license 6118 */ 6119 6120/* jshint browser: true, strict: true, undef: true, unused: true */ 6121/* globals console: false */ 6122 6123( function( window, factory ) { 6124 /* jshint strict: false */ /* globals define, module */ 6125 if ( typeof define == 'function' && define.amd ) { 6126 // AMD 6127 define( 'get-size/get-size',factory ); 6128 } else if ( typeof module == 'object' && module.exports ) { 6129 // CommonJS 6130 module.exports = factory(); 6131 } else { 6132 // browser global 6133 window.getSize = factory(); 6134 } 6135 6136})( window, function factory() { 6137'use strict'; 6138 6139// -------------------------- helpers -------------------------- // 6140 6141// get a number from a string, not a percentage 6142function getStyleSize( value ) { 6143 var num = parseFloat( value ); 6144 // not a percent like '100%', and a number 6145 var isValid = value.indexOf('%') == -1 && !isNaN( num ); 6146 return isValid && num; 6147} 6148 6149function noop() {} 6150 6151var logError = typeof console == 'undefined' ? noop : 6152 function( message ) { 6153 console.error( message ); 6154 }; 6155 6156// -------------------------- measurements -------------------------- // 6157 6158var measurements = [ 6159 'paddingLeft', 6160 'paddingRight', 6161 'paddingTop', 6162 'paddingBottom', 6163 'marginLeft', 6164 'marginRight', 6165 'marginTop', 6166 'marginBottom', 6167 'borderLeftWidth', 6168 'borderRightWidth', 6169 'borderTopWidth', 6170 'borderBottomWidth' 6171]; 6172 6173var measurementsLength = measurements.length; 6174 6175function getZeroSize() { 6176 var size = { 6177 width: 0, 6178 height: 0, 6179 innerWidth: 0, 6180 innerHeight: 0, 6181 outerWidth: 0, 6182 outerHeight: 0 6183 }; 6184 for ( var i=0; i < measurementsLength; i++ ) { 6185 var measurement = measurements[i]; 6186 size[ measurement ] = 0; 6187 } 6188 return size; 6189} 6190 6191// -------------------------- getStyle -------------------------- // 6192 6193/** 6194 * getStyle, get style of element, check for Firefox bug 6195 * https://bugzilla.mozilla.org/show_bug.cgi?id=548397 6196 */ 6197function getStyle( elem ) { 6198 var style = getComputedStyle( elem ); 6199 if ( !style ) { 6200 logError( 'Style returned ' + style + 6201 '. Are you running this code in a hidden iframe on Firefox? ' + 6202 'See https://bit.ly/getsizebug1' ); 6203 } 6204 return style; 6205} 6206 6207// -------------------------- setup -------------------------- // 6208 6209var isSetup = false; 6210 6211var isBoxSizeOuter; 6212 6213/** 6214 * setup 6215 * check isBoxSizerOuter 6216 * do on first getSize() rather than on page load for Firefox bug 6217 */ 6218function setup() { 6219 // setup once 6220 if ( isSetup ) { 6221 return; 6222 } 6223 isSetup = true; 6224 6225 // -------------------------- box sizing -------------------------- // 6226 6227 /** 6228 * Chrome & Safari measure the outer-width on style.width on border-box elems 6229 * IE11 & Firefox<29 measures the inner-width 6230 */ 6231 var div = document.createElement('div'); 6232 div.style.width = '200px'; 6233 div.style.padding = '1px 2px 3px 4px'; 6234 div.style.borderStyle = 'solid'; 6235 div.style.borderWidth = '1px 2px 3px 4px'; 6236 div.style.boxSizing = 'border-box'; 6237 6238 var body = document.body || document.documentElement; 6239 body.appendChild( div ); 6240 var style = getStyle( div ); 6241 // round value for browser zoom. desandro/masonry#928 6242 isBoxSizeOuter = Math.round( getStyleSize( style.width ) ) == 200; 6243 getSize.isBoxSizeOuter = isBoxSizeOuter; 6244 6245 body.removeChild( div ); 6246} 6247 6248// -------------------------- getSize -------------------------- // 6249 6250function getSize( elem ) { 6251 setup(); 6252 6253 // use querySeletor if elem is string 6254 if ( typeof elem == 'string' ) { 6255 elem = document.querySelector( elem ); 6256 } 6257 6258 // do not proceed on non-objects 6259 if ( !elem || typeof elem != 'object' || !elem.nodeType ) { 6260 return; 6261 } 6262 6263 var style = getStyle( elem ); 6264 6265 // if hidden, everything is 0 6266 if ( style.display == 'none' ) { 6267 return getZeroSize(); 6268 } 6269 6270 var size = {}; 6271 size.width = elem.offsetWidth; 6272 size.height = elem.offsetHeight; 6273 6274 var isBorderBox = size.isBorderBox = style.boxSizing == 'border-box'; 6275 6276 // get all measurements 6277 for ( var i=0; i < measurementsLength; i++ ) { 6278 var measurement = measurements[i]; 6279 var value = style[ measurement ]; 6280 var num = parseFloat( value ); 6281 // any 'auto', 'medium' value will be 0 6282 size[ measurement ] = !isNaN( num ) ? num : 0; 6283 } 6284 6285 var paddingWidth = size.paddingLeft + size.paddingRight; 6286 var paddingHeight = size.paddingTop + size.paddingBottom; 6287 var marginWidth = size.marginLeft + size.marginRight; 6288 var marginHeight = size.marginTop + size.marginBottom; 6289 var borderWidth = size.borderLeftWidth + size.borderRightWidth; 6290 var borderHeight = size.borderTopWidth + size.borderBottomWidth; 6291 6292 var isBorderBoxSizeOuter = isBorderBox && isBoxSizeOuter; 6293 6294 // overwrite width and height if we can get it from style 6295 var styleWidth = getStyleSize( style.width ); 6296 if ( styleWidth !== false ) { 6297 size.width = styleWidth + 6298 // add padding and border unless it's already including it 6299 ( isBorderBoxSizeOuter ? 0 : paddingWidth + borderWidth ); 6300 } 6301 6302 var styleHeight = getStyleSize( style.height ); 6303 if ( styleHeight !== false ) { 6304 size.height = styleHeight + 6305 // add padding and border unless it's already including it 6306 ( isBorderBoxSizeOuter ? 0 : paddingHeight + borderHeight ); 6307 } 6308 6309 size.innerWidth = size.width - ( paddingWidth + borderWidth ); 6310 size.innerHeight = size.height - ( paddingHeight + borderHeight ); 6311 6312 size.outerWidth = size.width + marginWidth; 6313 size.outerHeight = size.height + marginHeight; 6314 6315 return size; 6316} 6317 6318return getSize; 6319 6320}); 6321 6322/** 6323 * matchesSelector v2.0.2 6324 * matchesSelector( element, '.selector' ) 6325 * MIT license 6326 */ 6327 6328/*jshint browser: true, strict: true, undef: true, unused: true */ 6329 6330( function( window, factory ) { 6331 /*global define: false, module: false */ 6332 'use strict'; 6333 // universal module definition 6334 if ( typeof define == 'function' && define.amd ) { 6335 // AMD 6336 define( 'desandro-matches-selector/matches-selector',factory ); 6337 } else if ( typeof module == 'object' && module.exports ) { 6338 // CommonJS 6339 module.exports = factory(); 6340 } else { 6341 // browser global 6342 window.matchesSelector = factory(); 6343 } 6344 6345}( window, function factory() { 6346 'use strict'; 6347 6348 var matchesMethod = ( function() { 6349 var ElemProto = window.Element.prototype; 6350 // check for the standard method name first 6351 if ( ElemProto.matches ) { 6352 return 'matches'; 6353 } 6354 // check un-prefixed 6355 if ( ElemProto.matchesSelector ) { 6356 return 'matchesSelector'; 6357 } 6358 // check vendor prefixes 6359 var prefixes = [ 'webkit', 'moz', 'ms', 'o' ]; 6360 6361 for ( var i=0; i < prefixes.length; i++ ) { 6362 var prefix = prefixes[i]; 6363 var method = prefix + 'MatchesSelector'; 6364 if ( ElemProto[ method ] ) { 6365 return method; 6366 } 6367 } 6368 })(); 6369 6370 return function matchesSelector( elem, selector ) { 6371 return elem[ matchesMethod ]( selector ); 6372 }; 6373 6374})); 6375 6376/** 6377 * Fizzy UI utils v2.0.7 6378 * MIT license 6379 */ 6380 6381/*jshint browser: true, undef: true, unused: true, strict: true */ 6382 6383( function( window, factory ) { 6384 // universal module definition 6385 /*jshint strict: false */ /*globals define, module, require */ 6386 6387 if ( typeof define == 'function' && define.amd ) { 6388 // AMD 6389 define( 'fizzy-ui-utils/utils',[ 6390 'desandro-matches-selector/matches-selector' 6391 ], function( matchesSelector ) { 6392 return factory( window, matchesSelector ); 6393 }); 6394 } else if ( typeof module == 'object' && module.exports ) { 6395 // CommonJS 6396 module.exports = factory( 6397 window, 6398 require('desandro-matches-selector') 6399 ); 6400 } else { 6401 // browser global 6402 window.fizzyUIUtils = factory( 6403 window, 6404 window.matchesSelector 6405 ); 6406 } 6407 6408}( window, function factory( window, matchesSelector ) { 6409 6410 6411 6412var utils = {}; 6413 6414// ----- extend ----- // 6415 6416// extends objects 6417utils.extend = function( a, b ) { 6418 for ( var prop in b ) { 6419 a[ prop ] = b[ prop ]; 6420 } 6421 return a; 6422}; 6423 6424// ----- modulo ----- // 6425 6426utils.modulo = function( num, div ) { 6427 return ( ( num % div ) + div ) % div; 6428}; 6429 6430// ----- makeArray ----- // 6431 6432var arraySlice = Array.prototype.slice; 6433 6434// turn element or nodeList into an array 6435utils.makeArray = function( obj ) { 6436 if ( Array.isArray( obj ) ) { 6437 // use object if already an array 6438 return obj; 6439 } 6440 // return empty array if undefined or null. #6 6441 if ( obj === null || obj === undefined ) { 6442 return []; 6443 } 6444 6445 var isArrayLike = typeof obj == 'object' && typeof obj.length == 'number'; 6446 if ( isArrayLike ) { 6447 // convert nodeList to array 6448 return arraySlice.call( obj ); 6449 } 6450 6451 // array of single index 6452 return [ obj ]; 6453}; 6454 6455// ----- removeFrom ----- // 6456 6457utils.removeFrom = function( ary, obj ) { 6458 var index = ary.indexOf( obj ); 6459 if ( index != -1 ) { 6460 ary.splice( index, 1 ); 6461 } 6462}; 6463 6464// ----- getParent ----- // 6465 6466utils.getParent = function( elem, selector ) { 6467 while ( elem.parentNode && elem != document.body ) { 6468 elem = elem.parentNode; 6469 if ( matchesSelector( elem, selector ) ) { 6470 return elem; 6471 } 6472 } 6473}; 6474 6475// ----- getQueryElement ----- // 6476 6477// use element as selector string 6478utils.getQueryElement = function( elem ) { 6479 if ( typeof elem == 'string' ) { 6480 return document.querySelector( elem ); 6481 } 6482 return elem; 6483}; 6484 6485// ----- handleEvent ----- // 6486 6487// enable .ontype to trigger from .addEventListener( elem, 'type' ) 6488utils.handleEvent = function( event ) { 6489 var method = 'on' + event.type; 6490 if ( this[ method ] ) { 6491 this[ method ]( event ); 6492 } 6493}; 6494 6495// ----- filterFindElements ----- // 6496 6497utils.filterFindElements = function( elems, selector ) { 6498 // make array of elems 6499 elems = utils.makeArray( elems ); 6500 var ffElems = []; 6501 6502 elems.forEach( function( elem ) { 6503 // check that elem is an actual element 6504
6504// START UNCODE EDIT 6505 // if ( !( elem instanceof HTMLElement ) ) { 6506 if ( !( elem instanceof HTMLElement ) && !SiteParameters.is_frontend_editor ) { 6507 // END UNCODE EDIT
vendor: 23,480 bytes, lines 6507-7419
6507 6508 return; 6509 } 6510 // add elem if no selector 6511 if ( !selector ) { 6512 ffElems.push( elem ); 6513 return; 6514 } 6515 // filter & find items if we have a selector 6516 // filter 6517 if ( matchesSelector( elem, selector ) ) { 6518 ffElems.push( elem ); 6519 } 6520 // find children 6521 var childElems = elem.querySelectorAll( selector ); 6522 // concat childElems to filterFound array 6523 for ( var i=0; i < childElems.length; i++ ) { 6524 ffElems.push( childElems[i] ); 6525 } 6526 }); 6527 6528 return ffElems; 6529}; 6530 6531// ----- debounceMethod ----- // 6532 6533utils.debounceMethod = function( _class, methodName, threshold ) { 6534 threshold = threshold || 100; 6535 // original method 6536 var method = _class.prototype[ methodName ]; 6537 var timeoutName = methodName + 'Timeout'; 6538 6539 _class.prototype[ methodName ] = function() { 6540 var timeout = this[ timeoutName ]; 6541 clearTimeout( timeout ); 6542 6543 var args = arguments; 6544 var _this = this; 6545 this[ timeoutName ] = setTimeout( function() { 6546 method.apply( _this, args ); 6547 delete _this[ timeoutName ]; 6548 }, threshold ); 6549 }; 6550}; 6551 6552// ----- docReady ----- // 6553 6554utils.docReady = function( callback ) { 6555 var readyState = document.readyState; 6556 if ( readyState == 'complete' || readyState == 'interactive' ) { 6557 // do async to allow for other scripts to run. metafizzy/flickity#441 6558 setTimeout( callback ); 6559 } else { 6560 document.addEventListener( 'DOMContentLoaded', callback ); 6561 } 6562}; 6563 6564// ----- htmlInit ----- // 6565 6566// http://jamesroberts.name/blog/2010/02/22/string-functions-for-javascript-trim-to-camel-case-to-dashed-and-to-underscore/ 6567utils.toDashed = function( str ) { 6568 return str.replace( /(.)([A-Z])/g, function( match, $1, $2 ) { 6569 return $1 + '-' + $2; 6570 }).toLowerCase(); 6571}; 6572 6573var console = window.console; 6574/** 6575 * allow user to initialize classes via [data-namespace] or .js-namespace class 6576 * htmlInit( Widget, 'widgetName' ) 6577 * options are parsed from data-namespace-options 6578 */ 6579utils.htmlInit = function( WidgetClass, namespace ) { 6580 utils.docReady( function() { 6581 var dashedNamespace = utils.toDashed( namespace ); 6582 var dataAttr = 'data-' + dashedNamespace; 6583 var dataAttrElems = document.querySelectorAll( '[' + dataAttr + ']' ); 6584 var jsDashElems = document.querySelectorAll( '.js-' + dashedNamespace ); 6585 var elems = utils.makeArray( dataAttrElems ) 6586 .concat( utils.makeArray( jsDashElems ) ); 6587 var dataOptionsAttr = dataAttr + '-options'; 6588 var jQuery = window.jQuery; 6589 6590 elems.forEach( function( elem ) { 6591 var attr = elem.getAttribute( dataAttr ) || 6592 elem.getAttribute( dataOptionsAttr ); 6593 var options; 6594 try { 6595 options = attr && JSON.parse( attr ); 6596 } catch ( error ) { 6597 // log error, do not initialize 6598 if ( console ) { 6599 console.error( 'Error parsing ' + dataAttr + ' on ' + elem.className + 6600 ': ' + error ); 6601 } 6602 return; 6603 } 6604 // initialize 6605 var instance = new WidgetClass( elem, options ); 6606 // make available via $().data('namespace') 6607 if ( jQuery ) { 6608 jQuery.data( elem, namespace, instance ); 6609 } 6610 }); 6611 6612 }); 6613}; 6614 6615// ----- ----- // 6616 6617return utils; 6618 6619})); 6620 6621/** 6622 * Outlayer Item 6623 */ 6624 6625( function( window, factory ) { 6626 // universal module definition 6627 /* jshint strict: false */ /* globals define, module, require */ 6628 if ( typeof define == 'function' && define.amd ) { 6629 // AMD - RequireJS 6630 define( 'outlayer/item',[ 6631 'ev-emitter/ev-emitter', 6632 'get-size/get-size' 6633 ], 6634 factory 6635 ); 6636 } else if ( typeof module == 'object' && module.exports ) { 6637 // CommonJS - Browserify, Webpack 6638 module.exports = factory( 6639 require('ev-emitter'), 6640 require('get-size') 6641 ); 6642 } else { 6643 // browser global 6644 window.Outlayer = {}; 6645 window.Outlayer.Item = factory( 6646 window.EvEmitter, 6647 window.getSize 6648 ); 6649 } 6650 6651}( window, function factory( EvEmitter, getSize ) { 6652'use strict'; 6653 6654// ----- helpers ----- // 6655 6656function isEmptyObj( obj ) { 6657 for ( var prop in obj ) { 6658 return false; 6659 } 6660 prop = null; 6661 return true; 6662} 6663 6664// -------------------------- CSS3 support -------------------------- // 6665 6666 6667var docElemStyle = document.documentElement.style; 6668 6669var transitionProperty = typeof docElemStyle.transition == 'string' ? 6670 'transition' : 'WebkitTransition'; 6671var transformProperty = typeof docElemStyle.transform == 'string' ? 6672 'transform' : 'WebkitTransform'; 6673 6674var transitionEndEvent = { 6675 WebkitTransition: 'webkitTransitionEnd', 6676 transition: 'transitionend' 6677}[ transitionProperty ]; 6678 6679// cache all vendor properties that could have vendor prefix 6680var vendorProperties = { 6681 transform: transformProperty, 6682 transition: transitionProperty, 6683 transitionDuration: transitionProperty + 'Duration', 6684 transitionProperty: transitionProperty + 'Property', 6685 transitionDelay: transitionProperty + 'Delay' 6686}; 6687 6688// -------------------------- Item -------------------------- // 6689 6690function Item( element, layout ) { 6691 if ( !element ) { 6692 return; 6693 } 6694 6695 this.element = element; 6696 // parent layout class, i.e. Masonry, Isotope, or Packery 6697 this.layout = layout; 6698 this.position = { 6699 x: 0, 6700 y: 0 6701 }; 6702 6703 this._create(); 6704} 6705 6706// inherit EvEmitter 6707var proto = Item.prototype = Object.create( EvEmitter.prototype ); 6708proto.constructor = Item; 6709 6710proto._create = function() { 6711 // transition objects 6712 this._transn = { 6713 ingProperties: {}, 6714 clean: {}, 6715 onEnd: {} 6716 }; 6717 6718 this.css({ 6719 position: 'absolute' 6720 }); 6721}; 6722 6723// trigger specified handler for event type 6724proto.handleEvent = function( event ) { 6725 var method = 'on' + event.type; 6726 if ( this[ method ] ) { 6727 this[ method ]( event ); 6728 } 6729}; 6730 6731proto.getSize = function() { 6732 this.size = getSize( this.element ); 6733}; 6734 6735/** 6736 * apply CSS styles to element 6737 * @param {Object} style 6738 */ 6739proto.css = function( style ) { 6740 var elemStyle = this.element.style; 6741 6742 for ( var prop in style ) { 6743 // use vendor property if available 6744 var supportedProp = vendorProperties[ prop ] || prop; 6745 elemStyle[ supportedProp ] = style[ prop ]; 6746 } 6747}; 6748 6749 // measure position, and sets it 6750proto.getPosition = function() { 6751 var style = getComputedStyle( this.element ); 6752 var isOriginLeft = this.layout._getOption('originLeft'); 6753 var isOriginTop = this.layout._getOption('originTop'); 6754 var xValue = style[ isOriginLeft ? 'left' : 'right' ]; 6755 var yValue = style[ isOriginTop ? 'top' : 'bottom' ]; 6756 var x = parseFloat( xValue ); 6757 var y = parseFloat( yValue ); 6758 // convert percent to pixels 6759 var layoutSize = this.layout.size; 6760 if ( xValue.indexOf('%') != -1 ) { 6761 x = ( x / 100 ) * layoutSize.width; 6762 } 6763 if ( yValue.indexOf('%') != -1 ) { 6764 y = ( y / 100 ) * layoutSize.height; 6765 } 6766 // clean up 'auto' or other non-integer values 6767 x = isNaN( x ) ? 0 : x; 6768 y = isNaN( y ) ? 0 : y; 6769 // remove padding from measurement 6770 x -= isOriginLeft ? layoutSize.paddingLeft : layoutSize.paddingRight; 6771 y -= isOriginTop ? layoutSize.paddingTop : layoutSize.paddingBottom; 6772 6773 this.position.x = x; 6774 this.position.y = y; 6775}; 6776 6777// set settled position, apply padding 6778proto.layoutPosition = function() { 6779 var layoutSize = this.layout.size; 6780 var style = {}; 6781 var isOriginLeft = this.layout._getOption('originLeft'); 6782 var isOriginTop = this.layout._getOption('originTop'); 6783 6784 // x 6785 var xPadding = isOriginLeft ? 'paddingLeft' : 'paddingRight'; 6786 var xProperty = isOriginLeft ? 'left' : 'right'; 6787 var xResetProperty = isOriginLeft ? 'right' : 'left'; 6788 6789 var x = this.position.x + layoutSize[ xPadding ]; 6790 // set in percentage or pixels 6791 style[ xProperty ] = this.getXValue( x ); 6792 // reset other property 6793 style[ xResetProperty ] = ''; 6794 6795 // y 6796 var yPadding = isOriginTop ? 'paddingTop' : 'paddingBottom'; 6797 var yProperty = isOriginTop ? 'top' : 'bottom'; 6798 var yResetProperty = isOriginTop ? 'bottom' : 'top'; 6799 6800 var y = this.position.y + layoutSize[ yPadding ]; 6801 // set in percentage or pixels 6802 style[ yProperty ] = this.getYValue( y ); 6803 // reset other property 6804 style[ yResetProperty ] = ''; 6805 6806 this.css( style ); 6807 this.emitEvent( 'layout', [ this ] ); 6808}; 6809 6810proto.getXValue = function( x ) { 6811 var isHorizontal = this.layout._getOption('horizontal'); 6812 return this.layout.options.percentPosition && !isHorizontal ? 6813 ( ( x / this.layout.size.width ) * 100 ) + '%' : x + 'px'; 6814}; 6815 6816proto.getYValue = function( y ) { 6817 var isHorizontal = this.layout._getOption('horizontal'); 6818 return this.layout.options.percentPosition && isHorizontal ? 6819 ( ( y / this.layout.size.height ) * 100 ) + '%' : y + 'px'; 6820}; 6821 6822proto._transitionTo = function( x, y ) { 6823 this.getPosition(); 6824 // get current x & y from top/left 6825 var curX = this.position.x; 6826 var curY = this.position.y; 6827 6828 var didNotMove = x == this.position.x && y == this.position.y; 6829 6830 // save end position 6831 this.setPosition( x, y ); 6832 6833 // if did not move and not transitioning, just go to layout 6834 if ( didNotMove && !this.isTransitioning ) { 6835 this.layoutPosition(); 6836 return; 6837 } 6838 6839 var transX = x - curX; 6840 var transY = y - curY; 6841 var transitionStyle = {}; 6842 transitionStyle.transform = this.getTranslate( transX, transY ); 6843 6844 this.transition({ 6845 to: transitionStyle, 6846 onTransitionEnd: { 6847 transform: this.layoutPosition 6848 }, 6849 isCleaning: true 6850 }); 6851}; 6852 6853proto.getTranslate = function( x, y ) { 6854 // flip cooridinates if origin on right or bottom 6855 var isOriginLeft = this.layout._getOption('originLeft'); 6856 var isOriginTop = this.layout._getOption('originTop'); 6857 x = isOriginLeft ? x : -x; 6858 y = isOriginTop ? y : -y; 6859 return 'translate3d(' + x + 'px, ' + y + 'px, 0)'; 6860}; 6861 6862// non transition + transform support 6863proto.goTo = function( x, y ) { 6864 this.setPosition( x, y ); 6865 this.layoutPosition(); 6866}; 6867 6868proto.moveTo = proto._transitionTo; 6869 6870proto.setPosition = function( x, y ) { 6871 this.position.x = parseFloat( x ); 6872 this.position.y = parseFloat( y ); 6873}; 6874 6875// ----- transition ----- // 6876 6877/** 6878 * @param {Object} style - CSS 6879 * @param {Function} onTransitionEnd 6880 */ 6881 6882// non transition, just trigger callback 6883proto._nonTransition = function( args ) { 6884 this.css( args.to ); 6885 if ( args.isCleaning ) { 6886 this._removeStyles( args.to ); 6887 } 6888 for ( var prop in args.onTransitionEnd ) { 6889 args.onTransitionEnd[ prop ].call( this ); 6890 } 6891}; 6892 6893/** 6894 * proper transition 6895 * @param {Object} args - arguments 6896 * @param {Object} to - style to transition to 6897 * @param {Object} from - style to start transition from 6898 * @param {Boolean} isCleaning - removes transition styles after transition 6899 * @param {Function} onTransitionEnd - callback 6900 */ 6901proto.transition = function( args ) { 6902 // redirect to nonTransition if no transition duration 6903 if ( !parseFloat( this.layout.options.transitionDuration ) ) { 6904 this._nonTransition( args ); 6905 return; 6906 } 6907 6908 var _transition = this._transn; 6909 // keep track of onTransitionEnd callback by css property 6910 for ( var prop in args.onTransitionEnd ) { 6911 _transition.onEnd[ prop ] = args.onTransitionEnd[ prop ]; 6912 } 6913 // keep track of properties that are transitioning 6914 for ( prop in args.to ) { 6915 _transition.ingProperties[ prop ] = true; 6916 // keep track of properties to clean up when transition is done 6917 if ( args.isCleaning ) { 6918 _transition.clean[ prop ] = true; 6919 } 6920 } 6921 6922 // set from styles 6923 if ( args.from ) { 6924 this.css( args.from ); 6925 // force redraw. http://blog.alexmaccaw.com/css-transitions 6926 var h = this.element.offsetHeight; 6927 // hack for JSHint to hush about unused var 6928 h = null; 6929 } 6930 // enable transition 6931 this.enableTransition( args.to ); 6932 // set styles that are transitioning 6933 this.css( args.to ); 6934 6935 this.isTransitioning = true; 6936 6937}; 6938 6939// dash before all cap letters, including first for 6940// WebkitTransform => -webkit-transform 6941function toDashedAll( str ) { 6942 return str.replace( /([A-Z])/g, function( $1 ) { 6943 return '-' + $1.toLowerCase(); 6944 }); 6945} 6946 6947var transitionProps = 'opacity,' + toDashedAll( transformProperty ); 6948 6949proto.enableTransition = function(/* style */) { 6950 // HACK changing transitionProperty during a transition 6951 // will cause transition to jump 6952 if ( this.isTransitioning ) { 6953 return; 6954 } 6955 6956 // make `transition: foo, bar, baz` from style object 6957 // HACK un-comment this when enableTransition can work 6958 // while a transition is happening 6959 // var transitionValues = []; 6960 // for ( var prop in style ) { 6961 // // dash-ify camelCased properties like WebkitTransition 6962 // prop = vendorProperties[ prop ] || prop; 6963 // transitionValues.push( toDashedAll( prop ) ); 6964 // } 6965 // munge number to millisecond, to match stagger 6966 var duration = this.layout.options.transitionDuration; 6967 duration = typeof duration == 'number' ? duration + 'ms' : duration; 6968 // enable transition styles 6969 this.css({ 6970 transitionProperty: transitionProps, 6971 transitionDuration: duration, 6972 transitionDelay: this.staggerDelay || 0 6973 }); 6974 // listen for transition end event 6975 this.element.addEventListener( transitionEndEvent, this, false ); 6976}; 6977 6978// ----- events ----- // 6979 6980proto.onwebkitTransitionEnd = function( event ) { 6981 this.ontransitionend( event ); 6982}; 6983 6984proto.onotransitionend = function( event ) { 6985 this.ontransitionend( event ); 6986}; 6987 6988// properties that I munge to make my life easier 6989var dashedVendorProperties = { 6990 '-webkit-transform': 'transform' 6991}; 6992 6993proto.ontransitionend = function( event ) { 6994 // disregard bubbled events from children 6995 if ( event.target !== this.element ) { 6996 return; 6997 } 6998 var _transition = this._transn; 6999 // get property name of transitioned property, convert to prefix-free 7000 var propertyName = dashedVendorProperties[ event.propertyName ] || event.propertyName; 7001 7002 // remove property that has completed transitioning 7003 delete _transition.ingProperties[ propertyName ]; 7004 // check if any properties are still transitioning 7005 if ( isEmptyObj( _transition.ingProperties ) ) { 7006 // all properties have completed transitioning 7007 this.disableTransition(); 7008 } 7009 // clean style 7010 if ( propertyName in _transition.clean ) { 7011 // clean up style 7012 this.element.style[ event.propertyName ] = ''; 7013 delete _transition.clean[ propertyName ]; 7014 } 7015 // trigger onTransitionEnd callback 7016 if ( propertyName in _transition.onEnd ) { 7017 var onTransitionEnd = _transition.onEnd[ propertyName ]; 7018 onTransitionEnd.call( this ); 7019 delete _transition.onEnd[ propertyName ]; 7020 } 7021 7022 this.emitEvent( 'transitionEnd', [ this ] ); 7023}; 7024 7025proto.disableTransition = function() { 7026 this.removeTransitionStyles(); 7027 this.element.removeEventListener( transitionEndEvent, this, false ); 7028 this.isTransitioning = false; 7029}; 7030 7031/** 7032 * removes style property from element 7033 * @param {Object} style 7034**/ 7035proto._removeStyles = function( style ) { 7036 // clean up transition styles 7037 var cleanStyle = {}; 7038 for ( var prop in style ) { 7039 cleanStyle[ prop ] = ''; 7040 } 7041 this.css( cleanStyle ); 7042}; 7043 7044var cleanTransitionStyle = { 7045 transitionProperty: '', 7046 transitionDuration: '', 7047 transitionDelay: '' 7048}; 7049 7050proto.removeTransitionStyles = function() { 7051 // remove transition 7052 this.css( cleanTransitionStyle ); 7053}; 7054 7055// ----- stagger ----- // 7056 7057proto.stagger = function( delay ) { 7058 delay = isNaN( delay ) ? 0 : delay; 7059 this.staggerDelay = delay + 'ms'; 7060}; 7061 7062// ----- show/hide/remove ----- // 7063 7064// remove element from DOM 7065proto.removeElem = function() { 7066 this.element.parentNode.removeChild( this.element ); 7067 // remove display: none 7068 this.css({ display: '' }); 7069 this.emitEvent( 'remove', [ this ] ); 7070}; 7071 7072proto.remove = function() { 7073 // just remove element if no transition support or no transition 7074 if ( !transitionProperty || !parseFloat( this.layout.options.transitionDuration ) ) { 7075 this.removeElem(); 7076 return; 7077 } 7078 7079 // start transition 7080 this.once( 'transitionEnd', function() { 7081 this.removeElem(); 7082 }); 7083 this.hide(); 7084}; 7085 7086proto.reveal = function() { 7087 delete this.isHidden; 7088 // remove display: none 7089 this.css({ display: '' }); 7090 7091 var options = this.layout.options; 7092 7093 var onTransitionEnd = {}; 7094 var transitionEndProperty = this.getHideRevealTransitionEndProperty('visibleStyle'); 7095 onTransitionEnd[ transitionEndProperty ] = this.onRevealTransitionEnd; 7096 7097 this.transition({ 7098 from: options.hiddenStyle, 7099 to: options.visibleStyle, 7100 isCleaning: true, 7101 onTransitionEnd: onTransitionEnd 7102 }); 7103}; 7104 7105proto.onRevealTransitionEnd = function() { 7106 // check if still visible 7107 // during transition, item may have been hidden 7108 if ( !this.isHidden ) { 7109 this.emitEvent('reveal'); 7110 } 7111}; 7112 7113/** 7114 * get style property use for hide/reveal transition end 7115 * @param {String} styleProperty - hiddenStyle/visibleStyle 7116 * @returns {String} 7117 */ 7118proto.getHideRevealTransitionEndProperty = function( styleProperty ) { 7119 var optionStyle = this.layout.options[ styleProperty ]; 7120 // use opacity 7121 if ( optionStyle.opacity ) { 7122 return 'opacity'; 7123 } 7124 // get first property 7125 for ( var prop in optionStyle ) { 7126 return prop; 7127 } 7128}; 7129 7130proto.hide = function() { 7131 // set flag 7132 this.isHidden = true; 7133 // remove display: none 7134 this.css({ display: '' }); 7135 7136 var options = this.layout.options; 7137 7138 var onTransitionEnd = {}; 7139 var transitionEndProperty = this.getHideRevealTransitionEndProperty('hiddenStyle'); 7140 onTransitionEnd[ transitionEndProperty ] = this.onHideTransitionEnd; 7141 7142 this.transition({ 7143 from: options.visibleStyle, 7144 to: options.hiddenStyle, 7145 // keep hidden stuff hidden 7146 isCleaning: true, 7147 onTransitionEnd: onTransitionEnd 7148 }); 7149}; 7150 7151proto.onHideTransitionEnd = function() { 7152 // check if still hidden 7153 // during transition, item may have been un-hidden 7154 if ( this.isHidden ) { 7155 this.css({ display: 'none' }); 7156 this.emitEvent('hide'); 7157 } 7158}; 7159 7160proto.destroy = function() { 7161 this.css({ 7162 position: '', 7163 left: '', 7164 right: '', 7165 top: '', 7166 bottom: '', 7167 transition: '', 7168 transform: '' 7169 }); 7170}; 7171 7172return Item; 7173 7174})); 7175 7176/*! 7177 * Outlayer v2.1.1 7178 * the brains and guts of a layout library 7179 * MIT license 7180 */ 7181 7182( function( window, factory ) { 7183 'use strict'; 7184 // universal module definition 7185 /* jshint strict: false */ /* globals define, module, require */ 7186 if ( typeof define == 'function' && define.amd ) { 7187 // AMD - RequireJS 7188 define( 'outlayer/outlayer',[ 7189 'ev-emitter/ev-emitter', 7190 'get-size/get-size', 7191 'fizzy-ui-utils/utils', 7192 './item' 7193 ], 7194 function( EvEmitter, getSize, utils, Item ) { 7195 return factory( window, EvEmitter, getSize, utils, Item); 7196 } 7197 ); 7198 } else if ( typeof module == 'object' && module.exports ) { 7199 // CommonJS - Browserify, Webpack 7200 module.exports = factory( 7201 window, 7202 require('ev-emitter'), 7203 require('get-size'), 7204 require('fizzy-ui-utils'), 7205 require('./item') 7206 ); 7207 } else { 7208 // browser global 7209 window.Outlayer = factory( 7210 window, 7211 window.EvEmitter, 7212 window.getSize, 7213 window.fizzyUIUtils, 7214 window.Outlayer.Item 7215 ); 7216 } 7217 7218}( window, function factory( window, EvEmitter, getSize, utils, Item ) { 7219'use strict'; 7220 7221// ----- vars ----- // 7222 7223var console = window.console; 7224var jQuery = window.jQuery; 7225var noop = function() {}; 7226 7227// -------------------------- Outlayer -------------------------- // 7228 7229// globally unique identifiers 7230var GUID = 0; 7231// internal store of all Outlayer intances 7232var instances = {}; 7233 7234 7235/** 7236 * @param {Element, String} element 7237 * @param {Object} options 7238 * @constructor 7239 */ 7240function Outlayer( element, options ) { 7241 var queryElement = utils.getQueryElement( element ); 7242 if ( !queryElement ) { 7243 if ( console ) { 7244 console.error( 'Bad element for ' + this.constructor.namespace + 7245 ': ' + ( queryElement || element ) ); 7246 } 7247 return; 7248 } 7249 this.element = queryElement; 7250 // add jQuery 7251 if ( jQuery ) { 7252 this.$element = jQuery( this.element ); 7253 } 7254 7255 // options 7256 this.options = utils.extend( {}, this.constructor.defaults ); 7257 this.option( options ); 7258 7259 // add id for Outlayer.getFromElement 7260 var id = ++GUID; 7261 this.element.outlayerGUID = id; // expando 7262 instances[ id ] = this; // associate via id 7263 7264 // kick it off 7265 this._create(); 7266 7267 var isInitLayout = this._getOption('initLayout'); 7268 if ( isInitLayout ) { 7269 this.layout(); 7270 } 7271} 7272 7273// settings are for internal use only 7274Outlayer.namespace = 'outlayer'; 7275Outlayer.Item = Item; 7276 7277// default options 7278Outlayer.defaults = { 7279 containerStyle: { 7280 position: 'relative' 7281 }, 7282 initLayout: true, 7283 originLeft: true, 7284 originTop: true, 7285 resize: true, 7286 resizeContainer: true, 7287 // item options 7288 transitionDuration: '0.4s', 7289 hiddenStyle: { 7290 opacity: 0, 7291 transform: 'scale(0.001)' 7292 }, 7293 visibleStyle: { 7294 opacity: 1, 7295 transform: 'scale(1)' 7296 } 7297}; 7298 7299var proto = Outlayer.prototype; 7300// inherit EvEmitter 7301utils.extend( proto, EvEmitter.prototype ); 7302 7303/** 7304 * set options 7305 * @param {Object} opts 7306 */ 7307proto.option = function( opts ) { 7308 utils.extend( this.options, opts ); 7309}; 7310 7311/** 7312 * get backwards compatible option value, check old name 7313 */ 7314proto._getOption = function( option ) { 7315 var oldOption = this.constructor.compatOptions[ option ]; 7316 return oldOption && this.options[ oldOption ] !== undefined ? 7317 this.options[ oldOption ] : this.options[ option ]; 7318}; 7319 7320Outlayer.compatOptions = { 7321 // currentName: oldName 7322 initLayout: 'isInitLayout', 7323 horizontal: 'isHorizontal', 7324 layoutInstant: 'isLayoutInstant', 7325 originLeft: 'isOriginLeft', 7326 originTop: 'isOriginTop', 7327 resize: 'isResizeBound', 7328 resizeContainer: 'isResizingContainer' 7329}; 7330 7331proto._create = function() { 7332 // get items from children 7333 this.reloadItems(); 7334 // elements that affect layout, but are not laid out 7335 this.stamps = []; 7336 this.stamp( this.options.stamp ); 7337 // set container style 7338 utils.extend( this.element.style, this.options.containerStyle ); 7339 7340 // bind resize method 7341 var canBindResize = this._getOption('resize'); 7342 if ( canBindResize ) { 7343 this.bindResize(); 7344 } 7345}; 7346 7347// goes through all children again and gets bricks in proper order 7348proto.reloadItems = function() { 7349 // collection of item elements 7350 this.items = this._itemize( this.element.children ); 7351}; 7352 7353 7354/** 7355 * turn elements into Outlayer.Items to be used in layout 7356 * @param {Array or NodeList or HTMLElement} elems 7357 * @returns {Array} items - collection of new Outlayer Items 7358 */ 7359proto._itemize = function( elems ) { 7360 7361 var itemElems = this._filterFindItemElements( elems ); 7362 var Item = this.constructor.Item; 7363 7364 // create new Outlayer Items for collection 7365 var items = []; 7366 for ( var i=0; i < itemElems.length; i++ ) { 7367 var elem = itemElems[i]; 7368 var item = new Item( elem, this ); 7369 items.push( item ); 7370 } 7371 7372 return items; 7373}; 7374 7375/** 7376 * get item elements to be used in layout 7377 * @param {Array or NodeList or HTMLElement} elems 7378 * @returns {Array} items - item elements 7379 */ 7380proto._filterFindItemElements = function( elems ) { 7381 return utils.filterFindElements( elems, this.options.itemSelector ); 7382}; 7383 7384/** 7385 * getter method for getting item elements 7386 * @returns {Array} elems - collection of item elements 7387 */ 7388proto.getItemElements = function() { 7389 return this.items.map( function( item ) { 7390 return item.element; 7391 }); 7392}; 7393 7394// ----- init & layout ----- // 7395 7396/** 7397 * lays out all items 7398 */ 7399proto.layout = function() { 7400 this._resetLayout(); 7401 this._manageStamps(); 7402 7403 // don't animate first layout 7404 var layoutInstant = this._getOption('layoutInstant'); 7405 var isInstant = layoutInstant !== undefined ? 7406 layoutInstant : !this._isLayoutInited; 7407 this.layoutItems( this.items, isInstant ); 7408 7409 // flag for initalized 7410 this._isLayoutInited = true; 7411}; 7412 7413// _init is alias for layout 7414proto._init = proto.layout; 7415 7416/** 7417 * logic before any new layout 7418 */ 7419proto._resetLayout = function() {
vendor: 13,499 bytes, lines 7420-7988
7420 this.getSize(); 7421}; 7422 7423 7424proto.getSize = function() { 7425 this.size = getSize( this.element ); 7426}; 7427 7428/** 7429 * get measurement from option, for columnWidth, rowHeight, gutter 7430 * if option is String -> get element from selector string, & get size of element 7431 * if option is Element -> get size of element 7432 * else use option as a number 7433 * 7434 * @param {String} measurement 7435 * @param {String} size - width or height 7436 * @private 7437 */ 7438proto._getMeasurement = function( measurement, size ) { 7439 var option = this.options[ measurement ]; 7440 var elem; 7441 if ( !option ) { 7442 // default to 0 7443 this[ measurement ] = 0; 7444 } else { 7445 // use option as an element 7446 if ( typeof option == 'string' ) { 7447 elem = this.element.querySelector( option ); 7448 } else if ( option instanceof HTMLElement ) { 7449 elem = option; 7450 } 7451 // use size of element, if element 7452 this[ measurement ] = elem ? getSize( elem )[ size ] : option; 7453 } 7454}; 7455 7456/** 7457 * layout a collection of item elements 7458 * @api public 7459 */ 7460proto.layoutItems = function( items, isInstant ) { 7461 items = this._getItemsForLayout( items ); 7462 7463 this._layoutItems( items, isInstant ); 7464 7465 this._postLayout(); 7466}; 7467 7468/** 7469 * get the items to be laid out 7470 * you may want to skip over some items 7471 * @param {Array} items 7472 * @returns {Array} items 7473 */ 7474proto._getItemsForLayout = function( items ) { 7475 return items.filter( function( item ) { 7476 return !item.isIgnored; 7477 }); 7478}; 7479 7480/** 7481 * layout items 7482 * @param {Array} items 7483 * @param {Boolean} isInstant 7484 */ 7485proto._layoutItems = function( items, isInstant ) { 7486 this._emitCompleteOnItems( 'layout', items ); 7487 7488 if ( !items || !items.length ) { 7489 // no items, emit event with empty array 7490 return; 7491 } 7492 7493 var queue = []; 7494 7495 items.forEach( function( item ) { 7496 // get x/y object from method 7497 var position = this._getItemLayoutPosition( item ); 7498 // enqueue 7499 position.item = item; 7500 position.isInstant = isInstant || item.isLayoutInstant; 7501 queue.push( position ); 7502 }, this ); 7503 7504 this._processLayoutQueue( queue ); 7505}; 7506 7507/** 7508 * get item layout position 7509 * @param {Outlayer.Item} item 7510 * @returns {Object} x and y position 7511 */ 7512proto._getItemLayoutPosition = function( /* item */ ) { 7513 return { 7514 x: 0, 7515 y: 0 7516 }; 7517}; 7518 7519/** 7520 * iterate over array and position each item 7521 * Reason being - separating this logic prevents 'layout invalidation' 7522 * thx @paul_irish 7523 * @param {Array} queue 7524 */ 7525proto._processLayoutQueue = function( queue ) { 7526 this.updateStagger(); 7527 queue.forEach( function( obj, i ) { 7528 this._positionItem( obj.item, obj.x, obj.y, obj.isInstant, i ); 7529 }, this ); 7530}; 7531 7532// set stagger from option in milliseconds number 7533proto.updateStagger = function() { 7534 var stagger = this.options.stagger; 7535 if ( stagger === null || stagger === undefined ) { 7536 this.stagger = 0; 7537 return; 7538 } 7539 this.stagger = getMilliseconds( stagger ); 7540 return this.stagger; 7541}; 7542 7543/** 7544 * Sets position of item in DOM 7545 * @param {Outlayer.Item} item 7546 * @param {Number} x - horizontal position 7547 * @param {Number} y - vertical position 7548 * @param {Boolean} isInstant - disables transitions 7549 */ 7550proto._positionItem = function( item, x, y, isInstant, i ) { 7551 if ( isInstant ) { 7552 // if not transition, just set CSS 7553 item.goTo( x, y ); 7554 } else { 7555 item.stagger( i * this.stagger ); 7556 item.moveTo( x, y ); 7557 } 7558}; 7559 7560/** 7561 * Any logic you want to do after each layout, 7562 * i.e. size the container 7563 */ 7564proto._postLayout = function() { 7565 this.resizeContainer(); 7566}; 7567 7568proto.resizeContainer = function() { 7569 var isResizingContainer = this._getOption('resizeContainer'); 7570 if ( !isResizingContainer ) { 7571 return; 7572 } 7573 var size = this._getContainerSize(); 7574 if ( size ) { 7575 this._setContainerMeasure( size.width, true ); 7576 this._setContainerMeasure( size.height, false ); 7577 } 7578}; 7579 7580/** 7581 * Sets width or height of container if returned 7582 * @returns {Object} size 7583 * @param {Number} width 7584 * @param {Number} height 7585 */ 7586proto._getContainerSize = noop; 7587 7588/** 7589 * @param {Number} measure - size of width or height 7590 * @param {Boolean} isWidth 7591 */ 7592proto._setContainerMeasure = function( measure, isWidth ) { 7593 if ( measure === undefined ) { 7594 return; 7595 } 7596 7597 var elemSize = this.size; 7598 // add padding and border width if border box 7599 if ( elemSize.isBorderBox ) { 7600 measure += isWidth ? elemSize.paddingLeft + elemSize.paddingRight + 7601 elemSize.borderLeftWidth + elemSize.borderRightWidth : 7602 elemSize.paddingBottom + elemSize.paddingTop + 7603 elemSize.borderTopWidth + elemSize.borderBottomWidth; 7604 } 7605 7606 measure = Math.max( measure, 0 ); 7607 this.element.style[ isWidth ? 'width' : 'height' ] = measure + 'px'; 7608}; 7609 7610/** 7611 * emit eventComplete on a collection of items events 7612 * @param {String} eventName 7613 * @param {Array} items - Outlayer.Items 7614 */ 7615proto._emitCompleteOnItems = function( eventName, items ) { 7616 var _this = this; 7617 function onComplete() { 7618 _this.dispatchEvent( eventName + 'Complete', null, [ items ] ); 7619 } 7620 7621 var count = items.length; 7622 if ( !items || !count ) { 7623 onComplete(); 7624 return; 7625 } 7626 7627 var doneCount = 0; 7628 function tick() { 7629 doneCount++; 7630 if ( doneCount == count ) { 7631 onComplete(); 7632 } 7633 } 7634 7635 // bind callback 7636 items.forEach( function( item ) { 7637 item.once( eventName, tick ); 7638 }); 7639}; 7640 7641/** 7642 * emits events via EvEmitter and jQuery events 7643 * @param {String} type - name of event 7644 * @param {Event} event - original event 7645 * @param {Array} args - extra arguments 7646 */ 7647proto.dispatchEvent = function( type, event, args ) { 7648 // add original event to arguments 7649 var emitArgs = event ? [ event ].concat( args ) : args; 7650 this.emitEvent( type, emitArgs ); 7651 7652 if ( jQuery ) { 7653 // set this.$element 7654 this.$element = this.$element || jQuery( this.element ); 7655 if ( event ) { 7656 // create jQuery event 7657 var $event = jQuery.Event( event ); 7658 $event.type = type; 7659 this.$element.trigger( $event, args ); 7660 } else { 7661 // just trigger with type if no event available 7662 this.$element.trigger( type, args ); 7663 } 7664 } 7665}; 7666 7667// -------------------------- ignore & stamps -------------------------- // 7668 7669 7670/** 7671 * keep item in collection, but do not lay it out 7672 * ignored items do not get skipped in layout 7673 * @param {Element} elem 7674 */ 7675proto.ignore = function( elem ) { 7676 var item = this.getItem( elem ); 7677 if ( item ) { 7678 item.isIgnored = true; 7679 } 7680}; 7681 7682/** 7683 * return item to layout collection 7684 * @param {Element} elem 7685 */ 7686proto.unignore = function( elem ) { 7687 var item = this.getItem( elem ); 7688 if ( item ) { 7689 delete item.isIgnored; 7690 } 7691}; 7692 7693/** 7694 * adds elements to stamps 7695 * @param {NodeList, Array, Element, or String} elems 7696 */ 7697proto.stamp = function( elems ) { 7698 elems = this._find( elems ); 7699 if ( !elems ) { 7700 return; 7701 } 7702 7703 this.stamps = this.stamps.concat( elems ); 7704 // ignore 7705 elems.forEach( this.ignore, this ); 7706}; 7707 7708/** 7709 * removes elements to stamps 7710 * @param {NodeList, Array, or Element} elems 7711 */ 7712proto.unstamp = function( elems ) { 7713 elems = this._find( elems ); 7714 if ( !elems ){ 7715 return; 7716 } 7717 7718 elems.forEach( function( elem ) { 7719 // filter out removed stamp elements 7720 utils.removeFrom( this.stamps, elem ); 7721 this.unignore( elem ); 7722 }, this ); 7723}; 7724 7725/** 7726 * finds child elements 7727 * @param {NodeList, Array, Element, or String} elems 7728 * @returns {Array} elems 7729 */ 7730proto._find = function( elems ) { 7731 if ( !elems ) { 7732 return; 7733 } 7734 // if string, use argument as selector string 7735 if ( typeof elems == 'string' ) { 7736 elems = this.element.querySelectorAll( elems ); 7737 } 7738 elems = utils.makeArray( elems ); 7739 return elems; 7740}; 7741 7742proto._manageStamps = function() { 7743 if ( !this.stamps || !this.stamps.length ) { 7744 return; 7745 } 7746 7747 this._getBoundingRect(); 7748 7749 this.stamps.forEach( this._manageStamp, this ); 7750}; 7751 7752// update boundingLeft / Top 7753proto._getBoundingRect = function() { 7754 // get bounding rect for container element 7755 var boundingRect = this.element.getBoundingClientRect(); 7756 var size = this.size; 7757 this._boundingRect = { 7758 left: boundingRect.left + size.paddingLeft + size.borderLeftWidth, 7759 top: boundingRect.top + size.paddingTop + size.borderTopWidth, 7760 right: boundingRect.right - ( size.paddingRight + size.borderRightWidth ), 7761 bottom: boundingRect.bottom - ( size.paddingBottom + size.borderBottomWidth ) 7762 }; 7763}; 7764 7765/** 7766 * @param {Element} stamp 7767**/ 7768proto._manageStamp = noop; 7769 7770/** 7771 * get x/y position of element relative to container element 7772 * @param {Element} elem 7773 * @returns {Object} offset - has left, top, right, bottom 7774 */ 7775proto._getElementOffset = function( elem ) { 7776 var boundingRect = elem.getBoundingClientRect(); 7777 var thisRect = this._boundingRect; 7778 var size = getSize( elem ); 7779 var offset = { 7780 left: boundingRect.left - thisRect.left - size.marginLeft, 7781 top: boundingRect.top - thisRect.top - size.marginTop, 7782 right: thisRect.right - boundingRect.right - size.marginRight, 7783 bottom: thisRect.bottom - boundingRect.bottom - size.marginBottom 7784 }; 7785 return offset; 7786}; 7787 7788// -------------------------- resize -------------------------- // 7789 7790// enable event handlers for listeners 7791// i.e. resize -> onresize 7792proto.handleEvent = utils.handleEvent; 7793 7794/** 7795 * Bind layout to window resizing 7796 */ 7797proto.bindResize = function() { 7798 window.addEventListener( 'resize', this ); 7799 this.isResizeBound = true; 7800}; 7801 7802/** 7803 * Unbind layout to window resizing 7804 */ 7805proto.unbindResize = function() { 7806 window.removeEventListener( 'resize', this ); 7807 this.isResizeBound = false; 7808}; 7809 7810proto.onresize = function() { 7811 this.resize(); 7812}; 7813 7814utils.debounceMethod( Outlayer, 'onresize', 100 ); 7815 7816proto.resize = function() { 7817 // don't trigger if size did not change 7818 // or if resize was unbound. See #9 7819 if ( !this.isResizeBound || !this.needsResizeLayout() ) { 7820 return; 7821 } 7822 7823 this.layout(); 7824}; 7825 7826/** 7827 * check if layout is needed post layout 7828 * @returns Boolean 7829 */ 7830proto.needsResizeLayout = function() { 7831 var size = getSize( this.element ); 7832 // check that this.size and size are there 7833 // IE8 triggers resize on body size change, so they might not be 7834 var hasSizes = this.size && size; 7835 return hasSizes && size.innerWidth !== this.size.innerWidth; 7836}; 7837 7838// -------------------------- methods -------------------------- // 7839 7840/** 7841 * add items to Outlayer instance 7842 * @param {Array or NodeList or Element} elems 7843 * @returns {Array} items - Outlayer.Items 7844**/ 7845proto.addItems = function( elems ) { 7846 var items = this._itemize( elems ); 7847 // add items to collection 7848 if ( items.length ) { 7849 this.items = this.items.concat( items ); 7850 } 7851 return items; 7852}; 7853 7854/** 7855 * Layout newly-appended item elements 7856 * @param {Array or NodeList or Element} elems 7857 */ 7858proto.appended = function( elems ) { 7859 var items = this.addItems( elems ); 7860 if ( !items.length ) { 7861 return; 7862 } 7863 // layout and reveal just the new items 7864 this.layoutItems( items, true ); 7865 this.reveal( items ); 7866}; 7867 7868/** 7869 * Layout prepended elements 7870 * @param {Array or NodeList or Element} elems 7871 */ 7872proto.prepended = function( elems ) { 7873 var items = this._itemize( elems ); 7874 if ( !items.length ) { 7875 return; 7876 } 7877 // add items to beginning of collection 7878 var previousItems = this.items.slice(0); 7879 this.items = items.concat( previousItems ); 7880 // start new layout 7881 this._resetLayout(); 7882 this._manageStamps(); 7883 // layout new stuff without transition 7884 this.layoutItems( items, true ); 7885 this.reveal( items ); 7886 // layout previous items 7887 this.layoutItems( previousItems ); 7888}; 7889 7890/** 7891 * reveal a collection of items 7892 * @param {Array of Outlayer.Items} items 7893 */ 7894proto.reveal = function( items ) { 7895 this._emitCompleteOnItems( 'reveal', items ); 7896 if ( !items || !items.length ) { 7897 return; 7898 } 7899 var stagger = this.updateStagger(); 7900 items.forEach( function( item, i ) { 7901 item.stagger( i * stagger ); 7902 item.reveal(); 7903 }); 7904}; 7905 7906/** 7907 * hide a collection of items 7908 * @param {Array of Outlayer.Items} items 7909 */ 7910proto.hide = function( items ) { 7911 this._emitCompleteOnItems( 'hide', items ); 7912 if ( !items || !items.length ) { 7913 return; 7914 } 7915 var stagger = this.updateStagger(); 7916 items.forEach( function( item, i ) { 7917 item.stagger( i * stagger ); 7918 item.hide(); 7919 }); 7920}; 7921 7922/** 7923 * reveal item elements 7924 * @param {Array}, {Element}, {NodeList} items 7925 */ 7926proto.revealItemElements = function( elems ) { 7927 var items = this.getItems( elems ); 7928 this.reveal( items ); 7929}; 7930 7931/** 7932 * hide item elements 7933 * @param {Array}, {Element}, {NodeList} items 7934 */ 7935proto.hideItemElements = function( elems ) { 7936 var items = this.getItems( elems ); 7937 this.hide( items ); 7938}; 7939 7940/** 7941 * get Outlayer.Item, given an Element 7942 * @param {Element} elem 7943 * @param {Function} callback 7944 * @returns {Outlayer.Item} item 7945 */ 7946proto.getItem = function( elem ) { 7947 // loop through items to get the one that matches 7948 for ( var i=0; i < this.items.length; i++ ) { 7949 var item = this.items[i]; 7950 if ( item.element == elem ) { 7951 // return item 7952 return item; 7953 } 7954 } 7955}; 7956 7957/** 7958 * get collection of Outlayer.Items, given Elements 7959 * @param {Array} elems 7960 * @returns {Array} items - Outlayer.Items 7961 */ 7962proto.getItems = function( elems ) { 7963 elems = utils.makeArray( elems ); 7964 var items = []; 7965 elems.forEach( function( elem ) { 7966 var item = this.getItem( elem ); 7967 if ( item ) { 7968 items.push( item ); 7969 } 7970 }, this ); 7971 7972 return items; 7973}; 7974 7975/** 7976 * remove element(s) from instance and DOM 7977 * @param {Array or NodeList or Element} elems 7978 */ 7979proto.remove = function( elems ) { 7980 var removeItems = this.getItems( elems ); 7981 7982 this._emitCompleteOnItems( 'remove', removeItems ); 7983 7984 // bail if no items to remove 7985 if ( !removeItems || !removeItems.length ) { 7986 return; 7987 } 7988
vendor: 38,285 bytes, lines 7989-9412
7989 removeItems.forEach( function( item ) { 7990 item.remove(); 7991 // remove item from collection 7992 utils.removeFrom( this.items, item ); 7993 }, this ); 7994}; 7995 7996// ----- destroy ----- // 7997 7998// remove and disable Outlayer instance 7999proto.destroy = function() { 8000 // clean up dynamic styles 8001 var style = this.element.style; 8002 style.height = ''; 8003 style.position = ''; 8004 style.width = ''; 8005 // destroy items 8006 this.items.forEach( function( item ) { 8007 item.destroy(); 8008 }); 8009 8010 this.unbindResize(); 8011 8012 var id = this.element.outlayerGUID; 8013 delete instances[ id ]; // remove reference to instance by id 8014 delete this.element.outlayerGUID; 8015 // remove data for jQuery 8016 if ( jQuery ) { 8017 jQuery.removeData( this.element, this.constructor.namespace ); 8018 } 8019 8020}; 8021 8022// -------------------------- data -------------------------- // 8023 8024/** 8025 * get Outlayer instance from element 8026 * @param {Element} elem 8027 * @returns {Outlayer} 8028 */ 8029Outlayer.data = function( elem ) { 8030 elem = utils.getQueryElement( elem ); 8031 var id = elem && elem.outlayerGUID; 8032 return id && instances[ id ]; 8033}; 8034 8035 8036// -------------------------- create Outlayer class -------------------------- // 8037 8038/** 8039 * create a layout class 8040 * @param {String} namespace 8041 */ 8042Outlayer.create = function( namespace, options ) { 8043 // sub-class Outlayer 8044 var Layout = subclass( Outlayer ); 8045 // apply new options and compatOptions 8046 Layout.defaults = utils.extend( {}, Outlayer.defaults ); 8047 utils.extend( Layout.defaults, options ); 8048 Layout.compatOptions = utils.extend( {}, Outlayer.compatOptions ); 8049 8050 Layout.namespace = namespace; 8051 8052 Layout.data = Outlayer.data; 8053 8054 // sub-class Item 8055 Layout.Item = subclass( Item ); 8056 8057 // -------------------------- declarative -------------------------- // 8058 8059 utils.htmlInit( Layout, namespace ); 8060 8061 // -------------------------- jQuery bridge -------------------------- // 8062 8063 // make into jQuery plugin 8064 if ( jQuery && jQuery.bridget ) { 8065 jQuery.bridget( namespace, Layout ); 8066 } 8067 8068 return Layout; 8069}; 8070 8071function subclass( Parent ) { 8072 function SubClass() { 8073 Parent.apply( this, arguments ); 8074 } 8075 8076 SubClass.prototype = Object.create( Parent.prototype ); 8077 SubClass.prototype.constructor = SubClass; 8078 8079 return SubClass; 8080} 8081 8082// ----- helpers ----- // 8083 8084// how many milliseconds are in each unit 8085var msUnits = { 8086 ms: 1, 8087 s: 1000 8088}; 8089 8090// munge time-like parameter into millisecond number 8091// '0.4s' -> 40 8092function getMilliseconds( time ) { 8093 if ( typeof time == 'number' ) { 8094 return time; 8095 } 8096 var matches = time.match( /(^\d*\.?\d*)(\w*)/ ); 8097 var num = matches && matches[1]; 8098 var unit = matches && matches[2]; 8099 if ( !num.length ) { 8100 return 0; 8101 } 8102 num = parseFloat( num ); 8103 var mult = msUnits[ unit ] || 1; 8104 return num * mult; 8105} 8106 8107// ----- fin ----- // 8108 8109// back in global 8110Outlayer.Item = Item; 8111 8112return Outlayer; 8113 8114})); 8115 8116/** 8117 * Isotope Item 8118**/ 8119 8120( function( window, factory ) { 8121 // universal module definition 8122 /* jshint strict: false */ /*globals define, module, require */ 8123 if ( typeof define == 'function' && define.amd ) { 8124 // AMD 8125 define( 'isotope-layout/js/item',[ 8126 'outlayer/outlayer' 8127 ], 8128 factory ); 8129 } else if ( typeof module == 'object' && module.exports ) { 8130 // CommonJS 8131 module.exports = factory( 8132 require('outlayer') 8133 ); 8134 } else { 8135 // browser global 8136 window.Isotope = window.Isotope || {}; 8137 window.Isotope.Item = factory( 8138 window.Outlayer 8139 ); 8140 } 8141 8142}( window, function factory( Outlayer ) { 8143'use strict'; 8144 8145// -------------------------- Item -------------------------- // 8146 8147// sub-class Outlayer Item 8148function Item() { 8149 Outlayer.Item.apply( this, arguments ); 8150} 8151 8152var proto = Item.prototype = Object.create( Outlayer.Item.prototype ); 8153 8154var _create = proto._create; 8155proto._create = function() { 8156 // assign id, used for original-order sorting 8157 this.id = this.layout.itemGUID++; 8158 _create.call( this ); 8159 this.sortData = {}; 8160}; 8161 8162proto.updateSortData = function() { 8163 if ( this.isIgnored ) { 8164 return; 8165 } 8166 // default sorters 8167 this.sortData.id = this.id; 8168 // for backward compatibility 8169 this.sortData['original-order'] = this.id; 8170 this.sortData.random = Math.random(); 8171 // go thru getSortData obj and apply the sorters 8172 var getSortData = this.layout.options.getSortData; 8173 var sorters = this.layout._sorters; 8174 for ( var key in getSortData ) { 8175 var sorter = sorters[ key ]; 8176 this.sortData[ key ] = sorter( this.element, this ); 8177 } 8178}; 8179 8180var _destroy = proto.destroy; 8181proto.destroy = function() { 8182 // call super 8183 _destroy.apply( this, arguments ); 8184 // reset display, #741 8185 this.css({ 8186 display: '' 8187 }); 8188}; 8189 8190return Item; 8191 8192})); 8193 8194/** 8195 * Isotope LayoutMode 8196 */ 8197 8198( function( window, factory ) { 8199 // universal module definition 8200 /* jshint strict: false */ /*globals define, module, require */ 8201 if ( typeof define == 'function' && define.amd ) { 8202 // AMD 8203 define( 'isotope-layout/js/layout-mode',[ 8204 'get-size/get-size', 8205 'outlayer/outlayer' 8206 ], 8207 factory ); 8208 } else if ( typeof module == 'object' && module.exports ) { 8209 // CommonJS 8210 module.exports = factory( 8211 require('get-size'), 8212 require('outlayer') 8213 ); 8214 } else { 8215 // browser global 8216 window.Isotope = window.Isotope || {}; 8217 window.Isotope.LayoutMode = factory( 8218 window.getSize, 8219 window.Outlayer 8220 ); 8221 } 8222 8223}( window, function factory( getSize, Outlayer ) { 8224 'use strict'; 8225 8226 // layout mode class 8227 function LayoutMode( isotope ) { 8228 this.isotope = isotope; 8229 // link properties 8230 if ( isotope ) { 8231 this.options = isotope.options[ this.namespace ]; 8232 this.element = isotope.element; 8233 this.items = isotope.filteredItems; 8234 this.size = isotope.size; 8235 } 8236 } 8237 8238 var proto = LayoutMode.prototype; 8239 8240 /** 8241 * some methods should just defer to default Outlayer method 8242 * and reference the Isotope instance as `this` 8243 **/ 8244 var facadeMethods = [ 8245 '_resetLayout', 8246 '_getItemLayoutPosition', 8247 '_manageStamp', 8248 '_getContainerSize', 8249 '_getElementOffset', 8250 'needsResizeLayout', 8251 '_getOption' 8252 ]; 8253 8254 facadeMethods.forEach( function( methodName ) { 8255 proto[ methodName ] = function() { 8256 return Outlayer.prototype[ methodName ].apply( this.isotope, arguments ); 8257 }; 8258 }); 8259 8260 // ----- ----- // 8261 8262 // for horizontal layout modes, check vertical size 8263 proto.needsVerticalResizeLayout = function() { 8264 // don't trigger if size did not change 8265 var size = getSize( this.isotope.element ); 8266 // check that this.size and size are there 8267 // IE8 triggers resize on body size change, so they might not be 8268 var hasSizes = this.isotope.size && size; 8269 return hasSizes && size.innerHeight != this.isotope.size.innerHeight; 8270 }; 8271 8272 // ----- measurements ----- // 8273 8274 proto._getMeasurement = function() { 8275 this.isotope._getMeasurement.apply( this, arguments ); 8276 }; 8277 8278 proto.getColumnWidth = function() { 8279 this.getSegmentSize( 'column', 'Width' ); 8280 }; 8281 8282 proto.getRowHeight = function() { 8283 this.getSegmentSize( 'row', 'Height' ); 8284 }; 8285 8286 /** 8287 * get columnWidth or rowHeight 8288 * segment: 'column' or 'row' 8289 * size 'Width' or 'Height' 8290 **/ 8291 proto.getSegmentSize = function( segment, size ) { 8292 var segmentName = segment + size; 8293 var outerSize = 'outer' + size; 8294 // columnWidth / outerWidth // rowHeight / outerHeight 8295 this._getMeasurement( segmentName, outerSize ); 8296 // got rowHeight or columnWidth, we can chill 8297 if ( this[ segmentName ] ) { 8298 return; 8299 } 8300 // fall back to item of first element 8301 var firstItemSize = this.getFirstItemSize(); 8302 this[ segmentName ] = firstItemSize && firstItemSize[ outerSize ] || 8303 // or size of container 8304 this.isotope.size[ 'inner' + size ]; 8305 }; 8306 8307 proto.getFirstItemSize = function() { 8308 var firstItem = this.isotope.filteredItems[0]; 8309 return firstItem && firstItem.element && getSize( firstItem.element ); 8310 }; 8311 8312 // ----- methods that should reference isotope ----- // 8313 8314 proto.layout = function() { 8315 this.isotope.layout.apply( this.isotope, arguments ); 8316 }; 8317 8318 proto.getSize = function() { 8319 this.isotope.getSize(); 8320 this.size = this.isotope.size; 8321 }; 8322 8323 // -------------------------- create -------------------------- // 8324 8325 LayoutMode.modes = {}; 8326 8327 LayoutMode.create = function( namespace, options ) { 8328 8329 function Mode() { 8330 LayoutMode.apply( this, arguments ); 8331 } 8332 8333 Mode.prototype = Object.create( proto ); 8334 Mode.prototype.constructor = Mode; 8335 8336 // default options 8337 if ( options ) { 8338 Mode.options = options; 8339 } 8340 8341 Mode.prototype.namespace = namespace; 8342 // register in Isotope 8343 LayoutMode.modes[ namespace ] = Mode; 8344 8345 return Mode; 8346 }; 8347 8348 return LayoutMode; 8349 8350})); 8351 8352/*! 8353 * Masonry v4.2.1 8354 * Cascading grid layout library 8355 * https://masonry.desandro.com 8356 * MIT License 8357 * by David DeSandro 8358 */ 8359 8360( function( window, factory ) { 8361 // universal module definition 8362 /* jshint strict: false */ /*globals define, module, require */ 8363 if ( typeof define == 'function' && define.amd ) { 8364 // AMD 8365 define( 'masonry-layout/masonry',[ 8366 'outlayer/outlayer', 8367 'get-size/get-size' 8368 ], 8369 factory ); 8370 } else if ( typeof module == 'object' && module.exports ) { 8371 // CommonJS 8372 module.exports = factory( 8373 require('outlayer'), 8374 require('get-size') 8375 ); 8376 } else { 8377 // browser global 8378 window.Masonry = factory( 8379 window.Outlayer, 8380 window.getSize 8381 ); 8382 } 8383 8384}( window, function factory( Outlayer, getSize ) { 8385 8386 8387 8388// -------------------------- masonryDefinition -------------------------- // 8389 8390 // create an Outlayer layout class 8391 var Masonry = Outlayer.create('masonry'); 8392 // isFitWidth -> fitWidth 8393 Masonry.compatOptions.fitWidth = 'isFitWidth'; 8394 8395 var proto = Masonry.prototype; 8396 8397 proto._resetLayout = function() { 8398 this.getSize(); 8399 this._getMeasurement( 'columnWidth', 'outerWidth' ); 8400 this._getMeasurement( 'gutter', 'outerWidth' ); 8401 this.measureColumns(); 8402 8403 // reset column Y 8404 this.colYs = []; 8405 for ( var i=0; i < this.cols; i++ ) { 8406 this.colYs.push( 0 ); 8407 } 8408 8409 this.maxY = 0; 8410 this.horizontalColIndex = 0; 8411 }; 8412 8413 proto.measureColumns = function() { 8414 this.getContainerWidth(); 8415 // if columnWidth is 0, default to outerWidth of first item 8416 if ( !this.columnWidth ) { 8417 var firstItem = this.items[0]; 8418 var firstItemElem = firstItem && firstItem.element; 8419 // columnWidth fall back to item of first element 8420 this.columnWidth = firstItemElem && getSize( firstItemElem ).outerWidth || 8421 // if first elem has no width, default to size of container 8422 this.containerWidth; 8423 } 8424 8425 var columnWidth = this.columnWidth += this.gutter; 8426 8427 // calculate columns 8428 var containerWidth = this.containerWidth + this.gutter; 8429 var cols = containerWidth / columnWidth; 8430 // fix rounding errors, typically with gutters 8431 var excess = columnWidth - containerWidth % columnWidth; 8432 // if overshoot is less than a pixel, round up, otherwise floor it 8433 var mathMethod = excess && excess < 1 ? 'round' : 'floor'; 8434 cols = Math[ mathMethod ]( cols ); 8435 this.cols = Math.max( cols, 1 ); 8436 }; 8437 8438 proto.getContainerWidth = function() { 8439 // container is parent if fit width 8440 var isFitWidth = this._getOption('fitWidth'); 8441 var container = isFitWidth ? this.element.parentNode : this.element; 8442 // check that this.size and size are there 8443 // IE8 triggers resize on body size change, so they might not be 8444 var size = getSize( container ); 8445 this.containerWidth = size && size.innerWidth; 8446 }; 8447 8448 proto._getItemLayoutPosition = function( item ) { 8449 item.getSize(); 8450 // how many columns does this brick span 8451 var remainder = item.size.outerWidth % this.columnWidth; 8452 var mathMethod = remainder && remainder < 1 ? 'round' : 'ceil'; 8453 // round if off by 1 pixel, otherwise use ceil 8454 var colSpan = Math[ mathMethod ]( item.size.outerWidth / this.columnWidth ); 8455 colSpan = Math.min( colSpan, this.cols ); 8456 // use horizontal or top column position 8457 var colPosMethod = this.options.horizontalOrder ? 8458 '_getHorizontalColPosition' : '_getTopColPosition'; 8459 var colPosition = this[ colPosMethod ]( colSpan, item ); 8460 // position the brick 8461 var position = { 8462 x: this.columnWidth * colPosition.col, 8463 y: colPosition.y 8464 }; 8465 // apply setHeight to necessary columns 8466 var setHeight = colPosition.y + item.size.outerHeight; 8467 var setMax = colSpan + colPosition.col; 8468 for ( var i = colPosition.col; i < setMax; i++ ) { 8469 this.colYs[i] = setHeight; 8470 } 8471 8472 return position; 8473 }; 8474 8475 proto._getTopColPosition = function( colSpan ) { 8476 var colGroup = this._getTopColGroup( colSpan ); 8477 // get the minimum Y value from the columns 8478 var minimumY = Math.min.apply( Math, colGroup ); 8479 8480 return { 8481 col: colGroup.indexOf( minimumY ), 8482 y: minimumY, 8483 }; 8484 }; 8485 8486 /** 8487 * @param {Number} colSpan - number of columns the element spans 8488 * @returns {Array} colGroup 8489 */ 8490 proto._getTopColGroup = function( colSpan ) { 8491 if ( colSpan < 2 ) { 8492 // if brick spans only one column, use all the column Ys 8493 return this.colYs; 8494 } 8495 8496 var colGroup = []; 8497 // how many different places could this brick fit horizontally 8498 var groupCount = this.cols + 1 - colSpan; 8499 // for each group potential horizontal position 8500 for ( var i = 0; i < groupCount; i++ ) { 8501 colGroup[i] = this._getColGroupY( i, colSpan ); 8502 } 8503 return colGroup; 8504 }; 8505 8506 proto._getColGroupY = function( col, colSpan ) { 8507 if ( colSpan < 2 ) { 8508 return this.colYs[ col ]; 8509 } 8510 // make an array of colY values for that one group 8511 var groupColYs = this.colYs.slice( col, col + colSpan ); 8512 // and get the max value of the array 8513 return Math.max.apply( Math, groupColYs ); 8514 }; 8515 8516 // get column position based on horizontal index. #873 8517 proto._getHorizontalColPosition = function( colSpan, item ) { 8518 var col = this.horizontalColIndex % this.cols; 8519 var isOver = colSpan > 1 && col + colSpan > this.cols; 8520 // shift to next row if item can't fit on current row 8521 col = isOver ? 0 : col; 8522 // don't let zero-size items take up space 8523 var hasSize = item.size.outerWidth && item.size.outerHeight; 8524 this.horizontalColIndex = hasSize ? col + colSpan : this.horizontalColIndex; 8525 8526 return { 8527 col: col, 8528 y: this._getColGroupY( col, colSpan ), 8529 }; 8530 }; 8531 8532 proto._manageStamp = function( stamp ) { 8533 var stampSize = getSize( stamp ); 8534 var offset = this._getElementOffset( stamp ); 8535 // get the columns that this stamp affects 8536 var isOriginLeft = this._getOption('originLeft'); 8537 var firstX = isOriginLeft ? offset.left : offset.right; 8538 var lastX = firstX + stampSize.outerWidth; 8539 var firstCol = Math.floor( firstX / this.columnWidth ); 8540 firstCol = Math.max( 0, firstCol ); 8541 var lastCol = Math.floor( lastX / this.columnWidth ); 8542 // lastCol should not go over if multiple of columnWidth #425 8543 lastCol -= lastX % this.columnWidth ? 0 : 1; 8544 lastCol = Math.min( this.cols - 1, lastCol ); 8545 // set colYs to bottom of the stamp 8546 8547 var isOriginTop = this._getOption('originTop'); 8548 var stampMaxY = ( isOriginTop ? offset.top : offset.bottom ) + 8549 stampSize.outerHeight; 8550 for ( var i = firstCol; i <= lastCol; i++ ) { 8551 this.colYs[i] = Math.max( stampMaxY, this.colYs[i] ); 8552 } 8553 }; 8554 8555 proto._getContainerSize = function() { 8556 this.maxY = Math.max.apply( Math, this.colYs ); 8557 var size = { 8558 height: this.maxY 8559 }; 8560 8561 if ( this._getOption('fitWidth') ) { 8562 size.width = this._getContainerFitWidth(); 8563 } 8564 8565 return size; 8566 }; 8567 8568 proto._getContainerFitWidth = function() { 8569 var unusedCols = 0; 8570 // count unused columns 8571 var i = this.cols; 8572 while ( --i ) { 8573 if ( this.colYs[i] !== 0 ) { 8574 break; 8575 } 8576 unusedCols++; 8577 } 8578 // fit container to columns that have been used 8579 return ( this.cols - unusedCols ) * this.columnWidth - this.gutter; 8580 }; 8581 8582 proto.needsResizeLayout = function() { 8583 var previousWidth = this.containerWidth; 8584 this.getContainerWidth(); 8585 return previousWidth != this.containerWidth; 8586 }; 8587 8588 return Masonry; 8589 8590})); 8591 8592/*! 8593 * Masonry layout mode 8594 * sub-classes Masonry 8595 * https://masonry.desandro.com 8596 */ 8597 8598( function( window, factory ) { 8599 // universal module definition 8600 /* jshint strict: false */ /*globals define, module, require */ 8601 if ( typeof define == 'function' && define.amd ) { 8602 // AMD 8603 define( 'isotope-layout/js/layout-modes/masonry',[ 8604 '../layout-mode', 8605 'masonry-layout/masonry' 8606 ], 8607 factory ); 8608 } else if ( typeof module == 'object' && module.exports ) { 8609 // CommonJS 8610 module.exports = factory( 8611 require('../layout-mode'), 8612 require('masonry-layout') 8613 ); 8614 } else { 8615 // browser global 8616 factory( 8617 window.Isotope.LayoutMode, 8618 window.Masonry 8619 ); 8620 } 8621 8622}( window, function factory( LayoutMode, Masonry ) { 8623'use strict'; 8624 8625// -------------------------- masonryDefinition -------------------------- // 8626 8627 // create an Outlayer layout class 8628 var MasonryMode = LayoutMode.create('masonry'); 8629 8630 var proto = MasonryMode.prototype; 8631 8632 var keepModeMethods = { 8633 _getElementOffset: true, 8634 layout: true, 8635 _getMeasurement: true 8636 }; 8637 8638 // inherit Masonry prototype 8639 for ( var method in Masonry.prototype ) { 8640 // do not inherit mode methods 8641 if ( !keepModeMethods[ method ] ) { 8642 proto[ method ] = Masonry.prototype[ method ]; 8643 } 8644 } 8645 8646 var measureColumns = proto.measureColumns; 8647 proto.measureColumns = function() { 8648 // set items, used if measuring first item 8649 this.items = this.isotope.filteredItems; 8650 measureColumns.call( this ); 8651 }; 8652 8653 // point to mode options for fitWidth 8654 var _getOption = proto._getOption; 8655 proto._getOption = function( option ) { 8656 if ( option == 'fitWidth' ) { 8657 return this.options.isFitWidth !== undefined ? 8658 this.options.isFitWidth : this.options.fitWidth; 8659 } 8660 return _getOption.apply( this.isotope, arguments ); 8661 }; 8662 8663 return MasonryMode; 8664 8665})); 8666 8667/** 8668 * fitRows layout mode 8669 */ 8670 8671( function( window, factory ) { 8672 // universal module definition 8673 /* jshint strict: false */ /*globals define, module, require */ 8674 if ( typeof define == 'function' && define.amd ) { 8675 // AMD 8676 define( 'isotope-layout/js/layout-modes/fit-rows',[ 8677 '../layout-mode' 8678 ], 8679 factory ); 8680 } else if ( typeof exports == 'object' ) { 8681 // CommonJS 8682 module.exports = factory( 8683 require('../layout-mode') 8684 ); 8685 } else { 8686 // browser global 8687 factory( 8688 window.Isotope.LayoutMode 8689 ); 8690 } 8691 8692}( window, function factory( LayoutMode ) { 8693'use strict'; 8694 8695var FitRows = LayoutMode.create('fitRows'); 8696 8697var proto = FitRows.prototype; 8698 8699proto._resetLayout = function() { 8700 this.x = 0; 8701 this.y = 0; 8702 this.maxY = 0; 8703 this._getMeasurement( 'gutter', 'outerWidth' ); 8704}; 8705 8706proto._getItemLayoutPosition = function( item ) { 8707 item.getSize(); 8708 8709 var itemWidth = item.size.outerWidth + this.gutter; 8710 // if this element cannot fit in the current row 8711 var containerWidth = this.isotope.size.innerWidth + this.gutter; 8712 if ( this.x !== 0 && itemWidth + this.x > containerWidth ) { 8713 this.x = 0; 8714 this.y = this.maxY; 8715 } 8716 8717 var position = { 8718 x: this.x, 8719 y: this.y 8720 }; 8721 8722 this.maxY = Math.max( this.maxY, this.y + item.size.outerHeight ); 8723 this.x += itemWidth; 8724 8725 return position; 8726}; 8727 8728proto._getContainerSize = function() { 8729 return { height: this.maxY }; 8730}; 8731 8732return FitRows; 8733 8734})); 8735 8736/** 8737 * vertical layout mode 8738 */ 8739 8740( function( window, factory ) { 8741 // universal module definition 8742 /* jshint strict: false */ /*globals define, module, require */ 8743 if ( typeof define == 'function' && define.amd ) { 8744 // AMD 8745 define( 'isotope-layout/js/layout-modes/vertical',[ 8746 '../layout-mode' 8747 ], 8748 factory ); 8749 } else if ( typeof module == 'object' && module.exports ) { 8750 // CommonJS 8751 module.exports = factory( 8752 require('../layout-mode') 8753 ); 8754 } else { 8755 // browser global 8756 factory( 8757 window.Isotope.LayoutMode 8758 ); 8759 } 8760 8761}( window, function factory( LayoutMode ) { 8762'use strict'; 8763 8764var Vertical = LayoutMode.create( 'vertical', { 8765 horizontalAlignment: 0 8766}); 8767 8768var proto = Vertical.prototype; 8769 8770proto._resetLayout = function() { 8771 this.y = 0; 8772}; 8773 8774proto._getItemLayoutPosition = function( item ) { 8775 item.getSize(); 8776 var x = ( this.isotope.size.innerWidth - item.size.outerWidth ) * 8777 this.options.horizontalAlignment; 8778 var y = this.y; 8779 this.y += item.size.outerHeight; 8780 return { x: x, y: y }; 8781}; 8782 8783proto._getContainerSize = function() { 8784 return { height: this.y }; 8785}; 8786 8787return Vertical; 8788 8789})); 8790 8791/*! 8792 * Isotope v3.0.6 8793 * 8794 * Licensed GPLv3 for open source use 8795 * or Isotope Commercial License for commercial use 8796 * 8797 * https://isotope.metafizzy.co 8798 * Copyright 2010-2018 Metafizzy 8799 */ 8800 8801( function( window, factory ) { 8802 // universal module definition 8803 /* jshint strict: false */ /*globals define, module, require */ 8804 if ( typeof define == 'function' && define.amd ) { 8805 // AMD 8806 define( [ 8807 'outlayer/outlayer', 8808 'get-size/get-size', 8809 'desandro-matches-selector/matches-selector', 8810 'fizzy-ui-utils/utils', 8811 'isotope-layout/js/item', 8812 'isotope-layout/js/layout-mode', 8813 // include default layout modes 8814 'isotope-layout/js/layout-modes/masonry', 8815 'isotope-layout/js/layout-modes/fit-rows', 8816 'isotope-layout/js/layout-modes/vertical' 8817 ], 8818 function( Outlayer, getSize, matchesSelector, utils, Item, LayoutMode ) { 8819 return factory( window, Outlayer, getSize, matchesSelector, utils, Item, LayoutMode ); 8820 }); 8821 } else if ( typeof module == 'object' && module.exports ) { 8822 // CommonJS 8823 module.exports = factory( 8824 window, 8825 require('outlayer'), 8826 require('get-size'), 8827 require('desandro-matches-selector'), 8828 require('fizzy-ui-utils'), 8829 require('isotope-layout/js/item'), 8830 require('isotope-layout/js/layout-mode'), 8831 // include default layout modes 8832 require('isotope-layout/js/layout-modes/masonry'), 8833 require('isotope-layout/js/layout-modes/fit-rows'), 8834 require('isotope-layout/js/layout-modes/vertical') 8835 ); 8836 } else { 8837 // browser global 8838 window.Isotope = factory( 8839 window, 8840 window.Outlayer, 8841 window.getSize, 8842 window.matchesSelector, 8843 window.fizzyUIUtils, 8844 window.Isotope.Item, 8845 window.Isotope.LayoutMode 8846 ); 8847 } 8848 8849}( window, function factory( window, Outlayer, getSize, matchesSelector, utils, 8850 Item, LayoutMode ) { 8851 8852 8853 8854// -------------------------- vars -------------------------- // 8855 8856var jQuery = window.jQuery; 8857 8858// -------------------------- helpers -------------------------- // 8859 8860var trim = String.prototype.trim ? 8861 function( str ) { 8862 return str.trim(); 8863 } : 8864 function( str ) { 8865 return str.replace( /^\s+|\s+$/g, '' ); 8866 }; 8867 8868// -------------------------- isotopeDefinition -------------------------- // 8869 8870 // create an Outlayer layout class 8871 var Isotope = Outlayer.create( 'isotope', { 8872 layoutMode: 'masonry', 8873 isJQueryFiltering: true, 8874 sortAscending: true 8875 }); 8876 8877 Isotope.Item = Item; 8878 Isotope.LayoutMode = LayoutMode; 8879 8880 var proto = Isotope.prototype; 8881 8882 proto._create = function() { 8883 this.itemGUID = 0; 8884 // functions that sort items 8885 this._sorters = {}; 8886 this._getSorters(); 8887 // call super 8888 Outlayer.prototype._create.call( this ); 8889 8890 // create layout modes 8891 this.modes = {}; 8892 // start filteredItems with all items 8893 this.filteredItems = this.items; 8894 // keep of track of sortBys 8895 this.sortHistory = [ 'original-order' ]; 8896 // create from registered layout modes 8897 for ( var name in LayoutMode.modes ) { 8898 this._initLayoutMode( name ); 8899 } 8900 }; 8901 8902 proto.reloadItems = function() { 8903 // reset item ID counter 8904 this.itemGUID = 0; 8905 // call super 8906 Outlayer.prototype.reloadItems.call( this ); 8907 }; 8908 8909 proto._itemize = function() { 8910 var items = Outlayer.prototype._itemize.apply( this, arguments ); 8911 // assign ID for original-order 8912 for ( var i=0; i < items.length; i++ ) { 8913 var item = items[i]; 8914 item.id = this.itemGUID++; 8915 } 8916 this._updateItemsSortData( items ); 8917 return items; 8918 }; 8919 8920 8921 // -------------------------- layout -------------------------- // 8922 8923 proto._initLayoutMode = function( name ) { 8924 var Mode = LayoutMode.modes[ name ]; 8925 // set mode options 8926 // HACK extend initial options, back-fill in default options 8927 var initialOpts = this.options[ name ] || {}; 8928 this.options[ name ] = Mode.options ? 8929 utils.extend( Mode.options, initialOpts ) : initialOpts; 8930 // init layout mode instance 8931 this.modes[ name ] = new Mode( this ); 8932 }; 8933 8934 8935 proto.layout = function() { 8936 // if first time doing layout, do all magic 8937 if ( !this._isLayoutInited && this._getOption('initLayout') ) { 8938 this.arrange(); 8939 return; 8940 } 8941 this._layout(); 8942 }; 8943 8944 // private method to be used in layout() & magic() 8945 proto._layout = function() { 8946 // don't animate first layout 8947 var isInstant = this._getIsInstant(); 8948 // layout flow 8949 this._resetLayout(); 8950 this._manageStamps(); 8951 this.layoutItems( this.filteredItems, isInstant ); 8952 8953 // flag for initalized 8954 this._isLayoutInited = true; 8955 }; 8956 8957 // filter + sort + layout 8958 proto.arrange = function( opts ) { 8959 // set any options pass 8960 this.option( opts ); 8961 this._getIsInstant(); 8962 // filter, sort, and layout 8963 8964 // filter 8965 var filtered = this._filter( this.items ); 8966 this.filteredItems = filtered.matches; 8967 8968 this._bindArrangeComplete(); 8969 8970 if ( this._isInstant ) { 8971 this._noTransition( this._hideReveal, [ filtered ] ); 8972 } else { 8973 this._hideReveal( filtered ); 8974 } 8975 8976 this._sort(); 8977 this._layout(); 8978 }; 8979 // alias to _init for main plugin method 8980 proto._init = proto.arrange; 8981 8982 proto._hideReveal = function( filtered ) { 8983 this.reveal( filtered.needReveal ); 8984 this.hide( filtered.needHide ); 8985 }; 8986 8987 // HACK 8988 // Don't animate/transition first layout 8989 // Or don't animate/transition other layouts 8990 proto._getIsInstant = function() { 8991 var isLayoutInstant = this._getOption('layoutInstant'); 8992 var isInstant = isLayoutInstant !== undefined ? isLayoutInstant : 8993 !this._isLayoutInited; 8994 this._isInstant = isInstant; 8995 return isInstant; 8996 }; 8997 8998 // listen for layoutComplete, hideComplete and revealComplete 8999 // to trigger arrangeComplete 9000 proto._bindArrangeComplete = function() { 9001 // listen for 3 events to trigger arrangeComplete 9002 var isLayoutComplete, isHideComplete, isRevealComplete; 9003 var _this = this; 9004 function arrangeParallelCallback() { 9005 if ( isLayoutComplete && isHideComplete && isRevealComplete ) { 9006 _this.dispatchEvent( 'arrangeComplete', null, [ _this.filteredItems ] ); 9007 } 9008 } 9009 this.once( 'layoutComplete', function() { 9010 isLayoutComplete = true; 9011 arrangeParallelCallback(); 9012 }); 9013 this.once( 'hideComplete', function() { 9014 isHideComplete = true; 9015 arrangeParallelCallback(); 9016 }); 9017 this.once( 'revealComplete', function() { 9018 isRevealComplete = true; 9019 arrangeParallelCallback(); 9020 }); 9021 }; 9022 9023 // -------------------------- filter -------------------------- // 9024 9025 proto._filter = function( items ) { 9026 var filter = this.options.filter; 9027 filter = filter || '*'; 9028 var matches = []; 9029 var hiddenMatched = []; 9030 var visibleUnmatched = []; 9031 9032 var test = this._getFilterTest( filter ); 9033 9034 // test each item 9035 for ( var i=0; i < items.length; i++ ) { 9036 var item = items[i]; 9037 if ( item.isIgnored ) { 9038 continue; 9039 } 9040 // add item to either matched or unmatched group 9041 var isMatched = test( item ); 9042 // item.isFilterMatched = isMatched; 9043 // add to matches if its a match 9044 if ( isMatched ) { 9045 matches.push( item ); 9046 } 9047 // add to additional group if item needs to be hidden or revealed 9048 if ( isMatched && item.isHidden ) { 9049 hiddenMatched.push( item ); 9050 } else if ( !isMatched && !item.isHidden ) { 9051 visibleUnmatched.push( item ); 9052 } 9053 } 9054 9055 // return collections of items to be manipulated 9056 return { 9057 matches: matches, 9058 needReveal: hiddenMatched, 9059 needHide: visibleUnmatched 9060 }; 9061 }; 9062 9063 // get a jQuery, function, or a matchesSelector test given the filter 9064 proto._getFilterTest = function( filter ) { 9065 if ( jQuery && this.options.isJQueryFiltering ) { 9066 // use jQuery 9067 return function( item ) { 9068 return jQuery( item.element ).is( filter ); 9069 }; 9070 } 9071 if ( typeof filter == 'function' ) { 9072 // use filter as function 9073 return function( item ) { 9074 return filter( item.element ); 9075 }; 9076 } 9077 // default, use filter as selector string 9078 return function( item ) { 9079 return matchesSelector( item.element, filter ); 9080 }; 9081 }; 9082 9083 // -------------------------- sorting -------------------------- // 9084 9085 /** 9086 * @params {Array} elems 9087 * @public 9088 */ 9089 proto.updateSortData = function( elems ) { 9090 // get items 9091 var items; 9092 if ( elems ) { 9093 elems = utils.makeArray( elems ); 9094 items = this.getItems( elems ); 9095 } else { 9096 // update all items if no elems provided 9097 items = this.items; 9098 } 9099 9100 this._getSorters(); 9101 this._updateItemsSortData( items ); 9102 }; 9103 9104 proto._getSorters = function() { 9105 var getSortData = this.options.getSortData; 9106 for ( var key in getSortData ) { 9107 var sorter = getSortData[ key ]; 9108 this._sorters[ key ] = mungeSorter( sorter ); 9109 } 9110 }; 9111 9112 /** 9113 * @params {Array} items - of Isotope.Items 9114 * @private 9115 */ 9116 proto._updateItemsSortData = function( items ) { 9117 // do not update if no items 9118 var len = items && items.length; 9119 9120 for ( var i=0; len && i < len; i++ ) { 9121 var item = items[i]; 9122 item.updateSortData(); 9123 } 9124 }; 9125 9126 // ----- munge sorter ----- // 9127 9128 // encapsulate this, as we just need mungeSorter 9129 // other functions in here are just for munging 9130 var mungeSorter = ( function() { 9131 // add a magic layer to sorters for convienent shorthands 9132 // `.foo-bar` will use the text of .foo-bar querySelector 9133 // `[foo-bar]` will use attribute 9134 // you can also add parser 9135 // `.foo-bar parseInt` will parse that as a number 9136 function mungeSorter( sorter ) { 9137 // if not a string, return function or whatever it is 9138 if ( typeof sorter != 'string' ) { 9139 return sorter; 9140 } 9141 // parse the sorter string 9142 var args = trim( sorter ).split(' '); 9143 var query = args[0]; 9144 // check if query looks like [an-attribute] 9145 var attrMatch = query.match( /^\[(.+)\]$/ ); 9146 var attr = attrMatch && attrMatch[1]; 9147 var getValue = getValueGetter( attr, query ); 9148 // use second argument as a parser 9149 var parser = Isotope.sortDataParsers[ args[1] ]; 9150 // parse the value, if there was a parser 9151 sorter = parser ? function( elem ) { 9152 return elem && parser( getValue( elem ) ); 9153 } : 9154 // otherwise just return value 9155 function( elem ) { 9156 return elem && getValue( elem ); 9157 }; 9158 9159 return sorter; 9160 } 9161 9162 // get an attribute getter, or get text of the querySelector 9163 function getValueGetter( attr, query ) { 9164 // if query looks like [foo-bar], get attribute 9165 if ( attr ) { 9166 return function getAttribute( elem ) { 9167 return elem.getAttribute( attr ); 9168 }; 9169 } 9170 9171 // otherwise, assume its a querySelector, and get its text 9172 return function getChildText( elem ) { 9173 var child = elem.querySelector( query ); 9174 return child && child.textContent; 9175 }; 9176 } 9177 9178 return mungeSorter; 9179 })(); 9180 9181 // parsers used in getSortData shortcut strings 9182 Isotope.sortDataParsers = { 9183 'parseInt': function( val ) { 9184 return parseInt( val, 10 ); 9185 }, 9186 'parseFloat': function( val ) { 9187 return parseFloat( val ); 9188 } 9189 }; 9190 9191 // ----- sort method ----- // 9192 9193 // sort filteredItem order 9194 proto._sort = function() { 9195 if ( !this.options.sortBy ) { 9196 return; 9197 } 9198 // keep track of sortBy History 9199 var sortBys = utils.makeArray( this.options.sortBy ); 9200 if ( !this._getIsSameSortBy( sortBys ) ) { 9201 // concat all sortBy and sortHistory, add to front, oldest goes in last 9202 this.sortHistory = sortBys.concat( this.sortHistory ); 9203 } 9204 // sort magic 9205 var itemSorter = getItemSorter( this.sortHistory, this.options.sortAscending ); 9206 this.filteredItems.sort( itemSorter ); 9207 }; 9208 9209 // check if sortBys is same as start of sortHistory 9210 proto._getIsSameSortBy = function( sortBys ) { 9211 for ( var i=0; i < sortBys.length; i++ ) { 9212 if ( sortBys[i] != this.sortHistory[i] ) { 9213 return false; 9214 } 9215 } 9216 return true; 9217 }; 9218 9219 // returns a function used for sorting 9220 function getItemSorter( sortBys, sortAsc ) { 9221 return function sorter( itemA, itemB ) { 9222 // cycle through all sortKeys 9223 for ( var i = 0; i < sortBys.length; i++ ) { 9224 var sortBy = sortBys[i]; 9225 var a = itemA.sortData[ sortBy ]; 9226 var b = itemB.sortData[ sortBy ]; 9227 if ( a > b || a < b ) { 9228 // if sortAsc is an object, use the value given the sortBy key 9229 var isAscending = sortAsc[ sortBy ] !== undefined ? sortAsc[ sortBy ] : sortAsc; 9230 var direction = isAscending ? 1 : -1; 9231 return ( a > b ? 1 : -1 ) * direction; 9232 } 9233 } 9234 return 0; 9235 }; 9236 } 9237 9238 // -------------------------- methods -------------------------- // 9239 9240 // get layout mode 9241 proto._mode = function() { 9242 var layoutMode = this.options.layoutMode; 9243 var mode = this.modes[ layoutMode ]; 9244 if ( !mode ) { 9245 // TODO console.error 9246 throw new Error( 'No layout mode: ' + layoutMode ); 9247 } 9248 // HACK sync mode's options 9249 // any options set after init for layout mode need to be synced 9250 mode.options = this.options[ layoutMode ]; 9251 return mode; 9252 }; 9253 9254 proto._resetLayout = function() { 9255 // trigger original reset layout 9256 Outlayer.prototype._resetLayout.call( this ); 9257 this._mode()._resetLayout(); 9258 }; 9259 9260 proto._getItemLayoutPosition = function( item ) { 9261 return this._mode()._getItemLayoutPosition( item ); 9262 }; 9263 9264 proto._manageStamp = function( stamp ) { 9265 this._mode()._manageStamp( stamp ); 9266 }; 9267 9268 proto._getContainerSize = function() { 9269 return this._mode()._getContainerSize(); 9270 }; 9271 9272 proto.needsResizeLayout = function() { 9273 return this._mode().needsResizeLayout(); 9274 }; 9275 9276 // -------------------------- adding & removing -------------------------- // 9277 9278 // HEADS UP overwrites default Outlayer appended 9279 proto.appended = function( elems ) { 9280 var items = this.addItems( elems ); 9281 if ( !items.length ) { 9282 return; 9283 } 9284 // filter, layout, reveal new items 9285 var filteredItems = this._filterRevealAdded( items ); 9286 // add to filteredItems 9287 this.filteredItems = this.filteredItems.concat( filteredItems ); 9288 }; 9289 9290 // HEADS UP overwrites default Outlayer prepended 9291 proto.prepended = function( elems ) { 9292 var items = this._itemize( elems ); 9293 if ( !items.length ) { 9294 return; 9295 } 9296 // start new layout 9297 this._resetLayout(); 9298 this._manageStamps(); 9299 // filter, layout, reveal new items 9300 var filteredItems = this._filterRevealAdded( items ); 9301 // layout previous items 9302 this.layoutItems( this.filteredItems ); 9303 // add to items and filteredItems 9304 this.filteredItems = filteredItems.concat( this.filteredItems ); 9305 this.items = items.concat( this.items ); 9306 }; 9307 9308 proto._filterRevealAdded = function( items ) { 9309 var filtered = this._filter( items ); 9310 this.hide( filtered.needHide ); 9311 // reveal all new items 9312 this.reveal( filtered.matches ); 9313 // layout new items, no transition 9314 this.layoutItems( filtered.matches, true ); 9315 return filtered.matches; 9316 }; 9317 9318 /** 9319 * Filter, sort, and layout newly-appended item elements 9320 * @param {Array or NodeList or Element} elems 9321 */ 9322 proto.insert = function( elems ) { 9323 var items = this.addItems( elems ); 9324 if ( !items.length ) { 9325 return; 9326 } 9327 // append item elements 9328 var i, item; 9329 var len = items.length; 9330 for ( i=0; i < len; i++ ) { 9331 item = items[i]; 9332 this.element.appendChild( item.element ); 9333 } 9334 // filter new stuff 9335 var filteredInsertItems = this._filter( items ).matches; 9336 // set flag 9337 for ( i=0; i < len; i++ ) { 9338 items[i].isLayoutInstant = true; 9339 } 9340 this.arrange(); 9341 // reset flag 9342 for ( i=0; i < len; i++ ) { 9343 delete items[i].isLayoutInstant; 9344 } 9345 this.reveal( filteredInsertItems ); 9346 }; 9347 9348 var _remove = proto.remove; 9349 proto.remove = function( elems ) { 9350 elems = utils.makeArray( elems ); 9351 var removeItems = this.getItems( elems ); 9352 // do regular thing 9353 _remove.call( this, elems ); 9354 // bail if no items to remove 9355 var len = removeItems && removeItems.length; 9356 // remove elems from filteredItems 9357 for ( var i=0; len && i < len; i++ ) { 9358 var item = removeItems[i]; 9359 // remove item from collection 9360 utils.removeFrom( this.filteredItems, item ); 9361 } 9362 }; 9363 9364 proto.shuffle = function() { 9365 // update random sortData 9366 for ( var i=0; i < this.items.length; i++ ) { 9367 var item = this.items[i]; 9368 item.sortData.random = Math.random(); 9369 } 9370 this.options.sortBy = 'random'; 9371 this._sort(); 9372 this._layout(); 9373 }; 9374 9375 /** 9376 * trigger fn without transition 9377 * kind of hacky to have this in the first place 9378 * @param {Function} fn 9379 * @param {Array} args 9380 * @returns ret 9381 * @private 9382 */ 9383 proto._noTransition = function( fn, args ) { 9384 // save transitionDuration before disabling 9385 var transitionDuration = this.options.transitionDuration; 9386 // disable transition 9387 this.options.transitionDuration = 0; 9388 // do it 9389 var returnValue = fn.apply( this, args ); 9390 // re-enable transition for reveal 9391 this.options.transitionDuration = transitionDuration; 9392 return returnValue; 9393 }; 9394 9395 // ----- helper methods ----- // 9396 9397 /** 9398 * getter method for getting filtered item elements 9399 * @returns {Array} elems - collection of item elements 9400 */ 9401 proto.getFilteredItemElements = function() { 9402 return this.filteredItems.map( function( item ) { 9403 return item.element; 9404 }); 9405 }; 9406 9407 // ----- ----- // 9408 9409 return Isotope; 9410 9411})); 9412
vendor: 29,252 bytes, lines 9413-10569
9413/*! 9414 * Packery layout mode PACKAGED v2.0.1 9415 * sub-classes Packery 9416 */ 9417 9418/** 9419 * Rect 9420 * low-level utility class for basic geometry 9421 */ 9422 9423( function( window, factory ) { 9424 // universal module definition 9425 /* jshint strict: false */ /* globals define, module */ 9426 if ( typeof define == 'function' && define.amd ) { 9427 // AMD 9428 define( 'packery/js/rect',factory ); 9429 } else if ( typeof module == 'object' && module.exports ) { 9430 // CommonJS 9431 module.exports = factory(); 9432 } else { 9433 // browser global 9434 window.Packery = window.Packery || {}; 9435 window.Packery.Rect = factory(); 9436 } 9437 9438}( window, function factory() { 9439 9440 9441// -------------------------- Rect -------------------------- // 9442 9443function Rect( props ) { 9444 // extend properties from defaults 9445 for ( var prop in Rect.defaults ) { 9446 this[ prop ] = Rect.defaults[ prop ]; 9447 } 9448 9449 for ( prop in props ) { 9450 this[ prop ] = props[ prop ]; 9451 } 9452 9453} 9454 9455Rect.defaults = { 9456 x: 0, 9457 y: 0, 9458 width: 0, 9459 height: 0 9460}; 9461 9462var proto = Rect.prototype; 9463 9464/** 9465 * Determines whether or not this rectangle wholly encloses another rectangle or point. 9466 * @param {Rect} rect 9467 * @returns {Boolean} 9468**/ 9469proto.contains = function( rect ) { 9470 // points don't have width or height 9471 var otherWidth = rect.width || 0; 9472 var otherHeight = rect.height || 0; 9473 return this.x <= rect.x && 9474 this.y <= rect.y && 9475 this.x + this.width >= rect.x + otherWidth && 9476 this.y + this.height >= rect.y + otherHeight; 9477}; 9478 9479/** 9480 * Determines whether or not the rectangle intersects with another. 9481 * @param {Rect} rect 9482 * @returns {Boolean} 9483**/ 9484proto.overlaps = function( rect ) { 9485 var thisRight = this.x + this.width; 9486 var thisBottom = this.y + this.height; 9487 var rectRight = rect.x + rect.width; 9488 var rectBottom = rect.y + rect.height; 9489 9490 // http://stackoverflow.com/a/306332 9491 return this.x < rectRight && 9492 thisRight > rect.x && 9493 this.y < rectBottom && 9494 thisBottom > rect.y; 9495}; 9496 9497/** 9498 * @param {Rect} rect - the overlapping rect 9499 * @returns {Array} freeRects - rects representing the area around the rect 9500**/ 9501proto.getMaximalFreeRects = function( rect ) { 9502 9503 // if no intersection, return false 9504 if ( !this.overlaps( rect ) ) { 9505 return false; 9506 } 9507 9508 var freeRects = []; 9509 var freeRect; 9510 9511 var thisRight = this.x + this.width; 9512 var thisBottom = this.y + this.height; 9513 var rectRight = rect.x + rect.width; 9514 var rectBottom = rect.y + rect.height; 9515 9516 // top 9517 if ( this.y < rect.y ) { 9518 freeRect = new Rect({ 9519 x: this.x, 9520 y: this.y, 9521 width: this.width, 9522 height: rect.y - this.y 9523 }); 9524 freeRects.push( freeRect ); 9525 } 9526 9527 // right 9528 if ( thisRight > rectRight ) { 9529 freeRect = new Rect({ 9530 x: rectRight, 9531 y: this.y, 9532 width: thisRight - rectRight, 9533 height: this.height 9534 }); 9535 freeRects.push( freeRect ); 9536 } 9537 9538 // bottom 9539 if ( thisBottom > rectBottom ) { 9540 freeRect = new Rect({ 9541 x: this.x, 9542 y: rectBottom, 9543 width: this.width, 9544 height: thisBottom - rectBottom 9545 }); 9546 freeRects.push( freeRect ); 9547 } 9548 9549 // left 9550 if ( this.x < rect.x ) { 9551 freeRect = new Rect({ 9552 x: this.x, 9553 y: this.y, 9554 width: rect.x - this.x, 9555 height: this.height 9556 }); 9557 freeRects.push( freeRect ); 9558 } 9559 9560 return freeRects; 9561}; 9562 9563proto.canFit = function( rect ) { 9564 return this.width >= rect.width && this.height >= rect.height; 9565}; 9566 9567return Rect; 9568 9569})); 9570 9571/** 9572 * Packer 9573 * bin-packing algorithm 9574 */ 9575 9576( function( window, factory ) { 9577 // universal module definition 9578 /* jshint strict: false */ /* globals define, module, require */ 9579 if ( typeof define == 'function' && define.amd ) { 9580 // AMD 9581 define( 'packery/js/packer',[ './rect' ], factory ); 9582 } else if ( typeof module == 'object' && module.exports ) { 9583 // CommonJS 9584 module.exports = factory( 9585 require('./rect') 9586 ); 9587 } else { 9588 // browser global 9589 var Packery = window.Packery = window.Packery || {}; 9590 Packery.Packer = factory( Packery.Rect ); 9591 } 9592 9593}( window, function factory( Rect ) { 9594 9595 9596// -------------------------- Packer -------------------------- // 9597 9598/** 9599 * @param {Number} width 9600 * @param {Number} height 9601 * @param {String} sortDirection 9602 * topLeft for vertical, leftTop for horizontal 9603 */ 9604function Packer( width, height, sortDirection ) { 9605 this.width = width || 0; 9606 this.height = height || 0; 9607 this.sortDirection = sortDirection || 'downwardLeftToRight'; 9608 9609 this.reset(); 9610} 9611 9612var proto = Packer.prototype; 9613 9614proto.reset = function() { 9615 this.spaces = []; 9616 9617 var initialSpace = new Rect({ 9618 x: 0, 9619 y: 0, 9620 width: this.width, 9621 height: this.height 9622 }); 9623 9624 this.spaces.push( initialSpace ); 9625 // set sorter 9626 this.sorter = sorters[ this.sortDirection ] || sorters.downwardLeftToRight; 9627}; 9628 9629// change x and y of rect to fit with in Packer's available spaces 9630proto.pack = function( rect ) { 9631 for ( var i=0; i < this.spaces.length; i++ ) { 9632 var space = this.spaces[i]; 9633 if ( space.canFit( rect ) ) { 9634 this.placeInSpace( rect, space ); 9635 break; 9636 } 9637 } 9638}; 9639 9640proto.columnPack = function( rect ) { 9641 for ( var i=0; i < this.spaces.length; i++ ) { 9642 var space = this.spaces[i]; 9643 var canFitInSpaceColumn = space.x <= rect.x && 9644 space.x + space.width >= rect.x + rect.width && 9645 space.height >= rect.height - 0.01; // fudge number for rounding error 9646 if ( canFitInSpaceColumn ) { 9647 rect.y = space.y; 9648 this.placed( rect ); 9649 break; 9650 } 9651 } 9652}; 9653 9654proto.rowPack = function( rect ) { 9655 for ( var i=0; i < this.spaces.length; i++ ) { 9656 var space = this.spaces[i]; 9657 var canFitInSpaceRow = space.y <= rect.y && 9658 space.y + space.height >= rect.y + rect.height && 9659 space.width >= rect.width - 0.01; // fudge number for rounding error 9660 if ( canFitInSpaceRow ) { 9661 rect.x = space.x; 9662 this.placed( rect ); 9663 break; 9664 } 9665 } 9666}; 9667 9668proto.placeInSpace = function( rect, space ) { 9669 // place rect in space 9670 rect.x = space.x; 9671 rect.y = space.y; 9672 9673 this.placed( rect ); 9674}; 9675 9676// update spaces with placed rect 9677proto.placed = function( rect ) { 9678 // update spaces 9679 var revisedSpaces = []; 9680 for ( var i=0; i < this.spaces.length; i++ ) { 9681 var space = this.spaces[i]; 9682 var newSpaces = space.getMaximalFreeRects( rect ); 9683 // add either the original space or the new spaces to the revised spaces 9684 if ( newSpaces ) { 9685 revisedSpaces.push.apply( revisedSpaces, newSpaces ); 9686 } else { 9687 revisedSpaces.push( space ); 9688 } 9689 } 9690 9691 this.spaces = revisedSpaces; 9692 9693 this.mergeSortSpaces(); 9694}; 9695 9696proto.mergeSortSpaces = function() { 9697 // remove redundant spaces 9698 Packer.mergeRects( this.spaces ); 9699 this.spaces.sort( this.sorter ); 9700}; 9701 9702// add a space back 9703proto.addSpace = function( rect ) { 9704 this.spaces.push( rect ); 9705 this.mergeSortSpaces(); 9706}; 9707 9708// -------------------------- utility functions -------------------------- // 9709 9710/** 9711 * Remove redundant rectangle from array of rectangles 9712 * @param {Array} rects: an array of Rects 9713 * @returns {Array} rects: an array of Rects 9714**/ 9715Packer.mergeRects = function( rects ) { 9716 var i = 0; 9717 var rect = rects[i]; 9718 9719 rectLoop: 9720 while ( rect ) { 9721 var j = 0; 9722 var compareRect = rects[ i + j ]; 9723 9724 while ( compareRect ) { 9725 if ( compareRect == rect ) { 9726 j++; // next 9727 } else if ( compareRect.contains( rect ) ) { 9728 // remove rect 9729 rects.splice( i, 1 ); 9730 rect = rects[i]; // set next rect 9731 continue rectLoop; // bail on compareLoop 9732 } else if ( rect.contains( compareRect ) ) { 9733 // remove compareRect 9734 rects.splice( i + j, 1 ); 9735 } else { 9736 j++; 9737 } 9738 compareRect = rects[ i + j ]; // set next compareRect 9739 } 9740 i++; 9741 rect = rects[i]; 9742 } 9743 9744 return rects; 9745}; 9746 9747 9748// -------------------------- sorters -------------------------- // 9749 9750// functions for sorting rects in order 9751var sorters = { 9752 // top down, then left to right 9753 downwardLeftToRight: function( a, b ) { 9754 return a.y - b.y || a.x - b.x; 9755 }, 9756 // left to right, then top down 9757 rightwardTopToBottom: function( a, b ) { 9758 return a.x - b.x || a.y - b.y; 9759 } 9760}; 9761 9762 9763// -------------------------- -------------------------- // 9764 9765return Packer; 9766 9767})); 9768 9769/** 9770 * Packery Item Element 9771**/ 9772 9773( function( window, factory ) { 9774 // universal module definition 9775 /* jshint strict: false */ /* globals define, module, require */ 9776 if ( typeof define == 'function' && define.amd ) { 9777 // AMD 9778 define( 'packery/js/item',[ 9779 'outlayer/outlayer', 9780 './rect' 9781 ], 9782 factory ); 9783 } else if ( typeof module == 'object' && module.exports ) { 9784 // CommonJS 9785 module.exports = factory( 9786 require('outlayer'), 9787 require('./rect') 9788 ); 9789 } else { 9790 // browser global 9791 window.Packery.Item = factory( 9792 window.Outlayer, 9793 window.Packery.Rect 9794 ); 9795 } 9796 9797}( window, function factory( Outlayer, Rect ) { 9798 9799 9800// -------------------------- Item -------------------------- // 9801 9802var docElemStyle = document.documentElement.style; 9803 9804var transformProperty = typeof docElemStyle.transform == 'string' ? 9805 'transform' : 'WebkitTransform'; 9806 9807// sub-class Item 9808var Item = function PackeryItem() { 9809 Outlayer.Item.apply( this, arguments ); 9810}; 9811 9812var proto = Item.prototype = Object.create( Outlayer.Item.prototype ); 9813 9814var __create = proto._create; 9815proto._create = function() { 9816 // call default _create logic 9817 __create.call( this ); 9818 this.rect = new Rect(); 9819}; 9820 9821var _moveTo = proto.moveTo; 9822proto.moveTo = function( x, y ) { 9823 // don't shift 1px while dragging 9824 var dx = Math.abs( this.position.x - x ); 9825 var dy = Math.abs( this.position.y - y ); 9826 9827 var canHackGoTo = this.layout.dragItemCount && !this.isPlacing && 9828 !this.isTransitioning && dx < 1 && dy < 1; 9829 if ( canHackGoTo ) { 9830 this.goTo( x, y ); 9831 return; 9832 } 9833 _moveTo.apply( this, arguments ); 9834}; 9835 9836// -------------------------- placing -------------------------- // 9837 9838proto.enablePlacing = function() { 9839 this.removeTransitionStyles(); 9840 // remove transform property from transition 9841 if ( this.isTransitioning && transformProperty ) { 9842 this.element.style[ transformProperty ] = 'none'; 9843 } 9844 this.isTransitioning = false; 9845 this.getSize(); 9846 this.layout._setRectSize( this.element, this.rect ); 9847 this.isPlacing = true; 9848}; 9849 9850proto.disablePlacing = function() { 9851 this.isPlacing = false; 9852}; 9853 9854// ----- ----- // 9855 9856// remove element from DOM 9857proto.removeElem = function() { 9858 this.element.parentNode.removeChild( this.element ); 9859 // add space back to packer 9860 this.layout.packer.addSpace( this.rect ); 9861 this.emitEvent( 'remove', [ this ] ); 9862}; 9863 9864// ----- dropPlaceholder ----- // 9865 9866proto.showDropPlaceholder = function() { 9867 var dropPlaceholder = this.dropPlaceholder; 9868 if ( !dropPlaceholder ) { 9869 // create dropPlaceholder 9870 dropPlaceholder = this.dropPlaceholder = document.createElement('div'); 9871 dropPlaceholder.className = 'packery-drop-placeholder'; 9872 dropPlaceholder.style.position = 'absolute'; 9873 } 9874 9875 dropPlaceholder.style.width = this.size.width + 'px'; 9876 dropPlaceholder.style.height = this.size.height + 'px'; 9877 this.positionDropPlaceholder(); 9878 this.layout.element.appendChild( dropPlaceholder ); 9879}; 9880 9881proto.positionDropPlaceholder = function() { 9882 this.dropPlaceholder.style[ transformProperty ] = 'translate(' + 9883 this.rect.x + 'px, ' + this.rect.y + 'px)'; 9884}; 9885 9886proto.hideDropPlaceholder = function() { 9887 this.layout.element.removeChild( this.dropPlaceholder ); 9888}; 9889 9890// ----- ----- // 9891 9892return Item; 9893 9894})); 9895 9896/*! 9897 * Packery v2.0.0 9898 * Gapless, draggable grid layouts 9899 * 9900 * Licensed GPLv3 for open source use 9901 * or Packery Commercial License for commercial use 9902 * 9903 * http://packery.metafizzy.co 9904 * Copyright 2016 Metafizzy 9905 */ 9906 9907( function( window, factory ) { 9908 // universal module definition 9909 /* jshint strict: false */ /* globals define, module, require */ 9910 if ( typeof define == 'function' && define.amd ) { 9911 // AMD 9912 define( 'packery/js/packery',[ 9913 'get-size/get-size', 9914 'outlayer/outlayer', 9915 './rect', 9916 './packer', 9917 './item' 9918 ], 9919 factory ); 9920 } else if ( typeof module == 'object' && module.exports ) { 9921 // CommonJS 9922 module.exports = factory( 9923 require('get-size'), 9924 require('outlayer'), 9925 require('./rect'), 9926 require('./packer'), 9927 require('./item') 9928 ); 9929 } else { 9930 // browser global 9931 window.Packery = factory( 9932 window.getSize, 9933 window.Outlayer, 9934 window.Packery.Rect, 9935 window.Packery.Packer, 9936 window.Packery.Item 9937 ); 9938 } 9939 9940}( window, function factory( getSize, Outlayer, Rect, Packer, Item ) { 9941 9942 9943// ----- Rect ----- // 9944 9945// allow for pixel rounding errors IE8-IE11 & Firefox; #227 9946Rect.prototype.canFit = function( rect ) { 9947 return this.width >= rect.width - 1 && this.height >= rect.height - 1; 9948}; 9949 9950// -------------------------- Packery -------------------------- // 9951 9952// create an Outlayer layout class 9953var Packery = Outlayer.create('packery'); 9954Packery.Item = Item; 9955 9956var proto = Packery.prototype; 9957 9958proto._create = function() { 9959 // call super 9960 Outlayer.prototype._create.call( this ); 9961 9962 // initial properties 9963 this.packer = new Packer(); 9964 // packer for drop targets 9965 this.shiftPacker = new Packer(); 9966 this.isEnabled = true; 9967 9968 this.dragItemCount = 0; 9969 9970 // create drag handlers 9971 var _this = this; 9972 this.handleDraggabilly = { 9973 dragStart: function() { 9974 _this.itemDragStart( this.element ); 9975 }, 9976 dragMove: function() { 9977 _this.itemDragMove( this.element, this.position.x, this.position.y ); 9978 }, 9979 dragEnd: function() { 9980 _this.itemDragEnd( this.element ); 9981 } 9982 }; 9983 9984 this.handleUIDraggable = { 9985 start: function handleUIDraggableStart( event, ui ) { 9986 // HTML5 may trigger dragstart, dismiss HTML5 dragging 9987 if ( !ui ) { 9988 return; 9989 } 9990 _this.itemDragStart( event.currentTarget ); 9991 }, 9992 drag: function handleUIDraggableDrag( event, ui ) { 9993 if ( !ui ) { 9994 return; 9995 } 9996 _this.itemDragMove( event.currentTarget, ui.position.left, ui.position.top ); 9997 }, 9998 stop: function handleUIDraggableStop( event, ui ) { 9999 if ( !ui ) { 10000 return; 10001 } 10002 _this.itemDragEnd( event.currentTarget ); 10003 } 10004 }; 10005 10006}; 10007 10008 10009// ----- init & layout ----- // 10010 10011/** 10012 * logic before any new layout 10013 */ 10014proto._resetLayout = function() { 10015 this.getSize(); 10016 10017 this._getMeasurements(); 10018 10019 // reset packer 10020 var width, height, sortDirection; 10021 // packer settings, if horizontal or vertical 10022 if ( this._getOption('horizontal') ) { 10023 width = Infinity; 10024 height = this.size.innerHeight + this.gutter; 10025 sortDirection = 'rightwardTopToBottom'; 10026 } else { 10027 width = this.size.innerWidth + this.gutter; 10028 height = Infinity; 10029 sortDirection = 'downwardLeftToRight'; 10030 } 10031 10032 this.packer.width = this.shiftPacker.width = width; 10033 this.packer.height = this.shiftPacker.height = height; 10034 this.packer.sortDirection = this.shiftPacker.sortDirection = sortDirection; 10035 10036 this.packer.reset(); 10037 10038 // layout 10039 this.maxY = 0; 10040 this.maxX = 0; 10041}; 10042 10043/** 10044 * update columnWidth, rowHeight, & gutter 10045 * @private 10046 */ 10047proto._getMeasurements = function() { 10048 this._getMeasurement( 'columnWidth', 'width' ); 10049 this._getMeasurement( 'rowHeight', 'height' ); 10050 this._getMeasurement( 'gutter', 'width' ); 10051}; 10052 10053proto._getItemLayoutPosition = function( item ) { 10054 this._setRectSize( item.element, item.rect ); 10055 if ( this.isShifting || this.dragItemCount > 0 ) { 10056 var packMethod = this._getPackMethod(); 10057 this.packer[ packMethod ]( item.rect ); 10058 } else { 10059 this.packer.pack( item.rect ); 10060 } 10061 10062 this._setMaxXY( item.rect ); 10063 return item.rect; 10064}; 10065 10066proto.shiftLayout = function() { 10067 this.isShifting = true; 10068 this.layout(); 10069 delete this.isShifting; 10070}; 10071 10072proto._getPackMethod = function() { 10073 return this._getOption('horizontal') ? 'rowPack' : 'columnPack'; 10074}; 10075 10076 10077/** 10078 * set max X and Y value, for size of container 10079 * @param {Packery.Rect} rect 10080 * @private 10081 */ 10082proto._setMaxXY = function( rect ) { 10083 this.maxX = Math.max( rect.x + rect.width, this.maxX ); 10084 this.maxY = Math.max( rect.y + rect.height, this.maxY ); 10085}; 10086 10087/** 10088 * set the width and height of a rect, applying columnWidth and rowHeight 10089 * @param {Element} elem 10090 * @param {Packery.Rect} rect 10091 */ 10092proto._setRectSize = function( elem, rect ) { 10093 var size = getSize( elem ); 10094 var w = size.outerWidth; 10095 var h = size.outerHeight; 10096 // size for columnWidth and rowHeight, if available 10097 // only check if size is non-zero, #177 10098 if ( w || h ) { 10099 w = this._applyGridGutter( w, this.columnWidth ); 10100 h = this._applyGridGutter( h, this.rowHeight ); 10101 } 10102 // rect must fit in packer 10103 rect.width = Math.min( w, this.packer.width ); 10104 rect.height = Math.min( h, this.packer.height ); 10105}; 10106 10107/** 10108 * fits item to columnWidth/rowHeight and adds gutter 10109 * @param {Number} measurement - item width or height 10110 * @param {Number} gridSize - columnWidth or rowHeight 10111 * @returns measurement 10112 */ 10113proto._applyGridGutter = function( measurement, gridSize ) { 10114 // just add gutter if no gridSize 10115 if ( !gridSize ) { 10116 return measurement + this.gutter; 10117 } 10118 gridSize += this.gutter; 10119 // fit item to columnWidth/rowHeight 10120 var remainder = measurement % gridSize; 10121 var mathMethod = remainder && remainder < 1 ? 'round' : 'ceil'; 10122 measurement = Math[ mathMethod ]( measurement / gridSize ) * gridSize; 10123 return measurement; 10124}; 10125 10126proto._getContainerSize = function() { 10127 if ( this._getOption('horizontal') ) { 10128 return { 10129 width: this.maxX - this.gutter 10130 }; 10131 } else { 10132 return { 10133 height: this.maxY - this.gutter 10134 }; 10135 } 10136}; 10137 10138 10139// -------------------------- stamp -------------------------- // 10140 10141/** 10142 * makes space for element 10143 * @param {Element} elem 10144 */ 10145proto._manageStamp = function( elem ) { 10146 10147 var item = this.getItem( elem ); 10148 var rect; 10149 if ( item && item.isPlacing ) { 10150 rect = item.rect; 10151 } else { 10152 var offset = this._getElementOffset( elem ); 10153 rect = new Rect({ 10154 x: this._getOption('originLeft') ? offset.left : offset.right, 10155 y: this._getOption('originTop') ? offset.top : offset.bottom 10156 }); 10157 } 10158 10159 this._setRectSize( elem, rect ); 10160 // save its space in the packer 10161 this.packer.placed( rect ); 10162 this._setMaxXY( rect ); 10163}; 10164 10165// -------------------------- methods -------------------------- // 10166 10167function verticalSorter( a, b ) { 10168 return a.position.y - b.position.y || a.position.x - b.position.x; 10169} 10170 10171function horizontalSorter( a, b ) { 10172 return a.position.x - b.position.x || a.position.y - b.position.y; 10173} 10174 10175proto.sortItemsByPosition = function() { 10176 var sorter = this._getOption('horizontal') ? horizontalSorter : verticalSorter; 10177 this.items.sort( sorter ); 10178}; 10179 10180/** 10181 * Fit item element in its current position 10182 * Packery will position elements around it 10183 * useful for expanding elements 10184 * 10185 * @param {Element} elem 10186 * @param {Number} x - horizontal destination position, optional 10187 * @param {Number} y - vertical destination position, optional 10188 */ 10189proto.fit = function( elem, x, y ) { 10190 var item = this.getItem( elem ); 10191 if ( !item ) { 10192 return; 10193 } 10194 10195 // stamp item to get it out of layout 10196 this.stamp( item.element ); 10197 // set placing flag 10198 item.enablePlacing(); 10199 this.updateShiftTargets( item ); 10200 // fall back to current position for fitting 10201 x = x === undefined ? item.rect.x: x; 10202 y = y === undefined ? item.rect.y: y; 10203 // position it best at its destination 10204 this.shift( item, x, y ); 10205 this._bindFitEvents( item ); 10206 item.moveTo( item.rect.x, item.rect.y ); 10207 // layout everything else 10208 this.shiftLayout(); 10209 // return back to regularly scheduled programming 10210 this.unstamp( item.element ); 10211 this.sortItemsByPosition(); 10212 item.disablePlacing(); 10213}; 10214 10215/** 10216 * emit event when item is fit and other items are laid out 10217 * @param {Packery.Item} item 10218 * @private 10219 */ 10220proto._bindFitEvents = function( item ) { 10221 var _this = this; 10222 var ticks = 0; 10223 function onLayout() { 10224 ticks++; 10225 if ( ticks != 2 ) { 10226 return; 10227 } 10228 _this.dispatchEvent( 'fitComplete', null, [ item ] ); 10229 } 10230 // when item is laid out 10231 item.once( 'layout', onLayout ); 10232 // when all items are laid out 10233 this.once( 'layoutComplete', onLayout ); 10234}; 10235 10236// -------------------------- resize -------------------------- // 10237 10238// debounced, layout on resize 10239proto.resize = function() { 10240 // don't trigger if size did not change 10241 // or if resize was unbound. See #285, outlayer#9 10242 if ( !this.isResizeBound || !this.needsResizeLayout() ) { 10243 return; 10244 } 10245 10246 if ( this.options.shiftPercentResize ) { 10247 this.resizeShiftPercentLayout(); 10248 } else { 10249 this.layout(); 10250 } 10251}; 10252 10253/** 10254 * check if layout is needed post layout 10255 * @returns Boolean 10256 */ 10257proto.needsResizeLayout = function() { 10258 var size = getSize( this.element ); 10259 var innerSize = this._getOption('horizontal') ? 'innerHeight' : 'innerWidth'; 10260 return size[ innerSize ] != this.size[ innerSize ]; 10261}; 10262 10263proto.resizeShiftPercentLayout = function() { 10264 var items = this._getItemsForLayout( this.items ); 10265 10266 var isHorizontal = this._getOption('horizontal'); 10267 var coord = isHorizontal ? 'y' : 'x'; 10268 var measure = isHorizontal ? 'height' : 'width'; 10269 var segmentName = isHorizontal ? 'rowHeight' : 'columnWidth'; 10270 var innerSize = isHorizontal ? 'innerHeight' : 'innerWidth'; 10271 10272 // proportional re-align items 10273 var previousSegment = this[ segmentName ]; 10274 previousSegment = previousSegment && previousSegment + this.gutter; 10275 10276 if ( previousSegment ) { 10277 this._getMeasurements(); 10278 var currentSegment = this[ segmentName ] + this.gutter; 10279 items.forEach( function( item ) { 10280 var seg = Math.round( item.rect[ coord ] / previousSegment ); 10281 item.rect[ coord ] = seg * currentSegment; 10282 }); 10283 } else { 10284 var currentSize = getSize( this.element )[ innerSize ] + this.gutter; 10285 var previousSize = this.packer[ measure ]; 10286 items.forEach( function( item ) { 10287 item.rect[ coord ] = ( item.rect[ coord ] / previousSize ) * currentSize; 10288 }); 10289 } 10290 10291 this.shiftLayout(); 10292}; 10293 10294// -------------------------- drag -------------------------- // 10295 10296/** 10297 * handle an item drag start event 10298 * @param {Element} elem 10299 */ 10300proto.itemDragStart = function( elem ) { 10301 if ( !this.isEnabled ) { 10302 return; 10303 } 10304 this.stamp( elem ); 10305 // this.ignore( elem ); 10306 var item = this.getItem( elem ); 10307 if ( !item ) { 10308 return; 10309 } 10310 10311 item.enablePlacing(); 10312 item.showDropPlaceholder(); 10313 this.dragItemCount++; 10314 this.updateShiftTargets( item ); 10315}; 10316 10317proto.updateShiftTargets = function( dropItem ) { 10318 this.shiftPacker.reset(); 10319 10320 // pack stamps 10321 this._getBoundingRect(); 10322 var isOriginLeft = this._getOption('originLeft'); 10323 var isOriginTop = this._getOption('originTop'); 10324 this.stamps.forEach( function( stamp ) { 10325 // ignore dragged item 10326 var item = this.getItem( stamp ); 10327 if ( item && item.isPlacing ) { 10328 return; 10329 } 10330 var offset = this._getElementOffset( stamp ); 10331 var rect = new Rect({ 10332 x: isOriginLeft ? offset.left : offset.right, 10333 y: isOriginTop ? offset.top : offset.bottom 10334 }); 10335 this._setRectSize( stamp, rect ); 10336 // save its space in the packer 10337 this.shiftPacker.placed( rect ); 10338 }, this ); 10339 10340 // reset shiftTargets 10341 var isHorizontal = this._getOption('horizontal'); 10342 var segmentName = isHorizontal ? 'rowHeight' : 'columnWidth'; 10343 var measure = isHorizontal ? 'height' : 'width'; 10344 10345 this.shiftTargetKeys = []; 10346 this.shiftTargets = []; 10347 var boundsSize; 10348 var segment = this[ segmentName ]; 10349 segment = segment && segment + this.gutter; 10350 10351 if ( segment ) { 10352 var segmentSpan = Math.ceil( dropItem.rect[ measure ] / segment ); 10353 var segs = Math.floor( ( this.shiftPacker[ measure ] + this.gutter ) / segment ); 10354 boundsSize = ( segs - segmentSpan ) * segment; 10355 // add targets on top 10356 for ( var i=0; i < segs; i++ ) { 10357 this._addShiftTarget( i * segment, 0, boundsSize ); 10358 } 10359 } else { 10360 boundsSize = ( this.shiftPacker[ measure ] + this.gutter ) - dropItem.rect[ measure ]; 10361 this._addShiftTarget( 0, 0, boundsSize ); 10362 } 10363 10364 // pack each item to measure where shiftTargets are 10365 var items = this._getItemsForLayout( this.items ); 10366 var packMethod = this._getPackMethod(); 10367 items.forEach( function( item ) { 10368 var rect = item.rect; 10369 this._setRectSize( item.element, rect ); 10370 this.shiftPacker[ packMethod ]( rect ); 10371 10372 // add top left corner 10373 this._addShiftTarget( rect.x, rect.y, boundsSize ); 10374 // add bottom left / top right corner 10375 var cornerX = isHorizontal ? rect.x + rect.width : rect.x; 10376 var cornerY = isHorizontal ? rect.y : rect.y + rect.height; 10377 this._addShiftTarget( cornerX, cornerY, boundsSize ); 10378 10379 if ( segment ) { 10380 // add targets for each column on bottom / row on right 10381 var segSpan = Math.round( rect[ measure ] / segment ); 10382 for ( var i=1; i < segSpan; i++ ) { 10383 var segX = isHorizontal ? cornerX : rect.x + segment * i; 10384 var segY = isHorizontal ? rect.y + segment * i : cornerY; 10385 this._addShiftTarget( segX, segY, boundsSize ); 10386 } 10387 } 10388 }, this ); 10389 10390}; 10391 10392proto._addShiftTarget = function( x, y, boundsSize ) { 10393 var checkCoord = this._getOption('horizontal') ? y : x; 10394 if ( checkCoord !== 0 && checkCoord > boundsSize ) { 10395 return; 10396 } 10397 // create string for a key, easier to keep track of what targets 10398 var key = x + ',' + y; 10399 var hasKey = this.shiftTargetKeys.indexOf( key ) != -1; 10400 if ( hasKey ) { 10401 return; 10402 } 10403 this.shiftTargetKeys.push( key ); 10404 this.shiftTargets.push({ x: x, y: y }); 10405}; 10406 10407// -------------------------- drop -------------------------- // 10408 10409proto.shift = function( item, x, y ) { 10410 var shiftPosition; 10411 var minDistance = Infinity; 10412 var position = { x: x, y: y }; 10413 this.shiftTargets.forEach( function( target ) { 10414 var distance = getDistance( target, position ); 10415 if ( distance < minDistance ) { 10416 shiftPosition = target; 10417 minDistance = distance; 10418 } 10419 }); 10420 item.rect.x = shiftPosition.x; 10421 item.rect.y = shiftPosition.y; 10422}; 10423 10424function getDistance( a, b ) { 10425 var dx = b.x - a.x; 10426 var dy = b.y - a.y; 10427 return Math.sqrt( dx * dx + dy * dy ); 10428} 10429 10430// -------------------------- drag move -------------------------- // 10431 10432var DRAG_THROTTLE_TIME = 120; 10433 10434/** 10435 * handle an item drag move event 10436 * @param {Element} elem 10437 * @param {Number} x - horizontal change in position 10438 * @param {Number} y - vertical change in position 10439 */ 10440proto.itemDragMove = function( elem, x, y ) { 10441 var item = this.isEnabled && this.getItem( elem ); 10442 if ( !item ) { 10443 return; 10444 } 10445 10446 x -= this.size.paddingLeft; 10447 y -= this.size.paddingTop; 10448 10449 var _this = this; 10450 function onDrag() { 10451 _this.shift( item, x, y ); 10452 item.positionDropPlaceholder(); 10453 _this.layout(); 10454 } 10455 10456 // throttle 10457 var now = new Date(); 10458 if ( this._itemDragTime && now - this._itemDragTime < DRAG_THROTTLE_TIME ) { 10459 clearTimeout( this.dragTimeout ); 10460 this.dragTimeout = setTimeout( onDrag, DRAG_THROTTLE_TIME ); 10461 } else { 10462 onDrag(); 10463 this._itemDragTime = now; 10464 } 10465}; 10466 10467// -------------------------- drag end -------------------------- // 10468 10469/** 10470 * handle an item drag end event 10471 * @param {Element} elem 10472 */ 10473proto.itemDragEnd = function( elem ) { 10474 var item = this.isEnabled && this.getItem( elem ); 10475 if ( !item ) { 10476 return; 10477 } 10478 10479 clearTimeout( this.dragTimeout ); 10480 item.element.classList.add('is-positioning-post-drag'); 10481 10482 var completeCount = 0; 10483 var _this = this; 10484 function onDragEndLayoutComplete() { 10485 completeCount++; 10486 if ( completeCount != 2 ) { 10487 return; 10488 } 10489 // reset drag item 10490 item.element.classList.remove('is-positioning-post-drag'); 10491 item.hideDropPlaceholder(); 10492 _this.dispatchEvent( 'dragItemPositioned', null, [ item ] ); 10493 } 10494 10495 item.once( 'layout', onDragEndLayoutComplete ); 10496 this.once( 'layoutComplete', onDragEndLayoutComplete ); 10497 item.moveTo( item.rect.x, item.rect.y ); 10498 this.layout(); 10499 this.dragItemCount = Math.max( 0, this.dragItemCount - 1 ); 10500 this.sortItemsByPosition(); 10501 item.disablePlacing(); 10502 this.unstamp( item.element ); 10503}; 10504 10505/** 10506 * binds Draggabilly events 10507 * @param {Draggabilly} draggie 10508 */ 10509proto.bindDraggabillyEvents = function( draggie ) { 10510 this._bindDraggabillyEvents( draggie, 'on' ); 10511}; 10512 10513proto.unbindDraggabillyEvents = function( draggie ) { 10514 this._bindDraggabillyEvents( draggie, 'off' ); 10515}; 10516 10517proto._bindDraggabillyEvents = function( draggie, method ) { 10518 var handlers = this.handleDraggabilly; 10519 draggie[ method ]( 'dragStart', handlers.dragStart ); 10520 draggie[ method ]( 'dragMove', handlers.dragMove ); 10521 draggie[ method ]( 'dragEnd', handlers.dragEnd ); 10522}; 10523 10524/** 10525 * binds jQuery UI Draggable events 10526 * @param {jQuery} $elems 10527 */ 10528proto.bindUIDraggableEvents = function( $elems ) { 10529 this._bindUIDraggableEvents( $elems, 'on' ); 10530}; 10531 10532proto.unbindUIDraggableEvents = function( $elems ) { 10533 this._bindUIDraggableEvents( $elems, 'off' ); 10534}; 10535 10536proto._bindUIDraggableEvents = function( $elems, method ) { 10537 var handlers = this.handleUIDraggable; 10538 $elems 10539 [ method ]( 'dragstart', handlers.start ) 10540 [ method ]( 'drag', handlers.drag ) 10541 [ method ]( 'dragstop', handlers.stop ); 10542}; 10543 10544// ----- destroy ----- // 10545 10546var _destroy = proto.destroy; 10547proto.destroy = function() { 10548 _destroy.apply( this, arguments ); 10549 // disable flag; prevent drag events from triggering. #72 10550 this.isEnabled = false; 10551}; 10552 10553// ----- ----- // 10554 10555Packery.Rect = Rect; 10556Packery.Packer = Packer; 10557 10558return Packery; 10559 10560})); 10561 10562/*! 10563 * Packery layout mode v2.0.1 10564 * sub-classes Packery 10565 */ 10566 10567/*jshint browser: true, strict: true, undef: true, unused: true */ 10568 10569( function( window, factory ) {
10570 10571 // universal module definition 10572 if ( typeof define == 'function' && define.amd ) { 10573 // AMD 10574 define( [ 10575 'isotope-layout/js/layout-mode', 10576 'packery/js/packery' 10577 ], 10578 factory ); 10579 } else if ( typeof module == 'object' && module.exports ) { 10580 // CommonJS 10581 module.exports = factory( 10582 require('isotope-layout/js/layout-mode'), 10583 require('packery') 10584 ); 10585 } else { 10586 // browser global 10587 factory( 10588 window.Isotope.LayoutMode, 10589 window.Packery 10590 ); 10591 } 10592 10593}( window, function factor( LayoutMode, Packery ) { 10594 10595 10596 // create an Outlayer layout class 10597 var PackeryMode = LayoutMode.create('packery'); 10598 var proto = PackeryMode.prototype; 10599 10600 var keepModeMethods = { 10601 _getElementOffset: true, 10602 _getMeasurement: true 10603 }; 10604 10605 // inherit Packery prototype 10606 for ( var method in Packery.prototype ) { 10607 // do not inherit mode methods 10608 if ( !keepModeMethods[ method ] ) { 10609 proto[ method ] = Packery.prototype[ method ]; 10610 } 10611 } 10612 10613 // set packer in _resetLayout 10614 var _resetLayout = proto._resetLayout; 10615 proto._resetLayout = function() { 10616 this.packer = this.packer || new Packery.Packer(); 10617 this.shiftPacker = this.shiftPacker || new Packery.Packer(); 10618 _resetLayout.apply( this, arguments ); 10619 }; 10620 10621 var _getItemLayoutPosition = proto._getItemLayoutPosition; 10622 proto._getItemLayoutPosition = function( item ) { 10623 // set packery rect 10624 item.rect = item.rect || new Packery.Rect(); 10625 return _getItemLayoutPosition.call( this, item ); 10626 }; 10627 10628 // needsResizeLayout for vertical or horizontal 10629 var _needsResizeLayout = proto.needsResizeLayout; 10630 proto.needsResizeLayout = function() { 10631 if ( this._getOption('horizontal') ) { 10632 return this.needsVerticalResizeLayout(); 10633 } else { 10634 return _needsResizeLayout.call( this ); 10635 } 10636 }; 10637 10638 // point to mode options for horizontal 10639 var _getOption = proto._getOption; 10640 proto._getOption = function( option ) { 10641 if ( option == 'horizontal' ) { 10642 return this.options.isHorizontal !== undefined ? 10643 this.options.isHorizontal : this.options.horizontal; 10644 } 10645 return _getOption.apply( this.isotope, arguments ); 10646 }; 10647 10648 return PackeryMode; 10649 10650})); 10651 10652/*! 10653 * cellsByRows layout mode for Isotope 10654 * v1.1.3 10655 * http://isotope.metafizzy.co/layout-modes/cellsbyrow.html 10656 */ 10657 10658/*jshint browser: true, devel: false, strict: true, undef: true, unused: true */ 10659 10660( function( window, factory ) { 10661 // universal module definition 10662 /* jshint strict: false */ /*globals define, module, require */ 10663 if ( typeof define === 'function' && define.amd ) { 10664 // AMD 10665 define( [ 10666 'isotope/js/layout-mode' 10667 ], 10668 factory ); 10669 } else if ( typeof exports === 'object' ) { 10670 // CommonJS 10671 module.exports = factory( 10672 require('isotope-layout/js/layout-mode') 10673 ); 10674 } else { 10675 // browser global 10676 factory( 10677 window.Isotope.LayoutMode 10678 ); 10679 } 10680 10681}( window, function factory( LayoutMode ) { 10682 'use strict'; 10683 10684 var CellsByRow = LayoutMode.create( 'cellsByRow' ); 10685 var proto = CellsByRow.prototype; 10686 10687 proto._resetLayout = function() { 10688 // reset properties 10689 this.itemIndex = 0; 10690 // measurements 10691 this.getColumnWidth(); 10692 this.getRowHeight(); 10693 // set cols 10694 this.cols = Math.floor( this.isotope.size.innerWidth / this.columnWidth ); 10695 this.cols = Math.max( this.cols, 1 ); 10696 }; 10697 10698 proto._getItemLayoutPosition = function( item ) { 10699 item.getSize(); 10700 var col = this.itemIndex % this.cols; 10701 var row = Math.floor( this.itemIndex / this.cols ); 10702 // center item within cell 10703 var x = ( col + 0.5 ) * this.columnWidth - item.size.outerWidth / 2; 10704 var y = ( row + 0.5 ) * this.rowHeight - item.size.outerHeight / 2; 10705 this.itemIndex++; 10706 return { x: x, y: y }; 10707 }; 10708 10709 proto._getContainerSize = function() { 10710 return { 10711 height: Math.ceil( this.itemIndex / this.cols ) * this.rowHeight 10712 }; 10713 }; 10714 10715 return CellsByRow; 10716 10717})); 10718/*global jQuery: true */ 10719 10720/*! 10721 -------------------------------- 10722 Infinite Scroll 10723 -------------------------------- 10724 + https://github.com/paulirish/infinite-scroll 10725 + version 2.1.0 10726 + Copyright 2011/12 Paul Irish & Luke Shumard 10727 + Licensed under the MIT license 10728 10729 + Documentation: http://infinite-scroll.com/ 10730*/ 10731 10732// Uses AMD or browser globals to create a jQuery plugin. 10733(function (factory) { 10734 if (typeof define === 'function' && define.amd) { 10735 // AMD. Register as an anonymous module. 10736 define(['jquery'], factory); 10737 } else { 10738 // Browser globals 10739 factory(jQuery); 10740 } 10741}(function ($, undefined) { 10742 'use strict'; 10743
10744 $.infinitescroll = function infscr(options, callback, element) { 10745 this.element = $(element); 10746 10747 // Flag the object in the event of a failed creation 10748 if (!this._create(options, callback)) { 10749 this.failed = true; 10750 } 10751 }; 10752 10753 $.infinitescroll.defaults = { 10754 loading: { 10755 finished: undefined, 10756 finishedMsg: "<em>Congratulations, you've reached the end of the internet.</em>", 10757 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
10757MzExnbRvQ2Sy7vN0zvVtNfU2tLY3rPgLdnDvca4VQS/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
10757iqpQpZ4apwSwRtjqrB3muoF9BboaXKmshlqWqsWiGt2wphJkQbAU5hoCACH5BAUKABsALAcABADOAAsAAAX/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', 10758 msg: null, 10759 msgText: '<em>Loading the next set of posts...</em>', 10760 selector: null, 10761 speed: 'fast', 10762 start: undefined 10763 }, 10764 state: { 10765 isDuringAjax: false, 10766 isInvalidPage: false,
10767 isDestroyed: false, 10768 isDone: false, // For when it goes all the way through the archive. 10769 isPaused: false, 10770 isBeyondMaxPage: false, 10771 currPage: 1 10772 }, 10773 debug: false, 10774 behavior: undefined, 10775 binder: $(window), // used to cache the selector 10776 nextSelector: 'div.navigation a:first', 10777 navSelector: 'div.navigation', 10778 contentSelector: null, // rename to pageFragment 10779 extraScrollPx: 150, 10780 itemSelector: 'div.post', 10781 animate: false, 10782 pathParse: undefined, 10783 dataType: 'html', 10784 appendCallback: true, 10785 bufferPx: 40, 10786 errorCallback: function () { }, 10787 infid: 0, //Instance ID 10788 pixelsFromNavToBottom: undefined, 10789 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 10790 prefill: false, // When the document is smaller than the window, load data until the document is larger or links are exhausted 10791 maxPage: undefined // to manually control maximum page (when maxPage is undefined, maximum page limitation is not work) 10792 }; 10793 10794 $.infinitescroll.prototype = { 10795 10796 /* 10797 ---------------------------- 10798 Private methods 10799 ---------------------------- 10800 */ 10801 10802 // Bind or unbind from scroll 10803 _binding: function infscr_binding(binding) { 10804 10805 var instance = this, 10806 opts = instance.options; 10807 10808 opts.v = '2.0b2.120520'; 10809 10810 // if behavior is defined and this function is extended, call that instead of default 10811 if (!!opts.behavior && this['_binding_'+opts.behavior] !== undefined) { 10812 this['_binding_'+opts.behavior].call(this); 10813 return; 10814 } 10815 10816 if (binding !== 'bind' && binding !== 'unbind') { 10817 this._debug('Binding value ' + binding + ' not valid'); 10818 return false; 10819 } 10820 10821 if (binding === 'unbind') { 10822 (this.options.binder).unbind('smartscroll.infscr.' + instance.options.infid); 10823 } else { 10824 (this.options.binder)[binding]('smartscroll.infscr.' + instance.options.infid, function () { 10825 instance.scroll(); 10826 }); 10827 } 10828 10829 this._debug('Binding', binding); 10830 }, 10831 10832 // Fundamental aspects of the plugin are initialized 10833 _create: function infscr_create(options, callback) { 10834 10835 // Add custom options to defaults 10836 var opts = $.extend(true, {}, $.infinitescroll.defaults, options); 10837 this.options = opts; 10838 var $window = $(window); 10839 var instance = this; 10840 10841 // Validate selectors 10842 if (!instance._validate(options)) { 10843 return false; 10844 } 10845 10846 // Validate page fragment path 10847 var path = $(opts.nextSelector).attr('href'); 10848 if (!path) { 10849 this._debug('Navigation selector not found'); 10850 return false; 10851 } 10852 10853 // Set the path to be a relative URL from root. 10854 opts.path = opts.path || this._determinepath(path); 10855 10856 // contentSelector is 'page fragment' option for .load() / .ajax() calls 10857 opts.contentSelector = opts.contentSelector || this.element; 10858 10859 // loading.selector - if we want to place the load message in a specific selector, defaulted to the contentSelector 10860 opts.loading.selector = opts.loading.selector || opts.contentSelector; 10861 10862 // Define loading.msg 10863 opts.loading.msg = opts.loading.msg || $('<div id="infscr-loading"><img alt="Loading..." src="' + opts.loading.img + '" /><div>' + opts.loading.msgText + '</div></div>'); 10864 10865 // Preload loading.img 10866 (new Image()).src = opts.loading.img; 10867 10868 // distance from nav links to bottom 10869 // computed as: height of the document + top offset of container - top offset of nav link 10870 if(opts.pixelsFromNavToBottom === undefined) { 10871 opts.pixelsFromNavToBottom = $(document).height() - $(opts.navSelector).offset().top; 10872 this._debug('pixelsFromNavToBottom: ' + opts.pixelsFromNavToBottom); 10873 } 10874 10875 var self = this; 10876 10877 // determine loading.start actions 10878 opts.loading.start = opts.loading.start || function() { 10879 $(opts.navSelector).hide(); 10880 opts.loading.msg 10881 .appendTo(opts.loading.selector) 10882 .show(opts.loading.speed, $.proxy(function() { 10883 this.beginAjax(opts); 10884 }, self)); 10885 }; 10886 10887 // determine loading.finished actions 10888 opts.loading.finished = opts.loading.finished || function() { 10889 if (!opts.state.isBeyondMaxPage) 10890 opts.loading.msg.fadeOut(opts.loading.speed); 10891 }; 10892 10893 // callback loading 10894 opts.callback = function(instance, data, url) { 10895 if (!!opts.behavior && instance['_callback_'+opts.behavior] !== undefined) { 10896 instance['_callback_'+opts.behavior].call($(opts.contentSelector)[0], data, url); 10897 } 10898 10899 if (callback) { 10900 callback.call($(opts.contentSelector)[0], data, opts, url); 10901 } 10902 10903 if (opts.prefill) { 10904 $window.bind('resize.infinite-scroll', instance._prefill); 10905 } 10906 }; 10907 10908 if (options.debug) { 10909 // Tell IE9 to use its built-in console 10910 if (Function.prototype.bind && (typeof console === 'object' || typeof console === 'function') && typeof console.log === 'object') { 10911 ['log','info','warn','error','assert','dir','clear','profile','profileEnd'] 10912 .forEach(function (method) { 10913 console[method] = this.call(console[method], console); 10914 }, Function.prototype.bind); 10915 } 10916 } 10917 10918 this._setup(); 10919 10920 // Setups the prefill method for use 10921 if (opts.prefill) { 10922 this._prefill(); 10923 } 10924 10925 // Return true to indicate successful creation 10926 return true; 10927 }, 10928 10929 _prefill: function infscr_prefill() { 10930 var instance = this; 10931 var $window = $(window); 10932 10933 function needsPrefill() { 10934 return ( $(instance.options.contentSelector).height() <= $window.height() ); 10935 } 10936 10937 this._prefill = function() { 10938 if (needsPrefill()) { 10939 instance.scroll(); 10940 } 10941 10942 $window.bind('resize.infinite-scroll', function() { 10943 if (needsPrefill()) { 10944 $window.unbind('resize.infinite-scroll'); 10945 instance.scroll(); 10946 } 10947 }); 10948 }; 10949 10950 // Call self after setting up the new function 10951 this._prefill(); 10952 }, 10953 10954 // Console log wrapper 10955 _debug: function infscr_debug() { 10956 if (true !== this.options.debug) { 10957 return; 10958 } 10959 10960 if (typeof console !== 'undefined' && typeof console.log === 'function') { 10961 // Modern browsers 10962 // Single argument, which is a string 10963 if ((Array.prototype.slice.call(arguments)).length === 1 && typeof Array.prototype.slice.call(arguments)[0] === 'string') { 10964 console.log( (Array.prototype.slice.call(arguments)).toString() ); 10965 } else { 10966 console.log( Array.prototype.slice.call(arguments) ); 10967 } 10968 } else if (!Function.prototype.bind && typeof console !== 'undefined' && typeof console.log === 'object') { 10969 // IE8 10970 Function.prototype.call.call(console.log, console, Array.prototype.slice.call(arguments)); 10971 } 10972 }, 10973 10974 // find the number to increment in the path.
10975 _determinepath: function infscr_determinepath(path) { 10976 10977 var opts = this.options; 10978 10979 // if behavior is defined and this function is extended, call that instead of default 10980 if (!!opts.behavior && this['_determinepath_'+opts.behavior] !== undefined) { 10981 return this['_determinepath_'+opts.behavior].call(this,path); 10982 } 10983 10984 if (!!opts.pathParse) { 10985 10986 this._debug('pathParse manual'); 10987 return opts.pathParse(path, this.options.state.currPage+1); 10988 10989 } else if (path.match(/^(.*?)\b2\b(.*?$)/)) { 10990 path = path.match(/^(.*?)\b2\b(.*?$)/).slice(1); 10991 10992 // if there is any 2 in the url at all. 10993 } else if (path.match(/^(.*?)2(.*?$)/)) { 10994 10995 // page= is used in django: 10996 // http://www.infinite-scroll.com/changelog/comment-page-1/#comment-127 10997 if (path.match(/^(.*?page=)2(\/.*|$)/)) { 10998 path = path.match(/^(.*?page=)2(\/.*|$)/).slice(1); 10999 return path; 11000 } 11001 11002 path = path.match(/^(.*?)2(.*?$)/).slice(1); 11003 11004 } else { 11005 11006 // page= is used in drupal too but second page is page=1 not page=2: 11007 // thx Jerod Fritz, vladikoff 11008 if (path.match(/^(.*?page=)1(\/.*|$)/)) { 11009 path = path.match(/^(.*?page=)1(\/.*|$)/).slice(1); 11010 return path; 11011 } else { 11012 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."); 11013 // Get rid of isInvalidPage to allow permalink to state 11014 opts.state.isInvalidPage = true; //prevent it from running on this page. 11015 } 11016 } 11017 this._debug('determinePath', path); 11018 return path; 11019 11020 }, 11021 11022 // Custom error 11023 _error: function infscr_error(xhr) { 11024 11025 var opts = this.options; 11026 11027 // if behavior is defined and this function is extended, call that instead of default 11028 if (!!opts.behavior && this['_error_'+opts.behavior] !== undefined) { 11029 this['_error_'+opts.behavior].call(this,xhr); 11030 return; 11031 } 11032 11033 if (xhr !== 'destroy' && xhr !== 'end') { 11034 xhr = 'unknown'; 11035 } 11036 11037 this._debug('Error', xhr); 11038 11039 if (xhr === 'end' || opts.state.isBeyondMaxPage) { 11040 this._showdonemsg(); 11041 } 11042 11043 opts.state.isDone = true; 11044 opts.state.currPage = 1; // if you need to go back to this instance 11045 opts.state.isPaused = false; 11046 opts.state.isBeyondMaxPage = false; 11047 this._binding('unbind'); 11048 11049 }, 11050 11051 // Load Callback 11052 _loadcallback: function infscr_loadcallback(box, data, url) { 11053 var opts = this.options, 11054 callback = this.options.callback, // GLOBAL OBJECT FOR CALLBACK 11055 result = (opts.state.isDone) ? 'done' : (!opts.appendCallback) ? 'no-append' : 'append', 11056 frag; 11057 11058 // if behavior is defined and this function is extended, call that instead of default 11059 if (!!opts.behavior && this['_loadcallback_'+opts.behavior] !== undefined) { 11060 this['_loadcallback_'+opts.behavior].call(this,box,data); 11061 return; 11062 } 11063 11064 switch (result) { 11065 case 'done': 11066 this._showdonemsg(); 11067 return false; 11068 11069 case 'no-append': 11070 if (opts.dataType === 'html') { 11071 data = '<div>' + data + '</div>'; 11072 data = $(data).find(opts.itemSelector); 11073 } 11074 11075 // if it didn't return anything 11076 if (data.length === 0) { 11077 return this._error('end'); 11078 } 11079 11080 break; 11081 11082 case 'append': 11083 var children = box.children(); 11084 // if it didn't return anything 11085 if (children.length === 0) { 11086 return this._error('end'); 11087 } 11088 11089 // use a documentFragment because it works when content is going into a table or UL 11090 frag = document.createDocumentFragment(); 11091 while (box[0].firstChild) { 11092 frag.appendChild(box[0].firstChild); 11093 } 11094 11095 this._debug('contentSelector', $(opts.contentSelector)[0]); 11096 $(opts.contentSelector)[0].appendChild(frag); 11097 // previously, we would pass in the new DOM element as context for the callback 11098 // however we're now using a documentfragment, which doesn't have parents or children, 11099 // so the context is the contentContainer guy, and we pass in an array 11100 // of the elements collected as the first argument. 11101 11102 data = children.get(); 11103 break; 11104 } 11105 11106 // loadingEnd function 11107 opts.loading.finished.call($(opts.contentSelector)[0],opts); 11108 11109 // smooth scroll to ease in the new content 11110 if (opts.animate) { 11111 var scrollTo = $(window).scrollTop() + $(opts.loading.msg).height() + opts.extraScrollPx + 'px'; 11112 $('html,body').animate({ scrollTop: scrollTo }, 800, function () { opts.state.isDuringAjax = false; }); 11113 } 11114 11115 if (!opts.animate) { 11116 // once the call is done, we can allow it again. 11117 opts.state.isDuringAjax = false;
11118 } 11119 11120 callback(this, data, url); 11121 11122 if (opts.prefill) { 11123 this._prefill(); 11124 } 11125 }, 11126 11127 _nearbottom: function infscr_nearbottom() { 11128 11129 var opts = this.options, 11130 pixelsFromWindowBottomToBottom = 0 + $(document).height() - (opts.binder.scrollTop()) - $(window).height(); 11131 11132 // if behavior is defined and this function is extended, call that instead of default 11133 if (!!opts.behavior && this['_nearbottom_'+opts.behavior] !== undefined) { 11134 return this['_nearbottom_'+opts.behavior].call(this); 11135 } 11136 11137 this._debug('math:', pixelsFromWindowBottomToBottom, opts.pixelsFromNavToBottom); 11138 11139 // if distance remaining in the scroll (including buffer) is less than the orignal nav to bottom.... 11140 return (pixelsFromWindowBottomToBottom - opts.bufferPx < opts.pixelsFromNavToBottom); 11141 11142 }, 11143 11144 // Pause / temporarily disable plugin from firing 11145 _pausing: function infscr_pausing(pause) { 11146 11147 var opts = this.options; 11148 11149 // if behavior is defined and this function is extended, call that instead of default 11150 if (!!opts.behavior && this['_pausing_'+opts.behavior] !== undefined) { 11151 this['_pausing_'+opts.behavior].call(this,pause); 11152 return; 11153 } 11154 11155 // If pause is not 'pause' or 'resume', toggle it's value 11156 if (pause !== 'pause' && pause !== 'resume' && pause !== null) { 11157 this._debug('Invalid argument. Toggling pause value instead'); 11158 } 11159 11160 pause = (pause && (pause === 'pause' || pause === 'resume')) ? pause : 'toggle'; 11161 11162 switch (pause) { 11163 case 'pause': 11164 opts.state.isPaused = true; 11165 break; 11166 11167 case 'resume': 11168 opts.state.isPaused = false; 11169 break; 11170 11171 case 'toggle': 11172 opts.state.isPaused = !opts.state.isPaused; 11173 break; 11174 } 11175 11176 this._debug('Paused', opts.state.isPaused); 11177 return false; 11178 11179 }, 11180 11181 // Behavior is determined 11182 // If the behavior option is undefined, it will set to default and bind to scroll 11183 _setup: function infscr_setup() { 11184 11185 var opts = this.options; 11186 11187 // if behavior is defined and this function is extended, call that instead of default 11188 if (!!opts.behavior && this['_setup_'+opts.behavior] !== undefined) { 11189 this['_setup_'+opts.behavior].call(this); 11190 return; 11191 } 11192 11193 this._binding('bind'); 11194 11195 return false; 11196 11197 }, 11198 11199 // Show done message 11200 _showdonemsg: function infscr_showdonemsg() { 11201 11202 var opts = this.options; 11203 11204 // if behavior is defined and this function is extended, call that instead of default 11205 if (!!opts.behavior && this['_showdonemsg_'+opts.behavior] !== undefined) { 11206 this['_showdonemsg_'+opts.behavior].call(this); 11207 return; 11208 } 11209 11210 opts.loading.msg 11211 .find('img') 11212 .hide() 11213 .parent() 11214 .find('div').html(opts.loading.finishedMsg).animate({ opacity: 1 }, 2000, function () { 11215 $(this).parent().fadeOut(opts.loading.speed); 11216 }); 11217 11218 // user provided callback when done 11219 opts.errorCallback.call($(opts.contentSelector)[0],'done'); 11220 }, 11221 11222 // grab each selector option and see if any fail 11223 _validate: function infscr_validate(opts) { 11224 for (var key in opts) { 11225 if (key.indexOf && key.indexOf('Selector') > -1 && $(opts[key]).length === 0) { 11226 this._debug('Your ' + key + ' found no elements.'); 11227 return false; 11228 } 11229 } 11230 11231 return true; 11232 }, 11233 11234 /* 11235 ---------------------------- 11236 Public methods 11237 ---------------------------- 11238 */ 11239 11240 // Bind to scroll 11241 bind: function infscr_bind() { 11242 this._binding('bind'); 11243 }, 11244 11245 // Destroy current instance of plugin 11246 destroy: function infscr_destroy() { 11247 this.options.state.isDestroyed = true; 11248 this.options.loading.finished(); 11249 return this._error('destroy'); 11250 }, 11251 11252 // Set pause value to false 11253 pause: function infscr_pause() { 11254 this._pausing('pause'); 11255 }, 11256 11257 // Set pause value to false 11258 resume: function infscr_resume() { 11259 this._pausing('resume'); 11260 }, 11261 11262 beginAjax: function infscr_ajax(opts) { 11263 var instance = this, 11264 path = opts.path, 11265 box, desturl, method, condition; 11266 11267 // increment the URL bit. e.g. /page/3/ 11268 opts.state.currPage++; 11269 11270 // Manually control maximum page 11271 if ( opts.maxPage !== undefined && opts.state.currPage > opts.maxPage ){ 11272 opts.state.isBeyondMaxPage = true; 11273 this.destroy(); 11274 return; 11275 } 11276 11277 // if we're dealing with a table we can't use DIVs 11278 box = $(opts.contentSelector).is('table, tbody') ? $('<tbody/>') : $('<div/>'); 11279 11280 desturl = (typeof path === 'function') ? path(opts.state.currPage) : path.join(opts.state.currPage); 11281 instance._debug('heading into ajax', desturl); 11282 11283 method = (opts.dataType === 'html' || opts.dataType === 'json' ) ? opts.dataType : 'html+callback'; 11284 if (opts.appendCallback && opts.dataType === 'html') { 11285 method += '+callback'; 11286 } 11287 11288 switch (method) { 11289 case 'html+callback': 11290 instance._debug('Using HTML via .load() method'); 11291 box.load(desturl + ' ' + opts.itemSelector, undefined, function infscr_ajax_callback(responseText) { 11292 instance._loadcallback(box, responseText, desturl); 11293 }); 11294 11295 break; 11296 11297 case 'html': 11298 instance._debug('Using ' + (method.toUpperCase()) + ' via $.ajax() method'); 11299 $.ajax({ 11300 // params 11301 url: desturl, 11302 dataType: opts.dataType, 11303 complete: function infscr_ajax_callback(jqXHR, textStatus) { 11304 condition = (typeof (jqXHR.isResolved) !== 'undefined') ? (jqXHR.isResolved()) : (textStatus === 'success' || textStatus === 'notmodified'); 11305 if (condition) { 11306 instance._loadcallback(box, jqXHR.responseText, desturl); 11307 } else { 11308 instance._error('end'); 11309 } 11310 } 11311 }); 11312 11313 break; 11314 case 'json': 11315 instance._debug('Using ' + (method.toUpperCase()) + ' via $.ajax() method'); 11316 $.ajax({ 11317 dataType: 'json', 11318 type: 'GET', 11319 url: desturl, 11320 success: function (data, textStatus, jqXHR) { 11321 condition = (typeof (jqXHR.isResolved) !== 'undefined') ? (jqXHR.isResolved()) : (textStatus === 'success' || textStatus === 'notmodified'); 11322 if (opts.appendCallback) { 11323 // if appendCallback is true, you must defined template in options. 11324 // note that data passed into _loadcallback is already an html (after processed in opts.template(data)). 11325 if (opts.template !== undefined) { 11326 var theData = opts.template(data); 11327 box.append(theData); 11328 if (condition) { 11329 instance._loadcallback(box, theData); 11330 } else { 11331 instance._error('end'); 11332 } 11333 } else { 11334 instance._debug('template must be defined.'); 11335 instance._error('end'); 11336 } 11337 } else { 11338 // if appendCallback is false, we will pass in the JSON object. you should handle it yourself in your callback. 11339 if (condition) { 11340 instance._loadcallback(box, data, desturl); 11341 } else { 11342 instance._error('end'); 11343 } 11344 } 11345 }, 11346 error: function() { 11347 instance._debug('JSON ajax request failed.'); 11348 instance._error('end'); 11349 } 11350 }); 11351 11352 break; 11353 } 11354 }, 11355 11356 // Retrieve next set of content items 11357 retrieve: function infscr_retrieve(pageNum) { 11358 pageNum = pageNum || null; 11359 11360 var instance = this, 11361 opts = instance.options; 11362 11363 // if behavior is defined and this function is extended, call that instead of default 11364 if (!!opts.behavior && this['retrieve_'+opts.behavior] !== undefined) { 11365 this['retrieve_'+opts.behavior].call(this,pageNum); 11366 return; 11367 } 11368 11369 // for manual triggers, if destroyed, get out of here 11370 if (opts.state.isDestroyed) { 11371 this._debug('Instance is destroyed'); 11372 return false;
11373 } 11374 11375 // we dont want to fire the ajax multiple times 11376 opts.state.isDuringAjax = true; 11377 11378 opts.loading.start.call($(opts.contentSelector)[0],opts); 11379 }, 11380 11381 // Check to see next page is needed 11382 scroll: function infscr_scroll() { 11383 11384 var opts = this.options, 11385 state = opts.state; 11386 11387 // if behavior is defined and this function is extended, call that instead of default 11388 if (!!opts.behavior && this['scroll_'+opts.behavior] !== undefined) { 11389 this['scroll_'+opts.behavior].call(this); 11390 return; 11391 } 11392 11393 if (state.isDuringAjax || state.isInvalidPage || state.isDone || state.isDestroyed || state.isPaused) { 11394 return; 11395 } 11396 11397 if (!this._nearbottom()) { 11398 return; 11399 } 11400 11401 this.retrieve(); 11402 11403 }, 11404 11405 // Toggle pause value 11406 toggle: function infscr_toggle() { 11407 this._pausing(); 11408 }, 11409 11410 // Unbind from scroll 11411 unbind: function infscr_unbind() { 11412 this._binding('unbind'); 11413 }, 11414 11415 // update options 11416 update: function infscr_options(key) { 11417 if ($.isPlainObject(key)) { 11418 this.options = $.extend(true,this.options,key); 11419 } 11420 } 11421 }; 11422 11423 11424 /* 11425 ---------------------------- 11426 Infinite Scroll function 11427 ---------------------------- 11428 11429 Borrowed logic from the following... 11430 11431 jQuery UI 11432 - https://github.com/jquery/jquery-ui/blob/master/ui/jquery.ui.widget.js 11433 11434 jCarousel 11435 - https://github.com/jsor/jcarousel/blob/master/lib/jquery.jcarousel.js 11436 11437 Masonry 11438 - https://github.com/desandro/masonry/blob/master/jquery.masonry.js 11439 11440*/ 11441 11442 $.fn.infinitescroll = function infscr_init(options, callback) { 11443 11444 11445 var thisCall = typeof options; 11446 11447 switch (thisCall) { 11448 11449 // method 11450 case 'string': 11451 var args = Array.prototype.slice.call(arguments, 1); 11452 11453 this.each(function () { 11454 var instance = $.data(this, 'infinitescroll'); 11455 11456 if (!instance) { 11457 // not setup yet 11458 // return $.error('Method ' + options + ' cannot be called until Infinite Scroll is setup'); 11459 return false; 11460 } 11461 11462 if (!$.isFunction(instance[options]) || options.charAt(0) === '_') { 11463 // return $.error('No such method ' + options + ' for Infinite Scroll'); 11464 return false; 11465 } 11466 11467 // no errors! 11468 instance[options].apply(instance, args); 11469 }); 11470 11471 break; 11472 11473 // creation 11474 case 'object': 11475 11476 this.each(function () { 11477 11478 var instance = $.data(this, 'infinitescroll'); 11479 11480 if (instance) { 11481 11482 // update options of current instance 11483 instance.update(options); 11484 11485 } else { 11486 11487 // initialize new instance 11488 instance = new $.infinitescroll(options, callback, this); 11489 11490 // don't attach if instantiation failed 11491 if (!instance.failed) { 11492 $.data(this, 'infinitescroll', instance); 11493 } 11494 11495 } 11496 11497 }); 11498 11499 break; 11500 11501 } 11502 11503 return this; 11504 }; 11505 11506 11507 11508 /* 11509 * smartscroll: debounced scroll event for jQuery * 11510 * https://github.com/lukeshumard/smartscroll 11511 * Based on smartresize by @louis_remi: https://github.com/lrbabe/jquery.smartresize.js * 11512 * Copyright 2011 Louis-Remi & Luke Shumard * Licensed under the MIT license. * 11513 */ 11514 11515 var event = $.event, 11516 scrollTimeout; 11517 11518 event.special.smartscroll = { 11519 setup: function () { 11520 $(this).bind('scroll', event.special.smartscroll.handler); 11521 }, 11522 teardown: function () { 11523 $(this).unbind('scroll', event.special.smartscroll.handler); 11524 }, 11525 handler: function (event, execAsap) { 11526 // Save the context 11527 var context = this, 11528 args = arguments; 11529 11530 // set correct event type 11531 event.type = 'smartscroll'; 11532 11533 if (scrollTimeout) { clearTimeout(scrollTimeout); } 11534 scrollTimeout = setTimeout(function () { 11535 $(context).trigger('smartscroll', args); 11536 }, execAsap === 'execAsap' ? 0 : 100); 11537 } 11538 }; 11539 11540 $.fn.smartscroll = function (fn) {
11541 return fn ? this.bind('smartscroll', fn) : this.trigger('smartscroll', ['execAsap']); 11542 }; 11543 11544})); 11545 11546/*! 11547Waypoints - 4.0.1 11548Copyright © 2011-2016 Caleb Troughton 11549Licensed under the MIT license. 11550https://github.com/imakewebthings/waypoints/blob/master/licenses.txt 11551*/ 11552(function() { 11553 'use strict' 11554 11555 var keyCounter = 0 11556 var allWaypoints = {} 11557 11558 /* http://imakewebthings.com/waypoints/api/waypoint */ 11559 function Waypoint(options) { 11560 if (!options) { 11561 throw new Error('No options passed to Waypoint constructor') 11562 } 11563 if (!options.element) { 11564 throw new Error('No element option passed to Waypoint constructor') 11565 } 11566 if (!options.handler) { 11567 throw new Error('No handler option passed to Waypoint constructor') 11568 } 11569 11570 this.key = 'waypoint-' + keyCounter 11571 this.options = Waypoint.Adapter.extend({}, Waypoint.defaults, options) 11572 this.element = this.options.element 11573 this.adapter = new Waypoint.Adapter(this.element) 11574 this.callback = options.handler 11575 this.axis = this.options.horizontal ? 'horizontal' : 'vertical' 11576 this.enabled = this.options.enabled 11577 this.triggerPoint = null 11578 this.group = Waypoint.Group.findOrCreate({ 11579 name: this.options.group, 11580 axis: this.axis 11581 }) 11582 this.context = Waypoint.Context.findOrCreateByElement(this.options.context) 11583 11584 if (Waypoint.offsetAliases[this.options.offset]) { 11585 this.options.offset = Waypoint.offsetAliases[this.options.offset] 11586 } 11587 this.group.add(this) 11588 this.context.add(this) 11589 allWaypoints[this.key] = this 11590 keyCounter += 1 11591 } 11592 11593 /* Private */ 11594 Waypoint.prototype.queueTrigger = function(direction) { 11595 this.group.queueTrigger(this, direction) 11596 } 11597 11598 /* Private */ 11599 Waypoint.prototype.trigger = function(args) { 11600 if (!this.enabled) { 11601 return 11602 } 11603 if (this.callback) { 11604 this.callback.apply(this, args) 11605 } 11606 } 11607 11608 /* Public */ 11609 /* http://imakewebthings.com/waypoints/api/destroy */ 11610 Waypoint.prototype.destroy = function() { 11611 this.context.remove(this) 11612 this.group.remove(this) 11613 delete allWaypoints[this.key] 11614 } 11615 11616 /* Public */ 11617 /* http://imakewebthings.com/waypoints/api/disable */ 11618 Waypoint.prototype.disable = function() { 11619 this.enabled = false 11620 return this 11621 } 11622 11623 /* Public */ 11624 /* http://imakewebthings.com/waypoints/api/enable */ 11625 Waypoint.prototype.enable = function() { 11626 this.context.refresh() 11627 this.enabled = true 11628 return this 11629 } 11630 11631 /* Public */ 11632 /* http://imakewebthings.com/waypoints/api/next */ 11633 Waypoint.prototype.next = function() { 11634 return this.group.next(this) 11635 } 11636 11637 /* Public */ 11638 /* http://imakewebthings.com/waypoints/api/previous */ 11639 Waypoint.prototype.previous = function() { 11640 return this.group.previous(this) 11641 } 11642 11643 /* Private */ 11644 Waypoint.invokeAll = function(method) { 11645 var allWaypointsArray = []
11646 for (var waypointKey in allWaypoints) { 11647 allWaypointsArray.push(allWaypoints[waypointKey]) 11648 } 11649 for (var i = 0, end = allWaypointsArray.length; i < end; i++) { 11650 allWaypointsArray[i][method]() 11651 } 11652 } 11653 11654 /* Public */ 11655 /* http://imakewebthings.com/waypoints/api/destroy-all */ 11656 Waypoint.destroyAll = function() { 11657 Waypoint.invokeAll('destroy') 11658 } 11659 11660 /* Public */ 11661 /* http://imakewebthings.com/waypoints/api/disable-all */ 11662 Waypoint.disableAll = function() { 11663 Waypoint.invokeAll('disable') 11664 } 11665 11666 /* Public */ 11667 /* http://imakewebthings.com/waypoints/api/enable-all */ 11668 Waypoint.enableAll = function() { 11669 Waypoint.Context.refreshAll() 11670 for (var waypointKey in allWaypoints) { 11671 allWaypoints[waypointKey].enabled = true 11672 } 11673 return this 11674 } 11675 11676 /* Public */ 11677 /* http://imakewebthings.com/waypoints/api/refresh-all */ 11678 Waypoint.refreshAll = function() { 11679 Waypoint.Context.refreshAll() 11680 } 11681 11682 /* Public */ 11683 /* http://imakewebthings.com/waypoints/api/viewport-height */ 11684 Waypoint.viewportHeight = function() { 11685 return window.innerHeight || document.documentElement.clientHeight 11686 } 11687 11688 /* Public */ 11689 /* http://imakewebthings.com/waypoints/api/viewport-width */ 11690 Waypoint.viewportWidth = function() { 11691 return document.documentElement.clientWidth 11692 } 11693 11694 Waypoint.adapters = [] 11695 11696 Waypoint.defaults = { 11697 context: window, 11698 continuous: true, 11699 enabled: true, 11700 group: 'default', 11701 horizontal: false, 11702 offset: 0 11703 } 11704 11705 Waypoint.offsetAliases = { 11706 'bottom-in-view': function() { 11707 return this.context.innerHeight() - this.adapter.outerHeight() 11708 }, 11709 'right-in-view': function() { 11710 return this.context.innerWidth() - this.adapter.outerWidth() 11711 } 11712 } 11713 11714 window.Waypoint = Waypoint 11715}()) 11716;(function() { 11717 'use strict' 11718 11719 function requestAnimationFrameShim(callback) { 11720 window.setTimeout(callback, 1000 / 60) 11721 } 11722 11723 var keyCounter = 0 11724 var contexts = {} 11725 var Waypoint = window.Waypoint 11726 var oldWindowLoad = window.onload 11727 11728 /* http://imakewebthings.com/waypoints/api/context */ 11729 function Context(element) { 11730 this.element = element 11731 this.Adapter = Waypoint.Adapter 11732 this.adapter = new this.Adapter(element) 11733 this.key = 'waypoint-context-' + keyCounter 11734 this.didScroll = false 11735 this.didResize = false 11736 this.oldScroll = { 11737 x: this.adapter.scrollLeft(), 11738 y: this.adapter.scrollTop() 11739 } 11740 this.waypoints = { 11741 vertical: {}, 11742 horizontal: {} 11743 } 11744 11745 element.waypointContextKey = this.key 11746 contexts[element.waypointContextKey] = this 11747 keyCounter += 1 11748 if (!Waypoint.windowContext) { 11749 Waypoint.windowContext = true 11750 Waypoint.windowContext = new Context(window) 11751 } 11752 11753 this.createThrottledScrollHandler() 11754 this.createThrottledResizeHandler() 11755 } 11756 11757 /* Private */ 11758 Context.prototype.add = function(waypoint) { 11759 var axis = waypoint.options.horizontal ? 'horizontal' : 'vertical' 11760 this.waypoints[axis][waypoint.key] = waypoint 11761 this.refresh() 11762 } 11763 11764 /* Private */ 11765 Context.prototype.checkEmpty = function() { 11766 var horizontalEmpty = this.Adapter.isEmptyObject(this.waypoints.horizontal) 11767 var verticalEmpty = this.Adapter.isEmptyObject(this.waypoints.vertical) 11768 var isWindow = this.element == this.element.window 11769 if (horizontalEmpty && verticalEmpty && !isWindow) { 11770 this.adapter.off('.waypoints') 11771 delete contexts[this.key] 11772 } 11773 } 11774 11775 /* Private */ 11776 Context.prototype.createThrottledResizeHandler = function() { 11777 var self = this 11778 11779 function resizeHandler() { 11780 self.handleResize() 11781 self.didResize = false 11782 } 11783 11784 this.adapter.on('resize.waypoints', function() { 11785 if (!self.didResize) { 11786 self.didResize = true 11787 Waypoint.requestAnimationFrame(resizeHandler) 11788 } 11789 }) 11790 } 11791 11792 /* Private */ 11793 Context.prototype.createThrottledScrollHandler = function() { 11794 var self = this 11795 function scrollHandler() { 11796 self.handleScroll() 11797 self.didScroll = false 11798 } 11799 11800 this.adapter.on('scroll.waypoints', function() { 11801 if (!self.didScroll || Waypoint.isTouch) { 11802 self.didScroll = true 11803 Waypoint.requestAnimationFrame(scrollHandler) 11804 } 11805 }) 11806 } 11807 11808 /* Private */ 11809 Context.prototype.handleResize = function() { 11810 Waypoint.Context.refreshAll() 11811 } 11812 11813 /* Private */ 11814 Context.prototype.handleScroll = function() { 11815 var triggeredGroups = {} 11816 var axes = { 11817 horizontal: { 11818 newScroll: this.adapter.scrollLeft(), 11819 oldScroll: this.oldScroll.x, 11820 forward: 'right', 11821 backward: 'left' 11822 }, 11823 vertical: { 11824 newScroll: this.adapter.scrollTop(), 11825 oldScroll: this.oldScroll.y, 11826 forward: 'down', 11827 backward: 'up' 11828 } 11829 } 11830 11831 for (var axisKey in axes) { 11832 var axis = axes[axisKey] 11833 var isForward = axis.newScroll > axis.oldScroll 11834 var direction = isForward ? axis.forward : axis.backward 11835
11836 for (var waypointKey in this.waypoints[axisKey]) { 11837 var waypoint = this.waypoints[axisKey][waypointKey] 11838 if (waypoint.triggerPoint === null) { 11839 continue 11840 } 11841 var wasBeforeTriggerPoint = axis.oldScroll < waypoint.triggerPoint 11842 var nowAfterTriggerPoint = axis.newScroll >= waypoint.triggerPoint 11843 var crossedForward = wasBeforeTriggerPoint && nowAfterTriggerPoint 11844 var crossedBackward = !wasBeforeTriggerPoint && !nowAfterTriggerPoint 11845 if (crossedForward || crossedBackward) { 11846 waypoint.queueTrigger(direction) 11847 triggeredGroups[waypoint.group.id] = waypoint.group 11848 } 11849 } 11850 } 11851 11852 for (var groupKey in triggeredGroups) { 11853 triggeredGroups[groupKey].flushTriggers() 11854 } 11855 11856 this.oldScroll = { 11857 x: axes.horizontal.newScroll, 11858 y: axes.vertical.newScroll 11859 } 11860 } 11861 11862 /* Private */ 11863 Context.prototype.innerHeight = function() { 11864 /*eslint-disable eqeqeq */ 11865 if (this.element == this.element.window) { 11866 return Waypoint.viewportHeight() 11867 } 11868 /*eslint-enable eqeqeq */ 11869 return this.adapter.innerHeight() 11870 } 11871 11872 /* Private */ 11873 Context.prototype.remove = function(waypoint) { 11874 delete this.waypoints[waypoint.axis][waypoint.key] 11875 this.checkEmpty() 11876 } 11877 11878 /* Private */ 11879 Context.prototype.innerWidth = function() { 11880 /*eslint-disable eqeqeq */ 11881 if (this.element == this.element.window) { 11882 return Waypoint.viewportWidth() 11883 } 11884 /*eslint-enable eqeqeq */ 11885 return this.adapter.innerWidth() 11886 } 11887 11888 /* Public */ 11889 /* http://imakewebthings.com/waypoints/api/context-destroy */ 11890 Context.prototype.destroy = function() { 11891 var allWaypoints = [] 11892 for (var axis in this.waypoints) {
11893 for (var waypointKey in this.waypoints[axis]) { 11894 allWaypoints.push(this.waypoints[axis][waypointKey]) 11895 } 11896 } 11897 for (var i = 0, end = allWaypoints.length; i < end; i++) { 11898 allWaypoints[i].destroy() 11899 } 11900 } 11901 11902 /* Public */ 11903 /* http://imakewebthings.com/waypoints/api/context-refresh */ 11904 Context.prototype.refresh = function() { 11905 /*eslint-disable eqeqeq */ 11906 var isWindow = this.element == this.element.window 11907 /*eslint-enable eqeqeq */ 11908 var contextOffset = isWindow ? undefined : this.adapter.offset() 11909 var triggeredGroups = {} 11910 var axes 11911 11912 this.handleScroll() 11913 axes = { 11914 horizontal: { 11915 contextOffset: isWindow ? 0 : contextOffset.left, 11916 contextScroll: isWindow ? 0 : this.oldScroll.x, 11917 contextDimension: this.innerWidth(), 11918 oldScroll: this.oldScroll.x, 11919 forward: 'right', 11920 backward: 'left', 11921 offsetProp: 'left' 11922 }, 11923 vertical: { 11924 contextOffset: isWindow ? 0 : contextOffset.top, 11925 contextScroll: isWindow ? 0 : this.oldScroll.y, 11926 contextDimension: this.innerHeight(), 11927 oldScroll: this.oldScroll.y, 11928 forward: 'down', 11929 backward: 'up', 11930 offsetProp: 'top' 11931 } 11932 } 11933 11934 for (var axisKey in axes) { 11935 var axis = axes[axisKey]
11936 for (var waypointKey in this.waypoints[axisKey]) { 11937 var waypoint = this.waypoints[axisKey][waypointKey] 11938 var adjustment = waypoint.options.offset 11939 var oldTriggerPoint = waypoint.triggerPoint 11940 var elementOffset = 0 11941 var freshWaypoint = oldTriggerPoint == null 11942 var contextModifier, wasBeforeScroll, nowAfterScroll 11943 var triggeredBackward, triggeredForward 11944 11945 if (waypoint.element !== waypoint.element.window) { 11946 elementOffset = waypoint.adapter.offset()[axis.offsetProp] 11947 } 11948 11949 if (typeof adjustment === 'function') { 11950 adjustment = adjustment.apply(waypoint) 11951 } 11952 else if (typeof adjustment === 'string') { 11953 adjustment = parseFloat(adjustment) 11954 if (waypoint.options.offset.indexOf('%') > - 1) { 11955 adjustment = Math.ceil(axis.contextDimension * adjustment / 100) 11956 } 11957 } 11958 11959 contextModifier = axis.contextScroll - axis.contextOffset 11960 waypoint.triggerPoint = Math.floor(elementOffset + contextModifier - adjustment) 11961 wasBeforeScroll = oldTriggerPoint < axis.oldScroll 11962 nowAfterScroll = waypoint.triggerPoint >= axis.oldScroll 11963 triggeredBackward = wasBeforeScroll && nowAfterScroll 11964 triggeredForward = !wasBeforeScroll && !nowAfterScroll 11965 11966 if (!freshWaypoint && triggeredBackward) { 11967 waypoint.queueTrigger(axis.backward) 11968 triggeredGroups[waypoint.group.id] = waypoint.group 11969 } 11970 else if (!freshWaypoint && triggeredForward) { 11971 waypoint.queueTrigger(axis.forward) 11972 triggeredGroups[waypoint.group.id] = waypoint.group 11973 } 11974 else if (freshWaypoint && axis.oldScroll >= waypoint.triggerPoint) { 11975 waypoint.queueTrigger(axis.forward) 11976 triggeredGroups[waypoint.group.id] = waypoint.group 11977 } 11978 } 11979 } 11980 11981 Waypoint.requestAnimationFrame(function() { 11982 for (var groupKey in triggeredGroups) { 11983 triggeredGroups[groupKey].flushTriggers() 11984 } 11985 }) 11986 11987 return this 11988 } 11989 11990 /* Private */ 11991 Context.findOrCreateByElement = function(element) { 11992 return Context.findByElement(element) || new Context(element) 11993 } 11994 11995 /* Private */ 11996 Context.refreshAll = function() { 11997 for (var contextId in contexts) { 11998 contexts[contextId].refresh() 11999 } 12000 } 12001 12002 /* Public */ 12003 /* http://imakewebthings.com/waypoints/api/context-find-by-element */ 12004 Context.findByElement = function(element) { 12005 return contexts[element.waypointContextKey] 12006 } 12007 12008 window.onload = function() { 12009 if (oldWindowLoad) { 12010 oldWindowLoad() 12011 } 12012 Context.refreshAll() 12013 } 12014 12015 12016 Waypoint.requestAnimationFrame = function(callback) { 12017 var requestFn = window.requestAnimationFrame || 12018 window.mozRequestAnimationFrame || 12019 window.webkitRequestAnimationFrame || 12020 requestAnimationFrameShim 12021 requestFn.call(window, callback) 12022 } 12023 Waypoint.Context = Context 12024}()) 12025;(function() { 12026 'use strict' 12027 12028 function byTriggerPoint(a, b) { 12029 return a.triggerPoint - b.triggerPoint 12030 } 12031 12032 function byReverseTriggerPoint(a, b) { 12033 return b.triggerPoint - a.triggerPoint 12034 } 12035 12036 var groups = { 12037 vertical: {}, 12038 horizontal: {} 12039 } 12040 var Waypoint = window.Waypoint 12041 12042 /* http://imakewebthings.com/waypoints/api/group */ 12043 function Group(options) { 12044 this.name = options.name 12045 this.axis = options.axis 12046 this.id = this.name + '-' + this.axis 12047 this.waypoints = [] 12048 this.clearTriggerQueues() 12049 groups[this.axis][this.name] = this 12050 } 12051 12052 /* Private */ 12053 Group.prototype.add = function(waypoint) { 12054 this.waypoints.push(waypoint) 12055 } 12056 12057 /* Private */ 12058 Group.prototype.clearTriggerQueues = function() { 12059 this.triggerQueues = { 12060 up: [], 12061 down: [], 12062 left: [], 12063 right: [] 12064 } 12065 } 12066 12067 /* Private */ 12068 Group.prototype.flushTriggers = function() { 12069 for (var direction in this.triggerQueues) { 12070 var waypoints = this.triggerQueues[direction] 12071 var reverse = direction === 'up' || direction === 'left' 12072 waypoints.sort(reverse ? byReverseTriggerPoint : byTriggerPoint) 12073 for (var i = 0, end = waypoints.length; i < end; i += 1) { 12074 var waypoint = waypoints[i] 12075 if (waypoint.options.continuous || i === waypoints.length - 1) { 12076 waypoint.trigger([direction]) 12077 } 12078 } 12079 } 12080 this.clearTriggerQueues() 12081 } 12082 12083 /* Private */ 12084 Group.prototype.next = function(waypoint) { 12085 this.waypoints.sort(byTriggerPoint) 12086 var index = Waypoint.Adapter.inArray(waypoint, this.waypoints) 12087 var isLast = index === this.waypoints.length - 1 12088 return isLast ? null : this.waypoints[index + 1] 12089 } 12090 12091 /* Private */ 12092 Group.prototype.previous = function(waypoint) { 12093 this.waypoints.sort(byTriggerPoint) 12094 var index = Waypoint.Adapter.inArray(waypoint, this.waypoints) 12095 return index ? this.waypoints[index - 1] : null 12096 } 12097 12098 /* Private */ 12099 Group.prototype.queueTrigger = function(waypoint, direction) { 12100 this.triggerQueues[direction].push(waypoint) 12101 } 12102 12103 /* Private */ 12104 Group.prototype.remove = function(waypoint) { 12105 var index = Waypoint.Adapter.inArray(waypoint, this.waypoints) 12106 if (index > -1) { 12107 this.waypoints.splice(index, 1) 12108 } 12109 } 12110 12111 /* Public */ 12112 /* http://imakewebthings.com/waypoints/api/first */ 12113 Group.prototype.first = function() { 12114 return this.waypoints[0] 12115 } 12116 12117 /* Public */ 12118 /* http://imakewebthings.com/waypoints/api/last */ 12119 Group.prototype.last = function() { 12120 return this.waypoints[this.waypoints.length - 1] 12121 } 12122 12123 /* Private */ 12124 Group.findOrCreate = function(options) { 12125 return groups[options.axis][options.name] || new Group(options) 12126 } 12127 12128 Waypoint.Group = Group 12129}()) 12130;(function() { 12131 'use strict' 12132 12133 var $ = window.jQuery 12134 var Waypoint = window.Waypoint 12135 12136 function JQueryAdapter(element) { 12137 this.$element = $(element) 12138 } 12139 12140 $.each([
12141 'innerHeight', 12142 'innerWidth', 12143 'off', 12144 'offset', 12145 'on', 12146 'outerHeight', 12147 'outerWidth', 12148 'scrollLeft', 12149 'scrollTop' 12150 ], function(i, method) { 12151 JQueryAdapter.prototype[method] = function() { 12152 var args = Array.prototype.slice.call(arguments) 12153 return this.$element[method].apply(this.$element, args) 12154 } 12155 }) 12156 12157 $.each([ 12158 'extend', 12159 'inArray', 12160 'isEmptyObject' 12161 ], function(i, method) { 12162 JQueryAdapter[method] = $[method] 12163 }) 12164 12165 Waypoint.adapters.push({ 12166 name: 'jquery', 12167 Adapter: JQueryAdapter 12168 }) 12169 Waypoint.Adapter = JQueryAdapter 12170}()) 12171;(function() { 12172 'use strict' 12173 12174 var Waypoint = window.Waypoint 12175 12176 function createExtension(framework) { 12177 return function() { 12178 var waypoints = [] 12179 var overrides = arguments[0] 12180 12181 if (framework.isFunction(arguments[0])) { 12182 overrides = framework.extend({}, arguments[1]) 12183 overrides.handler = arguments[0] 12184 } 12185 12186 this.each(function() { 12187 var options = framework.extend({}, overrides, { 12188 element: this 12189 }) 12190 if (typeof options.context === 'string') { 12191 options.context = framework(this).closest(options.context)[0] 12192 } 12193 waypoints.push(new Waypoint(options)) 12194 }) 12195 12196 return waypoints 12197 } 12198 } 12199 12200 if (window.jQuery) { 12201 window.jQuery.fn.waypoint = createExtension(window.jQuery) 12202 } 12203 if (window.Zepto) { 12204 window.Zepto.fn.waypoint = createExtension(window.Zepto) 12205 } 12206}()) 12207; 12208/*! 12209Waypoints Inview Shortcut - 4.0.1 12210Copyright © 2011-2016 Caleb Troughton 12211Licensed under the MIT license. 12212https://github.com/imakewebthings/waypoints/blob/master/licenses.txt 12213*/ 12214(function() { 12215 'use strict' 12216 12217 function noop() {} 12218 12219 var Waypoint = window.Waypoint 12220 12221 /* http://imakewebthings.com/waypoints/shortcuts/inview */ 12222 function Inview(options) { 12223 this.options = Waypoint.Adapter.extend({}, Inview.defaults, options) 12224 this.axis = this.options.horizontal ? 'horizontal' : 'vertical' 12225 this.waypoints = [] 12226 this.element = this.options.element 12227 this.createWaypoints() 12228 } 12229 12230 /* Private */ 12231 Inview.prototype.createWaypoints = function() { 12232 var configs = { 12233 vertical: [{ 12234 down: 'enter', 12235 up: 'exited', 12236 offset: '100%' 12237 }, { 12238 down: 'entered', 12239 up: 'exit', 12240 offset: 'bottom-in-view' 12241 }, { 12242 down: 'exit', 12243 up: 'entered', 12244 offset: 0 12245 }, { 12246 down: 'exited', 12247 up: 'enter', 12248 offset: function() { 12249 return -this.adapter.outerHeight() 12250 } 12251 }], 12252 horizontal: [{ 12253 right: 'enter', 12254 left: 'exited', 12255 offset: '100%' 12256 }, { 12257 right: 'entered', 12258 left: 'exit', 12259 offset: 'right-in-view' 12260 }, { 12261 right: 'exit', 12262 left: 'entered', 12263 offset: 0 12264 }, { 12265 right: 'exited', 12266 left: 'enter', 12267 offset: function() { 12268 return -this.adapter.outerWidth() 12269 } 12270 }] 12271 } 12272 12273 for (var i = 0, end = configs[this.axis].length; i < end; i++) { 12274 var config = configs[this.axis][i] 12275 this.createWaypoint(config) 12276 } 12277 } 12278 12279 /* Private */ 12280 Inview.prototype.createWaypoint = function(config) { 12281 var self = this 12282 this.waypoints.push(new Waypoint({ 12283 context: this.options.context, 12284 element: this.options.element, 12285 enabled: this.options.enabled, 12286 handler: (function(config) { 12287 return function(direction) { 12288 self.options[config[direction]].call(self, direction) 12289 } 12290 }(config)), 12291 offset: config.offset, 12292 horizontal: this.options.horizontal 12293 })) 12294 } 12295 12296 /* Public */ 12297 Inview.prototype.destroy = function() { 12298 for (var i = 0, end = this.waypoints.length; i < end; i++) { 12299 this.waypoints[i].destroy() 12300 } 12301 this.waypoints = [] 12302 } 12303 12304 Inview.prototype.disable = function() { 12305 for (var i = 0, end = this.waypoints.length; i < end; i++) { 12306 this.waypoints[i].disable() 12307 } 12308 } 12309 12310 Inview.prototype.enable = function() { 12311 for (var i = 0, end = this.waypoints.length; i < end; i++) { 12312 this.waypoints[i].enable() 12313 } 12314 } 12315 12316 Inview.defaults = { 12317 context: window, 12318 enabled: true, 12319 enter: noop, 12320 entered: noop,
12321 exit: noop, 12322 exited: noop 12323 } 12324 12325 Waypoint.Inview = Inview 12326}()) 12327; 12328 12329/* 12330 * SmartMenus jQuery v0.9.6 12331 * http://www.smartmenus.org/ 12332 * 12333 * Copyright 2014 Vasil Dinkov, Vadikom Web Ltd. 12334 * http://vadikom.com/ 12335 * 12336 * Released under the MIT license: 12337 * http://www.opensource.org/licenses/MIT 12338 */ 12339 12340(function($) { 12341 12342 var menuTrees = [], 12343 IE = !!window.createPopup, // we need to detect it, unfortunately 12344 IElt9 = IE && !document.defaultView, 12345 IElt8 = IE && !document.querySelector, 12346 IE6 = IE && typeof document.documentElement.currentStyle.minWidth == 'undefined', 12347 mouse = false, // optimize for touch by default - we will detect for mouse input 12348 mouseDetectionEnabled = false; 12349 12350 // Handle detection for mouse input (i.e. desktop browsers, tablets with a mouse, etc.) 12351 function initMouseDetection(disable) { 12352 if (!mouseDetectionEnabled && !disable) { 12353 // if we get two consecutive mousemoves within 2 pixels from each other and within 300ms, we assume a real mouse/cursor is present 12354 // 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) 12355 var firstTime = true, 12356 lastMove = null; 12357 $(document).bind({ 12358 'mousemove.smartmenus_mouse': function(e) { 12359 var thisMove = { x: e.pageX, y: e.pageY, timeStamp: new Date().getTime() }; 12360 if (lastMove) { 12361 var deltaX = Math.abs(lastMove.x - thisMove.x), 12362 deltaY = Math.abs(lastMove.y - thisMove.y); 12363 if ((deltaX > 0 || deltaY > 0) && deltaX <= 2 && deltaY <= 2 && thisMove.timeStamp - lastMove.timeStamp <= 300) { 12364 mouse = true; 12365 // 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 12366 if (firstTime) { 12367 var $a = $(e.target).closest('a'); 12368 if ($a.is('a')) { 12369 $.each(menuTrees, function() { 12370 if ($.contains(this.$root[0], $a[0])) { 12371 this.itemEnter({ currentTarget: $a[0] }); 12372 return false; 12373 } 12374 }); 12375 } 12376 firstTime = false; 12377 } 12378 } 12379 } 12380 lastMove = thisMove; 12381 }, 12382 'touchstart.smartmenus_mouse pointerover.smartmenus_mouse MSPointerOver.smartmenus_mouse': function(e) { 12383 if (!/^(4|mouse|pen)$/.test(e.originalEvent.pointerType)) { 12384 mouse = false; 12385 } 12386 } 12387 }); 12388 mouseDetectionEnabled = true; 12389 } else if (mouseDetectionEnabled && disable) { 12390 $(document).unbind('.smartmenus_mouse'); 12391 mouseDetectionEnabled = false; 12392 } 12393 }; 12394 12395 $.SmartMenus = function(elm, options) { 12396 this.$root = $(elm); 12397 this.opts = options; 12398 this.rootId = ''; // internal 12399 this.$subArrow = null; 12400 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) 12401 this.activatedItems = []; // stores last activated A's for each level 12402 this.visibleSubMenus = []; // stores visible sub menus UL's 12403 this.showTimeout = 0; 12404 this.hideTimeout = 0; 12405 this.scrollTimeout = 0; 12406 this.clickActivated = false; 12407 this.zIndexInc = 0; 12408 this.$firstLink = null; // we'll use these for some tests 12409 this.$firstSub = null; // at runtime so we'll cache them 12410 this.disabled = false; 12411 this.$disableOverlay = null; 12412 this.init(); 12413 }; 12414 12415 $.extend($.SmartMenus, { 12416 hideAll: function() { 12417 $.each(menuTrees, function() { 12418 this.menuHideAll(); 12419 }); 12420 }, 12421 destroy: function() { 12422 while (menuTrees.length) { 12423 menuTrees[0].destroy(); 12424 } 12425 initMouseDetection(true); 12426 }, 12427 prototype: { 12428 init: function(refresh) { 12429 var self = this; 12430 12431 if (!refresh) { 12432 menuTrees.push(this); 12433 12434 this.rootId = (new Date().getTime() + Math.random() + '').replace(/\D/g, ''); 12435 12436 if (this.$root.hasClass('sm-rtl')) { 12437 this.opts.rightToLeftSubMenus = true; 12438 } 12439 12440 // init root (main menu) 12441 this.$root 12442 .data('smartmenus', this) 12443 .attr('data-smartmenus-id', this.rootId) 12444 .dataSM('level', 1) 12445 .bind({ 12446 'mouseover.smartmenus focusin.smartmenus': $.proxy(this.rootOver, this),
12447 'mouseout.smartmenus focusout.smartmenus': $.proxy(this.rootOut, this) 12448 }) 12449 .delegate('a, div.logo-container', { 12450 'mouseenter.smartmenus': $.proxy(this.itemEnter, this), 12451 'mouseleave.smartmenus': $.proxy(this.itemLeave, this), 12452 'mousedown.smartmenus': $.proxy(this.itemDown, this), 12453 'focus.smartmenus': $.proxy(this.itemFocus, this), 12454 'blur.smartmenus': $.proxy(this.itemBlur, this), 12455 'click.smartmenus': $.proxy(this.itemClick, this), 12456 'touchend.smartmenus': $.proxy(this.itemTouchEnd, this) 12457 }); 12458 12459 var eNamespace = '.smartmenus' + this.rootId; 12460 // hide menus on tap or click outside the root UL 12461 if (this.opts.hideOnClick) { 12462 $(document).on('touchstart' + eNamespace, $.proxy(this.docTouchStart, this)) 12463 .on('touchmove' + eNamespace, $.proxy(this.docTouchMove, this)) 12464 .on('touchend' + eNamespace, $.proxy(this.docTouchEnd, this)) 12465 // for Opera Mobile < 11.5, webOS browser, etc. we'll check click too 12466 .on('click' + eNamespace, $.proxy(this.docClick, this)); 12467 } 12468 // hide sub menus on resize 12469 $(window).on('resize' + eNamespace + ' orientationchange' + eNamespace, $.proxy(this.winResize, this)); 12470 $(window).on('scroll' + eNamespace + ' orientationchange' + eNamespace, $.proxy(this.winResize, this)); 12471 12472 if (this.opts.subIndicators) { 12473 this.$subArrow = $('<span/>').addClass('sub-arrow'); 12474 if (this.opts.subIndicatorsText) { 12475 this.$subArrow.html(this.opts.subIndicatorsText); 12476 } 12477 } 12478 12479 // make sure mouse detection is enabled 12480 initMouseDetection(); 12481 } 12482 12483 // init sub menus 12484 this.$firstSub = this.$root.find('ul').each(function() { self.menuInit($(this)); }).eq(0); 12485 12486 this.$firstLink = this.$root.find('a').eq(0); 12487 12488 // find current item 12489 if (this.opts.markCurrentItem) { 12490 var reDefaultDoc = /(index|default)\.[^#\?\/]*/i, 12491 reHash = /#.*/, 12492 locHref = window.location.href.replace(reDefaultDoc, ''), 12493 locHrefNoHash = locHref.replace(reHash, ''); 12494 this.$root.find('a').each(function() { 12495 var href = this.href.replace(reDefaultDoc, ''), 12496 $this = $(this); 12497 if (href == locHref || href == locHrefNoHash) { 12498 $this.addClass('current'); 12499 if (self.opts.markCurrentTree) { 12500 $this.parents('li').each(function() { 12501 var $this = $(this); 12502 if ($this.dataSM('sub')) { 12503 $this.children('a').addClass('current'); 12504 } 12505 }); 12506 } 12507 } 12508 }); 12509 } 12510 }, 12511 destroy: function() { 12512 this.menuHideAll(); 12513 this.$root 12514 .removeData('smartmenus') 12515 .removeAttr('data-smartmenus-id') 12516 .removeDataSM('level') 12517 .unbind('.smartmenus') 12518 .undelegate('.smartmenus'); 12519 var eNamespace = '.smartmenus' + this.rootId; 12520 $(document).unbind(eNamespace); 12521 $(window).unbind(eNamespace); 12522 if (this.opts.subIndicators) { 12523 this.$subArrow = null; 12524 } 12525 var self = this; 12526 $.each(this.subMenus, function() { 12527 if (this.hasClass('mega-menu')) { 12528 this.find('ul').removeDataSM('in-mega'); 12529 } 12530 if (this.dataSM('shown-before')) { 12531 if (IElt8) { 12532 this.children().css({ styleFloat: '', width: '' }); 12533 } 12534 if (self.opts.subMenusMinWidth || self.opts.subMenusMaxWidth) { 12535 if (!IE6) { 12536 this.css({ width: '', minWidth: '', maxWidth: '' }).removeClass('sm-nowrap'); 12537 } else { 12538 this.css({ width: '', overflowX: '', overflowY: '' }).children().children('a').css('white-space', ''); 12539 } 12540 } 12541 if (this.dataSM('scroll-arrows')) { 12542 this.dataSM('scroll-arrows').remove(); 12543 } 12544 this.css({ zIndex: '', top: '', left: '', marginLeft: '', marginTop: '', display: '' }); 12545 } 12546 if (self.opts.subIndicators) { 12547 this.dataSM('parent-a').removeClass('has-submenu').children('span.sub-arrow').remove(); 12548 } 12549 this.removeDataSM('shown-before') 12550 .removeDataSM('ie-shim') 12551 .removeDataSM('scroll-arrows') 12552 .removeDataSM('parent-a') 12553 .removeDataSM('level') 12554 .removeDataSM('beforefirstshowfired') 12555 .parent().removeDataSM('sub'); 12556 }); 12557 if (this.opts.markCurrentItem) { 12558 this.$root.find('a.current').removeClass('current'); 12559 } 12560 this.$root = null; 12561 this.$firstLink = null; 12562 this.$firstSub = null; 12563 if (this.$disableOverlay) { 12564 this.$disableOverlay.remove(); 12565 this.$disableOverlay = null; 12566 } 12567 menuTrees.splice($.inArray(this, menuTrees), 1); 12568 }, 12569 disable: function(noOverlay) { 12570 if (!this.disabled) { 12571 this.menuHideAll(); 12572 // display overlay over the menu to prevent interaction 12573 if (!noOverlay && !this.opts.isPopup && this.$root.is(':visible')) { 12574 var pos = this.$root.offset(); 12575 this.$disableOverlay = $('<div class="sm-jquery-disable-overlay"/>').css({ 12576 position: 'absolute', 12577 top: pos.top, 12578 left: pos.left, 12579 width: this.$root.outerWidth(), 12580 height: this.$root.outerHeight(),
12581 zIndex: this.getStartZIndex() + 1, 12582 opacity: 0 12583 }).appendTo(document.body); 12584 } 12585 this.disabled = true; 12586 } 12587 }, 12588 docClick: function(e) { 12589 // hide on any click outside the menu or on a menu link 12590 if (this.visibleSubMenus.length && !$.contains(this.$root[0], e.target) || $(e.target).is('a')) { 12591 this.menuHideAll($(e.target)); 12592 } 12593 }, 12594 docTouchEnd: function(e) { 12595 if (!this.lastTouch) { 12596 return; 12597 } 12598 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))) { 12599 if (this.hideTimeout) { 12600 clearTimeout(this.hideTimeout); 12601 this.hideTimeout = 0; 12602 } 12603 // hide with a delay to prevent triggering accidental unwanted click on some page element 12604 var self = this; 12605 this.hideTimeout = setTimeout(function() { self.menuHideAll($(e.target)); }, 350); 12606 } 12607 this.lastTouch = null; 12608 }, 12609 docTouchMove: function(e) { 12610 if (!this.lastTouch) { 12611 return; 12612 } 12613 var touchPoint = e.originalEvent.touches[0]; 12614 this.lastTouch.x2 = touchPoint.pageX; 12615 this.lastTouch.y2 = touchPoint.pageY; 12616 }, 12617 docTouchStart: function(e) { 12618 var touchPoint = e.originalEvent.touches[0]; 12619 this.lastTouch = { x1: touchPoint.pageX, y1: touchPoint.pageY, target: touchPoint.target }; 12620 }, 12621 enable: function() { 12622 if (this.disabled) { 12623 if (this.$disableOverlay) { 12624 this.$disableOverlay.remove(); 12625 this.$disableOverlay = null; 12626 } 12627 this.disabled = false; 12628 } 12629 }, 12630 getHeight: function($elm) { 12631 return this.getOffset($elm, true); 12632 }, 12633 // returns precise width/height float values in IE9+, FF4+, recent WebKit 12634 // http://vadikom.com/dailies/offsetwidth-offsetheight-useless-in-ie9-firefox4/ 12635 getOffset: function($elm, height) { 12636 var old, 12637 $win = $(window), 12638 winW = $win.width(); 12639 if ($elm.css('display') == 'none') { 12640 old = { position: $elm[0].style.position, visibility: $elm[0].style.visibility }; 12641 $elm.css({ position: 'absolute', visibility: 'hidden' }).show(); 12642 if ( 12643 ($('body').hasClass('menu-mobile-off-canvas') && winW < 960 && $elm.closest('.main-menu-container').length) 12644 || 12645 ($('body').hasClass('vmenu-offcanvas-overlay') && winW >= 960 && $elm.closest('.main-menu-container').length) 12646 ) { 12647 $elm.closest('li').addClass('smartmenu-open-item'); 12648 } 12649 } 12650 var defaultView = $elm[0].ownerDocument.defaultView, 12651 compStyle = defaultView && defaultView.getComputedStyle && defaultView.getComputedStyle($elm[0], null), 12652 val = compStyle && parseFloat(compStyle[height ? 'height' : 'width']); 12653 if (val) { 12654 val += parseFloat(compStyle[height ? 'paddingTop' : 'paddingLeft']) 12655 + parseFloat(compStyle[height ? 'paddingBottom' : 'paddingRight']) 12656 + parseInt(compStyle[height ? 'borderTopWidth' : 'borderLeftWidth']) 12657 + parseInt(compStyle[height ? 'borderBottomWidth' : 'borderRightWidth']); 12658 } else { 12659 val = height ? $elm[0].offsetHeight : $elm[0].offsetWidth; 12660 } 12661 if (old) { 12662 $elm.hide().css(old); 12663 } 12664 return val; 12665 }, 12666 getWidth: function($elm) { 12667 return this.getOffset($elm); 12668 }, 12669 getStartZIndex: function() { 12670 var zIndex = parseInt(this.$root.css('z-index')); 12671 return !isNaN(zIndex) ? zIndex : 1; 12672 }, 12673 handleEvents: function() { 12674 return !this.disabled && this.isCSSOn(); 12675 }, 12676 handleItemEvents: function($a) { 12677 return this.handleEvents() && !this.isLinkInMegaMenu($a); 12678 }, 12679 isCollapsible: function() { 12680 return this.$firstSub.css('position') == 'static'; 12681 }, 12682 isCSSOn: function() { 12683 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'; 12684 }, 12685 isFixed: function() { 12686 return this.$root.css('position') == 'fixed'; 12687 }, 12688 isLinkInMegaMenu: function($a) { 12689 return !$a.parent().parent().dataSM('level'); 12690 }, 12691 isTouchMode: function() { 12692 return !mouse || this.isCollapsible(); 12693 }, 12694 itemActivate: function($a) { 12695 var $li = $a.parent(), 12696 $ul = $li.parent(), 12697 level = $ul.dataSM('level'); 12698 // 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 12699 if (level > 1 && (!this.activatedItems[level - 2] || this.activatedItems[level - 2][0] != $ul.dataSM('parent-a')[0])) { 12700 var self = this; 12701 $($ul.parentsUntil('[data-smartmenus-id]', 'ul').get().reverse()).add($ul).each(function() { 12702 self.itemActivate($(this).dataSM('parent-a')); 12703 }); 12704 } 12705 // hide any visible deeper level sub menus 12706 if (this.visibleSubMenus.length > level) { 12707 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--) { 12708 //if ( !this.visibleSubMenus[i].closest('.menu-accordion').length ) { 12709 this.menuHide(this.visibleSubMenus[i]); 12710 //} 12711 } 12712 } 12713 // save new active item and sub menu for this level 12714 this.activatedItems[level - 1] = $a; 12715 this.visibleSubMenus[level - 1] = $ul; 12716 if (this.$root.triggerHandler('activate.smapi', $a[0]) === false) { 12717 return; 12718 } 12719 // show the sub menu if this item has one 12720 var $sub = $li.dataSM('sub'); 12721 if ($sub && (this.isTouchMode() || (!this.opts.showOnClick || this.clickActivated))) { 12722 this.menuShow($sub); 12723 } 12724 }, 12725 itemBlur: function(e) { 12726 var $a = $(e.currentTarget); 12727 if (!this.handleItemEvents($a)) { 12728 return; 12729 } 12730 this.$root.triggerHandler('blur.smapi', $a[0]); 12731 }, 12732 itemClick: function(e) { 12733 var $a = $(e.currentTarget); 12734 12735 if (!this.handleItemEvents($a)) { 12736 return; 12737 } 12738 $a.removeDataSM('mousedown'); 12739 if (this.$root.triggerHandler('click.smapi', $a[0]) === false) { 12740 return false;
12741 } 12742 var $sub = $a.parent().dataSM('sub'); 12743 if (this.isTouchMode()) { 12744 // undo fix: prevent the address bar on iPhone from sliding down when expanding a sub menu 12745 if ($a.dataSM('href')) { 12746 $a.attr('href', $a.dataSM('href')).removeDataSM('href'); 12747 } 12748 // if the sub is not visible 12749 if ($sub && (!$sub.dataSM('shown-before') || !$sub.is(':visible'))) { 12750 // try to activate the item and show the sub 12751 this.itemActivate($a); 12752 // if "itemActivate" showed the sub, prevent the click so that the link is not loaded 12753 // 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 12754 if ($sub.is(':visible')) { 12755 return false; 12756 } 12757 } 12758 } else if (this.opts.showOnClick && $a.parent().parent().dataSM('level') == 1 && $sub) { 12759 this.clickActivated = true; 12760 this.menuShow($sub); 12761 return false; 12762 } 12763 if ($a.hasClass('disabled')) { 12764 return false; 12765 } 12766 if (this.$root.triggerHandler('select.smapi', $a[0]) === false) { 12767 return false; 12768 } 12769 }, 12770 itemDown: function(e) { 12771 var $a = $(e.currentTarget); 12772 if (!this.handleItemEvents($a)) { 12773 return; 12774 } 12775 $a.dataSM('mousedown', true); 12776 }, 12777 itemEnter: function(e) { 12778 var $a = $(e.currentTarget); 12779 if (!this.handleItemEvents($a)) { 12780 return; 12781 } 12782 if (!this.isTouchMode()) { 12783 if (this.showTimeout) { 12784 clearTimeout(this.showTimeout); 12785 this.showTimeout = 0; 12786 } 12787 var self = this; 12788 this.showTimeout = setTimeout(function() { self.itemActivate($a); }, this.opts.showOnClick && $a.parent().parent().dataSM('level') == 1 ? 1 : this.opts.showTimeout); 12789 } 12790 this.$root.triggerHandler('mouseenter.smapi', $a[0]); 12791 }, 12792 itemFocus: function(e) { 12793 var $a = $(e.currentTarget); 12794 if (!this.handleItemEvents($a)) { 12795 return; 12796 } 12797 // 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 12798 if ((!this.isTouchMode() || !$a.dataSM('mousedown')) && (!this.activatedItems.length || this.activatedItems[this.activatedItems.length - 1][0] != $a[0])) { 12799 this.itemActivate($a); 12800 } 12801 this.$root.triggerHandler('focus.smapi', $a[0]); 12802 }, 12803 itemLeave: function(e) { 12804 var $a = $(e.currentTarget); 12805 if (!this.handleItemEvents($a)) { 12806 return; 12807 } 12808 if (!this.isTouchMode()) { 12809 if ($a[0].blur) { 12810 $a[0].blur(); 12811 } 12812 if (this.showTimeout) { 12813 clearTimeout(this.showTimeout); 12814 this.showTimeout = 0; 12815 } 12816 } 12817 $a.removeDataSM('mousedown'); 12818 this.$root.triggerHandler('mouseleave.smapi', $a[0]); 12819 }, 12820 itemTouchEnd: function(e) { 12821 var $a = $(e.currentTarget); 12822 if (!this.handleItemEvents($a)) { 12823 return; 12824 } 12825 // prevent the address bar on iPhone from sliding down when expanding a sub menu 12826 var $sub = $a.parent().dataSM('sub'); 12827 if ($a.attr('href').charAt(0) !== '#' && $sub && (!$sub.dataSM('shown-before') || !$sub.is(':visible'))) { 12828 $a.dataSM('href', $a.attr('href')); 12829 $a.attr('href', '#'); 12830 } 12831 }, 12832 menuFixLayout: function($ul) { 12833 // fixes a menu that is being shown for the first time 12834 if (!$ul.dataSM('shown-before')) { 12835 $ul.hide().dataSM('shown-before', true); 12836 // fix the layout of the items in IE<8 12837 if (IElt8) { 12838 $ul.children().css({ styleFloat: 'left', width: '100%' }); 12839 } 12840 } 12841 }, 12842 menuHide: function($sub) { 12843 if (this.$root.triggerHandler('beforehide.smapi', $sub[0]) === false) { 12844 return; 12845 } 12846 $sub.stop(true, true); 12847 if ($sub.is(':visible')) { 12848 var complete = function() { 12849 // unset z-index 12850 if (IElt9) { 12851 $sub.parent().css('z-index', ''); 12852 } else { 12853 $sub.css('z-index', ''); 12854 } 12855 }; 12856 // if sub is collapsible (mobile view) 12857 if (this.isCollapsible()) { 12858 if (this.opts.collapsibleHideFunction) { 12859 this.opts.collapsibleHideFunction.call(this, $sub, complete); 12860 } else { 12861 $sub.hide(this.opts.collapsibleHideDuration, complete); 12862 } 12863 } else { 12864 if (this.opts.hideFunction) { 12865 this.opts.hideFunction.call(this, $sub, complete); 12866 } else { 12867 $sub.hide(this.opts.hideDuration, complete); 12868 } 12869 } 12870 // remove IE iframe shim 12871 if ($sub.dataSM('ie-shim')) { 12872 $sub.dataSM('ie-shim').remove(); 12873 } 12874 // deactivate scrolling if it is activated for this sub 12875 if ($sub.dataSM('scroll')) { 12876 $sub.unbind('.smartmenus_scroll').removeDataSM('scroll').dataSM('scroll-arrows').hide(); 12877 } 12878 // unhighlight parent item 12879 $sub.dataSM('parent-a').removeClass('highlighted'); 12880 var level = $sub.dataSM('level'); 12881 this.activatedItems.splice(level - 1, 1); 12882 this.visibleSubMenus.splice(level - 1, 1); 12883 this.$root.triggerHandler('hide.smapi', $sub[0]); 12884 } 12885 }, 12886 menuHideAll: function($item) { 12887 if ($item != undefined && $item.parent().hasClass('menu-item') && !$item.parent().hasClass('menu-item-has-children')) return; 12888 var $win = $(window), 12889 winW = $win.width(); 12890 if (this.showTimeout) { 12891 clearTimeout(this.showTimeout); 12892 this.showTimeout = 0; 12893 } 12894 // hide all subs 12895 for (var i = this.visibleSubMenus.length - 1; i > 0; i--) { 12896 if ( this.visibleSubMenus[i].closest('.smartmenu-open-item').length ) { 12897 if ( $item != undefined && $item.closest('.smartmenu-open-item').length ) { 12898 this.menuHide(this.visibleSubMenus[i]); 12899 $(this.visibleSubMenus[i]).closest('.smartmenu-open-item').removeClass('smartmenu-open-item'); 12900 } else { 12901 return; 12902 } 12903 } else { 12904 this.menuHide(this.visibleSubMenus[i]); 12905 } 12906 } 12907 // hide root if it's popup 12908 if (this.opts.isPopup) { 12909 this.$root.stop(true, true); 12910 if (this.$root.is(':visible')) { 12911 if (this.opts.hideFunction) { 12912 this.opts.hideFunction.call(this, this.$root); 12913 } else { 12914 this.$root.hide(this.opts.hideDuration); 12915 } 12916 // remove IE iframe shim 12917 if (this.$root.dataSM('ie-shim')) { 12918 this.$root.dataSM('ie-shim').remove(); 12919 } 12920 } 12921 } 12922 this.activatedItems = []; 12923 this.visibleSubMenus = []; 12924 this.clickActivated = false;
12925 // reset z-index increment 12926 this.zIndexInc = 0; 12927 }, 12928 menuIframeShim: function($ul) { 12929 // create iframe shim for the menu 12930 if (IE && this.opts.overlapControlsInIE && !$ul.dataSM('ie-shim')) { 12931 $ul.dataSM('ie-shim', $('<iframe/>').attr({ src: 'javascript:0', tabindex: -9 }) 12932 .css({ position: 'absolute', top: 'auto', left: '0', opacity: 0, border: '0' }) 12933 ); 12934 } 12935 }, 12936 menuInit: function($ul) { 12937 if (!$ul.dataSM('in-mega')) { 12938 this.subMenus.push($ul); 12939 // mark UL's in mega drop downs (if any) so we can neglect them 12940 if ($ul.hasClass('mega-menu')) { 12941 $ul.find('ul').dataSM('in-mega', true); 12942 } 12943 // get level (much faster than, for example, using parentsUntil) 12944 var level = 2, 12945 par = $ul[0]; 12946 while (par != null && par.parentNode != null && ( par = par.parentNode.parentNode) != this.$root[0]) { 12947 level++; 12948 } 12949 // cache stuff 12950 $ul.dataSM('parent-a', $ul.prevAll('a').eq(-1)) 12951 .dataSM('level', level) 12952 .parent().dataSM('sub', $ul); 12953 // add sub indicator to parent item 12954 if (this.opts.subIndicators) { 12955 $ul.dataSM('parent-a').addClass('has-submenu')[this.opts.subIndicatorsPos](this.$subArrow.clone()); 12956 } 12957 } 12958 }, 12959 menuPosition: function($sub) { 12960 var fixIE = $('html.ie').length; 12961 // if (fixIE) { 12962 // var $rowParent = $($sub).closest('.main-menu-container'); 12963 // $rowParent.height($rowParent.height()); 12964 // } 12965 var $a = $sub.dataSM('parent-a'), 12966 $li = $sub.parent(), 12967 $ul = $sub.parent().parent(), 12968 // $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'), 12969 $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'), 12970 level = $sub.dataSM('level'), 12971 subW = this.getWidth($sub), 12972 subH = this.getHeight($sub), 12973 itemOffset = $a.offset(), 12974 itemX = itemOffset.left, 12975 itemY = itemOffset.top, 12976 itemW = this.getWidth($a), 12977 itemH = this.getHeight($a), 12978 $win = $(window), 12979 winX = $win.scrollLeft(), 12980 winY = $win.scrollTop(), 12981 winW = $win.width(), 12982 winH = $win.height(), 12983 containerW = $container.width(), 12984 containerOffsetX = containerW + ((winW - containerW) / 2), 12985 horizontalParent = $ul.hasClass('sm') && !$ul.hasClass('sm-vertical'), 12986 subOffsetX = level == 2 ? this.opts.mainMenuSubOffsetX : this.opts.subMenusSubOffsetX, 12987 subOffsetY = level == 2 ? this.opts.mainMenuSubOffsetY : this.opts.subMenusSubOffsetY, 12988 x, y, leftPos; 12989 12990 if (horizontalParent) { 12991 x = this.opts.rightToLeftSubMenus ? itemW - subW - subOffsetX : subOffsetX; 12992 y = this.opts.bottomToTopSubMenus ? -subH - subOffsetY : itemH + subOffsetY; 12993 } else { 12994 x = this.opts.rightToLeftSubMenus ? subOffsetX - subW : subW - subOffsetX; 12995 y = this.opts.bottomToTopSubMenus ? itemH - subOffsetY - subH : subOffsetY; 12996 } 12997 if (this.opts.keepInViewport && !this.isCollapsible()) { 12998 if (this.isFixed()) { 12999 itemX -= winX; 13000 itemY -= winY; 13001 winX = winY = 0; 13002 } 13003 var absX = itemX + x, 13004 absY = itemY + y; 13005 if (this.opts.rightToLeftSubMenus && absX < winX) { 13006 x = horizontalParent ? winX - absX + x : itemW - subOffsetX; 13007 } else if (!this.opts.rightToLeftSubMenus && absX + subW > winX + containerOffsetX ) { 13008 x = horizontalParent ? winX + containerOffsetX - subW - absX + x : subOffsetX - subW; 13009 } 13010 if (!horizontalParent) { 13011 if (subH < winH && absY + subH > winY + winH) { 13012 y += winY + winH - subH - absY; 13013 } else if (subH >= winH || absY < winY) { 13014 y += winY - absY; 13015 } 13016 } 13017 // do we need scrolling? 13018 // 0.49 added for the sake of IE9/FF4+ where we might be dealing with float numbers for "subH" 13019 if (mouse && (horizontalParent && (absY + subH > winY + winH + 0.49 || absY < winY) || !horizontalParent && subH > winH + 0.49)) { 13020 var self = this; 13021 if (!$sub.dataSM('scroll-arrows')) { 13022 $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]]) 13023 .bind({ 13024 mouseenter: function() { self.menuScroll($sub, $(this).hasClass('scroll-up')); }, 13025 mouseleave: function(e) { 13026 self.menuScrollStop($sub); 13027 self.menuScrollOut($sub, e); 13028 }, 13029 'mousewheel DOMMouseScroll': function(e) { e.preventDefault(); } 13030 }) 13031 .insertAfter($sub) 13032 ); 13033 } 13034 // bind events to show/hide arrows on hover and save scrolling data for this sub 13035 var vportY = winY - (itemY + itemH); 13036 $sub.dataSM('scroll', { 13037 vportY: vportY, 13038 subH: subH, 13039 winH: winH, 13040 step: 1 13041 }) 13042 .bind({ 13043 'mouseover.smartmenus_scroll': function(e) { self.menuScrollOver($sub, e); }, 13044 'mouseout.smartmenus_scroll': function(e) { self.menuScrollOut($sub, e); }, 13045 'mousewheel.smartmenus_scroll DOMMouseScroll.smartmenus_scroll': function(e) { self.menuScrollMousewheel($sub, e); } 13046 }) 13047 .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
13047StartZIndex() + this.zIndexInc }) 13048 .eq(0).css('margin-top', vportY).end() 13049 .eq(1).css('margin-top', vportY + winH - this.getHeight($sub.dataSM('scroll-arrows').eq(1))).end() 13050 .eq(horizontalParent && this.opts.bottomToTopSubMenus ? 0 : 1).show(); 13051 } 13052 } 13053 if ( !$sub.closest('.menu-accordion').length ) { 13054 var rightPos = 'auto'; 13055 if ( $sub.closest('.grid-filters').length ) { 13056 if ( $sub.closest('.text-right').length ) { 13057 leftPos = '0px'; 13058 rightPos = 'auto'; 13059 } else { 13060 leftPos = 'auto'; 13061 rightPos = '0px'; 13062 } 13063 x = 0; 13064 } else { 13065 if ( $sub.hasClass('mega-menu-inner') ) { 13066 $sub.css({ width: containerW}); 13067 leftPos = -1 * (parseFloat($sub.closest('ul.menu-smart').offset().left) - parseFloat($sub.closest('.row-menu').offset().left)); 13068 if ( ! $('body').hasClass('megamenu-side-to-side') ) { 13069 leftPos += parseFloat($sub.closest('.row-menu-inner').css('paddingLeft')); 13070 } 13071 x = 0; 13072 } else { 13073 leftPos = (level > 2 ? $li.position().left - parseFloat($li.closest('ul').css('paddingLeft')) : $li.position().left ) + 'px'; 13074 x = (level > 2 && x >= 0) ? x + 1 : x - 1; 13075 } 13076 } 13077 } 13078 13079 // $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) }); 13080 $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) }); 13081 // IE iframe shim 13082 this.menuIframeShim($sub); 13083 if ($sub.dataSM('ie-shim')) { 13084 $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) }); 13085 } 13086 }, 13087 menuScroll: function($sub, up, wheel) { 13088 var y = parseFloat($sub.css('margin-top')), 13089 scroll = $sub.dataSM('scroll'), 13090 end = scroll.vportY + (up ? 0 : scroll.winH - scroll.subH), 13091 step = wheel || !this.opts.scrollAccelerate ? this.opts.scrollStep : Math.floor($sub.dataSM('scroll').step); 13092 $sub.add($sub.dataSM('ie-shim')).css('margin-top', Math.abs(end - y) > step ? y + (up ? step : -step) : end); 13093 y = parseFloat($sub.css('margin-top')); 13094 // show opposite arrow if appropriate 13095 if (up && y + scroll.subH > scroll.vportY + scroll.winH || !up && y < scroll.vportY) { 13096 $sub.dataSM('scroll-arrows').eq(up ? 1 : 0).show(); 13097 } 13098 // accelerate when not using mousewheel to scroll 13099 if (!wheel && this.opts.scrollAccelerate && $sub.dataSM('scroll').step < this.opts.scrollStep) { 13100 $sub.dataSM('scroll').step += 0.5; 13101 } 13102 // "y" and "end" might be float numbers in IE9/FF4+ so this weird way to check is used 13103 if (Math.abs(y - end) < 1) { 13104 $sub.dataSM('scroll-arrows').eq(up ? 0 : 1).hide(); 13105 $sub.dataSM('scroll').step = 1; 13106 } else if (!wheel) { 13107 var self = this; 13108 this.scrollTimeout = setTimeout(function() { self.menuScroll($sub, up); }, this.opts.scrollInterval); 13109 } 13110 }, 13111 menuScrollMousewheel: function($sub, e) { 13112 var $closestSub = $(e.target).closest('ul'); 13113 while ($closestSub.dataSM('in-mega')) { 13114 $closestSub = $closestSub.parent().closest('ul'); 13115 } 13116 if ($closestSub[0] == $sub[0]) { 13117 var up = (e.originalEvent.wheelDelta || -e.originalEvent.detail) > 0; 13118 if ($sub.dataSM('scroll-arrows').eq(up ? 0 : 1).is(':visible')) { 13119 this.menuScroll($sub, up, true); 13120 } 13121 } 13122 e.preventDefault(); 13123 }, 13124 menuScrollOut: function($sub, e) { 13125 var reClass = /^scroll-(up|down)/, 13126 $closestSub = $(e.relatedTarget).closest('ul'); 13127 while ($closestSub.dataSM('in-mega')) { 13128 $closestSub = $closestSub.parent().closest('ul'); 13129 } 13130 if (!reClass.test((e.relatedTarget || '').className) && ($sub[0] != e.relatedTarget && !$.contains($sub[0], e.relatedTarget) || $closestSub[0] != $sub[0])) { 13131 $sub.dataSM('scroll-arrows').css('visibility', 'hidden'); 13132 } 13133 }, 13134 menuScrollOver: function($sub, e) { 13135 var reClass = /^scroll-(up|down)/, 13136 $closestSub = $(e.target).closest('ul'); 13137 while ($closestSub.dataSM('in-mega')) { 13138 $closestSub = $closestSub.parent().closest('ul'); 13139 } 13140 if (!reClass.test(e.target.className) && $closestSub[0] == $sub[0]) { 13141 $sub.dataSM('scroll-arrows').css('visibility', 'visible'); 13142 } 13143 }, 13144 menuScrollStop: function($sub) { 13145 if (this.scrollTimeout) { 13146 clearTimeout(this.scrollTimeout); 13147 this.scrollTimeout = 0; 13148 $sub.dataSM('scroll').step = 1; 13149 } 13150 }, 13151 menuShow: function($sub) { 13152 if (!$sub.dataSM('beforefirstshowfired')) { 13153 $sub.dataSM('beforefirstshowfired', true); 13154 if (this.$root.triggerHandler('beforefirstshow.smapi', $sub[0]) === false) { 13155 return; 13156 } 13157 } 13158 if (this.$root.triggerHandler('beforeshow.smapi', $sub[0]) === false) { 13159 return; 13160 } 13161 this.menuFixLayout($sub); 13162 $sub.stop(true, true); 13163 if (!$sub.is(':visible')) { 13164 $sub.css({ 13165 'visibility': 'visible', 13166 'pointer-events': 'auto', 13167 }); 13168 // set z-index - for IE < 9 set it to the parent LI
13169 var zIndex = this.getStartZIndex() + (++this.zIndexInc); 13170 if (IElt9) { 13171 $sub.parent().css('z-index', zIndex); 13172 } else { 13173 $sub.css('z-index', zIndex); 13174 } 13175 // highlight parent item 13176 if (this.opts.keepHighlighted || this.isCollapsible()) { 13177 if ($sub.dataSM('parent-a').attr('data-type') != 'title') 13178 $sub.dataSM('parent-a').addClass('highlighted'); 13179 } 13180 // min/max-width fix - no way to rely purely on CSS as all UL's are nested 13181 if (this.opts.subMenusMinWidth || this.opts.subMenusMaxWidth) { 13182 if (!IElt8) { 13183 $sub.css({ width: ($sub.hasClass('mega-menu-inner')) ? $('.box-container').outerWidth() + 'px' : 'auto', minWidth: '', maxWidth: '' }).addClass('sm-nowrap'); 13184 if (this.opts.subMenusMinWidth) { 13185 $sub.css('min-width', this.opts.subMenusMinWidth); 13186 } 13187 if (this.opts.subMenusMaxWidth) { 13188 var noMaxWidth = this.getWidth($sub); 13189 if ( ! $sub.hasClass('mega-menu-inner') ) { 13190 $sub.css('max-width', this.opts.subMenusMaxWidth); 13191 } 13192 if (noMaxWidth > this.getWidth($sub)) { 13193 $sub.removeClass('sm-nowrap').css('width', this.opts.subMenusMaxWidth); 13194 } 13195 } 13196 // IE6,7 13197 } else { 13198 $sub.children().css('styleFloat', 'none'); 13199 if (IE6) { 13200 $sub.width(this.opts.subMenusMinWidth ? this.opts.subMenusMinWidth : 1) 13201 .children().children('a').css('white-space', 'nowrap'); 13202 } else { // IE7 13203 $sub.css({ width: ($sub.hasClass('mega-menu-inner')) ? $('.box-container').outerWidth() + 'px' : 'auto', minWidth: '', maxWidth: '' }).addClass('sm-nowrap'); 13204 if (this.opts.subMenusMinWidth) { 13205 $sub.css('min-width', this.opts.subMenusMinWidth); 13206 } 13207 } 13208 if (this.opts.subMenusMaxWidth) { 13209 var noMaxWidth = $sub.width(); 13210 if (IE6) { 13211 var maxWidth = $sub.css({ width: this.opts.subMenusMaxWidth, overflowX: 'hidden', overflowY: 'hidden' }).width(); 13212 if (noMaxWidth > maxWidth) { 13213 $sub.css({ width: maxWidth, overflowX: 'visible', overflowY: 'visible' }).children().children('a').css('white-space', ''); 13214 } else { 13215 $sub.css({ width: noMaxWidth, overflowX: 'visible', overflowY: 'visible' }); 13216 } 13217 } else { // IE7 13218 if ( ! $sub.hasClass('mega-menu-inner') ) { 13219 $sub.css('max-width', this.opts.subMenusMaxWidth); 13220 } 13221 if (noMaxWidth > $sub.width()) { 13222 $sub.removeClass('sm-nowrap').css('width', this.opts.subMenusMaxWidth); 13223 } else { 13224 $sub.width(noMaxWidth); 13225 } 13226 } 13227 } else { 13228 $sub.width($sub.width()); 13229 } 13230 $sub.children().css('styleFloat', 'left'); 13231 } 13232 } 13233 this.menuPosition($sub); 13234 // insert IE iframe shim 13235 if ($sub.dataSM('ie-shim')) { 13236 $sub.dataSM('ie-shim').insertBefore($sub); 13237 } 13238 var complete = function() { 13239 // fix: "overflow: hidden;" is not reset on animation complete in jQuery < 1.9.0 in Chrome when global "box-sizing: border-box;" is used 13240 $sub.css('overflow', ''); 13241 }; 13242 // if sub is collapsible (mobile view) 13243 if (this.isCollapsible()) { 13244 if (this.opts.collapsibleShowFunction) { 13245 this.opts.collapsibleShowFunction.call(this, $sub, complete); 13246 } else { 13247 $sub.show(this.opts.collapsibleShowDuration, complete); 13248 } 13249 } else { 13250 if (this.opts.showFunction) { 13251 this.opts.showFunction.call(this, $sub, complete); 13252 } else { 13253 $sub.show(this.opts.showDuration, complete); 13254 } 13255 } 13256 // save new sub menu for this level 13257 this.visibleSubMenus[$sub.dataSM('level') - 1] = $sub; 13258 this.$root.triggerHandler('show.smapi', $sub[0]); 13259 } 13260 }, 13261 popupHide: function(noHideTimeout) { 13262 if (this.hideTimeout) { 13263 clearTimeout(this.hideTimeout); 13264 this.hideTimeout = 0; 13265 } 13266 var self = this; 13267 this.hideTimeout = setTimeout(function() { 13268 self.menuHideAll(); 13269 }, noHideTimeout ? 1 : this.opts.hideTimeout); 13270 }, 13271 popupShow: function(left, top) { 13272 if (!this.opts.isPopup) { 13273 alert('SmartMenus jQuery Error:\n\nIf you want to show this menu via the "popupShow" method, set the isPopup:true option.'); 13274 return; 13275 } 13276 if (this.hideTimeout) { 13277 clearTimeout(this.hideTimeout); 13278 this.hideTimeout = 0; 13279 } 13280 this.menuFixLayout(this.$root); 13281 this.$root.stop(true, true); 13282 if (!this.$root.is(':visible')) { 13283 this.$root.css({ left: left, top: top }); 13284 // IE iframe shim 13285 this.menuIframeShim(this.$root); 13286 if (this.$root.dataSM('ie-shim')) { 13287 this.$root.dataSM('ie-shim').css({ zIndex: this.$root.css('z-index'), width: this.getWidth(this.$root), height: this.getHeight(this.$root), left
13287: left, top: top }).insertBefore(this.$root); 13288 } 13289 // show menu 13290 if (this.opts.showFunction) { 13291 this.opts.showFunction.call(this, this.$root); 13292 } else { 13293 this.$root.show(this.opts.showDuration); 13294 } 13295 this.visibleSubMenus[0] = this.$root; 13296 } 13297 }, 13298 refresh: function() { 13299 this.menuHideAll(); 13300 this.$root.find('ul').each(function() { 13301 var $this = $(this); 13302 if ($this.dataSM('scroll-arrows')) { 13303 $this.dataSM('scroll-arrows').remove(); 13304 } 13305 }) 13306 .removeDataSM('in-mega') 13307 .removeDataSM('shown-before') 13308 .removeDataSM('ie-shim') 13309 .removeDataSM('scroll-arrows') 13310 .removeDataSM('parent-a') 13311 .removeDataSM('level') 13312 .removeDataSM('beforefirstshowfired'); 13313 this.$root.find('a.has-submenu').removeClass('has-submenu') 13314 .parent().removeDataSM('sub'); 13315 if (this.opts.subIndicators) { 13316 this.$root.find('span.sub-arrow').remove(); 13317 } 13318 if (this.opts.markCurrentItem) { 13319 this.$root.find('a.current').removeClass('current'); 13320 } 13321 this.subMenus = []; 13322 this.init(true); 13323 }, 13324 rootOut: function(e) { 13325 if (!this.handleEvents() || this.isTouchMode() || e.target == this.$root[0]) { 13326 return; 13327 } 13328 if (this.hideTimeout) { 13329 clearTimeout(this.hideTimeout); 13330 this.hideTimeout = 0; 13331 } 13332 if (!this.opts.showOnClick || !this.opts.hideOnClick) { 13333 var self = this; 13334 this.hideTimeout = setTimeout(function() { self.menuHideAll(); }, this.opts.hideTimeout); 13335 } 13336 }, 13337 rootOver: function(e) { 13338 if (!this.handleEvents() || this.isTouchMode() || e.target == this.$root[0]) { 13339 return; 13340 } 13341 if (this.hideTimeout) { 13342 clearTimeout(this.hideTimeout); 13343 this.hideTimeout = 0; 13344 } 13345 }, 13346 winResize: function(e) { 13347 if (!this.handleEvents()) { 13348 // we still need to resize the disable overlay if it's visible 13349 if (this.$disableOverlay) { 13350 var pos = this.$root.offset(); 13351 this.$disableOverlay.css({ 13352 top: pos.top, 13353 left: pos.left, 13354 width: this.$root.outerWidth(), 13355 height: this.$root.outerHeight() 13356 }); 13357 } 13358 return; 13359 } 13360 // hide sub menus on resize - on mobile do it only on orientation change 13361 if (!this.isCollapsible() && (!('onorientationchange' in window) || e.type == 'orientationchange')) { 13362 if (this.activatedItems.length) { 13363 this.activatedItems[this.activatedItems.length - 1][0].blur(); 13364 } 13365 this.menuHideAll(); 13366 } 13367 } 13368 } 13369 }); 13370 13371 $.fn.dataSM = function(key, val) { 13372 if (val) { 13373 return this.data(key + '_smartmenus', val); 13374 } 13375 return this.data(key + '_smartmenus'); 13376 } 13377 13378 $.fn.removeDataSM = function(key) { 13379 return this.removeData(key + '_smartmenus'); 13380 } 13381 13382 $.fn.smartmenus = function(options) { 13383 if (typeof options == 'string') { 13384 var args = arguments, 13385 method = options; 13386 Array.prototype.shift.call(args); 13387 return this.each(function() { 13388 var smartmenus = $(this).data('smartmenus'); 13389 if (smartmenus && smartmenus[method]) { 13390 smartmenus[method].apply(smartmenus, args); 13391 } 13392 }); 13393 } 13394 var opts = $.extend({}, $.fn.smartmenus.defaults, options); 13395 return this.each(function() { 13396 new $.SmartMenus(this, opts); 13397 }); 13398 } 13399 13400 // default settings 13401 $.fn.smartmenus.defaults = { 13402 isPopup: false, // is this a popup menu (can be shown via the popupShow/popupHide methods) or a permanent menu bar 13403 mainMenuSubOffsetX: 0, // pixels offset from default position
13404 mainMenuSubOffsetY: 0, // pixels offset from default position 13405 subMenusSubOffsetX: 0, // pixels offset from default position 13406 subMenusSubOffsetY: 0, // pixels offset from default position 13407 subMenusMinWidth: false, //'10em', // min-width for the sub menus (any CSS unit) - if set, the fixed width set in CSS will be ignored 13408 subMenusMaxWidth: false, //'20em', // max-width for the sub menus (any CSS unit) - if set, the fixed width set in CSS will be ignored 13409 subIndicators: true, // create sub menu indicators - creates a SPAN and inserts it in the A 13410 subIndicatorsPos: 'prepend', // position of the SPAN relative to the menu item content ('prepend', 'append') 13411 subIndicatorsText: '+', // [optionally] add text in the SPAN (e.g. '+') (you may want to check the CSS for the sub indicators too) 13412 scrollStep: 30, // pixels step when scrolling long sub menus that do not fit in the viewport height 13413 scrollInterval: 30, // interval between each scrolling step 13414 scrollAccelerate: true, // accelerate scrolling or use a fixed step 13415 showTimeout: 250, // timeout before showing the sub menus 13416 hideTimeout: 500, // timeout before hiding the sub menus 13417 showDuration: 0, // duration for show animation - set to 0 for no animation - matters only if showFunction:null 13418 showFunction: null, // custom function to use when showing a sub menu (the default is the jQuery 'show') 13419 // don't forget to call complete() at the end of whatever you do 13420 // e.g.: function($ul, complete) { $ul.fadeIn(250, complete); } 13421 hideDuration: 0, // duration for hide animation - set to 0 for no animation - matters only if hideFunction:null 13422 hideFunction: function($ul, complete) { $ul.fadeOut(200, complete); }, // custom function to use when hiding a sub menu (the default is the jQuery 'hide') 13423 // don't forget to call complete() at the end of whatever you do 13424 // e.g.: function($ul, complete) { $ul.fadeOut(250, complete); } 13425 collapsibleShowDuration:0, // duration for show animation for collapsible sub menus - matters only if collapsibleShowFunction:null 13426 collapsibleShowFunction:function($ul, complete) { $ul.slideDown(200, complete); }, // custom function to use when showing a collapsible sub menu 13427 // (i.e. when mobile styles are used to make the sub menus collapsible) 13428 collapsibleHideDuration:0, // duration for hide animation for collapsible sub menus - matters only if collapsibleHideFunction:null 13429 collapsibleHideFunction:function($ul, complete) { $ul.slideUp(200, complete); }, // custom function to use when hiding a collapsible sub menu 13430 // (i.e. when mobile styles are used to make the sub menus collapsible) 13431 showOnClick: false, // show the first-level sub menus onclick instead of onmouseover (matters only for mouse input) 13432 hideOnClick: true, // hide the sub menus on click/tap anywhere on the page 13433 keepInViewport: true, // reposition the sub menus if needed to make sure they always appear inside the viewport 13434 keepHighlighted: true, // keep all ancestor items of the current sub menu highlighted (adds the 'highlighted' class to the A's) 13435 markCurrentItem: false, // automatically add the 'current' class to the A element of the item linking to the current URL 13436 markCurrentTree: true, // add the 'current' class also to the A elements of all ancestor items of the current item 13437 rightToLeftSubMenus: false, // right to left display of the sub menus (check the CSS for the sub indicators' position) 13438 bottomToTopSubMenus: false, // bottom to top display of the sub menus 13439 overlapControlsInIE: true // make sure sub menus appear on top of special OS controls in IE (i.e. SELECT, OBJECT, EMBED, etc.) 13440 }; 13441 13442})(jQuery); 13443/* 13444 * jQuery Easing v1.4.1 - http://gsgd.co.uk/sandbox/jquery/easing/ 13445 * Open source under the BSD License. 13446 * Copyright © 2008 George McGinley Smith 13447 * All rights reserved. 13448 * https://raw.github.com/gdsmith/jquery.easing/master/LICENSE 13449*/ 13450 13451/* globals jQuery, define, module, require */ 13452(function (factory) { 13453 if (typeof define === "function" && define.amd) { 13454 define(['jquery'], function ($) { 13455 return factory($); 13456 }); 13457 } else if (typeof module === "object" && typeof module.exports === "object") { 13458 module.exports = factory(require('jquery')); 13459 } else { 13460 factory(jQuery); 13461 } 13462})(function($){ 13463 13464 // Preserve the original jQuery "swing" easing as "jswing" 13465 if (typeof $.easing !== 'undefined') { 13466 $.easing['jswing'] = $.easing['swing']; 13467 } 13468 13469 var pow = Math.pow, 13470 sqrt = Math.sqrt, 13471 sin = Math.sin, 13472 cos = Math.cos, 13473 PI = Math.PI,
13474 c1 = 1.70158, 13475 c2 = c1 * 1.525, 13476 c3 = c1 + 1, 13477 c4 = ( 2 * PI ) / 3, 13478 c5 = ( 2 * PI ) / 4.5; 13479 13480 // x is the fraction of animation progress, in the range 0..1 13481 function bounceOut(x) { 13482 var n1 = 7.5625, 13483 d1 = 2.75; 13484 if ( x < 1/d1 ) { 13485 return n1*x*x; 13486 } else if ( x < 2/d1 ) { 13487 return n1*(x-=(1.5/d1))*x + .75; 13488 } else if ( x < 2.5/d1 ) { 13489 return n1*(x-=(2.25/d1))*x + .9375; 13490 } else { 13491 return n1*(x-=(2.625/d1))*x + .984375; 13492 } 13493 } 13494 13495 $.extend( $.easing, { 13496 def: 'easeOutQuad', 13497 swing: function (x) { 13498 return $.easing[$.easing.def](x); 13499 }, 13500 easeInQuad: function (x) { 13501 return x * x; 13502 }, 13503 easeOutQuad: function (x) { 13504 return 1 - ( 1 - x ) * ( 1 - x ); 13505 }, 13506 easeInOutQuad: function (x) { 13507 return x < 0.5 ? 13508 2 * x * x : 13509 1 - pow( -2 * x + 2, 2 ) / 2; 13510 }, 13511 easeInCubic: function (x) { 13512 return x * x * x; 13513 }, 13514 easeOutCubic: function (x) { 13515 return 1 - pow( 1 - x, 3 ); 13516 }, 13517 easeInOutCubic: function (x) { 13518 return x < 0.5 ? 13519 4 * x * x * x : 13520 1 - pow( -2 * x + 2, 3 ) / 2; 13521 }, 13522 easeInQuart: function (x) { 13523 return x * x * x * x; 13524 }, 13525 easeOutQuart: function (x) { 13526 return 1 - pow( 1 - x, 4 ); 13527 }, 13528 easeInOutQuart: function (x) { 13529 return x < 0.5 ? 13530 8 * x * x * x * x : 13531 1 - pow( -2 * x + 2, 4 ) / 2; 13532 }, 13533 easeInQuint: function (x) { 13534 return x * x * x * x * x; 13535 }, 13536 easeOutQuint: function (x) { 13537 return 1 - pow( 1 - x, 5 ); 13538 }, 13539 easeInOutQuint: function (x) { 13540 return x < 0.5 ? 13541 16 * x * x * x * x * x : 13542 1 - pow( -2 * x + 2, 5 ) / 2; 13543 }, 13544 easeInSine: function (x) { 13545 return 1 - cos( x * PI/2 ); 13546 }, 13547 easeOutSine: function (x) { 13548 return sin( x * PI/2 ); 13549 }, 13550 easeInOutSine: function (x) { 13551 return -( cos( PI * x ) - 1 ) / 2; 13552 }, 13553 easeInExpo: function (x) { 13554 return x === 0 ? 0 : pow( 2, 10 * x - 10 ); 13555 }, 13556 easeOutExpo: function (x) { 13557 return x === 1 ? 1 : 1 - pow( 2, -10 * x ); 13558 }, 13559 easeInOutExpo: function (x) { 13560 return x === 0 ? 0 : x === 1 ? 1 : x < 0.5 ? 13561 pow( 2, 20 * x - 10 ) / 2 : 13562 ( 2 - pow( 2, -20 * x + 10 ) ) / 2; 13563 }, 13564 easeInCirc: function (x) { 13565 return 1 - sqrt( 1 - pow( x, 2 ) ); 13566 }, 13567 easeOutCirc: function (x) { 13568 return sqrt( 1 - pow( x - 1, 2 ) ); 13569 }, 13570 easeInOutCirc: function (x) { 13571 return x < 0.5 ? 13572 ( 1 - sqrt( 1 - pow( 2 * x, 2 ) ) ) / 2 : 13573 ( sqrt( 1 - pow( -2 * x + 2, 2 ) ) + 1 ) / 2; 13574 }, 13575 easeInElastic: function (x) { 13576 return x === 0 ? 0 : x === 1 ? 1 : 13577 -pow( 2, 10 * x - 10 ) * sin( ( x * 10 - 10.75 ) * c4 ); 13578 }, 13579 easeOutElastic: function (x) { 13580 return x === 0 ? 0 : x === 1 ? 1 : 13581 pow( 2, -10 * x ) * sin( ( x * 10 - 0.75 ) * c4 ) + 1; 13582 }, 13583 easeInOutElastic: function (x) { 13584 return x === 0 ? 0 : x === 1 ? 1 : x < 0.5 ? 13585 -( pow( 2, 20 * x - 10 ) * sin( ( 20 * x - 11.125 ) * c5 )) / 2 : 13586 pow( 2, -20 * x + 10 ) * sin( ( 20 * x - 11.125 ) * c5 ) / 2 + 1; 13587 }, 13588 easeInBack: function (x) { 13589 return c3 * x * x * x - c1 * x * x; 13590 }, 13591 easeOutBack: function (x) { 13592 return 1 + c3 * pow( x - 1, 3 ) + c1 * pow( x - 1, 2 ); 13593 }, 13594 easeInOutBack: function (x) { 13595 return x < 0.5 ? 13596 ( pow( 2 * x, 2 ) * ( ( c2 + 1 ) * 2 * x - c2 ) ) / 2 : 13597 ( pow( 2 * x - 2, 2 ) *( ( c2 + 1 ) * ( x * 2 - 2 ) + c2 ) + 2 ) / 2; 13598 }, 13599 easeInBounce: function (x) { 13600 return 1 - bounceOut( 1 - x ); 13601 }, 13602 easeOutBounce: bounceOut, 13603 easeInOutBounce: function (x) { 13604 return x < 0.5 ? 13605 ( 1 - bounceOut( 1 - 2 * x ) ) / 2 : 13606 ( 1 + bounceOut( 2 * x - 1 ) ) / 2; 13607 } 13608 }); 13609 return $; 13610}); 13611 13612/*! Copyright (c) 2011 Brandon Aaron (http://brandonaaron.net) 13613 * Licensed under the MIT License (LICENSE.txt). 13614 * 13615 * Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers. 13616 * Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix. 13617 * Thanks to: Seamus Leahy for adding deltaX and deltaY 13618 * 13619 * Version: 3.0.6 13620 * 13621 * Requires: 1.2.2+ 13622 */ 13623(function($) { 13624 var types = ['DOMMouseScroll', 'mousewheel']; 13625 if ($.event.fixHooks) { 13626 for (var i = types.length; i;) { 13627 $.event.fixHooks[types[--i]] = $.event.mouseHooks; 13628 } 13629 } 13630 $.event.special.mousewheel = { 13631 setup: function() { 13632 if (this.addEventListener) { 13633 for (var i = types.length; i;) { 13634 this.addEventListener(types[--i], handler, false); 13635 } 13636 } else { 13637 this.onmousewheel = handler; 13638 } 13639 }, 13640 teardown: function() { 13641 if (this.removeEventListener) { 13642 for (var i = types.length; i;) { 13643 this.removeEventListener(types[--i], handler, false); 13644 } 13645 } else { 13646 this.onmousewheel = null; 13647 } 13648 } 13649 }; 13650 $.fn.extend({ 13651 mousewheel: function(fn) { 13652 return fn ? this.bind("mousewheel", fn) : this.trigger("mousewheel"); 13653 }, 13654 unmousewheel: function(fn) { 13655 return this.unbind("mousewheel", fn); 13656 } 13657 }); 13658 13659 function handler(event) { 13660 var orgEvent = event || window.event, 13661 args = [].slice.call(arguments, 1), 13662 delta = 0, 13663 returnValue = true, 13664 deltaX = 0, 13665 deltaY = 0; 13666 event = $.event.fix(orgEvent); 13667 event.type = "mousewheel"; 13668 // Old school scrollwheel delta 13669 if (orgEvent.wheelDelta) { 13670 delta = orgEvent.wheelDelta / 120; 13671 } 13672 if (orgEvent.detail) { 13673 delta = -orgEvent.detail / 3; 13674 } 13675 // New school multidimensional scroll (touchpads) deltas 13676 deltaY = delta; 13677 // Gecko 13678 if (orgEvent.axis !== undefined && orgEvent.axis === orgEvent.HORIZONTAL_AXIS) { 13679 deltaY = 0; 13680 deltaX = -1 * delta; 13681 } 13682 // Webkit 13683 if (orgEvent.wheelDeltaY !== undefined) { 13684 deltaY = orgEvent.wheelDeltaY / 120; 13685 } 13686 if (orgEvent.wheelDeltaX !== undefined) { 13687 deltaX = -1 * orgEvent.wheelDeltaX / 120; 13688 } 13689 // Add event and delta to the front of the arguments 13690 args.unshift(event, delta, deltaX, deltaY); 13691 return ($.event.dispatch || $.event.handle).apply(this, args); 13692 } 13693})(jQuery); 13694/** 13695 * jQuery iLightBox - Revolutionary Lightbox Plugin 13696 * http://www.ilightbox.net/ 13697 * 13698 * @version: 2.2.4 - October 14, 2017 13699 * 13700 * @author: iProDev (Hemn Chawroka) 13701 * http://www.iprodev.com/ 13702 * 13703 */ 13704(function($, window, undefined) { 13705 13706 var extensions = { 13707 flash: ['swf'], 13708 image: ['bmp', 'gif', 'jpeg', 'jpg', 'png', 'tiff', 'tif', 'jfif', 'jpe', 'webp'], 13709 iframe: ['asp', 'aspx', 'cgi', 'cfm', 'htm', 'html', 'jsp', 'php', 'pl', 'php3', 'php4', 'php5', 'phtml', 'rb', 'rhtml', 'shtml', 'txt'], 13710 video: ['avi', 'mov', 'mpg', 'mpeg', 'movie', 'mp4', 'webm', 'ogv', 'ogg', '3gp', 'm4v'] 13711 }, 13712 13713 // Global DOM elements 13714 $win = $(window), 13715 $doc = $(document), 13716
13717 // Support indicators 13718 browser, 13719 transform, 13720 gpuAcceleration, 13721 fullScreenApi = '', 13722 userAgent = navigator.userAgent || navigator.vendor || window.opera, 13723 supportTouch = "ontouchstart" in window || navigator.msMaxTouchPoints || (navigator.maxTouchPoints && navigator.userAgent.indexOf('Windows') > -1), 13724 ishybrid = navigator.maxTouchPoints && navigator.userAgent.indexOf('Windows') > -1, 13725 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)), 13726 13727 // Events 13728 clickEvent = ishybrid ? "itap.iLightBox click.iLightBox" : supportTouch ? "itap.iLightBox" : "click.iLightBox", 13729 touchStartEvent = ishybrid ? "touchstart.iLightBox mousedown.iLightBox" : supportTouch ? "touchstart.iLightBox" : "mousedown.iLightBox", 13730 touchStopEvent = ishybrid ? "touchend.iLightBox mouseup.iLightBox" : supportTouch ? "touchend.iLightBox" : "mouseup.iLightBox", 13731 touchMoveEvent = ishybrid ? "touchmove.iLightBox mousemove.iLightBox" : supportTouch ? "touchmove.iLightBox" : "mousemove.iLightBox", 13732 13733 // Math shorthands 13734 abs = Math.abs, 13735 sqrt = Math.sqrt, 13736 round = Math.round, 13737 max = Math.max, 13738 min = Math.min, 13739 floor = Math.floor, 13740 random = Math.random, 13741 13742 pluginspages = { 13743 quicktime: 'http://www.apple.com/quicktime/download', 13744 flash: 'http://www.adobe.com/go/getflash' 13745 }, 13746 13747 iLightBox = function(el, options, items, instant) { 13748 var iL = this; 13749 13750 iL.options = options, 13751 iL.selector = options.selector || el, 13752 iL.context = document, 13753 iL.instant = instant; 13754 13755 if (items.length < 1) iL.attachItems(); 13756 else iL.items = items; 13757 13758 iL.vars = { 13759 total: iL.items.length, 13760 start: 0, 13761 current: null, 13762 next: null, 13763 prev: null, 13764 BODY: $('body'), 13765 loadRequests: 0, 13766 overlay: $('<div class="ilightbox-overlay"></div>'), 13767 loader: $('<div class="ilightbox-loader"><div></div></div>'), 13768 toolbar: $('<div class="ilightbox-toolbar"></div>'), 13769 innerToolbar: $('<div class="ilightbox-inner-toolbar"></div>'), 13770 title: $('<div class="ilightbox-title"></div>'), 13771 closeButton: $('<a class="ilightbox-close" title="' + iL.options.text.close + '"></a>'), 13772 fullScreenButton: $('<a class="ilightbox-fullscreen" title="' + iL.options.text.enterFullscreen + '"></a>'), 13773 innerPlayButton: $('<a class="ilightbox-play" title="' + iL.options.text.slideShow + '"></a>'), 13774 innerNextButton: $('<a class="ilightbox-next-button" title="' + iL.options.text.next + '"></a>'), 13775 innerPrevButton: $('<a class="ilightbox-prev-button" title="' + iL.options.text.previous + '"></a>'), 13776 holder: $('<div class="ilightbox-holder' + (supportTouch ? ' supportTouch' : '') + '" ondragstart="return false;"><div class="ilightbox-container"></div></div>'), 13777 nextPhoto: $('<div class="ilightbox-holder' + (supportTouch ? ' supportTouch' : '') + ' ilightbox-next" ondragstart="return false;"><div class="ilightbox-container"></div></div>'), 13778 prevPhoto: $('<div class="ilightbox-holder' + (supportTouch ? ' supportTouch' : '') + ' ilightbox-prev" ondragstart="return false;"><div class="ilightbox-container"></div></div>'), 13779 nextButton: $('<a class="ilightbox-button ilightbox-next-button" ondragstart="return false;" title="' + iL.options.text.next + '"><span></span></a>'), 13780 prevButton: $('<a class="ilightbox-button ilightbox-prev-button" ondragstart="return false;" title="' + iL.options.text.previous + '"><span></span></a>'),
13781 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>'), 13782 thumbs: false, 13783 nextLock: false, 13784 prevLock: false, 13785 hashLock: false, 13786 isMobile: false, 13787 mobileMaxWidth: 980, 13788 isInFullScreen: false, 13789 isSwipe: false, 13790 mouseID: 0, 13791 cycleID: 0, 13792 isPaused: 0, 13793 captionHeight: 39, 13794 }; 13795 13796 // Hideable elements with mousemove event 13797 iL.vars.hideableElements = iL.vars.nextButton.add(iL.vars.prevButton); 13798 13799 iL.normalizeItems(); 13800 13801 //Check necessary plugins 13802 iL.availPlugins(); 13803 13804 //Set startFrom 13805 iL.options.startFrom = (iL.options.startFrom > 0 && iL.options.startFrom >= iL.vars.total) ? iL.vars.total - 1 : iL.options.startFrom; 13806 13807 //If randomStart 13808 iL.options.startFrom = (iL.options.randomStart) ? floor(random() * iL.vars.total) : iL.options.startFrom; 13809 iL.vars.start = iL.options.startFrom; 13810 13811 if (instant) iL.instantCall(); 13812 else iL.patchItemsEvents(); 13813 13814 if (iL.options.linkId) { 13815 iL.hashChangeHandler(); 13816 $win.iLightBoxHashChange(function() { 13817 iL.hashChangeHandler(); 13818 }); 13819 } 13820 13821 if (supportTouch) { 13822 var RegExp = /(click|mouseenter|mouseleave|mouseover|mouseout)/ig, 13823 replace = "itap"; 13824 iL.options.caption.show = iL.options.caption.show.replace(RegExp, replace), 13825 iL.options.caption.hide = iL.options.caption.hide.replace(RegExp, replace), 13826 iL.options.social.show = iL.options.social.show.replace(RegExp, replace), 13827 iL.options.social.hide = iL.options.social.hide.replace(RegExp, replace); 13828 } 13829 13830 if (iL.options.controls.arrows || $(window).width() < UNCODE.mediaQuery) { 13831 $.extend(iL.options.styles, { 13832 nextOffsetX: ($(window).width() > UNCODE.mediaQuery) ? 36 : 4, 13833 prevOffsetX: ($(window).width() > UNCODE.mediaQuery) ? 36 : 4, 13834 nextOpacity: 0, 13835 prevOpacity: 0 13836 }); 13837 } 13838 }; 13839 13840 //iLightBox helpers 13841 iLightBox.prototype = { 13842 showLoader: function() { 13843 var iL = this; 13844 iL.vars.loadRequests += 1; 13845 if (iL.options.path.toLowerCase() == "horizontal") iL.vars.loader.addClass('ilightbox-show').stop().animate({ 13846 //top: '-30px' 13847 opacity: '1' 13848 }, iL.options.show.speed, 'easeOutCirc'); 13849 else iL.vars.loader.addClass('ilightbox-show').stop().animate({ 13850 //left: '-30px' 13851 opacity: '1' 13852 }, iL.options.show.speed, 'easeOutCirc'); 13853 }, 13854 13855 hideLoader: function() { 13856 var iL = this; 13857 iL.vars.loadRequests -= 1; 13858 iL.vars.loadRequests = (iL.vars.loadRequests < 0) ? 0 : iL.vars.loadRequests; 13859 if (iL.options.path.toLowerCase() == "horizontal") { 13860 if (iL.vars.loadRequests <= 0) iL.vars.loader.removeClass('ilightbox-show').stop().animate({ 13861 //top: '-192px' 13862 opacity: '0' 13863 }, iL.options.show.speed, 'easeInCirc'); 13864 } else { 13865 if (iL.vars.loadRequests <= 0) iL.vars.loader.removeClass('ilightbox-show').stop().animate({ 13866 //left: '-192px' 13867 opacity: '0' 13868 }, iL.options.show.speed, 'easeInCirc'); 13869 } 13870 }, 13871 13872 createUI: function() { 13873 var iL = this; 13874 13875 iL.ui = { 13876 currentElement: iL.vars.holder, 13877 nextElement: iL.vars.nextPhoto, 13878 prevElement: iL.vars.prevPhoto, 13879 currentItem: iL.vars.current, 13880 nextItem: iL.vars.next, 13881 prevItem: iL.vars.prev, 13882 hide: function() { 13883 iL.closeAction(); 13884 }, 13885 refresh: function() { 13886 (arguments.length > 0) ? iL.repositionPhoto(true): iL.repositionPhoto(); 13887 }, 13888 fullscreen: function() { 13889 iL.fullScreenAction(); 13890 } 13891 }; 13892 }, 13893 13894 attachItems: function() { 13895 var iL = this, 13896 itemsObject = new Array(), 13897 items = new Array(); 13898 13899 $(iL.selector, iL.context).each(function() { 13900 var t = $(this), 13901 URL = t.attr(iL.options.attr) || null, 13902 options = t.data("options") && eval("({" + t.data("options") + "})") || {}, 13903 caption = t.data('caption'), 13904 title = t.data('title'), 13905 type = t.data('type') || getTypeByExtension(URL), 13906 clone = t.data('lbox-clone') || false; 13907 13908 //Uncode addition ##START## 13909 if (type === false) { 13910 return; 13911 } 13912 //Uncode addition ##END## 13913 13914 if (t.data('lbox-clone') != undefined) return; 13915 13916 //Uncode addition ##START## 13917 if ( typeof t.attr('data-album') != 'undefined' && t.attr('data-album') != '' ) { 13918 var ALBUM_URLS = JSON.parse(t.attr('data-album')), 13919 URL_i, 13920 URLS_LENGHT = ALBUM_URLS.length; 13921 13922 for (URL_i = 0; URL_i < URLS_LENGHT; URL_i++) { 13923 if ( typeof ALBUM_URLS[URL_i].url !== 'undefined' && ALBUM_URLS[URL_i].url != '' ) { 13924 var item_opts = 'width:' + ALBUM_URLS[URL_i].width + ',height:' + ALBUM_URLS[URL_i].height + ',thumbnail: \'' + ALBUM_URLS[URL_i].thumbnail + '\''; 13925 item_opts = item_opts && eval("({" + item_opts + "})") || {}, 13926 items.push({ 13927 URL: ALBUM_URLS[URL_i].url, 13928 caption: ALBUM_URLS[URL_i].caption, 13929 title: ALBUM_URLS[URL_i].title, 13930 type: getTypeByExtension(ALBUM_URLS[URL_i].url), 13931 options: item_opts, 13932 clone: clone 13933 }); 13934 var newT = t; 13935 newT.attr('href',ALBUM_URLS[URL_i].url); 13936 if (!iL.instant) itemsObject.push(newT); 13937 } 13938 } 13939 } else { 13940 //Uncode addition ##END## 13941 items.push({ 13942 URL: URL, 13943 caption: caption, 13944 title: title, 13945 type: type, 13946 options: options, 13947 clone: clone 13948 }); 13949 } 13950 13951 13952 if (iL.vars != undefined) iL.vars.total = items.length; 13953 13954 if (!iL.instant) itemsObject.push(t); 13955 }); 13956 13957 iL.items = items, 13958 iL.itemsObject = itemsObject; 13959 13960 }, 13961 13962 normalizeItems: function() { 13963 var iL = this, 13964 newItems = new Array(); 13965 13966 $.each(iL.items, function(key, val) { 13967 13968 if (typeof val == "string") val = { 13969 url: val 13970 }; 13971 13972 var URL = val.url || val.URL || null, 13973 options = val.options || {}, 13974 caption = val.caption || null, 13975 title = val.title || null, 13976 type = (val.type) ? val.type.toLowerCase() : getTypeByExtension(URL), 13977 ext = (typeof URL != 'object') ? getExtension(URL) : ''; 13978 13979 options.thumbnail = options.thumbnail || ((type == "image") ? URL : null),
13980 options.videoType = options.videoType || null, 13981 options.skin = options.skin || iL.options.skin, 13982 options.width = options.width || null, 13983 options.height = options.height || null, 13984 options.mousewheel = (typeof options.mousewheel != 'undefined') ? options.mousewheel : true, 13985 options.swipe = (typeof options.swipe != 'undefined') ? options.swipe : true, 13986 options.social = (typeof options.social != 'undefined') ? options.social : iL.options.social.buttons && $.extend({}, {}, iL.options.social.buttons); 13987 13988 if (type == "video") { 13989 options.html5video = (typeof options.html5video != 'undefined') ? options.html5video : {}; 13990 13991 options.html5video.webm = options.html5video.webm || options.html5video.WEBM || null; 13992 options.html5video.controls = (typeof options.html5video.controls != 'undefined') ? options.html5video.controls : "controls"; 13993 options.html5video.preload = options.html5video.preload || "metadata"; 13994 options.html5video.autoplay = (typeof options.html5video.autoplay != 'undefined') ? options.html5video.autoplay : false; 13995 //UNCODE addition 13996 options.html5video.loop = (typeof options.html5video.loop != 'undefined') ? options.html5video.loop : false; 13997 } 13998 13999 if (!options.width || !options.height) { 14000 if (type == "video") options.width = 1280, options.height = 720; 14001 else if (type == "iframe") options.width = '100%', options.height = '90%'; 14002 else if (type == "flash") options.width = 1280, options.height = 720; 14003 } 14004 14005 delete val.url; 14006 val.index = key; 14007 val.URL = URL; 14008 val.caption = caption; 14009 val.title = title; 14010 val.type = type; 14011 val.options = options; 14012 val.ext = ext; 14013 14014 newItems.push(val); 14015 }); 14016 14017 iL.items = newItems; 14018 }, 14019 14020 instantCall: function() { 14021 var iL = this, 14022 key = iL.vars.start; 14023 14024 iL.vars.current = key; 14025 iL.vars.next = (iL.items[key + 1]) ? key + 1 : null; 14026 iL.vars.prev = (iL.items[key - 1]) ? key - 1 : null; 14027 14028 iL.addContents(); 14029 iL.patchEvents(); 14030 }, 14031 14032 addContents: function() { 14033 var iL = this, 14034 vars = iL.vars, 14035 opts = iL.options, 14036 viewport = getViewport(), 14037 path = opts.path.toLowerCase(), 14038 recognizingItems = vars.total > 0 && iL.items.filter(function(e, i, arr) { 14039 return ['image', 'flash', 'video'].indexOf(e.type) === -1 && typeof e.recognized === 'undefined' && (opts.smartRecognition || e.options.smartRecognition); 14040 }), 14041 needRecognition = recognizingItems.length > 0; 14042 14043 if (opts.mobileOptimizer && !opts.innerToolbar) 14044 vars.isMobile = viewport.width <= vars.mobileMaxWidth; 14045 14046 vars.overlay.addClass(opts.skin).hide().css('opacity', opts.overlay.opacity); 14047 14048 if (opts.linkId) 14049 vars.overlay[0].setAttribute('linkid', opts.linkId); 14050 14051 //Add Toolbar Buttons 14052 if (opts.controls.toolbar) { 14053 vars.toolbar.addClass(opts.skin).append(vars.closeButton); 14054 if (opts.controls.fullscreen) 14055 vars.toolbar.append(vars.fullScreenButton); 14056 if (opts.controls.slideshow) 14057 vars.toolbar.append(vars.innerPlayButton); 14058 if (vars.total > 1) 14059 vars.toolbar.append(vars.innerPrevButton).append(vars.innerNextButton); 14060 } 14061 14062 //Append elements to body 14063 vars.BODY.addClass('ilightbox-noscroll').append(vars.overlay).append(vars.loader).append(vars.holder).append(vars.nextPhoto).append(vars.prevPhoto); 14064 14065 if (!opts.innerToolbar) 14066 vars.BODY.append(vars.toolbar); 14067 if (opts.controls.arrows) 14068 vars.BODY.append(vars.nextButton).append(vars.prevButton); 14069 14070 if (opts.controls.thumbnail && vars.total > 1) { 14071 vars.BODY.append(vars.thumbnails); 14072 vars.thumbnails.addClass(opts.skin).addClass('ilightbox-' + path); 14073 $('div.ilightbox-thumbnails-grid', vars.thumbnails).empty(); 14074 vars.thumbs = true; 14075 } 14076 14077 //Configure loader and arrows 14078 var loaderCss = (opts.path.toLowerCase() == "horizontal") ? { 14079 left: parseInt((viewport.width / 2) - (vars.loader.outerWidth() / 2)) 14080 } : { 14081 top: parseInt((viewport.height / 2) - (vars.loader.outerHeight() / 2)) 14082 }; 14083 vars.loader.addClass(opts.skin).css(loaderCss); 14084 vars.nextButton.add(vars.prevButton).addClass(opts.skin); 14085 if (path == "horizontal") 14086 vars.loader.add(vars.nextButton).add(vars.prevButton).addClass('horizontal'); 14087 14088 // Configure arrow buttons 14089 vars.BODY[vars.isMobile ? 'addClass' : 'removeClass']('isMobile'); 14090 14091 if (!opts.infinite) { 14092 vars.prevButton.add(vars.prevButton).add(vars.innerPrevButton).add(vars.innerNextButton).removeClass('disabled'); 14093 14094 if (vars.current == 0) 14095 vars.prevButton.add(vars.innerPrevButton).addClass('disabled'); 14096 if (vars.current >= vars.total - 1) 14097 vars.nextButton.add(vars.innerNextButton).addClass('disabled'); 14098 } 14099 14100 if (opts.show.effect) { 14101 vars.overlay.stop().fadeIn(opts.show.speed); 14102 vars.toolbar.stop().fadeIn(opts.show.speed); 14103 } else { 14104 vars.overlay.show(); 14105 vars.toolbar.show(); 14106 } 14107 14108 var length = recognizingItems.length; 14109 if (needRecognition) { 14110 iL.showLoader(); 14111 14112 $.each(recognizingItems, function(key, val) { 14113 var resultFnc = function(result) { 14114 var key = -1, 14115 filter = iL.items.filter(function(e, i, arr) { 14116 if (e.URL == result.url) 14117 key = i; 14118 14119 return e.URL == result.url; 14120 }), 14121 self = iL.items[key]; 14122 14123 if (result) 14124 $.extend(true, self, { 14125 URL: result.source, 14126 type: result.type, 14127 recognized: true, 14128 options: { 14129 html5video: result.html5video, 14130 width: (result.type == "image") ? 0 : (result.width || self.width), 14131 height: (result.type == "image") ? 0 : (result.height || self.height), 14132 thumbnail: self.options.thumbnail || result.thumbnail 14133 } 14134 }); 14135 14136 length--; 14137 14138 if (length == 0) { 14139 iL.hideLoader(); 14140 14141 vars.dontGenerateThumbs = false;
14142 iL.generateThumbnails(); 14143 14144 if (opts.show.effect) 14145 setTimeout(function() { 14146 iL.generateBoxes(); 14147 }, opts.show.speed); 14148 else 14149 iL.generateBoxes(); 14150 } 14151 }; 14152 14153 iL.ogpRecognition(this, resultFnc); 14154 }); 14155 } 14156 else { 14157 if (opts.show.effect) 14158 setTimeout(function() { 14159 iL.generateBoxes(); 14160 }, opts.show.speed); 14161 else 14162 iL.generateBoxes(); 14163 } 14164 14165 iL.createUI(); 14166 14167 window.iLightBox = { 14168 close: function() { 14169 iL.closeAction(); 14170 }, 14171 fullscreen: function() { 14172 iL.fullScreenAction(); 14173 }, 14174 moveNext: function() { 14175 iL.moveTo('next'); 14176 }, 14177 movePrev: function() { 14178 iL.moveTo('prev'); 14179 }, 14180 goTo: function(index) { 14181 iL.goTo(index); 14182 }, 14183 refresh: function() { 14184 iL.refresh(); 14185 }, 14186 reposition: function() { 14187 (arguments.length > 0) ? iL.repositionPhoto(true): iL.repositionPhoto(); 14188 }, 14189 setOption: function(options) { 14190 iL.setOption(options); 14191 }, 14192 destroy: function() { 14193 iL.closeAction(); 14194 iL.dispatchItemsEvents(); 14195 } 14196 }; 14197 14198 if (opts.linkId) { 14199 vars.hashLock = true; 14200 window.location.hash = opts.linkId + '/' + vars.current; 14201 setTimeout(function() { 14202 vars.hashLock = false; 14203 }, 55); 14204 } 14205 14206 if (!opts.slideshow.startPaused) { 14207 iL.resume(); 14208 vars.innerPlayButton.removeClass('ilightbox-play').addClass('ilightbox-pause'); 14209 } 14210 14211 //Trigger the onOpen callback 14212 if (typeof iL.options.callback.onOpen == 'function') iL.options.callback.onOpen.call(iL); 14213 }, 14214 14215 loadContent: function(obj, opt, speed) { 14216 var iL = this, 14217 holder, item; 14218 14219 iL.createUI(); 14220 14221 obj.speed = speed || iL.options.effects.loadedFadeSpeed; 14222 14223 if (opt == 'current') { 14224 if (!obj.options.mousewheel) iL.vars.lockWheel = true; 14225 else iL.vars.lockWheel = false; 14226 14227 if (!obj.options.swipe) iL.vars.lockSwipe = true; 14228 else iL.vars.lockSwipe = false; 14229 } 14230 14231 switch (opt) { 14232 case 'current': 14233 holder = iL.vars.holder, item = iL.vars.current; 14234 break; 14235 case 'next': 14236 holder = iL.vars.nextPhoto, item = iL.vars.next; 14237 break; 14238 case 'prev': 14239 holder = iL.vars.prevPhoto, item = iL.vars.prev; 14240 break; 14241 } 14242 14243 holder.removeAttr('style class').addClass('ilightbox-holder' + (supportTouch ? ' supportTouch' : '')).addClass(obj.options.skin); 14244 $('div.ilightbox-inner-toolbar', holder).remove(); 14245 14246 if (obj.title || iL.options.innerToolbar) { 14247 var innerToolbar = iL.vars.innerToolbar.clone(); 14248 if (obj.title && iL.options.show.title) { 14249 var title = iL.vars.title.clone(); 14250 title.empty().html(obj.title); 14251 innerToolbar.append(title); 14252 } 14253 if (iL.options.innerToolbar) { 14254 innerToolbar.append((iL.vars.total > 1) ? iL.vars.toolbar.clone() : iL.vars.toolbar); 14255 } 14256 holder.prepend(innerToolbar); 14257 } 14258 14259 //console.warn('loadContent', arguments); 14260 14261 iL.loadSwitcher(obj, holder, item, opt); 14262 }, 14263 14264 loadSwitcher: function(obj, holder, item, opt) { 14265 var iL = this, 14266 opts = iL.options, 14267 api = { 14268 element: holder, 14269 position: item 14270 }; 14271 14272 switch (obj.type) { 14273 case 'image': 14274 //Trigger the onBeforeLoad callback 14275 if (typeof opts.callback.onBeforeLoad == 'function') opts.callback.onBeforeLoad.call(iL, iL.ui, item); 14276 if (typeof obj.options.onBeforeLoad == 'function') obj.options.onBeforeLoad.call(iL, api); 14277 14278 iL.loadImage(obj.URL, function(img) { 14279 //Trigger the onAfterLoad callback 14280 if (typeof opts.callback.onAfterLoad == 'function') opts.callback.onAfterLoad.call(iL, iL.ui, item); 14281 if (typeof obj.options.onAfterLoad == 'function') obj.options.onAfterLoad.call(iL, api); 14282 14283 var width = (img) ? img.width : 400, 14284 height = (img) ? img.height : 200; 14285 14286 holder.data({ 14287 naturalWidth: width, 14288 naturalHeight: height 14289 }); 14290 14291 $('div.ilightbox-container', holder).empty().append((img) ? '<img src="' + obj.URL + '" class="ilightbox-image" />' : '<span class="ilightbox-alert">' + opts.errors.loadImage + '</span>'); 14292 14293 //Trigger the onRender callback 14294 if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item); 14295 if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api); 14296 14297 iL.configureHolder(obj, opt, holder); 14298 }); 14299 14300 break; 14301
14302 case 'video': 14303 holder.data({ 14304 naturalWidth: obj.options.width, 14305 naturalHeight: obj.options.height 14306 }); 14307 14308 if (opt === 'current') { 14309 iL.addContent(holder, obj); 14310 14311 //Trigger the onRender callback 14312 if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item); 14313 if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api); 14314 } else { 14315 $('div.ilightbox-container', holder).empty(); 14316 } 14317 14318 iL.configureHolder(obj, opt, holder); 14319 14320 break; 14321 14322 case 'iframe': 14323 //iL.showLoader(); 14324 holder.data({ 14325 naturalWidth: obj.options.width, 14326 naturalHeight: obj.options.height 14327 }); 14328 14329 iL.configureHolder(obj, opt, holder); 14330 14331 if (opt === 'current') { 14332 var el = iL.addContent(holder, obj); 14333 14334 //Trigger the onRender callback 14335 if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item); 14336 if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api); 14337 14338 //Trigger the onBeforeLoad callback 14339 if (typeof opts.callback.onBeforeLoad == 'function') opts.callback.onBeforeLoad.call(iL, iL.ui, item); 14340 if (typeof obj.options.onBeforeLoad == 'function') obj.options.onBeforeLoad.call(iL, api); 14341 14342 el.bind('load', function() { 14343 //Trigger the onAfterLoad callback 14344 if (typeof opts.callback.onAfterLoad == 'function') opts.callback.onAfterLoad.call(iL, iL.ui, item); 14345 if (typeof obj.options.onAfterLoad == 'function') obj.options.onAfterLoad.call(iL, api); 14346 14347 //iL.hideLoader(); 14348 el.unbind('load'); 14349 }); 14350 } else { 14351 $('div.ilightbox-container', holder).empty(); 14352 } 14353 14354 break; 14355 14356 case 'inline': 14357 var el = $(obj.URL), 14358 content = iL.addContent(holder, obj), 14359 images = findImageInElement(holder); 14360 14361 holder.data({ 14362 naturalWidth: (iL.items[item].options.width || el.outerWidth()), 14363 naturalHeight: (iL.items[item].options.height || el.outerHeight()) 14364 }); 14365 content.children().eq(0).show(); 14366 14367 //Trigger the onRender callback 14368 if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item); 14369 if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api); 14370 14371 //Trigger the onBeforeLoad callback 14372 if (typeof opts.callback.onBeforeLoad == 'function') opts.callback.onBeforeLoad.call(iL, iL.ui, item); 14373 if (typeof obj.options.onBeforeLoad == 'function') obj.options.onBeforeLoad.call(iL, api); 14374 14375 iL.loadImage(images, function() { 14376 //Trigger the onAfterLoad callback 14377 if (typeof opts.callback.onAfterLoad == 'function') opts.callback.onAfterLoad.call(iL, iL.ui, item); 14378 if (typeof obj.options.onAfterLoad == 'function') obj.options.onAfterLoad.call(iL, api); 14379 14380 iL.configureHolder(obj, opt, holder); 14381 }); 14382 14383 break; 14384 14385 case 'flash': 14386 var el = iL.addContent(holder, obj); 14387 14388 holder.data({ 14389 naturalWidth: (iL.items[item].options.width || el.outerWidth()), 14390 naturalHeight: (iL.items[item].options.height || el.outerHeight()) 14391 }); 14392 14393 //Trigger the onRender callback 14394 if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item); 14395 if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api); 14396 14397 iL.configureHolder(obj, opt, holder); 14398 14399 break; 14400 14401 case 'ajax': 14402 var ajax = obj.options.ajax || {}; 14403 //Trigger the onBeforeLoad callback 14404 if (typeof opts.callback.onBeforeLoad == 'function') opts.callback.onBeforeLoad.call(iL, iL.ui, item); 14405 if (typeof obj.options.onBeforeLoad == 'function') obj.options.onBeforeLoad.call(iL, api); 14406 14407 iL.showLoader(); 14408 $.ajax({ 14409 url: obj.URL || opts.ajaxSetup.url, 14410 data: ajax.data || null, 14411 dataType: ajax.dataType || "html", 14412 type: ajax.type || opts.ajaxSetup.type, 14413 cache: ajax.cache || opts.ajaxSetup.cache, 14414 crossDomain: ajax.crossDomain || opts.ajaxSetup.crossDomain, 14415 global: ajax.global || opts.ajaxSetup.global, 14416 ifModified: ajax.ifModified || opts.ajaxSetup.ifModified, 14417 username: ajax.username || opts.ajaxSetup.username, 14418 password: ajax.password || opts.ajaxSetup.password, 14419 beforeSend: ajax.beforeSend || opts.ajaxSetup.beforeSend, 14420 complete: ajax.complete || opts.ajaxSetup.complete, 14421 success: function(data, textStatus, jqXHR) { 14422 iL.hideLoader(); 14423 14424 var el = $(data), 14425 container = $('div.ilightbox-container', holder), 14426 elWidth = iL.items[item].options.width || parseInt(el[0].getAttribute('width')), 14427 elHeight = iL.items[item].options.height || parseInt(el[0].getAttribute('height')), 14428 css = (el[0].getAttribute('width') && el[0].getAttribute('height')) ? { 14429 'overflow': 'hidden' 14430 } : {}; 14431 14432 container.empty().append($('<div class="ilightbox-wrapper"></div>').css(css).html(el)); 14433 holder.show().data({
14434 naturalWidth: (elWidth || container.outerWidth()), 14435 naturalHeight: (elHeight || container.outerHeight()) 14436 }).hide(); 14437 14438 //Trigger the onRender callback 14439 if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item); 14440 if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api); 14441 14442 var images = findImageInElement(holder); 14443 iL.loadImage(images, function() { 14444 //Trigger the onAfterLoad callback 14445 if (typeof opts.callback.onAfterLoad == 'function') opts.callback.onAfterLoad.call(iL, iL.ui, item); 14446 if (typeof obj.options.onAfterLoad == 'function') obj.options.onAfterLoad.call(iL, api); 14447 14448 iL.configureHolder(obj, opt, holder); 14449 }); 14450 14451 opts.ajaxSetup.success(data, textStatus, jqXHR); 14452 if (typeof ajax.success == 'function') ajax.success(data, textStatus, jqXHR); 14453 }, 14454 error: function(jqXHR, textStatus, errorThrown) { 14455 //Trigger the onAfterLoad callback 14456 if (typeof opts.callback.onAfterLoad == 'function') opts.callback.onAfterLoad.call(iL, iL.ui, item); 14457 if (typeof obj.options.onAfterLoad == 'function') obj.options.onAfterLoad.call(iL, api); 14458 14459 iL.hideLoader(); 14460 $('div.ilightbox-container', holder).empty().append('<span class="ilightbox-alert">' + opts.errors.loadContents + '</span>'); 14461 iL.configureHolder(obj, opt, holder); 14462 14463 opts.ajaxSetup.error(jqXHR, textStatus, errorThrown); 14464 if (typeof ajax.error == 'function') ajax.error(jqXHR, textStatus, errorThrown); 14465 } 14466 }); 14467 14468 break; 14469 14470 case 'html': 14471 var object = obj.URL, 14472 el 14473 container = $('div.ilightbox-container', holder); 14474 14475 if (object[0].nodeName) el = object.clone(); 14476 else { 14477 var dom = $(object); 14478 if (dom.selector) el = $('<div>' + dom + '</div>'); 14479 else el = dom; 14480 } 14481 14482 var elWidth = iL.items[item].options.width || parseInt(el.attr('width')), 14483 elHeight = iL.items[item].options.height || parseInt(el.attr('height')); 14484 14485 iL.addContent(holder, obj); 14486 14487 el.appendTo(document.documentElement).hide(); 14488 14489 //Trigger the onRender callback 14490 if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item); 14491 if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api); 14492 14493 var images = findImageInElement(holder); 14494 14495 //Trigger the onBeforeLoad callback 14496 if (typeof opts.callback.onBeforeLoad == 'function') opts.callback.onBeforeLoad.call(iL, iL.ui, item); 14497 if (typeof obj.options.onBeforeLoad == 'function') obj.options.onBeforeLoad.call(iL, api); 14498 14499 iL.loadImage(images, function() { 14500 //Trigger the onAfterLoad callback 14501 if (typeof opts.callback.onAfterLoad == 'function') opts.callback.onAfterLoad.call(iL, iL.ui, item); 14502 if (typeof obj.options.onAfterLoad == 'function') obj.options.onAfterLoad.call(iL, api); 14503 14504 holder.show().data({ 14505 naturalWidth: (elWidth || container.outerWidth()), 14506 naturalHeight: (elHeight || container.outerHeight()) 14507 }).hide(); 14508 el.remove(); 14509 14510 iL.configureHolder(obj, opt, holder); 14511 }); 14512 14513 break; 14514 } 14515 }, 14516 14517 configureHolder: function(obj, opt, holder) { 14518 var iL = this, 14519 vars = iL.vars, 14520 opts = iL.options; 14521 14522 if (opt != "current")(opt == "next") ? holder.addClass('ilightbox-next') : holder.addClass('ilightbox-prev'); 14523 14524 if (opt == "current") 14525 var item = vars.current; 14526 else if (opt == "next") 14527 var opacity = opts.styles.nextOpacity, 14528 item = vars.next; 14529 else 14530 var opacity = opts.styles.prevOpacity, 14531 item = vars.prev; 14532 14533 var api = { 14534 element: holder, 14535 position: item 14536 }; 14537 14538 iL.items[item].options.width = iL.items[item].options.width || 0, 14539 iL.items[item].options.height = iL.items[item].options.height || 0; 14540 14541 if (opt == "current") { 14542 if (opts.show.effect) holder.css(transform, gpuAcceleration).fadeIn(obj.speed, function() { 14543 holder.css(transform, ''); 14544 if (obj.caption) { 14545 iL.setCaption(obj, holder); 14546 var caption = $('div.ilightbox-caption', holder), 14547 percent = parseInt((caption.outerHeight() / holder.outerHeight()) * 100); 14548 if (opts.caption.start & percent <= 50) caption.fadeIn(opts.effects.fade
14548Speed); 14549 } 14550 14551 var social = obj.options.social; 14552 if (social) { 14553 iL.setSocial(social, obj.URL, holder); 14554 if (opts.social.start) $('div.ilightbox-social', holder).fadeIn(opts.effects.fadeSpeed); 14555 } 14556 14557 //Generate thumbnails 14558 iL.generateThumbnails(); 14559 14560 //Trigger the onShow callback 14561 if (typeof opts.callback.onShow == 'function') opts.callback.onShow.call(iL, iL.ui, item); 14562 if (typeof obj.options.onShow == 'function') obj.options.onShow.call(iL, api); 14563 }); 14564 else { 14565 holder.show(); 14566 14567 //Generate thumbnails 14568 iL.generateThumbnails(); 14569 14570 //Trigger the onShow callback 14571 if (typeof opts.callback.onShow == 'function') opts.callback.onShow.call(iL, iL.ui, item); 14572 if (typeof obj.options.onShow == 'function') obj.options.onShow.call(iL, api); 14573 } 14574 } else { 14575 if (opts.show.effect) holder.fadeTo(obj.speed, opacity, function() { 14576 if (opt == "next") vars.nextLock = false; 14577 else vars.prevLock = false; 14578 14579 //Generate thumbnails 14580 iL.generateThumbnails(); 14581 14582 //Trigger the onShow callback 14583 if (typeof opts.callback.onShow == 'function') opts.callback.onShow.call(iL, iL.ui, item); 14584 if (typeof obj.options.onShow == 'function') obj.options.onShow.call(iL, api); 14585 }); 14586 else { 14587 holder.css({ 14588 opacity: opacity 14589 }).show(); 14590 if (opt == "next") vars.nextLock = false; 14591 else vars.prevLock = false; 14592 14593 //Generate thumbnails 14594 iL.generateThumbnails(); 14595 14596 //Trigger the onShow callback 14597 if (typeof opts.callback.onShow == 'function') opts.callback.onShow.call(iL, iL.ui, item); 14598 if (typeof obj.options.onShow == 'function') obj.options.onShow.call(iL, api); 14599 } 14600 } 14601 14602 setTimeout(function() { 14603 iL.repositionPhoto(); 14604 }, 0); 14605 }, 14606 14607 generateBoxes: function() { 14608 var iL = this, 14609 vars = iL.vars, 14610 opts = iL.options; 14611 14612 if (opts.infinite && vars.total >= 3) { 14613 if (vars.current == vars.total - 1) vars.next = 0; 14614 if (vars.current == 0) vars.prev = vars.total - 1; 14615 } else opts.infinite = false; 14616 14617 //UNCODE addition 14618 if ( typeof iL.items[vars.current] == 'undefined' ) 14619 vars.current = 0; 14620 14621 iL.loadContent(iL.items[vars.current], 'current', opts.show.speed); 14622 14623 if (iL.items[vars.next]) iL.loadContent(iL.items[vars.next], 'next', opts.show.speed); 14624 if (iL.items[vars.prev]) iL.loadContent(iL.items[vars.prev], 'prev', opts.show.speed); 14625 }, 14626 14627 generateThumbnails: function() { 14628 var iL = this, 14629 vars = iL.vars, 14630 opts = iL.options, 14631 timeOut = null; 14632 14633 if (vars.thumbs && !iL.vars.dontGenerateThumbs) { 14634 var thumbnails = vars.thumbnails, 14635 container = $('div.ilightbox-thumbnails-container', thumbnails), 14636 grid = $('div.ilightbox-thumbnails-grid', container), 14637 i = 0; 14638 14639 grid.removeAttr('style').empty(); 14640 14641 $.each(iL.items, function(key, val) { 14642 var isActive = (vars.current == key) ? 'ilightbox-active' : '', 14643 opacity = (vars.current == key) ? opts.thumbnails.activeOpacity : opts.thumbnails.normalOpacity, 14644 thumb = val.options.thumbnail, 14645 thumbnail = $('<div class="ilightbox-thumbnail"></div>'), 14646 icon = $('<div class="ilightbox-thumbnail-icon"></div>'); 14647 14648 thumbnail.css({ 14649 opacity: 0 14650 }).addClass(isActive); 14651 14652 if ((val.type == "video" || val.type == "flash") && typeof val.options.icon == 'undefined') { 14653 icon.addClass('ilightbox-thumbnail-video'); 14654 thumbnail.append(icon); 14655 } else if (val.options.icon) { 14656 icon.addClass('ilightbox-thumbnail-' + val.options.icon); 14657 thumbnail.append(icon); 14658 } 14659 14660 if (thumb) iL.loadImage(thumb, function(img) { 14661 i++; 14662 if (img) thumbnail.data({ 14663 naturalWidth: img.width, 14664 naturalHeight: img.height 14665 }).append('<img src="' + thumb + '" border="0" />'); 14666 else thumbnail.data({ 14667 naturalWidth: opts.thumbnails.maxWidth, 14668 naturalHeight: opts.thumbnails.maxHeight 14669 }); 14670 14671 clearTimeout(timeOut); 14672 timeOut = setTimeout(function() { 14673 iL.positionThumbnails(thumbnails, container, grid); 14674 }, 20); 14675 setTimeout(function() { 14676 thumbnail.fadeTo(opts.effects.loadedFadeSpeed, opacity); 14677 }, i * 20); 14678 }); 14679 14680 grid.append(thumbnail); 14681 }); 14682 iL.vars.dontGenerateThumbs = true; 14683 } 14684 }, 14685
14686 positionThumbnails: function(thumbnails, container, grid) { 14687 var iL = this, 14688 vars = iL.vars, 14689 opts = iL.options, 14690 viewport = getViewport(), 14691 path = opts.path.toLowerCase(); 14692 14693 if (!thumbnails) thumbnails = vars.thumbnails; 14694 if (!container) container = $('div.ilightbox-thumbnails-container', thumbnails); 14695 if (!grid) grid = $('div.ilightbox-thumbnails-grid', container); 14696 14697 var thumbs = $('.ilightbox-thumbnail', grid), 14698 widthAvail = (path == 'horizontal') ? viewport.width - opts.styles.pageOffsetX : thumbs.eq(0).outerWidth() - opts.styles.pageOffsetX, 14699 heightAvail = (path == 'horizontal') ? thumbs.eq(0).outerHeight() - opts.styles.pageOffsetY : viewport.height - opts.styles.pageOffsetY, 14700 gridWidth = (path == 'horizontal') ? 0 : widthAvail, 14701 gridHeight = (path == 'horizontal') ? heightAvail : 0, 14702 active = $('.ilightbox-active', grid), 14703 gridCss = {}, 14704 css = {}; 14705 14706 if (arguments.length < 3) { 14707 thumbs.css({ 14708 opacity: opts.thumbnails.normalOpacity 14709 }); 14710 active.css({ 14711 opacity: opts.thumbnails.activeOpacity 14712 }); 14713 } 14714 14715 thumbs.each(function(i) { 14716 var t = $(this), 14717 data = t.data(), 14718 width = (path == 'horizontal') ? 0 : opts.thumbnails.maxWidth; 14719 height = (path == 'horizontal') ? opts.thumbnails.maxHeight : 0; 14720 dims = iL.getNewDimenstions(width, height, data.naturalWidth, data.naturalHeight, true); 14721 14722 t.css({ 14723 width: dims.width, 14724 height: dims.height 14725 }); 14726 if (path == 'horizontal') t.css({ 14727 'float': 'left' 14728 }); 14729 14730 (path == 'horizontal') ? ( 14731 gridWidth += t.outerWidth() 14732 ) : ( 14733 gridHeight += t.outerHeight() 14734 ); 14735 }); 14736 14737 gridCss = { 14738 width: gridWidth, 14739 height: gridHeight 14740 }; 14741 14742 grid.css(gridCss); 14743 14744 gridCss = {}; 14745 14746 var gridOffset = grid.offset(), 14747 activeOffset = (active.length) ? active.offset() : { 14748 top: parseInt(heightAvail / 2), 14749 left: parseInt(widthAvail / 2) 14750 }; 14751 14752 gridOffset.top = (gridOffset.top - $doc.scrollTop()), 14753 gridOffset.left = (gridOffset.left - $doc.scrollLeft()), 14754 activeOffset.top = (activeOffset.top - gridOffset.top - $doc.scrollTop()), 14755 activeOffset.left = (activeOffset.left - gridOffset.left - $doc.scrollLeft()); 14756 14757 (path == 'horizontal') ? ( 14758 gridCss.top = 0, 14759 gridCss.left = parseInt((widthAvail / 2) - activeOffset.left - (active.outerWidth() / 2)) 14760 ) : ( 14761 gridCss.top = parseInt(((heightAvail / 2) - activeOffset.top - (active.outerHeight() / 2))), 14762 gridCss.left = 0 14763 ); 14764 14765 if (arguments.length < 3) grid.stop().animate(gridCss, opts.effects.repositionSpeed, 'easeOutCirc'); 14766 else grid.css(gridCss); 14767 }, 14768 14769 loadImage: function(image, callback) { 14770 if (!$.isArray(image)) image = [image]; 14771 14772 var iL = this, 14773 length = image.length; 14774 14775 if (length > 0) { 14776 iL.showLoader(); 14777 $.each(image, function(index, value) { 14778 var img = new Image(); 14779 img.onload = function() { 14780 length -= 1; 14781 if (length == 0) { 14782 iL.hideLoader(); 14783 callback(img); 14784 } 14785 }; 14786 img.onerror = img.onabort = function() { 14787 length -= 1; 14788 if (length == 0) { 14789 iL.hideLoader(); 14790 callback(false); 14791 } 14792 }; 14793 img.src = image[index]; 14794 }); 14795 } else callback(false); 14796 }, 14797 14798 patchItemsEvents: function() { 14799 var iL = this, 14800 vars = iL.vars, 14801 clickEvent = ishybrid ? "itap.iL click.iL" : supportTouch ? "itap.iL" : "click.iL", 14802 vEvent = ishybrid ? "click.iL itap.iL" : supportTouch ? "click.iL" : "itap.iL"; 14803 14804 if (iL.context && iL.selector) { 14805 var $items = $(iL.selector, iL.context); 14806 14807 $(iL.context).on(clickEvent, iL.selector, function() { 14808 var $this = $(this), 14809 //UNCODE addition 14810 key = typeof $(this).data('lb-index') !== '' && $(this).closest('.owl-item').length ? $(this).data('lb-index') : $items.index($this); 14811 if (UNCODE.isMobile) { 14812 var isCarousel = $this.closest('.owl-carousel'); 14813 if (isCarousel.length) { 14814 if (isCarousel.hasClass('owl-translating')) return false; 14815 } 14816 } 14817 14818 vars.current = key; 14819 vars.next = iL.items[key + 1] ? key + 1 : null; 14820 vars.prev = iL.items[key - 1] ? key - 1 : null; 14821 14822 //UNCODE addition 14823 if ( vars.BODY.hasClass('fp-slide-scrolling') ) 14824 return false;
14825 14826 iL.addContents(); 14827 iL.patchEvents(); 14828 14829 return false; 14830 }).on(vEvent, iL.selector, function() { 14831 return false; 14832 }); 14833 } else 14834 $.each(iL.itemsObject, function(key, val) { 14835 val.on(clickEvent, function() { 14836 vars.current = key; 14837 vars.next = iL.items[key + 1] ? key + 1 : null; 14838 vars.prev = iL.items[key - 1] ? key - 1 : null; 14839 14840 iL.addContents(); 14841 iL.patchEvents(); 14842 14843 return false; 14844 }).on(vEvent, function() { 14845 return false; 14846 }); 14847 }); 14848 }, 14849 14850 dispatchItemsEvents: function() { 14851 var iL = this, 14852 vars = iL.vars, 14853 opts = iL.options; 14854 14855 if (iL.context && iL.selector) 14856 $(iL.context).off('.iL', iL.selector); 14857 else 14858 $.each(iL.itemsObject, function(key, val) { 14859 val.off('.iL'); 14860 }); 14861 }, 14862 14863 refresh: function() { 14864 var iL = this; 14865 14866 iL.dispatchItemsEvents(); 14867 iL.attachItems(); 14868 iL.normalizeItems(); 14869 iL.patchItemsEvents(); 14870 }, 14871 14872 patchEvents: function() { 14873 var iL = this, 14874 vars = iL.vars, 14875 opts = iL.options, 14876 path = opts.path.toLowerCase(), 14877 holders = $('.ilightbox-holder'), 14878 fullscreenEvent = fullScreenApi.fullScreenEventName + '.iLightBox', 14879 durationThreshold = 1000, 14880 horizontalDistanceThreshold = 14881 verticalDistanceThreshold = 100, 14882 buttonsArray = [vars.nextButton[0], vars.prevButton[0], vars.nextButton[0].firstChild, vars.prevButton[0].firstChild]; 14883 14884 $win.bind('resize.iLightBox', function() { 14885 var viewport = getViewport(); 14886 14887 if (opts.mobileOptimizer && !opts.innerToolbar) vars.isMobile = viewport.width <= vars.mobileMaxWidth; 14888 vars.BODY[vars.isMobile ? 'addClass' : 'removeClass']('isMobile'); 14889 14890 iL.repositionPhoto(null); 14891 if (supportTouch) { 14892 clearTimeout(vars.setTime); 14893 vars.setTime = setTimeout(function() { 14894 var scrollTop = getScrollXY().y; 14895 window.scrollTo(0, scrollTop - 30); 14896 window.scrollTo(0, scrollTop + 30); 14897 window.scrollTo(0, scrollTop); 14898 }, 2000); 14899 } 14900 if (vars.thumbs) iL.positionThumbnails(); 14901 }).bind('keydown.iLightBox', function(event) { 14902 if (opts.controls.keyboard) { 14903 switch (event.keyCode) { 14904 case 13: 14905 if (event.shiftKey && opts.keyboard.shift_enter) iL.fullScreenAction(); 14906 break; 14907 case 27: 14908 if (opts.keyboard.esc) iL.closeAction(); 14909 break; 14910 case 37: 14911 if (opts.keyboard.left && !vars.lockKey) iL.moveTo('prev'); 14912 break; 14913 case 38: 14914 if (opts.keyboard.up && !vars.lockKey) iL.moveTo('prev'); 14915 break; 14916 case 39: 14917 if (opts.keyboard.right && !vars.lockKey) iL.moveTo('next'); 14918 break; 14919 case 40: 14920 if (opts.keyboard.down && !vars.lockKey) iL.moveTo('next'); 14921 break; 14922 } 14923 } 14924 }); 14925 14926 if (fullScreenApi.supportsFullScreen) $win.bind(fullscreenEvent, function() { 14927 iL.doFullscreen(); 14928 }); 14929 14930 var holderEventsArr = [opts.caption.show + '.iLightBox', opts.caption.hide + '.iLightBox', opts.social.show + '.iLightBox', opts.social.hide + '.iLightBox'].filter(function(e, i, arr) { 14931 return arr.lastIndexOf(e) === i; 14932 }), 14933 holderEvents = ""; 14934 14935 $.each(holderEventsArr, function(key, val) { 14936 if (key != 0) holderEvents += ' '; 14937 holderEvents += val; 14938 }); 14939 14940 $doc.on(clickEvent, '.ilightbox-overlay', function() { 14941 if (opts.overlay.blur) iL.closeAction(); 14942 }).on(clickEvent, '.ilightbox-next, .ilightbox-next-button', function() { 14943 iL.moveTo('next'); 14944 }).on(clickEvent, '.ilightbox-prev, .ilightbox-prev-button', function() { 14945 iL.moveTo('prev'); 14946 }).on(clickEvent, '.ilightbox-thumbnail', function() { 14947 var t = $(this), 14948 thumbs = $('.ilightbox-thumbnail', vars.thumbnails), 14949 index = thumbs.index(t); 14950 14951 if (index != vars.current) iL.goTo(index); 14952 }).on(holderEvents, '.ilightbox-holder:not(.ilightbox-next, .ilightbox-prev)', function(e) { 14953 var caption = $('div.ilightbox-caption', vars.holder), 14954 social = $('div.ilightbox-social', vars.holder), 14955 fadeSpeed = opts.effects.fadeSpeed; 14956 14957 if (vars.nextLock || vars.prevLock) { 14958 if (e.type == opts.caption.show && !caption.is(':visible')) caption.fadeIn(fadeSpeed); 14959 else if (e.type == opts.caption.hide && caption.is(':visible')) caption.fadeOut(fadeSpeed); 14960 14961 if (e.type == opts.social.show && !social.is(':visible')) social.fadeIn(fadeSpeed); 14962 else if (e.type == opts.social.hide && social.is(':visible')) social.fadeOut(fadeSpeed); 14963 } else { 14964 if (e.type == opts.caption.show && !caption.is(':visible')) caption.stop().fadeIn(fadeSpeed); 14965 else if (e.type == opts.caption.hide && caption.is(':visible')) caption.stop().fadeOut(fadeSpeed); 14966 14967 if (e.type == opts.social.show && !social.is(':visible')) social.stop().fadeIn(fadeSpeed); 14968 else if (e.type == opts.social.hide && social.is(':visible')) social.stop().fadeOut(fadeSpeed); 14969 } 14970 }).on('mouseenter.iLightBox mouseleave.iLightBox', '.ilightbox-wrapper', function(e) { 14971 if (e.type == 'mouseenter') vars.lockWheel = true; 14972 else vars.lockWheel = false;
14973 }).on(clickEvent, '.ilightbox-toolbar a.ilightbox-close, .ilightbox-toolbar a.ilightbox-fullscreen, .ilightbox-toolbar a.ilightbox-play, .ilightbox-toolbar a.ilightbox-pause', function() { 14974 var t = $(this); 14975 14976 if (t.hasClass('ilightbox-fullscreen')) iL.fullScreenAction(); 14977 else if (t.hasClass('ilightbox-play')) { 14978 iL.resume(); 14979 t.addClass('ilightbox-pause').removeClass('ilightbox-play'); 14980 } else if (t.hasClass('ilightbox-pause')) { 14981 iL.pause(); 14982 t.addClass('ilightbox-play').removeClass('ilightbox-pause'); 14983 } else iL.closeAction(); 14984 }).on(touchMoveEvent, '.ilightbox-overlay, .ilightbox-thumbnails-container', function(e) { 14985 // prevent scrolling 14986 e.preventDefault(); 14987 }); 14988 14989 function mouseMoveHandler(e) { 14990 if (!vars.isMobile) { 14991 if (!vars.mouseID) { 14992 vars.hideableElements.show(); 14993 } 14994 14995 vars.mouseID = clearTimeout(vars.mouseID); 14996 14997 if (buttonsArray.indexOf(e.target) === -1) 14998 vars.mouseID = setTimeout(function() { 14999 vars.hideableElements.hide(); 15000 vars.mouseID = clearTimeout(vars.mouseID); 15001 }, 3000); 15002 } 15003 } 15004 15005 if (opts.controls.arrows && !supportTouch) $doc.on('mousemove.iLightBox', mouseMoveHandler); 15006 15007 if (opts.controls.slideshow && opts.slideshow.pauseOnHover) $doc.on('mouseenter.iLightBox mouseleave.iLightBox', '.ilightbox-holder:not(.ilightbox-next, .ilightbox-prev)', function(e) { 15008 if (e.type == 'mouseenter' && vars.cycleID) iL.pause(); 15009 else if (e.type == 'mouseleave' && vars.isPaused) iL.resume(); 15010 }); 15011 15012 var switchers = $('.ilightbox-overlay, .ilightbox-holder, .ilightbox-thumbnails'), 15013 delay = false; 15014 15015 if (opts.controls.mousewheel) switchers.on('mousewheel.iLightBox', function(event, delta) { 15016 event.preventDefault(); 15017 if (delay) return; 15018 delay = true; 15019 if (!vars.lockWheel) { 15020 event.preventDefault(); 15021 if (delta < 0) { 15022 iL.moveTo('next'); 15023 } else if (delta > 0) { 15024 iL.moveTo('prev'); 15025 } 15026 } 15027 setTimeout(function(){
15028 delay = false; 15029 }, 2000); 15030 }); 15031 15032 if (opts.controls.swipe) holders.on(touchStartEvent, function(event) { 15033 if (vars.nextLock || vars.prevLock || vars.total == 1 || vars.lockSwipe) return; 15034 15035 vars.BODY.addClass('ilightbox-closedhand'); 15036 15037 var data = event.originalEvent.touches ? event.originalEvent.touches[0] : event, 15038 scrollTop = $doc.scrollTop(), 15039 scrollLeft = $doc.scrollLeft(), 15040 offsets = [ 15041 holders.eq(0).offset(), 15042 holders.eq(1).offset(), 15043 holders.eq(2).offset() 15044 ], 15045 offSet = [{ 15046 top: offsets[0].top - scrollTop, 15047 left: offsets[0].left - scrollLeft 15048 }, { 15049 top: offsets[1].top - scrollTop, 15050 left: offsets[1].left - scrollLeft 15051 }, { 15052 top: offsets[2].top - scrollTop, 15053 left: offsets[2].left - scrollLeft 15054 }], 15055 start = { 15056 time: (new Date()).getTime(), 15057 coords: [data.pageX - scrollLeft, data.pageY - scrollTop] 15058 }, 15059 stop; 15060 15061 function moveEachHandler(i) { 15062 var t = $(this), 15063 offset = offSet[i], 15064 scroll = [(start.coords[0] - stop.coords[0]), (start.coords[1] - stop.coords[1])]; 15065 15066 t[0].style[path == "horizontal" ? 'left' : 'top'] = (path == "horizontal" ? offset.left - scroll[0] : offset.top - scroll[1]) + 'px'; 15067 } 15068 15069 function moveHandler(event) { 15070 15071 if (!start) return; 15072 15073 var data = event.originalEvent.touches ? event.originalEvent.touches[0] : event; 15074 15075 stop = { 15076 time: (new Date()).getTime(), 15077 coords: [data.pageX - scrollLeft, data.pageY - scrollTop] 15078 }; 15079 15080 holders.each(moveEachHandler); 15081 15082 // prevent scrolling 15083 event.preventDefault(); 15084 } 15085 15086 function repositionHolders() { 15087 holders.each(function() { 15088 var t = $(this), 15089 offset = t.data('offset') || { 15090 top: t.offset().top - scrollTop, 15091 left: t.offset().left - scrollLeft 15092 }, 15093 top = offset.top, 15094 left = offset.left; 15095 15096 t.css(transform, gpuAcceleration).stop().animate({ 15097 top: top, 15098 left: left 15099 }, 500, 'easeOutCirc', function() { 15100 t.css(transform, ''); 15101 }); 15102 }); 15103 } 15104 15105 holders.bind(touchMoveEvent, moveHandler); 15106 $doc.one(touchStopEvent, function(event) { 15107 holders.unbind(touchMoveEvent, moveHandler); 15108 15109 vars.BODY.removeClass('ilightbox-closedhand'); 15110 15111 if (start && stop) { 15112 if (path == "horizontal" && stop.time - start.time < durationThreshold && abs(start.coords[0] - stop.coords[0]) > horizontalDistanceThreshold && abs(start.coords[1] - stop.coords[1]) < verticalDistanceThreshold) { 15113 if (start.coords[0] > stop.coords[0]) { 15114 if (vars.current == vars.total - 1 && !opts.infinite) repositionHolders(); 15115 else { 15116 vars.isSwipe = true; 15117 iL.moveTo('next'); 15118 } 15119 } else { 15120 if (vars.current == 0 && !opts.infinite) repositionHolders(); 15121 else { 15122 vars.isSwipe = true; 15123 iL.moveTo('prev'); 15124 } 15125 } 15126 } 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) { 15127 if (start.coords[1] > stop.coords[1]) { 15128 if (vars.current == vars.total - 1 && !opts.infinite) repositionHolders(); 15129 else { 15130 vars.isSwipe = true; 15131 iL.moveTo('next'); 15132 } 15133 } else { 15134 if (vars.current == 0 && !opts.infinite) repositionHolders(); 15135 else { 15136 vars.isSwipe = true; 15137 iL.moveTo('prev'); 15138 } 15139 } 15140 } else repositionHolders(); 15141 } 15142 start = stop = undefined; 15143 }); 15144 }); 15145 15146 }, 15147 15148 goTo: function(index) { 15149 var iL = this, 15150 vars = iL.vars, 15151 opts = iL.options, 15152 diff = (index - vars.current); 15153 15154 if (opts.infinite) { 15155 if (index == vars.total - 1 && vars.current == 0) diff = -1; 15156 if (vars.current == vars.total - 1 && index == 0) diff = 1; 15157 } 15158 15159 if (diff == 1) iL.moveTo('next'); 15160 else if (diff == -1) iL.moveTo('prev'); 15161 else { 15162 15163 if (vars.nextLock || vars.prevLock) return false; 15164 15165 //Trigger the onBeforeChange callback 15166 if (typeof opts.callback.onBeforeChange == 'function') opts.callback.onBeforeChange.call(iL, iL.ui); 15167 15168 if (opts.linkId) { 15169 vars.hashLock = true; 15170 window.location.hash = opts.linkId + '/' + index; 15171 } 15172 15173 if (iL.items[index]) { 15174 if (!iL.items[index].options.mousewheel) vars.lockWheel = true; 15175 else iL.vars.lockWheel = false;
15176 15177 if (!iL.items[index].options.swipe) vars.lockSwipe = true; 15178 else vars.lockSwipe = false; 15179 } 15180 15181 $.each([vars.holder, vars.nextPhoto, vars.prevPhoto], function(key, val) { 15182 val.css(transform, gpuAcceleration).fadeOut(opts.effects.loadedFadeSpeed); 15183 }); 15184 15185 vars.current = index; 15186 vars.next = index + 1; 15187 vars.prev = index - 1; 15188 15189 iL.createUI(); 15190 15191 setTimeout(function() { 15192 iL.generateBoxes(); 15193 }, opts.effects.loadedFadeSpeed + 50); 15194 15195 $('.ilightbox-thumbnail', vars.thumbnails).removeClass('ilightbox-active').eq(index).addClass('ilightbox-active'); 15196 iL.positionThumbnails(); 15197 15198 if (opts.linkId) setTimeout(function() { 15199 vars.hashLock = false; 15200 }, 55); 15201 15202 // Configure arrow buttons 15203 if (!opts.infinite) { 15204 vars.nextButton.add(vars.prevButton).add(vars.innerPrevButton).add(vars.innerNextButton).removeClass('disabled'); 15205 15206 if (vars.current == 0) { 15207 vars.prevButton.add(vars.innerPrevButton).addClass('disabled'); 15208 } 15209 if (vars.current >= vars.total - 1) { 15210 vars.nextButton.add(vars.innerNextButton).addClass('disabled'); 15211 } 15212 } 15213 15214 // Reset next cycle timeout 15215 iL.resetCycle(); 15216 15217 //Trigger the onAfterChange callback 15218 if (typeof opts.callback.onAfterChange == 'function') opts.callback.onAfterChange.call(iL, iL.ui); 15219 } 15220 }, 15221 15222 moveTo: function(side) { 15223 var iL = this, 15224 vars = iL.vars, 15225 opts = iL.options, 15226 path = opts.path.toLowerCase(), 15227 viewport = getViewport(), 15228 switchSpeed = opts.effects.switchSpeed; 15229 15230 if (vars.nextLock || vars.prevLock) return false; 15231 else { 15232 15233 var item = (side == "next") ? vars.next : vars.prev; 15234 15235 if (opts.linkId) { 15236 vars.hashLock = true; 15237 window.location.hash = opts.linkId + '/' + item; 15238 } 15239 15240 if (side == "next") { 15241 if (!iL.items[item]) return false; 15242 var firstHolder = vars.nextPhoto, 15243 secondHolder = vars.holder, 15244 lastHolder = vars.prevPhoto, 15245 firstClass = 'ilightbox-prev', 15246 secondClass = 'ilightbox-next'; 15247 } else if (side == "prev") { 15248 if (!iL.items[item]) return false; 15249 var firstHolder = vars.prevPhoto, 15250 secondHolder = vars.holder, 15251 lastHolder = vars.nextPhoto, 15252 firstClass = 'ilightbox-next', 15253 secondClass = 'ilightbox-prev'; 15254 } 15255 15256 //Trigger the onBeforeChange callback 15257 if (typeof opts.callback.onBeforeChange == 'function') 15258 opts.callback.onBeforeChange.call(iL, iL.ui); 15259 15260 (side == "next") ? vars.nextLock = true: vars.prevLock = true; 15261 15262 var captionFirst = $('div.ilightbox-caption', secondHolder), 15263 socialFirst = $('div.ilightbox-social', secondHolder); 15264 15265 if (captionFirst.length) 15266 captionFirst.stop().fadeOut(switchSpeed, function() { 15267 $(this).remove(); 15268 }); 15269 if (socialFirst.length) 15270 socialFirst.stop().fadeOut(switchSpeed, function() { 15271 $(this).remove(); 15272 }); 15273 15274 if (iL.items[item].caption) { 15275 iL.setCaption(iL.items[item], firstHolder); 15276 var caption = $('div.ilightbox-caption', firstHolder), 15277 percent = parseInt((caption.outerHeight() / firstHolder.outerHeight()) * 100); 15278 if (opts.caption.start && percent <= 50) caption.fadeIn(switchSpeed); 15279 } 15280 15281 var social = iL.items[item].options.social; 15282 if (social) { 15283 iL.setSocial(social, iL.items[item].URL, firstHolder); 15284 if (opts.social.start) $('div.ilightbox-social', firstHolder).fadeIn(opts.effects.fadeSpeed); 15285 } 15286 15287 $.each([firstHolder, secondHolder, lastHolder], function(key, val) { 15288 val.removeClass('ilightbox-next ilightbox-prev'); 15289 }); 15290 15291 var firstOffset = firstHolder.data('offset'), 15292 winW = (viewport.width - (opts.styles.pageOffsetX)), 15293 winH = (viewport.height - (opts.styles.pageOffsetY)), 15294 width = firstOffset.newDims.width, 15295 height = firstOffset.newDims.height, 15296 thumbsOffset = firstOffset.thumbsOffset, 15297 diff = firstOffset.diff, 15298 top = parseInt((winH / 2) - (height / 2) - diff.H - (thumbsOffset.H / 2)), 15299 left = parseInt((winW / 2) - (width / 2) - diff.W - (thumbsOffset.W / 2)); 15300 15301 var secondOffset = secondHolder.data('offset'), 15302 object = secondOffset.object; 15303 15304 /*if (object.item.caption && !isNaN(width) && !isNaN(height) && UNCODE.wwidth > UNCODE.mediaQuery) { 15305 var objRatio = width / height; 15306 height = height - vars.captionHeight; 15307 width = height * objRatio; 15308 top = path == 'horizontal' ? parseInt((winH / 2) - (height / 2) - diff.H - (thumbsOffset.H / 2)) : top, 15309 left = parseInt((winW / 2) - (width / 2) - diff.W - (thumbsOffset.W / 2)); 15310 }*/ 15311 15312 firstHolder.show().css(transform, gpuAcceleration).animate({ 15313 top: top, 15314 left: left, 15315 opacity: 1 15316 }, switchSpeed, (vars.isSwipe) ? 'easeOutCirc' : 'easeInOutCirc', function() { 15317 firstHolder.css(transform, ''); 15318 }); 15319 15320 $('div.ilightbox-container', firstHolder).animate({ 15321 width: width, 15322 height: height 15323 }, switchSpeed, (vars.isSwipe) ? 'easeOutCirc' : 'easeInOutCirc'); 15324 15325 diff = secondOffset.diff; 15326 15327 width = secondOffset.newDims.width, 15328 height = secondOffset.newDims.height; 15329 15330 width = parseInt(width * opts.styles[side == 'next' ? 'prevScale' : 'nextScale']), 15331 height = parseInt(height * opts.styles[side == 'next' ? 'prevScale' : 'nextScale']), 15332 top = (path == 'horizontal') ? parseInt((winH / 2) - object.offsetY - (height / 2) - diff.H - (thumbsOffset.H / 2)) : parseInt(winH - object.offsetX - diff.H - (thumbsOffset.H / 2)); 15333 15334 if (side == 'prev') 15335 left = (path == 'horizontal') ? parseInt(winW - object.offsetX - diff.W - (thumbsOffset.W / 2)) : parseInt((winW / 2) - (width / 2) - diff.W - object.offsetY - (thumbsOffset.W / 2)); 15336 else { 15337 top = (path == 'horizontal') ? top : parseInt(object.offsetX - diff.H - height - (thumbsOffset.H / 2)), 15338 left = (path == 'horizontal') ? parseInt(object.offsetX - diff.W - width - (thumbsOffset.W / 2)) : parseInt((winW / 2) - object.offsetY - (width / 2) - diff.W - (thumbsOffset.W / 2)); 15339 } 15340 15341 /*if (object.item.caption && !isNaN(width) && !isNaN(height) && UNCODE.wwidth > UNCODE.mediaQuery) { 15342 var objRatio = width / height; 15343 height = height - vars.captionHeight; 15344 width = height * objRatio; 15345 top = path == 'horizontal' ? parseInt((winH / 2) - (height / 2) - diff.H - (thumbsOffset.H / 2)) : top; 15346 }*/ 15347 15348 $('div.ilightbox-container', secondHolder).animate({ 15349 width: width, 15350 height: height 15351 }, switchSpeed, (vars.isSwipe) ? 'easeOutCirc' : 'easeInOutCirc'); 15352 15353 secondHolder.addClass(firstClass).css(transform, gpuAcceleration).animate({ 15354 top: top, 15355 left: left, 15356 opacity: opts.styles.prevOpacity, 15357 }, switchSpeed, (vars.isSwipe) ? 'easeOutCirc' : 'easeInOutCirc', function() { 15358 secondHolder.css(transform, ''); 15359
15360 $('.ilightbox-thumbnail', vars.thumbnails).removeClass('ilightbox-active').eq(item).addClass('ilightbox-active'); 15361 iL.positionThumbnails(); 15362 15363 if (iL.items[item]) { 15364 if (!iL.items[item].options.mousewheel) vars.lockWheel = true; 15365 else vars.lockWheel = false; 15366 15367 if (!iL.items[item].options.swipe) vars.lockSwipe = true; 15368 else vars.lockSwipe = false; 15369 } 15370 15371 vars.isSwipe = false; 15372 15373 // Remove iframe & video from previous slide 15374 if (['iframe', 'video'].indexOf(iL.items[vars.current].type) !== -1) { 15375 $('div.ilightbox-container', secondHolder).empty(); 15376 } 15377 15378 if (side == "next") { 15379 vars.nextPhoto = lastHolder, 15380 vars.prevPhoto = secondHolder, 15381 vars.holder = firstHolder; 15382 15383 vars.nextPhoto.hide(); 15384 15385 vars.next = vars.next + 1, 15386 vars.prev = vars.current, 15387 vars.current = vars.current + 1; 15388 15389 if (opts.infinite) { 15390 if (vars.current > vars.total - 1) vars.current = 0; 15391 if (vars.current == vars.total - 1) vars.next = 0; 15392 if (vars.current == 0) vars.prev = vars.total - 1; 15393 } 15394 15395 iL.createUI(); 15396 15397 if (!iL.items[vars.next]) 15398 vars.nextLock = false; 15399 else 15400 iL.loadContent(iL.items[vars.next], 'next'); 15401 } else { 15402 vars.prevPhoto = lastHolder; 15403 vars.nextPhoto = secondHolder; 15404 vars.holder = firstHolder; 15405 15406 vars.prevPhoto.hide(); 15407 15408 vars.next = vars.current; 15409 vars.current = vars.prev; 15410 vars.prev = vars.current - 1; 15411 15412 if (opts.infinite) { 15413 if (vars.current == vars.total - 1) vars.next = 0; 15414 if (vars.current == 0) vars.prev = vars.total - 1; 15415 } 15416 15417 iL.createUI(); 15418 15419 if (!iL.items[vars.prev]) 15420 vars.prevLock = false; 15421 else 15422 iL.loadContent(iL.items[vars.prev], 'prev'); 15423 } 15424 15425 // Add iframe & video content for current slide 15426 if (['iframe', 'video'].indexOf(iL.items[vars.current].type) !== -1) { 15427 iL.loadContent(iL.items[vars.current], 'current'); 15428 } 15429 15430 if (opts.linkId) setTimeout(function() { 15431 vars.hashLock = false; 15432 }, 55); 15433 15434 // Configure arrow buttons 15435 if (!opts.infinite) { 15436 vars.nextButton.add(vars.prevButton).add(vars.innerPrevButton).add(vars.innerNextButton).removeClass('disabled'); 15437 15438 if (vars.current == 0) 15439 vars.prevButton.add(vars.innerPrevButton).addClass('disabled'); 15440 if (vars.current >= vars.total - 1) 15441 vars.nextButton.add(vars.innerNextButton).addClass('disabled'); 15442 } 15443 15444 iL.repositionPhoto(); 15445 15446 // Reset next cycle timeout 15447 iL.resetCycle(); 15448 15449 //Trigger the onAfterChange callback 15450 if (typeof opts.callback.onAfterChange == 'function') 15451 opts.callback.onAfterChange.call(iL, iL.ui); 15452 }); 15453 15454 top = (path == 'horizontal') ? getPixel(lastHolder, 'top') : ((side == "next") ? parseInt(-(winH / 2) - lastHolder.outerHeight()) : parseInt(top * 2)), 15455 left = (path == 'horizontal') ? ((side == "next") ? parseInt(-(winW / 2) - lastHolder.outerWidth()) : parseInt(left * 2)) : getPixel(lastHolder, 'left'); 15456 15457 lastHolder.css(transform, gpuAcceleration).animate({ 15458 top: top, 15459 left: left, 15460 opacity: opts.styles.nextOpacity 15461 }, switchSpeed, (vars.isSwipe) ? 'easeOutCirc' : 'easeInOutCirc', function() { 15462 lastHolder.css(transform, ''); 15463 }).addClass(secondClass); 15464 } 15465 }, 15466 15467 setCaption: function(obj, target) { 15468 var iL = this, 15469 caption = $('<div class="ilightbox-caption"></div>'); 15470 15471 if (obj.caption) { 15472 caption.html(obj.caption); 15473 $('div.ilightbox-container', target).append(caption); 15474 } 15475 }, 15476 15477 normalizeSocial: function(obj, url) { 15478 var iL = this, 15479 vars = iL.vars, 15480 opts = iL.options, 15481 baseURL = window.location.href; 15482 15483 $.each(obj, function(key, value) { 15484 if (!value) 15485 return true; 15486 15487 var item = key.toLowerCase(), 15488 source, text; 15489 15490 switch (item) { 15491 case 'facebook': 15492 source = "http://www.facebook.com/share.php?v=4&src=bm&u={URL}", 15493 text = "Share on Facebook"; 15494 break; 15495 case 'twitter': 15496 source = "http://twitter.com/home?status={URL}", 15497 text = "Share on Twitter"; 15498 break; 15499 case 'digg': 15500 source = "http://digg.com/submit?phase=2&url={URL}", 15501 text = "Share on Digg"; 15502 break; 15503 case 'reddit': 15504 source = "http://reddit.com/submit?url={URL}", 15505 text = "Share on reddit"; 15506 break; 15507 } 15508 15509 obj[key] = { 15510 URL: value.URL && absolutizeURI(baseURL, value.URL) || opts.linkId && window.location.href || typeof url !== 'string' && baseURL || url && absolutizeURI(baseURL, url) || baseURL, 15511 source: value.source || source || value.URL && absolutizeURI(baseURL, value.URL) || url && absolutizeURI(baseURL, url), 15512 text: value.text || text || "Share on " + key, 15513 width: (typeof(value.width) != 'undefined' && !isNaN(value.width)) ? parseInt(value.width) : 640, 15514 height: value.height || 360 15515 }; 15516 15517 }); 15518 15519 return obj; 15520 }, 15521 15522 setSocial: function(obj, url, target) { 15523 var iL = this, 15524 socialBar = $('<div class="ilightbox-social"></div>'), 15525 buttons = '<ul>'; 15526 15527 obj = iL.normalizeSocial(obj, url); 15528 15529 $.each(obj, function(key, value) { 15530 var item = key.toLowerCase(), 15531 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, '+')); 15532 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>'; 15533 }); 15534 15535 buttons += '</ul>'; 15536 15537 socialBar.html(buttons); 15538 $('div.ilightbox-container', target).append(socialBar); 15539 }, 15540 15541 fullScreenAction: function() { 15542 var iL = this, 15543 vars = iL.vars; 15544 15545 if (fullScreenApi.supportsFullScreen) { 15546 if (fullScreenApi.isFullScreen()) fullScreenApi.cancelFullScreen(document.documentElement); 15547 else fullScreenApi.requestFullScreen(document.documentElement); 15548 } else { 15549 iL.doFullscreen(); 15550 } 15551 }, 15552 15553 doFullscreen: function() { 15554 var iL = this, 15555 vars = iL.vars, 15556 viewport = getViewport(), 15557 opts = iL.options; 15558 15559 if (opts.fullAlone) { 15560 var currentHolder = vars.holder, 15561 current = iL.items[vars.current], 15562 windowWidth = viewport.width, 15563 windowHeight = viewport.height, 15564 elements = [currentHolder, vars.nextPhoto, vars.prevPhoto, vars.nextButton, vars.prevButton, vars.overlay, vars.toolbar, vars.thumbnails, vars.loader], 15565 hideElements = [vars.nextPhoto, vars.prevPhoto, vars.nextButton, vars.prevButton, vars.loader, vars.thumbnails]; 15566 15567 if (!vars.isInFullScreen) { 15568 vars.isInFullScreen = vars.lockKey = vars.lockWheel = vars.lockSwipe = true; 15569 vars.overlay.css({ 15570 opacity: 1 15571 }); 15572 15573 $.each(hideElements, function(i, element) { 15574 element.hide(); 15575 }); 15576 15577 vars.fullScreenButton.attr('title', opts.text.exitFullscreen); 15578 15579 if (opts.fullStretchTypes.indexOf(current.type) != -1) currentHolder.data({
15580 naturalWidthOld: currentHolder.data('naturalWidth'), 15581 naturalHeightOld: currentHolder.data('naturalHeight'), 15582 naturalWidth: windowWidth, 15583 naturalHeight: windowHeight 15584 }); 15585 else { 15586 var viewport = current.options.fullViewPort || opts.fullViewPort || '', 15587 newWidth = windowWidth, 15588 newHeight = windowHeight, 15589 width = currentHolder.data('naturalWidth'), 15590 height = currentHolder.data('naturalHeight'); 15591 15592 if (viewport.toLowerCase() == 'fill') { 15593 newHeight = (newWidth / width) * height; 15594 15595 if (newHeight < windowHeight) { 15596 newWidth = (windowHeight / height) * width, 15597 newHeight = windowHeight; 15598 } 15599 } else if (viewport.toLowerCase() == 'fit') { 15600 var dims = iL.getNewDimenstions(newWidth, newHeight, width, height, true); 15601 15602 newWidth = dims.width, 15603 newHeight = dims.height; 15604 } else if (viewport.toLowerCase() == 'stretch') { 15605 newWidth = newWidth, 15606 newHeight = newHeight; 15607 } else { 15608 var scale = (width > newWidth || height > newHeight) ? true : false, 15609 dims = iL.getNewDimenstions(newWidth, newHeight, width, height, scale); 15610 newWidth = dims.width, 15611 newHeight = dims.height; 15612 } 15613 15614 currentHolder.data({ 15615 naturalWidthOld: currentHolder.data('naturalWidth'), 15616 naturalHeightOld: currentHolder.data('naturalHeight'), 15617 naturalWidth: newWidth, 15618 naturalHeight: newHeight 15619 }); 15620 } 15621 15622 $.each(elements, function(key, val) { 15623 val.addClass('ilightbox-fullscreen'); 15624 }); 15625 15626 //Trigger the onEnterFullScreen callback 15627 if (typeof opts.callback.onEnterFullScreen == 'function') opts.callback.onEnterFullScreen.call(iL, iL.ui); 15628 } else { 15629 vars.isInFullScreen = vars.lockKey = vars.lockWheel = vars.lockSwipe = false; 15630 vars.overlay.css({ 15631 opacity: iL.options.overlay.opacity 15632 }); 15633 15634 $.each(hideElements, function(i, element) { 15635 element.show(); 15636 }); 15637 15638 vars.fullScreenButton.attr('title', opts.text.enterFullscreen); 15639 15640 currentHolder.data({ 15641 naturalWidth: currentHolder.data('naturalWidthOld'), 15642 naturalHeight: currentHolder.data('naturalHeightOld'), 15643 naturalWidthOld: null, 15644 naturalHeightOld: null 15645 }); 15646 15647 $.each(elements, function(key, val) { 15648 val.removeClass('ilightbox-fullscreen'); 15649 }); 15650 15651 //Trigger the onExitFullScreen callback 15652 if (typeof opts.callback.onExitFullScreen == 'function') opts.callback.onExitFullScreen.call(iL, iL.ui); 15653 } 15654 } else { 15655 if (!vars.isInFullScreen) vars.isInFullScreen = true; 15656 else vars.isInFullScreen = false; 15657 } 15658 iL.repositionPhoto(true); 15659 }, 15660 15661 closeAction: function() { 15662 var iL = this, 15663 vars = iL.vars, 15664 opts = iL.options; 15665 15666 $win.unbind('.iLightBox'); 15667 $doc.off('.iLightBox'); 15668 15669 if (vars.isInFullScreen) fullScreenApi.cancelFullScreen(document.documentElement); 15670 15671 $('.ilightbox-overlay, .ilightbox-holder, .ilightbox-thumbnails').off('.iLightBox'); 15672 15673 if (opts.hide.effect) vars.overlay.stop().fadeOut(opts.hide.speed, function() { 15674 vars.overlay.remove(); 15675 vars.BODY.removeClass('ilightbox-noscroll').off('.iLightBox'); 15676 }); 15677 else { 15678 vars.overlay.remove(); 15679 vars.BODY.removeClass('ilightbox-noscroll').off('.iLightBox'); 15680 } 15681 15682 var fadeOuts = [vars.toolbar, vars.holder, vars.nextPhoto, vars.prevPhoto, vars.nextButton, vars.prevButton, vars.loader, vars.thumbnails]; 15683 15684 $.each(fadeOuts, function(i, element) { 15685 element.removeAttr('style').remove(); 15686 }); 15687 15688 vars.dontGenerateThumbs = vars.isInFullScreen = false; 15689 15690 window.iLightBox = null; 15691 15692 if (opts.linkId) { 15693 vars.hashLock = true; 15694 removeHash(); 15695 setTimeout(function() { 15696 vars.hashLock = false; 15697 }, 55); 15698 } 15699 15700 vars.nextButton.add(vars.prevButton).add(vars.innerPrevButton).add(vars.innerNextButton).removeClass('disabled'); 15701 15702 //Trigger the onHide callback 15703 if (typeof opts.callback.onHide == 'function') opts.callback.onHide.call(iL, iL.ui); 15704 }, 15705 15706 repositionPhoto: function() { 15707 var iL = this, 15708 vars = iL.vars, 15709 opts = iL.options, 15710 path = opts.path.toLowerCase(), 15711 viewport = getViewport(), 15712 winWidth = viewport.width, 15713 winHeight = viewport.height; 15714 15715 if (viewport.width < UNCODE.mediaQuery) opts.styles.nextOffsetX = 0; 15716 15717 var thumbsOffsetW = (vars.isInFullScreen && opts.fullAlone || vars.isMobile) ? 0 : ((path == 'horizontal') ? 0 : vars.thumbnails.outerWidth()), 15718 thumbsOffsetH = vars.isMobile ? vars.toolbar.outerHeight() : ((vars.isInFullScreen && opts.fullAlone) ? 0 : ((path == 'horizontal') ? vars.thumbnails.outerHeight() : 0)), 15719 width = (vars.isInFullScreen && opts.fullAlone) ? winWidth : (winWidth - (opts.styles.pageOffsetX)), 15720 height = (vars.isInFullScreen && opts.fullAlone) ? winHeight : (winHeight - (opts.styles.pageOffsetY)), 15721 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, 15722 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))); 15723 15724 var elObject = { 15725 type: 'current', 15726 width: width, 15727 height: height, 15728 item: iL.items[vars.current], 15729 offsetW: offsetW, 15730 offsetH: offsetH,
15731 thumbsOffsetW: thumbsOffsetW, 15732 thumbsOffsetH: thumbsOffsetH, 15733 animate: arguments.length, 15734 holder: vars.holder 15735 }; 15736 15737 iL.repositionEl(elObject); 15738 15739 if (iL.items[vars.next]) { 15740 elObject = $.extend(elObject, { 15741 type: 'next', 15742 item: iL.items[vars.next], 15743 offsetX: opts.styles.nextOffsetX, 15744 offsetY: opts.styles.nextOffsetY, 15745 holder: vars.nextPhoto 15746 }); 15747 15748 iL.repositionEl(elObject); 15749 } 15750 15751 if (iL.items[vars.prev]) { 15752 elObject = $.extend(elObject, { 15753 type: 'prev', 15754 item: iL.items[vars.prev], 15755 offsetX: opts.styles.nextOffsetX, 15756 offsetY: opts.styles.prevOffsetY, 15757 holder: vars.prevPhoto 15758 }); 15759 15760 iL.repositionEl(elObject); 15761 } 15762 15763 var loaderCss = (path == "horizontal") ? { 15764 left: parseInt((width / 2) - (vars.loader.outerWidth() / 2)) 15765 } : { 15766 top: parseInt((height / 2) - (vars.loader.outerHeight() / 2)) 15767 }; 15768 vars.loader.css(loaderCss); 15769 }, 15770 15771 repositionEl: function(obj) { 15772 var iL = this, 15773 vars = iL.vars, 15774 opts = iL.options, 15775 path = opts.path.toLowerCase(), 15776 widthAvail = (obj.type == 'current') ? ((vars.isInFullScreen && opts.fullAlone) ? obj.width : (obj.width - obj.offsetW)) : (obj.width - obj.offsetW), 15777 heightAvail = (obj.type == 'current') ? ((vars.isInFullScreen && opts.fullAlone) ? obj.height : (obj.height - obj.offsetH)) : (obj.height - obj.offsetH), 15778 itemParent = obj.item, 15779 item = obj.item.options, 15780 holder = obj.holder, 15781 offsetX = obj.offsetX || 0, 15782 offsetY = obj.offsetY || 0, 15783 //Uncode change ##START## 15784 toolbarHeight = $('.ilightbox-inner-toolbar', holder).length ? parseInt( $('.ilightbox-inner-toolbar', holder).outerHeight() ) : 0, 15785 //Uncode change ##END## 15786 thumbsOffsetW = obj.thumbsOffsetW, 15787 thumbsOffsetH = obj.thumbsOffsetH; 15788 15789 if (obj.type == 'current') { 15790 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); 15791 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); 15792 } else { 15793 if (typeof item.width == 'number' && item.width) widthAvail = (item.width > widthAvail) ? widthAvail : item.width; 15794 if (typeof item.height == 'number' && item.height) heightAvail = (item.height > heightAvail) ? heightAvail : item.height; 15795 } 15796 15797 15798 //Uncode change ##START## 15799 heightAvail = parseInt(heightAvail - toolbarHeight); 15800 // heightAvail = parseInt(heightAvail - $('.ilightbox-inner-toolbar', holder).outerHeight()); 15801 //Uncode change ##END## 15802 15803 var width = (typeof item.width == 'string' && item.width.indexOf('%') != -1) ? percentToValue(parseInt(item.width.replace('%', '')), obj.width) : holder.data('naturalWidth'), 15804 height = (typeof item.height == 'string' && item.height.indexOf('%') != -1) ? percentToValue(parseInt(item.height.replace('%', '')), obj.height) : holder.data('naturalHeight'); 15805 15806 var dims = ((typeof item.width == 'string' && item.width.indexOf('%') != -1 || typeof item.height == 'string' && item.height.indexOf('%') != -1) ? { 15807 width: width, 15808 height: height 15809 } : iL.getNewDimenstions(widthAvail, heightAvail, width, height)), 15810 newDims = $.extend({}, dims, {}); 15811 15812 if (obj.type == 'prev' || obj.type == 'next') 15813 width = parseInt(dims.width * ((obj.type == 'next') ? opts.styles.nextScale : opts.styles.prevScale)), 15814 height = parseInt(dims.height * ((obj.type == 'next') ? opts.styles.nextScale : opts.styles.prevScale)); 15815 else 15816 width = dims.width, 15817 height = dims.height; 15818 15819 var widthDiff = parseInt((getPixel(holder, 'padding-left') + getPixel(holder, 'padding-right') + getPixel(holder, 'border-left-width') + getPixel(holder, 'border-right-width')) / 2), 15820 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); 15821 15822 switch (obj.type) { 15823 case 'current': 15824 var top = parseInt((obj.height / 2) - (height / 2) - heightDiff - (thumbsOffsetH / 2)), 15825 left = parseInt((obj.width / 2) - (width / 2) - widthDiff - (thumbsOffsetW / 2)); 15826 break; 15827
15828 case 'next': 15829 var top = (path == 'horizontal') ? parseInt((obj.height / 2) - offsetY - (height / 2) - heightDiff - (thumbsOffsetH / 2)) : parseInt(obj.height - offsetX - heightDiff - (thumbsOffsetH / 2)), 15830 left = (path == 'horizontal') ? parseInt(obj.width - offsetX - widthDiff - (thumbsOffsetW / 2)) : parseInt((obj.width / 2) - (width / 2) - widthDiff - offsetY - (thumbsOffsetW / 2)); 15831 break; 15832 15833 case 'prev': 15834 var top = (path == 'horizontal') ? parseInt((obj.height / 2) - offsetY - (height / 2) - heightDiff - (thumbsOffsetH / 2)) : parseInt(offsetX - heightDiff - height - (thumbsOffsetH / 2)), 15835 left = (path == 'horizontal') ? parseInt(offsetX - widthDiff - width - (thumbsOffsetW / 2)) : parseInt((obj.width / 2) - offsetY - (width / 2) - widthDiff - (thumbsOffsetW / 2)); 15836 break; 15837 } 15838 15839 holder.data('offset', { 15840 top: top, 15841 left: left, 15842 newDims: newDims, 15843 diff: { 15844 W: widthDiff, 15845 H: heightDiff 15846 }, 15847 thumbsOffset: { 15848 W: thumbsOffsetW, 15849 H: thumbsOffsetH 15850 }, 15851 object: obj 15852 }); 15853 15854 var opacityMobile; 15855 if ( isMobile ) { 15856 opacityMobile = { 15857 opacity: 1, 15858 top: top, 15859 left: left 15860 }; 15861 } else { 15862 opacityMobile = { 15863 top: top, 15864 left: left 15865 }; 15866 } 15867 15868 if (obj.animate > 0 && opts.effects.reposition) { 15869 holder.css(transform, gpuAcceleration).stop().animate( 15870 opacityMobile, 15871 opts.effects.repositionSpeed, 'easeOutCirc', function() { 15872 holder.css(transform, ''); 15873 }); 15874 $('div.ilightbox-container', holder).stop().animate({ 15875 width: width, 15876 height: height 15877 }, opts.effects.repositionSpeed, 'easeOutCirc'); 15878 $('div.ilightbox-inner-toolbar', holder).stop().animate({ 15879 width: width 15880 }, opts.effects.repositionSpeed, 'easeOutCirc', function() { 15881 $(this).css('overflow', 'visible'); 15882 }); 15883 } else { 15884 holder.css(opacityMobile); 15885 $('div.ilightbox-container', holder).css({ 15886 width: width, 15887 height: height 15888 }); 15889 $('div.ilightbox-inner-toolbar', holder).css({ 15890 width: width 15891 }); 15892 } 15893 }, 15894 15895 15896 resume: function(priority) { 15897 var iL = this, 15898 vars = iL.vars, 15899 opts = iL.options; 15900 15901 if (!opts.slideshow.pauseTime || opts.controls.slideshow && vars.total <= 1 || priority < vars.isPaused) { 15902 return; 15903 } 15904 15905 vars.isPaused = 0; 15906 15907 if (vars.cycleID) { 15908 vars.cycleID = clearTimeout(vars.cycleID); 15909 } 15910 15911 vars.cycleID = setTimeout(function() { 15912 if (vars.current == vars.total - 1) iL.goTo(0); 15913 else iL.moveTo('next'); 15914 }, opts.slideshow.pauseTime); 15915 }, 15916 15917 pause: function(priority) { 15918 var iL = this, 15919 vars = iL.vars, 15920 opts = iL.options; 15921 15922 if (priority < vars.isPaused) { 15923 return; 15924 } 15925 15926 vars.isPaused = priority || 100; 15927 15928 if (vars.cycleID) { 15929 vars.cycleID = clearTimeout(vars.cycleID); 15930 } 15931 }, 15932 15933 resetCycle: function() { 15934 var iL = this, 15935 vars = iL.vars, 15936 opts = iL.options; 15937 15938 if (opts.controls.slideshow && vars.cycleID && !vars.isPaused) { 15939 iL.resume(); 15940 } 15941 }, 15942 15943 getNewDimenstions: function(width, height, width_old, height_old, thumb) { 15944 var iL = this; 15945 15946 if (!width) factor = height / height_old; 15947 else if (!height) factor = width / width_old; 15948 else factor = min(width / width_old, height / height_old); 15949 15950 if (!thumb) { 15951 if (factor > iL.options.maxScale) factor = iL.options.maxScale; 15952 else if (factor < iL.options.minScale) factor = iL.options.minScale; 15953 } 15954 15955 var final_width = (iL.options.keepAspectRatio) ? round(width_old * factor) : width, 15956 final_height = (iL.options.keepAspectRatio) ? round(height_old * factor) : height; 15957 15958 return { 15959 width: final_width, 15960 height: final_height, 15961 ratio: factor 15962 }; 15963 }, 15964 15965 setOption: function(options) { 15966 var iL = this; 15967 15968 iL.options = $.extend(true, iL.options, options || {}); 15969 iL.refresh(); 15970 }, 15971 15972 availPlugins: function() { 15973 var iL = this, 15974 testEl = document.createElement("video"); 15975 15976 iL.plugins = { 15977 flash: !isMobile, 15978 quicktime: (parseInt(PluginDetect.getVersion("QuickTime")) >= 0) ? true : false, 15979 html5H264: !!(testEl.canPlayType && testEl.canPlayType('video/mp4').replace(/no/, '')), 15980 html5WebM: !!(testEl.canPlayType && testEl.canPlayType('video/webm').replace(/no/, '')), 15981 html5Vorbis: !!(testEl.canPlayType && testEl.canPlayType('video/ogg').replace(/no/, '')), 15982 html5QuickTime: !!(testEl.canPlayType && testEl.canPlayType('video/quicktime').replace(/no/, '')) 15983 }; 15984 }, 15985 15986 addContent: function(element, obj) { 15987 var iL = this, 15988 el; 15989 15990 switch (obj.type) { 15991 case 'video': 15992 var HTML5 = false, 15993 videoType = obj.videoType, 15994 html5video = obj.options.html5video; 15995 15996 if (((videoType == 'video/mp4' || obj.ext == 'mp4' || obj.ext == 'm4v') || html5video.h264) && iL.plugins.html5H264) 15997 obj.ext = 'mp4', 15998 obj.URL = html5video.h264 || obj.URL; 15999 else if (html5video.webm && iL.plugins.html5WebM) 16000 obj.ext = 'webm', 16001 obj.URL = html5video.webm || obj.URL; 16002 else if (html5video.ogg && iL.plugins.html5Vorbis) 16003 obj.ext = 'ogv', 16004 obj.URL = html5video.ogg || obj.URL; 16005 16006 if (iL.plugins.html5H264 && (videoType == 'video/mp4' || obj.ext == 'mp4' || obj.ext == 'm4v')) HTML5 = true, videoType = "video/mp4"; 16007 else if (iL.plugins.html5WebM && (videoType == 'video/webm' || obj.ext == 'webm')) HTML5 = true, videoType = "video/webm"; 16008 else if (iL.plugins.html5Vorbis && (videoType == 'video/ogg' || obj.ext == 'ogv')) HTML5 = true, videoType = "video/ogg"; 16009 else if (iL.plugins.html5QuickTime && (videoType == 'video/quicktime' || obj.ext == 'mov' || obj.ext == 'qt')) HTML5 = true, videoType = "video/quicktime"; 16010 16011 if (HTML5) { 16012 el = $('<video />
16012', { 16013 "width": "100%", 16014 "height": "100%", 16015 "preload": html5video.preload, 16016 "autoplay": html5video.autoplay, 16017 "loop": html5video.loop, 16018 "poster": html5video.poster, 16019 "controls": html5video.controls, 16020 "controlslist": "nodownload" 16021 }).append($('<source />', { 16022 "src": obj.URL, 16023 "type": videoType 16024 })); 16025 } else { 16026 if (!iL.plugins.quicktime) el = $('<span />', { 16027 "class": "ilightbox-alert", 16028 html: iL.options.errors.missingPlugin.replace('{pluginspage}', pluginspages.quicktime).replace('{type}', 'QuickTime') 16029 }); 16030 else { 16031 16032 el = $('<object />', { 16033 "type": "video/quicktime", 16034 "pluginspage": pluginspages.quicktime 16035 }).attr({ 16036 "data": obj.URL, 16037 "width": "100%", 16038 "height": "100%" 16039 }).append($('<param />', { 16040 "name": "src", 16041 "value": obj.URL 16042 })).append($('<param />', { 16043 "name": "autoplay", 16044 "value": "false" 16045 })).append($('<param />', { 16046 "name": "loop", 16047 "value": "false" 16048 })).append($('<param />', { 16049 "name": "scale", 16050 "value": "tofit" 16051 })); 16052 16053 if (browser.msie) el = QT_GenerateOBJECTText(obj.URL, '100%', '100%', '', 'SCALE', 'tofit', 'AUTOPLAY', 'false', 'LOOP', 'false'); 16054 } 16055 } 16056 16057 break; 16058 16059 case 'flash': 16060 if (!iL.plugins.flash) el = $('<span />', { 16061 "class": "ilightbox-alert", 16062 html: iL.options.errors.missingPlugin.replace('{pluginspage}', pluginspages.flash).replace('{type}', 'Adobe Flash player') 16063 }); 16064 else { 16065 var flashvars = "", 16066 i = 0; 16067 16068 if (obj.options.flashvars) $.each(obj.options.flashvars, function(k, v) { 16069 if (i != 0) flashvars += "&"; 16070 flashvars += k + "=" + encodeURIComponent(v); 16071 i++; 16072 }); 16073 else flashvars = null; 16074 16075 el = $('<embed />').attr({ 16076 "type": "application/x-shockwave-flash", 16077 "src": obj.URL, 16078 "width": (typeof obj.options.width == 'number' && obj.options.width && iL.options.minScale == '1' && iL.options.maxScale == '1') ? obj.options.width : "100%", 16079 "height": (typeof obj.options.height == 'number' && obj.options.height && iL.options.minScale == '1' && iL.options.maxScale == '1') ? obj.options.height : "100%", 16080 "quality": "high", 16081 "bgcolor": "#000000", 16082 "play": "true", 16083 "loop": "true", 16084 "menu": "true", 16085 "wmode": "transparent", 16086 "scale": "showall", 16087 "allowScriptAccess": "always", 16088 "allowFullScreen": "true", 16089 "flashvars": flashvars, 16090 "fullscreen": "yes" 16091 }); 16092 } 16093 16094 break; 16095 16096 case 'iframe': 16097 el = $('<iframe />').attr({ 16098 "width": (typeof obj.options.width == 'number' && obj.options.width && iL.options.minScale == '1' && iL.options.maxScale == '1') ? obj.options.width : "100%", 16099 "height": (typeof obj.options.height == 'number' && obj.options.height && iL.options.minScale == '1' && iL.options.maxScale == '1') ? obj.options.height : "100%", 16100 src: obj.URL, 16101 frameborder: 0, 16102 'hspace': 0, 16103 'vspace': 0, 16104 'scrolling': supportTouch ? 'auto' : 'scroll', 16105 'webkitAllowFullScreen': '', 16106 'mozallowfullscreen': '', 16107 'allowFullScreen': '' 16108 }); 16109 16110 break; 16111 16112 case 'inline': 16113 el = $('<div class="ilightbox-wrapper"></div>').html($(obj.URL).clone(true)); 16114 16115 break; 16116 16117 case 'html': 16118 var object = obj.URL, 16119 el; 16120 16121 if (object[0].nodeName) { 16122 el = $('<div class="ilightbox-wrapper"></div>').html(object); 16123 } else { 16124 var dom = $(obj.URL), 16125 html = (dom.selector) ? $('<div>' + dom + '</div>') : dom; 16126 el = $('<div class="ilightbox-wrapper"></div>').html(html); 16127 } 16128 16129 break; 16130 } 16131 16132 $('div.ilightbox-container', element).empty().html(el); 16133 16134 // For fixing Chrome about just playing the video for first time 16135 if (el[0].tagName.toLowerCase() === 'video' && browser.webkit) setTimeout(function() { 16136 var src = el[0].currentSrc + '?' + floor(random() * 30000); 16137 el[0].currentSrc = src; 16138 el[0].src = src; 16139 }); 16140 16141 return el; 16142 }, 16143 16144 ogpRecognition: function(obj, callback) { 16145 var iL = this, 16146 url = obj.URL; 16147 16148 iL.showLoader(); 16149 doAjax(url, function(data) { 16150 iL.hideLoader(); 16151 if (data) { 16152 var object = new Object(); 16153 16154 object.length = false, 16155 object.url = data.url; 16156 16157 if (data.status == 200) { 16158 var result = data.results, 16159 type = result.type, 16160 source = result.source; 16161 16162 object.source = source.src, 16163 object.width = source.width && parseInt(source.width) || 0, 16164 object.height = source.height && parseInt(source.height) || 0, 16165 object.type = type, 16166 object.thumbnail = source.thumbnail || result.images && result.images[0], 16167 object.html5video = result.html5video || {}, 16168 object.length = true; 16169 16170 if (source.type == 'application/x-shockwave-flash') object.type = "flash"; 16171 else if (source.type.indexOf("video/") != -1) object.type = "video"; 16172 else if (source.type.indexOf("/html") != -1) object.type = "iframe"; 16173 else if (source.type.indexOf("image/") != -1) object.type = "image"; 16174 16175 } else if (typeof data.response != 'undefined') 16176 throw data.response; 16177 16178 callback.call(this, object.length ? object : false); 16179 } 16180 }); 16181 }, 16182 16183 hashChangeHandler: function(url) { 16184 var iL = this, 16185 vars = iL.vars, 16186 opts = iL.options, 16187 URL = url || window.location.href, 16188 hash = parseURI(URL).hash, 16189 split = hash.split('/'), 16190 index = split[1]; 16191 16192 if (vars.hashLock || ('#' + opts.linkId != split[0] && hash.length > 1)) return; 16193 16194 if (index) { 16195 var target = split[1] || 0; 16196 if (iL.items[target]) {
16197 var overlay = $('.ilightbox-overlay'); 16198 if (overlay.length && overlay.attr('linkid') == opts.linkId) { 16199 iL.goTo(target); 16200 } else { 16201 iL.itemsObject[target].trigger(ishybrid ? "itap click" : supportTouch ? 'itap' : 'click'); 16202 //iL.goTo(target); 16203 } 16204 } else { 16205 var overlay = $('.ilightbox-overlay'); 16206 if (overlay.length) iL.closeAction(); 16207 } 16208 } else { 16209 var overlay = $('.ilightbox-overlay'); 16210 if (overlay.length) iL.closeAction(); 16211 } 16212 } 16213 }; 16214 16215 /** 16216 * Parse style to pixels. 16217 * 16218 * @param {Object} $element jQuery object with element. 16219 * @param {Property} property CSS property to get the pixels from. 16220 * 16221 * @return {Int} 16222 */ 16223 function getPixel($element, property) { 16224 return parseInt($element.css(property), 10) || 0; 16225 } 16226 16227 /** 16228 * Make sure that number is within the limits. 16229 * 16230 * @param {Number} number 16231 * @param {Number} min 16232 * @param {Number} max 16233 * 16234 * @return {Number} 16235 */ 16236 function within(number, min, max) { 16237 return number < min ? min : number > max ? max : number; 16238 } 16239 16240 /** 16241 * Get viewport/window size (width and height). 16242 * 16243 * @return {Object} 16244 */ 16245 function getViewport() { 16246 var e = window, 16247 a = 'inner'; 16248 if (!('innerWidth' in window)) { 16249 a = 'client'; 16250 e = document.documentElement || document.body; 16251 } 16252 return { 16253 width: e[a + 'Width'], 16254 height: e[a + 'Height'] 16255 } 16256 } 16257 16258 /** 16259 * Remove hash tag from the URL 16260 * 16261 * @return {Void} 16262 */ 16263 function removeHash() { 16264 var scroll = getScrollXY(); 16265 16266 //UNCODE change 16267 // window.location.hash = ""; 16268 // history.pushState("", document.title, window.location.pathname + window.location.search); 16269 history.replaceState({}, document.title, window.location.pathname + window.location.search); 16270 16271 // Restore the scroll offset, should be flicker free 16272 window.scrollTo(scroll.x, scroll.y); 16273 } 16274 16275 /** 16276 * Do the ajax requests with callback. 16277 * 16278 * @param {String} url 16279 * @param {Function} callback 16280 * 16281 * @return {Void} 16282 */ 16283 function doAjax(url, callback) { 16284 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'); 16285 $.ajax({ 16286 url: url, 16287 dataType: 'jsonp' 16288 }); 16289 16290 iLCallback = function(data) { 16291 callback.call(this, data); 16292 }; 16293 } 16294 16295 /** 16296 * Find image from DOM elements 16297 * 16298 * @param {Element} element 16299 * 16300 * @return {Void} 16301 */ 16302 function findImageInElement(element) { 16303 var elements = $('*', element), 16304 imagesArr = new Array(); 16305 16306 elements.each(function() { 16307 var url = "", 16308 element = this; 16309 16310 if ($(element).css("background-image") != "none") { 16311 url = $(element).css("background-image"); 16312 } else if (typeof($(element).attr("src")) != "undefined" && element.nodeName.toLowerCase() == "img") { 16313 url = $(element).attr("src"); 16314 } 16315 16316 if (url.indexOf("gradient") == -1) { 16317 url = url.replace(/url\(\"/g, ""); 16318 url = url.replace(/url\(/g, ""); 16319 url = url.replace(/\"\)/g, ""); 16320 url = url.replace(/\)/g, ""); 16321 16322 var urls = url.split(","); 16323 16324 for (var i = 0; i < urls.length; i++) { 16325 if (urls[i].length > 0 && $.inArray(urls[i], imagesArr) == -1) { 16326 var extra = ""; 16327 if (browser.msie && browser.version < 9) { 16328 extra = "?" + floor(random() * 3000); 16329 } 16330 imagesArr.push(urls[i] + extra); 16331 } 16332 } 16333 } 16334 }); 16335 16336 return imagesArr; 16337 } 16338 16339 /** 16340 * Get file extension. 16341 * 16342 * @param {String} URL 16343 * 16344 * @return {String} 16345 */ 16346 function getExtension(URL) { 16347 if (URL !== null) { 16348 //UNCODE: fix issue to detect media type with query strings 16349 var ext = URL.indexOf('?') !== -1 ? URL.split('?')[0] : URL; 16350 ext = ext.split('.').pop().toLowerCase(); 16351 16352 return ext; 16353 } 16354 } 16355 16356 /** 16357 * Get type via extension. 16358 * 16359 * @param {String} URL 16360 * 16361 * @return {String} 16362 */ 16363 function getTypeByExtension(URL) { 16364 var type, 16365 ext = getExtension(URL); 16366 16367 //Uncode addition ##START## 16368 if (URL == undefined) { 16369 return false; 16370 } 16371 //Uncode addition ##END## 16372 16373 if (extensions.image.indexOf(ext) !== -1) type = 'image'; 16374 else if (extensions.flash.indexOf(ext) !== -1) type = 'flash'; 16375 else if (extensions.video.indexOf(ext) !== -1) type = 'video'; 16376 else if (ext.substring(0, 1) == "#") type = 'inline'; //Uncode addition 16377 else type = 'iframe'; 16378 16379 return type; 16380 } 16381 16382 /** 16383 * Return value from percent of a number. 16384 * 16385 * @param {Number} percent 16386 * @param {Number} total 16387 * 16388 * @return {Number} 16389 */ 16390 function percentToValue(percent, total) { 16391 return parseInt((total / 100) * percent); 16392 } 16393 16394 /** 16395 * A JavaScript equivalent of PHPâs parse_url. 16396 * 16397 * @param {String} url The URL to parse. 16398 * 16399 * @return {Mixed} 16400 */ 16401 function parseURI(url) { 16402 var m = String(url).replace(/^\s+|\s+$/g, '').match(/^([^:\/?#]+:)?(\/\/(?:[^:@]*(?::[^:@]*)?@)?(([^:\/?#]*)(?::(\d*))?))?([^?#]*)(\?[^#]*)?(#[\s\S]*)?/); 16403 // authority = '//' + user + ':' + pass '@' + hostname + ':' port 16404 return (m ? { 16405 href: m[0] || '', 16406 protocol: m[1] || '', 16407 authority: m[2] || '', 16408 host: m[3] || '', 16409 hostname: m[4] || '', 16410 port: m[5] || '', 16411 pathname: m[6] || '', 16412 search: m[7] || '', 16413 hash: m[8] || '' 16414 } : null); 16415 } 16416 16417 /** 16418 * Gets the absolute URI. 16419 * 16420 * @param {String} href The relative URL. 16421 * @param {String} base The base URL. 16422 * 16423 * @return {String} The absolute URL. 16424 */ 16425 function absolutizeURI(base, href) { // RFC 3986 16426 var iL = this; 16427 16428 function removeDotSegments(input) { 16429 var output = []; 16430 input.replace(/^(\.\.?(\/|$))+/, '') 16431 .replace(/\/(\.(\/|$))+/g, '/') 16432 .replace(/\/\.\.$/, '/../') 16433 .replace(/\/?[^\/]*/g, function(p) { 16434 if (p === '/..') { 16435 output.pop(); 16436 } else { 16437 output.push(p); 16438 } 16439 }); 16440 return output.join('').replace(/^\//, input.charAt(0) === '/' ? '/' : ''); 16441 } 16442 16443 href = parseURI(href || ''); 16444 base = parseURI(base || ''); 16445 16446 return !href || !base ? null : (href.protocol || base.protocol) + 16447 (href.protocol || href.authority ? href.authority : base.authority) + 16448 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)) + 16449 (href.protocol || href.authority || href.pathname ? href.search : (href.search || base.search)) + 16450 href.hash; 16451 } 16452 16453 /** 16454 * A JavaScript equivalent of PHPâs version_compare. 16455 * 16456 * @param {String} v1 16457 * @param {String} v2 16458 * @param {String} operator
16459 * 16460 * @return {Boolean} 16461 */ 16462 function version_compare(v1, v2, operator) { 16463 this.php_js = this.php_js || {}; 16464 this.php_js.ENV = this.php_js.ENV || {}; 16465 var i = 0, 16466 x = 0, 16467 compare = 0, 16468 vm = { 16469 'dev': -6, 16470 'alpha': -5, 16471 'a': -5, 16472 'beta': -4, 16473 'b': -4, 16474 'RC': -3, 16475 'rc': -3, 16476 '#': -2, 16477 'p': 1, 16478 'pl': 1 16479 }, 16480 prepVersion = function(v) { 16481 v = ('' + v).replace(/[_\-+]/g, '.'); 16482 v = v.replace(/([^.\d]+)/g, '.$1.').replace(/\.{2,}/g, '.'); 16483 return (!v.length ? [-8] : v.split('.')); 16484 }, 16485 numVersion = function(v) { 16486 return !v ? 0 : (isNaN(v) ? vm[v] || -7 : parseInt(v, 10)); 16487 }; 16488 v1 = prepVersion(v1); 16489 v2 = prepVersion(v2); 16490 x = max(v1.length, v2.length); 16491 for (i = 0; i < x; i++) { 16492 if (v1[i] == v2[i]) { 16493 continue; 16494 } 16495 v1[i] = numVersion(v1[i]); 16496 v2[i] = numVersion(v2[i]); 16497 if (v1[i] < v2[i]) { 16498 compare = -1; 16499 break; 16500 } else if (v1[i] > v2[i]) { 16501 compare = 1; 16502 break; 16503 } 16504 } 16505 if (!operator) { 16506 return compare; 16507 } 16508 16509 switch (operator) { 16510 case '>': 16511 case 'gt': 16512 return (compare > 0); 16513 case '>=': 16514 case 'ge': 16515 return (compare >= 0); 16516 case '<=': 16517 case 'le': 16518 return (compare <= 0); 16519 case '==': 16520 case '=': 16521 case 'eq': 16522 return (compare === 0); 16523 case '<>': 16524 case '!=': 16525 case 'ne': 16526 return (compare !== 0); 16527 case '': 16528 case '<': 16529 case 'lt': 16530 return (compare < 0); 16531 default: 16532 return null; 16533 } 16534 } 16535 16536 16537 // Begin the iLightBox plugin 16538 $.fn.iLightBox = function() { 16539 16540 var args = arguments, 16541 opt = ($.isPlainObject(args[0])) ? args[0] : args[1], 16542 items = ($.isArray(args[0]) || typeof args[0] == 'string') ? args[0] : args[1]; 16543 16544 if (!opt) opt = {}; 16545 16546 // Default options. Play carefully. 16547 var options = $.extend(true, { 16548 attr: 'href', 16549 path: 'vertical', 16550 skin: 'dark', 16551 linkId: false, 16552 infinite: false, 16553 startFrom: 0, 16554 randomStart: false, 16555 keepAspectRatio: true, 16556 maxScale: 1, 16557 minScale: .2, 16558 innerToolbar: false, 16559 smartRecognition: false, 16560 mobileOptimizer: true, 16561 fullAlone: true, 16562 fullViewPort: null, 16563 fullStretchTypes: 'flash, video', 16564 overlay: { 16565 blur: true, 16566 opacity: .85 16567 }, 16568 controls: { 16569 arrows: false, 16570 slideshow: false, 16571 toolbar: true, 16572 fullscreen: true, 16573 thumbnail: true, 16574 keyboard: true, 16575 mousewheel: true, 16576 swipe: true 16577 }, 16578 keyboard: { 16579 left: true, // previous 16580 right: true, // next 16581 up: true, // previous 16582 down: true, // next 16583 esc: true, // close 16584 shift_enter: true // fullscreen 16585 }, 16586 show: { 16587 effect: true, 16588 speed: 300, 16589 title: true 16590 }, 16591 hide: { 16592 effect: true, 16593 speed: 300 16594 }, 16595 caption: { 16596 start: true, 16597 show: 'mouseenter', 16598 hide: 'mouseleave' 16599 }, 16600 social: { 16601 start: true, 16602 show: 'mouseenter', 16603 hide: 'mouseleave',
16604 buttons: false 16605 }, 16606 styles: { 16607 pageOffsetX: 0, 16608 pageOffsetY: 0, 16609 nextOffsetX: 45, 16610 nextOffsetY: 0, 16611 nextOpacity: 1, 16612 nextScale: 1, 16613 prevOffsetX: 45, 16614 prevOffsetY: 0, 16615 prevOpacity: 1, 16616 prevScale: 1 16617 }, 16618 thumbnails: { 16619 maxWidth: 120, 16620 maxHeight: 80, 16621 normalOpacity: 1, 16622 activeOpacity: .6 16623 }, 16624 effects: { 16625 reposition: true, 16626 repositionSpeed: 200, 16627 switchSpeed: 500, 16628 loadedFadeSpeed: 180, 16629 fadeSpeed: 200 16630 }, 16631 slideshow: { 16632 pauseTime: 5000, 16633 pauseOnHover: false, 16634 startPaused: true 16635 }, 16636 text: { 16637 close: "Press Esc to close", 16638 enterFullscreen: "Enter Fullscreen (Shift+Enter)", 16639 exitFullscreen: "Exit Fullscreen (Shift+Enter)", 16640 slideShow: "Slideshow", 16641 next: "Next", 16642 previous: "Previous" 16643 }, 16644 errors: { 16645 loadImage: "An error occurred when trying to load photo.", 16646 loadContents: "An error occurred when trying to load contents.", 16647 missingPlugin: "The content your are attempting to view requires the <a href='{pluginspage}' target='_blank'>{type} plugin<\/a>." 16648 }, 16649 ajaxSetup: { 16650 url: '', 16651 beforeSend: function(jqXHR, settings) {}, 16652 cache: false, 16653 complete: function(jqXHR, textStatus) {}, 16654 crossDomain: false, 16655 error: function(jqXHR, textStatus, errorThrown) {}, 16656 success: function(data, textStatus, jqXHR) {}, 16657 global: true, 16658 ifModified: false, 16659 username: null, 16660 password: null, 16661 type: 'GET' 16662 }, 16663 callback: {} 16664 }, opt); 16665 16666 var instant = ($.isArray(items) || typeof items == 'string') ? true : false; 16667 16668 items = $.isArray(items) ? items : new Array(); 16669 16670 if (typeof args[0] == 'string') items[0] = args[0]; 16671 16672 if (version_compare($.fn.jquery, '1.8', '>=')) { 16673 var iLB = new iLightBox($(this), options, items, instant); 16674 return { 16675 close: function() { 16676 iLB.closeAction(); 16677 }, 16678 fullscreen: function() { 16679 iLB.fullScreenAction(); 16680 }, 16681 moveNext: function() { 16682 iLB.moveTo('next'); 16683 }, 16684 movePrev: function() { 16685 iLB.moveTo('prev'); 16686 }, 16687 goTo: function(index) { 16688 iLB.goTo(index); 16689 }, 16690 refresh: function() { 16691 iLB.refresh(); 16692 }, 16693 reposition: function() { 16694 (arguments.length > 0) ? iLB.repositionPhoto(true): iLB.repositionPhoto(); 16695 }, 16696 setOption: function(options) { 16697 iLB.setOption(options); 16698 }, 16699 destroy: function() { 16700 iLB.closeAction(); 16701 iLB.dispatchItemsEvents(); 16702 } 16703 }; 16704 } else { 16705 throw "The jQuery version that was loaded is too old. iLightBox requires jQuery 1.8+"; 16706 } 16707 16708 }; 16709 16710 16711 $.iLightBox = function() { 16712 return $.fn.iLightBox(arguments[0], arguments[1]); 16713 }; 16714 16715 function getScrollXY() { 16716 var scrOfX = 0, 16717 scrOfY = 0; 16718 if (typeof(window.pageYOffset) == 'number') { 16719 //Netscape compliant 16720 scrOfY = window.pageYOffset; 16721 scrOfX = window.pageXOffset; 16722 } else if (document.body && (document.body.scrollLeft || document.body.scrollTop)) { 16723 //DOM compliant 16724 scrOfY = document.body.scrollTop; 16725 scrOfX = document.body.scrollLeft; 16726 } else if (document.documentElement && (document.documentElement.scrollLeft || document.documentElement.scrollTop)) { 16727 //IE6 standards compliant mode 16728 scrOfY = document.documentElement.scrollTop; 16729 scrOfX = document.documentElement.scrollLeft; 16730 } 16731 return { 16732 x: scrOfX, 16733 y: scrOfY 16734 }; 16735 } 16736 16737 (function() { 16738 // add new event shortcuts 16739 $.each(("touchstart touchmove touchend " + 16740 "tap taphold " + 16741 "swipe swipeleft swiperight " + 16742 "scrollstart scrollstop").split(" "), function(i, name) { 16743 16744 $.fn[name] = function(fn) { 16745 return fn ? this.bind(name, fn) : this.trigger(name); 16746 }; 16747 16748 // jQuery < 1.8 16749 // if ($.attrFn) { 16750 // $.attrFn[name] = true; 16751 // } 16752 }); 16753 16754 var tapSettings = { 16755 startEvent: 'touchstart.iTap', 16756 endEvent: 'touchend.iTap' 16757 }; 16758 16759 // tap Event: 16760 $.event.special.itap = { 16761 setup: function() { 16762 16763 var self = this, 16764 $self = $(this), 16765 start, stop; 16766 16767 $self.bind(tapSettings.startEvent, function(event) { 16768 start = getScrollXY(); 16769 16770 $self.one(tapSettings.endEvent, function(event) { 16771 stop = getScrollXY(); 16772 16773 var orgEvent = event || window.event; 16774 event = $.event.fix(orgEvent); 16775 event.type = "itap"; 16776 16777 if ((start && stop) && (start.x == stop.x && start.y == stop.y))($.event.dispatch || $.event.handle).call(self, event); 16778 16779 start = stop = undefined; 16780 }); 16781 }); 16782 }, 16783 16784 teardown: function() { 16785 $(this).unbind(tapSettings.startEvent); 16786 } 16787 }; 16788 }()); 16789 16790 16791 //Fullscreen API 16792 (function() { 16793 fullScreenApi = { 16794 supportsFullScreen: false, 16795 isFullScreen: function() { 16796 return false;
16797 }, 16798 requestFullScreen: function() {}, 16799 cancelFullScreen: function() {}, 16800 fullScreenEventName: '', 16801 prefix: '' 16802 }, 16803 browserPrefixes = 'webkit moz o ms khtml'.split(' '); 16804 16805 // check for native support 16806 if (typeof document.cancelFullScreen != 'undefined') { 16807 fullScreenApi.supportsFullScreen = true; 16808 } else { 16809 // check for fullscreen support by vendor prefix 16810 for (var i = 0, il = browserPrefixes.length; i < il; i++) { 16811 fullScreenApi.prefix = browserPrefixes[i]; 16812 16813 if (typeof document[fullScreenApi.prefix + 'CancelFullScreen'] != 'undefined') { 16814 fullScreenApi.supportsFullScreen = true; 16815 16816 break; 16817 } 16818 } 16819 } 16820 16821 // update methods to do something useful 16822 if (fullScreenApi.supportsFullScreen) { 16823 fullScreenApi.fullScreenEventName = fullScreenApi.prefix + 'fullscreenchange'; 16824 16825 fullScreenApi.isFullScreen = function() { 16826 switch (this.prefix) { 16827 case '': 16828 return document.fullScreen; 16829 case 'webkit': 16830 return document.webkitIsFullScreen; 16831 default: 16832 return document[this.prefix + 'FullScreen']; 16833 } 16834 } 16835 fullScreenApi.requestFullScreen = function(el) { 16836 return (this.prefix === '') ? el.requestFullScreen() : el[this.prefix + 'RequestFullScreen'](); 16837 } 16838 fullScreenApi.cancelFullScreen = function(el) { 16839 return (this.prefix === '') ? document.cancelFullScreen() : document[this.prefix + 'CancelFullScreen'](); 16840 } 16841 } 16842 }()); 16843 16844 // Browser detect 16845 (function() { 16846 function uaMatch(ua) { 16847 ua = ua.toLowerCase(); 16848 16849 var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || 16850 /(webkit)[ \/]([\w.]+)/.exec(ua) || 16851 /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || 16852 /(msie) ([\w.]+)/.exec(ua) || 16853 ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || []; 16854 16855 return { 16856 browser: match[1] || "", 16857 version: match[2] || "0" 16858 }; 16859 } 16860 16861 var matched = uaMatch(navigator.userAgent); 16862 browser = {}; 16863 16864 if (matched.browser) { 16865 browser[matched.browser] = true; 16866 browser.version = matched.version; 16867 } 16868 16869 // Chrome is Webkit, but Webkit is also Safari. 16870 if (browser.chrome) { 16871 browser.webkit = true; 16872 } else if (browser.webkit) { 16873 browser.safari = true; 16874 } 16875 }()); 16876 16877 // Feature detects 16878 (function() { 16879 var prefixes = ['', 'webkit', 'moz', 'ms', 'o']; 16880 var el = document.createElement('div'); 16881 16882 function testProp(prop) { 16883 for (var p = 0, pl = prefixes.length; p < pl; p++) { 16884 var prefixedProp = prefixes[p] ? prefixes[p] + prop.charAt(0).toUpperCase() + prop.slice(1) : prop; 16885 if (el.style[prefixedProp] !== undefined) { 16886 return prefixedProp; 16887 } 16888 } 16889 } 16890 16891 // Global support indicators 16892 transform = testProp('transform') || ''; 16893 gpuAcceleration = testProp('perspective') ? 'translateZ(0) ' : ''; 16894 }()); 16895 16896 16897 /* 16898 PluginDetect v0.7.9 16899 www.pinlady.net/PluginDetect/license/ 16900 [ getVersion onWindowLoaded BetterIE ] 16901 [ Flash QuickTime Shockwave ] 16902 */ 16903 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;
16903d++){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);
16903d.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)}
16903c.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;
16903if(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(); 16904 16905 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)}; 16906 16907 16908 /* 16909 jQuery hashchange event v1.3 16910 https://github.com/cowboy/jquery-hashchange 16911 Copyright (c) 2010 "Cowboy" Ben Alman 16912 Dual licensed under the MIT and GPL licenses. 16913 */ 16914 (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= 16915 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|| 16916 "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;
16916a!==d&&(b.title=k.title,b.open(),e&&b.write('<script>document.domain="'+e+'"\x3c/script>'),b.close(),c.location.hash=a)}}();return h}()})(); 16917 16918 if (!Array.prototype.filter) { 16919 Array.prototype.filter = function(fun /*, thisp */ ) { 16920 "use strict"; 16921 16922 if (this == null) 16923 throw new TypeError(); 16924 16925 var t = Object(this); 16926 var len = t.length >>> 0; 16927 if (typeof fun != "function") 16928 throw new TypeError(); 16929 16930 var res = []; 16931 var thisp = arguments[1]; 16932 for (var i = 0; i < len; i++) { 16933 if (i in t) { 16934 var val = t[i]; // in case fun mutates this 16935 if (fun.call(thisp, val, i, t)) 16936 res.push(val); 16937 } 16938 } 16939 16940 return res; 16941 }; 16942 } 16943 16944 if (!Array.prototype.indexOf) { 16945 Array.prototype.indexOf = function(searchElement, fromIndex) { 16946 var k; 16947 16948 if (this == null) { 16949 throw new TypeError('"this" is null or not defined'); 16950 } 16951 16952 var O = Object(this); 16953 16954 var len = O.length >>> 0; 16955 16956 if (len === 0) { 16957 return -1; 16958 } 16959 16960 var n = +fromIndex || 0; 16961 16962 if (abs(n) === Infinity) { 16963 n = 0; 16964 } 16965 16966 if (n >= len) { 16967 return -1; 16968 } 16969 16970 k = max(n >= 0 ? n : len - abs(n), 0); 16971 16972 while (k < len) { 16973 var kValue; 16974 if (k in O && O[k] === searchElement) { 16975 return k; 16976 } 16977 k++; 16978 } 16979 return -1; 16980 }; 16981 } 16982 16983 if (!Array.prototype.lastIndexOf) { 16984 Array.prototype.lastIndexOf = function(searchElement /*, fromIndex*/ ) { 16985 "use strict"; 16986 16987 if (this == null) 16988 throw new TypeError(); 16989 16990 var t = Object(this); 16991 var len = t.length >>> 0; 16992 if (len === 0) 16993 return -1; 16994 16995 var n = len; 16996 if (arguments.length > 1) { 16997 n = Number(arguments[1]); 16998 if (n != n) 16999 n = 0; 17000 else if (n != 0 && n != (1 / 0) && n != -(1 / 0)) 17001 n = (n > 0 || -1) * floor(abs(n)); 17002 } 17003 17004 var k = n >= 0 ? min(n, len - 1) : len - abs(n); 17005 17006 for (; k >= 0; k--) { 17007 if (k in t && t[k] === searchElement) 17008 return k; 17009 } 17010 return -1; 17011 }; 17012 } 17013})(jQuery, this); 17014 17015/*! 17016 * lightgallery | 2.5.0 | June 13th 2022 17017 * http://www.lightgalleryjs.com/ 17018 * Copyright (c) 2020 Sachin Neravath; 17019 * @license GPLv3 17020 */ 17021 17022(function (global, factory) { 17023 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 17024 typeof define === 'function' && define.amd ? define(factory) : 17025 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lightGallery = factory()); 17026}(this, (function () { 'use strict'; 17027 17028 /*! ***************************************************************************** 17029 Copyright (c) Microsoft Corporation. 17030 17031 Permission to use, copy, modify, and/or distribute this software for any 17032 purpose with or without fee is hereby granted. 17033 17034 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 17035 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 17036 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 17037 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 17038 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 17039 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17040 PERFORMANCE OF THIS SOFTWARE. 17041 ***************************************************************************** */ 17042 17043 var __assign = function() { 17044 __assign = Object.assign || function __assign(t) { 17045 for (var s, i = 1, n = arguments.length; i < n; i++) { 17046 s = arguments[i]; 17047 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 17048 } 17049 return t; 17050 }; 17051 return __assign.apply(this, arguments); 17052 }; 17053 17054 function __spreadArrays() { 17055 for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; 17056 for (var r = Array(s), k = 0, i = 0; i < il; i++) 17057 for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) 17058 r[k] = a[j]; 17059 return r; 17060 } 17061 17062 /** 17063 * List of lightGallery events 17064 * All events should be documented here 17065 * Below interfaces are used to build the website documentations 17066 * */ 17067 var lGEvents = { 17068 afterAppendSlide: 'lgAfterAppendSlide', 17069 init: 'lgInit', 17070 hasVideo: 'lgHasVideo', 17071 containerResize: 'lgContainerResize', 17072 updateSlides: 'lgUpdateSlides', 17073 afterAppendSubHtml: 'lgAfterAppendSubHtml', 17074 beforeOpen: 'lgBeforeOpen', 17075 afterOpen: 'lgAfterOpen', 17076 slideItemLoad: 'lgSlideItemLoad', 17077 beforeSlide: 'lgBeforeSlide', 17078 afterSlide: 'lgAfterSlide', 17079 posterClick: 'lgPosterClick', 17080 dragStart: 'lgDragStart', 17081 dragMove: 'lgDragMove', 17082 dragEnd: 'lgDragEnd', 17083 beforeNextSlide: 'lgBeforeNextSlide', 17084 beforePrevSlide: 'lgBeforePrevSlide', 17085 beforeClose: 'lgBeforeClose', 17086 afterClose: 'lgAfterClose', 17087 rotateLeft: 'lgRotateLeft', 17088 rotateRight: 'lgRotateRight', 17089 flipHorizontal: 'lgFlipHorizontal', 17090 flipVertical: 'lgFlipVertical', 17091 autoplay: 'lgAutoplay', 17092 autoplayStart: 'lgAutoplayStart', 17093 autoplayStop: 'lgAutoplayStop', 17094 }; 17095 17096 var lightGalleryCoreSettings = { 17097 mode: 'lg-slide', 17098 easing: 'ease', 17099 speed: 400, 17100 licenseKey: '0000-0000-000-0000', 17101 height: '100%', 17102 width: '100%', 17103 addClass: '', 17104 startClass: 'lg-start-zoom', 17105 backdropDuration: 300, 17106 container: '', 17107 startAnimationDuration: 400, 17108 zoomFromOrigin: true, 17109 hideBarsDelay: 0, 17110 showBarsAfter: 10000, 17111 slideDelay: 0, 17112 supportLegacyBrowser: true, 17113 allowMediaOverlap: false, 17114 videoMaxSize: '1280-720', 17115 loadYouTubePoster: true, 17116 defaultCaptionHeight: 0, 17117 ariaLabelledby: '', 17118 ariaDescribedby: '', 17119 resetScrollPosition: true, 17120 hideScrollbar: false, 17121 closable: true, 17122 swipeToClose: true, 17123 closeOnTap: true, 17124 showCloseIcon: true, 17125 showMaximizeIcon: false, 17126 loop: true, 17127 escKey: true, 17128 keyPress: true, 17129 trapFocus: true, 17130 controls: true, 17131 slideEndAnimation: true, 17132 hideControlOnEnd: false,
vendor: 15,066 bytes, lines 17133-17680
17133 mousewheel: false, 17134 getCaptionFromTitleOrAlt: true, 17135 appendSubHtmlTo: '.lg-sub-html', 17136 subHtmlSelectorRelative: false, 17137 preload: 2, 17138 numberOfSlideItemsInDom: 10, 17139 selector: '', 17140 selectWithin: '', 17141 nextHtml: '', 17142 prevHtml: '', 17143 index: 0, 17144 iframeWidth: '100%', 17145 iframeHeight: '100%', 17146 iframeMaxWidth: '100%', 17147 iframeMaxHeight: '100%', 17148 download: true, 17149 counter: true, 17150 appendCounterTo: '.lg-toolbar', 17151 swipeThreshold: 50, 17152 enableSwipe: true, 17153 enableDrag: true, 17154 dynamic: false, 17155 dynamicEl: [], 17156 extraProps: [], 17157 exThumbImage: '', 17158 isMobile: undefined, 17159 mobileSettings: { 17160 controls: false, 17161 showCloseIcon: false, 17162 download: false, 17163 }, 17164 plugins: [], 17165 strings: { 17166 closeGallery: 'Close gallery', 17167 toggleMaximize: 'Toggle maximize', 17168 previousSlide: 'Previous slide', 17169 nextSlide: 'Next slide', 17170 download: 'Download', 17171 playVideo: 'Play video', 17172 }, 17173 }; 17174 17175 function initLgPolyfills() { 17176 (function () { 17177 if (typeof window.CustomEvent === 'function') 17178 return false; 17179 function CustomEvent(event, params) { 17180 params = params || { 17181 bubbles: false, 17182 cancelable: false, 17183 detail: null, 17184 }; 17185 var evt = document.createEvent('CustomEvent'); 17186 evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail); 17187 return evt; 17188 } 17189 window.CustomEvent = CustomEvent; 17190 })(); 17191 (function () { 17192 if (!Element.prototype.matches) { 17193 Element.prototype.matches = 17194 Element.prototype.msMatchesSelector || 17195 Element.prototype.webkitMatchesSelector; 17196 } 17197 })(); 17198 } 17199 var lgQuery = /** @class */ (function () { 17200 function lgQuery(selector) { 17201 this.cssVenderPrefixes = [ 17202 'TransitionDuration', 17203 'TransitionTimingFunction', 17204 'Transform', 17205 'Transition', 17206 ]; 17207 this.selector = this._getSelector(selector); 17208 this.firstElement = this._getFirstEl(); 17209 return this; 17210 } 17211 lgQuery.generateUUID = function () { 17212 return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { 17213 var r = (Math.random() * 16) | 0, v = c == 'x' ? r : (r & 0x3) | 0x8; 17214 return v.toString(16); 17215 }); 17216 }; 17217 lgQuery.prototype._getSelector = function (selector, context) { 17218 if (context === void 0) { context = document; } 17219 if (typeof selector !== 'string') { 17220 return selector; 17221 } 17222 context = context || document; 17223 var fl = selector.substring(0, 1); 17224 if (fl === '#') { 17225 return context.querySelector(selector); 17226 } 17227 else { 17228 return context.querySelectorAll(selector); 17229 } 17230 }; 17231 lgQuery.prototype._each = function (func) { 17232 if (!this.selector) { 17233 return this; 17234 } 17235 if (this.selector.length !== undefined) { 17236 [].forEach.call(this.selector, func); 17237 } 17238 else { 17239 func(this.selector, 0); 17240 } 17241 return this; 17242 }; 17243 lgQuery.prototype._setCssVendorPrefix = function (el, cssProperty, value) { 17244 // prettier-ignore 17245 var property = cssProperty.replace(/-([a-z])/gi, function (s, group1) { 17246 return group1.toUpperCase(); 17247 }); 17248 if (this.cssVenderPrefixes.indexOf(property) !== -1) { 17249 el.style[property.charAt(0).toLowerCase() + property.slice(1)] = value; 17250 el.style['webkit' + property] = value; 17251 el.style['moz' + property] = value; 17252 el.style['ms' + property] = value; 17253 el.style['o' + property] = value; 17254 } 17255 else { 17256 el.style[property] = value; 17257 } 17258 }; 17259 lgQuery.prototype._getFirstEl = function () { 17260 if (this.selector && this.selector.length !== undefined) { 17261 return this.selector[0]; 17262 } 17263 else { 17264 return this.selector; 17265 } 17266 }; 17267 lgQuery.prototype.isEventMatched = function (event, eventName) { 17268 var eventNamespace = eventName.split('.'); 17269 return event 17270 .split('.') 17271 .filter(function (e) { return e; }) 17272 .every(function (e) { 17273 return eventNamespace.indexOf(e) !== -1; 17274 }); 17275 }; 17276 lgQuery.prototype.attr = function (attr, value) { 17277 if (value === undefined) { 17278 if (!this.firstElement) { 17279 return ''; 17280 } 17281 return this.firstElement.getAttribute(attr); 17282 } 17283 this._each(function (el) { 17284 el.setAttribute(attr, value); 17285 }); 17286 return this; 17287 }; 17288 lgQuery.prototype.find = function (selector) { 17289 return $LG(this._getSelector(selector, this.selector)); 17290 }; 17291 lgQuery.prototype.first = function () { 17292 if (this.selector && this.selector.length !== undefined) { 17293 return $LG(this.selector[0]); 17294 } 17295 else { 17296 return $LG(this.selector); 17297 } 17298 }; 17299 lgQuery.prototype.eq = function (index) { 17300 return $LG(this.selector[index]); 17301 }; 17302 lgQuery.prototype.parent = function () { 17303 return $LG(this.selector.parentElement); 17304 }; 17305 lgQuery.prototype.get = function () { 17306 return this._getFirstEl(); 17307 }; 17308 lgQuery.prototype.removeAttr = function (attributes) { 17309 var attrs = attributes.split(' '); 17310 this._each(function (el) { 17311 attrs.forEach(function (attr) { return el.removeAttribute(attr); }); 17312 }); 17313 return this; 17314 }; 17315 lgQuery.prototype.wrap = function (className) { 17316 if (!this.firstElement) { 17317 return this; 17318 } 17319 var wrapper = document.createElement('div'); 17320 wrapper.className = className; 17321 this.firstElement.parentNode.insertBefore(wrapper, this.firstElement); 17322 this.firstElement.parentNode.removeChild(this.firstElement); 17323 wrapper.appendChild(this.firstElement); 17324 return this; 17325 }; 17326 lgQuery.prototype.addClass = function (classNames) { 17327 if (classNames === void 0) { classNames = ''; } 17328 this._each(function (el) { 17329 // IE doesn't support multiple arguments 17330 classNames.split(' ').forEach(function (className) { 17331 if (className) { 17332 el.classList.add(className); 17333 } 17334 }); 17335 }); 17336 return this; 17337 }; 17338 lgQuery.prototype.removeClass = function (classNames) { 17339 this._each(function (el) { 17340 // IE doesn't support multiple arguments 17341 classNames.split(' ').forEach(function (className) { 17342 if (className) { 17343 el.classList.remove(className); 17344 } 17345 }); 17346 }); 17347 return this; 17348 }; 17349 lgQuery.prototype.hasClass = function (className) { 17350 if (!this.firstElement) { 17351 return false; 17352 } 17353 return this.firstElement.classList.contains(className); 17354 }; 17355 lgQuery.prototype.hasAttribute = function (attribute) { 17356 if (!this.firstElement) { 17357 return false; 17358 } 17359 return this.firstElement.hasAttribute(attribute); 17360 }; 17361 lgQuery.prototype.toggleClass = function (className) { 17362 if (!this.firstElement) { 17363 return this; 17364 } 17365 if (this.hasClass(className)) { 17366 this.removeClass(className); 17367 } 17368 else { 17369 this.addClass(className); 17370 } 17371 return this; 17372 }; 17373 lgQuery.prototype.css = function (property, value) { 17374 var _this = this; 17375 this._each(function (el) { 17376 _this._setCssVendorPrefix(el, property, value); 17377 }); 17378 return this; 17379 }; 17380 // Need to pass separate namespaces for separate elements 17381 lgQuery.prototype.on = function (events, listener) { 17382 var _this = this; 17383 if (!this.selector) { 17384 return this; 17385 } 17386 events.split(' ').forEach(function (event) { 17387 if (!Array.isArray(lgQuery.eventListeners[event])) { 17388 lgQuery.eventListeners[event] = []; 17389 } 17390 lgQuery.eventListeners[event].push(listener); 17391 _this.selector.addEventListener(event.split('.')[0], listener); 17392 }); 17393 return this; 17394 }; 17395 // @todo - test this 17396 lgQuery.prototype.once = function (event, listener) { 17397 var _this = this; 17398 this.on(event, function () { 17399 _this.off(event); 17400 listener(event); 17401 }); 17402 return this; 17403 }; 17404 lgQuery.prototype.off = function (event) { 17405 var _this = this; 17406 if (!this.selector) { 17407 return this; 17408 } 17409 Object.keys(lgQuery.eventListeners).forEach(function (eventName) { 17410 if (_this.isEventMatched(event, eventName)) { 17411 lgQuery.eventListeners[eventName].forEach(function (listener) { 17412 _this.selector.removeEventListener(eventName.split('.')[0], listener); 17413 }); 17414 lgQuery.eventListeners[eventName] = []; 17415 } 17416 }); 17417 return this; 17418 }; 17419 lgQuery.prototype.trigger = function (event, detail) { 17420 if (!this.firstElement) { 17421 return this; 17422 } 17423 var customEvent = new CustomEvent(event.split('.')[0], { 17424 detail: detail || null, 17425 }); 17426 this.firstElement.dispatchEvent(customEvent); 17427 return this; 17428 }; 17429 // Does not support IE 17430 lgQuery.prototype.load = function (url) { 17431 var _this = this; 17432 fetch(url) 17433 .then(function (res) { return res.text(); }) 17434 .then(function (html) { 17435 _this.selector.innerHTML = html; 17436 }); 17437 return this; 17438 }; 17439 lgQuery.prototype.html = function (html) { 17440 if (html === undefined) { 17441 if (!this.firstElement) { 17442 return ''; 17443 } 17444 return this.firstElement.innerHTML; 17445 } 17446 this._each(function (el) { 17447 el.innerHTML = html; 17448 }); 17449 return this; 17450 }; 17451 lgQuery.prototype.append = function (html) { 17452 this._each(function (el) { 17453 if (typeof html === 'string') { 17454 el.insertAdjacentHTML('beforeend', html); 17455 } 17456 else { 17457 el.appendChild(html); 17458 } 17459 }); 17460 return this; 17461 }; 17462 lgQuery.prototype.prepend = function (html) { 17463 this._each(function (el) { 17464 el.insertAdjacentHTML('afterbegin', html); 17465 }); 17466 return this; 17467 }; 17468 lgQuery.prototype.remove = function () { 17469 this._each(function (el) { 17470 el.parentNode.removeChild(el); 17471 }); 17472 return this; 17473 }; 17474 lgQuery.prototype.empty = function () { 17475 this._each(function (el) { 17476 el.innerHTML = ''; 17477 }); 17478 return this; 17479 }; 17480 lgQuery.prototype.scrollTop = function (scrollTop) { 17481 if (scrollTop !== undefined) { 17482 document.body.scrollTop = scrollTop; 17483 document.documentElement.scrollTop = scrollTop; 17484 return this; 17485 } 17486 else { 17487 return (window.pageYOffset || 17488 document.documentElement.scrollTop || 17489 document.body.scrollTop || 17490 0); 17491 } 17492 }; 17493 lgQuery.prototype.scrollLeft = function (scrollLeft) { 17494 if (scrollLeft !== undefined) { 17495 document.body.scrollLeft = scrollLeft; 17496 document.documentElement.scrollLeft = scrollLeft; 17497 return this; 17498 } 17499 else { 17500 return (window.pageXOffset || 17501 document.documentElement.scrollLeft || 17502 document.body.scrollLeft || 17503 0); 17504 } 17505 }; 17506 lgQuery.prototype.offset = function () { 17507 if (!this.firstElement) { 17508 return { 17509 left: 0, 17510 top: 0, 17511 }; 17512 } 17513 var rect = this.firstElement.getBoundingClientRect(); 17514 var bodyMarginLeft = $LG('body').style().marginLeft; 17515 // Minus body margin - https://stackoverflow.com/questions/30711548/is-getboundingclientrect-left-returning-a-wrong-value 17516 return { 17517 left: rect.left - parseFloat(bodyMarginLeft) + this.scrollLeft(), 17518 top: rect.top + this.scrollTop(), 17519 }; 17520 }; 17521 lgQuery.prototype.style = function () { 17522 if (!this.firstElement) { 17523 return {}; 17524 } 17525 return (this.firstElement.currentStyle || 17526 window.getComputedStyle(this.firstElement)); 17527 }; 17528 // Width without padding and border even if box-sizing is used. 17529 lgQuery.prototype.width = function () { 17530 var style = this.style(); 17531 return (this.firstElement.clientWidth - 17532 parseFloat(style.paddingLeft) - 17533 parseFloat(style.paddingRight)); 17534 }; 17535 // Height without padding and border even if box-sizing is used. 17536 lgQuery.prototype.height = function () { 17537 var style = this.style(); 17538 return (this.firstElement.clientHeight - 17539 parseFloat(style.paddingTop) - 17540 parseFloat(style.paddingBottom)); 17541 }; 17542 lgQuery.eventListeners = {}; 17543 return lgQuery; 17544 }()); 17545 function $LG(selector) { 17546 initLgPolyfills(); 17547 return new lgQuery(selector); 17548 } 17549 17550 var defaultDynamicOptions = [ 17551 'src', 17552 'sources', 17553 'subHtml', 17554 'subHtmlUrl', 17555 'html', 17556 'video', 17557 'poster', 17558 'slideName', 17559 'responsive', 17560 'srcset', 17561 'sizes', 17562 'iframe', 17563 'downloadUrl', 17564 'download', 17565 'width', 17566 'facebookShareUrl', 17567 'tweetText', 17568 'iframeTitle', 17569 'twitterShareUrl', 17570 'pinterestShareUrl', 17571 'pinterestText', 17572 'fbHtml', 17573 'disqusIdentifier', 17574 'disqusUrl', 17575 ]; 17576 // Convert html data-attribute to camalcase 17577 function convertToData(attr) { 17578 // FInd a way for lgsize 17579 if (attr === 'href') { 17580 return 'src'; 17581 } 17582 attr = attr.replace('data-', ''); 17583 attr = attr.charAt(0).toLowerCase() + attr.slice(1); 17584 attr = attr.replace(/-([a-z])/g, function (g) { return g[1].toUpperCase(); }); 17585 return attr; 17586 } 17587 var utils = { 17588 /** 17589 * get possible width and height from the lgSize attribute. Used for ZoomFromOrigin option 17590 */ 17591 //Uncode edit ##START## 17592 getSize: function (el, container, spacing, defaultLgSize, galleryItem) { 17593 // getSize: function (el, container, spacing, defaultLgSize) { 17594 //Uncode edit ##END## 17595 if (spacing === void 0) { spacing = 0; } 17596 var LGel = $LG(el); 17597 var lgSize = LGel.attr('data-lg-size') || defaultLgSize; 17598 //Uncode edit ##START## 17599 if ( typeof galleryItem.size && galleryItem.size != null ) { 17600 lgSize = galleryItem.size; 17601 } 17602 //Uncode edit ##END## 17603 if (!lgSize) { 17604 return; 17605 } 17606 var isResponsiveSizes = lgSize.split(','); 17607 // if at-least two viewport sizes are available 17608 if (isResponsiveSizes[1]) { 17609 var wWidth = window.innerWidth; 17610 for (var i = 0; i < isResponsiveSizes.length; i++) { 17611 var size_1 = isResponsiveSizes[i]; 17612 var responsiveWidth = parseInt(size_1.split('-')[2], 10); 17613 if (responsiveWidth > wWidth) { 17614 lgSize = size_1; 17615 break; 17616 } 17617 // take last item as last option 17618 if (i === isResponsiveSizes.length - 1) { 17619 lgSize = size_1; 17620 } 17621 } 17622 } 17623 var size = lgSize.split('-'); 17624 var width = parseInt(size[0], 10); 17625 var height = parseInt(size[1], 10); 17626 var cWidth = container.width(); 17627 var cHeight = container.height() - spacing; 17628 var maxWidth = Math.min(cWidth, width); 17629 var maxHeight = Math.min(cHeight, height); 17630 var ratio = Math.min(maxWidth / width, maxHeight / height); 17631 return { width: width * ratio, height: height * ratio }; 17632 }, 17633 /** 17634 * @desc Get transform value based on the imageSize. Used for ZoomFromOrigin option 17635 * @param {jQuery Element} 17636 * @returns {String} Transform CSS string 17637 */ 17638 getTransform: function (el, container, top, bottom, imageSize) { 17639 if (!imageSize) { 17640 return; 17641 } 17642 var LGel = $LG(el).find('img').first(); 17643 if (!LGel.get()) { 17644 return; 17645 } 17646 var containerRect = container.get().getBoundingClientRect(); 17647 var wWidth = containerRect.width; 17648 // using innerWidth to include mobile safari bottom bar 17649 var wHeight = container.height() - (top + bottom); 17650 var elWidth = LGel.width(); 17651 var elHeight = LGel.height(); 17652 var elStyle = LGel.style(); 17653 var x = (wWidth - elWidth) / 2 - 17654 LGel.offset().left + 17655 (parseFloat(elStyle.paddingLeft) || 0) + 17656 (parseFloat(elStyle.borderLeft) || 0) + 17657 $LG(window).scrollLeft() + 17658 containerRect.left; 17659 var y = (wHeight - elHeight) / 2 - 17660 LGel.offset().top + 17661 (parseFloat(elStyle.paddingTop) || 0) + 17662 (parseFloat(elStyle.borderTop) || 0) + 17663 $LG(window).scrollTop() + 17664 top; 17665 var scX = elWidth / imageSize.width; 17666 var scY = elHeight / imageSize.height; 17667 var transform = 'translate3d(' + 17668 (x *= -1) + 17669 'px, ' + 17670 (y *= -1) + 17671 'px, 0) scale3d(' + 17672 scX + 17673 ', ' + 17674 scY + 17675 ', 1)'; 17676 return transform; 17677 }, 17678 getIframeMarkup: function (iframeWidth, iframeHeight, iframeMaxWidth, iframeMaxHeight, src, iframeTitle) { 17679 var title = iframeTitle ? 'title="' + iframeTitle + '"' : ''; 17680 return "<div class=\"lg-video-cont lg-has-iframe\" style=\"width:"
vendor: 2,803 bytes, lines 17680-17752
17680+ iframeWidth + "; max-width:" + iframeMaxWidth + "; height: " + iframeHeight + "; max-height:" + iframeMaxHeight + "\">\n <iframe class=\"lg-object\" frameborder=\"0\" " + title + " src=\"" + src + "\" allowfullscreen=\"true\"></iframe>\n </div>"; 17681 }, 17682 getImgMarkup: function (index, src, altAttr, srcset, sizes, sources) { 17683 var srcsetAttr = srcset ? "srcset=\"" + srcset + "\"" : ''; 17684 var sizesAttr = sizes ? "sizes=\"" + sizes + "\"" : ''; 17685 var imgMarkup = "<img " + altAttr + " " + srcsetAttr + " " + sizesAttr + " class=\"lg-object lg-image\" data-index=\"" + index + "\" src=\"" + src + "\" />"; 17686 var sourceTag = ''; 17687 if (sources) { 17688 var sourceObj = typeof sources === 'string' ? JSON.parse(sources) : sources; 17689 sourceTag = sourceObj.map(function (source) { 17690 var attrs = ''; 17691 Object.keys(source).forEach(function (key) { 17692 // Do not remove the first space as it is required to separate the attributes 17693 attrs += " " + key + "=\"" + source[key] + "\""; 17694 }); 17695 return "<source " + attrs + "></source>"; 17696 }); 17697 } 17698 return "" + sourceTag + imgMarkup; 17699 }, 17700 // Get src from responsive src 17701 getResponsiveSrc: function (srcItms) { 17702 var rsWidth = []; 17703 var rsSrc = []; 17704 var src = ''; 17705 for (var i = 0; i < srcItms.length; i++) { 17706 var _src = srcItms[i].split(' '); 17707 // Manage empty space 17708 if (_src[0] === '') { 17709 _src.splice(0, 1); 17710 } 17711 rsSrc.push(_src[0]); 17712 rsWidth.push(_src[1]); 17713 } 17714 var wWidth = window.innerWidth; 17715 for (var j = 0; j < rsWidth.length; j++) { 17716 if (parseInt(rsWidth[j], 10) > wWidth) { 17717 src = rsSrc[j]; 17718 break; 17719 } 17720 } 17721 return src; 17722 }, 17723 isImageLoaded: function (img) { 17724 if (!img) 17725 return false; 17726 // During the onload event, IE correctly identifies any images that 17727 // werenât downloaded as not complete. Others should too. Gecko-based 17728 // browsers act like NS4 in that they report this incorrectly. 17729 if (!img.complete) { 17730 return false; 17731 } 17732 // However, they do have two very useful properties: naturalWidth and 17733 // naturalHeight. These give the true size of the image. If it failed 17734 // to load, either of these should be zero. 17735 if (img.naturalWidth === 0) { 17736 return false; 17737 } 17738 // No other way of checking: assume itâs ok. 17739 return true; 17740 }, 17741 getVideoPosterMarkup: function (_poster, dummyImg, videoContStyle, playVideoString, _isVideo) { 17742 var videoClass = ''; 17743 if (_isVideo && _isVideo.youtube) { 17744 videoClass = 'lg-has-youtube'; 17745 } 17746 else if (_isVideo && _isVideo.vimeo) { 17747 videoClass = 'lg-has-vimeo'; 17748 } 17749 else { 17750 videoClass = 'lg-has-html5'; 17751 } 17752 return "<div class=\"lg-video-cont " + videoClass + "\" style=\"" + videoContStyle + "\">\n <div class=\"lg-video-play-button\">
vendor: 5,030 bytes, lines 17752-17863
17752\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>"; 17753 }, 17754 getFocusableElements: function (container) { 17755 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])'); 17756 var visibleElements = [].filter.call(elements, function (element) { 17757 var style = window.getComputedStyle(element); 17758 return style.display !== 'none' && style.visibility !== 'hidden'; 17759 }); 17760 return visibleElements; 17761 }, 17762 /** 17763 * @desc Create dynamic elements array from gallery items when dynamic option is false 17764 * It helps to avoid frequent DOM interaction 17765 * and avoid multiple checks for dynamic elments 17766 * 17767 * @returns {Array} dynamicEl 17768 */ 17769 getDynamicOptions: function (items, extraProps, getCaptionFromTitleOrAlt, exThumbImage) { 17770 var dynamicElements = []; 17771 var availableDynamicOptions = __spreadArrays(defaultDynamicOptions, extraProps); 17772 [].forEach.call(items, function (item) { 17773 var dynamicEl = {}; 17774 for (var i = 0; i < item.attributes.length; i++) { 17775 var attr = item.attributes[i]; 17776 if (attr.specified) { 17777 var dynamicAttr = convertToData(attr.name); 17778 var label = ''; 17779 if (availableDynamicOptions.indexOf(dynamicAttr) > -1) { 17780 label = dynamicAttr; 17781 } 17782 if (label) { 17783 dynamicEl[label] = attr.value; 17784 } 17785 } 17786 } 17787 var currentItem = $LG(item); 17788 var alt = currentItem.find('img').first().attr('alt'); 17789 var title = currentItem.attr('title'); 17790 //Uncode edit ##START## 17791 // var thumb = exThumbImage 17792 var thumb = exThumbImage && currentItem.attr(exThumbImage) 17793 //Uncode edit ##END## 17794 ? currentItem.attr(exThumbImage) 17795 : currentItem.find('img').first().attr('src'); 17796 dynamicEl.thumb = thumb; 17797 //Uncode edit ##START## 17798 if (getCaptionFromTitleOrAlt && !dynamicEl.subHtml) { 17799 // dynamicEl.subHtml = title || alt || ''; 17800 dynamicEl.subHtml = title || ''; 17801 } 17802 // dynamicEl.alt = alt || title || ''; 17803 dynamicEl.alt = title || ''; 17804 var inlineType = currentItem.attr('data-type'); 17805 dynamicEl.type = inlineType; 17806 //Uncode edit ##END## 17807 dynamicElements.push(dynamicEl); 17808 }); 17809 return dynamicElements; 17810 }, 17811 isMobile: function () { 17812 return /iPhone|iPad|iPod|Android/i.test(navigator.userAgent); 17813 }, 17814 /** 17815 * @desc Check the given src is video 17816 * @param {String} src 17817 * @return {Object} video type 17818 * Ex:{ youtube : ["//www.youtube.com/watch?v=c0asJgSyxcY", "c0asJgSyxcY"] } 17819 * 17820 * @todo - this information can be moved to dynamicEl to avoid frequent calls 17821 */ 17822 isVideo: function (src, isHTML5VIdeo, index) { 17823 if (!src || src.match(/\.(mp4|m4v|ogg|webm)$/) ) { 17824 if (isHTML5VIdeo) { 17825 return { 17826 html5: true, 17827 }; 17828 } 17829 else { 17830 console.warn('lightGallery :- data-src is not provided on slide item ' + 17831 (index + 1) + 17832 '. Please make sure the selector property is properly configured. More info - https://www.lightgalleryjs.com/demos/html-markup/'); 17833 return; 17834 } 17835 } 17836 var youtube = src.match(/\/\/(?:www\.)?youtu(?:\.be|be\.com|be-nocookie\.com)\/(?:watch\?v=|embed\/)?([a-z0-9\-\_\%]+)([\&|?][\S]*)*/i); 17837 var vimeo = src.match(/\/\/(?:www\.)?(?:player\.)?vimeo.com\/(?:video\/)?([0-9a-z\-_]+)(.*)?/i); 17838 var wistia = src.match(/https?:\/\/(.+)?(wistia\.com|wi\.st)\/(medias|embed)\/([0-9a-z\-_]+)(.*)/); 17839 if (youtube) { 17840 return { 17841 youtube: youtube, 17842 }; 17843 } 17844 else if (vimeo) { 17845 return { 17846 vimeo: vimeo, 17847 }; 17848 } 17849 else if (wistia) { 17850 return { 17851 wistia: wistia, 17852 }; 17853 } 17854 }, 17855 }; 17856 17857 // @ref - https://stackoverflow.com/questions/3971841/how-to-resize-images-proportionally-keeping-the-aspect-ratio 17858 // @ref - https://2ality.com/2017/04/setting-up-multi-platform-packages.html 17859 // Unique id for each gallery 17860 var lgId = 0; 17861 var LightGallery = /** @class */ (function () { 17862 function LightGallery(element, options) { 17863 this.lgOpened = false;
vendor: 4,563 bytes, lines 17864-17998
17864 this.index = 0; 17865 // lightGallery modules 17866 this.plugins = []; 17867 // false when lightGallery load first slide content; 17868 this.lGalleryOn = false; 17869 // True when a slide animation is in progress 17870 this.lgBusy = false; 17871 this.currentItemsInDom = []; 17872 // Scroll top value before lightGallery is opened 17873 this.prevScrollTop = 0; 17874 this.bodyPaddingRight = 0; 17875 this.isDummyImageRemoved = false; 17876 this.dragOrSwipeEnabled = false; 17877 this.mediaContainerPosition = { 17878 top: 0, 17879 bottom: 0, 17880 }; 17881 if (!element) { 17882 return this; 17883 } 17884 lgId++; 17885 this.lgId = lgId; 17886 this.el = element; 17887 this.LGel = $LG(element); 17888 this.generateSettings(options); 17889 this.buildModules(); 17890 // When using dynamic mode, ensure dynamicEl is an array 17891 if (this.settings.dynamic && 17892 this.settings.dynamicEl !== undefined && 17893 !Array.isArray(this.settings.dynamicEl)) { 17894 throw 'When using dynamic mode, you must also define dynamicEl as an Array.'; 17895 } 17896 this.galleryItems = this.getItems(); 17897 this.normalizeSettings(); 17898 // Gallery items 17899 this.init(); 17900 //Uncode edit ##START## 17901 // this.validateLicense(); 17902 //Uncode edit ##END## 17903 return this; 17904 } 17905 LightGallery.prototype.generateSettings = function (options) { 17906 // lightGallery settings 17907 this.settings = __assign(__assign({}, lightGalleryCoreSettings), options); 17908 if (this.settings.isMobile && 17909 typeof this.settings.isMobile === 'function' 17910 ? this.settings.isMobile() 17911 : utils.isMobile()) { 17912 var mobileSettings = __assign(__assign({}, this.settings.mobileSettings), this.settings.mobileSettings); 17913 this.settings = __assign(__assign({}, this.settings), mobileSettings); 17914 } 17915 }; 17916 LightGallery.prototype.normalizeSettings = function () { 17917 if (this.settings.slideEndAnimation) { 17918 this.settings.hideControlOnEnd = false; 17919 } 17920 if (!this.settings.closable) { 17921 this.settings.swipeToClose = false; 17922 } 17923 // And reset it on close to get the correct value next time 17924 this.zoomFromOrigin = this.settings.zoomFromOrigin; 17925 // At the moment, Zoom from image doesn't support dynamic options 17926 // @todo add zoomFromOrigin support for dynamic images 17927 if (this.settings.dynamic) { 17928 this.zoomFromOrigin = false; 17929 } 17930 if (!this.settings.container) { 17931 this.settings.container = document.body; 17932 } 17933 // settings.preload should not be grater than $item.length 17934 this.settings.preload = Math.min(this.settings.preload, this.galleryItems.length); 17935 }; 17936 LightGallery.prototype.init = function () { 17937 var _this = this; 17938 this.addSlideVideoInfo(this.galleryItems); 17939 this.buildStructure(); 17940 this.LGel.trigger(lGEvents.init, { 17941 instance: this, 17942 }); 17943 if (this.settings.keyPress) { 17944 this.keyPress(); 17945 } 17946 setTimeout(function () { 17947 _this.enableDrag(); 17948 _this.enableSwipe(); 17949 _this.triggerPosterClick(); 17950 }, 50); 17951 this.arrow(); 17952 if (this.settings.mousewheel) { 17953 this.mousewheel(); 17954 } 17955 if (!this.settings.dynamic) { 17956 this.openGalleryOnItemClick(); 17957 } 17958 }; 17959 LightGallery.prototype.openGalleryOnItemClick = function () { 17960 var _this = this; 17961 var _loop_1 = function (index) { 17962 var element = this_1.items[index]; 17963 var $element = $LG(element); 17964 // Using different namespace for click because click event should not unbind if selector is same object('this') 17965 // @todo manage all event listners - should have namespace that represent element 17966 var uuid = lgQuery.generateUUID(); 17967 $element 17968 .attr('data-lg-id', uuid) 17969 .on("click.lgcustom-item-" + uuid, function (e) { 17970 e.preventDefault(); 17971 var currentItemIndex = _this.settings.index || index; 17972 _this.openGallery(currentItemIndex, element); 17973 }); 17974 }; 17975 var this_1 = this; 17976 // Using for loop instead of using bubbling as the items can be any html element. 17977 for (var index = 0; index < this.items.length; index++) { 17978 _loop_1(index); 17979 } 17980 }; 17981 /** 17982 * Module constructor 17983 * Modules are build incrementally. 17984 * Gallery should be opened only once all the modules are initialized. 17985 * use moduleBuildTimeout to make sure this 17986 */ 17987 LightGallery.prototype.buildModules = function () { 17988 var _this = this; 17989 this.settings.plugins.forEach(function (plugin) { 17990 _this.plugins.push(new plugin(_this, $LG)); 17991 }); 17992 }; 17993 LightGallery.prototype.validateLicense = function () { 17994 if (!this.settings.licenseKey) { 17995 console.warn('Please provide a valid license key'); 17996 } 17997 else if (this.settings.licenseKey === '0000-0000-000-0000') { 17998 console.warn("lightGallery: " + this.settings.licenseKey + " license key is not val
vendor: 17,473 bytes, lines 17998-18412
17998id for production use"); 17999 } 18000 }; 18001 LightGallery.prototype.getSlideItem = function (index) { 18002 return $LG(this.getSlideItemId(index)); 18003 }; 18004 LightGallery.prototype.getSlideItemId = function (index) { 18005 return "#lg-item-" + this.lgId + "-" + index; 18006 }; 18007 LightGallery.prototype.getIdName = function (id) { 18008 return id + "-" + this.lgId; 18009 }; 18010 LightGallery.prototype.getElementById = function (id) { 18011 return $LG("#" + this.getIdName(id)); 18012 }; 18013 LightGallery.prototype.manageSingleSlideClassName = function () { 18014 if (this.galleryItems.length < 2) { 18015 this.outer.addClass('lg-single-item'); 18016 } 18017 else { 18018 this.outer.removeClass('lg-single-item'); 18019 } 18020 }; 18021 LightGallery.prototype.buildStructure = function () { 18022 var _this = this; 18023 var container = this.$container && this.$container.get(); 18024 if (container) { 18025 return; 18026 } 18027 var controls = ''; 18028 var subHtmlCont = ''; 18029 // Create controls 18030 if (this.settings.controls) { 18031 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>"; 18032 } 18033 if (this.settings.appendSubHtmlTo !== '.lg-item') { 18034 subHtmlCont = 18035 '<div class="lg-sub-html" role="status" aria-live="polite"></div>'; 18036 } 18037 var addClasses = ''; 18038 if (this.settings.allowMediaOverlap) { 18039 // Do not remove space before last single quote 18040 addClasses += 'lg-media-overlap '; 18041 } 18042 var ariaLabelledby = this.settings.ariaLabelledby 18043 ? 'aria-labelledby="' + this.settings.ariaLabelledby + '"' 18044 : ''; 18045 var ariaDescribedby = this.settings.ariaDescribedby 18046 ? 'aria-describedby="' + this.settings.ariaDescribedby + '"' 18047 : ''; 18048 var containerClassName = "lg-container " + this.settings.addClass + " " + (document.body !== this.settings.container ? 'lg-inline' : ''); 18049 var closeIcon = this.settings.closable && this.settings.showCloseIcon 18050 ? "<button type=\"button\" aria-label=\"" + this.settings.strings['closeGallery'] + "\" id=\"" + this.getIdName('lg-close') + "\" class=\"lg-close lg-icon\"></button>" 18051 : ''; 18052 var maximizeIcon = this.settings.showMaximizeIcon 18053 ? "<button type=\"button\" aria-label=\"" + this.settings.strings['toggleMaximize'] + "\" id=\"" + this.getIdName('lg-maximize') + "\" class=\"lg-maximize lg-icon\"></button>" 18054 : ''; 18055 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' 18056 ? subHtmlCont 18057 : '') + "\n <div id=\"" + this.getIdName('lg-components') + "\" class=\"lg-components\">\n " + (this.settings.appendSubHtmlTo === '.lg-sub-html' 18058 ? subHtmlCont 18059 : '') + "\n </div>\n </div>\n </div>\n "; 18060 $LG(this.settings.container).append(template); 18061 if (document.body !== this.settings.container) { 18062 $LG(this.settings.container).css('position', 'relative'); 18063 } 18064 this.outer = this.getElementById('lg-outer'); 18065 this.$lgComponents = this.getElementById('lg-components'); 18066 this.$backdrop = this.getElementById('lg-backdrop'); 18067 this.$container = this.getElementById('lg-container'); 18068 this.$inner = this.getElementById('lg-inner'); 18069 this.$content = this.getElementById('lg-content'); 18070 this.$toolbar = this.getElementById('lg-toolbar'); 18071 this.$backdrop.css('transition-duration', this.settings.backdropDuration + 'ms'); 18072 var outerClassNames = this.settings.mode + " "; 18073 this.manageSingleSlideClassName(); 18074 if (this.settings.enableDrag) { 18075 outerClassNames += 'lg-grab '; 18076 } 18077 this.outer.addClass(outerClassNames); 18078 this.$inner.css('transition-timing-function', this.settings.easing); 18079 this.$inner.css('transition-duration', this.settings.speed + 'ms'); 18080 if (this.settings.download) { 18081 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>"); 18082 } 18083 this.counter(); 18084 $LG(window).on("resize.lg.global" + this.lgId + " orientationchange.lg.global" + this.lgId, function () { 18085 _this.refreshOnResize(); 18086 }); 18087 this.hideBars(); 18088 this.manageCloseGallery(); 18089 this.toggleMaximize(); 18090 this.initModules(); 18091 }; 18092 LightGallery.prototype.refreshOnResize = function () { 18093 if (this.lgOpened) { 18094 var currentGalleryItem = this.galleryItems[this.index]; 18095 var __slideVideoInfo = currentGalleryItem.__slideVideoInfo; 18096 this.mediaContainerPosition = this.getMediaContainerPosition(); 18097 var _a = this.mediaContainerPosition, top_1 = _a.top, bottom = _a.bottom; 18098 //Uncode edit ##START## 18099 this.currentImageSize = utils.getSize(this.items[this.index], this.outer, top_1 + bottom, __slideVideoInfo && this.settings.videoMaxSize, this.galleryItems[this.index]); 18100 // this.currentImageSize = utils.getSize(this.items[this.index], this.outer, top_1 + bottom, __slideVideoInfo && this.settings.videoMaxSize); 18101 //Uncode edit ##END## 18102 if (__slideVideoInfo) { 18103 this.resizeVideoSlide(this.index, this.currentImageSize); 18104 } 18105 if (this.zoomFromOrigin && !this.isDummyImageRemoved) { 18106 var imgStyle = this.getDummyImgStyles(this.currentImageSize); 18107 this.outer 18108 .find('.lg-current .lg-dummy-img') 18109 .first() 18110 .attr('style', imgStyle); 18111 } 18112 this.LGel.trigger(lGEvents.containerResize); 18113 } 18114 }; 18115 LightGallery.prototype.resizeVideoSlide = function (index, imageSize) { 18116 var lgVideoStyle = this.getVideoContStyle(imageSize); 18117 var currentSlide = this.getSlideItem(index); 18118 currentSlide.find('.lg-video-cont').attr('style', lgVideoStyle); 18119 }; 18120 /** 18121 * Update slides dynamically. 18122 * Add, edit or delete slides dynamically when lightGallery is opened. 18123 * Modify the current gallery items and pass it via updateSlides method 18124 * @note 18125 * - Do not mutate existing lightGallery items directly. 18126 * - Always pass new list of gallery items 18127 * - You need to take care of thumbnails outside the gallery if any 18128 * - user this method only if you want to update slides when the gallery is opened. Otherwise, use `refresh()` method. 18129 * @param items Gallery items 18130 * @param index After the update operation, which slide gallery should navigate to 18131 * @category lGPublicMethods 18132 * @example 18133 * const plugin = lightGallery(); 18134 * 18135 * // Adding slides dynamically 18136 * let galleryItems = [ 18137 * // Access existing lightGallery items 18138 * // galleryItems are automatically generated internally from the gallery HTML markup 18139 * // or directly from galleryItems when dynamic gallery is used 18140 * ...plugin.galleryItems, 18141 * ...[ 18142 * { 18143 * src: 'img/img-1.png', 18144 * thumb: 'img/thumb1.png', 18145 * }, 18146 * ], 18147 * ]; 18148 * plugin.updateSlides( 18149 * galleryItems, 18150 * plugin.index, 18151 * ); 18152 * 18153 * 18154 * // Remove slides dynamically 18155 * galleryItems = JSON.parse( 18156 * JSON.stringify(updateSlideInstance.galleryItems), 18157 * ); 18158 * galleryItems.shift(); 18159 * updateSlideInstance.updateSlides(galleryItems, 1); 18160 * @see <a href="/demos/update-slides/">Demo</a> 18161 */ 18162 LightGallery.prototype.updateSlides = function (items, index) { 18163 if (this.index > items.length - 1) { 18164 this.index = items.length - 1; 18165 } 18166 if (items.length === 1) { 18167 this.index = 0; 18168 } 18169 if (!items.length) { 18170 this.closeGallery(); 18171 return; 18172 } 18173 var currentSrc = this.galleryItems[index].src; 18174 this.galleryItems = items; 18175 this.updateControls(); 18176 this.$inner.empty(); 18177 this.currentItemsInDom = []; 18178 var _index = 0; 18179 // Find the current index based on source value of the slide 18180 this.galleryItems.some(function (galleryItem, itemIndex) { 18181 if (galleryItem.src === currentSrc) { 18182 _index = itemIndex; 18183 return true; 18184 } 18185 return false; 18186 }); 18187 this.currentItemsInDom = this.organizeSlideItems(_index, -1); 18188 this.loadContent(_index, true); 18189 this.getSlideItem(_index).addClass('lg-current'); 18190 this.index = _index; 18191 this.updateCurrentCounter(_index); 18192 this.LGel.trigger(lGEvents.updateSlides); 18193 }; 18194 // Get gallery items based on multiple conditions 18195 LightGallery.prototype.getItems = function () { 18196 // Gallery items 18197 this.items = []; 18198 if (!this.settings.dynamic) { 18199 if (this.settings.selector === 'this') { 18200 this.items.push(this.el); 18201 } 18202 else if (this.settings.selector) { 18203 if (typeof this.settings.selector === 'string') { 18204 if (this.settings.selectWithin) { 18205 var selectWithin = $LG(this.settings.selectWithin); 18206 this.items = selectWithin 18207 .find(this.settings.selector) 18208 .get(); 18209 } 18210 else { 18211 this.items = this.el.querySelectorAll(this.settings.selector); 18212 } 18213 } 18214 else { 18215 this.items = this.settings.selector; 18216 } 18217 } 18218 else { 18219 this.items = this.el.children; 18220 } 18221 return utils.getDynamicOptions(this.items, this.settings.extraProps, this.settings.getCaptionFromTitleOrAlt, this.settings.exThumbImage); 18222 } 18223 else { 18224 return this.settings.dynamicEl || []; 18225 } 18226 }; 18227 LightGallery.prototype.shouldHideScrollbar = function () { 18228 return (this.settings.hideScrollbar && 18229 document.body === this.settings.container); 18230 }; 18231 LightGallery.prototype.hideScrollbar = function () { 18232 if (!this.shouldHideScrollbar()) { 18233 return; 18234 } 18235 this.bodyPaddingRight = parseFloat($LG('body').style().paddingRight); 18236 var bodyRect = document.documentElement.getBoundingClientRect(); 18237 var scrollbarWidth = window.innerWidth - bodyRect.width; 18238 $LG(document.body).css('padding-right', scrollbarWidth + this.bodyPaddingRight + 'px'); 18239 $LG(document.body).addClass('lg-overlay-open'); 18240 }; 18241 LightGallery.prototype.resetScrollBar = function () { 18242 if (!this.shouldHideScrollbar()) { 18243 return; 18244 } 18245 $LG(document.body).css('padding-right', this.bodyPaddingRight + 'px'); 18246 $LG(document.body).removeClass('lg-overlay-open'); 18247 }; 18248 /** 18249 * Open lightGallery. 18250 * Open gallery with specific slide by passing index of the slide as parameter. 18251 * @category lGPublicMethods 18252 * @param {Number} index - index of the slide 18253 * @param {HTMLElement} element - Which image lightGallery should zoom from 18254 * 18255 * @example 18256 * const $dynamicGallery = document.getElementById('dynamic-gallery-demo'); 18257 * const dynamicGallery = lightGallery($dynamicGallery, { 18258 * dynamic: true, 18259 * dynamicEl: [ 18260 * { 18261 * src: 'img/1.jpg', 18262 * thumb: 'img/thumb-1.jpg', 18263 * subHtml: '<h4>Image 1 title</h4><p>Image 1 descriptions.</p>', 18264 * }, 18265 * ... 18266 * ], 18267 * }); 18268 * $dynamicGallery.addEventListener('click', function () { 18269 * // Starts with third item.(Optional). 18270 * // This is useful if you want use dynamic mode with 18271 * // custom thumbnails (thumbnails outside gallery), 18272 * dynamicGallery.openGallery(2); 18273 * }); 18274 * 18275 */ 18276 LightGallery.prototype.openGallery = function (index, element) { 18277 var _this = this; 18278 if (index === void 0) { index = this.settings.index; } 18279 // prevent accidental double execution 18280 if (this.lgOpened) 18281 return; 18282 this.lgOpened = true; 18283 this.outer.removeClass('lg-hide-items'); 18284 this.hideScrollbar(); 18285 // Add display block, but still has opacity 0 18286 this.$container.addClass('lg-show'); 18287 var itemsToBeInsertedToDom = this.getItemsToBeInsertedToDom(index, index); 18288 this.currentItemsInDom = itemsToBeInsertedToDom; 18289 var items = ''; 18290 itemsToBeInsertedToDom.forEach(function (item) { 18291 items = items + ("<div id=\"" + item + "\" class=\"lg-item\"></div>"); 18292 }); 18293 this.$inner.append(items); 18294 this.addHtml(index); 18295 var transform = ''; 18296 this.mediaContainerPosition = this.getMediaContainerPosition(); 18297 var _a = this.mediaContainerPosition, top = _a.top, bottom = _a.bottom; 18298 if (!this.settings.allowMediaOverlap) { 18299 this.setMediaContainerPosition(top, bottom); 18300 } 18301 var __slideVideoInfo = this.galleryItems[index].__slideVideoInfo; 18302 if (this.zoomFromOrigin && element) { 18303 //Uncode edit ##START## 18304 this.currentImageSize = utils.getSize(element, this.outer, top + bottom, __slideVideoInfo && this.settings.videoMaxSize, this.galleryItems[this.index]); 18305 // this.currentImageSize = utils.getSize(element, this.outer, top + bottom, __slideVideoInfo && this.settings.videoMaxSize); 18306 //Uncode edit ##END## 18307 transform = utils.getTransform(element, this.outer, top, bottom, this.currentImageSize); 18308 } 18309 if (!this.zoomFromOrigin || !transform) { 18310 this.outer.addClass(this.settings.startClass); 18311 this.getSlideItem(index).removeClass('lg-complete'); 18312 } 18313 var timeout = this.settings.zoomFromOrigin 18314 ? 100 18315 : this.settings.backdropDuration; 18316 setTimeout(function () { 18317 _this.outer.addClass('lg-components-open'); 18318 }, timeout); 18319 this.index = index; 18320 //Uncode edit ##START## 18321 // this.LGel.trigger(lGEvents.beforeOpen); 18322 this.LGel.trigger(lGEvents.beforeOpen, { 18323 galleryItems: this.galleryItems, 18324 items: this.items, 18325 outer: this.outer, 18326 }); 18327 //Uncode edit ##END## 18328 // add class lg-current to remove initial transition 18329 this.getSlideItem(index).addClass('lg-current'); 18330 this.lGalleryOn = false; 18331 // Store the current scroll top value to scroll back after closing the gallery.. 18332 this.prevScrollTop = $LG(window).scrollTop(); 18333 setTimeout(function () { 18334 // Need to check both zoomFromOrigin and transform values as we need to set set the 18335 // default opening animation if user missed to add the lg-size attribute 18336 if (_this.zoomFromOrigin && transform) { 18337 var currentSlide_1 = _this.getSlideItem(index); 18338 currentSlide_1.css('transform', transform); 18339 setTimeout(function () { 18340 currentSlide_1 18341 .addClass('lg-start-progress lg-start-end-progress') 18342 .css('transition-duration', _this.settings.startAnimationDuration + 'ms'); 18343 _this.outer.addClass('lg-zoom-from-image'); 18344 }); 18345 setTimeout(function () { 18346 currentSlide_1.css('transform', 'translate3d(0, 0, 0)'); 18347 }, 100); 18348 } 18349 setTimeout(function () { 18350 _this.$backdrop.addClass('in'); 18351 _this.$container.addClass('lg-show-in'); 18352 }, 10); 18353 setTimeout(function () { 18354 if (_this.settings.trapFocus && 18355 document.body === _this.settings.container) { 18356 _this.trapFocus(); 18357 } 18358 }, _this.settings.backdropDuration + 50); 18359 // lg-visible class resets gallery opacity to 1 18360 if (!_this.zoomFromOrigin || !transform) { 18361 setTimeout(function () { 18362 _this.outer.addClass('lg-visible'); 18363 }, _this.settings.backdropDuration); 18364 } 18365 // initiate slide function 18366 _this.slide(index, false, false, false); 18367 _this.LGel.trigger(lGEvents.afterOpen); 18368 }); 18369 if (document.body === this.settings.container) { 18370 $LG('html').addClass('lg-on'); 18371 } 18372 }; 18373 /** 18374 * Note - Changing the position of the media on every slide transition creates a flickering effect. 18375 * Therefore, The height of the caption is calculated dynamically, only once based on the first slide caption. 18376 * if you have dynamic captions for each media, 18377 * you can provide an appropriate height for the captions via allowMediaOverlap option 18378 */ 18379 LightGallery.prototype.getMediaContainerPosition = function () { 18380 if (this.settings.allowMediaOverlap) { 18381 return { 18382 top: 0, 18383 bottom: 0, 18384 }; 18385 } 18386 var top = this.$toolbar.get().clientHeight || 0; 18387 var subHtml = this.outer.find('.lg-components .lg-sub-html').get(); 18388 var captionHeight = this.settings.defaultCaptionHeight || 18389 (subHtml && subHtml.clientHeight) || 18390 0; 18391 var thumbContainer = this.outer.find('.lg-thumb-outer').get(); 18392 var thumbHeight = thumbContainer ? thumbContainer.clientHeight : 0; 18393 var bottom = thumbHeight + captionHeight; 18394 //Uncode edit ##START## 18395 bottom = bottom < 55 ? 55 : bottom; 18396 //Uncode edit ##END## 18397 return { 18398 top: top, 18399 bottom: bottom, 18400 }; 18401 }; 18402 LightGallery.prototype.setMediaContainerPosition = function (top, bottom) { 18403 if (top === void 0) { top = 0; } 18404 if (bottom === void 0) { bottom = 0; } 18405 this.$content.css('top', top + 'px').css('bottom', bottom + 'px'); 18406 }; 18407 LightGallery.prototype.hideBars = function () { 18408 var _this = this; 18409 // Hide controllers if mouse doesn't move for some period 18410 setTimeout(function () { 18411 _this.outer.removeClass('lg-hide-items'); 18412 if (_this.settings.hideBarsDelay > 0) {
vendor: 4,223 bytes, lines 18413-18543
18413 _this.outer.on('mousemove.lg click.lg touchstart.lg', function () { 18414 _this.outer.removeClass('lg-hide-items'); 18415 clearTimeout(_this.hideBarTimeout); 18416 // Timeout will be cleared on each slide movement also 18417 _this.hideBarTimeout = setTimeout(function () { 18418 _this.outer.addClass('lg-hide-items'); 18419 }, _this.settings.hideBarsDelay); 18420 }); 18421 _this.outer.trigger('mousemove.lg'); 18422 } 18423 }, this.settings.showBarsAfter); 18424 }; 18425 LightGallery.prototype.initPictureFill = function ($img) { 18426 if (this.settings.supportLegacyBrowser) { 18427 try { 18428 picturefill({ 18429 elements: [$img.get()], 18430 }); 18431 } 18432 catch (e) { 18433 console.warn('lightGallery :- If you want srcset or picture tag to be supported for older browser please include picturefil javascript library in your document.'); 18434 } 18435 } 18436 }; 18437 /** 18438 * @desc Create image counter 18439 * Ex: 1/10 18440 */ 18441 LightGallery.prototype.counter = function () { 18442 if (this.settings.counter) { 18443 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>"; 18444 this.outer.find(this.settings.appendCounterTo).append(counterHtml); 18445 } 18446 }; 18447 /** 18448 * @desc add sub-html into the slide 18449 * @param {Number} index - index of the slide 18450 */ 18451 LightGallery.prototype.addHtml = function (index) { 18452 var subHtml; 18453 var subHtmlUrl; 18454 if (this.galleryItems[index].subHtmlUrl) { 18455 subHtmlUrl = this.galleryItems[index].subHtmlUrl; 18456 } 18457 else { 18458 subHtml = this.galleryItems[index].subHtml; 18459 } 18460 if (!subHtmlUrl) { 18461 if (subHtml) { 18462 // get first letter of sub-html 18463 // if first letter starts with . or # get the html form the jQuery object 18464 var fL = subHtml.substring(0, 1); 18465 if (fL === '.' || fL === '#') { 18466 if (this.settings.subHtmlSelectorRelative && 18467 !this.settings.dynamic) { 18468 subHtml = $LG(this.items) 18469 .eq(index) 18470 .find(subHtml) 18471 .first() 18472 .html(); 18473 } 18474 else { 18475 subHtml = $LG(subHtml).first().html(); 18476 } 18477 } 18478 } 18479 else { 18480 subHtml = ''; 18481 } 18482 } 18483 if (this.settings.appendSubHtmlTo !== '.lg-item') { 18484 if (subHtmlUrl) { 18485 this.outer.find('.lg-sub-html').load(subHtmlUrl); 18486 } 18487 else { 18488 this.outer.find('.lg-sub-html').html(subHtml); 18489 } 18490 } 18491 else { 18492 var currentSlide = $LG(this.getSlideItemId(index)); 18493 if (subHtmlUrl) { 18494 currentSlide.load(subHtmlUrl); 18495 } 18496 else { 18497 currentSlide.append("<div class=\"lg-sub-html\">" + subHtml + "</div>"); 18498 } 18499 } 18500 // Add lg-empty-html class if title doesn't exist 18501 if (typeof subHtml !== 'undefined' && subHtml !== null) { 18502 if (subHtml === '') { 18503 this.outer 18504 .find(this.settings.appendSubHtmlTo) 18505 .addClass('lg-empty-html'); 18506 } 18507 else { 18508 this.outer 18509 .find(this.settings.appendSubHtmlTo) 18510 .removeClass('lg-empty-html'); 18511 } 18512 } 18513 this.LGel.trigger(lGEvents.afterAppendSubHtml, { 18514 index: index, 18515 }); 18516 }; 18517 /** 18518 * @desc Preload slides 18519 * @param {Number} index - index of the slide 18520 * @todo preload not working for the first slide, Also, should work for the first and last slide as well 18521 */ 18522 LightGallery.prototype.preload = function (index) { 18523 for (var i = 1; i <= this.settings.preload; i++) { 18524 if (i >= this.galleryItems.length - index) { 18525 break; 18526 } 18527 this.loadContent(index + i, false); 18528 } 18529 for (var j = 1; j <= this.settings.preload; j++) { 18530 if (index - j < 0) { 18531 break; 18532 } 18533 this.loadContent(index - j, false); 18534 } 18535 }; 18536 LightGallery.prototype.getDummyImgStyles = function (imageSize) { 18537 if (!imageSize) 18538 return ''; 18539 return "width:" + imageSize.width + "px;\n margin-left: -" + imageSize.width / 2 + "px;\n margin-top: -" + imageSize.height / 2 + "px;\n height:" + imageSize.height + "px"; 18540 }; 18541 LightGallery.prototype.getVideoContStyle = function (imageSize) { 18542 if (!imageSize) 18543 return '';
18544 return "width:" + imageSize.width + "px;\n height:" + imageSize.height + "px"; 18545 }; 18546 LightGallery.prototype.getDummyImageContent = function ($currentSlide, index, alt) { 18547 var $currentItem; 18548 if (!this.settings.dynamic) { 18549 $currentItem = $LG(this.items).eq(index); 18550 } 18551 if ($currentItem) { 18552 var _dummyImgSrc = void 0; 18553 if (!this.settings.exThumbImage) { 18554 _dummyImgSrc = $currentItem.find('img').first().attr('src'); 18555 } 18556 else { 18557 _dummyImgSrc = $currentItem.attr(this.settings.exThumbImage); 18558 } 18559 if (!_dummyImgSrc) 18560 return ''; 18561 var imgStyle = this.getDummyImgStyles(this.currentImageSize); 18562 var dummyImgContent = "<img " + alt + " style=\"" + imgStyle + "\" class=\"lg-dummy-img\" src=\"" + _dummyImgSrc + "\" />"; 18563 $currentSlide.addClass('lg-first-slide'); 18564 this.outer.addClass('lg-first-slide-loading'); 18565 return dummyImgContent; 18566 } 18567 return ''; 18568 }; 18569 LightGallery.prototype.setImgMarkup = function (src, $currentSlide, index) { 18570 var currentGalleryItem = this.galleryItems[index]; 18571 var alt = currentGalleryItem.alt, srcset = currentGalleryItem.srcset, sizes = currentGalleryItem.sizes, sources = currentGalleryItem.sources; 18572 // Use the thumbnail as dummy image which will be resized to actual image size and 18573 // displayed on top of actual image 18574 var imgContent = ''; 18575 var altAttr = alt ? 'alt="' + alt + '"' : ''; 18576 if (this.isFirstSlideWithZoomAnimation()) { 18577 imgContent = this.getDummyImageContent($currentSlide, index, altAttr); 18578 } 18579 else { 18580 imgContent = utils.getImgMarkup(index, src, altAttr, srcset, sizes, sources); 18581 } 18582 var imgMarkup = "<picture class=\"lg-img-wrap\"> " + imgContent + "</picture>"; 18583 $currentSlide.prepend(imgMarkup); 18584 }; 18585 LightGallery.prototype.onSlideObjectLoad = function ($slide, isHTML5VideoWithoutPoster, onLoad, onError) { 18586 var mediaObject = $slide.find('.lg-object').first(); 18587 if (utils.isImageLoaded(mediaObject.get()) || 18588 isHTML5VideoWithoutPoster) { 18589 onLoad(); 18590 } 18591 else { 18592 mediaObject.on('load.lg error.lg', function () { 18593 onLoad && onLoad(); 18594 }); 18595 mediaObject.on('error.lg', function () { 18596 onError && onError(); 18597 }); 18598 } 18599 }; 18600 /** 18601 * 18602 * @param $el Current slide item 18603 * @param index 18604 * @param delay Delay is 0 except first time 18605 * @param speed Speed is same as delay, except it is 0 if gallery is opened via hash plugin 18606 * @param isFirstSlide 18607 */ 18608 LightGallery.prototype.onLgObjectLoad = function (currentSlide, index, delay, speed, isFirstSlide, isHTML5VideoWithoutPoster) { 18609 var _this = this; 18610 //Uncode edit ##START## 18611 var $item = _this.galleryItems[index], 18612 type = $item.type; 18613 18614 if ( typeof $item.src !== 'undefined' ) { 18615 var inline_id = $item.src.replace('#', ''), 18616 $inline = document.getElementById(inline_id), 18617 inline_html; 18618 18619 if ( type === 'inline' && inline_id != null && typeof $inline !== 'undefined' ) { 18620 inline_html = $inline.innerHTML; 18621 } else { 18622 inline_html = ''; 18623 } 18624 } 18625 //Uncode edit ##END## 18626 this.onSlideObjectLoad(currentSlide, true, function () { 18627 _this.triggerSlideItemLoad(currentSlide, index, delay, speed, isFirstSlide); 18628 }, function () { 18629 currentSlide.addClass('lg-complete lg-complete_'); 18630 //Uncode edit ##START## 18631 // currentSlide.html('<span class="lg-error-msg">Oops... Failed to load content...</span>'); 18632 if ( inline_html !== '' ) { 18633 currentSlide.html(inline_html); 18634 } else { 18635 currentSlide.html('<span class="lg-error-msg">Oops... Failed to load content...</span>'); 18636 } 18637 //Uncode edit ##END## 18638 }); 18639 }; 18640 LightGallery.prototype.triggerSlideItemLoad = function ($currentSlide, index, delay, speed, isFirstSlide) { 18641 var _this = this; 18642 var currentGalleryItem = this.galleryItems[index]; 18643 // Adding delay for video slides without poster for better performance and user experience 18644 // Videos should start playing once once the gallery is completely loaded 18645 var _speed = isFirstSlide &&
vendor: 37,932 bytes, lines 18646-19735
18646 this.getSlideType(currentGalleryItem) === 'video' && 18647 !currentGalleryItem.poster 18648 ? speed 18649 : 0; 18650 setTimeout(function () { 18651 $currentSlide.addClass('lg-complete lg-complete_'); 18652 _this.LGel.trigger(lGEvents.slideItemLoad, { 18653 index: index, 18654 delay: delay || 0, 18655 isFirstSlide: isFirstSlide, 18656 }); 18657 }, _speed); 18658 }; 18659 LightGallery.prototype.isFirstSlideWithZoomAnimation = function () { 18660 return !!(!this.lGalleryOn && 18661 this.zoomFromOrigin && 18662 this.currentImageSize); 18663 }; 18664 // Add video slideInfo 18665 LightGallery.prototype.addSlideVideoInfo = function (items) { 18666 var _this = this; 18667 items.forEach(function (element, index) { 18668 element.__slideVideoInfo = utils.isVideo(element.src, !!element.video, index); 18669 if (element.__slideVideoInfo && 18670 _this.settings.loadYouTubePoster && 18671 !element.poster && 18672 element.__slideVideoInfo.youtube) { 18673 element.poster = "//img.youtube.com/vi/" + element.__slideVideoInfo.youtube[1] + "/maxresdefault.jpg"; 18674 } 18675 }); 18676 }; 18677 /** 18678 * Load slide content into slide. 18679 * This is used to load content into slides that is not visible too 18680 * @param {Number} index - index of the slide. 18681 * @param {Boolean} rec - if true call loadcontent() function again. 18682 */ 18683 LightGallery.prototype.loadContent = function (index, rec) { 18684 var _this = this; 18685 var currentGalleryItem = this.galleryItems[index]; 18686 var $currentSlide = $LG(this.getSlideItemId(index)); 18687 var poster = currentGalleryItem.poster, srcset = currentGalleryItem.srcset, sizes = currentGalleryItem.sizes, sources = currentGalleryItem.sources; 18688 var src = currentGalleryItem.src; 18689 var video = currentGalleryItem.video; 18690 var _html5Video = video && typeof video === 'string' ? JSON.parse(video) : video; 18691 if (currentGalleryItem.responsive) { 18692 var srcDyItms = currentGalleryItem.responsive.split(','); 18693 src = utils.getResponsiveSrc(srcDyItms) || src; 18694 } 18695 var videoInfo = currentGalleryItem.__slideVideoInfo; 18696 var lgVideoStyle = ''; 18697 var iframe = !!currentGalleryItem.iframe; 18698 var isFirstSlide = !this.lGalleryOn; 18699 // delay for adding complete class. it is 0 except first time. 18700 var delay = 0; 18701 if (isFirstSlide) { 18702 if (this.zoomFromOrigin && this.currentImageSize) { 18703 delay = this.settings.startAnimationDuration + 10; 18704 } 18705 else { 18706 delay = this.settings.backdropDuration + 10; 18707 } 18708 } 18709 if (!$currentSlide.hasClass('lg-loaded')) { 18710 if (videoInfo) { 18711 var _a = this.mediaContainerPosition, top_2 = _a.top, bottom = _a.bottom; 18712 //Uncode edit ##START## 18713 var videoSize = utils.getSize(this.items[index], this.outer, top_2 + bottom, videoInfo && this.settings.videoMaxSize, this.galleryItems[this.index]); 18714 // var videoSize = utils.getSize(this.items[index], this.outer, top_2 + bottom, videoInfo && this.settings.videoMaxSize); 18715 //Uncode edit ##END## 18716 lgVideoStyle = this.getVideoContStyle(videoSize); 18717 } 18718 if (iframe) { 18719 var markup = utils.getIframeMarkup(this.settings.iframeWidth, this.settings.iframeHeight, this.settings.iframeMaxWidth, this.settings.iframeMaxHeight, src, currentGalleryItem.iframeTitle); 18720 $currentSlide.prepend(markup); 18721 } 18722 else if (poster) { 18723 var dummyImg = ''; 18724 var hasStartAnimation = isFirstSlide && 18725 this.zoomFromOrigin && 18726 this.currentImageSize; 18727 if (hasStartAnimation) { 18728 dummyImg = this.getDummyImageContent($currentSlide, index, ''); 18729 } 18730 var markup = utils.getVideoPosterMarkup(poster, dummyImg || '', lgVideoStyle, this.settings.strings['playVideo'], videoInfo); 18731 $currentSlide.prepend(markup); 18732 } 18733 //Uncode edit ##START## 18734 // else if (videoInfo) { 18735 else if (videoInfo || this.getSlideType(currentGalleryItem) === 'audio') { 18736 if (! _html5Video) { 18737 var markup = "<div class=\"lg-video-cont \" style=\"" + lgVideoStyle + "\"></div>"; 18738 } 18739 //Uncode edit ##END## 18740 $currentSlide.prepend(markup); 18741 } 18742 else { 18743 this.setImgMarkup(src, $currentSlide, index); 18744 if (srcset || sources) { 18745 var $img = $currentSlide.find('.lg-object'); 18746 this.initPictureFill($img); 18747 } 18748 } 18749 if (poster || videoInfo) { 18750 this.LGel.trigger(lGEvents.hasVideo, { 18751 index: index, 18752 src: src, 18753 html5Video: _html5Video, 18754 hasPoster: !!poster, 18755 }); 18756 } 18757 this.LGel.trigger(lGEvents.afterAppendSlide, { index: index }); 18758 if (this.lGalleryOn && 18759 this.settings.appendSubHtmlTo === '.lg-item') { 18760 this.addHtml(index); 18761 } 18762 } 18763 // For first time add some delay for displaying the start animation. 18764 var _speed = 0; 18765 // Do not change the delay value because it is required for zoom plugin. 18766 // If gallery opened from direct url (hash) speed value should be 0 18767 if (delay && !$LG(document.body).hasClass('lg-from-hash')) { 18768 _speed = delay; 18769 } 18770 // Only for first slide and zoomFromOrigin is enabled 18771 if (this.isFirstSlideWithZoomAnimation()) { 18772 setTimeout(function () { 18773 $currentSlide 18774 .removeClass('lg-start-end-progress lg-start-progress') 18775 .removeAttr('style'); 18776 }, this.settings.startAnimationDuration + 100); 18777 if (!$currentSlide.hasClass('lg-loaded')) { 18778 setTimeout(function () { 18779 if (_this.getSlideType(currentGalleryItem) === 'image') { 18780 var alt = currentGalleryItem.alt; 18781 var altAttr = alt ? 'alt="' + alt + '"' : ''; 18782 $currentSlide 18783 .find('.lg-img-wrap') 18784 .append(utils.getImgMarkup(index, src, altAttr, srcset, sizes, currentGalleryItem.sources)); 18785 if (srcset || sources) { 18786 var $img = $currentSlide.find('.lg-object'); 18787 _this.initPictureFill($img); 18788 } 18789 } 18790 if (_this.getSlideType(currentGalleryItem) === 'image' || 18791 (_this.getSlideType(currentGalleryItem) === 'video' && 18792 poster)) { 18793 _this.onLgObjectLoad($currentSlide, index, delay, _speed, true, false); 18794 // load remaining slides once the slide is completely loaded 18795 _this.onSlideObjectLoad($currentSlide, !!(videoInfo && videoInfo.html5 && !poster), function () { 18796 _this.loadContentOnFirstSlideLoad(index, $currentSlide, _speed); 18797 }, function () { 18798 _this.loadContentOnFirstSlideLoad(index, $currentSlide, _speed); 18799 }); 18800 } 18801 }, this.settings.startAnimationDuration + 100); 18802 } 18803 } 18804 // SLide content has been added to dom 18805 $currentSlide.addClass('lg-loaded'); 18806 if (!this.isFirstSlideWithZoomAnimation() || 18807 (this.getSlideType(currentGalleryItem) === 'video' && !poster)) { 18808 //Uncode edit ##START## 18809 // this.onLgObjectLoad($currentSlide, index, delay, _speed, isFirstSlide, !!(videoInfo && videoInfo.html5 && !poster)); 18810 this.onLgObjectLoad($currentSlide, index, delay, _speed, isFirstSlide, !!( (videoInfo && videoInfo.html5 && !poster) || this.getSlideType(currentGalleryItem) === 'audio')); 18811 //Uncode edit ##END## 18812 } 18813 // When gallery is opened once content is loaded (second time) need to add lg-complete class for css styling 18814 if ((!this.zoomFromOrigin || !this.currentImageSize) && 18815 $currentSlide.hasClass('lg-complete_') && 18816 !this.lGalleryOn) { 18817 setTimeout(function () { 18818 $currentSlide.addClass('lg-complete'); 18819 }, this.settings.backdropDuration); 18820 } 18821 // Content loaded 18822 // Need to set lGalleryOn before calling preload function 18823 this.lGalleryOn = true; 18824 if (rec === true) { 18825 if (!$currentSlide.hasClass('lg-complete_')) { 18826 $currentSlide 18827 .find('.lg-object') 18828 .first() 18829 .on('load.lg error.lg', function () { 18830 _this.preload(index); 18831 }); 18832 } 18833 else { 18834 this.preload(index); 18835 } 18836 } 18837 }; 18838 /** 18839 * @desc Remove dummy image content and load next slides 18840 * Called only for the first time if zoomFromOrigin animation is enabled 18841 * @param index 18842 * @param $currentSlide 18843 * @param speed 18844 */ 18845 LightGallery.prototype.loadContentOnFirstSlideLoad = function (index, $currentSlide, speed) { 18846 var _this = this; 18847 setTimeout(function () { 18848 $currentSlide.find('.lg-dummy-img').remove(); 18849 $currentSlide.removeClass('lg-first-slide'); 18850 _this.outer.removeClass('lg-first-slide-loading'); 18851 _this.isDummyImageRemoved = true; 18852 _this.preload(index); 18853 }, speed + 300); 18854 }; 18855 LightGallery.prototype.getItemsToBeInsertedToDom = function (index, prevIndex, numberOfItems) { 18856 var _this = this; 18857 if (numberOfItems === void 0) { numberOfItems = 0; } 18858 var itemsToBeInsertedToDom = []; 18859 // Minimum 2 items should be there 18860 var possibleNumberOfItems = Math.max(numberOfItems, 3); 18861 possibleNumberOfItems = Math.min(possibleNumberOfItems, this.galleryItems.length); 18862 var prevIndexItem = "lg-item-" + this.lgId + "-" + prevIndex; 18863 if (this.galleryItems.length <= 3) { 18864 this.galleryItems.forEach(function (_element, index) { 18865 itemsToBeInsertedToDom.push("lg-item-" + _this.lgId + "-" + index); 18866 }); 18867 return itemsToBeInsertedToDom; 18868 } 18869 if (index < (this.galleryItems.length - 1) / 2) { 18870 for (var idx = index; idx > index - possibleNumberOfItems / 2 && idx >= 0; idx--) { 18871 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + idx); 18872 } 18873 var numberOfExistingItems = itemsToBeInsertedToDom.length; 18874 for (var idx = 0; idx < possibleNumberOfItems - numberOfExistingItems; idx++) { 18875 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + (index + idx + 1)); 18876 } 18877 } 18878 else { 18879 for (var idx = index; idx <= this.galleryItems.length - 1 && 18880 idx < index + possibleNumberOfItems / 2; idx++) { 18881 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + idx); 18882 } 18883 var numberOfExistingItems = itemsToBeInsertedToDom.length; 18884 for (var idx = 0; idx < possibleNumberOfItems - numberOfExistingItems; idx++) { 18885 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + (index - idx - 1)); 18886 } 18887 } 18888 if (this.settings.loop) { 18889 if (index === this.galleryItems.length - 1) { 18890 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + 0); 18891 } 18892 else if (index === 0) { 18893 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + (this.galleryItems.length - 1)); 18894 } 18895 } 18896 if (itemsToBeInsertedToDom.indexOf(prevIndexItem) === -1) { 18897 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + prevIndex); 18898 } 18899 return itemsToBeInsertedToDom; 18900 }; 18901 LightGallery.prototype.organizeSlideItems = function (index, prevIndex) { 18902 var _this = this; 18903 var itemsToBeInsertedToDom = this.getItemsToBeInsertedToDom(index, prevIndex, this.settings.numberOfSlideItemsInDom); 18904 itemsToBeInsertedToDom.forEach(function (item) { 18905 if (_this.currentItemsInDom.indexOf(item) === -1) { 18906 _this.$inner.append("<div id=\"" + item + "\" class=\"lg-item\"></div>"); 18907 } 18908 }); 18909 this.currentItemsInDom.forEach(function (item) { 18910 if (itemsToBeInsertedToDom.indexOf(item) === -1) { 18911 $LG("#" + item).remove(); 18912 } 18913 }); 18914 return itemsToBeInsertedToDom; 18915 }; 18916 /** 18917 * Get previous index of the slide 18918 */ 18919 LightGallery.prototype.getPreviousSlideIndex = function () { 18920 var prevIndex = 0; 18921 try { 18922 var currentItemId = this.outer 18923 .find('.lg-current') 18924 .first() 18925 .attr('id'); 18926 prevIndex = parseInt(currentItemId.split('-')[3]) || 0; 18927 } 18928 catch (error) { 18929 prevIndex = 0; 18930 } 18931 return prevIndex; 18932 }; 18933 LightGallery.prototype.setDownloadValue = function (index) { 18934 if (this.settings.download) { 18935 var currentGalleryItem = this.galleryItems[index]; 18936 var hideDownloadBtn = currentGalleryItem.downloadUrl === false || 18937 currentGalleryItem.downloadUrl === 'false'; 18938 if (hideDownloadBtn) { 18939 this.outer.addClass('lg-hide-download'); 18940 } 18941 else { 18942 var $download = this.getElementById('lg-download'); 18943 this.outer.removeClass('lg-hide-download'); 18944 $download.attr('href', currentGalleryItem.downloadUrl || 18945 currentGalleryItem.src); 18946 if (currentGalleryItem.download) { 18947 //Uncode edit ##START## 18948 var currentVideo, download_url, download_name; 18949 if ( currentGalleryItem.video ) { 18950 currentVideo = JSON.parse( currentGalleryItem.video ); 18951 download_name = currentVideo.source[0].src; 18952 $download.attr('href', download_name).removeAttr('download'); 18953 } else { 18954 download_url = currentGalleryItem.downloadUrl || currentGalleryItem.src; 18955 download_name = download_url.substring(download_url.lastIndexOf('/')+1); 18956 $download.attr('download', download_name).removeAttr('href'); 18957 } 18958 // $download.attr('download', currentGalleryItem.download); 18959 //Uncode edit ##END## 18960 } 18961 } 18962 } 18963 }; 18964 LightGallery.prototype.makeSlideAnimation = function (direction, currentSlideItem, previousSlideItem) { 18965 var _this = this; 18966 if (this.lGalleryOn) { 18967 previousSlideItem.addClass('lg-slide-progress'); 18968 } 18969 setTimeout(function () { 18970 // remove all transitions 18971 _this.outer.addClass('lg-no-trans'); 18972 _this.outer 18973 .find('.lg-item') 18974 .removeClass('lg-prev-slide lg-next-slide'); 18975 if (direction === 'prev') { 18976 //prevslide 18977 currentSlideItem.addClass('lg-prev-slide'); 18978 previousSlideItem.addClass('lg-next-slide'); 18979 } 18980 else { 18981 // next slide 18982 currentSlideItem.addClass('lg-next-slide'); 18983 previousSlideItem.addClass('lg-prev-slide'); 18984 } 18985 // give 50 ms for browser to add/remove class 18986 setTimeout(function () { 18987 _this.outer.find('.lg-item').removeClass('lg-current'); 18988 currentSlideItem.addClass('lg-current'); 18989 // reset all transitions 18990 _this.outer.removeClass('lg-no-trans'); 18991 }, 50); 18992 }, this.lGalleryOn ? this.settings.slideDelay : 0); 18993 }; 18994 /** 18995 * Goto a specific slide. 18996 * @param {Number} index - index of the slide 18997 * @param {Boolean} fromTouch - true if slide function called via touch event or mouse drag 18998 * @param {Boolean} fromThumb - true if slide function called via thumbnail click 18999 * @param {String} direction - Direction of the slide(next/prev) 19000 * @category lGPublicMethods 19001 * @example 19002 * const plugin = lightGallery(); 19003 * // to go to 3rd slide 19004 * plugin.slide(2); 19005 * 19006 */ 19007 LightGallery.prototype.slide = function (index, fromTouch, fromThumb, direction) { 19008 var _this = this; 19009 var prevIndex = this.getPreviousSlideIndex(); 19010 this.currentItemsInDom = this.organizeSlideItems(index, prevIndex); 19011 // Prevent multiple call, Required for hsh plugin 19012 if (this.lGalleryOn && prevIndex === index) { 19013 return; 19014 } 19015 var numberOfGalleryItems = this.galleryItems.length; 19016 if (!this.lgBusy) { 19017 if (this.settings.counter) { 19018 this.updateCurrentCounter(index); 19019 } 19020 var currentSlideItem = this.getSlideItem(index); 19021 var previousSlideItem_1 = this.getSlideItem(prevIndex); 19022 var currentGalleryItem = this.galleryItems[index]; 19023 var videoInfo = currentGalleryItem.__slideVideoInfo; 19024 this.outer.attr('data-lg-slide-type', this.getSlideType(currentGalleryItem)); 19025 this.setDownloadValue(index); 19026 if (videoInfo) { 19027 var _a = this.mediaContainerPosition, top_3 = _a.top, bottom = _a.bottom; 19028 //Uncode edit ##START## 19029 var videoSize = utils.getSize(this.items[index], this.outer, top_3 + bottom, videoInfo && this.settings.videoMaxSize, this.galleryItems[this.index]); 19030 // var videoSize = utils.getSize(this.items[index], this.outer, top_3 + bottom, videoInfo && this.settings.videoMaxSize); 19031 //Uncode edit ##END## 19032 this.resizeVideoSlide(index, videoSize); 19033 } 19034 this.LGel.trigger(lGEvents.beforeSlide, { 19035 prevIndex: prevIndex, 19036 index: index, 19037 fromTouch: !!fromTouch, 19038 fromThumb: !!fromThumb, 19039 //Uncode edit ##START## 19040 currentSlide: currentSlideItem, 19041 previousSlide: previousSlideItem_1, 19042 info: currentGalleryItem, 19043 item: this.items[index] 19044 //Uncode edit ##END## 19045 }); 19046 this.lgBusy = true; 19047 clearTimeout(this.hideBarTimeout); 19048 this.arrowDisable(index); 19049 if (!direction) { 19050 if (index < prevIndex) { 19051 direction = 'prev'; 19052 } 19053 else if (index > prevIndex) { 19054 direction = 'next'; 19055 } 19056 } 19057 if (!fromTouch) { 19058 this.makeSlideAnimation(direction, currentSlideItem, previousSlideItem_1); 19059 } 19060 else { 19061 this.outer 19062 .find('.lg-item') 19063 .removeClass('lg-prev-slide lg-current lg-next-slide'); 19064 var touchPrev = void 0; 19065 var touchNext = void 0; 19066 if (numberOfGalleryItems > 2) { 19067 touchPrev = index - 1; 19068 touchNext = index + 1; 19069 if (index === 0 && prevIndex === numberOfGalleryItems - 1) { 19070 // next slide 19071 touchNext = 0; 19072 touchPrev = numberOfGalleryItems - 1; 19073 } 19074 else if (index === numberOfGalleryItems - 1 && 19075 prevIndex === 0) { 19076 // prev slide 19077 touchNext = 0; 19078 touchPrev = numberOfGalleryItems - 1; 19079 } 19080 } 19081 else { 19082 touchPrev = 0; 19083 touchNext = 1; 19084 } 19085 if (direction === 'prev') { 19086 this.getSlideItem(touchNext).addClass('lg-next-slide'); 19087 } 19088 else { 19089 this.getSlideItem(touchPrev).addClass('lg-prev-slide'); 19090 } 19091 currentSlideItem.addClass('lg-current'); 19092 } 19093 // Do not put load content in set timeout as it needs to load immediately when the gallery is opened 19094 if (!this.lGalleryOn) { 19095 this.loadContent(index, true); 19096 } 19097 else { 19098 setTimeout(function () { 19099 _this.loadContent(index, true); 19100 // Add title if this.settings.appendSubHtmlTo === lg-sub-html 19101 if (_this.settings.appendSubHtmlTo !== '.lg-item') { 19102 _this.addHtml(index); 19103 } 19104 }, this.settings.speed + 50 + (fromTouch ? 0 : this.settings.slideDelay)); 19105 } 19106 setTimeout(function () { 19107 _this.lgBusy = false; 19108 previousSlideItem_1.removeClass('lg-slide-progress'); 19109 _this.LGel.trigger(lGEvents.afterSlide, { 19110 prevIndex: prevIndex, 19111 index: index, 19112 fromTouch: fromTouch, 19113 fromThumb: fromThumb, 19114 }); 19115 }, (this.lGalleryOn ? this.settings.speed + 100 : 100) + (fromTouch ? 0 : this.settings.slideDelay)); 19116 } 19117 this.index = index; 19118 }; 19119 LightGallery.prototype.updateCurrentCounter = function (index) { 19120 this.getElementById('lg-counter-current').html(index + 1 + ''); 19121 }; 19122 LightGallery.prototype.updateCounterTotal = function () { 19123 this.getElementById('lg-counter-all').html(this.galleryItems.length + ''); 19124 }; 19125 LightGallery.prototype.getSlideType = function (item) { 19126 if (item.__slideVideoInfo) { 19127 return 'video'; 19128 } 19129 else if (item.iframe) { 19130 return 'iframe'; 19131 } 19132 //Uncode edit ##START## 19133 else if (typeof item.src !== '' && item.src.search(/.mp3|.m4a/i) > -1) { 19134 return 'audio'; 19135 } 19136 //Uncode edit ##END## 19137 else { 19138 return 'image'; 19139 } 19140 }; 19141 LightGallery.prototype.touchMove = function (startCoords, endCoords, e) { 19142 var distanceX = endCoords.pageX - startCoords.pageX; 19143 var distanceY = endCoords.pageY - startCoords.pageY; 19144 var allowSwipe = false; 19145 if (this.swipeDirection) { 19146 allowSwipe = true; 19147 } 19148 else { 19149 if (Math.abs(distanceX) > 15) { 19150 this.swipeDirection = 'horizontal'; 19151 allowSwipe = true; 19152 } 19153 else if (Math.abs(distanceY) > 15) { 19154 this.swipeDirection = 'vertical'; 19155 allowSwipe = true; 19156 } 19157 } 19158 if (!allowSwipe) { 19159 return; 19160 } 19161 var $currentSlide = this.getSlideItem(this.index); 19162 if (this.swipeDirection === 'horizontal') { 19163 e === null || e === void 0 ? void 0 : e.preventDefault(); 19164 // reset opacity and transition duration 19165 this.outer.addClass('lg-dragging'); 19166 // move current slide 19167 this.setTranslate($currentSlide, distanceX, 0); 19168 // move next and prev slide with current slide 19169 var width = $currentSlide.get().offsetWidth; 19170 var slideWidthAmount = (width * 15) / 100; 19171 var gutter = slideWidthAmount - Math.abs((distanceX * 10) / 100); 19172 this.setTranslate(this.outer.find('.lg-prev-slide').first(), -width + distanceX - gutter, 0); 19173 this.setTranslate(this.outer.find('.lg-next-slide').first(), width + distanceX + gutter, 0); 19174 } 19175 else if (this.swipeDirection === 'vertical') { 19176 if (this.settings.swipeToClose) { 19177 e === null || e === void 0 ? void 0 : e.preventDefault(); 19178 this.$container.addClass('lg-dragging-vertical'); 19179 var opacity = 1 - Math.abs(distanceY) / window.innerHeight; 19180 this.$backdrop.css('opacity', opacity); 19181 var scale = 1 - Math.abs(distanceY) / (window.innerWidth * 2); 19182 this.setTranslate($currentSlide, 0, distanceY, scale, scale); 19183 if (Math.abs(distanceY) > 100) { 19184 this.outer 19185 .addClass('lg-hide-items') 19186 .removeClass('lg-components-open'); 19187 } 19188 } 19189 } 19190 }; 19191 LightGallery.prototype.touchEnd = function (endCoords, startCoords, event) { 19192 var _this = this; 19193 var distance; 19194 // keep slide animation for any mode while dragg/swipe 19195 if (this.settings.mode !== 'lg-slide') { 19196 this.outer.addClass('lg-slide'); 19197 } 19198 // set transition duration 19199 setTimeout(function () { 19200 _this.$container.removeClass('lg-dragging-vertical'); 19201 _this.outer 19202 .removeClass('lg-dragging lg-hide-items') 19203 .addClass('lg-components-open'); 19204 var triggerClick = true; 19205 if (_this.swipeDirection === 'horizontal') { 19206 distance = endCoords.pageX - startCoords.pageX; 19207 var distanceAbs = Math.abs(endCoords.pageX - startCoords.pageX); 19208 if (distance < 0 && 19209 distanceAbs > _this.settings.swipeThreshold) { 19210 _this.goToNextSlide(true); 19211 triggerClick = false; 19212 } 19213 else if (distance > 0 && 19214 distanceAbs > _this.settings.swipeThreshold) { 19215 _this.goToPrevSlide(true); 19216 triggerClick = false; 19217 } 19218 } 19219 else if (_this.swipeDirection === 'vertical') { 19220 distance = Math.abs(endCoords.pageY - startCoords.pageY); 19221 if (_this.settings.closable && 19222 _this.settings.swipeToClose && 19223 distance > 100) { 19224 _this.closeGallery(); 19225 return; 19226 } 19227 else { 19228 _this.$backdrop.css('opacity', 1); 19229 } 19230 } 19231 _this.outer.find('.lg-item').removeAttr('style'); 19232 if (triggerClick && 19233 Math.abs(endCoords.pageX - startCoords.pageX) < 5) { 19234 // Trigger click if distance is less than 5 pix 19235 var target = $LG(event.target); 19236 if (_this.isPosterElement(target)) { 19237 _this.LGel.trigger(lGEvents.posterClick); 19238 } 19239 } 19240 _this.swipeDirection = undefined; 19241 }); 19242 // remove slide class once drag/swipe is completed if mode is not slide 19243 setTimeout(function () { 19244 if (!_this.outer.hasClass('lg-dragging') && 19245 _this.settings.mode !== 'lg-slide') { 19246 _this.outer.removeClass('lg-slide'); 19247 } 19248 }, this.settings.speed + 100); 19249 }; 19250 LightGallery.prototype.enableSwipe = function () { 19251 var _this = this; 19252 var startCoords = {}; 19253 var endCoords = {}; 19254 var isMoved = false; 19255 var isSwiping = false; 19256 if (this.settings.enableSwipe) { 19257 this.$inner.on('touchstart.lg', function (e) { 19258 _this.dragOrSwipeEnabled = true; 19259 var $item = _this.getSlideItem(_this.index); 19260 if (($LG(e.target).hasClass('lg-item') || 19261 $item.get().contains(e.target)) && 19262 !_this.outer.hasClass('lg-zoomed') && 19263 !_this.lgBusy && 19264 e.targetTouches.length === 1) { 19265 isSwiping = true; 19266 _this.touchAction = 'swipe'; 19267 _this.manageSwipeClass(); 19268 startCoords = { 19269 pageX: e.targetTouches[0].pageX, 19270 pageY: e.targetTouches[0].pageY, 19271 }; 19272 } 19273 }); 19274 this.$inner.on('touchmove.lg', function (e) { 19275 if (isSwiping && 19276 _this.touchAction === 'swipe' && 19277 e.targetTouches.length === 1) { 19278 endCoords = { 19279 pageX: e.targetTouches[0].pageX, 19280 pageY: e.targetTouches[0].pageY, 19281 }; 19282 _this.touchMove(startCoords, endCoords, e); 19283 isMoved = true; 19284 } 19285 }); 19286 this.$inner.on('touchend.lg', function (event) { 19287 if (_this.touchAction === 'swipe') { 19288 if (isMoved) { 19289 isMoved = false; 19290 _this.touchEnd(endCoords, startCoords, event); 19291 } 19292 else if (isSwiping) { 19293 var target = $LG(event.target); 19294 if (_this.isPosterElement(target)) { 19295 _this.LGel.trigger(lGEvents.posterClick); 19296 } 19297 } 19298 _this.touchAction = undefined; 19299 isSwiping = false; 19300 } 19301 }); 19302 } 19303 }; 19304 LightGallery.prototype.enableDrag = function () { 19305 var _this = this; 19306 var startCoords = {}; 19307 var endCoords = {}; 19308 var isDraging = false; 19309 var isMoved = false; 19310 if (this.settings.enableDrag) { 19311 this.outer.on('mousedown.lg', function (e) { 19312 _this.dragOrSwipeEnabled = true; 19313 var $item = _this.getSlideItem(_this.index); 19314 if ($LG(e.target).hasClass('lg-item') || 19315 $item.get().contains(e.target)) { 19316 if (!_this.outer.hasClass('lg-zoomed') && !_this.lgBusy) { 19317 e.preventDefault(); 19318 if (!_this.lgBusy) { 19319 _this.manageSwipeClass(); 19320 startCoords = { 19321 pageX: e.pageX, 19322 pageY: e.pageY, 19323 }; 19324 isDraging = true; 19325 // ** Fix for webkit cursor issue https://code.google.com/p/chromium/issues/detail?id=26723 19326 _this.outer.get().scrollLeft += 1; 19327 _this.outer.get().scrollLeft -= 1; 19328 // * 19329 _this.outer 19330 .removeClass('lg-grab') 19331 .addClass('lg-grabbing'); 19332 _this.LGel.trigger(lGEvents.dragStart); 19333 } 19334 } 19335 } 19336 }); 19337 $LG(window).on("mousemove.lg.global" + this.lgId, function (e) { 19338 if (isDraging && _this.lgOpened) { 19339 isMoved = true; 19340 endCoords = { 19341 pageX: e.pageX, 19342 pageY: e.pageY, 19343 }; 19344 _this.touchMove(startCoords, endCoords); 19345 _this.LGel.trigger(lGEvents.dragMove); 19346 } 19347 }); 19348 $LG(window).on("mouseup.lg.global" + this.lgId, function (event) { 19349 if (!_this.lgOpened) { 19350 return; 19351 } 19352 var target = $LG(event.target); 19353 if (isMoved) { 19354 isMoved = false; 19355 _this.touchEnd(endCoords, startCoords, event); 19356 _this.LGel.trigger(lGEvents.dragEnd); 19357 } 19358 else if (_this.isPosterElement(target)) { 19359 _this.LGel.trigger(lGEvents.posterClick); 19360 } 19361 // Prevent execution on click 19362 if (isDraging) { 19363 isDraging = false; 19364 _this.outer.removeClass('lg-grabbing').addClass('lg-grab'); 19365 } 19366 }); 19367 } 19368 }; 19369 LightGallery.prototype.triggerPosterClick = function () { 19370 var _this = this; 19371 this.$inner.on('click.lg', function (event) { 19372 if (!_this.dragOrSwipeEnabled && 19373 _this.isPosterElement($LG(event.target))) { 19374 _this.LGel.trigger(lGEvents.posterClick); 19375 } 19376 }); 19377 }; 19378 LightGallery.prototype.manageSwipeClass = function () { 19379 var _touchNext = this.index + 1; 19380 var _touchPrev = this.index - 1; 19381 if (this.settings.loop && this.galleryItems.length > 2) { 19382 if (this.index === 0) { 19383 _touchPrev = this.galleryItems.length - 1; 19384 } 19385 else if (this.index === this.galleryItems.length - 1) { 19386 _touchNext = 0; 19387 } 19388 } 19389 this.outer.find('.lg-item').removeClass('lg-next-slide lg-prev-slide'); 19390 if (_touchPrev > -1) { 19391 this.getSlideItem(_touchPrev).addClass('lg-prev-slide'); 19392 } 19393 this.getSlideItem(_touchNext).addClass('lg-next-slide'); 19394 }; 19395 /** 19396 * Go to next slide 19397 * @param {Boolean} fromTouch - true if slide function called via touch event 19398 * @category lGPublicMethods 19399 * @example 19400 * const plugin = lightGallery(); 19401 * plugin.goToNextSlide(); 19402 * @see <a href="/demos/methods/">Demo</a> 19403 */ 19404 LightGallery.prototype.goToNextSlide = function (fromTouch) { 19405 var _this = this; 19406 var _loop = this.settings.loop; 19407 if (fromTouch && this.galleryItems.length < 3) { 19408 _loop = false; 19409 } 19410 if (!this.lgBusy) { 19411 if (this.index + 1 < this.galleryItems.length) { 19412 this.index++; 19413 this.LGel.trigger(lGEvents.beforeNextSlide, { 19414 index: this.index, 19415 }); 19416 this.slide(this.index, !!fromTouch, false, 'next'); 19417 } 19418 else { 19419 if (_loop) { 19420 this.index = 0; 19421 this.LGel.trigger(lGEvents.beforeNextSlide, { 19422 index: this.index, 19423 }); 19424 this.slide(this.index, !!fromTouch, false, 'next'); 19425 } 19426 else if (this.settings.slideEndAnimation && !fromTouch) { 19427 this.outer.addClass('lg-right-end'); 19428 setTimeout(function () { 19429 _this.outer.removeClass('lg-right-end'); 19430 }, 400); 19431 } 19432 } 19433 } 19434 }; 19435 /** 19436 * Go to previous slides 19437 * @param {Boolean} fromTouch - true if slide function called via touch event 19438 * @category lGPublicMethods 19439 * @example 19440 * const plugin = lightGallery({}); 19441 * plugin.goToPrevSlide(); 19442 * @see <a href="/demos/methods/">Demo</a> 19443 * 19444 */ 19445 LightGallery.prototype.goToPrevSlide = function (fromTouch) { 19446 var _this = this; 19447 var _loop = this.settings.loop; 19448 if (fromTouch && this.galleryItems.length < 3) { 19449 _loop = false; 19450 } 19451 if (!this.lgBusy) { 19452 if (this.index > 0) { 19453 this.index--; 19454 this.LGel.trigger(lGEvents.beforePrevSlide, { 19455 index: this.index, 19456 fromTouch: fromTouch, 19457 }); 19458 this.slide(this.index, !!fromTouch, false, 'prev'); 19459 } 19460 else { 19461 if (_loop) { 19462 this.index = this.galleryItems.length - 1; 19463 this.LGel.trigger(lGEvents.beforePrevSlide, { 19464 index: this.index, 19465 fromTouch: fromTouch, 19466 }); 19467 this.slide(this.index, !!fromTouch, false, 'prev'); 19468 } 19469 else if (this.settings.slideEndAnimation && !fromTouch) { 19470 this.outer.addClass('lg-left-end'); 19471 setTimeout(function () { 19472 _this.outer.removeClass('lg-left-end'); 19473 }, 400); 19474 } 19475 } 19476 } 19477 }; 19478 LightGallery.prototype.keyPress = function () { 19479 var _this = this; 19480 $LG(window).on("keydown.lg.global" + this.lgId, function (e) { 19481 if (_this.lgOpened && 19482 _this.settings.escKey === true && 19483 e.keyCode === 27) { 19484 e.preventDefault(); 19485 if (_this.settings.allowMediaOverlap && 19486 _this.outer.hasClass('lg-can-toggle') && 19487 _this.outer.hasClass('lg-components-open')) { 19488 _this.outer.removeClass('lg-components-open'); 19489 } 19490 else { 19491 _this.closeGallery(); 19492 } 19493 } 19494 if (_this.lgOpened && _this.galleryItems.length > 1) { 19495 if (e.keyCode === 37) { 19496 e.preventDefault(); 19497 _this.goToPrevSlide(); 19498 } 19499 if (e.keyCode === 39) { 19500 e.preventDefault(); 19501 _this.goToNextSlide(); 19502 } 19503 } 19504 }); 19505 }; 19506 LightGallery.prototype.arrow = function () { 19507 var _this = this; 19508 this.getElementById('lg-prev').on('click.lg', function () { 19509 _this.goToPrevSlide(); 19510 }); 19511 this.getElementById('lg-next').on('click.lg', function () { 19512 _this.goToNextSlide(); 19513 }); 19514 }; 19515 LightGallery.prototype.arrowDisable = function (index) { 19516 // Disable arrows if settings.hideControlOnEnd is true 19517 if (!this.settings.loop && this.settings.hideControlOnEnd) { 19518 var $prev = this.getElementById('lg-prev'); 19519 var $next = this.getElementById('lg-next'); 19520 if (index + 1 === this.galleryItems.length) { 19521 $next.attr('disabled', 'disabled').addClass('disabled'); 19522 } 19523 else { 19524 $next.removeAttr('disabled').removeClass('disabled'); 19525 } 19526 if (index === 0) { 19527 $prev.attr('disabled', 'disabled').addClass('disabled'); 19528 } 19529 else { 19530 $prev.removeAttr('disabled').removeClass('disabled'); 19531 } 19532 } 19533 }; 19534 LightGallery.prototype.setTranslate = function ($el, xValue, yValue, scaleX, scaleY) { 19535 if (scaleX === void 0) { scaleX = 1; } 19536 if (scaleY === void 0) { scaleY = 1; } 19537 $el.css('transform', 'translate3d(' + 19538 xValue + 19539 'px, ' + 19540 yValue + 19541 'px, 0px) scale3d(' + 19542 scaleX + 19543 ', ' + 19544 scaleY + 19545 ', 1)'); 19546 }; 19547 LightGallery.prototype.mousewheel = function () { 19548 var _this = this; 19549 var lastCall = 0; 19550 this.outer.on('wheel.lg', function (e) { 19551 if (!e.deltaY || _this.galleryItems.length < 2) { 19552 return; 19553 } 19554 e.preventDefault(); 19555 var now = new Date().getTime(); 19556 if (now - lastCall < 1000) { 19557 return; 19558 } 19559 lastCall = now; 19560 if (e.deltaY > 0) { 19561 _this.goToNextSlide(); 19562 } 19563 else if (e.deltaY < 0) { 19564 _this.goToPrevSlide(); 19565 } 19566 }); 19567 }; 19568 LightGallery.prototype.isSlideElement = function (target) { 19569 return (target.hasClass('lg-outer') || 19570 target.hasClass('lg-item') || 19571 target.hasClass('lg-img-wrap')); 19572 }; 19573 LightGallery.prototype.isPosterElement = function (target) { 19574 var playButton = this.getSlideItem(this.index) 19575 .find('.lg-video-play-button') 19576 .get(); 19577 return (target.hasClass('lg-video-poster') || 19578 target.hasClass('lg-video-play-button') || 19579 (playButton && playButton.contains(target.get()))); 19580 }; 19581 /** 19582 * Maximize minimize inline gallery. 19583 * @category lGPublicMethods 19584 */ 19585 LightGallery.prototype.toggleMaximize = function () { 19586 var _this = this; 19587 this.getElementById('lg-maximize').on('click.lg', function () { 19588 _this.$container.toggleClass('lg-inline'); 19589 _this.refreshOnResize(); 19590 }); 19591 }; 19592 LightGallery.prototype.invalidateItems = function () { 19593 for (var index = 0; index < this.items.length; index++) { 19594 var element = this.items[index]; 19595 var $element = $LG(element); 19596 $element.off("click.lgcustom-item-" + $element.attr('data-lg-id')); 19597 } 19598 }; 19599 LightGallery.prototype.trapFocus = function () { 19600 var _this = this; 19601 this.$container.get().focus({ 19602 preventScroll: true, 19603 }); 19604 $LG(window).on("keydown.lg.global" + this.lgId, function (e) { 19605 if (!_this.lgOpened) { 19606 return; 19607 } 19608 var isTabPressed = e.key === 'Tab' || e.keyCode === 9; 19609 if (!isTabPressed) { 19610 return; 19611 } 19612 var focusableEls = utils.getFocusableElements(_this.$container.get()); 19613 var firstFocusableEl = focusableEls[0]; 19614 var lastFocusableEl = focusableEls[focusableEls.length - 1]; 19615 if (e.shiftKey) { 19616 if (document.activeElement === firstFocusableEl) { 19617 lastFocusableEl.focus(); 19618 e.preventDefault(); 19619 } 19620 } 19621 else { 19622 if (document.activeElement === lastFocusableEl) { 19623 firstFocusableEl.focus(); 19624 e.preventDefault(); 19625 } 19626 } 19627 }); 19628 }; 19629 LightGallery.prototype.manageCloseGallery = function () { 19630 var _this = this; 19631 if (!this.settings.closable) 19632 return; 19633 var mousedown = false; 19634 this.getElementById('lg-close').on('click.lg', function () { 19635 _this.closeGallery(); 19636 }); 19637 if (this.settings.closeOnTap) { 19638 // If you drag the slide and release outside gallery gets close on chrome 19639 // for preventing this check mousedown and mouseup happened on .lg-item or lg-outer 19640 this.outer.on('mousedown.lg', function (e) { 19641 var target = $LG(e.target); 19642 if (_this.isSlideElement(target)) { 19643 mousedown = true; 19644 } 19645 else { 19646 mousedown = false; 19647 } 19648 }); 19649 this.outer.on('mousemove.lg', function () { 19650 mousedown = false; 19651 }); 19652 this.outer.on('mouseup.lg', function (e) { 19653 var target = $LG(e.target); 19654 if (_this.isSlideElement(target) && mousedown) { 19655 if (!_this.outer.hasClass('lg-dragging')) { 19656 _this.closeGallery(); 19657 } 19658 } 19659 }); 19660 } 19661 }; 19662 /** 19663 * Close lightGallery if it is opened. 19664 * 19665 * @description If closable is false in the settings, you need to pass true via closeGallery method to force close gallery 19666 * @return returns the estimated time to close gallery completely including the close animation duration 19667 * @category lGPublicMethods 19668 * @example 19669 * const plugin = lightGallery(); 19670 * plugin.closeGallery(); 19671 * 19672 */ 19673 LightGallery.prototype.closeGallery = function (force) { 19674 var _this = this; 19675 if (!this.lgOpened || (!this.settings.closable && !force)) { 19676 return 0; 19677 } 19678 this.LGel.trigger(lGEvents.beforeClose); 19679 if (this.settings.resetScrollPosition && !this.settings.hideScrollbar) { 19680 $LG(window).scrollTop(this.prevScrollTop); 19681 } 19682 var currentItem = this.items[this.index]; 19683 var transform; 19684 if (this.zoomFromOrigin && currentItem) { 19685 var _a = this.mediaContainerPosition, top_4 = _a.top, bottom = _a.bottom; 19686 var _b = this.galleryItems[this.index], __slideVideoInfo = _b.__slideVideoInfo, poster = _b.poster; 19687 //Uncode edit ##START## 19688 var imageSize = utils.getSize(currentItem, this.outer, top_4 + bottom, __slideVideoInfo && poster && this.settings.videoMaxSize, this.galleryItems[this.index]); 19689 // var imageSize = utils.getSize(currentItem, this.outer, top_4 + bottom, __slideVideoInfo && poster && this.settings.videoMaxSize); 19690 //Uncode edit ##END## 19691 transform = utils.getTransform(currentItem, this.outer, top_4, bottom, imageSize); 19692 } 19693 if (this.zoomFromOrigin && transform) { 19694 this.outer.addClass('lg-closing lg-zoom-from-image'); 19695 this.getSlideItem(this.index) 19696 .addClass('lg-start-end-progress') 19697 .css('transition-duration', this.settings.startAnimationDuration + 'ms') 19698 .css('transform', transform); 19699 } 19700 else { 19701 this.outer.addClass('lg-hide-items'); 19702 // lg-zoom-from-image is used for setting the opacity to 1 if zoomFromOrigin is true 19703 // If the closing item doesn't have the lg-size attribute, remove this class to avoid the closing css conflicts 19704 this.outer.removeClass('lg-zoom-from-image'); 19705 } 19706 // Unbind all events added by lightGallery 19707 // @todo 19708 //this.$el.off('.lg.tm'); 19709 this.destroyModules(); 19710 this.lGalleryOn = false; 19711 this.isDummyImageRemoved = false; 19712 this.zoomFromOrigin = this.settings.zoomFromOrigin; 19713 clearTimeout(this.hideBarTimeout); 19714 this.hideBarTimeout = false; 19715 $LG('html').removeClass('lg-on'); 19716 this.outer.removeClass('lg-visible lg-components-open'); 19717 // Resetting opacity to 0 isd required as vertical swipe to close function adds inline opacity. 19718 this.$backdrop.removeClass('in').css('opacity', 0); 19719 var removeTimeout = this.zoomFromOrigin && transform 19720 ? Math.max(this.settings.startAnimationDuration, this.settings.backdropDuration) 19721 : this.settings.backdropDuration; 19722 this.$container.removeClass('lg-show-in'); 19723 // Once the closign animation is completed and gallery is invisible 19724 setTimeout(function () { 19725 if (_this.zoomFromOrigin && transform) { 19726 _this.outer.removeClass('lg-zoom-from-image'); 19727 } 19728 _this.$container.removeClass('lg-show'); 19729 // Reset scrollbar 19730 _this.resetScrollBar(); 19731 // Need to remove inline opacity as it is used in the stylesheet as well 19732 _this.$backdrop 19733 .removeAttr('style') 19734 .css('transition-duration', _this.settings.backdropDuration + 'ms'); 19735 _this.outer.removeClass("lg-closing " + _this.settings.startClass);
vendor: 6,259 bytes, lines 19736-19939
19736 _this.getSlideItem(_this.index).removeClass('lg-start-end-progress'); 19737 _this.$inner.empty(); 19738 if (_this.lgOpened) { 19739 _this.LGel.trigger(lGEvents.afterClose, { 19740 instance: _this, 19741 }); 19742 } 19743 if (_this.$container.get()) { 19744 _this.$container.get().blur(); 19745 } 19746 _this.lgOpened = false; 19747 }, removeTimeout + 100); 19748 return removeTimeout + 100; 19749 }; 19750 LightGallery.prototype.initModules = function () { 19751 this.plugins.forEach(function (module) { 19752 try { 19753 module.init(); 19754 } 19755 catch (err) { 19756 console.warn("lightGallery:- make sure lightGallery module is properly initiated"); 19757 } 19758 }); 19759 }; 19760 LightGallery.prototype.destroyModules = function (destroy) { 19761 this.plugins.forEach(function (module) { 19762 try { 19763 if (destroy) { 19764 module.destroy(); 19765 } 19766 else { 19767 module.closeGallery && module.closeGallery(); 19768 } 19769 } 19770 catch (err) { 19771 console.warn("lightGallery:- make sure lightGallery module is properly destroyed"); 19772 } 19773 }); 19774 }; 19775 /** 19776 * Refresh lightGallery with new set of children. 19777 * 19778 * @description This is useful to update the gallery when the child elements are changed without calling destroy method. 19779 * 19780 * If you are using dynamic mode, you can pass the modified array of dynamicEl as the first parameter to refresh the dynamic gallery 19781 * @see <a href="/demos/dynamic-mode/">Demo</a> 19782 * @category lGPublicMethods 19783 * @example 19784 * const plugin = lightGallery(); 19785 * // Delete or add children, then call 19786 * plugin.refresh(); 19787 * 19788 */ 19789 LightGallery.prototype.refresh = function (galleryItems) { 19790 if (!this.settings.dynamic) { 19791 this.invalidateItems(); 19792 } 19793 if (galleryItems) { 19794 this.galleryItems = galleryItems; 19795 } 19796 else { 19797 this.galleryItems = this.getItems(); 19798 } 19799 this.updateControls(); 19800 this.openGalleryOnItemClick(); 19801 this.LGel.trigger(lGEvents.updateSlides); 19802 }; 19803 LightGallery.prototype.updateControls = function () { 19804 this.addSlideVideoInfo(this.galleryItems); 19805 this.updateCounterTotal(); 19806 this.manageSingleSlideClassName(); 19807 }; 19808 /** 19809 * Destroy lightGallery. 19810 * Destroy lightGallery and its plugin instances completely 19811 * 19812 * @description This method also calls CloseGallery function internally. Returns the time takes to completely close and destroy the instance. 19813 * In case if you want to re-initialize lightGallery right after destroying it, initialize it only once the destroy process is completed. 19814 * You can use refresh method most of the times. 19815 * @category lGPublicMethods 19816 * @example 19817 * const plugin = lightGallery(); 19818 * plugin.destroy(); 19819 * 19820 */ 19821 LightGallery.prototype.destroy = function () { 19822 var _this = this; 19823 var closeTimeout = this.closeGallery(true); 19824 setTimeout(function () { 19825 _this.destroyModules(true); 19826 if (!_this.settings.dynamic) { 19827 _this.invalidateItems(); 19828 } 19829 $LG(window).off(".lg.global" + _this.lgId); 19830 _this.LGel.off('.lg'); 19831 _this.$container.remove(); 19832 }, closeTimeout); 19833 return closeTimeout; 19834 }; 19835 return LightGallery; 19836 }()); 19837 19838 function lightGallery(el, options) { 19839 return new LightGallery(el, options); 19840 } 19841 19842 return lightGallery; 19843 19844}))); 19845 19846/*! 19847 * lightgallery | 2.5.0 | June 13th 2022 19848 * http://www.lightgalleryjs.com/ 19849 * Copyright (c) 2020 Sachin Neravath; 19850 * @license GPLv3 19851 */ 19852 19853(function (global, factory) { 19854 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 19855 typeof define === 'function' && define.amd ? define(factory) : 19856 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lgZoom = factory()); 19857}(this, (function () { 'use strict'; 19858 19859 /*! ***************************************************************************** 19860 Copyright (c) Microsoft Corporation. 19861 19862 Permission to use, copy, modify, and/or distribute this software for any 19863 purpose with or without fee is hereby granted. 19864 19865 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 19866 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 19867 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 19868 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 19869 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 19870 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 19871 PERFORMANCE OF THIS SOFTWARE. 19872 ***************************************************************************** */ 19873 19874 var __assign = function() { 19875 __assign = Object.assign || function __assign(t) { 19876 for (var s, i = 1, n = arguments.length; i < n; i++) { 19877 s = arguments[i]; 19878 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 19879 } 19880 return t; 19881 }; 19882 return __assign.apply(this, arguments); 19883 }; 19884 19885 var zoomSettings = { 19886 scale: 1, 19887 zoom: true, 19888 actualSize: true, 19889 showZoomInOutIcons: false, 19890 actualSizeIcons: { 19891 zoomIn: 'lg-zoom-in', 19892 zoomOut: 'lg-zoom-out', 19893 }, 19894 enableZoomAfter: 300, 19895 zoomPluginStrings: { 19896 zoomIn: 'Zoom in', 19897 zoomOut: 'Zoom out', 19898 viewActualSize: 'View actual size', 19899 }, 19900 }; 19901 19902 /** 19903 * List of lightGallery events 19904 * All events should be documented here 19905 * Below interfaces are used to build the website documentations 19906 * */ 19907 var lGEvents = { 19908 afterAppendSlide: 'lgAfterAppendSlide', 19909 init: 'lgInit', 19910 hasVideo: 'lgHasVideo', 19911 containerResize: 'lgContainerResize', 19912 updateSlides: 'lgUpdateSlides', 19913 afterAppendSubHtml: 'lgAfterAppendSubHtml', 19914 beforeOpen: 'lgBeforeOpen', 19915 afterOpen: 'lgAfterOpen', 19916 slideItemLoad: 'lgSlideItemLoad', 19917 beforeSlide: 'lgBeforeSlide', 19918 afterSlide: 'lgAfterSlide', 19919 posterClick: 'lgPosterClick', 19920 dragStart: 'lgDragStart', 19921 dragMove: 'lgDragMove', 19922 dragEnd: 'lgDragEnd', 19923 beforeNextSlide: 'lgBeforeNextSlide', 19924 beforePrevSlide: 'lgBeforePrevSlide', 19925 beforeClose: 'lgBeforeClose', 19926 afterClose: 'lgAfterClose', 19927 rotateLeft: 'lgRotateLeft', 19928 rotateRight: 'lgRotateRight', 19929 flipHorizontal: 'lgFlipHorizontal', 19930 flipVertical: 'lgFlipVertical', 19931 autoplay: 'lgAutoplay', 19932 autoplayStart: 'lgAutoplayStart', 19933 autoplayStop: 'lgAutoplayStop', 19934 }; 19935 19936 var Zoom = /** @class */ (function () { 19937 function Zoom(instance, $LG) { 19938 // get lightGallery core plugin instance 19939 this.core = instance;
19940 this.$LG = $LG; 19941 this.settings = __assign(__assign({}, zoomSettings), this.core.settings); 19942 return this; 19943 } 19944 // Append Zoom controls. Actual size, Zoom-in, Zoom-out 19945 Zoom.prototype.buildTemplates = function () { 19946 var zoomIcons = this.settings.showZoomInOutIcons 19947 ? "<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>" 19948 : ''; 19949 if (this.settings.actualSize) { 19950 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>"; 19951 } 19952 this.core.outer.addClass('lg-use-transition-for-zoom'); 19953 this.core.$toolbar.first().append(zoomIcons); 19954 }; 19955 /** 19956 * @desc Enable zoom option only once the image is completely loaded 19957 * If zoomFromOrigin is true, Zoom is enabled once the dummy image has been inserted 19958 * 19959 * Zoom styles are defined under lg-zoomable CSS class. 19960 */ 19961 Zoom.prototype.enableZoom = function (event) { 19962 var _this = this; 19963 // delay will be 0 except first time 19964 var _speed = this.settings.enableZoomAfter + event.detail.delay; 19965 // set _speed value 0 if gallery opened from direct url and if it is first slide 19966 if (this.$LG('body').first().hasClass('lg-from-hash') && 19967 event.detail.delay) { 19968 // will execute only once 19969 _speed = 0; 19970 } 19971 else { 19972 // Remove lg-from-hash to enable starting animation. 19973 this.$LG('body').first().removeClass('lg-from-hash'); 19974 } 19975 this.zoomableTimeout = setTimeout(function () { 19976 if (!_this.isImageSlide()) { 19977 return; 19978 } 19979 _this.core.getSlideItem(event.detail.index).addClass('lg-zoomable'); 19980 if (event.detail.index === _this.core.index) { 19981 _this.setZoomEssentials(); 19982 } 19983 }, _speed + 30); 19984 }; 19985 Zoom.prototype.enableZoomOnSlideItemLoad = function () { 19986 // Add zoomable class 19987 this.core.LGel.on(lGEvents.slideItemLoad + ".zoom", this.enableZoom.bind(this)); 19988 }; 19989 Zoom.prototype.getModifier = function (rotateValue, axis, el) { 19990 var originalRotate = rotateValue; 19991 rotateValue = Math.abs(rotateValue); 19992 var transformValues = this.getCurrentTransform(el); 19993 if (!transformValues) { 19994 return 1; 19995 } 19996 var modifier = 1; 19997 if (axis === 'X') { 19998 var flipHorizontalValue = Math.sign(parseFloat(transformValues[0])); 19999 if (rotateValue === 0 || rotateValue === 180) { 20000 modifier = 1; 20001 } 20002 else if (rotateValue === 90) { 20003 if ((originalRotate === -90 && flipHorizontalValue === 1) || 20004 (originalRotate === 90 && flipHorizontalValue === -1)) { 20005 modifier = -1; 20006 } 20007 else { 20008 modifier = 1; 20009 } 20010 } 20011 modifier = modifier * flipHorizontalValue; 20012 } 20013 else { 20014 var flipVerticalValue = Math.sign(parseFloat(transformValues[3])); 20015 if (rotateValue === 0 || rotateValue === 180) { 20016 modifier = 1; 20017 } 20018 else if (rotateValue === 90) { 20019 var sinX = parseFloat(transformValues[1]); 20020 var sinMinusX = parseFloat(transformValues[2]); 20021 modifier = Math.sign(sinX * sinMinusX * originalRotate * flipVerticalValue); 20022 } 20023 modifier = modifier * flipVerticalValue; 20024 } 20025 return modifier; 20026 }; 20027 Zoom.prototype.getImageSize = function ($image, rotateValue, axis) { 20028 var imageSizes = { 20029 y: 'offsetHeight', 20030 x: 'offsetWidth', 20031 }; 20032 if (Math.abs(rotateValue) === 90) { 20033 // Swap axis 20034 if (axis === 'x') { 20035 axis = 'y'; 20036 } 20037 else { 20038 axis = 'x'; 20039 } 20040 } 20041 return $image[imageSizes[axis]]; 20042 }; 20043 Zoom.prototype.getDragCords = function (e, rotateValue) { 20044 if (rotateValue === 90) { 20045 return { 20046 x: e.pageY, 20047 y: e.pageX, 20048 }; 20049 } 20050 else { 20051 return { 20052 x: e.pageX, 20053 y: e.pageY, 20054 }; 20055 } 20056 }; 20057 Zoom.prototype.getSwipeCords = function (e, rotateValue) { 20058 var x = e.targetTouches[0].pageX; 20059 var y = e.targetTouches[0].pageY; 20060 if (rotateValue === 90) { 20061 return { 20062 x: y, 20063 y: x, 20064 }; 20065 } 20066 else { 20067 return { 20068 x: x, 20069 y: y, 20070 }; 20071 } 20072 }; 20073 Zoom.prototype.getDragAllowedAxises = function (rotateValue, scale) { 20074 scale = scale || this.scale || 1; 20075 var allowY = this.imageYSize * scale > this.containerRect.height; 20076 var allowX = this.imageXSize * scale > this.containerRect.width; 20077 if (rotateValue === 90) { 20078 return { 20079 allowX: allowY, 20080 allowY: allowX, 20081 }; 20082 } 20083 else { 20084 return { 20085 allowX: allowX, 20086 allowY: allowY, 20087 }; 20088 } 20089 }; 20090 /** 20091 * 20092 * @param {Element} el 20093 * @return matrix(cos(X), sin(X), -sin(X), cos(X), 0, 0); 20094 * Get the current transform value 20095 */ 20096 Zoom.prototype.getCurrentTransform = function (el) { 20097 if (!el) { 20098 return; 20099 } 20100 var st = window.getComputedStyle(el, null); 20101 var tm = st.getPropertyValue('-webkit-transform') || 20102 st.getPropertyValue('-moz-transform') || 20103 st.getPropertyValue('-ms-transform') || 20104 st.getPropertyValue('-o-transform') || 20105 st.getPropertyValue('transform') || 20106 'none'; 20107 if (tm !== 'none') { 20108 return tm.split('(')[1].split(')')[0].split(','); 20109 } 20110 return; 20111 }; 20112 Zoom.prototype.getCurrentRotation = function (el) { 20113 if (!el) { 20114 return 0; 20115 } 20116 var values = this.getCurrentTransform(el); 20117 if (values) { 20118 return Math.round(Math.atan2(parseFloat(values[1]), parseFloat(values[0])) * 20119 (180 / Math.PI)); 20120 // If you want rotate in 360 20121 //return (angle < 0 ? angle + 360 : angle); 20122 } 20123 return 0; 20124 }; 20125 Zoom.prototype.setZoomEssentials = function () { 20126 var $image = this.core 20127 .getSlideItem(this.core.index) 20128 .find('.lg-image') 20129 .first(); 20130 var rotateEl = this.core 20131 .getSlideItem(this.core.index) 20132 .find('.lg-img-rotate') 20133 .first() 20134 .get(); 20135 this.rotateValue = this.getCurrentRotation(rotateEl); 20136 this.imageYSize = this.getImageSize($image.get(), this.rotateValue, 'y'); 20137 this.imageXSize = this.getImageSize($image.get(), this.rotateValue, 'x'); 20138 this.containerRect = this.core.outer.get().getBoundingClientRect(); 20139 this.modifierX = this.getModifier(this.rotateValue, 'X', rotateEl); 20140 this.modifierY = this.getModifier(this.rotateValue, 'Y', rotateEl); 20141 }; 20142 /** 20143 * @desc Image zoom 20144 * Translate the wrap and scale the image to get better user experience 20145 * 20146 * @param {String} scale - Zoom decrement/increment value 20147 */ 20148 Zoom.prototype.zoomImage = function (scale) { 20149 // Find offset manually to avoid issue after zoom 20150 var offsetX = (this.containerRect.width - this.imageXSize) / 2 + 20151 this.containerRect.left; 20152 var _a = this.core.mediaContainerPosition, top = _a.top, bottom = _a.bottom; 20153 var topBottomSpacing = Math.abs(top - bottom) / 2; 20154 var offsetY = (this.containerRect.height - 20155 this.imageYSize - 20156 topBottomSpacing * this.modifierX) / 20157 2 + 20158 this.scrollTop + 20159 this.containerRect.top; 20160 var originalX; 20161 var originalY; 20162 if (scale === 1) { 20163 this.positionChanged = false;
20164 } 20165 var dragAllowedAxises = this.getDragAllowedAxises(Math.abs(this.rotateValue), scale); 20166 var allowY = dragAllowedAxises.allowY, allowX = dragAllowedAxises.allowX; 20167 if (this.positionChanged) { 20168 originalX = this.left / (this.scale - 1); 20169 originalY = this.top / (this.scale - 1); 20170 this.pageX = Math.abs(originalX) + offsetX; 20171 this.pageY = Math.abs(originalY) + offsetY; 20172 this.positionChanged = false; 20173 } 20174 var possibleSwipeCords = this.getPossibleSwipeDragCords(this.rotateValue, scale); 20175 var _x = offsetX - this.pageX; 20176 var _y = offsetY - this.pageY; 20177 var x = (scale - 1) * _x; 20178 var y = (scale - 1) * _y; 20179 if (allowX) { 20180 if (this.isBeyondPossibleLeft(x, possibleSwipeCords.minX)) { 20181 x = possibleSwipeCords.minX; 20182 } 20183 else if (this.isBeyondPossibleRight(x, possibleSwipeCords.maxX)) { 20184 x = possibleSwipeCords.maxX; 20185 } 20186 } 20187 else { 20188 if (scale > 1) { 20189 if (x < possibleSwipeCords.minX) { 20190 x = possibleSwipeCords.minX; 20191 } 20192 else if (x > possibleSwipeCords.maxX) { 20193 x = possibleSwipeCords.maxX; 20194 } 20195 } 20196 }
20197 if (allowY) { 20198 if (this.isBeyondPossibleTop(y, possibleSwipeCords.minY)) { 20199 y = possibleSwipeCords.minY; 20200 } 20201 else if (this.isBeyondPossibleBottom(y, possibleSwipeCords.maxY)) { 20202 y = possibleSwipeCords.maxY; 20203 } 20204 } 20205 else { 20206 // If the translate value based on index of beyond the viewport, utilize the available space to prevent image being cut out 20207 if (scale > 1) { 20208 //If image goes beyond viewport top, use the minim possible translate value 20209 if (y < possibleSwipeCords.minY) { 20210 y = possibleSwipeCords.minY; 20211 } 20212 else if (y > possibleSwipeCords.maxY) { 20213 y = possibleSwipeCords.maxY; 20214 } 20215 } 20216 } 20217 this.setZoomStyles({ 20218 x: x, 20219 y: y, 20220 scale: scale, 20221 }); 20222 }; 20223 /** 20224 * @desc apply scale3d to image and translate to image wrap 20225 * @param {style} X,Y and scale 20226 */ 20227 Zoom.prototype.setZoomStyles = function (style) { 20228 var $image = this.core 20229 .getSlideItem(this.core.index) 20230 .find('.lg-image') 20231 .first(); 20232 var $dummyImage = this.core.outer 20233 .find('.lg-current .lg-dummy-img') 20234 .first(); 20235 var $imageWrap = $image.parent(); 20236 this.scale = style.scale; 20237 $image.css('transform', 'scale3d(' + style.scale + ', ' + style.scale + ', 1)'); 20238 $dummyImage.css('transform', 'scale3d(' + style.scale + ', ' + style.scale + ', 1)'); 20239 var transform = 'translate3d(' + style.x + 'px, ' + style.y + 'px, 0)'; 20240 $imageWrap.css('transform', transform); 20241 this.left = style.x; 20242 this.top = style.y; 20243 }; 20244 /** 20245 * @param index - Index of the current slide 20246 * @param event - event will be available only if the function is called on clicking/taping the imags 20247 */ 20248 Zoom.prototype.setActualSize = function (index, event) { 20249 var _this = this; 20250 // Allow zoom only on image 20251 if (!this.isImageSlide() || 20252 this.core.outer.hasClass('lg-first-slide-loading')) { 20253 return; 20254 } 20255 var scale = this.getCurrentImageActualSizeScale(); 20256 if (this.core.outer.hasClass('lg-zoomed')) { 20257 this.scale = 1; 20258 } 20259 else { 20260 this.scale = this.getScale(scale); 20261 } 20262 this.setPageCords(event); 20263 this.beginZoom(this.scale); 20264 this.zoomImage(this.scale); 20265 setTimeout(function () { 20266 _this.core.outer.removeClass('lg-grabbing').addClass('lg-grab'); 20267 }, 10); 20268 }; 20269 Zoom.prototype.getNaturalWidth = function (index) { 20270 var $image = this.core.getSlideItem(index).find('.lg-image').first(); 20271 var naturalWidth = this.core.galleryItems[index].width; 20272 return naturalWidth 20273 ? parseFloat(naturalWidth) 20274 : $image.get().naturalWidth; 20275 }; 20276 Zoom.prototype.getActualSizeScale = function (naturalWidth, width) { 20277 var _scale; 20278 var scale;
20279 if (naturalWidth > width) { 20280 _scale = naturalWidth / width; 20281 scale = _scale || 2; 20282 } 20283 else { 20284 scale = 1; 20285 } 20286 return scale; 20287 }; 20288 Zoom.prototype.getCurrentImageActualSizeScale = function () { 20289 var $image = this.core 20290 .getSlideItem(this.core.index) 20291 .find('.lg-image') 20292 .first(); 20293 var width = $image.get().offsetWidth; 20294 var naturalWidth = this.getNaturalWidth(this.core.index) || width; 20295 return this.getActualSizeScale(naturalWidth, width); 20296 }; 20297 Zoom.prototype.getPageCords = function (event) { 20298 var cords = {}; 20299 if (event) { 20300 cords.x = event.pageX || event.targetTouches[0].pageX; 20301 cords.y = event.pageY || event.targetTouches[0].pageY; 20302 } 20303 else { 20304 var containerRect = this.core.outer.get().getBoundingClientRect(); 20305 cords.x = containerRect.width / 2 + containerRect.left; 20306 cords.y = 20307 containerRect.height / 2 + this.scrollTop + containerRect.top; 20308 } 20309 return cords; 20310 }; 20311 Zoom.prototype.setPageCords = function (event) { 20312 var pageCords = this.getPageCords(event); 20313 this.pageX = pageCords.x; 20314 this.pageY = pageCords.y; 20315 }; 20316 // If true, zoomed - in else zoomed out 20317 Zoom.prototype.beginZoom = function (scale) { 20318 this.core.outer.removeClass('lg-zoom-drag-transition lg-zoom-dragging'); 20319 if (scale > 1) { 20320 this.core.outer.addClass('lg-zoomed'); 20321 var $actualSize = this.core.getElementById('lg-actual-size'); 20322 $actualSize 20323 .removeClass(this.settings.actualSizeIcons.zoomIn) 20324 .addClass(this.settings.actualSizeIcons.zoomOut); 20325 } 20326 else { 20327 this.resetZoom(); 20328 } 20329 return scale > 1; 20330 }; 20331 Zoom.prototype.getScale = function (scale) { 20332 var actualSizeScale = this.getCurrentImageActualSizeScale(); 20333 if (scale < 1) { 20334 scale = 1; 20335 } 20336 else if (scale > actualSizeScale) { 20337 scale = actualSizeScale; 20338 } 20339 return scale; 20340 }; 20341 Zoom.prototype.init = function () { 20342 var _this = this; 20343 if (!this.settings.zoom) { 20344 return; 20345 } 20346 this.buildTemplates(); 20347 this.enableZoomOnSlideItemLoad(); 20348 var tapped = null; 20349 this.core.outer.on('dblclick.lg', function (event) { 20350 if (!_this.$LG(event.target).hasClass('lg-image')) { 20351 return; 20352 } 20353 _this.setActualSize(_this.core.index, event); 20354 }); 20355 this.core.outer.on('touchstart.lg', function (event) { 20356 var $target = _this.$LG(event.target); 20357 if (event.targetTouches.length === 1 && 20358 $target.hasClass('lg-image')) { 20359 if (!tapped) { 20360 tapped = setTimeout(function () { 20361 tapped = null; 20362 }, 300); 20363 } 20364 else { 20365 clearTimeout(tapped); 20366 tapped = null; 20367 event.preventDefault(); 20368 _this.setActualSize(_this.core.index, event); 20369 } 20370 } 20371 }); 20372 // Update zoom on resize and orientationchange 20373 this.core.LGel.on(lGEvents.containerResize + ".zoom " + lGEvents.rotateRight + ".zoom " + lGEvents.rotateLeft + ".zoom " + lGEvents.flipHorizontal + ".zoom " + lGEvents.flipVertical + ".zoom", function () { 20374 if (!_this.core.lgOpened || !_this.isImageSlide()) 20375 return; 20376 _this.setPageCords(); 20377 _this.setZoomEssentials(); 20378 _this.zoomImage(_this.scale); 20379 }); 20380 // Update zoom on resize and orientationchange 20381 this.$LG(window).on("scroll.lg.zoom.global" + this.core.lgId, function () { 20382 if (!_this.core.lgOpened) 20383 return; 20384 _this.scrollTop = _this.$LG(window).scrollTop(); 20385 }); 20386 this.core.getElementById('lg-zoom-out').on('click.lg', function () { 20387 if (_this.core.outer.find('.lg-current .lg-image').get()) { 20388 _this.scale -= _this.settings.scale; 20389 _this.scale = _this.getScale(_this.scale); 20390 _this.beginZoom(_this.scale); 20391 _this.zoomImage(_this.scale); 20392 } 20393 }); 20394 this.core.getElementById('lg-zoom-in').on('click.lg', function () { 20395 _this.zoomIn(); 20396 }); 20397 this.core.getElementById('lg-actual-size').on('click.lg', function () { 20398 _this.setActualSize(_this.core.index); 20399 }); 20400 this.core.LGel.on(lGEvents.beforeOpen + ".zoom", function () { 20401 _this.core.outer.find('.lg-item').removeClass('lg-zoomable'); 20402 }); 20403 this.core.LGel.on(lGEvents.afterOpen + ".zoom", function () { 20404 _this.scrollTop = _this.$LG(window).scrollTop(); 20405 // Set the initial value center 20406 _this.pageX = _this.core.outer.width() / 2;
20407 _this.pageY = _this.core.outer.height() / 2 + _this.scrollTop; 20408 _this.scale = 1; 20409 }); 20410 // Reset zoom on slide change 20411 this.core.LGel.on(lGEvents.afterSlide + ".zoom", function (event) { 20412 var prevIndex = event.detail.prevIndex; 20413 _this.scale = 1; 20414 _this.positionChanged = false; 20415 _this.resetZoom(prevIndex); 20416 if (_this.isImageSlide()) { 20417 _this.setZoomEssentials(); 20418 } 20419 }); 20420 // Drag option after zoom 20421 this.zoomDrag(); 20422 this.pinchZoom(); 20423 this.zoomSwipe(); 20424 // Store the zoomable timeout value just to clear it while closing 20425 this.zoomableTimeout = false; 20426 this.positionChanged = false; 20427 }; 20428 Zoom.prototype.zoomIn = function (scale) { 20429 // Allow zoom only on image 20430 if (!this.isImageSlide()) { 20431 return; 20432 } 20433 if (scale) { 20434 this.scale = scale; 20435 } 20436 else { 20437 this.scale += this.settings.scale; 20438 } 20439 this.scale = this.getScale(this.scale); 20440 this.beginZoom(this.scale); 20441 this.zoomImage(this.scale); 20442 }; 20443 // Reset zoom effect 20444 Zoom.prototype.resetZoom = function (index) { 20445 this.core.outer.removeClass('lg-zoomed lg-zoom-drag-transition'); 20446 var $actualSize = this.core.getElementById('lg-actual-size'); 20447 var $item = this.core.getSlideItem(index !== undefined ? index : this.core.index); 20448 $actualSize 20449 .removeClass(this.settings.actualSizeIcons.zoomOut) 20450 .addClass(this.settings.actualSizeIcons.zoomIn); 20451 $item.find('.lg-img-wrap').first().removeAttr('style'); 20452 $item.find('.lg-image').first().removeAttr('style'); 20453 this.scale = 1; 20454 this.left = 0; 20455 this.top = 0; 20456 // Reset pagx pagy values to center 20457 this.setPageCords(); 20458 }; 20459 Zoom.prototype.getTouchDistance = function (e) { 20460 return Math.sqrt((e.targetTouches[0].pageX - e.targetTouches[1].pageX) * 20461 (e.targetTouches[0].pageX - e.targetTouches[1].pageX) + 20462 (e.targetTouches[0].pageY - e.targetTouches[1].pageY) * 20463 (e.targetTouches[0].pageY - e.targetTouches[1].pageY)); 20464 }; 20465 Zoom.prototype.pinchZoom = function () { 20466 var _this = this; 20467 var startDist = 0; 20468 var pinchStarted = false; 20469 var initScale = 1; 20470 var $item = this.core.getSlideItem(this.core.index); 20471 this.core.$inner.on('touchstart.lg', function (e) { 20472 $item = _this.core.getSlideItem(_this.core.index); 20473 if (!_this.isImageSlide()) { 20474 return; 20475 } 20476 if (e.targetTouches.length === 2 && 20477 !_this.core.outer.hasClass('lg-first-slide-loading') && 20478 (_this.$LG(e.target).hasClass('lg-item') || 20479 $item.get().contains(e.target))) { 20480 initScale = _this.scale || 1; 20481 _this.core.outer.removeClass('lg-zoom-drag-transition lg-zoom-dragging'); 20482 _this.core.touchAction = 'pinch'; 20483 startDist = _this.getTouchDistance(e); 20484 } 20485 }); 20486 this.core.$inner.on('touchmove.lg', function (e) { 20487 if (e.targetTouches.length === 2 && 20488 _this.core.touchAction === 'pinch' && 20489 (_this.$LG(e.target).hasClass('lg-item') || 20490 $item.get().contains(e.target))) { 20491 e.preventDefault(); 20492 var endDist = _this.getTouchDistance(e); 20493 var distance = startDist - endDist; 20494 if (!pinchStarted && Math.abs(distance) > 5) { 20495 pinchStarted = true; 20496 } 20497 if (pinchStarted) { 20498 _this.scale = Math.max(1, initScale + -distance * 0.008); 20499 _this.zoomImage(_this.scale); 20500 } 20501 } 20502 }); 20503 this.core.$inner.on('touchend.lg', function (e) { 20504 if (_this.core.touchAction === 'pinch' && 20505 (_this.$LG(e.target).hasClass('lg-item') || 20506 $item.get().contains(e.target))) { 20507 pinchStarted = false; 20508 startDist = 0; 20509 if (_this.scale <= 1) { 20510 _this.resetZoom(); 20511 } 20512 else { 20513 _this.scale = _this.getScale(_this.scale); 20514 _this.zoomImage(_this.scale); 20515 _this.core.outer.addClass('lg-zoomed'); 20516 } 20517 _this.core.touchAction = undefined; 20518 } 20519 }); 20520 }; 20521 Zoom.prototype.touchendZoom = function (startCoords, endCoords, allowX, allowY, touchDuration, rotateValue) { 20522 var distanceXnew = endCoords.x - startCoords.x; 20523 var distanceYnew = endCoords.y - startCoords.y; 20524 var speedX = Math.abs(distanceXnew) / touchDuration + 1; 20525 var speedY = Math.abs(distanceYnew) / touchDuration + 1; 20526 if (speedX > 2) { 20527 speedX += 1; 20528 } 20529 if (speedY > 2) { 20530 speedY += 1; 20531 } 20532 distanceXnew = distanceXnew * speedX; 20533 distanceYnew = distanceYnew * speedY; 20534 var _LGel = this.core 20535 .getSlideItem(this.core.index) 20536 .find('.lg-img-wrap') 20537 .first(); 20538 var distance = {}; 20539 distance.x = this.left + distanceXnew * this.modifierX; 20540 distance.y = this.top + distanceYnew * this.modifierY; 20541 var possibleSwipeCords = this.getPossibleSwipeDragCords(rotateValue); 20542 if (Math.abs(distanceXnew) > 15 || Math.abs(distanceYnew) > 15) { 20543 if (allowY) { 20544 if (this.isBeyondPossibleTop(distance.y, possibleSwipeCords.minY)) { 20545 distance.y = possibleSwipeCords.minY; 20546 } 20547 else if (this.isBeyondPossibleBottom(distance.y, possibleSwipeCords.maxY)) { 20548 distance.y = possibleSwipeCords.maxY; 20549 } 20550 } 20551 if (allowX) { 20552 if (this.isBeyondPossibleLeft(distance.x, possibleSwipeCords.minX)) { 20553 distance.x = possibleSwipeCords.minX; 20554 } 20555 else if (this.isBeyondPossibleRight(distance.x, possibleSwipeCords.maxX)) { 20556 distance.x = possibleSwipeCords.maxX; 20557 } 20558 } 20559 if (allowY) { 20560 this.top = distance.y; 20561 } 20562 else { 20563 distance.y = this.top; 20564 } 20565 if (allowX) { 20566 this.left = distance.x; 20567 } 20568 else { 20569 distance.x = this.left; 20570 } 20571 this.setZoomSwipeStyles(_LGel, distance); 20572 this.positionChanged = true; 20573 } 20574 }; 20575 Zoom.prototype.getZoomSwipeCords = function (startCoords, endCoords, allowX, allowY, possibleSwipeCords) { 20576 var distance = {}; 20577 if (allowY) { 20578 distance.y = 20579 this.top + (endCoords.y - startCoords.y) * this.modifierY; 20580 if (this.isBeyondPossibleTop(distance.y, possibleSwipeCords.minY)) { 20581 var diffMinY = possibleSwipeCords.minY - distance.y; 20582 distance.y = possibleSwipeCords.minY - diffMinY / 6; 20583 } 20584 else if (this.isBeyondPossibleBottom(distance.y, possibleSwipeCords.maxY)) { 20585 var diffMaxY = distance.y - possibleSwipeCords.maxY; 20586 distance.y = possibleSwipeCords.maxY + diffMaxY / 6; 20587 } 20588 } 20589 else { 20590 distance.y = this.top; 20591 }
20592 if (allowX) { 20593 distance.x = 20594 this.left + (endCoords.x - startCoords.x) * this.modifierX; 20595 if (this.isBeyondPossibleLeft(distance.x, possibleSwipeCords.minX)) { 20596 var diffMinX = possibleSwipeCords.minX - distance.x; 20597 distance.x = possibleSwipeCords.minX - diffMinX / 6; 20598 } 20599 else if (this.isBeyondPossibleRight(distance.x, possibleSwipeCords.maxX)) { 20600 var difMaxX = distance.x - possibleSwipeCords.maxX; 20601 distance.x = possibleSwipeCords.maxX + difMaxX / 6; 20602 } 20603 } 20604 else { 20605 distance.x = this.left; 20606 } 20607 return distance; 20608 }; 20609 Zoom.prototype.isBeyondPossibleLeft = function (x, minX) { 20610 return x >= minX; 20611 }; 20612 Zoom.prototype.isBeyondPossibleRight = function (x, maxX) { 20613 return x <= maxX; 20614 }; 20615 Zoom.prototype.isBeyondPossibleTop = function (y, minY) { 20616 return y >= minY; 20617 }; 20618 Zoom.prototype.isBeyondPossibleBottom = function (y, maxY) { 20619 return y <= maxY; 20620 }; 20621 Zoom.prototype.isImageSlide = function () { 20622 var currentItem = this.core.galleryItems[this.core.index]; 20623 return this.core.getSlideType(currentItem) === 'image'; 20624 }; 20625 Zoom.prototype.getPossibleSwipeDragCords = function (rotateValue, scale) { 20626 var dataScale = scale || this.scale || 1; 20627 var elDataScale = Math.abs(dataScale); 20628 var _a = this.core.mediaContainerPosition, top = _a.top, bottom = _a.bottom; 20629 var topBottomSpacing = Math.abs(top - bottom) / 2; 20630 var minY = (this.imageYSize - this.containerRect.height) / 2 + 20631 topBottomSpacing * this.modifierX; 20632 var maxY = this.containerRect.height - this.imageYSize * elDataScale + minY; 20633 var minX = (this.imageXSize - this.containerRect.width) / 2; 20634 var maxX = this.containerRect.width - this.imageXSize * elDataScale + minX; 20635 var possibleSwipeCords = { 20636 minY: minY, 20637 maxY: maxY, 20638 minX: minX, 20639 maxX: maxX, 20640 }; 20641 if (Math.abs(rotateValue) === 90) { 20642 possibleSwipeCords = { 20643 minY: minX, 20644 maxY: maxX, 20645 minX: minY, 20646 maxX: maxY, 20647 }; 20648 } 20649 return possibleSwipeCords; 20650 }; 20651 Zoom.prototype.setZoomSwipeStyles = function (LGel, distance) { 20652 LGel.css('transform', 'translate3d(' + distance.x + 'px, ' + distance.y + 'px, 0)'); 20653 }; 20654 Zoom.prototype.zoomSwipe = function () { 20655 var _this = this; 20656 var startCoords = {}; 20657 var endCoords = {}; 20658 var isMoved = false; 20659 // Allow x direction drag 20660 var allowX = false; 20661 // Allow Y direction drag 20662 var allowY = false; 20663 var startTime = new Date(); 20664 var endTime = new Date(); 20665 var possibleSwipeCords; 20666 var _LGel; 20667 var $item = this.core.getSlideItem(this.core.index); 20668 this.core.$inner.on('touchstart.lg', function (e) { 20669 // Allow zoom only on image 20670 if (!_this.isImageSlide()) { 20671 return; 20672 } 20673 $item = _this.core.getSlideItem(_this.core.index); 20674 if ((_this.$LG(e.target).hasClass('lg-item') || 20675 $item.get().contains(e.target)) && 20676 e.targetTouches.length === 1 && 20677 _this.core.outer.hasClass('lg-zoomed')) { 20678 e.preventDefault(); 20679 startTime = new Date(); 20680 _this.core.touchAction = 'zoomSwipe'; 20681 _LGel = _this.core 20682 .getSlideItem(_this.core.index) 20683 .find('.lg-img-wrap') 20684 .first(); 20685 var dragAllowedAxises = _this.getDragAllowedAxises(Math.abs(_this.rotateValue)); 20686 allowY = dragAllowedAxises.allowY; 20687 allowX = dragAllowedAxises.allowX; 20688 if (allowX || allowY) { 20689 startCoords = _this.getSwipeCords(e, Math.abs(_this.rotateValue)); 20690 } 20691 possibleSwipeCords = _this.getPossibleSwipeDragCords(_this.rotateValue); 20692 // reset opacity and transition duration 20693 _this.core.outer.addClass('lg-zoom-dragging lg-zoom-drag-transition'); 20694 } 20695 }); 20696 this.core.$inner.on('touchmove.lg', function (e) { 20697 if (e.targetTouches.length === 1 && 20698 _this.core.touchAction === 'zoomSwipe' && 20699 (_this.$LG(e.target).hasClass('lg-item') || 20700 $item.get().contains(e.target))) { 20701 e.preventDefault(); 20702 _this.core.touchAction = 'zoomSwipe'; 20703 endCoords = _this.getSwipeCords(e, Math.abs(_this.rotateValue)); 20704 var distance = _this.getZoomSwipeCords(startCoords, endCoords, allowX, allowY, possibleSwipeCords); 20705 if (Math.abs(endCoords.x - startCoords.x) > 15 || 20706 Math.abs(endCoords.y - startCoords.y) > 15) { 20707 isMoved = true; 20708 _this.setZoomSwipeStyles(_LGel, distance); 20709 } 20710 } 20711 }); 20712 this.core.$inner.on('touchend.lg', function (e) { 20713 if (_this.core.touchAction === 'zoomSwipe' && 20714 (_this.$LG(e.target).hasClass('lg-item') || 20715 $item.get().contains(e.target))) { 20716 _this.core.touchAction = undefined; 20717 _this.core.outer.removeClass('lg-zoom-dragging'); 20718 if (!isMoved) { 20719 return; 20720 } 20721 isMoved = false;
20722 endTime = new Date(); 20723 var touchDuration = endTime.valueOf() - startTime.valueOf(); 20724 _this.touchendZoom(startCoords, endCoords, allowX, allowY, touchDuration, _this.rotateValue); 20725 } 20726 }); 20727 }; 20728 Zoom.prototype.zoomDrag = function () { 20729 var _this = this; 20730 var startCoords = {}; 20731 var endCoords = {}; 20732 var isDragging = false; 20733 var isMoved = false; 20734 // Allow x direction drag 20735 var allowX = false; 20736 // Allow Y direction drag 20737 var allowY = false; 20738 var startTime; 20739 var endTime; 20740 var possibleSwipeCords; 20741 var _LGel; 20742 this.core.outer.on('mousedown.lg.zoom', function (e) { 20743 // Allow zoom only on image 20744 if (!_this.isImageSlide()) { 20745 return; 20746 } 20747 var $item = _this.core.getSlideItem(_this.core.index); 20748 if (_this.$LG(e.target).hasClass('lg-item') || 20749 $item.get().contains(e.target)) { 20750 startTime = new Date(); 20751 _LGel = _this.core 20752 .getSlideItem(_this.core.index) 20753 .find('.lg-img-wrap') 20754 .first(); 20755 var dragAllowedAxises = _this.getDragAllowedAxises(Math.abs(_this.rotateValue)); 20756 allowY = dragAllowedAxises.allowY; 20757 allowX = dragAllowedAxises.allowX; 20758 if (_this.core.outer.hasClass('lg-zoomed')) { 20759 if (_this.$LG(e.target).hasClass('lg-object') && 20760 (allowX || allowY)) { 20761 e.preventDefault(); 20762 startCoords = _this.getDragCords(e, Math.abs(_this.rotateValue)); 20763 possibleSwipeCords = _this.getPossibleSwipeDragCords(_this.rotateValue); 20764 isDragging = true; 20765 // ** Fix for webkit cursor issue https://code.google.com/p/chromium/issues/detail?id=26723 20766 _this.core.outer.get().scrollLeft += 1; 20767 _this.core.outer.get().scrollLeft -= 1; 20768 _this.core.outer 20769 .removeClass('lg-grab') 20770 .addClass('lg-grabbing lg-zoom-drag-transition lg-zoom-dragging'); 20771 // reset opacity and transition duration 20772 } 20773 } 20774 } 20775 }); 20776 this.$LG(window).on("mousemove.lg.zoom.global" + this.core.lgId, function (e) { 20777 if (isDragging) { 20778 isMoved = true; 20779 endCoords = _this.getDragCords(e, Math.abs(_this.rotateValue)); 20780 var distance = _this.getZoomSwipeCords(startCoords, endCoords, allowX, allowY, possibleSwipeCords); 20781 _this.setZoomSwipeStyles(_LGel, distance); 20782 } 20783 }); 20784 this.$LG(window).on("mouseup.lg.zoom.global" + this.core.lgId, function (e) { 20785 if (isDragging) { 20786 endTime = new Date(); 20787 isDragging = false; 20788 _this.core.outer.removeClass('lg-zoom-dragging'); 20789 // Fix for chrome mouse move on click 20790 if (isMoved && 20791 (startCoords.x !== endCoords.x || 20792 startCoords.y !== endCoords.y)) { 20793 endCoords = _this.getDragCords(e, Math.abs(_this.rotateValue)); 20794 var touchDuration = endTime.valueOf() - startTime.valueOf(); 20795 _this.touchendZoom(startCoords, endCoords, allowX, allowY, touchDuration, _this.rotateValue); 20796 } 20797 isMoved = false; 20798 } 20799 _this.core.outer.removeClass('lg-grabbing').addClass('lg-grab'); 20800 }); 20801 }; 20802 Zoom.prototype.closeGallery = function () { 20803 this.resetZoom(); 20804 }; 20805 Zoom.prototype.destroy = function () { 20806 // Unbind all events added by lightGallery zoom plugin 20807 this.$LG(window).off(".lg.zoom.global" + this.core.lgId); 20808 this.core.LGel.off('.lg.zoom'); 20809 this.core.LGel.off('.zoom'); 20810 clearTimeout(this.zoomableTimeout); 20811 this.zoomableTimeout = false; 20812 }; 20813 return Zoom; 20814 }()); 20815 20816 return Zoom; 20817 20818}))); 20819/*! 20820 * lightgallery | 2.5.0 | June 13th 2022 20821 * http://www.lightgalleryjs.com/ 20822 * Copyright (c) 2020 Sachin Neravath; 20823 * @license GPLv3 20824 */ 20825 20826(function (global, factory) { 20827 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 20828 typeof define === 'function' && define.amd ? define(factory) : 20829 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lgFullscreen = factory()); 20830}(this, (function () { 'use strict'; 20831 20832 /*! ***************************************************************************** 20833 Copyright (c) Microsoft Corporation. 20834 20835 Permission to use, copy, modify, and/or distribute this software for any 20836 purpose with or without fee is hereby granted. 20837 20838 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 20839 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 20840 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 20841 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 20842 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 20843 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 20844 PERFORMANCE OF THIS SOFTWARE. 20845 ***************************************************************************** */ 20846 20847 var __assign = function() { 20848 __assign = Object.assign || function __assign(t) { 20849 for (var s, i = 1, n = arguments.length; i < n; i++) { 20850 s = arguments[i]; 20851 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 20852 } 20853 return t; 20854 }; 20855 return __assign.apply(this, arguments); 20856 }; 20857 20858 var fullscreenSettings = { 20859 fullScreen: true, 20860 fullscreenPluginStrings: { 20861 toggleFullscreen: 'Toggle Fullscreen', 20862 }, 20863 }; 20864 20865 var FullScreen = /** @class */ (function () { 20866 function FullScreen(instance, $LG) { 20867 // get lightGallery core plugin instance 20868 this.core = instance;
20869 this.$LG = $LG; 20870 // extend module default settings with lightGallery core settings 20871 this.settings = __assign(__assign({}, fullscreenSettings), this.core.settings); 20872 return this; 20873 } 20874 FullScreen.prototype.init = function () { 20875 var fullScreen = ''; 20876 if (this.settings.fullScreen) { 20877 // check for fullscreen browser support 20878 if (!document.fullscreenEnabled && 20879 !document.webkitFullscreenEnabled && 20880 !document.mozFullScreenEnabled && 20881 !document.msFullscreenEnabled) { 20882 return; 20883 } 20884 else { 20885 fullScreen = "<button type=\"button\" aria-label=\"" + this.settings.fullscreenPluginStrings['toggleFullscreen'] + "\" class=\"lg-fullscreen lg-icon\"></button>"; 20886 this.core.$toolbar.append(fullScreen); 20887 this.fullScreen(); 20888 } 20889 } 20890 }; 20891 FullScreen.prototype.isFullScreen = function () { 20892 return (document.fullscreenElement || 20893 document.mozFullScreenElement || 20894 document.webkitFullscreenElement || 20895 document.msFullscreenElement); 20896 }; 20897 FullScreen.prototype.requestFullscreen = function () { 20898 var el = document.documentElement; 20899 if (el.requestFullscreen) { 20900 el.requestFullscreen(); 20901 } 20902 else if (el.msRequestFullscreen) { 20903 el.msRequestFullscreen(); 20904 } 20905 else if (el.mozRequestFullScreen) { 20906 el.mozRequestFullScreen(); 20907 } 20908 else if (el.webkitRequestFullscreen) { 20909 el.webkitRequestFullscreen(); 20910 } 20911 }; 20912 FullScreen.prototype.exitFullscreen = function () { 20913 if (document.exitFullscreen) { 20914 document.exitFullscreen(); 20915 } 20916 else if (document.msExitFullscreen) { 20917 document.msExitFullscreen(); 20918 } 20919 else if (document.mozCancelFullScreen) { 20920 document.mozCancelFullScreen(); 20921 } 20922 else if (document.webkitExitFullscreen) { 20923 document.webkitExitFullscreen(); 20924 } 20925 }; 20926 // https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Using_full_screen_mode 20927 FullScreen.prototype.fullScreen = function () { 20928 var _this = this; 20929 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 () { 20930 if (!_this.core.lgOpened) 20931 return; 20932 _this.core.outer.toggleClass('lg-fullscreen-on'); 20933 }); 20934 this.core.outer 20935 .find('.lg-fullscreen') 20936 .first() 20937 .on('click.lg', function () { 20938 if (_this.isFullScreen()) { 20939 _this.exitFullscreen(); 20940 } 20941 else { 20942 _this.requestFullscreen(); 20943 } 20944 }); 20945 }; 20946 FullScreen.prototype.closeGallery = function () { 20947 // exit from fullscreen if activated 20948 if (this.isFullScreen()) { 20949 this.exitFullscreen(); 20950 } 20951 }; 20952 FullScreen.prototype.destroy = function () { 20953 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); 20954 }; 20955 return FullScreen; 20956 }()); 20957 20958 return FullScreen; 20959 20960}))); 20961 20962/*! 20963 * lightgallery | 2.5.0 | June 13th 2022 20964 * http://www.lightgalleryjs.com/ 20965 * Copyright (c) 2020 Sachin Neravath; 20966 * @license GPLv3 20967 */ 20968 20969(function (global, factory) { 20970 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 20971 typeof define === 'function' && define.amd ? define(factory) : 20972 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lgHash = factory()); 20973}(this, (function () { 'use strict'; 20974 20975 /*! ***************************************************************************** 20976 Copyright (c) Microsoft Corporation. 20977 20978 Permission to use, copy, modify, and/or distribute this software for any 20979 purpose with or without fee is hereby granted. 20980 20981 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 20982 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 20983 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 20984 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 20985 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 20986 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 20987 PERFORMANCE OF THIS SOFTWARE. 20988 ***************************************************************************** */ 20989 20990 var __assign = function() { 20991 __assign = Object.assign || function __assign(t) { 20992 for (var s, i = 1, n = arguments.length; i < n; i++) { 20993 s = arguments[i]; 20994 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 20995 } 20996 return t; 20997 }; 20998 return __assign.apply(this, arguments); 20999 }; 21000 21001 /** 21002 * List of lightGallery events 21003 * All events should be documented here 21004 * Below interfaces are used to build the website documentations 21005 * */ 21006 var lGEvents = { 21007 afterAppendSlide: 'lgAfterAppendSlide', 21008 init: 'lgInit', 21009 hasVideo: 'lgHasVideo', 21010 containerResize: 'lgContainerResize', 21011 updateSlides: 'lgUpdateSlides', 21012 afterAppendSubHtml: 'lgAfterAppendSubHtml', 21013 beforeOpen: 'lgBeforeOpen', 21014 afterOpen: 'lgAfterOpen', 21015 slideItemLoad: 'lgSlideItemLoad', 21016 beforeSlide: 'lgBeforeSlide', 21017 afterSlide: 'lgAfterSlide', 21018 posterClick: 'lgPosterClick', 21019 dragStart: 'lgDragStart', 21020 dragMove: 'lgDragMove', 21021 dragEnd: 'lgDragEnd', 21022 beforeNextSlide: 'lgBeforeNextSlide', 21023 beforePrevSlide: 'lgBeforePrevSlide', 21024 beforeClose: 'lgBeforeClose', 21025 afterClose: 'lgAfterClose', 21026 rotateLeft: 'lgRotateLeft', 21027 rotateRight: 'lgRotateRight', 21028 flipHorizontal: 'lgFlipHorizontal', 21029 flipVertical: 'lgFlipVertical', 21030 autoplay: 'lgAutoplay', 21031 autoplayStart: 'lgAutoplayStart', 21032 autoplayStop: 'lgAutoplayStop', 21033 }; 21034 21035 var hashSettings = { 21036 hash: true, 21037 galleryId: '1', 21038 customSlideName: false, 21039 }; 21040 21041 var Hash = /** @class */ (function () { 21042 function Hash(instance, $LG) { 21043 // get lightGallery core plugin instance 21044 this.core = instance;
21045 this.$LG = $LG; 21046 // extend module default settings with lightGallery core settings 21047 this.settings = __assign(__assign({}, hashSettings), this.core.settings); 21048 return this; 21049 } 21050 Hash.prototype.init = function () { 21051 var _this = this; 21052 if (!this.settings.hash) { 21053 return; 21054 } 21055 this.oldHash = window.location.hash; 21056 setTimeout(function () { 21057 _this.buildFromHash(); 21058 }, 100); 21059 // Change hash value on after each slide transition 21060 this.core.LGel.on(lGEvents.afterSlide + ".hash", this.onAfterSlide.bind(this)); 21061 this.core.LGel.on(lGEvents.afterClose + ".hash", this.onCloseAfter.bind(this)); 21062 // Listen hash change and change the slide according to slide value 21063 this.$LG(window).on("hashchange.lg.hash.global" + this.core.lgId, this.onHashchange.bind(this)); 21064 }; 21065 Hash.prototype.onAfterSlide = function (event) { 21066 var slideName = this.core.galleryItems[event.detail.index].slideName; 21067 slideName = this.settings.customSlideName 21068 ? slideName || event.detail.index 21069 : event.detail.index; 21070 if (history.replaceState) { 21071 history.replaceState(null, '', window.location.pathname + 21072 window.location.search + 21073 '#lg=' + 21074 this.settings.galleryId + 21075 '&slide=' + 21076 slideName); 21077 } 21078 else { 21079 window.location.hash = 21080 'lg=' + this.settings.galleryId + '&slide=' + slideName; 21081 } 21082 }; 21083 /** 21084 * Get index of the slide from custom slideName. Has to be a public method. Used in hash plugin 21085 * @param {String} hash 21086 * @returns {Number} Index of the slide. 21087 */ 21088 Hash.prototype.getIndexFromUrl = function (hash) { 21089 if (hash === void 0) { hash = window.location.hash; } 21090 var slideName = hash.split('&slide=')[1]; 21091 var _idx = 0; 21092 if (this.settings.customSlideName) { 21093 for (var index = 0; index < this.core.galleryItems.length; index++) { 21094 var dynamicEl = this.core.galleryItems[index]; 21095 if (dynamicEl.slideName === slideName) { 21096 _idx = index; 21097 break; 21098 } 21099 } 21100 } 21101 else { 21102 _idx = parseInt(slideName, 10); 21103 } 21104 return isNaN(_idx) ? 0 : _idx; 21105 }; 21106 // Build Gallery if gallery id exist in the URL 21107 Hash.prototype.buildFromHash = function () { 21108 // if dynamic option is enabled execute immediately 21109 var _hash = window.location.hash; 21110 //Uncode edit ##START## 21111 // if (_hash.indexOf('lg=' + this.settings.galleryId) > 0) { 21112 if (_hash.indexOf('lg=' + this.settings.galleryId + '&') > 0) { 21113 //Uncode edit ##END## 21114 // This class is used to remove the initial animation if galleryId present in the URL 21115 this.$LG(document.body).addClass('lg-from-hash'); 21116 var index = this.getIndexFromUrl(_hash); 21117 this.core.openGallery(index); 21118 return true; 21119 } 21120 }; 21121 Hash.prototype.onCloseAfter = function () { 21122 // Reset to old hash value 21123 if (this.oldHash && 21124 this.oldHash.indexOf('lg=' + this.settings.galleryId) < 0) { 21125 if (history.replaceState) { 21126 history.replaceState(null, '', this.oldHash); 21127 } 21128 else { 21129 window.location.hash = this.oldHash; 21130 } 21131 } 21132 else { 21133 if (history.replaceState) { 21134 history.replaceState(null, document.title, window.location.pathname + window.location.search); 21135 } 21136 else { 21137 window.location.hash = ''; 21138 } 21139 } 21140 }; 21141 Hash.prototype.onHashchange = function () { 21142 if (!this.core.lgOpened) 21143 return; 21144 var _hash = window.location.hash; 21145 var index = this.getIndexFromUrl(_hash); 21146 // it galleryId doesn't exist in the url close the gallery 21147 if (_hash.indexOf('lg=' + this.settings.galleryId) > -1) { 21148 this.core.slide(index, false, false); 21149 } 21150 else if (this.core.lGalleryOn) { 21151 this.core.closeGallery(); 21152 } 21153 }; 21154 Hash.prototype.closeGallery = function () { 21155 if (this.settings.hash) { 21156 this.$LG(document.body).removeClass('lg-from-hash'); 21157 } 21158 }; 21159 Hash.prototype.destroy = function () { 21160 this.core.LGel.off('.lg.hash'); 21161 this.core.LGel.off('.hash'); 21162 this.$LG(window).off("hashchange.lg.hash.global" + this.core.lgId); 21163 }; 21164 return Hash; 21165 }()); 21166 21167 return Hash; 21168 21169}))); 21170/*! 21171 * lightgallery | 2.5.0 | June 13th 2022 21172 * http://www.lightgalleryjs.com/ 21173 * Copyright (c) 2020 Sachin Neravath; 21174 * @license GPLv3 21175 */ 21176 21177(function (global, factory) { 21178 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 21179 typeof define === 'function' && define.amd ? define(factory) : 21180 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lgShare = factory()); 21181}(this, (function () { 'use strict'; 21182 21183 /*! ***************************************************************************** 21184 Copyright (c) Microsoft Corporation. 21185 21186 Permission to use, copy, modify, and/or distribute this software for any 21187 purpose with or without fee is hereby granted. 21188 21189 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 21190 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 21191 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 21192 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 21193 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 21194 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 21195 PERFORMANCE OF THIS SOFTWARE. 21196 ***************************************************************************** */ 21197 21198 var __assign = function() { 21199 __assign = Object.assign || function __assign(t) { 21200 for (var s, i = 1, n = arguments.length; i < n; i++) { 21201 s = arguments[i]; 21202 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 21203 } 21204 return t; 21205 }; 21206 return __assign.apply(this, arguments); 21207 }; 21208 21209 function __spreadArrays() { 21210 for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; 21211 for (var r = Array(s), k = 0, i = 0; i < il; i++) 21212 for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) 21213 r[k] = a[j]; 21214 return r; 21215 } 21216 21217 var shareSettings = { 21218 share: true, 21219 facebook: true, 21220 facebookDropdownText: 'Facebook', 21221 twitter: true, 21222 twitterDropdownText: 'Twitter', 21223 pinterest: true, 21224 pinterestDropdownText: 'Pinterest', 21225 additionalShareOptions: [], 21226 sharePluginStrings: { share: 'Share' }, 21227 }; 21228 21229 function getFacebookShareLink(galleryItem) { 21230 var facebookBaseUrl = '//www.facebook.com/sharer/sharer.php?u='; 21231 return (facebookBaseUrl + 21232 encodeURIComponent(galleryItem.facebookShareUrl || window.location.href)); 21233 } 21234 21235 function getTwitterShareLink(galleryItem) { 21236 var twitterBaseUrl = '//twitter.com/intent/tweet?text='; 21237 var url = encodeURIComponent(galleryItem.twitterShareUrl || window.location.href); 21238 var text = galleryItem.tweetText;
21239 return twitterBaseUrl + text + '&url=' + url; 21240 } 21241 21242 function getPinterestShareLink(galleryItem) { 21243 var pinterestBaseUrl = 'http://www.pinterest.com/pin/create/button/?url='; 21244 var description = galleryItem.pinterestText; 21245 var media = encodeURIComponent(galleryItem.src); 21246 var url = encodeURIComponent(galleryItem.pinterestShareUrl || window.location.href); 21247 return (pinterestBaseUrl + 21248 url + 21249 '&media=' + 21250 media + 21251 '&description=' + 21252 description); 21253 } 21254 21255 /** 21256 * List of lightGallery events 21257 * All events should be documented here 21258 * Below interfaces are used to build the website documentations 21259 * */ 21260 var lGEvents = { 21261 afterAppendSlide: 'lgAfterAppendSlide', 21262 init: 'lgInit', 21263 hasVideo: 'lgHasVideo', 21264 containerResize: 'lgContainerResize', 21265 updateSlides: 'lgUpdateSlides', 21266 afterAppendSubHtml: 'lgAfterAppendSubHtml', 21267 beforeOpen: 'lgBeforeOpen', 21268 afterOpen: 'lgAfterOpen', 21269 slideItemLoad: 'lgSlideItemLoad', 21270 beforeSlide: 'lgBeforeSlide', 21271 afterSlide: 'lgAfterSlide', 21272 posterClick: 'lgPosterClick', 21273 dragStart: 'lgDragStart', 21274 dragMove: 'lgDragMove', 21275 dragEnd: 'lgDragEnd', 21276 beforeNextSlide: 'lgBeforeNextSlide', 21277 beforePrevSlide: 'lgBeforePrevSlide', 21278 beforeClose: 'lgBeforeClose', 21279 afterClose: 'lgAfterClose', 21280 rotateLeft: 'lgRotateLeft', 21281 rotateRight: 'lgRotateRight', 21282 flipHorizontal: 'lgFlipHorizontal', 21283 flipVertical: 'lgFlipVertical', 21284 autoplay: 'lgAutoplay', 21285 autoplayStart: 'lgAutoplayStart', 21286 autoplayStop: 'lgAutoplayStop', 21287 }; 21288 21289 var Share = /** @class */ (function () { 21290 function Share(instance) { 21291 this.shareOptions = []; 21292 // get lightGallery core plugin instance 21293 this.core = instance; 21294 // extend module default settings with lightGallery core settings 21295 this.settings = __assign(__assign({}, shareSettings), this.core.settings); 21296 return this; 21297 } 21298 Share.prototype.init = function () { 21299 if (!this.settings.share) { 21300 return; 21301 } 21302 this.shareOptions = __spreadArrays(this.getDefaultShareOptions(), this.settings.additionalShareOptions); 21303 this.setLgShareMarkup(); 21304 this.core.outer 21305 .find('.lg-share .lg-dropdown') 21306 .append(this.getShareListHtml()); 21307 this.core.LGel.on(lGEvents.afterSlide + ".share", this.onAfterSlide.bind(this)); 21308 }; 21309 Share.prototype.getShareListHtml = function () { 21310 var shareHtml = ''; 21311 this.shareOptions.forEach(function (shareOption) { 21312 shareHtml += shareOption.dropdownHTML; 21313 }); 21314 return shareHtml; 21315 }; 21316 Share.prototype.setLgShareMarkup = function () { 21317 var _this = this; 21318 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>"); 21319 this.core.outer.append('<div class="lg-dropdown-overlay"></div>'); 21320 var $shareButton = this.core.outer.find('.lg-share'); 21321 $shareButton.first().on('click.lg', function () { 21322 _this.core.outer.toggleClass('lg-dropdown-active'); 21323 if (_this.core.outer.hasClass('lg-dropdown-active')) { 21324 _this.core.outer.attr('aria-expanded', true); 21325 } 21326 else { 21327 _this.core.outer.attr('aria-expanded', false); 21328 } 21329 }); 21330 this.core.outer 21331 .find('.lg-dropdown-overlay') 21332 .first() 21333 .on('click.lg', function () { 21334 _this.core.outer.removeClass('lg-dropdown-active'); 21335 _this.core.outer.attr('aria-expanded', false); 21336 }); 21337 }; 21338 Share.prototype.onAfterSlide = function (event) { 21339 var _this = this; 21340 var index = event.detail.index; 21341 var currentItem = this.core.galleryItems[index]; 21342 setTimeout(function () { 21343 _this.shareOptions.forEach(function (shareOption) { 21344 var selector = shareOption.selector; 21345 _this.core.outer 21346 .find(selector) 21347 .attr('href', shareOption.generateLink(currentItem)); 21348 }); 21349 }, 100); 21350 }; 21351 Share.prototype.getShareListItemHTML = function (type, text) { 21352 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>"; 21353 }; 21354 Share.prototype.getDefaultShareOptions = function () { 21355 return __spreadArrays((this.settings.facebook 21356 ? [ 21357 { 21358 type: 'facebook', 21359 generateLink: getFacebookShareLink,
21360 dropdownHTML: this.getShareListItemHTML('facebook', this.settings.facebookDropdownText), 21361 selector: '.lg-share-facebook', 21362 }, 21363 ] 21364 : []), (this.settings.twitter 21365 ? [ 21366 { 21367 type: 'twitter', 21368 generateLink: getTwitterShareLink, 21369 dropdownHTML: this.getShareListItemHTML('twitter', this.settings.twitterDropdownText), 21370 selector: '.lg-share-twitter', 21371 }, 21372 ] 21373 : []), (this.settings.pinterest 21374 ? [ 21375 { 21376 type: 'pinterest', 21377 generateLink: getPinterestShareLink, 21378 dropdownHTML: this.getShareListItemHTML('pinterest', this.settings.pinterestDropdownText), 21379 selector: '.lg-share-pinterest', 21380 }, 21381 ] 21382 : [])); 21383 }; 21384 Share.prototype.destroy = function () { 21385 this.core.outer.find('.lg-dropdown-overlay').remove(); 21386 this.core.outer.find('.lg-share').remove(); 21387 this.core.LGel.off('.lg.share'); 21388 this.core.LGel.off('.share'); 21389 }; 21390 return Share; 21391 }()); 21392 21393 return Share; 21394 21395}))); 21396/*! 21397 * lightgallery | 2.5.0 | June 13th 2022 21398 * http://www.lightgalleryjs.com/ 21399 * Copyright (c) 2020 Sachin Neravath; 21400 * @license GPLv3 21401 */ 21402 21403(function (global, factory) { 21404 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 21405 typeof define === 'function' && define.amd ? define(factory) : 21406 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lgThumbnail = factory()); 21407}(this, (function () { 'use strict'; 21408 21409 /*! ***************************************************************************** 21410 Copyright (c) Microsoft Corporation. 21411 21412 Permission to use, copy, modify, and/or distribute this software for any 21413 purpose with or without fee is hereby granted. 21414 21415 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 21416 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 21417 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 21418 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 21419 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 21420 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 21421 PERFORMANCE OF THIS SOFTWARE. 21422 ***************************************************************************** */ 21423 21424 var __assign = function() { 21425 __assign = Object.assign || function __assign(t) { 21426 for (var s, i = 1, n = arguments.length; i < n; i++) { 21427 s = arguments[i]; 21428 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 21429 } 21430 return t; 21431 }; 21432 return __assign.apply(this, arguments); 21433 }; 21434 21435 var thumbnailsSettings = { 21436 thumbnail: true, 21437 animateThumb: true, 21438 currentPagerPosition: 'middle', 21439 alignThumbnails: 'middle', 21440 thumbWidth: 100, 21441 thumbHeight: '80px', 21442 thumbMargin: 5, 21443 appendThumbnailsTo: '.lg-components', 21444 toggleThumb: false, 21445 enableThumbDrag: true, 21446 enableThumbSwipe: true, 21447 thumbnailSwipeThreshold: 10, 21448 loadYouTubeThumbnail: true, 21449 youTubeThumbSize: 1, 21450 thumbnailPluginStrings: { 21451 toggleThumbnails: 'Toggle thumbnails', 21452 }, 21453 }; 21454 21455 /** 21456 * List of lightGallery events 21457 * All events should be documented here 21458 * Below interfaces are used to build the website documentations 21459 * */ 21460 var lGEvents = { 21461 afterAppendSlide: 'lgAfterAppendSlide', 21462 init: 'lgInit', 21463 hasVideo: 'lgHasVideo', 21464 containerResize: 'lgContainerResize', 21465 updateSlides: 'lgUpdateSlides', 21466 afterAppendSubHtml: 'lgAfterAppendSubHtml', 21467 beforeOpen: 'lgBeforeOpen', 21468 afterOpen: 'lgAfterOpen', 21469 slideItemLoad: 'lgSlideItemLoad', 21470 beforeSlide: 'lgBeforeSlide', 21471 afterSlide: 'lgAfterSlide', 21472 posterClick: 'lgPosterClick', 21473 dragStart: 'lgDragStart', 21474 dragMove: 'lgDragMove', 21475 dragEnd: 'lgDragEnd', 21476 beforeNextSlide: 'lgBeforeNextSlide', 21477 beforePrevSlide: 'lgBeforePrevSlide', 21478 beforeClose: 'lgBeforeClose', 21479 afterClose: 'lgAfterClose', 21480 rotateLeft: 'lgRotateLeft', 21481 rotateRight: 'lgRotateRight', 21482 flipHorizontal: 'lgFlipHorizontal', 21483 flipVertical: 'lgFlipVertical', 21484 autoplay: 'lgAutoplay', 21485 autoplayStart: 'lgAutoplayStart', 21486 autoplayStop: 'lgAutoplayStop', 21487 }; 21488 21489 var Thumbnail = /** @class */ (function () { 21490 function Thumbnail(instance, $LG) { 21491 this.thumbOuterWidth = 0; 21492 this.thumbTotalWidth = 0; 21493 this.translateX = 0; 21494 this.thumbClickable = false;
21495 // get lightGallery core plugin instance 21496 this.core = instance; 21497 this.$LG = $LG; 21498 return this; 21499 } 21500 Thumbnail.prototype.init = function () { 21501 // extend module default settings with lightGallery core settings 21502 this.settings = __assign(__assign({}, thumbnailsSettings), this.core.settings); 21503 this.thumbOuterWidth = 0; 21504 this.thumbTotalWidth = 21505 this.core.galleryItems.length * 21506 (this.settings.thumbWidth + this.settings.thumbMargin); 21507 // Thumbnail animation value 21508 this.translateX = 0; 21509 this.setAnimateThumbStyles(); 21510 if (!this.core.settings.allowMediaOverlap) { 21511 this.settings.toggleThumb = false; 21512 } 21513 if (this.settings.thumbnail) { 21514 this.build(); 21515 if (this.settings.animateThumb) { 21516 if (this.settings.enableThumbDrag) { 21517 this.enableThumbDrag(); 21518 } 21519 if (this.settings.enableThumbSwipe) { 21520 this.enableThumbSwipe(); 21521 } 21522 this.thumbClickable = false; 21523 } 21524 else { 21525 this.thumbClickable = true; 21526 } 21527 this.toggleThumbBar(); 21528 this.thumbKeyPress(); 21529 } 21530 }; 21531 Thumbnail.prototype.build = function () { 21532 var _this = this; 21533 this.setThumbMarkup(); 21534 this.manageActiveClassOnSlideChange(); 21535 this.$lgThumb.first().on('click.lg touchend.lg', function (e) { 21536 var $target = _this.$LG(e.target); 21537 if (!$target.hasAttribute('data-lg-item-id')) { 21538 return; 21539 } 21540 setTimeout(function () { 21541 // In IE9 and bellow touch does not support 21542 // Go to slide if browser does not support css transitions 21543 if (_this.thumbClickable && !_this.core.lgBusy) { 21544 var index = parseInt($target.attr('data-lg-item-id')); 21545 _this.core.slide(index, false, true, false); 21546 } 21547 }, 50); 21548 }); 21549 //Uncode edit ##START## 21550 // this.core.LGel.on(lGEvents.beforeSlide + ".thumb", function (event) { 21551 this.core.LGel.on(lGEvents.beforeSlide, function (event) { 21552 //Uncode edit ##END## 21553 var index = event.detail.index; 21554 _this.animateThumb(index); 21555 }); 21556 //Uncode edit ##START## 21557 // this.core.LGel.on(lGEvents.beforeOpen + ".thumb", function () { 21558 this.core.LGel.on(lGEvents.beforeOpen, function () { 21559 //Uncode edit ##END## 21560 _this.thumbOuterWidth = _this.core.outer.get().offsetWidth; 21561 }); 21562 //Uncode edit ##START## 21563 // this.core.LGel.on(lGEvents.updateSlides + ".thumb", function () { 21564 this.core.LGel.on(lGEvents.updateSlides, function () { 21565 //Uncode edit ##END## 21566 _this.rebuildThumbnails(); 21567 }); 21568 //Uncode edit ##START## 21569 // this.core.LGel.on(lGEvents.containerResize + ".thumb", function () { 21570 this.core.LGel.on(lGEvents.containerResize, function () { 21571 //Uncode edit ##END## 21572 if (!_this.core.lgOpened) 21573 return; 21574 setTimeout(function () { 21575 _this.thumbOuterWidth = _this.core.outer.get().offsetWidth; 21576 _this.animateThumb(_this.core.index); 21577 _this.thumbOuterWidth = _this.core.outer.get().offsetWidth; 21578 }, 50); 21579 }); 21580 }; 21581 Thumbnail.prototype.setThumbMarkup = function () { 21582 var thumbOuterClassNames = 'lg-thumb-outer '; 21583 if (this.settings.alignThumbnails) { 21584 thumbOuterClassNames += "lg-thumb-align-" + this.settings.alignThumbnails; 21585 } 21586 var html = "<div class=\"" + thumbOuterClassNames + "\">\n <div class=\"lg-thumb lg-group\">\n </div>\n </div>"; 21587 this.core.outer.addClass('lg-has-thumb'); 21588 if (this.settings.appendThumbnailsTo === '.lg-components') { 21589 this.core.$lgComponents.append(html); 21590 } 21591 else { 21592 this.core.outer.append(html); 21593 } 21594 this.$thumbOuter = this.core.outer.find('.lg-thumb-outer').first(); 21595 this.$lgThumb = this.core.outer.find('.lg-thumb').first(); 21596 if (this.settings.animateThumb) { 21597 this.core.outer 21598 .find('.lg-thumb') 21599 .css('transition-duration', this.core.settings.speed + 'ms') 21600 .css('width', this.thumbTotalWidth + 'px') 21601 .css('position', 'relative'); 21602 } 21603 this.setThumbItemHtml(this.core.galleryItems); 21604 }; 21605 Thumbnail.prototype.enableThumbDrag = function () { 21606 var _this = this; 21607 var thumbDragUtils = { 21608 cords: { 21609 startX: 0, 21610 endX: 0, 21611 }, 21612 isMoved: false, 21613 newTranslateX: 0, 21614 startTime: new Date(), 21615 endTime: new Date(), 21616 touchMoveTime: 0, 21617 }; 21618 var isDragging = false;
21619 this.$thumbOuter.addClass('lg-grab'); 21620 this.core.outer 21621 .find('.lg-thumb') 21622 .first() 21623 .on('mousedown.lg.thumb', function (e) { 21624 if (_this.thumbTotalWidth > _this.thumbOuterWidth) { 21625 // execute only on .lg-object 21626 e.preventDefault(); 21627 thumbDragUtils.cords.startX = e.pageX; 21628 thumbDragUtils.startTime = new Date(); 21629 _this.thumbClickable = false; 21630 isDragging = true; 21631 // ** Fix for webkit cursor issue https://code.google.com/p/chromium/issues/detail?id=26723 21632 _this.core.outer.get().scrollLeft += 1; 21633 _this.core.outer.get().scrollLeft -= 1; 21634 // * 21635 _this.$thumbOuter 21636 .removeClass('lg-grab') 21637 .addClass('lg-grabbing'); 21638 } 21639 }); 21640 this.$LG(window).on("mousemove.lg.thumb.global" + this.core.lgId, function (e) { 21641 if (!_this.core.lgOpened) 21642 return; 21643 if (isDragging) { 21644 thumbDragUtils.cords.endX = e.pageX; 21645 thumbDragUtils = _this.onThumbTouchMove(thumbDragUtils); 21646 } 21647 }); 21648 this.$LG(window).on("mouseup.lg.thumb.global" + this.core.lgId, function () { 21649 if (!_this.core.lgOpened) 21650 return; 21651 if (thumbDragUtils.isMoved) { 21652 thumbDragUtils = _this.onThumbTouchEnd(thumbDragUtils); 21653 } 21654 else { 21655 _this.thumbClickable = true; 21656 } 21657 if (isDragging) { 21658 isDragging = false; 21659 _this.$thumbOuter.removeClass('lg-grabbing').addClass('lg-grab'); 21660 } 21661 }); 21662 }; 21663 Thumbnail.prototype.enableThumbSwipe = function () { 21664 var _this = this; 21665 var thumbDragUtils = { 21666 cords: { 21667 startX: 0, 21668 endX: 0, 21669 }, 21670 isMoved: false, 21671 newTranslateX: 0, 21672 startTime: new Date(), 21673 endTime: new Date(), 21674 touchMoveTime: 0, 21675 }; 21676 this.$lgThumb.on('touchstart.lg', function (e) { 21677 if (_this.thumbTotalWidth > _this.thumbOuterWidth) { 21678 e.preventDefault(); 21679 thumbDragUtils.cords.startX = e.targetTouches[0].pageX; 21680 _this.thumbClickable = false; 21681 thumbDragUtils.startTime = new Date(); 21682 } 21683 }); 21684 this.$lgThumb.on('touchmove.lg', function (e) { 21685 if (_this.thumbTotalWidth > _this.thumbOuterWidth) { 21686 e.preventDefault(); 21687 thumbDragUtils.cords.endX = e.targetTouches[0].pageX; 21688 thumbDragUtils = _this.onThumbTouchMove(thumbDragUtils); 21689 } 21690 }); 21691 this.$lgThumb.on('touchend.lg', function () { 21692 if (thumbDragUtils.isMoved) { 21693 thumbDragUtils = _this.onThumbTouchEnd(thumbDragUtils); 21694 } 21695 else { 21696 _this.thumbClickable = true; 21697 } 21698 }); 21699 }; 21700 // Rebuild thumbnails 21701 Thumbnail.prototype.rebuildThumbnails = function () { 21702 var _this = this; 21703 // Remove transitions 21704 this.$thumbOuter.addClass('lg-rebuilding-thumbnails'); 21705 setTimeout(function () { 21706 _this.thumbTotalWidth = 21707 _this.core.galleryItems.length * 21708 (_this.settings.thumbWidth + _this.settings.thumbMargin); 21709 _this.$lgThumb.css('width', _this.thumbTotalWidth + 'px'); 21710 _this.$lgThumb.empty(); 21711 _this.setThumbItemHtml(_this.core.galleryItems); 21712 _this.animateThumb(_this.core.index); 21713 }, 50); 21714 setTimeout(function () { 21715 _this.$thumbOuter.removeClass('lg-rebuilding-thumbnails'); 21716 }, 200); 21717 }; 21718 // @ts-check 21719 Thumbnail.prototype.setTranslate = function (value) { 21720 this.$lgThumb.css('transform', 'translate3d(-' + value + 'px, 0px, 0px)'); 21721 }; 21722 Thumbnail.prototype.getPossibleTransformX = function (left) { 21723 if (left > this.thumbTotalWidth - this.thumbOuterWidth) { 21724 left = this.thumbTotalWidth - this.thumbOuterWidth; 21725 } 21726 if (left < 0) { 21727 left = 0; 21728 } 21729 return left; 21730 }; 21731 Thumbnail.prototype.animateThumb = function (index) { 21732 this.$lgThumb.css('transition-duration', this.core.settings.speed + 'ms'); 21733 if (this.settings.animateThumb) { 21734 var position = 0; 21735 switch (this.settings.currentPagerPosition) { 21736 case 'left': 21737 position = 0; 21738 break; 21739 case 'middle': 21740 position = 21741 this.thumbOuterWidth / 2 - this.settings.thumbWidth / 2; 21742 break; 21743 case 'right': 21744 position = this.thumbOuterWidth - this.settings.thumbWidth; 21745 } 21746 this.translateX = 21747 (this.settings.thumbWidth + this.settings.thumbMargin) * index - 21748 1 - 21749 position; 21750 if (this.translateX > this.thumbTotalWidth - this.thumbOuterWidth) { 21751 this.translateX = this.thumbTotalWidth - this.thumbOuterWidth; 21752 } 21753 if (this.translateX < 0) { 21754 this.translateX = 0; 21755 } 21756 this.setTranslate(this.translateX); 21757 } 21758 };
21759 Thumbnail.prototype.onThumbTouchMove = function (thumbDragUtils) { 21760 thumbDragUtils.newTranslateX = this.translateX; 21761 thumbDragUtils.isMoved = true; 21762 thumbDragUtils.touchMoveTime = new Date().valueOf(); 21763 thumbDragUtils.newTranslateX -= 21764 thumbDragUtils.cords.endX - thumbDragUtils.cords.startX; 21765 thumbDragUtils.newTranslateX = this.getPossibleTransformX(thumbDragUtils.newTranslateX); 21766 // move current slide 21767 this.setTranslate(thumbDragUtils.newTranslateX); 21768 this.$thumbOuter.addClass('lg-dragging'); 21769 return thumbDragUtils; 21770 }; 21771 Thumbnail.prototype.onThumbTouchEnd = function (thumbDragUtils) { 21772 thumbDragUtils.isMoved = false; 21773 thumbDragUtils.endTime = new Date(); 21774 this.$thumbOuter.removeClass('lg-dragging'); 21775 var touchDuration = thumbDragUtils.endTime.valueOf() - 21776 thumbDragUtils.startTime.valueOf(); 21777 var distanceXnew = thumbDragUtils.cords.endX - thumbDragUtils.cords.startX; 21778 var speedX = Math.abs(distanceXnew) / touchDuration; 21779 // Some magical numbers 21780 // Can be improved 21781 if (speedX > 0.15 && 21782 thumbDragUtils.endTime.valueOf() - thumbDragUtils.touchMoveTime < 30) { 21783 speedX += 1; 21784 if (speedX > 2) { 21785 speedX += 1; 21786 } 21787 speedX = 21788 speedX + 21789 speedX * (Math.abs(distanceXnew) / this.thumbOuterWidth); 21790 this.$lgThumb.css('transition-duration', Math.min(speedX - 1, 2) + 'settings'); 21791 distanceXnew = distanceXnew * speedX; 21792 this.translateX = this.getPossibleTransformX(this.translateX - distanceXnew); 21793 this.setTranslate(this.translateX); 21794 } 21795 else { 21796 this.translateX = thumbDragUtils.newTranslateX; 21797 } 21798 if (Math.abs(thumbDragUtils.cords.endX - thumbDragUtils.cords.startX) < 21799 this.settings.thumbnailSwipeThreshold) { 21800 this.thumbClickable = true; 21801 } 21802 return thumbDragUtils; 21803 }; 21804 Thumbnail.prototype.getThumbHtml = function (thumb, index) { 21805 var slideVideoInfo = this.core.galleryItems[index].__slideVideoInfo || {}; 21806 var thumbImg; 21807 if (slideVideoInfo.youtube) { 21808 if (this.settings.loadYouTubeThumbnail) { 21809 thumbImg = 21810 '//img.youtube.com/vi/' + 21811 slideVideoInfo.youtube[1] + 21812 '/' + 21813 this.settings.youTubeThumbSize + 21814 '.jpg'; 21815 } 21816 else { 21817 thumbImg = thumb; 21818 } 21819 } 21820 else { 21821 thumbImg = thumb; 21822 } 21823 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>"; 21824 }; 21825 Thumbnail.prototype.getThumbItemHtml = function (items) { 21826 var thumbList = ''; 21827 for (var i = 0; i < items.length; i++) { 21828 thumbList += this.getThumbHtml(items[i].thumb, i); 21829 } 21830 return thumbList; 21831 }; 21832 Thumbnail.prototype.setThumbItemHtml = function (items) { 21833 var thumbList = this.getThumbItemHtml(items); 21834 this.$lgThumb.html(thumbList); 21835 }; 21836 Thumbnail.prototype.setAnimateThumbStyles = function () { 21837 if (this.settings.animateThumb) { 21838 this.core.outer.addClass('lg-animate-thumb'); 21839 } 21840 }; 21841 // Manage thumbnail active calss
21842 Thumbnail.prototype.manageActiveClassOnSlideChange = function () { 21843 var _this = this; 21844 // manage active class for thumbnail 21845 //Uncode edit ##START## 21846 // this.core.LGel.on(lGEvents.beforeSlide + ".thumb", function (event) { 21847 this.core.LGel.on(lGEvents.beforeSlide, function (event) { 21848 //Uncode edit ##END## 21849 var $thumb = _this.core.outer.find('.lg-thumb-item'); 21850 var index = event.detail.index; 21851 $thumb.removeClass('active'); 21852 $thumb.eq(index).addClass('active'); 21853 }); 21854 }; 21855 // Toggle thumbnail bar 21856 Thumbnail.prototype.toggleThumbBar = function () { 21857 var _this = this; 21858 if (this.settings.toggleThumb) { 21859 this.core.outer.addClass('lg-can-toggle'); 21860 this.core.$toolbar.append('<button type="button" aria-label="' + 21861 this.settings.thumbnailPluginStrings['toggleThumbnails'] + 21862 '" class="lg-toggle-thumb lg-icon"></button>'); 21863 this.core.outer 21864 .find('.lg-toggle-thumb') 21865 .first() 21866 .on('click.lg', function () { 21867 _this.core.outer.toggleClass('lg-components-open'); 21868 }); 21869 } 21870 }; 21871 Thumbnail.prototype.thumbKeyPress = function () { 21872 var _this = this; 21873 this.$LG(window).on("keydown.lg.thumb.global" + this.core.lgId, function (e) { 21874 if (!_this.core.lgOpened || !_this.settings.toggleThumb) 21875 return; 21876 if (e.keyCode === 38) { 21877 e.preventDefault(); 21878 _this.core.outer.addClass('lg-components-open'); 21879 } 21880 else if (e.keyCode === 40) { 21881 e.preventDefault(); 21882 _this.core.outer.removeClass('lg-components-open'); 21883 } 21884 }); 21885 }; 21886 Thumbnail.prototype.destroy = function () { 21887 if (this.settings.thumbnail) { 21888 this.$LG(window).off(".lg.thumb.global" + this.core.lgId); 21889 this.core.LGel.off('.lg.thumb'); 21890 this.core.LGel.off('.thumb'); 21891 this.$thumbOuter.remove(); 21892 this.core.outer.removeClass('lg-has-thumb'); 21893 } 21894 }; 21895 return Thumbnail; 21896 }()); 21897 21898 return Thumbnail; 21899 21900}))); 21901/*! 21902 * lightgallery | 2.5.0 | June 13th 2022 21903 * http://www.lightgalleryjs.com/ 21904 * Copyright (c) 2020 Sachin Neravath; 21905 * @license GPLv3 21906 */ 21907 21908(function (global, factory) { 21909 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 21910 typeof define === 'function' && define.amd ? define(factory) : 21911 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lgVideo = factory()); 21912}(this, (function () { 'use strict'; 21913 21914 /*! ***************************************************************************** 21915 Copyright (c) Microsoft Corporation. 21916 21917 Permission to use, copy, modify, and/or distribute this software for any 21918 purpose with or without fee is hereby granted. 21919 21920 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 21921 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 21922 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 21923 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 21924 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 21925 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 21926 PERFORMANCE OF THIS SOFTWARE. 21927 ***************************************************************************** */ 21928 21929 var __assign = function() { 21930 __assign = Object.assign || function __assign(t) { 21931 for (var s, i = 1, n = arguments.length; i < n; i++) { 21932 s = arguments[i]; 21933 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 21934 } 21935 return t; 21936 }; 21937 return __assign.apply(this, arguments); 21938 }; 21939 21940 var videoSettings = { 21941 autoplayFirstVideo: true, 21942 youTubePlayerParams: false, 21943 vimeoPlayerParams: false, 21944 wistiaPlayerParams: false, 21945 gotoNextSlideOnVideoEnd: true, 21946 autoplayVideoOnSlide: false, 21947 videojs: false, 21948 videojsTheme: '', 21949 videojsOptions: {}, 21950 }; 21951 21952 /** 21953 * List of lightGallery events 21954 * All events should be documented here 21955 * Below interfaces are used to build the website documentations 21956 * */ 21957 var lGEvents = { 21958 afterAppendSlide: 'lgAfterAppendSlide', 21959 init: 'lgInit', 21960 hasVideo: 'lgHasVideo', 21961 containerResize: 'lgContainerResize', 21962 updateSlides: 'lgUpdateSlides', 21963 afterAppendSubHtml: 'lgAfterAppendSubHtml', 21964 beforeOpen: 'lgBeforeOpen', 21965 afterOpen: 'lgAfterOpen', 21966 slideItemLoad: 'lgSlideItemLoad', 21967 beforeSlide: 'lgBeforeSlide', 21968 afterSlide: 'lgAfterSlide', 21969 posterClick: 'lgPosterClick', 21970 dragStart: 'lgDragStart', 21971 dragMove: 'lgDragMove', 21972 dragEnd: 'lgDragEnd', 21973 beforeNextSlide: 'lgBeforeNextSlide', 21974 beforePrevSlide: 'lgBeforePrevSlide', 21975 beforeClose: 'lgBeforeClose', 21976 afterClose: 'lgAfterClose', 21977 rotateLeft: 'lgRotateLeft', 21978 rotateRight: 'lgRotateRight', 21979 flipHorizontal: 'lgFlipHorizontal', 21980 flipVertical: 'lgFlipVertical', 21981 autoplay: 'lgAutoplay', 21982 autoplayStart: 'lgAutoplayStart', 21983 autoplayStop: 'lgAutoplayStop', 21984 }; 21985 21986 var param = function (obj) { 21987 return Object.keys(obj) 21988 .map(function (k) { 21989 return encodeURIComponent(k) + '=' + encodeURIComponent(obj[k]); 21990 }) 21991 .join('&'); 21992 }; 21993 var getVimeoURLParams = function (defaultParams, videoInfo) { 21994 if (!videoInfo || !videoInfo.vimeo) 21995 return '';
21996 var urlParams = videoInfo.vimeo[2] || ''; 21997 var defaultPlayerParams = defaultParams && Object.keys(defaultParams).length !== 0 21998 ? '&' + param(defaultParams) 21999 : ''; 22000 // Support private video 22001 var urlWithHash = videoInfo.vimeo[0].split('/').pop() || ''; 22002 var urlWithHashWithParams = urlWithHash.split('?')[0] || ''; 22003 var hash = urlWithHashWithParams.split('#')[0]; 22004 var isPrivate = videoInfo.vimeo[1] !== hash; 22005 if (isPrivate) { 22006 urlParams = urlParams.replace("/" + hash, ''); 22007 } 22008 urlParams = 22009 urlParams[0] == '?' ? '&' + urlParams.slice(1) : urlParams || ''; 22010 // For vimeo last params gets priority if duplicates found 22011 // Uncode edit ##START## 22012 var vimeoPlayerParams = '?autoplay=0'; 22013 if ( videoInfo.autoplay !== '' ) { 22014 vimeoPlayerParams = vimeoPlayerParams.replace(new RegExp('([?&])autoplay=(.*?)(&|$)'), '$1$3' ); 22015 vimeoPlayerParams = vimeoPlayerParams.replace(new RegExp('([?&])autoplay(&|$)'), '$1$2' ); 22016 } else { 22017 if ( typeof SiteParameters !== 'undefined' && typeof SiteParameters.vimeoPlayerParams !== 'undefined' && SiteParameters.vimeoPlayerParams !== '' ) { 22018 vimeoPlayerParams = SiteParameters.vimeoPlayerParams; 22019 } 22020 } 22021 if ( videoInfo.muted !== '' ) { 22022 vimeoPlayerParams += '&muted=' + (videoInfo.muted === 'yes'); 22023 } else { 22024 if ( urlParams.indexOf('muted=') < 0 && vimeoPlayerParams.indexOf('muted=') < 0 ) { 22025 vimeoPlayerParams += '&muted=1'; 22026 } 22027 } 22028 // var vimeoPlayerParams = "?autoplay=0&muted=1" + (isPrivate ? "&h=" + hash : '') + defaultPlayerParams + urlParams; 22029 vimeoPlayerParams += (isPrivate ? "&h=" + hash : '') + defaultPlayerParams + urlParams; 22030 // Uncode edit ##END## 22031 return vimeoPlayerParams; 22032 }; 22033 22034 /** 22035 * Video module for lightGallery 22036 * Supports HTML5, YouTube, Vimeo, wistia videos 22037 * 22038 * 22039 * @ref Wistia 22040 * https://wistia.com/support/integrations/wordpress(How to get url) 22041 * https://wistia.com/support/developers/embed-options#using-embed-options 22042 * https://wistia.com/support/developers/player-api 22043 * https://wistia.com/support/developers/construct-an-embed-code 22044 * http://jsfiddle.net/xvnm7xLm/ 22045 * https://developer.mozilla.org/en-US/docs/Web/HTML/Element/video 22046 * https://wistia.com/support/embed-and-share/sharing-videos 22047 * https://private-sharing.wistia.com/medias/mwhrulrucj 22048 * 22049 * @ref Youtube 22050 * https://developers.google.com/youtube/player_parameters#enablejsapi 22051 * https://developers.google.com/youtube/iframe_api_reference 22052 * https://developer.chrome.com/blog/autoplay/#iframe-delegation 22053 * 22054 * @ref Vimeo 22055 * https://stackoverflow.com/questions/10488943/easy-way-to-get-vimeo-id-from-a-vimeo-url 22056 * https://vimeo.zendesk.com/hc/en-us/articles/360000121668-Starting-playback-at-a-specific-timecode 22057 * https://vimeo.zendesk.com/hc/en-us/articles/360001494447-Using-Player-Parameters 22058 */ 22059 var Video = /** @class */ (function () { 22060 function Video(instance) { 22061 // get lightGallery core plugin instance 22062 this.core = instance; 22063 this.settings = __assign(__assign({}, videoSettings), this.core.settings); 22064 return this; 22065 } 22066 Video.prototype.init = function () { 22067 var _this = this; 22068 /** 22069 * Event triggered when video url found without poster 22070 * Append video HTML 22071 * Play if autoplayFirstVideo is true 22072 */ 22073 this.core.LGel.on(lGEvents.hasVideo + ".video", this.onHasVideo.bind(this)); 22074 this.core.LGel.on(lGEvents.posterClick + ".video", function () { 22075 var $el = _this.core.getSlideItem(_this.core.index); 22076 _this.loadVideoOnPosterClick($el); 22077 }); 22078 this.core.LGel.on(lGEvents.slideItemLoad + ".video", this.onSlideItemLoad.bind(this)); 22079 // @desc fired immediately before each slide transition. 22080 this.core.LGel.on(lGEvents.beforeSlide + ".video", this.onBeforeSlide.bind(this)); 22081 // @desc fired immediately after each slide transition. 22082 this.core.LGel.on(lGEvents.afterSlide + ".video", this.onAfterSlide.bind(this)); 22083 }; 22084 /** 22085 * @desc Event triggered when a slide is completely loaded 22086 * 22087 * @param {Event} event - lightGalley custom event 22088 */ 22089 Video.prototype.onSlideItemLoad = function (event) { 22090 var _this = this; 22091 var _a = event.detail, isFirstSlide = _a.isFirstSlide, index = _a.index; 22092 // Should check the active slide as well as user may have moved to different slide before the first slide is loaded 22093 if (this.settings.autoplayFirstVideo && 22094 isFirstSlide && 22095 index === this.core.index) { 22096 // Delay is just for the transition effect on video load 22097 setTimeout(function () { 22098 _this.loadAndPlayVideo(index); 22099 }, 200); 22100 } 22101 // Should not call on first slide. should check only if the slide is active 22102 if (!isFirstSlide && 22103 this.settings.autoplayVideoOnSlide && 22104 index === this.core.index) { 22105 setTimeout(function () { 22106 _this.loadAndPlayVideo(index); 22107 }, 500); 22108 } 22109 }; 22110 /** 22111 * @desc Event triggered when video url or poster found 22112 * Append video HTML is poster is not given 22113 * Play if autoplayFirstVideo is true 22114 * 22115 * @param {Event} event - Javascript Event object. 22116 */ 22117 Video.prototype.onHasVideo = function (event) { 22118 var _a = event.detail, index = _a.index, src = _a.src, html5Video = _a.html5Video, hasPoster = _a.hasPoster; 22119 if (!hasPoster) { 22120 // All functions are called separately if poster exist in loadVideoOnPosterClick function 22121 this.appendVideos(this.core.getSlideItem(index), { 22122 src: src, 22123 addClass: 'lg-object', 22124 index: index, 22125 html5Video: html5Video, 22126 // Uncode edit ##START## 22127 autoplay: event.target.getAttribute('data-lb-autoplay'), 22128 muted: event.target.getAttribute('data-lb-muted'), 22129 // Uncode edit ##END## 22130 }); 22131 // Automatically navigate to next slide once video reaches the end. 22132 this.gotoNextSlideOnVideoEnd(src, index); 22133 } 22134 }; 22135 /** 22136 * @desc fired immediately before each slide transition. 22137 * Pause the previous video 22138 * Hide the download button if the slide contains YouTube, Vimeo, or Wistia videos. 22139 * 22140 * @param {Event} event - Javascript Event object. 22141 * @param {number} prevIndex - Previous index of the slide. 22142 * @param {number} index - Current index of the slide 22143 */ 22144 Video.prototype.onBeforeSlide = function (event) { 22145 if (this.core.lGalleryOn) { 22146 var prevIndex = event.detail.prevIndex; 22147 this.pauseVideo(prevIndex); 22148 } 22149 // Uncode edit ##START## 22150 var _a = event.detail, index = _a.index; 22151 var $slide = this.core.getSlideItem(index); 22152
22153 var iframe = $slide.selector.querySelector('iframe'); 22154 if ( iframe != null ) { 22155 22156 var data_play = iframe.getAttribute('data-autoplay'); 22157 if ( typeof data_play !== 'undefined' && data_play === '1' ) { 22158 this.loadAndPlayVideo(index); 22159 22160 var videoInfo = this.core.galleryItems[index].__slideVideoInfo || {}, 22161 $videoElement = this.core.getSlideItem(index).find('.lg-video-object').first(); 22162 if (videoInfo.vimeo) { 22163 var vimeoPlayer = new Vimeo.Player($videoElement.get()); 22164 vimeoPlayer.on('play', function () { 22165 vimeoPlayer.setCurrentTime(0); 22166 }); 22167 } else if ( videoInfo.youtube ) { 22168 try { 22169 $videoElement.get().contentWindow.postMessage("{\"event\":\"command\",\"func\":\"seekTo\",\"args\":[0, true]}", '*'); 22170 } 22171 catch (e) { 22172 console.warn(e); 22173 } 22174 } 22175 } 22176 } 22177 // Uncode edit ##END## 22178 }; 22179 /** 22180 * @desc fired immediately after each slide transition. 22181 * Play video if autoplayVideoOnSlide option is enabled. 22182 * 22183 * @param {Event} event - Javascript Event object. 22184 * @param {number} prevIndex - Previous index of the slide. 22185 * @param {number} index - Current index of the slide 22186 * @todo should check on onSlideLoad as well if video is not loaded on after slide 22187 */ 22188 Video.prototype.onAfterSlide = function (event) { 22189 var _this = this; 22190 var _a = event.detail, index = _a.index, prevIndex = _a.prevIndex; 22191 // Do not call on first slide 22192 var $slide = this.core.getSlideItem(index); 22193 if (this.settings.autoplayVideoOnSlide && index !== prevIndex) { 22194 if ($slide.hasClass('lg-complete')) { 22195 setTimeout(function () { 22196 _this.loadAndPlayVideo(index); 22197 }, 100); 22198 } 22199 } 22200 }; 22201 Video.prototype.loadAndPlayVideo = function (index) { 22202 var $slide = this.core.getSlideItem(index); 22203 var currentGalleryItem = this.core.galleryItems[index]; 22204 if (currentGalleryItem.poster) { 22205 this.loadVideoOnPosterClick($slide, true); 22206 } 22207 else { 22208 //Uncode edit ##START## 22209 // this.playVideo(index); 22210 var iframe = $slide.selector.querySelector('iframe'); 22211 if ( iframe != null ) { 22212 var data_play = iframe.getAttribute('data-autoplay'); 22213 if ( typeof data_play !== 'undefined' ) { 22214 if ( data_play === '1' && this.core.index == index ) { 22215 this.playVideo(index); 22216 } else { 22217 this.pauseVideo(index); 22218 } 22219 } 22220 } 22221 //Uncode edit ##END## 22222 } 22223 }; 22224 /** 22225 * Play HTML5, Youtube, Vimeo or Wistia videos in a particular slide. 22226 * @param {number} index - Index of the slide 22227 */ 22228 Video.prototype.playVideo = function (index) { 22229 this.controlVideo(index, 'play'); 22230 }; 22231 /** 22232 * Pause HTML5, Youtube, Vimeo or Wistia videos in a particular slide. 22233 * @param {number} index - Index of the slide 22234 */ 22235 Video.prototype.pauseVideo = function (index) { 22236 this.controlVideo(index, 'pause'); 22237 }; 22238 // Uncode edit ##START## 22239 //Video.prototype.getVideoHtml = function (src, addClass, index, html5Video) { 22240 Video.prototype.getVideoHtml = function (src, addClass, index, html5Video, autoplay, muted) { 22241 // Uncode edit ##END## 22242 var video = ''; 22243 var videoInfo = this.core.galleryItems[index] 22244 .__slideVideoInfo || {}; 22245 var currentGalleryItem = this.core.galleryItems[index]; 22246 var videoTitle = currentGalleryItem.title || currentGalleryItem.alt; 22247 videoTitle = videoTitle ? 'title="' + videoTitle + '"' : ''; 22248 var commonIframeProps = "allowtransparency=\"true\"\n frameborder=\"0\"\n scrolling=\"no\"\n allowfullscreen\n mozallowfullscreen\n webkitallowfullscreen\n oallowfullscreen\n msallowfullscreen"; 22249 if (videoInfo.youtube) { 22250 var videoId = 'lg-youtube' + index; 22251 var slideUrlParams = videoInfo.youtube[2] 22252 ? videoInfo.youtube[2] + '&' 22253 : ''; 22254 // For youtube first parms gets priority if duplicates found 22255 // Uncode edit ##START## 22256 // var youTubePlayerParams = "?" + slideUrlParams + "wmode=opaque&autoplay=0&mute=1&enablejsapi=1"; 22257 var youTubePlayerParams = "?" + slideUrlParams + "wmode=opaque&enablejsapi=1"; 22258 if ( ( slideUrlParams.indexOf('autoplay=') < 0 && youTubePlayerParams.indexOf('autoplay=') < 0 ) ) { 22259 youTubePlayerParams += '&autoplay=0'; 22260 } 22261 if ( slideUrlParams.indexOf('mute=') < 0 && youTubePlayerParams.indexOf('mute=') < 0 ) { 22262 youTubePlayerParams += '&mute=1'; 22263 } 22264 var data_video = ''; 22265 if ( autoplay !== '' ) { 22266 //youTubePlayerParams = youTubePlayerParams.replace(new RegExp('([?&])autoplay=(.*?)(&|$)'), '$1autoplay=' + (autoplay === 'yes' ? 1 : 0) + '$3' ); 22267 youTubePlayerParams = youTubePlayerParams.replace(new RegExp('([?&])autoplay=(.*?)(&|$)'), '$1$3' ); 22268 youTubePlayerParams = youTubePlayerParams.replace(new RegExp('([?&])autoplay'), '$1' ); 22269 data_video = ' data-autoplay="' + (autoplay === 'yes' ? 1 : 0) + '"'; 22270 } 22271 // if ( muted !== '' ) { 22272 // youTubePlayerParams = youTubePlayerParams.replace(new RegExp('([?&])mute=(.*?)(&|$)'), '$1mute=' + (muted === 'yes' ? 1 : 0) + '$3' ); 22273 // } 22274 youTubePlayerParams = youTubePlayerParams.replace(new RegExp('([?&])mute=(.*?)(&|$)'), '$1$3' ); 22275 22276 youTubePlayerParams = youTubePlayerParams.replace('??', '?'); 22277 // Uncode edit ##END## 22278 var playerParams = youTubePlayerParams + 22279 (this.settings.youTubePlayerParams 22280 ? '&' + param(this.settings.youTubePlayerParams) 22281 : ''); 22282 // Uncode edit ##START## 22283 // 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>"; 22284 video = "<iframe allow=\"autoplay\"" + data_video + " id=" + videoId + " class=\"lg-video-object lg-youtube " + addClass + "\" " + videoTitle + " src=\"//www.youtube.com/embed/" + (videoInfo.youtube[1] + playerParams) + "\" " + commonIframeProps + "></iframe>"; 22285 var tag = document.createElement('script'); 22286 tag.src = "//www.youtube.com/player_api"; 22287 var firstScriptTag = document.getElementsByTagName('script')[0]; 22288 firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); 22289 22290 // Replace the 'ytplayer' element with an <iframe> and 22291 // YouTube player after the API code downloads. 22292 var ytIframeplayer, 22293 setMute = muted === 'yes' ? 0 : 100; 22294 window.onYouTubePlayerAPIReady = function() { 22295 ytIframeplayer = new YT.Player(videoId, { 22296 videoId: videoInfo.youtube[1], 22297 events: { 22298 'onReady': function (event) { 22299 event.target.setVolume(setMute); 22300 } 22301 } 22302 }); 22303 } 22304 // Uncode edit ##END## 22305 } 22306 else if (videoInfo.vimeo) { 22307 var videoId = 'lg-vimeo' + index; 22308 // Uncode edit ##START## 22309 videoInfo.autoplay = autoplay; 22310 videoInfo.muted = muted; 22311 // Uncode edit ##END## 22312 var playerParams = getVimeoURLParams(this.settings.vimeoPlayerParams, videoInfo); 22313 // Uncode edit ##START## 22314 // 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>"; 22315 var data_video = ''; 22316 if ( autoplay !== '' ) { 22317 data_video = ' data-autoplay="' + (autoplay === 'yes' ? 1 : 0) + '"'; 22318 } 22319 video = "<iframe allow=\"autoplay\"" + data_video + " id=" + videoId + " class=\"lg-video-object lg-vimeo " + addClass + "\" " + videoTitle + " src=\"//player.vimeo.com/video/" + (videoInfo.vimeo[1] + playerParams) + "\" " + commonIframeProps + "></iframe>"; 22320 // Uncode edit ##END## 22321 } 22322 else if (videoInfo.wistia) { 22323 var wistiaId = 'lg-wistia' + index; 22324 var playerParams = param(this.settings.wistiaPlayerParams); 22325 playerParams = playerParams ? '?' + playerParams : ''; 22326 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>"; 22327 } 22328 else if (videoInfo.html5) { 22329 var html5VideoMarkup = ''; 22330 for (var i = 0; i < html5Video.source.length; i++) { 22331 html5VideoMarkup += "<source src=\"" + html5Video.source[i].src + "\" type=\"" + html5Video.source[i].type + "\">"; 22332 } 22333 if (html5Video.tracks) { 22334 var _loop_1 = function (i) { 22335 var trackAttributes = ''; 22336 var track = html5Video.tracks[i]; 22337 Object.keys(track || {}
22337).forEach(function (key) { 22338 trackAttributes += key + "=\"" + track[key] + "\" "; 22339 }); 22340 html5VideoMarkup += "<track " + trackAttributes + ">"; 22341 }; 22342 for (var i = 0; i < html5Video.tracks.length; i++) { 22343 _loop_1(i); 22344 } 22345 } 22346 var html5VideoAttrs_1 = ''; 22347 var videoAttributes_1 = html5Video.attributes || {}; 22348 Object.keys(videoAttributes_1 || {}).forEach(function (key) { 22349 html5VideoAttrs_1 += key + "=\"" + videoAttributes_1[key] + "\" "; 22350 }); 22351 video = "<video class=\"lg-video-object lg-html5 " + (this.settings.videojs && this.settings.videojsTheme 22352 ? this.settings.videojsTheme + ' ' 22353 : '') + " " + (this.settings.videojs ? ' video-js' : '') + "\" " + html5VideoAttrs_1 + ">\n " + html5VideoMarkup + "\n Your browser does not support HTML5 video.\n </video>"; 22354 } 22355 return video; 22356 }; 22357 /** 22358 * @desc - Append videos to the slide 22359 * 22360 * @param {HTMLElement} el - slide element 22361 * @param {Object} videoParams - Video parameters, Contains src, class, index, htmlVideo 22362 */ 22363 Video.prototype.appendVideos = function (el, videoParams) { 22364 var _a; 22365 // Uncode edit ##START## 22366 // var videoHtml = this.getVideoHtml(videoParams.src, videoParams.addClass, videoParams.index, videoParams.html5Video); 22367 var videoHtml = this.getVideoHtml(videoParams.src, videoParams.addClass, videoParams.index, videoParams.html5Video, videoParams.autoplay, videoParams.muted); 22368 // Uncode edit ##END## 22369 el.find('.lg-video-cont').append(videoHtml); 22370 var $videoElement = el.find('.lg-video-object').first(); 22371 if (videoParams.html5Video) { 22372 $videoElement.on('mousedown.lg.video', function (e) { 22373 e.stopPropagation(); 22374 }); 22375 } 22376 if (this.settings.videojs && ((_a = this.core.galleryItems[videoParams.index].__slideVideoInfo) === null || _a === void 0 ? void 0 : _a.html5)) { 22377 try { 22378 return videojs($videoElement.get(), this.settings.videojsOptions); 22379 } 22380 catch (e) { 22381 console.warn('lightGallery:- Make sure you have included videojs'); 22382 } 22383 } 22384 }; 22385 Video.prototype.gotoNextSlideOnVideoEnd = function (src, index) { 22386 var _this = this; 22387 var $videoElement = this.core 22388 .getSlideItem(index) 22389 .find('.lg-video-object') 22390 .first(); 22391 var videoInfo = this.core.galleryItems[index].__slideVideoInfo || {}; 22392 if (this.settings.gotoNextSlideOnVideoEnd) { 22393 if (videoInfo.html5) { 22394 $videoElement.on('ended', function () { 22395 _this.core.goToNextSlide(); 22396 }); 22397 } 22398 else if (videoInfo.vimeo) { 22399 try { 22400 // https://github.com/vimeo/player.js/#ended 22401 new Vimeo.Player($videoElement.get()).on('ended', function () { 22402 _this.core.goToNextSlide(); 22403 }); 22404 } 22405 catch (e) { 22406 console.warn('lightGallery:- Make sure you have included //github.com/vimeo/player.js'); 22407 } 22408 } 22409 else if (videoInfo.wistia) { 22410 try { 22411 window._wq = window._wq || []; 22412 // @todo Event is gettign triggered multiple times 22413 window._wq.push({ 22414 id: $videoElement.attr('id'), 22415 onReady: function (video) { 22416 video.bind('end', function () { 22417 _this.core.goToNextSlide(); 22418 }); 22419 }, 22420 }); 22421 } 22422 catch (e) { 22423 console.warn('lightGallery:- Make sure you have included //fast.wistia.com/assets/external/E-v1.js'); 22424 } 22425 } 22426 } 22427 }; 22428 Video.prototype.controlVideo = function (index, action) { 22429 var $videoElement = this.core 22430 .getSlideItem(index) 22431 .find('.lg-video-object') 22432 .first(); 22433 var videoInfo = this.core.galleryItems[index].__slideVideoInfo || {}; 22434 if (!$videoElement.get()) 22435 return; 22436 if (videoInfo.youtube) { 22437 try { 22438 $videoElement.get().contentWindow.postMessage("{\"event\":\"command\",\"func\":\"" + action + "Video\",\"args\":\"\"}", '*'); 22439 } 22440 catch (e) { 22441 console.warn("lightGallery:- " + e); 22442 } 22443 } 22444 else if (videoInfo.vimeo) { 22445 try { 22446 new Vimeo.Player($videoElement.get())[action](); 22447 } 22448 catch (e) { 22449 console.warn('lightGallery:- Make sure you have included //github.com/vimeo/player.js'); 22450 } 22451 } 22452 else if (videoInfo.html5) { 22453 if (this.settings.videojs) { 22454 try { 22455 videojs($videoElement.get())[action](); 22456 } 22457 catch (e) { 22458 console.warn('lightGallery:- Make sure you have included videojs'); 22459 } 22460 } 22461 else { 22462 $videoElement.get()[action](); 22463 } 22464 } 22465 else if (videoInfo.wistia) { 22466 try { 22467 window._wq = window._wq || []; 22468 // @todo Find a way to destroy wistia player instance 22469 window._wq.push({ 22470 id: $videoElement.attr('id'), 22471 onReady: function (video) { 22472 video[action](); 22473 }, 22474 }); 22475 } 22476 catch (e) { 22477 console.warn('lightGallery:- Make sure you have included //fast.wistia.com/assets/external/E-v1.js'); 22478 } 22479 } 22480 }; 22481 Video.prototype.loadVideoOnPosterClick = function ($el, forcePlay) { 22482 var _this = this; 22483 // check slide has poster 22484 if (!$el.hasClass('lg-video-loaded')) { 22485 // check already video element present
22486 if (!$el.hasClass('lg-has-video')) { 22487 $el.addClass('lg-has-video'); 22488 var _html = void 0; 22489 var _src = this.core.galleryItems[this.core.index].src; 22490 var video = this.core.galleryItems[this.core.index].video; 22491 if (video) { 22492 _html = 22493 typeof video === 'string' ? JSON.parse(video) : video; 22494 } 22495 var videoJsPlayer_1 = this.appendVideos($el, { 22496 src: _src, 22497 addClass: '', 22498 index: this.core.index, 22499 html5Video: _html, 22500 }); 22501 this.gotoNextSlideOnVideoEnd(_src, this.core.index); 22502 var $tempImg = $el.find('.lg-object').first().get(); 22503 // @todo make sure it is working 22504 $el.find('.lg-video-cont').first().append($tempImg); 22505 $el.addClass('lg-video-loading'); 22506 videoJsPlayer_1 && 22507 videoJsPlayer_1.ready(function () { 22508 videoJsPlayer_1.on('loadedmetadata', function () { 22509 _this.onVideoLoadAfterPosterClick($el, _this.core.index); 22510 }); 22511 }); 22512 $el.find('.lg-video-object') 22513 .first() 22514 .on('load.lg error.lg loadedmetadata.lg', function () { 22515 setTimeout(function () { 22516 _this.onVideoLoadAfterPosterClick($el, _this.core.index); 22517 }, 50); 22518 }); 22519 } 22520 else { 22521 this.playVideo(this.core.index); 22522 } 22523 } 22524 else if (forcePlay) { 22525 this.playVideo(this.core.index); 22526 } 22527 }; 22528 Video.prototype.onVideoLoadAfterPosterClick = function ($el, index) { 22529 $el.addClass('lg-video-loaded'); 22530 this.playVideo(index); 22531 }; 22532 Video.prototype.destroy = function () { 22533 this.core.LGel.off('.lg.video'); 22534 this.core.LGel.off('.video'); 22535 }; 22536 return Video; 22537 }()); 22538 22539 return Video; 22540 22541}))); 22542 22543 22544/*! @vimeo/player v2.17.1 | (c) 2022 Vimeo | MIT License | https://github.com/vimeo/player.js */ 22545!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:{}}
22545),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 22545
22545var 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)}
22545},{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 22545-23752
22545))}(),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}); 22546 22547/** 22548 * Owl carousel 22549 * @version 2.0.0-beta.3 22550 * @author Bartosz Wojciechowski 22551 * @license The MIT License (MIT) 22552 * @todo Lazy Load Icon 22553 * @todo prevent animationend bubling 22554 * @todo itemsScaleUp 22555 * @todo Test Zepto 22556 * @todo stagePadding calculate wrong active classes 22557 */ 22558;(function($, window, document, undefined) { 22559 22560 /** 22561 * Creates a carousel. 22562 * @class The Owl Carousel. 22563 * @public 22564 * @param {HTMLElement|jQuery} element - The element to create the carousel for. 22565 * @param {Object} [options] - The options 22566 */ 22567 function Owl(element, options) { 22568 22569 /** 22570 * Current settings for the carousel. 22571 * @public 22572 */ 22573 this.settings = null; 22574 22575 /** 22576 * Current options set by the caller including defaults. 22577 * @public 22578 */ 22579 this.options = $.extend({}, Owl.Defaults, options); 22580 22581 /** 22582 * Plugin element. 22583 * @public 22584 */ 22585 this.$element = $(element); 22586 22587 /** 22588 * Proxied event handlers. 22589 * @protected 22590 */ 22591 this._handlers = {}; 22592 22593 /** 22594 * References to the running plugins of this carousel. 22595 * @protected 22596 */ 22597 this._plugins = {}; 22598 22599 /** 22600 * Currently suppressed events to prevent them from beeing retriggered. 22601 * @protected 22602 */ 22603 this._supress = {}; 22604 22605 /** 22606 * Absolute current position. 22607 * @protected 22608 */ 22609 this._current = null; 22610 22611 /** 22612 * Animation speed in milliseconds. 22613 * @protected 22614 */ 22615 this._speed = null; 22616 22617 /** 22618 * Coordinates of all items in pixel. 22619 * @todo The name of this member is missleading. 22620 * @protected 22621 */ 22622 this._coordinates = []; 22623 22624 /** 22625 * Current breakpoint. 22626 * @todo Real media queries would be nice. 22627 * @protected 22628 */ 22629 this._breakpoint = null; 22630 22631 /** 22632 * Current width of the plugin element. 22633 */ 22634 this._width = null; 22635 22636 /** 22637 * All real items. 22638 * @protected 22639 */ 22640 this._items = []; 22641 22642 /** 22643 * All cloned items. 22644 * @protected 22645 */ 22646 this._clones = []; 22647 22648 /** 22649 * Merge values of all items. 22650 * @todo Maybe this could be part of a plugin. 22651 * @protected 22652 */ 22653 this._mergers = []; 22654 22655 /** 22656 * Widths of all items. 22657 */ 22658 this._widths = []; 22659 22660 /** 22661 * Invalidated parts within the update process. 22662 * @protected 22663 */ 22664 this._invalidated = {}; 22665 22666 /** 22667 * Ordered list of workers for the update process. 22668 * @protected 22669 */ 22670 this._pipe = []; 22671 22672 /** 22673 * Current state information for the drag operation. 22674 * @todo #261 22675 * @protected 22676 */ 22677 this._drag = { 22678 time: null, 22679 target: null, 22680 pointer: null, 22681 stage: { 22682 start: null, 22683 current: null 22684 }, 22685 direction: null 22686 }; 22687 22688 /** 22689 * Current state information and their tags. 22690 * @type {Object} 22691 * @protected 22692 */ 22693 this._states = { 22694 current: {}, 22695 tags: { 22696 'initializing': [ 'busy' ], 22697 'animating': [ 'busy' ], 22698 'dragging': [ 'interacting' ] 22699 } 22700 }; 22701 22702 $.each([ 'onResize', 'onThrottledResize' ], $.proxy(function(i, handler) { 22703 this._handlers[handler] = $.proxy(this[handler], this); 22704 }, this)); 22705 22706 $.each(Owl.Plugins, $.proxy(function(key, plugin) { 22707 this._plugins[key.charAt(0).toLowerCase() + key.slice(1)] 22708 = new plugin(this); 22709 }, this)); 22710 22711 $.each(Owl.Workers, $.proxy(function(priority, worker) { 22712 this._pipe.push({ 22713 'filter': worker.filter, 22714 'run': $.proxy(worker.run, this) 22715 }); 22716 }, this)); 22717 22718 this.setup(); 22719 this.initialize(); 22720 } 22721 22722 /** 22723 * Default options for the carousel. 22724 * @public 22725 */ 22726 Owl.Defaults = { 22727 items: 3, 22728 loop: false, 22729 center: false, 22730 rewind: false, 22731 22732 mouseDrag: true, 22733 touchDrag: true, 22734 pullDrag: true, 22735 freeDrag: false, 22736 22737 margin: 0, 22738 stagePadding: 0, 22739 22740 merge: false, 22741 mergeFit: true, 22742 autoWidth: false, 22743 22744 startPosition: 0, 22745 rtl: false, 22746 22747 smartSpeed: 250, 22748 fluidSpeed: false, 22749 dragEndSpeed: false, 22750 22751 responsive: {}, 22752 responsiveRefreshRate: 200, 22753 responsiveBaseElement: window, 22754 22755 fallbackEasing: 'swing', 22756 22757 info: false, 22758 22759 nestedItemSelector: false, 22760 itemElement: 'div', 22761 stageElement: 'div', 22762 22763 refreshClass: 'owl-refresh', 22764 loadedClass: 'owl-loaded', 22765 loadingClass: 'owl-loading', 22766 rtlClass: 'owl-rtl', 22767 responsiveClass: 'owl-responsive', 22768 dragClass: 'owl-drag', 22769 itemClass: 'owl-item', 22770 stageClass: 'owl-stage', 22771 stageOuterClass: 'owl-stage-outer', 22772 grabClass: 'owl-grab' 22773 }; 22774 22775 /** 22776 * Enumeration for width. 22777 * @public 22778 * @readonly 22779 * @enum {String} 22780 */ 22781 Owl.Width = { 22782 Default: 'default', 22783 Inner: 'inner', 22784 Outer: 'outer' 22785 }; 22786 22787 /** 22788 * Enumeration for types. 22789 * @public 22790 * @readonly 22791 * @enum {String} 22792 */ 22793 Owl.Type = { 22794 Event: 'event', 22795 State: 'state' 22796 }; 22797 22798 /** 22799 * Contains all registered plugins. 22800 * @public 22801 */ 22802 Owl.Plugins = {}; 22803 22804 /** 22805 * List of workers involved in the update process. 22806 */ 22807 Owl.Workers = [ { 22808 filter: [ 'width', 'settings' ], 22809 run: function() { 22810 this._width = (this.$element.closest('.px-gutter').length) ? 12 * Math.ceil(this.$element.width() / 12) : this.$element.width(); 22811 //this._width = (UNCODE.isMobile) ? this.$element.width() : 12 * Math.ceil(this.$element.width() / 12); 22812 } 22813 }, { 22814 filter: [ 'width', 'items', 'settings' ], 22815 run: function(cache) { 22816 cache.current = this._items && this._items[this.relative(this._current)]; 22817 } 22818 }, { 22819 filter: [ 'items', 'settings' ], 22820 run: function() { 22821 this.$stage.children('.cloned').remove(); 22822 } 22823 }, { 22824 filter: [ 'width', 'items', 'settings' ], 22825 run: function(cache) { 22826 var margin = this.settings.margin || '', 22827 grid = !this.settings.autoWidth, 22828 rtl = this.settings.rtl, 22829 css = { 22830 'width': 'auto', 22831 'margin-left': rtl ? margin : '', 22832 'margin-right': rtl ? '' : margin 22833 }; 22834 22835 !grid && this.$stage.children().css(css); 22836 22837 cache.css = css; 22838 } 22839 }, { 22840 filter: [ 'width', 'items', 'settings' ], 22841 run: function(cache) { 22842 //UNCODE edit to fix Chrome stage padding issue 22843 var width = Math.round((this.width() / this.settings.items).toFixed(3) - this.settings.margin), 22844 merge = null, 22845 iterator = this._items.length, 22846 grid = !this.settings.autoWidth, 22847 widths = []; 22848 22849 cache.items = { 22850 merge: false, 22851 width: width 22852 }; 22853 22854 while (iterator--) { 22855 merge = this._mergers[iterator]; 22856 merge = this.settings.mergeFit && Math.min(merge, this.settings.items) || merge; 22857 22858 cache.items.merge = merge > 1 || cache.items.merge; 22859 22860 widths[iterator] = !grid ? this._items[iterator].width() : width * merge; 22861 } 22862 22863 this._widths = widths; 22864 } 22865 }, { 22866 filter: [ 'items', 'settings' ], 22867 run: function() { 22868 var clones = [], 22869 items = this._items, 22870 settings = this.settings, 22871 view = Math.max(settings.items * 2, 4), 22872 size = Math.ceil(items.length / 2) * 2, 22873 repeat = settings.loop && items.length ? settings.rewind ? view : Math.max(view, size) : 0, 22874 append = '', 22875 prepend = ''; 22876 22877 repeat /= 2; 22878 22879 while (repeat--) { 22880 clones.push(this.normalize(clones.length / 2, true)); 22881 append = append + items[clones[clones.length - 1]][0].outerHTML; 22882 clones.push(this.normalize(items.length - 1 - (clones.length - 1) / 2, true)); 22883 prepend = items[clones[clones.length - 1]][0].outerHTML + prepend; 22884 } 22885 22886 this._clones = clones; 22887 22888 // var appendVideo = $(append).find('.uncode-video-container'); 22889 // if (appendVideo.length) { 22890 // appendVideo.attr('data-id', Math.round(Math.random() * 100000)); 22891 // } 22892 // var prependVideo = $(prepend).find('.uncode-video-container'); 22893 // if (prependVideo.length) { 22894 // prependVideo.attr('data-id', Math.round(Math.random() * 100000)); 22895 // } 22896 $(append).addClass('cloned').appendTo(this.$stage); 22897 $(prepend).addClass('cloned').prependTo(this.$stage); 22898 } 22899 }, { 22900 filter: [ 'width', 'items', 'settings' ], 22901 run: function() { 22902 var rtl = this.settings.rtl ? 1 : -1, 22903 size = this._clones.length + this._items.length, 22904 iterator = -1, 22905 previous = 0, 22906 current = 0, 22907 coordinates = []; 22908 22909 while (++iterator < size) { 22910 previous = coordinates[iterator - 1] || 0; 22911 current = this._widths[this.relative(iterator)] + this.settings.margin; 22912 coordinates.push(previous + current * rtl); 22913 } 22914 22915 this._coordinates = coordinates; 22916 } 22917 }, { 22918 filter: [ 'width', 'items', 'settings' ], 22919 run: function() { 22920 var stagePadding = (this._width < 480 && this.settings.stagePadding > 0) ? 41 : (this._width * this.settings.stagePadding) / 200, 22921 padding = stagePadding, 22922 coordinates = this._coordinates, 22923 css = { 22924 'width': Math.ceil(Math.abs(coordinates[coordinates.length - 1])) + padding * 2, 22925 'padding-left': padding || '', 22926 'padding-right': padding || '' 22927 }; 22928 22929 this.$stage.css(css); 22930 } 22931 }, { 22932 filter: [ 'width', 'items', 'settings' ], 22933 run: function(cache) { 22934 var iterator = this._coordinates.length, 22935 grid = !this.settings.autoWidth, 22936 items = this.$stage.children(); 22937 22938 if (grid && cache.items.merge) { 22939 while (iterator--) { 22940 cache.css.width = this._widths[this.relative(iterator)]; 22941 items.eq(iterator).css(cache.css); 22942 } 22943 } else if (grid) { 22944 cache.css.width = cache.items.width; 22945 items.css(cache.css); 22946 } 22947 } 22948 }, { 22949 filter: [ 'items' ], 22950 run: function() { 22951 this._coordinates.length < 1 && this.$stage.removeAttr('style'); 22952 } 22953 }, { 22954 filter: [ 'width', 'items', 'settings' ], 22955 run: function(cache) { 22956 cache.current = cache.current ? this.$stage.children().index(cache.current) : 0; 22957 cache.current = Math.max(this.minimum(), Math.min(this.maximum(), cache.current)); 22958 this.reset(cache.current); 22959 } 22960 }, { 22961 filter: [ 'position' ], 22962 run: function() { 22963 this.animate(this.coordinates(this._current)); 22964 } 22965 }, { 22966 filter: [ 'width', 'position', 'items', 'settings' ], 22967 run: function() { 22968 var stagePadding = (this._width < 480 && this.settings.stagePadding > 0) ? 41 : (this._width * this.settings.stagePadding) / 200, 22969 rtl = this.settings.rtl ? 1 : -1, 22970 padding = this.settings.stagePadding * 2, 22971 begin = this.coordinates(this.current()) + padding, 22972 end = begin + this.width() * rtl, 22973 inner, outer, matches = [], i, n; 22974 22975 for (i = 0, n = this._coordinates.length; i < n; i++) { 22976 inner = this._coordinates[i - 1] || 0; 22977 outer = Math.abs(this._coordinates[i]) + padding * rtl; 22978 22979 if ((this.op(inner, '<=', begin) && (this.op(inner, '>', end))) 22980 || (this.op(outer, '<', begin) && this.op(outer, '>', end))) { 22981 matches.push(i); 22982 } 22983 } 22984 22985 this.$stage.children('.active').removeClass('active'); 22986 this.$stage.children(':eq(' + matches.join('), :eq(') + ')').addClass('active'); 22987 22988 if (this.settings.center) { 22989 this.$stage.children('.center').removeClass('center'); 22990 this.$stage.children().eq(this.current()).addClass('center'); 22991 } 22992 } 22993 } ]; 22994 22995 /** 22996 * Initializes the carousel. 22997 * @protected 22998 */ 22999 Owl.prototype.initialize = function() { 23000 this.enter('initializing'); 23001 this.trigger('initialize'); 23002 23003 this.$element.toggleClass(this.settings.rtlClass, this.settings.rtl); 23004 23005 if (this.settings.autoWidth && !this.is('pre-loading')) { 23006 var imgs, nestedSelector, width; 23007 imgs = this.$element.find('img'); 23008 nestedSelector = this.settings.nestedItemSelector ? '.' + this.settings.nestedItemSelector : undefined; 23009 width = this.$element.children(nestedSelector).width(); 23010 23011 if (imgs.length && width <= 0) { 23012 this.preloadAutoWidthImages(imgs); 23013 } 23014 } 23015 23016 this.$element.addClass(this.options.loadingClass); 23017 23018 // create stage 23019 this.$stage = $('<' + this.settings.stageElement + ' class="' + this.settings.stageClass + '"/>') 23020 .wrap('<div class="' + this.settings.stageOuterClass + '"/>'); 23021 23022 // append stage 23023 this.$element.append(this.$stage.parent()); 23024 23025 // append content 23026 this.replace(this.$element.children().not(this.$stage.parent())); 23027 23028 // check visibility 23029 if (this.$element.is(':visible')) { 23030 // update view 23031 this.refresh(); 23032 } else { 23033 // invalidate width 23034 this.invalidate('width'); 23035 } 23036 23037 this.$element 23038 .removeClass(this.options.loadingClass) 23039 .addClass(this.options.loadedClass); 23040 23041 // register event handlers 23042 this.registerEventHandlers(); 23043 23044 this.leave('initializing'); 23045 this.trigger('initialized'); 23046 }; 23047 23048 /** 23049 * Setups the current settings. 23050 * @todo Remove responsive classes. Why should adaptive designs be brought into IE8? 23051 * @todo Support for media queries by using `matchMedia` would be nice. 23052 * @public 23053 */ 23054 Owl.prototype.setup = function() { 23055 var viewport = this.viewport(), 23056 overwrites = this.options.responsive, 23057 match = -1, 23058 settings = null; 23059 23060 if (!overwrites) { 23061 settings = $.extend({}, this.options); 23062 } else { 23063 $.each(overwrites, function(breakpoint) { 23064 if (breakpoint <= viewport && breakpoint > match) { 23065 match = Number(breakpoint); 23066 } 23067 }); 23068 23069 settings = $.extend({}, this.options, overwrites[match]); 23070 delete settings.responsive; 23071 23072 // responsive class 23073 if (settings.responsiveClass) { 23074 this.$element.attr('class', 23075 this.$element.attr('class').replace(new RegExp('(' + this.options.responsiveClass + '-)\\S+\\s', 'g'), '$1' + match) 23076 ); 23077 } 23078 } 23079 23080 if (this.settings === null || this._breakpoint !== match) { 23081 this.trigger('change', { property: { name: 'settings', value: settings } }); 23082 this._breakpoint = match; 23083 this.settings = settings; 23084 this.invalidate('settings'); 23085 this.trigger('changed', { property: { name: 'settings', value: this.settings } }); 23086 } 23087 }; 23088 23089 /** 23090 * Updates option logic if necessery. 23091 * @protected 23092 */ 23093 Owl.prototype.optionsLogic = function() { 23094 if (this.settings.autoWidth) { 23095 this.settings.stagePadding = false; 23096 this.settings.merge = false; 23097 } 23098 }; 23099 23100 /** 23101 * Prepares an item before add. 23102 * @todo Rename event parameter `content` to `item`. 23103 * @protected 23104 * @returns {jQuery|HTMLElement} - The item container. 23105 */ 23106 Owl.prototype.prepare = function(item, index) { 23107 var event = this.trigger('prepare', { content: item }); 23108 if (!event.data) { 23109 event.data = $('<' + this.settings.itemElement + '/>') 23110 .addClass(this.options.itemClass).attr('data-index', index + 1).append(item) 23111 } 23112 23113 this.trigger('prepared', { content: event.data }); 23114 23115 return event.data; 23116 }; 23117 23118 /** 23119 * Updates the view. 23120 * @public 23121 */ 23122 Owl.prototype.update = function() { 23123 var i = 0, 23124 n = this._pipe.length, 23125 filter = $.proxy(function(p) { return this[p] }, this._invalidated), 23126 cache = {}; 23127 23128 while (i < n) { 23129 if (this._invalidated.all || $.grep(this._pipe[i].filter, filter).length > 0) { 23130 this._pipe[i].run(cache); 23131 } 23132 i++; 23133 } 23134 23135 this._invalidated = {}; 23136 23137 !this.is('valid') && this.enter('valid'); 23138 }; 23139 23140 /** 23141 * Gets the width of the view. 23142 * @public 23143 * @param {Owl.Width} [dimension=Owl.Width.Default] - The dimension to return. 23144 * @returns {Number} - The width of the view in pixel. 23145 */ 23146 Owl.prototype.width = function(dimension) { 23147 dimension = dimension || Owl.Width.Default; 23148 var stagePadding = (this._width < 480 && this.settings.stagePadding > 0) ? 41 : (this._width * this.settings.stagePadding) / 200; 23149 switch (dimension) { 23150 case Owl.Width.Inner: 23151 case Owl.Width.Outer: 23152 return this._width; 23153 default: 23154 return this._width - stagePadding * 2 + this.settings.margin; 23155 } 23156 }; 23157 23158 /** 23159 * Refreshes the carousel primarily for adaptive purposes. 23160 * @public 23161 */ 23162 Owl.prototype.refresh = function() { 23163 this.enter('refreshing'); 23164 this.trigger('refresh'); 23165 23166 this.setup(); 23167 23168 this.optionsLogic(); 23169 23170 this.$element.addClass(this.options.refreshClass); 23171 23172 this.update(); 23173 23174 this.$element.removeClass(this.options.refreshClass); 23175 23176 this.leave('refreshing'); 23177 this.trigger('refreshed'); 23178 }; 23179 23180 /** 23181 * Checks window `resize` event. 23182 * @protected 23183 */ 23184 Owl.prototype.onThrottledResize = function() { 23185 window.clearTimeout(this.resizeTimer); 23186 this.resizeTimer = window.setTimeout(this._handlers.onResize, this.settings.responsiveRefreshRate); 23187 }; 23188 23189 /** 23190 * Checks window `resize` event. 23191 * @protected 23192 */ 23193 Owl.prototype.onResize = function() { 23194 if (!this._items.length) { 23195 return false; 23196 } 23197 23198 if (this._width === this.$element.width()) { 23199 return false; 23200 } 23201 23202 if (!this.$element.is(':visible')) { 23203 return false; 23204 } 23205 23206 this.enter('resizing'); 23207 23208 if (this.trigger('resize').isDefaultPrevented()) { 23209 this.leave('resizing'); 23210 return false; 23211 } 23212 23213 this.invalidate('width'); 23214 23215 this.refresh(); 23216 23217 this.leave('resizing'); 23218 this.trigger('resized'); 23219 }; 23220 23221 /** 23222 * Registers event handlers. 23223 * @todo Check `msPointerEnabled` 23224 * @todo #261 23225 * @protected 23226 */ 23227 Owl.prototype.registerEventHandlers = function() { 23228 if ($.support.transition) { 23229 this.$stage.on($.support.transition.end + '.owl.core', $.proxy(this.onTransitionEnd, this)); 23230 } 23231 23232 if (this.settings.responsive !== false) { 23233 this.on(window, 'resize', this._handlers.onThrottledResize); 23234 } 23235 23236 if (this.settings.mouseDrag) { 23237 this.$element.addClass(this.options.dragClass); 23238 this.$stage.on('mousedown.owl.core', $.proxy(this.onDragStart, this)); 23239 this.$stage.on('dragstart.owl.core selectstart.owl.core', function() { return false }); 23240 } 23241 23242 if (this.settings.touchDrag){ 23243 this.$stage.on('touchstart.owl.core', $.proxy(this.onDragStart, this)); 23244 this.$stage.on('touchcancel.owl.core', $.proxy(this.onDragEnd, this)); 23245 } 23246 }; 23247 23248 /** 23249 * Handles `touchstart` and `mousedown` events. 23250 * @todo Horizontal swipe threshold as option 23251 * @todo #261 23252 * @protected 23253 * @param {Event} event - The event arguments. 23254 */ 23255 Owl.prototype.onDragStart = function(event) { 23256 var stage = null; 23257 23258 if (event.which === 3) { 23259 return; 23260 } 23261 23262 if ($.support.transform) { 23263 stage = this.$stage.css('transform').replace(/.*\(|\)| /g, '').split(','); 23264 stage = { 23265 x: stage[stage.length === 16 ? 12 : 4], 23266 y: stage[stage.length === 16 ? 13 : 5] 23267 }; 23268 } else { 23269 stage = this.$stage.position(); 23270 stage = { 23271 x: this.settings.rtl ? 23272 stage.left + this.$stage.width() - this.width() + this.settings.margin : 23273 stage.left, 23274 y: stage.top 23275 }; 23276 } 23277 23278 if (this.is('animating')) { 23279 $.support.transform ? this.animate(stage.x) : this.$stage.stop() 23280 this.invalidate('position'); 23281 } 23282 23283 this.$element.toggleClass(this.options.grabClass, event.type === 'mousedown'); 23284 23285 this.speed(0); 23286 23287 this._drag.time = new Date().getTime(); 23288 this._drag.target = $(event.target); 23289 this._drag.stage.start = stage; 23290 this._drag.stage.current = stage; 23291 this._drag.pointer = this.pointer(event); 23292 23293 $(document).on('mouseup.owl.core touchend.owl.core', $.proxy(this.onDragEnd, this)); 23294 23295 $(document).one('mousemove.owl.core touchmove.owl.core', $.proxy(function(event) { 23296 var delta = this.difference(this._drag.pointer, this.pointer(event)); 23297 23298 $(document).on('mousemove.owl.core touchmove.owl.core', $.proxy(this.onDragMove, this)); 23299 23300 if (Math.abs(delta.x) < Math.abs(delta.y) && this.is('valid')) { 23301 return; 23302 } 23303 23304 event.preventDefault(); 23305 23306 this.enter('dragging'); 23307 this.trigger('drag'); 23308 }, this)); 23309 }; 23310 23311 /** 23312 * Handles the `touchmove` and `mousemove` events. 23313 * @todo #261 23314 * @protected 23315 * @param {Event} event - The event arguments. 23316 */ 23317 Owl.prototype.onDragMove = function(event) { 23318 var minimum = null, 23319 maximum = null, 23320 pull = null, 23321 delta = this.difference(this._drag.pointer, this.pointer(event)), 23322 stage = this.difference(this._drag.stage.start, delta); 23323 23324 if (!this.is('dragging')) { 23325 return; 23326 } 23327 23328 event.preventDefault(); 23329 23330 if (this.settings.loop) { 23331 minimum = this.coordinates(this.minimum()); 23332 maximum = this.coordinates(this.maximum() + 1) - minimum; 23333 stage.x = (((stage.x - minimum) % maximum + maximum) % maximum) + minimum; 23334 } else { 23335 minimum = this.settings.rtl ? this.coordinates(this.maximum()) : this.coordinates(this.minimum()); 23336 maximum = this.settings.rtl ? this.coordinates(this.minimum()) : this.coordinates(this.maximum()); 23337 pull = this.settings.pullDrag ? -1 * delta.x / 5 : 0; 23338 stage.x = Math.max(Math.min(stage.x, minimum + pull), maximum + pull); 23339 } 23340 23341 this._drag.stage.current = stage; 23342 23343 this.animate(stage.x); 23344 }; 23345 23346 /** 23347 * Handles the `touchend` and `mouseup` events. 23348 * @todo #261 23349 * @todo Threshold for click event 23350 * @protected 23351 * @param {Event} event - The event arguments. 23352 */ 23353 Owl.prototype.onDragEnd = function(event) { 23354 var delta = this.difference(this._drag.pointer, this.pointer(event)), 23355 stage = this._drag.stage.current, 23356 direction = delta.x > 0 ^ this.settings.rtl ? 'left' : 'right'; 23357 23358 $(document).off('.owl.core'); 23359 23360 this.$element.removeClass(this.options.grabClass); 23361 23362 if (delta.x !== 0 && this.is('dragging') || !this.is('valid')) { 23363 this.speed(this.settings.dragEndSpeed || this.settings.smartSpeed); 23364 this.current(this.closest(stage.x, delta.x !== 0 ? direction : this._drag.direction)); 23365 this.invalidate('position'); 23366 this.update(); 23367 23368 this._drag.direction = direction; 23369 23370 if (Math.abs(delta.x) > 3 || new Date().getTime() - this._drag.time > 300) { 23371 this._drag.target.one('click.owl.core', function() { return false; }); 23372 } 23373 } 23374 23375 if (!this.is('dragging')) { 23376 return; 23377 } 23378 23379 this.leave('dragging'); 23380 this.trigger('dragged'); 23381 }; 23382 23383 /** 23384 * Gets absolute position of the closest item for a coordinate. 23385 * @todo Setting `freeDrag` makes `closest` not reusable. See #165. 23386 * @protected 23387 * @param {Number} coordinate - The coordinate in pixel. 23388 * @param {String} direction - The direction to check for the closest item. Ether `left` or `right`. 23389 * @return {Number} - The absolute position of the closest item. 23390 */ 23391 Owl.prototype.closest = function(coordinate, direction) { 23392 var position = -1, 23393 pull = 30, 23394 width = this.width(), 23395 coordinates = this.coordinates(); 23396 23397 if (!this.settings.freeDrag) { 23398 // check closest item 23399 $.each(coordinates, $.proxy(function(index, value) { 23400 if (coordinate > value - pull && coordinate < value + pull) { 23401 position = index; 23402 } else if (this.op(coordinate, '<', value) 23403 && this.op(coordinate, '>', coordinates[index + 1] || value - width)) { 23404 position = direction === 'left' ? index + 1 : index; 23405 } 23406 return position === -1; 23407 }, this)); 23408 } 23409 23410 if (!this.settings.loop) { 23411 // non loop boundries 23412 if (this.op(coordinate, '>', coordinates[this.minimum()])) { 23413 position = coordinate = this.minimum(); 23414 } else if (this.op(coordinate, '<', coordinates[this.maximum()])) { 23415 position = coordinate = this.maximum(); 23416 } 23417 } 23418 23419 return position; 23420 }; 23421 23422 /** 23423 * Animates the stage. 23424 * @todo #270 23425 * @public 23426 * @param {Number} coordinate - The coordinate in pixels. 23427 */ 23428 Owl.prototype.animate = function(coordinate) { 23429 var animate = this.speed() > 0; 23430 23431 this.is('animating') && this.onTransitionEnd(); 23432 23433 if (animate) { 23434 this.enter('animating'); 23435 this.trigger('translate'); 23436 } 23437 23438 if ($.support.transform3d && $.support.transition) { 23439 this.$stage.css({ 23440 transform: 'translate3d(' + coordinate + 'px,0px,0px)', 23441 transition: (this.speed() / 1000) + 's' 23442 }); 23443 } else if (animate) { 23444 this.$stage.animate({ 23445 left: coordinate + 'px' 23446 }, this.speed(), this.settings.fallbackEasing, $.proxy(this.onTransitionEnd, this)); 23447 } else { 23448 this.$stage.css({ 23449 left: coordinate + 'px' 23450 }); 23451 } 23452 }; 23453 23454 /** 23455 * Checks whether the carousel is in a specific state or not. 23456 * @param {String} state - The state to check. 23457 * @returns {Boolean} - The flag which indicates if the carousel is busy. 23458 */ 23459 Owl.prototype.is = function(state) { 23460 return this._states.current[state] && this._states.current[state] > 0; 23461 }; 23462 23463 /** 23464 * Sets the absolute position of the current item. 23465 * @public 23466 * @param {Number} [position] - The new absolute position or nothing to leave it unchanged. 23467 * @returns {Number} - The absolute position of the current item. 23468 */ 23469 Owl.prototype.current = function(position) { 23470 if (position === undefined) { 23471 return this._current; 23472 } 23473 23474 if (this._items.length === 0) { 23475 return undefined; 23476 } 23477 23478 position = this.normalize(position); 23479 23480 if (this._current !== position) { 23481 var event = this.trigger('change', { property: { name: 'position', value: position } }); 23482 23483 if (event.data !== undefined) { 23484 position = this.normalize(event.data); 23485 } 23486 23487 this._current = position; 23488 23489 this.invalidate('position'); 23490 23491 this.trigger('changed', { property: { name: 'position', value: this._current } }); 23492 } 23493 23494 return this._current; 23495 }; 23496 23497 /** 23498 * Invalidates the given part of the update routine. 23499 * @param {String} [part] - The part to invalidate. 23500 * @returns {Array.<String>} - The invalidated parts. 23501 */ 23502 Owl.prototype.invalidate = function(part) { 23503 if ($.type(part) === 'string') { 23504 this._invalidated[part] = true; 23505 this.is('valid') && this.leave('valid'); 23506 } 23507 return $.map(this._invalidated, function(v, i) { return i }); 23508 }; 23509 23510 /** 23511 * Resets the absolute position of the current item. 23512 * @public 23513 * @param {Number} position - The absolute position of the new item. 23514 */ 23515 Owl.prototype.reset = function(position) { 23516 position = this.normalize(position); 23517 23518 if (position === undefined) { 23519 return; 23520 } 23521 23522 this._speed = 0; 23523 this._current = position; 23524 23525 this.suppress([ 'translate', 'translated' ]); 23526 23527 this.animate(this.coordinates(position)); 23528 23529 this.release([ 'translate', 'translated' ]); 23530 }; 23531 23532 /** 23533 * Normalizes an absolute or a relative position of an item. 23534 * @public 23535 * @param {Number} position - The absolute or relative position to normalize. 23536 * @param {Boolean} [relative=false] - Whether the given position is relative or not. 23537 * @returns {Number} - The normalized position. 23538 */ 23539 Owl.prototype.normalize = function(position, relative) { 23540 var n = this._items.length, 23541 m = relative ? 0 : this._clones.length; 23542 23543 if (!$.isNumeric(position) || n < 1) { 23544 position = undefined; 23545 } else if (position < 0 || position >= n + m) { 23546 position = ((position - m / 2) % n + n) % n + m / 2; 23547 } 23548 23549 return position; 23550 }; 23551 23552 /** 23553 * Converts an absolute position of an item into a relative one. 23554 * @public 23555 * @param {Number} position - The absolute position to convert. 23556 * @returns {Number} - The converted position. 23557 */ 23558 Owl.prototype.relative = function(position) { 23559 position -= this._clones.length / 2; 23560 return this.normalize(position, true); 23561 }; 23562 23563 /** 23564 * Gets the maximum position for the current item. 23565 * @public 23566 * @param {Boolean} [relative=false] - Whether to return an absolute position or a relative position. 23567 * @returns {Number} 23568 */ 23569 Owl.prototype.maximum = function(relative) { 23570 var settings = this.settings, 23571 maximum = this._coordinates.length, 23572 boundary = Math.abs(this._coordinates[maximum - 1]) - this._width, 23573 i = -1, j; 23574 23575 if (settings.loop) { 23576 maximum = this._clones.length / 2 + this._items.length - 1; 23577 } else if (settings.autoWidth || settings.merge) { 23578 // binary search 23579 while (maximum - i > 1) { 23580 Math.abs(this._coordinates[j = maximum + i >> 1]) < boundary 23581 ? i = j : maximum = j; 23582 } 23583 } else if (settings.center) { 23584 maximum = this._items.length - 1; 23585 } else { 23586 maximum = this._items.length - settings.items; 23587 } 23588 23589 if (relative) { 23590 maximum -= this._clones.length / 2; 23591 } 23592 23593 return Math.max(maximum, 0); 23594 }; 23595 23596 /** 23597 * Gets the minimum position for the current item. 23598 * @public 23599 * @param {Boolean} [relative=false] - Whether to return an absolute position or a relative position. 23600 * @returns {Number} 23601 */ 23602 Owl.prototype.minimum = function(relative) { 23603 return relative ? 0 : this._clones.length / 2; 23604 }; 23605 23606 /** 23607 * Gets an item at the specified relative position. 23608 * @public 23609 * @param {Number} [position] - The relative position of the item. 23610 * @return {jQuery|Array.<jQuery>} - The item at the given position or all items if no position was given. 23611 */ 23612 Owl.prototype.items = function(position) { 23613 if (position === undefined) { 23614 return this._items.slice(); 23615 } 23616 23617 position = this.normalize(position, true); 23618 return this._items[position]; 23619 }; 23620 23621 /** 23622 * Gets an item at the specified relative position. 23623 * @public 23624 * @param {Number} [position] - The relative position of the item. 23625 * @return {jQuery|Array.<jQuery>} - The item at the given position or all items if no position was given. 23626 */ 23627 Owl.prototype.mergers = function(position) { 23628 if (position === undefined) { 23629 return this._mergers.slice(); 23630 } 23631 23632 position = this.normalize(position, true); 23633 return this._mergers[position]; 23634 }; 23635 23636 /** 23637 * Gets the absolute positions of clones for an item. 23638 * @public 23639 * @param {Number} [position] - The relative position of the item. 23640 * @returns {Array.<Number>} - The absolute positions of clones for the item or all if no position was given. 23641 */ 23642 Owl.prototype.clones = function(position) { 23643 var odd = this._clones.length / 2, 23644 even = odd + this._items.length, 23645 map = function(index) { return index % 2 === 0 ? even + index / 2 : odd - (index + 1) / 2 }; 23646 23647 if (position === undefined) { 23648 return $.map(this._clones, function(v, i) { return map(i) }); 23649 } 23650 23651 return $.map(this._clones, function(v, i) { return v === position ? map(i) : null }); 23652 }; 23653 23654 /** 23655 * Sets the current animation speed. 23656 * @public 23657 * @param {Number} [speed] - The animation speed in milliseconds or nothing to leave it unchanged. 23658 * @returns {Number} - The current animation speed in milliseconds. 23659 */ 23660 Owl.prototype.speed = function(speed) { 23661 if (speed !== undefined) { 23662 this._speed = speed; 23663 } 23664 23665 return this._speed; 23666 }; 23667 23668 /** 23669 * Gets the coordinate of an item. 23670 * @todo The name of this method is missleanding. 23671 * @public 23672 * @param {Number} position - The absolute position of the item within `minimum()` and `maximum()`. 23673 * @returns {Number|Array.<Number>} - The coordinate of the item in pixel or all coordinates. 23674 */ 23675 Owl.prototype.coordinates = function(position) { 23676 var coordinate = null; 23677 23678 if (position === undefined) { 23679 return $.map(this._coordinates, $.proxy(function(coordinate, index) { 23680 return this.coordinates(index); 23681 }, this)); 23682 } 23683 23684 if (this.settings.center) { 23685 coordinate = this._coordinates[position]; 23686 coordinate += (this.width() - coordinate + (this._coordinates[position - 1] || 0)) / 2 * (this.settings.rtl ? -1 : 1); 23687 } else { 23688 coordinate = this._coordinates[position - 1] || 0; 23689 } 23690 23691 return coordinate; 23692 }; 23693 23694 /** 23695 * Calculates the speed for a translation. 23696 * @protected 23697 * @param {Number} from - The absolute position of the start item. 23698 * @param {Number} to - The absolute position of the target item. 23699 * @param {Number} [factor=undefined] - The time factor in milliseconds. 23700 * @returns {Number} - The time in milliseconds for the translation. 23701 */ 23702 Owl.prototype.duration = function(from, to, factor) { 23703 return Math.min(Math.max(Math.abs(to - from), 1), 6) * Math.abs((factor || this.settings.smartSpeed)); 23704 }; 23705 23706 /** 23707 * Slides to the specified item. 23708 * @public 23709 * @param {Number} position - The position of the item. 23710 * @param {Number} [speed] - The time in milliseconds for the transition. 23711 */ 23712 Owl.prototype.to = function(position, speed) { 23713 var current = this.current(), 23714 revert = null, 23715 distance = position - this.relative(current), 23716 direction = (distance > 0) - (distance < 0), 23717 items = this._items.length, 23718 minimum = this.minimum(), 23719 maximum = this.maximum(); 23720 23721 if (this.settings.loop) { 23722 if (!this.settings.rewind && Math.abs(distance) > items / 2) { 23723 distance += direction * -1 * items; 23724 } 23725 23726 position = current + distance; 23727 revert = ((position - minimum) % items + items) % items + minimum; 23728 23729 if (revert !== position && revert - distance <= maximum && revert - distance > 0) { 23730 current = revert - distance; 23731 position = revert; 23732 this.reset(current); 23733 } 23734 } else if (this.settings.rewind) { 23735 maximum += 1; 23736 position = (position % maximum + maximum) % maximum; 23737 } else { 23738 position = Math.max(minimum, Math.min(maximum, position)); 23739 } 23740 23741 this.speed(this.duration(current, position, speed)); 23742 this.current(position); 23743 23744 if (this.$element.is(':visible')) { 23745 this.update(); 23746 } 23747 }; 23748 23749 /** 23750 * Slides to the next item. 23751 * @public 23752 * @param {Number}
vendor: 12,284 bytes, lines 23752-24172
23752 [speed] - The time in milliseconds for the transition. 23753 */ 23754 Owl.prototype.next = function(speed) { 23755 speed = speed || false; 23756 this.to(this.relative(this.current()) + 1, speed); 23757 }; 23758 23759 /** 23760 * Slides to the previous item. 23761 * @public 23762 * @param {Number} [speed] - The time in milliseconds for the transition. 23763 */ 23764 Owl.prototype.prev = function(speed) { 23765 speed = speed || false; 23766 this.to(this.relative(this.current()) - 1, speed); 23767 }; 23768 23769 /** 23770 * Handles the end of an animation. 23771 * @protected 23772 * @param {Event} event - The event arguments. 23773 */ 23774 Owl.prototype.onTransitionEnd = function(event) { 23775 23776 // if css2 animation then event object is undefined 23777 if (event !== undefined) { 23778 event.stopPropagation(); 23779 23780 // Catch only owl-stage transitionEnd event 23781 if ((event.target || event.srcElement || event.originalTarget) !== this.$stage.get(0)) { 23782 return false; 23783 } 23784 } 23785 23786 this.leave('animating'); 23787 this.trigger('translated'); 23788 }; 23789 23790 /** 23791 * Gets viewport width. 23792 * @protected 23793 * @return {Number} - The width in pixel. 23794 */ 23795 Owl.prototype.viewport = function() { 23796 var width; 23797 if (this.options.responsiveBaseElement !== window) { 23798 width = $(this.options.responsiveBaseElement).width(); 23799 } else if (window.innerWidth) { 23800 width = window.innerWidth; 23801 } else if (document.documentElement && document.documentElement.clientWidth) { 23802 width = document.documentElement.clientWidth; 23803 } else { 23804 throw 'Can not detect viewport width.'; 23805 } 23806 23807 return width; 23808 }; 23809 23810 /** 23811 * Replaces the current content. 23812 * @public 23813 * @param {HTMLElement|jQuery|String} content - The new content. 23814 */ 23815 Owl.prototype.replace = function(content) { 23816 this.$stage.empty(); 23817 this._items = []; 23818 23819 if (content) { 23820 content = (content instanceof jQuery) ? content : $(content); 23821 } 23822 23823 if (this.settings.nestedItemSelector) { 23824 content = content.find('.' + this.settings.nestedItemSelector); 23825 } 23826 23827 content.filter(function() { 23828 return this.nodeType === 1; 23829 }).each($.proxy(function(index, item) { 23830 item = this.prepare(item, index); 23831 this.$stage.append(item); 23832 this._items.push(item); 23833 this._mergers.push(item.find('[data-merge]').addBack('[data-merge]').attr('data-merge') * 1 || 1); 23834 }, this)); 23835 23836 this.reset($.isNumeric(this.settings.startPosition) ? this.settings.startPosition : 0); 23837 23838 this.invalidate('items'); 23839 }; 23840 23841 /** 23842 * Adds an item. 23843 * @todo Use `item` instead of `content` for the event arguments. 23844 * @public 23845 * @param {HTMLElement|jQuery|String} content - The item content to add. 23846 * @param {Number} [position] - The relative position at which to insert the item otherwise the item will be added to the end. 23847 */ 23848 Owl.prototype.add = function(content, position) { 23849 var current = this.relative(this._current); 23850 23851 position = position === undefined ? this._items.length : this.normalize(position, true); 23852 content = content instanceof jQuery ? content : $(content); 23853 23854 this.trigger('add', { content: content, position: position }); 23855 23856 content = this.prepare(content, this._items[current].index()); 23857 23858 if (this._items.length === 0 || position === this._items.length) { 23859 this._items.length === 0 && this.$stage.append(content); 23860 this._items.length !== 0 && this._items[position - 1].after(content); 23861 this._items.push(content); 23862 this._mergers.push(content.find('[data-merge]').andSelf('[data-merge]').attr('data-merge') * 1 || 1); 23863 } else { 23864 this._items[position].before(content); 23865 this._items.splice(position, 0, content); 23866 this._mergers.splice(position, 0, content.find('[data-merge]').andSelf('[data-merge]').attr('data-merge') * 1 || 1); 23867 } 23868 23869 this._items[current] && this.reset(this._items[current].index()); 23870 23871 this.invalidate('items'); 23872 23873 this.trigger('added', { content: content, position: position }); 23874 }; 23875 23876 /** 23877 * Removes an item by its position. 23878 * @todo Use `item` instead of `content` for the event arguments. 23879 * @public 23880 * @param {Number} position - The relative position of the item to remove. 23881 */ 23882 Owl.prototype.remove = function(position) { 23883 position = this.normalize(position, true); 23884 23885 if (position === undefined) { 23886 return; 23887 } 23888 23889 this.trigger('remove', { content: this._items[position], position: position }); 23890 23891 this._items[position].remove(); 23892 this._items.splice(position, 1); 23893 this._mergers.splice(position, 1); 23894 23895 this.invalidate('items'); 23896 23897 this.trigger('removed', { content: null, position: position }); 23898 }; 23899 23900 /** 23901 * Preloads images with auto width. 23902 * @todo Replace by a more generic approach 23903 * @protected 23904 */ 23905 Owl.prototype.preloadAutoWidthImages = function(images) { 23906 images.each($.proxy(function(i, element) { 23907 this.enter('pre-loading'); 23908 element = $(element); 23909 $(new Image()).one('load', $.proxy(function(e) { 23910 element.attr('src', e.target.src); 23911 element.css('opacity', 1); 23912 this.leave('pre-loading'); 23913 !this.is('pre-loading') && !this.is('initializing') && this.refresh(); 23914 }, this)).attr('src', element.attr('src') || element.attr('data-src') || element.attr('data-src-retina')); 23915 }, this)); 23916 }; 23917 23918 /** 23919 * Destroys the carousel. 23920 * @public 23921 */ 23922 Owl.prototype.destroy = function() { 23923 23924 this.$element.off('.owl.core'); 23925 this.$stage.off('.owl.core'); 23926 $(document).off('.owl.core'); 23927 23928 if (this.settings.responsive !== false) { 23929 window.clearTimeout(this.resizeTimer); 23930 this.off(window, 'resize', this._handlers.onThrottledResize); 23931 } 23932 23933 for (var i in this._plugins) { 23934 this._plugins[i].destroy(); 23935 } 23936 23937 this.$stage.children('.cloned').remove(); 23938 23939 this.$stage.unwrap(); 23940 this.$stage.children().contents().unwrap(); 23941 this.$stage.children().unwrap(); 23942 23943 this.$element 23944 .removeClass(this.options.refreshClass) 23945 .removeClass(this.options.loadingClass) 23946 .removeClass(this.options.loadedClass) 23947 .removeClass(this.options.rtlClass) 23948 .removeClass(this.options.dragClass) 23949 .removeClass(this.options.grabClass) 23950 .attr('class', this.$element.attr('class').replace(new RegExp(this.options.responsiveClass + '-\\S+\\s', 'g'), '')) 23951 .removeData('owl.carousel'); 23952 }; 23953 23954 /** 23955 * Operators to calculate right-to-left and left-to-right. 23956 * @protected 23957 * @param {Number} [a] - The left side operand. 23958 * @param {String} [o] - The operator. 23959 * @param {Number} [b] - The right side operand. 23960 */ 23961 Owl.prototype.op = function(a, o, b) { 23962 var rtl = this.settings.rtl; 23963 switch (o) { 23964 case '<': 23965 return rtl ? a > b : a < b; 23966 case '>': 23967 return rtl ? a < b : a > b; 23968 case '>=': 23969 return rtl ? a <= b : a >= b; 23970 case '<=': 23971 return rtl ? a >= b : a <= b; 23972 default: 23973 break; 23974 } 23975 }; 23976 23977 /** 23978 * Attaches to an internal event. 23979 * @protected 23980 * @param {HTMLElement} element - The event source. 23981 * @param {String} event - The event name. 23982 * @param {Function} listener - The event handler to attach. 23983 * @param {Boolean} capture - Wether the event should be handled at the capturing phase or not. 23984 */ 23985 Owl.prototype.on = function(element, event, listener, capture) { 23986 if (element.addEventListener) { 23987 element.addEventListener(event, listener, capture); 23988 } else if (element.attachEvent) { 23989 element.attachEvent('on' + event, listener); 23990 } 23991 }; 23992 23993 /** 23994 * Detaches from an internal event. 23995 * @protected 23996 * @param {HTMLElement} element - The event source. 23997 * @param {String} event - The event name. 23998 * @param {Function} listener - The attached event handler to detach. 23999 * @param {Boolean} capture - Wether the attached event handler was registered as a capturing listener or not. 24000 */ 24001 Owl.prototype.off = function(element, event, listener, capture) { 24002 if (element.removeEventListener) { 24003 element.removeEventListener(event, listener, capture); 24004 } else if (element.detachEvent) { 24005 element.detachEvent('on' + event, listener); 24006 } 24007 }; 24008 24009 /** 24010 * Triggers a public event. 24011 * @todo Remove `status`, `relatedTarget` should be used instead. 24012 * @protected 24013 * @param {String} name - The event name. 24014 * @param {*} [data=null] - The event data. 24015 * @param {String} [namespace=carousel] - The event namespace. 24016 * @param {String} [state] - The state which is associated with the event. 24017 * @param {Boolean} [enter=false] - Indicates if the call enters the specified state or not. 24018 * @returns {Event} - The event arguments. 24019 */ 24020 Owl.prototype.trigger = function(name, data, namespace, state, enter) { 24021 var status = { 24022 item: { count: this._items.length, index: this.current() } 24023 }, handler = $.camelCase( 24024 $.grep([ 'on', name, namespace ], function(v) { return v }) 24025 .join('-').toLowerCase() 24026 ), event = $.Event( 24027 [ name, 'owl', namespace || 'carousel' ].join('.').toLowerCase(), 24028 $.extend({ relatedTarget: this }, status, data) 24029 ); 24030 24031 if (!this._supress[name]) { 24032 $.each(this._plugins, function(name, plugin) { 24033 if (plugin.onTrigger) { 24034 plugin.onTrigger(event); 24035 } 24036 }); 24037 24038 this.register({ type: Owl.Type.Event, name: name }); 24039 this.$element.trigger(event); 24040 24041 if (this.settings && typeof this.settings[handler] === 'function') { 24042 this.settings[handler].call(this, event); 24043 } 24044 } 24045 24046 return event; 24047 }; 24048 24049 /** 24050 * Enters a state. 24051 * @param name - The state name. 24052 */ 24053 Owl.prototype.enter = function(name) { 24054 $.each([ name ].concat(this._states.tags[name] || []), $.proxy(function(i, name) { 24055 if (this._states.current[name] === undefined) { 24056 this._states.current[name] = 0; 24057 } 24058 24059 this._states.current[name]++; 24060 }, this)); 24061 }; 24062 24063 /** 24064 * Leaves a state. 24065 * @param name - The state name. 24066 */ 24067 Owl.prototype.leave = function(name) { 24068 $.each([ name ].concat(this._states.tags[name] || []), $.proxy(function(i, name) { 24069 this._states.current[name]--; 24070 }, this)); 24071 }; 24072 24073 /** 24074 * Registers an event or state. 24075 * @public 24076 * @param {Object} object - The event or state to register. 24077 */ 24078 Owl.prototype.register = function(object) { 24079 if (object.type === Owl.Type.Event) { 24080 if (!$.event.special[object.name]) { 24081 $.event.special[object.name] = {}; 24082 } 24083 24084 if (!$.event.special[object.name].owl) { 24085 var _default = $.event.special[object.name]._default; 24086 $.event.special[object.name]._default = function(e) { 24087 if (_default && _default.apply && (!e.namespace || e.namespace.indexOf('owl') === -1)) { 24088 return _default.apply(this, arguments); 24089 } 24090 return e.namespace && e.namespace.indexOf('owl') > -1; 24091 }; 24092 $.event.special[object.name].owl = true; 24093 } 24094 } else if (object.type === Owl.Type.State) { 24095 if (!this._states.tags[object.name]) { 24096 this._states.tags[object.name] = object.tags; 24097 } else { 24098 this._states.tags[object.name] = this._states.tags[object.name].concat(object.tags); 24099 } 24100 24101 this._states.tags[object.name] = $.grep(this._states.tags[object.name], $.proxy(function(tag, i) { 24102 return $.inArray(tag, this._states.tags[object.name]) === i; 24103 }, this)); 24104 } 24105 }; 24106 24107 /** 24108 * Suppresses events. 24109 * @protected 24110 * @param {Array.<String>} events - The events to suppress. 24111 */ 24112 Owl.prototype.suppress = function(events) { 24113 $.each(events, $.proxy(function(index, event) { 24114 this._supress[event] = true; 24115 }, this)); 24116 }; 24117 24118 /** 24119 * Releases suppressed events. 24120 * @protected 24121 * @param {Array.<String>} events - The events to release. 24122 */ 24123 Owl.prototype.release = function(events) { 24124 $.each(events, $.proxy(function(index, event) { 24125 delete this._supress[event]; 24126 }, this)); 24127 }; 24128 24129 /** 24130 * Gets unified pointer coordinates from event. 24131 * @todo #261 24132 * @protected 24133 * @param {Event} - The `mousedown` or `touchstart` event. 24134 * @returns {Object} - Contains `x` and `y` coordinates of current pointer position. 24135 */ 24136 Owl.prototype.pointer = function(event) { 24137 var result = { x: null, y: null }; 24138 24139 event = event.originalEvent || event || window.event; 24140 24141 event = event.touches && event.touches.length ? 24142 event.touches[0] : event.changedTouches && event.changedTouches.length ? 24143 event.changedTouches[0] : event; 24144 24145 if (event.pageX) { 24146 result.x = event.pageX; 24147 result.y = event.pageY; 24148 } else { 24149 result.x = event.clientX; 24150 result.y = event.clientY; 24151 } 24152 24153 return result; 24154 }; 24155 24156 /** 24157 * Gets the difference of two vectors. 24158 * @todo #261 24159 * @protected 24160 * @param {Object} - The first vector. 24161 * @param {Object} - The second vector. 24162 * @returns {Object} - The difference. 24163 */ 24164 Owl.prototype.difference = function(first, second) { 24165 return { 24166 x: first.x - second.x, 24167 y: first.y - second.y 24168 }; 24169 }; 24170 24171 /** 24172 * The jQuery Plugin for the Owl Carousel
vendor: 32,216 bytes, lines 24173-25455
24173 * @todo Navigation plugin `next` and `prev` 24174 * @public 24175 */ 24176 $.fn.owlCarousel = function(option) { 24177 var args = Array.prototype.slice.call(arguments, 1); 24178 24179 return this.each(function() { 24180 var $this = $(this), 24181 data = $this.data('owl.carousel'); 24182 24183 if (!data) { 24184 data = new Owl(this, typeof option == 'object' && option); 24185 $this.data('owl.carousel', data); 24186 24187 $.each([ 24188 'next', 'prev', 'to', 'destroy', 'refresh', 'replace', 'add', 'remove' 24189 ], function(i, event) { 24190 data.register({ type: Owl.Type.Event, name: event }); 24191 data.$element.on(event + '.owl.carousel.core', $.proxy(function(e) { 24192 if (e.namespace && e.relatedTarget !== this) { 24193 this.suppress([ event ]); 24194 data[event].apply(this, [].slice.call(arguments, 1)); 24195 this.release([ event ]); 24196 } 24197 }, data)); 24198 }); 24199 } 24200 24201 if (typeof option == 'string' && option.charAt(0) !== '_') { 24202 data[option].apply(data, args); 24203 } 24204 }); 24205 }; 24206 24207 /** 24208 * The constructor for the jQuery Plugin 24209 * @public 24210 */ 24211 $.fn.owlCarousel.Constructor = Owl; 24212 24213})(window.Zepto || window.jQuery, window, document); 24214 24215/** 24216 * AutoRefresh Plugin 24217 * @version 2.0.0-beta.3 24218 * @author Artus Kolanowski 24219 * @license The MIT License (MIT) 24220 */ 24221;(function($, window, document, undefined) { 24222 24223 /** 24224 * Creates the auto refresh plugin. 24225 * @class The Auto Refresh Plugin 24226 * @param {Owl} carousel - The Owl Carousel 24227 */ 24228 var AutoRefresh = function(carousel) { 24229 /** 24230 * Reference to the core. 24231 * @protected 24232 * @type {Owl} 24233 */ 24234 this._core = carousel; 24235 24236 /** 24237 * Refresh interval. 24238 * @protected 24239 * @type {number} 24240 */ 24241 this._interval = null; 24242 24243 /** 24244 * Whether the element is currently visible or not. 24245 * @protected 24246 * @type {Boolean} 24247 */ 24248 this._visible = null; 24249 24250 /** 24251 * All event handlers. 24252 * @protected 24253 * @type {Object} 24254 */ 24255 this._handlers = { 24256 'initialized.owl.carousel': $.proxy(function(e) { 24257 if (e.namespace && this._core.settings.autoRefresh) { 24258 this.watch(); 24259 } 24260 }, this) 24261 }; 24262 24263 // set default options 24264 this._core.options = $.extend({}, AutoRefresh.Defaults, this._core.options); 24265 24266 // register event handlers 24267 this._core.$element.on(this._handlers); 24268 }; 24269 24270 /** 24271 * Default options. 24272 * @public 24273 */ 24274 AutoRefresh.Defaults = { 24275 autoRefresh: true, 24276 autoRefreshInterval: 500 24277 }; 24278 24279 /** 24280 * Watches the element. 24281 */ 24282 AutoRefresh.prototype.watch = function() { 24283 if (this._interval) { 24284 return; 24285 } 24286 24287 this._visible = this._core.$element.is(':visible'); 24288 this._interval = window.setInterval($.proxy(this.refresh, this), this._core.settings.autoRefreshInterval); 24289 }; 24290 24291 /** 24292 * Refreshes the element. 24293 */ 24294 AutoRefresh.prototype.refresh = function() { 24295 if (this._core.$element.is(':visible') === this._visible) { 24296 return; 24297 } 24298 24299 this._visible = !this._visible; 24300 24301 this._core.$element.toggleClass('owl-hidden', !this._visible); 24302 24303 this._visible && (this._core.invalidate('width') && this._core.refresh()); 24304 }; 24305 24306 /** 24307 * Destroys the plugin. 24308 */ 24309 AutoRefresh.prototype.destroy = function() { 24310 var handler, property; 24311 24312 window.clearInterval(this._interval); 24313 24314 for (handler in this._handlers) { 24315 this._core.$element.off(handler, this._handlers[handler]); 24316 } 24317 for (property in Object.getOwnPropertyNames(this)) { 24318 typeof this[property] != 'function' && (this[property] = null); 24319 } 24320 }; 24321 24322 $.fn.owlCarousel.Constructor.Plugins.AutoRefresh = AutoRefresh; 24323 24324})(window.Zepto || window.jQuery, window, document); 24325 24326/** 24327 * Lazy Plugin 24328 * @version 2.0.0-beta.3 24329 * @author Bartosz Wojciechowski 24330 * @license The MIT License (MIT) 24331 */ 24332;(function($, window, document, undefined) { 24333 24334 /** 24335 * Creates the lazy plugin. 24336 * @class The Lazy Plugin 24337 * @param {Owl} carousel - The Owl Carousel 24338 */ 24339 var Lazy = function(carousel) { 24340 24341 /** 24342 * Reference to the core. 24343 * @protected 24344 * @type {Owl} 24345 */ 24346 this._core = carousel; 24347 24348 /** 24349 * Already loaded items. 24350 * @protected 24351 * @type {Array.<jQuery>} 24352 */ 24353 this._loaded = []; 24354 24355 /** 24356 * Event handlers. 24357 * @protected 24358 * @type {Object} 24359 */ 24360 this._handlers = { 24361 'initialized.owl.carousel change.owl.carousel': $.proxy(function(e) { 24362 if (!e.namespace) { 24363 return; 24364 } 24365 24366 if (!this._core.settings || !this._core.settings.lazyLoad) { 24367 return; 24368 } 24369 24370 if ((e.property && e.property.name == 'position') || e.type == 'initialized') { 24371 var settings = this._core.settings, 24372 n = (settings.center && Math.ceil(settings.items / 2) || settings.items), 24373 i = ((settings.center && n * -1) || 0), 24374 position = ((e.property && e.property.value) || this._core.current()) + i, 24375 clones = this._core.clones().length, 24376 load = $.proxy(function(i, v) { this.load(v) }, this); 24377 24378 while (i++ < n) { 24379 this.load(clones / 2 + this._core.relative(position)); 24380 clones && $.each(this._core.clones(this._core.relative(position)), load); 24381 position++; 24382 } 24383 } 24384 }, this) 24385 }; 24386 24387 // set the default options 24388 this._core.options = $.extend({}, Lazy.Defaults, this._core.options); 24389 24390 // register event handler 24391 this._core.$element.on(this._handlers); 24392 } 24393 24394 /** 24395 * Default options. 24396 * @public 24397 */ 24398 Lazy.Defaults = { 24399 lazyLoad: false 24400 } 24401 24402 /** 24403 * Loads all resources of an item at the specified position. 24404 * @param {Number} position - The absolute position of the item. 24405 * @protected 24406 */ 24407 Lazy.prototype.load = function(position) { 24408 var $item = this._core.$stage.children().eq(position), 24409 $elements = $item && $item.find('.owl-lazy'); 24410 24411 if (!$elements || $.inArray($item.get(0), this._loaded) > -1) { 24412 return; 24413 } 24414 24415 $elements.each($.proxy(function(index, element) { 24416 var $element = $(element), image, 24417 url = (window.devicePixelRatio > 1 && $element.attr('data-src-retina')) || $element.attr('data-src'); 24418 24419 this._core.trigger('load', { element: $element, url: url }, 'lazy'); 24420 24421 if ($element.is('img')) { 24422 $element.one('load.owl.lazy', $.proxy(function() { 24423 $element.css('opacity', 1); 24424 this._core.trigger('loaded', { element: $element, url: url }, 'lazy'); 24425 }, this)).attr('src', url); 24426 } else { 24427 image = new Image(); 24428 image.onload = $.proxy(function() { 24429 $element.css({ 24430 'background-image': 'url(' + url + ')', 24431 'opacity': '1' 24432 }); 24433 this._core.trigger('loaded', { element: $element, url: url }, 'lazy'); 24434 }, this); 24435 image.src = url; 24436 } 24437 }, this)); 24438 24439 this._loaded.push($item.get(0)); 24440 } 24441 24442 /** 24443 * Destroys the plugin. 24444 * @public 24445 */ 24446 Lazy.prototype.destroy = function() { 24447 var handler, property; 24448 24449 for (handler in this.handlers) { 24450 this._core.$element.off(handler, this.handlers[handler]); 24451 } 24452 for (property in Object.getOwnPropertyNames(this)) { 24453 typeof this[property] != 'function' && (this[property] = null); 24454 } 24455 }; 24456 24457 $.fn.owlCarousel.Constructor.Plugins.Lazy = Lazy; 24458 24459})(window.Zepto || window.jQuery, window, document); 24460 24461/** 24462 * AutoHeight Plugin 24463 * @version 2.0.0-beta.3 24464 * @author Bartosz Wojciechowski 24465 * @license The MIT License (MIT) 24466 */ 24467;(function($, window, document, undefined) { 24468 24469 /** 24470 * Creates the auto height plugin. 24471 * @class The Auto Height Plugin 24472 * @param {Owl} carousel - The Owl Carousel 24473 */ 24474 var AutoHeight = function(carousel) { 24475 /** 24476 * Reference to the core. 24477 * @protected 24478 * @type {Owl} 24479 */ 24480 this._core = carousel; 24481 24482 /** 24483 * All event handlers. 24484 * @protected 24485 * @type {Object} 24486 */ 24487 this._handlers = { 24488 'initialized.owl.carousel refreshed.owl.carousel': $.proxy(function(e) { 24489 if (e.namespace && this._core.settings.autoHeight) { 24490 this.update(); 24491 } 24492 }, this), 24493 'changed.owl.carousel': $.proxy(function(e) { 24494 if (e.namespace && this._core.settings.autoHeight && e.property.name == 'position'){ 24495 this.update(); 24496 } 24497 }, this), 24498 'loaded.owl.lazy': $.proxy(function(e) { 24499 if (e.namespace && this._core.settings.autoHeight 24500 && e.element.closest('.' + this._core.settings.itemClass).index() === this._core.current()) { 24501 this.update(); 24502 } 24503 }, this) 24504 }; 24505 24506 // set default options 24507 this._core.options = $.extend({}, AutoHeight.Defaults, this._core.options); 24508 24509 // register event handlers 24510 this._core.$element.on(this._handlers); 24511 }; 24512 24513 /** 24514 * Default options. 24515 * @public 24516 */ 24517 AutoHeight.Defaults = { 24518 autoHeight: false, 24519 autoHeightClass: 'owl-height' 24520 }; 24521 24522 /** 24523 * Updates the view. 24524 */ 24525 AutoHeight.prototype.update = function() { 24526 var start = this._core._current, 24527 end = start + this._core.settings.items, 24528 visible = this._core.$stage.children().toArray().slice(start, end); 24529 heights = [], 24530 maxheight = 0; 24531 24532 $.each(visible, function(index, item) { 24533 heights.push($(item).height()); 24534 }); 24535 24536 maxheight = Math.max.apply(null, heights); 24537 24538 this._core.$stage.parent() 24539 .height(maxheight) 24540 .addClass(this._core.settings.autoHeightClass); 24541 }; 24542 24543 AutoHeight.prototype.destroy = function() { 24544 var handler, property; 24545 24546 for (handler in this._handlers) { 24547 this._core.$element.off(handler, this._handlers[handler]); 24548 } 24549 for (property in Object.getOwnPropertyNames(this)) { 24550 typeof this[property] != 'function' && (this[property] = null); 24551 } 24552 }; 24553 24554 $.fn.owlCarousel.Constructor.Plugins.AutoHeight = AutoHeight; 24555 24556})(window.Zepto || window.jQuery, window, document); 24557 24558/** 24559 * Video Plugin 24560 * @version 2.0.0-beta.3 24561 * @author Bartosz Wojciechowski 24562 * @license The MIT License (MIT) 24563 */ 24564;(function($, window, document, undefined) { 24565 24566 /** 24567 * Creates the video plugin. 24568 * @class The Video Plugin 24569 * @param {Owl} carousel - The Owl Carousel 24570 */ 24571 var Video = function(carousel) { 24572 /** 24573 * Reference to the core. 24574 * @protected 24575 * @type {Owl} 24576 */ 24577 this._core = carousel; 24578 24579 /** 24580 * Cache all video URLs. 24581 * @protected 24582 * @type {Object} 24583 */ 24584 this._videos = {}; 24585 24586 /** 24587 * Current playing item. 24588 * @protected 24589 * @type {jQuery} 24590 */ 24591 this._playing = null; 24592 24593 /** 24594 * All event handlers. 24595 * @todo The cloned content removale is too late 24596 * @protected 24597 * @type {Object} 24598 */ 24599 this._handlers = { 24600 'initialized.owl.carousel': $.proxy(function(e) { 24601 if (e.namespace) { 24602 this._core.register({ type: 'state', name: 'playing', tags: [ 'interacting' ] }); 24603 } 24604 }, this), 24605 'resize.owl.carousel': $.proxy(function(e) { 24606 if (e.namespace && this._core.settings.video && this.isInFullScreen()) { 24607 e.preventDefault(); 24608 } 24609 }, this), 24610 'refreshed.owl.carousel': $.proxy(function(e) { 24611 if (e.namespace && this._core.is('resizing')) { 24612 this._core.$stage.find('.cloned .owl-video-frame').remove(); 24613 } 24614 }, this), 24615 'changed.owl.carousel': $.proxy(function(e) { 24616 if (e.namespace && e.property.name === 'position' && this._playing) { 24617 this.stop(); 24618 } 24619 }, this), 24620 'prepared.owl.carousel': $.proxy(function(e) { 24621 if (!e.namespace) { 24622 return; 24623 } 24624 24625 var $element = $(e.content).find('.owl-video'); 24626 24627 if ($element.length) { 24628 $element.css('display', 'none'); 24629 this.fetch($element, $(e.content)); 24630 } 24631 }, this) 24632 }; 24633 24634 // set default options 24635 this._core.options = $.extend({}, Video.Defaults, this._core.options); 24636 24637 // register event handlers 24638 this._core.$element.on(this._handlers); 24639 24640 this._core.$element.on('click.owl.video', '.owl-video-play-icon', $.proxy(function(e) { 24641 this.play(e); 24642 }, this)); 24643 }; 24644 24645 /** 24646 * Default options. 24647 * @public 24648 */ 24649 Video.Defaults = { 24650 video: false, 24651 videoHeight: false, 24652 videoWidth: false 24653 }; 24654 24655 /** 24656 * Gets the video ID and the type (YouTube/Vimeo only). 24657 * @protected 24658 * @param {jQuery} target - The target containing the video data. 24659 * @param {jQuery} item - The item containing the video. 24660 */ 24661 Video.prototype.fetch = function(target, item) { 24662 var type = target.attr('data-vimeo-id') ? 'vimeo' : 'youtube', 24663 id = target.attr('data-vimeo-id') || target.attr('data-youtube-id'), 24664 width = target.attr('data-width') || this._core.settings.videoWidth, 24665 height = target.attr('data-height') || this._core.settings.videoHeight, 24666 url = target.attr('href'); 24667 24668 if (url) { 24669 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+)?/); 24670 24671 if (id[3].indexOf('youtu') > -1) { 24672 type = 'youtube'; 24673 } else if (id[3].indexOf('vimeo') > -1) { 24674 type = 'vimeo'; 24675 } else { 24676 throw new Error('Video URL not supported.'); 24677 } 24678 id = id[6]; 24679 } else { 24680 throw new Error('Missing video URL.'); 24681 } 24682 24683 this._videos[url] = { 24684 type: type, 24685 id: id, 24686 width: width, 24687 height: height 24688 }; 24689 24690 item.attr('data-video', url); 24691 24692 this.thumbnail(target, this._videos[url]); 24693 }; 24694 24695 /** 24696 * Creates video thumbnail. 24697 * @protected 24698 * @param {jQuery} target - The target containing the video data. 24699 * @param {Object} info - The video info object. 24700 * @see `fetch` 24701 */ 24702 Video.prototype.thumbnail = function(target, video) { 24703 var tnLink, 24704 icon, 24705 path, 24706 dimensions = video.width && video.height ? 'style="width:' + video.width + 'px;height:' + video.height + 'px;"' : '', 24707 customTn = target.find('img'), 24708 srcType = 'src', 24709 lazyClass = '', 24710 settings = this._core.settings, 24711 create = function(path) { 24712 icon = '<div class="owl-video-play-icon"></div>'; 24713 24714 if (settings.lazyLoad) { 24715 tnLink = '<div class="owl-video-tn ' + lazyClass + '" ' + srcType + '="' + path + '"></div>'; 24716 } else { 24717 tnLink = '<div class="owl-video-tn" style="opacity:1;background-image:url(' + path + ')"></div>'; 24718 } 24719 target.after(tnLink); 24720 target.after(icon); 24721 }; 24722 24723 // wrap video content into owl-video-wrapper div 24724 target.wrap('<div class="owl-video-wrapper"' + dimensions + '></div>'); 24725 24726 if (this._core.settings.lazyLoad) { 24727 srcType = 'data-src'; 24728 lazyClass = 'owl-lazy'; 24729 } 24730 24731 // custom thumbnail 24732 if (customTn.length) { 24733 create(customTn.attr(srcType)); 24734 customTn.remove(); 24735 return false; 24736 } 24737 24738 if (video.type === 'youtube') { 24739 path = "//img.youtube.com/vi/" + video.id + "/hqdefault.jpg"; 24740 create(path); 24741 } else if (video.type === 'vimeo') { 24742 $.ajax({ 24743 type: 'GET', 24744 url: '//vimeo.com/api/v2/video/' + video.id + '.json', 24745 jsonp: 'callback', 24746 dataType: 'jsonp', 24747 success: function(data) { 24748 path = data[0].thumbnail_large; 24749 create(path); 24750 } 24751 }); 24752 } 24753 }; 24754 24755 /** 24756 * Stops the current video. 24757 * @public 24758 */ 24759 Video.prototype.stop = function() { 24760 this._core.trigger('stop', null, 'video'); 24761 this._playing.find('.owl-video-frame').remove(); 24762 this._playing.removeClass('owl-video-playing'); 24763 this._playing = null; 24764 this._core.leave('playing'); 24765 this._core.trigger('stopped', null, 'video'); 24766 }; 24767 24768 /** 24769 * Starts the current video. 24770 * @public 24771 * @param {Event} event - The event arguments. 24772 */ 24773 Video.prototype.play = function(event) { 24774 var target = $(event.target), 24775 item = target.closest('.' + this._core.settings.itemClass), 24776 video = this._videos[item.attr('data-video')], 24777 width = video.width || '100%', 24778 height = video.height || this._core.$stage.height(), 24779 html; 24780 24781 if (this._playing) { 24782 return; 24783 } 24784 24785 this._core.enter('playing'); 24786 this._core.trigger('play', null, 'video'); 24787 24788 item = this._core.items(this._core.relative(item.index())); 24789 24790 this._core.reset(item.index()); 24791 24792 if (video.type === 'youtube') { 24793 html = '<iframe width="' + width + '" height="' + height + '" src="//www.youtube.com/embed/' + 24794 video.id + '?autoplay=1&v=' + video.id + '" frameborder="0" allowfullscreen></iframe>'; 24795 } else if (video.type === 'vimeo') { 24796 html = '<iframe src="//player.vimeo.com/video/' + video.id + 24797 '?autoplay=1" width="' + width + '" height="' + height + 24798 '" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>'; 24799 } 24800 24801 $('<div class="owl-video-frame">' + html + '</div>').insertAfter(item.find('.owl-video')); 24802 24803 this._playing = item.addClass('owl-video-playing'); 24804 }; 24805 24806 /** 24807 * Checks whether an video is currently in full screen mode or not. 24808 * @todo Bad style because looks like a readonly method but changes members. 24809 * @protected 24810 * @returns {Boolean} 24811 */ 24812 Video.prototype.isInFullScreen = function() { 24813 var element = document.fullscreenElement || document.mozFullScreenElement || 24814 document.webkitFullscreenElement; 24815 24816 return element && $(element).parent().hasClass('owl-video-frame'); 24817 }; 24818 24819 /** 24820 * Destroys the plugin. 24821 */ 24822 Video.prototype.destroy = function() { 24823 var handler, property; 24824 24825 this._core.$element.off('click.owl.video'); 24826 24827 for (handler in this._handlers) { 24828 this._core.$element.off(handler, this._handlers[handler]); 24829 } 24830 for (property in Object.getOwnPropertyNames(this)) { 24831 typeof this[property] != 'function' && (this[property] = null); 24832 } 24833 }; 24834 24835 $.fn.owlCarousel.Constructor.Plugins.Video = Video; 24836 24837})(window.Zepto || window.jQuery, window, document); 24838 24839/** 24840 * Animate Plugin 24841 * @version 2.0.0-beta.3 24842 * @author Bartosz Wojciechowski 24843 * @license The MIT License (MIT) 24844 */ 24845;(function($, window, document, undefined) { 24846 24847 /** 24848 * Creates the animate plugin. 24849 * @class The Navigation Plugin 24850 * @param {Owl} scope - The Owl Carousel 24851 */ 24852 var Animate = function(scope) { 24853 this.core = scope; 24854 this.core.options = $.extend({}, Animate.Defaults, this.core.options); 24855 this.swapping = true; 24856 this.previous = undefined; 24857 this.next = undefined; 24858 24859 this.handlers = { 24860 'change.owl.carousel': $.proxy(function(e) { 24861 if (e.namespace && e.property.name == 'position') { 24862 this.previous = this.core.current(); 24863 this.next = e.property.value; 24864 } 24865 }, this), 24866 'drag.owl.carousel dragged.owl.carousel translated.owl.carousel': $.proxy(function(e) { 24867 if (e.namespace) { 24868 this.swapping = e.type == 'translated'; 24869 } 24870 }, this), 24871 'translate.owl.carousel': $.proxy(function(e) { 24872 if (e.namespace && this.swapping && (this.core.options.animateOut || this.core.options.animateIn)) { 24873 this.swap(); 24874 } 24875 }, this) 24876 }; 24877 24878 this.core.$element.on(this.handlers); 24879 }; 24880 24881 /** 24882 * Default options. 24883 * @public 24884 */ 24885 Animate.Defaults = { 24886 animateOut: false, 24887 animateIn: false 24888 }; 24889 24890 /** 24891 * Toggles the animation classes whenever an translations starts. 24892 * @protected 24893 * @returns {Boolean|undefined} 24894 */ 24895 Animate.prototype.swap = function() { 24896 24897 if (this.core.settings.items !== 1) { 24898 return; 24899 } 24900 24901 if (!$.support.animation || !$.support.transition) { 24902 return; 24903 } 24904 24905 this.core.speed(0); 24906 24907 var left, 24908 clear = $.proxy(this.clear, this), 24909 previous = this.core.$stage.children().eq(this.previous), 24910 next = this.core.$stage.children().eq(this.next), 24911 incoming = this.core.settings.animateIn, 24912 outgoing = this.core.settings.animateOut; 24913 24914 if (this.core.current() === this.previous) { 24915 return; 24916 } 24917 24918 if (outgoing) { 24919 left = this.core.coordinates(this.previous) - this.core.coordinates(this.next); 24920 previous.css( { 'left': left + 'px' } ) 24921 .addClass('animated owl-animated-out') 24922 .addClass(outgoing) 24923 .on($.support.animation.end, clear); 24924 } 24925 24926 if (incoming) { 24927 next.addClass('animated owl-animated-in') 24928 .addClass(incoming) 24929 .on($.support.animation.end, clear); 24930 } 24931 }; 24932 24933 Animate.prototype.clear = function(e) { 24934 if ($(e.target).hasClass('animated')) { 24935 $(e.target).css( { 'left': '' } ) 24936 .removeClass('animated owl-animated-out owl-animated-in') 24937 .removeClass(this.core.settings.animateIn) 24938 .removeClass(this.core.settings.animateOut); 24939 this.core.onTransitionEnd(); 24940 } 24941 }; 24942 24943 /** 24944 * Destroys the plugin. 24945 * @public 24946 */ 24947 Animate.prototype.destroy = function() { 24948 var handler, property; 24949 24950 for (handler in this.handlers) { 24951 this.core.$element.off(handler, this.handlers[handler]); 24952 } 24953 for (property in Object.getOwnPropertyNames(this)) { 24954 typeof this[property] != 'function' && (this[property] = null); 24955 } 24956 }; 24957 24958 $.fn.owlCarousel.Constructor.Plugins.Animate = Animate; 24959 24960})(window.Zepto || window.jQuery, window, document); 24961 24962/** 24963 * Autoplay Plugin 24964 * @version 2.0.0-beta.3 24965 * @author Bartosz Wojciechowski 24966 * @author Artus Kolanowski 24967 * @license The MIT License (MIT) 24968 */ 24969;(function($, window, document, undefined) { 24970 24971 /** 24972 * Creates the autoplay plugin. 24973 * @class The Autoplay Plugin 24974 * @param {Owl} scope - The Owl Carousel 24975 */ 24976 var Autoplay = function(carousel) { 24977 /** 24978 * Reference to the core. 24979 * @protected 24980 * @type {Owl} 24981 */ 24982 this._core = carousel; 24983 24984 /** 24985 * The autoplay interval. 24986 * @type {Number} 24987 */ 24988 this._interval = null; 24989 24990 /** 24991 * Indicates whenever the autoplay is paused. 24992 * @type {Boolean} 24993 */ 24994 this._paused = false; 24995 24996 /** 24997 * All event handlers. 24998 * @protected 24999 * @type {Object} 25000 */ 25001 this._handlers = { 25002 'changed.owl.carousel': $.proxy(function(e) { 25003 if (e.namespace && e.property.name === 'settings') { 25004 if (this._core.settings.autoplay) { 25005 this.play(); 25006 } else { 25007 this.stop(); 25008 } 25009 } 25010 }, this), 25011 'initialized.owl.carousel': $.proxy(function(e) { 25012 if (e.namespace && this._core.settings.autoplay) { 25013 this.play(); 25014 } 25015 }, this), 25016 'play.owl.autoplay': $.proxy(function(e, t, s) { 25017 if (e.namespace) { 25018 this.play(t, s); 25019 } 25020 }, this), 25021 'stop.owl.autoplay': $.proxy(function(e) { 25022 if (e.namespace) { 25023 this.stop(); 25024 } 25025 }, this), 25026 'mouseover.owl.autoplay': $.proxy(function() { 25027 if (this._core.settings.autoplayHoverPause && this._core.is('rotating')) { 25028 this.pause(); 25029 } 25030 }, this), 25031 'mouseleave.owl.autoplay': $.proxy(function() { 25032 if (this._core.settings.autoplayHoverPause && this._core.is('rotating')) { 25033 this.play(); 25034 } 25035 }, this) 25036 }; 25037 25038 // register event handlers 25039 this._core.$element.on(this._handlers); 25040 25041 // set default options 25042 this._core.options = $.extend({}, Autoplay.Defaults, this._core.options); 25043 }; 25044 25045 /** 25046 * Default options. 25047 * @public 25048 */ 25049 Autoplay.Defaults = { 25050 autoplay: false, 25051 autoplayTimeout: 5000, 25052 autoplayHoverPause: false, 25053 autoplaySpeed: false 25054 }; 25055 25056 /** 25057 * Starts the autoplay. 25058 * @public 25059 * @param {Number} [timeout] - The interval before the next animation starts. 25060 * @param {Number} [speed] - The animation speed for the animations. 25061 */ 25062 Autoplay.prototype.play = function(timeout, speed) { 25063 this._paused = false; 25064 25065 if (this._core.is('rotating')) { 25066 return; 25067 } 25068 25069 this._core.enter('rotating'); 25070 25071 this._interval = window.setInterval($.proxy(function() { 25072 if (this._paused || this._core.is('busy') || this._core.is('interacting') || document.hidden) { 25073 return; 25074 } 25075 this._core.next(speed || this._core.settings.autoplaySpeed); 25076 }, this), timeout || this._core.settings.autoplayTimeout); 25077 }; 25078 25079 /** 25080 * Stops the autoplay. 25081 * @public 25082 */ 25083 Autoplay.prototype.stop = function() { 25084 if (!this._core.is('rotating')) { 25085 return; 25086 } 25087 25088 window.clearInterval(this._interval); 25089 this._core.leave('rotating'); 25090 }; 25091 25092 /** 25093 * Stops the autoplay. 25094 * @public 25095 */ 25096 Autoplay.prototype.pause = function() { 25097 if (!this._core.is('rotating')) { 25098 return; 25099 } 25100 25101 this._paused = true; 25102 }; 25103 25104 /** 25105 * Destroys the plugin. 25106 */ 25107 Autoplay.prototype.destroy = function() { 25108 var handler, property; 25109 25110 this.stop(); 25111 25112 for (handler in this._handlers) { 25113 this._core.$element.off(handler, this._handlers[handler]); 25114 } 25115 for (property in Object.getOwnPropertyNames(this)) { 25116 typeof this[property] != 'function' && (this[property] = null); 25117 } 25118 }; 25119 25120 $.fn.owlCarousel.Constructor.Plugins.autoplay = Autoplay; 25121 25122})(window.Zepto || window.jQuery, window, document); 25123 25124/** 25125 * Navigation Plugin 25126 * @version 2.0.0-beta.3 25127 * @author Artus Kolanowski 25128 * @license The MIT License (MIT) 25129 */ 25130;(function($, window, document, undefined) { 25131 'use strict'; 25132 25133 /** 25134 * Creates the navigation plugin. 25135 * @class The Navigation Plugin 25136 * @param {Owl} carousel - The Owl Carousel. 25137 */ 25138 var Navigation = function(carousel) { 25139 /** 25140 * Reference to the core. 25141 * @protected 25142 * @type {Owl} 25143 */ 25144 this._core = carousel; 25145 25146 /** 25147 * Indicates whether the plugin is initialized or not. 25148 * @protected 25149 * @type {Boolean} 25150 */ 25151 this._initialized = false; 25152 25153 /** 25154 * The current paging indexes. 25155 * @protected 25156 * @type {Array} 25157 */ 25158 this._pages = []; 25159 25160 /** 25161 * All DOM elements of the user interface. 25162 * @protected 25163 * @type {Object} 25164 */ 25165 this._controls = {}; 25166 25167 /** 25168 * Markup for an indicator. 25169 * @protected 25170 * @type {Array.<String>} 25171 */ 25172 this._templates = []; 25173 25174 /** 25175 * The carousel element. 25176 * @type {jQuery} 25177 */ 25178 this.$element = this._core.$element; 25179 25180 /** 25181 * Overridden methods of the carousel. 25182 * @protected 25183 * @type {Object} 25184 */ 25185 this._overrides = { 25186 next: this._core.next, 25187 prev: this._core.prev, 25188 to: this._core.to 25189 }; 25190 25191 /** 25192 * All event handlers. 25193 * @protected 25194 * @type {Object} 25195 */ 25196 this._handlers = { 25197 'prepared.owl.carousel': $.proxy(function(e) { 25198 if (e.namespace && this._core.settings.dotsData) { 25199 this._templates.push('<div class="' + this._core.settings.dotClass + '">' + 25200 $(e.content).find('[data-dot]').andSelf('[data-dot]').attr('data-dot') + '</div>'); 25201 } 25202 }, this), 25203 'added.owl.carousel': $.proxy(function(e) { 25204 if (e.namespace && this._core.settings.dotsData) { 25205 this._templates.splice(e.position, 0, this._templates.pop()); 25206 } 25207 }, this), 25208 'remove.owl.carousel': $.proxy(function(e) { 25209 if (e.namespace && this._core.settings.dotsData) { 25210 this._templates.splice(e.position, 1); 25211 } 25212 }, this), 25213 'changed.owl.carousel': $.proxy(function(e) { 25214 if (e.namespace && e.property.name == 'position') { 25215 this.draw(); 25216 } 25217 }, this), 25218 'initialized.owl.carousel': $.proxy(function(e) { 25219 if (e.namespace && !this._initialized) { 25220 this._core.trigger('initialize', null, 'navigation'); 25221 this.initialize(); 25222 this.update(); 25223 this.draw(); 25224 this._initialized = true; 25225 this._core.trigger('initialized', null, 'navigation'); 25226 } 25227 }, this), 25228 'refreshed.owl.carousel': $.proxy(function(e) { 25229 if (e.namespace && this._initialized) { 25230 this._core.trigger('refresh', null, 'navigation'); 25231 this.update(); 25232 this.draw(); 25233 this._core.trigger('refreshed', null, 'navigation'); 25234 } 25235 }, this) 25236 }; 25237 25238 // set default options 25239 this._core.options = $.extend({}, Navigation.Defaults, this._core.options); 25240 25241 // register event handlers 25242 this.$element.on(this._handlers); 25243 }; 25244 25245 /** 25246 * Default options. 25247 * @public 25248 * @todo Rename `slideBy` to `navBy` 25249 */ 25250 Navigation.Defaults = { 25251 nav: false, 25252 navText: [ 'prev', 'next' ], 25253 navSpeed: false, 25254 navElement: 'div', 25255 navContainer: false, 25256 navContainerClass: 'owl-nav', 25257 navClass: [ 'owl-prev', 'owl-next' ], 25258 slideBy: 1, 25259 dotClass: 'owl-dot', 25260 dotsClass: 'owl-dots', 25261 dots: true, 25262 dotsEach: false, 25263 dotsData: false, 25264 dotsSpeed: false, 25265 dotsContainer: false 25266 }; 25267 25268 /** 25269 * Initializes the layout of the plugin and extends the carousel. 25270 * @protected 25271 */ 25272 Navigation.prototype.initialize = function() { 25273 var override, 25274 settings = this._core.settings; 25275 25276 // create DOM structure for relative navigation 25277 this._controls.$relative = (settings.navContainer ? $(settings.navContainer) 25278 : $('<div>').addClass(settings.navContainerClass).appendTo(this.$element)).addClass('disabled'); 25279 25280 this._controls.$previous = $('<' + settings.navElement + '>') 25281 .addClass(settings.navClass[0]) 25282 .html(settings.navText[0]) 25283 .prependTo(this._controls.$relative) 25284 .on('click', $.proxy(function(e) { 25285 this.prev(settings.navSpeed); 25286 }, this)); 25287 this._controls.$next = $('<' + settings.navElement + '>') 25288 .addClass(settings.navClass[1]) 25289 .html(settings.navText[1]) 25290 .appendTo(this._controls.$relative) 25291 .on('click', $.proxy(function(e) { 25292 this.next(settings.navSpeed); 25293 }, this)); 25294 25295 // create DOM structure for absolute navigation 25296 if (!settings.dotsData) { 25297 this._templates = [ $('<div>') 25298 .addClass(settings.dotClass) 25299 .append($('<span>')) 25300 .prop('outerHTML') ]; 25301 } 25302 25303 this._controls.$absolute = (settings.dotsContainer ? $(settings.dotsContainer) 25304 : $('<div>').addClass(settings.dotsClass).appendTo(this.$element)).addClass('disabled'); 25305 25306 this._controls.$absolute.on('click', 'div', $.proxy(function(e) { 25307 var index = $(e.target).parent().is(this._controls.$absolute) 25308 ? $(e.target).index() : $(e.target).parent().index(); 25309 25310 e.preventDefault(); 25311 25312 this.to(index, settings.dotsSpeed); 25313 }, this)); 25314 25315 // override public methods of the carousel 25316 for (override in this._overrides) { 25317 this._core[override] = $.proxy(this[override], this); 25318 } 25319 }; 25320 25321 /** 25322 * Destroys the plugin. 25323 * @protected 25324 */ 25325 Navigation.prototype.destroy = function() { 25326 var handler, control, property, override; 25327 25328 for (handler in this._handlers) { 25329 this.$element.off(handler, this._handlers[handler]); 25330 } 25331 for (control in this._controls) { 25332 this._controls[control].remove(); 25333 } 25334 for (override in this.overides) { 25335 this._core[override] = this._overrides[override]; 25336 } 25337 for (property in Object.getOwnPropertyNames(this)) { 25338 typeof this[property] != 'function' && (this[property] = null); 25339 } 25340 }; 25341 25342 /** 25343 * Updates the internal state. 25344 * @protected 25345 */ 25346 Navigation.prototype.update = function() { 25347 var i, j, k, 25348 lower = this._core.clones().length / 2, 25349 upper = lower + this._core.items().length, 25350 maximum = this._core.maximum(true), 25351 settings = this._core.settings, 25352 size = settings.center || settings.autoWidth || settings.dotsData 25353 ? 1 : settings.dotsEach || settings.items; 25354 25355 if (settings.slideBy !== 'page') { 25356 settings.slideBy = Math.min(settings.slideBy, settings.items); 25357 } 25358 25359 if (settings.dots || settings.slideBy == 'page') { 25360 this._pages = []; 25361 25362 for (i = lower, j = 0, k = 0; i < upper; i++) { 25363 if (j >= size || j === 0) { 25364 this._pages.push({ 25365 start: Math.min(maximum, i - lower), 25366 end: i - lower + size - 1 25367 }); 25368 if (Math.min(maximum, i - lower) === maximum) { 25369 break; 25370 } 25371 j = 0, ++k; 25372 } 25373 j += this._core.mergers(this._core.relative(i)); 25374 } 25375 } 25376 }; 25377 25378 /** 25379 * Draws the user interface. 25380 * @todo The option `dotsData` wont work. 25381 * @protected 25382 */ 25383 Navigation.prototype.draw = function() { 25384 var difference, 25385 settings = this._core.settings, 25386 disabled = this._core.items().length <= settings.items, 25387 index = this._core.relative(this._core.current()), 25388 loop = settings.loop || settings.rewind; 25389 25390 this._controls.$relative.toggleClass('disabled', !settings.nav || disabled); 25391 25392 if (settings.nav) { 25393 this._controls.$previous.toggleClass('disabled', !loop && index <= this._core.minimum(true)); 25394 this._controls.$next.toggleClass('disabled', !loop && index >= this._core.maximum(true)); 25395 } 25396 25397 this._controls.$absolute.toggleClass('disabled', !settings.dots || disabled); 25398 25399 if (settings.dots) { 25400 difference = this._pages.length - this._controls.$absolute.children().length; 25401 25402 if (settings.dotsData && difference !== 0) { 25403 this._controls.$absolute.html(this._templates.join('')); 25404 } else if (difference > 0) { 25405 this._controls.$absolute.append(new Array(difference + 1).join(this._templates[0])); 25406 } else if (difference < 0) { 25407 this._controls.$absolute.children().slice(difference).remove(); 25408 } 25409 25410 this._controls.$absolute.find('.active').removeClass('active'); 25411 this._controls.$absolute.children().eq($.inArray(this.current(), this._pages)).addClass('active'); 25412 } 25413 }; 25414 25415 /** 25416 * Extends event data. 25417 * @protected 25418 * @param {Event} event - The event object which gets thrown. 25419 */ 25420 Navigation.prototype.onTrigger = function(event) { 25421 var settings = this._core.settings; 25422 25423 event.page = { 25424 index: $.inArray(this.current(), this._pages), 25425 count: this._pages.length, 25426 size: settings && (settings.center || settings.autoWidth || settings.dotsData 25427 ? 1 : settings.dotsEach || settings.items) 25428 }; 25429 }; 25430 25431 /** 25432 * Gets the current page position of the carousel. 25433 * @protected 25434 * @returns {Number} 25435 */ 25436 Navigation.prototype.current = function() { 25437 var current = this._core.relative(this._core.current()); 25438 return $.grep(this._pages, $.proxy(function(page, index) { 25439 return page.start <= current && page.end >= current; 25440 }, this)).pop(); 25441 }; 25442 25443 /** 25444 * Gets the current succesor/predecessor position. 25445 * @protected 25446 * @returns {Number} 25447 */ 25448 Navigation.prototype.getPosition = function(successor) { 25449 var position, length, 25450 settings = this._core.settings; 25451 25452 if (settings.slideBy == 'page') { 25453 position = $.inArray(this.current(), this._pages); 25454 length = this._pages.length; 25455 successor ? ++position : --position;
vendor: 5,678 bytes, lines 25456-25680
25456 position = this._pages[((position % length) + length) % length].start; 25457 } else { 25458 position = this._core.relative(this._core.current()); 25459 length = this._core.items().length; 25460 successor ? position += settings.slideBy : position -= settings.slideBy; 25461 } 25462 25463 return position; 25464 }; 25465 25466 /** 25467 * Slides to the next item or page. 25468 * @public 25469 * @param {Number} [speed=false] - The time in milliseconds for the transition. 25470 */ 25471 Navigation.prototype.next = function(speed) { 25472 $.proxy(this._overrides.to, this._core)(this.getPosition(true), speed); 25473 }; 25474 25475 /** 25476 * Slides to the previous item or page. 25477 * @public 25478 * @param {Number} [speed=false] - The time in milliseconds for the transition. 25479 */ 25480 Navigation.prototype.prev = function(speed) { 25481 $.proxy(this._overrides.to, this._core)(this.getPosition(false), speed); 25482 }; 25483 25484 /** 25485 * Slides to the specified item or page. 25486 * @public 25487 * @param {Number} position - The position of the item or page. 25488 * @param {Number} [speed] - The time in milliseconds for the transition. 25489 * @param {Boolean} [standard=false] - Whether to use the standard behaviour or not. 25490 */ 25491 Navigation.prototype.to = function(position, speed, standard) { 25492 var length; 25493 25494 if (!standard) { 25495 length = this._pages.length; 25496 $.proxy(this._overrides.to, this._core)(this._pages[((position % length) + length) % length].start, speed); 25497 } else { 25498 $.proxy(this._overrides.to, this._core)(position, speed); 25499 } 25500 }; 25501 25502 $.fn.owlCarousel.Constructor.Plugins.Navigation = Navigation; 25503 25504})(window.Zepto || window.jQuery, window, document); 25505 25506/** 25507 * Hash Plugin 25508 * @version 2.0.0-beta.3 25509 * @author Artus Kolanowski 25510 * @license The MIT License (MIT) 25511 */ 25512;(function($, window, document, undefined) { 25513 'use strict'; 25514 25515 /** 25516 * Creates the hash plugin. 25517 * @class The Hash Plugin 25518 * @param {Owl} carousel - The Owl Carousel 25519 */ 25520 var Hash = function(carousel) { 25521 /** 25522 * Reference to the core. 25523 * @protected 25524 * @type {Owl} 25525 */ 25526 this._core = carousel; 25527 25528 /** 25529 * Hash index for the items. 25530 * @protected 25531 * @type {Object} 25532 */ 25533 this._hashes = {}; 25534 25535 /** 25536 * The carousel element. 25537 * @type {jQuery} 25538 */ 25539 this.$element = this._core.$element; 25540 25541 /** 25542 * All event handlers. 25543 * @protected 25544 * @type {Object} 25545 */ 25546 this._handlers = { 25547 /*'initialized.owl.carousel': $.proxy(function(e) { 25548 if (e.namespace && this._core.settings.startPosition === 'URLHash') { 25549 $(window).trigger('hashchange.owl.navigation'); 25550 } 25551 }, this),*/ 25552 'prepared.owl.carousel': $.proxy(function(e) { 25553 if (e.namespace) { 25554 var hash = $(e.content).find('[data-hash]').addBack('[data-hash]').attr('data-hash'); 25555 25556 if (!hash) { 25557 return; 25558 } 25559 25560 this._hashes[hash] = e.content; 25561 } 25562 }, this), 25563 'changed.owl.carousel': $.proxy(function(e) { 25564 if (e.namespace && e.property.name === 'position') { 25565 var current = this._core.items(this._core.relative(this._core.current())), 25566 hash = $.map(this._hashes, function(item, hash) { 25567 return item === current ? hash : null; 25568 }).join(); 25569 25570 if (!hash || window.location.hash.slice(1) === hash) { 25571 return; 25572 } 25573 25574 window.location.hash = hash; 25575 } 25576 }, this) 25577 }; 25578 25579 // set default options 25580 this._core.options = $.extend({}, Hash.Defaults, this._core.options); 25581 25582 // register the event handlers 25583 this.$element.on(this._handlers); 25584 25585 // register event listener for hash navigation 25586 /*$(window).on('hashchange.owl.navigation', $.proxy(function(e) { 25587 var hash = window.location.hash.substring(1), 25588 items = this._core.$stage.children(), 25589 position = this._hashes[hash] && items.index(this._hashes[hash]); 25590 25591 if (position === undefined || position === this._core.current()) { 25592 return; 25593 } 25594 25595 this._core.to(this._core.relative(position), false, true); 25596 }, this));*/ 25597 }; 25598 25599 /** 25600 * Default options. 25601 * @public 25602 */ 25603 Hash.Defaults = { 25604 URLhashListener: false 25605 }; 25606 25607 /** 25608 * Destroys the plugin. 25609 * @public 25610 */ 25611 Hash.prototype.destroy = function() { 25612 var handler, property; 25613 25614 $(window).off('hashchange.owl.navigation'); 25615 25616 for (handler in this._handlers) { 25617 this._core.$element.off(handler, this._handlers[handler]); 25618 } 25619 for (property in Object.getOwnPropertyNames(this)) { 25620 typeof this[property] != 'function' && (this[property] = null); 25621 } 25622 }; 25623 25624 $.fn.owlCarousel.Constructor.Plugins.Hash = Hash; 25625 25626})(window.Zepto || window.jQuery, window, document); 25627 25628/** 25629 * Support Plugin 25630 * 25631 * @version 2.0.0-beta.3 25632 * @author Vivid Planet Software GmbH 25633 * @author Artus Kolanowski 25634 * @license The MIT License (MIT) 25635 */ 25636;(function($, window, document, undefined) { 25637 25638 var style = $('<support>').get(0).style, 25639 prefixes = 'Webkit Moz O ms'.split(' '), 25640 events = { 25641 transition: { 25642 end: { 25643 WebkitTransition: 'webkitTransitionEnd', 25644 MozTransition: 'transitionend', 25645 OTransition: 'oTransitionEnd', 25646 transition: 'transitionend' 25647 } 25648 }, 25649 animation: { 25650 end: { 25651 WebkitAnimation: 'webkitAnimationEnd', 25652 MozAnimation: 'animationend', 25653 OAnimation: 'oAnimationEnd', 25654 animation: 'animationend' 25655 } 25656 } 25657 }, 25658 tests = { 25659 csstransforms: function() { 25660 return !!test('transform'); 25661 }, 25662 csstransforms3d: function() { 25663 return !!test('perspective'); 25664 }, 25665 csstransitions: function() { 25666 return !!test('transition'); 25667 }, 25668 cssanimations: function() { 25669 return !!test('animation'); 25670 } 25671 }; 25672 25673 function test(property, prefixed) { 25674 var result = false, 25675 upper = property.charAt(0).toUpperCase() + property.slice(1); 25676 25677 $.each((property + ' ' + prefixes.join(upper + ' ') + upper).split(' '), function(i, property) { 25678 if (style[property] !== undefined) { 25679 result = prefixed ? property : true; 25680 return false;
25681 } 25682 }); 25683 25684 return result; 25685 } 25686 25687 function prefixed(property) { 25688 return test(property, true); 25689 } 25690 25691 if (tests.csstransitions()) { 25692 /* jshint -W053 */ 25693 $.support.transition = new String(prefixed('transition')) 25694 $.support.transition.end = events.transition.end[ $.support.transition ]; 25695 } 25696 25697 if (tests.cssanimations()) { 25698 /* jshint -W053 */ 25699 $.support.animation = new String(prefixed('animation')) 25700 $.support.animation.end = events.animation.end[ $.support.animation ]; 25701 } 25702 25703 if (tests.csstransforms()) { 25704 /* jshint -W053 */ 25705 $.support.transform = new String(prefixed('transform')); 25706 $.support.transform3d = tests.csstransforms3d(); 25707 } 25708 25709})(window.Zepto || window.jQuery, window, document); 25710 25711(function(window, document, undefined) { 25712 25713 /** 25714 * Find the absolute position of an element 25715 */ 25716 var absPos = function(element) { 25717 var offsetLeft, offsetTop; 25718 offsetLeft = offsetTop = 0; 25719 if (element.offsetParent) { 25720 do { 25721 offsetLeft += element.offsetLeft; 25722 offsetTop += element.offsetTop; 25723 } while (element = element.offsetParent); 25724 } 25725 return [offsetLeft, offsetTop]; 25726 }; 25727 25728 /** 25729 * @constructor Progress Circle class 25730 * @param params.canvas Canvas on which the circles will be drawn. 25731 * @param params.minRadius Inner radius of the innermost circle, in px. 25732 * @param params.arcWidth Width of each circle(to be more accurate, ring). 25733 * @param params.gapWidth Space between each circle. 25734 * @param params.centerX X coordinate of the center of circles. 25735 * @param params.centerY Y coordinate of the center of circles. 25736 * @param params.infoLineBaseAngle Base angle of the info line. 25737 * @param params.infoLineAngleInterval Angles between the info lines. 25738 */ 25739 var ProgressCircle = function(params) { 25740 this.canvas = params.canvas; 25741 this.minRadius = params.minRadius || 15; 25742 this.arcWidth = params.arcWidth || 5; 25743 this.gapWidth = params.gapWidth || 3; 25744 this.centerX = params.centerX || this.canvas.width / 2; 25745 this.centerY = params.centerY || this.canvas.height / 2;
25746 this.infoLineLength = params.infoLineLength || 60; 25747 this.horizLineLength = params.horizLineLength || 10; 25748 this.infoLineAngleInterval = params.infoLineAngleInterval || Math.PI / 8; 25749 this.infoLineBaseAngle = params.infoLineBaseAngle || Math.PI / 6; 25750 25751 this.context = this.canvas.getContext('2d'); 25752 25753 this.width = this.canvas.width; 25754 this.height = this.canvas.height; 25755 25756 this.circles = []; 25757 this.runningCount = 0; 25758 }; 25759 25760 ProgressCircle.prototype = { 25761 constructor: ProgressCircle, 25762 25763 /** 25764 * @method Adds an progress monitor entry. 25765 * @param params.fillColor Color to fill in the circle. 25766 * @param params.outlineColor Color to outline the circle. 25767 * @param params.progressListener Callback function to fetch the progress. 25768 * @param params.infoListener Callback function to fetch the info. 25769 * @returns this 25770 */ 25771 addEntry: function(params) { 25772 this.circles.push(new Circle({ 25773 canvas: this.canvas, 25774 context: this.context, 25775 centerX: this.centerX, 25776 centerY: this.centerY, 25777 innerRadius: this.minRadius + this.circles.length * 25778 (this.gapWidth + this.arcWidth), 25779 arcWidth: this.arcWidth,
25780 infoLineLength: this.infoLineLength, 25781 horizLineLength: this.horizLineLength, 25782 25783 id: this.circles.length, 25784 fillColor: params.fillColor, 25785 outlineColor: params.outlineColor, 25786 progressListener: params.progressListener, 25787 infoListener: params.infoListener, 25788 infoLineAngle: this.infoLineBaseAngle + 25789 this.circles.length * this.infoLineAngleInterval, 25790 })); 25791 25792 return this; 25793 }, 25794 25795 /** 25796 * @method Starts the monitor and updates with the given interval. 25797 * @param interval Interval between updates, in millisecond. 25798 * @returns this 25799 */ 25800 start: function(interval) { 25801 var self = this; 25802 this.timer = setInterval(function() { 25803 self._update(); 25804 }, interval || 33); 25805 25806 return this; 25807 }, 25808 25809 /** 25810 * @method Stop the animation. 25811 */ 25812 stop: function() { 25813 clearTimeout(this.timer); 25814 }, 25815 25816 /** 25817 * @private 25818 * @method Call update on each circle and redraw them. 25819 * @returns this 25820 */ 25821 _update: function() { 25822 this._clear(); 25823 this.circles.forEach(function(circle, idx, array) { 25824 circle.update(); 25825 }); 25826 25827 return this; 25828 }, 25829 25830 /** 25831 * @private 25832 * @method Clear the canvas. 25833 * @returns this 25834 */ 25835 _clear: function() { 25836 this.context.clearRect(0, 0, this.canvas.width, this.canvas.height); 25837 25838 return this; 25839 }, 25840 25841 }; 25842 25843 /** 25844 * @private 25845 * @class Individual progress circle. 25846 * @param params.canvas Canvas on which the circle will be drawn. 25847 * @param params.context Context of the canvas. 25848 * @param params.innerRadius Inner radius of the circle, in px. 25849 * @param params.arcWidth Width of each arc(circle). 25850 * @param params.gapWidth Distance between each arc. 25851 * @param params.centerX X coordinate of the center of circles. 25852 * @param params.centerY Y coordinate of the center of circles. 25853 * @param params.fillColor Color to fill in the circle. 25854 * @param params.outlineColor Color to outline the circle. 25855 * @param params.progressListener Callback function to fetch the progress. 25856 * @param params.infoListener Callback function to fetch the info. 25857 * @param params.infoLineAngle Angle of info line. 25858 */ 25859 var Circle = function(params) { 25860 this.id = params.id; 25861 this.canvas = params.canvas; 25862 this.context = params.context; 25863 this.centerX = params.centerX; 25864 this.centerY = params.centerY; 25865 this.arcWidth = params.arcWidth; 25866 this.innerRadius = params.innerRadius || 0; 25867 this.fillColor = params.fillColor || '#fff'; 25868 this.outlineColor = params.outlineColor || this.fillColor; 25869 this.progressListener = params.progressListener;
25870 this.infoLineLength = params.infoLineLength || 250; 25871 this.horizLineLength = params.horizLineLength || 50; 25872 this.infoListener = params.infoListener; 25873 this.infoLineAngle = params.infoLineAngle; 25874 25875 this.outerRadius = this.innerRadius + this.arcWidth; 25876 25877 // If the info listener is not registered, then don't calculate 25878 // the related coordinates 25879 if (!this.infoListener) return; 25880 25881 // calculate the info-line turning points 25882 var angle = this.infoLineAngle, 25883 arcDistance = (this.innerRadius + this.outerRadius) / 2, 25884 25885 sinA = Math.sin(angle), 25886 cosA = Math.cos(angle); 25887 25888 this.infoLineStartX = this.centerX + sinA * arcDistance; 25889 this.infoLineStartY = this.centerY - cosA * arcDistance; 25890 25891 this.infoLineMidX = this.centerX + sinA * this.infoLineLength; 25892 this.infoLineMidY = this.centerY - cosA * this.infoLineLength; 25893 25894 this.infoLineEndX = this.infoLineMidX + 25895 (sinA < 0 ? -this.horizLineLength : this.horizLineLength); 25896 this.infoLineEndY = this.infoLineMidY; 25897 25898 var infoText = document.createElement('div'), 25899 style = infoText.style; 25900 25901 style.color = this.fillColor; 25902 style.position = 'absolute'; 25903 style.left = this.infoLineEndX + absPos(this.canvas)[0] + 'px'; 25904 // style.top will be calculated in the `drawInfo` method. Since 25905 // user may want to change the size of the font, so the top offset 25906 // must be updated in each loop. 25907 infoText.className = 'ProgressCircleInfo'; // For css styling 25908 infoText.id = 'progress_circle_info_' + this.id; 25909 document.body.appendChild(infoText); 25910 this.infoText = infoText; 25911 }; 25912 25913 Circle.prototype = { 25914 constructor: Circle, 25915 25916 update: function() { 25917 this.progress = this.progressListener(); 25918 this._draw(); 25919 25920 if (this.infoListener) { 25921 this.info = this.infoListener(); 25922 this._drawInfo(); 25923 } 25924 }, 25925 25926 /** 25927 * @private 25928 * @method Draw the circle on the canvas. 25929 * @returns this 25930 */ 25931 _draw: function() { 25932 var ctx = this.context, 25933 25934 ANGLE_OFFSET = -Math.PI / 2, 25935 25936 startAngle = 0 + ANGLE_OFFSET, 25937 endAngle= startAngle + this.progress * Math.PI * 2, 25938 25939 x = this.centerX, 25940 y = this.centerY, 25941 25942 innerRadius = this.innerRadius - this.arcWidth - 1, 25943 outerRadius = this.outerRadius - this.arcWidth - 1; 25944 25945 if ( innerRadius < 0 ) 25946 return; 25947 25948 ctx.fillStyle = this.fillColor; 25949 ctx.strokeStyle = this.outlineColor; 25950 25951 ctx.beginPath(); 25952 ctx.arc(x, y, innerRadius, startAngle, endAngle, false); 25953 ctx.arc(x, y, outerRadius, endAngle, startAngle, true); 25954 ctx.closePath(); 25955 ctx.stroke(); 25956 ctx.fill(); 25957 25958 return this; 25959 }, 25960 25961 /** 25962 * @private 25963 * @method Draw the info lines and info text. 25964 * @returns this 25965 */ 25966 _drawInfo: function() { 25967 25968 var pointList, lineHeight; 25969 25970 pointList = [ 25971 [this.infoLineStartX, this.infoLineStartY], 25972 [this.infoLineMidX, this.infoLineMidY], 25973 [this.infoLineEndX, this.infoLineEndY], 25974 ]; 25975 this._drawSegments(pointList, false); 25976 25977 this.infoText.innerHTML = this.info; 25978 25979 lineHeight = this.infoText.offsetHeight; 25980 this.infoText.style.top = this.infoLineEndY + 25981 absPos(this.canvas)[1] - lineHeight / 2 + 'px'; 25982 25983 return this; 25984 }, 25985 25986 /** 25987 * @private 25988 * @method Helper function to draw the segments 25989 * @param pointList An array of points in the form of [x, y]. 25990 * @param close Whether to connect the first and last point. 25991 */ 25992 _drawSegments: function(pointList, close) { 25993 var ctx = this.context; 25994 25995 ctx.beginPath(); 25996 ctx.moveTo(pointList[0][0], pointList[0][1]); 25997 for (var i = 1; i < pointList.length; ++i) { 25998 ctx.lineTo(pointList[i][0], pointList[i][1]); 25999 } 26000 26001 if (close) { 26002 ctx.closePath(); 26003 } 26004 ctx.stroke(); 26005 }, 26006 }; 26007 26008 window.ProgressCircle = ProgressCircle; 26009 26010})(window, document); 26011 26012 26013 26014 26015/* ========================================================= 26016 * jquery.vc_chart.js v1.0 26017 * ========================================================= 26018 * Copyright 2013 Wpbakery 26019 * 26020 * Jquery chart plugin for the Visual Composer. 26021 * ========================================================= */ 26022(function($){ 26023 /** 26024 * Pie chart animated. 26025 * @param element - DOM element 26026 * @param options - settings object. 26027 * @constructor 26028 */ 26029 var VcChart = function(element, options) { 26030 this.el = element; 26031 this.$el = $(this.el); 26032 var $this = this; 26033 $this.options = $.extend({ 26034 color: 'wpb_button', 26035 units: '', 26036 width: '', 26037 label_selector: '.vc_pie_chart_value', 26038 back_selector: '.vc_pie_chart_back', 26039 responsive: true 26040 }, options); 26041 $this.init(); 26042 }; 26043 VcChart.prototype = { 26044 constructor: VcChart, 26045 _progress_v: 0, 26046 animated: false, 26047 colors: { 26048 'wpb_button': 'rgba(247, 247, 247, 1)', 26049 'btn-primary': 'rgba(0, 136, 204, 1)', 26050 'btn-info': 'rgba(88, 185, 218, 1)', 26051 'btn-success': 'rgba(106, 177, 101, 1)', 26052 'btn-warning': 'rgba(255, 153, 0, 1)', 26053 'btn-danger': 'rgba(255, 103, 91, 1)', 26054 'btn-inverse': 'rgba(85, 85, 85, 1)' 26055 }, 26056 init: function() { 26057 this.setupColor(); 26058 this.value = this.$el.data('pie-value')/100; 26059 this.label_value = this.$el.data('pie-label-value') || this.$el.data('pie-value'); 26060 this.$wrapper = $('.vc_pie_wrapper', this.$el); 26061 this.$label = $(this.options.label_selector, this.$el); 26062 this.$back = $(this.options.back_selector, this.$el); 26063 this.$canvas = this.$el.find('canvas'); 26064 this.arcWidth = this.$el.data('pie-width') * 2; 26065 this.draw(); 26066 this.setWayPoint(); 26067 if(this.options.responsive === true) this.setResponsive(); 26068 if (UNCODE.isMobile) this._progress_v = this.value; 26069 }, 26070 setupColor: function() { 26071 // if(typeof this.colors[this.options.color] !== 'undefined') { 26072 // this.color = this.colors[this.options.color]; 26073 // } else if(typeof this.options.color === 'string' && this.options.color.match(/^rgba?\([^\)]+\)/)) { 26074 // this.color = this.options.color; 26075 // } else { 26076 // this.color = 'rgba(247, 247, 247, 0.2)'; 26077 // } 26078 if(typeof this.options.color !== 'undefined') { 26079 this.color = this.options.color; 26080 } else this.color = 'rgba(247, 247, 247, 0.2)'; 26081 26082 }, 26083 setResponsive: function() { 26084 var that = this; 26085 if (!UNCODE.isMobile) { 26086 $(window).resize(function(){ 26087 if(that.animated === true) that.circle.stop(); 26088 that.draw(true); 26089 }); 26090 } 26091 }, 26092 draw: function(redraw) { 26093 var w = this.$el.addClass('vc_ready').width() * 2, 26094 border_w = this.arcWidth, 26095 radius; 26096 if(!w) w = this.$el.parents(':visible').first().width()-2; 26097 //w = Math.round(w/100*80); 26098 //if (w < 250) w = 250; 26099 radius = w/2; 26100 this.$wrapper.css({"width" : (w / 2) + "px"}); 26101 this.$label.css({"width" : (w / 2), "height" : (w / 2), "line-height" : (w / 2)+"px"}); 26102 this.$back.css({"width" : (w / 2), "height" : (w / 2)}); 26103 this.$canvas.attr({"width" : w + "px", "height" : w + "px"}); 26104 this.$el.addClass('vc_ready'); 26105 this.circle = new ProgressCircle({ 26106 canvas: this.$canvas.get(0), 26107 minRadius: radius, 26108 arcWidth: border_w 26109 }); 26110 if(redraw === true && this.animated === true) { 26111 this._progress_v = this.value; 26112 this.circle.addEntry({ 26113 fillColor: this.color, 26114 progressListener: $.proxy(this.setProgress, this) 26115 }).start(); 26116 } 26117 }, 26118 setProgress: function() { 26119 if (this._progress_v >= this.value) { 26120 this.circle.stop(); 26121 this.animated = true; 26122 this.$label.html(this.label_value + this.options.units); 26123 return this._progress_v; 26124 } 26125 this._progress_v += 0.01; 26126 if (!isNaN(this.label_value)) { 26127 var label_value = this._progress_v/this.value*this.label_value; 26128 var val = Math.round(label_value) + this.options.units; 26129 this.$label.html(val); 26130 } else this.$label.html(this.label_value + this.options.units); 26131 return this._progress_v; 26132 }, 26133 animate: function() { 26134 if(this.animated !== true) { 26135 this.circle.addEntry({ 26136 fillColor: this.color, 26137 progressListener: $.proxy(this.setProgress, this) 26138 }).start(10); 26139 } 26140 }, 26141 setWayPoint: function() { 26142 if (typeof $.fn.waypoint !== 'undefined' && !UNCODE.isMobile) { 26143 this.$el.waypoint($.proxy(this.animate, this), { offset: '85%' }); 26144 } else { 26145 this.animate(); 26146 } 26147 } 26148 }; 26149 /** 26150 * jQuery plugin 26151 * @param option - object with settings 26152 * @return {*} 26153 */ 26154 $.fn.vcChat = function(option, value) { 26155 return this.each(function () { 26156 var $this = $(this), 26157 data = $this.data('vc_chart'), 26158 options = typeof option === 'object' ? option : { 26159 color: $this.data('pie-color'), 26160 units: $this.data('pie-units') 26161 }; 26162 if (typeof option == 'undefined') $this.data('vc_chart', (data = new VcChart(this, options))); 26163 if (typeof option == 'string') data[option](value); 26164 }); 26165 }; 26166 /** 26167 * Allows users to rewrite function inside theme. 26168 */ 26169 if ( typeof window['vc_pieChart'] !== 'function' ) { 26170 window.vc_pieChart = function() { 26171 $('.vc_pie_chart:visible:not(.vc_ready)').vcChat(); 26172 } 26173 } 26174 $(document).ready(function(){ 26175 !window.vc_iframe && vc_pieChart(); 26176 26177 /** 26178 * Tab and collapse integration. 26179 */ 26180 $('.nav-tabs a').on('shown.bs.tab', function(e){ 26181 var $cont = $(e.target).closest('.tab-container'), 26182 $active = $('.tab-pane.active', $cont); 26183 $('.vc_pie_chart:not(.vc_ready)', $active).vcChat(); 26184 }); 26185 26186 $('.panel-collapse').on('shown.bs.collapse', function (e) { 26187 $('.vc_pie_chart:not(.vc_ready)', e.target).vcChat(); 26188 }) 26189 }); 26190 26191})(window.jQuery); 26192 26193/* Progress bar 26194 ---------------------------------------------------------- */ 26195function uncode_progress_bar() { 26196 jQuery.each(jQuery('.vc_progress_bar'), function(index, val) { 26197 if (UNCODE.isUnmodalOpen && !val.closest('#unmodal-content')) { 26198 return; 26199 } 26200 if (!UNCODE.isMobile) { 26201 new Waypoint({ 26202 context: UNCODE.isUnmodalOpen ? document.getElementById('unmodal-content') : window, 26203 element: val, 26204 handler: function() { 26205 var element = jQuery(this.element); 26206 element.find('.vc_single_bar').each(function(index) { 26207 var $this = jQuery(this), 26208 bar = $this.find('.vc_bar'), 26209 val = bar.data('percentage-value'); 26210 setTimeout(function() { 26211 bar.css({ 26212 "width": val + '%' 26213 }); 26214 }, index * 200); 26215 }); 26216 }, 26217 offset: '80%' 26218 }); 26219 } else { 26220 var element = jQuery(val); 26221 element.find('.vc_single_bar').each(function(index) { 26222 var $this = jQuery(this), 26223 bar = $this.find('.vc_bar'), 26224 val = bar.data('percentage-value'); 26225 setTimeout(function() { 26226 bar.css({ 26227 "width": val + '%' 26228 }); 26229 }, index * 200); 26230 }); 26231 } 26232 }); 26233}; 26234uncode_progress_bar(); 26235 26236/*! 26237 * jquery.counterup.js 1.0 26238 * 26239 * Copyright 2013, Benjamin Intal http://gambit.ph @bfintal 26240 * Released under the GPL v2 License 26241 * 26242 * Date: Nov 26, 2013 26243 */ 26244(function($) { 26245 "use strict"; 26246 $.fn.counterUp = function(options) { 26247 // Defaults 26248 var settings = $.extend({ 26249 'time': 400, 26250 'delay': 10 26251 }, options); 26252 return this.each(function() { 26253 // Store the object 26254 var $this = $(this); 26255 var $settings = settings; 26256 var counterUpper = function() { 26257 var nums = []; 26258 var divisions = $settings.time / $settings.delay; 26259 var numReal = $this.attr('data-val'), 26260 num = numReal; 26261 var isComma = /[0-9]+,[0-9]+/.test(num); 26262 num = num.replace(/,/g, ''); 26263 var isInt = /^[0-9]+$/.test(num); 26264 var isFloat = /^[0-9]+\.[0-9]+$/.test(num); 26265 var decimalPlaces = isFloat ? (num.split('.')[1] || []).length : 0; 26266 // Generate list of incremental numbers to display 26267 for (var i = divisions; i >= 1; i--) { 26268 // Preserve as int if input was int 26269 var newNum = parseInt(num / divisions * i); 26270 // Preserve float if input was float 26271 if (isFloat) { 26272 newNum = parseFloat(num / divisions * i).toFixed(decimalPlaces); 26273 } 26274 // Preserve commas if input had commas 26275 if (isComma) { 26276 while (/(\d+)(\d{3})/.test(newNum.toString())) { 26277 newNum = newNum.toString().replace(/(\d+)(\d{3})/, '$1' + ',' + '$2'); 26278 } 26279 } 26280 nums.unshift(newNum); 26281 } 26282 nums.push(numReal); 26283 $this.data('counterup-nums', nums); 26284 $this.text('0'); 26285 // Updates the number until we're done 26286 var f = function() { 26287 if ($this.data('counterup-nums') != null) { 26288 $this.text($this.data('counterup-nums').shift()); 26289 if ($this.data('counterup-nums').length) { 26290 setTimeout($this.data('counterup-func'), $settings.delay); 26291 } else { 26292 delete $this.data('counterup-nums'); 26293 $this.data('counterup-nums', null); 26294 $this.data('counterup-func', null); 26295 } 26296 } 26297 }; 26298 $this.data('counterup-func', f); 26299 // Start the count up 26300 setTimeout($this.data('counterup-func'), $settings.delay); 26301 }; 26302 // Perform counts when the element gets into view 26303 new Waypoint({ 26304 context: UNCODE.isUnmodalOpen ? document.getElementById('unmodal-content') : window, 26305 element: this, 26306 handler: function() { 26307 counterUpper(); 26308 if (!UNCODE.isUnmodalOpen) { 26309 this.destroy(); 26310 } 26311 }, 26312 offset: '100%' 26313 }); 26314 }); 26315 }; 26316})(jQuery); 26317 26318/*! 26319 * The Final Countdown for jQuery v2.2.0 (http://hilios.github.io/jQuery.countdown/) 26320 * Copyright (c) 2016 Edson Hilios 26321 * 26322 * Permission is hereby granted, free of charge, to any person obtaining a copy of 26323 * this software and associated documentation files (the "Software"), to deal in 26324 * the Software without restriction, including without limitation the rights to 26325 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 26326 * the Software, and to permit persons to whom the Software is furnished to do so, 26327 * subject to the following conditions: 26328 * 26329 * The above copyright notice and this permission notice shall be included in all 26330 * copies or substantial portions of the Software. 26331 * 26332 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26333 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 26334 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 26335 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 26336 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 26337 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26338 */ 26339(function(factory) { 26340 "use strict"; 26341 if (typeof define === "function" && define.amd) { 26342 define([ "jquery" ], factory); 26343 } else { 26344 factory(jQuery); 26345 } 26346})(function($) { 26347 "use strict"; 26348 var instances = [], matchers = [], defaultOptions = { 26349 precision: 100, 26350 elapse: false, 26351 defer: false 26352 }; 26353 matchers.push(/^[0-9]*$/.source); 26354 matchers.push(/([0-9]{1,2}\/){2}[0-9]{4}( [0-9]{1,2}(:[0-9]{2}){2})?/.source); 26355 matchers.push(/[0-9]{4}([\/\-][0-9]{1,2}){2}( [0-9]{1,2}(:[0-9]{2}){2})?/.source); 26356 matchers = new RegExp(matchers.join("|")); 26357 function parseDateString(dateString) { 26358 if (dateString instanceof Date) { 26359 return dateString; 26360 } 26361 if (String(dateString).match(matchers)) { 26362 if (String(dateString).match(/^[0-9]*$/)) { 26363 dateString = Number(dateString); 26364 } 26365 if (String(dateString).match(/\-/)) { 26366 dateString = String(dateString).replace(/\-/g, "/"); 26367 } 26368 return new Date(dateString); 26369 } else { 26370 throw new Error("Couldn't cast `" + dateString + "` to a date object."); 26371 } 26372 } 26373 var DIRECTIVE_KEY_MAP = { 26374 Y: "years", 26375 m: "months", 26376 n: "daysToMonth", 26377 d: "daysToWeek", 26378 w: "weeks", 26379 W: "weeksToMonth", 26380 H: "hours", 26381 M: "minutes", 26382 S: "seconds", 26383 D: "totalDays", 26384 I: "totalHours", 26385 N: "totalMinutes", 26386 T: "totalSeconds" 26387 }; 26388 function escapedRegExp(str) { 26389 var sanitize = str.toString().replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1"); 26390 return new RegExp(sanitize); 26391 } 26392 function strftime(offsetObject) { 26393 return function(format) { 26394 var directives = format.match(/%(-|!)?[A-Z]{1}(:[^;]+;)?/gi); 26395 if (directives) { 26396 for (var i = 0, len = directives.length; i < len; ++i) { 26397 var directive = directives[i].match(/%(-|!)?([a-zA-Z]{1})(:[^;]+;)?/), regexp = escapedRegExp(directive[0]), modifier = directive[1] || "", plural = directive[3] || "", value = null; 26398 directive = directive[2]; 26399 if (DIRECTIVE_KEY_MAP.hasOwnProperty(directive)) { 26400 value = DIRECTIVE_KEY_MAP[directive]; 26401 value = Number(offsetObject[value]); 26402 } 26403 if (value !== null) { 26404 if (modifier === "!") { 26405 value = pluralize(plural, value); 26406 } 26407 if (modifier === "") { 26408 if (value < 10) { 26409 value = "0" + value.toString(); 26410 } 26411 } 26412 format = format.replace(regexp, value.toString()); 26413 } 26414 } 26415 } 26416 format = format.replace(/%%/, "%"); 26417 return format; 26418 }; 26419 } 26420 function pluralize(format, count) { 26421 var plural = "s", singular = ""; 26422 if (format) { 26423 format = format.rep
vendor: 8,618 bytes, lines 26423-26567
26423lace(/(:|;|\s)/gi, "").split(/\,/); 26424 if (format.length === 1) { 26425 plural = format[0]; 26426 } else { 26427 singular = format[0]; 26428 plural = format[1]; 26429 } 26430 } 26431 if (Math.abs(count) > 1) { 26432 return plural; 26433 } else { 26434 return singular; 26435 } 26436 } 26437 var Countdown = function(el, finalDate, options) { 26438 this.el = el; 26439 this.$el = $(el); 26440 this.interval = null; 26441 this.offset = {}; 26442 this.options = $.extend({}, defaultOptions); 26443 this.instanceNumber = instances.length; 26444 instances.push(this); 26445 this.$el.data("countdown-instance", this.instanceNumber); 26446 if (options) { 26447 if (typeof options === "function") { 26448 this.$el.on("update.countdown", options); 26449 this.$el.on("stoped.countdown", options); 26450 this.$el.on("finish.countdown", options); 26451 } else { 26452 this.options = $.extend({}, defaultOptions, options); 26453 } 26454 } 26455 this.setFinalDate(finalDate); 26456 if (this.options.defer === false) { 26457 this.start(); 26458 } 26459 }; 26460 $.extend(Countdown.prototype, { 26461 start: function() { 26462 if (this.interval !== null) { 26463 clearInterval(this.interval); 26464 } 26465 var self = this; 26466 this.update(); 26467 this.interval = setInterval(function() { 26468 self.update.call(self); 26469 }, this.options.precision); 26470 }, 26471 stop: function() { 26472 clearInterval(this.interval); 26473 this.interval = null; 26474 this.dispatchEvent("stoped"); 26475 }, 26476 toggle: function() { 26477 if (this.interval) { 26478 this.stop(); 26479 } else { 26480 this.start(); 26481 } 26482 }, 26483 pause: function() { 26484 this.stop(); 26485 }, 26486 resume: function() { 26487 this.start(); 26488 }, 26489 remove: function() { 26490 this.stop.call(this); 26491 instances[this.instanceNumber] = null; 26492 delete this.$el.data().countdownInstance; 26493 }, 26494 setFinalDate: function(value) { 26495 this.finalDate = parseDateString(value); 26496 }, 26497 update: function() { 26498 if (this.$el.closest("html").length === 0) { 26499 this.remove(); 26500 return; 26501 } 26502 var hasEventsAttached = $._data(this.el, "events") !== undefined, now = new Date(), newTotalSecsLeft; 26503 newTotalSecsLeft = this.finalDate.getTime() - now.getTime(); 26504 newTotalSecsLeft = Math.ceil(newTotalSecsLeft / 1e3); 26505 newTotalSecsLeft = !this.options.elapse && newTotalSecsLeft < 0 ? 0 : Math.abs(newTotalSecsLeft); 26506 if (this.totalSecsLeft === newTotalSecsLeft || !hasEventsAttached) { 26507 return; 26508 } else { 26509 this.totalSecsLeft = newTotalSecsLeft; 26510 } 26511 this.elapsed = now >= this.finalDate; 26512 this.offset = { 26513 seconds: this.totalSecsLeft % 60, 26514 minutes: Math.floor(this.totalSecsLeft / 60) % 60, 26515 hours: Math.floor(this.totalSecsLeft / 60 / 60) % 24, 26516 days: Math.floor(this.totalSecsLeft / 60 / 60 / 24) % 7, 26517 daysToWeek: Math.floor(this.totalSecsLeft / 60 / 60 / 24) % 7, 26518 daysToMonth: Math.floor(this.totalSecsLeft / 60 / 60 / 24 % 30.4368), 26519 weeks: Math.floor(this.totalSecsLeft / 60 / 60 / 24 / 7), 26520 weeksToMonth: Math.floor(this.totalSecsLeft / 60 / 60 / 24 / 7) % 4, 26521 months: Math.floor(this.totalSecsLeft / 60 / 60 / 24 / 30.4368), 26522 years: Math.abs(this.finalDate.getFullYear() - now.getFullYear()), 26523 totalDays: Math.floor(this.totalSecsLeft / 60 / 60 / 24), 26524 totalHours: Math.floor(this.totalSecsLeft / 60 / 60), 26525 totalMinutes: Math.floor(this.totalSecsLeft / 60), 26526 totalSeconds: this.totalSecsLeft 26527 }; 26528 if (!this.options.elapse && this.totalSecsLeft === 0) { 26529 this.stop(); 26530 this.dispatchEvent("finish"); 26531 } else { 26532 this.dispatchEvent("update"); 26533 } 26534 }, 26535 dispatchEvent: function(eventName) { 26536 var event = $.Event(eventName + ".countdown"); 26537 event.finalDate = this.finalDate; 26538 event.elapsed = this.elapsed; 26539 event.offset = $.extend({}, this.offset); 26540 event.strftime = strftime(this.offset); 26541 this.$el.trigger(event); 26542 } 26543 }); 26544 $.fn.countdown = function() { 26545 var argumentsArray = Array.prototype.slice.call(arguments, 0); 26546 return this.each(function() { 26547 var instanceNumber = $(this).data("countdown-instance"); 26548 if (instanceNumber !== undefined) { 26549 var instance = instances[instanceNumber], method = argumentsArray[0]; 26550 if (Countdown.prototype.hasOwnProperty(method)) { 26551 instance[method].apply(instance, argumentsArray.slice(1)); 26552 } else if (String(method).match(/^[$A-Z_][0-9A-Z_$]*$/i) === null) { 26553 instance.setFinalDate.call(instance, method); 26554 instance.start(); 26555 } else { 26556 $.error("Method %s does not exist on jQuery.countdown".replace(/\%s/gi, method)); 26557 } 26558 } else { 26559 new Countdown(this, argumentsArray[0], argumentsArray[1]); 26560 } 26561 }); 26562 }; 26563}); 26564 26565!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; 26566function getStyles(config){ 26567 // 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;
26567left: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+"}" 26568}; 26569 var ShareUtils; 26570 26571if ((!("classList" in document.documentElement)) && Object.defineProperty && typeof HTMLElement !== "undefined") { 26572 Object.defineProperty(HTMLElement.prototype, "classList", { 26573 get: function() { 26574 var ret, self, update; 26575 update = function(fn) { 26576 return function(value) { 26577 var classes, index; 26578 classes = self.className.split(/\s+/); 26579 index = classes.indexOf(value); 26580 fn(classes, index, value); 26581 self.className = classes.join(" "); 26582 }; 26583 }; 26584 self = this; 26585 ret = { 26586 add: update(function(classes, index, value) { 26587 ~index || classes.push(value); 26588 }), 26589 remove: update(function(classes, index) { 26590 ~index && classes.splice(index, 1); 26591 }), 26592 toggle: update(function(classes, index, value) { 26593 if (~index) { 26594 classes.splice(index, 1); 26595 } else { 26596 classes.push(value); 26597 } 26598 }), 26599 contains: function(value) { 26600 return !!~self.className.split(/\s+/).indexOf(value); 26601 }, 26602 item: function(i) { 26603 return self.className.split(/\s+/)[i] || null; 26604 } 26605 }; 26606 Object.defineProperty(ret, "length", { 26607 get: function() { 26608 return self.className.split(/\s+/).length; 26609 } 26610 }); 26611 return ret; 26612 } 26613 }); 26614} 26615 26616String.prototype.to_rfc3986 = function() { 26617 var tmp; 26618 tmp = encodeURIComponent(this); 26619 return tmp.replace(/[!'()*]/g, function(c) { 26620 return "%" + c.charCodeAt(0).toString(16); 26621 }); 26622}; 26623 26624ShareUtils = (function() { 26625 function ShareUtils() {} 26626 26627 ShareUtils.prototype.extend = function(to, from, overwrite) { 26628 var hasProp, prop; 26629 for (prop in from) { 26630 hasProp = to[prop] !== undefined; 26631 if (hasProp && typeof from[prop] === "object") { 26632 this.extend(to[prop], from[prop], overwrite); 26633 } else { 26634 if (overwrite || !hasProp) { 26635 to[prop] = from[prop]; 26636 } 26637 } 26638 } 26639 }; 26640 26641 ShareUtils.prototype.hide = function(el) { 26642 return el.style.display = "none"; 26643 }; 26644 26645 ShareUtils.prototype.show = function(el) { 26646 return el.style.display = "block"; 26647 }; 26648 26649 ShareUtils.prototype.has_class = function(el, class_name) { 26650 return el.classList.contains(class_name); 26651 }; 26652 26653 ShareUtils.prototype.add_class = function(el, class_name) { 26654 return el.classList.add(class_name); 26655 }; 26656 26657 ShareUtils.prototype.remove_class = function(el, class_name) { 26658 return el.classList.remove(class_name); 26659 }; 26660 26661 ShareUtils.prototype.is_encoded = function(str) { 26662 str = str.to_rfc3986(); 26663 return decodeURIComponent(str) !== str; 26664 }; 26665 26666 ShareUtils.prototype.encode = function(str) { 26667 if (typeof str === "undefined" || this.is_encoded(str)) { 26668 return str; 26669 } else { 26670 return str.to_rfc3986(); 26671 } 26672 }; 26673 26674 ShareUtils.prototype.popup = function(url, params) { 26675 var k, popup, qs, v; 26676 if (params == null) { 26677 params = {}; 26678 } 26679 popup = { 26680 width: 500, 26681 height: 350 26682 }; 26683 popup.top = (screen.height / 2) - (popup.height / 2); 26684 popup.left = (screen.width / 2) - (popup.width / 2); 26685 qs = ((function() { 26686 var _results; 26687 _results = []; 26688 for (k in params) { 26689 v = params[k]; 26690 _results.push("" + k + "=" + (this.encode(v))); 26691 } 26692 return _results; 26693 }).call(this)).join('&'); 26694 if (qs) { 26695 qs = "?" + qs; 26696 } 26697 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="
26697+ popup.width + ",height=" + popup.height); 26698 }; 26699 26700 return ShareUtils; 26701 26702})(); 26703var Share, 26704 __hasProp = {}.hasOwnProperty, 26705 __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; }; 26706 26707Share = (function(_super) { 26708 __extends(Share, _super); 26709 26710 function Share(element, options) { 26711 this.element = element; 26712 this.el = { 26713 head: document.getElementsByTagName('head')[0], 26714 body: document.getElementsByTagName('body')[0] 26715 }; 26716 this.config = { 26717 enabled_networks: 0, 26718 protocol: ['http', 'https'].indexOf(window.location.href.split(':')[0]) === -1 ? 'https://' : '//', 26719 url: window.location.href.replace("&", "%26"), 26720 caption: null, 26721 title: this.default_title(), 26722 image: this.default_image(), 26723 description: this.default_description(), 26724 ui: { 26725 flyout: 'top center', 26726 button_text: 'Share', 26727 button_font: true, 26728 icon_font: true 26729 }, 26730 networks: { 26731 twitter: { 26732 enabled: true, 26733 url: null, 26734 title: null, 26735 description: null 26736 }, 26737 facebook: { 26738 enabled: true, 26739 load_sdk: true, 26740 url: null, 26741 app_id: null, 26742 title: null, 26743 caption: null, 26744 description: null, 26745 image: null 26746 }, 26747 pinterest: { 26748 enabled: true, 26749 url: null, 26750 image: null, 26751 description: null 26752 }, 26753 reddit: { 26754 enabled: true, 26755 url: null, 26756 title: null 26757 }, 26758 linkedin: { 26759 enabled: true, 26760 url: null, 26761 title: null, 26762 description: null 26763 }, 26764 xing: { 26765 enabled: true, 26766 url: null, 26767 title: null, 26768 image: null, 26769 description: null 26770 }, 26771 whatsapp: { 26772 enabled: true, 26773 title: null, 26774 url: null 26775 }, 26776 email: { 26777 enabled: true, 26778 title: null, 26779 description: null, 26780 url: null 26781 } 26782 } 26783 }; 26784 this.setup(element, options); 26785 return this; 26786 } 26787 26788 Share.prototype.setup = function(element, opts) { 26789 var index, instance, instances, _i, _len; 26790 instances = document.querySelectorAll(element); 26791 this.extend(this.config, opts, true); 26792 this.set_global_configuration(); 26793 this.normalize_network_configuration(); 26794 if (this.config.ui.icon_font) { 26795 this.inject_icons(); 26796 } 26797 if (this.config.ui.button_font) { 26798 this.inject_fonts(); 26799 } 26800 if (this.config.networks.facebook.enabled && this.config.networks.facebook.load_sdk) { 26801 this.inject_facebook_sdk(); 26802 } 26803 for (index = _i = 0, _len = instances.length; _i < _len; index = ++_i) { 26804 instance = instances[index]; 26805 this.setup_instance(element, index); 26806 } 26807 }; 26808 26809 Share.prototype.setup_instance = function(element, index) { 26810 var button, instance, label, network, networks, _i, _len, _results, 26811 _this = this; 26812 instance = document.querySelectorAll(element)[index]; 26813 this.hide(instance); 26814 this.add_class(instance, "sharer-" + index); 26815 instance = document.querySelectorAll(element)[index]; 26816 this.inject_css(instance); 26817 this.inject_html(instance); 26818 this.show(instance); 26819 label = instance.getElementsByTagName("label")[0]; 26820 button = instance.getElementsByClassName("social")[0]; 26821 networks = instance.getElementsByTagName('li'); 26822 this.add_class(button, "networks-" + this.config.enabled_networks); 26823 label.addEventListener("click", function() { 26824 return _this.event_toggle(button); 26825 }); 26826 _this = this; 26827 _results = []; 26828 for (index = _i = 0, _len = networks.length; _i < _len; index = ++_i) { 26829 network = networks[index]; 26830 _results.push(network.addEventListener("click", function() { 26831 _this.event_network(instance, this); 26832 return _this.event_close(button); 26833 })); 26834 } 26835 return _results; 26836 }; 26837 26838 Share.prototype.event_toggle = function(button) { 26839 if (this.has_class(button, "active")) { 26840 return this.event_close(button); 26841 } else { 26842 return this.event_open(button); 26843 } 26844 }; 26845 26846 Share.prototype.event_open = function(button) { 26847 if (this.has_class(button, "load")) { 26848 this.remove_class(button, "load"); 26849 } 26850 return this.add_class(button, "active"); 26851 }; 26852 26853 Share.prototype.event_close = function(button) { 26854 return this.remove_class(button, "active"); 26855 }; 26856 26857 Share.prototype.event_network = function(instance, network) { 26858 var name; 26859 name = network.getAttribute("data-network"); 26860 this.hook("before", name, instance);
26861 this["network_" + name](); 26862 return this.hook("after", name, instance); 26863 }; 26864 26865 Share.prototype.open = function() { 26866 return this["public"]("open"); 26867 }; 26868 26869 Share.prototype.close = function() { 26870 return this["public"]("close"); 26871 }; 26872 26873 Share.prototype.toggle = function() { 26874 return this["public"]("toggle"); 26875 }; 26876 26877 Share.prototype["public"] = function(action) { 26878 var button, index, instance, _i, _len, _ref, _results; 26879 _ref = document.querySelectorAll(this.element); 26880 _results = []; 26881 for (index = _i = 0, _len = _ref.length; _i < _len; index = ++_i) { 26882 instance = _ref[index]; 26883 button = instance.getElementsByClassName("social")[0]; 26884 _results.push(this["event_" + action](button)); 26885 } 26886 return _results; 26887 }; 26888 26889 Share.prototype.network_facebook = function() { 26890 if (this.config.networks.facebook.load_sdk) { 26891 if (!window.FB) { 26892 return console.error("The Facebook JS SDK hasn't loaded yet."); 26893 } 26894 return FB.ui({ 26895 method: 'feed', 26896 name: this.config.networks.facebook.title, 26897 link: this.config.networks.facebook.url, 26898 picture: this.config.networks.facebook.image, 26899 caption: this.config.networks.facebook.caption, 26900 description: this.config.networks.facebook.description 26901 }); 26902 } else { 26903 return this.popup('https://www.facebook.com/sharer/sharer.php', { 26904 u: this.config.networks.facebook.url 26905 }); 26906 } 26907 }; 26908 26909 Share.prototype.network_twitter = function() { 26910 return this.popup('https://twitter.com/intent/tweet', { 26911 text: this.config.networks.twitter.title, 26912 url: this.config.networks.twitter.url 26913 }); 26914 }; 26915 26916 Share.prototype.network_pinterest = function() { 26917 return this.popup('https://www.pinterest.com/pin/create/button', { 26918 url: this.config.networks.pinterest.url, 26919 media: this.config.networks.pinterest.image, 26920 description: this.config.networks.pinterest.description 26921 }); 26922 }; 26923 26924 Share.prototype.network_linkedin = function() { 26925 return this.popup('https://www.linkedin.com/shareArticle', { 26926 url: this.config.networks.linkedin.url, 26927 title: this.config.networks.linkedin.title, 26928 summary: this.config.networks.linkedin.description 26929 }); 26930 } 26931 26932 Share.prototype.network_xing = function() { 26933 return this.popup('https://www.xing.com/spi/shares/new', { 26934 url: this.config.networks.xing.url, 26935 image: this.config.networks.xing.image, 26936 title: this.config.networks.xing.title, 26937 summary: this.config.networks.xing.description 26938 }); 26939 } 26940 26941 Share.prototype.network_whatsapp = function() { 26942 return this.popup('https://api.whatsapp.com/send', { 26943 text: this.config.networks.whatsapp.title + '%20' + this.config.networks.whatsapp.url, 26944 }); 26945 } 26946 26947 Share.prototype.network_email = function() { 26948 return this.popup('mailto:', { 26949 subject: this.config.networks.email.title, 26950 body: this.config.networks.email.url + '%0A%0A' + this.config.networks.email.description, 26951 }); 26952 }; 26953 26954 Share.prototype.inject_icons = function() { 26955 // return this.inject_stylesheet("https://www.sharebutton.co/fonts/v2/entypo.min.css"); 26956 }; 26957 26958 Share.prototype.inject_fonts = function() { 26959 // return this.inject_stylesheet("http://fonts.googleapis.com/css?family=Lato:900&text=" + this.config.ui.button_text); 26960 }; 26961 26962 Share.prototype.inject_stylesheet = function(url) { 26963 var link; 26964 if (!this.el.head.querySelector("link[href=\"" + url + "\"]")) { 26965 link = document.createElement("link"); 26966 link.setAttribute("rel", "stylesheet"); 26967 link.setAttribute("href", url); 26968 return this.el.head.appendChild(link); 26969 } 26970 }; 26971 26972 Share.prototype.inject_css = function(instance) { 26973 var css, meta, selector, style; 26974 selector = "." + (instance.getAttribute('class').split(" ").join(".")); 26975 if (!this.el.head.querySelector("meta[name='sharer" + selector + "']")) { 26976 this.config.selector = selector; 26977 css = getStyles(this.config); 26978 style = document.createElement("style"); 26979 style.type = "text/css"; 26980 if (style.styleSheet) { 26981 style.styleSheet.cssText = css; 26982 } else { 26983 style.appendChild(document.createTextNode(css)); 26984 } 26985 this.el.head.appendChild(style); 26986 delete this.config.selector; 26987 meta = document.createElement("meta"); 26988 meta.setAttribute("name", "sharer" + selector); 26989 return this.el.head.appendChild(meta); 26990 } 26991 }; 26992 26993 Share.prototype.inject_html = function(instance) { 26994 //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>"; 26995 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-whatsapp' data-network='whatsapp' 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>"; 26996 }; 26997 26998 Share.prototype.inject_facebook_sdk = function() { 26999 var fb_root, script; 27000 if (!window.FB && this.config.networks.facebook.app_id && !this.el.body.querySelector('#fb-root')) { 27001 script = document.createElement("script"); 27002 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')"; 27003 fb_root = document.createElement("div"); 27004 fb_root.id = "fb-root"; 27005 this.el.body.appendChild(fb_root); 27006 return this.el.body.appendChild(script); 27007 } 27008 }; 27009 27010 Share.prototype.hook = function(type, network, instance) { 27011 var fn, opts; 27012 fn = this.config.networks[network][type]; 27013 if (typeof fn === "function") { 27014 opts = fn.call(this.config.networks[network], instance); 27015 if (opts !== void 0) { 27016 opts = this.normalize_filter_config_updates(opts); 27017 this.extend(this.config.networks[network], opts, true); 27018 this.normalize_network_configuration(); 27019 } 27020 } 27021 }; 27022 27023 Share.prototype.default_title = function() { 27024 var content; 27025 if (content = document.querySelector('meta[property="og:title"]') || document.querySelector('meta[name="twitter:title"]')) { 27026 return encodeURIComponent(content.getAttribute('content')); 27027 } else if (content = document.querySelector('title')) { 27028 return encodeURIComponent(content.innerText); 27029 } 27030 }; 27031 27032 Share.prototype.default_image = function() { 27033 var content; 27034 if (content = document.querySelector('meta[property="og:image"]') || document.querySelector('meta[name="twitter:image"]')) { 27035 return content.getAttribute('content'); 27036 } 27037 }; 27038 27039 Share.prototype.default_description = function() { 27040 var content; 27041 if (content = document.querySelector('meta[property="og:description"]') || document.querySelector('meta[name="twitter:description"]') || document.querySelector('meta[name="description"]')) { 27042 return encodeURIComponent(content.getAttribute('content')); 27043 } else { 27044 return ''; 27045 } 27046 }; 27047 27048 Share.prototype.set_global_configuration = function() { 27049 var display, network, option, options, _ref, _results; 27050 _ref = this.config.networks; 27051 _results = []; 27052 for (network in _ref) { 27053 options = _ref[network]; 27054 for (option in options) { 27055 if (this.config.networks[network][option] == null) { 27056 this.config.networks[network][option] = this.config[option]; 27057 } 27058 } 27059 if (this.config.networks[network].enabled) { 27060 display = 'block'; 27061 this.config.enabled_networks += 1; 27062 } else { 27063 display = 'none'; 27064 } 27065 _results.push(this.config.networks[network].display = display); 27066 } 27067 return _results; 27068 }; 27069 27070 Share.prototype.normalize_network_configuration = function() { 27071 if (!this.config.networks.facebook.app_id) { 27072 this.config.networks.facebook.load_sdk = false;
27073 } 27074 if (!this.is_encoded(this.config.networks.twitter.description)) { 27075 this.config.networks.twitter.description = encodeURIComponent(this.config.networks.twitter.description); 27076 } 27077 if (typeof this.config.networks.facebook.app_id === 'number') { 27078 return this.config.networks.facebook.app_id = this.config.networks.facebook.app_id.toString(); 27079 } 27080 }; 27081 27082 Share.prototype.normalize_filter_config_updates = function(opts) { 27083 if (this.config.networks.facebook.app_id !== opts.app_id) { 27084 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."); 27085 delete opts.app_id; 27086 } 27087 if (this.config.networks.facebook.load_sdk !== opts.load_sdk) { 27088 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."); 27089 delete opts.app_id; 27090 } 27091 return opts; 27092 }; 27093 27094 return Share; 27095 27096})(ShareUtils); 27097 return Share; 27098}); 27099 27100// Generated by CoffeeScript 1.9.2 27101 27102// @license Sticky-kit v1.1.2 | WTFPL | Leaf Corcoran 2015 | http://leafo.net 27103 27104(function() { 27105 var $, win; 27106 27107 $ = this.jQuery || window.jQuery; 27108 27109 win = $(window); 27110 27111 $.fn.stick_in_parent = function(opts) { 27112 var doc, elm, enable_bottoming, fn, i, inner_scrolling, len, manual_spacer, offset_top, outer_width, parent_selector, recalc_every, sticky_class; 27113 if (opts == null) { 27114 opts = {}; 27115 } 27116 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; 27117 if (offset_top == null) { 27118 offset_top = 0; 27119 } 27120 if (parent_selector == null) { 27121 parent_selector = void 0; 27122 } 27123 if (inner_scrolling == null) { 27124 inner_scrolling = true; 27125 } 27126 if (sticky_class == null) { 27127 sticky_class = "is_stuck"; 27128 } 27129 doc = $(document); 27130 if (enable_bottoming == null) { 27131 enable_bottoming = true; 27132 } 27133 outer_width = function(el) { 27134 var _el, computed, w; 27135 if (window.getComputedStyle) { 27136 _el = el[0]; 27137 computed = window.getComputedStyle(el[0]); 27138 w = parseFloat(computed.getPropertyValue("width")) + parseFloat(computed.getPropertyValue("margin-left")) + parseFloat(computed.getPropertyValue("margin-right")); 27139 if (computed.getPropertyValue("box-sizing") !== "border-box") { 27140 w += parseFloat(computed.getPropertyValue("border-left-width")) + parseFloat(computed.getPropertyValue("border-right-width")) + parseFloat(computed.getPropertyValue("padding-left")) + parseFloat(computed.getPropertyValue("padding-right")); 27141 } 27142 return w; 27143 } else { 27144 return el.outerWidth(true); 27145 } 27146 }; 27147 fn = function(elm, padding_bottom, parent_top, parent_height, top, height, el_float, detached) { 27148 var bottomed, detach, fixed, last_pos, last_scroll_height, offset, parent, recalc, recalc_and_tick, recalc_counter, spacer, tick; 27149 if (elm.data("sticky_kit")) { 27150 return; 27151 } 27152 elm.data("sticky_kit", true); 27153 last_scroll_height = doc.height(); 27154 parent = elm.parent(); 27155 if (parent_selector != null) { 27156 parent = parent.closest(parent_selector); 27157 } 27158 if (!parent.length) { 27159 throw "failed to find stick parent"; 27160 } 27161 fixed = false; 27162 bottomed = false; 27163 spacer = manual_spacer != null ? manual_spacer && elm.closest(manual_spacer) : $("<div />"); 27164 if (spacer) { 27165 spacer.css('position', elm.css('position')); 27166 } 27167 recalc = function() { 27168 var border_top, padding_top, restore; 27169 if (detached) { 27170 return; 27171 } 27172 last_scroll_height = doc.height(); 27173 border_top = parseInt(parent.css("border-top-width"), 10); 27174 padding_top = parseInt(parent.css("padding-top"), 10); 27175 padding_bottom = parseInt(parent.css("padding-bottom"), 10); 27176 parent_top = parent.offset().top + border_top + padding_top; 27177 parent_height = parent.height(); 27178 if (fixed) { 27179 fixed = false;
vendor: 6,068 bytes, lines 27180-27374
27180 bottomed = false; 27181 if (manual_spacer == null) { 27182 elm.insertAfter(spacer); 27183 spacer.detach(); 27184 } 27185 elm.css({ 27186 position: "", 27187 top: "", 27188 width: "", 27189 bottom: "" 27190 }).removeClass(sticky_class); 27191 restore = true; 27192 } 27193 top = elm.offset().top - (parseInt(elm.css("margin-top"), 10) || 0) - offset_top; 27194 height = elm.outerHeight(true); 27195 el_float = elm.css("float"); 27196 if (spacer) { 27197 spacer.css({ 27198 width: outer_width(elm), 27199 height: height, 27200 display: elm.css("display"), 27201 "vertical-align": elm.css("vertical-align"), 27202 "float": el_float 27203 }); 27204 } 27205 if (restore) { 27206 return tick(); 27207 } 27208 }; 27209 recalc(); 27210 if (height === parent_height) { 27211 return; 27212 } 27213 last_pos = void 0; 27214 offset = offset_top; 27215 recalc_counter = recalc_every; 27216 tick = function() { 27217 var css, delta, recalced, scroll, will_bottom, win_height; 27218 if (detached) { 27219 return; 27220 } 27221 recalced = false; 27222 if (recalc_counter != null) { 27223 recalc_counter -= 1; 27224 if (recalc_counter <= 0) { 27225 recalc_counter = recalc_every; 27226 recalc(); 27227 recalced = true; 27228 } 27229 } 27230 if (!recalced && doc.height() !== last_scroll_height) { 27231 recalc(); 27232 recalced = true; 27233 } 27234 scroll = win.scrollTop(); 27235 if (last_pos != null) { 27236 delta = scroll - last_pos; 27237 } 27238 last_pos = scroll; 27239 if (fixed) { 27240 if (enable_bottoming) { 27241 will_bottom = scroll + height + offset > parent_height + parent_top; 27242 if (bottomed && !will_bottom) { 27243 bottomed = false; 27244 elm.css({ 27245 position: "fixed", 27246 bottom: "", 27247 top: offset 27248 }).trigger("sticky_kit:unbottom"); 27249 } 27250 } 27251 if (scroll < top) { 27252 fixed = false; 27253 offset = offset_top; 27254 if (manual_spacer == null) { 27255 if (el_float === "left" || el_float === "right") { 27256 elm.insertAfter(spacer); 27257 } 27258 spacer.detach(); 27259 } 27260 css = { 27261 position: "", 27262 width: "", 27263 top: "" 27264 }; 27265 elm.css(css).removeClass(sticky_class).trigger("sticky_kit:unstick"); 27266 } 27267 if (inner_scrolling) { 27268 win_height = win.height(); 27269 if (height + offset_top > win_height) { 27270 if (!bottomed) { 27271 offset -= delta; 27272 offset = Math.max(win_height - height, offset); 27273 offset = Math.min(offset_top, offset); 27274 if (fixed) { 27275 elm.css({ 27276 top: offset + "px" 27277 }); 27278 } 27279 } 27280 } 27281 } 27282 } else { 27283 if (scroll > top) { 27284 fixed = true; 27285 css = { 27286 position: "fixed", 27287 top: offset 27288 }; 27289 css.width = elm.css("box-sizing") === "border-box" ? elm.outerWidth() + "px" : elm.width() + "px"; 27290 elm.css(css).addClass(sticky_class); 27291 if (manual_spacer == null) { 27292 elm.after(spacer); 27293 if (el_float === "left" || el_float === "right") { 27294 spacer.append(elm); 27295 } 27296 } 27297 elm.trigger("sticky_kit:stick"); 27298 } 27299 } 27300 if (fixed && enable_bottoming) { 27301 if (will_bottom == null) { 27302 will_bottom = scroll + height + offset > parent_height + parent_top; 27303 } 27304 if (!bottomed && will_bottom) { 27305 bottomed = true; 27306 if (parent.css("position") === "static") { 27307 parent.css({ 27308 position: "relative" 27309 }); 27310 } 27311 return elm.css({ 27312 position: "absolute", 27313 bottom: padding_bottom, 27314 top: "auto" 27315 }).trigger("sticky_kit:bottom"); 27316 } 27317 } 27318 }; 27319 recalc_and_tick = function() { 27320 recalc(); 27321 return tick(); 27322 }; 27323 detach = function() { 27324 detached = true; 27325 win.off("touchmove", tick); 27326 win.off("scroll", tick); 27327 win.off("resize", recalc_and_tick); 27328 $(document.body).off("sticky_kit:recalc", recalc_and_tick); 27329 elm.off("sticky_kit:detach", detach); 27330 elm.removeData("sticky_kit"); 27331 elm.css({ 27332 position: "", 27333 bottom: "", 27334 top: "", 27335 width: "" 27336 }); 27337 parent.position("position", ""); 27338 if (fixed) { 27339 if (manual_spacer == null) { 27340 if (el_float === "left" || el_float === "right") { 27341 elm.insertAfter(spacer); 27342 } 27343 spacer.remove(); 27344 } 27345 return elm.removeClass(sticky_class); 27346 } 27347 }; 27348 win.on("touchmove", tick); 27349 win.on("scroll", tick); 27350 win.on("resize", recalc_and_tick); 27351 $(document.body).on("sticky_kit:recalc", recalc_and_tick); 27352 elm.on("sticky_kit:detach", detach); 27353 return setTimeout(tick, 0); 27354 }; 27355 for (i = 0, len = this.length; i < len; i++) { 27356 elm = this[i]; 27357 fn($(elm)); 27358 } 27359 return this; 27360 }; 27361 27362}).call(this); 27363/* ========================================================================== 27364 * bootstrap-tab-history.js 27365 * Author: Michael Narayan <[email protected]> 27366 * Repository: https://github.com/mnarayan01/bootstrap-tab-history/ 27367 * ========================================================================== 27368 * Licensed under the Apache License, Version 2.0 (the "License"); you may 27369 * not use this file except in compliance with the License. You may obtain a 27370 * copy of the License at 27371 * 27372 * http://www.apache.org/licenses/LICENSE-2.0 27373 * 27374 * Unless required by applicable law or agreed to in writing, softw
27374are 27375 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 27376 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 27377 * License for the specific language governing permissions and limitations 27378 * under the License. 27379 * ========================================================================== */ 27380 27381/* ========================================================================== */ 27382/* JSHint directives */ 27383/* */ 27384/* global BootstrapTabHistory: true */ 27385/* */ 27386/* global document */ 27387/* global jQuery */ 27388/* global history */ 27389/* global window */ 27390/* ========================================================================== */ 27391 27392/** 27393 * Integrate [HTML5 history state tracking](https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Manipulating_the_browser_history) 27394 * with [`bootstrap/tab.js`](http://getbootstrap.com/javascript/#tabs). To enable tracking on a tab element, simply set 27395 * the `data-tab-history` attribute to true (or a string denoting a tab grouping). 27396 * 27397 * See the README for additional information. 27398 * 27399 * Functionality based upon bootstrap/tab.js v3.1.0; reference it when making any changes. 27400 */ 27401 27402BootstrapTabHistory = { 27403 options: { 27404 /** 27405 * When the anchor portion of the URI is used to activate a tab, scroll down to the given offset, rather than the 27406 * element with the given `id` attribute. Set to null to disable. Only relevant if showTabsBasedOnAnchor is true. 27407 * 27408 * May be overriden on a per-element basis by the attribute `data-tab-history-anchor-y-offset`. 27409 * 27410 * @public 27411 * @type {?number} 27412 */ 27413 defaultAnchorYOffset: 0, 27414 /** 27415 * Either 'push' or 'replace', for whether to use `history.pushState` or `history.replaceState`, resp. 27416 * 27417 * May be overriden on a per-element basis by the attribute `data-tab-history-changer`. 27418 * 27419 * @public 27420 * @type {string} 27421 */ 27422 defaultChanger: 'replace', 27423 /** 27424 * If true, update the URL in onShownTab in the calls to `history.pushState` and `history.replaceState`. Otherwise, 27425 * `null` is passed as the third parameter to these calls. 27426 * 27427 * May be overriden on a per-element basis by the attribute `data-tab-history-update-url`. 27428 * 27429 * @public 27430 * @type {boolean} 27431 */ 27432 defaultUpdateURL: false, 27433 /** 27434 * Should the anchor portion of the loaded URI be used to activate a single tab if no history was present on page 27435 * load. 27436 * 27437 * @public 27438 * @type {boolean} 27439 */ 27440 showTabsBasedOnAnchor: true 27441 } 27442}; 27443 27444(function () { 27445 'use strict'; 27446 27447 jQuery(function () { 27448 if(history && history.pushState && history.replaceState) { 27449 var bootstrapTabHistory = history.state && history.state.bootstrapTabHistory; 27450 27451 if(bootstrapTabHistory) { 27452 showTabsBasedOnState(bootstrapTabHistory); 27453 } else { 27454 showTabsBasedOnAnchor(); 27455 } 27456 27457 backfillHistoryState(); 27458 27459 jQuery(document).on('shown.bs.tab show.bs.collapse', onShownTab); 27460 jQuery(window).on('popstate', onPopState); 27461 } else { 27462 showTabsBasedOnAnchor(); 27463 } 27464 }); 27465 27466 /** 27467 * Used to prevent onShownTab from registering shown events that we triggered via showTabsBasedOnState. 27468 * 27469 * @type {boolean} 27470 */ 27471 var showingTabsBasedOnState = false; 27472 27473 /** 27474 * Used to update `history.state` to reflect the default active tabs on initial page load. This supports proper 27475 * `history.back` handling when `data-tab-history-update-url` is true. 27476 */ 27477 function backfillHistoryState() { 27478 var newState = null; 27479 27480 jQuery('li.active > [data-tab-history], .panel-title.active [data-tab-history]').each(function () {//edited by Uncode 27481 var $activeTabElement = jQuery(this); 27482 var selector = getTabSelector($activeTabElement); 27483 27484 if(selector) { 27485 var tabGroup = getTabGroup($activeTabElement); 27486 27487 if(tabGroup) { 27488 newState = createNewHistoryState(newState || history.state, tabGroup, selector); 27489 } 27490 } 27491 }); 27492 27493 if(newState) { 27494 history.replaceState(newState, '', null); 27495 } 27496 } 27497 27498 /** 27499 * Clone the existing state, ensure its bootstrapTabHistory attribute is an Object, and add the provided tabGroup to 27500 * said bootstrapTabHistory attribute. 27501 * 27502 * @param {?object} existingState 27503 * @param {!string} tabGroup 27504 * @param {!string} selector 27505 * @returns {!object} 27506 */ 27507 function createNewHistoryState(existingState, tabGroup, selector) { 27508 // Clone history.state and ensure it has a bootstrapTabHistory entry. 27509 var newState = jQuery.extend(true, {}, existingState, { 27510 bootstrapTabHistory: {} 27511 }); 27512 27513 newState.bootstrapTabHistory[tabGroup] = selector; 27514 27515 return newState; 27516 } 27517 27518 /** 27519 * @param {jQuery} $tab
27520 * @returns {?string} 27521 */ 27522 function getTabGroup($tab) { 27523 return parseTruthyAttributeValue($tab.data('tab-history')); 27524 } 27525 27526 /** 27527 * @param {jQuery} $tab 27528 * @returns {?string} 27529 */ 27530 function getTabSelector($tab) { 27531 return $tab.data('target') || $tab.attr('href'); 27532 } 27533 27534 /** 27535 * Receives the `shown.bs.tab` event. Updates `history.state` as appropriate. 27536 * 27537 * @param {jQuery.Event} shownEvt 27538 */ 27539 function onShownTab(shownEvt) { 27540 if(!showingTabsBasedOnState) { 27541 var $activatedTab = jQuery(shownEvt.target); 27542 if ( $activatedTab.hasClass('panel-collapse') ) 27543 $activatedTab = $activatedTab.closest('.panel').find('a'); 27544 var selector = getTabSelector($activatedTab); 27545 27546 if(selector) { 27547 var tabGroup = getTabGroup($activatedTab); 27548 27549 if(tabGroup) { 27550 var historyChanger = $activatedTab.data('tab-history-changer') || BootstrapTabHistory.options.defaultChanger; 27551 var newState = createNewHistoryState(history.state, tabGroup, selector); 27552 var updateURL = (function ($activatedTab) { 27553 if(selector[0] === '#') { 27554 var elementUpdateURLOption = parseTruthyAttributeValue($activatedTab.data('tab-history-update-url')); 27555 27556 if(elementUpdateURLOption === undefined) { 27557 return BootstrapTabHistory.options.defaultUpdateURL; 27558 } else { 27559 return elementUpdateURLOption; 27560 } 27561 } else { 27562 return false; 27563 } 27564 })($activatedTab); 27565 27566 switch(historyChanger) { 27567 case 'push': 27568 history.pushState(newState, '', updateURL ? selector : null); 27569 break; 27570 case 'replace': 27571 history.replaceState(newState, '', updateURL ? selector : null); 27572 break; 27573 default: 27574 throw new Error('Unknown tab-history-changer: ' + historyChanger); 27575 } 27576 } 27577 } 27578 } 27579 } 27580 27581 /** 27582 * Receives the `popstate` event. Shows tabs based on the value of `history.state` as appropriate. 27583 */ 27584 function onPopState() { 27585 var bootstrapTabHistory = history.state && history.state.bootstrapTabHistory; 27586 27587 if(bootstrapTabHistory) { 27588 showTabsBasedOnState(bootstrapTabHistory); 27589 } 27590 } 27591 27592 /** 27593 * Returns the given value, _unless_ that value is an empty string, in which case `true` is returned. 27594 * 27595 * Rationale: HAML data attributes which are set to `true` are rendered as a blank string. 27596 * 27597 * @param {*} value 27598 * @returns {*} 27599 */ 27600 function parseTruthyAttributeValue(value) { 27601 if(value) { 27602 return value; 27603 } else if(value === '') { 27604 return true; 27605 } else { 27606 return value; 27607 } 27608 } 27609 27610 /** 27611 * Show tabs based upon the anchor component of `window.location`. 27612 */ 27613 function showTabsBasedOnAnchor() { 27614 if(BootstrapTabHistory.options.showTabsBasedOnAnchor) { 27615 var anchor = window.location && window.location.hash; 27616 27617 if(anchor) { 27618 var $tabElement = showTabForSelector(anchor); 27619 27620 if($tabElement && window.addEventListener && window.removeEventListener) { 27621 var anchorYOffset = (function ($tabElement) { 27622 var elementSetting = $tabElement.data('tab-history-anchor-y-offset'); 27623 27624 if(elementSetting === undefined) { 27625 return BootstrapTabHistory.options.defaultAnchorYOffset; 27626 } else { 27627 return elementSetting; 27628 } 27629 })($tabElement); 27630 27631 // HACK: This prevents scrolling to the tab on page load. This relies on the fact that we should never get 27632 // here on `history.forward`, `history.back`, or `location.reload`, since in all those situations the 27633 // `history.state` object should have been used (unless the browser did not support the modern History API). 27634 if(anchorYOffset || anchorYOffset === 0) { 27635 var scrollListener = function resetAnchorScroll () { 27636 window.removeEventListener('scroll', scrollListener); 27637 window.scrollTo(0, anchorYOffset); 27638 }; 27639 27640 window.addEventListener('scroll', scrollListener); 27641 } 27642 } 27643 } 27644 } 27645 } 27646 27647 /** 27648 * Show a tab which corresponds to the provided selector. 27649 * 27650 * @param {string} selector - A CSS selector. 27651 * @returns {?jQuery} - The tab which was found to show (even if said tab was already active). 27652 */ 27653 function showTabForSelector(selector) { 27654 var $tabElement = (function (selector) { 27655 var $ret = null; 27656 27657 jQuery('[data-toggle="tab"], [data-toggle="pill"], [data-toggle="collapse"]').each(function () { 27658 var $potentialTab = jQuery(this); 27659 27660 if(($potentialTab.attr('href') === selector || $potentialTab.data('target') === selector ) && getTabGroup($potentialTab)) { 27661 $ret = $potentialTab; 27662 return false;
vendor: 43,483 bytes, lines 27663-28879
27663 } else { 27664 return null; 27665 } 27666 }); 27667 27668 return $ret; 27669 })(selector); 27670 27671 if($tabElement) { 27672 if ( !$tabElement.parent().hasClass('active') ) { 27673 $tabElement.trigger('click'); 27674 } 27675 //$tabElement.tab('show'); 27676 } 27677 27678 return $tabElement; 27679 } 27680 27681 /** 27682 * Iterate through the provided set of tab tab groups, showing the tabs based on the stored selectors. 27683 * 27684 * @param {object} bootstrapTabHistory - Each of the values is passed to showTabForSelector; the keys are actually irrelevant. 27685 */ 27686 function showTabsBasedOnState(bootstrapTabHistory) { 27687 showingTabsBasedOnState = true; 27688 27689 try { 27690 for(var k in bootstrapTabHistory) { 27691 if(bootstrapTabHistory.hasOwnProperty(k)) { 27692 showTabForSelector(bootstrapTabHistory[k]); 27693 } 27694 } 27695 } finally { 27696 showingTabsBasedOnState = false; 27697 } 27698 } 27699})(); 27700 27701/*! 27702 * justifiedGallery - v3.8.1 27703 * http://miromannino.github.io/Justified-Gallery/ 27704 * Copyright (c) 2020 Miro Mannino 27705 * Licensed under the MIT license. 27706 */ 27707(function (factory) { 27708 if (typeof define === 'function' && define.amd) { 27709 // AMD. Register as an anonymous module. 27710 define(['jquery'], factory); 27711 } else if (typeof module === 'object' && module.exports) { 27712 // Node/CommonJS 27713 module.exports = function (root, jQuery) { 27714 if (jQuery === undefined) { 27715 // require('jQuery') returns a factory that requires window to 27716 // build a jQuery instance, we normalize how we use modules 27717 // that require this pattern but the window provided is a noop 27718 // if it's defined (how jquery works) 27719 if (typeof window !== 'undefined') { 27720 jQuery = require('jquery'); 27721 } 27722 else { 27723 jQuery = require('jquery')(root); 27724 } 27725 } 27726 factory(jQuery); 27727 return jQuery; 27728 }; 27729 } else { 27730 // Browser globals 27731 factory(jQuery); 27732 } 27733}(function ($) { 27734 27735 /** 27736 * Justified Gallery controller constructor 27737 * 27738 * @param $gallery the gallery to build 27739 * @param settings the settings (the defaults are in JustifiedGallery.defaults) 27740 * @constructor 27741 */ 27742 var JustifiedGallery = function ($gallery, settings) { 27743 27744 this.settings = settings; 27745 this.checkSettings(); 27746 27747 this.imgAnalyzerTimeout = null; 27748 this.entries = null; 27749 this.buildingRow = { 27750 entriesBuff: [], 27751 width: 0, 27752 height: 0, 27753 aspectRatio: 0 27754 }; 27755 this.lastFetchedEntry = null; 27756 this.lastAnalyzedIndex = -1; 27757 this.yield = { 27758 every: 2, // do a flush every n flushes (must be greater than 1) 27759 flushed: 0 // flushed rows without a yield 27760 }; 27761 this.border = settings.border >= 0 ? settings.border : settings.margins; 27762 this.maxRowHeight = this.retrieveMaxRowHeight(); 27763 this.suffixRanges = this.retrieveSuffixRanges(); 27764 this.offY = this.border; 27765 this.rows = 0; 27766 this.spinner = { 27767 phase: 0, 27768 timeSlot: 150, 27769 $el: $('<div class="jg-spinner"><span></span><span></span><span></span></div>'), 27770 intervalId: null 27771 }; 27772 this.scrollBarOn = false; 27773 this.checkWidthIntervalId = null; 27774 this.galleryWidth = $gallery.width(); 27775 this.$gallery = $gallery; 27776 27777 }; 27778 27779 /** @returns {String} the best suffix given the width and the height */ 27780 JustifiedGallery.prototype.getSuffix = function (width, height) { 27781 var longestSide, i; 27782 longestSide = (width > height) ? width : height; 27783 for (i = 0; i < this.suffixRanges.length; i++) { 27784 if (longestSide <= this.suffixRanges[i]) { 27785 return this.settings.sizeRangeSuffixes[this.suffixRanges[i]]; 27786 } 27787 } 27788 return this.settings.sizeRangeSuffixes[this.suffixRanges[i - 1]]; 27789 }; 27790 27791 /** 27792 * Remove the suffix from the string 27793 * 27794 * @returns {string} a new string without the suffix 27795 */ 27796 JustifiedGallery.prototype.removeSuffix = function (str, suffix) { 27797 return str.substring(0, str.length - suffix.length); 27798 }; 27799 27800 /** 27801 * @returns {boolean} a boolean to say if the suffix is contained in the str or not 27802 */ 27803 JustifiedGallery.prototype.endsWith = function (str, suffix) { 27804 return str.indexOf(suffix, str.length - suffix.length) !== -1; 27805 }; 27806 27807 /** 27808 * Get the used suffix of a particular url 27809 * 27810 * @param str 27811 * @returns {String} return the used suffix 27812 */ 27813 JustifiedGallery.prototype.getUsedSuffix = function (str) { 27814 for (var si in this.settings.sizeRangeSuffixes) { 27815 if (this.settings.sizeRangeSuffixes.hasOwnProperty(si)) { 27816 if (this.settings.sizeRangeSuffixes[si].length === 0) continue; 27817 if (this.endsWith(str, this.settings.sizeRangeSuffixes[si])) return this.settings.sizeRangeSuffixes[si]; 27818 } 27819 } 27820 return ''; 27821 }; 27822 27823 /** 27824 * Given an image src, with the width and the height, returns the new image src with the 27825 * best suffix to show the best quality thumbnail. 27826 * 27827 * @returns {String} the suffix to use 27828 */ 27829 JustifiedGallery.prototype.newSrc = function (imageSrc, imgWidth, imgHeight, image) { 27830 var newImageSrc; 27831 27832 if (this.settings.thumbnailPath) { 27833 newImageSrc = this.settings.thumbnailPath(imageSrc, imgWidth, imgHeight, image); 27834 } else { 27835 var matchRes = imageSrc.match(this.settings.extension); 27836 var ext = (matchRes !== null) ? matchRes[0] : ''; 27837 newImageSrc = imageSrc.replace(this.settings.extension, ''); 27838 newImageSrc = this.removeSuffix(newImageSrc, this.getUsedSuffix(newImageSrc)); 27839 newImageSrc += this.getSuffix(imgWidth, imgHeight) + ext; 27840 } 27841 27842 return newImageSrc; 27843 }; 27844 27845 /** 27846 * Shows the images that is in the given entry 27847 * 27848 * @param $entry the entry 27849 * @param callback the callback that is called when the show animation is finished 27850 */ 27851 JustifiedGallery.prototype.showImg = function ($entry, callback) { 27852 if (this.settings.cssAnimation) { 27853 $entry.addClass('jg-entry-visible'); 27854 if (callback) callback(); 27855 } else { 27856 $entry.stop().fadeTo(this.settings.imagesAnimationDuration, 1.0, callback); 27857 $entry.find(this.settings.imgSelector).stop().fadeTo(this.settings.imagesAnimationDuration, 1.0, callback); 27858 } 27859 }; 27860 27861 /** 27862 * Extract the image src form the image, looking from the 'safe-src', and if it can't be found, from the 27863 * 'src' attribute. It saves in the image data the 'jg.originalSrc' field, with the extracted src. 27864 * 27865 * @param $image the image to analyze 27866 * @returns {String} the extracted src 27867 */ 27868 JustifiedGallery.prototype.extractImgSrcFromImage = function ($image) { 27869 var imageSrc = $image.data('safe-src'); 27870 var imageSrcLoc = 'data-safe-src'; 27871 // Begin Uncode edit 27872 if (typeof imageSrc === 'undefined') { 27873 var imageCurrentSrc = $image[0].currentSrc; 27874 if (imageCurrentSrc) { 27875 imageSrc = imageCurrentSrc; 27876 } else { 27877 imageSrc = $image.attr('src'); 27878 } 27879 imageSrcLoc = 'src'; 27880 } 27881 // End Uncode edit 27882 $image.data('jg.originalSrc', imageSrc); // this is saved for the destroy method 27883 $image.data('jg.src', imageSrc); // this will change overtime 27884 $image.data('jg.originalSrcLoc', imageSrcLoc); // this is saved for the destroy method 27885 return imageSrc; 27886 }; 27887 27888 /** @returns {jQuery} the image in the given entry */ 27889 JustifiedGallery.prototype.imgFromEntry = function ($entry) { 27890 var $img = $entry.find(this.settings.imgSelector); 27891 if ($img.length === 0) $img = $entry.find('.t-entry-visual-cont img');//hacked by Uncode 27892 return $img.length === 0 ? null : $img; 27893 }; 27894 27895 /** @returns {jQuery} the caption in the given entry */ 27896 JustifiedGallery.prototype.captionFromEntry = function ($entry) { 27897 var $caption = $entry.find('> .jg-caption'); 27898 return $caption.length === 0 ? null : $caption; 27899 }; 27900 27901 /** 27902 * Display the entry 27903 * 27904 * @param {jQuery} $entry the entry to display 27905 * @param {int} x the x position where the entry must be positioned 27906 * @param y the y position where the entry must be positioned 27907 * @param imgWidth the image width 27908 * @param imgHeight the image height 27909 * @param rowHeight the row height of the row that owns the entry 27910 */ 27911 JustifiedGallery.prototype.displayEntry = function ($entry, x, y, imgWidth, imgHeight, rowHeight) { 27912 $entry.width(imgWidth); 27913 $entry.height(Math.floor(rowHeight));//hacked by Uncode 27914 $entry.css('top', Math.floor(y));//hacked by Uncode 27915 $entry.css('left', x); 27916 27917 var $image = this.imgFromEntry($entry); 27918 if ($image !== null) { 27919 $image.css('width', imgWidth); 27920 $image.css('height', imgHeight); 27921 $image.css('margin-left', - imgWidth / 2); 27922 $image.css('margin-top', - imgHeight / 2); 27923 27924 // Image reloading for an high quality of thumbnails 27925 var imageSrc = $image.data('jg.src'); 27926 if (imageSrc) { 27927 imageSrc = this.newSrc(imageSrc, imgWidth, imgHeight, $image[0]); 27928 27929 $image.one('error', function () { 27930 this.resetImgSrc($image); //revert to the original thumbnail 27931 }); 27932 27933 var loadNewImage = function () { 27934 // if (imageSrc !== newImageSrc) { 27935 $image.attr('src', imageSrc); 27936 // } 27937 }; 27938 27939 if ($entry.data('jg.loaded') === 'skipped' && imageSrc) { 27940 this.onImageEvent(imageSrc, (function() { 27941 this.showImg($entry, loadNewImage); //load the new image after the fadeIn 27942 $entry.data('jg.loaded', true); 27943 }).bind(this)); 27944 } else { 27945 this.showImg($entry, loadNewImage); //load the new image after the fadeIn 27946 } 27947 27948 } 27949 27950 } else { 27951 this.showImg($entry); 27952 } 27953 27954 this.displayEntryCaption($entry); 27955 }; 27956 27957 /** 27958 * Display the entry caption. If the caption element doesn't exists, it creates the caption using the 'alt' 27959 * or the 'title' attributes. 27960 * 27961 * @param {jQuery} $entry the entry to process 27962 */ 27963 JustifiedGallery.prototype.displayEntryCaption = function ($entry) { 27964 var $image = this.imgFromEntry($entry); 27965 if ($image !== null && this.settings.captions) { 27966 var $imgCaption = this.captionFromEntry($entry); 27967 27968 // Create it if it doesn't exists 27969 if ($imgCaption === null) { 27970 var caption = $image.attr('alt'); 27971 if (!this.isValidCaption(caption)) caption = $entry.attr('title'); 27972 if (this.isValidCaption(caption)) { // Create only we found something 27973 $imgCaption = $('<div class="jg-caption">' + caption + '</div>'); 27974 $entry.append($imgCaption); 27975 $entry.data('jg.createdCaption', true); 27976 } 27977 } 27978 27979 // Create events (we check again the $imgCaption because it can be still inexistent) 27980 if ($imgCaption !== null) { 27981 if (!this.settings.cssAnimation) $imgCaption.stop().fadeTo(0, this.settings.captionSettings.nonVisibleOpacity); 27982 this.addCaptionEventsHandlers($entry); 27983 } 27984 } else { 27985 this.removeCaptionEventsHandlers($entry); 27986 } 27987 }; 27988 27989 /** 27990 * Validates the caption 27991 * 27992 * @param caption The caption that should be validated 27993 * @return {boolean} Validation result 27994 */ 27995 JustifiedGallery.prototype.isValidCaption = function (caption) { 27996 return (typeof caption !== 'undefined' && caption.length > 0); 27997 }; 27998 27999 /** 28000 * The callback for the event 'mouseenter'. It assumes that the event currentTarget is an entry. 28001 * It shows the caption using jQuery (or using CSS if it is configured so) 28002 * 28003 * @param {Event} eventObject the event object 28004 */ 28005 JustifiedGallery.prototype.onEntryMouseEnterForCaption = function (eventObject) { 28006 var $caption = this.captionFromEntry($(eventObject.currentTarget)); 28007 if (this.settings.cssAnimation) { 28008 $caption.addClass('jg-caption-visible').removeClass('jg-caption-hidden'); 28009 } else { 28010 $caption.stop().fadeTo(this.settings.captionSettings.animationDuration, 28011 this.settings.captionSettings.visibleOpacity); 28012 } 28013 }; 28014 28015 /** 28016 * The callback for the event 'mouseleave'. It assumes that the event currentTarget is an entry. 28017 * It hides the caption using jQuery (or using CSS if it is configured so) 28018 * 28019 * @param {Event} eventObject the event object 28020 */ 28021 JustifiedGallery.prototype.onEntryMouseLeaveForCaption = function (eventObject) { 28022 var $caption = this.captionFromEntry($(eventObject.currentTarget)); 28023 if (this.settings.cssAnimation) { 28024 $caption.removeClass('jg-caption-visible').removeClass('jg-caption-hidden'); 28025 } else { 28026 $caption.stop().fadeTo(this.settings.captionSettings.animationDuration, 28027 this.settings.captionSettings.nonVisibleOpacity); 28028 } 28029 }; 28030 28031 /** 28032 * Add the handlers of the entry for the caption 28033 * 28034 * @param $entry the entry to modify 28035 */ 28036 JustifiedGallery.prototype.addCaptionEventsHandlers = function ($entry) { 28037 var captionMouseEvents = $entry.data('jg.captionMouseEvents'); 28038 if (typeof captionMouseEvents === 'undefined') { 28039 captionMouseEvents = { 28040 mouseenter: $.proxy(this.onEntryMouseEnterForCaption, this), 28041 mouseleave: $.proxy(this.onEntryMouseLeaveForCaption, this) 28042 }; 28043 $entry.on('mouseenter', undefined, undefined, captionMouseEvents.mouseenter); 28044 $entry.on('mouseleave', undefined, undefined, captionMouseEvents.mouseleave); 28045 $entry.data('jg.captionMouseEvents', captionMouseEvents); 28046 } 28047 }; 28048 28049 /** 28050 * Remove the handlers of the entry for the caption 28051 * 28052 * @param $entry the entry to modify 28053 */ 28054 JustifiedGallery.prototype.removeCaptionEventsHandlers = function ($entry) { 28055 var captionMouseEvents = $entry.data('jg.captionMouseEvents'); 28056 if (typeof captionMouseEvents !== 'undefined') { 28057 $entry.off('mouseenter', undefined, captionMouseEvents.mouseenter); 28058 $entry.off('mouseleave', undefined, captionMouseEvents.mouseleave); 28059 $entry.removeData('jg.captionMouseEvents'); 28060 } 28061 }; 28062 28063 /** 28064 * Clear the building row data to be used for a new row 28065 */ 28066 JustifiedGallery.prototype.clearBuildingRow = function () { 28067 this.buildingRow.entriesBuff = []; 28068 this.buildingRow.aspectRatio = 0; 28069 this.buildingRow.width = 0; 28070 }; 28071 28072 /** 28073 * Justify the building row, preparing it to 28074 * 28075 * @param isLastRow 28076 * @param hiddenRow undefined or false for normal behavior. hiddenRow = true to hide the row. 28077 * @returns a boolean to know if the row has been justified or not 28078 */ 28079 JustifiedGallery.prototype.prepareBuildingRow = function (isLastRow, hiddenRow) { 28080 var i, $entry, imgAspectRatio, newImgW, newImgH, justify = true; 28081 var minHeight = 0; 28082 var availableWidth = this.galleryWidth - 2 * this.border - ( 28083 (this.buildingRow.entriesBuff.length - 1) * this.settings.margins); 28084 var rowHeight = Math.floor( availableWidth / this.buildingRow.aspectRatio );//hacked by Uncode 28085 var defaultRowHeight = this.settings.rowHeight; 28086 var justifiable = this.buildingRow.width / availableWidth > this.settings.justifyThreshold; 28087 28088 //Skip the last row if we can't justify it and the lastRow == 'hide' 28089 if (hiddenRow || (isLastRow && this.settings.lastRow === 'hide' && !justifiable)) { 28090 for (i = 0; i < this.buildingRow.entriesBuff.length; i++) { 28091 $entry = this.buildingRow.entriesBuff[i]; 28092 if (this.settings.cssAnimation) 28093 $entry.removeClass('jg-entry-visible'); 28094 else { 28095 $entry.stop().fadeTo(0, 0.1); 28096 $entry.find('> img, > a > img').fadeTo(0, 0); 28097 } 28098 } 28099 return -1; 28100 } 28101 28102 // With lastRow = nojustify, justify if is justificable (the images will not become too big) 28103 if (isLastRow && !justifiable && this.settings.lastRow !== 'justify' && this.settings.lastRow !== 'hide') { 28104 justify = false; 28105 28106 if (this.rows > 0) { 28107 defaultRowHeight = (this.offY - this.border - this.settings.margins * this.rows) / this.rows; 28108 justify = defaultRowHeight * this.buildingRow.aspectRatio / availableWidth > this.settings.justifyThreshold; 28109 } 28110 } 28111 28112 for (i = 0; i < this.buildingRow.entriesBuff.length; i++) { 28113 $entry = this.buildingRow.entriesBuff[i]; 28114 imgAspectRatio = $entry.data('jg.width') / $entry.data('jg.height'); 28115 28116 if (justify) { 28117 newImgW = (i === this.buildingRow.entriesBuff.length - 1) ? availableWidth : rowHeight * imgAspectRatio; 28118 newImgH = rowHeight; 28119 } else { 28120 newImgW = defaultRowHeight * imgAspectRatio; 28121 newImgH = defaultRowHeight; 28122 } 28123 28124 availableWidth -= Math.round(newImgW); 28125 $entry.data('jg.jwidth', Math.round(newImgW)); 28126 $entry.data('jg.jheight', Math.ceil(newImgH)); 28127 if (i === 0 || minHeight > newImgH) minHeight = newImgH; 28128 } 28129 28130 this.buildingRow.height = minHeight; 28131 return justify; 28132 }; 28133 28134 /** 28135 * Flush a row: justify it, modify the gallery height accordingly to the row height 28136 * 28137 * @param isLastRow 28138 * @param hiddenRow undefined or false for normal behavior. hiddenRow = true to hide the row. 28139 */ 28140 JustifiedGallery.prototype.flushRow = function (isLastRow, hiddenRow) { 28141 var settings = this.settings; 28142 var $entry, buildingRowRes, offX = this.border, i; 28143 28144 buildingRowRes = this.prepareBuildingRow(isLastRow, hiddenRow); 28145 if (hiddenRow || (isLastRow && settings.lastRow === 'hide' && buildingRowRes === -1)) { 28146 this.clearBuildingRow(); 28147 return; 28148 } 28149 28150 if (this.maxRowHeight) { 28151 if (this.maxRowHeight < this.buildingRow.height) this.buildingRow.height = this.maxRowHeight; 28152 } 28153 28154 //Align last (unjustified) row 28155 if (isLastRow && (settings.lastRow === 'center' || settings.lastRow === 'right')) { 28156 var availableWidth = this.galleryWidth - 2 * this.border - (this.buildingRow.entriesBuff.length - 1) * settings.margins; 28157 28158 for (i = 0; i < this.buildingRow.entriesBuff.length; i++) { 28159 $entry = this.buildingRow.entriesBuff[i]; 28160 availableWidth -= $entry.data('jg.jwidth'); 28161 } 28162 28163 if (settings.lastRow === 'center') 28164 offX += Math.round(availableWidth / 2); 28165 else if (settings.lastRow === 'right') 28166 offX += availableWidth; 28167 } 28168 28169 var lastEntryIdx = this.buildingRow.entriesBuff.length - 1; 28170 for (i = 0; i <= lastEntryIdx; i++) { 28171 $entry = this.buildingRow.entriesBuff[this.settings.rtl ? lastEntryIdx - i : i]; 28172 this.displayEntry($entry, offX, this.offY, $entry.data('jg.jwidth'), $entry.data('jg.jheight'), this.buildingRow.height); 28173 offX += $entry.data('jg.jwidth') + settings.margins; 28174 } 28175 28176 //Gallery Height 28177 this.galleryHeightToSet = this.offY + this.buildingRow.height + this.border; 28178 this.setGalleryTempHeight(this.galleryHeightToSet + this.getSpinnerHeight()); 28179 28180 if (!isLastRow || (this.buildingRow.height <= settings.rowHeight && buildingRowRes)) { 28181 //Ready for a new row 28182 this.offY += this.buildingRow.height + settings.margins; 28183 this.rows += 1; 28184 this.clearBuildingRow(); 28185 this.settings.triggerEvent.call(this, 'jg.rowflush'); 28186 } 28187 }; 28188 28189 28190 // Scroll position not restoring: https://github.com/miromannino/Justified-Gallery/issues/221 28191 var galleryPrevStaticHeight = 0; 28192 28193 JustifiedGallery.prototype.rememberGalleryHeight = function () { 28194 galleryPrevStaticHeight = this.$gallery.height(); 28195 this.$gallery.height(galleryPrevStaticHeight); 28196 }; 28197 28198 // grow only 28199 JustifiedGallery.prototype.setGalleryTempHeight = function (height) { 28200 galleryPrevStaticHeight = Math.max(height, galleryPrevStaticHeight); 28201 this.$gallery.height(galleryPrevStaticHeight); 28202 }; 28203 28204 JustifiedGallery.prototype.setGalleryFinalHeight = function (height) { 28205 galleryPrevStaticHeight = height; 28206 this.$gallery.height(height); 28207 }; 28208 28209 /** 28210 * Checks the width of the gallery container, to know if a new justification is needed 28211 */ 28212 JustifiedGallery.prototype.checkWidth = function () { 28213 this.checkWidthIntervalId = setInterval($.proxy(function () { 28214 28215 // if the gallery is not currently visible, abort. 28216 if (!this.$gallery.is(":visible")) return; 28217 28218 var galleryWidth = parseFloat(this.$gallery.width()); 28219 if (Math.abs(galleryWidth - this.galleryWidth) > this.settings.refreshSensitivity) { 28220 this.galleryWidth = galleryWidth; 28221 this.rewind(); 28222 28223 this.rememberGalleryHeight(); 28224 28225 // Restart to analyze 28226 this.startImgAnalyzer(true); 28227 } 28228 }, this), this.settings.refreshTime); 28229 }; 28230 28231 /** 28232 * @returns {boolean} a boolean saying if the spinner is active or not 28233 */ 28234 JustifiedGallery.prototype.isSpinnerActive = function () { 28235 return this.spinner.intervalId !== null; 28236 }; 28237 28238 /** 28239 * @returns {int} the spinner height 28240 */ 28241 JustifiedGallery.prototype.getSpinnerHeight = function () { 28242 return this.spinner.$el.innerHeight(); 28243 }; 28244 28245 /** 28246 * Stops the spinner animation and modify the gallery height to exclude the spinner 28247 */ 28248 JustifiedGallery.prototype.stopLoadingSpinnerAnimation = function () { 28249 clearInterval(this.spinner.intervalId); 28250 this.spinner.intervalId = null; 28251 this.setGalleryTempHeight(this.$gallery.height() - this.getSpinnerHeight()); 28252 this.spinner.$el.detach(); 28253 }; 28254 28255 /** 28256 * Starts the spinner animation 28257 */ 28258 JustifiedGallery.prototype.startLoadingSpinnerAnimation = function () { 28259 var spinnerContext = this.spinner; 28260 var $spinnerPoints = spinnerContext.$el.find('span'); 28261 clearInterval(spinnerContext.intervalId); 28262 this.$gallery.append(spinnerContext.$el); 28263 this.setGalleryTempHeight(this.offY + this.buildingRow.height + this.getSpinnerHeight()); 28264 spinnerContext.intervalId = setInterval(function () { 28265 if (spinnerContext.phase < $spinnerPoints.length) { 28266 $spinnerPoints.eq(spinnerContext.phase).fadeTo(spinnerContext.timeSlot, 1); 28267 } else { 28268 $spinnerPoints.eq(spinnerContext.phase - $spinnerPoints.length).fadeTo(spinnerContext.timeSlot, 0); 28269 } 28270 spinnerContext.phase = (spinnerContext.phase + 1) % ($spinnerPoints.length * 2); 28271 }, spinnerContext.timeSlot); 28272 }; 28273 28274 /** 28275 * Rewind the image analysis to start from the first entry. 28276 */ 28277 JustifiedGallery.prototype.rewind = function () { 28278 this.lastFetchedEntry = null; 28279 this.lastAnalyzedIndex = -1; 28280 this.offY = this.border; 28281 this.rows = 0; 28282 this.clearBuildingRow(); 28283 }; 28284 28285 /** 28286 * @returns {String} `settings.selector` rejecting spinner element 28287 */ 28288 JustifiedGallery.prototype.getSelectorWithoutSpinner = function () { 28289 return this.settings.selector + ', div:not(.jg-spinner)'; 28290 }; 28291 28292 /** 28293 * @returns {Array} all entries matched by `settings.selector` 28294 */ 28295 JustifiedGallery.prototype.getAllEntries = function () { 28296 var selector = this.getSelectorWithoutSpinner(); 28297 return this.$gallery.children(selector).toArray(); 28298 }; 28299 28300 /** 28301 * Update the entries searching it from the justified gallery HTML element 28302 * 28303 * @param norewind if norewind only the new entries will be changed (i.e. randomized, sorted or filtered) 28304 * @returns {boolean} true if some entries has been founded 28305 */ 28306 JustifiedGallery.prototype.updateEntries = function (norewind) { 28307 var newEntries; 28308 28309 if (norewind && this.lastFetchedEntry != null) { 28310 var selector = this.getSelectorWithoutSpinner(); 28311 newEntries = $(this.lastFetchedEntry).nextAll(selector).toArray(); 28312 } else { 28313 this.entries = []; 28314 newEntries = this.getAllEntries(); 28315 } 28316 28317 if (newEntries.length > 0) { 28318 28319 // Sort or randomize 28320 if ($.isFunction(this.settings.sort)) { 28321 newEntries = this.sortArray(newEntries); 28322 } else if (this.settings.randomize) { 28323 newEntries = this.shuffleArray(newEntries); 28324 } 28325 this.lastFetchedEntry = newEntries[newEntries.length - 1]; 28326 28327 // Filter 28328 if (this.settings.filter) { 28329 newEntries = this.filterArray(newEntries); 28330 } else { 28331 this.resetFilters(newEntries); 28332 } 28333 28334 } 28335 28336 this.entries = this.entries.concat(newEntries); 28337 return true; 28338 }; 28339 28340 /** 28341 * Apply the entries order to the DOM, iterating the entries and appending the images 28342 * 28343 * @param entries the entries that has been modified and that must be re-ordered in the DOM 28344 */ 28345 JustifiedGallery.prototype.insertToGallery = function (entries) { 28346 var that = this; 28347 $.each(entries, function () { 28348 $(this).appendTo(that.$gallery); 28349 }); 28350 }; 28351 28352 /** 28353 * Shuffle the array using the Fisher-Yates shuffle algorithm 28354 * 28355 * @param a the array to shuffle 28356 * @return the shuffled array 28357 */ 28358 JustifiedGallery.prototype.shuffleArray = function (a) { 28359 var i, j, temp; 28360 for (i = a.length - 1; i > 0; i--) { 28361 j = Math.floor(Math.random() * (i + 1)); 28362 temp = a[i]; 28363 a[i] = a[j]; 28364 a[j] = temp; 28365 } 28366 this.insertToGallery(a); 28367 return a; 28368 }; 28369 28370 /** 28371 * Sort the array using settings.comparator as comparator 28372 * 28373 * @param a the array to sort (it is sorted) 28374 * @return the sorted array 28375 */ 28376 JustifiedGallery.prototype.sortArray = function (a) { 28377 a.sort(this.settings.sort); 28378 this.insertToGallery(a); 28379 return a; 28380 }; 28381 28382 /** 28383 * Reset the filters removing the 'jg-filtered' class from all the entries 28384 * 28385 * @param a the array to reset 28386 */ 28387 JustifiedGallery.prototype.resetFilters = function (a) { 28388 for (var i = 0; i < a.length; i++) $(a[i]).removeClass('jg-filtered'); 28389 }; 28390 28391 /** 28392 * Filter the entries considering theirs classes (if a string has been passed) or using a function for filtering. 28393 * 28394 * @param a the array to filter 28395 * @return the filtered array 28396 */ 28397 JustifiedGallery.prototype.filterArray = function (a) { 28398 var settings = this.settings; 28399 if ($.type(settings.filter) === 'string') { 28400 // Filter only keeping the entries passed in the string 28401 return a.filter(function (el) { 28402 var $el = $(el); 28403 if ($el.is(settings.filter)) { 28404 $el.removeClass('jg-filtered'); 28405 return true; 28406 } else { 28407 $el.addClass('jg-filtered').removeClass('jg-visible'); 28408 return false; 28409 } 28410 }); 28411 } else if ($.isFunction(settings.filter)) { 28412 // Filter using the passed function 28413 var filteredArr = a.filter(settings.filter); 28414 for (var i = 0; i < a.length; i++) { 28415 if (filteredArr.indexOf(a[i]) === -1) { 28416 $(a[i]).addClass('jg-filtered').removeClass('jg-visible'); 28417 } else { 28418 $(a[i]).removeClass('jg-filtered'); 28419 } 28420 } 28421 return filteredArr; 28422 } 28423 }; 28424 28425 /** 28426 * Revert the image src to the default value. 28427 */ 28428 JustifiedGallery.prototype.resetImgSrc = function ($img) { 28429 if ($img.data('jg.originalSrcLoc') === 'src') { 28430 $img.attr('src', $img.data('jg.originalSrc')); 28431 } else { 28432 $img.attr('src', ''); 28433 } 28434 }; 28435 28436 /** 28437 * Destroy the Justified Gallery instance. 28438 * 28439 * It clears all the css properties added in the style attributes. We doesn't backup the original 28440 * values for those css attributes, because it costs (performance) and because in general one 28441 * shouldn't use the style attribute for an uniform set of images (where we suppose the use of 28442 * classes). Creating a backup is also difficult because JG could be called multiple times and 28443 * with different style attributes. 28444 */ 28445 JustifiedGallery.prototype.destroy = function () { 28446 clearInterval(this.checkWidthIntervalId); 28447 this.stopImgAnalyzerStarter(); 28448 28449 // Get fresh entries list since filtered entries are absent in `this.entries` 28450 $.each(this.getAllEntries(), $.proxy(function (_, entry) { 28451 var $entry = $(entry); 28452 28453 // Reset entry style 28454 $entry.css('width', ''); 28455 $entry.css('height', ''); 28456 $entry.css('top', ''); 28457 $entry.css('left', ''); 28458 $entry.data('jg.loaded', undefined); 28459 $entry.removeClass('jg-entry jg-filtered jg-entry-visible'); 28460 28461 // Reset image style 28462 var $img = this.imgFromEntry($entry); 28463 if ($img) { 28464 $img.css('width', ''); 28465 $img.css('height', ''); 28466 $img.css('margin-left', ''); 28467 $img.css('margin-top', ''); 28468 this.resetImgSrc($img); 28469 $img.data('jg.originalSrc', undefined); 28470 $img.data('jg.originalSrcLoc', undefined); 28471 $img.data('jg.src', undefined); 28472 } 28473 28474 // Remove caption 28475 this.removeCaptionEventsHandlers($entry); 28476 var $caption = this.captionFromEntry($entry); 28477 if ($entry.data('jg.createdCaption')) { 28478 // remove also the caption element (if created by jg) 28479 $entry.data('jg.createdCaption', undefined); 28480 if ($caption !== null) $caption.remove(); 28481 } else { 28482 if ($caption !== null) $caption.fadeTo(0, 1); 28483 } 28484 28485 }, this)); 28486 28487 this.$gallery.css('height', ''); 28488 this.$gallery.removeClass('justified-gallery'); 28489 this.$gallery.data('jg.controller', undefined); 28490 this.settings.triggerEvent.call(this, 'jg.destroy'); 28491 }; 28492 28493 /** 28494 * Analyze the images and builds the rows. It returns if it found an image that is not loaded. 28495 * 28496 * @param isForResize if the image analyzer is called for resizing or not, to call a different callback at the end 28497 */ 28498 JustifiedGallery.prototype.analyzeImages = function (isForResize) { 28499 for (var i = this.lastAnalyzedIndex + 1; i < this.entries.length; i++) { 28500 var $entry = $(this.entries[i]); 28501 if ($entry.data('jg.loaded') === true || $entry.data('jg.loaded') === 'skipped') { 28502 var availableWidth = this.galleryWidth - 2 * this.border - ( 28503 (this.buildingRow.entriesBuff.length - 1) * this.settings.margins); 28504 var imgAspectRatio = $entry.data('jg.width') / $entry.data('jg.height'); 28505 28506 this.buildingRow.entriesBuff.push($entry); 28507 this.buildingRow.aspectRatio += imgAspectRatio; 28508 this.buildingRow.width += imgAspectRatio * this.settings.rowHeight; 28509 this.lastAnalyzedIndex = i; 28510 28511 if (availableWidth / (this.buildingRow.aspectRatio + imgAspectRatio) < this.settings.rowHeight) { 28512 this.flushRow(false, this.settings.maxRowsCount > 0 && this.rows === this.settings.maxRowsCount); 28513 28514 if (++this.yield.flushed >= this.yield.every) { 28515 this.startImgAnalyzer(isForResize); 28516 return; 28517 } 28518 } 28519 } else if ($entry.data('jg.loaded') !== 'error') { 28520 return; 28521 } 28522 } 28523 28524 // Last row flush (the row is not full) 28525 if (this.buildingRow.entriesBuff.length > 0) { 28526 this.flushRow(true, this.settings.maxRowsCount > 0 && this.rows === this.settings.maxRowsCount); 28527 } 28528 28529 if (this.isSpinnerActive()) { 28530 this.stopLoadingSpinnerAnimation(); 28531 } 28532 28533 /* Stop, if there is, the timeout to start the analyzeImages. 28534 This is because an image can be set loaded, and the timeout can be set, 28535 but this image can be analyzed yet. 28536 */ 28537 this.stopImgAnalyzerStarter(); 28538 28539 this.setGalleryFinalHeight(this.galleryHeightToSet); 28540 28541 //On complete callback 28542 this.settings.triggerEvent.call(this, isForResize ? 'jg.resize' : 'jg.complete'); 28543 }; 28544 28545 /** 28546 * Stops any ImgAnalyzer starter (that has an assigned timeout) 28547 */ 28548 JustifiedGallery.prototype.stopImgAnalyzerStarter = function () { 28549 this.yield.flushed = 0; 28550 if (this.imgAnalyzerTimeout !== null) { 28551 clearTimeout(this.imgAnalyzerTimeout); 28552 this.imgAnalyzerTimeout = null; 28553 } 28554 }; 28555 28556 /** 28557 * Starts the image analyzer. It is not immediately called to let the browser to update the view 28558 * 28559 * @param isForResize specifies if the image analyzer must be called for resizing or not 28560 */ 28561 JustifiedGallery.prototype.startImgAnalyzer = function (isForResize) { 28562 var that = this; 28563 this.stopImgAnalyzerStarter(); 28564 this.imgAnalyzerTimeout = setTimeout(function () { 28565 that.analyzeImages(isForResize); 28566 }, 0.001); // we can't start it immediately due to a IE different behaviour 28567 }; 28568 28569 /** 28570 * Checks if the image is loaded or not using another image object. We cannot use the 'complete' image property, 28571 * because some browsers, with a 404 set complete = true. 28572 * 28573 * @param imageSrc the image src to load 28574 * @param onLoad callback that is called when the image has been loaded 28575 * @param onError callback that is called in case of an error 28576 */ 28577 JustifiedGallery.prototype.onImageEvent = function (imageSrc, onLoad, onError) { 28578 if (!onLoad && !onError) return; 28579 28580 var memImage = new Image(); 28581 var $memImage = $(memImage); 28582 if (onLoad) { 28583 $memImage.one('load', function () { 28584 $memImage.off('load error'); 28585 onLoad(memImage); 28586 }); 28587 } 28588 if (onError) { 28589 $memImage.one('error', function () { 28590 $memImage.off('load error'); 28591 onError(memImage); 28592 }); 28593 } 28594 memImage.src = imageSrc; 28595 }; 28596 28597 /** 28598 * Init of Justified Gallery controlled 28599 * It analyzes all the entries starting theirs loading and calling the image analyzer (that works with loaded images) 28600 */ 28601 JustifiedGallery.prototype.init = function () { 28602 var imagesToLoad = false, skippedImages = false, that = this; 28603 $.each(this.entries, function (index, entry) { 28604 var $entry = $(entry); 28605 var $image = that.imgFromEntry($entry); 28606 28607 $entry.addClass('jg-entry'); 28608 28609 if ($entry.data('jg.loaded') !== true && $entry.data('jg.loaded') !== 'skipped') { 28610 28611 // Link Rel global overwrite 28612 if (that.settings.rel !== null) $entry.attr('rel', that.settings.rel); 28613 28614 // Link Target global overwrite 28615 if (that.settings.target !== null) $entry.attr('target', that.settings.target); 28616 28617 if ($image !== null) { 28618 28619 // Image src 28620 var imageSrc = that.extractImgSrcFromImage($image); 28621 28622 /* If we have the height and the width, we don't wait that the image is loaded, 28623 but we start directly with the justification */ 28624 if (that.settings.waitThumbnailsLoad === false || !imageSrc) { 28625 var width = parseFloat($image.attr('width')); 28626 var height = parseFloat($image.attr('height')); 28627 if ($image.prop('tagName') === 'svg') { 28628 width = parseFloat($image[0].getBBox().width); 28629 height = parseFloat($image[0].getBBox().height); 28630 } 28631 if (!isNaN(width) && !isNaN(height)) { 28632 $entry.data('jg.width', width); 28633 $entry.data('jg.height', height); 28634 $entry.data('jg.loaded', 'skipped'); 28635 skippedImages = true; 28636 that.startImgAnalyzer(false); 28637 return true; // continue 28638 } 28639 } 28640 28641 $entry.data('jg.loaded', false); 28642 imagesToLoad = true; 28643 28644 // Spinner start 28645 if (!that.isSpinnerActive()) that.startLoadingSpinnerAnimation(); 28646 28647 that.onImageEvent(imageSrc, function (loadImg) { // image loaded 28648 $entry.data('jg.width', loadImg.width); 28649 $entry.data('jg.height', loadImg.height); 28650 $entry.data('jg.loaded', true); 28651 that.startImgAnalyzer(false); 28652 }, function () { // image load error 28653 $entry.data('jg.loaded', 'error'); 28654 that.startImgAnalyzer(false); 28655 }); 28656 28657 } else { 28658 $entry.data('jg.loaded', true); 28659 $entry.data('jg.width', $entry.width() | parseFloat($entry.css('width')) | 1); 28660 $entry.data('jg.height', $entry.height() | parseFloat($entry.css('height')) | 1); 28661 } 28662 28663 } 28664 28665 }); 28666 28667 if (!imagesToLoad && !skippedImages) this.startImgAnalyzer(false); 28668 this.checkWidth(); 28669 }; 28670 28671 /** 28672 * Checks that it is a valid number. If a string is passed it is converted to a number 28673 * 28674 * @param settingContainer the object that contains the setting (to allow the conversion) 28675 * @param settingName the setting name 28676 */ 28677 JustifiedGallery.prototype.checkOrConvertNumber = function (settingContainer, settingName) { 28678 if ($.type(settingContainer[settingName]) === 'string') { 28679 settingContainer[settingName] = parseFloat(settingContainer[settingName]); 28680 } 28681 28682 if ($.type(settingContainer[settingName]) === 'number') { 28683 if (isNaN(settingContainer[settingName])) throw 'invalid number for ' + settingName; 28684 } else { 28685 throw settingName + ' must be a number'; 28686 } 28687 }; 28688 28689 /** 28690 * Checks the sizeRangeSuffixes and, if necessary, converts 28691 * its keys from string (e.g. old settings with 'lt100') to int. 28692 */ 28693 JustifiedGallery.prototype.checkSizeRangesSuffixes = function () { 28694 if ($.type(this.settings.sizeRangeSuffixes) !== 'object') { 28695 throw 'sizeRangeSuffixes must be defined and must be an object'; 28696 } 28697 28698 var suffixRanges = []; 28699 for (var rangeIdx in this.settings.sizeRangeSuffixes) { 28700 if (this.settings.sizeRangeSuffixes.hasOwnProperty(rangeIdx)) suffixRanges.push(rangeIdx); 28701 } 28702 28703 var newSizeRngSuffixes = { 0: '' }; 28704 for (var i = 0; i < suffixRanges.length; i++) { 28705 if ($.type(suffixRanges[i]) === 'string') { 28706 try { 28707 var numIdx = parseInt(suffixRanges[i].replace(/^[a-z]+/, ''), 10); 28708 newSizeRngSuffixes[numIdx] = this.settings.sizeRangeSuffixes[suffixRanges[i]]; 28709 } catch (e) { 28710 throw 'sizeRangeSuffixes keys must contains correct numbers (' + e + ')'; 28711 } 28712 } else { 28713 newSizeRngSuffixes[suffixRanges[i]] = this.settings.sizeRangeSuffixes[suffixRanges[i]]; 28714 } 28715 } 28716 28717 this.settings.sizeRangeSuffixes = newSizeRngSuffixes; 28718 }; 28719 28720 /** 28721 * check and convert the maxRowHeight setting 28722 * requires rowHeight to be already set 28723 * TODO: should be always called when only rowHeight is changed 28724 * @return number or null 28725 */ 28726 JustifiedGallery.prototype.retrieveMaxRowHeight = function () { 28727 var newMaxRowHeight = null; 28728 var rowHeight = this.settings.rowHeight; 28729 28730 if ($.type(this.settings.maxRowHeight) === 'string') { 28731 if (this.settings.maxRowHeight.match(/^[0-9]+%$/)) { 28732 newMaxRowHeight = rowHeight * parseFloat(this.settings.maxRowHeight.match(/^([0-9]+)%$/)[1]) / 100; 28733 } else { 28734 newMaxRowHeight = parseFloat(this.settings.maxRowHeight); 28735 } 28736 } else if ($.type(this.settings.maxRowHeight) === 'number') { 28737 newMaxRowHeight = this.settings.maxRowHeight; 28738 } else if (this.settings.maxRowHeight === false || this.settings.maxRowHeight == null) { 28739 return null; 28740 } else { 28741 throw 'maxRowHeight must be a number or a percentage'; 28742 } 28743 28744 // check if the converted value is not a number 28745 if (isNaN(newMaxRowHeight)) throw 'invalid number for maxRowHeight'; 28746 28747 // check values, maxRowHeight must be >= rowHeight 28748 if (newMaxRowHeight < rowHeight) newMaxRowHeight = rowHeight; 28749 28750 return newMaxRowHeight; 28751 }; 28752 28753 /** 28754 * Checks the settings 28755 */ 28756 JustifiedGallery.prototype.checkSettings = function () { 28757 this.checkSizeRangesSuffixes(); 28758 28759 this.checkOrConvertNumber(this.settings, 'rowHeight'); 28760 this.checkOrConvertNumber(this.settings, 'margins'); 28761 this.checkOrConvertNumber(this.settings, 'border'); 28762 this.checkOrConvertNumber(this.settings, 'maxRowsCount'); 28763 28764 var lastRowModes = [ 28765 'justify', 28766 'nojustify', 28767 'left', 28768 'center', 28769 'right', 28770 'hide' 28771 ]; 28772 if (lastRowModes.indexOf(this.settings.lastRow) === -1) { 28773 throw 'lastRow must be one of: ' + lastRowModes.join(', '); 28774 } 28775 28776 this.checkOrConvertNumber(this.settings, 'justifyThreshold'); 28777 if (this.settings.justifyThreshold < 0 || this.settings.justifyThreshold > 1) { 28778 throw 'justifyThreshold must be in the interval [0,1]'; 28779 } 28780 if ($.type(this.settings.cssAnimation) !== 'boolean') { 28781 throw 'cssAnimation must be a boolean'; 28782 } 28783 28784 if ($.type(this.settings.captions) !== 'boolean') throw 'captions must be a boolean'; 28785 this.checkOrConvertNumber(this.settings.captionSettings, 'animationDuration'); 28786 28787 this.checkOrConvertNumber(this.settings.captionSettings, 'visibleOpacity'); 28788 if (this.settings.captionSettings.visibleOpacity < 0 || 28789 this.settings.captionSettings.visibleOpacity > 1) { 28790 throw 'captionSettings.visibleOpacity must be in the interval [0, 1]'; 28791 } 28792 28793 this.checkOrConvertNumber(this.settings.captionSettings, 'nonVisibleOpacity'); 28794 if (this.settings.captionSettings.nonVisibleOpacity < 0 || 28795 this.settings.captionSettings.nonVisibleOpacity > 1) { 28796 throw 'captionSettings.nonVisibleOpacity must be in the interval [0, 1]'; 28797 } 28798 28799 this.checkOrConvertNumber(this.settings, 'imagesAnimationDuration'); 28800 this.checkOrConvertNumber(this.settings, 'refreshTime'); 28801 this.checkOrConvertNumber(this.settings, 'refreshSensitivity'); 28802 if ($.type(this.settings.randomize) !== 'boolean') throw 'randomize must be a boolean'; 28803 if ($.type(this.settings.selector) !== 'string') throw 'selector must be a string'; 28804 28805 if (this.settings.sort !== false && !$.isFunction(this.settings.sort)) { 28806 throw 'sort must be false or a comparison function'; 28807 } 28808 28809 if (this.settings.filter !== false && !$.isFunction(this.settings.filter) && 28810 $.type(this.settings.filter) !== 'string') { 28811 throw 'filter must be false, a string or a filter function'; 28812 } 28813 }; 28814 28815 /** 28816 * It brings all the indexes from the sizeRangeSuffixes and it orders them. They are then sorted and returned. 28817 * @returns {Array} sorted suffix ranges 28818 */ 28819 JustifiedGallery.prototype.retrieveSuffixRanges = function () { 28820 var suffixRanges = []; 28821 for (var rangeIdx in this.settings.sizeRangeSuffixes) { 28822 if (this.settings.sizeRangeSuffixes.hasOwnProperty(rangeIdx)) suffixRanges.push(parseInt(rangeIdx, 10)); 28823 } 28824 suffixRanges.sort(function (a, b) { return a > b ? 1 : a < b ? -1 : 0; }); 28825 return suffixRanges; 28826 }; 28827 28828 /** 28829 * Update the existing settings only changing some of them 28830 * 28831 * @param newSettings the new settings (or a subgroup of them) 28832 */ 28833 JustifiedGallery.prototype.updateSettings = function (newSettings) { 28834 // In this case Justified Gallery has been called again changing only some options 28835 this.settings = $.extend({}, this.settings, newSettings); 28836 this.checkSettings(); 28837 28838 // As reported in the settings: negative value = same as margins, 0 = disabled 28839 this.border = this.settings.border >= 0 ? this.settings.border : this.settings.margins; 28840 28841 this.maxRowHeight = this.retrieveMaxRowHeight(); 28842 this.suffixRanges = this.retrieveSuffixRanges(); 28843 }; 28844 28845 JustifiedGallery.prototype.defaults = { 28846 sizeRangeSuffixes: {}, /* e.g. Flickr configuration 28847 { 28848 100: '_t', // used when longest is less than 100px 28849 240: '_m', // used when longest is between 101px and 240px 28850 320: '_n', // ... 28851 500: '', 28852 640: '_z', 28853 1024: '_b' // used as else case because it is the last 28854 } 28855 */ 28856 thumbnailPath: undefined, /* If defined, sizeRangeSuffixes is not used, and this function is used to determine the 28857 path relative to a specific thumbnail size. The function should accept respectively three arguments: 28858 current path, width and height */ 28859 rowHeight: 120, // required? required to be > 0? 28860 maxRowHeight: false, // false or negative value to deactivate. Positive number to express the value in pixels, 28861 // A string '[0-9]+%' to express in percentage (e.g. 300% means that the row height 28862 // can't exceed 3 * rowHeight) 28863 maxRowsCount: 0, // maximum number of rows to be displayed (0 = disabled) 28864 margins: 1, 28865 border: -1, // negative value = same as margins, 0 = disabled, any other value to set the border 28866 28867 lastRow: 'nojustify', // ⦠which is the same as 'left', or can be 'justify', 'center', 'right' or 'hide' 28868 28869 justifyThreshold: 0.90, /* if row width / available space > 0.90 it will be always justified 28870 * (i.e. lastRow setting is not considered) */ 28871 waitThumbnailsLoad: true, 28872 captions: true, 28873 cssAnimation: true, 28874 imagesAnimationDuration: 500, // ignored with css animations 28875 captionSettings: { // ignored with css animations 28876 animationDuration: 500, 28877 visibleOpacity: 0.7, 28878 nonVisibleOpacity: 0.0 28879 },
28880 rel: null, // rewrite the rel of each analyzed links 28881 target: null, // rewrite the target of all links 28882 extension: /\.[^.\\/]+$/, // regexp to capture the extension of an image 28883 refreshTime: 200, // time interval (in ms) to check if the page changes its width 28884 refreshSensitivity: 0, // change in width allowed (in px) without re-building the gallery 28885 randomize: false, 28886 rtl: false, // right-to-left mode 28887 sort: false, /* 28888 - false: to do not sort 28889 - function: to sort them using the function as comparator (see Array.prototype.sort()) 28890 */ 28891 filter: false, /* 28892 - false, null or undefined: for a disabled filter 28893 - a string: an entry is kept if entry.is(filter string) returns true 28894 see jQuery's .is() function for further information 28895 - a function: invoked with arguments (entry, index, array). Return true to keep the entry, false otherwise. 28896 It follows the specifications of the Array.prototype.filter() function of JavaScript. 28897 */ 28898 selector: 'a', // The selector that is used to know what are the entries of the gallery 28899 imgSelector: '> img, > a > img, > svg, > a > svg', // The selector that is used to know what are the images of each entry 28900 triggerEvent: function (event) { // This is called to trigger events, the default behavior is to call $.trigger 28901 this.$gallery.trigger(event); // Consider that 'this' is this set to the JustifiedGallery object, so it can 28902 } // access to fields such as $gallery, useful to trigger events with jQuery. 28903 }; 28904 28905 28906 /** 28907 * Justified Gallery plugin for jQuery 28908 * 28909 * Events 28910 * - jg.complete : called when all the gallery has been created 28911 * - jg.resize : called when the gallery has been resized 28912 * - jg.rowflush : when a new row appears 28913 * 28914 * @param arg the action (or the settings) passed when the plugin is called 28915 * @returns {*} the object itself 28916 */ 28917 $.fn.justifiedGallery = function (arg) { 28918 return this.each(function (index, gallery) { 28919 28920 var $gallery = $(gallery); 28921 $gallery.addClass('justified-gallery'); 28922 28923 var controller = $gallery.data('jg.controller'); 28924 if (typeof controller === 'undefined') { 28925 // Create controller and assign it to the object data 28926 if (typeof arg !== 'undefined' && arg !== null && $.type(arg) !== 'object') { 28927 if (arg === 'destroy') return; // Just a call to an unexisting object 28928 throw 'The argument must be an object'; 28929 } 28930 controller = new JustifiedGallery($gallery, $.extend({}, JustifiedGallery.prototype.defaults, arg)); 28931 $gallery.data('jg.controller', controller); 28932 } else if (arg === 'norewind') { 28933 // In this case we don't rewind: we analyze only the latest images (e.g. to complete the last unfinished row 28934 // ... left to be more readable 28935 } else if (arg === 'destroy') { 28936 controller.destroy(); 28937 return; 28938 } else { 28939 // In this case Justified Gallery has been called again changing only some options 28940 controller.updateSettings(arg); 28941 controller.rewind(); 28942 } 28943 28944 // Update the entries list 28945 if (!controller.updateEntries(arg === 'norewind')) return; 28946 28947 // Init justified gallery 28948 controller.init(); 28949 28950 }); 28951 }; 28952 28953})); 28954 28955/*! 28956* Customized version of iScroll.js 0.0.1 28957* It fixes bugs affecting its integration with fullpage.js 28958*/ 28959/*! iScroll v5.2.0 ~ (c) 2008-2016 Matteo Spinelli ~ http://cubiq.org/license */ 28960(function (window, document, Math) { 28961var rAF = window.requestAnimationFrame || 28962 window.webkitRequestAnimationFrame || 28963 window.mozRequestAnimationFrame || 28964 window.oRequestAnimationFrame || 28965 window.msRequestAnimationFrame || 28966 function (callback) { window.setTimeout(callback, 1000 / 60); }; 28967 28968var utils = (function () { 28969 var me = {}; 28970 28971 var _elementStyle = document.createElement('div').style; 28972 var _vendor = (function () { 28973 var vendors = ['t', 'webkitT', 'MozT', 'msT', 'OT'], 28974 transform, 28975 i = 0, 28976 l = vendors.length; 28977 28978 for ( ; i < l; i++ ) { 28979 transform = vendors[i] + 'ransform'; 28980 if ( transform in _elementStyle ) return vendors[i].substr(0, vendors[i].length-1); 28981 } 28982 28983 return false;
vendor: 5,154 bytes, lines 28984-29136
28984 })(); 28985 28986 function _prefixStyle (style) { 28987 if ( _vendor === false ) return false; 28988 if ( _vendor === '' ) return style; 28989 return _vendor + style.charAt(0).toUpperCase() + style.substr(1); 28990 } 28991 28992 me.getTime = Date.now || function getTime () { return new Date().getTime(); }; 28993 28994 me.extend = function (target, obj) { 28995 for ( var i in obj ) { 28996 target[i] = obj[i]; 28997 } 28998 }; 28999 29000 me.addEvent = function (el, type, fn, capture) { 29001 el.addEventListener(type, fn, !!capture); 29002 }; 29003 29004 me.removeEvent = function (el, type, fn, capture) { 29005 el.removeEventListener(type, fn, !!capture); 29006 }; 29007 29008 me.prefixPointerEvent = function (pointerEvent) { 29009 return window.MSPointerEvent ? 29010 'MSPointer' + pointerEvent.charAt(7).toUpperCase() + pointerEvent.substr(8): 29011 pointerEvent; 29012 }; 29013 29014 me.momentum = function (current, start, time, lowerMargin, wrapperSize, deceleration) { 29015 var distance = current - start, 29016 speed = Math.abs(distance) / time, 29017 destination, 29018 duration; 29019 29020 deceleration = deceleration === undefined ? 0.0006 : deceleration; 29021 29022 destination = current + ( speed * speed ) / ( 2 * deceleration ) * ( distance < 0 ? -1 : 1 ); 29023 duration = speed / deceleration; 29024 29025 if ( destination < lowerMargin ) { 29026 destination = wrapperSize ? lowerMargin - ( wrapperSize / 2.5 * ( speed / 8 ) ) : lowerMargin; 29027 distance = Math.abs(destination - current); 29028 duration = distance / speed; 29029 } else if ( destination > 0 ) { 29030 destination = wrapperSize ? wrapperSize / 2.5 * ( speed / 8 ) : 0; 29031 distance = Math.abs(current) + destination; 29032 duration = distance / speed; 29033 } 29034 29035 return { 29036 destination: Math.round(destination), 29037 duration: duration 29038 }; 29039 }; 29040 29041 var _transform = _prefixStyle('transform'); 29042 29043 me.extend(me, { 29044 hasTransform: _transform !== false, 29045 hasPerspective: _prefixStyle('perspective') in _elementStyle, 29046 hasTouch: 'ontouchstart' in window, 29047 hasPointer: !!(window.PointerEvent || window.MSPointerEvent), // IE10 is prefixed 29048 hasTransition: _prefixStyle('transition') in _elementStyle 29049 }); 29050 29051 /* 29052 This should find all Android browsers lower than build 535.19 (both stock browser and webview) 29053 - galaxy S2 is ok 29054 - 2.3.6 : `AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1` 29055 - 4.0.4 : `AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30` 29056 - galaxy S3 is badAndroid (stock brower, webview) 29057 `AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30` 29058 - galaxy S4 is badAndroid (stock brower, webview) 29059 `AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30` 29060 - galaxy S5 is OK 29061 `AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Mobile Safari/537.36 (Chrome/)` 29062 - galaxy S6 is OK 29063 `AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Mobile Safari/537.36 (Chrome/)` 29064 */ 29065 me.isBadAndroid = (function() { 29066 var appVersion = window.navigator.appVersion; 29067 // Android browser is not a chrome browser. 29068 if (/Android/.test(appVersion) && !(/Chrome\/\d/.test(appVersion))) { 29069 var safariVersion = appVersion.match(/Safari\/(\d+.\d)/); 29070 if(safariVersion && typeof safariVersion === "object" && safariVersion.length >= 2) { 29071 return parseFloat(safariVersion[1]) < 535.19; 29072 } else { 29073 return true; 29074 } 29075 } else { 29076 return false; 29077 } 29078 })(); 29079 29080 me.extend(me.style = {}, { 29081 transform: _transform, 29082 transitionTimingFunction: _prefixStyle('transitionTimingFunction'), 29083 transitionDuration: _prefixStyle('transitionDuration'), 29084 transitionDelay: _prefixStyle('transitionDelay'), 29085 transformOrigin: _prefixStyle('transformOrigin') 29086 }); 29087 29088 me.hasClass = function (e, c) { 29089 var re = new RegExp("(^|\\s)" + c + "(\\s|$)"); 29090 return re.test(e.className); 29091 }; 29092 29093 me.addClass = function (e, c) { 29094 if ( me.hasClass(e, c) ) { 29095 return; 29096 } 29097 29098 var newclass = e.className.split(' '); 29099 newclass.push(c); 29100 e.className = newclass.join(' '); 29101 }; 29102 29103 me.removeClass = function (e, c) { 29104 if ( !me.hasClass(e, c) ) { 29105 return; 29106 } 29107 29108 var re = new RegExp("(^|\\s)" + c + "(\\s|$)", 'g'); 29109 e.className = e.className.replace(re, ' '); 29110 }; 29111 29112 me.offset = function (el) { 29113 var left = -el.offsetLeft, 29114 top = -el.offsetTop; 29115 29116 // jshint -W084 29117 while (el = el.offsetParent) { 29118 left -= el.offsetLeft; 29119 top -= el.offsetTop; 29120 } 29121 // jshint +W084 29122 29123 return { 29124 left: left, 29125 top: top 29126 }; 29127 }; 29128 29129 me.preventDefaultException = function (el, exceptions) { 29130 for ( var i in exceptions ) { 29131 if ( exceptions[i].test(el[i]) ) { 29132 return true; 29133 } 29134 } 29135 29136 return false;
vendor: 5,660 bytes, lines 29137-29302
29137 }; 29138 29139 me.extend(me.eventType = {}, { 29140 touchstart: 1, 29141 touchmove: 1, 29142 touchend: 1, 29143 29144 mousedown: 2, 29145 mousemove: 2, 29146 mouseup: 2, 29147 29148 pointerdown: 3, 29149 pointermove: 3, 29150 pointerup: 3, 29151 29152 MSPointerDown: 3, 29153 MSPointerMove: 3, 29154 MSPointerUp: 3 29155 }); 29156 29157 me.extend(me.ease = {}, { 29158 quadratic: { 29159 style: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)', 29160 fn: function (k) { 29161 return k * ( 2 - k ); 29162 } 29163 }, 29164 circular: { 29165 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) 29166 fn: function (k) { 29167 return Math.sqrt( 1 - ( --k * k ) ); 29168 } 29169 }, 29170 back: { 29171 style: 'cubic-bezier(0.175, 0.885, 0.32, 1.275)', 29172 fn: function (k) { 29173 var b = 4; 29174 return ( k = k - 1 ) * k * ( ( b + 1 ) * k + b ) + 1; 29175 } 29176 }, 29177 bounce: { 29178 style: '', 29179 fn: function (k) { 29180 if ( ( k /= 1 ) < ( 1 / 2.75 ) ) { 29181 return 7.5625 * k * k; 29182 } else if ( k < ( 2 / 2.75 ) ) { 29183 return 7.5625 * ( k -= ( 1.5 / 2.75 ) ) * k + 0.75; 29184 } else if ( k < ( 2.5 / 2.75 ) ) { 29185 return 7.5625 * ( k -= ( 2.25 / 2.75 ) ) * k + 0.9375; 29186 } else { 29187 return 7.5625 * ( k -= ( 2.625 / 2.75 ) ) * k + 0.984375; 29188 } 29189 } 29190 }, 29191 elastic: { 29192 style: '', 29193 fn: function (k) { 29194 var f = 0.22, 29195 e = 0.4; 29196 29197 if ( k === 0 ) { return 0; } 29198 if ( k == 1 ) { return 1; } 29199 29200 return ( e * Math.pow( 2, - 10 * k ) * Math.sin( ( k - f / 4 ) * ( 2 * Math.PI ) / f ) + 1 ); 29201 } 29202 } 29203 }); 29204 29205 me.tap = function (e, eventName) { 29206 var ev = document.createEvent('Event'); 29207 ev.initEvent(eventName, true, true); 29208 ev.pageX = e.pageX; 29209 ev.pageY = e.pageY; 29210 e.target.dispatchEvent(ev); 29211 }; 29212 29213 me.click = function (e) { 29214 var target = e.target, 29215 ev; 29216 29217 if ( !(/(SELECT|INPUT|TEXTAREA)/i).test(target.tagName) ) { 29218 // https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/initMouseEvent 29219 // initMouseEvent is deprecated. 29220 ev = document.createEvent(window.MouseEvent ? 'MouseEvents' : 'Event'); 29221 ev.initEvent('click', true, true); 29222 ev.view = e.view || window; 29223 ev.detail = 1; 29224 ev.screenX = target.screenX || 0; 29225 ev.screenY = target.screenY || 0; 29226 ev.clientX = target.clientX || 0; 29227 ev.clientY = target.clientY || 0; 29228 ev.ctrlKey = !!e.ctrlKey; 29229 ev.altKey = !!e.altKey; 29230 ev.shiftKey = !!e.shiftKey; 29231 ev.metaKey = !!e.metaKey; 29232 ev.button = 0; 29233 ev.relatedTarget = null; 29234 ev._constructed = true; 29235 target.dispatchEvent(ev); 29236 } 29237 }; 29238 29239 return me; 29240})(); 29241function IScroll (el, options) { 29242 this.wrapper = typeof el == 'string' ? document.querySelector(el) : el; 29243 this.scroller = this.wrapper.children[0]; 29244 this.scrollerStyle = this.scroller.style; // cache style for better performance 29245 29246 this.options = { 29247 29248 resizeScrollbars: true, 29249 29250 mouseWheelSpeed: 20, 29251 29252 snapThreshold: 0.334, 29253 29254// INSERT POINT: OPTIONS 29255 disablePointer : !utils.hasPointer, 29256 disableTouch : utils.hasPointer || !utils.hasTouch, 29257 disableMouse : utils.hasPointer || utils.hasTouch, 29258 startX: 0, 29259 startY: 0, 29260 scrollY: true, 29261 directionLockThreshold: 5, 29262 momentum: true, 29263 29264 bounce: true, 29265 bounceTime: 600, 29266 bounceEasing: '', 29267 29268 preventDefault: true, 29269 preventDefaultException: { tagName: /^(INPUT|TEXTAREA|BUTTON|SELECT|LABEL)$/ }, 29270 29271 HWCompositing: true, 29272 useTransition: true, 29273 useTransform: true, 29274 bindToWrapper: typeof window.onmousedown === "undefined" 29275 }; 29276 29277 for ( var i in options ) { 29278 this.options[i] = options[i]; 29279 } 29280 29281 // Normalize options 29282 this.translateZ = this.options.HWCompositing && utils.hasPerspective ? ' translateZ(0)' : ''; 29283 29284 this.options.useTransition = utils.hasTransition && this.options.useTransition; 29285 this.options.useTransform = utils.hasTransform && this.options.useTransform; 29286 29287 this.options.eventPassthrough = this.options.eventPassthrough === true ? 'vertical' : this.options.eventPassthrough; 29288 this.options.preventDefault = !this.options.eventPassthrough && this.options.preventDefault; 29289 29290 // If you want eventPassthrough I have to lock one of the axes 29291 this.options.scrollY = this.options.eventPassthrough == 'vertical' ? false : this.options.scrollY; 29292 this.options.scrollX = this.options.eventPassthrough == 'horizontal' ? false : this.options.scrollX; 29293 29294 // With eventPassthrough we also need lockDirection mechanism 29295 this.options.freeScroll = this.options.freeScroll && !this.options.eventPassthrough; 29296 this.options.directionLockThreshold = this.options.eventPassthrough ? 0 : this.options.directionLockThreshold; 29297 29298 this.options.bounceEasing = typeof this.options.bounceEasing == 'string' ? utils.ease[this.options.bounceEasing] || utils.ease.circular : this.options.bounceEasing; 29299 29300 this.options.resizePolling = this.options.resizePolling === undefined ? 60 : this.options.resizePolling; 29301 29302 if ( this.options.tap === true ) {
vendor: 4,893 bytes, lines 29303-29474
29303 this.options.tap = 'tap'; 29304 } 29305 29306 // https://github.com/cubiq/iscroll/issues/1029 29307 if (!this.options.useTransition && !this.options.useTransform) { 29308 if(!(/relative|absolute/i).test(this.scrollerStyle.position)) { 29309 this.scrollerStyle.position = "relative"; 29310 } 29311 } 29312 29313 if ( this.options.shrinkScrollbars == 'scale' ) { 29314 this.options.useTransition = false; 29315 } 29316 29317 this.options.invertWheelDirection = this.options.invertWheelDirection ? -1 : 1; 29318 29319// INSERT POINT: NORMALIZATION 29320 29321 // Some defaults 29322 this.x = 0; 29323 this.y = 0; 29324 this.directionX = 0; 29325 this.directionY = 0; 29326 this._events = {}; 29327 29328// INSERT POINT: DEFAULTS 29329 29330 this._init(); 29331 this.refresh(); 29332 29333 this.scrollTo(this.options.startX, this.options.startY); 29334 this.enable(); 29335} 29336 29337IScroll.prototype = { 29338 version: '5.2.0', 29339 29340 _init: function () { 29341 this._initEvents(); 29342 29343 if ( this.options.scrollbars || this.options.indicators ) { 29344 this._initIndicators(); 29345 } 29346 29347 if ( this.options.mouseWheel ) { 29348 this._initWheel(); 29349 } 29350 29351 if ( this.options.snap ) { 29352 this._initSnap(); 29353 } 29354 29355 if ( this.options.keyBindings ) { 29356 this._initKeys(); 29357 } 29358 29359// INSERT POINT: _init 29360 29361 }, 29362 29363 destroy: function () { 29364 this._initEvents(true); 29365 clearTimeout(this.resizeTimeout); 29366 this.resizeTimeout = null; 29367 this._execEvent('destroy'); 29368 }, 29369 29370 _transitionEnd: function (e) { 29371 if ( e.target != this.scroller || !this.isInTransition ) { 29372 return; 29373 } 29374 29375 this._transitionTime(); 29376 if ( !this.resetPosition(this.options.bounceTime) ) { 29377 this.isInTransition = false; 29378 this._execEvent('scrollEnd'); 29379 } 29380 }, 29381 29382 _start: function (e) { 29383 // React to left mouse button only 29384 if ( utils.eventType[e.type] != 1 ) { 29385 // for button property 29386 // http://unixpapa.com/js/mouse.html 29387 var button; 29388 if (!e.which) { 29389 /* IE case */ 29390 button = (e.button < 2) ? 0 : 29391 ((e.button == 4) ? 1 : 2); 29392 } else { 29393 /* All others */ 29394 button = e.button; 29395 } 29396 if ( button !== 0 ) { 29397 return; 29398 } 29399 } 29400 29401 if ( !this.enabled || (this.initiated && utils.eventType[e.type] !== this.initiated) ) { 29402 return; 29403 } 29404 29405 if ( this.options.preventDefault && !utils.isBadAndroid && !utils.preventDefaultException(e.target, this.options.preventDefaultException) ) { 29406 e.preventDefault(); 29407 } 29408 29409 var point = e.touches ? e.touches[0] : e, 29410 pos; 29411 29412 this.initiated = utils.eventType[e.type]; 29413 this.moved = false; 29414 this.distX = 0; 29415 this.distY = 0; 29416 this.directionX = 0; 29417 this.directionY = 0; 29418 this.directionLocked = 0; 29419 29420 this.startTime = utils.getTime(); 29421 29422 if ( this.options.useTransition && this.isInTransition ) { 29423 this._transitionTime(); 29424 this.isInTransition = false; 29425 pos = this.getComputedPosition(); 29426 this._translate(Math.round(pos.x), Math.round(pos.y)); 29427 this._execEvent('scrollEnd'); 29428 } else if ( !this.options.useTransition && this.isAnimating ) { 29429 this.isAnimating = false; 29430 this._execEvent('scrollEnd'); 29431 } 29432 29433 this.startX = this.x; 29434 this.startY = this.y; 29435 this.absStartX = this.x; 29436 this.absStartY = this.y; 29437 this.pointX = point.pageX; 29438 this.pointY = point.pageY; 29439 29440 this._execEvent('beforeScrollStart'); 29441 }, 29442 29443 _move: function (e) { 29444 if ( !this.enabled || utils.eventType[e.type] !== this.initiated ) { 29445 return; 29446 } 29447 29448 if ( this.options.preventDefault ) { // increases performance on Android? TODO: check! 29449 e.preventDefault(); 29450 } 29451 29452 var point = e.touches ? e.touches[0] : e, 29453 deltaX = point.pageX - this.pointX, 29454 deltaY = point.pageY - this.pointY, 29455 timestamp = utils.getTime(), 29456 newX, newY, 29457 absDistX, absDistY; 29458 29459 this.pointX = point.pageX; 29460 this.pointY = point.pageY; 29461 29462 this.distX += deltaX; 29463 this.distY += deltaY; 29464 absDistX = Math.abs(this.distX); 29465 absDistY = Math.abs(this.distY); 29466 29467 // We need to move at least 10 pixels for the scrolling to initiate 29468 if ( timestamp - this.endTime > 300 && (absDistX < 10 && absDistY < 10) ) { 29469 return; 29470 } 29471 29472 // If you are scrolling in one direction lock the other 29473 if ( !this.directionLocked && !this.options.freeScroll ) { 29474 if ( absDistX > absDistY + this.options.directionLockThreshold ) {
vendor: 6,057 bytes, lines 29475-29661
29475 this.directionLocked = 'h'; // lock horizontally 29476 } else if ( absDistY >= absDistX + this.options.directionLockThreshold ) { 29477 this.directionLocked = 'v'; // lock vertically 29478 } else { 29479 this.directionLocked = 'n'; // no lock 29480 } 29481 } 29482 29483 if ( this.directionLocked == 'h' ) { 29484 if ( this.options.eventPassthrough == 'vertical' ) { 29485 e.preventDefault(); 29486 } else if ( this.options.eventPassthrough == 'horizontal' ) { 29487 this.initiated = false; 29488 return; 29489 } 29490 29491 deltaY = 0; 29492 } else if ( this.directionLocked == 'v' ) { 29493 if ( this.options.eventPassthrough == 'horizontal' ) { 29494 e.preventDefault(); 29495 } else if ( this.options.eventPassthrough == 'vertical' ) { 29496 this.initiated = false; 29497 return; 29498 } 29499 29500 deltaX = 0; 29501 } 29502 29503 deltaX = this.hasHorizontalScroll ? deltaX : 0; 29504 deltaY = this.hasVerticalScroll ? deltaY : 0; 29505 29506 newX = this.x + deltaX; 29507 newY = this.y + deltaY; 29508 29509 // Slow down if outside of the boundaries 29510 if ( newX > 0 || newX < this.maxScrollX ) { 29511 newX = this.options.bounce ? this.x + deltaX / 3 : newX > 0 ? 0 : this.maxScrollX; 29512 } 29513 if ( newY > 0 || newY < this.maxScrollY ) { 29514 newY = this.options.bounce ? this.y + deltaY / 3 : newY > 0 ? 0 : this.maxScrollY; 29515 } 29516 29517 this.directionX = deltaX > 0 ? -1 : deltaX < 0 ? 1 : 0; 29518 this.directionY = deltaY > 0 ? -1 : deltaY < 0 ? 1 : 0; 29519 29520 if ( !this.moved ) { 29521 this._execEvent('scrollStart'); 29522 } 29523 29524 this.moved = true; 29525 29526 this._translate(newX, newY); 29527 29528/* REPLACE START: _move */ 29529 29530 if ( timestamp - this.startTime > 300 ) { 29531 this.startTime = timestamp; 29532 this.startX = this.x; 29533 this.startY = this.y; 29534 } 29535 29536/* REPLACE END: _move */ 29537 29538 }, 29539 29540 _end: function (e) { 29541 if ( !this.enabled || utils.eventType[e.type] !== this.initiated ) { 29542 return; 29543 } 29544 29545 if ( this.options.preventDefault && !utils.preventDefaultException(e.target, this.options.preventDefaultException) ) { 29546 e.preventDefault(); 29547 } 29548 29549 var point = e.changedTouches ? e.changedTouches[0] : e, 29550 momentumX, 29551 momentumY, 29552 duration = utils.getTime() - this.startTime, 29553 newX = Math.round(this.x), 29554 newY = Math.round(this.y), 29555 distanceX = Math.abs(newX - this.startX), 29556 distanceY = Math.abs(newY - this.startY), 29557 time = 0, 29558 easing = ''; 29559 29560 this.isInTransition = 0; 29561 this.initiated = 0; 29562 this.endTime = utils.getTime(); 29563 29564 // reset if we are outside of the boundaries 29565 if ( this.resetPosition(this.options.bounceTime) ) { 29566 return; 29567 } 29568 29569 this.scrollTo(newX, newY); // ensures that the last position is rounded 29570 29571 // we scrolled less than 10 pixels 29572 if ( !this.moved ) { 29573 if ( this.options.tap ) { 29574 utils.tap(e, this.options.tap); 29575 } 29576 29577 if ( this.options.click ) { 29578 utils.click(e); 29579 } 29580 29581 this._execEvent('scrollCancel'); 29582 return; 29583 } 29584 29585 if ( this._events.flick && duration < 200 && distanceX < 100 && distanceY < 100 ) { 29586 this._execEvent('flick'); 29587 return; 29588 } 29589 29590 // start momentum animation if needed 29591 if ( this.options.momentum && duration < 300 ) { 29592 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 }; 29593 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 }; 29594 newX = momentumX.destination; 29595 newY = momentumY.destination; 29596 time = Math.max(momentumX.duration, momentumY.duration); 29597 this.isInTransition = 1; 29598 } 29599 29600 29601 if ( this.options.snap ) { 29602 var snap = this._nearestSnap(newX, newY); 29603 this.currentPage = snap; 29604 time = this.options.snapSpeed || Math.max( 29605 Math.max( 29606 Math.min(Math.abs(newX - snap.x), 1000), 29607 Math.min(Math.abs(newY - snap.y), 1000) 29608 ), 300); 29609 newX = snap.x; 29610 newY = snap.y; 29611 29612 this.directionX = 0; 29613 this.directionY = 0; 29614 easing = this.options.bounceEasing; 29615 } 29616 29617// INSERT POINT: _end 29618 29619 if ( newX != this.x || newY != this.y ) { 29620 // change easing function when scroller goes out of the boundaries 29621 if ( newX > 0 || newX < this.maxScrollX || newY > 0 || newY < this.maxScrollY ) { 29622 easing = utils.ease.quadratic; 29623 } 29624 29625 this.scrollTo(newX, newY, time, easing); 29626 return; 29627 } 29628 29629 this._execEvent('scrollEnd'); 29630 }, 29631 29632 _resize: function () { 29633 var that = this; 29634 29635 clearTimeout(this.resizeTimeout); 29636 29637 this.resizeTimeout = setTimeout(function () { 29638 that.refresh(); 29639 }, this.options.resizePolling); 29640 }, 29641 29642 resetPosition: function (time) { 29643 var x = this.x, 29644 y = this.y; 29645 29646 time = time || 0; 29647 29648 if ( !this.hasHorizontalScroll || this.x > 0 ) { 29649 x = 0; 29650 } else if ( this.x < this.maxScrollX ) { 29651 x = this.maxScrollX; 29652 } 29653 29654 if ( !this.hasVerticalScroll || this.y > 0 ) { 29655 y = 0; 29656 } else if ( this.y < this.maxScrollY ) { 29657 y = this.maxScrollY; 29658 } 29659 29660 if ( x == this.x && y == this.y ) { 29661 return false;
vendor: 5,509 bytes, lines 29662-29866
29662 } 29663 29664 this.scrollTo(x, y, time, this.options.bounceEasing); 29665 29666 return true; 29667 }, 29668 29669 disable: function () { 29670 this.enabled = false; 29671 }, 29672 29673 enable: function () { 29674 this.enabled = true; 29675 }, 29676 29677 refresh: function () { 29678 var rf = this.wrapper.offsetHeight; // Force reflow 29679 29680 this.wrapperWidth = this.wrapper.clientWidth; 29681 this.wrapperHeight = this.wrapper.clientHeight; 29682 29683/* REPLACE START: refresh */ 29684 29685 this.scrollerWidth = this.scroller.offsetWidth; 29686 this.scrollerHeight = this.scroller.offsetHeight; 29687 29688 this.maxScrollX = this.wrapperWidth - this.scrollerWidth; 29689 this.maxScrollY = this.wrapperHeight - this.scrollerHeight; 29690 29691/* REPLACE END: refresh */ 29692 29693 this.hasHorizontalScroll = this.options.scrollX && this.maxScrollX < 0; 29694 this.hasVerticalScroll = this.options.scrollY && this.maxScrollY < 0; 29695 29696 if ( !this.hasHorizontalScroll ) { 29697 this.maxScrollX = 0; 29698 this.scrollerWidth = this.wrapperWidth; 29699 } 29700 29701 if ( !this.hasVerticalScroll ) { 29702 this.maxScrollY = 0; 29703 this.scrollerHeight = this.wrapperHeight; 29704 } 29705 29706 this.endTime = 0; 29707 this.directionX = 0; 29708 this.directionY = 0; 29709 29710 this.wrapperOffset = utils.offset(this.wrapper); 29711 29712 this._execEvent('refresh'); 29713 29714 this.resetPosition(); 29715 29716// INSERT POINT: _refresh 29717 29718 }, 29719 29720 29721 on: function (type, fn) { 29722 if ( !this._events[type] ) { 29723 this._events[type] = []; 29724 } 29725 29726 this._events[type].push(fn); 29727 }, 29728 29729 off: function (type, fn) { 29730 if ( !this._events[type] ) { 29731 return; 29732 } 29733 29734 var index = this._events[type].indexOf(fn); 29735 29736 if ( index > -1 ) { 29737 this._events[type].splice(index, 1); 29738 } 29739 }, 29740 29741 _execEvent: function (type) { 29742 if ( !this._events[type] ) { 29743 return; 29744 } 29745 29746 var i = 0, 29747 l = this._events[type].length; 29748 29749 if ( !l ) { 29750 return; 29751 } 29752 29753 for ( ; i < l; i++ ) { 29754 this._events[type][i].apply(this, [].slice.call(arguments, 1)); 29755 } 29756 }, 29757 29758 scrollBy: function (x, y, time, easing) { 29759 x = this.x + x; 29760 y = this.y + y; 29761 time = time || 0; 29762 29763 this.scrollTo(x, y, time, easing); 29764 }, 29765 29766 scrollTo: function (x, y, time, easing) { 29767 easing = easing || utils.ease.circular; 29768 29769 this.isInTransition = this.options.useTransition && time > 0; 29770 var transitionType = this.options.useTransition && easing.style; 29771 if ( !time || transitionType ) { 29772 if(transitionType) { 29773 this._transitionTimingFunction(easing.style); 29774 this._transitionTime(time); 29775 } 29776 this._translate(x, y); 29777 } else { 29778 this._animate(x, y, time, easing.fn); 29779 } 29780 }, 29781 29782 scrollToElement: function (el, time, offsetX, offsetY, easing) { 29783 el = el.nodeType ? el : this.scroller.querySelector(el); 29784 29785 if ( !el ) { 29786 return; 29787 } 29788 29789 var pos = utils.offset(el); 29790 29791 pos.left -= this.wrapperOffset.left; 29792 pos.top -= this.wrapperOffset.top; 29793 29794 // if offsetX/Y are true we center the element to the screen 29795 if ( offsetX === true ) { 29796 offsetX = Math.round(el.offsetWidth / 2 - this.wrapper.offsetWidth / 2); 29797 } 29798 if ( offsetY === true ) { 29799 offsetY = Math.round(el.offsetHeight / 2 - this.wrapper.offsetHeight / 2); 29800 } 29801 29802 pos.left -= offsetX || 0; 29803 pos.top -= offsetY || 0; 29804 29805 pos.left = pos.left > 0 ? 0 : pos.left < this.maxScrollX ? this.maxScrollX : pos.left; 29806 pos.top = pos.top > 0 ? 0 : pos.top < this.maxScrollY ? this.maxScrollY : pos.top; 29807 29808 time = time === undefined || time === null || time === 'auto' ? Math.max(Math.abs(this.x-pos.left), Math.abs(this.y-pos.top)) : time; 29809 29810 this.scrollTo(pos.left, pos.top, time, easing); 29811 }, 29812 29813 _transitionTime: function (time) { 29814 if (!this.options.useTransition) { 29815 return; 29816 } 29817 time = time || 0; 29818 var durationProp = utils.style.transitionDuration; 29819 if(!durationProp) { 29820 return; 29821 } 29822 29823 this.scrollerStyle[durationProp] = time + 'ms'; 29824 29825 if ( !time && utils.isBadAndroid ) { 29826 this.scrollerStyle[durationProp] = '0.0001ms'; 29827 // remove 0.0001ms 29828 var self = this; 29829 rAF(function() { 29830 if(self.scrollerStyle[durationProp] === '0.0001ms') { 29831 self.scrollerStyle[durationProp] = '0s'; 29832 } 29833 }); 29834 } 29835 29836 29837 if ( this.indicators ) { 29838 for ( var i = this.indicators.length; i--; ) { 29839 this.indicators[i].transitionTime(time); 29840 } 29841 } 29842 29843 29844// INSERT POINT: _transitionTime 29845 29846 }, 29847 29848 _transitionTimingFunction: function (easing) { 29849 this.scrollerStyle[utils.style.transitionTimingFunction] = easing; 29850 29851 29852 if ( this.indicators ) { 29853 for ( var i = this.indicators.length; i--; ) { 29854 this.indicators[i].transitionTimingFunction(easing); 29855 } 29856 } 29857 29858 29859// INSERT POINT: _transitionTimingFunction 29860 29861 }, 29862 29863 _translate: function (x, y) { 29864 //Uncode addition 29865 if ( (" " + this.wrapper.className + " ").replace(/[\n\t]/g, " ").indexOf(" no-scrolloverflow ") > -1 ) 29866 return false;
vendor: 9,939 bytes, lines 29867-30178
29867 29868 if ( this.options.useTransform ) { 29869 29870/* REPLACE START: _translate */ 29871 29872 this.scrollerStyle[utils.style.transform] = 'translate(' + x + 'px,' + y + 'px)' + this.translateZ; 29873 29874/* REPLACE END: _translate */ 29875 29876 } else { 29877 x = Math.round(x); 29878 y = Math.round(y); 29879 this.scrollerStyle.left = x + 'px'; 29880 this.scrollerStyle.top = y + 'px'; 29881 } 29882 29883 this.x = x; 29884 this.y = y; 29885 29886 29887 if ( this.indicators ) { 29888 for ( var i = this.indicators.length; i--; ) { 29889 this.indicators[i].updatePosition(); 29890 } 29891 } 29892 29893 //Uncode addition 29894 var uncodevent = new CustomEvent('fp-slide-scroll'); 29895 window.dispatchEvent(uncodevent); 29896 29897// INSERT POINT: _translate 29898 29899 }, 29900 29901 _initEvents: function (remove) { 29902 var eventType = remove ? utils.removeEvent : utils.addEvent, 29903 target = this.options.bindToWrapper ? this.wrapper : window; 29904 29905 eventType(window, 'orientationchange', this); 29906 eventType(window, 'resize', this); 29907 29908 if ( this.options.click ) { 29909 eventType(this.wrapper, 'click', this, true); 29910 } 29911 29912 if ( !this.options.disableMouse ) { 29913 eventType(this.wrapper, 'mousedown', this); 29914 eventType(target, 'mousemove', this); 29915 eventType(target, 'mousecancel', this); 29916 eventType(target, 'mouseup', this); 29917 } 29918 29919 if ( utils.hasPointer && !this.options.disablePointer ) { 29920 eventType(this.wrapper, utils.prefixPointerEvent('pointerdown'), this); 29921 eventType(target, utils.prefixPointerEvent('pointermove'), this); 29922 eventType(target, utils.prefixPointerEvent('pointercancel'), this); 29923 eventType(target, utils.prefixPointerEvent('pointerup'), this); 29924 } 29925 29926 if ( utils.hasTouch && !this.options.disableTouch ) { 29927 eventType(this.wrapper, 'touchstart', this); 29928 eventType(target, 'touchmove', this); 29929 eventType(target, 'touchcancel', this); 29930 eventType(target, 'touchend', this); 29931 } 29932 29933 eventType(this.scroller, 'transitionend', this); 29934 eventType(this.scroller, 'webkitTransitionEnd', this); 29935 eventType(this.scroller, 'oTransitionEnd', this); 29936 eventType(this.scroller, 'MSTransitionEnd', this); 29937 }, 29938 29939 getComputedPosition: function () { 29940 var matrix = window.getComputedStyle(this.scroller, null), 29941 x, y; 29942 29943 if ( this.options.useTransform ) { 29944 matrix = matrix[utils.style.transform].split(')')[0].split(', '); 29945 x = +(matrix[12] || matrix[4]); 29946 y = +(matrix[13] || matrix[5]); 29947 } else { 29948 x = +matrix.left.replace(/[^-\d.]/g, ''); 29949 y = +matrix.top.replace(/[^-\d.]/g, ''); 29950 } 29951 29952 return { x: x, y: y }; 29953 }, 29954 _initIndicators: function () { 29955 var interactive = this.options.interactiveScrollbars, 29956 customStyle = typeof this.options.scrollbars != 'string', 29957 indicators = [], 29958 indicator; 29959 29960 var that = this; 29961 29962 this.indicators = []; 29963 29964 if ( this.options.scrollbars ) { 29965 // Vertical scrollbar 29966 if ( this.options.scrollY ) { 29967 indicator = { 29968 el: createDefaultScrollbar('v', interactive, this.options.scrollbars), 29969 interactive: interactive, 29970 defaultScrollbars: true, 29971 customStyle: customStyle, 29972 resize: this.options.resizeScrollbars, 29973 shrink: this.options.shrinkScrollbars, 29974 fade: this.options.fadeScrollbars, 29975 listenX: false 29976 }; 29977 29978 this.wrapper.appendChild(indicator.el); 29979 indicators.push(indicator); 29980 } 29981 29982 // Horizontal scrollbar 29983 if ( this.options.scrollX ) { 29984 indicator = { 29985 el: createDefaultScrollbar('h', interactive, this.options.scrollbars), 29986 interactive: interactive, 29987 defaultScrollbars: true, 29988 customStyle: customStyle, 29989 resize: this.options.resizeScrollbars, 29990 shrink: this.options.shrinkScrollbars, 29991 fade: this.options.fadeScrollbars, 29992 listenY: false 29993 }; 29994 29995 this.wrapper.appendChild(indicator.el); 29996 indicators.push(indicator); 29997 } 29998 } 29999 30000 if ( this.options.indicators ) { 30001 // TODO: check concat compatibility 30002 indicators = indicators.concat(this.options.indicators); 30003 } 30004 30005 for ( var i = indicators.length; i--; ) { 30006 this.indicators.push( new Indicator(this, indicators[i]) ); 30007 } 30008 30009 // TODO: check if we can use array.map (wide compatibility and performance issues) 30010 function _indicatorsMap (fn) { 30011 if (that.indicators) { 30012 for ( var i = that.indicators.length; i--; ) { 30013 fn.call(that.indicators[i]); 30014 } 30015 } 30016 } 30017 30018 if ( this.options.fadeScrollbars ) { 30019 this.on('scrollEnd', function () { 30020 _indicatorsMap(function () { 30021 this.fade(); 30022 }); 30023 }); 30024 30025 this.on('scrollCancel', function () { 30026 _indicatorsMap(function () { 30027 this.fade(); 30028 }); 30029 }); 30030 30031 this.on('scrollStart', function () { 30032 _indicatorsMap(function () { 30033 this.fade(1); 30034 }); 30035 }); 30036 30037 this.on('beforeScrollStart', function () { 30038 _indicatorsMap(function () { 30039 this.fade(1, true); 30040 }); 30041 }); 30042 } 30043 30044 30045 this.on('refresh', function () { 30046 _indicatorsMap(function () { 30047 this.refresh(); 30048 }); 30049 }); 30050 30051 this.on('destroy', function () { 30052 _indicatorsMap(function () { 30053 this.destroy(); 30054 }); 30055 30056 delete this.indicators; 30057 }); 30058 }, 30059 30060 _initWheel: function () { 30061 utils.addEvent(this.wrapper, 'wheel', this); 30062 utils.addEvent(this.wrapper, 'mousewheel', this); 30063 utils.addEvent(this.wrapper, 'DOMMouseScroll', this); 30064 30065 this.on('destroy', function () { 30066 clearTimeout(this.wheelTimeout); 30067 this.wheelTimeout = null; 30068 utils.removeEvent(this.wrapper, 'wheel', this); 30069 utils.removeEvent(this.wrapper, 'mousewheel', this); 30070 utils.removeEvent(this.wrapper, 'DOMMouseScroll', this); 30071 }); 30072 }, 30073 30074 _wheel: function (e) { 30075 if ( !this.enabled ) { 30076 return; 30077 } 30078 30079 var wheelDeltaX, wheelDeltaY, 30080 newX, newY, 30081 that = this; 30082 30083 if ( this.wheelTimeout === undefined ) { 30084 that._execEvent('scrollStart'); 30085 } 30086 30087 // Execute the scrollEnd event after 400ms the wheel stopped scrolling 30088 clearTimeout(this.wheelTimeout); 30089 this.wheelTimeout = setTimeout(function () { 30090 if(!that.options.snap) { 30091 that._execEvent('scrollEnd'); 30092 } 30093 that.wheelTimeout = undefined; 30094 }, 400); 30095 30096 if ( 'deltaX' in e ) { 30097 if (e.deltaMode === 1) { 30098 wheelDeltaX = -e.deltaX * this.options.mouseWheelSpeed; 30099 wheelDeltaY = -e.deltaY * this.options.mouseWheelSpeed; 30100 } else { 30101 wheelDeltaX = -e.deltaX; 30102 wheelDeltaY = -e.deltaY; 30103 } 30104 } else if ( 'wheelDeltaX' in e ) { 30105 wheelDeltaX = e.wheelDeltaX / 120 * this.options.mouseWheelSpeed; 30106 wheelDeltaY = e.wheelDeltaY / 120 * this.options.mouseWheelSpeed; 30107 } else if ( 'wheelDelta' in e ) { 30108 wheelDeltaX = wheelDeltaY = e.wheelDelta / 120 * this.options.mouseWheelSpeed; 30109 } else if ( 'detail' in e ) { 30110 wheelDeltaX = wheelDeltaY = -e.detail / 3 * this.options.mouseWheelSpeed; 30111 } else { 30112 return; 30113 } 30114 30115 wheelDeltaX *= this.options.invertWheelDirection; 30116 wheelDeltaY *= this.options.invertWheelDirection; 30117 30118 if ( !this.hasVerticalScroll ) { 30119 wheelDeltaX = wheelDeltaY; 30120 wheelDeltaY = 0; 30121 } 30122 30123 if ( this.options.snap ) { 30124 newX = this.currentPage.pageX; 30125 newY = this.currentPage.pageY; 30126 30127 if ( wheelDeltaX > 0 ) { 30128 newX--; 30129 } else if ( wheelDeltaX < 0 ) { 30130 newX++; 30131 } 30132 30133 if ( wheelDeltaY > 0 ) { 30134 newY--; 30135 } else if ( wheelDeltaY < 0 ) { 30136 newY++; 30137 } 30138 30139 this.goToPage(newX, newY); 30140 30141 return; 30142 } 30143 30144 newX = this.x + Math.round(this.hasHorizontalScroll ? wheelDeltaX : 0); 30145 newY = this.y + Math.round(this.hasVerticalScroll ? wheelDeltaY : 0); 30146 30147 this.directionX = wheelDeltaX > 0 ? -1 : wheelDeltaX < 0 ? 1 : 0; 30148 this.directionY = wheelDeltaY > 0 ? -1 : wheelDeltaY < 0 ? 1 : 0; 30149 30150 if ( newX > 0 ) { 30151 newX = 0; 30152 } else if ( newX < this.maxScrollX ) { 30153 newX = this.maxScrollX; 30154 } 30155 30156 if ( newY > 0 ) { 30157 newY = 0; 30158 } else if ( newY < this.maxScrollY ) { 30159 newY = this.maxScrollY; 30160 } 30161 30162 this.scrollTo(newX, newY, 0); 30163 30164// INSERT POINT: _wheel 30165 }, 30166 30167 _initSnap: function () { 30168 this.currentPage = {}; 30169 30170 if ( typeof this.options.snap == 'string' ) { 30171 this.options.snap = this.scroller.querySelectorAll(this.options.snap); 30172 } 30173 30174 this.on('refresh', function () { 30175 var i = 0, l, 30176 m = 0, n, 30177 cx, cy, 30178 x = 0, y,
vendor: 7,339 bytes, lines 30179-30432
30179 stepX = this.options.snapStepX || this.wrapperWidth, 30180 stepY = this.options.snapStepY || this.wrapperHeight, 30181 el; 30182 30183 this.pages = []; 30184 30185 if ( !this.wrapperWidth || !this.wrapperHeight || !this.scrollerWidth || !this.scrollerHeight ) { 30186 return; 30187 } 30188 30189 if ( this.options.snap === true ) { 30190 cx = Math.round( stepX / 2 ); 30191 cy = Math.round( stepY / 2 ); 30192 30193 while ( x > -this.scrollerWidth ) { 30194 this.pages[i] = []; 30195 l = 0; 30196 y = 0; 30197 30198 while ( y > -this.scrollerHeight ) { 30199 this.pages[i][l] = { 30200 x: Math.max(x, this.maxScrollX), 30201 y: Math.max(y, this.maxScrollY), 30202 width: stepX, 30203 height: stepY, 30204 cx: x - cx, 30205 cy: y - cy 30206 }; 30207 30208 y -= stepY; 30209 l++; 30210 } 30211 30212 x -= stepX; 30213 i++; 30214 } 30215 } else { 30216 el = this.options.snap; 30217 l = el.length; 30218 n = -1; 30219 30220 for ( ; i < l; i++ ) { 30221 if ( i === 0 || el[i].offsetLeft <= el[i-1].offsetLeft ) { 30222 m = 0; 30223 n++; 30224 } 30225 30226 if ( !this.pages[m] ) { 30227 this.pages[m] = []; 30228 } 30229 30230 x = Math.max(-el[i].offsetLeft, this.maxScrollX); 30231 y = Math.max(-el[i].offsetTop, this.maxScrollY); 30232 cx = x - Math.round(el[i].offsetWidth / 2); 30233 cy = y - Math.round(el[i].offsetHeight / 2); 30234 30235 this.pages[m][n] = { 30236 x: x, 30237 y: y, 30238 width: el[i].offsetWidth, 30239 height: el[i].offsetHeight, 30240 cx: cx, 30241 cy: cy 30242 }; 30243 30244 if ( x > this.maxScrollX ) { 30245 m++; 30246 } 30247 } 30248 } 30249 30250 this.goToPage(this.currentPage.pageX || 0, this.currentPage.pageY || 0, 0); 30251 30252 // Update snap threshold if needed 30253 if ( this.options.snapThreshold % 1 === 0 ) { 30254 this.snapThresholdX = this.options.snapThreshold; 30255 this.snapThresholdY = this.options.snapThreshold; 30256 } else { 30257 this.snapThresholdX = Math.round(this.pages[this.currentPage.pageX][this.currentPage.pageY].width * this.options.snapThreshold); 30258 this.snapThresholdY = Math.round(this.pages[this.currentPage.pageX][this.currentPage.pageY].height * this.options.snapThreshold); 30259 } 30260 }); 30261 30262 this.on('flick', function () { 30263 var time = this.options.snapSpeed || Math.max( 30264 Math.max( 30265 Math.min(Math.abs(this.x - this.startX), 1000), 30266 Math.min(Math.abs(this.y - this.startY), 1000) 30267 ), 300); 30268 30269 this.goToPage( 30270 this.currentPage.pageX + this.directionX, 30271 this.currentPage.pageY + this.directionY, 30272 time 30273 ); 30274 }); 30275 }, 30276 30277 _nearestSnap: function (x, y) { 30278 if ( !this.pages.length ) { 30279 return { x: 0, y: 0, pageX: 0, pageY: 0 }; 30280 } 30281 30282 var i = 0, 30283 l = this.pages.length, 30284 m = 0; 30285 30286 // Check if we exceeded the snap threshold 30287 if ( Math.abs(x - this.absStartX) < this.snapThresholdX && 30288 Math.abs(y - this.absStartY) < this.snapThresholdY ) { 30289 return this.currentPage; 30290 } 30291 30292 if ( x > 0 ) { 30293 x = 0; 30294 } else if ( x < this.maxScrollX ) { 30295 x = this.maxScrollX; 30296 } 30297 30298 if ( y > 0 ) { 30299 y = 0; 30300 } else if ( y < this.maxScrollY ) { 30301 y = this.maxScrollY; 30302 } 30303 30304 for ( ; i < l; i++ ) { 30305 if ( x >= this.pages[i][0].cx ) { 30306 x = this.pages[i][0].x; 30307 break; 30308 } 30309 } 30310 30311 l = this.pages[i].length; 30312 30313 for ( ; m < l; m++ ) { 30314 if ( y >= this.pages[0][m].cy ) { 30315 y = this.pages[0][m].y; 30316 break; 30317 } 30318 } 30319 30320 if ( i == this.currentPage.pageX ) { 30321 i += this.directionX; 30322 30323 if ( i < 0 ) { 30324 i = 0; 30325 } else if ( i >= this.pages.length ) { 30326 i = this.pages.length - 1; 30327 } 30328 30329 x = this.pages[i][0].x; 30330 } 30331 30332 if ( m == this.currentPage.pageY ) { 30333 m += this.directionY; 30334 30335 if ( m < 0 ) { 30336 m = 0; 30337 } else if ( m >= this.pages[0].length ) { 30338 m = this.pages[0].length - 1; 30339 } 30340 30341 y = this.pages[0][m].y; 30342 } 30343 30344 return { 30345 x: x, 30346 y: y, 30347 pageX: i, 30348 pageY: m 30349 }; 30350 }, 30351 30352 goToPage: function (x, y, time, easing) { 30353 easing = easing || this.options.bounceEasing; 30354 30355 if ( x >= this.pages.length ) { 30356 x = this.pages.length - 1; 30357 } else if ( x < 0 ) { 30358 x = 0; 30359 } 30360 30361 if ( y >= this.pages[x].length ) { 30362 y = this.pages[x].length - 1; 30363 } else if ( y < 0 ) { 30364 y = 0; 30365 } 30366 30367 var posX = this.pages[x][y].x, 30368 posY = this.pages[x][y].y; 30369 30370 time = time === undefined ? this.options.snapSpeed || Math.max( 30371 Math.max( 30372 Math.min(Math.abs(posX - this.x), 1000), 30373 Math.min(Math.abs(posY - this.y), 1000) 30374 ), 300) : time; 30375 30376 this.currentPage = { 30377 x: posX, 30378 y: posY, 30379 pageX: x, 30380 pageY: y 30381 }; 30382 30383 this.scrollTo(posX, posY, time, easing); 30384 }, 30385 30386 next: function (time, easing) { 30387 var x = this.currentPage.pageX, 30388 y = this.currentPage.pageY; 30389 30390 x++; 30391 30392 if ( x >= this.pages.length && this.hasVerticalScroll ) { 30393 x = 0; 30394 y++; 30395 } 30396 30397 this.goToPage(x, y, time, easing); 30398 }, 30399 30400 prev: function (time, easing) { 30401 var x = this.currentPage.pageX, 30402 y = this.currentPage.pageY; 30403 30404 x--; 30405 30406 if ( x < 0 && this.hasVerticalScroll ) { 30407 x = 0; 30408 y--; 30409 } 30410 30411 this.goToPage(x, y, time, easing); 30412 }, 30413 30414 _initKeys: function (e) { 30415 // default key bindings 30416 var keys = { 30417 pageUp: 33, 30418 pageDown: 34, 30419 end: 35, 30420 home: 36, 30421 left: 37, 30422 up: 38, 30423 right: 39, 30424 down: 40 30425 }; 30426 var i; 30427 30428 // if you give me characters I give you keycode 30429 if ( typeof this.options.keyBindings == 'object' ) { 30430 for ( i in this.options.keyBindings ) { 30431 if ( typeof this.options.keyBindings[i] == 'string' ) { 30432 this.options.keyBindings[i] = this.options.keyBindings[i].toUpperCase().charCo
vendor: 11,097 bytes, lines 30432-30785
30432deAt(0); 30433 } 30434 } 30435 } else { 30436 this.options.keyBindings = {}; 30437 } 30438 30439 for ( i in keys ) { 30440 this.options.keyBindings[i] = this.options.keyBindings[i] || keys[i]; 30441 } 30442 30443 utils.addEvent(window, 'keydown', this); 30444 30445 this.on('destroy', function () { 30446 utils.removeEvent(window, 'keydown', this); 30447 }); 30448 }, 30449 30450 _key: function (e) { 30451 if ( !this.enabled ) { 30452 return; 30453 } 30454 30455 var snap = this.options.snap, // we are using this alot, better to cache it 30456 newX = snap ? this.currentPage.pageX : this.x, 30457 newY = snap ? this.currentPage.pageY : this.y, 30458 now = utils.getTime(), 30459 prevTime = this.keyTime || 0, 30460 acceleration = 0.250, 30461 pos; 30462 30463 if ( this.options.useTransition && this.isInTransition ) { 30464 pos = this.getComputedPosition(); 30465 30466 this._translate(Math.round(pos.x), Math.round(pos.y)); 30467 this.isInTransition = false; 30468 } 30469 30470 this.keyAcceleration = now - prevTime < 200 ? Math.min(this.keyAcceleration + acceleration, 50) : 0; 30471 30472 switch ( e.keyCode ) { 30473 case this.options.keyBindings.pageUp: 30474 if ( this.hasHorizontalScroll && !this.hasVerticalScroll ) { 30475 newX += snap ? 1 : this.wrapperWidth; 30476 } else { 30477 newY += snap ? 1 : this.wrapperHeight; 30478 } 30479 break; 30480 case this.options.keyBindings.pageDown: 30481 if ( this.hasHorizontalScroll && !this.hasVerticalScroll ) { 30482 newX -= snap ? 1 : this.wrapperWidth; 30483 } else { 30484 newY -= snap ? 1 : this.wrapperHeight; 30485 } 30486 break; 30487 case this.options.keyBindings.end: 30488 newX = snap ? this.pages.length-1 : this.maxScrollX; 30489 newY = snap ? this.pages[0].length-1 : this.maxScrollY; 30490 break; 30491 case this.options.keyBindings.home: 30492 newX = 0; 30493 newY = 0; 30494 break; 30495 case this.options.keyBindings.left: 30496 newX += snap ? -1 : 5 + this.keyAcceleration>>0; 30497 break; 30498 case this.options.keyBindings.up: 30499 newY += snap ? 1 : 5 + this.keyAcceleration>>0; 30500 break; 30501 case this.options.keyBindings.right: 30502 newX -= snap ? -1 : 5 + this.keyAcceleration>>0; 30503 break; 30504 case this.options.keyBindings.down: 30505 newY -= snap ? 1 : 5 + this.keyAcceleration>>0; 30506 break; 30507 default: 30508 return; 30509 } 30510 30511 if ( snap ) { 30512 this.goToPage(newX, newY); 30513 return; 30514 } 30515 30516 if ( newX > 0 ) { 30517 newX = 0; 30518 this.keyAcceleration = 0; 30519 } else if ( newX < this.maxScrollX ) { 30520 newX = this.maxScrollX; 30521 this.keyAcceleration = 0; 30522 } 30523 30524 if ( newY > 0 ) { 30525 newY = 0; 30526 this.keyAcceleration = 0; 30527 } else if ( newY < this.maxScrollY ) { 30528 newY = this.maxScrollY; 30529 this.keyAcceleration = 0; 30530 } 30531 30532 this.scrollTo(newX, newY, 0); 30533 30534 this.keyTime = now; 30535 }, 30536 30537 _animate: function (destX, destY, duration, easingFn) { 30538 var that = this, 30539 startX = this.x, 30540 startY = this.y, 30541 startTime = utils.getTime(), 30542 destTime = startTime + duration; 30543 30544 function step () { 30545 var now = utils.getTime(), 30546 newX, newY, 30547 easing; 30548 30549 if ( now >= destTime ) { 30550 that.isAnimating = false; 30551 that._translate(destX, destY); 30552 30553 if ( !that.resetPosition(that.options.bounceTime) ) { 30554 that._execEvent('scrollEnd'); 30555 } 30556 30557 return; 30558 } 30559 30560 now = ( now - startTime ) / duration; 30561 easing = easingFn(now); 30562 newX = ( destX - startX ) * easing + startX; 30563 newY = ( destY - startY ) * easing + startY; 30564 that._translate(newX, newY); 30565 30566 if ( that.isAnimating ) { 30567 rAF(step); 30568 } 30569 } 30570 30571 this.isAnimating = true; 30572 step(); 30573 }, 30574 handleEvent: function (e) { 30575 switch ( e.type ) { 30576 case 'touchstart': 30577 case 'pointerdown': 30578 case 'MSPointerDown': 30579 case 'mousedown': 30580 this._start(e); 30581 break; 30582 case 'touchmove': 30583 case 'pointermove': 30584 case 'MSPointerMove': 30585 case 'mousemove': 30586 this._move(e); 30587 break; 30588 case 'touchend': 30589 case 'pointerup': 30590 case 'MSPointerUp': 30591 case 'mouseup': 30592 case 'touchcancel': 30593 case 'pointercancel': 30594 case 'MSPointerCancel': 30595 case 'mousecancel': 30596 this._end(e); 30597 break; 30598 case 'orientationchange': 30599 case 'resize': 30600 this._resize(); 30601 break; 30602 case 'transitionend': 30603 case 'webkitTransitionEnd': 30604 case 'oTransitionEnd': 30605 case 'MSTransitionEnd': 30606 this._transitionEnd(e); 30607 break; 30608 case 'wheel': 30609 case 'DOMMouseScroll': 30610 case 'mousewheel': 30611 this._wheel(e); 30612 break; 30613 case 'keydown': 30614 this._key(e); 30615 break; 30616 case 'click': 30617 if ( this.enabled && !e._constructed ) { 30618 e.preventDefault(); 30619 e.stopPropagation(); 30620 } 30621 break; 30622 } 30623 } 30624}; 30625function createDefaultScrollbar (direction, interactive, type) { 30626 var scrollbar = document.createElement('div'), 30627 indicator = document.createElement('div'); 30628 30629 if ( type === true ) { 30630 scrollbar.style.cssText = 'position:absolute;z-index:9999'; 30631 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'; 30632 } 30633 30634 indicator.className = 'iScrollIndicator'; 30635 30636 if ( direction == 'h' ) { 30637 if ( type === true ) { 30638 scrollbar.style.cssText += ';height:7px;left:2px;right:2px;bottom:0'; 30639 indicator.style.height = '100%'; 30640 } 30641 scrollbar.className = 'iScrollHorizontalScrollbar'; 30642 } else { 30643 if ( type === true ) { 30644 scrollbar.style.cssText += ';width:7px;bottom:2px;top:2px;right:1px'; 30645 indicator.style.width = '100%'; 30646 } 30647 scrollbar.className = 'iScrollVerticalScrollbar'; 30648 } 30649 30650 scrollbar.style.cssText += ';overflow:hidden'; 30651 30652 if ( !interactive ) { 30653 scrollbar.style.pointerEvents = 'none'; 30654 } 30655 30656 scrollbar.appendChild(indicator); 30657 30658 return scrollbar; 30659} 30660 30661function Indicator (scroller, options) { 30662 this.wrapper = typeof options.el == 'string' ? document.querySelector(options.el) : options.el; 30663 this.wrapperStyle = this.wrapper.style; 30664 this.indicator = this.wrapper.children[0]; 30665 this.indicatorStyle = this.indicator.style; 30666 this.scroller = scroller; 30667 30668 this.options = { 30669 listenX: true, 30670 listenY: true, 30671 interactive: false, 30672 resize: true, 30673 defaultScrollbars: false, 30674 shrink: false, 30675 fade: false, 30676 speedRatioX: 0, 30677 speedRatioY: 0 30678 }; 30679 30680 for ( var i in options ) { 30681 this.options[i] = options[i]; 30682 } 30683 30684 this.sizeRatioX = 1; 30685 this.sizeRatioY = 1; 30686 this.maxPosX = 0; 30687 this.maxPosY = 0; 30688 30689 if ( this.options.interactive ) { 30690 if ( !this.options.disableTouch ) { 30691 utils.addEvent(this.indicator, 'touchstart', this); 30692 utils.addEvent(window, 'touchend', this); 30693 } 30694 if ( !this.options.disablePointer ) { 30695 utils.addEvent(this.indicator, utils.prefixPointerEvent('pointerdown'), this); 30696 utils.addEvent(window, utils.prefixPointerEvent('pointerup'), this); 30697 } 30698 if ( !this.options.disableMouse ) { 30699 utils.addEvent(this.indicator, 'mousedown', this); 30700 utils.addEvent(window, 'mouseup', this); 30701 } 30702 } 30703 30704 if ( this.options.fade ) { 30705 this.wrapperStyle[utils.style.transform] = this.scroller.translateZ; 30706 var durationProp = utils.style.transitionDuration; 30707 if(!durationProp) { 30708 return; 30709 } 30710 this.wrapperStyle[durationProp] = utils.isBadAndroid ? '0.0001ms' : '0ms'; 30711 // remove 0.0001ms 30712 var self = this; 30713 if(utils.isBadAndroid) { 30714 rAF(function() { 30715 if(self.wrapperStyle[durationProp] === '0.0001ms') { 30716 self.wrapperStyle[durationProp] = '0s'; 30717 } 30718 }); 30719 } 30720 this.wrapperStyle.opacity = '0'; 30721 } 30722} 30723 30724Indicator.prototype = { 30725 handleEvent: function (e) { 30726 switch ( e.type ) { 30727 case 'touchstart': 30728 case 'pointerdown': 30729 case 'MSPointerDown': 30730 case 'mousedown': 30731 this._start(e); 30732 break; 30733 case 'touchmove': 30734 case 'pointermove': 30735 case 'MSPointerMove': 30736 case 'mousemove': 30737 this._move(e); 30738 break; 30739 case 'touchend': 30740 case 'pointerup': 30741 case 'MSPointerUp': 30742 case 'mouseup': 30743 case 'touchcancel': 30744 case 'pointercancel': 30745 case 'MSPointerCancel': 30746 case 'mousecancel': 30747 this._end(e); 30748 break; 30749 } 30750 }, 30751 30752 destroy: function () { 30753 if ( this.options.fadeScrollbars ) { 30754 clearTimeout(this.fadeTimeout); 30755 this.fadeTimeout = null; 30756 } 30757 if ( this.options.interactive ) { 30758 utils.removeEvent(this.indicator, 'touchstart', this); 30759 utils.removeEvent(this.indicator, utils.prefixPointerEvent('pointerdown'), this); 30760 utils.removeEvent(this.indicator, 'mousedown', this); 30761 30762 utils.removeEvent(window, 'touchmove', this); 30763 utils.removeEvent(window, utils.prefixPointerEvent('pointermove'), this); 30764 utils.removeEvent(window, 'mousemove', this); 30765 30766 utils.removeEvent(window, 'touchend', this); 30767 utils.removeEvent(window, utils.prefixPointerEvent('pointerup'), this); 30768 utils.removeEvent(window, 'mouseup', this); 30769 } 30770 30771 if ( this.options.defaultScrollbars ) { 30772 this.wrapper.parentNode.removeChild(this.wrapper); 30773 } 30774 }, 30775 30776 _start: function (e) { 30777 var point = e.touches ? e.touches[0] : e; 30778 30779 e.preventDefault(); 30780 e.stopPropagation(); 30781 30782 this.transitionTime(); 30783 30784 this.initiated = true; 30785 this.moved = false;
vendor: 9,615 bytes, lines 30786-31044
30786 this.lastPointX = point.pageX; 30787 this.lastPointY = point.pageY; 30788 30789 this.startTime = utils.getTime(); 30790 30791 if ( !this.options.disableTouch ) { 30792 utils.addEvent(window, 'touchmove', this); 30793 } 30794 if ( !this.options.disablePointer ) { 30795 utils.addEvent(window, utils.prefixPointerEvent('pointermove'), this); 30796 } 30797 if ( !this.options.disableMouse ) { 30798 utils.addEvent(window, 'mousemove', this); 30799 } 30800 30801 this.scroller._execEvent('beforeScrollStart'); 30802 }, 30803 30804 _move: function (e) { 30805 var point = e.touches ? e.touches[0] : e, 30806 deltaX, deltaY, 30807 newX, newY, 30808 timestamp = utils.getTime(); 30809 30810 if ( !this.moved ) { 30811 this.scroller._execEvent('scrollStart'); 30812 } 30813 30814 this.moved = true; 30815 30816 deltaX = point.pageX - this.lastPointX; 30817 this.lastPointX = point.pageX; 30818 30819 deltaY = point.pageY - this.lastPointY; 30820 this.lastPointY = point.pageY; 30821 30822 newX = this.x + deltaX; 30823 newY = this.y + deltaY; 30824 30825 this._pos(newX, newY); 30826 30827// INSERT POINT: indicator._move 30828 30829 e.preventDefault(); 30830 e.stopPropagation(); 30831 }, 30832 30833 _end: function (e) { 30834 if ( !this.initiated ) { 30835 return; 30836 } 30837 30838 this.initiated = false; 30839 30840 e.preventDefault(); 30841 e.stopPropagation(); 30842 30843 utils.removeEvent(window, 'touchmove', this); 30844 utils.removeEvent(window, utils.prefixPointerEvent('pointermove'), this); 30845 utils.removeEvent(window, 'mousemove', this); 30846 30847 if ( this.scroller.options.snap ) { 30848 var snap = this.scroller._nearestSnap(this.scroller.x, this.scroller.y); 30849 30850 var time = this.options.snapSpeed || Math.max( 30851 Math.max( 30852 Math.min(Math.abs(this.scroller.x - snap.x), 1000), 30853 Math.min(Math.abs(this.scroller.y - snap.y), 1000) 30854 ), 300); 30855 30856 if ( this.scroller.x != snap.x || this.scroller.y != snap.y ) { 30857 this.scroller.directionX = 0; 30858 this.scroller.directionY = 0; 30859 this.scroller.currentPage = snap; 30860 this.scroller.scrollTo(snap.x, snap.y, time, this.scroller.options.bounceEasing); 30861 } 30862 } 30863 30864 if ( this.moved ) { 30865 this.scroller._execEvent('scrollEnd'); 30866 } 30867 }, 30868 30869 transitionTime: function (time) { 30870 time = time || 0; 30871 var durationProp = utils.style.transitionDuration; 30872 if(!durationProp) { 30873 return; 30874 } 30875 30876 this.indicatorStyle[durationProp] = time + 'ms'; 30877 30878 if ( !time && utils.isBadAndroid ) { 30879 this.indicatorStyle[durationProp] = '0.0001ms'; 30880 // remove 0.0001ms 30881 var self = this; 30882 rAF(function() { 30883 if(self.indicatorStyle[durationProp] === '0.0001ms') { 30884 self.indicatorStyle[durationProp] = '0s'; 30885 } 30886 }); 30887 } 30888 }, 30889 30890 transitionTimingFunction: function (easing) { 30891 this.indicatorStyle[utils.style.transitionTimingFunction] = easing; 30892 }, 30893 30894 refresh: function () { 30895 this.transitionTime(); 30896 30897 if ( this.options.listenX && !this.options.listenY ) { 30898 this.indicatorStyle.display = this.scroller.hasHorizontalScroll ? 'block' : 'none'; 30899 } else if ( this.options.listenY && !this.options.listenX ) { 30900 this.indicatorStyle.display = this.scroller.hasVerticalScroll ? 'block' : 'none'; 30901 } else { 30902 this.indicatorStyle.display = this.scroller.hasHorizontalScroll || this.scroller.hasVerticalScroll ? 'block' : 'none'; 30903 } 30904 30905 if ( this.scroller.hasHorizontalScroll && this.scroller.hasVerticalScroll ) { 30906 utils.addClass(this.wrapper, 'iScrollBothScrollbars'); 30907 utils.removeClass(this.wrapper, 'iScrollLoneScrollbar'); 30908 30909 if ( this.options.defaultScrollbars && this.options.customStyle ) { 30910 if ( this.options.listenX ) { 30911 this.wrapper.style.right = '8px'; 30912 } else { 30913 this.wrapper.style.bottom = '8px'; 30914 } 30915 } 30916 } else { 30917 utils.removeClass(this.wrapper, 'iScrollBothScrollbars'); 30918 utils.addClass(this.wrapper, 'iScrollLoneScrollbar'); 30919 30920 if ( this.options.defaultScrollbars && this.options.customStyle ) { 30921 if ( this.options.listenX ) { 30922 this.wrapper.style.right = '2px'; 30923 } else { 30924 this.wrapper.style.bottom = '2px'; 30925 } 30926 } 30927 } 30928 30929 var r = this.wrapper.offsetHeight; // force refresh 30930 30931 if ( this.options.listenX ) { 30932 this.wrapperWidth = this.wrapper.clientWidth; 30933 if ( this.options.resize ) { 30934 this.indicatorWidth = Math.max(Math.round(this.wrapperWidth * this.wrapperWidth / (this.scroller.scrollerWidth || this.wrapperWidth || 1)), 8); 30935 this.indicatorStyle.width = this.indicatorWidth + 'px'; 30936 } else { 30937 this.indicatorWidth = this.indicator.clientWidth; 30938 } 30939 30940 this.maxPosX = this.wrapperWidth - this.indicatorWidth; 30941 30942 if ( this.options.shrink == 'clip' ) { 30943 this.minBoundaryX = -this.indicatorWidth + 8; 30944 this.maxBoundaryX = this.wrapperWidth - 8; 30945 } else { 30946 this.minBoundaryX = 0; 30947 this.maxBoundaryX = this.maxPosX; 30948 } 30949 30950 this.sizeRatioX = this.options.speedRatioX || (this.scroller.maxScrollX && (this.maxPosX / this.scroller.maxScrollX)); 30951 } 30952 30953 if ( this.options.listenY ) { 30954 this.wrapperHeight = this.wrapper.clientHeight; 30955 if ( this.options.resize ) { 30956 this.indicatorHeight = Math.max(Math.round(this.wrapperHeight * this.wrapperHeight / (this.scroller.scrollerHeight || this.wrapperHeight || 1)), 8); 30957 this.indicatorStyle.height = this.indicatorHeight + 'px'; 30958 } else { 30959 this.indicatorHeight = this.indicator.clientHeight; 30960 } 30961 30962 this.maxPosY = this.wrapperHeight - this.indicatorHeight; 30963 30964 if ( this.options.shrink == 'clip' ) { 30965 this.minBoundaryY = -this.indicatorHeight + 8; 30966 this.maxBoundaryY = this.wrapperHeight - 8; 30967 } else { 30968 this.minBoundaryY = 0; 30969 this.maxBoundaryY = this.maxPosY; 30970 } 30971 30972 this.maxPosY = this.wrapperHeight - this.indicatorHeight; 30973 this.sizeRatioY = this.options.speedRatioY || (this.scroller.maxScrollY && (this.maxPosY / this.scroller.maxScrollY)); 30974 } 30975 30976 this.updatePosition(); 30977 }, 30978 30979 updatePosition: function () { 30980 var x = this.options.listenX && Math.round(this.sizeRatioX * this.scroller.x) || 0, 30981 y = this.options.listenY && Math.round(this.sizeRatioY * this.scroller.y) || 0; 30982 30983 if ( !this.options.ignoreBoundaries ) { 30984 if ( x < this.minBoundaryX ) { 30985 if ( this.options.shrink == 'scale' ) { 30986 this.width = Math.max(this.indicatorWidth + x, 8); 30987 this.indicatorStyle.width = this.width + 'px'; 30988 } 30989 x = this.minBoundaryX; 30990 } else if ( x > this.maxBoundaryX ) { 30991 if ( this.options.shrink == 'scale' ) { 30992 this.width = Math.max(this.indicatorWidth - (x - this.maxPosX), 8); 30993 this.indicatorStyle.width = this.width + 'px'; 30994 x = this.maxPosX + this.indicatorWidth - this.width; 30995 } else { 30996 x = this.maxBoundaryX; 30997 } 30998 } else if ( this.options.shrink == 'scale' && this.width != this.indicatorWidth ) { 30999 this.width = this.indicatorWidth; 31000 this.indicatorStyle.width = this.width + 'px'; 31001 } 31002 31003 if ( y < this.minBoundaryY ) { 31004 if ( this.options.shrink == 'scale' ) { 31005 this.height = Math.max(this.indicatorHeight + y * 3, 8); 31006 this.indicatorStyle.height = this.height + 'px'; 31007 } 31008 y = this.minBoundaryY; 31009 } else if ( y > this.maxBoundaryY ) { 31010 if ( this.options.shrink == 'scale' ) { 31011 this.height = Math.max(this.indicatorHeight - (y - this.maxPosY) * 3, 8); 31012 this.indicatorStyle.height = this.height + 'px'; 31013 y = this.maxPosY + this.indicatorHeight - this.height; 31014 } else { 31015 y = this.maxBoundaryY; 31016 } 31017 } else if ( this.options.shrink == 'scale' && this.height != this.indicatorHeight ) { 31018 this.height = this.indicatorHeight; 31019 this.indicatorStyle.height = this.height + 'px'; 31020 } 31021 } 31022 31023 this.x = x; 31024 this.y = y; 31025 31026 if ( this.scroller.options.useTransform ) { 31027 this.indicatorStyle[utils.style.transform] = 'translate(' + x + 'px,' + y + 'px)' + this.scroller.translateZ; 31028 } else { 31029 this.indicatorStyle.left = x + 'px'; 31030 this.indicatorStyle.top = y + 'px'; 31031 } 31032 }, 31033 31034 _pos: function (x, y) { 31035 if ( x < 0 ) { 31036 x = 0; 31037 } else if ( x > this.maxPosX ) { 31038 x = this.maxPosX; 31039 } 31040 31041 if ( y < 0 ) { 31042 y = 0; 31043 } else if ( y > this.maxPosY ) { 31044 y = this.maxPosY;
31045 } 31046 31047 x = this.options.listenX ? Math.round(x / this.sizeRatioX) : this.scroller.x; 31048 y = this.options.listenY ? Math.round(y / this.sizeRatioY) : this.scroller.y; 31049 31050 this.scroller.scrollTo(x, y); 31051 }, 31052 31053 fade: function (val, hold) { 31054 if ( hold && !this.visible ) { 31055 return; 31056 } 31057 31058 clearTimeout(this.fadeTimeout); 31059 this.fadeTimeout = null; 31060 31061 var time = val ? 250 : 500, 31062 delay = val ? 0 : 300; 31063 31064 val = val ? '1' : '0'; 31065 31066 this.wrapperStyle[utils.style.transitionDuration] = time + 'ms'; 31067 31068 this.fadeTimeout = setTimeout((function (val) { 31069 this.wrapperStyle.opacity = val; 31070 this.visible = +val; 31071 }).bind(this, val), delay); 31072 } 31073}; 31074 31075IScroll.utils = utils; 31076 31077if ( typeof module != 'undefined' && module.exports ) { 31078 module.exports = IScroll; 31079} else if ( typeof define == 'function' && define.amd ) { 31080 define( function () { return IScroll; } ); 31081} else { 31082 window.IScroll = IScroll; 31083} 31084 31085})(window, document, Math); 31086/*! 31087 * fullPage 2.9.4 31088 * https://github.com/alvarotrigo/fullPage.js 31089 * @license MIT licensed 31090 * 31091 * Copyright (C) 2015 alvarotrigo.com - A project by Alvaro Trigo 31092 */ 31093(function(global, factory) { 31094 'use strict'; 31095 if (typeof define === 'function' && define.amd) { 31096 define(['jquery'], function($) { 31097 return factory($, global, global.document, global.Math); 31098 }); 31099 } else if (typeof exports === "object" && exports) { 31100 module.exports = factory(require('jquery'), global, global.document, global.Math); 31101 } else { 31102 factory(jQuery, global, global.document, global.Math); 31103 } 31104})(typeof window !== 'undefined' ? window : this, function($, window, document, Math, undefined) { 31105 'use strict'; 31106 31107 // keeping central set of classnames and selectors 31108 var WRAPPER = 'fullpage-wrapper'; 31109 var WRAPPER_SEL = '.' + WRAPPER; 31110 31111 // slimscroll 31112 var SCROLLABLE = 'fp-scrollable'; 31113 var SCROLLABLE_SEL = '.' + SCROLLABLE; 31114 31115 // util 31116 var RESPONSIVE = 'fp-responsive'; 31117 var NO_TRANSITION = 'fp-notransition'; 31118 var DESTROYED = 'fp-destroyed'; 31119 var ENABLED = 'fp-enabled'; 31120 var VIEWING_PREFIX = 'fp-viewing'; 31121 var ACTIVE = 'active'; 31122 var ACTIVE_SEL = '.' + ACTIVE; 31123 var COMPLETELY = 'fp-completely'; 31124 var COMPLETELY_SEL = '.' + COMPLETELY; 31125 31126 // section 31127 var SECTION_DEFAULT_SEL = '.section'; 31128 var SECTION = 'fp-section'; 31129 var SECTION_SEL = '.' + SECTION; 31130 var SECTION_ACTIVE_SEL = SECTION_SEL + ACTIVE_SEL; 31131 var SECTION_FIRST_SEL = SECTION_SEL + ':first'; 31132 var SECTION_LAST_SEL = SECTION_SEL + ':last'; 31133 var TABLE_CELL = 'fp-tableCell'; 31134 var TABLE_CELL_SEL = '.' + TABLE_CELL; 31135 var AUTO_HEIGHT = 'fp-auto-height'; 31136 var AUTO_HEIGHT_SEL = '.fp-auto-height'; 31137 var NORMAL_SCROLL = 'fp-normal-scroll'; 31138 var NORMAL_SCROLL_SEL = '.fp-normal-scroll'; 31139 31140 // section nav 31141 var SECTION_NAV = 'fp-nav'; 31142 var SECTION_NAV_SEL = '#' + SECTION_NAV; 31143 var SECTION_NAV_TOOLTIP = 'fp-tooltip'; 31144 var SECTION_NAV_TOOLTIP_SEL='.'+SECTION_NAV_TOOLTIP; 31145 var SHOW_ACTIVE_TOOLTIP = 'fp-show-active'; 31146 31147 // slide 31148 var SLIDE_DEFAULT_SEL = '.slide'; 31149 var SLIDE = 'fp-slide'; 31150 var SLIDE_SEL = '.' + SLIDE; 31151 var SLIDE_ACTIVE_SEL = SLIDE_SEL + ACTIVE_SEL; 31152 var SLIDES_WRAPPER = 'fp-slides'; 31153 var SLIDES_WRAPPER_SEL = '.' + SLIDES_WRAPPER; 31154 var SLIDES_CONTAINER = 'fp-slidesContainer'; 31155 var SLIDES_CONTAINER_SEL = '.' + SLIDES_CONTAINER; 31156 var TABLE = 'fp-table'; 31157 31158 // slide nav 31159 var SLIDES_NAV = 'fp-slidesNav'; 31160 var SLIDES_NAV_SEL = '.' + SLIDES_NAV; 31161 var SLIDES_NAV_LINK_SEL = SLIDES_NAV_SEL + ' a'; 31162 var SLIDES_ARROW = 'fp-controlArrow'; 31163 var SLIDES_ARROW_SEL = '.' + SLIDES_ARROW; 31164 var SLIDES_PREV = 'fp-prev'; 31165 var SLIDES_PREV_SEL = '.' + SLIDES_PREV; 31166 var SLIDES_ARROW_PREV = SLIDES_ARROW + ' ' + SLIDES_PREV; 31167 var SLIDES_ARROW_PREV_SEL = SLIDES_ARROW_SEL + SLIDES_PREV_SEL; 31168 var SLIDES_NEXT = 'fp-next';
31169 var SLIDES_NEXT_SEL = '.' + SLIDES_NEXT; 31170 var SLIDES_ARROW_NEXT = SLIDES_ARROW + ' ' + SLIDES_NEXT; 31171 var SLIDES_ARROW_NEXT_SEL = SLIDES_ARROW_SEL + SLIDES_NEXT_SEL; 31172 31173 var $window = $(window); 31174 var $document = $(document); 31175 31176 // Default options for iScroll.js used when using scrollOverflow 31177 var iscrollOptions = { 31178 scrollbars: true, 31179 mouseWheel: true, 31180 hideScrollbars: false, 31181 fadeScrollbars: false, 31182 disableMouse: true, 31183 interactiveScrollbars: true, 31184 bounce: false, 31185 }; 31186 31187 $.fn.fullpage = function(options) { 31188 //only once my friend! 31189 if($('html').hasClass(ENABLED)){ displayWarnings(); return; } 31190 31191 // common jQuery objects 31192 var $htmlBody = $('html, body'); 31193 var $body = $('body'); 31194 31195 var FP = $.fn.fullpage; 31196 31197 // Creating some defaults, extending them with any options that were provided 31198 options = $.extend({ 31199 //navigation 31200 menu: false, 31201 anchors:[], 31202 lockAnchors: false, 31203 navigation: false, 31204 navigationPosition: 'right', 31205 navigationTooltips: [], 31206 showActiveTooltip: false, 31207 slidesNavigation: false, 31208 slidesNavPosition: 'bottom', 31209 scrollBar: false, 31210 hybrid: false, 31211 31212 //scrolling 31213 css3: true, 31214 scrollingSpeed: 700, 31215 autoScrolling: true, 31216 fitToSection: true, 31217 fitToSectionDelay: 1000, 31218 easing: 'easeInOutCubic', 31219 easingcss3: 'ease', 31220 loopBottom: false, 31221 loopTop: false, 31222 loopHorizontal: true, 31223 continuousVertical: false, 31224 continuousHorizontal: false, 31225 scrollHorizontally: false, 31226 interlockedSlides: false, 31227 dragAndMove: false, 31228 offsetSections: false, 31229 resetSliders: false, 31230 fadingEffect: false, 31231 normalScrollElements: null, 31232 scrollOverflow: false, 31233 scrollOverflowReset: false, 31234 scrollOverflowHandler: iscrollHandler, 31235 scrollOverflowOptions: null, 31236 touchSensitivity: 5, 31237 normalScrollElementTouchThreshold: 5, 31238 bigSectionsDestination: null, 31239 31240 //Accessibility 31241 keyboardScrolling: true, 31242 animateAnchor: true, 31243 recordHistory: true, 31244 31245 //design 31246 controlArrows: true, 31247 controlArrowColor: '#fff', 31248 verticalCentered: true, 31249 sectionsColor : [], 31250 paddingTop: 0, 31251 paddingBottom: 0, 31252 fixedElements: null, 31253 responsive: 0, //backwards compabitility with responsiveWiddth 31254 responsiveWidth: 0, 31255 responsiveHeight: 0, 31256 responsiveSlides: false, 31257 parallax: false, 31258 parallaxOptions: { 31259 type: 'reveal', 31260 percentage: 62, 31261 property: 'translate' 31262 }, 31263 31264 //Custom selectors 31265 sectionSelector: SECTION_DEFAULT_SEL, 31266 slideSelector: SLIDE_DEFAULT_SEL, 31267 31268 //events 31269 afterLoad: null, 31270 onLeave: null, 31271 afterRender: null, 31272 afterResize: null, 31273 afterReBuild: null, 31274 afterSlideLoad: null, 31275 onSlideLeave: null, 31276 afterResponsive: null, 31277 31278 lazyLoading: true 31279 }, options); 31280 31281 //flag to avoid very fast sliding for landscape sliders 31282 var slideMoving = false; 31283 31284 var isTouchDevice = navigator.userAgent.match(/(iPhone|iPod|iPad|Android|playbook|silk|BlackBerry|BB10|Windows Phone|Tizen|Bada|webOS|IEMobile|Opera Mini)/); 31285 var isTouch = (('ontouchstart' in window) || (navigator.msMaxTouchPoints > 0) || (navigator.maxTouchPoints)); 31286 var container = $(this); 31287 var windowsHeight = $window.height(); 31288 var isResizing = false; 31289 var isWindowFocused = true; 31290 var lastScrolledDestiny; 31291 var lastScrolledSlide; 31292 var canScroll = true; 31293 var scrollings = []; 31294 var controlPressed; 31295 var startingSection; 31296 var isScrollAllowed = {}; 31297 isScrollAllowed.m = { 'up':true, 'down':true, 'left':true, 'right':true }; 31298 isScrollAllowed.k = $.extend(true,{}, isScrollAllowed.m); 31299 var MSPointer = getMSPointer(); 31300 var events = { 31301 touchmove: 'ontouchmove' in window ? 'touchmove' : MSPointer.move, 31302 touchstart: 'ontouchstart' in window ? 'touchstart' : MSPointer.down 31303 }; 31304 31305 //cheks for passive event support 31306 //added by Uncode from new fullPage updates 31307 var g_supportsPassive = false;
31308 try { 31309 var opts = Object.defineProperty({}, 'passive', { 31310 get: function() { 31311 g_supportsPassive = true; 31312 } 31313 }); 31314 window.addEventListener("testPassive", null, opts); 31315 window.removeEventListener("testPassive", null, opts); 31316 } catch (e) {} 31317 31318 //timeouts 31319 var resizeId; 31320 var afterSectionLoadsId; 31321 var afterSlideLoadsId; 31322 var scrollId; 31323 var scrollId2; 31324 var keydownId; 31325 var originals = $.extend(true, {}, options); //deep copy 31326 31327 //Uncode addition 31328 var $masthead = $('#masthead'); 31329 var hideMenu = !$('body').hasClass('vmenu') && $('body').hasClass('uncode-fp-menu-hide') ? true : false; 31330 var menuHeight = $masthead.hasClass('menu-transparent') || hideMenu ? 0 : UNCODE.menuHeight; 31331 var bodyBorder = UNCODE.bodyBorder; 31332 var adminBarHeight = UNCODE.adminBarHeight; 31333 31334 displayWarnings(); 31335 31336 //fixing bug in iScroll with links: https://github.com/cubiq/iscroll/issues/783 31337 iscrollOptions.click = isTouch; // see #2035 31338 31339 //extending iScroll options with the user custom ones 31340 iscrollOptions = $.extend(iscrollOptions, options.scrollOverflowOptions); 31341 31342 //easeInOutCubic animation included in the plugin 31343 $.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;}}); 31344 31345 /** 31346 * Sets the autoScroll option. 31347 * It changes the scroll bar visibility and the history of the site as a result. 31348 */ 31349 function setAutoScrolling(value, type){ 31350 //removing the transformation 31351 if(!value){ 31352 silentScroll(0); 31353 } 31354 31355 setVariableState('autoScrolling', value, type); 31356 31357 var element = $(SECTION_ACTIVE_SEL); 31358 31359 if(options.autoScrolling && !options.scrollBar){ 31360 $htmlBody.css({ 31361 'overflow' : 'hidden !important', 31362 'height' : '100%' 31363 }); 31364 31365 //Uncode addition 31366 //setRecordHistory(originals.recordHistory, 'internal'); 31367 31368 //for IE touch devices 31369 container.css({ 31370 '-ms-touch-action': 'none', 31371 'touch-action': 'none' 31372 }); 31373 31374 if(element.length){ 31375 //moving the container up 31376 silentScroll(element.position().top); 31377 } 31378 31379 }else{ 31380 $htmlBody.css({ 31381 'overflow' : 'visible !important', 31382 'height' : 'initial' 31383 }); 31384 31385 //Uncode addition 31386 //setRecordHistory(false, 'internal'); 31387 31388 //for IE touch devices 31389 container.css({ 31390 '-ms-touch-action': '', 31391 'touch-action': '' 31392 }); 31393 31394 //scrolling the page to the section with no animation 31395 if (element.length) { 31396 $htmlBody.scrollTop(element.position().top); 31397 } 31398 } 31399 } 31400 31401 /** 31402 * Defines wheter to record the history for each hash change in the URL. 31403 */ 31404 function setRecordHistory(value, type){ 31405 setVariableState('recordHistory', value, type); 31406 } 31407 31408 /** 31409 * Defines the scrolling speed 31410 */ 31411 function setScrollingSpeed(value, type){ 31412 setVariableState('scrollingSpeed', value, type); 31413 } 31414 31415 /** 31416 * Sets fitToSection 31417 */ 31418 function setFitToSection(value, type){ 31419 setVariableState('fitToSection', value, type); 31420 } 31421 31422 /** 31423 * Sets lockAnchors 31424 */ 31425 function setLockAnchors(value){ 31426 options.lockAnchors = value; 31427 } 31428 31429 /** 31430 * Adds or remove the possiblity of scrolling through sections by using the mouse wheel or the trackpad. 31431 */ 31432 function setMouseWheelScrolling(value){ 31433 if(value){ 31434 addMouseWheelHandler(); 31435 addMiddleWheelHandler(); 31436 }else{ 31437 removeMouseWheelHandler(); 31438 removeMiddleWheelHandler(); 31439 } 31440 } 31441 31442 /** 31443 * Adds or remove the possibility of scrolling through sections by using the mouse wheel/trackpad or touch gestures. 31444 * Optionally a second parameter can be used to specify the direction for which the action will be applied. 31445 * 31446 * @param directions string containing the direction or directions separated by comma. 31447 */ 31448 function setAllowScrolling(value, directions){ 31449 if(typeof directions !== 'undefined'){ 31450 directions = directions.replace(/ /g,'').split(','); 31451 31452 $.each(directions, function (index, direction){ 31453 setIsScrollAllowed(value, direction, 'm'); 31454 }); 31455 } 31456 else if(value){ 31457 setMouseWheelScrolling(true); 31458 addTouchHandler(); 31459 }else{ 31460 setMouseWheelScrolling(false); 31461 removeTouchHandler(); 31462 } 31463 } 31464 31465 /** 31466 * Adds or remove the possibility of scrolling through sections by using the keyboard arrow keys 31467 */ 31468 function setKeyboardScrolling(value, directions){ 31469 if(typeof directions !== 'undefined'){ 31470 directions = directions.replace(/ /g,'').split(','); 31471 31472 $.each(directions, function (index, direction){ 31473 setIsScrollAllowed(value, direction, 'k'); 31474 }); 31475 }else{ 31476 options.keyboardScrolling = value; 31477 } 31478 } 31479 31480 /** 31481 * Moves the page up one section. 31482 */ 31483 function moveSectionUp(){ 31484 var prev = $(SECTION_ACTIVE_SEL).prev(SECTION_SEL); 31485 31486 //looping to the bottom if there's no more sections above 31487 if (!prev.length && (options.loopTop || options.continuousVertical)) {
31488 prev = $(SECTION_SEL).last(); 31489 } 31490 31491 if (prev.length) { 31492 scrollPage(prev, null, true); 31493 } 31494 } 31495 31496 /** 31497 * Moves the page down one section. 31498 */ 31499 function moveSectionDown(){ 31500 var next = $(SECTION_ACTIVE_SEL).next(SECTION_SEL); 31501 31502 //looping to the top if there's no more sections below 31503 if(!next.length && 31504 (options.loopBottom || options.continuousVertical)){ 31505 next = $(SECTION_SEL).first(); 31506 } 31507 31508 if(next.length){ 31509 scrollPage(next, null, false); 31510 } 31511 } 31512 31513 /** 31514 * Moves the page to the given section and slide with no animation. 31515 * Anchors or index positions can be used as params. 31516 */ 31517 function silentMoveTo(sectionAnchor, slideAnchor){ 31518 setScrollingSpeed (0, 'internal'); 31519 moveTo(sectionAnchor, slideAnchor); 31520 setScrollingSpeed (originals.scrollingSpeed, 'internal'); 31521 } 31522 31523 /** 31524 * Moves the page to the given section and slide. 31525 * Anchors or index positions can be used as params. 31526 */ 31527 function moveTo(sectionAnchor, slideAnchor){ 31528 var destiny = getSectionByAnchor(sectionAnchor); 31529 31530 if (typeof slideAnchor !== 'undefined'){ 31531 scrollPageAndSlide(sectionAnchor, slideAnchor); 31532 }else if(destiny.length > 0){ 31533 scrollPage(destiny); 31534 } 31535 } 31536 31537 /** 31538 * Slides right the slider of the active section. 31539 * Optional `section` param. 31540 */ 31541 function moveSlideRight(section){ 31542 moveSlide('right', section); 31543 } 31544 31545 /** 31546 * Slides left the slider of the active section. 31547 * Optional `section` param. 31548 */ 31549 function moveSlideLeft(section){ 31550 moveSlide('left', section); 31551 } 31552 31553 /** 31554 * When resizing is finished, we adjust the slides sizes and positions 31555 */ 31556 function reBuild(resizing){ 31557 if(container.hasClass(DESTROYED)){ return; } //nothing to do if the plugin was destroyed 31558 31559 isResizing = true; 31560 31561 windowsHeight = $window.height(); //updating global var 31562 31563 $(SECTION_SEL).each(function(){ 31564 var slidesWrap = $(this).find(SLIDES_WRAPPER_SEL); 31565 var slides = $(this).find(SLIDE_SEL); 31566 31567 //adjusting the height of the table-cell for IE and Firefox 31568 if(options.verticalCentered){ 31569 $(this).find(TABLE_CELL_SEL).css('height', getTableHeight($(this)) + 'px'); 31570 } 31571 31572 $(this).css('height', windowsHeight + 'px'); 31573 31574 //resizing the scrolling divs 31575 if(options.scrollOverflow){ 31576 if(slides.length){ 31577 slides.each(function(){ 31578 createScrollBar($(this)); 31579 }); 31580 }else{ 31581 createScrollBar($(this)); 31582 } 31583 } 31584 31585 //adjusting the position fo the FULL WIDTH slides... 31586 if (slides.length > 1) { 31587 landscapeScroll(slidesWrap, slidesWrap.find(SLIDE_ACTIVE_SEL)); 31588 } 31589 }); 31590 31591 var activeSection = $(SECTION_ACTIVE_SEL); 31592 var sectionIndex = activeSection.index(SECTION_SEL); 31593 31594 //isn't it the first section? 31595 if(sectionIndex){ 31596 //adjusting the position for the current section 31597 silentMoveTo(sectionIndex + 1); 31598 } 31599 31600 isResizing = false; 31601 // Uncode change 31602 // $.isFunction( options.afterResize ) && resizing && options.afterResize.call(container); 31603 $.isFunction( options.afterResize ) && resizing && options.afterResize.call(container, getTableHeight()); 31604 $.isFunction( options.afterReBuild ) && !resizing && options.afterReBuild.call(container); 31605 } 31606 31607 /** 31608 * Turns fullPage.js to normal scrolling mode when the viewport `width` or `height` 31609 * are smaller than the set limit values. 31610 */ 31611 function setResponsive(active){ 31612 var isResponsive = $body.hasClass(RESPONSIVE); 31613 31614 if(active){ 31615 if(!isResponsive){ 31616 setAutoScrolling(false, 'internal'); 31617 setFitToSection(false, 'internal'); 31618 $(SECTION_NAV_SEL).hide(); 31619 $body.addClass(RESPONSIVE); 31620 $.isFunction( options.afterResponsive ) && options.afterResponsive.call( container, active); 31621 } 31622 } 31623 else if(isResponsive){ 31624 setAutoScrolling(originals.autoScrolling, 'internal'); 31625 setFitToSection(originals.autoScrolling, 'internal'); 31626 $(SECTION_NAV_SEL).show(); 31627 $body.removeClass(RESPONSIVE); 31628 $.isFunction( options.afterResponsive ) && options.afterResponsive.call( container, active); 31629 } 31630 } 31631 31632 if($(this).length){ 31633 //public functions 31634 FP.setAutoScrolling = setAutoScrolling; 31635 FP.setRecordHistory = setRecordHistory; 31636 FP.setScrollingSpeed = setScrollingSpeed; 31637 FP.setFitToSection = setFitToSection; 31638 FP.setLockAnchors = setLockAnchors; 31639 FP.setMouseWheelScrolling = setMouseWheelScrolling; 31640 FP.setAllowScrolling = setAllowScrolling; 31641 FP.setKeyboardScrolling = setKeyboardScrolling; 31642 FP.moveSectionUp = moveSectionUp; 31643 FP.moveSectionDown = moveSectionDown; 31644 FP.silentMoveTo = silentMoveTo; 31645 FP.moveTo = moveTo; 31646 FP.moveSlideRight = moveSlideRight; 31647 FP.moveSlideLeft = moveSlideLeft; 31648 FP.fitToSection = fitToSection; 31649 FP.reBuild = reBuild; 31650 FP.setResponsive = setResponsive; 31651 FP.destroy = destroy; 31652 31653 init(); 31654 31655 bindEvents(); 31656 } 31657
31658 function init(){ 31659 //if css3 is not supported, it will use jQuery animations 31660 if(options.css3){ 31661 options.css3 = support3d(); 31662 } 31663 31664 options.scrollBar = options.scrollBar || options.hybrid; 31665 31666 setOptionsFromDOM(); 31667 prepareDom(); 31668 setAllowScrolling(true); 31669 setAutoScrolling(options.autoScrolling, 'internal'); 31670 responsive(); 31671 31672 //setting the class for the body element 31673 setBodyClass(); 31674 31675 //Uncode addition 31676 // if(document.readyState === 'complete'){ 31677 // scrollToAnchor(); 31678 // } 31679 // $window.on('load', scrollToAnchor); 31680 } 31681 31682 function bindEvents(){ 31683 $window 31684 //when scrolling... 31685 //.on('scroll', scrollHandler) 31686 31687 //detecting any change on the URL to scroll to the given anchor link 31688 //(a way to detect back history button as we play with the hashes on the URL) 31689 .on('hashchange', hashChangeHandler) 31690 31691 //when opening a new tab (ctrl + t), `control` won't be pressed when coming back. 31692 .blur(blurHandler) 31693 31694 //when resizing the site, we adjust the heights of the sections, slimScroll... 31695 .resize(resizeHandler); 31696 31697 $document 31698 //Sliding with arrow keys, both, vertical and horizontal 31699 .keydown(keydownHandler) 31700 31701 //to prevent scrolling while zooming 31702 .keyup(keyUpHandler) 31703 31704 //Scrolls to the section when clicking the navigation bullet 31705 .on('click touchstart', SECTION_NAV_SEL + ' a', sectionBulletHandler) 31706 31707 //Scrolls the slider to the given slide destination for the given section 31708 .on('click touchstart', SLIDES_NAV_LINK_SEL, slideBulletHandler) 31709 31710 .on('click', SECTION_NAV_TOOLTIP_SEL, tooltipTextHandler); 31711 31712 //Scrolling horizontally when clicking on the slider controls. 31713 $(SECTION_SEL).on('click touchstart', SLIDES_ARROW_SEL, slideArrowHandler); 31714 31715 /** 31716 * Applying normalScroll elements. 31717 * Ignoring the scrolls over the specified selectors. 31718 */ 31719 if(options.normalScrollElements){ 31720 $document.on('mouseenter', options.normalScrollElements, function () { 31721 setMouseWheelScrolling(false); 31722 }); 31723 31724 $document.on('mouseleave', options.normalScrollElements, function(){ 31725 setMouseWheelScrolling(true); 31726 }); 31727 } 31728 } 31729 31730 /** 31731 * Setting options from DOM elements if they are not provided. 31732 */ 31733 function setOptionsFromDOM(){ 31734 var sections = container.find(options.sectionSelector); 31735 31736 //no anchors option? Checking for them in the DOM attributes 31737 if(!options.anchors.length){ 31738 options.anchors = sections.filter('[data-anchor]').map(function(){ 31739 return $(this).data('anchor').toString(); 31740 }).get(); 31741 } 31742 31743 //no tooltips option? Checking for them in the DOM attributes 31744 if(!options.navigationTooltips.length){ 31745 options.navigationTooltips = sections.filter('[data-tooltip]').map(function(){ 31746 return $(this).data('tooltip').toString(); 31747 }).get(); 31748 } 31749 } 31750 31751 /** 31752 * Works over the DOM structure to set it up for the current fullpage options. 31753 */ 31754 function prepareDom(){ 31755 container.css({ 31756 'height': '100%', 31757 'position': 'relative' 31758 }); 31759 31760 //adding a class to recognize the container internally in the code 31761 container.addClass(WRAPPER); 31762 $('html').addClass(ENABLED); 31763 31764 windowsHeight = $window.height(); 31765 31766 container.removeClass(DESTROYED); //in case it was destroyed before initializing it again 31767 31768 addInternalSelectors(); 31769 31770 //styling the sections / slides / menu 31771 $(SECTION_SEL).each(function(index){ 31772 var section = $(this); 31773 var slides = section.find(SLIDE_SEL); 31774 var numSlides = slides.length; 31775 31776 styleSection(section, index); 31777 styleMenu(section, index); 31778 31779 // if there's any slide 31780 if (numSlides > 0) { 31781 styleSlides(section, slides, numSlides); 31782 }else{ 31783 if(options.verticalCentered){ 31784 addTableClass(section); 31785 } 31786 } 31787 }); 31788 31789 //fixed elements need to be moved out of the plugin container due to problems with CSS3. 31790 if(options.fixedElements && options.css3){ 31791 $(options.fixedElements).appendTo($body); 31792 } 31793 31794 //vertical centered of the navigation + active bullet 31795 if(options.navigation){ 31796 addVerticalNavigation(); 31797 } 31798 31799 enableYoutubeAPI(); 31800 31801 if(options.scrollOverflow){ 31802 if(document.readyState === 'complete'){ 31803 createScrollBarHandler(); 31804 } 31805 //after DOM and images are loaded 31806 $window.on('load', createScrollBarHandler); 31807 }else{ 31808 afterRenderActions(); 31809 } 31810 } 31811 31812 /** 31813 * Styles the horizontal slides for a section. 31814 */ 31815 function styleSlides(section, slides, numSlides){ 31816 var sliderWidth = numSlides * 100; 31817 var slideWidth = 100 / numSlides; 31818 31819 slides.wrapAll('<div class="' + SLIDES_CONTAINER + '" />'); 31820 slides.parent().wrap('<div class="' + SLIDES_WRAPPER + '" />'); 31821 31822 section.find(SLIDES_CONTAINER_SEL).css('width', sliderWidth + '%'); 31823 31824 if(numSlides > 1){ 31825 if(options.controlArrows){ 31826 createSlideArrows(section); 31827 } 31828 31829 if(options.slidesNavigation){ 31830 addSlidesNavigation(section, numSlides); 31831 } 31832 } 31833 31834 slides.each(function(index) { 31835 $(this).css('width', slideWidth + '%'); 31836 31837 if(options.verticalCentered){ 31838 addTableClass($(this)); 31839 } 31840 }); 31841 31842 var startingSlide = section.find(SLIDE_ACTIVE_SEL); 31843 31844 //if the slide won't be an starting point, the default will be the first one 31845 //the active section isn't the first one? Is not the first slide of the first section? Then we load that section/sl
31845ide by default. 31846 if( startingSlide.length && ($(SECTION_ACTIVE_SEL).index(SECTION_SEL) !== 0 || ($(SECTION_ACTIVE_SEL).index(SECTION_SEL) === 0 && startingSlide.index() !== 0))){ 31847 silentLandscapeScroll(startingSlide, 'internal'); 31848 }else{ 31849 slides.eq(0).addClass(ACTIVE); 31850 } 31851 } 31852 31853 /** 31854 * Styling vertical sections 31855 */ 31856 function styleSection(section, index){ 31857 //if no active section is defined, the 1st one will be the default one 31858 if(!index && $(SECTION_ACTIVE_SEL).length === 0) { 31859 section.addClass(ACTIVE); 31860 } 31861 startingSection = $(SECTION_ACTIVE_SEL); 31862 31863 section.css('height', windowsHeight + 'px'); 31864 31865 if(options.paddingTop){ 31866 section.css('padding-top', options.paddingTop); 31867 } 31868 31869 if(options.paddingBottom){ 31870 section.css('padding-bottom', options.paddingBottom); 31871 } 31872 31873 if (typeof options.sectionsColor[index] !== 'undefined') { 31874 section.css('background-color', options.sectionsColor[index]); 31875 } 31876 31877 if (typeof options.anchors[index] !== 'undefined') { 31878 section.attr('data-anchor', options.anchors[index]); 31879 } 31880 } 31881 31882 /** 31883 * Sets the data-anchor attributes to the menu elements and activates the current one. 31884 */ 31885 function styleMenu(section, index){ 31886 if (typeof options.anchors[index] !== 'undefined') { 31887 //activating the menu / nav element on load 31888 if(section.hasClass(ACTIVE)){ 31889 activateMenuAndNav(options.anchors[index], index); 31890 } 31891 } 31892 31893 //moving the menu outside the main container if it is inside (avoid problems with fixed positions when using CSS3 tranforms) 31894 if(options.menu && options.css3 && $(options.menu).closest(WRAPPER_SEL).length){ 31895 $(options.menu).appendTo($body); 31896 } 31897 } 31898 31899 /** 31900 * Adds internal classes to be able to provide customizable selectors 31901 * keeping the link with the style sheet. 31902 */ 31903 function addInternalSelectors(){ 31904 container.find(options.sectionSelector).addClass(SECTION); 31905 container.find(options.slideSelector).addClass(SLIDE); 31906 } 31907 31908 /** 31909 * Creates the control arrows for the given section 31910 */ 31911 function createSlideArrows(section){ 31912 section.find(SLIDES_WRAPPER_SEL).after('<div class="' + SLIDES_ARROW_PREV + '"></div><div class="' + SLIDES_ARROW_NEXT + '"></div>'); 31913 31914 if(options.controlArrowColor!='#fff'){ 31915 section.find(SLIDES_ARROW_NEXT_SEL).css('border-color', 'transparent transparent transparent '+options.controlArrowColor); 31916 section.find(SLIDES_ARROW_PREV_SEL).css('border-color', 'transparent '+ options.controlArrowColor + ' transparent transparent'); 31917 } 31918 31919 if(!options.loopHorizontal){ 31920 section.find(SLIDES_ARROW_PREV_SEL).hide(); 31921 } 31922 } 31923 31924 /** 31925 * Creates a vertical navigation bar. 31926 */ 31927 function addVerticalNavigation(){ 31928 $body.append('<div id="' + SECTION_NAV + '"><ul></ul></div>'); 31929 var nav = $(SECTION_NAV_SEL); 31930 31931 nav.addClass(function() { 31932 return options.showActiveTooltip ? SHOW_ACTIVE_TOOLTIP + ' ' + options.navigationPosition : options.navigationPosition; 31933 }); 31934 31935 for (var i = 0; i < $(SECTION_SEL).length; i++) { 31936 var link = ''; 31937 if (options.anchors.length) { 31938 link = options.anchors[i]; 31939 } 31940 31941 var li = '<li><a href="#' + link + '"><span></span></a>'; 31942 31943 // Only add tooltip if needed (defined by user) 31944 var tooltip = options.navigationTooltips[i]; 31945 31946 if (typeof tooltip !== 'undefined' && tooltip !== '') { 31947 li += '<div class="' + SECTION_NAV_TOOLTIP + ' ' + options.navigationPosition + '">' + tooltip + '</div>'; 31948 } 31949 31950 li += '</li>'; 31951 31952 nav.find('ul').append(li); 31953 } 31954 31955 //centering it vertically 31956 $(SECTION_NAV_SEL).css('margin-top', '-' + ($(SECTION_NAV_SEL).height()/2) + 'px'); 31957 31958 //activating the current active section 31959 $(SECTION_NAV_SEL).find('li').eq($(SECTION_ACTIVE_SEL).index(SECTION_SEL)).find('a').addClass(ACTIVE); 31960 } 31961 31962 /** 31963 * Creates the slim scroll scrollbar for the sections and slides inside them. 31964 */ 31965 function createScrollBarHandler(){ 31966 $(SECTION_SEL).each(function(){ 31967 var slides = $(this).find(SLIDE_SEL); 31968 31969 if(slides.length){ 31970 slides.each(function(){ 31971 createScrollBar($(this)); 31972 }); 31973 }else{ 31974 createScrollBar($(this)); 31975 } 31976 31977 }); 31978 afterRenderActions(); 31979 } 31980 31981 /*
31982 * Enables the Youtube videos API so we can control their flow if necessary. 31983 */ 31984 function enableYoutubeAPI(){ 31985 container.find('iframe[src*="youtube.com/embed/"]').each(function(){ 31986 addURLParam($(this), 'enablejsapi=1'); 31987 }); 31988 } 31989 31990 /** 31991 * Adds a new parameter and its value to the `src` of a given element 31992 */ 31993 function addURLParam(element, newParam){ 31994 var originalSrc = element.attr('src'); 31995 element.attr('src', originalSrc + getUrlParamSign(originalSrc) + newParam); 31996 } 31997 31998 /* 31999 * Returns the prefix sign to use for a new parameter in an existen URL. 32000 * 32001 * @return {String} ? | & 32002 */ 32003 function getUrlParamSign(url){ 32004 return ( !/\?/.test( url ) ) ? '?' : '&'; 32005 } 32006 32007 /** 32008 * Actions and callbacks to fire afterRender 32009 */ 32010 function afterRenderActions(){ 32011 var section = $(SECTION_ACTIVE_SEL); 32012 32013 section.addClass(COMPLETELY); 32014 32015 if(options.scrollOverflowHandler.afterRender){ 32016 options.scrollOverflowHandler.afterRender(section); 32017 } 32018 lazyLoad(section); 32019 playMedia(section); 32020 options.scrollOverflowHandler.afterLoad(); 32021 32022 if(isDestinyTheStartingSection()){ 32023 $.isFunction( options.afterLoad ) && options.afterLoad.call(section, section.data('anchor'), (section.index(SECTION_SEL) + 1)); 32024 } 32025 32026 // Uncode change 32027 // $.isFunction( options.afterRender ) && options.afterRender.call(container); 32028 $.isFunction( options.afterRender ) && options.afterRender.call(container, getTableHeight()); 32029 } 32030 32031 /** 32032 * Determines if the URL anchor destiny is the starting section (the one using 'active' class before initialization) 32033 */ 32034 function isDestinyTheStartingSection(){ 32035 var anchors = window.location.hash.replace('#', '').split('/'); 32036 var destinationSection = getSectionByAnchor(decodeURIComponent(anchors[0])); 32037 32038 return !destinationSection.length || destinationSection.length && destinationSection.index() === startingSection.index(); 32039 } 32040 32041 32042 var isScrolling = false; 32043 var lastScroll = 0; 32044 32045 //when scrolling... 32046 function scrollHandler(){ 32047 var currentSection; 32048 32049 if(!options.autoScrolling || options.scrollBar){ 32050 var currentScroll = $window.scrollTop(); 32051 var scrollDirection = getScrollDirection(currentScroll); 32052 var visibleSectionIndex = 0; 32053 var screen_mid = currentScroll + ($window.height() / 2.0); 32054 var isAtBottom = $body.height() - $window.height() === currentScroll; 32055 var sections = document.querySelectorAll(SECTION_SEL); 32056 32057 //when using `auto-height` for a small last section it won't be centered in the viewport 32058 if(isAtBottom){ 32059 visibleSectionIndex = sections.length - 1; 32060 } 32061 //is at top? when using `auto-height` for a small first section it won't be centered in the viewport 32062 else if(!currentScroll){ 32063 visibleSectionIndex = 0; 32064 } 32065 32066 //taking the section which is showing more content in the viewport 32067 else{ 32068 for (var i = 0; i < sections.length; ++i) { 32069 var section = sections[i]; 32070 32071 // Pick the the last section which passes the middle line of the screen. 32072 if (section.offsetTop <= screen_mid) 32073 { 32074 visibleSectionIndex = i; 32075 } 32076 } 32077 } 32078 32079 if(isCompletelyInViewPort(scrollDirection)){ 32080 if(!$(SECTION_ACTIVE_SEL).hasClass(COMPLETELY)){ 32081 $(SECTION_ACTIVE_SEL).addClass(COMPLETELY).siblings().removeClass(COMPLETELY); 32082 } 32083 } 32084 32085 //geting the last one, the current one on the screen 32086 currentSection = $(sections).eq(visibleSectionIndex); 32087 32088 //setting the visible section as active when manually scrolling 32089 //executing only once the first time we reach the section 32090 if(!currentSection.hasClass(ACTIVE)){ 32091 isScrolling = true; 32092 var leavingSection = $(SECTION_ACTIVE_SEL); 32093 var leavingSectionIndex = leavingSection.index(SECTION_SEL) + 1; 32094 var yMovement = getYmovement(currentSection); 32095 var anchorLink = currentSection.data('anchor'); 32096 var sectionIndex = currentSection.index(SECTION_SEL) + 1; 32097 var activeSlide = currentSection.find(SLIDE_ACTIVE_SEL); 32098 var slideIndex; 32099 var slideAnchorLink; 32100 32101 if(activeSlide.length){ 32102 slideAnchorLink = activeSlide.data('anchor'); 32103 slideIndex = activeSlide.index(); 32104 } 32105 32106 if(canScroll){ 32107 currentSection.addClass(ACTIVE).siblings().removeClass(ACTIVE); 32108 32109 $.isFunction( options.onLeave ) && options.onLeave.call( leavingSection, leavingSectionIndex, sectionIndex, yMovement); 32110 $.isFunction( options.afterLoad ) && options.afterLoad.call( currentSection, anchorLink, sectionIndex); 32111 32112 stopMedia(leavingSection); 32113 lazyLoad(currentSection); 32114 playMedia(currentSection); 32115 32116 activateMenuAndNav(anchorLink, sectionIndex - 1); 32117 32118 if(options.anchors.length){ 32119 //needed to enter in hashChange event when using the menu with anchor links 32120 lastScrolledDestiny = anchorLink; 32121 } 32122 setState(slideIndex, slideAnchorLink, anchorLink, sectionIndex); 32123 } 32124 32125 //small timeout in order to avoid entering in hashChange event when scrolling is not finished yet 32126 clearTimeout(scrollId); 32127 scrollId = setTimeout(function(){ 32128 isScrolling = false;
32129 }, 100); 32130 } 32131 32132 if(options.fitToSection){ 32133 //for the auto adjust of the viewport to fit a whole section 32134 clearTimeout(scrollId2); 32135 32136 scrollId2 = setTimeout(function(){ 32137 //checking it again in case it changed during the delay 32138 if(options.fitToSection){ 32139 fitToSection(); 32140 } 32141 }, options.fitToSectionDelay); 32142 } 32143 } 32144 } 32145 32146 /** 32147 * Fits the site to the nearest active section 32148 */ 32149 function fitToSection(){ 32150 //checking fitToSection again in case it was set to false before the timeout delay 32151 if(canScroll){ 32152 //allows to scroll to an active section and 32153 //if the section is already active, we prevent firing callbacks 32154 isResizing = true; 32155 32156 scrollPage($(SECTION_ACTIVE_SEL)); 32157 isResizing = false; 32158 } 32159 } 32160 32161 /** 32162 * Determines whether the active section has seen in its whole or not. 32163 */ 32164 function isCompletelyInViewPort(movement){ 32165 var top = $(SECTION_ACTIVE_SEL).position().top; 32166 var bottom = top + $window.height(); 32167 32168 if(movement == 'up'){ 32169 return bottom >= ($window.scrollTop() + $window.height()); 32170 } 32171 return top <= $window.scrollTop(); 32172 } 32173 32174 /** 32175 * Gets the directon of the the scrolling fired by the scroll event. 32176 */ 32177 function getScrollDirection(currentScroll){ 32178 var direction = currentScroll > lastScroll ? 'down' : 'up'; 32179 32180 lastScroll = currentScroll; 32181 32182 //needed for auto-height sections to determine if we want to scroll to the top or bottom of the destination 32183 previousDestTop = currentScroll; 32184 32185 return direction; 32186 } 32187 32188 /** 32189 * Determines the way of scrolling up or down: 32190 * by 'automatically' scrolling a section or by using the default and normal scrolling. 32191 */ 32192 function scrolling(type, scrollable){ 32193 if (!isScrollAllowed.m[type]){ 32194 return; 32195 } 32196 var check = (type === 'down') ? 'bottom' : 'top'; 32197 var scrollSection = (type === 'down') ? moveSectionDown : moveSectionUp; 32198 32199 if(scrollable.length > 0 ){ 32200 //is the scrollbar at the start/end of the scroll? 32201 if(options.scrollOverflowHandler.isScrolled(check, scrollable)){ 32202 scrollSection(); 32203 }else{ 32204 return true; 32205 } 32206 }else{ 32207 // moved up/down 32208 scrollSection(); 32209 } 32210 } 32211 32212 /* 32213 * Preventing bouncing in iOS #2285 32214 */ 32215 function preventBouncing(event){ 32216 var e = event.originalEvent; 32217 if(!checkParentForNormalScrollElement(event.target) && options.autoScrolling && isReallyTouch(e) && isScrollAllowed.m.up){ 32218 //preventing the easing on iOS devices 32219 event.preventDefault(); 32220 } 32221 } 32222 32223 var touchStartY = 0; 32224 var touchStartX = 0; 32225 var touchEndY = 0; 32226 var touchEndX = 0; 32227 32228 /* Detecting touch events 32229 32230 * As we are changing the top property of the page on scrolling, we can not use the traditional way to detect it. 32231 * This way, the touchstart and the touch moves shows an small difference between them which is the 32232 * used one to determine the direction. 32233 */ 32234 function touchMoveHandler(event){ 32235 var e = event.originalEvent; 32236 var activeSection = $(e.target).closest(SECTION_SEL); 32237 32238 // additional: if one of the normalScrollElements isn't within options.normalScrollElementTouchThreshold hops up the DOM chain 32239 if (!checkParentForNormalScrollElement(event.target) && isReallyTouch(e) ) { 32240 32241 if(options.autoScrolling){ 32242 //preventing the easing on iOS devices 32243 event.preventDefault(); 32244 } 32245 32246 var scrollable = options.scrollOverflowHandler.scrollable(activeSection); 32247 var touchEvents = getEventsPage(e); 32248 32249 touchEndY = touchEvents.y; 32250 touchEndX = touchEvents.x; 32251 32252 //if movement in the X axys is greater than in the Y and the currect section has slides... 32253 if (activeSection.find(SLIDES_WRAPPER_SEL).length && Math.abs(touchStartX - touchEndX) > (Math.abs(touchStartY - touchEndY))) { 32254 32255 //is the movement greater than the minimum resistance to scroll? 32256 if (!slideMoving && Math.abs(touchStartX - touchEndX) > ($window.outerWidth() / 100 * options.touchSensitivity)) { 32257 if (touchStartX > touchEndX) { 32258 if(isScrollAllowed.m.right){ 32259 moveSlideRight(activeSection); //next 32260 } 32261 } else { 32262 if(isScrollAllowed.m.left){ 32263 moveSlideLeft(activeSection); //prev 32264 } 32265 } 32266 } 32267 } 32268 32269 //vertical scrolling (only when autoScrolling is enabled) 32270 else if(options.autoScrolling && canScroll){ 32271 32272 //is the movement greater than the minimum resistance to scroll? 32273 if (Math.abs(touchStartY - touchEndY) > ($window.height() / 100 * options.touchSensitivity)) { 32274 if (touchStartY > touchEndY) { 32275 scrolling('down', scrollable); 32276 } else if (touchEndY > touchStartY) { 32277 scrolling('up', scrollable); 32278 } 32279 } 32280 } 32281 } 32282 } 32283 32284 /** 32285 * recursive function to loop up the parent nodes to check if one of them exists in options.normalScrollElements 32286 * Currently works well for iOS - Android might need some testing 32287 * @param {Element} el target element / jquery selector (in subsequent nodes) 32288 * @param {int} hop current hop compared to options.normalScrollElementTouchThreshold 32289 * @return {boolean} true if there is a match to options.normalScrollElements 32290 */ 32291 function checkParentForNormalScrollElement (el, hop) { 32292 hop = hop || 0; 32293 var parent = $(el).parent(); 32294 32295 if (hop < options.normalScrollElementTouchThreshold && 32296 parent.is(options.normalScrollElements) ) { 32297 return true; 32298 } else if (hop == options.normalScrollElementTouchThreshold) { 32299 return false;
32300 } else { 32301 return checkParentForNormalScrollElement(parent, ++hop); 32302 } 32303 } 32304 32305 /** 32306 * As IE >= 10 fires both touch and mouse events when using a mouse in a touchscreen 32307 * this way we make sure that is really a touch event what IE is detecting. 32308 */ 32309 function isReallyTouch(e){ 32310 //if is not IE || IE is detecting `touch` or `pen` 32311 return typeof e.pointerType === 'undefined' || e.pointerType != 'mouse'; 32312 } 32313 32314 /** 32315 * Handler for the touch start event. 32316 */ 32317 function touchStartHandler(event){ 32318 var e = event.originalEvent; 32319 32320 //stopping the auto scroll to adjust to a section 32321 if(options.fitToSection){ 32322 $htmlBody.stop(); 32323 } 32324 32325 if(isReallyTouch(e)){ 32326 var touchEvents = getEventsPage(e); 32327 touchStartY = touchEvents.y; 32328 touchStartX = touchEvents.x; 32329 } 32330 } 32331 32332 /** 32333 * Gets the average of the last `number` elements of the given array. 32334 */ 32335 function getAverage(elements, number){ 32336 var sum = 0; 32337 32338 //taking `number` elements from the end to make the average, if there are not enought, 1 32339 var lastElements = elements.slice(Math.max(elements.length - number, 1)); 32340 32341 for(var i = 0; i < lastElements.length; i++){ 32342 sum = sum + lastElements[i]; 32343 } 32344 32345 return Math.ceil(sum/number); 32346 } 32347 32348 /** 32349 * Detecting mousewheel scrolling 32350 * 32351 * http://blogs.sitepointstatic.com/examples/tech/mouse-wheel/index.html 32352 * http://www.sitepoint.com/html5-javascript-mouse-wheel/ 32353 */ 32354 var prevTime = new Date().getTime(); 32355 32356 function MouseWheelHandler(e) { 32357 var curTime = new Date().getTime(); 32358 var isNormalScroll = $(COMPLETELY_SEL).hasClass(NORMAL_SCROLL); 32359 32360 //autoscrolling and not zooming? 32361 if(options.autoScrolling && !controlPressed && !isNormalScroll){ 32362 // cross-browser wheel delta 32363 e = e || window.event; 32364 var value = e.wheelDelta || -e.deltaY || -e.detail; 32365 var delta = Math.max(-1, Math.min(1, value)); 32366 32367 var horizontalDetection = typeof e.wheelDeltaX !== 'undefined' || typeof e.deltaX !== 'undefined'; 32368 var isScrollingVertically = (Math.abs(e.wheelDeltaX) < Math.abs(e.wheelDelta)) || (Math.abs(e.deltaX ) < Math.abs(e.deltaY) || !horizontalDetection); 32369 32370 //Limiting the array to 150 (lets not waste memory!) 32371 if(scrollings.length > 149){ 32372 scrollings.shift(); 32373 } 32374 32375 //keeping record of the previous scrollings 32376 scrollings.push(Math.abs(value)); 32377 32378 //preventing to scroll the site on mouse wheel when scrollbar is present 32379 if(options.scrollBar){ 32380 e.preventDefault ? e.preventDefault() : e.returnValue = false; 32381 } 32382 32383 var activeSection = $(SECTION_ACTIVE_SEL); 32384 var scrollable = options.scrollOverflowHandler.scrollable(activeSection); 32385 32386 //time difference between the last scroll and the current one 32387 var timeDiff = curTime-prevTime; 32388 prevTime = curTime; 32389 32390 //haven't they scrolled in a while? 32391 //(enough to be consider a different scrolling action to scroll another section) 32392 if(timeDiff > 200){ 32393 //emptying the array, we dont care about old scrollings for our averages 32394 scrollings = []; 32395 } 32396 32397 if(canScroll){ 32398 var averageEnd = getAverage(scrollings, 10); 32399 var averageMiddle = getAverage(scrollings, 70); 32400 var isAccelerating = averageEnd >= averageMiddle; 32401 32402 //to avoid double swipes... 32403 if(isAccelerating && isScrollingVertically){ 32404 //scrolling down? 32405 if (delta < 0) { 32406 scrolling('down', scrollable); 32407 32408 //scrolling up? 32409 }else { 32410 scrolling('up', scrollable); 32411 } 32412 } 32413 } 32414 32415 return false;
32416 } 32417 32418 if(options.fitToSection){ 32419 //stopping the auto scroll to adjust to a section 32420 $htmlBody.stop(); 32421 } 32422 } 32423 32424 /** 32425 * Slides a slider to the given direction. 32426 * Optional `section` param. 32427 */ 32428 function moveSlide(direction, section){ 32429 var activeSection = typeof section === 'undefined' ? $(SECTION_ACTIVE_SEL) : section; 32430 var slides = activeSection.find(SLIDES_WRAPPER_SEL); 32431 var numSlides = slides.find(SLIDE_SEL).length; 32432 32433 // more than one slide needed and nothing should be sliding 32434 if (!slides.length || slideMoving || numSlides < 2) { 32435 return; 32436 } 32437 32438 var currentSlide = slides.find(SLIDE_ACTIVE_SEL); 32439 var destiny = null; 32440 32441 if(direction === 'left'){ 32442 destiny = currentSlide.prev(SLIDE_SEL); 32443 }else{ 32444 destiny = currentSlide.next(SLIDE_SEL); 32445 } 32446 32447 //isn't there a next slide in the secuence? 32448 if(!destiny.length){ 32449 //respect loopHorizontal settin 32450 if (!options.loopHorizontal) return; 32451 32452 if(direction === 'left'){ 32453 destiny = currentSlide.siblings(':last'); 32454 }else{ 32455 destiny = currentSlide.siblings(':first'); 32456 } 32457 } 32458 32459 slideMoving = true; 32460 32461 landscapeScroll(slides, destiny, direction); 32462 } 32463 32464 /** 32465 * Maintains the active slides in the viewport 32466 * (Because the `scroll` animation might get lost with some actions, such as when using continuousVertical) 32467 */ 32468 function keepSlidesPosition(){ 32469 $(SLIDE_ACTIVE_SEL).each(function(){ 32470 silentLandscapeScroll($(this), 'internal'); 32471 }); 32472 } 32473 32474 var previousDestTop = 0; 32475 /** 32476 * Returns the destination Y position based on the scrolling direction and 32477 * the height of the section. 32478 */ 32479 function getDestinationPosition(element){ 32480 var elemPosition = element.position(); 32481 32482 //top of the desination will be at the top of the viewport 32483 var position = elemPosition.top; 32484 var isScrollingDown = elemPosition.top > previousDestTop; 32485 var sectionBottom = position - windowsHeight + element.outerHeight(); 32486 var bigSectionsDestination = options.bigSectionsDestination; 32487 32488 //Uncode addition 32489 var containerH = container.outerHeight(); 32490 var containerPosition = container.offset(); 32491 32492 //########### Commented by Uncode - START ########### 32493 //is the destination element bigger than the viewport? 32494 // if(element.outerHeight() > windowsHeight){ 32495 // //scrolling up? 32496 // if(!isScrollingDown && !bigSectionsDestination || bigSectionsDestination === 'bottom' ){ 32497 // position = sectionBottom; 32498 // } 32499 // } 32500 32501 // //sections equal or smaller than the viewport height && scrolling down? || is resizing and its in the last section 32502 // else if(isScrollingDown || (isResizing && element.is(':last-child')) ){ 32503 // //The bottom of the destination will be at the bottom of the viewport 32504 // position = sectionBottom; 32505 // } 32506 //########### Commented by Uncode - END ########### 32507 32508 //Uncode addition 32509 if ( !$masthead.hasClass('menu-transparent') && $('body').hasClass('uncode-fp-menu-shrink') && !element.is(':first-child') ) 32510 position += 18; 32511 if ( ( containerH + menuHeight + bodyBorder + adminBarHeight - windowsHeight ) < position || ( isResizing && element.is(':last-child') ) ) { 32512 position = sectionBottom + menuHeight + bodyBorder*2 + adminBarHeight; 32513 } 32514 32515 /* 32516 Keeping record of the last scrolled position to determine the scrolling direction. 32517 No conventional methods can be used as the scroll bar might not be present 32518 AND the section might not be active if it is auto-height and didnt reach the middle 32519 of the viewport. 32520 */ 32521 previousDestTop = position; 32522 return position; 32523 } 32524 32525 /** 32526 * Scrolls the site to the given element and scrolls to the slide if a callback is given. 32527 */ 32528 function scrollPage(element, callback, isMovementUp){ 32529 if(typeof element === 'undefined'){ return; } //there's no element to scroll, leaving the function 32530 32531 var dtop = getDestinationPosition(element); 32532 var slideAnchorLink; 32533 var slideIndex; 32534 32535 //local variables 32536 var v = { 32537 element: element, 32538 callback: callback, 32539 isMovementUp: isMovementUp, 32540 dtop: dtop, 32541 yMovement: getYmovement(element), 32542 anchorLink: element.data('anchor'), 32543 sectionIndex: element.index(SECTION_SEL), 32544 activeSlide: element.find(SLIDE_ACTIVE_SEL), 32545 activeSection: $(SECTION_ACTIVE_SEL), 32546 leavingSection: $(SECTION_ACTIVE_SEL).index(SECTION_SEL) + 1, 32547 32548 //caching the value of isResizing at the momment the function is called 32549 //because it will be checked later inside a setTimeout and the value might change 32550 localIsResizing: isResizing 32551 }; 32552 32553 //quiting when destination scroll is the same as the current one 32554 if((v.activeSection.is(element) && !isResizing) || (options.scrollBar && $window.scrollTop() === v.dtop && !element.hasClass(AUTO_HEIGHT) )){ return; } 32555 32556 if(v.activeSlide.length){ 32557 slideAnchorLink = v.activeSlide.data('anchor'); 32558 slideIndex = v.activeSlide.index(); 32559 } 32560 32561 // If continuousVertical && we need to wrap around 32562 if (options.autoScrolling && options.continuousVertical && typeof (v.isMovementUp) !== "undefined" && 32563 ((!v.isMovementUp && v.yMovement == 'up') || // Intending to scroll down but about to go up or 32564 (v.isMovementUp && v.yMovement == 'down'))) { // intending to scroll up but about to go down 32565 32566 v = createInfiniteSections(v); 32567 } 32568 32569 //callback (onLeave) if the site is not just resizing and readjusting the slides 32570 if($.isFunction(options.onLeave) && !v.localIsResizing){ 32571 if(options.onLeave.call(v.activeSection, v.leavingSection, (v.sectionIndex + 1), v.yMovement) === false){ 32572 return; 32573 } 32574 } 32575 32576 //pausing media of the leaving section (if we are not just resizing, as destinatino will be the same one) 32577 if(!v.localIsResizing){ 32578 stopMedia(v.activeSection); 32579 } 32580 32581 options.scrollOverflowHandler.beforeLeave(); 32582 element.addClass(ACTIVE).siblings().removeClass(ACTIVE); 32583 lazyLoad(element); 32584 options.scrollOverflowHandler.onLeave(); 32585 32586 32587 //preventing from activating the MouseWheelHandler event 32588 //more than once if the page is scrolling 32589 canScroll = false;
32590 32591 setState(slideIndex, slideAnchorLink, v.anchorLink, v.sectionIndex); 32592 32593 performMovement(v); 32594 32595 //flag to avoid callingn `scrollPage()` twice in case of using anchor links 32596 lastScrolledDestiny = v.anchorLink; 32597 32598 //avoid firing it twice (as it does also on scroll) 32599 activateMenuAndNav(v.anchorLink, v.sectionIndex); 32600 } 32601 32602 /** 32603 * Performs the vertical movement (by CSS3 or by jQuery) 32604 */ 32605 function performMovement(v){ 32606 // using CSS3 translate functionality 32607 if (options.css3 && options.autoScrolling && !options.scrollBar) { 32608 32609 // The first section can have a negative value in iOS 10. Not quite sure why: -0.0142822265625 32610 // that's why we round it to 0. 32611 var translate3d = 'translate3d(0px, -' + Math.round(v.dtop) + 'px, 0px)'; 32612 transformContainer(translate3d, true); 32613 32614 //even when the scrollingSpeed is 0 there's a little delay, which might cause the 32615 //scrollingSpeed to change in case of using silentMoveTo(); 32616 if(options.scrollingSpeed){ 32617 clearTimeout(afterSectionLoadsId); 32618 afterSectionLoadsId = setTimeout(function () { 32619 afterSectionLoads(v); 32620 }, options.scrollingSpeed); 32621 }else{ 32622 afterSectionLoads(v); 32623 } 32624 } 32625 32626 // using jQuery animate 32627 else{ 32628 var scrollSettings = getScrollSettings(v); 32629 32630 $(scrollSettings.element).animate( 32631 scrollSettings.options, 32632 options.scrollingSpeed, options.easing).promise().done(function () { //only one single callback in case of animating `html, body` 32633 if(options.scrollBar){ 32634 32635 /* Hack! 32636 The timeout prevents setting the most dominant section in the viewport as "active" when the user 32637 scrolled to a smaller section by using the mousewheel (auto scrolling) rather than draging the scroll bar. 32638 32639 When using scrollBar:true It seems like the scroll events still getting propagated even after the scrolling animation has finished. 32640 */ 32641 setTimeout(function(){ 32642 afterSectionLoads(v); 32643 },30); 32644 }else{ 32645 afterSectionLoads(v); 32646 } 32647 }); 32648 } 32649 } 32650 32651 /** 32652 * Gets the scrolling settings depending on the plugin autoScrolling option 32653 */ 32654 function getScrollSettings(v){ 32655 var scroll = {}; 32656 32657 if(options.autoScrolling && !options.scrollBar){ 32658 scroll.options = { 'top': -v.dtop}; 32659 scroll.element = WRAPPER_SEL; 32660 }else{ 32661 scroll.options = { 'scrollTop': v.dtop}; 32662 scroll.element = 'html, body'; 32663 } 32664 32665 return scroll; 32666 } 32667 32668 /** 32669 * Adds sections before or after the current one to create the infinite effect. 32670 */ 32671 function createInfiniteSections(v){ 32672 // Scrolling down 32673 if (!v.isMovementUp) { 32674 // Move all previous sections to after the active section 32675 $(SECTION_ACTIVE_SEL).after(v.activeSection.prevAll(SECTION_SEL).get().reverse()); 32676 } 32677 else { // Scrolling up 32678 // Move all next sections to before the active section 32679 $(SECTION_ACTIVE_SEL).before(v.activeSection.nextAll(SECTION_SEL)); 32680 } 32681 32682 // Maintain the displayed position (now that we changed the element order) 32683 silentScroll($(SECTION_ACTIVE_SEL).position().top); 32684 32685 // Maintain the active slides visible in the viewport 32686 keepSlidesPosition(); 32687 32688 // save for later the elements that still need to be reordered 32689 v.wrapAroundElements = v.activeSection; 32690 32691 // Recalculate animation variables 32692 v.dtop = v.element.position().top; 32693 v.yMovement = getYmovement(v.element); 32694 32695 return v; 32696 } 32697 32698 /** 32699 * Fix section order after continuousVertical changes have been animated 32700 */ 32701 function continuousVerticalFixSectionOrder (v) {
32702 // If continuousVertical is in effect (and autoScrolling would also be in effect then), 32703 // finish moving the elements around so the direct navigation will function more simply 32704 if (!v.wrapAroundElements || !v.wrapAroundElements.length) { 32705 return; 32706 } 32707 32708 if (v.isMovementUp) { 32709 $(SECTION_FIRST_SEL).before(v.wrapAroundElements); 32710 } 32711 else { 32712 $(SECTION_LAST_SEL).after(v.wrapAroundElements); 32713 } 32714 32715 silentScroll($(SECTION_ACTIVE_SEL).position().top); 32716 32717 // Maintain the active slides visible in the viewport 32718 keepSlidesPosition(); 32719 } 32720 32721 32722 /** 32723 * Actions to do once the section is loaded. 32724 */ 32725 function afterSectionLoads (v){ 32726 continuousVerticalFixSectionOrder(v); 32727 32728 //callback (afterLoad) if the site is not just resizing and readjusting the slides 32729 $.isFunction(options.afterLoad) && !v.localIsResizing && options.afterLoad.call(v.element, v.anchorLink, (v.sectionIndex + 1)); 32730 options.scrollOverflowHandler.afterLoad(); 32731 32732 if(!v.localIsResizing){ 32733 playMedia(v.element); 32734 } 32735 32736 v.element.addClass(COMPLETELY).siblings().removeClass(COMPLETELY); 32737 32738 canScroll = true; 32739 32740 $.isFunction(v.callback) && v.callback.call(this); 32741 } 32742 32743 /** 32744 * Sets the value for the given attribute from the `data-` attribute with the same suffix 32745 * ie: data-srcset ==> srcset | data-src ==> src 32746 */ 32747 function setSrc(element, attribute){ 32748 element 32749 .attr(attribute, element.data(attribute)) 32750 .removeAttr('data-' + attribute); 32751 } 32752 32753 /** 32754 * Lazy loads image, video and audio elements. 32755 */ 32756 function lazyLoad(destiny){ 32757 if (!options.lazyLoading){ 32758 return; 32759 } 32760 32761 var panel = getSlideOrSection(destiny); 32762 var element; 32763 32764 panel.find('img[data-src], img[data-srcset], source[data-src], audio[data-src], iframe[data-src]').each(function(){ 32765 element = $(this); 32766 32767 $.each(['src', 'srcset'], function(index, type){ 32768 var attribute = element.attr('data-' + type); 32769 if(typeof attribute !== 'undefined' && attribute){ 32770 setSrc(element, type); 32771 } 32772 }); 32773 32774 if(element.is('source')){ 32775 element.closest('video').get(0).load(); 32776 } 32777 }); 32778 } 32779 32780 /** 32781 * Plays video and audio elements. 32782 */ 32783 function playMedia(destiny){ 32784 var panel = getSlideOrSection(destiny); 32785 32786 //playing HTML5 media elements 32787 panel.find('video, audio').each(function(){ 32788 var element = $(this).get(0); 32789 32790 if( element.hasAttribute('data-autoplay') && typeof element.play === 'function' ) { 32791 element.play(); 32792 } 32793 }); 32794 32795 //youtube videos 32796 panel.find('iframe[src*="youtube.com/embed/"]').each(function(){ 32797 var element = $(this).get(0); 32798 32799 if ( element.hasAttribute('data-autoplay') ){ 32800 playYoutube(element); 32801 } 32802 32803 //in case the URL was not loaded yet. On page load we need time for the new URL (with the API string) to load. 32804 element.onload = function() { 32805 if ( element.hasAttribute('data-autoplay') ){ 32806 playYoutube(element); 32807 } 32808 }; 32809 }); 32810 } 32811 32812 /** 32813 * Plays a youtube video 32814 */ 32815 function playYoutube(element){ 32816 element.contentWindow.postMessage('{"event":"command","func":"playVideo","args":""}', '*'); 32817 } 32818 32819 /** 32820 * Stops video and audio elements. 32821 */ 32822 function stopMedia(destiny){ 32823 var panel = getSlideOrSection(destiny); 32824 32825 //stopping HTML5 media elements 32826 panel.find('video, audio').each(function(){ 32827 var element = $(this).get(0); 32828 32829 if( !element.hasAttribute('data-keepplaying') && typeof element.pause === 'function' ) { 32830 element.pause(); 32831 } 32832 }); 32833 32834 //youtube videos 32835 panel.find('iframe[src*="youtube.com/embed/"]').each(function(){ 32836 var element = $(this).get(0); 32837 32838 if( /youtube\.com\/embed\//.test($(this).attr('src')) && !element.hasAttribute('data-keepplaying')){ 32839 $(this).get(0).contentWindow.postMessage('{"event":"command","func":"pauseVideo","args":""}','*'); 32840 } 32841 }); 32842 } 32843 32844 /** 32845 * Gets the active slide (or section) for the given section 32846 */ 32847 function getSlideOrSection(destiny){ 32848 var slide = destiny.find(SLIDE_ACTIVE_SEL); 32849 if( slide.length ) { 32850 destiny = $(slide); 32851 } 32852 32853 return destiny; 32854 } 32855 32856 /**
32857 * Scrolls to the anchor in the URL when loading the site 32858 */ 32859 function scrollToAnchor(){ 32860 //getting the anchor link in the URL and deleting the `#` 32861 var value = window.location.hash.replace('#', '').split('/'); 32862 var sectionAnchor = decodeURIComponent(value[0]); 32863 var slideAnchor = decodeURIComponent(value[1]); 32864 32865 if(sectionAnchor){ //if theres any # 32866 if(options.animateAnchor){ 32867 scrollPageAndSlide(sectionAnchor, slideAnchor); 32868 }else{ 32869 silentMoveTo(sectionAnchor, slideAnchor); 32870 } 32871 } 32872 } 32873 32874 /** 32875 * Detecting any change on the URL to scroll to the given anchor link 32876 * (a way to detect back history button as we play with the hashes on the URL) 32877 */ 32878 function hashChangeHandler(){ 32879 if(!isScrolling && !options.lockAnchors){ 32880 var value = window.location.hash.replace('#', '').split('/'); 32881 var sectionAnchor = decodeURIComponent(value[0]); 32882 var slideAnchor = decodeURIComponent(value[1]); 32883 32884 //when moving to a slide in the first section for the first time (first time to add an anchor to the URL) 32885 var isFirstSlideMove = (typeof lastScrolledDestiny === 'undefined'); 32886 var isFirstScrollMove = (typeof lastScrolledDestiny === 'undefined' && typeof slideAnchor === 'undefined' && !slideMoving); 32887 32888 32889 if(sectionAnchor.length){ 32890 /*in order to call scrollpage() only once for each destination at a time 32891 It is called twice for each scroll otherwise, as in case of using anchorlinks `hashChange` 32892 event is fired on every scroll too.*/ 32893 if ((sectionAnchor && sectionAnchor !== lastScrolledDestiny) && !isFirstSlideMove || isFirstScrollMove || (!slideMoving && lastScrolledSlide != slideAnchor )) { 32894 scrollPageAndSlide(sectionAnchor, slideAnchor); 32895 } 32896 } 32897 } 32898 } 32899 32900 //Sliding with arrow keys, both, vertical and horizontal 32901 function keydownHandler(e) { 32902 32903 clearTimeout(keydownId); 32904 32905 var activeElement = $(':focus'); 32906 32907 if(!activeElement.is('textarea') && !activeElement.is('input') && !activeElement.is('select') && 32908 activeElement.attr('contentEditable') !== "true" && activeElement.attr('contentEditable') !== '' && 32909 options.keyboardScrolling && options.autoScrolling){ 32910 var keyCode = e.which; 32911 32912 //preventing the scroll with arrow keys & spacebar & Page Up & Down keys 32913 var keyControls = [40, 38, 32, 33, 34]; 32914 if($.inArray(keyCode, keyControls) > -1){ 32915 e.preventDefault(); 32916 } 32917 32918 controlPressed = e.ctrlKey; 32919 32920 keydownId = setTimeout(function(){ 32921 onkeydown(e); 32922 },150); 32923 } 32924 } 32925 32926 function tooltipTextHandler(){ 32927 $(this).prev().trigger('click'); 32928 } 32929 32930 //to prevent scrolling while zooming 32931 function keyUpHandler(e){ 32932 if(isWindowFocused){ //the keyup gets fired on new tab ctrl + t in Firefox 32933 controlPressed = e.ctrlKey; 32934 } 32935 } 32936 32937 //binding the mousemove when the mouse's middle button is released 32938 function mouseDownHandler(e){ 32939 //middle button 32940 if (e.which == 2){ 32941 oldPageY = e.pageY; 32942 container.on('mousemove', mouseMoveHandler); 32943 } 32944 } 32945 32946 //unbinding the mousemove when the mouse's middle button is released 32947 function mouseUpHandler(e){ 32948 //middle button 32949 if (e.which == 2){ 32950 container.off('mousemove'); 32951 } 32952 } 32953 32954 //Scrolling horizontally when clicking on the slider controls. 32955 function slideArrowHandler(){ 32956 var section = $(this).closest(SECTION_SEL); 32957 32958 if ($(this).hasClass(SLIDES_PREV)) { 32959 if(isScrollAllowed.m.left){ 32960 moveSlideLeft(section); 32961 } 32962 } else { 32963 if(isScrollAllowed.m.right){ 32964 moveSlideRight(section); 32965 } 32966 } 32967 } 32968 32969 //when opening a new tab (ctrl + t), `control` won't be pressed when coming back. 32970 function blurHandler(){ 32971 isWindowFocused = false;
32972 controlPressed = false; 32973 } 32974 32975 //Scrolls to the section when clicking the navigation bullet 32976 function sectionBulletHandler(e){ 32977 e.preventDefault(); 32978 var index = $(this).parent().index(); 32979 scrollPage($(SECTION_SEL).eq(index)); 32980 } 32981 32982 //Scrolls the slider to the given slide destination for the given section 32983 function slideBulletHandler(e){ 32984 e.preventDefault(); 32985 var slides = $(this).closest(SECTION_SEL).find(SLIDES_WRAPPER_SEL); 32986 var destiny = slides.find(SLIDE_SEL).eq($(this).closest('li').index()); 32987 32988 landscapeScroll(slides, destiny); 32989 } 32990 32991 /** 32992 * Keydown event 32993 */ 32994 function onkeydown(e){ 32995 var shiftPressed = e.shiftKey; 32996 32997 //do nothing if we can not scroll or we are not using horizotnal key arrows. 32998 if(!canScroll && [37,39].indexOf(e.which) < 0){ 32999 return; 33000 } 33001 33002 switch (e.which) { 33003 //up 33004 case 38: 33005 case 33: 33006 if(isScrollAllowed.k.up){ 33007 moveSectionUp(); 33008 } 33009 break; 33010 33011 //down 33012 case 32: //spacebar 33013 if(shiftPressed && isScrollAllowed.k.up){ 33014 moveSectionUp(); 33015 break; 33016 } 33017 /* falls through */ 33018 case 40: 33019 case 34: 33020 if(isScrollAllowed.k.down){ 33021 moveSectionDown(); 33022 } 33023 break; 33024 33025 //Home 33026 case 36: 33027 if(isScrollAllowed.k.up){ 33028 moveTo(1); 33029 } 33030 break; 33031 33032 //End 33033 case 35: 33034 if(isScrollAllowed.k.down){ 33035 moveTo( $(SECTION_SEL).length ); 33036 } 33037 break; 33038 33039 //left 33040 case 37: 33041 if(isScrollAllowed.k.left){ 33042 moveSlideLeft(); 33043 } 33044 break; 33045 33046 //right 33047 case 39: 33048 if(isScrollAllowed.k.right){ 33049 moveSlideRight(); 33050 } 33051 break; 33052 33053 default: 33054 return; // exit this handler for other keys 33055 } 33056 } 33057 33058 /** 33059 * Detecting the direction of the mouse movement. 33060 * Used only for the middle button of the mouse. 33061 */ 33062 var oldPageY = 0; 33063 function mouseMoveHandler(e){ 33064 if(canScroll){ 33065 // moving up 33066 if (e.pageY < oldPageY && isScrollAllowed.m.up){ 33067 moveSectionUp(); 33068 } 33069 33070 // moving down 33071 else if(e.pageY > oldPageY && isScrollAllowed.m.down){ 33072 moveSectionDown(); 33073 } 33074 } 33075 oldPageY = e.pageY; 33076 } 33077 33078 /** 33079 * Scrolls horizontal sliders. 33080 */ 33081 function landscapeScroll(slides, destiny, direction){ 33082 var section = slides.closest(SECTION_SEL); 33083 var v = { 33084 slides: slides, 33085 destiny: destiny, 33086 direction: direction, 33087 destinyPos: destiny.position(), 33088 slideIndex: destiny.index(), 33089 section: section, 33090 sectionIndex: section.index(SECTION_SEL), 33091 anchorLink: section.data('anchor'), 33092 slidesNav: section.find(SLIDES_NAV_SEL), 33093 slideAnchor: getAnchor(destiny), 33094 prevSlide: section.find(SLIDE_ACTIVE_SEL), 33095 prevSlideIndex: section.find(SLIDE_ACTIVE_SEL).index(), 33096 33097 //caching the value of isResizing at the momment the function is called 33098 //because it will be checked later inside a setTimeout and the value might change 33099 localIsResizing: isResizing 33100 }; 33101 v.xMovement = getXmovement(v.prevSlideIndex, v.slideIndex); 33102 v.direction = v.direction ? v.direction : v.xMovement; 33103 33104 //important!! Only do it when not resizing 33105 if(!v.localIsResizing){ 33106 //preventing from scrolling to the next/prev section when using scrollHorizontally 33107 canScroll = false;
33108 } 33109 33110 if(options.onSlideLeave){ 33111 33112 //if the site is not just resizing and readjusting the slides 33113 if(!v.localIsResizing && v.xMovement!=='none'){ 33114 if($.isFunction( options.onSlideLeave )){ 33115 if(options.onSlideLeave.call( v.prevSlide, v.anchorLink, (v.sectionIndex + 1), v.prevSlideIndex, v.xMovement, v.slideIndex ) === false){ 33116 slideMoving = false; 33117 return; 33118 } 33119 } 33120 } 33121 } 33122 33123 destiny.addClass(ACTIVE).siblings().removeClass(ACTIVE); 33124 33125 if(!v.localIsResizing){ 33126 stopMedia(v.prevSlide); 33127 lazyLoad(destiny); 33128 } 33129 33130 if(!options.loopHorizontal && options.controlArrows){ 33131 //hidding it for the fist slide, showing for the rest 33132 section.find(SLIDES_ARROW_PREV_SEL).toggle(v.slideIndex!==0); 33133 33134 //hidding it for the last slide, showing for the rest 33135 section.find(SLIDES_ARROW_NEXT_SEL).toggle(!destiny.is(':last-child')); 33136 } 33137 33138 //only changing the URL if the slides are in the current section (not for resize re-adjusting) 33139 if(section.hasClass(ACTIVE) && !v.localIsResizing){ 33140 setState(v.slideIndex, v.slideAnchor, v.anchorLink, v.sectionIndex); 33141 } 33142 33143 performHorizontalMove(slides, v, true); 33144 } 33145 33146 33147 function afterSlideLoads(v){ 33148 activeSlidesNavigation(v.slidesNav, v.slideIndex); 33149 33150 //if the site is not just resizing and readjusting the slides 33151 if(!v.localIsResizing){ 33152 $.isFunction( options.afterSlideLoad ) && options.afterSlideLoad.call( v.destiny, v.anchorLink, (v.sectionIndex + 1), v.slideAnchor, v.slideIndex); 33153 33154 //needs to be inside the condition to prevent problems with continuousVertical and scrollHorizontally 33155 //and to prevent double scroll right after a windows resize 33156 canScroll = true; 33157 33158 playMedia(v.destiny); 33159 } 33160 33161 //letting them slide again 33162 slideMoving = false; 33163 } 33164 33165 /** 33166 * Performs the horizontal movement. (CSS3 or jQuery) 33167 * 33168 * @param fireCallback {Bool} - determines whether or not to fire the callback 33169 */ 33170 function performHorizontalMove(slides, v, fireCallback){ 33171 var destinyPos = v.destinyPos; 33172 33173 if(options.css3){ 33174 var translate3d = 'translate3d(-' + Math.round(destinyPos.left) + 'px, 0px, 0px)'; 33175 33176 addAnimation(slides.find(SLIDES_CONTAINER_SEL)).css(getTransforms(translate3d), v); 33177 33178 afterSlideLoadsId = setTimeout(function(){ 33179 fireCallback && afterSlideLoads(v); 33180 }, options.scrollingSpeed, options.easing); 33181 }else{ 33182 slides.animate({ 33183 scrollLeft : Math.round(destinyPos.left) 33184 }, options.scrollingSpeed, options.easing, function() { 33185 33186 fireCallback && afterSlideLoads(v); 33187 }); 33188 } 33189 } 33190 33191 /** 33192 * Sets the state for the horizontal bullet navigations. 33193 */ 33194 function activeSlidesNavigation(slidesNav, slideIndex){ 33195 slidesNav.find(ACTIVE_SEL).removeClass(ACTIVE); 33196 slidesNav.find('li').eq(slideIndex).find('a').addClass(ACTIVE); 33197 } 33198 33199 var previousHeight = windowsHeight; 33200 33201 //when resizing the site, we adjust the heights of the sections, slimScroll... 33202 function resizeHandler(){ 33203 //checking if it needs to get responsive 33204 responsive(); 33205 33206 // rebuild immediately on touch devices 33207 if (isTouchDevice) { 33208 var activeElement = $(document.activeElement); 33209 33210 //if the keyboard is NOT visible 33211 if (!activeElement.is('textarea') && !activeElement.is('input') && !activeElement.is('select')) { 33212 var currentHeight = $window.height(); 33213 33214 //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) 33215 if( Math.abs(currentHeight - previousHeight) > (20 * Math.max(previousHeight, currentHeight) / 100) ){ 33216 reBuild(true); 33217 previousHeight = currentHeight; 33218 } 33219 } 33220 }else{ 33221 //in order to call the functions only when the resize is finished 33222 //http://stackoverflow.com/questions/4298612/jquery-how-to-call-resize-event-only-once-its-finished-resizing 33223 clearTimeout(resizeId); 33224 33225 resizeId = setTimeout(function(){ 33226 reBuild(true); 33227 }, 350); 33228 } 33229 } 33230 33231 /** 33232 * Checks if the site needs to get responsive and disables autoScrolling if so. 33233 * A class `fp-responsive` is added to the plugin's container in case the user wants to use it for his own responsive CSS. 33234 */ 33235 function responsive(){ 33236 var widthLimit = options.responsive || options.responsiveWidth; //backwards compatiblity 33237 var heightLimit = options.responsiveHeight; 33238 33239 //only calculating what we need. Remember its called on the resize event. 33240 var isBreakingPointWidth = widthLimit && $window.outerWidth() < widthLimit; 33241 var isBreakingPointHeight = heightLimit && $window.height() < heightLimit; 33242 33243 if(widthLimit && heightLimit){ 33244 setResponsive(isBreakingPointWidth || isBreakingPointHeight); 33245 } 33246 else if(widthLimit){ 33247 setResponsive(isBreakingPointWidth); 33248 } 33249 else if(heightLimit){ 33250 setResponsive(isBreakingPointHeight); 33251 } 33252 } 33253 33254 /** 33255 * Adds transition animations for the given element 33256 */ 33257 function addAnimation(container, element){ 33258 var transition = 'all ' + options.scrollingSpeed + 'ms ' + options.easingcss3; 33259 33260 container.removeClass(NO_TRANSITION); 33261 return container.css({
33262 '-webkit-transition': transition, 33263 'transition': transition 33264 }); 33265 } 33266 33267 /** 33268 * Remove transition animations for the given element 33269 */ 33270 function removeAnimation(element){ 33271 return element.addClass(NO_TRANSITION); 33272 } 33273 33274 /** 33275 * Activating the vertical navigation bullets according to the given slide name. 33276 */ 33277 function activateNavDots(name, sectionIndex){ 33278 if(options.navigation){ 33279 $(SECTION_NAV_SEL).find(ACTIVE_SEL).removeClass(ACTIVE); 33280 if(name){ 33281 $(SECTION_NAV_SEL).find('a[href="#' + name + '"]').addClass(ACTIVE); 33282 }else{ 33283 $(SECTION_NAV_SEL).find('li').eq(sectionIndex).find('a').addClass(ACTIVE); 33284 } 33285 } 33286 } 33287 33288 /** 33289 * Activating the website main menu elements according to the given slide name. 33290 */ 33291 function activateMenuElement(name){ 33292 if(options.menu){ 33293 $(options.menu).find(ACTIVE_SEL).removeClass(ACTIVE); 33294 $(options.menu).find('[data-menuanchor="'+name+'"]').addClass(ACTIVE); 33295 } 33296 } 33297 33298 /** 33299 * Sets to active the current menu and vertical nav items. 33300 */ 33301 function activateMenuAndNav(anchor, index){ 33302 activateMenuElement(anchor); 33303 activateNavDots(anchor, index); 33304 } 33305 33306 /** 33307 * Retuns `up` or `down` depending on the scrolling movement to reach its destination 33308 * from the current section. 33309 */ 33310 function getYmovement(destiny){ 33311 var fromIndex = $(SECTION_ACTIVE_SEL).index(SECTION_SEL); 33312 var toIndex = destiny.index(SECTION_SEL); 33313 if( fromIndex == toIndex){ 33314 return 'none'; 33315 } 33316 if(fromIndex > toIndex){ 33317 return 'up'; 33318 } 33319 return 'down'; 33320 } 33321 33322 /** 33323 * Retuns `right` or `left` depending on the scrolling movement to reach its destination 33324 * from the current slide. 33325 */ 33326 function getXmovement(fromIndex, toIndex){ 33327 if( fromIndex == toIndex){ 33328 return 'none'; 33329 } 33330 if(fromIndex > toIndex){ 33331 return 'left'; 33332 } 33333 return 'right'; 33334 } 33335 33336 /** 33337 * Checks if the element needs scrollbar and if the user wants to apply it. 33338 * If so it creates it. 33339 * 33340 * @param {Object} element jQuery object of the section or slide 33341 */ 33342 function createScrollBar(element){ 33343 //User doesn't want scrollbar here? Sayonara baby! 33344 if(element.hasClass('fp-noscroll')) return; 33345 33346 //needed to make `scrollHeight` work under Opera 12 33347 element.css('overflow', 'hidden'); 33348 33349 var scrollOverflowHandler = options.scrollOverflowHandler; 33350 var wrap = scrollOverflowHandler.wrapContent(); 33351 //in case element is a slide 33352 var section = element.closest(SECTION_SEL); 33353 var scrollable = scrollOverflowHandler.scrollable(element); 33354 var contentHeight; 33355 33356 //if there was scroll, the contentHeight will be the one in the scrollable section 33357 if(scrollable.length){ 33358 contentHeight = scrollOverflowHandler.scrollHeight(element); 33359 }else{ 33360 contentHeight = element.get(0).scrollHeight; 33361 if(options.verticalCentered){ 33362 contentHeight = element.find(TABLE_CELL_SEL).get(0).scrollHeight; 33363 } 33364 } 33365 33366 var scrollHeight = windowsHeight - parseInt(section.css('padding-bottom')) - parseInt(section.css('padding-top')); 33367 33368 //needs scroll? 33369 if ( contentHeight > scrollHeight) { 33370 //did we already have an scrollbar ? Updating it 33371 if(scrollable.length){ 33372 scrollOverflowHandler.update(element, scrollHeight); 33373 } 33374 //creating the scrolling 33375 else{ 33376 if(options.verticalCentered){ 33377 element.find(TABLE_CELL_SEL).wrapInner(wrap); 33378 }else{ 33379 element.wrapInner(wrap); 33380 } 33381 scrollOverflowHandler.create(element, scrollHeight); 33382 } 33383 } 33384 //removing the scrolling when it is not necessary anymore 33385 else{ 33386 scrollOverflowHandler.remove(element); 33387 } 33388 33389 //undo 33390 element.css('overflow', ''); 33391 } 33392 33393 function addTableClass(element){ 33394 //In case we are styling for the 2nd time as in with reponsiveSlides 33395 if(!element.hasClass(TABLE)){ 33396 element.addClass(TABLE).wrapInner('<div class="' + TABLE_CELL + '" style="height:' + getTableHeight(element) + 'px;" />'); 33397 } 33398 } 33399 33400 function getTableHeight(element){ 33401 var sectionHeight = windowsHeight; 33402 33403 if(options.paddingTop || options.paddingBottom){ 33404 var section = element; 33405 if(!section.hasClass(SECTION)){ 33406 section = element.closest(SECTION_SEL); 33407 } 33408 33409 var paddings = parseInt(section.css('padding-top')) + parseInt(section.css('padding-bottom')); 33410 sectionHeight = (windowsHeight - paddings); 33411 } 33412 33413 return sectionHeight; 33414 } 33415 33416 /** 33417 * Adds a css3 transform property to the container class with or without animation depending on the animated param. 33418 */ 33419 function transformContainer(translate3d, animated){ 33420 if(animated){ 33421 addAnimation(container); 33422 }else{ 33423 removeAnimation(container); 33424 } 33425 33426 container.css(getTransforms(translate3d)); 33427 33428 //syncronously removing the class after the animation has been applied. 33429 setTimeout(function(){ 33430 container.removeClass(NO_TRANSITION); 33431 },10); 33432 } 33433 33434 /** 33435 * Gets a section by its anchor / index 33436 */ 33437 function getSectionByAnchor(sectionAnchor){ 33438 if(!sectionAnchor) return []; 33439 33440 var section = container.find(SECTION_SEL + '[data-anchor="'+sectionAnchor+'"]'); 33441 if(!section.length){ 33442 section = $(SECTION_SEL).eq( sectionAnchor -1); 33443 } 33444 33445 return section; 33446 } 33447 33448 /** 33449 * Gets a slide inside a given section by its anchor / index 33450 */ 33451 function getSlideByAnchor(slideAnchor, section){ 33452 var slides = section.find(SLIDES_WRAPPER_SEL); 33453 var slide = slides.find(SLIDE_SEL + '[data-anchor="'+slideAnchor+'"]'); 33454
33455 if(!slide.length){ 33456 slide = slides.find(SLIDE_SEL).eq(slideAnchor); 33457 } 33458 33459 return slide; 33460 } 33461 33462 /** 33463 * Scrolls to the given section and slide anchors 33464 */ 33465 function scrollPageAndSlide(destiny, slide){ 33466 var section = getSectionByAnchor(destiny); 33467 33468 //do nothing if there's no section with the given anchor name 33469 if(!section.length) return; 33470 33471 //default slide 33472 if (typeof slide === 'undefined') { 33473 slide = 0; 33474 } 33475 33476 //we need to scroll to the section and then to the slide 33477 if (destiny !== lastScrolledDestiny && !section.hasClass(ACTIVE)){ 33478 scrollPage(section, function(){ 33479 scrollSlider(section, slide); 33480 }); 33481 } 33482 //if we were already in the section 33483 else{ 33484 scrollSlider(section, slide); 33485 } 33486 } 33487 33488 /** 33489 * Scrolls the slider to the given slide destination for the given section 33490 */ 33491 function scrollSlider(section, slideAnchor){ 33492 if(typeof slideAnchor !== 'undefined'){ 33493 var slides = section.find(SLIDES_WRAPPER_SEL); 33494 var destiny = getSlideByAnchor(slideAnchor, section); 33495 33496 if(destiny.length){ 33497 landscapeScroll(slides, destiny); 33498 } 33499 } 33500 } 33501 33502 /** 33503 * Creates a landscape navigation bar with dots for horizontal sliders. 33504 */ 33505 function addSlidesNavigation(section, numSlides){ 33506 section.append('<div class="' + SLIDES_NAV + '"><ul></ul></div>'); 33507 var nav = section.find(SLIDES_NAV_SEL); 33508 33509 //top or bottom 33510 nav.addClass(options.slidesNavPosition); 33511 33512 for(var i=0; i< numSlides; i++){ 33513 nav.find('ul').append('<li><a href="#"><span></span></a></li>'); 33514 } 33515 33516 //centering it 33517 nav.css('margin-left', '-' + (nav.width()/2) + 'px'); 33518 33519 nav.find('li').first().find('a').addClass(ACTIVE); 33520 } 33521 33522 33523 /** 33524 * Sets the state of the website depending on the active section/slide. 33525 * It changes the URL hash when needed and updates the body class. 33526 */ 33527 function setState(slideIndex, slideAnchor, anchorLink, sectionIndex){ 33528 var sectionHash = ''; 33529 33530 if(options.anchors.length && !options.lockAnchors){ 33531 33532 //isn't it the first slide? 33533 if(slideIndex){ 33534 if(typeof anchorLink !== 'undefined'){ 33535 sectionHash = anchorLink; 33536 } 33537 33538 //slide without anchor link? We take the index instead. 33539 if(typeof slideAnchor === 'undefined'){ 33540 slideAnchor = slideIndex; 33541 } 33542 33543 lastScrolledSlide = slideAnchor; 33544 setUrlHash(sectionHash + '/' + slideAnchor); 33545 33546 //first slide won't have slide anchor, just the section one 33547 }else if(typeof slideIndex !== 'undefined'){ 33548 lastScrolledSlide = slideAnchor; 33549 setUrlHash(anchorLink); 33550 } 33551 33552 //section without slides 33553 else{ 33554 setUrlHash(anchorLink); 33555 } 33556 } 33557 33558 setBodyClass(); 33559 } 33560 33561 /** 33562 * Sets the URL hash. 33563 */ 33564 function setUrlHash(url){ 33565 //Uncode addition 33566 if ( typeof SiteParameters.slide_footer != 'undefined' && url == SiteParameters.slide_footer ) 33567 return false; 33568 33569 if(options.recordHistory){ 33570 location.hash = url; 33571 }else{ 33572 //Uncode addition 33573 //Mobile Chrome doesn't work the normal way, so... lets use HTML5 for phones :) 33574 // if(isTouchDevice || isTouch){ 33575 // window.history.replaceState(undefined, undefined, '#' + url); 33576 // }else{ 33577 // var baseUrl = window.location.href.split('#')[0]; 33578 // window.location.replace( baseUrl + '#' + url ); 33579 // } 33580 return false;
33581 } 33582 } 33583 33584 /** 33585 * Gets the anchor for the given slide / section. Its index will be used if there's none. 33586 */ 33587 function getAnchor(element){ 33588 var anchor = element.data('anchor'); 33589 var index = element.index(); 33590 33591 //Slide without anchor link? We take the index instead. 33592 if(typeof anchor === 'undefined'){ 33593 anchor = index; 33594 } 33595 33596 return anchor; 33597 } 33598 33599 /** 33600 * Sets a class for the body of the page depending on the active section / slide 33601 */ 33602 function setBodyClass(){ 33603 var section = $(SECTION_ACTIVE_SEL); 33604 var slide = section.find(SLIDE_ACTIVE_SEL); 33605 33606 var sectionAnchor = getAnchor(section); 33607 var slideAnchor = getAnchor(slide); 33608 33609 var text = String(sectionAnchor); 33610 33611 if(slide.length){ 33612 text = text + '-' + slideAnchor; 33613 } 33614 33615 //changing slash for dash to make it a valid CSS style 33616 text = text.replace('/', '-').replace('#',''); 33617 33618 //removing previous anchor classes 33619 var classRe = new RegExp('\\b\\s?' + VIEWING_PREFIX + '-[^\\s]+\\b', "g"); 33620 $body[0].className = $body[0].className.replace(classRe, ''); 33621 33622 //adding the current anchor 33623 $body.addClass(VIEWING_PREFIX + '-' + text); 33624 } 33625 33626 /** 33627 * Checks for translate3d support 33628 * @return boolean 33629 * http://stackoverflow.com/questions/5661671/detecting-transform-translate3d-support 33630 */ 33631 function support3d() { 33632 var el = document.createElement('p'), 33633 has3d, 33634 transforms = { 33635 'webkitTransform':'-webkit-transform', 33636 'OTransform':'-o-transform', 33637 'msTransform':'-ms-transform', 33638 'MozTransform':'-moz-transform', 33639 'transform':'transform' 33640 }; 33641 33642 // Add it to the body to get the computed style. 33643 document.body.insertBefore(el, null); 33644 33645 for (var t in transforms) { 33646 if (el.style[t] !== undefined) { 33647 el.style[t] = 'translate3d(1px,1px,1px)'; 33648 has3d = window.getComputedStyle(el).getPropertyValue(transforms[t]); 33649 } 33650 } 33651 33652 document.body.removeChild(el); 33653 33654 return (has3d !== undefined && has3d.length > 0 && has3d !== 'none'); 33655 } 33656 33657 /** 33658 * Removes the auto scrolling action fired by the mouse wheel and trackpad. 33659 * After this function is called, the mousewheel and trackpad movements won't scroll through sections. 33660 */ 33661 function removeMouseWheelHandler(){ 33662 if (document.addEventListener) { 33663 document.removeEventListener('mousewheel', MouseWheelHandler, false); //IE9, Chrome, Safari, Oper 33664 document.removeEventListener('wheel', MouseWheelHandler, false); //Firefox 33665 document.removeEventListener('MozMousePixelScroll', MouseWheelHandler, false); //old Firefox 33666 } else { 33667 document.detachEvent('onmousewheel', MouseWheelHandler); //IE 6/7/8 33668 } 33669 } 33670 33671 /** 33672 * Adds the auto scrolling action for the mouse wheel and trackpad. 33673 * After this function is called, the mousewheel and trackpad movements will scroll through sections 33674 * https://developer.mozilla.org/en-US/docs/Web/Events/wheel 33675 */ 33676 function addMouseWheelHandler(){ 33677 var prefix = ''; 33678 var _addEventListener; 33679 33680 if (window.addEventListener){ 33681 _addEventListener = "addEventListener"; 33682 }else{ 33683 _addEventListener = "attachEvent"; 33684 prefix = 'on'; 33685 } 33686 33687 // detect available wheel event 33688 var support = 'onwheel' in document.createElement('div') ? 'wheel' : // Modern browsers support "wheel" 33689 document.onmousewheel !== undefined ? 'mousewheel' : // Webkit and IE support at least "mousewheel" 33690 'DOMMouseScroll'; // let's assume that remaining browsers are older Firefox 33691 var passiveEvent = g_supportsPassive ? {passive: false }
33691: false; 33692 33693 33694 if(support == 'DOMMouseScroll'){ 33695 document[ _addEventListener ](prefix + 'MozMousePixelScroll', MouseWheelHandler, passiveEvent); 33696 } 33697 33698 //handle MozMousePixelScroll in older Firefox 33699 else{ 33700 document[ _addEventListener ](prefix + support, MouseWheelHandler, passiveEvent); 33701 } 33702 } 33703 33704 /** 33705 * Binding the mousemove when the mouse's middle button is pressed 33706 */ 33707 function addMiddleWheelHandler(){ 33708 container 33709 .on('mousedown', mouseDownHandler) 33710 .on('mouseup', mouseUpHandler); 33711 } 33712 33713 /** 33714 * Unbinding the mousemove when the mouse's middle button is released 33715 */ 33716 function removeMiddleWheelHandler(){ 33717 container 33718 .off('mousedown', mouseDownHandler) 33719 .off('mouseup', mouseUpHandler); 33720 } 33721 33722 /** 33723 * Adds the possibility to auto scroll through sections on touch devices. 33724 */ 33725 function addTouchHandler(){ 33726 if(isTouchDevice || isTouch){ 33727 if(options.autoScrolling){ 33728 $body.off(events.touchmove).on(events.touchmove, preventBouncing); 33729 } 33730 33731 $(WRAPPER_SEL) 33732 .off(events.touchstart).on(events.touchstart, touchStartHandler) 33733 .off(events.touchmove).on(events.touchmove, touchMoveHandler); 33734 } 33735 } 33736 33737 /** 33738 * Removes the auto scrolling for touch devices. 33739 */ 33740 function removeTouchHandler(){ 33741 if(isTouchDevice || isTouch){ 33742 $(WRAPPER_SEL) 33743 .off(events.touchstart) 33744 .off(events.touchmove); 33745 } 33746 } 33747 33748 /* 33749 * Returns and object with Microsoft pointers (for IE<11 and for IE >= 11) 33750 * http://msdn.microsoft.com/en-us/library/ie/dn304886(v=vs.85).aspx 33751 */ 33752 function getMSPointer(){ 33753 var pointer; 33754 33755 //IE >= 11 & rest of browsers 33756 if(window.PointerEvent){ 33757 pointer = { down: 'pointerdown', move: 'pointermove'}; 33758 } 33759 33760 //IE < 11 33761 else{ 33762 pointer = { down: 'MSPointerDown', move: 'MSPointerMove'}; 33763 } 33764 33765 return pointer; 33766 } 33767 33768 /** 33769 * Gets the pageX and pageY properties depending on the browser. 33770 * https://github.com/alvarotrigo/fullPage.js/issues/194#issuecomment-34069854 33771 */ 33772 function getEventsPage(e){ 33773 var events = []; 33774 33775 events.y = (typeof e.pageY !== 'undefined' && (e.pageY || e.pageX) ? e.pageY : e.touches[0].pageY); 33776 events.x = (typeof e.pageX !== 'undefined' && (e.pageY || e.pageX) ? e.pageX : e.touches[0].pageX); 33777 33778 //in touch devices with scrollBar:true, e.pageY is detected, but we have to deal with touch events. #1008 33779 if(isTouch && isReallyTouch(e) && options.scrollBar){ 33780 events.y = e.touches[0].pageY; 33781 events.x = e.touches[0].pageX; 33782 } 33783 33784 return events; 33785 } 33786 33787 /** 33788 * Slides silently (with no animation) the active slider to the given slide. 33789 * @param noCallback {bool} true or defined -> no callbacks 33790 */ 33791 function silentLandscapeScroll(activeSlide, noCallbacks){ 33792 setScrollingSpeed (0, 'internal'); 33793 33794 if(typeof noCallbacks !== 'undefined'){ 33795 //preventing firing callbacks afterSlideLoad etc. 33796 isResizing = true; 33797 } 33798 33799 landscapeScroll(activeSlide.closest(SLIDES_WRAPPER_SEL), activeSlide); 33800 33801 if(typeof noCallbacks !== 'undefined'){ 33802 isResizing = false; 33803 } 33804 33805 setScrollingSpeed(originals.scrollingSpeed, 'internal'); 33806 } 33807 33808 /** 33809 * Scrolls silently (with no animation) the page to the given Y position. 33810 */ 33811 function silentScroll(top){ 33812 // The first section can have a negative value in iOS 10. Not quite sure why: -0.0142822265625 33813 // that's why we round it to 0. 33814 var roundedTop = Math.round(top); 33815 33816 if (options.css3 && options.autoScrolling && !options.scrollBar){ 33817 var translate3d = 'translate3d(0px, -' + roundedTop + 'px, 0px)'; 33818 transformContainer(translate3d, false); 33819 } 33820 else if(options.autoScrolling && !options.scrollBar){ 33821 container.css('top', -roundedTop); 33822 } 33823 else{ 33824 $htmlBody.scrollTop(roundedTop); 33825 } 33826 } 33827 33828 /** 33829 * Returns the cross-browser transform string. 33830 */ 33831 function getTransforms(translate3d){ 33832 return {
33833 '-webkit-transform': translate3d, 33834 '-moz-transform': translate3d, 33835 '-ms-transform':translate3d, 33836 'transform': translate3d 33837 }; 33838 } 33839 33840 /** 33841 * Allowing or disallowing the mouse/swipe scroll in a given direction. (not for keyboard) 33842 * @type m (mouse) or k (keyboard) 33843 */ 33844 function setIsScrollAllowed(value, direction, type){ 33845 switch (direction){ 33846 case 'up': isScrollAllowed[type].up = value; break; 33847 case 'down': isScrollAllowed[type].down = value; break; 33848 case 'left': isScrollAllowed[type].left = value; break; 33849 case 'right': isScrollAllowed[type].right = value; break; 33850 case 'all': 33851 if(type == 'm'){ 33852 setAllowScrolling(value); 33853 }else{ 33854 setKeyboardScrolling(value); 33855 } 33856 } 33857 } 33858 33859 /* 33860 * Destroys fullpage.js plugin events and optinally its html markup and styles 33861 */ 33862 function destroy(all){ 33863 setAutoScrolling(false, 'internal'); 33864 setAllowScrolling(false); 33865 setKeyboardScrolling(false); 33866 container.addClass(DESTROYED); 33867 33868 clearTimeout(afterSlideLoadsId); 33869 clearTimeout(afterSectionLoadsId); 33870 clearTimeout(resizeId); 33871 clearTimeout(scrollId); 33872 clearTimeout(scrollId2); 33873 33874 $window 33875 .off('scroll', scrollHandler) 33876 .off('hashchange', hashChangeHandler) 33877 .off('resize', resizeHandler); 33878 33879 $document 33880 .off('click touchstart', SECTION_NAV_SEL + ' a') 33881 .off('mouseenter', SECTION_NAV_SEL + ' li') 33882 .off('mouseleave', SECTION_NAV_SEL + ' li') 33883 .off('click touchstart', SLIDES_NAV_LINK_SEL) 33884 .off('mouseover', options.normalScrollElements) 33885 .off('mouseout', options.normalScrollElements); 33886 33887 $(SECTION_SEL) 33888 .off('click touchstart', SLIDES_ARROW_SEL); 33889 33890 clearTimeout(afterSlideLoadsId); 33891 clearTimeout(afterSectionLoadsId); 33892 33893 //lets make a mess! 33894 if(all){ 33895 destroyStructure(); 33896 } 33897 } 33898 33899 /* 33900 * Removes inline styles added by fullpage.js 33901 */ 33902 function destroyStructure(){ 33903 //reseting the `top` or `translate` properties to 0 33904 silentScroll(0); 33905 33906 //loading all the lazy load content 33907 container.find('img[data-src], source[data-src], audio[data-src], iframe[data-src]').each(function(){ 33908 setSrc($(this), 'src'); 33909 }); 33910 33911 container.find('img[data-srcset]').each(function(){ 33912 setSrc($(this), 'srcset'); 33913 }); 33914 33915 $(SECTION_NAV_SEL + ', ' + SLIDES_NAV_SEL + ', ' + SLIDES_ARROW_SEL).remove(); 33916 33917 //removing inline styles 33918 $(SECTION_SEL).css( { 33919 'height': '', 33920 'background-color' : '', 33921 'padding': '' 33922 }); 33923 33924 $(SLIDE_SEL).css( { 33925 'width': '' 33926 }); 33927 33928 container.css({ 33929 'height': '', 33930 'position': '', 33931 '-ms-touch-action': '', 33932 'touch-action': '' 33933 }); 33934 33935 $htmlBody.css({ 33936 'overflow': '', 33937 'height': '' 33938 }); 33939 33940 // remove .fp-enabled class 33941 $('html').removeClass(ENABLED); 33942 33943 // remove .fp-responsive class 33944 $body.removeClass(RESPONSIVE); 33945 33946 // remove all of the .fp-viewing- classes 33947 $.each($body.get(0).className.split(/\s+/), function (index, className) { 33948 if (className.indexOf(VIEWING_PREFIX) === 0) { 33949 $body.removeClass(className); 33950 } 33951 }); 33952 33953 //removing added classes 33954 $(SECTION_SEL + ', ' + SLIDE_SEL).each(function(){ 33955 options.scrollOverflowHandler.remove($(this)); 33956 $(this).removeClass(TABLE + ' ' + ACTIVE); 33957 }); 33958 33959 removeAnimation(container); 33960 33961 //Unwrapping content 33962 container.find(TABLE_CELL_SEL + ', ' + SLIDES_CONTAINER_SEL + ', ' + SLIDES_WRAPPER_SEL).each(function(){ 33963 //unwrap not being use in case there's no child element inside and its just text 33964 $(this).replaceWith(this.childNodes); 33965 }); 33966 33967 //removing the applied transition from the fullpage wrapper 33968 container.css({
33969 '-webkit-transition': 'none', 33970 'transition': 'none' 33971 }); 33972 33973 //scrolling the page to the top with no animation 33974 $htmlBody.scrollTop(0); 33975 33976 //removing selectors 33977 var usedSelectors = [SECTION, SLIDE, SLIDES_CONTAINER]; 33978 $.each(usedSelectors, function(index, value){ 33979 $('.' + value).removeClass(value); 33980 }); 33981 } 33982 33983 /* 33984 * Sets the state for a variable with multiple states (original, and temporal) 33985 * Some variables such as `autoScrolling` or `recordHistory` might change automatically its state when using `responsive` or `autoScrolling:false`. 33986 * This function is used to keep track of both states, the original and the temporal one. 33987 * If type is not 'internal', then we assume the user is globally changing the variable. 33988 */ 33989 function setVariableState(variable, value, type){ 33990 options[variable] = value; 33991 if(type !== 'internal'){ 33992 originals[variable] = value; 33993 } 33994 } 33995 33996 /** 33997 * Displays warnings 33998 */ 33999 function displayWarnings(){ 34000 var extensions = ['fadingEffect', 'continuousHorizontal', 'scrollHorizontally', 'interlockedSlides', 'resetSliders', 'responsiveSlides', 'offsetSections', 'dragAndMove', 'scrollOverflowReset', 'parallax']; 34001 //UNCODE.addition 34002 // if($('html').hasClass(ENABLED)){ 34003 // showError('error', 'Fullpage.js can only be initialized once and you are doing it multiple times!'); 34004 // return; 34005 // } 34006 34007 // Disable mutually exclusive settings 34008 //UNCODE.addition 34009 // if (options.continuousVertical && 34010 // (options.loopTop || options.loopBottom)) { 34011 // options.continuousVertical = false;
34012 // showError('warn', 'Option `loopTop/loopBottom` is mutually exclusive with `continuousVertical`; `continuousVertical` disabled'); 34013 // } 34014 34015 // if(options.scrollBar && options.scrollOverflow){ 34016 // showError('warn', 'Option `scrollBar` is mutually exclusive with `scrollOverflow`. Sections with scrollOverflow might not work well in Firefox'); 34017 // } 34018 34019 // if(options.continuousVertical && (options.scrollBar || !options.autoScrolling)){ 34020 // options.continuousVertical = false; 34021 // showError('warn', 'Scroll bars (`scrollBar:true` or `autoScrolling:false`) are mutually exclusive with `continuousVertical`; `continuousVertical` disabled'); 34022 // } 34023 34024 //using extensions? Wrong file! 34025 $.each(extensions, function(index, extension){ 34026 //is the option set to true? 34027 if(options[extension]){ 34028 showError('warn', 'fullpage.js extensions require jquery.fullpage.extensions.min.js file instead of the usual jquery.fullpage.js. Requested: '+ extension); 34029 } 34030 }); 34031 34032 //anchors can not have the same value as any element ID or NAME 34033 $.each(options.anchors, function(index, name){ 34034 34035 //case insensitive selectors (http://stackoverflow.com/a/19465187/1081396) 34036 var nameAttr = $document.find('[name]').filter(function() { 34037 return $(this).attr('name') && $(this).attr('name').toLowerCase() == name.toLowerCase(); 34038 }); 34039 34040 var idAttr = $document.find('[id]').filter(function() { 34041 return $(this).attr('id') && $(this).attr('id').toLowerCase() == name.toLowerCase(); 34042 }); 34043 34044 if(idAttr.length || nameAttr.length ){ 34045 showError('error', 'data-anchor tags can not have the same value as any `id` element on the site (or `name` element for IE).'); 34046 idAttr.length && showError('error', '"' + name + '" is is being used by another element `id` property'); 34047 nameAttr.length && showError('error', '"' + name + '" is is being used by another element `name` property'); 34048 } 34049 }); 34050 } 34051 34052 /** 34053 * Shows a message in the console of the given type. 34054 */ 34055 function showError(type, text){ 34056 console && console[type] && console[type]('fullPage: ' + text); 34057 } 34058 34059 }; //end of $.fn.fullpage 34060 34061 if(typeof IScroll !== 'undefined'){ 34062 /* 34063 * Turns iScroll `mousewheel` option off dynamically 34064 * https://github.com/cubiq/iscroll/issues/1036 34065 */ 34066 IScroll.prototype.wheelOn = function () { 34067 this.wrapper.addEventListener('wheel', this); 34068 this.wrapper.addEventListener('mousewheel', this); 34069 this.wrapper.addEventListener('DOMMouseScroll', this); 34070 }; 34071 34072 /* 34073 * Turns iScroll `mousewheel` option on dynamically 34074 * https://github.com/cubiq/iscroll/issues/1036 34075 */ 34076 IScroll.prototype.wheelOff = function () { 34077 this.wrapper.removeEventListener('wheel', this); 34078 this.wrapper.removeEventListener('mousewheel', this); 34079 this.wrapper.removeEventListener('DOMMouseScroll', this); 34080 }; 34081 } 34082 34083 /** 34084 * An object to handle overflow scrolling. 34085 * This uses jquery.slimScroll to accomplish overflow scrolling. 34086 * It is possible to pass in an alternate scrollOverflowHandler 34087 * to the fullpage.js option that implements the same functions 34088 * as this handler. 34089 * 34090 * @type {Object} 34091 */ 34092 var iscrollHandler = { 34093 refreshId: null, 34094 iScrollInstances: [], 34095 34096 // Enables or disables the mouse wheel for the active section or all slides in it 34097 toggleWheel: function(value){ 34098 var scrollable = $(SECTION_ACTIVE_SEL).find(SCROLLABLE_SEL); 34099 scrollable.each(function(){ 34100 var iScrollInstance = $(this).data('iscrollInstance'); 34101 if(typeof iScrollInstance !== 'undefined' && iScrollInstance){ 34102 if(value){ 34103 iScrollInstance.wheelOn(); 34104 } 34105 else{ 34106 iScrollInstance.wheelOff(); 34107 } 34108 } 34109 }); 34110 }, 34111 34112 /** 34113 * Turns off iScroll for the destination section. 34114 * When scrolling very fast on some trackpads (and Apple laptops) the inertial scrolling would
34115 * scroll the destination section/slide before the sections animations ends. 34116 */ 34117 onLeave: function(){ 34118 iscrollHandler.toggleWheel(false); 34119 }, 34120 34121 // Turns off iScroll for the leaving section 34122 beforeLeave: function(){ 34123 iscrollHandler.onLeave() 34124 }, 34125 34126 // Turns on iScroll on section load 34127 afterLoad: function(){ 34128 iscrollHandler.toggleWheel(true); 34129 }, 34130 34131 /** 34132 * Called when overflow scrolling is needed for a section. 34133 * 34134 * @param {Object} element jQuery object containing current section 34135 * @param {Number} scrollHeight Current window height in pixels 34136 */ 34137 create: function(element, scrollHeight) { 34138 var scrollable = element.find(SCROLLABLE_SEL); 34139 34140 scrollable.height(scrollHeight); 34141 scrollable.each(function() { 34142 var $this = $(this); 34143 var iScrollInstance = $this.data('iscrollInstance'); 34144 if (iScrollInstance) { 34145 $.each(iscrollHandler.iScrollInstances, function(){ 34146 $(this).destroy(); 34147 }); 34148 } 34149 34150 iScrollInstance = new IScroll($this.get(0), iscrollOptions); 34151 iscrollHandler.iScrollInstances.push(iScrollInstance); 34152 34153 //off by default until the section gets active 34154 iScrollInstance.wheelOff(); 34155 34156 $this.data('iscrollInstance', iScrollInstance); 34157 }); 34158 }, 34159 34160 /** 34161 * Return a boolean depending on whether the scrollable element is a 34162 * the end or at the start of the scrolling depending on the given type. 34163 * 34164 * @param {String} type Either 'top' or 'bottom' 34165 * @param {Object} scrollable jQuery object for the scrollable element 34166 * @return {Boolean} 34167 */ 34168 isScrolled: function(type, scrollable) { 34169 var scroller = scrollable.data('iscrollInstance'); 34170 34171 //no scroller? 34172 if (!scroller) { 34173 return true; 34174 } 34175 34176 //Uncode addition 34177 var uncode_body_borders = parseFloat($('.body-borders').attr('data-border')) || 0; 34178 //End Uncode addition 34179 34180 if (type === 'top') { 34181 return scroller.y >= 0 && !scrollable.scrollTop(); 34182 } else if (type === 'bottom') { 34183 //Uncode change 34184 // return (0 - scroller.y) + scrollable.scrollTop() + 1 + scrollable.innerHeight() >= scrollable[0].scrollHeight; 34185 return (0 - scroller.y) + scrollable.scrollTop() + 1 + ( uncode_body_borders * 2 ) + scrollable.innerHeight() >= scrollable[0].scrollHeight; 34186 //End Uncode change 34187 } 34188 }, 34189 34190 /** 34191 * Returns the scrollable element for the given section. 34192 * If there are landscape slides, will only return a scrollable element 34193 * if it is in the active slide. 34194 * 34195 * @param {Object} activeSection jQuery object containing current section 34196 * @return {Boolean} 34197 */ 34198 scrollable: function(activeSection){ 34199 // if there are landscape slides, we check if the scrolling bar is in the current one or not 34200 if (activeSection.find(SLIDES_WRAPPER_SEL).length) { 34201 return activeSection.find(SLIDE_ACTIVE_SEL).find(SCROLLABLE_SEL); 34202 } 34203 return activeSection.find(SCROLLABLE_SEL); 34204 }, 34205 34206 /** 34207 * Returns the scroll height of the wrapped content. 34208 * If this is larger than the window height minus section padding, 34209 * overflow scrolling is needed. 34210 * 34211 * @param {Object} element jQuery object containing current section 34212 * @return {Number} 34213 */ 34214 scrollHeight: function(element) { 34215 return element.find(SCROLLABLE_SEL).children().first().get(0).scrollHeight; 34216 }, 34217 34218 /** 34219 * Called when overflow scrolling is no longer needed for a section. 34220 * 34221 * @param {Object}
34221 element jQuery object containing current section 34222 */ 34223 remove: function(element) { 34224 var scrollable = element.find(SCROLLABLE_SEL); 34225 if (scrollable.length) { 34226 var iScrollInstance = scrollable.data('iscrollInstance'); 34227 iScrollInstance.destroy(); 34228 34229 scrollable.data('iscrollInstance', null); 34230 } 34231 element.find(SCROLLABLE_SEL).children().first().children().first().unwrap().unwrap(); 34232 }, 34233 34234 /** 34235 * Called when overflow scrolling has already been setup but the 34236 * window height has potentially changed. 34237 * 34238 * @param {Object} element jQuery object containing current section 34239 * @param {Number} scrollHeight Current window height in pixels 34240 */ 34241 update: function(element, scrollHeight) { 34242 //using a timeout in order to execute the refresh function only once when `update` is called multiple times in a 34243 //short period of time. 34244 //it also comes on handy because iScroll requires the use of timeout when using `refresh`. 34245 clearTimeout(iscrollHandler.refreshId); 34246 iscrollHandler.refreshId = setTimeout(function(){ 34247 $.each(iscrollHandler.iScrollInstances, function(){ 34248 $(this).get(0).refresh(); 34249 }); 34250 }, 150); 34251 34252 //updating the wrappers height 34253 element.find(SCROLLABLE_SEL).css('height', scrollHeight + 'px').parent().css('height', scrollHeight + 'px'); 34254 }, 34255 34256 /** 34257 * Called to get any additional elements needed to wrap the section 34258 * content in order to facilitate overflow scrolling. 34259 * 34260 * @return {String|Object} Can be a string containing HTML, 34261 * a DOM element, or jQuery object. 34262 */ 34263 wrapContent: function() { 34264 return '<div class="' + SCROLLABLE + '"><div class="fp-scroller"></div></div>'; 34265 } 34266 }; 34267}); 34268 34269(function (global, factory) { 34270 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : 34271 typeof define === 'function' && define.amd ? define(['exports'], factory) : 34272 (global = global || self, factory(global.window = global.window || {})); 34273}(this, (function (exports) { 'use strict'; 34274 34275 /*! 34276 * ScrollTrigger 3.8.0 34277 * https://greensock.com 34278 * 34279 * @license Copyright 2008-2021, GreenSock. All rights reserved. 34280 * Subject to the terms at https://greensock.com/standard-license or for 34281 * Club GreenSock members, the agreement issued with that membership. 34282 * @author: Jack Doyle, [email protected] 34283 */ 34284 var gsap, 34285 _coreInitted, 34286 _win, 34287 _doc, 34288 _docEl, 34289 _body, 34290 _root, 34291 _resizeDelay, 34292 _raf, 34293 _request, 34294 _toArray, 34295 _clamp, 34296 _time2, 34297 _syncInterval, 34298 _refreshing, 34299 _pointerIsDown, 34300 _transformProp, 34301 _i, 34302 _prevWidth, 34303 _prevHeight, 34304 _autoRefresh, 34305 _sort, 34306 _suppressOverwrites, 34307 _ignoreResize, 34308 _limitCallbacks, 34309 _startup = 1, 34310 _proxies = [], 34311 _scrollers = [], 34312 _getTime = Date.now, 34313 _time1 = _getTime(), 34314 _lastScrollTime = 0, 34315 _enabled = 1, 34316 _passThrough = function _passThrough(v) { 34317 return v; 34318 }, 34319 _getTarget = function _getTarget(t) { 34320 return _toArray(t)[0] || (_isString(t) ? console.warn("Element not found:", t) : null); 34321 }, 34322 _round = function _round(value) { 34323 return Math.round(value * 100000) / 100000 || 0; 34324 }, 34325 _windowExists = function _windowExists() { 34326 return typeof window !== "undefined"; 34327 }, 34328 _getGSAP = function _getGSAP() { 34329 return gsap || _windowExists() && (gsap = window.gsap) && gsap.registerPlugin && gsap; 34330 }, 34331 _isViewport = function _isViewport(e) { 34332 return !!~_root.indexOf(e); 34333 }, 34334 _getProxyProp = function _getProxyProp(element, property) { 34335 return ~_proxies.indexOf(element) && _proxies[_proxies.indexOf(element) + 1][property]; 34336 }, 34337 _getScrollFunc = function _getScrollFunc(element, _ref) { 34338 var s = _ref.s, 34339 sc = _ref.sc; 34340 34341 var i = _scrollers.indexOf(element), 34342 offset = sc === _vertical.sc ? 1 : 2; 34343 34344 !~i && (i = _scrollers.push(element) - 1); 34345 return _scrollers[i + offset] || (_scrollers[i + offset] = _getProxyProp(element, s) || (_isViewport(element) ? sc : function (value) { 34346 return arguments.length ? element[s] = value : element[s]; 34347 })); 34348 }, 34349 _getBoundsFunc = function _getBoundsFunc(element) { 34350 return _getProxyProp(element, "getBoundingClientRect") || (_isViewport(element) ? function () { 34351 _winOffsets.width = _win.innerWidth; 34352 _winOffsets.height = _win.innerHeight; 34353 return _winOffsets; 34354 } : function () { 34355 return _getBounds(element); 34356 }); 34357 }, 34358 _getSizeFunc = function _getSizeFunc(scroller, isViewport, _ref2) { 34359 var d = _ref2.d, 34360 d2 = _ref2.d2, 34361 a = _ref2.a; 34362 return (a = _getProxyProp(scroller, "getBoundingClientRect")) ? function () { 34363 return a()[d]; 34364 } : function () { 34365 return (isViewport ? _win["inner" + d2] : scroller["client" + d2]) || 0; 34366 }; 34367 }, 34368 _getOffsetsFunc = function _getOffsetsFunc(element, isViewport) { 34369 return !isViewport || ~_proxies.indexOf(element) ? _getBoundsFunc(element) : function () { 34370 return _winOffsets; 34371 }; 34372 }, 34373 _maxScroll = function _maxScroll(element, _ref3) { 34374 var s = _ref3.s, 34375 d2 = _ref3.d2, 34376 d = _ref3.d, 34377 a = _ref3.a; 34378 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]; 34379 }, 34380 _iterateAutoRefresh = function _iterateAutoRefresh(func, events) { 34381 for (var i = 0; i < _autoRefresh.length; i += 3) {
vendor: 5,689 bytes, lines 34382-34586
34382 (!events || ~events.indexOf(_autoRefresh[i + 1])) && func(_autoRefresh[i], _autoRefresh[i + 1], _autoRefresh[i + 2]); 34383 } 34384 }, 34385 _isString = function _isString(value) { 34386 return typeof value === "string"; 34387 }, 34388 _isFunction = function _isFunction(value) { 34389 return typeof value === "function"; 34390 }, 34391 _isNumber = function _isNumber(value) { 34392 return typeof value === "number"; 34393 }, 34394 _isObject = function _isObject(value) { 34395 return typeof value === "object"; 34396 }, 34397 _callIfFunc = function _callIfFunc(value) { 34398 return _isFunction(value) && value(); 34399 }, 34400 _combineFunc = function _combineFunc(f1, f2) { 34401 return function () { 34402 var result1 = _callIfFunc(f1), 34403 result2 = _callIfFunc(f2); 34404 34405 return function () { 34406 _callIfFunc(result1); 34407 34408 _callIfFunc(result2); 34409 }; 34410 }; 34411 }, 34412 _endAnimation = function _endAnimation(animation, reversed, pause) { 34413 return animation && animation.progress(reversed ? 0 : 1) && pause && animation.pause(); 34414 }, 34415 _callback = function _callback(self, func) { 34416 var result = func(self); 34417 result && result.totalTime && (self.callbackAnimation = result); 34418 }, 34419 _abs = Math.abs, 34420 _scrollLeft = "scrollLeft", 34421 _scrollTop = "scrollTop", 34422 _left = "left", 34423 _top = "top", 34424 _right = "right", 34425 _bottom = "bottom", 34426 _width = "width", 34427 _height = "height", 34428 _Right = "Right", 34429 _Left = "Left", 34430 _Top = "Top", 34431 _Bottom = "Bottom", 34432 _padding = "padding", 34433 _margin = "margin", 34434 _Width = "Width", 34435 _Height = "Height", 34436 _px = "px", 34437 _horizontal = { 34438 s: _scrollLeft, 34439 p: _left, 34440 p2: _Left, 34441 os: _right, 34442 os2: _Right, 34443 d: _width, 34444 d2: _Width, 34445 a: "x", 34446 sc: function sc(value) { 34447 return arguments.length ? _win.scrollTo(value, _vertical.sc()) : _win.pageXOffset || _doc[_scrollLeft] || _docEl[_scrollLeft] || _body[_scrollLeft] || 0; 34448 } 34449 }, 34450 _vertical = { 34451 s: _scrollTop, 34452 p: _top, 34453 p2: _Top, 34454 os: _bottom, 34455 os2: _Bottom, 34456 d: _height, 34457 d2: _Height, 34458 a: "y", 34459 op: _horizontal, 34460 sc: function sc(value) { 34461 return arguments.length ? _win.scrollTo(_horizontal.sc(), value) : _win.pageYOffset || _doc[_scrollTop] || _docEl[_scrollTop] || _body[_scrollTop] || 0; 34462 } 34463 }, 34464 _getComputedStyle = function _getComputedStyle(element) { 34465 return _win.getComputedStyle(element); 34466 }, 34467 _makePositionable = function _makePositionable(element) { 34468 var position = _getComputedStyle(element).position; 34469 34470 element.style.position = position === "absolute" || position === "fixed" ? position : "relative"; 34471 }, 34472 _setDefaults = function _setDefaults(obj, defaults) { 34473 for (var p in defaults) { 34474 p in obj || (obj[p] = defaults[p]); 34475 } 34476 34477 return obj; 34478 }, 34479 _getBounds = function _getBounds(element, withoutTransforms) { 34480 var tween = withoutTransforms && _getComputedStyle(element)[_transformProp] !== "matrix(1, 0, 0, 1, 0, 0)" && gsap.to(element, { 34481 x: 0, 34482 y: 0, 34483 xPercent: 0, 34484 yPercent: 0, 34485 rotation: 0, 34486 rotationX: 0, 34487 rotationY: 0, 34488 scale: 1, 34489 skewX: 0, 34490 skewY: 0 34491 }).progress(1), 34492 bounds = element.getBoundingClientRect(); 34493 tween && tween.progress(0).kill(); 34494 return bounds; 34495 }, 34496 _getSize = function _getSize(element, _ref4) { 34497 var d2 = _ref4.d2; 34498 return element["offset" + d2] || element["client" + d2] || 0; 34499 }, 34500 _getLabelRatioArray = function _getLabelRatioArray(timeline) { 34501 var a = [], 34502 labels = timeline.labels, 34503 duration = timeline.duration(), 34504 p; 34505 34506 for (p in labels) { 34507 a.push(labels[p] / duration); 34508 } 34509 34510 return a; 34511 }, 34512 _getClosestLabel = function _getClosestLabel(animation) { 34513 return function (value) { 34514 return gsap.utils.snap(_getLabelRatioArray(animation), value); 34515 }; 34516 }, 34517 _snapDirectional = function _snapDirectional(snapIncrementOrArray) { 34518 var snap = gsap.utils.snap(snapIncrementOrArray), 34519 a = Array.isArray(snapIncrementOrArray) && snapIncrementOrArray.slice(0).sort(function (a, b) { 34520 return a - b; 34521 }); 34522 return a ? function (value, direction) { 34523 var i; 34524 34525 if (!direction) { 34526 return snap(value); 34527 } 34528 34529 if (direction > 0) { 34530 value -= 1e-4; 34531 34532 for (i = 0; i < a.length; i++) { 34533 if (a[i] >= value) { 34534 return a[i]; 34535 } 34536 } 34537 34538 return a[i - 1]; 34539 } else { 34540 i = a.length; 34541 value += 1e-4; 34542 34543 while (i--) { 34544 if (a[i] <= value) { 34545 return a[i]; 34546 } 34547 } 34548 } 34549 34550 return a[0]; 34551 } : function (value, direction) { 34552 var snapped = snap(value); 34553 return !direction || Math.abs(snapped - value) < 0.001 || snapped - value < 0 === direction < 0 ? snapped : snap(direction < 0 ? value - snapIncrementOrArray : value + snapIncrementOrArray); 34554 }; 34555 }, 34556 _getLabelAtDirection = function _getLabelAtDirection(timeline) { 34557 return function (value, st) { 34558 return _snapDirectional(_getLabelRatioArray(timeline))(value, st.direction); 34559 }; 34560 }, 34561 _multiListener = function _multiListener(func, element, types, callback) { 34562 return types.split(",").forEach(function (type) { 34563 return func(element, type, callback); 34564 }); 34565 }, 34566 _addListener = function _addListener(element, type, func) { 34567 return element.addEventListener(type, func, { 34568 passive: true 34569 }); 34570 }, 34571 _removeListener = function _removeListener(element, type, func) { 34572 return element.removeEventListener(type, func); 34573 }, 34574 _markerDefaults = { 34575 startColor: "green", 34576 endColor: "red", 34577 indent: 0, 34578 fontSize: "16px", 34579 fontWeight: "normal" 34580 }, 34581 _defaults = { 34582 toggleActions: "play", 34583 anticipatePin: 0 34584 }, 34585 _keywords = { 34586 top: 0,
34587 left: 0, 34588 center: 0.5, 34589 bottom: 1, 34590 right: 1 34591 }, 34592 _offsetToPx = function _offsetToPx(value, size) { 34593 if (_isString(value)) { 34594 var eqIndex = value.indexOf("="), 34595 relative = ~eqIndex ? +(value.charAt(eqIndex - 1) + 1) * parseFloat(value.substr(eqIndex + 1)) : 0; 34596 34597 if (~eqIndex) { 34598 value.indexOf("%") > eqIndex && (relative *= size / 100); 34599 value = value.substr(0, eqIndex - 1); 34600 } 34601 34602 value = relative + (value in _keywords ? _keywords[value] * size : ~value.indexOf("%") ? parseFloat(value) * size / 100 : parseFloat(value) || 0); 34603 } 34604 34605 return value; 34606 }, 34607 _createMarker = function _createMarker(type, name, container, direction, _ref5, offset, matchWidthEl, containerAnimation) { 34608 var startColor = _ref5.startColor, 34609 endColor = _ref5.endColor, 34610 fontSize = _ref5.fontSize, 34611 indent = _ref5.indent, 34612 fontWeight = _ref5.fontWeight; 34613 34614 var e = _doc.createElement("div"), 34615 useFixedPosition = _isViewport(container) || _getProxyProp(container, "pinType") === "fixed", 34616 isScroller = type.indexOf("scroller") !== -1, 34617 parent = useFixedPosition ? _body : container, 34618 isStart = type.indexOf("start") !== -1, 34619 color = isStart ? startColor : endColor, 34620 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;"; 34621 34622 css += "position:" + ((isScroller || containerAnimation) && useFixedPosition ? "fixed;" : "absolute;"); 34623 (isScroller || containerAnimation || !useFixedPosition) && (css += (direction === _vertical ? _right : _bottom) + ":" + (offset + parseFloat(indent)) + "px;"); 34624 matchWidthEl && (css += "box-sizing:border-box;text-align:left;width:" + matchWidthEl.offsetWidth + "px;"); 34625 e._isStart = isStart; 34626 e.setAttribute("class", "gsap-marker-" + type + (name ? " marker-" + name : "")); 34627 e.style.cssText = css; 34628 e.innerText = name || name === 0 ? type + "-" + name : type; 34629 parent.children[0] ? parent.insertBefore(e, parent.children[0]) : parent.appendChild(e); 34630 e._offset = e["offset" + direction.op.d2]; 34631 34632 _positionMarker(e, 0, direction, isStart); 34633 34634 return e; 34635 }, 34636 _positionMarker = function _positionMarker(marker, start, direction, flipped) { 34637 var vars = { 34638 display: "block" 34639 }, 34640 side = direction[flipped ? "os2" : "p2"], 34641 oppositeSide = direction[flipped ? "p2" : "os2"]; 34642 marker._isFlipped = flipped; 34643 vars[direction.a + "Percent"] = flipped ? -100 : 0; 34644 vars[direction.a] = flipped ? "1px" : 0; 34645 vars["border" + side + _Width] = 1; 34646 vars["border" + oppositeSide + _Width] = 0; 34647 vars[direction.p] = start + "px"; 34648 gsap.set(marker, vars); 34649 }, 34650 _triggers = [], 34651 _ids = {}, 34652 _sync = function _sync() { 34653 return _getTime() - _lastScrollTime > 20 && _updateAll(); 34654 }, 34655 _onScroll = function _onScroll() { 34656 var time = _getTime(); 34657 34658 if (_lastScrollTime !== time) { 34659 _updateAll(); 34660 34661 _lastScrollTime || _dispatch("scrollStart"); 34662 _lastScrollTime = time; 34663 } else if (!_request) { 34664 _request = _raf(_updateAll); 34665 } 34666 }, 34667 _onResize = function _onResize() { 34668 return !_refreshing && !_ignoreResize && !_doc.fullscreenElement && _resizeDelay.restart(true); 34669 }, 34670 _listeners = {}, 34671 _emptyArray = [], 34672 _media = [], 34673 _creatingMedia, 34674 _lastMediaTick, 34675 _onMediaChange = function _onMediaChange(e) { 34676 var tick = gsap.ticker.frame, 34677 matches = [], 34678 i = 0, 34679 index; 34680 34681 if (_lastMediaTick !== tick || _startup) { 34682 _revertAll(); 34683 34684 for (; i < _media.length; i += 4) { 34685 index = _win.matchMedia(_media[i]).matches; 34686 34687 if (index !== _media[i + 3]) { 34688 _media[i + 3] = index; 34689 index ? matches.push(i) : _revertAll(1, _media[i]) || _isFunction(_media[i + 2]) && _media[i + 2](); 34690 } 34691 } 34692 34693 _revertRecorded(); 34694 34695 for (i = 0; i < matches.length; i++) { 34696 index = matches[i]; 34697 _creatingMedia = _media[index]; 34698 _media[index + 2] = _media[index + 1](e); 34699 } 34700 34701 _creatingMedia = 0; 34702 _coreInitted && _refreshAll(0, 1); 34703 _lastMediaTick = tick; 34704 34705 _dispatch("matchMedia"); 34706 } 34707 }, 34708 _softRefresh = function _softRefresh() { 34709 return _removeListener(ScrollTrigger, "scrollEnd", _softRefresh) || _refreshAll(true); 34710 }, 34711 _dispatch = function _dispatch(type) { 34712 return _listeners[type] && _listeners[type].map(function (f) { 34713 return f(); 34714 }) || _emptyArray; 34715 }, 34716 _savedStyles = [], 34717 _revertRecorded = function _revertRecorded(media) { 34718 for (var i = 0; i < _savedStyles.length; i += 5) { 34719 if (!media || _savedStyles[i + 4] === media) { 34720 _savedStyles[i].style.cssText = _savedStyles[i + 1]; 34721 _savedStyles[i].getBBox && _savedStyles[i].setAttribute("transform", _savedStyles[i + 2] || ""); 34722 _savedStyles[i + 3].uncache = 1; 34723 } 34724 } 34725 }, 34726 _revertAll = function _revertAll(kill, media) { 34727 var trigger; 34728 34729 for (_i = 0; _i < _triggers.length; _i++) { 34730 trigger = _triggers[_i]; 34731 34732 if (!media || trigger.media === media) { 34733 if (kill) { 34734 trigger.kill(1); 34735 } else { 34736 trigger.revert(); 34737 } 34738 } 34739 } 34740 34741 media && _revertRecorded(media); 34742 media || _dispatch("revert"); 34743 }, 34744 _clearScrollMemory = function _clearScrollMemory() {
vendor: 10,266 bytes, lines 34745-35079
34745 return _scrollers.forEach(function (obj) { 34746 return typeof obj === "function" && (obj.rec = 0); 34747 }); 34748 }, 34749 _refreshingAll, 34750 _refreshAll = function _refreshAll(force, skipRevert) { 34751 if (_lastScrollTime && !force) { 34752 _addListener(ScrollTrigger, "scrollEnd", _softRefresh); 34753 34754 return; 34755 } 34756 34757 _refreshingAll = true; 34758 34759 var refreshInits = _dispatch("refreshInit"); 34760 34761 _sort && ScrollTrigger.sort(); 34762 skipRevert || _revertAll(); 34763 34764 _triggers.forEach(function (t) { 34765 return t.refresh(); 34766 }); 34767 34768 refreshInits.forEach(function (result) { 34769 return result && result.render && result.render(-1); 34770 }); 34771 34772 _clearScrollMemory(); 34773 34774 _resizeDelay.pause(); 34775 34776 _refreshingAll = false; 34777 34778 _dispatch("refresh"); 34779 }, 34780 _lastScroll = 0, 34781 _direction = 1, 34782 _updateAll = function _updateAll() { 34783 if (!_refreshingAll) { 34784 var l = _triggers.length, 34785 time = _getTime(), 34786 recordVelocity = time - _time1 >= 50, 34787 scroll = l && _triggers[0].scroll(); 34788 34789 _direction = _lastScroll > scroll ? -1 : 1; 34790 _lastScroll = scroll; 34791 34792 if (recordVelocity) { 34793 if (_lastScrollTime && !_pointerIsDown && time - _lastScrollTime > 200) { 34794 _lastScrollTime = 0; 34795 34796 _dispatch("scrollEnd"); 34797 } 34798 34799 _time2 = _time1; 34800 _time1 = time; 34801 } 34802 34803 if (_direction < 0) { 34804 _i = l; 34805 34806 while (_i-- > 0) { 34807 _triggers[_i] && _triggers[_i].update(0, recordVelocity); 34808 } 34809 34810 _direction = 1; 34811 } else { 34812 for (_i = 0; _i < l; _i++) { 34813 _triggers[_i] && _triggers[_i].update(0, recordVelocity); 34814 } 34815 } 34816 34817 _request = 0; 34818 } 34819 }, 34820 _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"], 34821 _stateProps = _propNamesToCopy.concat([_width, _height, "boxSizing", "max" + _Width, "max" + _Height, "position", _margin, _padding, _padding + _Top, _padding + _Right, _padding + _Bottom, _padding + _Left]), 34822 _swapPinOut = function _swapPinOut(pin, spacer, state) { 34823 _setState(state); 34824 34825 var cache = pin._gsap; 34826 34827 if (cache.spacerIsNative) { 34828 _setState(cache.spacerState); 34829 } else if (pin.parentNode === spacer) { 34830 var parent = spacer.parentNode; 34831 34832 if (parent) { 34833 parent.insertBefore(pin, spacer); 34834 parent.removeChild(spacer); 34835 } 34836 } 34837 }, 34838 _swapPinIn = function _swapPinIn(pin, spacer, cs, spacerState) { 34839 if (pin.parentNode !== spacer) { 34840 var i = _propNamesToCopy.length, 34841 spacerStyle = spacer.style, 34842 pinStyle = pin.style, 34843 p; 34844 34845 while (i--) { 34846 p = _propNamesToCopy[i]; 34847 spacerStyle[p] = cs[p]; 34848 } 34849 34850 spacerStyle.position = cs.position === "absolute" ? "absolute" : "relative"; 34851 cs.display === "inline" && (spacerStyle.display = "inline-block"); 34852 pinStyle[_bottom] = pinStyle[_right] = "auto"; 34853 spacerStyle.overflow = "visible"; 34854 spacerStyle.boxSizing = "border-box"; 34855 spacerStyle[_width] = _getSize(pin, _horizontal) + _px; 34856 spacerStyle[_height] = _getSize(pin, _vertical) + _px; 34857 spacerStyle[_padding] = pinStyle[_margin] = pinStyle[_top] = pinStyle[_left] = "0"; 34858 34859 _setState(spacerState); 34860 34861 pinStyle[_width] = pinStyle["max" + _Width] = cs[_width]; 34862 pinStyle[_height] = pinStyle["max" + _Height] = cs[_height]; 34863 pinStyle[_padding] = cs[_padding]; 34864 pin.parentNode.insertBefore(spacer, pin); 34865 spacer.appendChild(pin); 34866 } 34867 }, 34868 _capsExp = /([A-Z])/g, 34869 _setState = function _setState(state) { 34870 if (state) { 34871 var style = state.t.style, 34872 l = state.length, 34873 i = 0, 34874 p, 34875 value; 34876 (state.t._gsap || gsap.core.getCache(state.t)).uncache = 1; 34877 34878 for (; i < l; i += 2) { 34879 value = state[i + 1]; 34880 p = state[i]; 34881 34882 if (value) { 34883 style[p] = value; 34884 } else if (style[p]) { 34885 style.removeProperty(p.replace(_capsExp, "-$1").toLowerCase()); 34886 } 34887 } 34888 } 34889 }, 34890 _getState = function _getState(element) { 34891 var l = _stateProps.length, 34892 style = element.style, 34893 state = [], 34894 i = 0; 34895 34896 for (; i < l; i++) { 34897 state.push(_stateProps[i], style[_stateProps[i]]); 34898 } 34899 34900 state.t = element; 34901 return state; 34902 }, 34903 _copyState = function _copyState(state, override, omitOffsets) { 34904 var result = [], 34905 l = state.length, 34906 i = omitOffsets ? 8 : 0, 34907 p; 34908 34909 for (; i < l; i += 2) { 34910 p = state[i]; 34911 result.push(p, p in override ? override[p] : state[i + 1]); 34912 } 34913 34914 result.t = state.t; 34915 return result; 34916 }, 34917 _winOffsets = { 34918 left: 0, 34919 top: 0 34920 }, 34921 _parsePosition = function _parsePosition(value, trigger, scrollerSize, direction, scroll, marker, markerScroller, self, scrollerBounds, borderWidth, useFixedPosition, scrollerMax, containerAnimation) { 34922 _isFunction(value) && (value = value(self)); 34923 34924 if (_isString(value) && value.substr(0, 3) === "max") { 34925 value = scrollerMax + (value.charAt(4) === "=" ? _offsetToPx("0" + value.substr(3), scrollerSize) : 0); 34926 } 34927 34928 var time = containerAnimation ? containerAnimation.time() : 0, 34929 p1, 34930 p2, 34931 element; 34932 containerAnimation && containerAnimation.seek(0); 34933 34934 if (!_isNumber(value)) { 34935 _isFunction(trigger) && (trigger = trigger(self)); 34936 var offsets = value.split(" "), 34937 bounds, 34938 localOffset, 34939 globalOffset, 34940 display; 34941 element = _getTarget(trigger) || _body; 34942 bounds = _getBounds(element) || {}; 34943 34944 if ((!bounds || !bounds.left && !bounds.top) && _getComputedStyle(element).display === "none") { 34945 display = element.style.display; 34946 element.style.display = "block"; 34947 bounds = _getBounds(element); 34948 display ? element.style.display = display : element.style.removeProperty("display"); 34949 } 34950 34951 localOffset = _offsetToPx(offsets[0], bounds[direction.d]); 34952 globalOffset = _offsetToPx(offsets[1] || "0", scrollerSize); 34953 value = bounds[direction.p] - scrollerBounds[direction.p] - borderWidth + localOffset + scroll - globalOffset; 34954 markerScroller && _positionMarker(markerScroller, globalOffset, direction, scrollerSize - globalOffset < 20 || markerScroller._isStart && globalOffset > 20); 34955 scrollerSize -= scrollerSize - globalOffset; 34956 } else if (markerScroller) { 34957 _positionMarker(markerScroller, scrollerSize, direction, true); 34958 } 34959 34960 if (marker) { 34961 var position = value + scrollerSize, 34962 isStart = marker._isStart; 34963 p1 = "scroll" + direction.d2; 34964 34965 _positionMarker(marker, position, direction, isStart && position > 20 || !isStart && (useFixedPosition ? Math.max(_body[p1], _docEl[p1]) : marker.parentNode[p1]) <= position + 1); 34966 34967 if (useFixedPosition) { 34968 scrollerBounds = _getBounds(markerScroller); 34969 useFixedPosition && (marker.style[direction.op.p] = scrollerBounds[direction.op.p] - direction.op.m - marker._offset + _px); 34970 } 34971 } 34972 34973 if (containerAnimation && element) { 34974 p1 = _getBounds(element); 34975 containerAnimation.seek(scrollerMax); 34976 p2 = _getBounds(element); 34977 containerAnimation._caScrollDist = p1[direction.p] - p2[direction.p]; 34978 value = value / containerAnimation._caScrollDist * scrollerMax; 34979 } 34980 34981 containerAnimation && containerAnimation.seek(time); 34982 return containerAnimation ? value : Math.round(value); 34983 }, 34984 _prefixExp = /(?:webkit|moz|length|cssText|inset)/i, 34985 _reparent = function _reparent(element, parent, top, left) { 34986 if (element.parentNode !== parent) { 34987 var style = element.style, 34988 p, 34989 cs; 34990 34991 if (parent === _body) { 34992 element._stOrig = style.cssText; 34993 cs = _getComputedStyle(element); 34994 34995 for (p in cs) { 34996 if (!+p && !_prefixExp.test(p) && cs[p] && typeof style[p] === "string" && p !== "0") { 34997 style[p] = cs[p]; 34998 } 34999 } 35000 35001 style.top = top; 35002 style.left = left; 35003 } else { 35004 style.cssText = element._stOrig; 35005 } 35006 35007 gsap.core.getCache(element).uncache = 1; 35008 parent.appendChild(element); 35009 } 35010 }, 35011 _getTweenCreator = function _getTweenCreator(scroller, direction) { 35012 var getScroll = _getScrollFunc(scroller, direction), 35013 prop = "_scroll" + direction.p2, 35014 lastScroll1, 35015 lastScroll2, 35016 getTween = function getTween(scrollTo, vars, initialValue, change1, change2) { 35017 var tween = getTween.tween, 35018 onComplete = vars.onComplete, 35019 modifiers = {}; 35020 tween && tween.kill(); 35021 lastScroll1 = Math.round(initialValue); 35022 vars[prop] = scrollTo; 35023 vars.modifiers = modifiers; 35024 35025 modifiers[prop] = function (value) { 35026 value = _round(getScroll()); 35027 35028 if (value !== lastScroll1 && value !== lastScroll2 && Math.abs(value - lastScroll1) > 2) { 35029 tween.kill(); 35030 getTween.tween = 0; 35031 } else { 35032 value = initialValue + change1 * tween.ratio + change2 * tween.ratio * tween.ratio; 35033 } 35034 35035 lastScroll2 = lastScroll1; 35036 return lastScroll1 = _round(value); 35037 }; 35038 35039 vars.onComplete = function () { 35040 getTween.tween = 0; 35041 onComplete && onComplete.call(tween); 35042 }; 35043 35044 tween = getTween.tween = gsap.to(scroller, vars); 35045 return tween; 35046 }; 35047 35048 scroller[prop] = getScroll; 35049 scroller.addEventListener("wheel", function () { 35050 return getTween.tween && getTween.tween.kill() && (getTween.tween = 0); 35051 }, { 35052 passive: true 35053 }); 35054 return getTween; 35055 }; 35056 35057 _horizontal.op = _vertical; 35058 var ScrollTrigger = function () { 35059 function ScrollTrigger(vars, animation) { 35060 _coreInitted || ScrollTrigger.register(gsap) || console.warn("Please gsap.registerPlugin(ScrollTrigger)"); 35061 this.init(vars, animation); 35062 } 35063 35064 var _proto = ScrollTrigger.prototype; 35065 35066 _proto.init = function init(vars, animation) { 35067 this.progress = this.start = 0; 35068 this.vars && this.kill(1); 35069 35070 if (!_enabled) { 35071 this.update = this.refresh = this.kill = _passThrough; 35072 return; 35073 } 35074 35075 vars = _setDefaults(_isString(vars) || _isNumber(vars) || vars.nodeType ? { 35076 trigger: vars 35077 } : vars, _defaults); 35078 35079 var _vars = vars,
35080 onUpdate = _vars.onUpdate, 35081 toggleClass = _vars.toggleClass, 35082 id = _vars.id, 35083 onToggle = _vars.onToggle, 35084 onRefresh = _vars.onRefresh, 35085 scrub = _vars.scrub, 35086 trigger = _vars.trigger, 35087 pin = _vars.pin, 35088 pinSpacing = _vars.pinSpacing, 35089 invalidateOnRefresh = _vars.invalidateOnRefresh, 35090 anticipatePin = _vars.anticipatePin, 35091 onScrubComplete = _vars.onScrubComplete, 35092 onSnapComplete = _vars.onSnapComplete, 35093 once = _vars.once, 35094 snap = _vars.snap, 35095 pinReparent = _vars.pinReparent, 35096 pinSpacer = _vars.pinSpacer, 35097 containerAnimation = _vars.containerAnimation, 35098 fastScrollEnd = _vars.fastScrollEnd, 35099 preventOverlaps = _vars.preventOverlaps, 35100 direction = vars.horizontal || vars.containerAnimation && vars.horizontal !== false ? _horizontal : _vertical, 35101 isToggle = !scrub && scrub !== 0, 35102 scroller = _getTarget(vars.scroller || _win), 35103 scrollerCache = gsap.core.getCache(scroller), 35104 isViewport = _isViewport(scroller), 35105 useFixedPosition = ("pinType" in vars ? vars.pinType : _getProxyProp(scroller, "pinType") || isViewport && "fixed") === "fixed", 35106 callbacks = [vars.onEnter, vars.onLeave, vars.onEnterBack, vars.onLeaveBack], 35107 toggleActions = isToggle && vars.toggleActions.split(" "), 35108 markers = "markers" in vars ? vars.markers : _defaults.markers, 35109 borderWidth = isViewport ? 0 : parseFloat(_getComputedStyle(scroller)["border" + direction.p2 + _Width]) || 0, 35110 self = this, 35111 onRefreshInit = vars.onRefreshInit && function () { 35112 return vars.onRefreshInit(self); 35113 }, 35114 getScrollerSize = _getSizeFunc(scroller, isViewport, direction), 35115 getScrollerOffsets = _getOffsetsFunc(scroller, isViewport), 35116 lastSnap = 0, 35117 scrollFunc = _getScrollFunc(scroller, direction), 35118 tweenTo, 35119 pinCache, 35120 snapFunc, 35121 scroll1, 35122 scroll2, 35123 start, 35124 end, 35125 markerStart, 35126 markerEnd, 35127 markerStartTrigger, 35128 markerEndTrigger, 35129 markerVars, 35130 change, 35131 pinOriginalState, 35132 pinActiveState, 35133 pinState, 35134 spacer, 35135 offset, 35136 pinGetter, 35137 pinSetter, 35138 pinStart, 35139 pinChange, 35140 spacingStart, 35141 spacerState, 35142 markerStartSetter, 35143 markerEndSetter, 35144 cs, 35145 snap1, 35146 snap2, 35147 scrubTween, 35148 scrubSmooth, 35149 snapDurClamp, 35150 snapDelayedCall, 35151 prevProgress, 35152 prevScroll, 35153 prevAnimProgress, 35154 caMarkerSetter; 35155 35156 self.media = _creatingMedia; 35157 anticipatePin *= 45; 35158 self.scroller = scroller; 35159 self.scroll = containerAnimation ? containerAnimation.time.bind(containerAnimation) : scrollFunc; 35160 scroll1 = scrollFunc(); 35161 self.vars = vars; 35162 animation = animation || vars.animation; 35163 "refreshPriority" in vars && (_sort = 1); 35164 scrollerCache.tweenScroll = scrollerCache.tweenScroll || { 35165 top: _getTweenCreator(scroller, _vertical), 35166 left: _getTweenCreator(scroller, _horizontal) 35167 }; 35168 self.tweenTo = tweenTo = scrollerCache.tweenScroll[direction.p]; 35169 35170 if (animation) { 35171 animation.vars.lazy = false; 35172 animation._initted || animation.vars.immediateRender !== false && vars.immediateRender !== false && animation.render(0, true, true); 35173 self.animation = animation.pause(); 35174 animation.scrollTrigger = self; 35175 scrubSmooth = _isNumber(scrub) && scrub; 35176 scrubSmooth && (scrubTween = gsap.to(animation, { 35177 ease: "power3", 35178 duration: scrubSmooth, 35179 onComplete: function onComplete() { 35180 return onScrubComplete && onScrubComplete(self); 35181 } 35182 })); 35183 snap1 = 0; 35184 id || (id = animation.vars.id); 35185 } 35186 35187 _triggers.push(self); 35188 35189 if (snap) { 35190 if (!_isObject(snap) || snap.push) { 35191 snap = { 35192 snapTo: snap 35193 }; 35194 } 35195 35196 "scrollBehavior" in _body.style && gsap.set(isViewport ? [_body, _docEl] : scroller, { 35197 scrollBehavior: "auto" 35198 }); 35199 snapFunc = _isFunction(snap.snapTo) ? snap.snapTo : snap.snapTo === "labels" ? _getClosestLabel(animation) : snap.snapTo === "labelsDirectional" ? _getLabelAtDirection(animation) : snap.directional !== false ? function (value, st) { 35200 return _snapDirectional(snap.snapTo)(value, st.direction); 35201 } : gsap.utils.snap(snap.snapTo); 35202 snapDurClamp = snap.duration || { 35203 min: 0.1, 35204 max: 2 35205 }; 35206 snapDurClamp = _isObject(snapDurClamp) ? _clamp(snapDurClamp.min, snapDurClamp.max) : _clamp(snapDurClamp, snapDurClamp); 35207 snapDelayedCall = gsap.delayedCall(snap.delay || scrubSmooth / 2 || 0.1, function () { 35208 if (Math.abs(self.getVelocity()) < 10 && !_pointerIsDown && lastSnap !== scrollFunc()) { 35209 var totalProgress = animation && !isToggle ? animation.totalProgress() : self.progress, 35210 velocity = (totalProgress - snap2) / (_getTime() - _time2) * 1000 || 0, 35211 change1 = gsap.utils.clamp(-self.progress, 1 - self.progress, _abs(velocity / 2) * velocity / 0.185), 35212 naturalEnd = self.progress + (snap.inertia === false ? 0 : change1), 35213 endValue = _clamp(0, 1, snapFunc(naturalEnd, self)), 35214 scroll = scrollFunc(), 35215 endScroll = Math.round(start + endValue * change), 35216 _snap = snap, 35217 onStart = _snap.onStart, 35218 _onInterrupt = _snap.onInterrupt, 35219 _onComplete = _snap.onComplete, 35220 tween = tweenTo.tween; 35221 35222 if (scroll <= end && scroll >= start && endScroll !== scroll) { 35223 if (tween && !tween._initted && tween.data <= _abs(endScroll - scroll)) { 35224 return; 35225 } 35226 35227 if (snap.inertia === false) { 35228 change1 = endValue - self.progress; 35229 } 35230 35231 tweenTo(endScroll, { 35232 duration: snapDurClamp(_abs(Math.max(_abs(naturalEnd - totalProgress), _abs(endValue - totalProgress)) * 0.185 / velocity / 0.05 || 0)), 35233 ease: snap.ease || "power3", 35234 data: _abs(endScroll - scroll), 35235 onInterrupt: function onInterrupt() { 35236 return snapDelayedCall.restart(true) && _onInterrupt && _onInterrupt(self); 35237 }, 35238 onComplete: function onComplete() { 35239 lastSnap = scrollFunc(); 35240 snap1 = snap2 = animation && !isToggle ? animation.totalProgress() : self.progress; 35241 onSnapComplete && onSnapComplete(self); 35242 _onComplete && _onComplete(self); 35243 } 35244 }, scroll, change1 * change, endScroll - scroll - change1 * change); 35245 onStart && onStart(self, tweenTo.tween); 35246 } 35247 } else if (self.isActive) { 35248 snapDelayedCall.restart(true); 35249 } 35250 }).pause(); 35251 } 35252 35253 id && (_ids[id] = self); 35254 trigger = self.trigger = _getTarget(trigger || pin); 35255 pin = pin === true ? trigger : _getTarget(pin); 35256 _isString(toggleClass) && (toggleClass = { 35257 targets: trigger, 35258 className: toggleClass 35259 }); 35260 35261 if (pin) { 35262 pinSpacing === false || pinSpacing === _margin || (pinSpacing = !pinSpacing && _getComputedStyle(pin.parentNode).display === "flex" ? false : _padding); 35263 self.pin = pin; 35264 vars.force3D !== false && gsap.set(pin, {
35265 force3D: true 35266 }); 35267 pinCache = gsap.core.getCache(pin); 35268 35269 if (!pinCache.spacer) { 35270 if (pinSpacer) { 35271 pinSpacer = _getTarget(pinSpacer); 35272 pinSpacer && !pinSpacer.nodeType && (pinSpacer = pinSpacer.current || pinSpacer.nativeElement); 35273 pinCache.spacerIsNative = !!pinSpacer; 35274 pinSpacer && (pinCache.spacerState = _getState(pinSpacer)); 35275 } 35276 35277 pinCache.spacer = spacer = pinSpacer || _doc.createElement("div"); 35278 spacer.classList.add("pin-spacer"); 35279 id && spacer.classList.add("pin-spacer-" + id); 35280 pinCache.pinState = pinOriginalState = _getState(pin); 35281 } else { 35282 pinOriginalState = pinCache.pinState; 35283 } 35284 35285 self.spacer = spacer = pinCache.spacer; 35286 cs = _getComputedStyle(pin); 35287 spacingStart = cs[pinSpacing + direction.os2]; 35288 pinGetter = gsap.getProperty(pin); 35289 pinSetter = gsap.quickSetter(pin, direction.a, _px); 35290 35291 _swapPinIn(pin, spacer, cs); 35292 35293 pinState = _getState(pin); 35294 } 35295 35296 if (markers) { 35297 markerVars = _isObject(markers) ? _setDefaults(markers, _markerDefaults) : _markerDefaults; 35298 markerStartTrigger = _createMarker("scroller-start", id, scroller, direction, markerVars, 0); 35299 markerEndTrigger = _createMarker("scroller-end", id, scroller, direction, markerVars, 0, markerStartTrigger); 35300 offset = markerStartTrigger["offset" + direction.op.d2]; 35301 markerStart = _createMarker("start", id, scroller, direction, markerVars, offset, 0, containerAnimation); 35302 markerEnd = _createMarker("end", id, scroller, direction, markerVars, offset, 0, containerAnimation); 35303 containerAnimation && (caMarkerSetter = gsap.quickSetter([markerStart, markerEnd], direction.a, _px)); 35304 35305 if (!useFixedPosition && !(_proxies.length && _getProxyProp(scroller, "fixedMarkers") === true)) { 35306 _makePositionable(isViewport ? _body : scroller); 35307 35308 gsap.set([markerStartTrigger, markerEndTrigger], { 35309 force3D: true 35310 }); 35311 markerStartSetter = gsap.quickSetter(markerStartTrigger, direction.a, _px); 35312 markerEndSetter = gsap.quickSetter(markerEndTrigger, direction.a, _px); 35313 } 35314 } 35315 35316 if (containerAnimation) { 35317 var oldOnUpdate = containerAnimation.vars.onUpdate, 35318 oldParams = containerAnimation.vars.onUpdateParams; 35319 containerAnimation.eventCallback("onUpdate", function () { 35320 self.update(0, 0, 1); 35321 oldOnUpdate && oldOnUpdate.apply(oldParams || []); 35322 }); 35323 } 35324 35325 self.previous = function () { 35326 return _triggers[_triggers.indexOf(self) - 1]; 35327 }; 35328 35329 self.next = function () { 35330 return _triggers[_triggers.indexOf(self) + 1]; 35331 }; 35332 35333 self.revert = function (revert) { 35334 var r = revert !== false || !self.enabled, 35335 prevRefreshing = _refreshing; 35336 35337 if (r !== self.isReverted) { 35338 if (r) { 35339 self.scroll.rec || (self.scroll.rec = scrollFunc()); 35340 prevScroll = Math.max(scrollFunc(), self.scroll.rec || 0); 35341 prevProgress = self.progress; 35342 prevAnimProgress = animation && animation.progress(); 35343 } 35344 35345 markerStart && [markerStart, markerEnd, markerStartTrigger, markerEndTrigger].forEach(function (m) { 35346 return m.style.display = r ? "none" : "block"; 35347 }); 35348 r && (_refreshing = 1); 35349 self.update(r); 35350 _refreshing = prevRefreshing; 35351 pin && (r ? _swapPinOut(pin, spacer, pinOriginalState) : (!pinReparent || !self.isActive) && _swapPinIn(pin, spacer, _getComputedStyle(pin), spacerState)); 35352 self.isReverted = r; 35353 } 35354 }; 35355 35356 self.refresh = function (soft, force) { 35357 if ((_refreshing || !self.enabled) && !force) { 35358 return; 35359 } 35360 35361 if (pin && soft && _lastScrollTime) { 35362 _addListener(ScrollTrigger, "scrollEnd", _softRefresh); 35363 35364 return; 35365 } 35366 35367 _refreshing = 1; 35368 scrubTween && scrubTween.pause(); 35369 invalidateOnRefresh && animation && animation.progress(0).invalidate(); 35370 self.isReverted || self.revert(); 35371 35372 var size = getScrollerSize(), 35373 scrollerBounds = getScrollerOffsets(),
35374 max = containerAnimation ? containerAnimation.duration() : _maxScroll(scroller, direction), 35375 offset = 0, 35376 otherPinOffset = 0, 35377 parsedEnd = vars.end, 35378 parsedEndTrigger = vars.endTrigger || trigger, 35379 parsedStart = vars.start || (vars.start === 0 || !trigger ? 0 : pin ? "0 0" : "0 100%"), 35380 pinnedContainer = vars.pinnedContainer && _getTarget(vars.pinnedContainer), 35381 triggerIndex = trigger && Math.max(0, _triggers.indexOf(self)) || 0, 35382 i = triggerIndex, 35383 cs, 35384 bounds, 35385 scroll, 35386 isVertical, 35387 override, 35388 curTrigger, 35389 curPin, 35390 oppositeScroll, 35391 initted, 35392 revertedPins; 35393 35394 while (i--) { 35395 curTrigger = _triggers[i]; 35396 curTrigger.end || curTrigger.refresh(0, 1) || (_refreshing = 1); 35397 curPin = curTrigger.pin; 35398 35399 if (curPin && (curPin === trigger || curPin === pin) && !curTrigger.isReverted) { 35400 revertedPins || (revertedPins = []); 35401 revertedPins.unshift(curTrigger); 35402 curTrigger.revert(); 35403 } 35404 } 35405 35406 _isFunction(parsedStart) && (parsedStart = parsedStart(self)); 35407 start = _parsePosition(parsedStart, trigger, size, direction, scrollFunc(), markerStart, markerStartTrigger, self, scrollerBounds, borderWidth, useFixedPosition, max, containerAnimation) || (pin ? -0.001 : 0); 35408 _isFunction(parsedEnd) && (parsedEnd = parsedEnd(self)); 35409 35410 if (_isString(parsedEnd) && !parsedEnd.indexOf("+=")) { 35411 if (~parsedEnd.indexOf(" ")) { 35412 parsedEnd = (_isString(parsedStart) ? parsedStart.split(" ")[0] : "") + parsedEnd; 35413 } else { 35414 offset = _offsetToPx(parsedEnd.substr(2), size); 35415 parsedEnd = _isString(parsedStart) ? parsedStart : start + offset; 35416 parsedEndTrigger = trigger; 35417 } 35418 } 35419 35420 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; 35421 change = end - start || (start -= 0.01) && 0.001; 35422 offset = 0; 35423 i = triggerIndex; 35424 35425 while (i--) { 35426 curTrigger = _triggers[i]; 35427 curPin = curTrigger.pin; 35428 35429 if (curPin && curTrigger.start - curTrigger._pinPush < start && !containerAnimation) { 35430 cs = curTrigger.end - curTrigger.start; 35431 (curPin === trigger || curPin === pinnedContainer) && !_isNumber(parsedStart) && (offset += cs); 35432 curPin === pin && (otherPinOffset += cs); 35433 } 35434 } 35435 35436 start += offset; 35437 end += offset; 35438 self._pinPush = otherPinOffset; 35439 35440 if (markerStart && offset) { 35441 cs = {}; 35442 cs[direction.a] = "+=" + offset; 35443 pinnedContainer && (cs[direction.p] = "-=" + scrollFunc()); 35444 gsap.set([markerStart, markerEnd], cs); 35445 } 35446 35447 if (pin) { 35448 cs = _getComputedStyle(pin); 35449 isVertical = direction === _vertical; 35450 scroll = scrollFunc(); 35451 pinStart = parseFloat(pinGetter(direction.a)) + otherPinOffset; 35452 !max && end > 1 && ((isViewport ? _body : scroller).style["overflow-" + direction.a] = "scroll"); 35453 35454 _swapPinIn(pin, spacer, cs); 35455 35456 pinState = _getState(pin); 35457 bounds = _getBounds(pin, true); 35458 oppositeScroll = useFixedPosition && _getScrollFunc(scroller, isVertical ? _horizontal : _vertical)(); 35459 35460 if (pinSpacing) { 35461 spacerState = [pinSpacing + direction.os2, change + otherPinOffset + _px]; 35462 spacerState.t = spacer; 35463 i = pinSpacing === _padding ? _getSize(pin, direction) + change + otherPinOffset : 0; 35464 i && spacerState.push(direction.d, i + _px); 35465 35466 _setState(spacerState); 35467 35468 useFixedPosition && scrollFunc(prevScroll); 35469 } 35470 35471 if (useFixedPosition) { 35472 override = { 35473 top: bounds.top + (isVertical ? scroll - start : oppositeScroll) + _px, 35474 left: bounds.left + (isVertical ? oppositeScroll : scroll - start) + _px, 35475 boxSizing: "border-box", 35476 position: "fixed" 35477 }; 35478 override[_width] = override["max" + _Width] = Math.ceil(bounds.width) + _px; 35479 override[_height] = override["max" + _Height] = Math.ceil(bounds.height) + _px; 35480 override[_margin] = override[_margin + _Top] = override[_margin + _Right] = override[_margin + _Bottom] = override[_margin + _Left] = "0"; 35481 override[_padding] = cs[_padding]; 35482 override[_padding + _Top] = cs[_padding + _Top]; 35483 override[_padding + _Right] = cs[_padding + _Right]; 35484 override[_padding + _Bottom] = cs[_padding + _Bottom]; 35485 override[_padding + _Left] = cs[_padding + _Left]; 35486 pinActiveState = _copyState(pinOriginalState, override, pinReparent); 35487 } 35488 35489 if (animation) { 35490 initted = animation._initted; 35491 35492 _suppressOverwrites(1); 35493 35494 animation.render(animation.duration(), true, true); 35495 pinChange = pinGetter(direction.a) - pinStart + change + otherPinOffset; 35496 change !== pinChange && pinActiveState.splice(pinActiveState.length - 2, 2); 35497 animation.render(0, true, true); 35498 initted || animation.invalidate(); 35499 35500 _suppressOverwrites(0); 35501 } else { 35502 pinChange = change; 35503 } 35504 } else if (trigger && scrollFunc() && !containerAnimation) { 35505 bounds = trigger.parentNode; 35506 35507 while (bounds && bounds !== _body) { 35508 if (bounds._pinOffset) { 35509 start -= bounds._pinOffset; 35510 end -= bounds._pinOffset; 35511 } 35512 35513 bounds = bounds.parentNode; 35514 } 35515 } 35516 35517 revertedPins && revertedPins.forEach(function (t) { 35518 return t.revert(false); 35519 }); 35520 self.start = start; 35521 self.end = end; 35522 scroll1 = scroll2 = scrollFunc(); 35523 35524 if (!containerAnimation) { 35525 scroll1 < prevScroll && scrollFunc(prevScroll); 35526 self.scroll.rec = 0; 35527 } 35528 35529 self.revert(false); 35530 _refreshing = 0; 35531 animation && isToggle && animation._initted && animation.progress() !== prevAnimProgress && animation.progress(prevAnimProgress, true).render(animation.time(), true, true); 35532 35533 if (prevProgress !== self.progress) { 35534 animation && !isToggle && animation.totalProgress(prevProgress, true); 35535 self.progress = prevProgress; 35536 self.update(0, 0, 1); 35537 } 35538 35539 pin && pinSpacing && (spacer._pinOffset = Math.round(self.progress * pinChange)); 35540 onRefresh && onRefresh(self); 35541 }; 35542 35543 self.getVelocity = function () { 35544 return (scrollFunc() - scroll2) / (_getTime() - _time2) * 1000 || 0; 35545 }; 35546 35547 self.endAnimation = function () {
vendor: 8,601 bytes, lines 35548-35786
35548 _endAnimation(self.callbackAnimation); 35549 35550 if (animation) { 35551 scrubTween ? scrubTween.progress(1) : !animation.paused() ? _endAnimation(animation, animation.reversed()) : isToggle || _endAnimation(animation, self.direction < 0, 1); 35552 } 35553 }; 35554 35555 self.getTrailing = function (name) { 35556 var i = _triggers.indexOf(self), 35557 a = self.direction > 0 ? _triggers.slice(0, i).reverse() : _triggers.slice(i + 1); 35558 35559 return _isString(name) ? a.filter(function (t) { 35560 return t.vars.preventOverlaps === name; 35561 }) : a; 35562 }; 35563 35564 self.update = function (reset, recordVelocity, forceFake) { 35565 if (containerAnimation && !forceFake && !reset) { 35566 return; 35567 } 35568 35569 var scroll = self.scroll(), 35570 p = reset ? 0 : (scroll - start) / change, 35571 clipped = p < 0 ? 0 : p > 1 ? 1 : p || 0, 35572 prevProgress = self.progress, 35573 isActive, 35574 wasActive, 35575 toggleState, 35576 action, 35577 stateChanged, 35578 toggled, 35579 isAtMax, 35580 isTakingAction; 35581 35582 if (recordVelocity) { 35583 scroll2 = scroll1; 35584 scroll1 = containerAnimation ? scrollFunc() : scroll; 35585 35586 if (snap) { 35587 snap2 = snap1; 35588 snap1 = animation && !isToggle ? animation.totalProgress() : clipped; 35589 } 35590 } 35591 35592 anticipatePin && !clipped && pin && !_refreshing && !_startup && _lastScrollTime && start < scroll + (scroll - scroll2) / (_getTime() - _time2) * anticipatePin && (clipped = 0.0001); 35593 35594 if (clipped !== prevProgress && self.enabled) { 35595 isActive = self.isActive = !!clipped && clipped < 1; 35596 wasActive = !!prevProgress && prevProgress < 1; 35597 toggled = isActive !== wasActive; 35598 stateChanged = toggled || !!clipped !== !!prevProgress; 35599 self.direction = clipped > prevProgress ? 1 : -1; 35600 self.progress = clipped; 35601 35602 if (stateChanged && !_refreshing) { 35603 toggleState = clipped && !prevProgress ? 0 : clipped === 1 ? 1 : prevProgress === 1 ? 2 : 3; 35604 35605 if (isToggle) { 35606 action = !toggled && toggleActions[toggleState + 1] !== "none" && toggleActions[toggleState + 1] || toggleActions[toggleState]; 35607 isTakingAction = animation && (action === "complete" || action === "reset" || action in animation); 35608 } 35609 } 35610 35611 preventOverlaps && toggled && (isTakingAction || scrub || !animation) && (_isFunction(preventOverlaps) ? preventOverlaps(self) : self.getTrailing(preventOverlaps).forEach(function (t) { 35612 return t.endAnimation(); 35613 })); 35614 35615 if (!isToggle) { 35616 if (scrubTween && !_refreshing && !_startup) { 35617 scrubTween.vars.totalProgress = clipped; 35618 scrubTween.invalidate().restart(); 35619 } else if (animation) { 35620 animation.totalProgress(clipped, !!_refreshing); 35621 } 35622 } 35623 35624 if (pin) { 35625 reset && pinSpacing && (spacer.style[pinSpacing + direction.os2] = spacingStart); 35626 35627 if (!useFixedPosition) { 35628 pinSetter(pinStart + pinChange * clipped); 35629 } else if (stateChanged) { 35630 isAtMax = !reset && clipped > prevProgress && end + 1 > scroll && scroll + 1 >= _maxScroll(scroller, direction); 35631 35632 if (pinReparent) { 35633 if (!reset && (isActive || isAtMax)) { 35634 var bounds = _getBounds(pin, true), 35635 _offset = scroll - start; 35636 35637 _reparent(pin, _body, bounds.top + (direction === _vertical ? _offset : 0) + _px, bounds.left + (direction === _vertical ? 0 : _offset) + _px); 35638 } else { 35639 _reparent(pin, spacer); 35640 } 35641 } 35642 35643 _setState(isActive || isAtMax ? pinActiveState : pinState); 35644 35645 pinChange !== change && clipped < 1 && isActive || pinSetter(pinStart + (clipped === 1 && !isAtMax ? pinChange : 0)); 35646 } 35647 } 35648 35649 snap && !tweenTo.tween && !_refreshing && !_startup && snapDelayedCall.restart(true); 35650 toggleClass && (toggled || once && clipped && (clipped < 1 || !_limitCallbacks)) && _toArray(toggleClass.targets).forEach(function (el) { 35651 return el.classList[isActive || once ? "add" : "remove"](toggleClass.className); 35652 }); 35653 onUpdate && !isToggle && !reset && onUpdate(self); 35654 35655 if (stateChanged && !_refreshing) { 35656 if (isToggle) { 35657 if (isTakingAction) { 35658 if (action === "complete") { 35659 animation.pause().totalProgress(1); 35660 } else if (action === "reset") { 35661 animation.restart(true).pause(); 35662 } else if (action === "restart") { 35663 animation.restart(true); 35664 } else { 35665 animation[action](); 35666 } 35667 } 35668 35669 onUpdate && onUpdate(self); 35670 } 35671 35672 if (toggled || !_limitCallbacks) { 35673 onToggle && toggled && _callback(self, onToggle); 35674 callbacks[toggleState] && _callback(self, callbacks[toggleState]); 35675 once && (clipped === 1 ? self.kill(false, 1) : callbacks[toggleState] = 0); 35676 35677 if (!toggled) { 35678 toggleState = clipped === 1 ? 1 : 3; 35679 callbacks[toggleState] && _callback(self, callbacks[toggleState]); 35680 } 35681 } 35682 35683 if (fastScrollEnd && !isActive && Math.abs(self.getVelocity()) > (_isNumber(fastScrollEnd) ? fastScrollEnd : 2500)) { 35684 _endAnimation(self.callbackAnimation); 35685 35686 scrubTween ? scrubTween.progress(1) : _endAnimation(animation, !clipped, 1); 35687 } 35688 } else if (isToggle && onUpdate && !_refreshing) { 35689 onUpdate(self); 35690 } 35691 } 35692 35693 if (markerEndSetter) { 35694 var n = containerAnimation ? scroll / containerAnimation.duration() * (containerAnimation._caScrollDist || 0) : scroll; 35695 markerStartSetter(n + (markerStartTrigger._isFlipped ? 1 : 0)); 35696 markerEndSetter(n); 35697 } 35698 35699 caMarkerSetter && caMarkerSetter(-scroll / containerAnimation.duration() * (containerAnimation._caScrollDist || 0)); 35700 }; 35701 35702 self.enable = function (reset, refresh) { 35703 if (!self.enabled) { 35704 self.enabled = true; 35705 35706 _addListener(scroller, "resize", _onResize); 35707 35708 _addListener(scroller, "scroll", _onScroll); 35709 35710 onRefreshInit && _addListener(ScrollTrigger, "refreshInit", onRefreshInit); 35711 35712 if (reset !== false) { 35713 self.progress = prevProgress = 0; 35714 scroll1 = scroll2 = lastSnap = scrollFunc(); 35715 } 35716 35717 refresh !== false && self.refresh(); 35718 } 35719 }; 35720 35721 self.getTween = function (snap) { 35722 return snap && tweenTo ? tweenTo.tween : scrubTween; 35723 }; 35724 35725 self.disable = function (reset, allowAnimation) { 35726 if (self.enabled) { 35727 reset !== false && self.revert(); 35728 self.enabled = self.isActive = false; 35729 allowAnimation || scrubTween && scrubTween.pause(); 35730 prevScroll = 0; 35731 pinCache && (pinCache.uncache = 1); 35732 onRefreshInit && _removeListener(ScrollTrigger, "refreshInit", onRefreshInit); 35733 35734 if (snapDelayedCall) { 35735 snapDelayedCall.pause(); 35736 tweenTo.tween && tweenTo.tween.kill() && (tweenTo.tween = 0); 35737 } 35738 35739 if (!isViewport) { 35740 var i = _triggers.length; 35741 35742 while (i--) { 35743 if (_triggers[i].scroller === scroller && _triggers[i] !== self) { 35744 return; 35745 } 35746 } 35747 35748 _removeListener(scroller, "resize", _onResize); 35749 35750 _removeListener(scroller, "scroll", _onScroll); 35751 } 35752 } 35753 }; 35754 35755 self.kill = function (revert, allowAnimation) { 35756 self.disable(revert, allowAnimation); 35757 scrubTween && scrubTween.kill(); 35758 id && delete _ids[id]; 35759 35760 var i = _triggers.indexOf(self); 35761 35762 _triggers.splice(i, 1); 35763 35764 i === _i && _direction > 0 && _i--; 35765 i = 0; 35766 35767 _triggers.forEach(function (t) { 35768 return t.scroller === self.scroller && (i = 1); 35769 }); 35770 35771 i || (self.scroll.rec = 0); 35772 35773 if (animation) { 35774 animation.scrollTrigger = null; 35775 revert && animation.render(-1); 35776 allowAnimation || animation.kill(); 35777 } 35778 35779 markerStart && [markerStart, markerEnd, markerStartTrigger, markerEndTrigger].forEach(function (m) { 35780 return m.parentNode && m.parentNode.removeChild(m); 35781 }); 35782 35783 if (pin) { 35784 pinCache && (pinCache.uncache = 1); 35785 i = 0; 35786
35787 _triggers.forEach(function (t) { 35788 return t.pin === pin && i++; 35789 }); 35790 35791 i || (pinCache.spacer = 0); 35792 } 35793 }; 35794 35795 self.enable(false, false); 35796 !animation || !animation.add || change ? self.refresh() : gsap.delayedCall(0.01, function () { 35797 return start || end || self.refresh(); 35798 }) && (change = 0.01) && (start = end = 0); 35799 }; 35800 35801 ScrollTrigger.register = function register(core) { 35802 if (!_coreInitted) { 35803 gsap = core || _getGSAP(); 35804 35805 if (_windowExists() && window.document) { 35806 _win = window; 35807 _doc = document; 35808 _docEl = _doc.documentElement; 35809 _body = _doc.body; 35810 } 35811 35812 if (gsap) { 35813 _toArray = gsap.utils.toArray; 35814 _clamp = gsap.utils.clamp; 35815 _suppressOverwrites = gsap.core.suppressOverwrites || _passThrough; 35816 gsap.core.globals("ScrollTrigger", ScrollTrigger); 35817 35818 if (_body) { 35819 _raf = _win.requestAnimationFrame || function (f) { 35820 return setTimeout(f, 16); 35821 }; 35822 35823 _addListener(_win, "wheel", _onScroll); 35824 35825 _root = [_win, _doc, _docEl, _body]; 35826 35827 _addListener(_doc, "scroll", _onScroll); 35828 35829 var bodyStyle = _body.style, 35830 border = bodyStyle.borderTopStyle, 35831 bounds; 35832 bodyStyle.borderTopStyle = "solid"; 35833 bounds = _getBounds(_body); 35834 _vertical.m = Math.round(bounds.top + _vertical.sc()) || 0; 35835 _horizontal.m = Math.round(bounds.left + _horizontal.sc()) || 0; 35836 border ? bodyStyle.borderTopStyle = border : bodyStyle.removeProperty("border-top-style"); 35837 _syncInterval = setInterval(_sync, 200); 35838 gsap.delayedCall(0.5, function () { 35839 return _startup = 0; 35840 }); 35841 35842 _addListener(_doc, "touchcancel", _passThrough); 35843 35844 _addListener(_body, "touchstart", _passThrough); 35845 35846 _multiListener(_addListener, _doc, "pointerdown,touchstart,mousedown", function () { 35847 return _pointerIsDown = 1; 35848 }); 35849 35850 _multiListener(_addListener, _doc, "pointerup,touchend,mouseup", function () { 35851 return _pointerIsDown = 0; 35852 }); 35853 35854 _transformProp = gsap.utils.checkPrefix("transform"); 35855 35856 _stateProps.push(_transformProp); 35857 35858 _coreInitted = _getTime(); 35859 _resizeDelay = gsap.delayedCall(0.2, _refreshAll).pause(); 35860 _autoRefresh = [_doc, "visibilitychange", function () { 35861 var w = _win.innerWidth, 35862 h = _win.innerHeight; 35863 35864 if (_doc.hidden) { 35865 _prevWidth = w; 35866 _prevHeight = h; 35867 } else if (_prevWidth !== w || _prevHeight !== h) { 35868 _onResize(); 35869 } 35870 }, _doc, "DOMContentLoaded", _refreshAll, _win, "load", function () { 35871 return _lastScrollTime || _refreshAll(); 35872 }, _win, "resize", _onResize]; 35873 35874 _iterateAutoRefresh(_addListener); 35875 } 35876 } 35877 } 35878 35879 return _coreInitted; 35880 }; 35881 35882 ScrollTrigger.defaults = function defaults(config) { 35883 for (var p in config) { 35884 _defaults[p] = config[p]; 35885 } 35886 }; 35887 35888 ScrollTrigger.kill = function kill() { 35889 _enabled = 0; 35890 35891 _triggers.slice(0).forEach(function (trigger) { 35892 return trigger.kill(1); 35893 }); 35894 }; 35895 35896 ScrollTrigger.config = function config(vars) { 35897 "limitCallbacks" in vars && (_limitCallbacks = !!vars.limitCallbacks); 35898 var ms = vars.syncInterval; 35899 ms && clearInterval(_syncInterval) || (_syncInterval = ms) && setInterval(_sync, ms); 35900 35901 if ("autoRefreshEvents" in vars) { 35902 _iterateAutoRefresh(_removeListener) || _iterateAutoRefresh(_addListener, vars.autoRefreshEvents || "none"); 35903 _ignoreResize = (vars.autoRefreshEvents + "").indexOf("resize") === -1; 35904 } 35905 }; 35906 35907 ScrollTrigger.scrollerProxy = function scrollerProxy(target, vars) { 35908 var t = _getTarget(target), 35909 i = _scrollers.indexOf(t), 35910 isViewport = _isViewport(t); 35911 35912 if (~i) { 35913 _scrollers.splice(i, isViewport ? 6 : 2); 35914 } 35915 35916 isViewport ? _proxies.unshift(_win, vars, _body, vars, _docEl, vars) : _proxies.unshift(t, vars); 35917 }; 35918 35919 ScrollTrigger.matchMedia = function matchMedia(vars) { 35920 var mq, p, i, func, result; 35921 35922 for (p in vars) { 35923 i = _media.indexOf(p); 35924 func = vars[p]; 35925 _creatingMedia = p; 35926 35927 if (p === "all") { 35928 func(); 35929 } else { 35930 mq = _win.matchMedia(p); 35931 35932 if (mq) { 35933 mq.matches && (result = func()); 35934 35935 if (~i) { 35936 _media[i + 1] = _combineFunc(_media[i + 1], func); 35937 _media[i + 2] = _combineFunc(_media[i + 2], result); 35938 } else { 35939 i = _media.length; 35940 35941 _media.push(p, func, result); 35942 35943 mq.addListener ? mq.addListener(_onMediaChange) : mq.addEventListener("change", _onMediaChange); 35944 } 35945 35946 _media[i + 3] = mq.matches; 35947 } 35948 } 35949 35950 _creatingMedia = 0; 35951 } 35952 35953 return _media; 35954 }; 35955 35956 ScrollTrigger.clearMatchMedia = function clearMatchMedia(query) { 35957 query || (_media.length = 0); 35958 query = _media.indexOf(query); 35959 query >= 0 && _media.splice(query, 4); 35960 }; 35961 35962 ScrollTrigger.isInViewport = function isInViewport(element, ratio, horizontal) { 35963 var bounds = (_isString(element) ? _getTarget(element) : element).getBoundingClientRect(), 35964 offset = bounds[horizontal ? _width : _height] * ratio || 0; 35965 return horizontal ? bounds.right - offset > 0 && bounds.left + offset < _win.innerWidth : bounds.bottom - offset > 0 && bounds.top + offset < _win.innerHeight; 35966 }; 35967 35968 ScrollTrigger.positionInViewport = function positionInViewport(element, referencePoint, horizontal) { 35969 _isString(element) && (element = _getTarget(element)); 35970 var bounds = element.getBoundingClientRect(), 35971 size = bounds[horizontal ? _width : _height], 35972 offset = referencePoint == null ? size / 2 : referencePoint in _keywords ? _keywords[referencePoint] * size : ~referencePoint.indexOf("%") ? parseFloat(referencePoint) * size / 100 : parseFloat(referencePoint) || 0; 35973 return horizontal ? (bounds.left + offset) / _win.innerWidth : (bounds.top + offset) / _win.innerHeight; 35974 }; 35975 35976 return ScrollTrigger; 35977 }(); 35978 ScrollTrigger.version = "3.8.0"; 35979 35980 ScrollTrigger.saveStyles = function (targets) {
35981 return targets ? _toArray(targets).forEach(function (target) { 35982 if (target && target.style) { 35983 var i = _savedStyles.indexOf(target); 35984 35985 i >= 0 && _savedStyles.splice(i, 5); 35986 35987 _savedStyles.push(target, target.style.cssText, target.getBBox && target.getAttribute("transform"), gsap.core.getCache(target), _creatingMedia); 35988 } 35989 }) : _savedStyles; 35990 }; 35991 35992 ScrollTrigger.revert = function (soft, media) { 35993 return _revertAll(!soft, media); 35994 }; 35995 35996 ScrollTrigger.create = function (vars, animation) { 35997 return new ScrollTrigger(vars, animation); 35998 }; 35999 36000 ScrollTrigger.refresh = function (safe) { 36001 return safe ? _onResize() : (_coreInitted || ScrollTrigger.register()) && _refreshAll(true); 36002 }; 36003 36004 ScrollTrigger.update = _updateAll; 36005 ScrollTrigger.clearScrollMemory = _clearScrollMemory; 36006 36007 ScrollTrigger.maxScroll = function (element, horizontal) { 36008 return _maxScroll(element, horizontal ? _horizontal : _vertical); 36009 }; 36010 36011 ScrollTrigger.getScrollFunc = function (element, horizontal) { 36012 return _getScrollFunc(_getTarget(element), horizontal ? _horizontal : _vertical); 36013 }; 36014 36015 ScrollTrigger.getById = function (id) { 36016 return _ids[id]; 36017 }; 36018 36019 ScrollTrigger.getAll = function () { 36020 return _triggers.slice(0); 36021 }; 36022 36023 ScrollTrigger.isScrolling = function () { 36024 return !!_lastScrollTime; 36025 }; 36026 36027 ScrollTrigger.snapDirectional = _snapDirectional; 36028 36029 ScrollTrigger.addEventListener = function (type, callback) { 36030 var a = _listeners[type] || (_listeners[type] = []); 36031 ~a.indexOf(callback) || a.push(callback); 36032 }; 36033 36034 ScrollTrigger.removeEventListener = function (type, callback) { 36035 var a = _listeners[type], 36036 i = a && a.indexOf(callback); 36037 i >= 0 && a.splice(i, 1); 36038 }; 36039 36040 ScrollTrigger.batch = function (targets, vars) { 36041 var result = [], 36042 varsCopy = {}, 36043 interval = vars.interval || 0.016, 36044 batchMax = vars.batchMax || 1e9, 36045 proxyCallback = function proxyCallback(type, callback) { 36046 var elements = [], 36047 triggers = [], 36048 delay = gsap.delayedCall(interval, function () { 36049 callback(elements, triggers); 36050 elements = []; 36051 triggers = []; 36052 }).pause(); 36053 return function (self) { 36054 elements.length || delay.restart(true); 36055 elements.push(self.trigger); 36056 triggers.push(self); 36057 batchMax <= elements.length && delay.progress(1); 36058 }; 36059 }, 36060 p; 36061 36062 for (p in vars) { 36063 varsCopy[p] = p.substr(0, 2) === "on" && _isFunction(vars[p]) && p !== "onRefreshInit" ? proxyCallback(p, vars[p]) : vars[p]; 36064 } 36065 36066 if (_isFunction(batchMax)) { 36067 batchMax = batchMax(); 36068 36069 _addListener(ScrollTrigger, "refresh", function () { 36070 return batchMax = vars.batchMax(); 36071 }); 36072 } 36073 36074 _toArray(targets).forEach(function (target) { 36075 var config = {}; 36076 36077 for (p in varsCopy) { 36078 config[p] = varsCopy[p]; 36079 } 36080 36081 config.trigger = target; 36082 result.push(ScrollTrigger.create(config)); 36083 }); 36084 36085 return result; 36086 }; 36087 36088 ScrollTrigger.sort = function (func) { 36089 return _triggers.sort(func || function (a, b) { 36090 return (a.vars.refreshPriority || 0) * -1e6 + a.start - (b.start + (b.vars.refreshPriority || 0) * -1e6); 36091 }); 36092 }; 36093 36094 _getGSAP() && gsap.registerPlugin(ScrollTrigger); 36095 36096 exports.ScrollTrigger = ScrollTrigger; 36097 exports.default = ScrollTrigger; 36098 36099 Object.defineProperty(exports, '__esModule', { value: true }); 36100 36101}))); 36102 36103/* ======================================================================== 36104 * Bootstrap: collapse.js v3.1.1 36105 * http://getbootstrap.com/javascript/#collapse 36106 * ======================================================================== 36107 * Copyright 2011-2014 Twitter, Inc. 36108 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 36109 * ======================================================================== */ 36110 36111 36112+function ($) { 36113 'use strict'; 36114 36115 // COLLAPSE PUBLIC CLASS DEFINITION 36116 // ================================ 36117 36118 var Collapse = function (element, options) { 36119 this.$element = $(element) 36120 this.options = $.extend({}, Collapse.DEFAULTS, options) 36121 this.transitioning = null 36122 36123 if (this.options.parent) this.$parent = $(this.options.parent) 36124 if (this.options.toggle) this.toggle() 36125 } 36126 36127 Collapse.DEFAULTS = { 36128 toggle: true 36129 } 36130 36131 Collapse.prototype.dimension = function () { 36132 var hasWidth = this.$element.hasClass('width') 36133 return hasWidth ? 'width' : 'height' 36134 } 36135 36136 Collapse.prototype.show = function () { 36137 if (this.transitioning || this.$element.hasClass('in')) return 36138 36139 var startEvent = $.Event('show.bs.collapse') 36140 this.$element.trigger(startEvent) 36141 if (startEvent.isDefaultPrevented()) return 36142 36143 var actives = this.$parent && this.$parent.find('> .panel > .in') 36144 36145 if (actives && actives.length) { 36146 var hasData = actives.data('bs.collapse') 36147 if (hasData && hasData.transitioning) return 36148 //START UNCODE EDIT 36149 var parentNoToggle = this.$parent.data('no-toggle') 36150 if (!parentNoToggle) { 36151 actives.collapse('hide') 36152 } 36153 //END UNCODE EDIT 36154 hasData || actives.data('bs.collapse', null) 36155 } 36156 36157 var dimension = this.dimension() 36158 36159 this.$element 36160 .removeClass('collapse') 36161 .addClass('collapsing')[dimension](0) 36162 36163 this.transitioning = 1 36164 36165 var complete = function (e) { 36166 if (e && e.target != this.$element[0]) return 36167 this.$element 36168 .removeClass('collapsing') 36169 .addClass('collapse in')[dimension]('auto') 36170 this.transitioning = 0 36171 this.$element.trigger('shown.bs.collapse') 36172 } 36173 36174 if (!$.support.transition) return complete.call(this) 36175 36176 var scrollSize = $.camelCase(['scroll', dimension].join('-')) 36177 36178 this.$element 36179 .one($.support.transition.end, $.proxy(complete, this)) 36180 .emulateTransitionEnd(350)[dimension](this.$element[0][scrollSize]) 36181 } 36182 36183 Collapse.prototype.hide = function () { 36184 if (this.transitioning || !this.$element.hasClass('in')) return 36185 36186 var startEvent = $.Event('hide.bs.collapse') 36187 this.$element.trigger(startEvent) 36188 if (startEvent.isDefaultPrevented()) return 36189 36190 var dimension = this.dimension() 36191 36192 this.$element[dimension](this.$element[dimension]())[0].offsetHeight 36193 36194 this.$element 36195 .addClass('collapsing') 36196 .removeClass('collapse') 36197 .removeClass('in') 36198 36199 this.transitioning = 1 36200 36201 var complete = function (e) { 36202 if (e && e.target != this.$element[0]) return 36203 this.transitioning = 0 36204 this.$element 36205 .trigger('hidden.bs.collapse') 36206 .removeClass('collapsing') 36207 .addClass('collapse') 36208 } 36209 36210 if (!$.support.transition) return complete.call(this) 36211 36212 this.$element 36213 [dimension](0) 36214 .one($.support.transition.end, $.proxy(complete, this)) 36215 .emulateTransitionEnd(350) 36216 } 36217 36218 Collapse.prototype.toggle = function () { 36219 this[this.$element.hasClass('in') ? 'hide' : 'show']() 36220 } 36221 36222 36223 // COLLAPSE PLUGIN DEFINITION 36224 // ========================== 36225 36226 var old = $.fn.collapse 36227 36228 $.fn.collapse = function (option) { 36229 return this.each(function () { 36230 var $this = $(this) 36231 var data = $this.data('bs.collapse') 36232 var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option) 36233 36234 if (!data && options.toggle && option == 'show') option = !option 36235 if (!data) $this.data('bs.collapse', (data = new Collapse(this, options))) 36236 if (typeof option == 'string') data[option]() 36237 }) 36238 } 36239 36240 $.fn.collapse.Constructor = Collapse 36241 36242 36243 // COLLAPSE NO CONFLICT 36244 // ==================== 36245 36246 $.fn.collapse.noConflict = function () { 36247 $.fn.collapse = old 36248 return this 36249 } 36250 36251 36252 // COLLAPSE DATA-API 36253 // ================= 36254 36255 $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) { 36256 var $this = $(this), href 36257 var target = $this.attr('data-target') 36258 || e.preventDefault() 36259 || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7 36260 //Edited by Uncode to replace ID in panel [START] 36261 var _target = href.replace(/^#/, ""); 36262 if ( $('[data-id="' + _target + '"]').length ) { 36263 var $target = $('[data-id="' + _target + '"]') 36264 } else { 36265 var $target = $(target) 36266 } 36267 //Edited by Uncode to replace ID in panel [END] 36268 var data = $target.data('bs.collapse') 36269 var option = data ? 'toggle' : $this.data() 36270 var parent = $this.attr('data-parent') 36271 var $parent = parent && $(parent) 36272 36273 if (!data || !data.transitioning) { 36274 if ($parent) $parent.find('[data-toggle="collapse"][data-parent="' + parent + '"]').not($this).addClass('collapsed') 36275 $this[$target.hasClass('in') ? 'addClass' : 'removeClass']('collapsed') 36276 } 36277 36278 $target.collapse(option) 36279 }) 36280 36281}(jQuery); 36282 36283/* ======================================================================== 36284 * Bootstrap: tab.js v3.1.1 36285 * http://getbootstrap.com/javascript/#tabs 36286 * ======================================================================== 36287 * Copyright 2011-2014 Twitter, Inc. 36288 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 36289 * ======================================================================== */ 36290 36291 36292+function ($) { 36293 'use strict'; 36294 36295 // TAB CLASS DEFINITION 36296 // ==================== 36297 36298 var Tab = function (element) { 36299 this.element = $(element) 36300 } 36301 36302 Tab.prototype.show = function () { 36303 var $this = this.element 36304 var $ul = $this.closest('ul:not(.dropdown-menu)') 36305 var selector = $this.data('target') 36306 36307 if (!selector) { 36308 selector = $this.attr('href') 36309 selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7 36310 } 36311 36312 if ($this.parent('li').hasClass('active')) return 36313 36314 var previous = $ul.find('.active:last a')[0] 36315 var e = $.Event('show.bs.tab', { 36316 relatedTarget: previous 36317 }) 36318 36319 $this.trigger(e) 36320 36321 if (e.isDefaultPrevented()) return 36322 36323 //Edited by Uncode to replace ID in panel [START] 36324 var _target = selector.replace(/^#/, ""); 36325 if ( $('[data-id="' + _target + '"]').length ) 36326 var $target = $('[data-id="' + _target + '"]') 36327 else 36328 var $target = $(selector) 36329 //Edited by Uncode to replace ID in panel [END] 36330 36331 this.activate($this.parent('li'), $ul) 36332 this.activate($target, $target.parent(), function () { 36333 $this.trigger({ 36334 type: 'shown.bs.tab', 36335 relatedTarget: previous 36336 }) 36337 }) 36338 } 36339 36340 Tab.prototype.activate = function (element, container, callback) { 36341 var $active = container.find('> .active').add(container.find('> .active > .active')) 36342 var transition = callback 36343 && $.support.transition 36344 && $active.hasClass('fade') 36345 36346 function next() { 36347 $active 36348 .removeClass('active') 36349 .find('> .dropdown-menu > .active') 36350 .removeClass('active') 36351 36352 $active 36353 .find('.tab-excerpt').slideUp(); 36354 36355 element.addClass('active') 36356 $('.tab-excerpt', element).slideDown(); 36357 36358 //if (transition) { 36359 element[0].offsetWidth // reflow for transition 36360 element.add($active).addClass('in') 36361 /*} else { 36362 element.removeClass('fade') 36363 }*/ 36364 36365 if (element.parent('.dropdown-menu')) { 36366 element.closest('li.dropdown').addClass('active') 36367 } 36368 36369 callback && callback() 36370 } 36371 36372 transition ? 36373 $active 36374 .one($.support.transition.end, next) 36375 .emulateTransitionEnd(150) : 36376 next() 36377 36378 $active.removeClass('in') 36379 } 36380 36381 36382 // TAB PLUGIN DEFINITION 36383 // ===================== 36384 36385 var old = $.fn.tab 36386 36387 $.fn.tab = function ( option ) { 36388 return this.each(function () { 36389 var $this = $(this) 36390 var data = $this.data('bs.tab') 36391 36392 if (!data) $this.data('bs.tab', (data = new Tab(this))) 36393 if (typeof option == 'string') data[option]() 36394 }) 36395 } 36396 36397 $.fn.tab.Constructor = Tab 36398 36399 36400 // TAB NO CONFLICT 36401 // =============== 36402 36403 $.fn.tab.noConflict = function () { 36404 $.fn.tab = old 36405 return this 36406 } 36407 36408 36409 // TAB DATA-API 36410 // ============ 36411 36412 $(document).on('click.bs.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) { 36413 e.preventDefault() 36414 $(this).tab('show') 36415 }) 36416 36417}(jQuery); 36418 36419/* ======================================================================== 36420 * Bootstrap: tooltip.js v3.1.1 36421 * http://getbootstrap.com/javascript/#tooltip 36422 * Inspired by the original jQuery.tipsy by Jason Frame 36423 * ======================================================================== 36424 * Copyright 2011-2014 Twitter, Inc. 36425 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 36426 * ======================================================================== */ 36427 36428 36429+function ($) { 36430 'use strict'; 36431 36432 // TOOLTIP PUBLIC CLASS DEFINITION 36433 // =============================== 36434 36435 var Tooltip = function (element, options) { 36436 this.type = 36437 this.options = 36438 this.enabled = 36439 this.timeout = 36440 this.hoverState = 36441 this.$element = null 36442 36443 this.init('tooltip', element, options) 36444 } 36445 36446 Tooltip.DEFAULTS = { 36447 animation: true, 36448 placement: 'top', 36449 selector: false, 36450 template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>', 36451 trigger: 'hover focus', 36452 title: '', 36453 delay: 0, 36454 html: false, 36455 container: false, 36456 viewport: { 36457 selector: 'body', 36458 padding: 0 36459 } 36460 } 36461 36462 Tooltip.prototype.init = function (type, element, options) { 36463 this.enabled = true 36464 this.type = type 36465 this.$element = $(element) 36466 this.options = this.getOptions(options) 36467 this.$viewport = this.options.viewport && $(this.options.viewport.selector || this.options.viewport) 36468 36469 var triggers = this.options.trigger.split(' ') 36470 36471 for (var i = triggers.length; i--;) { 36472 var trigger = triggers[i] 36473 36474 if (trigger == 'click') { 36475 this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this)) 36476 } else if (trigger != 'manual') { 36477 var eventIn = trigger == 'hover' ? 'mouseenter' : 'focusin' 36478 var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout' 36479 36480 this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this)) 36481 this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this)) 36482 } 36483 } 36484 36485 this.options.selector ? 36486 (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) : 36487 this.fixTitle() 36488 } 36489 36490 Tooltip.prototype.getDefaults = function () { 36491 return Tooltip.DEFAULTS 36492 } 36493 36494 Tooltip.prototype.getOptions = function (options) { 36495 options = $.extend({}, this.getDefaults(), this.$element.data(), options) 36496 36497 if (options.delay && typeof options.delay == 'number') { 36498 options.delay = { 36499 show: options.delay, 36500 hide: options.delay 36501 } 36502 } 36503 36504 return options 36505 } 36506 36507 Tooltip.prototype.getDelegateOptions = function () { 36508 var options = {} 36509 var defaults = this.getDefaults() 36510 36511 this._options && $.each(this._options, function (key, value) { 36512 if (defaults[key] != value) options[key] = value 36513 }) 36514 36515 return options 36516 } 36517 36518 Tooltip.prototype.enter = function (obj) { 36519 var self = obj instanceof this.constructor ? 36520 obj : $(obj.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type) 36521 36522 clearTimeout(self.timeout) 36523 36524 self.hoverState = 'in' 36525 36526 if (!self.options.delay || !self.options.delay.show) return self.show() 36527 36528 self.timeout = setTimeout(function () { 36529 if (self.hoverState == 'in') self.show() 36530 }, self.options.delay.show) 36531 } 36532 36533 Tooltip.prototype.leave = function (obj) { 36534 var self = obj instanceof this.constructor ? 36535 obj : $(obj.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type) 36536 36537 clearTimeout(self.timeout) 36538 36539 self.hoverState = 'out' 36540 36541 if (!self.options.delay || !self.options.delay.hide) return self.hide() 36542 36543 self.timeout = setTimeout(function () { 36544 if (self.hoverState == 'out') self.hide() 36545 }, self.options.delay.hide) 36546 } 36547 36548 Tooltip.prototype.show = function () { 36549 var e = $.Event('show.bs.' + this.type) 36550 36551 if (this.hasContent() && this.enabled) { 36552 this.$element.trigger(e) 36553 36554 if (e.isDefaultPrevented()) return 36555 var that = this; 36556 36557 var $tip = this.tip() 36558 36559 this.setContent() 36560 36561 if (this.options.animation) $tip.addClass('fade') 36562 36563 var placement = typeof this.options.placement == 'function' ? 36564 this.options.placement.call(this, $tip[0], this.$element[0]) : 36565 this.options.placement 36566 36567 var autoToken = /\s?auto?\s?/i 36568 var autoPlace = autoToken.test(placement) 36569 if (autoPlace) placement = placement.replace(autoToken, '') || 'top' 36570 36571 $tip 36572 .detach() 36573 .cs
36573s({ top: 0, left: 0, display: 'block' }) 36574 .addClass(placement) 36575 36576 this.options.container ? $tip.appendTo($(document).find(this.options.container)) : $tip.insertAfter(this.$element) 36577 36578 var pos = this.getPosition() 36579 var actualWidth = $tip[0].offsetWidth 36580 var actualHeight = $tip[0].offsetHeight 36581 36582 if (autoPlace) { 36583 var orgPlacement = placement 36584 var $parent = this.$element.parent() 36585 var parentDim = this.getPosition($parent) 36586 36587 placement = placement == 'bottom' && pos.top + pos.height + actualHeight - parentDim.scroll > parentDim.height ? 'top' : 36588 placement == 'top' && pos.top - parentDim.scroll - actualHeight < 0 ? 'bottom' : 36589 placement == 'right' && pos.right + actualWidth > parentDim.width ? 'left' : 36590 placement == 'left' && pos.left - actualWidth < parentDim.left ? 'right' : 36591 placement 36592 36593 $tip 36594 .removeClass(orgPlacement) 36595 .addClass(placement) 36596 } 36597 36598 var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight) 36599 36600 this.applyPlacement(calculatedOffset, placement) 36601 this.hoverState = null 36602 36603 var complete = function() { 36604 that.$element.trigger('shown.bs.' + that.type) 36605 } 36606 36607 $.support.transition && this.$tip.hasClass('fade') ? 36608 $tip 36609 .one($.support.transition.end, complete) 36610 .emulateTransitionEnd(150) : 36611 complete() 36612 } 36613 } 36614 36615 Tooltip.prototype.applyPlacement = function (offset, placement) { 36616 var $tip = this.tip() 36617 var width = $tip[0].offsetWidth 36618 var height = $tip[0].offsetHeight 36619 36620 // manually read margins because getBoundingClientRect includes difference 36621 var marginTop = parseInt($tip.css('margin-top'), 10) 36622 var marginLeft = parseInt($tip.css('margin-left'), 10) 36623 36624 // we must check for NaN for ie 8/9 36625 if (isNaN(marginTop)) marginTop = 0 36626 if (isNaN(marginLeft)) marginLeft = 0 36627 36628 offset.top = offset.top + marginTop 36629 offset.left = offset.left + marginLeft 36630 36631 // $.fn.offset doesn't round pixel values 36632 // so we use setOffset directly with our own function B-0 36633 $.offset.setOffset($tip[0], $.extend({ 36634 using: function (props) { 36635 $tip.css({ 36636 top: Math.round(props.top), 36637 left: Math.round(props.left) 36638 }) 36639 } 36640 }, offset), 0) 36641 36642 $tip.addClass('in') 36643 36644 // check to see if placing tip in new offset caused the tip to resize itself 36645 var actualWidth = $tip[0].offsetWidth 36646 var actualHeight = $tip[0].offsetHeight 36647 36648 if (placement == 'top' && actualHeight != height) { 36649 offset.top = offset.top + height - actualHeight 36650 } 36651 36652 var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight) 36653 36654 if (delta.left) offset.left += delta.left 36655 else offset.top += delta.top 36656 36657 var arrowDelta = delta.left ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight 36658 var arrowPosition = delta.left ? 'left' : 'top' 36659 var arrowOffsetPosition = delta.left ? 'offsetWidth' : 'offsetHeight' 36660 36661 $tip.offset(offset) 36662 this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], arrowPosition) 36663 } 36664 36665 Tooltip.prototype.replaceArrow = function (delta, dimension, position) { 36666 this.arrow().css(position, delta ? (50 * (1 - delta / dimension) + '%') : '') 36667 } 36668 36669 Tooltip.prototype.setContent = function () { 36670 var $tip = this.tip() 36671 var title = this.getTitle() 36672 36673 $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title) 36674 $tip.removeClass('fade in top bottom left right') 36675 } 36676 36677 Tooltip.prototype.hide = function () { 36678 var that = this 36679 var $tip = this.tip() 36680 var e = $.Event('hide.bs.' + this.type) 36681 36682 function complete() { 36683 if (that.hoverState != 'in') $tip.detach() 36684 that.$element.trigger('hidden.bs.' + that.type) 36685 } 36686 36687 this.$element.trigger(e) 36688 36689 if (e.isDefaultPrevented()) return 36690 36691 $tip.removeClass('in') 36692 36693 $.support.transition && this.$tip.hasClass('fade') ? 36694 $tip 36695 .one($.support.transition.end, complete) 36696 .emulateTransitionEnd(150) : 36697 complete() 36698 36699 this.hoverState = null 36700 36701 return this 36702 } 36703 36704 Tooltip.prototype.fixTitle = function () { 36705 var $e = this.$element 36706 if ($e.attr('title') || typeof($e.attr('data-original-title')) != 'string') { 36707 $e.attr('data-original-title', $e.attr('title') || '').attr('title', '') 36708 } 36709 } 36710 36711 Tooltip.prototype.hasContent = function () { 36712 return this.getTitle() 36713 } 36714 36715 Tooltip.prototype.getPosition = function ($element) { 36716 $element = $element || this.$element 36717 var el = $element[0] 36718 var isBody = el.tagName == 'BODY' 36719 return $.extend({}, (typeof el.getBoundingClientRect == 'function') ? el.getBoundingClientRect() : null, { 36720 scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop(), 36721 width: isBody ? $(window).width() : $element.outerWidth(), 36722 height: isBody ? $(window).height() : $element.outerHeight() 36723 }, isBody ? {top: 0, left: 0} : $element.offset()) 36724 } 36725 36726 Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) { 36727 return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } : 36728 placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } : 36729 placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } : 36730 /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width } 36731 36732 } 36733 36734 Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) { 36735 var delta = { top: 0, left: 0 } 36736 if (!this.$viewport) return delta 36737 36738 var viewportPadding = this.options.viewport && this.options.viewport.padding || 0 36739 var viewportDimensions = this.getPosition(this.$viewport) 36740 36741 if (/right|left/.test(placement)) { 36742 var topEdgeOffset = pos.top - viewportPadding - viewportDimensions.scroll 36743 var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight 36744 if (topEdgeOffset < viewportDimensions.top) { // top overflow 36745 delta.top = viewportDimensions.top - topEdgeOffset 36746 } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow 36747 delta.top = viewportDimensions.top + viewportDimensions.height - bottom
36747EdgeOffset 36748 } 36749 } else { 36750 var leftEdgeOffset = pos.left - viewportPadding 36751 var rightEdgeOffset = pos.left + viewportPadding + actualWidth 36752 if (leftEdgeOffset < viewportDimensions.left) { // left overflow 36753 delta.left = viewportDimensions.left - leftEdgeOffset 36754 } else if (rightEdgeOffset > viewportDimensions.width) { // right overflow 36755 delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset 36756 } 36757 } 36758 36759 return delta 36760 } 36761 36762 Tooltip.prototype.getTitle = function () { 36763 var title 36764 var $e = this.$element 36765 var o = this.options 36766 36767 title = $e.attr('data-original-title') 36768 || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title) 36769 36770 return title 36771 } 36772 36773 Tooltip.prototype.tip = function () { 36774 return this.$tip = this.$tip || $(this.options.template) 36775 } 36776 36777 Tooltip.prototype.arrow = function () { 36778 return this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow') 36779 } 36780 36781 Tooltip.prototype.validate = function () { 36782 if (!this.$element[0].parentNode) { 36783 this.hide() 36784 this.$element = null 36785 this.options = null 36786 } 36787 } 36788 36789 Tooltip.prototype.enable = function () { 36790 this.enabled = true 36791 } 36792 36793 Tooltip.prototype.disable = function () { 36794 this.enabled = false 36795 } 36796 36797 Tooltip.prototype.toggleEnabled = function () { 36798 this.enabled = !this.enabled 36799 } 36800 36801 Tooltip.prototype.toggle = function (e) { 36802 var self = e ? $(e.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type) : this 36803 self.tip().hasClass('in') ? self.leave(self) : self.enter(self) 36804 } 36805 36806 Tooltip.prototype.destroy = function () { 36807 clearTimeout(this.timeout) 36808 this.hide().$element.off('.' + this.type).removeData('bs.' + this.type) 36809 } 36810 36811 36812 // TOOLTIP PLUGIN DEFINITION 36813 // ========================= 36814 36815 var old = $.fn.tooltip 36816 36817 $.fn.tooltip = function (option) { 36818 return this.each(function () { 36819 var $this = $(this) 36820 var data = $this.data('bs.tooltip') 36821 var options = typeof option == 'object' && option 36822 36823 if (!data && option == 'destroy') return 36824 if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options))) 36825 if (typeof option == 'string') data[option]() 36826 }) 36827 } 36828 36829 $.fn.tooltip.Constructor = Tooltip 36830 36831 36832 // TOOLTIP NO CONFLICT 36833 // =================== 36834 36835 $.fn.tooltip.noConflict = function () { 36836 $.fn.tooltip = old 36837 return this 36838 } 36839 36840}(jQuery); 36841 36842/* ======================================================================== 36843 * Bootstrap: transition.js v3.1.1 36844 * http://getbootstrap.com/javascript/#transitions 36845 * ======================================================================== 36846 * Copyright 2011-2014 Twitter, Inc. 36847 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 36848 * ======================================================================== */ 36849 36850 36851+function ($) { 36852 'use strict'; 36853 36854 // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/) 36855 // ============================================================ 36856 36857 function transitionEnd() { 36858 var el = document.createElement('bootstrap') 36859 36860 var transEndEventNames = { 36861 WebkitTransition : 'webkitTransitionEnd', 36862 MozTransition : 'transitionend', 36863 OTransition : 'oTransitionEnd otransitionend', 36864 transition : 'transitionend' 36865 } 36866 36867 for (var name in transEndEventNames) { 36868 if (el.style[name] !== undefined) { 36869 return { end: transEndEventNames[name] } 36870 } 36871 } 36872 36873 return false // explicit for ie8 ( ._.) 36874 } 36875 36876 // http://blog.alexmaccaw.com/css-transitions 36877 $.fn.emulateTransitionEnd = function (duration) { 36878 var called = false, $el = this 36879 $(this).one($.support.transition.end, function () { called = true }) 36880 var callback = function () { if (!called) $($el).trigger($.support.transition.end) } 36881 setTimeout(callback, duration) 36882 return this 36883 } 36884 36885 $(function () { 36886 $.support.transition = transitionEnd() 36887 }) 36888 36889}(jQuery); 36890 36891 36892// ------------------------------------------ 36893// Rellax.js 36894// Buttery smooth parallax library 36895// Copyright (c) 2016 Moe Amaya (@moeamaya) 36896// MIT license 36897// 36898// Thanks to Paraxify.js and Jaime Cabllero 36899// for parallax concepts 36900// ------------------------------------------ 36901 36902(function (root, factory) { 36903 if (typeof define === 'function' && define.amd) { 36904 // AMD. Register as an anonymous module. 36905 define([], factory); 36906 } else if (typeof module === 'object' && module.exports) { 36907 // Node. Does not work with strict CommonJS, but 36908 // only CommonJS-like environments that support module.exports, 36909 // like Node. 36910 module.exports = factory(); 36911 } else { 36912 // Browser globals (root is window) 36913 root.Rellax = factory(); 36914 } 36915}(typeof window !== "undefined" ? window : global, function () { 36916 var Rellax = function(el, options){ 36917 "use strict"; 36918 36919 var self = Object.create(Rellax.prototype); 36920 36921 var posY = 0; 36922 var screenY = 0; 36923 var posX = 0; 36924 var screenX = 0; 36925 var blocks = []; 36926 var pause = true; 36927 36928 // check what requestAnimationFrame to use, and if 36929 // it's not supported, use the onscroll event 36930 var loop = window.requestAnimationFrame || 36931 window.webkitRequestAnimationFrame || 36932 window.mozRequestAnimationFrame || 36933 window.msRequestAnimationFrame || 36934 window.oRequestAnimationFrame || 36935 function(callback){ return setTimeout(callback, 1000 / 60); }; 36936 36937 // store the id for later use 36938 var loopId = null; 36939 36940 // Test via a getter in the options object to see if the passive property is accessed 36941 var supportsPassive = false;
vendor: 10,724 bytes, lines 36942-37243
36942 try { 36943 var opts = Object.defineProperty({}, 'passive', { 36944 get: function() { 36945 supportsPassive = true; 36946 } 36947 }); 36948 window.addEventListener("testPassive", null, opts); 36949 window.removeEventListener("testPassive", null, opts); 36950 } catch (e) {} 36951 36952 // check what cancelAnimation method to use 36953 var clearLoop = window.cancelAnimationFrame || window.mozCancelAnimationFrame || clearTimeout; 36954 36955 // check which transform property to use 36956 var transformProp = window.transformProp || (function(){ 36957 var testEl = document.createElement('div'); 36958 if (testEl.style.transform === null) { 36959 var vendors = ['Webkit', 'Moz', 'ms']; 36960 for (var vendor in vendors) { 36961 if (testEl.style[ vendors[vendor] + 'Transform' ] !== undefined) { 36962 return vendors[vendor] + 'Transform'; 36963 } 36964 } 36965 } 36966 return 'transform'; 36967 })(); 36968 36969 // Default Settings 36970 self.options = { 36971 speed: -2, 36972 verticalSpeed: null, 36973 horizontalSpeed: null, 36974 breakpoints: [576, 768, 1201], 36975 center: false, 36976 wrapper: null, 36977 relativeToWrapper: false, 36978 round: true, 36979 vertical: true, 36980 horizontal: false, 36981 verticalScrollAxis: "y", 36982 horizontalScrollAxis: "x", 36983 callback: function() {}, 36984 }; 36985 36986 // User defined options (might have more in the future) 36987 if (options){ 36988 Object.keys(options).forEach(function(key){ 36989 self.options[key] = options[key]; 36990 }); 36991 } 36992 36993 function validateCustomBreakpoints () { 36994 if (self.options.breakpoints.length === 3 && Array.isArray(self.options.breakpoints)) { 36995 var isAscending = true; 36996 var isNumerical = true; 36997 var lastVal; 36998 self.options.breakpoints.forEach(function (i) { 36999 if (typeof i !== 'number') isNumerical = false; 37000 if (lastVal !== null) { 37001 if (i < lastVal) isAscending = false; 37002 } 37003 lastVal = i; 37004 }); 37005 if (isAscending && isNumerical) return; 37006 } 37007 // revert defaults if set incorrectly 37008 self.options.breakpoints = [576, 768, 1201]; 37009 console.warn("Rellax: You must pass an array of 3 numbers in ascending order to the breakpoints option. Defaults reverted"); 37010 } 37011 37012 if (options && options.breakpoints) { 37013 validateCustomBreakpoints(); 37014 } 37015 37016 // By default, rellax class 37017 if (!el) { 37018 el = '.rellax'; 37019 } 37020 37021 // check if el is a className or a node 37022 var elements = typeof el === 'string' ? document.querySelectorAll(el) : [el]; 37023 37024 // Now query selector 37025 if (elements.length > 0) { 37026 self.elems = elements; 37027 } 37028 37029 // The elements don't exist 37030 else { 37031 console.warn("Rellax: The elements you're trying to select don't exist."); 37032 return; 37033 } 37034 37035 // Has a wrapper and it exists 37036 if (self.options.wrapper) { 37037 if (!self.options.wrapper.nodeType) { 37038 var wrapper = document.querySelector(self.options.wrapper); 37039 37040 if (wrapper) { 37041 self.options.wrapper = wrapper; 37042 } else { 37043 console.warn("Rellax: The wrapper you're trying to use doesn't exist."); 37044 return; 37045 } 37046 } 37047 } 37048 37049 // set a placeholder for the current breakpoint 37050 var currentBreakpoint; 37051 37052 // helper to determine current breakpoint 37053 var getCurrentBreakpoint = function (w) { 37054 var bp = self.options.breakpoints; 37055 if (w < bp[0]) return 'xs'; 37056 if (w >= bp[0] && w < bp[1]) return 'sm'; 37057 if (w >= bp[1] && w < bp[2]) return 'md'; 37058 return 'lg'; 37059 }; 37060 37061 // Get and cache initial position of all elements 37062 var cacheBlocks = function() { 37063 for (var i = 0; i < self.elems.length; i++){ 37064 var block = createBlock(self.elems[i]); 37065 blocks.push(block); 37066 } 37067 }; 37068 37069 37070 // Let's kick this script off 37071 // Build array for cached element values 37072 var init = function() { 37073 for (var i = 0; i < blocks.length; i++){ 37074 self.elems[i].style.cssText = blocks[i].style; 37075 } 37076 37077 blocks = []; 37078 37079 screenY = window.innerHeight; 37080 screenX = window.innerWidth; 37081 currentBreakpoint = getCurrentBreakpoint(screenX); 37082 37083 setPosition(); 37084 37085 cacheBlocks(); 37086 37087 animate(); 37088 37089 // If paused, unpause and set listener for window resizing events 37090 if (pause) { 37091 window.addEventListener('resize', init); 37092 pause = false; 37093 // Start the loop 37094 update(); 37095 } 37096 }; 37097 37098 // We want to cache the parallax blocks' 37099 // values: base, top, height, speed 37100 // el: is dom object, return: el cache values 37101 var createBlock = function(el) { 37102 var dataPercentage = el.getAttribute( 'data-rellax-percentage' ); 37103 var dataSpeed = el.getAttribute( 'data-rellax-speed' ); 37104 var dataXsSpeed = el.getAttribute( 'data-rellax-xs-speed' ); 37105 var dataMobileSpeed = el.getAttribute( 'data-rellax-mobile-speed' ); 37106 var dataTabletSpeed = el.getAttribute( 'data-rellax-tablet-speed' ); 37107 var dataDesktopSpeed = el.getAttribute( 'data-rellax-desktop-speed' ); 37108 var dataVerticalSpeed = el.getAttribute('data-rellax-vertical-speed'); 37109 var dataHorizontalSpeed = el.getAttribute('data-rellax-horizontal-speed'); 37110 var dataVericalScrollAxis = el.getAttribute('data-rellax-vertical-scroll-axis'); 37111 var dataHorizontalScrollAxis = el.getAttribute('data-rellax-horizontal-scroll-axis'); 37112 var dataZindex = el.getAttribute( 'data-rellax-zindex' ) || 0; 37113 var dataMin = el.getAttribute( 'data-rellax-min' ); 37114 var dataMax = el.getAttribute( 'data-rellax-max' ); 37115 var dataMinX = el.getAttribute('data-rellax-min-x'); 37116 var dataMaxX = el.getAttribute('data-rellax-max-x'); 37117 var dataMinY = el.getAttribute('data-rellax-min-y'); 37118 var dataMaxY = el.getAttribute('data-rellax-max-y'); 37119 var mapBreakpoints; 37120 var breakpoints = true; 37121 37122 if (!dataXsSpeed && !dataMobileSpeed && !dataTabletSpeed && !dataDesktopSpeed) { 37123 breakpoints = false; 37124 } else { 37125 mapBreakpoints = { 37126 'xs': dataXsSpeed, 37127 'sm': dataMobileSpeed, 37128 'md': dataTabletSpeed, 37129 'lg': dataDesktopSpeed 37130 }; 37131 } 37132 37133 // initializing at scrollY = 0 (top of browser), scrollX = 0 (left of browser) 37134 // ensures elements are positioned based on HTML layout. 37135 // 37136 // If the element has the percentage attribute, the posY and posX needs to be 37137 // the current scroll position's value, so that the elements are still positioned based on HTML layout 37138 var wrapperPosY = self.options.wrapper ? self.options.wrapper.scrollTop : (window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop); 37139 // If the option relativeToWrapper is true, use the wrappers offset to top, subtracted from the current page scroll. 37140 if (self.options.relativeToWrapper) { 37141 var scrollPosY = (window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop); 37142 wrapperPosY = scrollPosY - self.options.wrapper.offsetTop; 37143 } 37144 var posY = self.options.vertical ? ( dataPercentage || self.options.center ? wrapperPosY : 0 ) : 0; 37145 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; 37146 37147 var blockTop = posY + el.getBoundingClientRect().top; 37148 var blockHeight = el.clientHeight || el.offsetHeight || el.scrollHeight; 37149 37150 var blockLeft = posX + el.getBoundingClientRect().left; 37151 var blockWidth = el.clientWidth || el.offsetWidth || el.scrollWidth; 37152 37153 // apparently parallax equation everyone uses 37154 var percentageY = dataPercentage ? dataPercentage : (posY - blockTop + screenY) / (blockHeight + screenY); 37155 var percentageX = dataPercentage ? dataPercentage : (posX - blockLeft + screenX) / (blockWidth + screenX); 37156 if(self.options.center){ percentageX = 0.5; percentageY = 0.5; } 37157 37158 // Optional individual block speed as data attr, otherwise global speed 37159 var speed = (breakpoints && mapBreakpoints[currentBreakpoint] !== null) ? Number(mapBreakpoints[currentBreakpoint]) : (dataSpeed ? dataSpeed : self.options.speed); 37160 var verticalSpeed = dataVerticalSpeed ? dataVerticalSpeed : self.options.verticalSpeed; 37161 var horizontalSpeed = dataHorizontalSpeed ? dataHorizontalSpeed : self.options.horizontalSpeed; 37162 37163 // Optional individual block movement axis direction as data attr, otherwise global movement direction 37164 var verticalScrollAxis = dataVericalScrollAxis ? dataVericalScrollAxis : self.options.verticalScrollAxis; 37165 var horizontalScrollAxis = dataHorizontalScrollAxis ? dataHorizontalScrollAxis : self.options.horizontalScrollAxis; 37166 37167 var bases = updatePosition(percentageX, percentageY, speed, verticalSpeed, horizontalSpeed); 37168 37169 // ~~Store non-translate3d transforms~~ 37170 // Store inline styles and extract transforms 37171 var style = el.style.cssText; 37172 var transform = ''; 37173 37174 // Check if there's an inline styled transform 37175 var searchResult = /transform\s*:/i.exec(style); 37176 if (searchResult) { 37177 // Get the index of the transform 37178 var index = searchResult.index; 37179 37180 // Trim the style to the transform point and get the following semi-colon index 37181 var trimmedStyle = style.slice(index); 37182 var delimiter = trimmedStyle.indexOf(';'); 37183 37184 // Remove "transform" string and save the attribute 37185 if (delimiter) { 37186 transform = " " + trimmedStyle.slice(11, delimiter).replace(/\s/g,''); 37187 } else { 37188 transform = " " + trimmedStyle.slice(11).replace(/\s/g,''); 37189 } 37190 } 37191 37192 return { 37193 baseX: bases.x, 37194 baseY: bases.y, 37195 top: blockTop, 37196 left: blockLeft, 37197 height: blockHeight, 37198 width: blockWidth, 37199 speed: speed, 37200 verticalSpeed: verticalSpeed, 37201 horizontalSpeed: horizontalSpeed, 37202 verticalScrollAxis: verticalScrollAxis, 37203 horizontalScrollAxis: horizontalScrollAxis, 37204 style: style, 37205 transform: transform, 37206 zindex: dataZindex, 37207 min: dataMin, 37208 max: dataMax, 37209 minX: dataMinX, 37210 maxX: dataMaxX, 37211 minY: dataMinY, 37212 maxY: dataMaxY 37213 }; 37214 }; 37215 37216 // set scroll position (posY, posX) 37217 // side effect method is not ideal, but okay for now 37218 // returns true if the scroll changed, false if nothing happened 37219 var setPosition = function() { 37220 var oldY = posY; 37221 var oldX = posX; 37222 37223 posY = self.options.wrapper ? self.options.wrapper.scrollTop : (document.documentElement || document.body.parentNode || document.body).scrollTop || window.pageYOffset; 37224 posX = self.options.wrapper ? self.options.wrapper.scrollLeft : (document.documentElement || document.body.parentNode || document.body).scrollLeft || window.pageXOffset; 37225 // If option relativeToWrapper is true, use relative wrapper value instead. 37226 if (self.options.relativeToWrapper) { 37227 var scrollPosY = (document.documentElement || document.body.parentNode || document.body).scrollTop || window.pageYOffset; 37228 posY = scrollPosY - self.options.wrapper.offsetTop; 37229 } 37230 37231 37232 if (oldY != posY && self.options.vertical) { 37233 // scroll changed, return true 37234 return true; 37235 } 37236 37237 if (oldX != posX && self.options.horizontal) { 37238 // scroll changed, return true 37239 return true; 37240 } 37241 37242 // scroll did not change 37243 return false;
37244 }; 37245 37246 // Ahh a pure function, gets new transform value 37247 // based on scrollPosition and speed 37248 // Allow for decimal pixel values 37249 var updatePosition = function(percentageX, percentageY, speed, verticalSpeed, horizontalSpeed) { 37250 var result = {}; 37251 var valueX = ((horizontalSpeed ? horizontalSpeed : speed) * (100 * (1 - percentageX))); 37252 var valueY = ((verticalSpeed ? verticalSpeed : speed) * (100 * (1 - percentageY))); 37253 37254 result.x = self.options.round ? Math.round(valueX) : Math.round(valueX * 100) / 100; 37255 result.y = self.options.round ? Math.round(valueY) : Math.round(valueY * 100) / 100; 37256 37257 return result; 37258 }; 37259 37260 // Remove event listeners and loop again 37261 var deferredUpdate = function() { 37262 window.removeEventListener('resize', deferredUpdate); 37263 window.removeEventListener('orientationchange', deferredUpdate); 37264 (self.options.wrapper ? self.options.wrapper : window).removeEventListener('scroll', deferredUpdate); 37265 (self.options.wrapper ? self.options.wrapper : document).removeEventListener('touchmove', deferredUpdate); 37266 37267 // loop again 37268 loopId = loop(update); 37269 }; 37270 37271 // Loop 37272 var update = function() { 37273 if (setPosition() && pause === false) { 37274 animate(); 37275 37276 // loop again 37277 loopId = loop(update); 37278 } else { 37279 loopId = null; 37280 37281 // Don't animate until we get a position updating event 37282 window.addEventListener('resize', deferredUpdate); 37283 window.addEventListener('orientationchange', deferredUpdate); 37284 (self.options.wrapper ? self.options.wrapper : window).addEventListener('scroll', deferredUpdate, supportsPassive ? { passive: true } : false); 37285 (self.options.wrapper ? self.options.wrapper : document).addEventListener('touchmove', deferredUpdate, supportsPassive ? { passive: true } : false); 37286 } 37287 }; 37288 37289 // Transform3d on parallax element 37290 var animate = function() { 37291 var positions; 37292 for (var i = 0; i < self.elems.length; i++){ 37293 // Determine relevant movement directions 37294 var verticalScrollAxis = blocks[i].verticalScrollAxis.toLowerCase(); 37295 var horizontalScrollAxis = blocks[i].horizontalScrollAxis.toLowerCase(); 37296 var verticalScrollX = verticalScrollAxis.indexOf("x") != -1 ? posY : 0; 37297 var verticalScrollY = verticalScrollAxis.indexOf("y") != -1 ? posY : 0; 37298 var horizontalScrollX = horizontalScrollAxis.indexOf("x") != -1 ? posX : 0; 37299 var horizontalScrollY = horizontalScrollAxis.indexOf("y") != -1 ? posX : 0; 37300 37301 var percentageY = ((verticalScrollY + horizontalScrollY - blocks[i].top + screenY) / (blocks[i].height + screenY)); 37302 var percentageX = ((verticalScrollX + horizontalScrollX - blocks[i].left + screenX) / (blocks[i].width + screenX)); 37303 37304 // Subtracting initialize value, so element stays in same spot as HTML 37305 positions = updatePosition(percentageX, percentageY, blocks[i].speed, blocks[i].verticalSpeed, blocks[i].horizontalSpeed); 37306 var positionY = positions.y - blocks[i].baseY; 37307 var positionX = positions.x - blocks[i].baseX; 37308 37309 // The next two "if" blocks go like this: 37310 // Check if a limit is defined (first "min", then "max"); 37311 // Check if we need to change the Y or the X 37312 // (Currently working only if just one of the axes is enabled) 37313 // Then, check if the new position is inside the allowed limit 37314 // If so, use new position. If not, set position to limit. 37315 37316 // Check if a min limit is defined 37317 if (blocks[i].min !== null) { 37318 if (self.options.vertical && !self.options.horizontal) { 37319 positionY = positionY <= blocks[i].min ? blocks[i].min : positionY; 37320 } 37321 if (self.options.horizontal && !self.options.vertical) { 37322 positionX = positionX <= blocks[i].min ? blocks[i].min : positionX; 37323 } 37324 } 37325 37326 // Check if directional min limits are defined 37327 if (blocks[i].minY != null) { 37328 positionY = positionY <= blocks[i].minY ? blocks[i].minY : positionY; 37329 } 37330 if (blocks[i].minX != null) { 37331 positionX = positionX <= blocks[i].minX ? blocks[i].minX : positionX; 37332 } 37333 37334 // Check if a max limit is defined 37335 if (blocks[i].max !== null) { 37336 if (self.options.vertical && !self.options.horizontal) { 37337 positionY = positionY >= blocks[i].max ? blocks[i].max : positionY; 37338 } 37339 if (self.options.horizontal && !self.options.vertical) { 37340 positionX = positionX >= blocks[i].max ? blocks[i].max : positionX; 37341 } 37342 } 37343 37344 // Check if directional max limits are defined 37345 if (blocks[i].maxY != null) { 37346 positionY = positionY >= blocks[i].maxY ? blocks[i].maxY : positionY; 37347 } 37348 if (blocks[i].maxX != null) { 37349 positionX = positionX >= blocks[i].maxX ? blocks[i].maxX : positionX; 37350 } 37351 37352 var zindex = blocks[i].zindex; 37353 37354 // Move that element 37355 // (Set the new translation and append initial inline transforms.) 37356 var translate = 'translate3d(' + (self.options.horizontal ? positionX : '0') + 'px,' + (self.options.vertical ? positionY : '0') + 'px,' + zindex + 'px) ' + blocks[i].transform; 37357 self.elems[i].style[transformProp] = translate; 37358 } 37359 self.options.callback(positions); 37360 }; 37361 37362 self.destroy = function() { 37363 for (var i = 0; i < self.elems.length; i++){ 37364 self.elems[i].style.cssText = blocks[i].style; 37365 } 37366 37367 // Remove resize event listener if not pause, and pause 37368 if (!pause) { 37369 window.removeEventListener('resize', init); 37370 pause = true; 37371 } 37372 37373 // Clear the animation loop to prevent possible memory leak 37374 clearLoop(loopId); 37375 loopId = null; 37376 }; 37377 37378 // Init 37379 init(); 37380 37381 // Allow to recalculate the initial values whenever we want 37382 self.refresh = init; 37383 37384 return self; 37385 }; 37386 return Rellax; 37387})); 37388 37389/* 37390 * OKVideo by OKFocus v2.3.2 37391 * http://okfoc.us 37392 * 37393 * Copyright 2014, OKFocus 37394 * Licensed under the MIT license. 37395 * 37396 */ 37397var player, OKEvents, options, videoWidth, videoHeight, YTplayers, youtubePlayers = new Array(); 37398// youtube player ready 37399function onYouTubeIframeAPIReady() { 37400 YTplayers = new Array(); 37401 jQuery('.uncode-video-container.video').each(function() { 37402 var playerY; 37403 if (jQuery(this).attr('data-provider') == 'youtube') { 37404 var id = jQuery(this).attr('data-id'), 37405 start = jQuery(this).attr('data-start'), 37406 end = jQuery(this).attr('data-end'); 37407 start = typeof start && start !== null ? start : 0; 37408 end = typeof end && end !== null ? end : 0; 37409 options = jQuery(window).data('okoptions-' + id); 37410 if ( typeof options === 'undefined' ) { 37411 return true; 37412 } 37413 options.time = jQuery(this).attr('data-t'); 37414 playerY = new YT.Player('okplayer-' + id, { 37415 videoId: options.video ? options.video.id : null, 37416 playerVars: { 37417 'autohide': 1, 37418 'autoplay': jQuery(this).hasClass('is-no-control') ? options.autoplay : 0, //options.autoplay, 37419 'disablekb': 1, 37420 'cc_load_policy': options.captions, 37421 'controls': 0, 37422 'enablejsapi': 1, 37423 'fs': 0, 37424 'modestbranding': 1, 37425 'origin': window.location.origin || (window.location.protocol + '//' + window.location.hostname), 37426 'iv_load_policy': options.annotations, 37427 'loop': options.loop, 37428 'showinfo': 0, 37429 'rel': 0, 37430 'wmode': 'opaque', 37431 'hd': options.hd, 37432 'mute': 1, 37433 'start': start, 37434 'end': end 37435 }, 37436 events: { 37437 'onReady': OKEvents.yt.ready, 37438 'onStateChange': OKEvents.yt.onStateChange, 37439 'onError': OKEvents.yt.error 37440 } 37441 }); 37442 YTplayers[id] = playerY; 37443 playerY.videoId = id; 37444 } 37445 37446 }); 37447} 37448// vimeo player ready 37449function vimeoPlayerReady(id) { 37450 options = jQuery(window).data('okoptions-' + id); 37451 if ( typeof options === 'undefined' ) { 37452 return true; 37453 }
37454 var jIframe = options.jobject, 37455 iframe = jIframe[0]; 37456 37457 jIframe.attr('src', jIframe.data('src')); 37458 var playerV = new Vimeo.Player(iframe); 37459 // hide player until Vimeo hides controls... 37460 playerV.on('loaded', function(e) { 37461 OKEvents.v.onReady(iframe); 37462 var carouselContainer = jQuery(iframe).closest('.owl-carousel'); 37463 if (carouselContainer.length) { 37464 UNCODE.owlPlayVideo(carouselContainer); 37465 } 37466 // "Do not try to add listeners or call functions before receiving this event." 37467 if (OKEvents.utils.isMobile()) { 37468 // mobile devices cannot listen for play event 37469 OKEvents.v.onPlay(playerV); 37470 } else { 37471 playerV.on('play', function(){ 37472 OKEvents.v.onPlay(playerV); 37473 jQuery(window).trigger('okevents.v.play', [playerV]); 37474 }); 37475 playerV.on('pause', function(){ 37476 OKEvents.v.onPause; 37477 jQuery(window).trigger('okevents.v.pause', [playerV]); 37478 }); 37479 playerV.on('ended', function(){ 37480 OKEvents.v.onFinish 37481 jQuery(window).trigger('okevents.v.ended', [playerV]); 37482 }); 37483 } 37484 if (options.time != null) { 37485 var optsTimeStr = (options.time).replace('t=', ''), 37486 timeV = ''; 37487 37488 if ( /[a-zA-Z]/g.test(optsTimeStr) ) { 37489 var timeArr = optsTimeStr.split(/([^\d.-])/); 37490 for ( var i = 0; i < timeArr.length; i++ ) { 37491 if ( timeArr[i] === 'h' ) { 37492 timeV += parseFloat(timeArr[i-1]) * 3600; 37493 } else if ( timeArr[i] === 'm' ) { 37494 timeV += parseFloat(timeArr[i-1]) * 60; 37495 } else if ( timeArr[i] === 's' ) { 37496 timeV += parseFloat(timeArr[i-1]); 37497 } 37498 } 37499 } else { 37500 timeV = optsTimeStr; 37501 } 37502 37503 playerV.setCurrentTime(timeV); 37504 } 37505 37506 playerV.setVolume(0); 37507 playerV.play(); 37508 jQuery(iframe).css({ 37509 visibility: 'visible', 37510 opacity: 1 37511 }); 37512 jQuery(iframe).closest('.uncode-video-container:not(.t-entry-drop)').css('opacity', '1'); 37513 jQuery(iframe).closest('#page-header').addClass('video-started'); 37514 jQuery(iframe).closest('.background-wrapper').find('.block-bg-blend-mode.not-ie').css('opacity', '1'); 37515 37516 jQuery(window).trigger('okevents.v.loaded', [playerV]); 37517 }); 37518} 37519OKEvents = { 37520 yt: { 37521 ready: function(event) { 37522 var id = event.target.videoId, 37523 $video = jQuery('#okplayer-' + id), 37524 options = jQuery(window).data('okoptions-' + id); 37525 if ( typeof options === 'undefined' ) { 37526 return true; 37527 } 37528 youtubePlayers[id] = event.target; 37529 event.target.setVolume(options.volume); 37530 if (options.autoplay === 1) { 37531 if (options.playlist.list) { 37532 player.loadPlaylist(options.playlist.list, options.playlist.index, options.playlist.startSeconds, options.playlist.suggestedQuality); 37533 } else { 37534 var inCarousel = $video.closest('.owl-item'); 37535 if (!inCarousel.length || (inCarousel.length && inCarousel.hasClass('active'))) { 37536 if (options.time != null) { 37537 event.target.seekTo(parseInt(options.time)); 37538 } 37539 event.target.playVideo(); 37540 } else { 37541 event.target.pauseVideo(); 37542 } 37543 } 37544 } 37545 OKEvents.utils.isFunction(options.onReady) && options.onReady(event.target); 37546 37547 $video.closest('[data-provider]').on('uncode-resume', function(){ 37548 if (options.time != null) { 37549 event.target.seekTo(parseInt(options.time)).playVideo(); 37550 } else { 37551 event.target.seekTo(0).playVideo(); 37552 } 37553 }); 37554 37555 $video.closest('[data-provider]').on('uncode-pause', function(){ 37556 if (options.time != null) { 37557 event.target.seekTo(parseInt(options.time)).pauseVideo(); 37558 } else { 37559 event.target.seekTo(0).pauseVideo(); 37560 } 37561 }); 37562 jQuery(window).trigger('okevents.y.loaded', [event]); 37563 }, 37564 onStateChange: function(event) { 37565 var id = event.target.videoId, 37566 $video = jQuery('#okplayer-' + id), 37567 options = jQuery(window).data('okoptions-' + id); 37568 if ( typeof options === 'undefined' ) { 37569 return true; 37570 } 37571 youtubePlayers[id] = event.target; 37572 event.target.setVolume(options.volume); 37573 var $fluid = $video.closest('.fluid-object'), 37574 $tmb = $video.closest('.tmb'), 37575 setTime; 37576 switch (event.data) { 37577 case -1: 37578 OKEvents.utils.isFunction(options.unstarted) && options.unstarted(); 37579 break; 37580 case 0: 37581 OKEvents.utils.isFunction(options.onFinished) && options.onFinished(); 37582 options.loop && event.target.playVideo(); 37583 break; 37584 case 1: 37585 OKEvents.utils.isFunction(options.onPlay) && options.onPlay(); 37586 setTimeout(function() { 37587 UNCODE.initVideoComponent(document.body, '.uncode-video-container.video:not(.drop-move), .uncode-video-container.self-video:not(.drop-move)'); 37588 jQuery('#okplayer-' + id).closest('.uncode-video-container:not(.t-entry-drop)').css('opacity', '1'); 37589 jQuery('#okplayer-' + id).closest('#page-header').addClass('video-started'); 37590 jQuery('#okplayer-' + id).closest('.background-wrapper').find('.block-bg-blend-mode.not-ie').css('opacity', '1'); 37591 }, 300); 37592 break; 37593 case 2: 37594 OKEvents.utils.isFunction(options.onPause) && options.onPause(); 37595 break; 37596 case 3: 37597 OKEvents.utils.isFunction(options.buffering) && options.buffering(); 37598 break; 37599 case 5: 37600 OKEvents.utils.isFunction(options.cued) && options.cued(); 37601 break; 37602 default:
37603 throw "OKVideo: received invalid data from YT player."; 37604 } 37605 37606 jQuery(window).trigger('okevents.y.change', [event]); 37607 }, 37608 error: function(event) { 37609 throw event; 37610 } 37611 }, 37612 v: { 37613 onReady: function(target) { 37614 if ( typeof options === 'undefined' ) { 37615 return true; 37616 } 37617 OKEvents.utils.isFunction(options.onReady) && options.onReady(target); 37618 }, 37619 onPlay: function(player) { 37620 if ( typeof options === 'undefined' ) { 37621 return true; 37622 } 37623 if (!OKEvents.utils.isMobile()) player.setVolume(options.volume); 37624 OKEvents.utils.isFunction(options.onPlay) && options.onPlay(); 37625 jQuery(player.element).closest('.uncode-video-container:not(.t-entry-drop)').css('opacity', '1'); 37626 jQuery(player.element).closest('#page-header').addClass('video-started'); 37627 jQuery(player.element).closest('.background-wrapper').find('.block-bg-blend-mode.not-ie').css('opacity', '1'); 37628 }, 37629 onPause: function() { 37630 if ( typeof options === 'undefined' ) { 37631 return true; 37632 } 37633 OKEvents.utils.isFunction(options.onPause) && options.onPause(); 37634 }, 37635 onFinish: function() { 37636 if ( typeof options === 'undefined' ) { 37637 return true; 37638 } 37639 OKEvents.utils.isFunction(options.onFinish) && options.onFinish(); 37640 } 37641 }, 37642 utils: { 37643 isFunction: function(func) { 37644 if (typeof func === 'function') { 37645 return true; 37646 } else { 37647 return false; 37648 } 37649 }, 37650 isMobile: function() { 37651 if (navigator.userAgent.match(/(iPhone|iPod|iPad|Android|BlackBerry)/)) { 37652 return true; 37653 } else { 37654 return false; 37655 } 37656 } 37657 } 37658}; 37659 37660/** 37661 * vivus - JavaScript library to make drawing animation on SVG 37662 * @version v0.4.4 37663 * @link https://github.com/maxwellito/vivus 37664 * @license MIT 37665 */ 37666 37667'use strict'; 37668 37669(function () { 37670 37671 'use strict'; 37672 37673/** 37674 * Pathformer 37675 * Beta version 37676 * 37677 * Take any SVG version 1.1 and transform 37678 * child elements to 'path' elements 37679 * 37680 * This code is purely forked from 37681 * https://github.com/Waest/SVGPathConverter 37682 */ 37683 37684/** 37685 * Class constructor 37686 * 37687 * @param {DOM|String} element Dom element of the SVG or id of it 37688 */ 37689function Pathformer(element) { 37690 // Test params 37691 if (typeof element === 'undefined') { 37692 throw new Error('Pathformer [constructor]: "element" parameter is required'); 37693 } 37694 37695 // Set the element 37696 if (element.constructor === String) { 37697 element = document.getElementById(element); 37698 if (!element) { 37699 throw new Error('Pathformer [constructor]: "element" parameter is not related to an existing ID'); 37700 } 37701 } 37702 if (element instanceof window.SVGElement || 37703 element instanceof window.SVGGElement || 37704 /^svg$/i.test(element.nodeName)) { 37705 this.el = element; 37706 } else { 37707 throw new Error('Pathformer [constructor]: "element" parameter must be a string or a SVGelement'); 37708 } 37709 37710 // Start 37711 this.scan(element); 37712} 37713 37714/** 37715 * List of tags which can be transformed 37716 * to path elements 37717 * 37718 * @type {Array} 37719 */ 37720Pathformer.prototype.TYPES = ['line', 'ellipse', 'circle', 'polygon', 'polyline', 'rect']; 37721 37722/** 37723 * List of attribute names which contain 37724 * data. This array list them to check if 37725 * they contain bad values, like percentage. 37726 * 37727 * @type {Array} 37728 */ 37729Pathformer.prototype.ATTR_WATCH = ['cx', 'cy', 'points', 'r', 'rx', 'ry', 'x', 'x1', 'x2', 'y', '
vendor: 24,640 bytes, lines 37729-38527
37729y1', 'y2']; 37730 37731/** 37732 * Finds the elements compatible for transform 37733 * and apply the liked method 37734 * 37735 * @param {object} options Object from the constructor 37736 */ 37737Pathformer.prototype.scan = function (svg) { 37738 var fn, element, pathData, pathDom, 37739 elements = svg.querySelectorAll(this.TYPES.join(',')); 37740 37741 for (var i = 0; i < elements.length; i++) { 37742 element = elements[i]; 37743 fn = this[element.tagName.toLowerCase() + 'ToPath']; 37744 pathData = fn(this.parseAttr(element.attributes)); 37745 pathDom = this.pathMaker(element, pathData); 37746 element.parentNode.replaceChild(pathDom, element); 37747 } 37748}; 37749 37750 37751/** 37752 * Read `line` element to extract and transform 37753 * data, to make it ready for a `path` object. 37754 * 37755 * @param {DOMelement} element Line element to transform 37756 * @return {object} Data for a `path` element 37757 */ 37758Pathformer.prototype.lineToPath = function (element) { 37759 var newElement = {}, 37760 x1 = element.x1 || 0, 37761 y1 = element.y1 || 0, 37762 x2 = element.x2 || 0, 37763 y2 = element.y2 || 0; 37764 37765 newElement.d = 'M' + x1 + ',' + y1 + 'L' + x2 + ',' + y2; 37766 return newElement; 37767}; 37768 37769/** 37770 * Read `rect` element to extract and transform 37771 * data, to make it ready for a `path` object. 37772 * The radius-border is not taken in charge yet. 37773 * (your help is more than welcomed) 37774 * 37775 * @param {DOMelement} element Rect element to transform 37776 * @return {object} Data for a `path` element 37777 */ 37778Pathformer.prototype.rectToPath = function (element) { 37779 var newElement = {}, 37780 x = parseFloat(element.x) || 0, 37781 y = parseFloat(element.y) || 0, 37782 width = parseFloat(element.width) || 0, 37783 height = parseFloat(element.height) || 0; 37784 37785 if (element.rx || element.ry) { 37786 var rx = parseInt(element.rx, 10) || -1, 37787 ry = parseInt(element.ry, 10) || -1; 37788 rx = Math.min(Math.max(rx < 0 ? ry : rx, 0), width/2); 37789 ry = Math.min(Math.max(ry < 0 ? rx : ry, 0), height/2); 37790 37791 newElement.d = 'M ' + (x + rx) + ',' + y + ' ' + 37792 'L ' + (x + width - rx) + ',' + y + ' ' + 37793 'A ' + rx + ',' + ry + ',0,0,1,' + (x + width) + ',' + (y + ry) + ' ' + 37794 'L ' + (x + width) + ',' + (y + height - ry) + ' ' + 37795 'A ' + rx + ',' + ry + ',0,0,1,' + (x + width - rx) + ',' + (y + height) + ' ' + 37796 'L ' + (x + rx) + ',' + (y + height) + ' ' + 37797 'A ' + rx + ',' + ry + ',0,0,1,' + x + ',' + (y + height - ry) + ' ' + 37798 'L ' + x + ',' + (y + ry) + ' ' + 37799 'A ' + rx + ',' + ry + ',0,0,1,' + (x + rx) + ',' + y; 37800 } 37801 else { 37802 newElement.d = 'M' + x + ' ' + y + ' ' + 37803 'L' + (x + width) + ' ' + y + ' ' + 37804 'L' + (x + width) + ' ' + (y + height) + ' ' + 37805 'L' + x + ' ' + (y + height) + ' Z'; 37806 } 37807 return newElement; 37808}; 37809 37810/** 37811 * Read `polyline` element to extract and transform 37812 * data, to make it ready for a `path` object. 37813 * 37814 * @param {DOMelement} element Polyline element to transform 37815 * @return {object} Data for a `path` element 37816 */ 37817Pathformer.prototype.polylineToPath = function (element) { 37818 var newElement = {}, 37819 points = element.points.trim().split(' '), 37820 i, path; 37821 37822 // Reformatting if points are defined without commas 37823 if (element.points.indexOf(',') === -1) { 37824 var formattedPoints = []; 37825 for (i = 0; i < points.length; i+=2) { 37826 formattedPoints.push(points[i] + ',' + points[i+1]); 37827 } 37828 points = formattedPoints; 37829 } 37830 37831 // Generate the path.d value 37832 path = 'M' + points[0]; 37833 for(i = 1; i < points.length; i++) { 37834 if (points[i].indexOf(',') !== -1) { 37835 path += 'L' + points[i]; 37836 } 37837 } 37838 newElement.d = path; 37839 return newElement; 37840}; 37841 37842/** 37843 * Read `polygon` element to extract and transform 37844 * data, to make it ready for a `path` object. 37845 * This method rely on polylineToPath, because the 37846 * logic is similar. The path created is just closed, 37847 * so it needs an 'Z' at the end. 37848 * 37849 * @param {DOMelement} element Polygon element to transform 37850 * @return {object} Data for a `path` element 37851 */ 37852Pathformer.prototype.polygonToPath = function (element) { 37853 var newElement = Pathformer.prototype.polylineToPath(element); 37854 37855 newElement.d += 'Z'; 37856 return newElement; 37857}; 37858 37859/** 37860 * Read `ellipse` element to extract and transform 37861 * data, to make it ready for a `path` object. 37862 * 37863 * @param {DOMelement} element ellipse element to transform 37864 * @return {object} Data for a `path` element 37865 */ 37866Pathformer.prototype.ellipseToPath = function (element) { 37867 var newElement = {}, 37868 rx = parseFloat(element.rx) || 0, 37869 ry = parseFloat(element.ry) || 0, 37870 cx = parseFloat(element.cx) || 0, 37871 cy = parseFloat(element.cy) || 0, 37872 startX = cx - rx, 37873 startY = cy, 37874 endX = parseFloat(cx) + parseFloat(rx), 37875 endY = cy; 37876 37877 newElement.d = 'M' + startX + ',' + startY + 37878 'A' + rx + ',' + ry + ' 0,1,1 ' + endX + ',' + endY + 37879 'A' + rx + ',' + ry + ' 0,1,1 ' + startX + ',' + endY; 37880 return newElement; 37881}; 37882 37883/** 37884 * Read `circle` element to extract and transform 37885 * data, to make it ready for a `path` object. 37886 * 37887 * @param {DOMelement} element Circle element to transform 37888 * @return {object} Data for a `path` element 37889 */ 37890Pathformer.prototype.circleToPath = function (element) { 37891 var newElement = {}, 37892 r = parseFloat(element.r) || 0, 37893 cx = parseFloat(element.cx) || 0, 37894 cy = parseFloat(element.cy) || 0, 37895 startX = cx - r, 37896 startY = cy, 37897 endX = parseFloat(cx) + parseFloat(r), 37898 endY = cy; 37899 37900 newElement.d = 'M' + startX + ',' + startY + 37901 'A' + r + ',' + r + ' 0,1,1 ' + endX + ',' + endY + 37902 'A' + r + ',' + r + ' 0,1,1 ' + startX + ',' + endY; 37903 return newElement; 37904}; 37905 37906/** 37907 * Create `path` elements form original element 37908 * and prepared objects 37909 * 37910 * @param {DOMelement} element Original element to transform 37911 * @param {object} pathData Path data (from `toPath` methods) 37912 * @return {DOMelement} Path element 37913 */ 37914Pathformer.prototype.pathMaker = function (element, pathData) { 37915 var i, attr, pathTag = document.createElementNS('http://www.w3.org/2000/svg','path'); 37916 for(i = 0; i < element.attributes.length; i++) { 37917 attr = element.attributes[i]; 37918 if (this.ATTR_WATCH.indexOf(attr.name) === -1) { 37919 pathTag.setAttribute(attr.name, attr.value); 37920 } 37921 } 37922 for(i in pathData) { 37923 pathTag.setAttribute(i, pathData[i]); 37924 } 37925 return pathTag; 37926}; 37927 37928/** 37929 * Parse attributes of a DOM element to 37930 * get an object of attribute => value 37931 * 37932 * @param {NamedNodeMap} attributes Attributes object from DOM element to parse 37933 * @return {object} Object of attributes 37934 */ 37935Pathformer.prototype.parseAttr = function (element) { 37936 var attr, output = {}; 37937 for (var i = 0; i < element.length; i++) { 37938 attr = element[i]; 37939 // Check if no data attribute contains '%', or the transformation is impossible 37940 if (this.ATTR_WATCH.indexOf(attr.name) !== -1 && attr.value.indexOf('%') !== -1) { 37941 throw new Error('Pathformer [parseAttr]: a SVG shape got values in percentage. This cannot be transformed into \'path\' tags. Please use \'viewBox\'.'); 37942 } 37943 output[attr.name] = attr.value; 37944 } 37945 return output; 37946}; 37947 37948 'use strict'; 37949 37950var setupEnv, requestAnimFrame, cancelAnimFrame, parsePositiveInt; 37951 37952/** 37953 * Vivus 37954 * Beta version 37955 * 37956 * Take any SVG and make the animation 37957 * to give give the impression of live drawing 37958 * 37959 * This in more than just inspired from codrops 37960 * At that point, it's a pure fork. 37961 */ 37962 37963/** 37964 * Class constructor 37965 * option structure 37966 * type: 'delayed'|'sync'|'oneByOne'|'script' (to know if the items must be drawn synchronously or not, default: delayed) 37967 * duration: <int> (in frames) 37968 * start: 'inViewport'|'manual'|'autostart' (start automatically the animation, default: inViewport) 37969 * delay: <int> (delay between the drawing of first and last path) 37970 * dashGap <integer> whitespace extra margin between dashes 37971 * pathTimingFunction <function> timing animation function for each path element of the SVG 37972 * animTimingFunction <function> timing animation function for the complete SVG 37973 * forceRender <boolean> force the browser to re-render all updated path items 37974 * selfDestroy <boolean> removes all extra styling on the SVG, and leaves it as original 37975 * 37976 * The attribute 'type' is by default on 'delayed'. 37977 * - 'delayed' 37978 * all paths are draw at the same time but with a 37979 * little delay between them before start 37980 * - 'sync' 37981 * all path are start and finish at the same time 37982 * - 'oneByOne' 37983 * only one path is draw at the time 37984 * the end of the first one will trigger the draw 37985 * of the next one 37986 * 37987 * All these values can be overwritten individually 37988 * for each path item in the SVG 37989 * The value of frames will always take the advantage of 37990 * the duration value. 37991 * If you fail somewhere, an error will be thrown. 37992 * Good luck. 37993 * 37994 * @constructor 37995 * @this {Vivus} 37996 * @param {DOM|String} element Dom element of the SVG or id of it 37997 * @param {Object} options Options about the animation 37998 * @param {Function} callback Callback for the end of the animation 37999 */ 38000function Vivus (element, options, callback) { 38001 38002 setupEnv(); 38003 38004 // Setup 38005 this.isReady = false; 38006 this.setElement(element, options); 38007 this.setOptions(options); 38008 this.setCallback(callback); 38009 38010 if (this.isReady) { 38011 this.init(); 38012 } 38013} 38014 38015/** 38016 * Timing functions 38017 ************************************** 38018 * 38019 * Default functions to help developers. 38020 * It always take a number as parameter (between 0 to 1) then 38021 * return a number (between 0 and 1) 38022 */ 38023Vivus.LINEAR = function (x) {return x;}; 38024Vivus.EASE = function (x) {return -Math.cos(x * Math.PI) / 2 + 0.5;}; 38025Vivus.EASE_OUT = function (x) {return 1 - Math.pow(1-x, 3);}; 38026Vivus.EASE_IN = function (x) {return Math.pow(x, 3);}; 38027Vivus.EASE_OUT_BOUNCE = function (x) { 38028 var base = -Math.cos(x * (0.5 * Math.PI)) + 1, 38029 rate = Math.pow(base,1.5), 38030 rateR = Math.pow(1 - x, 2), 38031 progress = -Math.abs(Math.cos(rate * (2.5 * Math.PI) )) + 1; 38032 return (1- rateR) + (progress * rateR); 38033}; 38034 38035 38036/** 38037 * Setters 38038 ************************************** 38039 */ 38040 38041/** 38042 * Check and set the element in the instance 38043 * The method will not return anything, but will throw an 38044 * error if the parameter is invalid 38045 * 38046 * @param {DOM|String} element SVG Dom element or id of it 38047 */ 38048Vivus.prototype.setElement = function (element, options) { 38049 var onLoad, self; 38050 38051 // Basic check 38052 if (typeof element === 'undefined') { 38053 throw new Error('Vivus [constructor]: "element" parameter is required'); 38054 } 38055 38056 // Set the element 38057 if (element.constructor === String) { 38058 element = document.getElementById(element); 38059 if (!element) { 38060 throw new Error('Vivus [constructor]: "element" parameter is not related to an existing ID'); 38061 } 38062 } 38063 this.parentEl = element; 38064 38065 // Load the SVG with XMLHttpRequest and extract the SVG 38066 if (options && options.file) { 38067 var self = this; 38068 onLoad = function (e) { 38069 var domSandbox = document.createElement('div'); 38070 domSandbox.innerHTML = this.responseText; 38071 38072 var svgTag = domSandbox.querySelector('svg'); 38073 if (!svgTag) { 38074 throw new Error('Vivus [load]: Cannot find the SVG in the loaded file : ' + options.file); 38075 } 38076 38077 self.el = svgTag 38078 self.el.setAttribute('width', '100%'); 38079 self.el.setAttribute('height', '100%'); 38080 self.parentEl.appendChild(self.el) 38081 self.isReady = true; 38082 self.init(); 38083 self = null; 38084 } 38085 38086 var oReq = new window.XMLHttpRequest(); 38087 oReq.addEventListener('load', onLoad); 38088 oReq.open('GET', options.file); 38089 oReq.send(); 38090 return; 38091 } 38092 38093 switch (element.constructor) { 38094 case window.SVGSVGElement: 38095 case window.SVGElement: 38096 case window.SVGGElement: 38097 this.el = element; 38098 this.isReady = true; 38099 break; 38100 38101 case window.HTMLObjectElement: 38102 self = this; 38103 onLoad = function (e) { 38104 if (self.isReady) { 38105 return; 38106 } 38107 self.el = element.contentDocument && element.contentDocument.querySelector('svg'); 38108 if (!self.el && e) { 38109 throw new Error('Vivus [constructor]: object loaded does not contain any SVG'); 38110 } 38111 else if (self.el) { 38112 if (element.getAttribute('built-by-vivus')) { 38113 self.parentEl.insertBefore(self.el, element); 38114 self.parentEl.removeChild(element); 38115 self.el.setAttribute('width', '100%'); 38116 self.el.setAttribute('height', '100%'); 38117 } 38118 self.isReady = true; 38119 self.init(); 38120 self = null; 38121 } 38122 }; 38123 38124 if (!onLoad()) { 38125 element.addEventListener('load', onLoad); 38126 } 38127 break; 38128 38129 default: 38130 throw new Error('Vivus [constructor]: "element" parameter is not valid (or miss the "file" attribute)'); 38131 } 38132}; 38133 38134/** 38135 * Set up user option to the instance 38136 * The method will not return anything, but will throw an 38137 * error if the parameter is invalid 38138 * 38139 * @param {object} options Object from the constructor 38140 */ 38141Vivus.prototype.setOptions = function (options) { 38142 var allowedTypes = ['delayed', 'sync', 'async', 'nsync', 'oneByOne', 'scenario', 'scenario-sync']; 38143 var allowedStarts = ['inViewport', 'manual', 'autostart']; 38144 38145 // Basic check 38146 if (options !== undefined && options.constructor !== Object) { 38147 throw new Error('Vivus [constructor]: "options" parameter must be an object'); 38148 } 38149 else { 38150 options = options || {}; 38151 } 38152 38153 // Set the animation type 38154 if (options.type && allowedTypes.indexOf(options.type) === -1) { 38155 throw new Error('Vivus [constructor]: ' + options.type + ' is not an existing animation `type`'); 38156 } 38157 else { 38158 this.type = options.type || allowedTypes[0]; 38159 } 38160 38161 // Set the start type 38162 if (options.start && allowedStarts.indexOf(options.start) === -1) { 38163 throw new Error('Vivus [constructor]: ' + options.start + ' is not an existing `start` option'); 38164 } 38165 else { 38166 this.start = options.start || allowedStarts[0]; 38167 } 38168 38169 this.isIE = (window.navigator.userAgent.indexOf('MSIE') !== -1 || window.navigator.userAgent.indexOf('Trident/') !== -1 || window.navigator.userAgent.indexOf('Edge/') !== -1 ); 38170 this.duration = parsePositiveInt(options.duration, 120); 38171 this.delay = parsePositiveInt(options.delay, null); 38172 //Uncode addition 38173 this.delayStart = parsePositiveInt(options.delayStart, null); 38174 //#END 38175 this.dashGap = parsePositiveInt(options.dashGap, 1); 38176 this.forceRender = options.hasOwnProperty('forceRender') ? !!options.forceRender : this.isIE; 38177 this.reverseStack = !!options.reverseStack; 38178 this.selfDestroy = !!options.selfDestroy; 38179 this.onReady = options.onReady; 38180 this.map = []; 38181 this.frameLength = this.currentFrame = this.delayUnit = this.speed = this.handle = null; 38182 38183 this.ignoreInvisible = options.hasOwnProperty('ignoreInvisible') ? !!options.ignoreInvisible : false; 38184 38185 this.animTimingFunction = options.animTimingFunction || Vivus.LINEAR; 38186 this.pathTimingFunction = options.pathTimingFunction || Vivus.LINEAR; 38187 38188 if (this.delay >= this.duration) { 38189 throw new Error('Vivus [constructor]: delay must be shorter than duration'); 38190 } 38191}; 38192 38193/** 38194 * Set up callback to the instance 38195 * The method will not return enything, but will throw an 38196 * error if the parameter is invalid 38197 * 38198 * @param {Function} callback Callback for the animation end 38199 */ 38200Vivus.prototype.setCallback = function (callback) { 38201 // Basic check 38202 if (!!callback && callback.constructor !== Function) { 38203 throw new Error('Vivus [constructor]: "callback" parameter must be a function'); 38204 } 38205 this.callback = callback || function () {}; 38206}; 38207 38208 38209/** 38210 * Core 38211 ************************************** 38212 */ 38213 38214/** 38215 * Map the svg, path by path. 38216 * The method return nothing, it just fill the 38217 * `map` array. Each item in this array represent 38218 * a path element from the SVG, with informations for 38219 * the animation. 38220 * 38221 * ``` 38222 * [ 38223 * { 38224 * el: <DOMobj> the path element 38225 * length: <number> length of the path line 38226 * startAt: <number> time start of the path animation (in frames) 38227 * duration: <number> path animation duration (in frames) 38228 * }, 38229 * ... 38230 * ] 38231 * ``` 38232 * 38233 */ 38234Vivus.prototype.mapping = function () { 38235 var i, paths, path, pAttrs, pathObj, totalLength, lengthMeter, timePoint; 38236 timePoint = totalLength = lengthMeter = 0; 38237 paths = this.el.querySelectorAll('path'); 38238 38239 for (i = 0; i < paths.length; i++) { 38240 path = paths[i]; 38241 if (this.isInvisible(path)) { 38242 continue; 38243 } 38244 pathObj = { 38245 el: path, 38246 length: Math.ceil(path.getTotalLength()) 38247 }; 38248 // Test if the path length is correct 38249 if (isNaN(pathObj.length)) { 38250 if (window.console && console.warn) { 38251 console.warn('Vivus [mapping]: cannot retrieve a path element length', path); 38252 } 38253 continue; 38254 } 38255 this.map.push(pathObj); 38256 path.style.strokeDasharray = pathObj.length + ' ' + (pathObj.length + this.dashGap * 2); 38257 path.style.strokeDashoffset = pathObj.length + this.dashGap; 38258 pathObj.length += this.dashGap; 38259 totalLength += pathObj.length; 38260 38261 this.renderPath(i); 38262 } 38263 38264 totalLength = totalLength === 0 ? 1 : totalLength; 38265 this.delay = this.delay === null ? this.duration / 3 : this.delay; 38266 this.delayUnit = this.delay / (paths.length > 1 ? paths.length - 1 : 1); 38267 38268 // Reverse stack if asked 38269 if (this.reverseStack) { 38270 this.map.reverse(); 38271 } 38272 38273 for (i = 0; i < this.map.length; i++) { 38274 pathObj = this.map[i]; 38275 38276 switch (this.type) { 38277 case 'delayed': 38278 pathObj.startAt = this.delayUnit * i; 38279 pathObj.duration = this.duration - this.delay; 38280 break; 38281 38282 case 'oneByOne': 38283 pathObj.startAt = lengthMeter / totalLength * this.duration; 38284 pathObj.duration = pathObj.length / totalLength * this.duration; 38285 break; 38286 38287 case 'sync': 38288 case 'async': 38289 case 'nsync': 38290 pathObj.startAt = 0; 38291 pathObj.duration = this.duration; 38292 break; 38293 38294 case 'scenario-sync': 38295 path = pathObj.el; 38296 pAttrs = this.parseAttr(path); 38297 pathObj.startAt = timePoint + (parsePositiveInt(pAttrs['data-delay'], this.delayUnit) || 0); 38298 pathObj.duration = parsePositiveInt(pAttrs['data-duration'], this.duration); 38299 timePoint = pAttrs['data-async'] !== undefined ? pathObj.startAt : pathObj.startAt + pathObj.duration; 38300 this.frameLength = Math.max(this.frameLength, (pathObj.startAt + pathObj.duration)); 38301 break; 38302 38303 case 'scenario': 38304 path = pathObj.el; 38305 pAttrs = this.parseAttr(path); 38306 pathObj.startAt = parsePositiveInt(pAttrs['data-start'], this.delayUnit) || 0; 38307 pathObj.duration = parsePositiveInt(pAttrs['data-duration'], this.duration); 38308 this.frameLength = Math.max(this.frameLength, (pathObj.startAt + pathObj.duration)); 38309 break; 38310 } 38311 lengthMeter += pathObj.length; 38312 this.frameLength = this.frameLength || this.duration; 38313 } 38314}; 38315 38316/** 38317 * Interval method to draw the SVG from current 38318 * position of the animation. It update the value of 38319 * `currentFrame` and re-trace the SVG. 38320 * 38321 * It use this.handle to store the requestAnimationFrame 38322 * and clear it one the animation is stopped. So this 38323 * attribute can be used to know if the animation is 38324 * playing. 38325 * 38326 * Once the animation at the end, this method will 38327 * trigger the Vivus callback. 38328 * 38329 */ 38330Vivus.prototype.drawer = function () { 38331 var self = this; 38332 this.currentFrame += this.speed; 38333 38334 if (this.currentFrame <= 0) { 38335 this.stop(); 38336 this.reset(); 38337 } else if (this.currentFrame >= this.frameLength) { 38338 this.stop(); 38339 this.currentFrame = this.frameLength; 38340 this.trace(); 38341 if (this.selfDestroy) { 38342 this.destroy(); 38343 } 38344 } else { 38345 this.trace(); 38346 this.handle = requestAnimFrame(function () { 38347 self.drawer(); 38348 }); 38349 return; 38350 } 38351 38352 this.callback(this); 38353 if (this.instanceCallback) { 38354 this.instanceCallback(this); 38355 this.instanceCallback = null; 38356 } 38357}; 38358 38359/** 38360 * Draw the SVG at the current instant from the 38361 * `currentFrame` value. Here is where most of the magic is. 38362 * The trick is to use the `strokeDashoffset` style property. 38363 * 38364 * For optimisation reasons, a new property called `progress` 38365 * is added in each item of `map`. This one contain the current 38366 * progress of the path element. Only if the new value is different 38367 * the new value will be applied to the DOM element. This 38368 * method save a lot of resources to re-render the SVG. And could 38369 * be improved if the animation couldn't be played forward. 38370 * 38371 */ 38372Vivus.prototype.trace = function () { 38373 var i, progress, path, currentFrame; 38374 currentFrame = this.animTimingFunction(this.currentFrame / this.frameLength) * this.frameLength; 38375 for (i = 0; i < this.map.length; i++) { 38376 path = this.map[i]; 38377 progress = (currentFrame - path.startAt) / path.duration; 38378 progress = this.pathTimingFunction(Math.max(0, Math.min(1, progress))); 38379 if (path.progress !== progress) { 38380 path.progress = progress; 38381 path.el.style.strokeDashoffset = Math.floor(path.length * (1 - progress)); 38382 this.renderPath(i); 38383 } 38384 } 38385}; 38386 38387/** 38388 * Method forcing the browser to re-render a path element 38389 * from it's index in the map. Depending on the `forceRender` 38390 * value. 38391 * The trick is to replace the path element by it's clone. 38392 * This practice is not recommended because it's asking more 38393 * ressources, too much DOM manupulation.. 38394 * but it's the only way to let the magic happen on IE. 38395 * By default, this fallback is only applied on IE. 38396 * 38397 * @param {Number} index Path index 38398 */ 38399Vivus.prototype.renderPath = function (index) { 38400 if (this.forceRender && this.map && this.map[index]) { 38401 var pathObj = this.map[index], 38402 newPath = pathObj.el.cloneNode(true); 38403 pathObj.el.parentNode.replaceChild(newPath, pathObj.el); 38404 pathObj.el = newPath; 38405 } 38406}; 38407 38408/** 38409 * When the SVG object is loaded and ready, 38410 * this method will continue the initialisation. 38411 * 38412 * This this mainly due to the case of passing an 38413 * object tag in the constructor. It will wait 38414 * the end of the loading to initialise. 38415 * 38416 */ 38417Vivus.prototype.init = function () { 38418 // Set object variables 38419 this.frameLength = 0; 38420 this.currentFrame = 0; 38421 this.map = []; 38422 38423 // Start 38424 new Pathformer(this.el); 38425 this.mapping(); 38426 this.starter(); 38427 38428 if (this.onReady) { 38429 this.onReady(this); 38430 } 38431}; 38432 38433/** 38434 * Trigger to start of the animation. 38435 * Depending on the `start` value, a different script 38436 * will be applied. 38437 * 38438 * If the `start` value is not valid, an error will be thrown. 38439 * Even if technically, this is impossible. 38440 * 38441 */ 38442Vivus.prototype.starter = function () { 38443 switch (this.start) { 38444 case 'manual': 38445 return; 38446 38447 case 'autostart': 38448 this.play(); 38449 break; 38450 38451 case 'inViewport': 38452 var self = this, 38453 listener = function () { 38454 if (self.isInViewport(self.parentEl, 1)) { 38455 self.play(); 38456 window.removeEventListener('scroll', listener); 38457 //Uncode addition 38458 window.removeEventListener('fp-slide-changed', listener); 38459 window.removeEventListener('fp-slide-scroll', listener); 38460 //#END 38461 } 38462 }; 38463 window.addEventListener('scroll', listener); 38464 //Uncode addition 38465 window.addEventListener('fp-slide-changed', listener); 38466 window.addEventListener('fp-slide-scroll', listener); 38467 //#END 38468 listener(); 38469 break; 38470 } 38471}; 38472 38473 38474/** 38475 * Controls 38476 ************************************** 38477 */ 38478 38479/** 38480 * Get the current status of the animation between 38481 * three different states: 'start', 'progress', 'end'. 38482 * @return {string} Instance status 38483 */ 38484Vivus.prototype.getStatus = function () { 38485 return this.currentFrame === 0 ? 'start' : this.currentFrame === this.frameLength ? 'end' : 'progress'; 38486}; 38487 38488/** 38489 * Reset the instance to the initial state : undraw 38490 * Be careful, it just reset the animation, if you're 38491 * playing the animation, this won't stop it. But just 38492 * make it start from start. 38493 * 38494 */ 38495Vivus.prototype.reset = function () { 38496 return this.setFrameProgress(0); 38497}; 38498 38499/** 38500 * Set the instance to the final state : drawn 38501 * Be careful, it just set the animation, if you're 38502 * playing the animation on rewind, this won't stop it. 38503 * But just make it start from the end. 38504 * 38505 */ 38506Vivus.prototype.finish = function () { 38507 return this.setFrameProgress(1); 38508}; 38509 38510/** 38511 * Set the level of progress of the drawing. 38512 * 38513 * @param {number} progress Level of progress to set 38514 */ 38515Vivus.prototype.setFrameProgress = function (progress) { 38516 progress = Math.min(1, Math.max(0, progress)); 38517 this.currentFrame = Math.round(this.frameLength * progress); 38518 this.trace(); 38519 return this; 38520}; 38521 38522/** 38523 * Play the animation at the desired speed. 38524 * Speed must be a valid number (no zero). 38525 * By default, the speed value is 1. 38526 * But a negative value is accepted to go forward. 38527 *
38528 * And works with float too. 38529 * But don't forget we are in JavaScript, se be nice 38530 * with him and give him a 1/2^x value. 38531 * 38532 * @param {number} speed Animation speed [optional] 38533 */ 38534Vivus.prototype.play = function (speed, callback) { 38535 this.instanceCallback = null; 38536 38537 if (speed && typeof speed === 'function') { 38538 this.instanceCallback = speed; // first parameter is actually the callback function 38539 speed = null; 38540 } 38541 else if (speed && typeof speed !== 'number') { 38542 throw new Error('Vivus [play]: invalid speed'); 38543 } 38544 // if the first parameter wasn't the callback, check if the seconds was 38545 if (callback && typeof(callback) === 'function' && !this.instanceCallback) { 38546 this.instanceCallback = callback; 38547 } 38548 38549 38550 this.speed = speed || 1; 38551 //Uncode addition 38552 if (!this.handle) { 38553 var $this = this, 38554 delay = (this.delayStart != null) ? this.delayStart : 0; 38555 setTimeout(function() { 38556 $this.drawer(); 38557 }, delay); 38558 } 38559 //#END 38560 return this; 38561}; 38562 38563/** 38564 * Stop the current animation, if on progress. 38565 * Should not trigger any error. 38566 * 38567 */ 38568Vivus.prototype.stop = function () { 38569 if (this.handle) { 38570 cancelAnimFrame(this.handle); 38571 this.handle = null; 38572 } 38573 return this; 38574}; 38575 38576/** 38577 * Destroy the instance. 38578 * Remove all bad styling attributes on all 38579 * path tags 38580 * 38581 */ 38582Vivus.prototype.destroy = function () { 38583 this.stop(); 38584 var i, path; 38585 for (i = 0; i < this.map.length; i++) { 38586 path = this.map[i]; 38587 path.el.style.strokeDashoffset = null; 38588 path.el.style.strokeDasharray = null; 38589 this.renderPath(i); 38590 } 38591}; 38592 38593 38594/** 38595 * Utils methods 38596 * include methods from Codrops 38597 ************************************** 38598 */ 38599 38600/** 38601 * Method to best guess if a path should added into 38602 * the animation or not. 38603 * 38604 * 1. Use the `data-vivus-ignore` attribute if set 38605 * 2. Check if the instance must ignore invisible paths 38606 * 3. Check if the path is visible 38607 * 38608 * For now the visibility checking is unstable. 38609 * It will be used for a beta phase. 38610 * 38611 * Other improvments are planned. Like detecting 38612 * is the path got a stroke or a valid opacity. 38613 */ 38614Vivus.prototype.isInvisible = function (el) { 38615 var rect, 38616 ignoreAttr = el.getAttribute('data-ignore'); 38617 38618 if (ignoreAttr !== null) { 38619 return ignoreAttr !== 'false'; 38620 } 38621 38622 if (this.ignoreInvisible) { 38623 rect = el.getBoundingClientRect(); 38624 return !rect.width && !rect.height; 38625 } 38626 else { 38627 return false; 38628 } 38629}; 38630 38631/** 38632 * Parse attributes of a DOM element to 38633 * get an object of {attributeName => attributeValue} 38634 * 38635 * @param {object} element DOM element to parse 38636 * @return {object} Object of attributes 38637 */ 38638Vivus.prototype.parseAttr = function (element) { 38639 var attr, output = {}; 38640 if (element && element.attributes) { 38641 for (var i = 0; i < element.attributes.length; i++) { 38642 attr = element.attributes[i]; 38643 output[attr.name] = attr.value; 38644 } 38645 } 38646 return output; 38647}; 38648 38649/** 38650 * Reply if an element is in the page viewport 38651 * 38652 * @param {object} el Element to observe 38653 * @param {number} h Percentage of height 38654 * @return {boolean} 38655 */ 38656Vivus.prototype.isInViewport = function (el, h) { 38657 var scrolled = this.scrollY(), 38658 viewed = scrolled + this.getViewportH(), 38659 elBCR = el.getBoundingClientRect(), 38660 elHeight = elBCR.height, 38661 elTop = scrolled + elBCR.top, 38662 elBottom = elTop + elHeight; 38663 38664 // if 0, the element is considered in the viewport as soon as it enters. 38665 // if 1, the element is considered in the viewport only when it's fully inside 38666 // value in percentage (1 >= h >= 0) 38667 h = h || 0; 38668 38669 return (elTop + elHeight * h) <= viewed && (elBottom) >= scrolled; 38670}; 38671 38672 38673/** 38674 * Get the viewport height in pixels 38675 * 38676 * @return {integer} Viewport height 38677 */ 38678Vivus.prototype.getViewportH = function () { 38679 var client = this.docElem.clientHeight, 38680 inner = window.innerHeight; 38681 38682 if (client < inner) { 38683 return inner; 38684 } 38685 else { 38686 return client; 38687 } 38688}; 38689 38690/** 38691 * Get the page Y offset 38692 * 38693 * @return {integer} Page Y offset 38694 */ 38695Vivus.prototype.scrollY = function () { 38696 return window.pageYOffset || this.docElem.scrollTop; 38697}; 38698 38699setupEnv = function () { 38700 38701 if (Vivus.prototype.docElem) { 38702 return; 38703 } 38704 38705 /** 38706 * Alias for document element 38707 * 38708 * @type {DOMelement} 38709 */ 38710 Vivus.prototype.docElem = window.document.documentElement; 38711 38712 /** 38713 * Alias for `requestAnimationFrame` or 38714 * `setTimeout` function for deprecated browsers. 38715 * 38716 */ 38717 requestAnimFrame = (function () { 38718 return ( 38719 window.requestAnimationFrame || 38720 window.webkitRequestAnimationFrame || 38721 window.mozRequestAnimationFrame || 38722 window.oRequestAnimationFrame || 38723 window.msRequestAnimationFrame || 38724 function(/* function */ callback){ 38725 return window.setTimeout(callback, 1000 / 60); 38726 } 38727 ); 38728 })(); 38729 38730 /** 38731 * Alias for `cancelAnimationFrame` or 38732 * `cancelTimeout` function for deprecated browsers. 38733 * 38734 */ 38735 cancelAnimFrame = (function () { 38736 return ( 38737 window.cancelAnimationFrame || 38738 window.webkitCancelAnimationFrame || 38739 window.mozCancelAnimationFrame || 38740 window.oCancelAnimationFrame || 38741 window.msCancelAnimationFrame || 38742 function(id){ 38743 return window.clearTimeout(id); 38744 } 38745 ); 38746 })(); 38747}; 38748 38749/** 38750 * Parse string to integer. 38751 * If the number is not positive or null 38752 * the method will return the default value 38753 * or 0 if undefined 38754 * 38755 * @param {string} value String to parse 38756 * @param {*}
38756 defaultValue Value to return if the result parsed is invalid 38757 * @return {number} 38758 * 38759 */ 38760parsePositiveInt = function (value, defaultValue) { 38761 var output = parseInt(value, 10); 38762 return (output >= 0) ? output : defaultValue; 38763}; 38764 38765 38766 if (typeof define === 'function' && define.amd) { 38767 // AMD. Register as an anonymous module. 38768 define([], function() { 38769 return Vivus; 38770 }); 38771 } else if (typeof exports === 'object') { 38772 // Node. Does not work with strict CommonJS, but 38773 // only CommonJS-like environments that support module.exports, 38774 // like Node. 38775 module.exports = Vivus; 38776 } else { 38777 // Browser globals 38778 window.Vivus = Vivus; 38779 } 38780 38781}());
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.