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 //if ( !this.visibleSubMenus[i].closest('.menu-accordion').length ) { 12905 this.menuHide(this.visibleSubMenus[i]); 12906 //} 12907 } 12908 } 12909 // hide root if it's popup 12910 if (this.opts.isPopup) { 12911 this.$root.stop(true, true); 12912 if (this.$root.is(':visible')) { 12913 if (this.opts.hideFunction) { 12914 this.opts.hideFunction.call(this, this.$root); 12915 } else { 12916 this.$root.hide(this.opts.hideDuration); 12917 } 12918 // remove IE iframe shim 12919 if (this.$root.dataSM('ie-shim')) { 12920 this.$root.dataSM('ie-shim').remove(); 12921 } 12922 } 12923 } 12924 this.activatedItems = []; 12925 this.visibleSubMenus = []; 12926 this.clickActivated = false;
12927 // reset z-index increment 12928 this.zIndexInc = 0; 12929 }, 12930 menuIframeShim: function($ul) { 12931 // create iframe shim for the menu 12932 if (IE && this.opts.overlapControlsInIE && !$ul.dataSM('ie-shim')) { 12933 $ul.dataSM('ie-shim', $('<iframe/>').attr({ src: 'javascript:0', tabindex: -9 }) 12934 .css({ position: 'absolute', top: 'auto', left: '0', opacity: 0, border: '0' }) 12935 ); 12936 } 12937 }, 12938 menuInit: function($ul) { 12939 if (!$ul.dataSM('in-mega')) { 12940 this.subMenus.push($ul); 12941 // mark UL's in mega drop downs (if any) so we can neglect them 12942 if ($ul.hasClass('mega-menu')) { 12943 $ul.find('ul').dataSM('in-mega', true); 12944 } 12945 // get level (much faster than, for example, using parentsUntil) 12946 var level = 2, 12947 par = $ul[0]; 12948 while (par != null && par.parentNode != null && ( par = par.parentNode.parentNode) != this.$root[0]) { 12949 level++; 12950 } 12951 // cache stuff 12952 $ul.dataSM('parent-a', $ul.prevAll('a').eq(-1)) 12953 .dataSM('level', level) 12954 .parent().dataSM('sub', $ul); 12955 // add sub indicator to parent item 12956 if (this.opts.subIndicators) { 12957 $ul.dataSM('parent-a').addClass('has-submenu')[this.opts.subIndicatorsPos](this.$subArrow.clone()); 12958 } 12959 } 12960 }, 12961 menuPosition: function($sub) { 12962 var fixIE = $('html.ie').length; 12963 // if (fixIE) { 12964 // var $rowParent = $($sub).closest('.main-menu-container'); 12965 // $rowParent.height($rowParent.height()); 12966 // } 12967 var $a = $sub.dataSM('parent-a'), 12968 $li = $sub.parent(), 12969 $ul = $sub.parent().parent(), 12970 // $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'), 12971 $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'), 12972 level = $sub.dataSM('level'), 12973 subW = this.getWidth($sub), 12974 subH = this.getHeight($sub), 12975 itemOffset = $a.offset(), 12976 itemX = itemOffset.left, 12977 itemY = itemOffset.top, 12978 itemW = this.getWidth($a), 12979 itemH = this.getHeight($a), 12980 $win = $(window), 12981 winX = $win.scrollLeft(), 12982 winY = $win.scrollTop(), 12983 winW = $win.width(), 12984 winH = $win.height(), 12985 containerW = $container.width(), 12986 containerOffsetX = containerW + ((winW - containerW) / 2), 12987 horizontalParent = $ul.hasClass('sm') && !$ul.hasClass('sm-vertical'), 12988 subOffsetX = level == 2 ? this.opts.mainMenuSubOffsetX : this.opts.subMenusSubOffsetX, 12989 subOffsetY = level == 2 ? this.opts.mainMenuSubOffsetY : this.opts.subMenusSubOffsetY, 12990 x, y, leftPos; 12991 12992 if (horizontalParent) { 12993 x = this.opts.rightToLeftSubMenus ? itemW - subW - subOffsetX : subOffsetX; 12994 y = this.opts.bottomToTopSubMenus ? -subH - subOffsetY : itemH + subOffsetY; 12995 } else { 12996 x = this.opts.rightToLeftSubMenus ? subOffsetX - subW : subW - subOffsetX; 12997 y = this.opts.bottomToTopSubMenus ? itemH - subOffsetY - subH : subOffsetY; 12998 } 12999 if (this.opts.keepInViewport && !this.isCollapsible()) { 13000 if (this.isFixed()) { 13001 itemX -= winX; 13002 itemY -= winY; 13003 winX = winY = 0; 13004 } 13005 var absX = itemX + x, 13006 absY = itemY + y; 13007 if (this.opts.rightToLeftSubMenus && absX < winX) { 13008 x = horizontalParent ? winX - absX + x : itemW - subOffsetX; 13009 } else if (!this.opts.rightToLeftSubMenus && absX + subW > winX + containerOffsetX ) { 13010 x = horizontalParent ? winX + containerOffsetX - subW - absX + x : subOffsetX - subW; 13011 } 13012 if (!horizontalParent) { 13013 if (subH < winH && absY + subH > winY + winH) { 13014 y += winY + winH - subH - absY; 13015 } else if (subH >= winH || absY < winY) { 13016 y += winY - absY; 13017 } 13018 } 13019 // do we need scrolling? 13020 // 0.49 added for the sake of IE9/FF4+ where we might be dealing with float numbers for "subH" 13021 if (mouse && (horizontalParent && (absY + subH > winY + winH + 0.49 || absY < winY) || !horizontalParent && subH > winH + 0.49)) { 13022 var self = this; 13023 if (!$sub.dataSM('scroll-arrows')) { 13024 $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]]) 13025 .bind({ 13026 mouseenter: function() { self.menuScroll($sub, $(this).hasClass('scroll-up')); }, 13027 mouseleave: function(e) { 13028 self.menuScrollStop($sub); 13029 self.menuScrollOut($sub, e); 13030 }, 13031 'mousewheel DOMMouseScroll': function(e) { e.preventDefault(); } 13032 }) 13033 .insertAfter($sub) 13034 ); 13035 } 13036 // bind events to show/hide arrows on hover and save scrolling data for this sub 13037 var vportY = winY - (itemY + itemH); 13038 $sub.dataSM('scroll', { 13039 vportY: vportY, 13040 subH: subH, 13041 winH: winH, 13042 step: 1 13043 }) 13044 .bind({ 13045 'mouseover.smartmenus_scroll': function(e) { self.menuScrollOver($sub, e); }, 13046 'mouseout.smartmenus_scroll': function(e) { self.menuScrollOut($sub, e); }, 13047 'mousewheel.smartmenus_scroll DOMMouseScroll.smartmenus_scroll': function(e) { self.menuScrollMousewheel($sub, e); } 13048 }) 13049 .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
13049StartZIndex() + this.zIndexInc }) 13050 .eq(0).css('margin-top', vportY).end() 13051 .eq(1).css('margin-top', vportY + winH - this.getHeight($sub.dataSM('scroll-arrows').eq(1))).end() 13052 .eq(horizontalParent && this.opts.bottomToTopSubMenus ? 0 : 1).show(); 13053 } 13054 } 13055 if ( !$sub.closest('.menu-accordion').length ) { 13056 var rightPos = 'auto'; 13057 if ( $sub.closest('.grid-filters').length ) { 13058 if ( $sub.closest('.text-right').length ) { 13059 leftPos = '0px'; 13060 rightPos = 'auto'; 13061 } else { 13062 leftPos = 'auto'; 13063 rightPos = '0px'; 13064 } 13065 x = 0; 13066 } else { 13067 if ( $sub.hasClass('mega-menu-inner') ) { 13068 $sub.css({ width: containerW}); 13069 leftPos = -1 * (parseFloat($sub.closest('ul.menu-smart').offset().left) - parseFloat($sub.closest('.row-menu').offset().left)); 13070 if ( ! $('body').hasClass('megamenu-side-to-side') ) { 13071 leftPos += parseFloat($sub.closest('.row-menu-inner').css('paddingLeft')); 13072 } 13073 x = 0; 13074 } else { 13075 leftPos = (level > 2 ? $li.position().left - parseFloat($li.closest('ul').css('paddingLeft')) : $li.position().left ) + 'px'; 13076 x = (level > 2 && x >= 0) ? x + 1 : x - 1; 13077 } 13078 } 13079 } 13080 13081 // $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) }); 13082 $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) }); 13083 // IE iframe shim 13084 this.menuIframeShim($sub); 13085 if ($sub.dataSM('ie-shim')) { 13086 $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) }); 13087 } 13088 }, 13089 menuScroll: function($sub, up, wheel) { 13090 var y = parseFloat($sub.css('margin-top')), 13091 scroll = $sub.dataSM('scroll'), 13092 end = scroll.vportY + (up ? 0 : scroll.winH - scroll.subH), 13093 step = wheel || !this.opts.scrollAccelerate ? this.opts.scrollStep : Math.floor($sub.dataSM('scroll').step); 13094 $sub.add($sub.dataSM('ie-shim')).css('margin-top', Math.abs(end - y) > step ? y + (up ? step : -step) : end); 13095 y = parseFloat($sub.css('margin-top')); 13096 // show opposite arrow if appropriate 13097 if (up && y + scroll.subH > scroll.vportY + scroll.winH || !up && y < scroll.vportY) { 13098 $sub.dataSM('scroll-arrows').eq(up ? 1 : 0).show(); 13099 } 13100 // accelerate when not using mousewheel to scroll 13101 if (!wheel && this.opts.scrollAccelerate && $sub.dataSM('scroll').step < this.opts.scrollStep) { 13102 $sub.dataSM('scroll').step += 0.5; 13103 } 13104 // "y" and "end" might be float numbers in IE9/FF4+ so this weird way to check is used 13105 if (Math.abs(y - end) < 1) { 13106 $sub.dataSM('scroll-arrows').eq(up ? 0 : 1).hide(); 13107 $sub.dataSM('scroll').step = 1; 13108 } else if (!wheel) { 13109 var self = this; 13110 this.scrollTimeout = setTimeout(function() { self.menuScroll($sub, up); }, this.opts.scrollInterval); 13111 } 13112 }, 13113 menuScrollMousewheel: function($sub, e) { 13114 var $closestSub = $(e.target).closest('ul'); 13115 while ($closestSub.dataSM('in-mega')) { 13116 $closestSub = $closestSub.parent().closest('ul'); 13117 } 13118 if ($closestSub[0] == $sub[0]) { 13119 var up = (e.originalEvent.wheelDelta || -e.originalEvent.detail) > 0; 13120 if ($sub.dataSM('scroll-arrows').eq(up ? 0 : 1).is(':visible')) { 13121 this.menuScroll($sub, up, true); 13122 } 13123 } 13124 e.preventDefault(); 13125 }, 13126 menuScrollOut: function($sub, e) { 13127 var reClass = /^scroll-(up|down)/, 13128 $closestSub = $(e.relatedTarget).closest('ul'); 13129 while ($closestSub.dataSM('in-mega')) { 13130 $closestSub = $closestSub.parent().closest('ul'); 13131 } 13132 if (!reClass.test((e.relatedTarget || '').className) && ($sub[0] != e.relatedTarget && !$.contains($sub[0], e.relatedTarget) || $closestSub[0] != $sub[0])) { 13133 $sub.dataSM('scroll-arrows').css('visibility', 'hidden'); 13134 } 13135 }, 13136 menuScrollOver: function($sub, e) { 13137 var reClass = /^scroll-(up|down)/, 13138 $closestSub = $(e.target).closest('ul'); 13139 while ($closestSub.dataSM('in-mega')) { 13140 $closestSub = $closestSub.parent().closest('ul'); 13141 } 13142 if (!reClass.test(e.target.className) && $closestSub[0] == $sub[0]) { 13143 $sub.dataSM('scroll-arrows').css('visibility', 'visible'); 13144 } 13145 }, 13146 menuScrollStop: function($sub) { 13147 if (this.scrollTimeout) { 13148 clearTimeout(this.scrollTimeout); 13149 this.scrollTimeout = 0; 13150 $sub.dataSM('scroll').step = 1; 13151 } 13152 }, 13153 menuShow: function($sub) { 13154 if (!$sub.dataSM('beforefirstshowfired')) { 13155 $sub.dataSM('beforefirstshowfired', true); 13156 if (this.$root.triggerHandler('beforefirstshow.smapi', $sub[0]) === false) { 13157 return; 13158 } 13159 } 13160 if (this.$root.triggerHandler('beforeshow.smapi', $sub[0]) === false) { 13161 return; 13162 } 13163 this.menuFixLayout($sub); 13164 $sub.stop(true, true); 13165 if (!$sub.is(':visible')) { 13166 $sub.css({ 13167 'visibility': 'visible', 13168 'pointer-events': 'auto', 13169 }); 13170 // set z-index - for IE < 9 set it to the parent LI
13171 var zIndex = this.getStartZIndex() + (++this.zIndexInc); 13172 if (IElt9) { 13173 $sub.parent().css('z-index', zIndex); 13174 } else { 13175 $sub.css('z-index', zIndex); 13176 } 13177 // highlight parent item 13178 if (this.opts.keepHighlighted || this.isCollapsible()) { 13179 if ($sub.dataSM('parent-a').attr('data-type') != 'title') 13180 $sub.dataSM('parent-a').addClass('highlighted'); 13181 } 13182 // min/max-width fix - no way to rely purely on CSS as all UL's are nested 13183 if (this.opts.subMenusMinWidth || this.opts.subMenusMaxWidth) { 13184 if (!IElt8) { 13185 $sub.css({ width: ($sub.hasClass('mega-menu-inner')) ? $('.box-container').outerWidth() + 'px' : 'auto', minWidth: '', maxWidth: '' }).addClass('sm-nowrap'); 13186 if (this.opts.subMenusMinWidth) { 13187 $sub.css('min-width', this.opts.subMenusMinWidth); 13188 } 13189 if (this.opts.subMenusMaxWidth) { 13190 var noMaxWidth = this.getWidth($sub); 13191 if ( ! $sub.hasClass('mega-menu-inner') ) { 13192 $sub.css('max-width', this.opts.subMenusMaxWidth); 13193 } 13194 if (noMaxWidth > this.getWidth($sub)) { 13195 $sub.removeClass('sm-nowrap').css('width', this.opts.subMenusMaxWidth); 13196 } 13197 } 13198 // IE6,7 13199 } else { 13200 $sub.children().css('styleFloat', 'none'); 13201 if (IE6) { 13202 $sub.width(this.opts.subMenusMinWidth ? this.opts.subMenusMinWidth : 1) 13203 .children().children('a').css('white-space', 'nowrap'); 13204 } else { // IE7 13205 $sub.css({ width: ($sub.hasClass('mega-menu-inner')) ? $('.box-container').outerWidth() + 'px' : 'auto', minWidth: '', maxWidth: '' }).addClass('sm-nowrap'); 13206 if (this.opts.subMenusMinWidth) { 13207 $sub.css('min-width', this.opts.subMenusMinWidth); 13208 } 13209 } 13210 if (this.opts.subMenusMaxWidth) { 13211 var noMaxWidth = $sub.width(); 13212 if (IE6) { 13213 var maxWidth = $sub.css({ width: this.opts.subMenusMaxWidth, overflowX: 'hidden', overflowY: 'hidden' }).width(); 13214 if (noMaxWidth > maxWidth) { 13215 $sub.css({ width: maxWidth, overflowX: 'visible', overflowY: 'visible' }).children().children('a').css('white-space', ''); 13216 } else { 13217 $sub.css({ width: noMaxWidth, overflowX: 'visible', overflowY: 'visible' }); 13218 } 13219 } else { // IE7 13220 if ( ! $sub.hasClass('mega-menu-inner') ) { 13221 $sub.css('max-width', this.opts.subMenusMaxWidth); 13222 } 13223 if (noMaxWidth > $sub.width()) { 13224 $sub.removeClass('sm-nowrap').css('width', this.opts.subMenusMaxWidth); 13225 } else { 13226 $sub.width(noMaxWidth); 13227 } 13228 } 13229 } else { 13230 $sub.width($sub.width()); 13231 } 13232 $sub.children().css('styleFloat', 'left'); 13233 } 13234 } 13235 this.menuPosition($sub); 13236 // insert IE iframe shim 13237 if ($sub.dataSM('ie-shim')) { 13238 $sub.dataSM('ie-shim').insertBefore($sub); 13239 } 13240 var complete = function() { 13241 // fix: "overflow: hidden;" is not reset on animation complete in jQuery < 1.9.0 in Chrome when global "box-sizing: border-box;" is used 13242 $sub.css('overflow', ''); 13243 }; 13244 // if sub is collapsible (mobile view) 13245 if (this.isCollapsible()) { 13246 if (this.opts.collapsibleShowFunction) { 13247 this.opts.collapsibleShowFunction.call(this, $sub, complete); 13248 } else { 13249 $sub.show(this.opts.collapsibleShowDuration, complete); 13250 } 13251 } else { 13252 if (this.opts.showFunction) { 13253 this.opts.showFunction.call(this, $sub, complete); 13254 } else { 13255 $sub.show(this.opts.showDuration, complete); 13256 } 13257 } 13258 // save new sub menu for this level 13259 this.visibleSubMenus[$sub.dataSM('level') - 1] = $sub; 13260 this.$root.triggerHandler('show.smapi', $sub[0]); 13261 } 13262 }, 13263 popupHide: function(noHideTimeout) { 13264 if (this.hideTimeout) { 13265 clearTimeout(this.hideTimeout); 13266 this.hideTimeout = 0; 13267 } 13268 var self = this; 13269 this.hideTimeout = setTimeout(function() { 13270 self.menuHideAll(); 13271 }, noHideTimeout ? 1 : this.opts.hideTimeout); 13272 }, 13273 popupShow: function(left, top) { 13274 if (!this.opts.isPopup) { 13275 alert('SmartMenus jQuery Error:\n\nIf you want to show this menu via the "popupShow" method, set the isPopup:true option.'); 13276 return; 13277 } 13278 if (this.hideTimeout) { 13279 clearTimeout(this.hideTimeout); 13280 this.hideTimeout = 0; 13281 } 13282 this.menuFixLayout(this.$root); 13283 this.$root.stop(true, true); 13284 if (!this.$root.is(':visible')) { 13285 this.$root.css({ left: left, top: top }); 13286 // IE iframe shim 13287 this.menuIframeShim(this.$root); 13288 if (this.$root.dataSM('ie-shim')) { 13289 this.$root.dataSM('ie-shim').css({ zIndex: this.$root.css('z-index'), width: this.getWidth(this.$root), height: this.getHeight(this.$root), left
13289: left, top: top }).insertBefore(this.$root); 13290 } 13291 // show menu 13292 if (this.opts.showFunction) { 13293 this.opts.showFunction.call(this, this.$root); 13294 } else { 13295 this.$root.show(this.opts.showDuration); 13296 } 13297 this.visibleSubMenus[0] = this.$root; 13298 } 13299 }, 13300 refresh: function() { 13301 this.menuHideAll(); 13302 this.$root.find('ul').each(function() { 13303 var $this = $(this); 13304 if ($this.dataSM('scroll-arrows')) { 13305 $this.dataSM('scroll-arrows').remove(); 13306 } 13307 }) 13308 .removeDataSM('in-mega') 13309 .removeDataSM('shown-before') 13310 .removeDataSM('ie-shim') 13311 .removeDataSM('scroll-arrows') 13312 .removeDataSM('parent-a') 13313 .removeDataSM('level') 13314 .removeDataSM('beforefirstshowfired'); 13315 this.$root.find('a.has-submenu').removeClass('has-submenu') 13316 .parent().removeDataSM('sub'); 13317 if (this.opts.subIndicators) { 13318 this.$root.find('span.sub-arrow').remove(); 13319 } 13320 if (this.opts.markCurrentItem) { 13321 this.$root.find('a.current').removeClass('current'); 13322 } 13323 this.subMenus = []; 13324 this.init(true); 13325 }, 13326 rootOut: function(e) { 13327 if (!this.handleEvents() || this.isTouchMode() || e.target == this.$root[0]) { 13328 return; 13329 } 13330 if (this.hideTimeout) { 13331 clearTimeout(this.hideTimeout); 13332 this.hideTimeout = 0; 13333 } 13334 if (!this.opts.showOnClick || !this.opts.hideOnClick) { 13335 var self = this; 13336 this.hideTimeout = setTimeout(function() { self.menuHideAll(); }, this.opts.hideTimeout); 13337 } 13338 }, 13339 rootOver: function(e) { 13340 if (!this.handleEvents() || this.isTouchMode() || e.target == this.$root[0]) { 13341 return; 13342 } 13343 if (this.hideTimeout) { 13344 clearTimeout(this.hideTimeout); 13345 this.hideTimeout = 0; 13346 } 13347 }, 13348 winResize: function(e) { 13349 if (!this.handleEvents()) { 13350 // we still need to resize the disable overlay if it's visible 13351 if (this.$disableOverlay) { 13352 var pos = this.$root.offset(); 13353 this.$disableOverlay.css({ 13354 top: pos.top, 13355 left: pos.left, 13356 width: this.$root.outerWidth(), 13357 height: this.$root.outerHeight() 13358 }); 13359 } 13360 return; 13361 } 13362 // hide sub menus on resize - on mobile do it only on orientation change 13363 if (!this.isCollapsible() && (!('onorientationchange' in window) || e.type == 'orientationchange')) { 13364 if (this.activatedItems.length) { 13365 this.activatedItems[this.activatedItems.length - 1][0].blur(); 13366 } 13367 this.menuHideAll(); 13368 } 13369 } 13370 } 13371 }); 13372 13373 $.fn.dataSM = function(key, val) { 13374 if (val) { 13375 return this.data(key + '_smartmenus', val); 13376 } 13377 return this.data(key + '_smartmenus'); 13378 } 13379 13380 $.fn.removeDataSM = function(key) { 13381 return this.removeData(key + '_smartmenus'); 13382 } 13383 13384 $.fn.smartmenus = function(options) { 13385 if (typeof options == 'string') { 13386 var args = arguments, 13387 method = options; 13388 Array.prototype.shift.call(args); 13389 return this.each(function() { 13390 var smartmenus = $(this).data('smartmenus'); 13391 if (smartmenus && smartmenus[method]) { 13392 smartmenus[method].apply(smartmenus, args); 13393 } 13394 }); 13395 } 13396 var opts = $.extend({}, $.fn.smartmenus.defaults, options); 13397 return this.each(function() { 13398 new $.SmartMenus(this, opts); 13399 }); 13400 } 13401 13402 // default settings 13403 $.fn.smartmenus.defaults = { 13404 isPopup: false, // is this a popup menu (can be shown via the popupShow/popupHide methods) or a permanent menu bar 13405 mainMenuSubOffsetX: 0, // pixels offset from default position
13406 mainMenuSubOffsetY: 0, // pixels offset from default position 13407 subMenusSubOffsetX: 0, // pixels offset from default position 13408 subMenusSubOffsetY: 0, // pixels offset from default position 13409 subMenusMinWidth: false, //'10em', // min-width for the sub menus (any CSS unit) - if set, the fixed width set in CSS will be ignored 13410 subMenusMaxWidth: false, //'20em', // max-width for the sub menus (any CSS unit) - if set, the fixed width set in CSS will be ignored 13411 subIndicators: true, // create sub menu indicators - creates a SPAN and inserts it in the A 13412 subIndicatorsPos: 'prepend', // position of the SPAN relative to the menu item content ('prepend', 'append') 13413 subIndicatorsText: '+', // [optionally] add text in the SPAN (e.g. '+') (you may want to check the CSS for the sub indicators too) 13414 scrollStep: 30, // pixels step when scrolling long sub menus that do not fit in the viewport height 13415 scrollInterval: 30, // interval between each scrolling step 13416 scrollAccelerate: true, // accelerate scrolling or use a fixed step 13417 showTimeout: 250, // timeout before showing the sub menus 13418 hideTimeout: 500, // timeout before hiding the sub menus 13419 showDuration: 0, // duration for show animation - set to 0 for no animation - matters only if showFunction:null 13420 showFunction: null, // custom function to use when showing a sub menu (the default is the jQuery 'show') 13421 // don't forget to call complete() at the end of whatever you do 13422 // e.g.: function($ul, complete) { $ul.fadeIn(250, complete); } 13423 hideDuration: 0, // duration for hide animation - set to 0 for no animation - matters only if hideFunction:null 13424 hideFunction: function($ul, complete) { $ul.fadeOut(200, complete); }, // custom function to use when hiding a sub menu (the default is the jQuery 'hide') 13425 // don't forget to call complete() at the end of whatever you do 13426 // e.g.: function($ul, complete) { $ul.fadeOut(250, complete); } 13427 collapsibleShowDuration:0, // duration for show animation for collapsible sub menus - matters only if collapsibleShowFunction:null 13428 collapsibleShowFunction:function($ul, complete) { $ul.slideDown(200, complete); }, // custom function to use when showing a collapsible sub menu 13429 // (i.e. when mobile styles are used to make the sub menus collapsible) 13430 collapsibleHideDuration:0, // duration for hide animation for collapsible sub menus - matters only if collapsibleHideFunction:null 13431 collapsibleHideFunction:function($ul, complete) { $ul.slideUp(200, complete); }, // custom function to use when hiding a collapsible sub menu 13432 // (i.e. when mobile styles are used to make the sub menus collapsible) 13433 showOnClick: false, // show the first-level sub menus onclick instead of onmouseover (matters only for mouse input) 13434 hideOnClick: true, // hide the sub menus on click/tap anywhere on the page 13435 keepInViewport: true, // reposition the sub menus if needed to make sure they always appear inside the viewport 13436 keepHighlighted: true, // keep all ancestor items of the current sub menu highlighted (adds the 'highlighted' class to the A's) 13437 markCurrentItem: false, // automatically add the 'current' class to the A element of the item linking to the current URL 13438 markCurrentTree: true, // add the 'current' class also to the A elements of all ancestor items of the current item 13439 rightToLeftSubMenus: false, // right to left display of the sub menus (check the CSS for the sub indicators' position) 13440 bottomToTopSubMenus: false, // bottom to top display of the sub menus 13441 overlapControlsInIE: true // make sure sub menus appear on top of special OS controls in IE (i.e. SELECT, OBJECT, EMBED, etc.) 13442 }; 13443 13444})(jQuery); 13445/* 13446 * jQuery Easing v1.4.1 - http://gsgd.co.uk/sandbox/jquery/easing/ 13447 * Open source under the BSD License. 13448 * Copyright © 2008 George McGinley Smith 13449 * All rights reserved. 13450 * https://raw.github.com/gdsmith/jquery.easing/master/LICENSE 13451*/ 13452 13453/* globals jQuery, define, module, require */ 13454(function (factory) { 13455 if (typeof define === "function" && define.amd) { 13456 define(['jquery'], function ($) { 13457 return factory($); 13458 }); 13459 } else if (typeof module === "object" && typeof module.exports === "object") { 13460 module.exports = factory(require('jquery')); 13461 } else { 13462 factory(jQuery); 13463 } 13464})(function($){ 13465 13466 // Preserve the original jQuery "swing" easing as "jswing" 13467 if (typeof $.easing !== 'undefined') { 13468 $.easing['jswing'] = $.easing['swing']; 13469 } 13470 13471 var pow = Math.pow, 13472 sqrt = Math.sqrt, 13473 sin = Math.sin, 13474 cos = Math.cos, 13475 PI = Math.PI,
13476 c1 = 1.70158, 13477 c2 = c1 * 1.525, 13478 c3 = c1 + 1, 13479 c4 = ( 2 * PI ) / 3, 13480 c5 = ( 2 * PI ) / 4.5; 13481 13482 // x is the fraction of animation progress, in the range 0..1 13483 function bounceOut(x) { 13484 var n1 = 7.5625, 13485 d1 = 2.75; 13486 if ( x < 1/d1 ) { 13487 return n1*x*x; 13488 } else if ( x < 2/d1 ) { 13489 return n1*(x-=(1.5/d1))*x + .75; 13490 } else if ( x < 2.5/d1 ) { 13491 return n1*(x-=(2.25/d1))*x + .9375; 13492 } else { 13493 return n1*(x-=(2.625/d1))*x + .984375; 13494 } 13495 } 13496 13497 $.extend( $.easing, { 13498 def: 'easeOutQuad', 13499 swing: function (x) { 13500 return $.easing[$.easing.def](x); 13501 }, 13502 easeInQuad: function (x) { 13503 return x * x; 13504 }, 13505 easeOutQuad: function (x) { 13506 return 1 - ( 1 - x ) * ( 1 - x ); 13507 }, 13508 easeInOutQuad: function (x) { 13509 return x < 0.5 ? 13510 2 * x * x : 13511 1 - pow( -2 * x + 2, 2 ) / 2; 13512 }, 13513 easeInCubic: function (x) { 13514 return x * x * x; 13515 }, 13516 easeOutCubic: function (x) { 13517 return 1 - pow( 1 - x, 3 ); 13518 }, 13519 easeInOutCubic: function (x) { 13520 return x < 0.5 ? 13521 4 * x * x * x : 13522 1 - pow( -2 * x + 2, 3 ) / 2; 13523 }, 13524 easeInQuart: function (x) { 13525 return x * x * x * x; 13526 }, 13527 easeOutQuart: function (x) { 13528 return 1 - pow( 1 - x, 4 ); 13529 }, 13530 easeInOutQuart: function (x) { 13531 return x < 0.5 ? 13532 8 * x * x * x * x : 13533 1 - pow( -2 * x + 2, 4 ) / 2; 13534 }, 13535 easeInQuint: function (x) { 13536 return x * x * x * x * x; 13537 }, 13538 easeOutQuint: function (x) { 13539 return 1 - pow( 1 - x, 5 ); 13540 }, 13541 easeInOutQuint: function (x) { 13542 return x < 0.5 ? 13543 16 * x * x * x * x * x : 13544 1 - pow( -2 * x + 2, 5 ) / 2; 13545 }, 13546 easeInSine: function (x) { 13547 return 1 - cos( x * PI/2 ); 13548 }, 13549 easeOutSine: function (x) { 13550 return sin( x * PI/2 ); 13551 }, 13552 easeInOutSine: function (x) { 13553 return -( cos( PI * x ) - 1 ) / 2; 13554 }, 13555 easeInExpo: function (x) { 13556 return x === 0 ? 0 : pow( 2, 10 * x - 10 ); 13557 }, 13558 easeOutExpo: function (x) { 13559 return x === 1 ? 1 : 1 - pow( 2, -10 * x ); 13560 }, 13561 easeInOutExpo: function (x) { 13562 return x === 0 ? 0 : x === 1 ? 1 : x < 0.5 ? 13563 pow( 2, 20 * x - 10 ) / 2 : 13564 ( 2 - pow( 2, -20 * x + 10 ) ) / 2; 13565 }, 13566 easeInCirc: function (x) { 13567 return 1 - sqrt( 1 - pow( x, 2 ) ); 13568 }, 13569 easeOutCirc: function (x) { 13570 return sqrt( 1 - pow( x - 1, 2 ) ); 13571 }, 13572 easeInOutCirc: function (x) { 13573 return x < 0.5 ? 13574 ( 1 - sqrt( 1 - pow( 2 * x, 2 ) ) ) / 2 : 13575 ( sqrt( 1 - pow( -2 * x + 2, 2 ) ) + 1 ) / 2; 13576 }, 13577 easeInElastic: function (x) { 13578 return x === 0 ? 0 : x === 1 ? 1 : 13579 -pow( 2, 10 * x - 10 ) * sin( ( x * 10 - 10.75 ) * c4 ); 13580 }, 13581 easeOutElastic: function (x) { 13582 return x === 0 ? 0 : x === 1 ? 1 : 13583 pow( 2, -10 * x ) * sin( ( x * 10 - 0.75 ) * c4 ) + 1; 13584 }, 13585 easeInOutElastic: function (x) { 13586 return x === 0 ? 0 : x === 1 ? 1 : x < 0.5 ? 13587 -( pow( 2, 20 * x - 10 ) * sin( ( 20 * x - 11.125 ) * c5 )) / 2 : 13588 pow( 2, -20 * x + 10 ) * sin( ( 20 * x - 11.125 ) * c5 ) / 2 + 1; 13589 }, 13590 easeInBack: function (x) { 13591 return c3 * x * x * x - c1 * x * x; 13592 }, 13593 easeOutBack: function (x) { 13594 return 1 + c3 * pow( x - 1, 3 ) + c1 * pow( x - 1, 2 ); 13595 }, 13596 easeInOutBack: function (x) { 13597 return x < 0.5 ? 13598 ( pow( 2 * x, 2 ) * ( ( c2 + 1 ) * 2 * x - c2 ) ) / 2 : 13599 ( pow( 2 * x - 2, 2 ) *( ( c2 + 1 ) * ( x * 2 - 2 ) + c2 ) + 2 ) / 2; 13600 }, 13601 easeInBounce: function (x) { 13602 return 1 - bounceOut( 1 - x ); 13603 }, 13604 easeOutBounce: bounceOut, 13605 easeInOutBounce: function (x) { 13606 return x < 0.5 ? 13607 ( 1 - bounceOut( 1 - 2 * x ) ) / 2 : 13608 ( 1 + bounceOut( 2 * x - 1 ) ) / 2; 13609 } 13610 }); 13611 return $; 13612}); 13613 13614/*! Copyright (c) 2011 Brandon Aaron (http://brandonaaron.net) 13615 * Licensed under the MIT License (LICENSE.txt). 13616 * 13617 * Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers. 13618 * Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix. 13619 * Thanks to: Seamus Leahy for adding deltaX and deltaY 13620 * 13621 * Version: 3.0.6 13622 * 13623 * Requires: 1.2.2+ 13624 */ 13625(function($) { 13626 var types = ['DOMMouseScroll', 'mousewheel']; 13627 if ($.event.fixHooks) { 13628 for (var i = types.length; i;) { 13629 $.event.fixHooks[types[--i]] = $.event.mouseHooks; 13630 } 13631 } 13632 $.event.special.mousewheel = { 13633 setup: function() { 13634 if (this.addEventListener) { 13635 for (var i = types.length; i;) { 13636 this.addEventListener(types[--i], handler, false); 13637 } 13638 } else { 13639 this.onmousewheel = handler; 13640 } 13641 }, 13642 teardown: function() { 13643 if (this.removeEventListener) { 13644 for (var i = types.length; i;) { 13645 this.removeEventListener(types[--i], handler, false); 13646 } 13647 } else { 13648 this.onmousewheel = null; 13649 } 13650 } 13651 }; 13652 $.fn.extend({ 13653 mousewheel: function(fn) { 13654 return fn ? this.bind("mousewheel", fn) : this.trigger("mousewheel"); 13655 }, 13656 unmousewheel: function(fn) { 13657 return this.unbind("mousewheel", fn); 13658 } 13659 }); 13660 13661 function handler(event) { 13662 var orgEvent = event || window.event, 13663 args = [].slice.call(arguments, 1), 13664 delta = 0, 13665 returnValue = true, 13666 deltaX = 0, 13667 deltaY = 0; 13668 event = $.event.fix(orgEvent); 13669 event.type = "mousewheel"; 13670 // Old school scrollwheel delta 13671 if (orgEvent.wheelDelta) { 13672 delta = orgEvent.wheelDelta / 120; 13673 } 13674 if (orgEvent.detail) { 13675 delta = -orgEvent.detail / 3; 13676 } 13677 // New school multidimensional scroll (touchpads) deltas 13678 deltaY = delta; 13679 // Gecko 13680 if (orgEvent.axis !== undefined && orgEvent.axis === orgEvent.HORIZONTAL_AXIS) { 13681 deltaY = 0; 13682 deltaX = -1 * delta; 13683 } 13684 // Webkit 13685 if (orgEvent.wheelDeltaY !== undefined) { 13686 deltaY = orgEvent.wheelDeltaY / 120; 13687 } 13688 if (orgEvent.wheelDeltaX !== undefined) { 13689 deltaX = -1 * orgEvent.wheelDeltaX / 120; 13690 } 13691 // Add event and delta to the front of the arguments 13692 args.unshift(event, delta, deltaX, deltaY); 13693 return ($.event.dispatch || $.event.handle).apply(this, args); 13694 } 13695})(jQuery); 13696/** 13697 * jQuery iLightBox - Revolutionary Lightbox Plugin 13698 * http://www.ilightbox.net/ 13699 * 13700 * @version: 2.2.4 - October 14, 2017 13701 * 13702 * @author: iProDev (Hemn Chawroka) 13703 * http://www.iprodev.com/ 13704 * 13705 */ 13706(function($, window, undefined) { 13707 13708 var extensions = { 13709 flash: ['swf'], 13710 image: ['bmp', 'gif', 'jpeg', 'jpg', 'png', 'tiff', 'tif', 'jfif', 'jpe', 'webp'], 13711 iframe: ['asp', 'aspx', 'cgi', 'cfm', 'htm', 'html', 'jsp', 'php', 'pl', 'php3', 'php4', 'php5', 'phtml', 'rb', 'rhtml', 'shtml', 'txt'], 13712 video: ['avi', 'mov', 'mpg', 'mpeg', 'movie', 'mp4', 'webm', 'ogv', 'ogg', '3gp', 'm4v'] 13713 }, 13714 13715 // Global DOM elements 13716 $win = $(window), 13717 $doc = $(document), 13718
13719 // Support indicators 13720 browser, 13721 transform, 13722 gpuAcceleration, 13723 fullScreenApi = '', 13724 userAgent = navigator.userAgent || navigator.vendor || window.opera, 13725 supportTouch = "ontouchstart" in window || navigator.msMaxTouchPoints || (navigator.maxTouchPoints && navigator.userAgent.indexOf('Windows') > -1), 13726 ishybrid = navigator.maxTouchPoints && navigator.userAgent.indexOf('Windows') > -1, 13727 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)), 13728 13729 // Events 13730 clickEvent = ishybrid ? "itap.iLightBox click.iLightBox" : supportTouch ? "itap.iLightBox" : "click.iLightBox", 13731 touchStartEvent = ishybrid ? "touchstart.iLightBox mousedown.iLightBox" : supportTouch ? "touchstart.iLightBox" : "mousedown.iLightBox", 13732 touchStopEvent = ishybrid ? "touchend.iLightBox mouseup.iLightBox" : supportTouch ? "touchend.iLightBox" : "mouseup.iLightBox", 13733 touchMoveEvent = ishybrid ? "touchmove.iLightBox mousemove.iLightBox" : supportTouch ? "touchmove.iLightBox" : "mousemove.iLightBox", 13734 13735 // Math shorthands 13736 abs = Math.abs, 13737 sqrt = Math.sqrt, 13738 round = Math.round, 13739 max = Math.max, 13740 min = Math.min, 13741 floor = Math.floor, 13742 random = Math.random, 13743 13744 pluginspages = { 13745 quicktime: 'http://www.apple.com/quicktime/download', 13746 flash: 'http://www.adobe.com/go/getflash' 13747 }, 13748 13749 iLightBox = function(el, options, items, instant) { 13750 var iL = this; 13751 13752 iL.options = options, 13753 iL.selector = options.selector || el, 13754 iL.context = document, 13755 iL.instant = instant; 13756 13757 if (items.length < 1) iL.attachItems(); 13758 else iL.items = items; 13759 13760 iL.vars = { 13761 total: iL.items.length, 13762 start: 0, 13763 current: null, 13764 next: null, 13765 prev: null, 13766 BODY: $('body'), 13767 loadRequests: 0, 13768 overlay: $('<div class="ilightbox-overlay"></div>'), 13769 loader: $('<div class="ilightbox-loader"><div></div></div>'), 13770 toolbar: $('<div class="ilightbox-toolbar"></div>'), 13771 innerToolbar: $('<div class="ilightbox-inner-toolbar"></div>'), 13772 title: $('<div class="ilightbox-title"></div>'), 13773 closeButton: $('<a class="ilightbox-close" title="' + iL.options.text.close + '"></a>'), 13774 fullScreenButton: $('<a class="ilightbox-fullscreen" title="' + iL.options.text.enterFullscreen + '"></a>'), 13775 innerPlayButton: $('<a class="ilightbox-play" title="' + iL.options.text.slideShow + '"></a>'), 13776 innerNextButton: $('<a class="ilightbox-next-button" title="' + iL.options.text.next + '"></a>'), 13777 innerPrevButton: $('<a class="ilightbox-prev-button" title="' + iL.options.text.previous + '"></a>'), 13778 holder: $('<div class="ilightbox-holder' + (supportTouch ? ' supportTouch' : '') + '" ondragstart="return false;"><div class="ilightbox-container"></div></div>'), 13779 nextPhoto: $('<div class="ilightbox-holder' + (supportTouch ? ' supportTouch' : '') + ' ilightbox-next" ondragstart="return false;"><div class="ilightbox-container"></div></div>'), 13780 prevPhoto: $('<div class="ilightbox-holder' + (supportTouch ? ' supportTouch' : '') + ' ilightbox-prev" ondragstart="return false;"><div class="ilightbox-container"></div></div>'), 13781 nextButton: $('<a class="ilightbox-button ilightbox-next-button" ondragstart="return false;" title="' + iL.options.text.next + '"><span></span></a>'), 13782 prevButton: $('<a class="ilightbox-button ilightbox-prev-button" ondragstart="return false;" title="' + iL.options.text.previous + '"><span></span></a>'),
13783 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>'), 13784 thumbs: false, 13785 nextLock: false, 13786 prevLock: false, 13787 hashLock: false, 13788 isMobile: false, 13789 mobileMaxWidth: 980, 13790 isInFullScreen: false, 13791 isSwipe: false, 13792 mouseID: 0, 13793 cycleID: 0, 13794 isPaused: 0, 13795 captionHeight: 39, 13796 }; 13797 13798 // Hideable elements with mousemove event 13799 iL.vars.hideableElements = iL.vars.nextButton.add(iL.vars.prevButton); 13800 13801 iL.normalizeItems(); 13802 13803 //Check necessary plugins 13804 iL.availPlugins(); 13805 13806 //Set startFrom 13807 iL.options.startFrom = (iL.options.startFrom > 0 && iL.options.startFrom >= iL.vars.total) ? iL.vars.total - 1 : iL.options.startFrom; 13808 13809 //If randomStart 13810 iL.options.startFrom = (iL.options.randomStart) ? floor(random() * iL.vars.total) : iL.options.startFrom; 13811 iL.vars.start = iL.options.startFrom; 13812 13813 if (instant) iL.instantCall(); 13814 else iL.patchItemsEvents(); 13815 13816 if (iL.options.linkId) { 13817 iL.hashChangeHandler(); 13818 $win.iLightBoxHashChange(function() { 13819 iL.hashChangeHandler(); 13820 }); 13821 } 13822 13823 if (supportTouch) { 13824 var RegExp = /(click|mouseenter|mouseleave|mouseover|mouseout)/ig, 13825 replace = "itap"; 13826 iL.options.caption.show = iL.options.caption.show.replace(RegExp, replace), 13827 iL.options.caption.hide = iL.options.caption.hide.replace(RegExp, replace), 13828 iL.options.social.show = iL.options.social.show.replace(RegExp, replace), 13829 iL.options.social.hide = iL.options.social.hide.replace(RegExp, replace); 13830 } 13831 13832 if (iL.options.controls.arrows || $(window).width() < UNCODE.mediaQuery) { 13833 $.extend(iL.options.styles, { 13834 nextOffsetX: ($(window).width() > UNCODE.mediaQuery) ? 36 : 4, 13835 prevOffsetX: ($(window).width() > UNCODE.mediaQuery) ? 36 : 4, 13836 nextOpacity: 0, 13837 prevOpacity: 0 13838 }); 13839 } 13840 }; 13841 13842 //iLightBox helpers 13843 iLightBox.prototype = { 13844 showLoader: function() { 13845 var iL = this; 13846 iL.vars.loadRequests += 1; 13847 if (iL.options.path.toLowerCase() == "horizontal") iL.vars.loader.addClass('ilightbox-show').stop().animate({ 13848 //top: '-30px' 13849 opacity: '1' 13850 }, iL.options.show.speed, 'easeOutCirc'); 13851 else iL.vars.loader.addClass('ilightbox-show').stop().animate({ 13852 //left: '-30px' 13853 opacity: '1' 13854 }, iL.options.show.speed, 'easeOutCirc'); 13855 }, 13856 13857 hideLoader: function() { 13858 var iL = this; 13859 iL.vars.loadRequests -= 1; 13860 iL.vars.loadRequests = (iL.vars.loadRequests < 0) ? 0 : iL.vars.loadRequests; 13861 if (iL.options.path.toLowerCase() == "horizontal") { 13862 if (iL.vars.loadRequests <= 0) iL.vars.loader.removeClass('ilightbox-show').stop().animate({ 13863 //top: '-192px' 13864 opacity: '0' 13865 }, iL.options.show.speed, 'easeInCirc'); 13866 } else { 13867 if (iL.vars.loadRequests <= 0) iL.vars.loader.removeClass('ilightbox-show').stop().animate({ 13868 //left: '-192px' 13869 opacity: '0' 13870 }, iL.options.show.speed, 'easeInCirc'); 13871 } 13872 }, 13873 13874 createUI: function() { 13875 var iL = this; 13876 13877 iL.ui = { 13878 currentElement: iL.vars.holder, 13879 nextElement: iL.vars.nextPhoto, 13880 prevElement: iL.vars.prevPhoto, 13881 currentItem: iL.vars.current, 13882 nextItem: iL.vars.next, 13883 prevItem: iL.vars.prev, 13884 hide: function() { 13885 iL.closeAction(); 13886 }, 13887 refresh: function() { 13888 (arguments.length > 0) ? iL.repositionPhoto(true): iL.repositionPhoto(); 13889 }, 13890 fullscreen: function() { 13891 iL.fullScreenAction(); 13892 } 13893 }; 13894 }, 13895 13896 attachItems: function() { 13897 var iL = this, 13898 itemsObject = new Array(), 13899 items = new Array(); 13900 13901 $(iL.selector, iL.context).each(function() { 13902 var t = $(this), 13903 URL = t.attr(iL.options.attr) || null, 13904 options = t.data("options") && eval("({" + t.data("options") + "})") || {}, 13905 caption = t.data('caption'), 13906 title = t.data('title'), 13907 type = t.data('type') || getTypeByExtension(URL), 13908 clone = t.data('lbox-clone') || false; 13909 13910 //Uncode addition ##START## 13911 if (type === false) { 13912 return; 13913 } 13914 //Uncode addition ##END## 13915 13916 if (t.data('lbox-clone') != undefined) return; 13917 13918 //Uncode addition ##START## 13919 if ( typeof t.attr('data-album') != 'undefined' && t.attr('data-album') != '' ) { 13920 var ALBUM_URLS = JSON.parse(t.attr('data-album')), 13921 URL_i, 13922 URLS_LENGHT = ALBUM_URLS.length; 13923 13924 for (URL_i = 0; URL_i < URLS_LENGHT; URL_i++) { 13925 if ( typeof ALBUM_URLS[URL_i].url !== 'undefined' && ALBUM_URLS[URL_i].url != '' ) { 13926 var item_opts = 'width:' + ALBUM_URLS[URL_i].width + ',height:' + ALBUM_URLS[URL_i].height + ',thumbnail: \'' + ALBUM_URLS[URL_i].thumbnail + '\''; 13927 item_opts = item_opts && eval("({" + item_opts + "})") || {}, 13928 items.push({ 13929 URL: ALBUM_URLS[URL_i].url, 13930 caption: ALBUM_URLS[URL_i].caption, 13931 title: ALBUM_URLS[URL_i].title, 13932 type: getTypeByExtension(ALBUM_URLS[URL_i].url), 13933 options: item_opts, 13934 clone: clone 13935 }); 13936 var newT = t; 13937 newT.attr('href',ALBUM_URLS[URL_i].url); 13938 if (!iL.instant) itemsObject.push(newT); 13939 } 13940 } 13941 } else { 13942 //Uncode addition ##END## 13943 items.push({ 13944 URL: URL, 13945 caption: caption, 13946 title: title, 13947 type: type, 13948 options: options, 13949 clone: clone 13950 }); 13951 } 13952 13953 13954 if (iL.vars != undefined) iL.vars.total = items.length; 13955 13956 if (!iL.instant) itemsObject.push(t); 13957 }); 13958 13959 iL.items = items, 13960 iL.itemsObject = itemsObject; 13961 13962 }, 13963 13964 normalizeItems: function() { 13965 var iL = this, 13966 newItems = new Array(); 13967 13968 $.each(iL.items, function(key, val) { 13969 13970 if (typeof val == "string") val = { 13971 url: val 13972 }; 13973 13974 var URL = val.url || val.URL || null, 13975 options = val.options || {}, 13976 caption = val.caption || null, 13977 title = val.title || null, 13978 type = (val.type) ? val.type.toLowerCase() : getTypeByExtension(URL), 13979 ext = (typeof URL != 'object') ? getExtension(URL) : ''; 13980 13981 options.thumbnail = options.thumbnail || ((type == "image") ? URL : null),
13982 options.videoType = options.videoType || null, 13983 options.skin = options.skin || iL.options.skin, 13984 options.width = options.width || null, 13985 options.height = options.height || null, 13986 options.mousewheel = (typeof options.mousewheel != 'undefined') ? options.mousewheel : true, 13987 options.swipe = (typeof options.swipe != 'undefined') ? options.swipe : true, 13988 options.social = (typeof options.social != 'undefined') ? options.social : iL.options.social.buttons && $.extend({}, {}, iL.options.social.buttons); 13989 13990 if (type == "video") { 13991 options.html5video = (typeof options.html5video != 'undefined') ? options.html5video : {}; 13992 13993 options.html5video.webm = options.html5video.webm || options.html5video.WEBM || null; 13994 options.html5video.controls = (typeof options.html5video.controls != 'undefined') ? options.html5video.controls : "controls"; 13995 options.html5video.preload = options.html5video.preload || "metadata"; 13996 options.html5video.autoplay = (typeof options.html5video.autoplay != 'undefined') ? options.html5video.autoplay : false; 13997 //UNCODE addition 13998 options.html5video.loop = (typeof options.html5video.loop != 'undefined') ? options.html5video.loop : false; 13999 } 14000 14001 if (!options.width || !options.height) { 14002 if (type == "video") options.width = 1280, options.height = 720; 14003 else if (type == "iframe") options.width = '100%', options.height = '90%'; 14004 else if (type == "flash") options.width = 1280, options.height = 720; 14005 } 14006 14007 delete val.url; 14008 val.index = key; 14009 val.URL = URL; 14010 val.caption = caption; 14011 val.title = title; 14012 val.type = type; 14013 val.options = options; 14014 val.ext = ext; 14015 14016 newItems.push(val); 14017 }); 14018 14019 iL.items = newItems; 14020 }, 14021 14022 instantCall: function() { 14023 var iL = this, 14024 key = iL.vars.start; 14025 14026 iL.vars.current = key; 14027 iL.vars.next = (iL.items[key + 1]) ? key + 1 : null; 14028 iL.vars.prev = (iL.items[key - 1]) ? key - 1 : null; 14029 14030 iL.addContents(); 14031 iL.patchEvents(); 14032 }, 14033 14034 addContents: function() { 14035 var iL = this, 14036 vars = iL.vars, 14037 opts = iL.options, 14038 viewport = getViewport(), 14039 path = opts.path.toLowerCase(), 14040 recognizingItems = vars.total > 0 && iL.items.filter(function(e, i, arr) { 14041 return ['image', 'flash', 'video'].indexOf(e.type) === -1 && typeof e.recognized === 'undefined' && (opts.smartRecognition || e.options.smartRecognition); 14042 }), 14043 needRecognition = recognizingItems.length > 0; 14044 14045 if (opts.mobileOptimizer && !opts.innerToolbar) 14046 vars.isMobile = viewport.width <= vars.mobileMaxWidth; 14047 14048 vars.overlay.addClass(opts.skin).hide().css('opacity', opts.overlay.opacity); 14049 14050 if (opts.linkId) 14051 vars.overlay[0].setAttribute('linkid', opts.linkId); 14052 14053 //Add Toolbar Buttons 14054 if (opts.controls.toolbar) { 14055 vars.toolbar.addClass(opts.skin).append(vars.closeButton); 14056 if (opts.controls.fullscreen) 14057 vars.toolbar.append(vars.fullScreenButton); 14058 if (opts.controls.slideshow) 14059 vars.toolbar.append(vars.innerPlayButton); 14060 if (vars.total > 1) 14061 vars.toolbar.append(vars.innerPrevButton).append(vars.innerNextButton); 14062 } 14063 14064 //Append elements to body 14065 vars.BODY.addClass('ilightbox-noscroll').append(vars.overlay).append(vars.loader).append(vars.holder).append(vars.nextPhoto).append(vars.prevPhoto); 14066 14067 if (!opts.innerToolbar) 14068 vars.BODY.append(vars.toolbar); 14069 if (opts.controls.arrows) 14070 vars.BODY.append(vars.nextButton).append(vars.prevButton); 14071 14072 if (opts.controls.thumbnail && vars.total > 1) { 14073 vars.BODY.append(vars.thumbnails); 14074 vars.thumbnails.addClass(opts.skin).addClass('ilightbox-' + path); 14075 $('div.ilightbox-thumbnails-grid', vars.thumbnails).empty(); 14076 vars.thumbs = true; 14077 } 14078 14079 //Configure loader and arrows 14080 var loaderCss = (opts.path.toLowerCase() == "horizontal") ? { 14081 left: parseInt((viewport.width / 2) - (vars.loader.outerWidth() / 2)) 14082 } : { 14083 top: parseInt((viewport.height / 2) - (vars.loader.outerHeight() / 2)) 14084 }; 14085 vars.loader.addClass(opts.skin).css(loaderCss); 14086 vars.nextButton.add(vars.prevButton).addClass(opts.skin); 14087 if (path == "horizontal") 14088 vars.loader.add(vars.nextButton).add(vars.prevButton).addClass('horizontal'); 14089 14090 // Configure arrow buttons 14091 vars.BODY[vars.isMobile ? 'addClass' : 'removeClass']('isMobile'); 14092 14093 if (!opts.infinite) { 14094 vars.prevButton.add(vars.prevButton).add(vars.innerPrevButton).add(vars.innerNextButton).removeClass('disabled'); 14095 14096 if (vars.current == 0) 14097 vars.prevButton.add(vars.innerPrevButton).addClass('disabled'); 14098 if (vars.current >= vars.total - 1) 14099 vars.nextButton.add(vars.innerNextButton).addClass('disabled'); 14100 } 14101 14102 if (opts.show.effect) { 14103 vars.overlay.stop().fadeIn(opts.show.speed); 14104 vars.toolbar.stop().fadeIn(opts.show.speed); 14105 } else { 14106 vars.overlay.show(); 14107 vars.toolbar.show(); 14108 } 14109 14110 var length = recognizingItems.length; 14111 if (needRecognition) { 14112 iL.showLoader(); 14113 14114 $.each(recognizingItems, function(key, val) { 14115 var resultFnc = function(result) { 14116 var key = -1, 14117 filter = iL.items.filter(function(e, i, arr) { 14118 if (e.URL == result.url) 14119 key = i; 14120 14121 return e.URL == result.url; 14122 }), 14123 self = iL.items[key]; 14124 14125 if (result) 14126 $.extend(true, self, { 14127 URL: result.source, 14128 type: result.type, 14129 recognized: true, 14130 options: { 14131 html5video: result.html5video, 14132 width: (result.type == "image") ? 0 : (result.width || self.width), 14133 height: (result.type == "image") ? 0 : (result.height || self.height), 14134 thumbnail: self.options.thumbnail || result.thumbnail 14135 } 14136 }); 14137 14138 length--; 14139 14140 if (length == 0) { 14141 iL.hideLoader(); 14142 14143 vars.dontGenerateThumbs = false;
14144 iL.generateThumbnails(); 14145 14146 if (opts.show.effect) 14147 setTimeout(function() { 14148 iL.generateBoxes(); 14149 }, opts.show.speed); 14150 else 14151 iL.generateBoxes(); 14152 } 14153 }; 14154 14155 iL.ogpRecognition(this, resultFnc); 14156 }); 14157 } 14158 else { 14159 if (opts.show.effect) 14160 setTimeout(function() { 14161 iL.generateBoxes(); 14162 }, opts.show.speed); 14163 else 14164 iL.generateBoxes(); 14165 } 14166 14167 iL.createUI(); 14168 14169 window.iLightBox = { 14170 close: function() { 14171 iL.closeAction(); 14172 }, 14173 fullscreen: function() { 14174 iL.fullScreenAction(); 14175 }, 14176 moveNext: function() { 14177 iL.moveTo('next'); 14178 }, 14179 movePrev: function() { 14180 iL.moveTo('prev'); 14181 }, 14182 goTo: function(index) { 14183 iL.goTo(index); 14184 }, 14185 refresh: function() { 14186 iL.refresh(); 14187 }, 14188 reposition: function() { 14189 (arguments.length > 0) ? iL.repositionPhoto(true): iL.repositionPhoto(); 14190 }, 14191 setOption: function(options) { 14192 iL.setOption(options); 14193 }, 14194 destroy: function() { 14195 iL.closeAction(); 14196 iL.dispatchItemsEvents(); 14197 } 14198 }; 14199 14200 if (opts.linkId) { 14201 vars.hashLock = true; 14202 window.location.hash = opts.linkId + '/' + vars.current; 14203 setTimeout(function() { 14204 vars.hashLock = false; 14205 }, 55); 14206 } 14207 14208 if (!opts.slideshow.startPaused) { 14209 iL.resume(); 14210 vars.innerPlayButton.removeClass('ilightbox-play').addClass('ilightbox-pause'); 14211 } 14212 14213 //Trigger the onOpen callback 14214 if (typeof iL.options.callback.onOpen == 'function') iL.options.callback.onOpen.call(iL); 14215 }, 14216 14217 loadContent: function(obj, opt, speed) { 14218 var iL = this, 14219 holder, item; 14220 14221 iL.createUI(); 14222 14223 obj.speed = speed || iL.options.effects.loadedFadeSpeed; 14224 14225 if (opt == 'current') { 14226 if (!obj.options.mousewheel) iL.vars.lockWheel = true; 14227 else iL.vars.lockWheel = false; 14228 14229 if (!obj.options.swipe) iL.vars.lockSwipe = true; 14230 else iL.vars.lockSwipe = false; 14231 } 14232 14233 switch (opt) { 14234 case 'current': 14235 holder = iL.vars.holder, item = iL.vars.current; 14236 break; 14237 case 'next': 14238 holder = iL.vars.nextPhoto, item = iL.vars.next; 14239 break; 14240 case 'prev': 14241 holder = iL.vars.prevPhoto, item = iL.vars.prev; 14242 break; 14243 } 14244 14245 holder.removeAttr('style class').addClass('ilightbox-holder' + (supportTouch ? ' supportTouch' : '')).addClass(obj.options.skin); 14246 $('div.ilightbox-inner-toolbar', holder).remove(); 14247 14248 if (obj.title || iL.options.innerToolbar) { 14249 var innerToolbar = iL.vars.innerToolbar.clone(); 14250 if (obj.title && iL.options.show.title) { 14251 var title = iL.vars.title.clone(); 14252 title.empty().html(obj.title); 14253 innerToolbar.append(title); 14254 } 14255 if (iL.options.innerToolbar) { 14256 innerToolbar.append((iL.vars.total > 1) ? iL.vars.toolbar.clone() : iL.vars.toolbar); 14257 } 14258 holder.prepend(innerToolbar); 14259 } 14260 14261 //console.warn('loadContent', arguments); 14262 14263 iL.loadSwitcher(obj, holder, item, opt); 14264 }, 14265 14266 loadSwitcher: function(obj, holder, item, opt) { 14267 var iL = this, 14268 opts = iL.options, 14269 api = { 14270 element: holder, 14271 position: item 14272 }; 14273 14274 switch (obj.type) { 14275 case 'image': 14276 //Trigger the onBeforeLoad callback 14277 if (typeof opts.callback.onBeforeLoad == 'function') opts.callback.onBeforeLoad.call(iL, iL.ui, item); 14278 if (typeof obj.options.onBeforeLoad == 'function') obj.options.onBeforeLoad.call(iL, api); 14279 14280 iL.loadImage(obj.URL, function(img) { 14281 //Trigger the onAfterLoad callback 14282 if (typeof opts.callback.onAfterLoad == 'function') opts.callback.onAfterLoad.call(iL, iL.ui, item); 14283 if (typeof obj.options.onAfterLoad == 'function') obj.options.onAfterLoad.call(iL, api); 14284 14285 var width = (img) ? img.width : 400, 14286 height = (img) ? img.height : 200; 14287 14288 holder.data({ 14289 naturalWidth: width, 14290 naturalHeight: height 14291 }); 14292 14293 $('div.ilightbox-container', holder).empty().append((img) ? '<img src="' + obj.URL + '" class="ilightbox-image" />' : '<span class="ilightbox-alert">' + opts.errors.loadImage + '</span>'); 14294 14295 //Trigger the onRender callback 14296 if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item); 14297 if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api); 14298 14299 iL.configureHolder(obj, opt, holder); 14300 }); 14301 14302 break; 14303
14304 case 'video': 14305 holder.data({ 14306 naturalWidth: obj.options.width, 14307 naturalHeight: obj.options.height 14308 }); 14309 14310 if (opt === 'current') { 14311 iL.addContent(holder, obj); 14312 14313 //Trigger the onRender callback 14314 if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item); 14315 if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api); 14316 } else { 14317 $('div.ilightbox-container', holder).empty(); 14318 } 14319 14320 iL.configureHolder(obj, opt, holder); 14321 14322 break; 14323 14324 case 'iframe': 14325 //iL.showLoader(); 14326 holder.data({ 14327 naturalWidth: obj.options.width, 14328 naturalHeight: obj.options.height 14329 }); 14330 14331 iL.configureHolder(obj, opt, holder); 14332 14333 if (opt === 'current') { 14334 var el = iL.addContent(holder, obj); 14335 14336 //Trigger the onRender callback 14337 if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item); 14338 if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api); 14339 14340 //Trigger the onBeforeLoad callback 14341 if (typeof opts.callback.onBeforeLoad == 'function') opts.callback.onBeforeLoad.call(iL, iL.ui, item); 14342 if (typeof obj.options.onBeforeLoad == 'function') obj.options.onBeforeLoad.call(iL, api); 14343 14344 el.bind('load', function() { 14345 //Trigger the onAfterLoad callback 14346 if (typeof opts.callback.onAfterLoad == 'function') opts.callback.onAfterLoad.call(iL, iL.ui, item); 14347 if (typeof obj.options.onAfterLoad == 'function') obj.options.onAfterLoad.call(iL, api); 14348 14349 //iL.hideLoader(); 14350 el.unbind('load'); 14351 }); 14352 } else { 14353 $('div.ilightbox-container', holder).empty(); 14354 } 14355 14356 break; 14357 14358 case 'inline': 14359 var el = $(obj.URL), 14360 content = iL.addContent(holder, obj), 14361 images = findImageInElement(holder); 14362 14363 holder.data({ 14364 naturalWidth: (iL.items[item].options.width || el.outerWidth()), 14365 naturalHeight: (iL.items[item].options.height || el.outerHeight()) 14366 }); 14367 content.children().eq(0).show(); 14368 14369 //Trigger the onRender callback 14370 if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item); 14371 if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api); 14372 14373 //Trigger the onBeforeLoad callback 14374 if (typeof opts.callback.onBeforeLoad == 'function') opts.callback.onBeforeLoad.call(iL, iL.ui, item); 14375 if (typeof obj.options.onBeforeLoad == 'function') obj.options.onBeforeLoad.call(iL, api); 14376 14377 iL.loadImage(images, function() { 14378 //Trigger the onAfterLoad callback 14379 if (typeof opts.callback.onAfterLoad == 'function') opts.callback.onAfterLoad.call(iL, iL.ui, item); 14380 if (typeof obj.options.onAfterLoad == 'function') obj.options.onAfterLoad.call(iL, api); 14381 14382 iL.configureHolder(obj, opt, holder); 14383 }); 14384 14385 break; 14386 14387 case 'flash': 14388 var el = iL.addContent(holder, obj); 14389 14390 holder.data({ 14391 naturalWidth: (iL.items[item].options.width || el.outerWidth()), 14392 naturalHeight: (iL.items[item].options.height || el.outerHeight()) 14393 }); 14394 14395 //Trigger the onRender callback 14396 if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item); 14397 if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api); 14398 14399 iL.configureHolder(obj, opt, holder); 14400 14401 break; 14402 14403 case 'ajax': 14404 var ajax = obj.options.ajax || {}; 14405 //Trigger the onBeforeLoad callback 14406 if (typeof opts.callback.onBeforeLoad == 'function') opts.callback.onBeforeLoad.call(iL, iL.ui, item); 14407 if (typeof obj.options.onBeforeLoad == 'function') obj.options.onBeforeLoad.call(iL, api); 14408 14409 iL.showLoader(); 14410 $.ajax({ 14411 url: obj.URL || opts.ajaxSetup.url, 14412 data: ajax.data || null, 14413 dataType: ajax.dataType || "html", 14414 type: ajax.type || opts.ajaxSetup.type, 14415 cache: ajax.cache || opts.ajaxSetup.cache, 14416 crossDomain: ajax.crossDomain || opts.ajaxSetup.crossDomain, 14417 global: ajax.global || opts.ajaxSetup.global, 14418 ifModified: ajax.ifModified || opts.ajaxSetup.ifModified, 14419 username: ajax.username || opts.ajaxSetup.username, 14420 password: ajax.password || opts.ajaxSetup.password, 14421 beforeSend: ajax.beforeSend || opts.ajaxSetup.beforeSend, 14422 complete: ajax.complete || opts.ajaxSetup.complete, 14423 success: function(data, textStatus, jqXHR) { 14424 iL.hideLoader(); 14425 14426 var el = $(data), 14427 container = $('div.ilightbox-container', holder), 14428 elWidth = iL.items[item].options.width || parseInt(el[0].getAttribute('width')), 14429 elHeight = iL.items[item].options.height || parseInt(el[0].getAttribute('height')), 14430 css = (el[0].getAttribute('width') && el[0].getAttribute('height')) ? { 14431 'overflow': 'hidden' 14432 } : {}; 14433 14434 container.empty().append($('<div class="ilightbox-wrapper"></div>').css(css).html(el)); 14435 holder.show().data({
14436 naturalWidth: (elWidth || container.outerWidth()), 14437 naturalHeight: (elHeight || container.outerHeight()) 14438 }).hide(); 14439 14440 //Trigger the onRender callback 14441 if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item); 14442 if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api); 14443 14444 var images = findImageInElement(holder); 14445 iL.loadImage(images, function() { 14446 //Trigger the onAfterLoad callback 14447 if (typeof opts.callback.onAfterLoad == 'function') opts.callback.onAfterLoad.call(iL, iL.ui, item); 14448 if (typeof obj.options.onAfterLoad == 'function') obj.options.onAfterLoad.call(iL, api); 14449 14450 iL.configureHolder(obj, opt, holder); 14451 }); 14452 14453 opts.ajaxSetup.success(data, textStatus, jqXHR); 14454 if (typeof ajax.success == 'function') ajax.success(data, textStatus, jqXHR); 14455 }, 14456 error: function(jqXHR, textStatus, errorThrown) { 14457 //Trigger the onAfterLoad callback 14458 if (typeof opts.callback.onAfterLoad == 'function') opts.callback.onAfterLoad.call(iL, iL.ui, item); 14459 if (typeof obj.options.onAfterLoad == 'function') obj.options.onAfterLoad.call(iL, api); 14460 14461 iL.hideLoader(); 14462 $('div.ilightbox-container', holder).empty().append('<span class="ilightbox-alert">' + opts.errors.loadContents + '</span>'); 14463 iL.configureHolder(obj, opt, holder); 14464 14465 opts.ajaxSetup.error(jqXHR, textStatus, errorThrown); 14466 if (typeof ajax.error == 'function') ajax.error(jqXHR, textStatus, errorThrown); 14467 } 14468 }); 14469 14470 break; 14471 14472 case 'html': 14473 var object = obj.URL, 14474 el 14475 container = $('div.ilightbox-container', holder); 14476 14477 if (object[0].nodeName) el = object.clone(); 14478 else { 14479 var dom = $(object); 14480 if (dom.selector) el = $('<div>' + dom + '</div>'); 14481 else el = dom; 14482 } 14483 14484 var elWidth = iL.items[item].options.width || parseInt(el.attr('width')), 14485 elHeight = iL.items[item].options.height || parseInt(el.attr('height')); 14486 14487 iL.addContent(holder, obj); 14488 14489 el.appendTo(document.documentElement).hide(); 14490 14491 //Trigger the onRender callback 14492 if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item); 14493 if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api); 14494 14495 var images = findImageInElement(holder); 14496 14497 //Trigger the onBeforeLoad callback 14498 if (typeof opts.callback.onBeforeLoad == 'function') opts.callback.onBeforeLoad.call(iL, iL.ui, item); 14499 if (typeof obj.options.onBeforeLoad == 'function') obj.options.onBeforeLoad.call(iL, api); 14500 14501 iL.loadImage(images, function() { 14502 //Trigger the onAfterLoad callback 14503 if (typeof opts.callback.onAfterLoad == 'function') opts.callback.onAfterLoad.call(iL, iL.ui, item); 14504 if (typeof obj.options.onAfterLoad == 'function') obj.options.onAfterLoad.call(iL, api); 14505 14506 holder.show().data({ 14507 naturalWidth: (elWidth || container.outerWidth()), 14508 naturalHeight: (elHeight || container.outerHeight()) 14509 }).hide(); 14510 el.remove(); 14511 14512 iL.configureHolder(obj, opt, holder); 14513 }); 14514 14515 break; 14516 } 14517 }, 14518 14519 configureHolder: function(obj, opt, holder) { 14520 var iL = this, 14521 vars = iL.vars, 14522 opts = iL.options; 14523 14524 if (opt != "current")(opt == "next") ? holder.addClass('ilightbox-next') : holder.addClass('ilightbox-prev'); 14525 14526 if (opt == "current") 14527 var item = vars.current; 14528 else if (opt == "next") 14529 var opacity = opts.styles.nextOpacity, 14530 item = vars.next; 14531 else 14532 var opacity = opts.styles.prevOpacity, 14533 item = vars.prev; 14534 14535 var api = { 14536 element: holder, 14537 position: item 14538 }; 14539 14540 iL.items[item].options.width = iL.items[item].options.width || 0, 14541 iL.items[item].options.height = iL.items[item].options.height || 0; 14542 14543 if (opt == "current") { 14544 if (opts.show.effect) holder.css(transform, gpuAcceleration).fadeIn(obj.speed, function() { 14545 holder.css(transform, ''); 14546 if (obj.caption) { 14547 iL.setCaption(obj, holder); 14548 var caption = $('div.ilightbox-caption', holder), 14549 percent = parseInt((caption.outerHeight() / holder.outerHeight()) * 100); 14550 if (opts.caption.start & percent <= 50) caption.fadeIn(opts.effects.fade
14550Speed); 14551 } 14552 14553 var social = obj.options.social; 14554 if (social) { 14555 iL.setSocial(social, obj.URL, holder); 14556 if (opts.social.start) $('div.ilightbox-social', holder).fadeIn(opts.effects.fadeSpeed); 14557 } 14558 14559 //Generate thumbnails 14560 iL.generateThumbnails(); 14561 14562 //Trigger the onShow callback 14563 if (typeof opts.callback.onShow == 'function') opts.callback.onShow.call(iL, iL.ui, item); 14564 if (typeof obj.options.onShow == 'function') obj.options.onShow.call(iL, api); 14565 }); 14566 else { 14567 holder.show(); 14568 14569 //Generate thumbnails 14570 iL.generateThumbnails(); 14571 14572 //Trigger the onShow callback 14573 if (typeof opts.callback.onShow == 'function') opts.callback.onShow.call(iL, iL.ui, item); 14574 if (typeof obj.options.onShow == 'function') obj.options.onShow.call(iL, api); 14575 } 14576 } else { 14577 if (opts.show.effect) holder.fadeTo(obj.speed, opacity, function() { 14578 if (opt == "next") vars.nextLock = false; 14579 else vars.prevLock = false; 14580 14581 //Generate thumbnails 14582 iL.generateThumbnails(); 14583 14584 //Trigger the onShow callback 14585 if (typeof opts.callback.onShow == 'function') opts.callback.onShow.call(iL, iL.ui, item); 14586 if (typeof obj.options.onShow == 'function') obj.options.onShow.call(iL, api); 14587 }); 14588 else { 14589 holder.css({ 14590 opacity: opacity 14591 }).show(); 14592 if (opt == "next") vars.nextLock = false; 14593 else vars.prevLock = false; 14594 14595 //Generate thumbnails 14596 iL.generateThumbnails(); 14597 14598 //Trigger the onShow callback 14599 if (typeof opts.callback.onShow == 'function') opts.callback.onShow.call(iL, iL.ui, item); 14600 if (typeof obj.options.onShow == 'function') obj.options.onShow.call(iL, api); 14601 } 14602 } 14603 14604 setTimeout(function() { 14605 iL.repositionPhoto(); 14606 }, 0); 14607 }, 14608 14609 generateBoxes: function() { 14610 var iL = this, 14611 vars = iL.vars, 14612 opts = iL.options; 14613 14614 if (opts.infinite && vars.total >= 3) { 14615 if (vars.current == vars.total - 1) vars.next = 0; 14616 if (vars.current == 0) vars.prev = vars.total - 1; 14617 } else opts.infinite = false; 14618 14619 //UNCODE addition 14620 if ( typeof iL.items[vars.current] == 'undefined' ) 14621 vars.current = 0; 14622 14623 iL.loadContent(iL.items[vars.current], 'current', opts.show.speed); 14624 14625 if (iL.items[vars.next]) iL.loadContent(iL.items[vars.next], 'next', opts.show.speed); 14626 if (iL.items[vars.prev]) iL.loadContent(iL.items[vars.prev], 'prev', opts.show.speed); 14627 }, 14628 14629 generateThumbnails: function() { 14630 var iL = this, 14631 vars = iL.vars, 14632 opts = iL.options, 14633 timeOut = null; 14634 14635 if (vars.thumbs && !iL.vars.dontGenerateThumbs) { 14636 var thumbnails = vars.thumbnails, 14637 container = $('div.ilightbox-thumbnails-container', thumbnails), 14638 grid = $('div.ilightbox-thumbnails-grid', container), 14639 i = 0; 14640 14641 grid.removeAttr('style').empty(); 14642 14643 $.each(iL.items, function(key, val) { 14644 var isActive = (vars.current == key) ? 'ilightbox-active' : '', 14645 opacity = (vars.current == key) ? opts.thumbnails.activeOpacity : opts.thumbnails.normalOpacity, 14646 thumb = val.options.thumbnail, 14647 thumbnail = $('<div class="ilightbox-thumbnail"></div>'), 14648 icon = $('<div class="ilightbox-thumbnail-icon"></div>'); 14649 14650 thumbnail.css({ 14651 opacity: 0 14652 }).addClass(isActive); 14653 14654 if ((val.type == "video" || val.type == "flash") && typeof val.options.icon == 'undefined') { 14655 icon.addClass('ilightbox-thumbnail-video'); 14656 thumbnail.append(icon); 14657 } else if (val.options.icon) { 14658 icon.addClass('ilightbox-thumbnail-' + val.options.icon); 14659 thumbnail.append(icon); 14660 } 14661 14662 if (thumb) iL.loadImage(thumb, function(img) { 14663 i++; 14664 if (img) thumbnail.data({ 14665 naturalWidth: img.width, 14666 naturalHeight: img.height 14667 }).append('<img src="' + thumb + '" border="0" />'); 14668 else thumbnail.data({ 14669 naturalWidth: opts.thumbnails.maxWidth, 14670 naturalHeight: opts.thumbnails.maxHeight 14671 }); 14672 14673 clearTimeout(timeOut); 14674 timeOut = setTimeout(function() { 14675 iL.positionThumbnails(thumbnails, container, grid); 14676 }, 20); 14677 setTimeout(function() { 14678 thumbnail.fadeTo(opts.effects.loadedFadeSpeed, opacity); 14679 }, i * 20); 14680 }); 14681 14682 grid.append(thumbnail); 14683 }); 14684 iL.vars.dontGenerateThumbs = true; 14685 } 14686 }, 14687
14688 positionThumbnails: function(thumbnails, container, grid) { 14689 var iL = this, 14690 vars = iL.vars, 14691 opts = iL.options, 14692 viewport = getViewport(), 14693 path = opts.path.toLowerCase(); 14694 14695 if (!thumbnails) thumbnails = vars.thumbnails; 14696 if (!container) container = $('div.ilightbox-thumbnails-container', thumbnails); 14697 if (!grid) grid = $('div.ilightbox-thumbnails-grid', container); 14698 14699 var thumbs = $('.ilightbox-thumbnail', grid), 14700 widthAvail = (path == 'horizontal') ? viewport.width - opts.styles.pageOffsetX : thumbs.eq(0).outerWidth() - opts.styles.pageOffsetX, 14701 heightAvail = (path == 'horizontal') ? thumbs.eq(0).outerHeight() - opts.styles.pageOffsetY : viewport.height - opts.styles.pageOffsetY, 14702 gridWidth = (path == 'horizontal') ? 0 : widthAvail, 14703 gridHeight = (path == 'horizontal') ? heightAvail : 0, 14704 active = $('.ilightbox-active', grid), 14705 gridCss = {}, 14706 css = {}; 14707 14708 if (arguments.length < 3) { 14709 thumbs.css({ 14710 opacity: opts.thumbnails.normalOpacity 14711 }); 14712 active.css({ 14713 opacity: opts.thumbnails.activeOpacity 14714 }); 14715 } 14716 14717 thumbs.each(function(i) { 14718 var t = $(this), 14719 data = t.data(), 14720 width = (path == 'horizontal') ? 0 : opts.thumbnails.maxWidth; 14721 height = (path == 'horizontal') ? opts.thumbnails.maxHeight : 0; 14722 dims = iL.getNewDimenstions(width, height, data.naturalWidth, data.naturalHeight, true); 14723 14724 t.css({ 14725 width: dims.width, 14726 height: dims.height 14727 }); 14728 if (path == 'horizontal') t.css({ 14729 'float': 'left' 14730 }); 14731 14732 (path == 'horizontal') ? ( 14733 gridWidth += t.outerWidth() 14734 ) : ( 14735 gridHeight += t.outerHeight() 14736 ); 14737 }); 14738 14739 gridCss = { 14740 width: gridWidth, 14741 height: gridHeight 14742 }; 14743 14744 grid.css(gridCss); 14745 14746 gridCss = {}; 14747 14748 var gridOffset = grid.offset(), 14749 activeOffset = (active.length) ? active.offset() : { 14750 top: parseInt(heightAvail / 2), 14751 left: parseInt(widthAvail / 2) 14752 }; 14753 14754 gridOffset.top = (gridOffset.top - $doc.scrollTop()), 14755 gridOffset.left = (gridOffset.left - $doc.scrollLeft()), 14756 activeOffset.top = (activeOffset.top - gridOffset.top - $doc.scrollTop()), 14757 activeOffset.left = (activeOffset.left - gridOffset.left - $doc.scrollLeft()); 14758 14759 (path == 'horizontal') ? ( 14760 gridCss.top = 0, 14761 gridCss.left = parseInt((widthAvail / 2) - activeOffset.left - (active.outerWidth() / 2)) 14762 ) : ( 14763 gridCss.top = parseInt(((heightAvail / 2) - activeOffset.top - (active.outerHeight() / 2))), 14764 gridCss.left = 0 14765 ); 14766 14767 if (arguments.length < 3) grid.stop().animate(gridCss, opts.effects.repositionSpeed, 'easeOutCirc'); 14768 else grid.css(gridCss); 14769 }, 14770 14771 loadImage: function(image, callback) { 14772 if (!$.isArray(image)) image = [image]; 14773 14774 var iL = this, 14775 length = image.length; 14776 14777 if (length > 0) { 14778 iL.showLoader(); 14779 $.each(image, function(index, value) { 14780 var img = new Image(); 14781 img.onload = function() { 14782 length -= 1; 14783 if (length == 0) { 14784 iL.hideLoader(); 14785 callback(img); 14786 } 14787 }; 14788 img.onerror = img.onabort = function() { 14789 length -= 1; 14790 if (length == 0) { 14791 iL.hideLoader(); 14792 callback(false); 14793 } 14794 }; 14795 img.src = image[index]; 14796 }); 14797 } else callback(false); 14798 }, 14799 14800 patchItemsEvents: function() { 14801 var iL = this, 14802 vars = iL.vars, 14803 clickEvent = ishybrid ? "itap.iL click.iL" : supportTouch ? "itap.iL" : "click.iL", 14804 vEvent = ishybrid ? "click.iL itap.iL" : supportTouch ? "click.iL" : "itap.iL"; 14805 14806 if (iL.context && iL.selector) { 14807 var $items = $(iL.selector, iL.context); 14808 14809 $(iL.context).on(clickEvent, iL.selector, function() { 14810 var $this = $(this), 14811 //UNCODE addition 14812 key = typeof $(this).data('lb-index') !== '' && $(this).closest('.owl-item').length ? $(this).data('lb-index') : $items.index($this); 14813 if (UNCODE.isMobile) { 14814 var isCarousel = $this.closest('.owl-carousel'); 14815 if (isCarousel.length) { 14816 if (isCarousel.hasClass('owl-translating')) return false; 14817 } 14818 } 14819 14820 vars.current = key; 14821 vars.next = iL.items[key + 1] ? key + 1 : null; 14822 vars.prev = iL.items[key - 1] ? key - 1 : null; 14823 14824 //UNCODE addition 14825 if ( vars.BODY.hasClass('fp-slide-scrolling') ) 14826 return false;
14827 14828 iL.addContents(); 14829 iL.patchEvents(); 14830 14831 return false; 14832 }).on(vEvent, iL.selector, function() { 14833 return false; 14834 }); 14835 } else 14836 $.each(iL.itemsObject, function(key, val) { 14837 val.on(clickEvent, function() { 14838 vars.current = key; 14839 vars.next = iL.items[key + 1] ? key + 1 : null; 14840 vars.prev = iL.items[key - 1] ? key - 1 : null; 14841 14842 iL.addContents(); 14843 iL.patchEvents(); 14844 14845 return false; 14846 }).on(vEvent, function() { 14847 return false; 14848 }); 14849 }); 14850 }, 14851 14852 dispatchItemsEvents: function() { 14853 var iL = this, 14854 vars = iL.vars, 14855 opts = iL.options; 14856 14857 if (iL.context && iL.selector) 14858 $(iL.context).off('.iL', iL.selector); 14859 else 14860 $.each(iL.itemsObject, function(key, val) { 14861 val.off('.iL'); 14862 }); 14863 }, 14864 14865 refresh: function() { 14866 var iL = this; 14867 14868 iL.dispatchItemsEvents(); 14869 iL.attachItems(); 14870 iL.normalizeItems(); 14871 iL.patchItemsEvents(); 14872 }, 14873 14874 patchEvents: function() { 14875 var iL = this, 14876 vars = iL.vars, 14877 opts = iL.options, 14878 path = opts.path.toLowerCase(), 14879 holders = $('.ilightbox-holder'), 14880 fullscreenEvent = fullScreenApi.fullScreenEventName + '.iLightBox', 14881 durationThreshold = 1000, 14882 horizontalDistanceThreshold = 14883 verticalDistanceThreshold = 100, 14884 buttonsArray = [vars.nextButton[0], vars.prevButton[0], vars.nextButton[0].firstChild, vars.prevButton[0].firstChild]; 14885 14886 $win.bind('resize.iLightBox', function() { 14887 var viewport = getViewport(); 14888 14889 if (opts.mobileOptimizer && !opts.innerToolbar) vars.isMobile = viewport.width <= vars.mobileMaxWidth; 14890 vars.BODY[vars.isMobile ? 'addClass' : 'removeClass']('isMobile'); 14891 14892 iL.repositionPhoto(null); 14893 if (supportTouch) { 14894 clearTimeout(vars.setTime); 14895 vars.setTime = setTimeout(function() { 14896 var scrollTop = getScrollXY().y; 14897 window.scrollTo(0, scrollTop - 30); 14898 window.scrollTo(0, scrollTop + 30); 14899 window.scrollTo(0, scrollTop); 14900 }, 2000); 14901 } 14902 if (vars.thumbs) iL.positionThumbnails(); 14903 }).bind('keydown.iLightBox', function(event) { 14904 if (opts.controls.keyboard) { 14905 switch (event.keyCode) { 14906 case 13: 14907 if (event.shiftKey && opts.keyboard.shift_enter) iL.fullScreenAction(); 14908 break; 14909 case 27: 14910 if (opts.keyboard.esc) iL.closeAction(); 14911 break; 14912 case 37: 14913 if (opts.keyboard.left && !vars.lockKey) iL.moveTo('prev'); 14914 break; 14915 case 38: 14916 if (opts.keyboard.up && !vars.lockKey) iL.moveTo('prev'); 14917 break; 14918 case 39: 14919 if (opts.keyboard.right && !vars.lockKey) iL.moveTo('next'); 14920 break; 14921 case 40: 14922 if (opts.keyboard.down && !vars.lockKey) iL.moveTo('next'); 14923 break; 14924 } 14925 } 14926 }); 14927 14928 if (fullScreenApi.supportsFullScreen) $win.bind(fullscreenEvent, function() { 14929 iL.doFullscreen(); 14930 }); 14931 14932 var holderEventsArr = [opts.caption.show + '.iLightBox', opts.caption.hide + '.iLightBox', opts.social.show + '.iLightBox', opts.social.hide + '.iLightBox'].filter(function(e, i, arr) { 14933 return arr.lastIndexOf(e) === i; 14934 }), 14935 holderEvents = ""; 14936 14937 $.each(holderEventsArr, function(key, val) { 14938 if (key != 0) holderEvents += ' '; 14939 holderEvents += val; 14940 }); 14941 14942 $doc.on(clickEvent, '.ilightbox-overlay', function() { 14943 if (opts.overlay.blur) iL.closeAction(); 14944 }).on(clickEvent, '.ilightbox-next, .ilightbox-next-button', function() { 14945 iL.moveTo('next'); 14946 }).on(clickEvent, '.ilightbox-prev, .ilightbox-prev-button', function() { 14947 iL.moveTo('prev'); 14948 }).on(clickEvent, '.ilightbox-thumbnail', function() { 14949 var t = $(this), 14950 thumbs = $('.ilightbox-thumbnail', vars.thumbnails), 14951 index = thumbs.index(t); 14952 14953 if (index != vars.current) iL.goTo(index); 14954 }).on(holderEvents, '.ilightbox-holder:not(.ilightbox-next, .ilightbox-prev)', function(e) { 14955 var caption = $('div.ilightbox-caption', vars.holder), 14956 social = $('div.ilightbox-social', vars.holder), 14957 fadeSpeed = opts.effects.fadeSpeed; 14958 14959 if (vars.nextLock || vars.prevLock) { 14960 if (e.type == opts.caption.show && !caption.is(':visible')) caption.fadeIn(fadeSpeed); 14961 else if (e.type == opts.caption.hide && caption.is(':visible')) caption.fadeOut(fadeSpeed); 14962 14963 if (e.type == opts.social.show && !social.is(':visible')) social.fadeIn(fadeSpeed); 14964 else if (e.type == opts.social.hide && social.is(':visible')) social.fadeOut(fadeSpeed); 14965 } else { 14966 if (e.type == opts.caption.show && !caption.is(':visible')) caption.stop().fadeIn(fadeSpeed); 14967 else if (e.type == opts.caption.hide && caption.is(':visible')) caption.stop().fadeOut(fadeSpeed); 14968 14969 if (e.type == opts.social.show && !social.is(':visible')) social.stop().fadeIn(fadeSpeed); 14970 else if (e.type == opts.social.hide && social.is(':visible')) social.stop().fadeOut(fadeSpeed); 14971 } 14972 }).on('mouseenter.iLightBox mouseleave.iLightBox', '.ilightbox-wrapper', function(e) { 14973 if (e.type == 'mouseenter') vars.lockWheel = true; 14974 else vars.lockWheel = false;
14975 }).on(clickEvent, '.ilightbox-toolbar a.ilightbox-close, .ilightbox-toolbar a.ilightbox-fullscreen, .ilightbox-toolbar a.ilightbox-play, .ilightbox-toolbar a.ilightbox-pause', function() { 14976 var t = $(this); 14977 14978 if (t.hasClass('ilightbox-fullscreen')) iL.fullScreenAction(); 14979 else if (t.hasClass('ilightbox-play')) { 14980 iL.resume(); 14981 t.addClass('ilightbox-pause').removeClass('ilightbox-play'); 14982 } else if (t.hasClass('ilightbox-pause')) { 14983 iL.pause(); 14984 t.addClass('ilightbox-play').removeClass('ilightbox-pause'); 14985 } else iL.closeAction(); 14986 }).on(touchMoveEvent, '.ilightbox-overlay, .ilightbox-thumbnails-container', function(e) { 14987 // prevent scrolling 14988 e.preventDefault(); 14989 }); 14990 14991 function mouseMoveHandler(e) { 14992 if (!vars.isMobile) { 14993 if (!vars.mouseID) { 14994 vars.hideableElements.show(); 14995 } 14996 14997 vars.mouseID = clearTimeout(vars.mouseID); 14998 14999 if (buttonsArray.indexOf(e.target) === -1) 15000 vars.mouseID = setTimeout(function() { 15001 vars.hideableElements.hide(); 15002 vars.mouseID = clearTimeout(vars.mouseID); 15003 }, 3000); 15004 } 15005 } 15006 15007 if (opts.controls.arrows && !supportTouch) $doc.on('mousemove.iLightBox', mouseMoveHandler); 15008 15009 if (opts.controls.slideshow && opts.slideshow.pauseOnHover) $doc.on('mouseenter.iLightBox mouseleave.iLightBox', '.ilightbox-holder:not(.ilightbox-next, .ilightbox-prev)', function(e) { 15010 if (e.type == 'mouseenter' && vars.cycleID) iL.pause(); 15011 else if (e.type == 'mouseleave' && vars.isPaused) iL.resume(); 15012 }); 15013 15014 var switchers = $('.ilightbox-overlay, .ilightbox-holder, .ilightbox-thumbnails'), 15015 delay = false; 15016 15017 if (opts.controls.mousewheel) switchers.on('mousewheel.iLightBox', function(event, delta) { 15018 event.preventDefault(); 15019 if (delay) return; 15020 delay = true; 15021 if (!vars.lockWheel) { 15022 event.preventDefault(); 15023 if (delta < 0) { 15024 iL.moveTo('next'); 15025 } else if (delta > 0) { 15026 iL.moveTo('prev'); 15027 } 15028 } 15029 setTimeout(function(){
15030 delay = false; 15031 }, 2000); 15032 }); 15033 15034 if (opts.controls.swipe) holders.on(touchStartEvent, function(event) { 15035 if (vars.nextLock || vars.prevLock || vars.total == 1 || vars.lockSwipe) return; 15036 15037 vars.BODY.addClass('ilightbox-closedhand'); 15038 15039 var data = event.originalEvent.touches ? event.originalEvent.touches[0] : event, 15040 scrollTop = $doc.scrollTop(), 15041 scrollLeft = $doc.scrollLeft(), 15042 offsets = [ 15043 holders.eq(0).offset(), 15044 holders.eq(1).offset(), 15045 holders.eq(2).offset() 15046 ], 15047 offSet = [{ 15048 top: offsets[0].top - scrollTop, 15049 left: offsets[0].left - scrollLeft 15050 }, { 15051 top: offsets[1].top - scrollTop, 15052 left: offsets[1].left - scrollLeft 15053 }, { 15054 top: offsets[2].top - scrollTop, 15055 left: offsets[2].left - scrollLeft 15056 }], 15057 start = { 15058 time: (new Date()).getTime(), 15059 coords: [data.pageX - scrollLeft, data.pageY - scrollTop] 15060 }, 15061 stop; 15062 15063 function moveEachHandler(i) { 15064 var t = $(this), 15065 offset = offSet[i], 15066 scroll = [(start.coords[0] - stop.coords[0]), (start.coords[1] - stop.coords[1])]; 15067 15068 t[0].style[path == "horizontal" ? 'left' : 'top'] = (path == "horizontal" ? offset.left - scroll[0] : offset.top - scroll[1]) + 'px'; 15069 } 15070 15071 function moveHandler(event) { 15072 15073 if (!start) return; 15074 15075 var data = event.originalEvent.touches ? event.originalEvent.touches[0] : event; 15076 15077 stop = { 15078 time: (new Date()).getTime(), 15079 coords: [data.pageX - scrollLeft, data.pageY - scrollTop] 15080 }; 15081 15082 holders.each(moveEachHandler); 15083 15084 // prevent scrolling 15085 event.preventDefault(); 15086 } 15087 15088 function repositionHolders() { 15089 holders.each(function() { 15090 var t = $(this), 15091 offset = t.data('offset') || { 15092 top: t.offset().top - scrollTop, 15093 left: t.offset().left - scrollLeft 15094 }, 15095 top = offset.top, 15096 left = offset.left; 15097 15098 t.css(transform, gpuAcceleration).stop().animate({ 15099 top: top, 15100 left: left 15101 }, 500, 'easeOutCirc', function() { 15102 t.css(transform, ''); 15103 }); 15104 }); 15105 } 15106 15107 holders.bind(touchMoveEvent, moveHandler); 15108 $doc.one(touchStopEvent, function(event) { 15109 holders.unbind(touchMoveEvent, moveHandler); 15110 15111 vars.BODY.removeClass('ilightbox-closedhand'); 15112 15113 if (start && stop) { 15114 if (path == "horizontal" && stop.time - start.time < durationThreshold && abs(start.coords[0] - stop.coords[0]) > horizontalDistanceThreshold && abs(start.coords[1] - stop.coords[1]) < verticalDistanceThreshold) { 15115 if (start.coords[0] > stop.coords[0]) { 15116 if (vars.current == vars.total - 1 && !opts.infinite) repositionHolders(); 15117 else { 15118 vars.isSwipe = true; 15119 iL.moveTo('next'); 15120 } 15121 } else { 15122 if (vars.current == 0 && !opts.infinite) repositionHolders(); 15123 else { 15124 vars.isSwipe = true; 15125 iL.moveTo('prev'); 15126 } 15127 } 15128 } 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) { 15129 if (start.coords[1] > stop.coords[1]) { 15130 if (vars.current == vars.total - 1 && !opts.infinite) repositionHolders(); 15131 else { 15132 vars.isSwipe = true; 15133 iL.moveTo('next'); 15134 } 15135 } else { 15136 if (vars.current == 0 && !opts.infinite) repositionHolders(); 15137 else { 15138 vars.isSwipe = true; 15139 iL.moveTo('prev'); 15140 } 15141 } 15142 } else repositionHolders(); 15143 } 15144 start = stop = undefined; 15145 }); 15146 }); 15147 15148 }, 15149 15150 goTo: function(index) { 15151 var iL = this, 15152 vars = iL.vars, 15153 opts = iL.options, 15154 diff = (index - vars.current); 15155 15156 if (opts.infinite) { 15157 if (index == vars.total - 1 && vars.current == 0) diff = -1; 15158 if (vars.current == vars.total - 1 && index == 0) diff = 1; 15159 } 15160 15161 if (diff == 1) iL.moveTo('next'); 15162 else if (diff == -1) iL.moveTo('prev'); 15163 else { 15164 15165 if (vars.nextLock || vars.prevLock) return false; 15166 15167 //Trigger the onBeforeChange callback 15168 if (typeof opts.callback.onBeforeChange == 'function') opts.callback.onBeforeChange.call(iL, iL.ui); 15169 15170 if (opts.linkId) { 15171 vars.hashLock = true; 15172 window.location.hash = opts.linkId + '/' + index; 15173 } 15174 15175 if (iL.items[index]) { 15176 if (!iL.items[index].options.mousewheel) vars.lockWheel = true; 15177 else iL.vars.lockWheel = false;
15178 15179 if (!iL.items[index].options.swipe) vars.lockSwipe = true; 15180 else vars.lockSwipe = false; 15181 } 15182 15183 $.each([vars.holder, vars.nextPhoto, vars.prevPhoto], function(key, val) { 15184 val.css(transform, gpuAcceleration).fadeOut(opts.effects.loadedFadeSpeed); 15185 }); 15186 15187 vars.current = index; 15188 vars.next = index + 1; 15189 vars.prev = index - 1; 15190 15191 iL.createUI(); 15192 15193 setTimeout(function() { 15194 iL.generateBoxes(); 15195 }, opts.effects.loadedFadeSpeed + 50); 15196 15197 $('.ilightbox-thumbnail', vars.thumbnails).removeClass('ilightbox-active').eq(index).addClass('ilightbox-active'); 15198 iL.positionThumbnails(); 15199 15200 if (opts.linkId) setTimeout(function() { 15201 vars.hashLock = false; 15202 }, 55); 15203 15204 // Configure arrow buttons 15205 if (!opts.infinite) { 15206 vars.nextButton.add(vars.prevButton).add(vars.innerPrevButton).add(vars.innerNextButton).removeClass('disabled'); 15207 15208 if (vars.current == 0) { 15209 vars.prevButton.add(vars.innerPrevButton).addClass('disabled'); 15210 } 15211 if (vars.current >= vars.total - 1) { 15212 vars.nextButton.add(vars.innerNextButton).addClass('disabled'); 15213 } 15214 } 15215 15216 // Reset next cycle timeout 15217 iL.resetCycle(); 15218 15219 //Trigger the onAfterChange callback 15220 if (typeof opts.callback.onAfterChange == 'function') opts.callback.onAfterChange.call(iL, iL.ui); 15221 } 15222 }, 15223 15224 moveTo: function(side) { 15225 var iL = this, 15226 vars = iL.vars, 15227 opts = iL.options, 15228 path = opts.path.toLowerCase(), 15229 viewport = getViewport(), 15230 switchSpeed = opts.effects.switchSpeed; 15231 15232 if (vars.nextLock || vars.prevLock) return false; 15233 else { 15234 15235 var item = (side == "next") ? vars.next : vars.prev; 15236 15237 if (opts.linkId) { 15238 vars.hashLock = true; 15239 window.location.hash = opts.linkId + '/' + item; 15240 } 15241 15242 if (side == "next") { 15243 if (!iL.items[item]) return false; 15244 var firstHolder = vars.nextPhoto, 15245 secondHolder = vars.holder, 15246 lastHolder = vars.prevPhoto, 15247 firstClass = 'ilightbox-prev', 15248 secondClass = 'ilightbox-next'; 15249 } else if (side == "prev") { 15250 if (!iL.items[item]) return false; 15251 var firstHolder = vars.prevPhoto, 15252 secondHolder = vars.holder, 15253 lastHolder = vars.nextPhoto, 15254 firstClass = 'ilightbox-next', 15255 secondClass = 'ilightbox-prev'; 15256 } 15257 15258 //Trigger the onBeforeChange callback 15259 if (typeof opts.callback.onBeforeChange == 'function') 15260 opts.callback.onBeforeChange.call(iL, iL.ui); 15261 15262 (side == "next") ? vars.nextLock = true: vars.prevLock = true; 15263 15264 var captionFirst = $('div.ilightbox-caption', secondHolder), 15265 socialFirst = $('div.ilightbox-social', secondHolder); 15266 15267 if (captionFirst.length) 15268 captionFirst.stop().fadeOut(switchSpeed, function() { 15269 $(this).remove(); 15270 }); 15271 if (socialFirst.length) 15272 socialFirst.stop().fadeOut(switchSpeed, function() { 15273 $(this).remove(); 15274 }); 15275 15276 if (iL.items[item].caption) { 15277 iL.setCaption(iL.items[item], firstHolder); 15278 var caption = $('div.ilightbox-caption', firstHolder), 15279 percent = parseInt((caption.outerHeight() / firstHolder.outerHeight()) * 100); 15280 if (opts.caption.start && percent <= 50) caption.fadeIn(switchSpeed); 15281 } 15282 15283 var social = iL.items[item].options.social; 15284 if (social) { 15285 iL.setSocial(social, iL.items[item].URL, firstHolder); 15286 if (opts.social.start) $('div.ilightbox-social', firstHolder).fadeIn(opts.effects.fadeSpeed); 15287 } 15288 15289 $.each([firstHolder, secondHolder, lastHolder], function(key, val) { 15290 val.removeClass('ilightbox-next ilightbox-prev'); 15291 }); 15292 15293 var firstOffset = firstHolder.data('offset'), 15294 winW = (viewport.width - (opts.styles.pageOffsetX)), 15295 winH = (viewport.height - (opts.styles.pageOffsetY)), 15296 width = firstOffset.newDims.width, 15297 height = firstOffset.newDims.height, 15298 thumbsOffset = firstOffset.thumbsOffset, 15299 diff = firstOffset.diff, 15300 top = parseInt((winH / 2) - (height / 2) - diff.H - (thumbsOffset.H / 2)), 15301 left = parseInt((winW / 2) - (width / 2) - diff.W - (thumbsOffset.W / 2)); 15302 15303 var secondOffset = secondHolder.data('offset'), 15304 object = secondOffset.object; 15305 15306 /*if (object.item.caption && !isNaN(width) && !isNaN(height) && UNCODE.wwidth > UNCODE.mediaQuery) { 15307 var objRatio = width / height; 15308 height = height - vars.captionHeight; 15309 width = height * objRatio; 15310 top = path == 'horizontal' ? parseInt((winH / 2) - (height / 2) - diff.H - (thumbsOffset.H / 2)) : top, 15311 left = parseInt((winW / 2) - (width / 2) - diff.W - (thumbsOffset.W / 2)); 15312 }*/ 15313 15314 firstHolder.show().css(transform, gpuAcceleration).animate({ 15315 top: top, 15316 left: left, 15317 opacity: 1 15318 }, switchSpeed, (vars.isSwipe) ? 'easeOutCirc' : 'easeInOutCirc', function() { 15319 firstHolder.css(transform, ''); 15320 }); 15321 15322 $('div.ilightbox-container', firstHolder).animate({ 15323 width: width, 15324 height: height 15325 }, switchSpeed, (vars.isSwipe) ? 'easeOutCirc' : 'easeInOutCirc'); 15326 15327 diff = secondOffset.diff; 15328 15329 width = secondOffset.newDims.width, 15330 height = secondOffset.newDims.height; 15331 15332 width = parseInt(width * opts.styles[side == 'next' ? 'prevScale' : 'nextScale']), 15333 height = parseInt(height * opts.styles[side == 'next' ? 'prevScale' : 'nextScale']), 15334 top = (path == 'horizontal') ? parseInt((winH / 2) - object.offsetY - (height / 2) - diff.H - (thumbsOffset.H / 2)) : parseInt(winH - object.offsetX - diff.H - (thumbsOffset.H / 2)); 15335 15336 if (side == 'prev') 15337 left = (path == 'horizontal') ? parseInt(winW - object.offsetX - diff.W - (thumbsOffset.W / 2)) : parseInt((winW / 2) - (width / 2) - diff.W - object.offsetY - (thumbsOffset.W / 2)); 15338 else { 15339 top = (path == 'horizontal') ? top : parseInt(object.offsetX - diff.H - height - (thumbsOffset.H / 2)), 15340 left = (path == 'horizontal') ? parseInt(object.offsetX - diff.W - width - (thumbsOffset.W / 2)) : parseInt((winW / 2) - object.offsetY - (width / 2) - diff.W - (thumbsOffset.W / 2)); 15341 } 15342 15343 /*if (object.item.caption && !isNaN(width) && !isNaN(height) && UNCODE.wwidth > UNCODE.mediaQuery) { 15344 var objRatio = width / height; 15345 height = height - vars.captionHeight; 15346 width = height * objRatio; 15347 top = path == 'horizontal' ? parseInt((winH / 2) - (height / 2) - diff.H - (thumbsOffset.H / 2)) : top; 15348 }*/ 15349 15350 $('div.ilightbox-container', secondHolder).animate({ 15351 width: width, 15352 height: height 15353 }, switchSpeed, (vars.isSwipe) ? 'easeOutCirc' : 'easeInOutCirc'); 15354 15355 secondHolder.addClass(firstClass).css(transform, gpuAcceleration).animate({ 15356 top: top, 15357 left: left, 15358 opacity: opts.styles.prevOpacity, 15359 }, switchSpeed, (vars.isSwipe) ? 'easeOutCirc' : 'easeInOutCirc', function() { 15360 secondHolder.css(transform, ''); 15361
15362 $('.ilightbox-thumbnail', vars.thumbnails).removeClass('ilightbox-active').eq(item).addClass('ilightbox-active'); 15363 iL.positionThumbnails(); 15364 15365 if (iL.items[item]) { 15366 if (!iL.items[item].options.mousewheel) vars.lockWheel = true; 15367 else vars.lockWheel = false; 15368 15369 if (!iL.items[item].options.swipe) vars.lockSwipe = true; 15370 else vars.lockSwipe = false; 15371 } 15372 15373 vars.isSwipe = false; 15374 15375 // Remove iframe & video from previous slide 15376 if (['iframe', 'video'].indexOf(iL.items[vars.current].type) !== -1) { 15377 $('div.ilightbox-container', secondHolder).empty(); 15378 } 15379 15380 if (side == "next") { 15381 vars.nextPhoto = lastHolder, 15382 vars.prevPhoto = secondHolder, 15383 vars.holder = firstHolder; 15384 15385 vars.nextPhoto.hide(); 15386 15387 vars.next = vars.next + 1, 15388 vars.prev = vars.current, 15389 vars.current = vars.current + 1; 15390 15391 if (opts.infinite) { 15392 if (vars.current > vars.total - 1) vars.current = 0; 15393 if (vars.current == vars.total - 1) vars.next = 0; 15394 if (vars.current == 0) vars.prev = vars.total - 1; 15395 } 15396 15397 iL.createUI(); 15398 15399 if (!iL.items[vars.next]) 15400 vars.nextLock = false; 15401 else 15402 iL.loadContent(iL.items[vars.next], 'next'); 15403 } else { 15404 vars.prevPhoto = lastHolder; 15405 vars.nextPhoto = secondHolder; 15406 vars.holder = firstHolder; 15407 15408 vars.prevPhoto.hide(); 15409 15410 vars.next = vars.current; 15411 vars.current = vars.prev; 15412 vars.prev = vars.current - 1; 15413 15414 if (opts.infinite) { 15415 if (vars.current == vars.total - 1) vars.next = 0; 15416 if (vars.current == 0) vars.prev = vars.total - 1; 15417 } 15418 15419 iL.createUI(); 15420 15421 if (!iL.items[vars.prev]) 15422 vars.prevLock = false; 15423 else 15424 iL.loadContent(iL.items[vars.prev], 'prev'); 15425 } 15426 15427 // Add iframe & video content for current slide 15428 if (['iframe', 'video'].indexOf(iL.items[vars.current].type) !== -1) { 15429 iL.loadContent(iL.items[vars.current], 'current'); 15430 } 15431 15432 if (opts.linkId) setTimeout(function() { 15433 vars.hashLock = false; 15434 }, 55); 15435 15436 // Configure arrow buttons 15437 if (!opts.infinite) { 15438 vars.nextButton.add(vars.prevButton).add(vars.innerPrevButton).add(vars.innerNextButton).removeClass('disabled'); 15439 15440 if (vars.current == 0) 15441 vars.prevButton.add(vars.innerPrevButton).addClass('disabled'); 15442 if (vars.current >= vars.total - 1) 15443 vars.nextButton.add(vars.innerNextButton).addClass('disabled'); 15444 } 15445 15446 iL.repositionPhoto(); 15447 15448 // Reset next cycle timeout 15449 iL.resetCycle(); 15450 15451 //Trigger the onAfterChange callback 15452 if (typeof opts.callback.onAfterChange == 'function') 15453 opts.callback.onAfterChange.call(iL, iL.ui); 15454 }); 15455 15456 top = (path == 'horizontal') ? getPixel(lastHolder, 'top') : ((side == "next") ? parseInt(-(winH / 2) - lastHolder.outerHeight()) : parseInt(top * 2)), 15457 left = (path == 'horizontal') ? ((side == "next") ? parseInt(-(winW / 2) - lastHolder.outerWidth()) : parseInt(left * 2)) : getPixel(lastHolder, 'left'); 15458 15459 lastHolder.css(transform, gpuAcceleration).animate({ 15460 top: top, 15461 left: left, 15462 opacity: opts.styles.nextOpacity 15463 }, switchSpeed, (vars.isSwipe) ? 'easeOutCirc' : 'easeInOutCirc', function() { 15464 lastHolder.css(transform, ''); 15465 }).addClass(secondClass); 15466 } 15467 }, 15468 15469 setCaption: function(obj, target) { 15470 var iL = this, 15471 caption = $('<div class="ilightbox-caption"></div>'); 15472 15473 if (obj.caption) { 15474 caption.html(obj.caption); 15475 $('div.ilightbox-container', target).append(caption); 15476 } 15477 }, 15478 15479 normalizeSocial: function(obj, url) { 15480 var iL = this, 15481 vars = iL.vars, 15482 opts = iL.options, 15483 baseURL = window.location.href; 15484 15485 $.each(obj, function(key, value) { 15486 if (!value) 15487 return true; 15488 15489 var item = key.toLowerCase(), 15490 source, text; 15491 15492 switch (item) { 15493 case 'facebook': 15494 source = "http://www.facebook.com/share.php?v=4&src=bm&u={URL}", 15495 text = "Share on Facebook"; 15496 break; 15497 case 'twitter': 15498 source = "http://twitter.com/home?status={URL}", 15499 text = "Share on Twitter"; 15500 break; 15501 case 'digg': 15502 source = "http://digg.com/submit?phase=2&url={URL}", 15503 text = "Share on Digg"; 15504 break; 15505 case 'reddit': 15506 source = "http://reddit.com/submit?url={URL}", 15507 text = "Share on reddit"; 15508 break; 15509 } 15510 15511 obj[key] = { 15512 URL: value.URL && absolutizeURI(baseURL, value.URL) || opts.linkId && window.location.href || typeof url !== 'string' && baseURL || url && absolutizeURI(baseURL, url) || baseURL, 15513 source: value.source || source || value.URL && absolutizeURI(baseURL, value.URL) || url && absolutizeURI(baseURL, url), 15514 text: value.text || text || "Share on " + key, 15515 width: (typeof(value.width) != 'undefined' && !isNaN(value.width)) ? parseInt(value.width) : 640, 15516 height: value.height || 360 15517 }; 15518 15519 }); 15520 15521 return obj; 15522 }, 15523 15524 setSocial: function(obj, url, target) { 15525 var iL = this, 15526 socialBar = $('<div class="ilightbox-social"></div>'), 15527 buttons = '<ul>'; 15528 15529 obj = iL.normalizeSocial(obj, url); 15530 15531 $.each(obj, function(key, value) { 15532 var item = key.toLowerCase(), 15533 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, '+')); 15534 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>'; 15535 }); 15536 15537 buttons += '</ul>'; 15538 15539 socialBar.html(buttons); 15540 $('div.ilightbox-container', target).append(socialBar); 15541 }, 15542 15543 fullScreenAction: function() { 15544 var iL = this, 15545 vars = iL.vars; 15546 15547 if (fullScreenApi.supportsFullScreen) { 15548 if (fullScreenApi.isFullScreen()) fullScreenApi.cancelFullScreen(document.documentElement); 15549 else fullScreenApi.requestFullScreen(document.documentElement); 15550 } else { 15551 iL.doFullscreen(); 15552 } 15553 }, 15554 15555 doFullscreen: function() { 15556 var iL = this, 15557 vars = iL.vars, 15558 viewport = getViewport(), 15559 opts = iL.options; 15560 15561 if (opts.fullAlone) { 15562 var currentHolder = vars.holder, 15563 current = iL.items[vars.current], 15564 windowWidth = viewport.width, 15565 windowHeight = viewport.height, 15566 elements = [currentHolder, vars.nextPhoto, vars.prevPhoto, vars.nextButton, vars.prevButton, vars.overlay, vars.toolbar, vars.thumbnails, vars.loader], 15567 hideElements = [vars.nextPhoto, vars.prevPhoto, vars.nextButton, vars.prevButton, vars.loader, vars.thumbnails]; 15568 15569 if (!vars.isInFullScreen) { 15570 vars.isInFullScreen = vars.lockKey = vars.lockWheel = vars.lockSwipe = true; 15571 vars.overlay.css({ 15572 opacity: 1 15573 }); 15574 15575 $.each(hideElements, function(i, element) { 15576 element.hide(); 15577 }); 15578 15579 vars.fullScreenButton.attr('title', opts.text.exitFullscreen); 15580 15581 if (opts.fullStretchTypes.indexOf(current.type) != -1) currentHolder.data({
15582 naturalWidthOld: currentHolder.data('naturalWidth'), 15583 naturalHeightOld: currentHolder.data('naturalHeight'), 15584 naturalWidth: windowWidth, 15585 naturalHeight: windowHeight 15586 }); 15587 else { 15588 var viewport = current.options.fullViewPort || opts.fullViewPort || '', 15589 newWidth = windowWidth, 15590 newHeight = windowHeight, 15591 width = currentHolder.data('naturalWidth'), 15592 height = currentHolder.data('naturalHeight'); 15593 15594 if (viewport.toLowerCase() == 'fill') { 15595 newHeight = (newWidth / width) * height; 15596 15597 if (newHeight < windowHeight) { 15598 newWidth = (windowHeight / height) * width, 15599 newHeight = windowHeight; 15600 } 15601 } else if (viewport.toLowerCase() == 'fit') { 15602 var dims = iL.getNewDimenstions(newWidth, newHeight, width, height, true); 15603 15604 newWidth = dims.width, 15605 newHeight = dims.height; 15606 } else if (viewport.toLowerCase() == 'stretch') { 15607 newWidth = newWidth, 15608 newHeight = newHeight; 15609 } else { 15610 var scale = (width > newWidth || height > newHeight) ? true : false, 15611 dims = iL.getNewDimenstions(newWidth, newHeight, width, height, scale); 15612 newWidth = dims.width, 15613 newHeight = dims.height; 15614 } 15615 15616 currentHolder.data({ 15617 naturalWidthOld: currentHolder.data('naturalWidth'), 15618 naturalHeightOld: currentHolder.data('naturalHeight'), 15619 naturalWidth: newWidth, 15620 naturalHeight: newHeight 15621 }); 15622 } 15623 15624 $.each(elements, function(key, val) { 15625 val.addClass('ilightbox-fullscreen'); 15626 }); 15627 15628 //Trigger the onEnterFullScreen callback 15629 if (typeof opts.callback.onEnterFullScreen == 'function') opts.callback.onEnterFullScreen.call(iL, iL.ui); 15630 } else { 15631 vars.isInFullScreen = vars.lockKey = vars.lockWheel = vars.lockSwipe = false; 15632 vars.overlay.css({ 15633 opacity: iL.options.overlay.opacity 15634 }); 15635 15636 $.each(hideElements, function(i, element) { 15637 element.show(); 15638 }); 15639 15640 vars.fullScreenButton.attr('title', opts.text.enterFullscreen); 15641 15642 currentHolder.data({ 15643 naturalWidth: currentHolder.data('naturalWidthOld'), 15644 naturalHeight: currentHolder.data('naturalHeightOld'), 15645 naturalWidthOld: null, 15646 naturalHeightOld: null 15647 }); 15648 15649 $.each(elements, function(key, val) { 15650 val.removeClass('ilightbox-fullscreen'); 15651 }); 15652 15653 //Trigger the onExitFullScreen callback 15654 if (typeof opts.callback.onExitFullScreen == 'function') opts.callback.onExitFullScreen.call(iL, iL.ui); 15655 } 15656 } else { 15657 if (!vars.isInFullScreen) vars.isInFullScreen = true; 15658 else vars.isInFullScreen = false; 15659 } 15660 iL.repositionPhoto(true); 15661 }, 15662 15663 closeAction: function() { 15664 var iL = this, 15665 vars = iL.vars, 15666 opts = iL.options; 15667 15668 $win.unbind('.iLightBox'); 15669 $doc.off('.iLightBox'); 15670 15671 if (vars.isInFullScreen) fullScreenApi.cancelFullScreen(document.documentElement); 15672 15673 $('.ilightbox-overlay, .ilightbox-holder, .ilightbox-thumbnails').off('.iLightBox'); 15674 15675 if (opts.hide.effect) vars.overlay.stop().fadeOut(opts.hide.speed, function() { 15676 vars.overlay.remove(); 15677 vars.BODY.removeClass('ilightbox-noscroll').off('.iLightBox'); 15678 }); 15679 else { 15680 vars.overlay.remove(); 15681 vars.BODY.removeClass('ilightbox-noscroll').off('.iLightBox'); 15682 } 15683 15684 var fadeOuts = [vars.toolbar, vars.holder, vars.nextPhoto, vars.prevPhoto, vars.nextButton, vars.prevButton, vars.loader, vars.thumbnails]; 15685 15686 $.each(fadeOuts, function(i, element) { 15687 element.removeAttr('style').remove(); 15688 }); 15689 15690 vars.dontGenerateThumbs = vars.isInFullScreen = false; 15691 15692 window.iLightBox = null; 15693 15694 if (opts.linkId) { 15695 vars.hashLock = true; 15696 removeHash(); 15697 setTimeout(function() { 15698 vars.hashLock = false; 15699 }, 55); 15700 } 15701 15702 vars.nextButton.add(vars.prevButton).add(vars.innerPrevButton).add(vars.innerNextButton).removeClass('disabled'); 15703 15704 //Trigger the onHide callback 15705 if (typeof opts.callback.onHide == 'function') opts.callback.onHide.call(iL, iL.ui); 15706 }, 15707 15708 repositionPhoto: function() { 15709 var iL = this, 15710 vars = iL.vars, 15711 opts = iL.options, 15712 path = opts.path.toLowerCase(), 15713 viewport = getViewport(), 15714 winWidth = viewport.width, 15715 winHeight = viewport.height; 15716 15717 if (viewport.width < UNCODE.mediaQuery) opts.styles.nextOffsetX = 0; 15718 15719 var thumbsOffsetW = (vars.isInFullScreen && opts.fullAlone || vars.isMobile) ? 0 : ((path == 'horizontal') ? 0 : vars.thumbnails.outerWidth()), 15720 thumbsOffsetH = vars.isMobile ? vars.toolbar.outerHeight() : ((vars.isInFullScreen && opts.fullAlone) ? 0 : ((path == 'horizontal') ? vars.thumbnails.outerHeight() : 0)), 15721 width = (vars.isInFullScreen && opts.fullAlone) ? winWidth : (winWidth - (opts.styles.pageOffsetX)), 15722 height = (vars.isInFullScreen && opts.fullAlone) ? winHeight : (winHeight - (opts.styles.pageOffsetY)), 15723 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, 15724 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))); 15725 15726 var elObject = { 15727 type: 'current', 15728 width: width, 15729 height: height, 15730 item: iL.items[vars.current], 15731 offsetW: offsetW, 15732 offsetH: offsetH,
15733 thumbsOffsetW: thumbsOffsetW, 15734 thumbsOffsetH: thumbsOffsetH, 15735 animate: arguments.length, 15736 holder: vars.holder 15737 }; 15738 15739 iL.repositionEl(elObject); 15740 15741 if (iL.items[vars.next]) { 15742 elObject = $.extend(elObject, { 15743 type: 'next', 15744 item: iL.items[vars.next], 15745 offsetX: opts.styles.nextOffsetX, 15746 offsetY: opts.styles.nextOffsetY, 15747 holder: vars.nextPhoto 15748 }); 15749 15750 iL.repositionEl(elObject); 15751 } 15752 15753 if (iL.items[vars.prev]) { 15754 elObject = $.extend(elObject, { 15755 type: 'prev', 15756 item: iL.items[vars.prev], 15757 offsetX: opts.styles.nextOffsetX, 15758 offsetY: opts.styles.prevOffsetY, 15759 holder: vars.prevPhoto 15760 }); 15761 15762 iL.repositionEl(elObject); 15763 } 15764 15765 var loaderCss = (path == "horizontal") ? { 15766 left: parseInt((width / 2) - (vars.loader.outerWidth() / 2)) 15767 } : { 15768 top: parseInt((height / 2) - (vars.loader.outerHeight() / 2)) 15769 }; 15770 vars.loader.css(loaderCss); 15771 }, 15772 15773 repositionEl: function(obj) { 15774 var iL = this, 15775 vars = iL.vars, 15776 opts = iL.options, 15777 path = opts.path.toLowerCase(), 15778 widthAvail = (obj.type == 'current') ? ((vars.isInFullScreen && opts.fullAlone) ? obj.width : (obj.width - obj.offsetW)) : (obj.width - obj.offsetW), 15779 heightAvail = (obj.type == 'current') ? ((vars.isInFullScreen && opts.fullAlone) ? obj.height : (obj.height - obj.offsetH)) : (obj.height - obj.offsetH), 15780 itemParent = obj.item, 15781 item = obj.item.options, 15782 holder = obj.holder, 15783 offsetX = obj.offsetX || 0, 15784 offsetY = obj.offsetY || 0, 15785 //Uncode change ##START## 15786 toolbarHeight = $('.ilightbox-inner-toolbar', holder).length ? parseInt( $('.ilightbox-inner-toolbar', holder).outerHeight() ) : 0, 15787 //Uncode change ##END## 15788 thumbsOffsetW = obj.thumbsOffsetW, 15789 thumbsOffsetH = obj.thumbsOffsetH; 15790 15791 if (obj.type == 'current') { 15792 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); 15793 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); 15794 } else { 15795 if (typeof item.width == 'number' && item.width) widthAvail = (item.width > widthAvail) ? widthAvail : item.width; 15796 if (typeof item.height == 'number' && item.height) heightAvail = (item.height > heightAvail) ? heightAvail : item.height; 15797 } 15798 15799 15800 //Uncode change ##START## 15801 heightAvail = parseInt(heightAvail - toolbarHeight); 15802 // heightAvail = parseInt(heightAvail - $('.ilightbox-inner-toolbar', holder).outerHeight()); 15803 //Uncode change ##END## 15804 15805 var width = (typeof item.width == 'string' && item.width.indexOf('%') != -1) ? percentToValue(parseInt(item.width.replace('%', '')), obj.width) : holder.data('naturalWidth'), 15806 height = (typeof item.height == 'string' && item.height.indexOf('%') != -1) ? percentToValue(parseInt(item.height.replace('%', '')), obj.height) : holder.data('naturalHeight'); 15807 15808 var dims = ((typeof item.width == 'string' && item.width.indexOf('%') != -1 || typeof item.height == 'string' && item.height.indexOf('%') != -1) ? { 15809 width: width, 15810 height: height 15811 } : iL.getNewDimenstions(widthAvail, heightAvail, width, height)), 15812 newDims = $.extend({}, dims, {}); 15813 15814 if (obj.type == 'prev' || obj.type == 'next') 15815 width = parseInt(dims.width * ((obj.type == 'next') ? opts.styles.nextScale : opts.styles.prevScale)), 15816 height = parseInt(dims.height * ((obj.type == 'next') ? opts.styles.nextScale : opts.styles.prevScale)); 15817 else 15818 width = dims.width, 15819 height = dims.height; 15820 15821 var widthDiff = parseInt((getPixel(holder, 'padding-left') + getPixel(holder, 'padding-right') + getPixel(holder, 'border-left-width') + getPixel(holder, 'border-right-width')) / 2), 15822 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); 15823 15824 switch (obj.type) { 15825 case 'current': 15826 var top = parseInt((obj.height / 2) - (height / 2) - heightDiff - (thumbsOffsetH / 2)), 15827 left = parseInt((obj.width / 2) - (width / 2) - widthDiff - (thumbsOffsetW / 2)); 15828 break; 15829
15830 case 'next': 15831 var top = (path == 'horizontal') ? parseInt((obj.height / 2) - offsetY - (height / 2) - heightDiff - (thumbsOffsetH / 2)) : parseInt(obj.height - offsetX - heightDiff - (thumbsOffsetH / 2)), 15832 left = (path == 'horizontal') ? parseInt(obj.width - offsetX - widthDiff - (thumbsOffsetW / 2)) : parseInt((obj.width / 2) - (width / 2) - widthDiff - offsetY - (thumbsOffsetW / 2)); 15833 break; 15834 15835 case 'prev': 15836 var top = (path == 'horizontal') ? parseInt((obj.height / 2) - offsetY - (height / 2) - heightDiff - (thumbsOffsetH / 2)) : parseInt(offsetX - heightDiff - height - (thumbsOffsetH / 2)), 15837 left = (path == 'horizontal') ? parseInt(offsetX - widthDiff - width - (thumbsOffsetW / 2)) : parseInt((obj.width / 2) - offsetY - (width / 2) - widthDiff - (thumbsOffsetW / 2)); 15838 break; 15839 } 15840 15841 holder.data('offset', { 15842 top: top, 15843 left: left, 15844 newDims: newDims, 15845 diff: { 15846 W: widthDiff, 15847 H: heightDiff 15848 }, 15849 thumbsOffset: { 15850 W: thumbsOffsetW, 15851 H: thumbsOffsetH 15852 }, 15853 object: obj 15854 }); 15855 15856 var opacityMobile; 15857 if ( isMobile ) { 15858 opacityMobile = { 15859 opacity: 1, 15860 top: top, 15861 left: left 15862 }; 15863 } else { 15864 opacityMobile = { 15865 top: top, 15866 left: left 15867 }; 15868 } 15869 15870 if (obj.animate > 0 && opts.effects.reposition) { 15871 holder.css(transform, gpuAcceleration).stop().animate( 15872 opacityMobile, 15873 opts.effects.repositionSpeed, 'easeOutCirc', function() { 15874 holder.css(transform, ''); 15875 }); 15876 $('div.ilightbox-container', holder).stop().animate({ 15877 width: width, 15878 height: height 15879 }, opts.effects.repositionSpeed, 'easeOutCirc'); 15880 $('div.ilightbox-inner-toolbar', holder).stop().animate({ 15881 width: width 15882 }, opts.effects.repositionSpeed, 'easeOutCirc', function() { 15883 $(this).css('overflow', 'visible'); 15884 }); 15885 } else { 15886 holder.css(opacityMobile); 15887 $('div.ilightbox-container', holder).css({ 15888 width: width, 15889 height: height 15890 }); 15891 $('div.ilightbox-inner-toolbar', holder).css({ 15892 width: width 15893 }); 15894 } 15895 }, 15896 15897 15898 resume: function(priority) { 15899 var iL = this, 15900 vars = iL.vars, 15901 opts = iL.options; 15902 15903 if (!opts.slideshow.pauseTime || opts.controls.slideshow && vars.total <= 1 || priority < vars.isPaused) { 15904 return; 15905 } 15906 15907 vars.isPaused = 0; 15908 15909 if (vars.cycleID) { 15910 vars.cycleID = clearTimeout(vars.cycleID); 15911 } 15912 15913 vars.cycleID = setTimeout(function() { 15914 if (vars.current == vars.total - 1) iL.goTo(0); 15915 else iL.moveTo('next'); 15916 }, opts.slideshow.pauseTime); 15917 }, 15918 15919 pause: function(priority) { 15920 var iL = this, 15921 vars = iL.vars, 15922 opts = iL.options; 15923 15924 if (priority < vars.isPaused) { 15925 return; 15926 } 15927 15928 vars.isPaused = priority || 100; 15929 15930 if (vars.cycleID) { 15931 vars.cycleID = clearTimeout(vars.cycleID); 15932 } 15933 }, 15934 15935 resetCycle: function() { 15936 var iL = this, 15937 vars = iL.vars, 15938 opts = iL.options; 15939 15940 if (opts.controls.slideshow && vars.cycleID && !vars.isPaused) { 15941 iL.resume(); 15942 } 15943 }, 15944 15945 getNewDimenstions: function(width, height, width_old, height_old, thumb) { 15946 var iL = this; 15947 15948 if (!width) factor = height / height_old; 15949 else if (!height) factor = width / width_old; 15950 else factor = min(width / width_old, height / height_old); 15951 15952 if (!thumb) { 15953 if (factor > iL.options.maxScale) factor = iL.options.maxScale; 15954 else if (factor < iL.options.minScale) factor = iL.options.minScale; 15955 } 15956 15957 var final_width = (iL.options.keepAspectRatio) ? round(width_old * factor) : width, 15958 final_height = (iL.options.keepAspectRatio) ? round(height_old * factor) : height; 15959 15960 return { 15961 width: final_width, 15962 height: final_height, 15963 ratio: factor 15964 }; 15965 }, 15966 15967 setOption: function(options) { 15968 var iL = this; 15969 15970 iL.options = $.extend(true, iL.options, options || {}); 15971 iL.refresh(); 15972 }, 15973 15974 availPlugins: function() { 15975 var iL = this, 15976 testEl = document.createElement("video"); 15977 15978 iL.plugins = { 15979 flash: !isMobile, 15980 quicktime: (parseInt(PluginDetect.getVersion("QuickTime")) >= 0) ? true : false, 15981 html5H264: !!(testEl.canPlayType && testEl.canPlayType('video/mp4').replace(/no/, '')), 15982 html5WebM: !!(testEl.canPlayType && testEl.canPlayType('video/webm').replace(/no/, '')), 15983 html5Vorbis: !!(testEl.canPlayType && testEl.canPlayType('video/ogg').replace(/no/, '')), 15984 html5QuickTime: !!(testEl.canPlayType && testEl.canPlayType('video/quicktime').replace(/no/, '')) 15985 }; 15986 }, 15987 15988 addContent: function(element, obj) { 15989 var iL = this, 15990 el; 15991 15992 switch (obj.type) { 15993 case 'video': 15994 var HTML5 = false, 15995 videoType = obj.videoType, 15996 html5video = obj.options.html5video; 15997 15998 if (((videoType == 'video/mp4' || obj.ext == 'mp4' || obj.ext == 'm4v') || html5video.h264) && iL.plugins.html5H264) 15999 obj.ext = 'mp4', 16000 obj.URL = html5video.h264 || obj.URL; 16001 else if (html5video.webm && iL.plugins.html5WebM) 16002 obj.ext = 'webm', 16003 obj.URL = html5video.webm || obj.URL; 16004 else if (html5video.ogg && iL.plugins.html5Vorbis) 16005 obj.ext = 'ogv', 16006 obj.URL = html5video.ogg || obj.URL; 16007 16008 if (iL.plugins.html5H264 && (videoType == 'video/mp4' || obj.ext == 'mp4' || obj.ext == 'm4v')) HTML5 = true, videoType = "video/mp4"; 16009 else if (iL.plugins.html5WebM && (videoType == 'video/webm' || obj.ext == 'webm')) HTML5 = true, videoType = "video/webm"; 16010 else if (iL.plugins.html5Vorbis && (videoType == 'video/ogg' || obj.ext == 'ogv')) HTML5 = true, videoType = "video/ogg"; 16011 else if (iL.plugins.html5QuickTime && (videoType == 'video/quicktime' || obj.ext == 'mov' || obj.ext == 'qt')) HTML5 = true, videoType = "video/quicktime"; 16012 16013 if (HTML5) { 16014 el = $('<video />
16014', { 16015 "width": "100%", 16016 "height": "100%", 16017 "preload": html5video.preload, 16018 "autoplay": html5video.autoplay, 16019 "loop": html5video.loop, 16020 "poster": html5video.poster, 16021 "controls": html5video.controls, 16022 "controlslist": "nodownload" 16023 }).append($('<source />', { 16024 "src": obj.URL, 16025 "type": videoType 16026 })); 16027 } else { 16028 if (!iL.plugins.quicktime) el = $('<span />', { 16029 "class": "ilightbox-alert", 16030 html: iL.options.errors.missingPlugin.replace('{pluginspage}', pluginspages.quicktime).replace('{type}', 'QuickTime') 16031 }); 16032 else { 16033 16034 el = $('<object />', { 16035 "type": "video/quicktime", 16036 "pluginspage": pluginspages.quicktime 16037 }).attr({ 16038 "data": obj.URL, 16039 "width": "100%", 16040 "height": "100%" 16041 }).append($('<param />', { 16042 "name": "src", 16043 "value": obj.URL 16044 })).append($('<param />', { 16045 "name": "autoplay", 16046 "value": "false" 16047 })).append($('<param />', { 16048 "name": "loop", 16049 "value": "false" 16050 })).append($('<param />', { 16051 "name": "scale", 16052 "value": "tofit" 16053 })); 16054 16055 if (browser.msie) el = QT_GenerateOBJECTText(obj.URL, '100%', '100%', '', 'SCALE', 'tofit', 'AUTOPLAY', 'false', 'LOOP', 'false'); 16056 } 16057 } 16058 16059 break; 16060 16061 case 'flash': 16062 if (!iL.plugins.flash) el = $('<span />', { 16063 "class": "ilightbox-alert", 16064 html: iL.options.errors.missingPlugin.replace('{pluginspage}', pluginspages.flash).replace('{type}', 'Adobe Flash player') 16065 }); 16066 else { 16067 var flashvars = "", 16068 i = 0; 16069 16070 if (obj.options.flashvars) $.each(obj.options.flashvars, function(k, v) { 16071 if (i != 0) flashvars += "&"; 16072 flashvars += k + "=" + encodeURIComponent(v); 16073 i++; 16074 }); 16075 else flashvars = null; 16076 16077 el = $('<embed />').attr({ 16078 "type": "application/x-shockwave-flash", 16079 "src": obj.URL, 16080 "width": (typeof obj.options.width == 'number' && obj.options.width && iL.options.minScale == '1' && iL.options.maxScale == '1') ? obj.options.width : "100%", 16081 "height": (typeof obj.options.height == 'number' && obj.options.height && iL.options.minScale == '1' && iL.options.maxScale == '1') ? obj.options.height : "100%", 16082 "quality": "high", 16083 "bgcolor": "#000000", 16084 "play": "true", 16085 "loop": "true", 16086 "menu": "true", 16087 "wmode": "transparent", 16088 "scale": "showall", 16089 "allowScriptAccess": "always", 16090 "allowFullScreen": "true", 16091 "flashvars": flashvars, 16092 "fullscreen": "yes" 16093 }); 16094 } 16095 16096 break; 16097 16098 case 'iframe': 16099 el = $('<iframe />').attr({ 16100 "width": (typeof obj.options.width == 'number' && obj.options.width && iL.options.minScale == '1' && iL.options.maxScale == '1') ? obj.options.width : "100%", 16101 "height": (typeof obj.options.height == 'number' && obj.options.height && iL.options.minScale == '1' && iL.options.maxScale == '1') ? obj.options.height : "100%", 16102 src: obj.URL, 16103 frameborder: 0, 16104 'hspace': 0, 16105 'vspace': 0, 16106 'scrolling': supportTouch ? 'auto' : 'scroll', 16107 'webkitAllowFullScreen': '', 16108 'mozallowfullscreen': '', 16109 'allowFullScreen': '' 16110 }); 16111 16112 break; 16113 16114 case 'inline': 16115 el = $('<div class="ilightbox-wrapper"></div>').html($(obj.URL).clone(true)); 16116 16117 break; 16118 16119 case 'html': 16120 var object = obj.URL, 16121 el; 16122 16123 if (object[0].nodeName) { 16124 el = $('<div class="ilightbox-wrapper"></div>').html(object); 16125 } else { 16126 var dom = $(obj.URL), 16127 html = (dom.selector) ? $('<div>' + dom + '</div>') : dom; 16128 el = $('<div class="ilightbox-wrapper"></div>').html(html); 16129 } 16130 16131 break; 16132 } 16133 16134 $('div.ilightbox-container', element).empty().html(el); 16135 16136 // For fixing Chrome about just playing the video for first time 16137 if (el[0].tagName.toLowerCase() === 'video' && browser.webkit) setTimeout(function() { 16138 var src = el[0].currentSrc + '?' + floor(random() * 30000); 16139 el[0].currentSrc = src; 16140 el[0].src = src; 16141 }); 16142 16143 return el; 16144 }, 16145 16146 ogpRecognition: function(obj, callback) { 16147 var iL = this, 16148 url = obj.URL; 16149 16150 iL.showLoader(); 16151 doAjax(url, function(data) { 16152 iL.hideLoader(); 16153 if (data) { 16154 var object = new Object(); 16155 16156 object.length = false, 16157 object.url = data.url; 16158 16159 if (data.status == 200) { 16160 var result = data.results, 16161 type = result.type, 16162 source = result.source; 16163 16164 object.source = source.src, 16165 object.width = source.width && parseInt(source.width) || 0, 16166 object.height = source.height && parseInt(source.height) || 0, 16167 object.type = type, 16168 object.thumbnail = source.thumbnail || result.images && result.images[0], 16169 object.html5video = result.html5video || {}, 16170 object.length = true; 16171 16172 if (source.type == 'application/x-shockwave-flash') object.type = "flash"; 16173 else if (source.type.indexOf("video/") != -1) object.type = "video"; 16174 else if (source.type.indexOf("/html") != -1) object.type = "iframe"; 16175 else if (source.type.indexOf("image/") != -1) object.type = "image"; 16176 16177 } else if (typeof data.response != 'undefined') 16178 throw data.response; 16179 16180 callback.call(this, object.length ? object : false); 16181 } 16182 }); 16183 }, 16184 16185 hashChangeHandler: function(url) { 16186 var iL = this, 16187 vars = iL.vars, 16188 opts = iL.options, 16189 URL = url || window.location.href, 16190 hash = parseURI(URL).hash, 16191 split = hash.split('/'), 16192 index = split[1]; 16193 16194 if (vars.hashLock || ('#' + opts.linkId != split[0] && hash.length > 1)) return; 16195 16196 if (index) { 16197 var target = split[1] || 0; 16198 if (iL.items[target]) {
16199 var overlay = $('.ilightbox-overlay'); 16200 if (overlay.length && overlay.attr('linkid') == opts.linkId) { 16201 iL.goTo(target); 16202 } else { 16203 iL.itemsObject[target].trigger(ishybrid ? "itap click" : supportTouch ? 'itap' : 'click'); 16204 //iL.goTo(target); 16205 } 16206 } else { 16207 var overlay = $('.ilightbox-overlay'); 16208 if (overlay.length) iL.closeAction(); 16209 } 16210 } else { 16211 var overlay = $('.ilightbox-overlay'); 16212 if (overlay.length) iL.closeAction(); 16213 } 16214 } 16215 }; 16216 16217 /** 16218 * Parse style to pixels. 16219 * 16220 * @param {Object} $element jQuery object with element. 16221 * @param {Property} property CSS property to get the pixels from. 16222 * 16223 * @return {Int} 16224 */ 16225 function getPixel($element, property) { 16226 return parseInt($element.css(property), 10) || 0; 16227 } 16228 16229 /** 16230 * Make sure that number is within the limits. 16231 * 16232 * @param {Number} number 16233 * @param {Number} min 16234 * @param {Number} max 16235 * 16236 * @return {Number} 16237 */ 16238 function within(number, min, max) { 16239 return number < min ? min : number > max ? max : number; 16240 } 16241 16242 /** 16243 * Get viewport/window size (width and height). 16244 * 16245 * @return {Object} 16246 */ 16247 function getViewport() { 16248 var e = window, 16249 a = 'inner'; 16250 if (!('innerWidth' in window)) { 16251 a = 'client'; 16252 e = document.documentElement || document.body; 16253 } 16254 return { 16255 width: e[a + 'Width'], 16256 height: e[a + 'Height'] 16257 } 16258 } 16259 16260 /** 16261 * Remove hash tag from the URL 16262 * 16263 * @return {Void} 16264 */ 16265 function removeHash() { 16266 var scroll = getScrollXY(); 16267 16268 //UNCODE change 16269 // window.location.hash = ""; 16270 // history.pushState("", document.title, window.location.pathname + window.location.search); 16271 history.replaceState({}, document.title, window.location.pathname + window.location.search); 16272 16273 // Restore the scroll offset, should be flicker free 16274 window.scrollTo(scroll.x, scroll.y); 16275 } 16276 16277 /** 16278 * Do the ajax requests with callback. 16279 * 16280 * @param {String} url 16281 * @param {Function} callback 16282 * 16283 * @return {Void} 16284 */ 16285 function doAjax(url, callback) { 16286 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'); 16287 $.ajax({ 16288 url: url, 16289 dataType: 'jsonp' 16290 }); 16291 16292 iLCallback = function(data) { 16293 callback.call(this, data); 16294 }; 16295 } 16296 16297 /** 16298 * Find image from DOM elements 16299 * 16300 * @param {Element} element 16301 * 16302 * @return {Void} 16303 */ 16304 function findImageInElement(element) { 16305 var elements = $('*', element), 16306 imagesArr = new Array(); 16307 16308 elements.each(function() { 16309 var url = "", 16310 element = this; 16311 16312 if ($(element).css("background-image") != "none") { 16313 url = $(element).css("background-image"); 16314 } else if (typeof($(element).attr("src")) != "undefined" && element.nodeName.toLowerCase() == "img") { 16315 url = $(element).attr("src"); 16316 } 16317 16318 if (url.indexOf("gradient") == -1) { 16319 url = url.replace(/url\(\"/g, ""); 16320 url = url.replace(/url\(/g, ""); 16321 url = url.replace(/\"\)/g, ""); 16322 url = url.replace(/\)/g, ""); 16323 16324 var urls = url.split(","); 16325 16326 for (var i = 0; i < urls.length; i++) { 16327 if (urls[i].length > 0 && $.inArray(urls[i], imagesArr) == -1) { 16328 var extra = ""; 16329 if (browser.msie && browser.version < 9) { 16330 extra = "?" + floor(random() * 3000); 16331 } 16332 imagesArr.push(urls[i] + extra); 16333 } 16334 } 16335 } 16336 }); 16337 16338 return imagesArr; 16339 } 16340 16341 /** 16342 * Get file extension. 16343 * 16344 * @param {String} URL 16345 * 16346 * @return {String} 16347 */ 16348 function getExtension(URL) { 16349 if (URL !== null) { 16350 //UNCODE: fix issue to detect media type with query strings 16351 var ext = URL.indexOf('?') !== -1 ? URL.split('?')[0] : URL; 16352 ext = ext.split('.').pop().toLowerCase(); 16353 16354 return ext; 16355 } 16356 } 16357 16358 /** 16359 * Get type via extension. 16360 * 16361 * @param {String} URL 16362 * 16363 * @return {String} 16364 */ 16365 function getTypeByExtension(URL) { 16366 var type, 16367 ext = getExtension(URL); 16368 16369 //Uncode addition ##START## 16370 if (URL == undefined) { 16371 return false; 16372 } 16373 //Uncode addition ##END## 16374 16375 if (extensions.image.indexOf(ext) !== -1) type = 'image'; 16376 else if (extensions.flash.indexOf(ext) !== -1) type = 'flash'; 16377 else if (extensions.video.indexOf(ext) !== -1) type = 'video'; 16378 else if (ext.substring(0, 1) == "#") type = 'inline'; //Uncode addition 16379 else type = 'iframe'; 16380 16381 return type; 16382 } 16383 16384 /** 16385 * Return value from percent of a number. 16386 * 16387 * @param {Number} percent 16388 * @param {Number} total 16389 * 16390 * @return {Number} 16391 */ 16392 function percentToValue(percent, total) { 16393 return parseInt((total / 100) * percent); 16394 } 16395 16396 /** 16397 * A JavaScript equivalent of PHPâs parse_url. 16398 * 16399 * @param {String} url The URL to parse. 16400 * 16401 * @return {Mixed} 16402 */ 16403 function parseURI(url) { 16404 var m = String(url).replace(/^\s+|\s+$/g, '').match(/^([^:\/?#]+:)?(\/\/(?:[^:@]*(?::[^:@]*)?@)?(([^:\/?#]*)(?::(\d*))?))?([^?#]*)(\?[^#]*)?(#[\s\S]*)?/); 16405 // authority = '//' + user + ':' + pass '@' + hostname + ':' port 16406 return (m ? { 16407 href: m[0] || '', 16408 protocol: m[1] || '', 16409 authority: m[2] || '', 16410 host: m[3] || '', 16411 hostname: m[4] || '', 16412 port: m[5] || '', 16413 pathname: m[6] || '', 16414 search: m[7] || '', 16415 hash: m[8] || '' 16416 } : null); 16417 } 16418 16419 /** 16420 * Gets the absolute URI. 16421 * 16422 * @param {String} href The relative URL. 16423 * @param {String} base The base URL. 16424 * 16425 * @return {String} The absolute URL. 16426 */ 16427 function absolutizeURI(base, href) { // RFC 3986 16428 var iL = this; 16429 16430 function removeDotSegments(input) { 16431 var output = []; 16432 input.replace(/^(\.\.?(\/|$))+/, '') 16433 .replace(/\/(\.(\/|$))+/g, '/') 16434 .replace(/\/\.\.$/, '/../') 16435 .replace(/\/?[^\/]*/g, function(p) { 16436 if (p === '/..') { 16437 output.pop(); 16438 } else { 16439 output.push(p); 16440 } 16441 }); 16442 return output.join('').replace(/^\//, input.charAt(0) === '/' ? '/' : ''); 16443 } 16444 16445 href = parseURI(href || ''); 16446 base = parseURI(base || ''); 16447 16448 return !href || !base ? null : (href.protocol || base.protocol) + 16449 (href.protocol || href.authority ? href.authority : base.authority) + 16450 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)) + 16451 (href.protocol || href.authority || href.pathname ? href.search : (href.search || base.search)) + 16452 href.hash; 16453 } 16454 16455 /** 16456 * A JavaScript equivalent of PHPâs version_compare. 16457 * 16458 * @param {String} v1 16459 * @param {String} v2 16460 * @param {String} operator
16461 * 16462 * @return {Boolean} 16463 */ 16464 function version_compare(v1, v2, operator) { 16465 this.php_js = this.php_js || {}; 16466 this.php_js.ENV = this.php_js.ENV || {}; 16467 var i = 0, 16468 x = 0, 16469 compare = 0, 16470 vm = { 16471 'dev': -6, 16472 'alpha': -5, 16473 'a': -5, 16474 'beta': -4, 16475 'b': -4, 16476 'RC': -3, 16477 'rc': -3, 16478 '#': -2, 16479 'p': 1, 16480 'pl': 1 16481 }, 16482 prepVersion = function(v) { 16483 v = ('' + v).replace(/[_\-+]/g, '.'); 16484 v = v.replace(/([^.\d]+)/g, '.$1.').replace(/\.{2,}/g, '.'); 16485 return (!v.length ? [-8] : v.split('.')); 16486 }, 16487 numVersion = function(v) { 16488 return !v ? 0 : (isNaN(v) ? vm[v] || -7 : parseInt(v, 10)); 16489 }; 16490 v1 = prepVersion(v1); 16491 v2 = prepVersion(v2); 16492 x = max(v1.length, v2.length); 16493 for (i = 0; i < x; i++) { 16494 if (v1[i] == v2[i]) { 16495 continue; 16496 } 16497 v1[i] = numVersion(v1[i]); 16498 v2[i] = numVersion(v2[i]); 16499 if (v1[i] < v2[i]) { 16500 compare = -1; 16501 break; 16502 } else if (v1[i] > v2[i]) { 16503 compare = 1; 16504 break; 16505 } 16506 } 16507 if (!operator) { 16508 return compare; 16509 } 16510 16511 switch (operator) { 16512 case '>': 16513 case 'gt': 16514 return (compare > 0); 16515 case '>=': 16516 case 'ge': 16517 return (compare >= 0); 16518 case '<=': 16519 case 'le': 16520 return (compare <= 0); 16521 case '==': 16522 case '=': 16523 case 'eq': 16524 return (compare === 0); 16525 case '<>': 16526 case '!=': 16527 case 'ne': 16528 return (compare !== 0); 16529 case '': 16530 case '<': 16531 case 'lt': 16532 return (compare < 0); 16533 default: 16534 return null; 16535 } 16536 } 16537 16538 16539 // Begin the iLightBox plugin 16540 $.fn.iLightBox = function() { 16541 16542 var args = arguments, 16543 opt = ($.isPlainObject(args[0])) ? args[0] : args[1], 16544 items = ($.isArray(args[0]) || typeof args[0] == 'string') ? args[0] : args[1]; 16545 16546 if (!opt) opt = {}; 16547 16548 // Default options. Play carefully. 16549 var options = $.extend(true, { 16550 attr: 'href', 16551 path: 'vertical', 16552 skin: 'dark', 16553 linkId: false, 16554 infinite: false, 16555 startFrom: 0, 16556 randomStart: false, 16557 keepAspectRatio: true, 16558 maxScale: 1, 16559 minScale: .2, 16560 innerToolbar: false, 16561 smartRecognition: false, 16562 mobileOptimizer: true, 16563 fullAlone: true, 16564 fullViewPort: null, 16565 fullStretchTypes: 'flash, video', 16566 overlay: { 16567 blur: true, 16568 opacity: .85 16569 }, 16570 controls: { 16571 arrows: false, 16572 slideshow: false, 16573 toolbar: true, 16574 fullscreen: true, 16575 thumbnail: true, 16576 keyboard: true, 16577 mousewheel: true, 16578 swipe: true 16579 }, 16580 keyboard: { 16581 left: true, // previous 16582 right: true, // next 16583 up: true, // previous 16584 down: true, // next 16585 esc: true, // close 16586 shift_enter: true // fullscreen 16587 }, 16588 show: { 16589 effect: true, 16590 speed: 300, 16591 title: true 16592 }, 16593 hide: { 16594 effect: true, 16595 speed: 300 16596 }, 16597 caption: { 16598 start: true, 16599 show: 'mouseenter', 16600 hide: 'mouseleave' 16601 }, 16602 social: { 16603 start: true, 16604 show: 'mouseenter', 16605 hide: 'mouseleave',
16606 buttons: false 16607 }, 16608 styles: { 16609 pageOffsetX: 0, 16610 pageOffsetY: 0, 16611 nextOffsetX: 45, 16612 nextOffsetY: 0, 16613 nextOpacity: 1, 16614 nextScale: 1, 16615 prevOffsetX: 45, 16616 prevOffsetY: 0, 16617 prevOpacity: 1, 16618 prevScale: 1 16619 }, 16620 thumbnails: { 16621 maxWidth: 120, 16622 maxHeight: 80, 16623 normalOpacity: 1, 16624 activeOpacity: .6 16625 }, 16626 effects: { 16627 reposition: true, 16628 repositionSpeed: 200, 16629 switchSpeed: 500, 16630 loadedFadeSpeed: 180, 16631 fadeSpeed: 200 16632 }, 16633 slideshow: { 16634 pauseTime: 5000, 16635 pauseOnHover: false, 16636 startPaused: true 16637 }, 16638 text: { 16639 close: "Press Esc to close", 16640 enterFullscreen: "Enter Fullscreen (Shift+Enter)", 16641 exitFullscreen: "Exit Fullscreen (Shift+Enter)", 16642 slideShow: "Slideshow", 16643 next: "Next", 16644 previous: "Previous" 16645 }, 16646 errors: { 16647 loadImage: "An error occurred when trying to load photo.", 16648 loadContents: "An error occurred when trying to load contents.", 16649 missingPlugin: "The content your are attempting to view requires the <a href='{pluginspage}' target='_blank'>{type} plugin<\/a>." 16650 }, 16651 ajaxSetup: { 16652 url: '', 16653 beforeSend: function(jqXHR, settings) {}, 16654 cache: false, 16655 complete: function(jqXHR, textStatus) {}, 16656 crossDomain: false, 16657 error: function(jqXHR, textStatus, errorThrown) {}, 16658 success: function(data, textStatus, jqXHR) {}, 16659 global: true, 16660 ifModified: false, 16661 username: null, 16662 password: null, 16663 type: 'GET' 16664 }, 16665 callback: {} 16666 }, opt); 16667 16668 var instant = ($.isArray(items) || typeof items == 'string') ? true : false; 16669 16670 items = $.isArray(items) ? items : new Array(); 16671 16672 if (typeof args[0] == 'string') items[0] = args[0]; 16673 16674 if (version_compare($.fn.jquery, '1.8', '>=')) { 16675 var iLB = new iLightBox($(this), options, items, instant); 16676 return { 16677 close: function() { 16678 iLB.closeAction(); 16679 }, 16680 fullscreen: function() { 16681 iLB.fullScreenAction(); 16682 }, 16683 moveNext: function() { 16684 iLB.moveTo('next'); 16685 }, 16686 movePrev: function() { 16687 iLB.moveTo('prev'); 16688 }, 16689 goTo: function(index) { 16690 iLB.goTo(index); 16691 }, 16692 refresh: function() { 16693 iLB.refresh(); 16694 }, 16695 reposition: function() { 16696 (arguments.length > 0) ? iLB.repositionPhoto(true): iLB.repositionPhoto(); 16697 }, 16698 setOption: function(options) { 16699 iLB.setOption(options); 16700 }, 16701 destroy: function() { 16702 iLB.closeAction(); 16703 iLB.dispatchItemsEvents(); 16704 } 16705 }; 16706 } else { 16707 throw "The jQuery version that was loaded is too old. iLightBox requires jQuery 1.8+"; 16708 } 16709 16710 }; 16711 16712 16713 $.iLightBox = function() { 16714 return $.fn.iLightBox(arguments[0], arguments[1]); 16715 }; 16716 16717 function getScrollXY() { 16718 var scrOfX = 0, 16719 scrOfY = 0; 16720 if (typeof(window.pageYOffset) == 'number') { 16721 //Netscape compliant 16722 scrOfY = window.pageYOffset; 16723 scrOfX = window.pageXOffset; 16724 } else if (document.body && (document.body.scrollLeft || document.body.scrollTop)) { 16725 //DOM compliant 16726 scrOfY = document.body.scrollTop; 16727 scrOfX = document.body.scrollLeft; 16728 } else if (document.documentElement && (document.documentElement.scrollLeft || document.documentElement.scrollTop)) { 16729 //IE6 standards compliant mode 16730 scrOfY = document.documentElement.scrollTop; 16731 scrOfX = document.documentElement.scrollLeft; 16732 } 16733 return { 16734 x: scrOfX, 16735 y: scrOfY 16736 }; 16737 } 16738 16739 (function() { 16740 // add new event shortcuts 16741 $.each(("touchstart touchmove touchend " + 16742 "tap taphold " + 16743 "swipe swipeleft swiperight " + 16744 "scrollstart scrollstop").split(" "), function(i, name) { 16745 16746 $.fn[name] = function(fn) { 16747 return fn ? this.bind(name, fn) : this.trigger(name); 16748 }; 16749 16750 // jQuery < 1.8 16751 // if ($.attrFn) { 16752 // $.attrFn[name] = true; 16753 // } 16754 }); 16755 16756 var tapSettings = { 16757 startEvent: 'touchstart.iTap', 16758 endEvent: 'touchend.iTap' 16759 }; 16760 16761 // tap Event: 16762 $.event.special.itap = { 16763 setup: function() { 16764 16765 var self = this, 16766 $self = $(this), 16767 start, stop; 16768 16769 $self.bind(tapSettings.startEvent, function(event) { 16770 start = getScrollXY(); 16771 16772 $self.one(tapSettings.endEvent, function(event) { 16773 stop = getScrollXY(); 16774 16775 var orgEvent = event || window.event; 16776 event = $.event.fix(orgEvent); 16777 event.type = "itap"; 16778 16779 if ((start && stop) && (start.x == stop.x && start.y == stop.y))($.event.dispatch || $.event.handle).call(self, event); 16780 16781 start = stop = undefined; 16782 }); 16783 }); 16784 }, 16785 16786 teardown: function() { 16787 $(this).unbind(tapSettings.startEvent); 16788 } 16789 }; 16790 }()); 16791 16792 16793 //Fullscreen API 16794 (function() { 16795 fullScreenApi = { 16796 supportsFullScreen: false, 16797 isFullScreen: function() { 16798 return false;
16799 }, 16800 requestFullScreen: function() {}, 16801 cancelFullScreen: function() {}, 16802 fullScreenEventName: '', 16803 prefix: '' 16804 }, 16805 browserPrefixes = 'webkit moz o ms khtml'.split(' '); 16806 16807 // check for native support 16808 if (typeof document.cancelFullScreen != 'undefined') { 16809 fullScreenApi.supportsFullScreen = true; 16810 } else { 16811 // check for fullscreen support by vendor prefix 16812 for (var i = 0, il = browserPrefixes.length; i < il; i++) { 16813 fullScreenApi.prefix = browserPrefixes[i]; 16814 16815 if (typeof document[fullScreenApi.prefix + 'CancelFullScreen'] != 'undefined') { 16816 fullScreenApi.supportsFullScreen = true; 16817 16818 break; 16819 } 16820 } 16821 } 16822 16823 // update methods to do something useful 16824 if (fullScreenApi.supportsFullScreen) { 16825 fullScreenApi.fullScreenEventName = fullScreenApi.prefix + 'fullscreenchange'; 16826 16827 fullScreenApi.isFullScreen = function() { 16828 switch (this.prefix) { 16829 case '': 16830 return document.fullScreen; 16831 case 'webkit': 16832 return document.webkitIsFullScreen; 16833 default: 16834 return document[this.prefix + 'FullScreen']; 16835 } 16836 } 16837 fullScreenApi.requestFullScreen = function(el) { 16838 return (this.prefix === '') ? el.requestFullScreen() : el[this.prefix + 'RequestFullScreen'](); 16839 } 16840 fullScreenApi.cancelFullScreen = function(el) { 16841 return (this.prefix === '') ? document.cancelFullScreen() : document[this.prefix + 'CancelFullScreen'](); 16842 } 16843 } 16844 }()); 16845 16846 // Browser detect 16847 (function() { 16848 function uaMatch(ua) { 16849 ua = ua.toLowerCase(); 16850 16851 var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || 16852 /(webkit)[ \/]([\w.]+)/.exec(ua) || 16853 /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || 16854 /(msie) ([\w.]+)/.exec(ua) || 16855 ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || []; 16856 16857 return { 16858 browser: match[1] || "", 16859 version: match[2] || "0" 16860 }; 16861 } 16862 16863 var matched = uaMatch(navigator.userAgent); 16864 browser = {}; 16865 16866 if (matched.browser) { 16867 browser[matched.browser] = true; 16868 browser.version = matched.version; 16869 } 16870 16871 // Chrome is Webkit, but Webkit is also Safari. 16872 if (browser.chrome) { 16873 browser.webkit = true; 16874 } else if (browser.webkit) { 16875 browser.safari = true; 16876 } 16877 }()); 16878 16879 // Feature detects 16880 (function() { 16881 var prefixes = ['', 'webkit', 'moz', 'ms', 'o']; 16882 var el = document.createElement('div'); 16883 16884 function testProp(prop) { 16885 for (var p = 0, pl = prefixes.length; p < pl; p++) { 16886 var prefixedProp = prefixes[p] ? prefixes[p] + prop.charAt(0).toUpperCase() + prop.slice(1) : prop; 16887 if (el.style[prefixedProp] !== undefined) { 16888 return prefixedProp; 16889 } 16890 } 16891 } 16892 16893 // Global support indicators 16894 transform = testProp('transform') || ''; 16895 gpuAcceleration = testProp('perspective') ? 'translateZ(0) ' : ''; 16896 }()); 16897 16898 16899 /* 16900 PluginDetect v0.7.9 16901 www.pinlady.net/PluginDetect/license/ 16902 [ getVersion onWindowLoaded BetterIE ] 16903 [ Flash QuickTime Shockwave ] 16904 */ 16905 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;
16905d++){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);
16905d.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)}
16905c.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;
16905if(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(); 16906 16907 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)}; 16908 16909 16910 /* 16911 jQuery hashchange event v1.3 16912 https://github.com/cowboy/jquery-hashchange 16913 Copyright (c) 2010 "Cowboy" Ben Alman 16914 Dual licensed under the MIT and GPL licenses. 16915 */ 16916 (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= 16917 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|| 16918 "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;
16918a!==d&&(b.title=k.title,b.open(),e&&b.write('<script>document.domain="'+e+'"\x3c/script>'),b.close(),c.location.hash=a)}}();return h}()})(); 16919 16920 if (!Array.prototype.filter) { 16921 Array.prototype.filter = function(fun /*, thisp */ ) { 16922 "use strict"; 16923 16924 if (this == null) 16925 throw new TypeError(); 16926 16927 var t = Object(this); 16928 var len = t.length >>> 0; 16929 if (typeof fun != "function") 16930 throw new TypeError(); 16931 16932 var res = []; 16933 var thisp = arguments[1]; 16934 for (var i = 0; i < len; i++) { 16935 if (i in t) { 16936 var val = t[i]; // in case fun mutates this 16937 if (fun.call(thisp, val, i, t)) 16938 res.push(val); 16939 } 16940 } 16941 16942 return res; 16943 }; 16944 } 16945 16946 if (!Array.prototype.indexOf) { 16947 Array.prototype.indexOf = function(searchElement, fromIndex) { 16948 var k; 16949 16950 if (this == null) { 16951 throw new TypeError('"this" is null or not defined'); 16952 } 16953 16954 var O = Object(this); 16955 16956 var len = O.length >>> 0; 16957 16958 if (len === 0) { 16959 return -1; 16960 } 16961 16962 var n = +fromIndex || 0; 16963 16964 if (abs(n) === Infinity) { 16965 n = 0; 16966 } 16967 16968 if (n >= len) { 16969 return -1; 16970 } 16971 16972 k = max(n >= 0 ? n : len - abs(n), 0); 16973 16974 while (k < len) { 16975 var kValue; 16976 if (k in O && O[k] === searchElement) { 16977 return k; 16978 } 16979 k++; 16980 } 16981 return -1; 16982 }; 16983 } 16984 16985 if (!Array.prototype.lastIndexOf) { 16986 Array.prototype.lastIndexOf = function(searchElement /*, fromIndex*/ ) { 16987 "use strict"; 16988 16989 if (this == null) 16990 throw new TypeError(); 16991 16992 var t = Object(this); 16993 var len = t.length >>> 0; 16994 if (len === 0) 16995 return -1; 16996 16997 var n = len; 16998 if (arguments.length > 1) { 16999 n = Number(arguments[1]); 17000 if (n != n) 17001 n = 0; 17002 else if (n != 0 && n != (1 / 0) && n != -(1 / 0)) 17003 n = (n > 0 || -1) * floor(abs(n)); 17004 } 17005 17006 var k = n >= 0 ? min(n, len - 1) : len - abs(n); 17007 17008 for (; k >= 0; k--) { 17009 if (k in t && t[k] === searchElement) 17010 return k; 17011 } 17012 return -1; 17013 }; 17014 } 17015})(jQuery, this); 17016 17017/*! 17018 * lightgallery | 2.5.0 | June 13th 2022 17019 * http://www.lightgalleryjs.com/ 17020 * Copyright (c) 2020 Sachin Neravath; 17021 * @license GPLv3 17022 */ 17023 17024(function (global, factory) { 17025 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 17026 typeof define === 'function' && define.amd ? define(factory) : 17027 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lightGallery = factory()); 17028}(this, (function () { 'use strict'; 17029 17030 /*! ***************************************************************************** 17031 Copyright (c) Microsoft Corporation. 17032 17033 Permission to use, copy, modify, and/or distribute this software for any 17034 purpose with or without fee is hereby granted. 17035 17036 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 17037 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 17038 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 17039 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 17040 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 17041 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17042 PERFORMANCE OF THIS SOFTWARE. 17043 ***************************************************************************** */ 17044 17045 var __assign = function() { 17046 __assign = Object.assign || function __assign(t) { 17047 for (var s, i = 1, n = arguments.length; i < n; i++) { 17048 s = arguments[i]; 17049 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 17050 } 17051 return t; 17052 }; 17053 return __assign.apply(this, arguments); 17054 }; 17055 17056 function __spreadArrays() { 17057 for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; 17058 for (var r = Array(s), k = 0, i = 0; i < il; i++) 17059 for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) 17060 r[k] = a[j]; 17061 return r; 17062 } 17063 17064 /** 17065 * List of lightGallery events 17066 * All events should be documented here 17067 * Below interfaces are used to build the website documentations 17068 * */ 17069 var lGEvents = { 17070 afterAppendSlide: 'lgAfterAppendSlide', 17071 init: 'lgInit', 17072 hasVideo: 'lgHasVideo', 17073 containerResize: 'lgContainerResize', 17074 updateSlides: 'lgUpdateSlides', 17075 afterAppendSubHtml: 'lgAfterAppendSubHtml', 17076 beforeOpen: 'lgBeforeOpen', 17077 afterOpen: 'lgAfterOpen', 17078 slideItemLoad: 'lgSlideItemLoad', 17079 beforeSlide: 'lgBeforeSlide', 17080 afterSlide: 'lgAfterSlide', 17081 posterClick: 'lgPosterClick', 17082 dragStart: 'lgDragStart', 17083 dragMove: 'lgDragMove', 17084 dragEnd: 'lgDragEnd', 17085 beforeNextSlide: 'lgBeforeNextSlide', 17086 beforePrevSlide: 'lgBeforePrevSlide', 17087 beforeClose: 'lgBeforeClose', 17088 afterClose: 'lgAfterClose', 17089 rotateLeft: 'lgRotateLeft', 17090 rotateRight: 'lgRotateRight', 17091 flipHorizontal: 'lgFlipHorizontal', 17092 flipVertical: 'lgFlipVertical', 17093 autoplay: 'lgAutoplay', 17094 autoplayStart: 'lgAutoplayStart', 17095 autoplayStop: 'lgAutoplayStop', 17096 }; 17097 17098 var lightGalleryCoreSettings = { 17099 mode: 'lg-slide', 17100 easing: 'ease', 17101 speed: 400, 17102 licenseKey: '0000-0000-000-0000', 17103 height: '100%', 17104 width: '100%', 17105 addClass: '', 17106 startClass: 'lg-start-zoom', 17107 backdropDuration: 300, 17108 container: '', 17109 startAnimationDuration: 400, 17110 zoomFromOrigin: true, 17111 hideBarsDelay: 0, 17112 showBarsAfter: 10000, 17113 slideDelay: 0, 17114 supportLegacyBrowser: true, 17115 allowMediaOverlap: false, 17116 videoMaxSize: '1280-720', 17117 loadYouTubePoster: true, 17118 defaultCaptionHeight: 0, 17119 ariaLabelledby: '', 17120 ariaDescribedby: '', 17121 resetScrollPosition: true, 17122 hideScrollbar: false, 17123 closable: true, 17124 swipeToClose: true, 17125 closeOnTap: true, 17126 showCloseIcon: true, 17127 showMaximizeIcon: false, 17128 loop: true, 17129 escKey: true, 17130 keyPress: true, 17131 trapFocus: true, 17132 controls: true, 17133 slideEndAnimation: true, 17134 hideControlOnEnd: false,
vendor: 15,066 bytes, lines 17135-17682
17135 mousewheel: false, 17136 getCaptionFromTitleOrAlt: true, 17137 appendSubHtmlTo: '.lg-sub-html', 17138 subHtmlSelectorRelative: false, 17139 preload: 2, 17140 numberOfSlideItemsInDom: 10, 17141 selector: '', 17142 selectWithin: '', 17143 nextHtml: '', 17144 prevHtml: '', 17145 index: 0, 17146 iframeWidth: '100%', 17147 iframeHeight: '100%', 17148 iframeMaxWidth: '100%', 17149 iframeMaxHeight: '100%', 17150 download: true, 17151 counter: true, 17152 appendCounterTo: '.lg-toolbar', 17153 swipeThreshold: 50, 17154 enableSwipe: true, 17155 enableDrag: true, 17156 dynamic: false, 17157 dynamicEl: [], 17158 extraProps: [], 17159 exThumbImage: '', 17160 isMobile: undefined, 17161 mobileSettings: { 17162 controls: false, 17163 showCloseIcon: false, 17164 download: false, 17165 }, 17166 plugins: [], 17167 strings: { 17168 closeGallery: 'Close gallery', 17169 toggleMaximize: 'Toggle maximize', 17170 previousSlide: 'Previous slide', 17171 nextSlide: 'Next slide', 17172 download: 'Download', 17173 playVideo: 'Play video', 17174 }, 17175 }; 17176 17177 function initLgPolyfills() { 17178 (function () { 17179 if (typeof window.CustomEvent === 'function') 17180 return false; 17181 function CustomEvent(event, params) { 17182 params = params || { 17183 bubbles: false, 17184 cancelable: false, 17185 detail: null, 17186 }; 17187 var evt = document.createEvent('CustomEvent'); 17188 evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail); 17189 return evt; 17190 } 17191 window.CustomEvent = CustomEvent; 17192 })(); 17193 (function () { 17194 if (!Element.prototype.matches) { 17195 Element.prototype.matches = 17196 Element.prototype.msMatchesSelector || 17197 Element.prototype.webkitMatchesSelector; 17198 } 17199 })(); 17200 } 17201 var lgQuery = /** @class */ (function () { 17202 function lgQuery(selector) { 17203 this.cssVenderPrefixes = [ 17204 'TransitionDuration', 17205 'TransitionTimingFunction', 17206 'Transform', 17207 'Transition', 17208 ]; 17209 this.selector = this._getSelector(selector); 17210 this.firstElement = this._getFirstEl(); 17211 return this; 17212 } 17213 lgQuery.generateUUID = function () { 17214 return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { 17215 var r = (Math.random() * 16) | 0, v = c == 'x' ? r : (r & 0x3) | 0x8; 17216 return v.toString(16); 17217 }); 17218 }; 17219 lgQuery.prototype._getSelector = function (selector, context) { 17220 if (context === void 0) { context = document; } 17221 if (typeof selector !== 'string') { 17222 return selector; 17223 } 17224 context = context || document; 17225 var fl = selector.substring(0, 1); 17226 if (fl === '#') { 17227 return context.querySelector(selector); 17228 } 17229 else { 17230 return context.querySelectorAll(selector); 17231 } 17232 }; 17233 lgQuery.prototype._each = function (func) { 17234 if (!this.selector) { 17235 return this; 17236 } 17237 if (this.selector.length !== undefined) { 17238 [].forEach.call(this.selector, func); 17239 } 17240 else { 17241 func(this.selector, 0); 17242 } 17243 return this; 17244 }; 17245 lgQuery.prototype._setCssVendorPrefix = function (el, cssProperty, value) { 17246 // prettier-ignore 17247 var property = cssProperty.replace(/-([a-z])/gi, function (s, group1) { 17248 return group1.toUpperCase(); 17249 }); 17250 if (this.cssVenderPrefixes.indexOf(property) !== -1) { 17251 el.style[property.charAt(0).toLowerCase() + property.slice(1)] = value; 17252 el.style['webkit' + property] = value; 17253 el.style['moz' + property] = value; 17254 el.style['ms' + property] = value; 17255 el.style['o' + property] = value; 17256 } 17257 else { 17258 el.style[property] = value; 17259 } 17260 }; 17261 lgQuery.prototype._getFirstEl = function () { 17262 if (this.selector && this.selector.length !== undefined) { 17263 return this.selector[0]; 17264 } 17265 else { 17266 return this.selector; 17267 } 17268 }; 17269 lgQuery.prototype.isEventMatched = function (event, eventName) { 17270 var eventNamespace = eventName.split('.'); 17271 return event 17272 .split('.') 17273 .filter(function (e) { return e; }) 17274 .every(function (e) { 17275 return eventNamespace.indexOf(e) !== -1; 17276 }); 17277 }; 17278 lgQuery.prototype.attr = function (attr, value) { 17279 if (value === undefined) { 17280 if (!this.firstElement) { 17281 return ''; 17282 } 17283 return this.firstElement.getAttribute(attr); 17284 } 17285 this._each(function (el) { 17286 el.setAttribute(attr, value); 17287 }); 17288 return this; 17289 }; 17290 lgQuery.prototype.find = function (selector) { 17291 return $LG(this._getSelector(selector, this.selector)); 17292 }; 17293 lgQuery.prototype.first = function () { 17294 if (this.selector && this.selector.length !== undefined) { 17295 return $LG(this.selector[0]); 17296 } 17297 else { 17298 return $LG(this.selector); 17299 } 17300 }; 17301 lgQuery.prototype.eq = function (index) { 17302 return $LG(this.selector[index]); 17303 }; 17304 lgQuery.prototype.parent = function () { 17305 return $LG(this.selector.parentElement); 17306 }; 17307 lgQuery.prototype.get = function () { 17308 return this._getFirstEl(); 17309 }; 17310 lgQuery.prototype.removeAttr = function (attributes) { 17311 var attrs = attributes.split(' '); 17312 this._each(function (el) { 17313 attrs.forEach(function (attr) { return el.removeAttribute(attr); }); 17314 }); 17315 return this; 17316 }; 17317 lgQuery.prototype.wrap = function (className) { 17318 if (!this.firstElement) { 17319 return this; 17320 } 17321 var wrapper = document.createElement('div'); 17322 wrapper.className = className; 17323 this.firstElement.parentNode.insertBefore(wrapper, this.firstElement); 17324 this.firstElement.parentNode.removeChild(this.firstElement); 17325 wrapper.appendChild(this.firstElement); 17326 return this; 17327 }; 17328 lgQuery.prototype.addClass = function (classNames) { 17329 if (classNames === void 0) { classNames = ''; } 17330 this._each(function (el) { 17331 // IE doesn't support multiple arguments 17332 classNames.split(' ').forEach(function (className) { 17333 if (className) { 17334 el.classList.add(className); 17335 } 17336 }); 17337 }); 17338 return this; 17339 }; 17340 lgQuery.prototype.removeClass = function (classNames) { 17341 this._each(function (el) { 17342 // IE doesn't support multiple arguments 17343 classNames.split(' ').forEach(function (className) { 17344 if (className) { 17345 el.classList.remove(className); 17346 } 17347 }); 17348 }); 17349 return this; 17350 }; 17351 lgQuery.prototype.hasClass = function (className) { 17352 if (!this.firstElement) { 17353 return false; 17354 } 17355 return this.firstElement.classList.contains(className); 17356 }; 17357 lgQuery.prototype.hasAttribute = function (attribute) { 17358 if (!this.firstElement) { 17359 return false; 17360 } 17361 return this.firstElement.hasAttribute(attribute); 17362 }; 17363 lgQuery.prototype.toggleClass = function (className) { 17364 if (!this.firstElement) { 17365 return this; 17366 } 17367 if (this.hasClass(className)) { 17368 this.removeClass(className); 17369 } 17370 else { 17371 this.addClass(className); 17372 } 17373 return this; 17374 }; 17375 lgQuery.prototype.css = function (property, value) { 17376 var _this = this; 17377 this._each(function (el) { 17378 _this._setCssVendorPrefix(el, property, value); 17379 }); 17380 return this; 17381 }; 17382 // Need to pass separate namespaces for separate elements 17383 lgQuery.prototype.on = function (events, listener) { 17384 var _this = this; 17385 if (!this.selector) { 17386 return this; 17387 } 17388 events.split(' ').forEach(function (event) { 17389 if (!Array.isArray(lgQuery.eventListeners[event])) { 17390 lgQuery.eventListeners[event] = []; 17391 } 17392 lgQuery.eventListeners[event].push(listener); 17393 _this.selector.addEventListener(event.split('.')[0], listener); 17394 }); 17395 return this; 17396 }; 17397 // @todo - test this 17398 lgQuery.prototype.once = function (event, listener) { 17399 var _this = this; 17400 this.on(event, function () { 17401 _this.off(event); 17402 listener(event); 17403 }); 17404 return this; 17405 }; 17406 lgQuery.prototype.off = function (event) { 17407 var _this = this; 17408 if (!this.selector) { 17409 return this; 17410 } 17411 Object.keys(lgQuery.eventListeners).forEach(function (eventName) { 17412 if (_this.isEventMatched(event, eventName)) { 17413 lgQuery.eventListeners[eventName].forEach(function (listener) { 17414 _this.selector.removeEventListener(eventName.split('.')[0], listener); 17415 }); 17416 lgQuery.eventListeners[eventName] = []; 17417 } 17418 }); 17419 return this; 17420 }; 17421 lgQuery.prototype.trigger = function (event, detail) { 17422 if (!this.firstElement) { 17423 return this; 17424 } 17425 var customEvent = new CustomEvent(event.split('.')[0], { 17426 detail: detail || null, 17427 }); 17428 this.firstElement.dispatchEvent(customEvent); 17429 return this; 17430 }; 17431 // Does not support IE 17432 lgQuery.prototype.load = function (url) { 17433 var _this = this; 17434 fetch(url) 17435 .then(function (res) { return res.text(); }) 17436 .then(function (html) { 17437 _this.selector.innerHTML = html; 17438 }); 17439 return this; 17440 }; 17441 lgQuery.prototype.html = function (html) { 17442 if (html === undefined) { 17443 if (!this.firstElement) { 17444 return ''; 17445 } 17446 return this.firstElement.innerHTML; 17447 } 17448 this._each(function (el) { 17449 el.innerHTML = html; 17450 }); 17451 return this; 17452 }; 17453 lgQuery.prototype.append = function (html) { 17454 this._each(function (el) { 17455 if (typeof html === 'string') { 17456 el.insertAdjacentHTML('beforeend', html); 17457 } 17458 else { 17459 el.appendChild(html); 17460 } 17461 }); 17462 return this; 17463 }; 17464 lgQuery.prototype.prepend = function (html) { 17465 this._each(function (el) { 17466 el.insertAdjacentHTML('afterbegin', html); 17467 }); 17468 return this; 17469 }; 17470 lgQuery.prototype.remove = function () { 17471 this._each(function (el) { 17472 el.parentNode.removeChild(el); 17473 }); 17474 return this; 17475 }; 17476 lgQuery.prototype.empty = function () { 17477 this._each(function (el) { 17478 el.innerHTML = ''; 17479 }); 17480 return this; 17481 }; 17482 lgQuery.prototype.scrollTop = function (scrollTop) { 17483 if (scrollTop !== undefined) { 17484 document.body.scrollTop = scrollTop; 17485 document.documentElement.scrollTop = scrollTop; 17486 return this; 17487 } 17488 else { 17489 return (window.pageYOffset || 17490 document.documentElement.scrollTop || 17491 document.body.scrollTop || 17492 0); 17493 } 17494 }; 17495 lgQuery.prototype.scrollLeft = function (scrollLeft) { 17496 if (scrollLeft !== undefined) { 17497 document.body.scrollLeft = scrollLeft; 17498 document.documentElement.scrollLeft = scrollLeft; 17499 return this; 17500 } 17501 else { 17502 return (window.pageXOffset || 17503 document.documentElement.scrollLeft || 17504 document.body.scrollLeft || 17505 0); 17506 } 17507 }; 17508 lgQuery.prototype.offset = function () { 17509 if (!this.firstElement) { 17510 return { 17511 left: 0, 17512 top: 0, 17513 }; 17514 } 17515 var rect = this.firstElement.getBoundingClientRect(); 17516 var bodyMarginLeft = $LG('body').style().marginLeft; 17517 // Minus body margin - https://stackoverflow.com/questions/30711548/is-getboundingclientrect-left-returning-a-wrong-value 17518 return { 17519 left: rect.left - parseFloat(bodyMarginLeft) + this.scrollLeft(), 17520 top: rect.top + this.scrollTop(), 17521 }; 17522 }; 17523 lgQuery.prototype.style = function () { 17524 if (!this.firstElement) { 17525 return {}; 17526 } 17527 return (this.firstElement.currentStyle || 17528 window.getComputedStyle(this.firstElement)); 17529 }; 17530 // Width without padding and border even if box-sizing is used. 17531 lgQuery.prototype.width = function () { 17532 var style = this.style(); 17533 return (this.firstElement.clientWidth - 17534 parseFloat(style.paddingLeft) - 17535 parseFloat(style.paddingRight)); 17536 }; 17537 // Height without padding and border even if box-sizing is used. 17538 lgQuery.prototype.height = function () { 17539 var style = this.style(); 17540 return (this.firstElement.clientHeight - 17541 parseFloat(style.paddingTop) - 17542 parseFloat(style.paddingBottom)); 17543 }; 17544 lgQuery.eventListeners = {}; 17545 return lgQuery; 17546 }()); 17547 function $LG(selector) { 17548 initLgPolyfills(); 17549 return new lgQuery(selector); 17550 } 17551 17552 var defaultDynamicOptions = [ 17553 'src', 17554 'sources', 17555 'subHtml', 17556 'subHtmlUrl', 17557 'html', 17558 'video', 17559 'poster', 17560 'slideName', 17561 'responsive', 17562 'srcset', 17563 'sizes', 17564 'iframe', 17565 'downloadUrl', 17566 'download', 17567 'width', 17568 'facebookShareUrl', 17569 'tweetText', 17570 'iframeTitle', 17571 'twitterShareUrl', 17572 'pinterestShareUrl', 17573 'pinterestText', 17574 'fbHtml', 17575 'disqusIdentifier', 17576 'disqusUrl', 17577 ]; 17578 // Convert html data-attribute to camalcase 17579 function convertToData(attr) { 17580 // FInd a way for lgsize 17581 if (attr === 'href') { 17582 return 'src'; 17583 } 17584 attr = attr.replace('data-', ''); 17585 attr = attr.charAt(0).toLowerCase() + attr.slice(1); 17586 attr = attr.replace(/-([a-z])/g, function (g) { return g[1].toUpperCase(); }); 17587 return attr; 17588 } 17589 var utils = { 17590 /** 17591 * get possible width and height from the lgSize attribute. Used for ZoomFromOrigin option 17592 */ 17593 //Uncode edit ##START## 17594 getSize: function (el, container, spacing, defaultLgSize, galleryItem) { 17595 // getSize: function (el, container, spacing, defaultLgSize) { 17596 //Uncode edit ##END## 17597 if (spacing === void 0) { spacing = 0; } 17598 var LGel = $LG(el); 17599 var lgSize = LGel.attr('data-lg-size') || defaultLgSize; 17600 //Uncode edit ##START## 17601 if ( typeof galleryItem.size && galleryItem.size != null ) { 17602 lgSize = galleryItem.size; 17603 } 17604 //Uncode edit ##END## 17605 if (!lgSize) { 17606 return; 17607 } 17608 var isResponsiveSizes = lgSize.split(','); 17609 // if at-least two viewport sizes are available 17610 if (isResponsiveSizes[1]) { 17611 var wWidth = window.innerWidth; 17612 for (var i = 0; i < isResponsiveSizes.length; i++) { 17613 var size_1 = isResponsiveSizes[i]; 17614 var responsiveWidth = parseInt(size_1.split('-')[2], 10); 17615 if (responsiveWidth > wWidth) { 17616 lgSize = size_1; 17617 break; 17618 } 17619 // take last item as last option 17620 if (i === isResponsiveSizes.length - 1) { 17621 lgSize = size_1; 17622 } 17623 } 17624 } 17625 var size = lgSize.split('-'); 17626 var width = parseInt(size[0], 10); 17627 var height = parseInt(size[1], 10); 17628 var cWidth = container.width(); 17629 var cHeight = container.height() - spacing; 17630 var maxWidth = Math.min(cWidth, width); 17631 var maxHeight = Math.min(cHeight, height); 17632 var ratio = Math.min(maxWidth / width, maxHeight / height); 17633 return { width: width * ratio, height: height * ratio }; 17634 }, 17635 /** 17636 * @desc Get transform value based on the imageSize. Used for ZoomFromOrigin option 17637 * @param {jQuery Element} 17638 * @returns {String} Transform CSS string 17639 */ 17640 getTransform: function (el, container, top, bottom, imageSize) { 17641 if (!imageSize) { 17642 return; 17643 } 17644 var LGel = $LG(el).find('img').first(); 17645 if (!LGel.get()) { 17646 return; 17647 } 17648 var containerRect = container.get().getBoundingClientRect(); 17649 var wWidth = containerRect.width; 17650 // using innerWidth to include mobile safari bottom bar 17651 var wHeight = container.height() - (top + bottom); 17652 var elWidth = LGel.width(); 17653 var elHeight = LGel.height(); 17654 var elStyle = LGel.style(); 17655 var x = (wWidth - elWidth) / 2 - 17656 LGel.offset().left + 17657 (parseFloat(elStyle.paddingLeft) || 0) + 17658 (parseFloat(elStyle.borderLeft) || 0) + 17659 $LG(window).scrollLeft() + 17660 containerRect.left; 17661 var y = (wHeight - elHeight) / 2 - 17662 LGel.offset().top + 17663 (parseFloat(elStyle.paddingTop) || 0) + 17664 (parseFloat(elStyle.borderTop) || 0) + 17665 $LG(window).scrollTop() + 17666 top; 17667 var scX = elWidth / imageSize.width; 17668 var scY = elHeight / imageSize.height; 17669 var transform = 'translate3d(' + 17670 (x *= -1) + 17671 'px, ' + 17672 (y *= -1) + 17673 'px, 0) scale3d(' + 17674 scX + 17675 ', ' + 17676 scY + 17677 ', 1)'; 17678 return transform; 17679 }, 17680 getIframeMarkup: function (iframeWidth, iframeHeight, iframeMaxWidth, iframeMaxHeight, src, iframeTitle) { 17681 var title = iframeTitle ? 'title="' + iframeTitle + '"' : ''; 17682 return "<div class=\"lg-video-cont lg-has-iframe\" style=\"width:"
vendor: 2,803 bytes, lines 17682-17754
17682+ iframeWidth + "; max-width:" + iframeMaxWidth + "; height: " + iframeHeight + "; max-height:" + iframeMaxHeight + "\">\n <iframe class=\"lg-object\" frameborder=\"0\" " + title + " src=\"" + src + "\" allowfullscreen=\"true\"></iframe>\n </div>"; 17683 }, 17684 getImgMarkup: function (index, src, altAttr, srcset, sizes, sources) { 17685 var srcsetAttr = srcset ? "srcset=\"" + srcset + "\"" : ''; 17686 var sizesAttr = sizes ? "sizes=\"" + sizes + "\"" : ''; 17687 var imgMarkup = "<img " + altAttr + " " + srcsetAttr + " " + sizesAttr + " class=\"lg-object lg-image\" data-index=\"" + index + "\" src=\"" + src + "\" />"; 17688 var sourceTag = ''; 17689 if (sources) { 17690 var sourceObj = typeof sources === 'string' ? JSON.parse(sources) : sources; 17691 sourceTag = sourceObj.map(function (source) { 17692 var attrs = ''; 17693 Object.keys(source).forEach(function (key) { 17694 // Do not remove the first space as it is required to separate the attributes 17695 attrs += " " + key + "=\"" + source[key] + "\""; 17696 }); 17697 return "<source " + attrs + "></source>"; 17698 }); 17699 } 17700 return "" + sourceTag + imgMarkup; 17701 }, 17702 // Get src from responsive src 17703 getResponsiveSrc: function (srcItms) { 17704 var rsWidth = []; 17705 var rsSrc = []; 17706 var src = ''; 17707 for (var i = 0; i < srcItms.length; i++) { 17708 var _src = srcItms[i].split(' '); 17709 // Manage empty space 17710 if (_src[0] === '') { 17711 _src.splice(0, 1); 17712 } 17713 rsSrc.push(_src[0]); 17714 rsWidth.push(_src[1]); 17715 } 17716 var wWidth = window.innerWidth; 17717 for (var j = 0; j < rsWidth.length; j++) { 17718 if (parseInt(rsWidth[j], 10) > wWidth) { 17719 src = rsSrc[j]; 17720 break; 17721 } 17722 } 17723 return src; 17724 }, 17725 isImageLoaded: function (img) { 17726 if (!img) 17727 return false; 17728 // During the onload event, IE correctly identifies any images that 17729 // werenât downloaded as not complete. Others should too. Gecko-based 17730 // browsers act like NS4 in that they report this incorrectly. 17731 if (!img.complete) { 17732 return false; 17733 } 17734 // However, they do have two very useful properties: naturalWidth and 17735 // naturalHeight. These give the true size of the image. If it failed 17736 // to load, either of these should be zero. 17737 if (img.naturalWidth === 0) { 17738 return false; 17739 } 17740 // No other way of checking: assume itâs ok. 17741 return true; 17742 }, 17743 getVideoPosterMarkup: function (_poster, dummyImg, videoContStyle, playVideoString, _isVideo) { 17744 var videoClass = ''; 17745 if (_isVideo && _isVideo.youtube) { 17746 videoClass = 'lg-has-youtube'; 17747 } 17748 else if (_isVideo && _isVideo.vimeo) { 17749 videoClass = 'lg-has-vimeo'; 17750 } 17751 else { 17752 videoClass = 'lg-has-html5'; 17753 } 17754 return "<div class=\"lg-video-cont " + videoClass + "\" style=\"" + videoContStyle + "\">\n <div class=\"lg-video-play-button\">
vendor: 5,030 bytes, lines 17754-17865
17754\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>"; 17755 }, 17756 getFocusableElements: function (container) { 17757 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])'); 17758 var visibleElements = [].filter.call(elements, function (element) { 17759 var style = window.getComputedStyle(element); 17760 return style.display !== 'none' && style.visibility !== 'hidden'; 17761 }); 17762 return visibleElements; 17763 }, 17764 /** 17765 * @desc Create dynamic elements array from gallery items when dynamic option is false 17766 * It helps to avoid frequent DOM interaction 17767 * and avoid multiple checks for dynamic elments 17768 * 17769 * @returns {Array} dynamicEl 17770 */ 17771 getDynamicOptions: function (items, extraProps, getCaptionFromTitleOrAlt, exThumbImage) { 17772 var dynamicElements = []; 17773 var availableDynamicOptions = __spreadArrays(defaultDynamicOptions, extraProps); 17774 [].forEach.call(items, function (item) { 17775 var dynamicEl = {}; 17776 for (var i = 0; i < item.attributes.length; i++) { 17777 var attr = item.attributes[i]; 17778 if (attr.specified) { 17779 var dynamicAttr = convertToData(attr.name); 17780 var label = ''; 17781 if (availableDynamicOptions.indexOf(dynamicAttr) > -1) { 17782 label = dynamicAttr; 17783 } 17784 if (label) { 17785 dynamicEl[label] = attr.value; 17786 } 17787 } 17788 } 17789 var currentItem = $LG(item); 17790 var alt = currentItem.find('img').first().attr('alt'); 17791 var title = currentItem.attr('title'); 17792 //Uncode edit ##START## 17793 // var thumb = exThumbImage 17794 var thumb = exThumbImage && currentItem.attr(exThumbImage) 17795 //Uncode edit ##END## 17796 ? currentItem.attr(exThumbImage) 17797 : currentItem.find('img').first().attr('src'); 17798 dynamicEl.thumb = thumb; 17799 //Uncode edit ##START## 17800 if (getCaptionFromTitleOrAlt && !dynamicEl.subHtml) { 17801 // dynamicEl.subHtml = title || alt || ''; 17802 dynamicEl.subHtml = title || ''; 17803 } 17804 // dynamicEl.alt = alt || title || ''; 17805 dynamicEl.alt = title || ''; 17806 var inlineType = currentItem.attr('data-type'); 17807 dynamicEl.type = inlineType; 17808 //Uncode edit ##END## 17809 dynamicElements.push(dynamicEl); 17810 }); 17811 return dynamicElements; 17812 }, 17813 isMobile: function () { 17814 return /iPhone|iPad|iPod|Android/i.test(navigator.userAgent); 17815 }, 17816 /** 17817 * @desc Check the given src is video 17818 * @param {String} src 17819 * @return {Object} video type 17820 * Ex:{ youtube : ["//www.youtube.com/watch?v=c0asJgSyxcY", "c0asJgSyxcY"] } 17821 * 17822 * @todo - this information can be moved to dynamicEl to avoid frequent calls 17823 */ 17824 isVideo: function (src, isHTML5VIdeo, index) { 17825 if (!src || src.match(/\.(mp4|m4v|ogg|webm)$/) ) { 17826 if (isHTML5VIdeo) { 17827 return { 17828 html5: true, 17829 }; 17830 } 17831 else { 17832 console.warn('lightGallery :- data-src is not provided on slide item ' + 17833 (index + 1) + 17834 '. Please make sure the selector property is properly configured. More info - https://www.lightgalleryjs.com/demos/html-markup/'); 17835 return; 17836 } 17837 } 17838 var youtube = src.match(/\/\/(?:www\.)?youtu(?:\.be|be\.com|be-nocookie\.com)\/(?:watch\?v=|embed\/)?([a-z0-9\-\_\%]+)([\&|?][\S]*)*/i); 17839 var vimeo = src.match(/\/\/(?:www\.)?(?:player\.)?vimeo.com\/(?:video\/)?([0-9a-z\-_]+)(.*)?/i); 17840 var wistia = src.match(/https?:\/\/(.+)?(wistia\.com|wi\.st)\/(medias|embed)\/([0-9a-z\-_]+)(.*)/); 17841 if (youtube) { 17842 return { 17843 youtube: youtube, 17844 }; 17845 } 17846 else if (vimeo) { 17847 return { 17848 vimeo: vimeo, 17849 }; 17850 } 17851 else if (wistia) { 17852 return { 17853 wistia: wistia, 17854 }; 17855 } 17856 }, 17857 }; 17858 17859 // @ref - https://stackoverflow.com/questions/3971841/how-to-resize-images-proportionally-keeping-the-aspect-ratio 17860 // @ref - https://2ality.com/2017/04/setting-up-multi-platform-packages.html 17861 // Unique id for each gallery 17862 var lgId = 0; 17863 var LightGallery = /** @class */ (function () { 17864 function LightGallery(element, options) { 17865 this.lgOpened = false;
vendor: 4,563 bytes, lines 17866-18000
17866 this.index = 0; 17867 // lightGallery modules 17868 this.plugins = []; 17869 // false when lightGallery load first slide content; 17870 this.lGalleryOn = false; 17871 // True when a slide animation is in progress 17872 this.lgBusy = false; 17873 this.currentItemsInDom = []; 17874 // Scroll top value before lightGallery is opened 17875 this.prevScrollTop = 0; 17876 this.bodyPaddingRight = 0; 17877 this.isDummyImageRemoved = false; 17878 this.dragOrSwipeEnabled = false; 17879 this.mediaContainerPosition = { 17880 top: 0, 17881 bottom: 0, 17882 }; 17883 if (!element) { 17884 return this; 17885 } 17886 lgId++; 17887 this.lgId = lgId; 17888 this.el = element; 17889 this.LGel = $LG(element); 17890 this.generateSettings(options); 17891 this.buildModules(); 17892 // When using dynamic mode, ensure dynamicEl is an array 17893 if (this.settings.dynamic && 17894 this.settings.dynamicEl !== undefined && 17895 !Array.isArray(this.settings.dynamicEl)) { 17896 throw 'When using dynamic mode, you must also define dynamicEl as an Array.'; 17897 } 17898 this.galleryItems = this.getItems(); 17899 this.normalizeSettings(); 17900 // Gallery items 17901 this.init(); 17902 //Uncode edit ##START## 17903 // this.validateLicense(); 17904 //Uncode edit ##END## 17905 return this; 17906 } 17907 LightGallery.prototype.generateSettings = function (options) { 17908 // lightGallery settings 17909 this.settings = __assign(__assign({}, lightGalleryCoreSettings), options); 17910 if (this.settings.isMobile && 17911 typeof this.settings.isMobile === 'function' 17912 ? this.settings.isMobile() 17913 : utils.isMobile()) { 17914 var mobileSettings = __assign(__assign({}, this.settings.mobileSettings), this.settings.mobileSettings); 17915 this.settings = __assign(__assign({}, this.settings), mobileSettings); 17916 } 17917 }; 17918 LightGallery.prototype.normalizeSettings = function () { 17919 if (this.settings.slideEndAnimation) { 17920 this.settings.hideControlOnEnd = false; 17921 } 17922 if (!this.settings.closable) { 17923 this.settings.swipeToClose = false; 17924 } 17925 // And reset it on close to get the correct value next time 17926 this.zoomFromOrigin = this.settings.zoomFromOrigin; 17927 // At the moment, Zoom from image doesn't support dynamic options 17928 // @todo add zoomFromOrigin support for dynamic images 17929 if (this.settings.dynamic) { 17930 this.zoomFromOrigin = false; 17931 } 17932 if (!this.settings.container) { 17933 this.settings.container = document.body; 17934 } 17935 // settings.preload should not be grater than $item.length 17936 this.settings.preload = Math.min(this.settings.preload, this.galleryItems.length); 17937 }; 17938 LightGallery.prototype.init = function () { 17939 var _this = this; 17940 this.addSlideVideoInfo(this.galleryItems); 17941 this.buildStructure(); 17942 this.LGel.trigger(lGEvents.init, { 17943 instance: this, 17944 }); 17945 if (this.settings.keyPress) { 17946 this.keyPress(); 17947 } 17948 setTimeout(function () { 17949 _this.enableDrag(); 17950 _this.enableSwipe(); 17951 _this.triggerPosterClick(); 17952 }, 50); 17953 this.arrow(); 17954 if (this.settings.mousewheel) { 17955 this.mousewheel(); 17956 } 17957 if (!this.settings.dynamic) { 17958 this.openGalleryOnItemClick(); 17959 } 17960 }; 17961 LightGallery.prototype.openGalleryOnItemClick = function () { 17962 var _this = this; 17963 var _loop_1 = function (index) { 17964 var element = this_1.items[index]; 17965 var $element = $LG(element); 17966 // Using different namespace for click because click event should not unbind if selector is same object('this') 17967 // @todo manage all event listners - should have namespace that represent element 17968 var uuid = lgQuery.generateUUID(); 17969 $element 17970 .attr('data-lg-id', uuid) 17971 .on("click.lgcustom-item-" + uuid, function (e) { 17972 e.preventDefault(); 17973 var currentItemIndex = _this.settings.index || index; 17974 _this.openGallery(currentItemIndex, element); 17975 }); 17976 }; 17977 var this_1 = this; 17978 // Using for loop instead of using bubbling as the items can be any html element. 17979 for (var index = 0; index < this.items.length; index++) { 17980 _loop_1(index); 17981 } 17982 }; 17983 /** 17984 * Module constructor 17985 * Modules are build incrementally. 17986 * Gallery should be opened only once all the modules are initialized. 17987 * use moduleBuildTimeout to make sure this 17988 */ 17989 LightGallery.prototype.buildModules = function () { 17990 var _this = this; 17991 this.settings.plugins.forEach(function (plugin) { 17992 _this.plugins.push(new plugin(_this, $LG)); 17993 }); 17994 }; 17995 LightGallery.prototype.validateLicense = function () { 17996 if (!this.settings.licenseKey) { 17997 console.warn('Please provide a valid license key'); 17998 } 17999 else if (this.settings.licenseKey === '0000-0000-000-0000') { 18000 console.warn("lightGallery: " + this.settings.licenseKey + " license key is not val
vendor: 17,473 bytes, lines 18000-18414
18000id for production use"); 18001 } 18002 }; 18003 LightGallery.prototype.getSlideItem = function (index) { 18004 return $LG(this.getSlideItemId(index)); 18005 }; 18006 LightGallery.prototype.getSlideItemId = function (index) { 18007 return "#lg-item-" + this.lgId + "-" + index; 18008 }; 18009 LightGallery.prototype.getIdName = function (id) { 18010 return id + "-" + this.lgId; 18011 }; 18012 LightGallery.prototype.getElementById = function (id) { 18013 return $LG("#" + this.getIdName(id)); 18014 }; 18015 LightGallery.prototype.manageSingleSlideClassName = function () { 18016 if (this.galleryItems.length < 2) { 18017 this.outer.addClass('lg-single-item'); 18018 } 18019 else { 18020 this.outer.removeClass('lg-single-item'); 18021 } 18022 }; 18023 LightGallery.prototype.buildStructure = function () { 18024 var _this = this; 18025 var container = this.$container && this.$container.get(); 18026 if (container) { 18027 return; 18028 } 18029 var controls = ''; 18030 var subHtmlCont = ''; 18031 // Create controls 18032 if (this.settings.controls) { 18033 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>"; 18034 } 18035 if (this.settings.appendSubHtmlTo !== '.lg-item') { 18036 subHtmlCont = 18037 '<div class="lg-sub-html" role="status" aria-live="polite"></div>'; 18038 } 18039 var addClasses = ''; 18040 if (this.settings.allowMediaOverlap) { 18041 // Do not remove space before last single quote 18042 addClasses += 'lg-media-overlap '; 18043 } 18044 var ariaLabelledby = this.settings.ariaLabelledby 18045 ? 'aria-labelledby="' + this.settings.ariaLabelledby + '"' 18046 : ''; 18047 var ariaDescribedby = this.settings.ariaDescribedby 18048 ? 'aria-describedby="' + this.settings.ariaDescribedby + '"' 18049 : ''; 18050 var containerClassName = "lg-container " + this.settings.addClass + " " + (document.body !== this.settings.container ? 'lg-inline' : ''); 18051 var closeIcon = this.settings.closable && this.settings.showCloseIcon 18052 ? "<button type=\"button\" aria-label=\"" + this.settings.strings['closeGallery'] + "\" id=\"" + this.getIdName('lg-close') + "\" class=\"lg-close lg-icon\"></button>" 18053 : ''; 18054 var maximizeIcon = this.settings.showMaximizeIcon 18055 ? "<button type=\"button\" aria-label=\"" + this.settings.strings['toggleMaximize'] + "\" id=\"" + this.getIdName('lg-maximize') + "\" class=\"lg-maximize lg-icon\"></button>" 18056 : ''; 18057 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' 18058 ? subHtmlCont 18059 : '') + "\n <div id=\"" + this.getIdName('lg-components') + "\" class=\"lg-components\">\n " + (this.settings.appendSubHtmlTo === '.lg-sub-html' 18060 ? subHtmlCont 18061 : '') + "\n </div>\n </div>\n </div>\n "; 18062 $LG(this.settings.container).append(template); 18063 if (document.body !== this.settings.container) { 18064 $LG(this.settings.container).css('position', 'relative'); 18065 } 18066 this.outer = this.getElementById('lg-outer'); 18067 this.$lgComponents = this.getElementById('lg-components'); 18068 this.$backdrop = this.getElementById('lg-backdrop'); 18069 this.$container = this.getElementById('lg-container'); 18070 this.$inner = this.getElementById('lg-inner'); 18071 this.$content = this.getElementById('lg-content'); 18072 this.$toolbar = this.getElementById('lg-toolbar'); 18073 this.$backdrop.css('transition-duration', this.settings.backdropDuration + 'ms'); 18074 var outerClassNames = this.settings.mode + " "; 18075 this.manageSingleSlideClassName(); 18076 if (this.settings.enableDrag) { 18077 outerClassNames += 'lg-grab '; 18078 } 18079 this.outer.addClass(outerClassNames); 18080 this.$inner.css('transition-timing-function', this.settings.easing); 18081 this.$inner.css('transition-duration', this.settings.speed + 'ms'); 18082 if (this.settings.download) { 18083 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>"); 18084 } 18085 this.counter(); 18086 $LG(window).on("resize.lg.global" + this.lgId + " orientationchange.lg.global" + this.lgId, function () { 18087 _this.refreshOnResize(); 18088 }); 18089 this.hideBars(); 18090 this.manageCloseGallery(); 18091 this.toggleMaximize(); 18092 this.initModules(); 18093 }; 18094 LightGallery.prototype.refreshOnResize = function () { 18095 if (this.lgOpened) { 18096 var currentGalleryItem = this.galleryItems[this.index]; 18097 var __slideVideoInfo = currentGalleryItem.__slideVideoInfo; 18098 this.mediaContainerPosition = this.getMediaContainerPosition(); 18099 var _a = this.mediaContainerPosition, top_1 = _a.top, bottom = _a.bottom; 18100 //Uncode edit ##START## 18101 this.currentImageSize = utils.getSize(this.items[this.index], this.outer, top_1 + bottom, __slideVideoInfo && this.settings.videoMaxSize, this.galleryItems[this.index]); 18102 // this.currentImageSize = utils.getSize(this.items[this.index], this.outer, top_1 + bottom, __slideVideoInfo && this.settings.videoMaxSize); 18103 //Uncode edit ##END## 18104 if (__slideVideoInfo) { 18105 this.resizeVideoSlide(this.index, this.currentImageSize); 18106 } 18107 if (this.zoomFromOrigin && !this.isDummyImageRemoved) { 18108 var imgStyle = this.getDummyImgStyles(this.currentImageSize); 18109 this.outer 18110 .find('.lg-current .lg-dummy-img') 18111 .first() 18112 .attr('style', imgStyle); 18113 } 18114 this.LGel.trigger(lGEvents.containerResize); 18115 } 18116 }; 18117 LightGallery.prototype.resizeVideoSlide = function (index, imageSize) { 18118 var lgVideoStyle = this.getVideoContStyle(imageSize); 18119 var currentSlide = this.getSlideItem(index); 18120 currentSlide.find('.lg-video-cont').attr('style', lgVideoStyle); 18121 }; 18122 /** 18123 * Update slides dynamically. 18124 * Add, edit or delete slides dynamically when lightGallery is opened. 18125 * Modify the current gallery items and pass it via updateSlides method 18126 * @note 18127 * - Do not mutate existing lightGallery items directly. 18128 * - Always pass new list of gallery items 18129 * - You need to take care of thumbnails outside the gallery if any 18130 * - user this method only if you want to update slides when the gallery is opened. Otherwise, use `refresh()` method. 18131 * @param items Gallery items 18132 * @param index After the update operation, which slide gallery should navigate to 18133 * @category lGPublicMethods 18134 * @example 18135 * const plugin = lightGallery(); 18136 * 18137 * // Adding slides dynamically 18138 * let galleryItems = [ 18139 * // Access existing lightGallery items 18140 * // galleryItems are automatically generated internally from the gallery HTML markup 18141 * // or directly from galleryItems when dynamic gallery is used 18142 * ...plugin.galleryItems, 18143 * ...[ 18144 * { 18145 * src: 'img/img-1.png', 18146 * thumb: 'img/thumb1.png', 18147 * }, 18148 * ], 18149 * ]; 18150 * plugin.updateSlides( 18151 * galleryItems, 18152 * plugin.index, 18153 * ); 18154 * 18155 * 18156 * // Remove slides dynamically 18157 * galleryItems = JSON.parse( 18158 * JSON.stringify(updateSlideInstance.galleryItems), 18159 * ); 18160 * galleryItems.shift(); 18161 * updateSlideInstance.updateSlides(galleryItems, 1); 18162 * @see <a href="/demos/update-slides/">Demo</a> 18163 */ 18164 LightGallery.prototype.updateSlides = function (items, index) { 18165 if (this.index > items.length - 1) { 18166 this.index = items.length - 1; 18167 } 18168 if (items.length === 1) { 18169 this.index = 0; 18170 } 18171 if (!items.length) { 18172 this.closeGallery(); 18173 return; 18174 } 18175 var currentSrc = this.galleryItems[index].src; 18176 this.galleryItems = items; 18177 this.updateControls(); 18178 this.$inner.empty(); 18179 this.currentItemsInDom = []; 18180 var _index = 0; 18181 // Find the current index based on source value of the slide 18182 this.galleryItems.some(function (galleryItem, itemIndex) { 18183 if (galleryItem.src === currentSrc) { 18184 _index = itemIndex; 18185 return true; 18186 } 18187 return false; 18188 }); 18189 this.currentItemsInDom = this.organizeSlideItems(_index, -1); 18190 this.loadContent(_index, true); 18191 this.getSlideItem(_index).addClass('lg-current'); 18192 this.index = _index; 18193 this.updateCurrentCounter(_index); 18194 this.LGel.trigger(lGEvents.updateSlides); 18195 }; 18196 // Get gallery items based on multiple conditions 18197 LightGallery.prototype.getItems = function () { 18198 // Gallery items 18199 this.items = []; 18200 if (!this.settings.dynamic) { 18201 if (this.settings.selector === 'this') { 18202 this.items.push(this.el); 18203 } 18204 else if (this.settings.selector) { 18205 if (typeof this.settings.selector === 'string') { 18206 if (this.settings.selectWithin) { 18207 var selectWithin = $LG(this.settings.selectWithin); 18208 this.items = selectWithin 18209 .find(this.settings.selector) 18210 .get(); 18211 } 18212 else { 18213 this.items = this.el.querySelectorAll(this.settings.selector); 18214 } 18215 } 18216 else { 18217 this.items = this.settings.selector; 18218 } 18219 } 18220 else { 18221 this.items = this.el.children; 18222 } 18223 return utils.getDynamicOptions(this.items, this.settings.extraProps, this.settings.getCaptionFromTitleOrAlt, this.settings.exThumbImage); 18224 } 18225 else { 18226 return this.settings.dynamicEl || []; 18227 } 18228 }; 18229 LightGallery.prototype.shouldHideScrollbar = function () { 18230 return (this.settings.hideScrollbar && 18231 document.body === this.settings.container); 18232 }; 18233 LightGallery.prototype.hideScrollbar = function () { 18234 if (!this.shouldHideScrollbar()) { 18235 return; 18236 } 18237 this.bodyPaddingRight = parseFloat($LG('body').style().paddingRight); 18238 var bodyRect = document.documentElement.getBoundingClientRect(); 18239 var scrollbarWidth = window.innerWidth - bodyRect.width; 18240 $LG(document.body).css('padding-right', scrollbarWidth + this.bodyPaddingRight + 'px'); 18241 $LG(document.body).addClass('lg-overlay-open'); 18242 }; 18243 LightGallery.prototype.resetScrollBar = function () { 18244 if (!this.shouldHideScrollbar()) { 18245 return; 18246 } 18247 $LG(document.body).css('padding-right', this.bodyPaddingRight + 'px'); 18248 $LG(document.body).removeClass('lg-overlay-open'); 18249 }; 18250 /** 18251 * Open lightGallery. 18252 * Open gallery with specific slide by passing index of the slide as parameter. 18253 * @category lGPublicMethods 18254 * @param {Number} index - index of the slide 18255 * @param {HTMLElement} element - Which image lightGallery should zoom from 18256 * 18257 * @example 18258 * const $dynamicGallery = document.getElementById('dynamic-gallery-demo'); 18259 * const dynamicGallery = lightGallery($dynamicGallery, { 18260 * dynamic: true, 18261 * dynamicEl: [ 18262 * { 18263 * src: 'img/1.jpg', 18264 * thumb: 'img/thumb-1.jpg', 18265 * subHtml: '<h4>Image 1 title</h4><p>Image 1 descriptions.</p>', 18266 * }, 18267 * ... 18268 * ], 18269 * }); 18270 * $dynamicGallery.addEventListener('click', function () { 18271 * // Starts with third item.(Optional). 18272 * // This is useful if you want use dynamic mode with 18273 * // custom thumbnails (thumbnails outside gallery), 18274 * dynamicGallery.openGallery(2); 18275 * }); 18276 * 18277 */ 18278 LightGallery.prototype.openGallery = function (index, element) { 18279 var _this = this; 18280 if (index === void 0) { index = this.settings.index; } 18281 // prevent accidental double execution 18282 if (this.lgOpened) 18283 return; 18284 this.lgOpened = true; 18285 this.outer.removeClass('lg-hide-items'); 18286 this.hideScrollbar(); 18287 // Add display block, but still has opacity 0 18288 this.$container.addClass('lg-show'); 18289 var itemsToBeInsertedToDom = this.getItemsToBeInsertedToDom(index, index); 18290 this.currentItemsInDom = itemsToBeInsertedToDom; 18291 var items = ''; 18292 itemsToBeInsertedToDom.forEach(function (item) { 18293 items = items + ("<div id=\"" + item + "\" class=\"lg-item\"></div>"); 18294 }); 18295 this.$inner.append(items); 18296 this.addHtml(index); 18297 var transform = ''; 18298 this.mediaContainerPosition = this.getMediaContainerPosition(); 18299 var _a = this.mediaContainerPosition, top = _a.top, bottom = _a.bottom; 18300 if (!this.settings.allowMediaOverlap) { 18301 this.setMediaContainerPosition(top, bottom); 18302 } 18303 var __slideVideoInfo = this.galleryItems[index].__slideVideoInfo; 18304 if (this.zoomFromOrigin && element) { 18305 //Uncode edit ##START## 18306 this.currentImageSize = utils.getSize(element, this.outer, top + bottom, __slideVideoInfo && this.settings.videoMaxSize, this.galleryItems[this.index]); 18307 // this.currentImageSize = utils.getSize(element, this.outer, top + bottom, __slideVideoInfo && this.settings.videoMaxSize); 18308 //Uncode edit ##END## 18309 transform = utils.getTransform(element, this.outer, top, bottom, this.currentImageSize); 18310 } 18311 if (!this.zoomFromOrigin || !transform) { 18312 this.outer.addClass(this.settings.startClass); 18313 this.getSlideItem(index).removeClass('lg-complete'); 18314 } 18315 var timeout = this.settings.zoomFromOrigin 18316 ? 100 18317 : this.settings.backdropDuration; 18318 setTimeout(function () { 18319 _this.outer.addClass('lg-components-open'); 18320 }, timeout); 18321 this.index = index; 18322 //Uncode edit ##START## 18323 // this.LGel.trigger(lGEvents.beforeOpen); 18324 this.LGel.trigger(lGEvents.beforeOpen, { 18325 galleryItems: this.galleryItems, 18326 items: this.items, 18327 outer: this.outer, 18328 }); 18329 //Uncode edit ##END## 18330 // add class lg-current to remove initial transition 18331 this.getSlideItem(index).addClass('lg-current'); 18332 this.lGalleryOn = false; 18333 // Store the current scroll top value to scroll back after closing the gallery.. 18334 this.prevScrollTop = $LG(window).scrollTop(); 18335 setTimeout(function () { 18336 // Need to check both zoomFromOrigin and transform values as we need to set set the 18337 // default opening animation if user missed to add the lg-size attribute 18338 if (_this.zoomFromOrigin && transform) { 18339 var currentSlide_1 = _this.getSlideItem(index); 18340 currentSlide_1.css('transform', transform); 18341 setTimeout(function () { 18342 currentSlide_1 18343 .addClass('lg-start-progress lg-start-end-progress') 18344 .css('transition-duration', _this.settings.startAnimationDuration + 'ms'); 18345 _this.outer.addClass('lg-zoom-from-image'); 18346 }); 18347 setTimeout(function () { 18348 currentSlide_1.css('transform', 'translate3d(0, 0, 0)'); 18349 }, 100); 18350 } 18351 setTimeout(function () { 18352 _this.$backdrop.addClass('in'); 18353 _this.$container.addClass('lg-show-in'); 18354 }, 10); 18355 setTimeout(function () { 18356 if (_this.settings.trapFocus && 18357 document.body === _this.settings.container) { 18358 _this.trapFocus(); 18359 } 18360 }, _this.settings.backdropDuration + 50); 18361 // lg-visible class resets gallery opacity to 1 18362 if (!_this.zoomFromOrigin || !transform) { 18363 setTimeout(function () { 18364 _this.outer.addClass('lg-visible'); 18365 }, _this.settings.backdropDuration); 18366 } 18367 // initiate slide function 18368 _this.slide(index, false, false, false); 18369 _this.LGel.trigger(lGEvents.afterOpen); 18370 }); 18371 if (document.body === this.settings.container) { 18372 $LG('html').addClass('lg-on'); 18373 } 18374 }; 18375 /** 18376 * Note - Changing the position of the media on every slide transition creates a flickering effect. 18377 * Therefore, The height of the caption is calculated dynamically, only once based on the first slide caption. 18378 * if you have dynamic captions for each media, 18379 * you can provide an appropriate height for the captions via allowMediaOverlap option 18380 */ 18381 LightGallery.prototype.getMediaContainerPosition = function () { 18382 if (this.settings.allowMediaOverlap) { 18383 return { 18384 top: 0, 18385 bottom: 0, 18386 }; 18387 } 18388 var top = this.$toolbar.get().clientHeight || 0; 18389 var subHtml = this.outer.find('.lg-components .lg-sub-html').get(); 18390 var captionHeight = this.settings.defaultCaptionHeight || 18391 (subHtml && subHtml.clientHeight) || 18392 0; 18393 var thumbContainer = this.outer.find('.lg-thumb-outer').get(); 18394 var thumbHeight = thumbContainer ? thumbContainer.clientHeight : 0; 18395 var bottom = thumbHeight + captionHeight; 18396 //Uncode edit ##START## 18397 bottom = bottom < 55 ? 55 : bottom; 18398 //Uncode edit ##END## 18399 return { 18400 top: top, 18401 bottom: bottom, 18402 }; 18403 }; 18404 LightGallery.prototype.setMediaContainerPosition = function (top, bottom) { 18405 if (top === void 0) { top = 0; } 18406 if (bottom === void 0) { bottom = 0; } 18407 this.$content.css('top', top + 'px').css('bottom', bottom + 'px'); 18408 }; 18409 LightGallery.prototype.hideBars = function () { 18410 var _this = this; 18411 // Hide controllers if mouse doesn't move for some period 18412 setTimeout(function () { 18413 _this.outer.removeClass('lg-hide-items'); 18414 if (_this.settings.hideBarsDelay > 0) {
vendor: 4,223 bytes, lines 18415-18545
18415 _this.outer.on('mousemove.lg click.lg touchstart.lg', function () { 18416 _this.outer.removeClass('lg-hide-items'); 18417 clearTimeout(_this.hideBarTimeout); 18418 // Timeout will be cleared on each slide movement also 18419 _this.hideBarTimeout = setTimeout(function () { 18420 _this.outer.addClass('lg-hide-items'); 18421 }, _this.settings.hideBarsDelay); 18422 }); 18423 _this.outer.trigger('mousemove.lg'); 18424 } 18425 }, this.settings.showBarsAfter); 18426 }; 18427 LightGallery.prototype.initPictureFill = function ($img) { 18428 if (this.settings.supportLegacyBrowser) { 18429 try { 18430 picturefill({ 18431 elements: [$img.get()], 18432 }); 18433 } 18434 catch (e) { 18435 console.warn('lightGallery :- If you want srcset or picture tag to be supported for older browser please include picturefil javascript library in your document.'); 18436 } 18437 } 18438 }; 18439 /** 18440 * @desc Create image counter 18441 * Ex: 1/10 18442 */ 18443 LightGallery.prototype.counter = function () { 18444 if (this.settings.counter) { 18445 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>"; 18446 this.outer.find(this.settings.appendCounterTo).append(counterHtml); 18447 } 18448 }; 18449 /** 18450 * @desc add sub-html into the slide 18451 * @param {Number} index - index of the slide 18452 */ 18453 LightGallery.prototype.addHtml = function (index) { 18454 var subHtml; 18455 var subHtmlUrl; 18456 if (this.galleryItems[index].subHtmlUrl) { 18457 subHtmlUrl = this.galleryItems[index].subHtmlUrl; 18458 } 18459 else { 18460 subHtml = this.galleryItems[index].subHtml; 18461 } 18462 if (!subHtmlUrl) { 18463 if (subHtml) { 18464 // get first letter of sub-html 18465 // if first letter starts with . or # get the html form the jQuery object 18466 var fL = subHtml.substring(0, 1); 18467 if (fL === '.' || fL === '#') { 18468 if (this.settings.subHtmlSelectorRelative && 18469 !this.settings.dynamic) { 18470 subHtml = $LG(this.items) 18471 .eq(index) 18472 .find(subHtml) 18473 .first() 18474 .html(); 18475 } 18476 else { 18477 subHtml = $LG(subHtml).first().html(); 18478 } 18479 } 18480 } 18481 else { 18482 subHtml = ''; 18483 } 18484 } 18485 if (this.settings.appendSubHtmlTo !== '.lg-item') { 18486 if (subHtmlUrl) { 18487 this.outer.find('.lg-sub-html').load(subHtmlUrl); 18488 } 18489 else { 18490 this.outer.find('.lg-sub-html').html(subHtml); 18491 } 18492 } 18493 else { 18494 var currentSlide = $LG(this.getSlideItemId(index)); 18495 if (subHtmlUrl) { 18496 currentSlide.load(subHtmlUrl); 18497 } 18498 else { 18499 currentSlide.append("<div class=\"lg-sub-html\">" + subHtml + "</div>"); 18500 } 18501 } 18502 // Add lg-empty-html class if title doesn't exist 18503 if (typeof subHtml !== 'undefined' && subHtml !== null) { 18504 if (subHtml === '') { 18505 this.outer 18506 .find(this.settings.appendSubHtmlTo) 18507 .addClass('lg-empty-html'); 18508 } 18509 else { 18510 this.outer 18511 .find(this.settings.appendSubHtmlTo) 18512 .removeClass('lg-empty-html'); 18513 } 18514 } 18515 this.LGel.trigger(lGEvents.afterAppendSubHtml, { 18516 index: index, 18517 }); 18518 }; 18519 /** 18520 * @desc Preload slides 18521 * @param {Number} index - index of the slide 18522 * @todo preload not working for the first slide, Also, should work for the first and last slide as well 18523 */ 18524 LightGallery.prototype.preload = function (index) { 18525 for (var i = 1; i <= this.settings.preload; i++) { 18526 if (i >= this.galleryItems.length - index) { 18527 break; 18528 } 18529 this.loadContent(index + i, false); 18530 } 18531 for (var j = 1; j <= this.settings.preload; j++) { 18532 if (index - j < 0) { 18533 break; 18534 } 18535 this.loadContent(index - j, false); 18536 } 18537 }; 18538 LightGallery.prototype.getDummyImgStyles = function (imageSize) { 18539 if (!imageSize) 18540 return ''; 18541 return "width:" + imageSize.width + "px;\n margin-left: -" + imageSize.width / 2 + "px;\n margin-top: -" + imageSize.height / 2 + "px;\n height:" + imageSize.height + "px"; 18542 }; 18543 LightGallery.prototype.getVideoContStyle = function (imageSize) { 18544 if (!imageSize) 18545 return '';
18546 return "width:" + imageSize.width + "px;\n height:" + imageSize.height + "px"; 18547 }; 18548 LightGallery.prototype.getDummyImageContent = function ($currentSlide, index, alt) { 18549 var $currentItem; 18550 if (!this.settings.dynamic) { 18551 $currentItem = $LG(this.items).eq(index); 18552 } 18553 if ($currentItem) { 18554 var _dummyImgSrc = void 0; 18555 if (!this.settings.exThumbImage) { 18556 _dummyImgSrc = $currentItem.find('img').first().attr('src'); 18557 } 18558 else { 18559 _dummyImgSrc = $currentItem.attr(this.settings.exThumbImage); 18560 } 18561 if (!_dummyImgSrc) 18562 return ''; 18563 var imgStyle = this.getDummyImgStyles(this.currentImageSize); 18564 var dummyImgContent = "<img " + alt + " style=\"" + imgStyle + "\" class=\"lg-dummy-img\" src=\"" + _dummyImgSrc + "\" />"; 18565 $currentSlide.addClass('lg-first-slide'); 18566 this.outer.addClass('lg-first-slide-loading'); 18567 return dummyImgContent; 18568 } 18569 return ''; 18570 }; 18571 LightGallery.prototype.setImgMarkup = function (src, $currentSlide, index) { 18572 var currentGalleryItem = this.galleryItems[index]; 18573 var alt = currentGalleryItem.alt, srcset = currentGalleryItem.srcset, sizes = currentGalleryItem.sizes, sources = currentGalleryItem.sources; 18574 // Use the thumbnail as dummy image which will be resized to actual image size and 18575 // displayed on top of actual image 18576 var imgContent = ''; 18577 var altAttr = alt ? 'alt="' + alt + '"' : ''; 18578 if (this.isFirstSlideWithZoomAnimation()) { 18579 imgContent = this.getDummyImageContent($currentSlide, index, altAttr); 18580 } 18581 else { 18582 imgContent = utils.getImgMarkup(index, src, altAttr, srcset, sizes, sources); 18583 } 18584 var imgMarkup = "<picture class=\"lg-img-wrap\"> " + imgContent + "</picture>"; 18585 $currentSlide.prepend(imgMarkup); 18586 }; 18587 LightGallery.prototype.onSlideObjectLoad = function ($slide, isHTML5VideoWithoutPoster, onLoad, onError) { 18588 var mediaObject = $slide.find('.lg-object').first(); 18589 if (utils.isImageLoaded(mediaObject.get()) || 18590 isHTML5VideoWithoutPoster) { 18591 onLoad(); 18592 } 18593 else { 18594 mediaObject.on('load.lg error.lg', function () { 18595 onLoad && onLoad(); 18596 }); 18597 mediaObject.on('error.lg', function () { 18598 onError && onError(); 18599 }); 18600 } 18601 }; 18602 /** 18603 * 18604 * @param $el Current slide item 18605 * @param index 18606 * @param delay Delay is 0 except first time 18607 * @param speed Speed is same as delay, except it is 0 if gallery is opened via hash plugin 18608 * @param isFirstSlide 18609 */ 18610 LightGallery.prototype.onLgObjectLoad = function (currentSlide, index, delay, speed, isFirstSlide, isHTML5VideoWithoutPoster) { 18611 var _this = this; 18612 //Uncode edit ##START## 18613 var $item = _this.galleryItems[index], 18614 type = $item.type; 18615 18616 if ( typeof $item.src !== 'undefined' ) { 18617 var inline_id = $item.src.replace('#', ''), 18618 $inline = document.getElementById(inline_id), 18619 inline_html; 18620 18621 if ( type === 'inline' && inline_id != null && typeof $inline !== 'undefined' ) { 18622 inline_html = $inline.innerHTML; 18623 } else { 18624 inline_html = ''; 18625 } 18626 } 18627 //Uncode edit ##END## 18628 this.onSlideObjectLoad(currentSlide, true, function () { 18629 _this.triggerSlideItemLoad(currentSlide, index, delay, speed, isFirstSlide); 18630 }, function () { 18631 currentSlide.addClass('lg-complete lg-complete_'); 18632 //Uncode edit ##START## 18633 // currentSlide.html('<span class="lg-error-msg">Oops... Failed to load content...</span>'); 18634 if ( inline_html !== '' ) { 18635 currentSlide.html(inline_html); 18636 } else { 18637 currentSlide.html('<span class="lg-error-msg">Oops... Failed to load content...</span>'); 18638 } 18639 //Uncode edit ##END## 18640 }); 18641 }; 18642 LightGallery.prototype.triggerSlideItemLoad = function ($currentSlide, index, delay, speed, isFirstSlide) { 18643 var _this = this; 18644 var currentGalleryItem = this.galleryItems[index]; 18645 // Adding delay for video slides without poster for better performance and user experience 18646 // Videos should start playing once once the gallery is completely loaded 18647 var _speed = isFirstSlide &&
vendor: 37,932 bytes, lines 18648-19737
18648 this.getSlideType(currentGalleryItem) === 'video' && 18649 !currentGalleryItem.poster 18650 ? speed 18651 : 0; 18652 setTimeout(function () { 18653 $currentSlide.addClass('lg-complete lg-complete_'); 18654 _this.LGel.trigger(lGEvents.slideItemLoad, { 18655 index: index, 18656 delay: delay || 0, 18657 isFirstSlide: isFirstSlide, 18658 }); 18659 }, _speed); 18660 }; 18661 LightGallery.prototype.isFirstSlideWithZoomAnimation = function () { 18662 return !!(!this.lGalleryOn && 18663 this.zoomFromOrigin && 18664 this.currentImageSize); 18665 }; 18666 // Add video slideInfo 18667 LightGallery.prototype.addSlideVideoInfo = function (items) { 18668 var _this = this; 18669 items.forEach(function (element, index) { 18670 element.__slideVideoInfo = utils.isVideo(element.src, !!element.video, index); 18671 if (element.__slideVideoInfo && 18672 _this.settings.loadYouTubePoster && 18673 !element.poster && 18674 element.__slideVideoInfo.youtube) { 18675 element.poster = "//img.youtube.com/vi/" + element.__slideVideoInfo.youtube[1] + "/maxresdefault.jpg"; 18676 } 18677 }); 18678 }; 18679 /** 18680 * Load slide content into slide. 18681 * This is used to load content into slides that is not visible too 18682 * @param {Number} index - index of the slide. 18683 * @param {Boolean} rec - if true call loadcontent() function again. 18684 */ 18685 LightGallery.prototype.loadContent = function (index, rec) { 18686 var _this = this; 18687 var currentGalleryItem = this.galleryItems[index]; 18688 var $currentSlide = $LG(this.getSlideItemId(index)); 18689 var poster = currentGalleryItem.poster, srcset = currentGalleryItem.srcset, sizes = currentGalleryItem.sizes, sources = currentGalleryItem.sources; 18690 var src = currentGalleryItem.src; 18691 var video = currentGalleryItem.video; 18692 var _html5Video = video && typeof video === 'string' ? JSON.parse(video) : video; 18693 if (currentGalleryItem.responsive) { 18694 var srcDyItms = currentGalleryItem.responsive.split(','); 18695 src = utils.getResponsiveSrc(srcDyItms) || src; 18696 } 18697 var videoInfo = currentGalleryItem.__slideVideoInfo; 18698 var lgVideoStyle = ''; 18699 var iframe = !!currentGalleryItem.iframe; 18700 var isFirstSlide = !this.lGalleryOn; 18701 // delay for adding complete class. it is 0 except first time. 18702 var delay = 0; 18703 if (isFirstSlide) { 18704 if (this.zoomFromOrigin && this.currentImageSize) { 18705 delay = this.settings.startAnimationDuration + 10; 18706 } 18707 else { 18708 delay = this.settings.backdropDuration + 10; 18709 } 18710 } 18711 if (!$currentSlide.hasClass('lg-loaded')) { 18712 if (videoInfo) { 18713 var _a = this.mediaContainerPosition, top_2 = _a.top, bottom = _a.bottom; 18714 //Uncode edit ##START## 18715 var videoSize = utils.getSize(this.items[index], this.outer, top_2 + bottom, videoInfo && this.settings.videoMaxSize, this.galleryItems[this.index]); 18716 // var videoSize = utils.getSize(this.items[index], this.outer, top_2 + bottom, videoInfo && this.settings.videoMaxSize); 18717 //Uncode edit ##END## 18718 lgVideoStyle = this.getVideoContStyle(videoSize); 18719 } 18720 if (iframe) { 18721 var markup = utils.getIframeMarkup(this.settings.iframeWidth, this.settings.iframeHeight, this.settings.iframeMaxWidth, this.settings.iframeMaxHeight, src, currentGalleryItem.iframeTitle); 18722 $currentSlide.prepend(markup); 18723 } 18724 else if (poster) { 18725 var dummyImg = ''; 18726 var hasStartAnimation = isFirstSlide && 18727 this.zoomFromOrigin && 18728 this.currentImageSize; 18729 if (hasStartAnimation) { 18730 dummyImg = this.getDummyImageContent($currentSlide, index, ''); 18731 } 18732 var markup = utils.getVideoPosterMarkup(poster, dummyImg || '', lgVideoStyle, this.settings.strings['playVideo'], videoInfo); 18733 $currentSlide.prepend(markup); 18734 } 18735 //Uncode edit ##START## 18736 // else if (videoInfo) { 18737 else if (videoInfo || this.getSlideType(currentGalleryItem) === 'audio') { 18738 if (! _html5Video) { 18739 var markup = "<div class=\"lg-video-cont \" style=\"" + lgVideoStyle + "\"></div>"; 18740 } 18741 //Uncode edit ##END## 18742 $currentSlide.prepend(markup); 18743 } 18744 else { 18745 this.setImgMarkup(src, $currentSlide, index); 18746 if (srcset || sources) { 18747 var $img = $currentSlide.find('.lg-object'); 18748 this.initPictureFill($img); 18749 } 18750 } 18751 if (poster || videoInfo) { 18752 this.LGel.trigger(lGEvents.hasVideo, { 18753 index: index, 18754 src: src, 18755 html5Video: _html5Video, 18756 hasPoster: !!poster, 18757 }); 18758 } 18759 this.LGel.trigger(lGEvents.afterAppendSlide, { index: index }); 18760 if (this.lGalleryOn && 18761 this.settings.appendSubHtmlTo === '.lg-item') { 18762 this.addHtml(index); 18763 } 18764 } 18765 // For first time add some delay for displaying the start animation. 18766 var _speed = 0; 18767 // Do not change the delay value because it is required for zoom plugin. 18768 // If gallery opened from direct url (hash) speed value should be 0 18769 if (delay && !$LG(document.body).hasClass('lg-from-hash')) { 18770 _speed = delay; 18771 } 18772 // Only for first slide and zoomFromOrigin is enabled 18773 if (this.isFirstSlideWithZoomAnimation()) { 18774 setTimeout(function () { 18775 $currentSlide 18776 .removeClass('lg-start-end-progress lg-start-progress') 18777 .removeAttr('style'); 18778 }, this.settings.startAnimationDuration + 100); 18779 if (!$currentSlide.hasClass('lg-loaded')) { 18780 setTimeout(function () { 18781 if (_this.getSlideType(currentGalleryItem) === 'image') { 18782 var alt = currentGalleryItem.alt; 18783 var altAttr = alt ? 'alt="' + alt + '"' : ''; 18784 $currentSlide 18785 .find('.lg-img-wrap') 18786 .append(utils.getImgMarkup(index, src, altAttr, srcset, sizes, currentGalleryItem.sources)); 18787 if (srcset || sources) { 18788 var $img = $currentSlide.find('.lg-object'); 18789 _this.initPictureFill($img); 18790 } 18791 } 18792 if (_this.getSlideType(currentGalleryItem) === 'image' || 18793 (_this.getSlideType(currentGalleryItem) === 'video' && 18794 poster)) { 18795 _this.onLgObjectLoad($currentSlide, index, delay, _speed, true, false); 18796 // load remaining slides once the slide is completely loaded 18797 _this.onSlideObjectLoad($currentSlide, !!(videoInfo && videoInfo.html5 && !poster), function () { 18798 _this.loadContentOnFirstSlideLoad(index, $currentSlide, _speed); 18799 }, function () { 18800 _this.loadContentOnFirstSlideLoad(index, $currentSlide, _speed); 18801 }); 18802 } 18803 }, this.settings.startAnimationDuration + 100); 18804 } 18805 } 18806 // SLide content has been added to dom 18807 $currentSlide.addClass('lg-loaded'); 18808 if (!this.isFirstSlideWithZoomAnimation() || 18809 (this.getSlideType(currentGalleryItem) === 'video' && !poster)) { 18810 //Uncode edit ##START## 18811 // this.onLgObjectLoad($currentSlide, index, delay, _speed, isFirstSlide, !!(videoInfo && videoInfo.html5 && !poster)); 18812 this.onLgObjectLoad($currentSlide, index, delay, _speed, isFirstSlide, !!( (videoInfo && videoInfo.html5 && !poster) || this.getSlideType(currentGalleryItem) === 'audio')); 18813 //Uncode edit ##END## 18814 } 18815 // When gallery is opened once content is loaded (second time) need to add lg-complete class for css styling 18816 if ((!this.zoomFromOrigin || !this.currentImageSize) && 18817 $currentSlide.hasClass('lg-complete_') && 18818 !this.lGalleryOn) { 18819 setTimeout(function () { 18820 $currentSlide.addClass('lg-complete'); 18821 }, this.settings.backdropDuration); 18822 } 18823 // Content loaded 18824 // Need to set lGalleryOn before calling preload function 18825 this.lGalleryOn = true; 18826 if (rec === true) { 18827 if (!$currentSlide.hasClass('lg-complete_')) { 18828 $currentSlide 18829 .find('.lg-object') 18830 .first() 18831 .on('load.lg error.lg', function () { 18832 _this.preload(index); 18833 }); 18834 } 18835 else { 18836 this.preload(index); 18837 } 18838 } 18839 }; 18840 /** 18841 * @desc Remove dummy image content and load next slides 18842 * Called only for the first time if zoomFromOrigin animation is enabled 18843 * @param index 18844 * @param $currentSlide 18845 * @param speed 18846 */ 18847 LightGallery.prototype.loadContentOnFirstSlideLoad = function (index, $currentSlide, speed) { 18848 var _this = this; 18849 setTimeout(function () { 18850 $currentSlide.find('.lg-dummy-img').remove(); 18851 $currentSlide.removeClass('lg-first-slide'); 18852 _this.outer.removeClass('lg-first-slide-loading'); 18853 _this.isDummyImageRemoved = true; 18854 _this.preload(index); 18855 }, speed + 300); 18856 }; 18857 LightGallery.prototype.getItemsToBeInsertedToDom = function (index, prevIndex, numberOfItems) { 18858 var _this = this; 18859 if (numberOfItems === void 0) { numberOfItems = 0; } 18860 var itemsToBeInsertedToDom = []; 18861 // Minimum 2 items should be there 18862 var possibleNumberOfItems = Math.max(numberOfItems, 3); 18863 possibleNumberOfItems = Math.min(possibleNumberOfItems, this.galleryItems.length); 18864 var prevIndexItem = "lg-item-" + this.lgId + "-" + prevIndex; 18865 if (this.galleryItems.length <= 3) { 18866 this.galleryItems.forEach(function (_element, index) { 18867 itemsToBeInsertedToDom.push("lg-item-" + _this.lgId + "-" + index); 18868 }); 18869 return itemsToBeInsertedToDom; 18870 } 18871 if (index < (this.galleryItems.length - 1) / 2) { 18872 for (var idx = index; idx > index - possibleNumberOfItems / 2 && idx >= 0; idx--) { 18873 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + idx); 18874 } 18875 var numberOfExistingItems = itemsToBeInsertedToDom.length; 18876 for (var idx = 0; idx < possibleNumberOfItems - numberOfExistingItems; idx++) { 18877 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + (index + idx + 1)); 18878 } 18879 } 18880 else { 18881 for (var idx = index; idx <= this.galleryItems.length - 1 && 18882 idx < index + possibleNumberOfItems / 2; idx++) { 18883 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + idx); 18884 } 18885 var numberOfExistingItems = itemsToBeInsertedToDom.length; 18886 for (var idx = 0; idx < possibleNumberOfItems - numberOfExistingItems; idx++) { 18887 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + (index - idx - 1)); 18888 } 18889 } 18890 if (this.settings.loop) { 18891 if (index === this.galleryItems.length - 1) { 18892 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + 0); 18893 } 18894 else if (index === 0) { 18895 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + (this.galleryItems.length - 1)); 18896 } 18897 } 18898 if (itemsToBeInsertedToDom.indexOf(prevIndexItem) === -1) { 18899 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + prevIndex); 18900 } 18901 return itemsToBeInsertedToDom; 18902 }; 18903 LightGallery.prototype.organizeSlideItems = function (index, prevIndex) { 18904 var _this = this; 18905 var itemsToBeInsertedToDom = this.getItemsToBeInsertedToDom(index, prevIndex, this.settings.numberOfSlideItemsInDom); 18906 itemsToBeInsertedToDom.forEach(function (item) { 18907 if (_this.currentItemsInDom.indexOf(item) === -1) { 18908 _this.$inner.append("<div id=\"" + item + "\" class=\"lg-item\"></div>"); 18909 } 18910 }); 18911 this.currentItemsInDom.forEach(function (item) { 18912 if (itemsToBeInsertedToDom.indexOf(item) === -1) { 18913 $LG("#" + item).remove(); 18914 } 18915 }); 18916 return itemsToBeInsertedToDom; 18917 }; 18918 /** 18919 * Get previous index of the slide 18920 */ 18921 LightGallery.prototype.getPreviousSlideIndex = function () { 18922 var prevIndex = 0; 18923 try { 18924 var currentItemId = this.outer 18925 .find('.lg-current') 18926 .first() 18927 .attr('id'); 18928 prevIndex = parseInt(currentItemId.split('-')[3]) || 0; 18929 } 18930 catch (error) { 18931 prevIndex = 0; 18932 } 18933 return prevIndex; 18934 }; 18935 LightGallery.prototype.setDownloadValue = function (index) { 18936 if (this.settings.download) { 18937 var currentGalleryItem = this.galleryItems[index]; 18938 var hideDownloadBtn = currentGalleryItem.downloadUrl === false || 18939 currentGalleryItem.downloadUrl === 'false'; 18940 if (hideDownloadBtn) { 18941 this.outer.addClass('lg-hide-download'); 18942 } 18943 else { 18944 var $download = this.getElementById('lg-download'); 18945 this.outer.removeClass('lg-hide-download'); 18946 $download.attr('href', currentGalleryItem.downloadUrl || 18947 currentGalleryItem.src); 18948 if (currentGalleryItem.download) { 18949 //Uncode edit ##START## 18950 var currentVideo, download_url, download_name; 18951 if ( currentGalleryItem.video ) { 18952 currentVideo = JSON.parse( currentGalleryItem.video ); 18953 download_name = currentVideo.source[0].src; 18954 $download.attr('href', download_name).removeAttr('download'); 18955 } else { 18956 download_url = currentGalleryItem.downloadUrl || currentGalleryItem.src; 18957 download_name = download_url.substring(download_url.lastIndexOf('/')+1); 18958 $download.attr('download', download_name).removeAttr('href'); 18959 } 18960 // $download.attr('download', currentGalleryItem.download); 18961 //Uncode edit ##END## 18962 } 18963 } 18964 } 18965 }; 18966 LightGallery.prototype.makeSlideAnimation = function (direction, currentSlideItem, previousSlideItem) { 18967 var _this = this; 18968 if (this.lGalleryOn) { 18969 previousSlideItem.addClass('lg-slide-progress'); 18970 } 18971 setTimeout(function () { 18972 // remove all transitions 18973 _this.outer.addClass('lg-no-trans'); 18974 _this.outer 18975 .find('.lg-item') 18976 .removeClass('lg-prev-slide lg-next-slide'); 18977 if (direction === 'prev') { 18978 //prevslide 18979 currentSlideItem.addClass('lg-prev-slide'); 18980 previousSlideItem.addClass('lg-next-slide'); 18981 } 18982 else { 18983 // next slide 18984 currentSlideItem.addClass('lg-next-slide'); 18985 previousSlideItem.addClass('lg-prev-slide'); 18986 } 18987 // give 50 ms for browser to add/remove class 18988 setTimeout(function () { 18989 _this.outer.find('.lg-item').removeClass('lg-current'); 18990 currentSlideItem.addClass('lg-current'); 18991 // reset all transitions 18992 _this.outer.removeClass('lg-no-trans'); 18993 }, 50); 18994 }, this.lGalleryOn ? this.settings.slideDelay : 0); 18995 }; 18996 /** 18997 * Goto a specific slide. 18998 * @param {Number} index - index of the slide 18999 * @param {Boolean} fromTouch - true if slide function called via touch event or mouse drag 19000 * @param {Boolean} fromThumb - true if slide function called via thumbnail click 19001 * @param {String} direction - Direction of the slide(next/prev) 19002 * @category lGPublicMethods 19003 * @example 19004 * const plugin = lightGallery(); 19005 * // to go to 3rd slide 19006 * plugin.slide(2); 19007 * 19008 */ 19009 LightGallery.prototype.slide = function (index, fromTouch, fromThumb, direction) { 19010 var _this = this; 19011 var prevIndex = this.getPreviousSlideIndex(); 19012 this.currentItemsInDom = this.organizeSlideItems(index, prevIndex); 19013 // Prevent multiple call, Required for hsh plugin 19014 if (this.lGalleryOn && prevIndex === index) { 19015 return; 19016 } 19017 var numberOfGalleryItems = this.galleryItems.length; 19018 if (!this.lgBusy) { 19019 if (this.settings.counter) { 19020 this.updateCurrentCounter(index); 19021 } 19022 var currentSlideItem = this.getSlideItem(index); 19023 var previousSlideItem_1 = this.getSlideItem(prevIndex); 19024 var currentGalleryItem = this.galleryItems[index]; 19025 var videoInfo = currentGalleryItem.__slideVideoInfo; 19026 this.outer.attr('data-lg-slide-type', this.getSlideType(currentGalleryItem)); 19027 this.setDownloadValue(index); 19028 if (videoInfo) { 19029 var _a = this.mediaContainerPosition, top_3 = _a.top, bottom = _a.bottom; 19030 //Uncode edit ##START## 19031 var videoSize = utils.getSize(this.items[index], this.outer, top_3 + bottom, videoInfo && this.settings.videoMaxSize, this.galleryItems[this.index]); 19032 // var videoSize = utils.getSize(this.items[index], this.outer, top_3 + bottom, videoInfo && this.settings.videoMaxSize); 19033 //Uncode edit ##END## 19034 this.resizeVideoSlide(index, videoSize); 19035 } 19036 this.LGel.trigger(lGEvents.beforeSlide, { 19037 prevIndex: prevIndex, 19038 index: index, 19039 fromTouch: !!fromTouch, 19040 fromThumb: !!fromThumb, 19041 //Uncode edit ##START## 19042 currentSlide: currentSlideItem, 19043 previousSlide: previousSlideItem_1, 19044 info: currentGalleryItem, 19045 item: this.items[index] 19046 //Uncode edit ##END## 19047 }); 19048 this.lgBusy = true; 19049 clearTimeout(this.hideBarTimeout); 19050 this.arrowDisable(index); 19051 if (!direction) { 19052 if (index < prevIndex) { 19053 direction = 'prev'; 19054 } 19055 else if (index > prevIndex) { 19056 direction = 'next'; 19057 } 19058 } 19059 if (!fromTouch) { 19060 this.makeSlideAnimation(direction, currentSlideItem, previousSlideItem_1); 19061 } 19062 else { 19063 this.outer 19064 .find('.lg-item') 19065 .removeClass('lg-prev-slide lg-current lg-next-slide'); 19066 var touchPrev = void 0; 19067 var touchNext = void 0; 19068 if (numberOfGalleryItems > 2) { 19069 touchPrev = index - 1; 19070 touchNext = index + 1; 19071 if (index === 0 && prevIndex === numberOfGalleryItems - 1) { 19072 // next slide 19073 touchNext = 0; 19074 touchPrev = numberOfGalleryItems - 1; 19075 } 19076 else if (index === numberOfGalleryItems - 1 && 19077 prevIndex === 0) { 19078 // prev slide 19079 touchNext = 0; 19080 touchPrev = numberOfGalleryItems - 1; 19081 } 19082 } 19083 else { 19084 touchPrev = 0; 19085 touchNext = 1; 19086 } 19087 if (direction === 'prev') { 19088 this.getSlideItem(touchNext).addClass('lg-next-slide'); 19089 } 19090 else { 19091 this.getSlideItem(touchPrev).addClass('lg-prev-slide'); 19092 } 19093 currentSlideItem.addClass('lg-current'); 19094 } 19095 // Do not put load content in set timeout as it needs to load immediately when the gallery is opened 19096 if (!this.lGalleryOn) { 19097 this.loadContent(index, true); 19098 } 19099 else { 19100 setTimeout(function () { 19101 _this.loadContent(index, true); 19102 // Add title if this.settings.appendSubHtmlTo === lg-sub-html 19103 if (_this.settings.appendSubHtmlTo !== '.lg-item') { 19104 _this.addHtml(index); 19105 } 19106 }, this.settings.speed + 50 + (fromTouch ? 0 : this.settings.slideDelay)); 19107 } 19108 setTimeout(function () { 19109 _this.lgBusy = false; 19110 previousSlideItem_1.removeClass('lg-slide-progress'); 19111 _this.LGel.trigger(lGEvents.afterSlide, { 19112 prevIndex: prevIndex, 19113 index: index, 19114 fromTouch: fromTouch, 19115 fromThumb: fromThumb, 19116 }); 19117 }, (this.lGalleryOn ? this.settings.speed + 100 : 100) + (fromTouch ? 0 : this.settings.slideDelay)); 19118 } 19119 this.index = index; 19120 }; 19121 LightGallery.prototype.updateCurrentCounter = function (index) { 19122 this.getElementById('lg-counter-current').html(index + 1 + ''); 19123 }; 19124 LightGallery.prototype.updateCounterTotal = function () { 19125 this.getElementById('lg-counter-all').html(this.galleryItems.length + ''); 19126 }; 19127 LightGallery.prototype.getSlideType = function (item) { 19128 if (item.__slideVideoInfo) { 19129 return 'video'; 19130 } 19131 else if (item.iframe) { 19132 return 'iframe'; 19133 } 19134 //Uncode edit ##START## 19135 else if (typeof item.src !== '' && item.src.search(/.mp3|.m4a/i) > -1) { 19136 return 'audio'; 19137 } 19138 //Uncode edit ##END## 19139 else { 19140 return 'image'; 19141 } 19142 }; 19143 LightGallery.prototype.touchMove = function (startCoords, endCoords, e) { 19144 var distanceX = endCoords.pageX - startCoords.pageX; 19145 var distanceY = endCoords.pageY - startCoords.pageY; 19146 var allowSwipe = false; 19147 if (this.swipeDirection) { 19148 allowSwipe = true; 19149 } 19150 else { 19151 if (Math.abs(distanceX) > 15) { 19152 this.swipeDirection = 'horizontal'; 19153 allowSwipe = true; 19154 } 19155 else if (Math.abs(distanceY) > 15) { 19156 this.swipeDirection = 'vertical'; 19157 allowSwipe = true; 19158 } 19159 } 19160 if (!allowSwipe) { 19161 return; 19162 } 19163 var $currentSlide = this.getSlideItem(this.index); 19164 if (this.swipeDirection === 'horizontal') { 19165 e === null || e === void 0 ? void 0 : e.preventDefault(); 19166 // reset opacity and transition duration 19167 this.outer.addClass('lg-dragging'); 19168 // move current slide 19169 this.setTranslate($currentSlide, distanceX, 0); 19170 // move next and prev slide with current slide 19171 var width = $currentSlide.get().offsetWidth; 19172 var slideWidthAmount = (width * 15) / 100; 19173 var gutter = slideWidthAmount - Math.abs((distanceX * 10) / 100); 19174 this.setTranslate(this.outer.find('.lg-prev-slide').first(), -width + distanceX - gutter, 0); 19175 this.setTranslate(this.outer.find('.lg-next-slide').first(), width + distanceX + gutter, 0); 19176 } 19177 else if (this.swipeDirection === 'vertical') { 19178 if (this.settings.swipeToClose) { 19179 e === null || e === void 0 ? void 0 : e.preventDefault(); 19180 this.$container.addClass('lg-dragging-vertical'); 19181 var opacity = 1 - Math.abs(distanceY) / window.innerHeight; 19182 this.$backdrop.css('opacity', opacity); 19183 var scale = 1 - Math.abs(distanceY) / (window.innerWidth * 2); 19184 this.setTranslate($currentSlide, 0, distanceY, scale, scale); 19185 if (Math.abs(distanceY) > 100) { 19186 this.outer 19187 .addClass('lg-hide-items') 19188 .removeClass('lg-components-open'); 19189 } 19190 } 19191 } 19192 }; 19193 LightGallery.prototype.touchEnd = function (endCoords, startCoords, event) { 19194 var _this = this; 19195 var distance; 19196 // keep slide animation for any mode while dragg/swipe 19197 if (this.settings.mode !== 'lg-slide') { 19198 this.outer.addClass('lg-slide'); 19199 } 19200 // set transition duration 19201 setTimeout(function () { 19202 _this.$container.removeClass('lg-dragging-vertical'); 19203 _this.outer 19204 .removeClass('lg-dragging lg-hide-items') 19205 .addClass('lg-components-open'); 19206 var triggerClick = true; 19207 if (_this.swipeDirection === 'horizontal') { 19208 distance = endCoords.pageX - startCoords.pageX; 19209 var distanceAbs = Math.abs(endCoords.pageX - startCoords.pageX); 19210 if (distance < 0 && 19211 distanceAbs > _this.settings.swipeThreshold) { 19212 _this.goToNextSlide(true); 19213 triggerClick = false; 19214 } 19215 else if (distance > 0 && 19216 distanceAbs > _this.settings.swipeThreshold) { 19217 _this.goToPrevSlide(true); 19218 triggerClick = false; 19219 } 19220 } 19221 else if (_this.swipeDirection === 'vertical') { 19222 distance = Math.abs(endCoords.pageY - startCoords.pageY); 19223 if (_this.settings.closable && 19224 _this.settings.swipeToClose && 19225 distance > 100) { 19226 _this.closeGallery(); 19227 return; 19228 } 19229 else { 19230 _this.$backdrop.css('opacity', 1); 19231 } 19232 } 19233 _this.outer.find('.lg-item').removeAttr('style'); 19234 if (triggerClick && 19235 Math.abs(endCoords.pageX - startCoords.pageX) < 5) { 19236 // Trigger click if distance is less than 5 pix 19237 var target = $LG(event.target); 19238 if (_this.isPosterElement(target)) { 19239 _this.LGel.trigger(lGEvents.posterClick); 19240 } 19241 } 19242 _this.swipeDirection = undefined; 19243 }); 19244 // remove slide class once drag/swipe is completed if mode is not slide 19245 setTimeout(function () { 19246 if (!_this.outer.hasClass('lg-dragging') && 19247 _this.settings.mode !== 'lg-slide') { 19248 _this.outer.removeClass('lg-slide'); 19249 } 19250 }, this.settings.speed + 100); 19251 }; 19252 LightGallery.prototype.enableSwipe = function () { 19253 var _this = this; 19254 var startCoords = {}; 19255 var endCoords = {}; 19256 var isMoved = false; 19257 var isSwiping = false; 19258 if (this.settings.enableSwipe) { 19259 this.$inner.on('touchstart.lg', function (e) { 19260 _this.dragOrSwipeEnabled = true; 19261 var $item = _this.getSlideItem(_this.index); 19262 if (($LG(e.target).hasClass('lg-item') || 19263 $item.get().contains(e.target)) && 19264 !_this.outer.hasClass('lg-zoomed') && 19265 !_this.lgBusy && 19266 e.targetTouches.length === 1) { 19267 isSwiping = true; 19268 _this.touchAction = 'swipe'; 19269 _this.manageSwipeClass(); 19270 startCoords = { 19271 pageX: e.targetTouches[0].pageX, 19272 pageY: e.targetTouches[0].pageY, 19273 }; 19274 } 19275 }); 19276 this.$inner.on('touchmove.lg', function (e) { 19277 if (isSwiping && 19278 _this.touchAction === 'swipe' && 19279 e.targetTouches.length === 1) { 19280 endCoords = { 19281 pageX: e.targetTouches[0].pageX, 19282 pageY: e.targetTouches[0].pageY, 19283 }; 19284 _this.touchMove(startCoords, endCoords, e); 19285 isMoved = true; 19286 } 19287 }); 19288 this.$inner.on('touchend.lg', function (event) { 19289 if (_this.touchAction === 'swipe') { 19290 if (isMoved) { 19291 isMoved = false; 19292 _this.touchEnd(endCoords, startCoords, event); 19293 } 19294 else if (isSwiping) { 19295 var target = $LG(event.target); 19296 if (_this.isPosterElement(target)) { 19297 _this.LGel.trigger(lGEvents.posterClick); 19298 } 19299 } 19300 _this.touchAction = undefined; 19301 isSwiping = false; 19302 } 19303 }); 19304 } 19305 }; 19306 LightGallery.prototype.enableDrag = function () { 19307 var _this = this; 19308 var startCoords = {}; 19309 var endCoords = {}; 19310 var isDraging = false; 19311 var isMoved = false; 19312 if (this.settings.enableDrag) { 19313 this.outer.on('mousedown.lg', function (e) { 19314 _this.dragOrSwipeEnabled = true; 19315 var $item = _this.getSlideItem(_this.index); 19316 if ($LG(e.target).hasClass('lg-item') || 19317 $item.get().contains(e.target)) { 19318 if (!_this.outer.hasClass('lg-zoomed') && !_this.lgBusy) { 19319 e.preventDefault(); 19320 if (!_this.lgBusy) { 19321 _this.manageSwipeClass(); 19322 startCoords = { 19323 pageX: e.pageX, 19324 pageY: e.pageY, 19325 }; 19326 isDraging = true; 19327 // ** Fix for webkit cursor issue https://code.google.com/p/chromium/issues/detail?id=26723 19328 _this.outer.get().scrollLeft += 1; 19329 _this.outer.get().scrollLeft -= 1; 19330 // * 19331 _this.outer 19332 .removeClass('lg-grab') 19333 .addClass('lg-grabbing'); 19334 _this.LGel.trigger(lGEvents.dragStart); 19335 } 19336 } 19337 } 19338 }); 19339 $LG(window).on("mousemove.lg.global" + this.lgId, function (e) { 19340 if (isDraging && _this.lgOpened) { 19341 isMoved = true; 19342 endCoords = { 19343 pageX: e.pageX, 19344 pageY: e.pageY, 19345 }; 19346 _this.touchMove(startCoords, endCoords); 19347 _this.LGel.trigger(lGEvents.dragMove); 19348 } 19349 }); 19350 $LG(window).on("mouseup.lg.global" + this.lgId, function (event) { 19351 if (!_this.lgOpened) { 19352 return; 19353 } 19354 var target = $LG(event.target); 19355 if (isMoved) { 19356 isMoved = false; 19357 _this.touchEnd(endCoords, startCoords, event); 19358 _this.LGel.trigger(lGEvents.dragEnd); 19359 } 19360 else if (_this.isPosterElement(target)) { 19361 _this.LGel.trigger(lGEvents.posterClick); 19362 } 19363 // Prevent execution on click 19364 if (isDraging) { 19365 isDraging = false; 19366 _this.outer.removeClass('lg-grabbing').addClass('lg-grab'); 19367 } 19368 }); 19369 } 19370 }; 19371 LightGallery.prototype.triggerPosterClick = function () { 19372 var _this = this; 19373 this.$inner.on('click.lg', function (event) { 19374 if (!_this.dragOrSwipeEnabled && 19375 _this.isPosterElement($LG(event.target))) { 19376 _this.LGel.trigger(lGEvents.posterClick); 19377 } 19378 }); 19379 }; 19380 LightGallery.prototype.manageSwipeClass = function () { 19381 var _touchNext = this.index + 1; 19382 var _touchPrev = this.index - 1; 19383 if (this.settings.loop && this.galleryItems.length > 2) { 19384 if (this.index === 0) { 19385 _touchPrev = this.galleryItems.length - 1; 19386 } 19387 else if (this.index === this.galleryItems.length - 1) { 19388 _touchNext = 0; 19389 } 19390 } 19391 this.outer.find('.lg-item').removeClass('lg-next-slide lg-prev-slide'); 19392 if (_touchPrev > -1) { 19393 this.getSlideItem(_touchPrev).addClass('lg-prev-slide'); 19394 } 19395 this.getSlideItem(_touchNext).addClass('lg-next-slide'); 19396 }; 19397 /** 19398 * Go to next slide 19399 * @param {Boolean} fromTouch - true if slide function called via touch event 19400 * @category lGPublicMethods 19401 * @example 19402 * const plugin = lightGallery(); 19403 * plugin.goToNextSlide(); 19404 * @see <a href="/demos/methods/">Demo</a> 19405 */ 19406 LightGallery.prototype.goToNextSlide = function (fromTouch) { 19407 var _this = this; 19408 var _loop = this.settings.loop; 19409 if (fromTouch && this.galleryItems.length < 3) { 19410 _loop = false; 19411 } 19412 if (!this.lgBusy) { 19413 if (this.index + 1 < this.galleryItems.length) { 19414 this.index++; 19415 this.LGel.trigger(lGEvents.beforeNextSlide, { 19416 index: this.index, 19417 }); 19418 this.slide(this.index, !!fromTouch, false, 'next'); 19419 } 19420 else { 19421 if (_loop) { 19422 this.index = 0; 19423 this.LGel.trigger(lGEvents.beforeNextSlide, { 19424 index: this.index, 19425 }); 19426 this.slide(this.index, !!fromTouch, false, 'next'); 19427 } 19428 else if (this.settings.slideEndAnimation && !fromTouch) { 19429 this.outer.addClass('lg-right-end'); 19430 setTimeout(function () { 19431 _this.outer.removeClass('lg-right-end'); 19432 }, 400); 19433 } 19434 } 19435 } 19436 }; 19437 /** 19438 * Go to previous slides 19439 * @param {Boolean} fromTouch - true if slide function called via touch event 19440 * @category lGPublicMethods 19441 * @example 19442 * const plugin = lightGallery({}); 19443 * plugin.goToPrevSlide(); 19444 * @see <a href="/demos/methods/">Demo</a> 19445 * 19446 */ 19447 LightGallery.prototype.goToPrevSlide = function (fromTouch) { 19448 var _this = this; 19449 var _loop = this.settings.loop; 19450 if (fromTouch && this.galleryItems.length < 3) { 19451 _loop = false; 19452 } 19453 if (!this.lgBusy) { 19454 if (this.index > 0) { 19455 this.index--; 19456 this.LGel.trigger(lGEvents.beforePrevSlide, { 19457 index: this.index, 19458 fromTouch: fromTouch, 19459 }); 19460 this.slide(this.index, !!fromTouch, false, 'prev'); 19461 } 19462 else { 19463 if (_loop) { 19464 this.index = this.galleryItems.length - 1; 19465 this.LGel.trigger(lGEvents.beforePrevSlide, { 19466 index: this.index, 19467 fromTouch: fromTouch, 19468 }); 19469 this.slide(this.index, !!fromTouch, false, 'prev'); 19470 } 19471 else if (this.settings.slideEndAnimation && !fromTouch) { 19472 this.outer.addClass('lg-left-end'); 19473 setTimeout(function () { 19474 _this.outer.removeClass('lg-left-end'); 19475 }, 400); 19476 } 19477 } 19478 } 19479 }; 19480 LightGallery.prototype.keyPress = function () { 19481 var _this = this; 19482 $LG(window).on("keydown.lg.global" + this.lgId, function (e) { 19483 if (_this.lgOpened && 19484 _this.settings.escKey === true && 19485 e.keyCode === 27) { 19486 e.preventDefault(); 19487 if (_this.settings.allowMediaOverlap && 19488 _this.outer.hasClass('lg-can-toggle') && 19489 _this.outer.hasClass('lg-components-open')) { 19490 _this.outer.removeClass('lg-components-open'); 19491 } 19492 else { 19493 _this.closeGallery(); 19494 } 19495 } 19496 if (_this.lgOpened && _this.galleryItems.length > 1) { 19497 if (e.keyCode === 37) { 19498 e.preventDefault(); 19499 _this.goToPrevSlide(); 19500 } 19501 if (e.keyCode === 39) { 19502 e.preventDefault(); 19503 _this.goToNextSlide(); 19504 } 19505 } 19506 }); 19507 }; 19508 LightGallery.prototype.arrow = function () { 19509 var _this = this; 19510 this.getElementById('lg-prev').on('click.lg', function () { 19511 _this.goToPrevSlide(); 19512 }); 19513 this.getElementById('lg-next').on('click.lg', function () { 19514 _this.goToNextSlide(); 19515 }); 19516 }; 19517 LightGallery.prototype.arrowDisable = function (index) { 19518 // Disable arrows if settings.hideControlOnEnd is true 19519 if (!this.settings.loop && this.settings.hideControlOnEnd) { 19520 var $prev = this.getElementById('lg-prev'); 19521 var $next = this.getElementById('lg-next'); 19522 if (index + 1 === this.galleryItems.length) { 19523 $next.attr('disabled', 'disabled').addClass('disabled'); 19524 } 19525 else { 19526 $next.removeAttr('disabled').removeClass('disabled'); 19527 } 19528 if (index === 0) { 19529 $prev.attr('disabled', 'disabled').addClass('disabled'); 19530 } 19531 else { 19532 $prev.removeAttr('disabled').removeClass('disabled'); 19533 } 19534 } 19535 }; 19536 LightGallery.prototype.setTranslate = function ($el, xValue, yValue, scaleX, scaleY) { 19537 if (scaleX === void 0) { scaleX = 1; } 19538 if (scaleY === void 0) { scaleY = 1; } 19539 $el.css('transform', 'translate3d(' + 19540 xValue + 19541 'px, ' + 19542 yValue + 19543 'px, 0px) scale3d(' + 19544 scaleX + 19545 ', ' + 19546 scaleY + 19547 ', 1)'); 19548 }; 19549 LightGallery.prototype.mousewheel = function () { 19550 var _this = this; 19551 var lastCall = 0; 19552 this.outer.on('wheel.lg', function (e) { 19553 if (!e.deltaY || _this.galleryItems.length < 2) { 19554 return; 19555 } 19556 e.preventDefault(); 19557 var now = new Date().getTime(); 19558 if (now - lastCall < 1000) { 19559 return; 19560 } 19561 lastCall = now; 19562 if (e.deltaY > 0) { 19563 _this.goToNextSlide(); 19564 } 19565 else if (e.deltaY < 0) { 19566 _this.goToPrevSlide(); 19567 } 19568 }); 19569 }; 19570 LightGallery.prototype.isSlideElement = function (target) { 19571 return (target.hasClass('lg-outer') || 19572 target.hasClass('lg-item') || 19573 target.hasClass('lg-img-wrap')); 19574 }; 19575 LightGallery.prototype.isPosterElement = function (target) { 19576 var playButton = this.getSlideItem(this.index) 19577 .find('.lg-video-play-button') 19578 .get(); 19579 return (target.hasClass('lg-video-poster') || 19580 target.hasClass('lg-video-play-button') || 19581 (playButton && playButton.contains(target.get()))); 19582 }; 19583 /** 19584 * Maximize minimize inline gallery. 19585 * @category lGPublicMethods 19586 */ 19587 LightGallery.prototype.toggleMaximize = function () { 19588 var _this = this; 19589 this.getElementById('lg-maximize').on('click.lg', function () { 19590 _this.$container.toggleClass('lg-inline'); 19591 _this.refreshOnResize(); 19592 }); 19593 }; 19594 LightGallery.prototype.invalidateItems = function () { 19595 for (var index = 0; index < this.items.length; index++) { 19596 var element = this.items[index]; 19597 var $element = $LG(element); 19598 $element.off("click.lgcustom-item-" + $element.attr('data-lg-id')); 19599 } 19600 }; 19601 LightGallery.prototype.trapFocus = function () { 19602 var _this = this; 19603 this.$container.get().focus({ 19604 preventScroll: true, 19605 }); 19606 $LG(window).on("keydown.lg.global" + this.lgId, function (e) { 19607 if (!_this.lgOpened) { 19608 return; 19609 } 19610 var isTabPressed = e.key === 'Tab' || e.keyCode === 9; 19611 if (!isTabPressed) { 19612 return; 19613 } 19614 var focusableEls = utils.getFocusableElements(_this.$container.get()); 19615 var firstFocusableEl = focusableEls[0]; 19616 var lastFocusableEl = focusableEls[focusableEls.length - 1]; 19617 if (e.shiftKey) { 19618 if (document.activeElement === firstFocusableEl) { 19619 lastFocusableEl.focus(); 19620 e.preventDefault(); 19621 } 19622 } 19623 else { 19624 if (document.activeElement === lastFocusableEl) { 19625 firstFocusableEl.focus(); 19626 e.preventDefault(); 19627 } 19628 } 19629 }); 19630 }; 19631 LightGallery.prototype.manageCloseGallery = function () { 19632 var _this = this; 19633 if (!this.settings.closable) 19634 return; 19635 var mousedown = false; 19636 this.getElementById('lg-close').on('click.lg', function () { 19637 _this.closeGallery(); 19638 }); 19639 if (this.settings.closeOnTap) { 19640 // If you drag the slide and release outside gallery gets close on chrome 19641 // for preventing this check mousedown and mouseup happened on .lg-item or lg-outer 19642 this.outer.on('mousedown.lg', function (e) { 19643 var target = $LG(e.target); 19644 if (_this.isSlideElement(target)) { 19645 mousedown = true; 19646 } 19647 else { 19648 mousedown = false; 19649 } 19650 }); 19651 this.outer.on('mousemove.lg', function () { 19652 mousedown = false; 19653 }); 19654 this.outer.on('mouseup.lg', function (e) { 19655 var target = $LG(e.target); 19656 if (_this.isSlideElement(target) && mousedown) { 19657 if (!_this.outer.hasClass('lg-dragging')) { 19658 _this.closeGallery(); 19659 } 19660 } 19661 }); 19662 } 19663 }; 19664 /** 19665 * Close lightGallery if it is opened. 19666 * 19667 * @description If closable is false in the settings, you need to pass true via closeGallery method to force close gallery 19668 * @return returns the estimated time to close gallery completely including the close animation duration 19669 * @category lGPublicMethods 19670 * @example 19671 * const plugin = lightGallery(); 19672 * plugin.closeGallery(); 19673 * 19674 */ 19675 LightGallery.prototype.closeGallery = function (force) { 19676 var _this = this; 19677 if (!this.lgOpened || (!this.settings.closable && !force)) { 19678 return 0; 19679 } 19680 this.LGel.trigger(lGEvents.beforeClose); 19681 if (this.settings.resetScrollPosition && !this.settings.hideScrollbar) { 19682 $LG(window).scrollTop(this.prevScrollTop); 19683 } 19684 var currentItem = this.items[this.index]; 19685 var transform; 19686 if (this.zoomFromOrigin && currentItem) { 19687 var _a = this.mediaContainerPosition, top_4 = _a.top, bottom = _a.bottom; 19688 var _b = this.galleryItems[this.index], __slideVideoInfo = _b.__slideVideoInfo, poster = _b.poster; 19689 //Uncode edit ##START## 19690 var imageSize = utils.getSize(currentItem, this.outer, top_4 + bottom, __slideVideoInfo && poster && this.settings.videoMaxSize, this.galleryItems[this.index]); 19691 // var imageSize = utils.getSize(currentItem, this.outer, top_4 + bottom, __slideVideoInfo && poster && this.settings.videoMaxSize); 19692 //Uncode edit ##END## 19693 transform = utils.getTransform(currentItem, this.outer, top_4, bottom, imageSize); 19694 } 19695 if (this.zoomFromOrigin && transform) { 19696 this.outer.addClass('lg-closing lg-zoom-from-image'); 19697 this.getSlideItem(this.index) 19698 .addClass('lg-start-end-progress') 19699 .css('transition-duration', this.settings.startAnimationDuration + 'ms') 19700 .css('transform', transform); 19701 } 19702 else { 19703 this.outer.addClass('lg-hide-items'); 19704 // lg-zoom-from-image is used for setting the opacity to 1 if zoomFromOrigin is true 19705 // If the closing item doesn't have the lg-size attribute, remove this class to avoid the closing css conflicts 19706 this.outer.removeClass('lg-zoom-from-image'); 19707 } 19708 // Unbind all events added by lightGallery 19709 // @todo 19710 //this.$el.off('.lg.tm'); 19711 this.destroyModules(); 19712 this.lGalleryOn = false; 19713 this.isDummyImageRemoved = false; 19714 this.zoomFromOrigin = this.settings.zoomFromOrigin; 19715 clearTimeout(this.hideBarTimeout); 19716 this.hideBarTimeout = false; 19717 $LG('html').removeClass('lg-on'); 19718 this.outer.removeClass('lg-visible lg-components-open'); 19719 // Resetting opacity to 0 isd required as vertical swipe to close function adds inline opacity. 19720 this.$backdrop.removeClass('in').css('opacity', 0); 19721 var removeTimeout = this.zoomFromOrigin && transform 19722 ? Math.max(this.settings.startAnimationDuration, this.settings.backdropDuration) 19723 : this.settings.backdropDuration; 19724 this.$container.removeClass('lg-show-in'); 19725 // Once the closign animation is completed and gallery is invisible 19726 setTimeout(function () { 19727 if (_this.zoomFromOrigin && transform) { 19728 _this.outer.removeClass('lg-zoom-from-image'); 19729 } 19730 _this.$container.removeClass('lg-show'); 19731 // Reset scrollbar 19732 _this.resetScrollBar(); 19733 // Need to remove inline opacity as it is used in the stylesheet as well 19734 _this.$backdrop 19735 .removeAttr('style') 19736 .css('transition-duration', _this.settings.backdropDuration + 'ms'); 19737 _this.outer.removeClass("lg-closing " + _this.settings.startClass);
vendor: 6,259 bytes, lines 19738-19941
19738 _this.getSlideItem(_this.index).removeClass('lg-start-end-progress'); 19739 _this.$inner.empty(); 19740 if (_this.lgOpened) { 19741 _this.LGel.trigger(lGEvents.afterClose, { 19742 instance: _this, 19743 }); 19744 } 19745 if (_this.$container.get()) { 19746 _this.$container.get().blur(); 19747 } 19748 _this.lgOpened = false; 19749 }, removeTimeout + 100); 19750 return removeTimeout + 100; 19751 }; 19752 LightGallery.prototype.initModules = function () { 19753 this.plugins.forEach(function (module) { 19754 try { 19755 module.init(); 19756 } 19757 catch (err) { 19758 console.warn("lightGallery:- make sure lightGallery module is properly initiated"); 19759 } 19760 }); 19761 }; 19762 LightGallery.prototype.destroyModules = function (destroy) { 19763 this.plugins.forEach(function (module) { 19764 try { 19765 if (destroy) { 19766 module.destroy(); 19767 } 19768 else { 19769 module.closeGallery && module.closeGallery(); 19770 } 19771 } 19772 catch (err) { 19773 console.warn("lightGallery:- make sure lightGallery module is properly destroyed"); 19774 } 19775 }); 19776 }; 19777 /** 19778 * Refresh lightGallery with new set of children. 19779 * 19780 * @description This is useful to update the gallery when the child elements are changed without calling destroy method. 19781 * 19782 * If you are using dynamic mode, you can pass the modified array of dynamicEl as the first parameter to refresh the dynamic gallery 19783 * @see <a href="/demos/dynamic-mode/">Demo</a> 19784 * @category lGPublicMethods 19785 * @example 19786 * const plugin = lightGallery(); 19787 * // Delete or add children, then call 19788 * plugin.refresh(); 19789 * 19790 */ 19791 LightGallery.prototype.refresh = function (galleryItems) { 19792 if (!this.settings.dynamic) { 19793 this.invalidateItems(); 19794 } 19795 if (galleryItems) { 19796 this.galleryItems = galleryItems; 19797 } 19798 else { 19799 this.galleryItems = this.getItems(); 19800 } 19801 this.updateControls(); 19802 this.openGalleryOnItemClick(); 19803 this.LGel.trigger(lGEvents.updateSlides); 19804 }; 19805 LightGallery.prototype.updateControls = function () { 19806 this.addSlideVideoInfo(this.galleryItems); 19807 this.updateCounterTotal(); 19808 this.manageSingleSlideClassName(); 19809 }; 19810 /** 19811 * Destroy lightGallery. 19812 * Destroy lightGallery and its plugin instances completely 19813 * 19814 * @description This method also calls CloseGallery function internally. Returns the time takes to completely close and destroy the instance. 19815 * In case if you want to re-initialize lightGallery right after destroying it, initialize it only once the destroy process is completed. 19816 * You can use refresh method most of the times. 19817 * @category lGPublicMethods 19818 * @example 19819 * const plugin = lightGallery(); 19820 * plugin.destroy(); 19821 * 19822 */ 19823 LightGallery.prototype.destroy = function () { 19824 var _this = this; 19825 var closeTimeout = this.closeGallery(true); 19826 setTimeout(function () { 19827 _this.destroyModules(true); 19828 if (!_this.settings.dynamic) { 19829 _this.invalidateItems(); 19830 } 19831 $LG(window).off(".lg.global" + _this.lgId); 19832 _this.LGel.off('.lg'); 19833 _this.$container.remove(); 19834 }, closeTimeout); 19835 return closeTimeout; 19836 }; 19837 return LightGallery; 19838 }()); 19839 19840 function lightGallery(el, options) { 19841 return new LightGallery(el, options); 19842 } 19843 19844 return lightGallery; 19845 19846}))); 19847 19848/*! 19849 * lightgallery | 2.5.0 | June 13th 2022 19850 * http://www.lightgalleryjs.com/ 19851 * Copyright (c) 2020 Sachin Neravath; 19852 * @license GPLv3 19853 */ 19854 19855(function (global, factory) { 19856 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 19857 typeof define === 'function' && define.amd ? define(factory) : 19858 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lgZoom = factory()); 19859}(this, (function () { 'use strict'; 19860 19861 /*! ***************************************************************************** 19862 Copyright (c) Microsoft Corporation. 19863 19864 Permission to use, copy, modify, and/or distribute this software for any 19865 purpose with or without fee is hereby granted. 19866 19867 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 19868 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 19869 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 19870 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 19871 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 19872 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 19873 PERFORMANCE OF THIS SOFTWARE. 19874 ***************************************************************************** */ 19875 19876 var __assign = function() { 19877 __assign = Object.assign || function __assign(t) { 19878 for (var s, i = 1, n = arguments.length; i < n; i++) { 19879 s = arguments[i]; 19880 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 19881 } 19882 return t; 19883 }; 19884 return __assign.apply(this, arguments); 19885 }; 19886 19887 var zoomSettings = { 19888 scale: 1, 19889 zoom: true, 19890 actualSize: true, 19891 showZoomInOutIcons: false, 19892 actualSizeIcons: { 19893 zoomIn: 'lg-zoom-in', 19894 zoomOut: 'lg-zoom-out', 19895 }, 19896 enableZoomAfter: 300, 19897 zoomPluginStrings: { 19898 zoomIn: 'Zoom in', 19899 zoomOut: 'Zoom out', 19900 viewActualSize: 'View actual size', 19901 }, 19902 }; 19903 19904 /** 19905 * List of lightGallery events 19906 * All events should be documented here 19907 * Below interfaces are used to build the website documentations 19908 * */ 19909 var lGEvents = { 19910 afterAppendSlide: 'lgAfterAppendSlide', 19911 init: 'lgInit', 19912 hasVideo: 'lgHasVideo', 19913 containerResize: 'lgContainerResize', 19914 updateSlides: 'lgUpdateSlides', 19915 afterAppendSubHtml: 'lgAfterAppendSubHtml', 19916 beforeOpen: 'lgBeforeOpen', 19917 afterOpen: 'lgAfterOpen', 19918 slideItemLoad: 'lgSlideItemLoad', 19919 beforeSlide: 'lgBeforeSlide', 19920 afterSlide: 'lgAfterSlide', 19921 posterClick: 'lgPosterClick', 19922 dragStart: 'lgDragStart', 19923 dragMove: 'lgDragMove', 19924 dragEnd: 'lgDragEnd', 19925 beforeNextSlide: 'lgBeforeNextSlide', 19926 beforePrevSlide: 'lgBeforePrevSlide', 19927 beforeClose: 'lgBeforeClose', 19928 afterClose: 'lgAfterClose', 19929 rotateLeft: 'lgRotateLeft', 19930 rotateRight: 'lgRotateRight', 19931 flipHorizontal: 'lgFlipHorizontal', 19932 flipVertical: 'lgFlipVertical', 19933 autoplay: 'lgAutoplay', 19934 autoplayStart: 'lgAutoplayStart', 19935 autoplayStop: 'lgAutoplayStop', 19936 }; 19937 19938 var Zoom = /** @class */ (function () { 19939 function Zoom(instance, $LG) { 19940 // get lightGallery core plugin instance 19941 this.core = instance;
19942 this.$LG = $LG; 19943 this.settings = __assign(__assign({}, zoomSettings), this.core.settings); 19944 return this; 19945 } 19946 // Append Zoom controls. Actual size, Zoom-in, Zoom-out 19947 Zoom.prototype.buildTemplates = function () { 19948 var zoomIcons = this.settings.showZoomInOutIcons 19949 ? "<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>" 19950 : ''; 19951 if (this.settings.actualSize) { 19952 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>"; 19953 } 19954 this.core.outer.addClass('lg-use-transition-for-zoom'); 19955 this.core.$toolbar.first().append(zoomIcons); 19956 }; 19957 /** 19958 * @desc Enable zoom option only once the image is completely loaded 19959 * If zoomFromOrigin is true, Zoom is enabled once the dummy image has been inserted 19960 * 19961 * Zoom styles are defined under lg-zoomable CSS class. 19962 */ 19963 Zoom.prototype.enableZoom = function (event) { 19964 var _this = this; 19965 // delay will be 0 except first time 19966 var _speed = this.settings.enableZoomAfter + event.detail.delay; 19967 // set _speed value 0 if gallery opened from direct url and if it is first slide 19968 if (this.$LG('body').first().hasClass('lg-from-hash') && 19969 event.detail.delay) { 19970 // will execute only once 19971 _speed = 0; 19972 } 19973 else { 19974 // Remove lg-from-hash to enable starting animation. 19975 this.$LG('body').first().removeClass('lg-from-hash'); 19976 } 19977 this.zoomableTimeout = setTimeout(function () { 19978 if (!_this.isImageSlide()) { 19979 return; 19980 } 19981 _this.core.getSlideItem(event.detail.index).addClass('lg-zoomable'); 19982 if (event.detail.index === _this.core.index) { 19983 _this.setZoomEssentials(); 19984 } 19985 }, _speed + 30); 19986 }; 19987 Zoom.prototype.enableZoomOnSlideItemLoad = function () { 19988 // Add zoomable class 19989 this.core.LGel.on(lGEvents.slideItemLoad + ".zoom", this.enableZoom.bind(this)); 19990 }; 19991 Zoom.prototype.getModifier = function (rotateValue, axis, el) { 19992 var originalRotate = rotateValue; 19993 rotateValue = Math.abs(rotateValue); 19994 var transformValues = this.getCurrentTransform(el); 19995 if (!transformValues) { 19996 return 1; 19997 } 19998 var modifier = 1; 19999 if (axis === 'X') { 20000 var flipHorizontalValue = Math.sign(parseFloat(transformValues[0])); 20001 if (rotateValue === 0 || rotateValue === 180) { 20002 modifier = 1; 20003 } 20004 else if (rotateValue === 90) { 20005 if ((originalRotate === -90 && flipHorizontalValue === 1) || 20006 (originalRotate === 90 && flipHorizontalValue === -1)) { 20007 modifier = -1; 20008 } 20009 else { 20010 modifier = 1; 20011 } 20012 } 20013 modifier = modifier * flipHorizontalValue; 20014 } 20015 else { 20016 var flipVerticalValue = Math.sign(parseFloat(transformValues[3])); 20017 if (rotateValue === 0 || rotateValue === 180) { 20018 modifier = 1; 20019 } 20020 else if (rotateValue === 90) { 20021 var sinX = parseFloat(transformValues[1]); 20022 var sinMinusX = parseFloat(transformValues[2]); 20023 modifier = Math.sign(sinX * sinMinusX * originalRotate * flipVerticalValue); 20024 } 20025 modifier = modifier * flipVerticalValue; 20026 } 20027 return modifier; 20028 }; 20029 Zoom.prototype.getImageSize = function ($image, rotateValue, axis) { 20030 var imageSizes = { 20031 y: 'offsetHeight', 20032 x: 'offsetWidth', 20033 }; 20034 if (Math.abs(rotateValue) === 90) { 20035 // Swap axis 20036 if (axis === 'x') { 20037 axis = 'y'; 20038 } 20039 else { 20040 axis = 'x'; 20041 } 20042 } 20043 return $image[imageSizes[axis]]; 20044 }; 20045 Zoom.prototype.getDragCords = function (e, rotateValue) { 20046 if (rotateValue === 90) { 20047 return { 20048 x: e.pageY, 20049 y: e.pageX, 20050 }; 20051 } 20052 else { 20053 return { 20054 x: e.pageX, 20055 y: e.pageY, 20056 }; 20057 } 20058 }; 20059 Zoom.prototype.getSwipeCords = function (e, rotateValue) { 20060 var x = e.targetTouches[0].pageX; 20061 var y = e.targetTouches[0].pageY; 20062 if (rotateValue === 90) { 20063 return { 20064 x: y, 20065 y: x, 20066 }; 20067 } 20068 else { 20069 return { 20070 x: x, 20071 y: y, 20072 }; 20073 } 20074 }; 20075 Zoom.prototype.getDragAllowedAxises = function (rotateValue, scale) { 20076 scale = scale || this.scale || 1; 20077 var allowY = this.imageYSize * scale > this.containerRect.height; 20078 var allowX = this.imageXSize * scale > this.containerRect.width; 20079 if (rotateValue === 90) { 20080 return { 20081 allowX: allowY, 20082 allowY: allowX, 20083 }; 20084 } 20085 else { 20086 return { 20087 allowX: allowX, 20088 allowY: allowY, 20089 }; 20090 } 20091 }; 20092 /** 20093 * 20094 * @param {Element} el 20095 * @return matrix(cos(X), sin(X), -sin(X), cos(X), 0, 0); 20096 * Get the current transform value 20097 */ 20098 Zoom.prototype.getCurrentTransform = function (el) { 20099 if (!el) { 20100 return; 20101 } 20102 var st = window.getComputedStyle(el, null); 20103 var tm = st.getPropertyValue('-webkit-transform') || 20104 st.getPropertyValue('-moz-transform') || 20105 st.getPropertyValue('-ms-transform') || 20106 st.getPropertyValue('-o-transform') || 20107 st.getPropertyValue('transform') || 20108 'none'; 20109 if (tm !== 'none') { 20110 return tm.split('(')[1].split(')')[0].split(','); 20111 } 20112 return; 20113 }; 20114 Zoom.prototype.getCurrentRotation = function (el) { 20115 if (!el) { 20116 return 0; 20117 } 20118 var values = this.getCurrentTransform(el); 20119 if (values) { 20120 return Math.round(Math.atan2(parseFloat(values[1]), parseFloat(values[0])) * 20121 (180 / Math.PI)); 20122 // If you want rotate in 360 20123 //return (angle < 0 ? angle + 360 : angle); 20124 } 20125 return 0; 20126 }; 20127 Zoom.prototype.setZoomEssentials = function () { 20128 var $image = this.core 20129 .getSlideItem(this.core.index) 20130 .find('.lg-image') 20131 .first(); 20132 var rotateEl = this.core 20133 .getSlideItem(this.core.index) 20134 .find('.lg-img-rotate') 20135 .first() 20136 .get(); 20137 this.rotateValue = this.getCurrentRotation(rotateEl); 20138 this.imageYSize = this.getImageSize($image.get(), this.rotateValue, 'y'); 20139 this.imageXSize = this.getImageSize($image.get(), this.rotateValue, 'x'); 20140 this.containerRect = this.core.outer.get().getBoundingClientRect(); 20141 this.modifierX = this.getModifier(this.rotateValue, 'X', rotateEl); 20142 this.modifierY = this.getModifier(this.rotateValue, 'Y', rotateEl); 20143 }; 20144 /** 20145 * @desc Image zoom 20146 * Translate the wrap and scale the image to get better user experience 20147 * 20148 * @param {String} scale - Zoom decrement/increment value 20149 */ 20150 Zoom.prototype.zoomImage = function (scale) { 20151 // Find offset manually to avoid issue after zoom 20152 var offsetX = (this.containerRect.width - this.imageXSize) / 2 + 20153 this.containerRect.left; 20154 var _a = this.core.mediaContainerPosition, top = _a.top, bottom = _a.bottom; 20155 var topBottomSpacing = Math.abs(top - bottom) / 2; 20156 var offsetY = (this.containerRect.height - 20157 this.imageYSize - 20158 topBottomSpacing * this.modifierX) / 20159 2 + 20160 this.scrollTop + 20161 this.containerRect.top; 20162 var originalX; 20163 var originalY; 20164 if (scale === 1) { 20165 this.positionChanged = false;
20166 } 20167 var dragAllowedAxises = this.getDragAllowedAxises(Math.abs(this.rotateValue), scale); 20168 var allowY = dragAllowedAxises.allowY, allowX = dragAllowedAxises.allowX; 20169 if (this.positionChanged) { 20170 originalX = this.left / (this.scale - 1); 20171 originalY = this.top / (this.scale - 1); 20172 this.pageX = Math.abs(originalX) + offsetX; 20173 this.pageY = Math.abs(originalY) + offsetY; 20174 this.positionChanged = false; 20175 } 20176 var possibleSwipeCords = this.getPossibleSwipeDragCords(this.rotateValue, scale); 20177 var _x = offsetX - this.pageX; 20178 var _y = offsetY - this.pageY; 20179 var x = (scale - 1) * _x; 20180 var y = (scale - 1) * _y; 20181 if (allowX) { 20182 if (this.isBeyondPossibleLeft(x, possibleSwipeCords.minX)) { 20183 x = possibleSwipeCords.minX; 20184 } 20185 else if (this.isBeyondPossibleRight(x, possibleSwipeCords.maxX)) { 20186 x = possibleSwipeCords.maxX; 20187 } 20188 } 20189 else { 20190 if (scale > 1) { 20191 if (x < possibleSwipeCords.minX) { 20192 x = possibleSwipeCords.minX; 20193 } 20194 else if (x > possibleSwipeCords.maxX) { 20195 x = possibleSwipeCords.maxX; 20196 } 20197 } 20198 }
20199 if (allowY) { 20200 if (this.isBeyondPossibleTop(y, possibleSwipeCords.minY)) { 20201 y = possibleSwipeCords.minY; 20202 } 20203 else if (this.isBeyondPossibleBottom(y, possibleSwipeCords.maxY)) { 20204 y = possibleSwipeCords.maxY; 20205 } 20206 } 20207 else { 20208 // If the translate value based on index of beyond the viewport, utilize the available space to prevent image being cut out 20209 if (scale > 1) { 20210 //If image goes beyond viewport top, use the minim possible translate value 20211 if (y < possibleSwipeCords.minY) { 20212 y = possibleSwipeCords.minY; 20213 } 20214 else if (y > possibleSwipeCords.maxY) { 20215 y = possibleSwipeCords.maxY; 20216 } 20217 } 20218 } 20219 this.setZoomStyles({ 20220 x: x, 20221 y: y, 20222 scale: scale, 20223 }); 20224 }; 20225 /** 20226 * @desc apply scale3d to image and translate to image wrap 20227 * @param {style} X,Y and scale 20228 */ 20229 Zoom.prototype.setZoomStyles = function (style) { 20230 var $image = this.core 20231 .getSlideItem(this.core.index) 20232 .find('.lg-image') 20233 .first(); 20234 var $dummyImage = this.core.outer 20235 .find('.lg-current .lg-dummy-img') 20236 .first(); 20237 var $imageWrap = $image.parent(); 20238 this.scale = style.scale; 20239 $image.css('transform', 'scale3d(' + style.scale + ', ' + style.scale + ', 1)'); 20240 $dummyImage.css('transform', 'scale3d(' + style.scale + ', ' + style.scale + ', 1)'); 20241 var transform = 'translate3d(' + style.x + 'px, ' + style.y + 'px, 0)'; 20242 $imageWrap.css('transform', transform); 20243 this.left = style.x; 20244 this.top = style.y; 20245 }; 20246 /** 20247 * @param index - Index of the current slide 20248 * @param event - event will be available only if the function is called on clicking/taping the imags 20249 */ 20250 Zoom.prototype.setActualSize = function (index, event) { 20251 var _this = this; 20252 // Allow zoom only on image 20253 if (!this.isImageSlide() || 20254 this.core.outer.hasClass('lg-first-slide-loading')) { 20255 return; 20256 } 20257 var scale = this.getCurrentImageActualSizeScale(); 20258 if (this.core.outer.hasClass('lg-zoomed')) { 20259 this.scale = 1; 20260 } 20261 else { 20262 this.scale = this.getScale(scale); 20263 } 20264 this.setPageCords(event); 20265 this.beginZoom(this.scale); 20266 this.zoomImage(this.scale); 20267 setTimeout(function () { 20268 _this.core.outer.removeClass('lg-grabbing').addClass('lg-grab'); 20269 }, 10); 20270 }; 20271 Zoom.prototype.getNaturalWidth = function (index) { 20272 var $image = this.core.getSlideItem(index).find('.lg-image').first(); 20273 var naturalWidth = this.core.galleryItems[index].width; 20274 return naturalWidth 20275 ? parseFloat(naturalWidth) 20276 : $image.get().naturalWidth; 20277 }; 20278 Zoom.prototype.getActualSizeScale = function (naturalWidth, width) { 20279 var _scale; 20280 var scale;
20281 if (naturalWidth > width) { 20282 _scale = naturalWidth / width; 20283 scale = _scale || 2; 20284 } 20285 else { 20286 scale = 1; 20287 } 20288 return scale; 20289 }; 20290 Zoom.prototype.getCurrentImageActualSizeScale = function () { 20291 var $image = this.core 20292 .getSlideItem(this.core.index) 20293 .find('.lg-image') 20294 .first(); 20295 var width = $image.get().offsetWidth; 20296 var naturalWidth = this.getNaturalWidth(this.core.index) || width; 20297 return this.getActualSizeScale(naturalWidth, width); 20298 }; 20299 Zoom.prototype.getPageCords = function (event) { 20300 var cords = {}; 20301 if (event) { 20302 cords.x = event.pageX || event.targetTouches[0].pageX; 20303 cords.y = event.pageY || event.targetTouches[0].pageY; 20304 } 20305 else { 20306 var containerRect = this.core.outer.get().getBoundingClientRect(); 20307 cords.x = containerRect.width / 2 + containerRect.left; 20308 cords.y = 20309 containerRect.height / 2 + this.scrollTop + containerRect.top; 20310 } 20311 return cords; 20312 }; 20313 Zoom.prototype.setPageCords = function (event) { 20314 var pageCords = this.getPageCords(event); 20315 this.pageX = pageCords.x; 20316 this.pageY = pageCords.y; 20317 }; 20318 // If true, zoomed - in else zoomed out 20319 Zoom.prototype.beginZoom = function (scale) { 20320 this.core.outer.removeClass('lg-zoom-drag-transition lg-zoom-dragging'); 20321 if (scale > 1) { 20322 this.core.outer.addClass('lg-zoomed'); 20323 var $actualSize = this.core.getElementById('lg-actual-size'); 20324 $actualSize 20325 .removeClass(this.settings.actualSizeIcons.zoomIn) 20326 .addClass(this.settings.actualSizeIcons.zoomOut); 20327 } 20328 else { 20329 this.resetZoom(); 20330 } 20331 return scale > 1; 20332 }; 20333 Zoom.prototype.getScale = function (scale) { 20334 var actualSizeScale = this.getCurrentImageActualSizeScale(); 20335 if (scale < 1) { 20336 scale = 1; 20337 } 20338 else if (scale > actualSizeScale) { 20339 scale = actualSizeScale; 20340 } 20341 return scale; 20342 }; 20343 Zoom.prototype.init = function () { 20344 var _this = this; 20345 if (!this.settings.zoom) { 20346 return; 20347 } 20348 this.buildTemplates(); 20349 this.enableZoomOnSlideItemLoad(); 20350 var tapped = null; 20351 this.core.outer.on('dblclick.lg', function (event) { 20352 if (!_this.$LG(event.target).hasClass('lg-image')) { 20353 return; 20354 } 20355 _this.setActualSize(_this.core.index, event); 20356 }); 20357 this.core.outer.on('touchstart.lg', function (event) { 20358 var $target = _this.$LG(event.target); 20359 if (event.targetTouches.length === 1 && 20360 $target.hasClass('lg-image')) { 20361 if (!tapped) { 20362 tapped = setTimeout(function () { 20363 tapped = null; 20364 }, 300); 20365 } 20366 else { 20367 clearTimeout(tapped); 20368 tapped = null; 20369 event.preventDefault(); 20370 _this.setActualSize(_this.core.index, event); 20371 } 20372 } 20373 }); 20374 // Update zoom on resize and orientationchange 20375 this.core.LGel.on(lGEvents.containerResize + ".zoom " + lGEvents.rotateRight + ".zoom " + lGEvents.rotateLeft + ".zoom " + lGEvents.flipHorizontal + ".zoom " + lGEvents.flipVertical + ".zoom", function () { 20376 if (!_this.core.lgOpened || !_this.isImageSlide()) 20377 return; 20378 _this.setPageCords(); 20379 _this.setZoomEssentials(); 20380 _this.zoomImage(_this.scale); 20381 }); 20382 // Update zoom on resize and orientationchange 20383 this.$LG(window).on("scroll.lg.zoom.global" + this.core.lgId, function () { 20384 if (!_this.core.lgOpened) 20385 return; 20386 _this.scrollTop = _this.$LG(window).scrollTop(); 20387 }); 20388 this.core.getElementById('lg-zoom-out').on('click.lg', function () { 20389 if (_this.core.outer.find('.lg-current .lg-image').get()) { 20390 _this.scale -= _this.settings.scale; 20391 _this.scale = _this.getScale(_this.scale); 20392 _this.beginZoom(_this.scale); 20393 _this.zoomImage(_this.scale); 20394 } 20395 }); 20396 this.core.getElementById('lg-zoom-in').on('click.lg', function () { 20397 _this.zoomIn(); 20398 }); 20399 this.core.getElementById('lg-actual-size').on('click.lg', function () { 20400 _this.setActualSize(_this.core.index); 20401 }); 20402 this.core.LGel.on(lGEvents.beforeOpen + ".zoom", function () { 20403 _this.core.outer.find('.lg-item').removeClass('lg-zoomable'); 20404 }); 20405 this.core.LGel.on(lGEvents.afterOpen + ".zoom", function () { 20406 _this.scrollTop = _this.$LG(window).scrollTop(); 20407 // Set the initial value center 20408 _this.pageX = _this.core.outer.width() / 2;
20409 _this.pageY = _this.core.outer.height() / 2 + _this.scrollTop; 20410 _this.scale = 1; 20411 }); 20412 // Reset zoom on slide change 20413 this.core.LGel.on(lGEvents.afterSlide + ".zoom", function (event) { 20414 var prevIndex = event.detail.prevIndex; 20415 _this.scale = 1; 20416 _this.positionChanged = false; 20417 _this.resetZoom(prevIndex); 20418 if (_this.isImageSlide()) { 20419 _this.setZoomEssentials(); 20420 } 20421 }); 20422 // Drag option after zoom 20423 this.zoomDrag(); 20424 this.pinchZoom(); 20425 this.zoomSwipe(); 20426 // Store the zoomable timeout value just to clear it while closing 20427 this.zoomableTimeout = false; 20428 this.positionChanged = false; 20429 }; 20430 Zoom.prototype.zoomIn = function (scale) { 20431 // Allow zoom only on image 20432 if (!this.isImageSlide()) { 20433 return; 20434 } 20435 if (scale) { 20436 this.scale = scale; 20437 } 20438 else { 20439 this.scale += this.settings.scale; 20440 } 20441 this.scale = this.getScale(this.scale); 20442 this.beginZoom(this.scale); 20443 this.zoomImage(this.scale); 20444 }; 20445 // Reset zoom effect 20446 Zoom.prototype.resetZoom = function (index) { 20447 this.core.outer.removeClass('lg-zoomed lg-zoom-drag-transition'); 20448 var $actualSize = this.core.getElementById('lg-actual-size'); 20449 var $item = this.core.getSlideItem(index !== undefined ? index : this.core.index); 20450 $actualSize 20451 .removeClass(this.settings.actualSizeIcons.zoomOut) 20452 .addClass(this.settings.actualSizeIcons.zoomIn); 20453 $item.find('.lg-img-wrap').first().removeAttr('style'); 20454 $item.find('.lg-image').first().removeAttr('style'); 20455 this.scale = 1; 20456 this.left = 0; 20457 this.top = 0; 20458 // Reset pagx pagy values to center 20459 this.setPageCords(); 20460 }; 20461 Zoom.prototype.getTouchDistance = function (e) { 20462 return Math.sqrt((e.targetTouches[0].pageX - e.targetTouches[1].pageX) * 20463 (e.targetTouches[0].pageX - e.targetTouches[1].pageX) + 20464 (e.targetTouches[0].pageY - e.targetTouches[1].pageY) * 20465 (e.targetTouches[0].pageY - e.targetTouches[1].pageY)); 20466 }; 20467 Zoom.prototype.pinchZoom = function () { 20468 var _this = this; 20469 var startDist = 0; 20470 var pinchStarted = false; 20471 var initScale = 1; 20472 var $item = this.core.getSlideItem(this.core.index); 20473 this.core.$inner.on('touchstart.lg', function (e) { 20474 $item = _this.core.getSlideItem(_this.core.index); 20475 if (!_this.isImageSlide()) { 20476 return; 20477 } 20478 if (e.targetTouches.length === 2 && 20479 !_this.core.outer.hasClass('lg-first-slide-loading') && 20480 (_this.$LG(e.target).hasClass('lg-item') || 20481 $item.get().contains(e.target))) { 20482 initScale = _this.scale || 1; 20483 _this.core.outer.removeClass('lg-zoom-drag-transition lg-zoom-dragging'); 20484 _this.core.touchAction = 'pinch'; 20485 startDist = _this.getTouchDistance(e); 20486 } 20487 }); 20488 this.core.$inner.on('touchmove.lg', function (e) { 20489 if (e.targetTouches.length === 2 && 20490 _this.core.touchAction === 'pinch' && 20491 (_this.$LG(e.target).hasClass('lg-item') || 20492 $item.get().contains(e.target))) { 20493 e.preventDefault(); 20494 var endDist = _this.getTouchDistance(e); 20495 var distance = startDist - endDist; 20496 if (!pinchStarted && Math.abs(distance) > 5) { 20497 pinchStarted = true; 20498 } 20499 if (pinchStarted) { 20500 _this.scale = Math.max(1, initScale + -distance * 0.008); 20501 _this.zoomImage(_this.scale); 20502 } 20503 } 20504 }); 20505 this.core.$inner.on('touchend.lg', function (e) { 20506 if (_this.core.touchAction === 'pinch' && 20507 (_this.$LG(e.target).hasClass('lg-item') || 20508 $item.get().contains(e.target))) { 20509 pinchStarted = false; 20510 startDist = 0; 20511 if (_this.scale <= 1) { 20512 _this.resetZoom(); 20513 } 20514 else { 20515 _this.scale = _this.getScale(_this.scale); 20516 _this.zoomImage(_this.scale); 20517 _this.core.outer.addClass('lg-zoomed'); 20518 } 20519 _this.core.touchAction = undefined; 20520 } 20521 }); 20522 }; 20523 Zoom.prototype.touchendZoom = function (startCoords, endCoords, allowX, allowY, touchDuration, rotateValue) { 20524 var distanceXnew = endCoords.x - startCoords.x; 20525 var distanceYnew = endCoords.y - startCoords.y; 20526 var speedX = Math.abs(distanceXnew) / touchDuration + 1; 20527 var speedY = Math.abs(distanceYnew) / touchDuration + 1; 20528 if (speedX > 2) { 20529 speedX += 1; 20530 } 20531 if (speedY > 2) { 20532 speedY += 1; 20533 } 20534 distanceXnew = distanceXnew * speedX; 20535 distanceYnew = distanceYnew * speedY; 20536 var _LGel = this.core 20537 .getSlideItem(this.core.index) 20538 .find('.lg-img-wrap') 20539 .first(); 20540 var distance = {}; 20541 distance.x = this.left + distanceXnew * this.modifierX; 20542 distance.y = this.top + distanceYnew * this.modifierY; 20543 var possibleSwipeCords = this.getPossibleSwipeDragCords(rotateValue); 20544 if (Math.abs(distanceXnew) > 15 || Math.abs(distanceYnew) > 15) { 20545 if (allowY) { 20546 if (this.isBeyondPossibleTop(distance.y, possibleSwipeCords.minY)) { 20547 distance.y = possibleSwipeCords.minY; 20548 } 20549 else if (this.isBeyondPossibleBottom(distance.y, possibleSwipeCords.maxY)) { 20550 distance.y = possibleSwipeCords.maxY; 20551 } 20552 } 20553 if (allowX) { 20554 if (this.isBeyondPossibleLeft(distance.x, possibleSwipeCords.minX)) { 20555 distance.x = possibleSwipeCords.minX; 20556 } 20557 else if (this.isBeyondPossibleRight(distance.x, possibleSwipeCords.maxX)) { 20558 distance.x = possibleSwipeCords.maxX; 20559 } 20560 } 20561 if (allowY) { 20562 this.top = distance.y; 20563 } 20564 else { 20565 distance.y = this.top; 20566 } 20567 if (allowX) { 20568 this.left = distance.x; 20569 } 20570 else { 20571 distance.x = this.left; 20572 } 20573 this.setZoomSwipeStyles(_LGel, distance); 20574 this.positionChanged = true; 20575 } 20576 }; 20577 Zoom.prototype.getZoomSwipeCords = function (startCoords, endCoords, allowX, allowY, possibleSwipeCords) { 20578 var distance = {}; 20579 if (allowY) { 20580 distance.y = 20581 this.top + (endCoords.y - startCoords.y) * this.modifierY; 20582 if (this.isBeyondPossibleTop(distance.y, possibleSwipeCords.minY)) { 20583 var diffMinY = possibleSwipeCords.minY - distance.y; 20584 distance.y = possibleSwipeCords.minY - diffMinY / 6; 20585 } 20586 else if (this.isBeyondPossibleBottom(distance.y, possibleSwipeCords.maxY)) { 20587 var diffMaxY = distance.y - possibleSwipeCords.maxY; 20588 distance.y = possibleSwipeCords.maxY + diffMaxY / 6; 20589 } 20590 } 20591 else { 20592 distance.y = this.top; 20593 }
20594 if (allowX) { 20595 distance.x = 20596 this.left + (endCoords.x - startCoords.x) * this.modifierX; 20597 if (this.isBeyondPossibleLeft(distance.x, possibleSwipeCords.minX)) { 20598 var diffMinX = possibleSwipeCords.minX - distance.x; 20599 distance.x = possibleSwipeCords.minX - diffMinX / 6; 20600 } 20601 else if (this.isBeyondPossibleRight(distance.x, possibleSwipeCords.maxX)) { 20602 var difMaxX = distance.x - possibleSwipeCords.maxX; 20603 distance.x = possibleSwipeCords.maxX + difMaxX / 6; 20604 } 20605 } 20606 else { 20607 distance.x = this.left; 20608 } 20609 return distance; 20610 }; 20611 Zoom.prototype.isBeyondPossibleLeft = function (x, minX) { 20612 return x >= minX; 20613 }; 20614 Zoom.prototype.isBeyondPossibleRight = function (x, maxX) { 20615 return x <= maxX; 20616 }; 20617 Zoom.prototype.isBeyondPossibleTop = function (y, minY) { 20618 return y >= minY; 20619 }; 20620 Zoom.prototype.isBeyondPossibleBottom = function (y, maxY) { 20621 return y <= maxY; 20622 }; 20623 Zoom.prototype.isImageSlide = function () { 20624 var currentItem = this.core.galleryItems[this.core.index]; 20625 return this.core.getSlideType(currentItem) === 'image'; 20626 }; 20627 Zoom.prototype.getPossibleSwipeDragCords = function (rotateValue, scale) { 20628 var dataScale = scale || this.scale || 1; 20629 var elDataScale = Math.abs(dataScale); 20630 var _a = this.core.mediaContainerPosition, top = _a.top, bottom = _a.bottom; 20631 var topBottomSpacing = Math.abs(top - bottom) / 2; 20632 var minY = (this.imageYSize - this.containerRect.height) / 2 + 20633 topBottomSpacing * this.modifierX; 20634 var maxY = this.containerRect.height - this.imageYSize * elDataScale + minY; 20635 var minX = (this.imageXSize - this.containerRect.width) / 2; 20636 var maxX = this.containerRect.width - this.imageXSize * elDataScale + minX; 20637 var possibleSwipeCords = { 20638 minY: minY, 20639 maxY: maxY, 20640 minX: minX, 20641 maxX: maxX, 20642 }; 20643 if (Math.abs(rotateValue) === 90) { 20644 possibleSwipeCords = { 20645 minY: minX, 20646 maxY: maxX, 20647 minX: minY, 20648 maxX: maxY, 20649 }; 20650 } 20651 return possibleSwipeCords; 20652 }; 20653 Zoom.prototype.setZoomSwipeStyles = function (LGel, distance) { 20654 LGel.css('transform', 'translate3d(' + distance.x + 'px, ' + distance.y + 'px, 0)'); 20655 }; 20656 Zoom.prototype.zoomSwipe = function () { 20657 var _this = this; 20658 var startCoords = {}; 20659 var endCoords = {}; 20660 var isMoved = false; 20661 // Allow x direction drag 20662 var allowX = false; 20663 // Allow Y direction drag 20664 var allowY = false; 20665 var startTime = new Date(); 20666 var endTime = new Date(); 20667 var possibleSwipeCords; 20668 var _LGel; 20669 var $item = this.core.getSlideItem(this.core.index); 20670 this.core.$inner.on('touchstart.lg', function (e) { 20671 // Allow zoom only on image 20672 if (!_this.isImageSlide()) { 20673 return; 20674 } 20675 $item = _this.core.getSlideItem(_this.core.index); 20676 if ((_this.$LG(e.target).hasClass('lg-item') || 20677 $item.get().contains(e.target)) && 20678 e.targetTouches.length === 1 && 20679 _this.core.outer.hasClass('lg-zoomed')) { 20680 e.preventDefault(); 20681 startTime = new Date(); 20682 _this.core.touchAction = 'zoomSwipe'; 20683 _LGel = _this.core 20684 .getSlideItem(_this.core.index) 20685 .find('.lg-img-wrap') 20686 .first(); 20687 var dragAllowedAxises = _this.getDragAllowedAxises(Math.abs(_this.rotateValue)); 20688 allowY = dragAllowedAxises.allowY; 20689 allowX = dragAllowedAxises.allowX; 20690 if (allowX || allowY) { 20691 startCoords = _this.getSwipeCords(e, Math.abs(_this.rotateValue)); 20692 } 20693 possibleSwipeCords = _this.getPossibleSwipeDragCords(_this.rotateValue); 20694 // reset opacity and transition duration 20695 _this.core.outer.addClass('lg-zoom-dragging lg-zoom-drag-transition'); 20696 } 20697 }); 20698 this.core.$inner.on('touchmove.lg', function (e) { 20699 if (e.targetTouches.length === 1 && 20700 _this.core.touchAction === 'zoomSwipe' && 20701 (_this.$LG(e.target).hasClass('lg-item') || 20702 $item.get().contains(e.target))) { 20703 e.preventDefault(); 20704 _this.core.touchAction = 'zoomSwipe'; 20705 endCoords = _this.getSwipeCords(e, Math.abs(_this.rotateValue)); 20706 var distance = _this.getZoomSwipeCords(startCoords, endCoords, allowX, allowY, possibleSwipeCords); 20707 if (Math.abs(endCoords.x - startCoords.x) > 15 || 20708 Math.abs(endCoords.y - startCoords.y) > 15) { 20709 isMoved = true; 20710 _this.setZoomSwipeStyles(_LGel, distance); 20711 } 20712 } 20713 }); 20714 this.core.$inner.on('touchend.lg', function (e) { 20715 if (_this.core.touchAction === 'zoomSwipe' && 20716 (_this.$LG(e.target).hasClass('lg-item') || 20717 $item.get().contains(e.target))) { 20718 _this.core.touchAction = undefined; 20719 _this.core.outer.removeClass('lg-zoom-dragging'); 20720 if (!isMoved) { 20721 return; 20722 } 20723 isMoved = false;
20724 endTime = new Date(); 20725 var touchDuration = endTime.valueOf() - startTime.valueOf(); 20726 _this.touchendZoom(startCoords, endCoords, allowX, allowY, touchDuration, _this.rotateValue); 20727 } 20728 }); 20729 }; 20730 Zoom.prototype.zoomDrag = function () { 20731 var _this = this; 20732 var startCoords = {}; 20733 var endCoords = {}; 20734 var isDragging = false; 20735 var isMoved = false; 20736 // Allow x direction drag 20737 var allowX = false; 20738 // Allow Y direction drag 20739 var allowY = false; 20740 var startTime; 20741 var endTime; 20742 var possibleSwipeCords; 20743 var _LGel; 20744 this.core.outer.on('mousedown.lg.zoom', function (e) { 20745 // Allow zoom only on image 20746 if (!_this.isImageSlide()) { 20747 return; 20748 } 20749 var $item = _this.core.getSlideItem(_this.core.index); 20750 if (_this.$LG(e.target).hasClass('lg-item') || 20751 $item.get().contains(e.target)) { 20752 startTime = new Date(); 20753 _LGel = _this.core 20754 .getSlideItem(_this.core.index) 20755 .find('.lg-img-wrap') 20756 .first(); 20757 var dragAllowedAxises = _this.getDragAllowedAxises(Math.abs(_this.rotateValue)); 20758 allowY = dragAllowedAxises.allowY; 20759 allowX = dragAllowedAxises.allowX; 20760 if (_this.core.outer.hasClass('lg-zoomed')) { 20761 if (_this.$LG(e.target).hasClass('lg-object') && 20762 (allowX || allowY)) { 20763 e.preventDefault(); 20764 startCoords = _this.getDragCords(e, Math.abs(_this.rotateValue)); 20765 possibleSwipeCords = _this.getPossibleSwipeDragCords(_this.rotateValue); 20766 isDragging = true; 20767 // ** Fix for webkit cursor issue https://code.google.com/p/chromium/issues/detail?id=26723 20768 _this.core.outer.get().scrollLeft += 1; 20769 _this.core.outer.get().scrollLeft -= 1; 20770 _this.core.outer 20771 .removeClass('lg-grab') 20772 .addClass('lg-grabbing lg-zoom-drag-transition lg-zoom-dragging'); 20773 // reset opacity and transition duration 20774 } 20775 } 20776 } 20777 }); 20778 this.$LG(window).on("mousemove.lg.zoom.global" + this.core.lgId, function (e) { 20779 if (isDragging) { 20780 isMoved = true; 20781 endCoords = _this.getDragCords(e, Math.abs(_this.rotateValue)); 20782 var distance = _this.getZoomSwipeCords(startCoords, endCoords, allowX, allowY, possibleSwipeCords); 20783 _this.setZoomSwipeStyles(_LGel, distance); 20784 } 20785 }); 20786 this.$LG(window).on("mouseup.lg.zoom.global" + this.core.lgId, function (e) { 20787 if (isDragging) { 20788 endTime = new Date(); 20789 isDragging = false; 20790 _this.core.outer.removeClass('lg-zoom-dragging'); 20791 // Fix for chrome mouse move on click 20792 if (isMoved && 20793 (startCoords.x !== endCoords.x || 20794 startCoords.y !== endCoords.y)) { 20795 endCoords = _this.getDragCords(e, Math.abs(_this.rotateValue)); 20796 var touchDuration = endTime.valueOf() - startTime.valueOf(); 20797 _this.touchendZoom(startCoords, endCoords, allowX, allowY, touchDuration, _this.rotateValue); 20798 } 20799 isMoved = false; 20800 } 20801 _this.core.outer.removeClass('lg-grabbing').addClass('lg-grab'); 20802 }); 20803 }; 20804 Zoom.prototype.closeGallery = function () { 20805 this.resetZoom(); 20806 }; 20807 Zoom.prototype.destroy = function () { 20808 // Unbind all events added by lightGallery zoom plugin 20809 this.$LG(window).off(".lg.zoom.global" + this.core.lgId); 20810 this.core.LGel.off('.lg.zoom'); 20811 this.core.LGel.off('.zoom'); 20812 clearTimeout(this.zoomableTimeout); 20813 this.zoomableTimeout = false; 20814 }; 20815 return Zoom; 20816 }()); 20817 20818 return Zoom; 20819 20820}))); 20821/*! 20822 * lightgallery | 2.5.0 | June 13th 2022 20823 * http://www.lightgalleryjs.com/ 20824 * Copyright (c) 2020 Sachin Neravath; 20825 * @license GPLv3 20826 */ 20827 20828(function (global, factory) { 20829 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 20830 typeof define === 'function' && define.amd ? define(factory) : 20831 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lgFullscreen = factory()); 20832}(this, (function () { 'use strict'; 20833 20834 /*! ***************************************************************************** 20835 Copyright (c) Microsoft Corporation. 20836 20837 Permission to use, copy, modify, and/or distribute this software for any 20838 purpose with or without fee is hereby granted. 20839 20840 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 20841 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 20842 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 20843 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 20844 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 20845 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 20846 PERFORMANCE OF THIS SOFTWARE. 20847 ***************************************************************************** */ 20848 20849 var __assign = function() { 20850 __assign = Object.assign || function __assign(t) { 20851 for (var s, i = 1, n = arguments.length; i < n; i++) { 20852 s = arguments[i]; 20853 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 20854 } 20855 return t; 20856 }; 20857 return __assign.apply(this, arguments); 20858 }; 20859 20860 var fullscreenSettings = { 20861 fullScreen: true, 20862 fullscreenPluginStrings: { 20863 toggleFullscreen: 'Toggle Fullscreen', 20864 }, 20865 }; 20866 20867 var FullScreen = /** @class */ (function () { 20868 function FullScreen(instance, $LG) { 20869 // get lightGallery core plugin instance 20870 this.core = instance;
20871 this.$LG = $LG; 20872 // extend module default settings with lightGallery core settings 20873 this.settings = __assign(__assign({}, fullscreenSettings), this.core.settings); 20874 return this; 20875 } 20876 FullScreen.prototype.init = function () { 20877 var fullScreen = ''; 20878 if (this.settings.fullScreen) { 20879 // check for fullscreen browser support 20880 if (!document.fullscreenEnabled && 20881 !document.webkitFullscreenEnabled && 20882 !document.mozFullScreenEnabled && 20883 !document.msFullscreenEnabled) { 20884 return; 20885 } 20886 else { 20887 fullScreen = "<button type=\"button\" aria-label=\"" + this.settings.fullscreenPluginStrings['toggleFullscreen'] + "\" class=\"lg-fullscreen lg-icon\"></button>"; 20888 this.core.$toolbar.append(fullScreen); 20889 this.fullScreen(); 20890 } 20891 } 20892 }; 20893 FullScreen.prototype.isFullScreen = function () { 20894 return (document.fullscreenElement || 20895 document.mozFullScreenElement || 20896 document.webkitFullscreenElement || 20897 document.msFullscreenElement); 20898 }; 20899 FullScreen.prototype.requestFullscreen = function () { 20900 var el = document.documentElement; 20901 if (el.requestFullscreen) { 20902 el.requestFullscreen(); 20903 } 20904 else if (el.msRequestFullscreen) { 20905 el.msRequestFullscreen(); 20906 } 20907 else if (el.mozRequestFullScreen) { 20908 el.mozRequestFullScreen(); 20909 } 20910 else if (el.webkitRequestFullscreen) { 20911 el.webkitRequestFullscreen(); 20912 } 20913 }; 20914 FullScreen.prototype.exitFullscreen = function () { 20915 if (document.exitFullscreen) { 20916 document.exitFullscreen(); 20917 } 20918 else if (document.msExitFullscreen) { 20919 document.msExitFullscreen(); 20920 } 20921 else if (document.mozCancelFullScreen) { 20922 document.mozCancelFullScreen(); 20923 } 20924 else if (document.webkitExitFullscreen) { 20925 document.webkitExitFullscreen(); 20926 } 20927 }; 20928 // https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Using_full_screen_mode 20929 FullScreen.prototype.fullScreen = function () { 20930 var _this = this; 20931 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 () { 20932 if (!_this.core.lgOpened) 20933 return; 20934 _this.core.outer.toggleClass('lg-fullscreen-on'); 20935 }); 20936 this.core.outer 20937 .find('.lg-fullscreen') 20938 .first() 20939 .on('click.lg', function () { 20940 if (_this.isFullScreen()) { 20941 _this.exitFullscreen(); 20942 } 20943 else { 20944 _this.requestFullscreen(); 20945 } 20946 }); 20947 }; 20948 FullScreen.prototype.closeGallery = function () { 20949 // exit from fullscreen if activated 20950 if (this.isFullScreen()) { 20951 this.exitFullscreen(); 20952 } 20953 }; 20954 FullScreen.prototype.destroy = function () { 20955 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); 20956 }; 20957 return FullScreen; 20958 }()); 20959 20960 return FullScreen; 20961 20962}))); 20963 20964/*! 20965 * lightgallery | 2.5.0 | June 13th 2022 20966 * http://www.lightgalleryjs.com/ 20967 * Copyright (c) 2020 Sachin Neravath; 20968 * @license GPLv3 20969 */ 20970 20971(function (global, factory) { 20972 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 20973 typeof define === 'function' && define.amd ? define(factory) : 20974 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lgHash = factory()); 20975}(this, (function () { 'use strict'; 20976 20977 /*! ***************************************************************************** 20978 Copyright (c) Microsoft Corporation. 20979 20980 Permission to use, copy, modify, and/or distribute this software for any 20981 purpose with or without fee is hereby granted. 20982 20983 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 20984 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 20985 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 20986 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 20987 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 20988 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 20989 PERFORMANCE OF THIS SOFTWARE. 20990 ***************************************************************************** */ 20991 20992 var __assign = function() { 20993 __assign = Object.assign || function __assign(t) { 20994 for (var s, i = 1, n = arguments.length; i < n; i++) { 20995 s = arguments[i]; 20996 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 20997 } 20998 return t; 20999 }; 21000 return __assign.apply(this, arguments); 21001 }; 21002 21003 /** 21004 * List of lightGallery events 21005 * All events should be documented here 21006 * Below interfaces are used to build the website documentations 21007 * */ 21008 var lGEvents = { 21009 afterAppendSlide: 'lgAfterAppendSlide', 21010 init: 'lgInit', 21011 hasVideo: 'lgHasVideo', 21012 containerResize: 'lgContainerResize', 21013 updateSlides: 'lgUpdateSlides', 21014 afterAppendSubHtml: 'lgAfterAppendSubHtml', 21015 beforeOpen: 'lgBeforeOpen', 21016 afterOpen: 'lgAfterOpen', 21017 slideItemLoad: 'lgSlideItemLoad', 21018 beforeSlide: 'lgBeforeSlide', 21019 afterSlide: 'lgAfterSlide', 21020 posterClick: 'lgPosterClick', 21021 dragStart: 'lgDragStart', 21022 dragMove: 'lgDragMove', 21023 dragEnd: 'lgDragEnd', 21024 beforeNextSlide: 'lgBeforeNextSlide', 21025 beforePrevSlide: 'lgBeforePrevSlide', 21026 beforeClose: 'lgBeforeClose', 21027 afterClose: 'lgAfterClose', 21028 rotateLeft: 'lgRotateLeft', 21029 rotateRight: 'lgRotateRight', 21030 flipHorizontal: 'lgFlipHorizontal', 21031 flipVertical: 'lgFlipVertical', 21032 autoplay: 'lgAutoplay', 21033 autoplayStart: 'lgAutoplayStart', 21034 autoplayStop: 'lgAutoplayStop', 21035 }; 21036 21037 var hashSettings = { 21038 hash: true, 21039 galleryId: '1', 21040 customSlideName: false, 21041 }; 21042 21043 var Hash = /** @class */ (function () { 21044 function Hash(instance, $LG) { 21045 // get lightGallery core plugin instance 21046 this.core = instance;
21047 this.$LG = $LG; 21048 // extend module default settings with lightGallery core settings 21049 this.settings = __assign(__assign({}, hashSettings), this.core.settings); 21050 return this; 21051 } 21052 Hash.prototype.init = function () { 21053 var _this = this; 21054 if (!this.settings.hash) { 21055 return; 21056 } 21057 this.oldHash = window.location.hash; 21058 setTimeout(function () { 21059 _this.buildFromHash(); 21060 }, 100); 21061 // Change hash value on after each slide transition 21062 this.core.LGel.on(lGEvents.afterSlide + ".hash", this.onAfterSlide.bind(this)); 21063 this.core.LGel.on(lGEvents.afterClose + ".hash", this.onCloseAfter.bind(this)); 21064 // Listen hash change and change the slide according to slide value 21065 this.$LG(window).on("hashchange.lg.hash.global" + this.core.lgId, this.onHashchange.bind(this)); 21066 }; 21067 Hash.prototype.onAfterSlide = function (event) { 21068 var slideName = this.core.galleryItems[event.detail.index].slideName; 21069 slideName = this.settings.customSlideName 21070 ? slideName || event.detail.index 21071 : event.detail.index; 21072 if (history.replaceState) { 21073 history.replaceState(null, '', window.location.pathname + 21074 window.location.search + 21075 '#lg=' + 21076 this.settings.galleryId + 21077 '&slide=' + 21078 slideName); 21079 } 21080 else { 21081 window.location.hash = 21082 'lg=' + this.settings.galleryId + '&slide=' + slideName; 21083 } 21084 }; 21085 /** 21086 * Get index of the slide from custom slideName. Has to be a public method. Used in hash plugin 21087 * @param {String} hash 21088 * @returns {Number} Index of the slide. 21089 */ 21090 Hash.prototype.getIndexFromUrl = function (hash) { 21091 if (hash === void 0) { hash = window.location.hash; } 21092 var slideName = hash.split('&slide=')[1]; 21093 var _idx = 0; 21094 if (this.settings.customSlideName) { 21095 for (var index = 0; index < this.core.galleryItems.length; index++) { 21096 var dynamicEl = this.core.galleryItems[index]; 21097 if (dynamicEl.slideName === slideName) { 21098 _idx = index; 21099 break; 21100 } 21101 } 21102 } 21103 else { 21104 _idx = parseInt(slideName, 10); 21105 } 21106 return isNaN(_idx) ? 0 : _idx; 21107 }; 21108 // Build Gallery if gallery id exist in the URL 21109 Hash.prototype.buildFromHash = function () { 21110 // if dynamic option is enabled execute immediately 21111 var _hash = window.location.hash; 21112 //Uncode edit ##START## 21113 // if (_hash.indexOf('lg=' + this.settings.galleryId) > 0) { 21114 if (_hash.indexOf('lg=' + this.settings.galleryId + '&') > 0) { 21115 //Uncode edit ##END## 21116 // This class is used to remove the initial animation if galleryId present in the URL 21117 this.$LG(document.body).addClass('lg-from-hash'); 21118 var index = this.getIndexFromUrl(_hash); 21119 this.core.openGallery(index); 21120 return true; 21121 } 21122 }; 21123 Hash.prototype.onCloseAfter = function () { 21124 // Reset to old hash value 21125 if (this.oldHash && 21126 this.oldHash.indexOf('lg=' + this.settings.galleryId) < 0) { 21127 if (history.replaceState) { 21128 history.replaceState(null, '', this.oldHash); 21129 } 21130 else { 21131 window.location.hash = this.oldHash; 21132 } 21133 } 21134 else { 21135 if (history.replaceState) { 21136 history.replaceState(null, document.title, window.location.pathname + window.location.search); 21137 } 21138 else { 21139 window.location.hash = ''; 21140 } 21141 } 21142 }; 21143 Hash.prototype.onHashchange = function () { 21144 if (!this.core.lgOpened) 21145 return; 21146 var _hash = window.location.hash; 21147 var index = this.getIndexFromUrl(_hash); 21148 // it galleryId doesn't exist in the url close the gallery 21149 if (_hash.indexOf('lg=' + this.settings.galleryId) > -1) { 21150 this.core.slide(index, false, false); 21151 } 21152 else if (this.core.lGalleryOn) { 21153 this.core.closeGallery(); 21154 } 21155 }; 21156 Hash.prototype.closeGallery = function () { 21157 if (this.settings.hash) { 21158 this.$LG(document.body).removeClass('lg-from-hash'); 21159 } 21160 }; 21161 Hash.prototype.destroy = function () { 21162 this.core.LGel.off('.lg.hash'); 21163 this.core.LGel.off('.hash'); 21164 this.$LG(window).off("hashchange.lg.hash.global" + this.core.lgId); 21165 }; 21166 return Hash; 21167 }()); 21168 21169 return Hash; 21170 21171}))); 21172/*! 21173 * lightgallery | 2.5.0 | June 13th 2022 21174 * http://www.lightgalleryjs.com/ 21175 * Copyright (c) 2020 Sachin Neravath; 21176 * @license GPLv3 21177 */ 21178 21179(function (global, factory) { 21180 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 21181 typeof define === 'function' && define.amd ? define(factory) : 21182 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lgShare = factory()); 21183}(this, (function () { 'use strict'; 21184 21185 /*! ***************************************************************************** 21186 Copyright (c) Microsoft Corporation. 21187 21188 Permission to use, copy, modify, and/or distribute this software for any 21189 purpose with or without fee is hereby granted. 21190 21191 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 21192 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 21193 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 21194 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 21195 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 21196 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 21197 PERFORMANCE OF THIS SOFTWARE. 21198 ***************************************************************************** */ 21199 21200 var __assign = function() { 21201 __assign = Object.assign || function __assign(t) { 21202 for (var s, i = 1, n = arguments.length; i < n; i++) { 21203 s = arguments[i]; 21204 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 21205 } 21206 return t; 21207 }; 21208 return __assign.apply(this, arguments); 21209 }; 21210 21211 function __spreadArrays() { 21212 for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; 21213 for (var r = Array(s), k = 0, i = 0; i < il; i++) 21214 for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) 21215 r[k] = a[j]; 21216 return r; 21217 } 21218 21219 var shareSettings = { 21220 share: true, 21221 facebook: true, 21222 facebookDropdownText: 'Facebook', 21223 twitter: true, 21224 twitterDropdownText: 'Twitter', 21225 pinterest: true, 21226 pinterestDropdownText: 'Pinterest', 21227 additionalShareOptions: [], 21228 sharePluginStrings: { share: 'Share' }, 21229 }; 21230 21231 function getFacebookShareLink(galleryItem) { 21232 var facebookBaseUrl = '//www.facebook.com/sharer/sharer.php?u='; 21233 return (facebookBaseUrl + 21234 encodeURIComponent(galleryItem.facebookShareUrl || window.location.href)); 21235 } 21236 21237 function getTwitterShareLink(galleryItem) { 21238 var twitterBaseUrl = '//twitter.com/intent/tweet?text='; 21239 var url = encodeURIComponent(galleryItem.twitterShareUrl || window.location.href); 21240 var text = galleryItem.tweetText;
21241 return twitterBaseUrl + text + '&url=' + url; 21242 } 21243 21244 function getPinterestShareLink(galleryItem) { 21245 var pinterestBaseUrl = 'http://www.pinterest.com/pin/create/button/?url='; 21246 var description = galleryItem.pinterestText; 21247 var media = encodeURIComponent(galleryItem.src); 21248 var url = encodeURIComponent(galleryItem.pinterestShareUrl || window.location.href); 21249 return (pinterestBaseUrl + 21250 url + 21251 '&media=' + 21252 media + 21253 '&description=' + 21254 description); 21255 } 21256 21257 /** 21258 * List of lightGallery events 21259 * All events should be documented here 21260 * Below interfaces are used to build the website documentations 21261 * */ 21262 var lGEvents = { 21263 afterAppendSlide: 'lgAfterAppendSlide', 21264 init: 'lgInit', 21265 hasVideo: 'lgHasVideo', 21266 containerResize: 'lgContainerResize', 21267 updateSlides: 'lgUpdateSlides', 21268 afterAppendSubHtml: 'lgAfterAppendSubHtml', 21269 beforeOpen: 'lgBeforeOpen', 21270 afterOpen: 'lgAfterOpen', 21271 slideItemLoad: 'lgSlideItemLoad', 21272 beforeSlide: 'lgBeforeSlide', 21273 afterSlide: 'lgAfterSlide', 21274 posterClick: 'lgPosterClick', 21275 dragStart: 'lgDragStart', 21276 dragMove: 'lgDragMove', 21277 dragEnd: 'lgDragEnd', 21278 beforeNextSlide: 'lgBeforeNextSlide', 21279 beforePrevSlide: 'lgBeforePrevSlide', 21280 beforeClose: 'lgBeforeClose', 21281 afterClose: 'lgAfterClose', 21282 rotateLeft: 'lgRotateLeft', 21283 rotateRight: 'lgRotateRight', 21284 flipHorizontal: 'lgFlipHorizontal', 21285 flipVertical: 'lgFlipVertical', 21286 autoplay: 'lgAutoplay', 21287 autoplayStart: 'lgAutoplayStart', 21288 autoplayStop: 'lgAutoplayStop', 21289 }; 21290 21291 var Share = /** @class */ (function () { 21292 function Share(instance) { 21293 this.shareOptions = []; 21294 // get lightGallery core plugin instance 21295 this.core = instance; 21296 // extend module default settings with lightGallery core settings 21297 this.settings = __assign(__assign({}, shareSettings), this.core.settings); 21298 return this; 21299 } 21300 Share.prototype.init = function () { 21301 if (!this.settings.share) { 21302 return; 21303 } 21304 this.shareOptions = __spreadArrays(this.getDefaultShareOptions(), this.settings.additionalShareOptions); 21305 this.setLgShareMarkup(); 21306 this.core.outer 21307 .find('.lg-share .lg-dropdown') 21308 .append(this.getShareListHtml()); 21309 this.core.LGel.on(lGEvents.afterSlide + ".share", this.onAfterSlide.bind(this)); 21310 }; 21311 Share.prototype.getShareListHtml = function () { 21312 var shareHtml = ''; 21313 this.shareOptions.forEach(function (shareOption) { 21314 shareHtml += shareOption.dropdownHTML; 21315 }); 21316 return shareHtml; 21317 }; 21318 Share.prototype.setLgShareMarkup = function () { 21319 var _this = this; 21320 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>"); 21321 this.core.outer.append('<div class="lg-dropdown-overlay"></div>'); 21322 var $shareButton = this.core.outer.find('.lg-share'); 21323 $shareButton.first().on('click.lg', function () { 21324 _this.core.outer.toggleClass('lg-dropdown-active'); 21325 if (_this.core.outer.hasClass('lg-dropdown-active')) { 21326 _this.core.outer.attr('aria-expanded', true); 21327 } 21328 else { 21329 _this.core.outer.attr('aria-expanded', false); 21330 } 21331 }); 21332 this.core.outer 21333 .find('.lg-dropdown-overlay') 21334 .first() 21335 .on('click.lg', function () { 21336 _this.core.outer.removeClass('lg-dropdown-active'); 21337 _this.core.outer.attr('aria-expanded', false); 21338 }); 21339 }; 21340 Share.prototype.onAfterSlide = function (event) { 21341 var _this = this; 21342 var index = event.detail.index; 21343 var currentItem = this.core.galleryItems[index]; 21344 setTimeout(function () { 21345 _this.shareOptions.forEach(function (shareOption) { 21346 var selector = shareOption.selector; 21347 _this.core.outer 21348 .find(selector) 21349 .attr('href', shareOption.generateLink(currentItem)); 21350 }); 21351 }, 100); 21352 }; 21353 Share.prototype.getShareListItemHTML = function (type, text) { 21354 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>"; 21355 }; 21356 Share.prototype.getDefaultShareOptions = function () { 21357 return __spreadArrays((this.settings.facebook 21358 ? [ 21359 { 21360 type: 'facebook', 21361 generateLink: getFacebookShareLink,
21362 dropdownHTML: this.getShareListItemHTML('facebook', this.settings.facebookDropdownText), 21363 selector: '.lg-share-facebook', 21364 }, 21365 ] 21366 : []), (this.settings.twitter 21367 ? [ 21368 { 21369 type: 'twitter', 21370 generateLink: getTwitterShareLink, 21371 dropdownHTML: this.getShareListItemHTML('twitter', this.settings.twitterDropdownText), 21372 selector: '.lg-share-twitter', 21373 }, 21374 ] 21375 : []), (this.settings.pinterest 21376 ? [ 21377 { 21378 type: 'pinterest', 21379 generateLink: getPinterestShareLink, 21380 dropdownHTML: this.getShareListItemHTML('pinterest', this.settings.pinterestDropdownText), 21381 selector: '.lg-share-pinterest', 21382 }, 21383 ] 21384 : [])); 21385 }; 21386 Share.prototype.destroy = function () { 21387 this.core.outer.find('.lg-dropdown-overlay').remove(); 21388 this.core.outer.find('.lg-share').remove(); 21389 this.core.LGel.off('.lg.share'); 21390 this.core.LGel.off('.share'); 21391 }; 21392 return Share; 21393 }()); 21394 21395 return Share; 21396 21397}))); 21398/*! 21399 * lightgallery | 2.5.0 | June 13th 2022 21400 * http://www.lightgalleryjs.com/ 21401 * Copyright (c) 2020 Sachin Neravath; 21402 * @license GPLv3 21403 */ 21404 21405(function (global, factory) { 21406 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 21407 typeof define === 'function' && define.amd ? define(factory) : 21408 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lgThumbnail = factory()); 21409}(this, (function () { 'use strict'; 21410 21411 /*! ***************************************************************************** 21412 Copyright (c) Microsoft Corporation. 21413 21414 Permission to use, copy, modify, and/or distribute this software for any 21415 purpose with or without fee is hereby granted. 21416 21417 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 21418 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 21419 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 21420 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 21421 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 21422 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 21423 PERFORMANCE OF THIS SOFTWARE. 21424 ***************************************************************************** */ 21425 21426 var __assign = function() { 21427 __assign = Object.assign || function __assign(t) { 21428 for (var s, i = 1, n = arguments.length; i < n; i++) { 21429 s = arguments[i]; 21430 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 21431 } 21432 return t; 21433 }; 21434 return __assign.apply(this, arguments); 21435 }; 21436 21437 var thumbnailsSettings = { 21438 thumbnail: true, 21439 animateThumb: true, 21440 currentPagerPosition: 'middle', 21441 alignThumbnails: 'middle', 21442 thumbWidth: 100, 21443 thumbHeight: '80px', 21444 thumbMargin: 5, 21445 appendThumbnailsTo: '.lg-components', 21446 toggleThumb: false, 21447 enableThumbDrag: true, 21448 enableThumbSwipe: true, 21449 thumbnailSwipeThreshold: 10, 21450 loadYouTubeThumbnail: true, 21451 youTubeThumbSize: 1, 21452 thumbnailPluginStrings: { 21453 toggleThumbnails: 'Toggle thumbnails', 21454 }, 21455 }; 21456 21457 /** 21458 * List of lightGallery events 21459 * All events should be documented here 21460 * Below interfaces are used to build the website documentations 21461 * */ 21462 var lGEvents = { 21463 afterAppendSlide: 'lgAfterAppendSlide', 21464 init: 'lgInit', 21465 hasVideo: 'lgHasVideo', 21466 containerResize: 'lgContainerResize', 21467 updateSlides: 'lgUpdateSlides', 21468 afterAppendSubHtml: 'lgAfterAppendSubHtml', 21469 beforeOpen: 'lgBeforeOpen', 21470 afterOpen: 'lgAfterOpen', 21471 slideItemLoad: 'lgSlideItemLoad', 21472 beforeSlide: 'lgBeforeSlide', 21473 afterSlide: 'lgAfterSlide', 21474 posterClick: 'lgPosterClick', 21475 dragStart: 'lgDragStart', 21476 dragMove: 'lgDragMove', 21477 dragEnd: 'lgDragEnd', 21478 beforeNextSlide: 'lgBeforeNextSlide', 21479 beforePrevSlide: 'lgBeforePrevSlide', 21480 beforeClose: 'lgBeforeClose', 21481 afterClose: 'lgAfterClose', 21482 rotateLeft: 'lgRotateLeft', 21483 rotateRight: 'lgRotateRight', 21484 flipHorizontal: 'lgFlipHorizontal', 21485 flipVertical: 'lgFlipVertical', 21486 autoplay: 'lgAutoplay', 21487 autoplayStart: 'lgAutoplayStart', 21488 autoplayStop: 'lgAutoplayStop', 21489 }; 21490 21491 var Thumbnail = /** @class */ (function () { 21492 function Thumbnail(instance, $LG) { 21493 this.thumbOuterWidth = 0; 21494 this.thumbTotalWidth = 0; 21495 this.translateX = 0; 21496 this.thumbClickable = false;
21497 // get lightGallery core plugin instance 21498 this.core = instance; 21499 this.$LG = $LG; 21500 return this; 21501 } 21502 Thumbnail.prototype.init = function () { 21503 // extend module default settings with lightGallery core settings 21504 this.settings = __assign(__assign({}, thumbnailsSettings), this.core.settings); 21505 this.thumbOuterWidth = 0; 21506 this.thumbTotalWidth = 21507 this.core.galleryItems.length * 21508 (this.settings.thumbWidth + this.settings.thumbMargin); 21509 // Thumbnail animation value 21510 this.translateX = 0; 21511 this.setAnimateThumbStyles(); 21512 if (!this.core.settings.allowMediaOverlap) { 21513 this.settings.toggleThumb = false; 21514 } 21515 if (this.settings.thumbnail) { 21516 this.build(); 21517 if (this.settings.animateThumb) { 21518 if (this.settings.enableThumbDrag) { 21519 this.enableThumbDrag(); 21520 } 21521 if (this.settings.enableThumbSwipe) { 21522 this.enableThumbSwipe(); 21523 } 21524 this.thumbClickable = false; 21525 } 21526 else { 21527 this.thumbClickable = true; 21528 } 21529 this.toggleThumbBar(); 21530 this.thumbKeyPress(); 21531 } 21532 }; 21533 Thumbnail.prototype.build = function () { 21534 var _this = this; 21535 this.setThumbMarkup(); 21536 this.manageActiveClassOnSlideChange(); 21537 this.$lgThumb.first().on('click.lg touchend.lg', function (e) { 21538 var $target = _this.$LG(e.target); 21539 if (!$target.hasAttribute('data-lg-item-id')) { 21540 return; 21541 } 21542 setTimeout(function () { 21543 // In IE9 and bellow touch does not support 21544 // Go to slide if browser does not support css transitions 21545 if (_this.thumbClickable && !_this.core.lgBusy) { 21546 var index = parseInt($target.attr('data-lg-item-id')); 21547 _this.core.slide(index, false, true, false); 21548 } 21549 }, 50); 21550 }); 21551 //Uncode edit ##START## 21552 // this.core.LGel.on(lGEvents.beforeSlide + ".thumb", function (event) { 21553 this.core.LGel.on(lGEvents.beforeSlide, function (event) { 21554 //Uncode edit ##END## 21555 var index = event.detail.index; 21556 _this.animateThumb(index); 21557 }); 21558 //Uncode edit ##START## 21559 // this.core.LGel.on(lGEvents.beforeOpen + ".thumb", function () { 21560 this.core.LGel.on(lGEvents.beforeOpen, function () { 21561 //Uncode edit ##END## 21562 _this.thumbOuterWidth = _this.core.outer.get().offsetWidth; 21563 }); 21564 //Uncode edit ##START## 21565 // this.core.LGel.on(lGEvents.updateSlides + ".thumb", function () { 21566 this.core.LGel.on(lGEvents.updateSlides, function () { 21567 //Uncode edit ##END## 21568 _this.rebuildThumbnails(); 21569 }); 21570 //Uncode edit ##START## 21571 // this.core.LGel.on(lGEvents.containerResize + ".thumb", function () { 21572 this.core.LGel.on(lGEvents.containerResize, function () { 21573 //Uncode edit ##END## 21574 if (!_this.core.lgOpened) 21575 return; 21576 setTimeout(function () { 21577 _this.thumbOuterWidth = _this.core.outer.get().offsetWidth; 21578 _this.animateThumb(_this.core.index); 21579 _this.thumbOuterWidth = _this.core.outer.get().offsetWidth; 21580 }, 50); 21581 }); 21582 }; 21583 Thumbnail.prototype.setThumbMarkup = function () { 21584 var thumbOuterClassNames = 'lg-thumb-outer '; 21585 if (this.settings.alignThumbnails) { 21586 thumbOuterClassNames += "lg-thumb-align-" + this.settings.alignThumbnails; 21587 } 21588 var html = "<div class=\"" + thumbOuterClassNames + "\">\n <div class=\"lg-thumb lg-group\">\n </div>\n </div>"; 21589 this.core.outer.addClass('lg-has-thumb'); 21590 if (this.settings.appendThumbnailsTo === '.lg-components') { 21591 this.core.$lgComponents.append(html); 21592 } 21593 else { 21594 this.core.outer.append(html); 21595 } 21596 this.$thumbOuter = this.core.outer.find('.lg-thumb-outer').first(); 21597 this.$lgThumb = this.core.outer.find('.lg-thumb').first(); 21598 if (this.settings.animateThumb) { 21599 this.core.outer 21600 .find('.lg-thumb') 21601 .css('transition-duration', this.core.settings.speed + 'ms') 21602 .css('width', this.thumbTotalWidth + 'px') 21603 .css('position', 'relative'); 21604 } 21605 this.setThumbItemHtml(this.core.galleryItems); 21606 }; 21607 Thumbnail.prototype.enableThumbDrag = function () { 21608 var _this = this; 21609 var thumbDragUtils = { 21610 cords: { 21611 startX: 0, 21612 endX: 0, 21613 }, 21614 isMoved: false, 21615 newTranslateX: 0, 21616 startTime: new Date(), 21617 endTime: new Date(), 21618 touchMoveTime: 0, 21619 }; 21620 var isDragging = false;
21621 this.$thumbOuter.addClass('lg-grab'); 21622 this.core.outer 21623 .find('.lg-thumb') 21624 .first() 21625 .on('mousedown.lg.thumb', function (e) { 21626 if (_this.thumbTotalWidth > _this.thumbOuterWidth) { 21627 // execute only on .lg-object 21628 e.preventDefault(); 21629 thumbDragUtils.cords.startX = e.pageX; 21630 thumbDragUtils.startTime = new Date(); 21631 _this.thumbClickable = false; 21632 isDragging = true; 21633 // ** Fix for webkit cursor issue https://code.google.com/p/chromium/issues/detail?id=26723 21634 _this.core.outer.get().scrollLeft += 1; 21635 _this.core.outer.get().scrollLeft -= 1; 21636 // * 21637 _this.$thumbOuter 21638 .removeClass('lg-grab') 21639 .addClass('lg-grabbing'); 21640 } 21641 }); 21642 this.$LG(window).on("mousemove.lg.thumb.global" + this.core.lgId, function (e) { 21643 if (!_this.core.lgOpened) 21644 return; 21645 if (isDragging) { 21646 thumbDragUtils.cords.endX = e.pageX; 21647 thumbDragUtils = _this.onThumbTouchMove(thumbDragUtils); 21648 } 21649 }); 21650 this.$LG(window).on("mouseup.lg.thumb.global" + this.core.lgId, function () { 21651 if (!_this.core.lgOpened) 21652 return; 21653 if (thumbDragUtils.isMoved) { 21654 thumbDragUtils = _this.onThumbTouchEnd(thumbDragUtils); 21655 } 21656 else { 21657 _this.thumbClickable = true; 21658 } 21659 if (isDragging) { 21660 isDragging = false; 21661 _this.$thumbOuter.removeClass('lg-grabbing').addClass('lg-grab'); 21662 } 21663 }); 21664 }; 21665 Thumbnail.prototype.enableThumbSwipe = function () { 21666 var _this = this; 21667 var thumbDragUtils = { 21668 cords: { 21669 startX: 0, 21670 endX: 0, 21671 }, 21672 isMoved: false, 21673 newTranslateX: 0, 21674 startTime: new Date(), 21675 endTime: new Date(), 21676 touchMoveTime: 0, 21677 }; 21678 this.$lgThumb.on('touchstart.lg', function (e) { 21679 if (_this.thumbTotalWidth > _this.thumbOuterWidth) { 21680 e.preventDefault(); 21681 thumbDragUtils.cords.startX = e.targetTouches[0].pageX; 21682 _this.thumbClickable = false; 21683 thumbDragUtils.startTime = new Date(); 21684 } 21685 }); 21686 this.$lgThumb.on('touchmove.lg', function (e) { 21687 if (_this.thumbTotalWidth > _this.thumbOuterWidth) { 21688 e.preventDefault(); 21689 thumbDragUtils.cords.endX = e.targetTouches[0].pageX; 21690 thumbDragUtils = _this.onThumbTouchMove(thumbDragUtils); 21691 } 21692 }); 21693 this.$lgThumb.on('touchend.lg', function () { 21694 if (thumbDragUtils.isMoved) { 21695 thumbDragUtils = _this.onThumbTouchEnd(thumbDragUtils); 21696 } 21697 else { 21698 _this.thumbClickable = true; 21699 } 21700 }); 21701 }; 21702 // Rebuild thumbnails 21703 Thumbnail.prototype.rebuildThumbnails = function () { 21704 var _this = this; 21705 // Remove transitions 21706 this.$thumbOuter.addClass('lg-rebuilding-thumbnails'); 21707 setTimeout(function () { 21708 _this.thumbTotalWidth = 21709 _this.core.galleryItems.length * 21710 (_this.settings.thumbWidth + _this.settings.thumbMargin); 21711 _this.$lgThumb.css('width', _this.thumbTotalWidth + 'px'); 21712 _this.$lgThumb.empty(); 21713 _this.setThumbItemHtml(_this.core.galleryItems); 21714 _this.animateThumb(_this.core.index); 21715 }, 50); 21716 setTimeout(function () { 21717 _this.$thumbOuter.removeClass('lg-rebuilding-thumbnails'); 21718 }, 200); 21719 }; 21720 // @ts-check 21721 Thumbnail.prototype.setTranslate = function (value) { 21722 this.$lgThumb.css('transform', 'translate3d(-' + value + 'px, 0px, 0px)'); 21723 }; 21724 Thumbnail.prototype.getPossibleTransformX = function (left) { 21725 if (left > this.thumbTotalWidth - this.thumbOuterWidth) { 21726 left = this.thumbTotalWidth - this.thumbOuterWidth; 21727 } 21728 if (left < 0) { 21729 left = 0; 21730 } 21731 return left; 21732 }; 21733 Thumbnail.prototype.animateThumb = function (index) { 21734 this.$lgThumb.css('transition-duration', this.core.settings.speed + 'ms'); 21735 if (this.settings.animateThumb) { 21736 var position = 0; 21737 switch (this.settings.currentPagerPosition) { 21738 case 'left': 21739 position = 0; 21740 break; 21741 case 'middle': 21742 position = 21743 this.thumbOuterWidth / 2 - this.settings.thumbWidth / 2; 21744 break; 21745 case 'right': 21746 position = this.thumbOuterWidth - this.settings.thumbWidth; 21747 } 21748 this.translateX = 21749 (this.settings.thumbWidth + this.settings.thumbMargin) * index - 21750 1 - 21751 position; 21752 if (this.translateX > this.thumbTotalWidth - this.thumbOuterWidth) { 21753 this.translateX = this.thumbTotalWidth - this.thumbOuterWidth; 21754 } 21755 if (this.translateX < 0) { 21756 this.translateX = 0; 21757 } 21758 this.setTranslate(this.translateX); 21759 } 21760 };
21761 Thumbnail.prototype.onThumbTouchMove = function (thumbDragUtils) { 21762 thumbDragUtils.newTranslateX = this.translateX; 21763 thumbDragUtils.isMoved = true; 21764 thumbDragUtils.touchMoveTime = new Date().valueOf(); 21765 thumbDragUtils.newTranslateX -= 21766 thumbDragUtils.cords.endX - thumbDragUtils.cords.startX; 21767 thumbDragUtils.newTranslateX = this.getPossibleTransformX(thumbDragUtils.newTranslateX); 21768 // move current slide 21769 this.setTranslate(thumbDragUtils.newTranslateX); 21770 this.$thumbOuter.addClass('lg-dragging'); 21771 return thumbDragUtils; 21772 }; 21773 Thumbnail.prototype.onThumbTouchEnd = function (thumbDragUtils) { 21774 thumbDragUtils.isMoved = false; 21775 thumbDragUtils.endTime = new Date(); 21776 this.$thumbOuter.removeClass('lg-dragging'); 21777 var touchDuration = thumbDragUtils.endTime.valueOf() - 21778 thumbDragUtils.startTime.valueOf(); 21779 var distanceXnew = thumbDragUtils.cords.endX - thumbDragUtils.cords.startX; 21780 var speedX = Math.abs(distanceXnew) / touchDuration; 21781 // Some magical numbers 21782 // Can be improved 21783 if (speedX > 0.15 && 21784 thumbDragUtils.endTime.valueOf() - thumbDragUtils.touchMoveTime < 30) { 21785 speedX += 1; 21786 if (speedX > 2) { 21787 speedX += 1; 21788 } 21789 speedX = 21790 speedX + 21791 speedX * (Math.abs(distanceXnew) / this.thumbOuterWidth); 21792 this.$lgThumb.css('transition-duration', Math.min(speedX - 1, 2) + 'settings'); 21793 distanceXnew = distanceXnew * speedX; 21794 this.translateX = this.getPossibleTransformX(this.translateX - distanceXnew); 21795 this.setTranslate(this.translateX); 21796 } 21797 else { 21798 this.translateX = thumbDragUtils.newTranslateX; 21799 } 21800 if (Math.abs(thumbDragUtils.cords.endX - thumbDragUtils.cords.startX) < 21801 this.settings.thumbnailSwipeThreshold) { 21802 this.thumbClickable = true; 21803 } 21804 return thumbDragUtils; 21805 }; 21806 Thumbnail.prototype.getThumbHtml = function (thumb, index) { 21807 var slideVideoInfo = this.core.galleryItems[index].__slideVideoInfo || {}; 21808 var thumbImg; 21809 if (slideVideoInfo.youtube) { 21810 if (this.settings.loadYouTubeThumbnail) { 21811 thumbImg = 21812 '//img.youtube.com/vi/' + 21813 slideVideoInfo.youtube[1] + 21814 '/' + 21815 this.settings.youTubeThumbSize + 21816 '.jpg'; 21817 } 21818 else { 21819 thumbImg = thumb; 21820 } 21821 } 21822 else { 21823 thumbImg = thumb; 21824 } 21825 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>"; 21826 }; 21827 Thumbnail.prototype.getThumbItemHtml = function (items) { 21828 var thumbList = ''; 21829 for (var i = 0; i < items.length; i++) { 21830 thumbList += this.getThumbHtml(items[i].thumb, i); 21831 } 21832 return thumbList; 21833 }; 21834 Thumbnail.prototype.setThumbItemHtml = function (items) { 21835 var thumbList = this.getThumbItemHtml(items); 21836 this.$lgThumb.html(thumbList); 21837 }; 21838 Thumbnail.prototype.setAnimateThumbStyles = function () { 21839 if (this.settings.animateThumb) { 21840 this.core.outer.addClass('lg-animate-thumb'); 21841 } 21842 }; 21843 // Manage thumbnail active calss
21844 Thumbnail.prototype.manageActiveClassOnSlideChange = function () { 21845 var _this = this; 21846 // manage active class for thumbnail 21847 //Uncode edit ##START## 21848 // this.core.LGel.on(lGEvents.beforeSlide + ".thumb", function (event) { 21849 this.core.LGel.on(lGEvents.beforeSlide, function (event) { 21850 //Uncode edit ##END## 21851 var $thumb = _this.core.outer.find('.lg-thumb-item'); 21852 var index = event.detail.index; 21853 $thumb.removeClass('active'); 21854 $thumb.eq(index).addClass('active'); 21855 }); 21856 }; 21857 // Toggle thumbnail bar 21858 Thumbnail.prototype.toggleThumbBar = function () { 21859 var _this = this; 21860 if (this.settings.toggleThumb) { 21861 this.core.outer.addClass('lg-can-toggle'); 21862 this.core.$toolbar.append('<button type="button" aria-label="' + 21863 this.settings.thumbnailPluginStrings['toggleThumbnails'] + 21864 '" class="lg-toggle-thumb lg-icon"></button>'); 21865 this.core.outer 21866 .find('.lg-toggle-thumb') 21867 .first() 21868 .on('click.lg', function () { 21869 _this.core.outer.toggleClass('lg-components-open'); 21870 }); 21871 } 21872 }; 21873 Thumbnail.prototype.thumbKeyPress = function () { 21874 var _this = this; 21875 this.$LG(window).on("keydown.lg.thumb.global" + this.core.lgId, function (e) { 21876 if (!_this.core.lgOpened || !_this.settings.toggleThumb) 21877 return; 21878 if (e.keyCode === 38) { 21879 e.preventDefault(); 21880 _this.core.outer.addClass('lg-components-open'); 21881 } 21882 else if (e.keyCode === 40) { 21883 e.preventDefault(); 21884 _this.core.outer.removeClass('lg-components-open'); 21885 } 21886 }); 21887 }; 21888 Thumbnail.prototype.destroy = function () { 21889 if (this.settings.thumbnail) { 21890 this.$LG(window).off(".lg.thumb.global" + this.core.lgId); 21891 this.core.LGel.off('.lg.thumb'); 21892 this.core.LGel.off('.thumb'); 21893 this.$thumbOuter.remove(); 21894 this.core.outer.removeClass('lg-has-thumb'); 21895 } 21896 }; 21897 return Thumbnail; 21898 }()); 21899 21900 return Thumbnail; 21901 21902}))); 21903/*! 21904 * lightgallery | 2.5.0 | June 13th 2022 21905 * http://www.lightgalleryjs.com/ 21906 * Copyright (c) 2020 Sachin Neravath; 21907 * @license GPLv3 21908 */ 21909 21910(function (global, factory) { 21911 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 21912 typeof define === 'function' && define.amd ? define(factory) : 21913 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lgVideo = factory()); 21914}(this, (function () { 'use strict'; 21915 21916 /*! ***************************************************************************** 21917 Copyright (c) Microsoft Corporation. 21918 21919 Permission to use, copy, modify, and/or distribute this software for any 21920 purpose with or without fee is hereby granted. 21921 21922 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 21923 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 21924 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 21925 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 21926 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 21927 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 21928 PERFORMANCE OF THIS SOFTWARE. 21929 ***************************************************************************** */ 21930 21931 var __assign = function() { 21932 __assign = Object.assign || function __assign(t) { 21933 for (var s, i = 1, n = arguments.length; i < n; i++) { 21934 s = arguments[i]; 21935 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 21936 } 21937 return t; 21938 }; 21939 return __assign.apply(this, arguments); 21940 }; 21941 21942 var videoSettings = { 21943 autoplayFirstVideo: true, 21944 youTubePlayerParams: false, 21945 vimeoPlayerParams: false, 21946 wistiaPlayerParams: false, 21947 gotoNextSlideOnVideoEnd: true, 21948 autoplayVideoOnSlide: false, 21949 videojs: false, 21950 videojsTheme: '', 21951 videojsOptions: {}, 21952 }; 21953 21954 /** 21955 * List of lightGallery events 21956 * All events should be documented here 21957 * Below interfaces are used to build the website documentations 21958 * */ 21959 var lGEvents = { 21960 afterAppendSlide: 'lgAfterAppendSlide', 21961 init: 'lgInit', 21962 hasVideo: 'lgHasVideo', 21963 containerResize: 'lgContainerResize', 21964 updateSlides: 'lgUpdateSlides', 21965 afterAppendSubHtml: 'lgAfterAppendSubHtml', 21966 beforeOpen: 'lgBeforeOpen', 21967 afterOpen: 'lgAfterOpen', 21968 slideItemLoad: 'lgSlideItemLoad', 21969 beforeSlide: 'lgBeforeSlide', 21970 afterSlide: 'lgAfterSlide', 21971 posterClick: 'lgPosterClick', 21972 dragStart: 'lgDragStart', 21973 dragMove: 'lgDragMove', 21974 dragEnd: 'lgDragEnd', 21975 beforeNextSlide: 'lgBeforeNextSlide', 21976 beforePrevSlide: 'lgBeforePrevSlide', 21977 beforeClose: 'lgBeforeClose', 21978 afterClose: 'lgAfterClose', 21979 rotateLeft: 'lgRotateLeft', 21980 rotateRight: 'lgRotateRight', 21981 flipHorizontal: 'lgFlipHorizontal', 21982 flipVertical: 'lgFlipVertical', 21983 autoplay: 'lgAutoplay', 21984 autoplayStart: 'lgAutoplayStart', 21985 autoplayStop: 'lgAutoplayStop', 21986 }; 21987 21988 var param = function (obj) { 21989 return Object.keys(obj) 21990 .map(function (k) { 21991 return encodeURIComponent(k) + '=' + encodeURIComponent(obj[k]); 21992 }) 21993 .join('&'); 21994 }; 21995 var getVimeoURLParams = function (defaultParams, videoInfo) { 21996 if (!videoInfo || !videoInfo.vimeo) 21997 return '';
21998 var urlParams = videoInfo.vimeo[2] || ''; 21999 var defaultPlayerParams = defaultParams && Object.keys(defaultParams).length !== 0 22000 ? '&' + param(defaultParams) 22001 : ''; 22002 // Support private video 22003 var urlWithHash = videoInfo.vimeo[0].split('/').pop() || ''; 22004 var urlWithHashWithParams = urlWithHash.split('?')[0] || ''; 22005 var hash = urlWithHashWithParams.split('#')[0]; 22006 var isPrivate = videoInfo.vimeo[1] !== hash; 22007 if (isPrivate) { 22008 urlParams = urlParams.replace("/" + hash, ''); 22009 } 22010 urlParams = 22011 urlParams[0] == '?' ? '&' + urlParams.slice(1) : urlParams || ''; 22012 // For vimeo last params gets priority if duplicates found 22013 // Uncode edit ##START## 22014 var vimeoPlayerParams = '?autoplay=0'; 22015 if ( videoInfo.autoplay !== '' ) { 22016 vimeoPlayerParams = vimeoPlayerParams.replace(new RegExp('([?&])autoplay=(.*?)(&|$)'), '$1$3' ); 22017 vimeoPlayerParams = vimeoPlayerParams.replace(new RegExp('([?&])autoplay(&|$)'), '$1$2' ); 22018 } else { 22019 if ( typeof SiteParameters !== 'undefined' && typeof SiteParameters.vimeoPlayerParams !== 'undefined' && SiteParameters.vimeoPlayerParams !== '' ) { 22020 vimeoPlayerParams = SiteParameters.vimeoPlayerParams; 22021 } 22022 } 22023 if ( videoInfo.muted !== '' ) { 22024 vimeoPlayerParams += '&muted=' + (videoInfo.muted === 'yes'); 22025 } else { 22026 if ( urlParams.indexOf('muted=') < 0 && vimeoPlayerParams.indexOf('muted=') < 0 ) { 22027 vimeoPlayerParams += '&muted=1'; 22028 } 22029 } 22030 // var vimeoPlayerParams = "?autoplay=0&muted=1" + (isPrivate ? "&h=" + hash : '') + defaultPlayerParams + urlParams; 22031 vimeoPlayerParams += (isPrivate ? "&h=" + hash : '') + defaultPlayerParams + urlParams; 22032 // Uncode edit ##END## 22033 return vimeoPlayerParams; 22034 }; 22035 22036 /** 22037 * Video module for lightGallery 22038 * Supports HTML5, YouTube, Vimeo, wistia videos 22039 * 22040 * 22041 * @ref Wistia 22042 * https://wistia.com/support/integrations/wordpress(How to get url) 22043 * https://wistia.com/support/developers/embed-options#using-embed-options 22044 * https://wistia.com/support/developers/player-api 22045 * https://wistia.com/support/developers/construct-an-embed-code 22046 * http://jsfiddle.net/xvnm7xLm/ 22047 * https://developer.mozilla.org/en-US/docs/Web/HTML/Element/video 22048 * https://wistia.com/support/embed-and-share/sharing-videos 22049 * https://private-sharing.wistia.com/medias/mwhrulrucj 22050 * 22051 * @ref Youtube 22052 * https://developers.google.com/youtube/player_parameters#enablejsapi 22053 * https://developers.google.com/youtube/iframe_api_reference 22054 * https://developer.chrome.com/blog/autoplay/#iframe-delegation 22055 * 22056 * @ref Vimeo 22057 * https://stackoverflow.com/questions/10488943/easy-way-to-get-vimeo-id-from-a-vimeo-url 22058 * https://vimeo.zendesk.com/hc/en-us/articles/360000121668-Starting-playback-at-a-specific-timecode 22059 * https://vimeo.zendesk.com/hc/en-us/articles/360001494447-Using-Player-Parameters 22060 */ 22061 var Video = /** @class */ (function () { 22062 function Video(instance) { 22063 // get lightGallery core plugin instance 22064 this.core = instance; 22065 this.settings = __assign(__assign({}, videoSettings), this.core.settings); 22066 return this; 22067 } 22068 Video.prototype.init = function () { 22069 var _this = this; 22070 /** 22071 * Event triggered when video url found without poster 22072 * Append video HTML 22073 * Play if autoplayFirstVideo is true 22074 */ 22075 this.core.LGel.on(lGEvents.hasVideo + ".video", this.onHasVideo.bind(this)); 22076 this.core.LGel.on(lGEvents.posterClick + ".video", function () { 22077 var $el = _this.core.getSlideItem(_this.core.index); 22078 _this.loadVideoOnPosterClick($el); 22079 }); 22080 this.core.LGel.on(lGEvents.slideItemLoad + ".video", this.onSlideItemLoad.bind(this)); 22081 // @desc fired immediately before each slide transition. 22082 this.core.LGel.on(lGEvents.beforeSlide + ".video", this.onBeforeSlide.bind(this)); 22083 // @desc fired immediately after each slide transition. 22084 this.core.LGel.on(lGEvents.afterSlide + ".video", this.onAfterSlide.bind(this)); 22085 }; 22086 /** 22087 * @desc Event triggered when a slide is completely loaded 22088 * 22089 * @param {Event} event - lightGalley custom event 22090 */ 22091 Video.prototype.onSlideItemLoad = function (event) { 22092 var _this = this; 22093 var _a = event.detail, isFirstSlide = _a.isFirstSlide, index = _a.index; 22094 // Should check the active slide as well as user may have moved to different slide before the first slide is loaded 22095 if (this.settings.autoplayFirstVideo && 22096 isFirstSlide && 22097 index === this.core.index) { 22098 // Delay is just for the transition effect on video load 22099 setTimeout(function () { 22100 _this.loadAndPlayVideo(index); 22101 }, 200); 22102 } 22103 // Should not call on first slide. should check only if the slide is active 22104 if (!isFirstSlide && 22105 this.settings.autoplayVideoOnSlide && 22106 index === this.core.index) { 22107 setTimeout(function () { 22108 _this.loadAndPlayVideo(index); 22109 }, 500); 22110 } 22111 }; 22112 /** 22113 * @desc Event triggered when video url or poster found 22114 * Append video HTML is poster is not given 22115 * Play if autoplayFirstVideo is true 22116 * 22117 * @param {Event} event - Javascript Event object. 22118 */ 22119 Video.prototype.onHasVideo = function (event) { 22120 var _a = event.detail, index = _a.index, src = _a.src, html5Video = _a.html5Video, hasPoster = _a.hasPoster; 22121 if (!hasPoster) { 22122 // All functions are called separately if poster exist in loadVideoOnPosterClick function 22123 this.appendVideos(this.core.getSlideItem(index), { 22124 src: src, 22125 addClass: 'lg-object', 22126 index: index, 22127 html5Video: html5Video, 22128 // Uncode edit ##START## 22129 autoplay: event.target.getAttribute('data-lb-autoplay'), 22130 muted: event.target.getAttribute('data-lb-muted'), 22131 // Uncode edit ##END## 22132 }); 22133 // Automatically navigate to next slide once video reaches the end. 22134 this.gotoNextSlideOnVideoEnd(src, index); 22135 } 22136 }; 22137 /** 22138 * @desc fired immediately before each slide transition. 22139 * Pause the previous video 22140 * Hide the download button if the slide contains YouTube, Vimeo, or Wistia videos. 22141 * 22142 * @param {Event} event - Javascript Event object. 22143 * @param {number} prevIndex - Previous index of the slide. 22144 * @param {number} index - Current index of the slide 22145 */ 22146 Video.prototype.onBeforeSlide = function (event) { 22147 if (this.core.lGalleryOn) { 22148 var prevIndex = event.detail.prevIndex; 22149 this.pauseVideo(prevIndex); 22150 } 22151 // Uncode edit ##START## 22152 var _a = event.detail, index = _a.index; 22153 var $slide = this.core.getSlideItem(index); 22154
22155 var iframe = $slide.selector.querySelector('iframe'); 22156 if ( iframe != null ) { 22157 22158 var data_play = iframe.getAttribute('data-autoplay'); 22159 if ( typeof data_play !== 'undefined' && data_play === '1' ) { 22160 this.loadAndPlayVideo(index); 22161 22162 var videoInfo = this.core.galleryItems[index].__slideVideoInfo || {}, 22163 $videoElement = this.core.getSlideItem(index).find('.lg-video-object').first(); 22164 if (videoInfo.vimeo) { 22165 var vimeoPlayer = new Vimeo.Player($videoElement.get()); 22166 vimeoPlayer.on('play', function () { 22167 vimeoPlayer.setCurrentTime(0); 22168 }); 22169 } else if ( videoInfo.youtube ) { 22170 try { 22171 $videoElement.get().contentWindow.postMessage("{\"event\":\"command\",\"func\":\"seekTo\",\"args\":[0, true]}", '*'); 22172 } 22173 catch (e) { 22174 console.warn(e); 22175 } 22176 } 22177 } 22178 } 22179 // Uncode edit ##END## 22180 }; 22181 /** 22182 * @desc fired immediately after each slide transition. 22183 * Play video if autoplayVideoOnSlide option is enabled. 22184 * 22185 * @param {Event} event - Javascript Event object. 22186 * @param {number} prevIndex - Previous index of the slide. 22187 * @param {number} index - Current index of the slide 22188 * @todo should check on onSlideLoad as well if video is not loaded on after slide 22189 */ 22190 Video.prototype.onAfterSlide = function (event) { 22191 var _this = this; 22192 var _a = event.detail, index = _a.index, prevIndex = _a.prevIndex; 22193 // Do not call on first slide 22194 var $slide = this.core.getSlideItem(index); 22195 if (this.settings.autoplayVideoOnSlide && index !== prevIndex) { 22196 if ($slide.hasClass('lg-complete')) { 22197 setTimeout(function () { 22198 _this.loadAndPlayVideo(index); 22199 }, 100); 22200 } 22201 } 22202 }; 22203 Video.prototype.loadAndPlayVideo = function (index) { 22204 var $slide = this.core.getSlideItem(index); 22205 var currentGalleryItem = this.core.galleryItems[index]; 22206 if (currentGalleryItem.poster) { 22207 this.loadVideoOnPosterClick($slide, true); 22208 } 22209 else { 22210 //Uncode edit ##START## 22211 // this.playVideo(index); 22212 var iframe = $slide.selector.querySelector('iframe'); 22213 if ( iframe != null ) { 22214 var data_play = iframe.getAttribute('data-autoplay'); 22215 if ( typeof data_play !== 'undefined' ) { 22216 if ( data_play === '1' && this.core.index == index ) { 22217 this.playVideo(index); 22218 } else { 22219 this.pauseVideo(index); 22220 } 22221 } 22222 } 22223 //Uncode edit ##END## 22224 } 22225 }; 22226 /** 22227 * Play HTML5, Youtube, Vimeo or Wistia videos in a particular slide. 22228 * @param {number} index - Index of the slide 22229 */ 22230 Video.prototype.playVideo = function (index) { 22231 this.controlVideo(index, 'play'); 22232 }; 22233 /** 22234 * Pause HTML5, Youtube, Vimeo or Wistia videos in a particular slide. 22235 * @param {number} index - Index of the slide 22236 */ 22237 Video.prototype.pauseVideo = function (index) { 22238 this.controlVideo(index, 'pause'); 22239 }; 22240 // Uncode edit ##START## 22241 //Video.prototype.getVideoHtml = function (src, addClass, index, html5Video) { 22242 Video.prototype.getVideoHtml = function (src, addClass, index, html5Video, autoplay, muted) { 22243 // Uncode edit ##END## 22244 var video = ''; 22245 var videoInfo = this.core.galleryItems[index] 22246 .__slideVideoInfo || {}; 22247 var currentGalleryItem = this.core.galleryItems[index]; 22248 var videoTitle = currentGalleryItem.title || currentGalleryItem.alt; 22249 videoTitle = videoTitle ? 'title="' + videoTitle + '"' : ''; 22250 var commonIframeProps = "allowtransparency=\"true\"\n frameborder=\"0\"\n scrolling=\"no\"\n allowfullscreen\n mozallowfullscreen\n webkitallowfullscreen\n oallowfullscreen\n msallowfullscreen"; 22251 if (videoInfo.youtube) { 22252 var videoId = 'lg-youtube' + index; 22253 var slideUrlParams = videoInfo.youtube[2] 22254 ? videoInfo.youtube[2] + '&' 22255 : ''; 22256 // For youtube first parms gets priority if duplicates found 22257 // Uncode edit ##START## 22258 // var youTubePlayerParams = "?" + slideUrlParams + "wmode=opaque&autoplay=0&mute=1&enablejsapi=1"; 22259 var youTubePlayerParams = "?" + slideUrlParams + "wmode=opaque&enablejsapi=1"; 22260 if ( ( slideUrlParams.indexOf('autoplay=') < 0 && youTubePlayerParams.indexOf('autoplay=') < 0 ) ) { 22261 youTubePlayerParams += '&autoplay=0'; 22262 } 22263 if ( slideUrlParams.indexOf('mute=') < 0 && youTubePlayerParams.indexOf('mute=') < 0 ) { 22264 youTubePlayerParams += '&mute=1'; 22265 } 22266 var data_video = ''; 22267 if ( autoplay !== '' ) { 22268 //youTubePlayerParams = youTubePlayerParams.replace(new RegExp('([?&])autoplay=(.*?)(&|$)'), '$1autoplay=' + (autoplay === 'yes' ? 1 : 0) + '$3' ); 22269 youTubePlayerParams = youTubePlayerParams.replace(new RegExp('([?&])autoplay=(.*?)(&|$)'), '$1$3' ); 22270 youTubePlayerParams = youTubePlayerParams.replace(new RegExp('([?&])autoplay'), '$1' ); 22271 data_video = ' data-autoplay="' + (autoplay === 'yes' ? 1 : 0) + '"'; 22272 } 22273 // if ( muted !== '' ) { 22274 // youTubePlayerParams = youTubePlayerParams.replace(new RegExp('([?&])mute=(.*?)(&|$)'), '$1mute=' + (muted === 'yes' ? 1 : 0) + '$3' ); 22275 // } 22276 youTubePlayerParams = youTubePlayerParams.replace(new RegExp('([?&])mute=(.*?)(&|$)'), '$1$3' ); 22277 22278 youTubePlayerParams = youTubePlayerParams.replace('??', '?'); 22279 // Uncode edit ##END## 22280 var playerParams = youTubePlayerParams + 22281 (this.settings.youTubePlayerParams 22282 ? '&' + param(this.settings.youTubePlayerParams) 22283 : ''); 22284 // Uncode edit ##START## 22285 // 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>"; 22286 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>"; 22287 var tag = document.createElement('script'); 22288 tag.src = "//www.youtube.com/player_api"; 22289 var firstScriptTag = document.getElementsByTagName('script')[0]; 22290 firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); 22291 22292 // Replace the 'ytplayer' element with an <iframe> and 22293 // YouTube player after the API code downloads. 22294 var ytIframeplayer, 22295 setMute = muted === 'yes' ? 0 : 100; 22296 window.onYouTubePlayerAPIReady = function() { 22297 ytIframeplayer = new YT.Player(videoId, { 22298 videoId: videoInfo.youtube[1], 22299 events: { 22300 'onReady': function (event) { 22301 event.target.setVolume(setMute); 22302 } 22303 } 22304 }); 22305 } 22306 // Uncode edit ##END## 22307 } 22308 else if (videoInfo.vimeo) { 22309 var videoId = 'lg-vimeo' + index; 22310 // Uncode edit ##START## 22311 videoInfo.autoplay = autoplay; 22312 videoInfo.muted = muted; 22313 // Uncode edit ##END## 22314 var playerParams = getVimeoURLParams(this.settings.vimeoPlayerParams, videoInfo); 22315 // Uncode edit ##START## 22316 // 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>"; 22317 var data_video = ''; 22318 if ( autoplay !== '' ) { 22319 data_video = ' data-autoplay="' + (autoplay === 'yes' ? 1 : 0) + '"'; 22320 } 22321 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>"; 22322 // Uncode edit ##END## 22323 } 22324 else if (videoInfo.wistia) { 22325 var wistiaId = 'lg-wistia' + index; 22326 var playerParams = param(this.settings.wistiaPlayerParams); 22327 playerParams = playerParams ? '?' + playerParams : ''; 22328 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>"; 22329 } 22330 else if (videoInfo.html5) { 22331 var html5VideoMarkup = ''; 22332 for (var i = 0; i < html5Video.source.length; i++) { 22333 html5VideoMarkup += "<source src=\"" + html5Video.source[i].src + "\" type=\"" + html5Video.source[i].type + "\">"; 22334 } 22335 if (html5Video.tracks) { 22336 var _loop_1 = function (i) { 22337 var trackAttributes = ''; 22338 var track = html5Video.tracks[i]; 22339 Object.keys(track || {}
22339).forEach(function (key) { 22340 trackAttributes += key + "=\"" + track[key] + "\" "; 22341 }); 22342 html5VideoMarkup += "<track " + trackAttributes + ">"; 22343 }; 22344 for (var i = 0; i < html5Video.tracks.length; i++) { 22345 _loop_1(i); 22346 } 22347 } 22348 var html5VideoAttrs_1 = ''; 22349 var videoAttributes_1 = html5Video.attributes || {}; 22350 Object.keys(videoAttributes_1 || {}).forEach(function (key) { 22351 html5VideoAttrs_1 += key + "=\"" + videoAttributes_1[key] + "\" "; 22352 }); 22353 video = "<video class=\"lg-video-object lg-html5 " + (this.settings.videojs && this.settings.videojsTheme 22354 ? this.settings.videojsTheme + ' ' 22355 : '') + " " + (this.settings.videojs ? ' video-js' : '') + "\" " + html5VideoAttrs_1 + ">\n " + html5VideoMarkup + "\n Your browser does not support HTML5 video.\n </video>"; 22356 } 22357 return video; 22358 }; 22359 /** 22360 * @desc - Append videos to the slide 22361 * 22362 * @param {HTMLElement} el - slide element 22363 * @param {Object} videoParams - Video parameters, Contains src, class, index, htmlVideo 22364 */ 22365 Video.prototype.appendVideos = function (el, videoParams) { 22366 var _a; 22367 // Uncode edit ##START## 22368 // var videoHtml = this.getVideoHtml(videoParams.src, videoParams.addClass, videoParams.index, videoParams.html5Video); 22369 var videoHtml = this.getVideoHtml(videoParams.src, videoParams.addClass, videoParams.index, videoParams.html5Video, videoParams.autoplay, videoParams.muted); 22370 // Uncode edit ##END## 22371 el.find('.lg-video-cont').append(videoHtml); 22372 var $videoElement = el.find('.lg-video-object').first(); 22373 if (videoParams.html5Video) { 22374 $videoElement.on('mousedown.lg.video', function (e) { 22375 e.stopPropagation(); 22376 }); 22377 } 22378 if (this.settings.videojs && ((_a = this.core.galleryItems[videoParams.index].__slideVideoInfo) === null || _a === void 0 ? void 0 : _a.html5)) { 22379 try { 22380 return videojs($videoElement.get(), this.settings.videojsOptions); 22381 } 22382 catch (e) { 22383 console.warn('lightGallery:- Make sure you have included videojs'); 22384 } 22385 } 22386 }; 22387 Video.prototype.gotoNextSlideOnVideoEnd = function (src, index) { 22388 var _this = this; 22389 var $videoElement = this.core 22390 .getSlideItem(index) 22391 .find('.lg-video-object') 22392 .first(); 22393 var videoInfo = this.core.galleryItems[index].__slideVideoInfo || {}; 22394 if (this.settings.gotoNextSlideOnVideoEnd) { 22395 if (videoInfo.html5) { 22396 $videoElement.on('ended', function () { 22397 _this.core.goToNextSlide(); 22398 }); 22399 } 22400 else if (videoInfo.vimeo) { 22401 try { 22402 // https://github.com/vimeo/player.js/#ended 22403 new Vimeo.Player($videoElement.get()).on('ended', function () { 22404 _this.core.goToNextSlide(); 22405 }); 22406 } 22407 catch (e) { 22408 console.warn('lightGallery:- Make sure you have included //github.com/vimeo/player.js'); 22409 } 22410 } 22411 else if (videoInfo.wistia) { 22412 try { 22413 window._wq = window._wq || []; 22414 // @todo Event is gettign triggered multiple times 22415 window._wq.push({ 22416 id: $videoElement.attr('id'), 22417 onReady: function (video) { 22418 video.bind('end', function () { 22419 _this.core.goToNextSlide(); 22420 }); 22421 }, 22422 }); 22423 } 22424 catch (e) { 22425 console.warn('lightGallery:- Make sure you have included //fast.wistia.com/assets/external/E-v1.js'); 22426 } 22427 } 22428 } 22429 }; 22430 Video.prototype.controlVideo = function (index, action) { 22431 var $videoElement = this.core 22432 .getSlideItem(index) 22433 .find('.lg-video-object') 22434 .first(); 22435 var videoInfo = this.core.galleryItems[index].__slideVideoInfo || {}; 22436 if (!$videoElement.get()) 22437 return; 22438 if (videoInfo.youtube) { 22439 try { 22440 $videoElement.get().contentWindow.postMessage("{\"event\":\"command\",\"func\":\"" + action + "Video\",\"args\":\"\"}", '*'); 22441 } 22442 catch (e) { 22443 console.warn("lightGallery:- " + e); 22444 } 22445 } 22446 else if (videoInfo.vimeo) { 22447 try { 22448 new Vimeo.Player($videoElement.get())[action](); 22449 } 22450 catch (e) { 22451 console.warn('lightGallery:- Make sure you have included //github.com/vimeo/player.js'); 22452 } 22453 } 22454 else if (videoInfo.html5) { 22455 if (this.settings.videojs) { 22456 try { 22457 videojs($videoElement.get())[action](); 22458 } 22459 catch (e) { 22460 console.warn('lightGallery:- Make sure you have included videojs'); 22461 } 22462 } 22463 else { 22464 $videoElement.get()[action](); 22465 } 22466 } 22467 else if (videoInfo.wistia) { 22468 try { 22469 window._wq = window._wq || []; 22470 // @todo Find a way to destroy wistia player instance 22471 window._wq.push({ 22472 id: $videoElement.attr('id'), 22473 onReady: function (video) { 22474 video[action](); 22475 }, 22476 }); 22477 } 22478 catch (e) { 22479 console.warn('lightGallery:- Make sure you have included //fast.wistia.com/assets/external/E-v1.js'); 22480 } 22481 } 22482 }; 22483 Video.prototype.loadVideoOnPosterClick = function ($el, forcePlay) { 22484 var _this = this; 22485 // check slide has poster 22486 if (!$el.hasClass('lg-video-loaded')) { 22487 // check already video element present
22488 if (!$el.hasClass('lg-has-video')) { 22489 $el.addClass('lg-has-video'); 22490 var _html = void 0; 22491 var _src = this.core.galleryItems[this.core.index].src; 22492 var video = this.core.galleryItems[this.core.index].video; 22493 if (video) { 22494 _html = 22495 typeof video === 'string' ? JSON.parse(video) : video; 22496 } 22497 var videoJsPlayer_1 = this.appendVideos($el, { 22498 src: _src, 22499 addClass: '', 22500 index: this.core.index, 22501 html5Video: _html, 22502 }); 22503 this.gotoNextSlideOnVideoEnd(_src, this.core.index); 22504 var $tempImg = $el.find('.lg-object').first().get(); 22505 // @todo make sure it is working 22506 $el.find('.lg-video-cont').first().append($tempImg); 22507 $el.addClass('lg-video-loading'); 22508 videoJsPlayer_1 && 22509 videoJsPlayer_1.ready(function () { 22510 videoJsPlayer_1.on('loadedmetadata', function () { 22511 _this.onVideoLoadAfterPosterClick($el, _this.core.index); 22512 }); 22513 }); 22514 $el.find('.lg-video-object') 22515 .first() 22516 .on('load.lg error.lg loadedmetadata.lg', function () { 22517 setTimeout(function () { 22518 _this.onVideoLoadAfterPosterClick($el, _this.core.index); 22519 }, 50); 22520 }); 22521 } 22522 else { 22523 this.playVideo(this.core.index); 22524 } 22525 } 22526 else if (forcePlay) { 22527 this.playVideo(this.core.index); 22528 } 22529 }; 22530 Video.prototype.onVideoLoadAfterPosterClick = function ($el, index) { 22531 $el.addClass('lg-video-loaded'); 22532 this.playVideo(index); 22533 }; 22534 Video.prototype.destroy = function () { 22535 this.core.LGel.off('.lg.video'); 22536 this.core.LGel.off('.video'); 22537 }; 22538 return Video; 22539 }()); 22540 22541 return Video; 22542 22543}))); 22544 22545 22546/*! @vimeo/player v2.17.1 | (c) 2022 Vimeo | MIT License | https://github.com/vimeo/player.js */ 22547!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:{}}
22547),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 22547
22547var 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)}
22547},{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 22547-23754
22547))}(),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}); 22548 22549/** 22550 * Owl carousel 22551 * @version 2.0.0-beta.3 22552 * @author Bartosz Wojciechowski 22553 * @license The MIT License (MIT) 22554 * @todo Lazy Load Icon 22555 * @todo prevent animationend bubling 22556 * @todo itemsScaleUp 22557 * @todo Test Zepto 22558 * @todo stagePadding calculate wrong active classes 22559 */ 22560;(function($, window, document, undefined) { 22561 22562 /** 22563 * Creates a carousel. 22564 * @class The Owl Carousel. 22565 * @public 22566 * @param {HTMLElement|jQuery} element - The element to create the carousel for. 22567 * @param {Object} [options] - The options 22568 */ 22569 function Owl(element, options) { 22570 22571 /** 22572 * Current settings for the carousel. 22573 * @public 22574 */ 22575 this.settings = null; 22576 22577 /** 22578 * Current options set by the caller including defaults. 22579 * @public 22580 */ 22581 this.options = $.extend({}, Owl.Defaults, options); 22582 22583 /** 22584 * Plugin element. 22585 * @public 22586 */ 22587 this.$element = $(element); 22588 22589 /** 22590 * Proxied event handlers. 22591 * @protected 22592 */ 22593 this._handlers = {}; 22594 22595 /** 22596 * References to the running plugins of this carousel. 22597 * @protected 22598 */ 22599 this._plugins = {}; 22600 22601 /** 22602 * Currently suppressed events to prevent them from beeing retriggered. 22603 * @protected 22604 */ 22605 this._supress = {}; 22606 22607 /** 22608 * Absolute current position. 22609 * @protected 22610 */ 22611 this._current = null; 22612 22613 /** 22614 * Animation speed in milliseconds. 22615 * @protected 22616 */ 22617 this._speed = null; 22618 22619 /** 22620 * Coordinates of all items in pixel. 22621 * @todo The name of this member is missleading. 22622 * @protected 22623 */ 22624 this._coordinates = []; 22625 22626 /** 22627 * Current breakpoint. 22628 * @todo Real media queries would be nice. 22629 * @protected 22630 */ 22631 this._breakpoint = null; 22632 22633 /** 22634 * Current width of the plugin element. 22635 */ 22636 this._width = null; 22637 22638 /** 22639 * All real items. 22640 * @protected 22641 */ 22642 this._items = []; 22643 22644 /** 22645 * All cloned items. 22646 * @protected 22647 */ 22648 this._clones = []; 22649 22650 /** 22651 * Merge values of all items. 22652 * @todo Maybe this could be part of a plugin. 22653 * @protected 22654 */ 22655 this._mergers = []; 22656 22657 /** 22658 * Widths of all items. 22659 */ 22660 this._widths = []; 22661 22662 /** 22663 * Invalidated parts within the update process. 22664 * @protected 22665 */ 22666 this._invalidated = {}; 22667 22668 /** 22669 * Ordered list of workers for the update process. 22670 * @protected 22671 */ 22672 this._pipe = []; 22673 22674 /** 22675 * Current state information for the drag operation. 22676 * @todo #261 22677 * @protected 22678 */ 22679 this._drag = { 22680 time: null, 22681 target: null, 22682 pointer: null, 22683 stage: { 22684 start: null, 22685 current: null 22686 }, 22687 direction: null 22688 }; 22689 22690 /** 22691 * Current state information and their tags. 22692 * @type {Object} 22693 * @protected 22694 */ 22695 this._states = { 22696 current: {}, 22697 tags: { 22698 'initializing': [ 'busy' ], 22699 'animating': [ 'busy' ], 22700 'dragging': [ 'interacting' ] 22701 } 22702 }; 22703 22704 $.each([ 'onResize', 'onThrottledResize' ], $.proxy(function(i, handler) { 22705 this._handlers[handler] = $.proxy(this[handler], this); 22706 }, this)); 22707 22708 $.each(Owl.Plugins, $.proxy(function(key, plugin) { 22709 this._plugins[key.charAt(0).toLowerCase() + key.slice(1)] 22710 = new plugin(this); 22711 }, this)); 22712 22713 $.each(Owl.Workers, $.proxy(function(priority, worker) { 22714 this._pipe.push({ 22715 'filter': worker.filter, 22716 'run': $.proxy(worker.run, this) 22717 }); 22718 }, this)); 22719 22720 this.setup(); 22721 this.initialize(); 22722 } 22723 22724 /** 22725 * Default options for the carousel. 22726 * @public 22727 */ 22728 Owl.Defaults = { 22729 items: 3, 22730 loop: false, 22731 center: false, 22732 rewind: false, 22733 22734 mouseDrag: true, 22735 touchDrag: true, 22736 pullDrag: true, 22737 freeDrag: false, 22738 22739 margin: 0, 22740 stagePadding: 0, 22741 22742 merge: false, 22743 mergeFit: true, 22744 autoWidth: false, 22745 22746 startPosition: 0, 22747 rtl: false, 22748 22749 smartSpeed: 250, 22750 fluidSpeed: false, 22751 dragEndSpeed: false, 22752 22753 responsive: {}, 22754 responsiveRefreshRate: 200, 22755 responsiveBaseElement: window, 22756 22757 fallbackEasing: 'swing', 22758 22759 info: false, 22760 22761 nestedItemSelector: false, 22762 itemElement: 'div', 22763 stageElement: 'div', 22764 22765 refreshClass: 'owl-refresh', 22766 loadedClass: 'owl-loaded', 22767 loadingClass: 'owl-loading', 22768 rtlClass: 'owl-rtl', 22769 responsiveClass: 'owl-responsive', 22770 dragClass: 'owl-drag', 22771 itemClass: 'owl-item', 22772 stageClass: 'owl-stage', 22773 stageOuterClass: 'owl-stage-outer', 22774 grabClass: 'owl-grab' 22775 }; 22776 22777 /** 22778 * Enumeration for width. 22779 * @public 22780 * @readonly 22781 * @enum {String} 22782 */ 22783 Owl.Width = { 22784 Default: 'default', 22785 Inner: 'inner', 22786 Outer: 'outer' 22787 }; 22788 22789 /** 22790 * Enumeration for types. 22791 * @public 22792 * @readonly 22793 * @enum {String} 22794 */ 22795 Owl.Type = { 22796 Event: 'event', 22797 State: 'state' 22798 }; 22799 22800 /** 22801 * Contains all registered plugins. 22802 * @public 22803 */ 22804 Owl.Plugins = {}; 22805 22806 /** 22807 * List of workers involved in the update process. 22808 */ 22809 Owl.Workers = [ { 22810 filter: [ 'width', 'settings' ], 22811 run: function() { 22812 this._width = (this.$element.closest('.px-gutter').length) ? 12 * Math.ceil(this.$element.width() / 12) : this.$element.width(); 22813 //this._width = (UNCODE.isMobile) ? this.$element.width() : 12 * Math.ceil(this.$element.width() / 12); 22814 } 22815 }, { 22816 filter: [ 'width', 'items', 'settings' ], 22817 run: function(cache) { 22818 cache.current = this._items && this._items[this.relative(this._current)]; 22819 } 22820 }, { 22821 filter: [ 'items', 'settings' ], 22822 run: function() { 22823 this.$stage.children('.cloned').remove(); 22824 } 22825 }, { 22826 filter: [ 'width', 'items', 'settings' ], 22827 run: function(cache) { 22828 var margin = this.settings.margin || '', 22829 grid = !this.settings.autoWidth, 22830 rtl = this.settings.rtl, 22831 css = { 22832 'width': 'auto', 22833 'margin-left': rtl ? margin : '', 22834 'margin-right': rtl ? '' : margin 22835 }; 22836 22837 !grid && this.$stage.children().css(css); 22838 22839 cache.css = css; 22840 } 22841 }, { 22842 filter: [ 'width', 'items', 'settings' ], 22843 run: function(cache) { 22844 //UNCODE edit to fix Chrome stage padding issue 22845 var width = Math.round((this.width() / this.settings.items).toFixed(3) - this.settings.margin), 22846 merge = null, 22847 iterator = this._items.length, 22848 grid = !this.settings.autoWidth, 22849 widths = []; 22850 22851 cache.items = { 22852 merge: false, 22853 width: width 22854 }; 22855 22856 while (iterator--) { 22857 merge = this._mergers[iterator]; 22858 merge = this.settings.mergeFit && Math.min(merge, this.settings.items) || merge; 22859 22860 cache.items.merge = merge > 1 || cache.items.merge; 22861 22862 widths[iterator] = !grid ? this._items[iterator].width() : width * merge; 22863 } 22864 22865 this._widths = widths; 22866 } 22867 }, { 22868 filter: [ 'items', 'settings' ], 22869 run: function() { 22870 var clones = [], 22871 items = this._items, 22872 settings = this.settings, 22873 view = Math.max(settings.items * 2, 4), 22874 size = Math.ceil(items.length / 2) * 2, 22875 repeat = settings.loop && items.length ? settings.rewind ? view : Math.max(view, size) : 0, 22876 append = '', 22877 prepend = ''; 22878 22879 repeat /= 2; 22880 22881 while (repeat--) { 22882 clones.push(this.normalize(clones.length / 2, true)); 22883 append = append + items[clones[clones.length - 1]][0].outerHTML; 22884 clones.push(this.normalize(items.length - 1 - (clones.length - 1) / 2, true)); 22885 prepend = items[clones[clones.length - 1]][0].outerHTML + prepend; 22886 } 22887 22888 this._clones = clones; 22889 22890 // var appendVideo = $(append).find('.uncode-video-container'); 22891 // if (appendVideo.length) { 22892 // appendVideo.attr('data-id', Math.round(Math.random() * 100000)); 22893 // } 22894 // var prependVideo = $(prepend).find('.uncode-video-container'); 22895 // if (prependVideo.length) { 22896 // prependVideo.attr('data-id', Math.round(Math.random() * 100000)); 22897 // } 22898 $(append).addClass('cloned').appendTo(this.$stage); 22899 $(prepend).addClass('cloned').prependTo(this.$stage); 22900 } 22901 }, { 22902 filter: [ 'width', 'items', 'settings' ], 22903 run: function() { 22904 var rtl = this.settings.rtl ? 1 : -1, 22905 size = this._clones.length + this._items.length, 22906 iterator = -1, 22907 previous = 0, 22908 current = 0, 22909 coordinates = []; 22910 22911 while (++iterator < size) { 22912 previous = coordinates[iterator - 1] || 0; 22913 current = this._widths[this.relative(iterator)] + this.settings.margin; 22914 coordinates.push(previous + current * rtl); 22915 } 22916 22917 this._coordinates = coordinates; 22918 } 22919 }, { 22920 filter: [ 'width', 'items', 'settings' ], 22921 run: function() { 22922 var stagePadding = (this._width < 480 && this.settings.stagePadding > 0) ? 41 : (this._width * this.settings.stagePadding) / 200, 22923 padding = stagePadding, 22924 coordinates = this._coordinates, 22925 css = { 22926 'width': Math.ceil(Math.abs(coordinates[coordinates.length - 1])) + padding * 2, 22927 'padding-left': padding || '', 22928 'padding-right': padding || '' 22929 }; 22930 22931 this.$stage.css(css); 22932 } 22933 }, { 22934 filter: [ 'width', 'items', 'settings' ], 22935 run: function(cache) { 22936 var iterator = this._coordinates.length, 22937 grid = !this.settings.autoWidth, 22938 items = this.$stage.children(); 22939 22940 if (grid && cache.items.merge) { 22941 while (iterator--) { 22942 cache.css.width = this._widths[this.relative(iterator)]; 22943 items.eq(iterator).css(cache.css); 22944 } 22945 } else if (grid) { 22946 cache.css.width = cache.items.width; 22947 items.css(cache.css); 22948 } 22949 } 22950 }, { 22951 filter: [ 'items' ], 22952 run: function() { 22953 this._coordinates.length < 1 && this.$stage.removeAttr('style'); 22954 } 22955 }, { 22956 filter: [ 'width', 'items', 'settings' ], 22957 run: function(cache) { 22958 cache.current = cache.current ? this.$stage.children().index(cache.current) : 0; 22959 cache.current = Math.max(this.minimum(), Math.min(this.maximum(), cache.current)); 22960 this.reset(cache.current); 22961 } 22962 }, { 22963 filter: [ 'position' ], 22964 run: function() { 22965 this.animate(this.coordinates(this._current)); 22966 } 22967 }, { 22968 filter: [ 'width', 'position', 'items', 'settings' ], 22969 run: function() { 22970 var stagePadding = (this._width < 480 && this.settings.stagePadding > 0) ? 41 : (this._width * this.settings.stagePadding) / 200, 22971 rtl = this.settings.rtl ? 1 : -1, 22972 padding = this.settings.stagePadding * 2, 22973 begin = this.coordinates(this.current()) + padding, 22974 end = begin + this.width() * rtl, 22975 inner, outer, matches = [], i, n; 22976 22977 for (i = 0, n = this._coordinates.length; i < n; i++) { 22978 inner = this._coordinates[i - 1] || 0; 22979 outer = Math.abs(this._coordinates[i]) + padding * rtl; 22980 22981 if ((this.op(inner, '<=', begin) && (this.op(inner, '>', end))) 22982 || (this.op(outer, '<', begin) && this.op(outer, '>', end))) { 22983 matches.push(i); 22984 } 22985 } 22986 22987 this.$stage.children('.active').removeClass('active'); 22988 this.$stage.children(':eq(' + matches.join('), :eq(') + ')').addClass('active'); 22989 22990 if (this.settings.center) { 22991 this.$stage.children('.center').removeClass('center'); 22992 this.$stage.children().eq(this.current()).addClass('center'); 22993 } 22994 } 22995 } ]; 22996 22997 /** 22998 * Initializes the carousel. 22999 * @protected 23000 */ 23001 Owl.prototype.initialize = function() { 23002 this.enter('initializing'); 23003 this.trigger('initialize'); 23004 23005 this.$element.toggleClass(this.settings.rtlClass, this.settings.rtl); 23006 23007 if (this.settings.autoWidth && !this.is('pre-loading')) { 23008 var imgs, nestedSelector, width; 23009 imgs = this.$element.find('img'); 23010 nestedSelector = this.settings.nestedItemSelector ? '.' + this.settings.nestedItemSelector : undefined; 23011 width = this.$element.children(nestedSelector).width(); 23012 23013 if (imgs.length && width <= 0) { 23014 this.preloadAutoWidthImages(imgs); 23015 } 23016 } 23017 23018 this.$element.addClass(this.options.loadingClass); 23019 23020 // create stage 23021 this.$stage = $('<' + this.settings.stageElement + ' class="' + this.settings.stageClass + '"/>') 23022 .wrap('<div class="' + this.settings.stageOuterClass + '"/>'); 23023 23024 // append stage 23025 this.$element.append(this.$stage.parent()); 23026 23027 // append content 23028 this.replace(this.$element.children().not(this.$stage.parent())); 23029 23030 // check visibility 23031 if (this.$element.is(':visible')) { 23032 // update view 23033 this.refresh(); 23034 } else { 23035 // invalidate width 23036 this.invalidate('width'); 23037 } 23038 23039 this.$element 23040 .removeClass(this.options.loadingClass) 23041 .addClass(this.options.loadedClass); 23042 23043 // register event handlers 23044 this.registerEventHandlers(); 23045 23046 this.leave('initializing'); 23047 this.trigger('initialized'); 23048 }; 23049 23050 /** 23051 * Setups the current settings. 23052 * @todo Remove responsive classes. Why should adaptive designs be brought into IE8? 23053 * @todo Support for media queries by using `matchMedia` would be nice. 23054 * @public 23055 */ 23056 Owl.prototype.setup = function() { 23057 var viewport = this.viewport(), 23058 overwrites = this.options.responsive, 23059 match = -1, 23060 settings = null; 23061 23062 if (!overwrites) { 23063 settings = $.extend({}, this.options); 23064 } else { 23065 $.each(overwrites, function(breakpoint) { 23066 if (breakpoint <= viewport && breakpoint > match) { 23067 match = Number(breakpoint); 23068 } 23069 }); 23070 23071 settings = $.extend({}, this.options, overwrites[match]); 23072 delete settings.responsive; 23073 23074 // responsive class 23075 if (settings.responsiveClass) { 23076 this.$element.attr('class', 23077 this.$element.attr('class').replace(new RegExp('(' + this.options.responsiveClass + '-)\\S+\\s', 'g'), '$1' + match) 23078 ); 23079 } 23080 } 23081 23082 if (this.settings === null || this._breakpoint !== match) { 23083 this.trigger('change', { property: { name: 'settings', value: settings } }); 23084 this._breakpoint = match; 23085 this.settings = settings; 23086 this.invalidate('settings'); 23087 this.trigger('changed', { property: { name: 'settings', value: this.settings } }); 23088 } 23089 }; 23090 23091 /** 23092 * Updates option logic if necessery. 23093 * @protected 23094 */ 23095 Owl.prototype.optionsLogic = function() { 23096 if (this.settings.autoWidth) { 23097 this.settings.stagePadding = false; 23098 this.settings.merge = false; 23099 } 23100 }; 23101 23102 /** 23103 * Prepares an item before add. 23104 * @todo Rename event parameter `content` to `item`. 23105 * @protected 23106 * @returns {jQuery|HTMLElement} - The item container. 23107 */ 23108 Owl.prototype.prepare = function(item, index) { 23109 var event = this.trigger('prepare', { content: item }); 23110 if (!event.data) { 23111 event.data = $('<' + this.settings.itemElement + '/>') 23112 .addClass(this.options.itemClass).attr('data-index', index + 1).append(item) 23113 } 23114 23115 this.trigger('prepared', { content: event.data }); 23116 23117 return event.data; 23118 }; 23119 23120 /** 23121 * Updates the view. 23122 * @public 23123 */ 23124 Owl.prototype.update = function() { 23125 var i = 0, 23126 n = this._pipe.length, 23127 filter = $.proxy(function(p) { return this[p] }, this._invalidated), 23128 cache = {}; 23129 23130 while (i < n) { 23131 if (this._invalidated.all || $.grep(this._pipe[i].filter, filter).length > 0) { 23132 this._pipe[i].run(cache); 23133 } 23134 i++; 23135 } 23136 23137 this._invalidated = {}; 23138 23139 !this.is('valid') && this.enter('valid'); 23140 }; 23141 23142 /** 23143 * Gets the width of the view. 23144 * @public 23145 * @param {Owl.Width} [dimension=Owl.Width.Default] - The dimension to return. 23146 * @returns {Number} - The width of the view in pixel. 23147 */ 23148 Owl.prototype.width = function(dimension) { 23149 dimension = dimension || Owl.Width.Default; 23150 var stagePadding = (this._width < 480 && this.settings.stagePadding > 0) ? 41 : (this._width * this.settings.stagePadding) / 200; 23151 switch (dimension) { 23152 case Owl.Width.Inner: 23153 case Owl.Width.Outer: 23154 return this._width; 23155 default: 23156 return this._width - stagePadding * 2 + this.settings.margin; 23157 } 23158 }; 23159 23160 /** 23161 * Refreshes the carousel primarily for adaptive purposes. 23162 * @public 23163 */ 23164 Owl.prototype.refresh = function() { 23165 this.enter('refreshing'); 23166 this.trigger('refresh'); 23167 23168 this.setup(); 23169 23170 this.optionsLogic(); 23171 23172 this.$element.addClass(this.options.refreshClass); 23173 23174 this.update(); 23175 23176 this.$element.removeClass(this.options.refreshClass); 23177 23178 this.leave('refreshing'); 23179 this.trigger('refreshed'); 23180 }; 23181 23182 /** 23183 * Checks window `resize` event. 23184 * @protected 23185 */ 23186 Owl.prototype.onThrottledResize = function() { 23187 window.clearTimeout(this.resizeTimer); 23188 this.resizeTimer = window.setTimeout(this._handlers.onResize, this.settings.responsiveRefreshRate); 23189 }; 23190 23191 /** 23192 * Checks window `resize` event. 23193 * @protected 23194 */ 23195 Owl.prototype.onResize = function() { 23196 if (!this._items.length) { 23197 return false; 23198 } 23199 23200 if (this._width === this.$element.width()) { 23201 return false; 23202 } 23203 23204 if (!this.$element.is(':visible')) { 23205 return false; 23206 } 23207 23208 this.enter('resizing'); 23209 23210 if (this.trigger('resize').isDefaultPrevented()) { 23211 this.leave('resizing'); 23212 return false; 23213 } 23214 23215 this.invalidate('width'); 23216 23217 this.refresh(); 23218 23219 this.leave('resizing'); 23220 this.trigger('resized'); 23221 }; 23222 23223 /** 23224 * Registers event handlers. 23225 * @todo Check `msPointerEnabled` 23226 * @todo #261 23227 * @protected 23228 */ 23229 Owl.prototype.registerEventHandlers = function() { 23230 if ($.support.transition) { 23231 this.$stage.on($.support.transition.end + '.owl.core', $.proxy(this.onTransitionEnd, this)); 23232 } 23233 23234 if (this.settings.responsive !== false) { 23235 this.on(window, 'resize', this._handlers.onThrottledResize); 23236 } 23237 23238 if (this.settings.mouseDrag) { 23239 this.$element.addClass(this.options.dragClass); 23240 this.$stage.on('mousedown.owl.core', $.proxy(this.onDragStart, this)); 23241 this.$stage.on('dragstart.owl.core selectstart.owl.core', function() { return false }); 23242 } 23243 23244 if (this.settings.touchDrag){ 23245 this.$stage.on('touchstart.owl.core', $.proxy(this.onDragStart, this)); 23246 this.$stage.on('touchcancel.owl.core', $.proxy(this.onDragEnd, this)); 23247 } 23248 }; 23249 23250 /** 23251 * Handles `touchstart` and `mousedown` events. 23252 * @todo Horizontal swipe threshold as option 23253 * @todo #261 23254 * @protected 23255 * @param {Event} event - The event arguments. 23256 */ 23257 Owl.prototype.onDragStart = function(event) { 23258 var stage = null; 23259 23260 if (event.which === 3) { 23261 return; 23262 } 23263 23264 if ($.support.transform) { 23265 stage = this.$stage.css('transform').replace(/.*\(|\)| /g, '').split(','); 23266 stage = { 23267 x: stage[stage.length === 16 ? 12 : 4], 23268 y: stage[stage.length === 16 ? 13 : 5] 23269 }; 23270 } else { 23271 stage = this.$stage.position(); 23272 stage = { 23273 x: this.settings.rtl ? 23274 stage.left + this.$stage.width() - this.width() + this.settings.margin : 23275 stage.left, 23276 y: stage.top 23277 }; 23278 } 23279 23280 if (this.is('animating')) { 23281 $.support.transform ? this.animate(stage.x) : this.$stage.stop() 23282 this.invalidate('position'); 23283 } 23284 23285 this.$element.toggleClass(this.options.grabClass, event.type === 'mousedown'); 23286 23287 this.speed(0); 23288 23289 this._drag.time = new Date().getTime(); 23290 this._drag.target = $(event.target); 23291 this._drag.stage.start = stage; 23292 this._drag.stage.current = stage; 23293 this._drag.pointer = this.pointer(event); 23294 23295 $(document).on('mouseup.owl.core touchend.owl.core', $.proxy(this.onDragEnd, this)); 23296 23297 $(document).one('mousemove.owl.core touchmove.owl.core', $.proxy(function(event) { 23298 var delta = this.difference(this._drag.pointer, this.pointer(event)); 23299 23300 $(document).on('mousemove.owl.core touchmove.owl.core', $.proxy(this.onDragMove, this)); 23301 23302 if (Math.abs(delta.x) < Math.abs(delta.y) && this.is('valid')) { 23303 return; 23304 } 23305 23306 event.preventDefault(); 23307 23308 this.enter('dragging'); 23309 this.trigger('drag'); 23310 }, this)); 23311 }; 23312 23313 /** 23314 * Handles the `touchmove` and `mousemove` events. 23315 * @todo #261 23316 * @protected 23317 * @param {Event} event - The event arguments. 23318 */ 23319 Owl.prototype.onDragMove = function(event) { 23320 var minimum = null, 23321 maximum = null, 23322 pull = null, 23323 delta = this.difference(this._drag.pointer, this.pointer(event)), 23324 stage = this.difference(this._drag.stage.start, delta); 23325 23326 if (!this.is('dragging')) { 23327 return; 23328 } 23329 23330 event.preventDefault(); 23331 23332 if (this.settings.loop) { 23333 minimum = this.coordinates(this.minimum()); 23334 maximum = this.coordinates(this.maximum() + 1) - minimum; 23335 stage.x = (((stage.x - minimum) % maximum + maximum) % maximum) + minimum; 23336 } else { 23337 minimum = this.settings.rtl ? this.coordinates(this.maximum()) : this.coordinates(this.minimum()); 23338 maximum = this.settings.rtl ? this.coordinates(this.minimum()) : this.coordinates(this.maximum()); 23339 pull = this.settings.pullDrag ? -1 * delta.x / 5 : 0; 23340 stage.x = Math.max(Math.min(stage.x, minimum + pull), maximum + pull); 23341 } 23342 23343 this._drag.stage.current = stage; 23344 23345 this.animate(stage.x); 23346 }; 23347 23348 /** 23349 * Handles the `touchend` and `mouseup` events. 23350 * @todo #261 23351 * @todo Threshold for click event 23352 * @protected 23353 * @param {Event} event - The event arguments. 23354 */ 23355 Owl.prototype.onDragEnd = function(event) { 23356 var delta = this.difference(this._drag.pointer, this.pointer(event)), 23357 stage = this._drag.stage.current, 23358 direction = delta.x > 0 ^ this.settings.rtl ? 'left' : 'right'; 23359 23360 $(document).off('.owl.core'); 23361 23362 this.$element.removeClass(this.options.grabClass); 23363 23364 if (delta.x !== 0 && this.is('dragging') || !this.is('valid')) { 23365 this.speed(this.settings.dragEndSpeed || this.settings.smartSpeed); 23366 this.current(this.closest(stage.x, delta.x !== 0 ? direction : this._drag.direction)); 23367 this.invalidate('position'); 23368 this.update(); 23369 23370 this._drag.direction = direction; 23371 23372 if (Math.abs(delta.x) > 3 || new Date().getTime() - this._drag.time > 300) { 23373 this._drag.target.one('click.owl.core', function() { return false; }); 23374 } 23375 } 23376 23377 if (!this.is('dragging')) { 23378 return; 23379 } 23380 23381 this.leave('dragging'); 23382 this.trigger('dragged'); 23383 }; 23384 23385 /** 23386 * Gets absolute position of the closest item for a coordinate. 23387 * @todo Setting `freeDrag` makes `closest` not reusable. See #165. 23388 * @protected 23389 * @param {Number} coordinate - The coordinate in pixel. 23390 * @param {String} direction - The direction to check for the closest item. Ether `left` or `right`. 23391 * @return {Number} - The absolute position of the closest item. 23392 */ 23393 Owl.prototype.closest = function(coordinate, direction) { 23394 var position = -1, 23395 pull = 30, 23396 width = this.width(), 23397 coordinates = this.coordinates(); 23398 23399 if (!this.settings.freeDrag) { 23400 // check closest item 23401 $.each(coordinates, $.proxy(function(index, value) { 23402 if (coordinate > value - pull && coordinate < value + pull) { 23403 position = index; 23404 } else if (this.op(coordinate, '<', value) 23405 && this.op(coordinate, '>', coordinates[index + 1] || value - width)) { 23406 position = direction === 'left' ? index + 1 : index; 23407 } 23408 return position === -1; 23409 }, this)); 23410 } 23411 23412 if (!this.settings.loop) { 23413 // non loop boundries 23414 if (this.op(coordinate, '>', coordinates[this.minimum()])) { 23415 position = coordinate = this.minimum(); 23416 } else if (this.op(coordinate, '<', coordinates[this.maximum()])) { 23417 position = coordinate = this.maximum(); 23418 } 23419 } 23420 23421 return position; 23422 }; 23423 23424 /** 23425 * Animates the stage. 23426 * @todo #270 23427 * @public 23428 * @param {Number} coordinate - The coordinate in pixels. 23429 */ 23430 Owl.prototype.animate = function(coordinate) { 23431 var animate = this.speed() > 0; 23432 23433 this.is('animating') && this.onTransitionEnd(); 23434 23435 if (animate) { 23436 this.enter('animating'); 23437 this.trigger('translate'); 23438 } 23439 23440 if ($.support.transform3d && $.support.transition) { 23441 this.$stage.css({ 23442 transform: 'translate3d(' + coordinate + 'px,0px,0px)', 23443 transition: (this.speed() / 1000) + 's' 23444 }); 23445 } else if (animate) { 23446 this.$stage.animate({ 23447 left: coordinate + 'px' 23448 }, this.speed(), this.settings.fallbackEasing, $.proxy(this.onTransitionEnd, this)); 23449 } else { 23450 this.$stage.css({ 23451 left: coordinate + 'px' 23452 }); 23453 } 23454 }; 23455 23456 /** 23457 * Checks whether the carousel is in a specific state or not. 23458 * @param {String} state - The state to check. 23459 * @returns {Boolean} - The flag which indicates if the carousel is busy. 23460 */ 23461 Owl.prototype.is = function(state) { 23462 return this._states.current[state] && this._states.current[state] > 0; 23463 }; 23464 23465 /** 23466 * Sets the absolute position of the current item. 23467 * @public 23468 * @param {Number} [position] - The new absolute position or nothing to leave it unchanged. 23469 * @returns {Number} - The absolute position of the current item. 23470 */ 23471 Owl.prototype.current = function(position) { 23472 if (position === undefined) { 23473 return this._current; 23474 } 23475 23476 if (this._items.length === 0) { 23477 return undefined; 23478 } 23479 23480 position = this.normalize(position); 23481 23482 if (this._current !== position) { 23483 var event = this.trigger('change', { property: { name: 'position', value: position } }); 23484 23485 if (event.data !== undefined) { 23486 position = this.normalize(event.data); 23487 } 23488 23489 this._current = position; 23490 23491 this.invalidate('position'); 23492 23493 this.trigger('changed', { property: { name: 'position', value: this._current } }); 23494 } 23495 23496 return this._current; 23497 }; 23498 23499 /** 23500 * Invalidates the given part of the update routine. 23501 * @param {String} [part] - The part to invalidate. 23502 * @returns {Array.<String>} - The invalidated parts. 23503 */ 23504 Owl.prototype.invalidate = function(part) { 23505 if ($.type(part) === 'string') { 23506 this._invalidated[part] = true; 23507 this.is('valid') && this.leave('valid'); 23508 } 23509 return $.map(this._invalidated, function(v, i) { return i }); 23510 }; 23511 23512 /** 23513 * Resets the absolute position of the current item. 23514 * @public 23515 * @param {Number} position - The absolute position of the new item. 23516 */ 23517 Owl.prototype.reset = function(position) { 23518 position = this.normalize(position); 23519 23520 if (position === undefined) { 23521 return; 23522 } 23523 23524 this._speed = 0; 23525 this._current = position; 23526 23527 this.suppress([ 'translate', 'translated' ]); 23528 23529 this.animate(this.coordinates(position)); 23530 23531 this.release([ 'translate', 'translated' ]); 23532 }; 23533 23534 /** 23535 * Normalizes an absolute or a relative position of an item. 23536 * @public 23537 * @param {Number} position - The absolute or relative position to normalize. 23538 * @param {Boolean} [relative=false] - Whether the given position is relative or not. 23539 * @returns {Number} - The normalized position. 23540 */ 23541 Owl.prototype.normalize = function(position, relative) { 23542 var n = this._items.length, 23543 m = relative ? 0 : this._clones.length; 23544 23545 if (!$.isNumeric(position) || n < 1) { 23546 position = undefined; 23547 } else if (position < 0 || position >= n + m) { 23548 position = ((position - m / 2) % n + n) % n + m / 2; 23549 } 23550 23551 return position; 23552 }; 23553 23554 /** 23555 * Converts an absolute position of an item into a relative one. 23556 * @public 23557 * @param {Number} position - The absolute position to convert. 23558 * @returns {Number} - The converted position. 23559 */ 23560 Owl.prototype.relative = function(position) { 23561 position -= this._clones.length / 2; 23562 return this.normalize(position, true); 23563 }; 23564 23565 /** 23566 * Gets the maximum position for the current item. 23567 * @public 23568 * @param {Boolean} [relative=false] - Whether to return an absolute position or a relative position. 23569 * @returns {Number} 23570 */ 23571 Owl.prototype.maximum = function(relative) { 23572 var settings = this.settings, 23573 maximum = this._coordinates.length, 23574 boundary = Math.abs(this._coordinates[maximum - 1]) - this._width, 23575 i = -1, j; 23576 23577 if (settings.loop) { 23578 maximum = this._clones.length / 2 + this._items.length - 1; 23579 } else if (settings.autoWidth || settings.merge) { 23580 // binary search 23581 while (maximum - i > 1) { 23582 Math.abs(this._coordinates[j = maximum + i >> 1]) < boundary 23583 ? i = j : maximum = j; 23584 } 23585 } else if (settings.center) { 23586 maximum = this._items.length - 1; 23587 } else { 23588 maximum = this._items.length - settings.items; 23589 } 23590 23591 if (relative) { 23592 maximum -= this._clones.length / 2; 23593 } 23594 23595 return Math.max(maximum, 0); 23596 }; 23597 23598 /** 23599 * Gets the minimum position for the current item. 23600 * @public 23601 * @param {Boolean} [relative=false] - Whether to return an absolute position or a relative position. 23602 * @returns {Number} 23603 */ 23604 Owl.prototype.minimum = function(relative) { 23605 return relative ? 0 : this._clones.length / 2; 23606 }; 23607 23608 /** 23609 * Gets an item at the specified relative position. 23610 * @public 23611 * @param {Number} [position] - The relative position of the item. 23612 * @return {jQuery|Array.<jQuery>} - The item at the given position or all items if no position was given. 23613 */ 23614 Owl.prototype.items = function(position) { 23615 if (position === undefined) { 23616 return this._items.slice(); 23617 } 23618 23619 position = this.normalize(position, true); 23620 return this._items[position]; 23621 }; 23622 23623 /** 23624 * Gets an item at the specified relative position. 23625 * @public 23626 * @param {Number} [position] - The relative position of the item. 23627 * @return {jQuery|Array.<jQuery>} - The item at the given position or all items if no position was given. 23628 */ 23629 Owl.prototype.mergers = function(position) { 23630 if (position === undefined) { 23631 return this._mergers.slice(); 23632 } 23633 23634 position = this.normalize(position, true); 23635 return this._mergers[position]; 23636 }; 23637 23638 /** 23639 * Gets the absolute positions of clones for an item. 23640 * @public 23641 * @param {Number} [position] - The relative position of the item. 23642 * @returns {Array.<Number>} - The absolute positions of clones for the item or all if no position was given. 23643 */ 23644 Owl.prototype.clones = function(position) { 23645 var odd = this._clones.length / 2, 23646 even = odd + this._items.length, 23647 map = function(index) { return index % 2 === 0 ? even + index / 2 : odd - (index + 1) / 2 }; 23648 23649 if (position === undefined) { 23650 return $.map(this._clones, function(v, i) { return map(i) }); 23651 } 23652 23653 return $.map(this._clones, function(v, i) { return v === position ? map(i) : null }); 23654 }; 23655 23656 /** 23657 * Sets the current animation speed. 23658 * @public 23659 * @param {Number} [speed] - The animation speed in milliseconds or nothing to leave it unchanged. 23660 * @returns {Number} - The current animation speed in milliseconds. 23661 */ 23662 Owl.prototype.speed = function(speed) { 23663 if (speed !== undefined) { 23664 this._speed = speed; 23665 } 23666 23667 return this._speed; 23668 }; 23669 23670 /** 23671 * Gets the coordinate of an item. 23672 * @todo The name of this method is missleanding. 23673 * @public 23674 * @param {Number} position - The absolute position of the item within `minimum()` and `maximum()`. 23675 * @returns {Number|Array.<Number>} - The coordinate of the item in pixel or all coordinates. 23676 */ 23677 Owl.prototype.coordinates = function(position) { 23678 var coordinate = null; 23679 23680 if (position === undefined) { 23681 return $.map(this._coordinates, $.proxy(function(coordinate, index) { 23682 return this.coordinates(index); 23683 }, this)); 23684 } 23685 23686 if (this.settings.center) { 23687 coordinate = this._coordinates[position]; 23688 coordinate += (this.width() - coordinate + (this._coordinates[position - 1] || 0)) / 2 * (this.settings.rtl ? -1 : 1); 23689 } else { 23690 coordinate = this._coordinates[position - 1] || 0; 23691 } 23692 23693 return coordinate; 23694 }; 23695 23696 /** 23697 * Calculates the speed for a translation. 23698 * @protected 23699 * @param {Number} from - The absolute position of the start item. 23700 * @param {Number} to - The absolute position of the target item. 23701 * @param {Number} [factor=undefined] - The time factor in milliseconds. 23702 * @returns {Number} - The time in milliseconds for the translation. 23703 */ 23704 Owl.prototype.duration = function(from, to, factor) { 23705 return Math.min(Math.max(Math.abs(to - from), 1), 6) * Math.abs((factor || this.settings.smartSpeed)); 23706 }; 23707 23708 /** 23709 * Slides to the specified item. 23710 * @public 23711 * @param {Number} position - The position of the item. 23712 * @param {Number} [speed] - The time in milliseconds for the transition. 23713 */ 23714 Owl.prototype.to = function(position, speed) { 23715 var current = this.current(), 23716 revert = null, 23717 distance = position - this.relative(current), 23718 direction = (distance > 0) - (distance < 0), 23719 items = this._items.length, 23720 minimum = this.minimum(), 23721 maximum = this.maximum(); 23722 23723 if (this.settings.loop) { 23724 if (!this.settings.rewind && Math.abs(distance) > items / 2) { 23725 distance += direction * -1 * items; 23726 } 23727 23728 position = current + distance; 23729 revert = ((position - minimum) % items + items) % items + minimum; 23730 23731 if (revert !== position && revert - distance <= maximum && revert - distance > 0) { 23732 current = revert - distance; 23733 position = revert; 23734 this.reset(current); 23735 } 23736 } else if (this.settings.rewind) { 23737 maximum += 1; 23738 position = (position % maximum + maximum) % maximum; 23739 } else { 23740 position = Math.max(minimum, Math.min(maximum, position)); 23741 } 23742 23743 this.speed(this.duration(current, position, speed)); 23744 this.current(position); 23745 23746 if (this.$element.is(':visible')) { 23747 this.update(); 23748 } 23749 }; 23750 23751 /** 23752 * Slides to the next item. 23753 * @public 23754 * @param {Number}
vendor: 12,284 bytes, lines 23754-24174
23754 [speed] - The time in milliseconds for the transition. 23755 */ 23756 Owl.prototype.next = function(speed) { 23757 speed = speed || false; 23758 this.to(this.relative(this.current()) + 1, speed); 23759 }; 23760 23761 /** 23762 * Slides to the previous item. 23763 * @public 23764 * @param {Number} [speed] - The time in milliseconds for the transition. 23765 */ 23766 Owl.prototype.prev = function(speed) { 23767 speed = speed || false; 23768 this.to(this.relative(this.current()) - 1, speed); 23769 }; 23770 23771 /** 23772 * Handles the end of an animation. 23773 * @protected 23774 * @param {Event} event - The event arguments. 23775 */ 23776 Owl.prototype.onTransitionEnd = function(event) { 23777 23778 // if css2 animation then event object is undefined 23779 if (event !== undefined) { 23780 event.stopPropagation(); 23781 23782 // Catch only owl-stage transitionEnd event 23783 if ((event.target || event.srcElement || event.originalTarget) !== this.$stage.get(0)) { 23784 return false; 23785 } 23786 } 23787 23788 this.leave('animating'); 23789 this.trigger('translated'); 23790 }; 23791 23792 /** 23793 * Gets viewport width. 23794 * @protected 23795 * @return {Number} - The width in pixel. 23796 */ 23797 Owl.prototype.viewport = function() { 23798 var width; 23799 if (this.options.responsiveBaseElement !== window) { 23800 width = $(this.options.responsiveBaseElement).width(); 23801 } else if (window.innerWidth) { 23802 width = window.innerWidth; 23803 } else if (document.documentElement && document.documentElement.clientWidth) { 23804 width = document.documentElement.clientWidth; 23805 } else { 23806 throw 'Can not detect viewport width.'; 23807 } 23808 23809 return width; 23810 }; 23811 23812 /** 23813 * Replaces the current content. 23814 * @public 23815 * @param {HTMLElement|jQuery|String} content - The new content. 23816 */ 23817 Owl.prototype.replace = function(content) { 23818 this.$stage.empty(); 23819 this._items = []; 23820 23821 if (content) { 23822 content = (content instanceof jQuery) ? content : $(content); 23823 } 23824 23825 if (this.settings.nestedItemSelector) { 23826 content = content.find('.' + this.settings.nestedItemSelector); 23827 } 23828 23829 content.filter(function() { 23830 return this.nodeType === 1; 23831 }).each($.proxy(function(index, item) { 23832 item = this.prepare(item, index); 23833 this.$stage.append(item); 23834 this._items.push(item); 23835 this._mergers.push(item.find('[data-merge]').addBack('[data-merge]').attr('data-merge') * 1 || 1); 23836 }, this)); 23837 23838 this.reset($.isNumeric(this.settings.startPosition) ? this.settings.startPosition : 0); 23839 23840 this.invalidate('items'); 23841 }; 23842 23843 /** 23844 * Adds an item. 23845 * @todo Use `item` instead of `content` for the event arguments. 23846 * @public 23847 * @param {HTMLElement|jQuery|String} content - The item content to add. 23848 * @param {Number} [position] - The relative position at which to insert the item otherwise the item will be added to the end. 23849 */ 23850 Owl.prototype.add = function(content, position) { 23851 var current = this.relative(this._current); 23852 23853 position = position === undefined ? this._items.length : this.normalize(position, true); 23854 content = content instanceof jQuery ? content : $(content); 23855 23856 this.trigger('add', { content: content, position: position }); 23857 23858 content = this.prepare(content, this._items[current].index()); 23859 23860 if (this._items.length === 0 || position === this._items.length) { 23861 this._items.length === 0 && this.$stage.append(content); 23862 this._items.length !== 0 && this._items[position - 1].after(content); 23863 this._items.push(content); 23864 this._mergers.push(content.find('[data-merge]').andSelf('[data-merge]').attr('data-merge') * 1 || 1); 23865 } else { 23866 this._items[position].before(content); 23867 this._items.splice(position, 0, content); 23868 this._mergers.splice(position, 0, content.find('[data-merge]').andSelf('[data-merge]').attr('data-merge') * 1 || 1); 23869 } 23870 23871 this._items[current] && this.reset(this._items[current].index()); 23872 23873 this.invalidate('items'); 23874 23875 this.trigger('added', { content: content, position: position }); 23876 }; 23877 23878 /** 23879 * Removes an item by its position. 23880 * @todo Use `item` instead of `content` for the event arguments. 23881 * @public 23882 * @param {Number} position - The relative position of the item to remove. 23883 */ 23884 Owl.prototype.remove = function(position) { 23885 position = this.normalize(position, true); 23886 23887 if (position === undefined) { 23888 return; 23889 } 23890 23891 this.trigger('remove', { content: this._items[position], position: position }); 23892 23893 this._items[position].remove(); 23894 this._items.splice(position, 1); 23895 this._mergers.splice(position, 1); 23896 23897 this.invalidate('items'); 23898 23899 this.trigger('removed', { content: null, position: position }); 23900 }; 23901 23902 /** 23903 * Preloads images with auto width. 23904 * @todo Replace by a more generic approach 23905 * @protected 23906 */ 23907 Owl.prototype.preloadAutoWidthImages = function(images) { 23908 images.each($.proxy(function(i, element) { 23909 this.enter('pre-loading'); 23910 element = $(element); 23911 $(new Image()).one('load', $.proxy(function(e) { 23912 element.attr('src', e.target.src); 23913 element.css('opacity', 1); 23914 this.leave('pre-loading'); 23915 !this.is('pre-loading') && !this.is('initializing') && this.refresh(); 23916 }, this)).attr('src', element.attr('src') || element.attr('data-src') || element.attr('data-src-retina')); 23917 }, this)); 23918 }; 23919 23920 /** 23921 * Destroys the carousel. 23922 * @public 23923 */ 23924 Owl.prototype.destroy = function() { 23925 23926 this.$element.off('.owl.core'); 23927 this.$stage.off('.owl.core'); 23928 $(document).off('.owl.core'); 23929 23930 if (this.settings.responsive !== false) { 23931 window.clearTimeout(this.resizeTimer); 23932 this.off(window, 'resize', this._handlers.onThrottledResize); 23933 } 23934 23935 for (var i in this._plugins) { 23936 this._plugins[i].destroy(); 23937 } 23938 23939 this.$stage.children('.cloned').remove(); 23940 23941 this.$stage.unwrap(); 23942 this.$stage.children().contents().unwrap(); 23943 this.$stage.children().unwrap(); 23944 23945 this.$element 23946 .removeClass(this.options.refreshClass) 23947 .removeClass(this.options.loadingClass) 23948 .removeClass(this.options.loadedClass) 23949 .removeClass(this.options.rtlClass) 23950 .removeClass(this.options.dragClass) 23951 .removeClass(this.options.grabClass) 23952 .attr('class', this.$element.attr('class').replace(new RegExp(this.options.responsiveClass + '-\\S+\\s', 'g'), '')) 23953 .removeData('owl.carousel'); 23954 }; 23955 23956 /** 23957 * Operators to calculate right-to-left and left-to-right. 23958 * @protected 23959 * @param {Number} [a] - The left side operand. 23960 * @param {String} [o] - The operator. 23961 * @param {Number} [b] - The right side operand. 23962 */ 23963 Owl.prototype.op = function(a, o, b) { 23964 var rtl = this.settings.rtl; 23965 switch (o) { 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 case '<=': 23973 return rtl ? a >= b : a <= b; 23974 default: 23975 break; 23976 } 23977 }; 23978 23979 /** 23980 * Attaches to an internal event. 23981 * @protected 23982 * @param {HTMLElement} element - The event source. 23983 * @param {String} event - The event name. 23984 * @param {Function} listener - The event handler to attach. 23985 * @param {Boolean} capture - Wether the event should be handled at the capturing phase or not. 23986 */ 23987 Owl.prototype.on = function(element, event, listener, capture) { 23988 if (element.addEventListener) { 23989 element.addEventListener(event, listener, capture); 23990 } else if (element.attachEvent) { 23991 element.attachEvent('on' + event, listener); 23992 } 23993 }; 23994 23995 /** 23996 * Detaches from an internal event. 23997 * @protected 23998 * @param {HTMLElement} element - The event source. 23999 * @param {String} event - The event name. 24000 * @param {Function} listener - The attached event handler to detach. 24001 * @param {Boolean} capture - Wether the attached event handler was registered as a capturing listener or not. 24002 */ 24003 Owl.prototype.off = function(element, event, listener, capture) { 24004 if (element.removeEventListener) { 24005 element.removeEventListener(event, listener, capture); 24006 } else if (element.detachEvent) { 24007 element.detachEvent('on' + event, listener); 24008 } 24009 }; 24010 24011 /** 24012 * Triggers a public event. 24013 * @todo Remove `status`, `relatedTarget` should be used instead. 24014 * @protected 24015 * @param {String} name - The event name. 24016 * @param {*} [data=null] - The event data. 24017 * @param {String} [namespace=carousel] - The event namespace. 24018 * @param {String} [state] - The state which is associated with the event. 24019 * @param {Boolean} [enter=false] - Indicates if the call enters the specified state or not. 24020 * @returns {Event} - The event arguments. 24021 */ 24022 Owl.prototype.trigger = function(name, data, namespace, state, enter) { 24023 var status = { 24024 item: { count: this._items.length, index: this.current() } 24025 }, handler = $.camelCase( 24026 $.grep([ 'on', name, namespace ], function(v) { return v }) 24027 .join('-').toLowerCase() 24028 ), event = $.Event( 24029 [ name, 'owl', namespace || 'carousel' ].join('.').toLowerCase(), 24030 $.extend({ relatedTarget: this }, status, data) 24031 ); 24032 24033 if (!this._supress[name]) { 24034 $.each(this._plugins, function(name, plugin) { 24035 if (plugin.onTrigger) { 24036 plugin.onTrigger(event); 24037 } 24038 }); 24039 24040 this.register({ type: Owl.Type.Event, name: name }); 24041 this.$element.trigger(event); 24042 24043 if (this.settings && typeof this.settings[handler] === 'function') { 24044 this.settings[handler].call(this, event); 24045 } 24046 } 24047 24048 return event; 24049 }; 24050 24051 /** 24052 * Enters a state. 24053 * @param name - The state name. 24054 */ 24055 Owl.prototype.enter = function(name) { 24056 $.each([ name ].concat(this._states.tags[name] || []), $.proxy(function(i, name) { 24057 if (this._states.current[name] === undefined) { 24058 this._states.current[name] = 0; 24059 } 24060 24061 this._states.current[name]++; 24062 }, this)); 24063 }; 24064 24065 /** 24066 * Leaves a state. 24067 * @param name - The state name. 24068 */ 24069 Owl.prototype.leave = function(name) { 24070 $.each([ name ].concat(this._states.tags[name] || []), $.proxy(function(i, name) { 24071 this._states.current[name]--; 24072 }, this)); 24073 }; 24074 24075 /** 24076 * Registers an event or state. 24077 * @public 24078 * @param {Object} object - The event or state to register. 24079 */ 24080 Owl.prototype.register = function(object) { 24081 if (object.type === Owl.Type.Event) { 24082 if (!$.event.special[object.name]) { 24083 $.event.special[object.name] = {}; 24084 } 24085 24086 if (!$.event.special[object.name].owl) { 24087 var _default = $.event.special[object.name]._default; 24088 $.event.special[object.name]._default = function(e) { 24089 if (_default && _default.apply && (!e.namespace || e.namespace.indexOf('owl') === -1)) { 24090 return _default.apply(this, arguments); 24091 } 24092 return e.namespace && e.namespace.indexOf('owl') > -1; 24093 }; 24094 $.event.special[object.name].owl = true; 24095 } 24096 } else if (object.type === Owl.Type.State) { 24097 if (!this._states.tags[object.name]) { 24098 this._states.tags[object.name] = object.tags; 24099 } else { 24100 this._states.tags[object.name] = this._states.tags[object.name].concat(object.tags); 24101 } 24102 24103 this._states.tags[object.name] = $.grep(this._states.tags[object.name], $.proxy(function(tag, i) { 24104 return $.inArray(tag, this._states.tags[object.name]) === i; 24105 }, this)); 24106 } 24107 }; 24108 24109 /** 24110 * Suppresses events. 24111 * @protected 24112 * @param {Array.<String>} events - The events to suppress. 24113 */ 24114 Owl.prototype.suppress = function(events) { 24115 $.each(events, $.proxy(function(index, event) { 24116 this._supress[event] = true; 24117 }, this)); 24118 }; 24119 24120 /** 24121 * Releases suppressed events. 24122 * @protected 24123 * @param {Array.<String>} events - The events to release. 24124 */ 24125 Owl.prototype.release = function(events) { 24126 $.each(events, $.proxy(function(index, event) { 24127 delete this._supress[event]; 24128 }, this)); 24129 }; 24130 24131 /** 24132 * Gets unified pointer coordinates from event. 24133 * @todo #261 24134 * @protected 24135 * @param {Event} - The `mousedown` or `touchstart` event. 24136 * @returns {Object} - Contains `x` and `y` coordinates of current pointer position. 24137 */ 24138 Owl.prototype.pointer = function(event) { 24139 var result = { x: null, y: null }; 24140 24141 event = event.originalEvent || event || window.event; 24142 24143 event = event.touches && event.touches.length ? 24144 event.touches[0] : event.changedTouches && event.changedTouches.length ? 24145 event.changedTouches[0] : event; 24146 24147 if (event.pageX) { 24148 result.x = event.pageX; 24149 result.y = event.pageY; 24150 } else { 24151 result.x = event.clientX; 24152 result.y = event.clientY; 24153 } 24154 24155 return result; 24156 }; 24157 24158 /** 24159 * Gets the difference of two vectors. 24160 * @todo #261 24161 * @protected 24162 * @param {Object} - The first vector. 24163 * @param {Object} - The second vector. 24164 * @returns {Object} - The difference. 24165 */ 24166 Owl.prototype.difference = function(first, second) { 24167 return { 24168 x: first.x - second.x, 24169 y: first.y - second.y 24170 }; 24171 }; 24172 24173 /** 24174 * The jQuery Plugin for the Owl Carousel
vendor: 32,216 bytes, lines 24175-25457
24175 * @todo Navigation plugin `next` and `prev` 24176 * @public 24177 */ 24178 $.fn.owlCarousel = function(option) { 24179 var args = Array.prototype.slice.call(arguments, 1); 24180 24181 return this.each(function() { 24182 var $this = $(this), 24183 data = $this.data('owl.carousel'); 24184 24185 if (!data) { 24186 data = new Owl(this, typeof option == 'object' && option); 24187 $this.data('owl.carousel', data); 24188 24189 $.each([ 24190 'next', 'prev', 'to', 'destroy', 'refresh', 'replace', 'add', 'remove' 24191 ], function(i, event) { 24192 data.register({ type: Owl.Type.Event, name: event }); 24193 data.$element.on(event + '.owl.carousel.core', $.proxy(function(e) { 24194 if (e.namespace && e.relatedTarget !== this) { 24195 this.suppress([ event ]); 24196 data[event].apply(this, [].slice.call(arguments, 1)); 24197 this.release([ event ]); 24198 } 24199 }, data)); 24200 }); 24201 } 24202 24203 if (typeof option == 'string' && option.charAt(0) !== '_') { 24204 data[option].apply(data, args); 24205 } 24206 }); 24207 }; 24208 24209 /** 24210 * The constructor for the jQuery Plugin 24211 * @public 24212 */ 24213 $.fn.owlCarousel.Constructor = Owl; 24214 24215})(window.Zepto || window.jQuery, window, document); 24216 24217/** 24218 * AutoRefresh Plugin 24219 * @version 2.0.0-beta.3 24220 * @author Artus Kolanowski 24221 * @license The MIT License (MIT) 24222 */ 24223;(function($, window, document, undefined) { 24224 24225 /** 24226 * Creates the auto refresh plugin. 24227 * @class The Auto Refresh Plugin 24228 * @param {Owl} carousel - The Owl Carousel 24229 */ 24230 var AutoRefresh = function(carousel) { 24231 /** 24232 * Reference to the core. 24233 * @protected 24234 * @type {Owl} 24235 */ 24236 this._core = carousel; 24237 24238 /** 24239 * Refresh interval. 24240 * @protected 24241 * @type {number} 24242 */ 24243 this._interval = null; 24244 24245 /** 24246 * Whether the element is currently visible or not. 24247 * @protected 24248 * @type {Boolean} 24249 */ 24250 this._visible = null; 24251 24252 /** 24253 * All event handlers. 24254 * @protected 24255 * @type {Object} 24256 */ 24257 this._handlers = { 24258 'initialized.owl.carousel': $.proxy(function(e) { 24259 if (e.namespace && this._core.settings.autoRefresh) { 24260 this.watch(); 24261 } 24262 }, this) 24263 }; 24264 24265 // set default options 24266 this._core.options = $.extend({}, AutoRefresh.Defaults, this._core.options); 24267 24268 // register event handlers 24269 this._core.$element.on(this._handlers); 24270 }; 24271 24272 /** 24273 * Default options. 24274 * @public 24275 */ 24276 AutoRefresh.Defaults = { 24277 autoRefresh: true, 24278 autoRefreshInterval: 500 24279 }; 24280 24281 /** 24282 * Watches the element. 24283 */ 24284 AutoRefresh.prototype.watch = function() { 24285 if (this._interval) { 24286 return; 24287 } 24288 24289 this._visible = this._core.$element.is(':visible'); 24290 this._interval = window.setInterval($.proxy(this.refresh, this), this._core.settings.autoRefreshInterval); 24291 }; 24292 24293 /** 24294 * Refreshes the element. 24295 */ 24296 AutoRefresh.prototype.refresh = function() { 24297 if (this._core.$element.is(':visible') === this._visible) { 24298 return; 24299 } 24300 24301 this._visible = !this._visible; 24302 24303 this._core.$element.toggleClass('owl-hidden', !this._visible); 24304 24305 this._visible && (this._core.invalidate('width') && this._core.refresh()); 24306 }; 24307 24308 /** 24309 * Destroys the plugin. 24310 */ 24311 AutoRefresh.prototype.destroy = function() { 24312 var handler, property; 24313 24314 window.clearInterval(this._interval); 24315 24316 for (handler in this._handlers) { 24317 this._core.$element.off(handler, this._handlers[handler]); 24318 } 24319 for (property in Object.getOwnPropertyNames(this)) { 24320 typeof this[property] != 'function' && (this[property] = null); 24321 } 24322 }; 24323 24324 $.fn.owlCarousel.Constructor.Plugins.AutoRefresh = AutoRefresh; 24325 24326})(window.Zepto || window.jQuery, window, document); 24327 24328/** 24329 * Lazy Plugin 24330 * @version 2.0.0-beta.3 24331 * @author Bartosz Wojciechowski 24332 * @license The MIT License (MIT) 24333 */ 24334;(function($, window, document, undefined) { 24335 24336 /** 24337 * Creates the lazy plugin. 24338 * @class The Lazy Plugin 24339 * @param {Owl} carousel - The Owl Carousel 24340 */ 24341 var Lazy = function(carousel) { 24342 24343 /** 24344 * Reference to the core. 24345 * @protected 24346 * @type {Owl} 24347 */ 24348 this._core = carousel; 24349 24350 /** 24351 * Already loaded items. 24352 * @protected 24353 * @type {Array.<jQuery>} 24354 */ 24355 this._loaded = []; 24356 24357 /** 24358 * Event handlers. 24359 * @protected 24360 * @type {Object} 24361 */ 24362 this._handlers = { 24363 'initialized.owl.carousel change.owl.carousel': $.proxy(function(e) { 24364 if (!e.namespace) { 24365 return; 24366 } 24367 24368 if (!this._core.settings || !this._core.settings.lazyLoad) { 24369 return; 24370 } 24371 24372 if ((e.property && e.property.name == 'position') || e.type == 'initialized') { 24373 var settings = this._core.settings, 24374 n = (settings.center && Math.ceil(settings.items / 2) || settings.items), 24375 i = ((settings.center && n * -1) || 0), 24376 position = ((e.property && e.property.value) || this._core.current()) + i, 24377 clones = this._core.clones().length, 24378 load = $.proxy(function(i, v) { this.load(v) }, this); 24379 24380 while (i++ < n) { 24381 this.load(clones / 2 + this._core.relative(position)); 24382 clones && $.each(this._core.clones(this._core.relative(position)), load); 24383 position++; 24384 } 24385 } 24386 }, this) 24387 }; 24388 24389 // set the default options 24390 this._core.options = $.extend({}, Lazy.Defaults, this._core.options); 24391 24392 // register event handler 24393 this._core.$element.on(this._handlers); 24394 } 24395 24396 /** 24397 * Default options. 24398 * @public 24399 */ 24400 Lazy.Defaults = { 24401 lazyLoad: false 24402 } 24403 24404 /** 24405 * Loads all resources of an item at the specified position. 24406 * @param {Number} position - The absolute position of the item. 24407 * @protected 24408 */ 24409 Lazy.prototype.load = function(position) { 24410 var $item = this._core.$stage.children().eq(position), 24411 $elements = $item && $item.find('.owl-lazy'); 24412 24413 if (!$elements || $.inArray($item.get(0), this._loaded) > -1) { 24414 return; 24415 } 24416 24417 $elements.each($.proxy(function(index, element) { 24418 var $element = $(element), image, 24419 url = (window.devicePixelRatio > 1 && $element.attr('data-src-retina')) || $element.attr('data-src'); 24420 24421 this._core.trigger('load', { element: $element, url: url }, 'lazy'); 24422 24423 if ($element.is('img')) { 24424 $element.one('load.owl.lazy', $.proxy(function() { 24425 $element.css('opacity', 1); 24426 this._core.trigger('loaded', { element: $element, url: url }, 'lazy'); 24427 }, this)).attr('src', url); 24428 } else { 24429 image = new Image(); 24430 image.onload = $.proxy(function() { 24431 $element.css({ 24432 'background-image': 'url(' + url + ')', 24433 'opacity': '1' 24434 }); 24435 this._core.trigger('loaded', { element: $element, url: url }, 'lazy'); 24436 }, this); 24437 image.src = url; 24438 } 24439 }, this)); 24440 24441 this._loaded.push($item.get(0)); 24442 } 24443 24444 /** 24445 * Destroys the plugin. 24446 * @public 24447 */ 24448 Lazy.prototype.destroy = function() { 24449 var handler, property; 24450 24451 for (handler in this.handlers) { 24452 this._core.$element.off(handler, this.handlers[handler]); 24453 } 24454 for (property in Object.getOwnPropertyNames(this)) { 24455 typeof this[property] != 'function' && (this[property] = null); 24456 } 24457 }; 24458 24459 $.fn.owlCarousel.Constructor.Plugins.Lazy = Lazy; 24460 24461})(window.Zepto || window.jQuery, window, document); 24462 24463/** 24464 * AutoHeight Plugin 24465 * @version 2.0.0-beta.3 24466 * @author Bartosz Wojciechowski 24467 * @license The MIT License (MIT) 24468 */ 24469;(function($, window, document, undefined) { 24470 24471 /** 24472 * Creates the auto height plugin. 24473 * @class The Auto Height Plugin 24474 * @param {Owl} carousel - The Owl Carousel 24475 */ 24476 var AutoHeight = function(carousel) { 24477 /** 24478 * Reference to the core. 24479 * @protected 24480 * @type {Owl} 24481 */ 24482 this._core = carousel; 24483 24484 /** 24485 * All event handlers. 24486 * @protected 24487 * @type {Object} 24488 */ 24489 this._handlers = { 24490 'initialized.owl.carousel refreshed.owl.carousel': $.proxy(function(e) { 24491 if (e.namespace && this._core.settings.autoHeight) { 24492 this.update(); 24493 } 24494 }, this), 24495 'changed.owl.carousel': $.proxy(function(e) { 24496 if (e.namespace && this._core.settings.autoHeight && e.property.name == 'position'){ 24497 this.update(); 24498 } 24499 }, this), 24500 'loaded.owl.lazy': $.proxy(function(e) { 24501 if (e.namespace && this._core.settings.autoHeight 24502 && e.element.closest('.' + this._core.settings.itemClass).index() === this._core.current()) { 24503 this.update(); 24504 } 24505 }, this) 24506 }; 24507 24508 // set default options 24509 this._core.options = $.extend({}, AutoHeight.Defaults, this._core.options); 24510 24511 // register event handlers 24512 this._core.$element.on(this._handlers); 24513 }; 24514 24515 /** 24516 * Default options. 24517 * @public 24518 */ 24519 AutoHeight.Defaults = { 24520 autoHeight: false, 24521 autoHeightClass: 'owl-height' 24522 }; 24523 24524 /** 24525 * Updates the view. 24526 */ 24527 AutoHeight.prototype.update = function() { 24528 var start = this._core._current, 24529 end = start + this._core.settings.items, 24530 visible = this._core.$stage.children().toArray().slice(start, end); 24531 heights = [], 24532 maxheight = 0; 24533 24534 $.each(visible, function(index, item) { 24535 heights.push($(item).height()); 24536 }); 24537 24538 maxheight = Math.max.apply(null, heights); 24539 24540 this._core.$stage.parent() 24541 .height(maxheight) 24542 .addClass(this._core.settings.autoHeightClass); 24543 }; 24544 24545 AutoHeight.prototype.destroy = function() { 24546 var handler, property; 24547 24548 for (handler in this._handlers) { 24549 this._core.$element.off(handler, this._handlers[handler]); 24550 } 24551 for (property in Object.getOwnPropertyNames(this)) { 24552 typeof this[property] != 'function' && (this[property] = null); 24553 } 24554 }; 24555 24556 $.fn.owlCarousel.Constructor.Plugins.AutoHeight = AutoHeight; 24557 24558})(window.Zepto || window.jQuery, window, document); 24559 24560/** 24561 * Video Plugin 24562 * @version 2.0.0-beta.3 24563 * @author Bartosz Wojciechowski 24564 * @license The MIT License (MIT) 24565 */ 24566;(function($, window, document, undefined) { 24567 24568 /** 24569 * Creates the video plugin. 24570 * @class The Video Plugin 24571 * @param {Owl} carousel - The Owl Carousel 24572 */ 24573 var Video = function(carousel) { 24574 /** 24575 * Reference to the core. 24576 * @protected 24577 * @type {Owl} 24578 */ 24579 this._core = carousel; 24580 24581 /** 24582 * Cache all video URLs. 24583 * @protected 24584 * @type {Object} 24585 */ 24586 this._videos = {}; 24587 24588 /** 24589 * Current playing item. 24590 * @protected 24591 * @type {jQuery} 24592 */ 24593 this._playing = null; 24594 24595 /** 24596 * All event handlers. 24597 * @todo The cloned content removale is too late 24598 * @protected 24599 * @type {Object} 24600 */ 24601 this._handlers = { 24602 'initialized.owl.carousel': $.proxy(function(e) { 24603 if (e.namespace) { 24604 this._core.register({ type: 'state', name: 'playing', tags: [ 'interacting' ] }); 24605 } 24606 }, this), 24607 'resize.owl.carousel': $.proxy(function(e) { 24608 if (e.namespace && this._core.settings.video && this.isInFullScreen()) { 24609 e.preventDefault(); 24610 } 24611 }, this), 24612 'refreshed.owl.carousel': $.proxy(function(e) { 24613 if (e.namespace && this._core.is('resizing')) { 24614 this._core.$stage.find('.cloned .owl-video-frame').remove(); 24615 } 24616 }, this), 24617 'changed.owl.carousel': $.proxy(function(e) { 24618 if (e.namespace && e.property.name === 'position' && this._playing) { 24619 this.stop(); 24620 } 24621 }, this), 24622 'prepared.owl.carousel': $.proxy(function(e) { 24623 if (!e.namespace) { 24624 return; 24625 } 24626 24627 var $element = $(e.content).find('.owl-video'); 24628 24629 if ($element.length) { 24630 $element.css('display', 'none'); 24631 this.fetch($element, $(e.content)); 24632 } 24633 }, this) 24634 }; 24635 24636 // set default options 24637 this._core.options = $.extend({}, Video.Defaults, this._core.options); 24638 24639 // register event handlers 24640 this._core.$element.on(this._handlers); 24641 24642 this._core.$element.on('click.owl.video', '.owl-video-play-icon', $.proxy(function(e) { 24643 this.play(e); 24644 }, this)); 24645 }; 24646 24647 /** 24648 * Default options. 24649 * @public 24650 */ 24651 Video.Defaults = { 24652 video: false, 24653 videoHeight: false, 24654 videoWidth: false 24655 }; 24656 24657 /** 24658 * Gets the video ID and the type (YouTube/Vimeo only). 24659 * @protected 24660 * @param {jQuery} target - The target containing the video data. 24661 * @param {jQuery} item - The item containing the video. 24662 */ 24663 Video.prototype.fetch = function(target, item) { 24664 var type = target.attr('data-vimeo-id') ? 'vimeo' : 'youtube', 24665 id = target.attr('data-vimeo-id') || target.attr('data-youtube-id'), 24666 width = target.attr('data-width') || this._core.settings.videoWidth, 24667 height = target.attr('data-height') || this._core.settings.videoHeight, 24668 url = target.attr('href'); 24669 24670 if (url) { 24671 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+)?/); 24672 24673 if (id[3].indexOf('youtu') > -1) { 24674 type = 'youtube'; 24675 } else if (id[3].indexOf('vimeo') > -1) { 24676 type = 'vimeo'; 24677 } else { 24678 throw new Error('Video URL not supported.'); 24679 } 24680 id = id[6]; 24681 } else { 24682 throw new Error('Missing video URL.'); 24683 } 24684 24685 this._videos[url] = { 24686 type: type, 24687 id: id, 24688 width: width, 24689 height: height 24690 }; 24691 24692 item.attr('data-video', url); 24693 24694 this.thumbnail(target, this._videos[url]); 24695 }; 24696 24697 /** 24698 * Creates video thumbnail. 24699 * @protected 24700 * @param {jQuery} target - The target containing the video data. 24701 * @param {Object} info - The video info object. 24702 * @see `fetch` 24703 */ 24704 Video.prototype.thumbnail = function(target, video) { 24705 var tnLink, 24706 icon, 24707 path, 24708 dimensions = video.width && video.height ? 'style="width:' + video.width + 'px;height:' + video.height + 'px;"' : '', 24709 customTn = target.find('img'), 24710 srcType = 'src', 24711 lazyClass = '', 24712 settings = this._core.settings, 24713 create = function(path) { 24714 icon = '<div class="owl-video-play-icon"></div>'; 24715 24716 if (settings.lazyLoad) { 24717 tnLink = '<div class="owl-video-tn ' + lazyClass + '" ' + srcType + '="' + path + '"></div>'; 24718 } else { 24719 tnLink = '<div class="owl-video-tn" style="opacity:1;background-image:url(' + path + ')"></div>'; 24720 } 24721 target.after(tnLink); 24722 target.after(icon); 24723 }; 24724 24725 // wrap video content into owl-video-wrapper div 24726 target.wrap('<div class="owl-video-wrapper"' + dimensions + '></div>'); 24727 24728 if (this._core.settings.lazyLoad) { 24729 srcType = 'data-src'; 24730 lazyClass = 'owl-lazy'; 24731 } 24732 24733 // custom thumbnail 24734 if (customTn.length) { 24735 create(customTn.attr(srcType)); 24736 customTn.remove(); 24737 return false; 24738 } 24739 24740 if (video.type === 'youtube') { 24741 path = "//img.youtube.com/vi/" + video.id + "/hqdefault.jpg"; 24742 create(path); 24743 } else if (video.type === 'vimeo') { 24744 $.ajax({ 24745 type: 'GET', 24746 url: '//vimeo.com/api/v2/video/' + video.id + '.json', 24747 jsonp: 'callback', 24748 dataType: 'jsonp', 24749 success: function(data) { 24750 path = data[0].thumbnail_large; 24751 create(path); 24752 } 24753 }); 24754 } 24755 }; 24756 24757 /** 24758 * Stops the current video. 24759 * @public 24760 */ 24761 Video.prototype.stop = function() { 24762 this._core.trigger('stop', null, 'video'); 24763 this._playing.find('.owl-video-frame').remove(); 24764 this._playing.removeClass('owl-video-playing'); 24765 this._playing = null; 24766 this._core.leave('playing'); 24767 this._core.trigger('stopped', null, 'video'); 24768 }; 24769 24770 /** 24771 * Starts the current video. 24772 * @public 24773 * @param {Event} event - The event arguments. 24774 */ 24775 Video.prototype.play = function(event) { 24776 var target = $(event.target), 24777 item = target.closest('.' + this._core.settings.itemClass), 24778 video = this._videos[item.attr('data-video')], 24779 width = video.width || '100%', 24780 height = video.height || this._core.$stage.height(), 24781 html; 24782 24783 if (this._playing) { 24784 return; 24785 } 24786 24787 this._core.enter('playing'); 24788 this._core.trigger('play', null, 'video'); 24789 24790 item = this._core.items(this._core.relative(item.index())); 24791 24792 this._core.reset(item.index()); 24793 24794 if (video.type === 'youtube') { 24795 html = '<iframe width="' + width + '" height="' + height + '" src="//www.youtube.com/embed/' + 24796 video.id + '?autoplay=1&v=' + video.id + '" frameborder="0" allowfullscreen></iframe>'; 24797 } else if (video.type === 'vimeo') { 24798 html = '<iframe src="//player.vimeo.com/video/' + video.id + 24799 '?autoplay=1" width="' + width + '" height="' + height + 24800 '" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>'; 24801 } 24802 24803 $('<div class="owl-video-frame">' + html + '</div>').insertAfter(item.find('.owl-video')); 24804 24805 this._playing = item.addClass('owl-video-playing'); 24806 }; 24807 24808 /** 24809 * Checks whether an video is currently in full screen mode or not. 24810 * @todo Bad style because looks like a readonly method but changes members. 24811 * @protected 24812 * @returns {Boolean} 24813 */ 24814 Video.prototype.isInFullScreen = function() { 24815 var element = document.fullscreenElement || document.mozFullScreenElement || 24816 document.webkitFullscreenElement; 24817 24818 return element && $(element).parent().hasClass('owl-video-frame'); 24819 }; 24820 24821 /** 24822 * Destroys the plugin. 24823 */ 24824 Video.prototype.destroy = function() { 24825 var handler, property; 24826 24827 this._core.$element.off('click.owl.video'); 24828 24829 for (handler in this._handlers) { 24830 this._core.$element.off(handler, this._handlers[handler]); 24831 } 24832 for (property in Object.getOwnPropertyNames(this)) { 24833 typeof this[property] != 'function' && (this[property] = null); 24834 } 24835 }; 24836 24837 $.fn.owlCarousel.Constructor.Plugins.Video = Video; 24838 24839})(window.Zepto || window.jQuery, window, document); 24840 24841/** 24842 * Animate Plugin 24843 * @version 2.0.0-beta.3 24844 * @author Bartosz Wojciechowski 24845 * @license The MIT License (MIT) 24846 */ 24847;(function($, window, document, undefined) { 24848 24849 /** 24850 * Creates the animate plugin. 24851 * @class The Navigation Plugin 24852 * @param {Owl} scope - The Owl Carousel 24853 */ 24854 var Animate = function(scope) { 24855 this.core = scope; 24856 this.core.options = $.extend({}, Animate.Defaults, this.core.options); 24857 this.swapping = true; 24858 this.previous = undefined; 24859 this.next = undefined; 24860 24861 this.handlers = { 24862 'change.owl.carousel': $.proxy(function(e) { 24863 if (e.namespace && e.property.name == 'position') { 24864 this.previous = this.core.current(); 24865 this.next = e.property.value; 24866 } 24867 }, this), 24868 'drag.owl.carousel dragged.owl.carousel translated.owl.carousel': $.proxy(function(e) { 24869 if (e.namespace) { 24870 this.swapping = e.type == 'translated'; 24871 } 24872 }, this), 24873 'translate.owl.carousel': $.proxy(function(e) { 24874 if (e.namespace && this.swapping && (this.core.options.animateOut || this.core.options.animateIn)) { 24875 this.swap(); 24876 } 24877 }, this) 24878 }; 24879 24880 this.core.$element.on(this.handlers); 24881 }; 24882 24883 /** 24884 * Default options. 24885 * @public 24886 */ 24887 Animate.Defaults = { 24888 animateOut: false, 24889 animateIn: false 24890 }; 24891 24892 /** 24893 * Toggles the animation classes whenever an translations starts. 24894 * @protected 24895 * @returns {Boolean|undefined} 24896 */ 24897 Animate.prototype.swap = function() { 24898 24899 if (this.core.settings.items !== 1) { 24900 return; 24901 } 24902 24903 if (!$.support.animation || !$.support.transition) { 24904 return; 24905 } 24906 24907 this.core.speed(0); 24908 24909 var left, 24910 clear = $.proxy(this.clear, this), 24911 previous = this.core.$stage.children().eq(this.previous), 24912 next = this.core.$stage.children().eq(this.next), 24913 incoming = this.core.settings.animateIn, 24914 outgoing = this.core.settings.animateOut; 24915 24916 if (this.core.current() === this.previous) { 24917 return; 24918 } 24919 24920 if (outgoing) { 24921 left = this.core.coordinates(this.previous) - this.core.coordinates(this.next); 24922 previous.css( { 'left': left + 'px' } ) 24923 .addClass('animated owl-animated-out') 24924 .addClass(outgoing) 24925 .on($.support.animation.end, clear); 24926 } 24927 24928 if (incoming) { 24929 next.addClass('animated owl-animated-in') 24930 .addClass(incoming) 24931 .on($.support.animation.end, clear); 24932 } 24933 }; 24934 24935 Animate.prototype.clear = function(e) { 24936 if ($(e.target).hasClass('animated')) { 24937 $(e.target).css( { 'left': '' } ) 24938 .removeClass('animated owl-animated-out owl-animated-in') 24939 .removeClass(this.core.settings.animateIn) 24940 .removeClass(this.core.settings.animateOut); 24941 this.core.onTransitionEnd(); 24942 } 24943 }; 24944 24945 /** 24946 * Destroys the plugin. 24947 * @public 24948 */ 24949 Animate.prototype.destroy = function() { 24950 var handler, property; 24951 24952 for (handler in this.handlers) { 24953 this.core.$element.off(handler, this.handlers[handler]); 24954 } 24955 for (property in Object.getOwnPropertyNames(this)) { 24956 typeof this[property] != 'function' && (this[property] = null); 24957 } 24958 }; 24959 24960 $.fn.owlCarousel.Constructor.Plugins.Animate = Animate; 24961 24962})(window.Zepto || window.jQuery, window, document); 24963 24964/** 24965 * Autoplay Plugin 24966 * @version 2.0.0-beta.3 24967 * @author Bartosz Wojciechowski 24968 * @author Artus Kolanowski 24969 * @license The MIT License (MIT) 24970 */ 24971;(function($, window, document, undefined) { 24972 24973 /** 24974 * Creates the autoplay plugin. 24975 * @class The Autoplay Plugin 24976 * @param {Owl} scope - The Owl Carousel 24977 */ 24978 var Autoplay = function(carousel) { 24979 /** 24980 * Reference to the core. 24981 * @protected 24982 * @type {Owl} 24983 */ 24984 this._core = carousel; 24985 24986 /** 24987 * The autoplay interval. 24988 * @type {Number} 24989 */ 24990 this._interval = null; 24991 24992 /** 24993 * Indicates whenever the autoplay is paused. 24994 * @type {Boolean} 24995 */ 24996 this._paused = false; 24997 24998 /** 24999 * All event handlers. 25000 * @protected 25001 * @type {Object} 25002 */ 25003 this._handlers = { 25004 'changed.owl.carousel': $.proxy(function(e) { 25005 if (e.namespace && e.property.name === 'settings') { 25006 if (this._core.settings.autoplay) { 25007 this.play(); 25008 } else { 25009 this.stop(); 25010 } 25011 } 25012 }, this), 25013 'initialized.owl.carousel': $.proxy(function(e) { 25014 if (e.namespace && this._core.settings.autoplay) { 25015 this.play(); 25016 } 25017 }, this), 25018 'play.owl.autoplay': $.proxy(function(e, t, s) { 25019 if (e.namespace) { 25020 this.play(t, s); 25021 } 25022 }, this), 25023 'stop.owl.autoplay': $.proxy(function(e) { 25024 if (e.namespace) { 25025 this.stop(); 25026 } 25027 }, this), 25028 'mouseover.owl.autoplay': $.proxy(function() { 25029 if (this._core.settings.autoplayHoverPause && this._core.is('rotating')) { 25030 this.pause(); 25031 } 25032 }, this), 25033 'mouseleave.owl.autoplay': $.proxy(function() { 25034 if (this._core.settings.autoplayHoverPause && this._core.is('rotating')) { 25035 this.play(); 25036 } 25037 }, this) 25038 }; 25039 25040 // register event handlers 25041 this._core.$element.on(this._handlers); 25042 25043 // set default options 25044 this._core.options = $.extend({}, Autoplay.Defaults, this._core.options); 25045 }; 25046 25047 /** 25048 * Default options. 25049 * @public 25050 */ 25051 Autoplay.Defaults = { 25052 autoplay: false, 25053 autoplayTimeout: 5000, 25054 autoplayHoverPause: false, 25055 autoplaySpeed: false 25056 }; 25057 25058 /** 25059 * Starts the autoplay. 25060 * @public 25061 * @param {Number} [timeout] - The interval before the next animation starts. 25062 * @param {Number} [speed] - The animation speed for the animations. 25063 */ 25064 Autoplay.prototype.play = function(timeout, speed) { 25065 this._paused = false; 25066 25067 if (this._core.is('rotating')) { 25068 return; 25069 } 25070 25071 this._core.enter('rotating'); 25072 25073 this._interval = window.setInterval($.proxy(function() { 25074 if (this._paused || this._core.is('busy') || this._core.is('interacting') || document.hidden) { 25075 return; 25076 } 25077 this._core.next(speed || this._core.settings.autoplaySpeed); 25078 }, this), timeout || this._core.settings.autoplayTimeout); 25079 }; 25080 25081 /** 25082 * Stops the autoplay. 25083 * @public 25084 */ 25085 Autoplay.prototype.stop = function() { 25086 if (!this._core.is('rotating')) { 25087 return; 25088 } 25089 25090 window.clearInterval(this._interval); 25091 this._core.leave('rotating'); 25092 }; 25093 25094 /** 25095 * Stops the autoplay. 25096 * @public 25097 */ 25098 Autoplay.prototype.pause = function() { 25099 if (!this._core.is('rotating')) { 25100 return; 25101 } 25102 25103 this._paused = true; 25104 }; 25105 25106 /** 25107 * Destroys the plugin. 25108 */ 25109 Autoplay.prototype.destroy = function() { 25110 var handler, property; 25111 25112 this.stop(); 25113 25114 for (handler in this._handlers) { 25115 this._core.$element.off(handler, this._handlers[handler]); 25116 } 25117 for (property in Object.getOwnPropertyNames(this)) { 25118 typeof this[property] != 'function' && (this[property] = null); 25119 } 25120 }; 25121 25122 $.fn.owlCarousel.Constructor.Plugins.autoplay = Autoplay; 25123 25124})(window.Zepto || window.jQuery, window, document); 25125 25126/** 25127 * Navigation Plugin 25128 * @version 2.0.0-beta.3 25129 * @author Artus Kolanowski 25130 * @license The MIT License (MIT) 25131 */ 25132;(function($, window, document, undefined) { 25133 'use strict'; 25134 25135 /** 25136 * Creates the navigation plugin. 25137 * @class The Navigation Plugin 25138 * @param {Owl} carousel - The Owl Carousel. 25139 */ 25140 var Navigation = function(carousel) { 25141 /** 25142 * Reference to the core. 25143 * @protected 25144 * @type {Owl} 25145 */ 25146 this._core = carousel; 25147 25148 /** 25149 * Indicates whether the plugin is initialized or not. 25150 * @protected 25151 * @type {Boolean} 25152 */ 25153 this._initialized = false; 25154 25155 /** 25156 * The current paging indexes. 25157 * @protected 25158 * @type {Array} 25159 */ 25160 this._pages = []; 25161 25162 /** 25163 * All DOM elements of the user interface. 25164 * @protected 25165 * @type {Object} 25166 */ 25167 this._controls = {}; 25168 25169 /** 25170 * Markup for an indicator. 25171 * @protected 25172 * @type {Array.<String>} 25173 */ 25174 this._templates = []; 25175 25176 /** 25177 * The carousel element. 25178 * @type {jQuery} 25179 */ 25180 this.$element = this._core.$element; 25181 25182 /** 25183 * Overridden methods of the carousel. 25184 * @protected 25185 * @type {Object} 25186 */ 25187 this._overrides = { 25188 next: this._core.next, 25189 prev: this._core.prev, 25190 to: this._core.to 25191 }; 25192 25193 /** 25194 * All event handlers. 25195 * @protected 25196 * @type {Object} 25197 */ 25198 this._handlers = { 25199 'prepared.owl.carousel': $.proxy(function(e) { 25200 if (e.namespace && this._core.settings.dotsData) { 25201 this._templates.push('<div class="' + this._core.settings.dotClass + '">' + 25202 $(e.content).find('[data-dot]').andSelf('[data-dot]').attr('data-dot') + '</div>'); 25203 } 25204 }, this), 25205 'added.owl.carousel': $.proxy(function(e) { 25206 if (e.namespace && this._core.settings.dotsData) { 25207 this._templates.splice(e.position, 0, this._templates.pop()); 25208 } 25209 }, this), 25210 'remove.owl.carousel': $.proxy(function(e) { 25211 if (e.namespace && this._core.settings.dotsData) { 25212 this._templates.splice(e.position, 1); 25213 } 25214 }, this), 25215 'changed.owl.carousel': $.proxy(function(e) { 25216 if (e.namespace && e.property.name == 'position') { 25217 this.draw(); 25218 } 25219 }, this), 25220 'initialized.owl.carousel': $.proxy(function(e) { 25221 if (e.namespace && !this._initialized) { 25222 this._core.trigger('initialize', null, 'navigation'); 25223 this.initialize(); 25224 this.update(); 25225 this.draw(); 25226 this._initialized = true; 25227 this._core.trigger('initialized', null, 'navigation'); 25228 } 25229 }, this), 25230 'refreshed.owl.carousel': $.proxy(function(e) { 25231 if (e.namespace && this._initialized) { 25232 this._core.trigger('refresh', null, 'navigation'); 25233 this.update(); 25234 this.draw(); 25235 this._core.trigger('refreshed', null, 'navigation'); 25236 } 25237 }, this) 25238 }; 25239 25240 // set default options 25241 this._core.options = $.extend({}, Navigation.Defaults, this._core.options); 25242 25243 // register event handlers 25244 this.$element.on(this._handlers); 25245 }; 25246 25247 /** 25248 * Default options. 25249 * @public 25250 * @todo Rename `slideBy` to `navBy` 25251 */ 25252 Navigation.Defaults = { 25253 nav: false, 25254 navText: [ 'prev', 'next' ], 25255 navSpeed: false, 25256 navElement: 'div', 25257 navContainer: false, 25258 navContainerClass: 'owl-nav', 25259 navClass: [ 'owl-prev', 'owl-next' ], 25260 slideBy: 1, 25261 dotClass: 'owl-dot', 25262 dotsClass: 'owl-dots', 25263 dots: true, 25264 dotsEach: false, 25265 dotsData: false, 25266 dotsSpeed: false, 25267 dotsContainer: false 25268 }; 25269 25270 /** 25271 * Initializes the layout of the plugin and extends the carousel. 25272 * @protected 25273 */ 25274 Navigation.prototype.initialize = function() { 25275 var override, 25276 settings = this._core.settings; 25277 25278 // create DOM structure for relative navigation 25279 this._controls.$relative = (settings.navContainer ? $(settings.navContainer) 25280 : $('<div>').addClass(settings.navContainerClass).appendTo(this.$element)).addClass('disabled'); 25281 25282 this._controls.$previous = $('<' + settings.navElement + '>') 25283 .addClass(settings.navClass[0]) 25284 .html(settings.navText[0]) 25285 .prependTo(this._controls.$relative) 25286 .on('click', $.proxy(function(e) { 25287 this.prev(settings.navSpeed); 25288 }, this)); 25289 this._controls.$next = $('<' + settings.navElement + '>') 25290 .addClass(settings.navClass[1]) 25291 .html(settings.navText[1]) 25292 .appendTo(this._controls.$relative) 25293 .on('click', $.proxy(function(e) { 25294 this.next(settings.navSpeed); 25295 }, this)); 25296 25297 // create DOM structure for absolute navigation 25298 if (!settings.dotsData) { 25299 this._templates = [ $('<div>') 25300 .addClass(settings.dotClass) 25301 .append($('<span>')) 25302 .prop('outerHTML') ]; 25303 } 25304 25305 this._controls.$absolute = (settings.dotsContainer ? $(settings.dotsContainer) 25306 : $('<div>').addClass(settings.dotsClass).appendTo(this.$element)).addClass('disabled'); 25307 25308 this._controls.$absolute.on('click', 'div', $.proxy(function(e) { 25309 var index = $(e.target).parent().is(this._controls.$absolute) 25310 ? $(e.target).index() : $(e.target).parent().index(); 25311 25312 e.preventDefault(); 25313 25314 this.to(index, settings.dotsSpeed); 25315 }, this)); 25316 25317 // override public methods of the carousel 25318 for (override in this._overrides) { 25319 this._core[override] = $.proxy(this[override], this); 25320 } 25321 }; 25322 25323 /** 25324 * Destroys the plugin. 25325 * @protected 25326 */ 25327 Navigation.prototype.destroy = function() { 25328 var handler, control, property, override; 25329 25330 for (handler in this._handlers) { 25331 this.$element.off(handler, this._handlers[handler]); 25332 } 25333 for (control in this._controls) { 25334 this._controls[control].remove(); 25335 } 25336 for (override in this.overides) { 25337 this._core[override] = this._overrides[override]; 25338 } 25339 for (property in Object.getOwnPropertyNames(this)) { 25340 typeof this[property] != 'function' && (this[property] = null); 25341 } 25342 }; 25343 25344 /** 25345 * Updates the internal state. 25346 * @protected 25347 */ 25348 Navigation.prototype.update = function() { 25349 var i, j, k, 25350 lower = this._core.clones().length / 2, 25351 upper = lower + this._core.items().length, 25352 maximum = this._core.maximum(true), 25353 settings = this._core.settings, 25354 size = settings.center || settings.autoWidth || settings.dotsData 25355 ? 1 : settings.dotsEach || settings.items; 25356 25357 if (settings.slideBy !== 'page') { 25358 settings.slideBy = Math.min(settings.slideBy, settings.items); 25359 } 25360 25361 if (settings.dots || settings.slideBy == 'page') { 25362 this._pages = []; 25363 25364 for (i = lower, j = 0, k = 0; i < upper; i++) { 25365 if (j >= size || j === 0) { 25366 this._pages.push({ 25367 start: Math.min(maximum, i - lower), 25368 end: i - lower + size - 1 25369 }); 25370 if (Math.min(maximum, i - lower) === maximum) { 25371 break; 25372 } 25373 j = 0, ++k; 25374 } 25375 j += this._core.mergers(this._core.relative(i)); 25376 } 25377 } 25378 }; 25379 25380 /** 25381 * Draws the user interface. 25382 * @todo The option `dotsData` wont work. 25383 * @protected 25384 */ 25385 Navigation.prototype.draw = function() { 25386 var difference, 25387 settings = this._core.settings, 25388 disabled = this._core.items().length <= settings.items, 25389 index = this._core.relative(this._core.current()), 25390 loop = settings.loop || settings.rewind; 25391 25392 this._controls.$relative.toggleClass('disabled', !settings.nav || disabled); 25393 25394 if (settings.nav) { 25395 this._controls.$previous.toggleClass('disabled', !loop && index <= this._core.minimum(true)); 25396 this._controls.$next.toggleClass('disabled', !loop && index >= this._core.maximum(true)); 25397 } 25398 25399 this._controls.$absolute.toggleClass('disabled', !settings.dots || disabled); 25400 25401 if (settings.dots) { 25402 difference = this._pages.length - this._controls.$absolute.children().length; 25403 25404 if (settings.dotsData && difference !== 0) { 25405 this._controls.$absolute.html(this._templates.join('')); 25406 } else if (difference > 0) { 25407 this._controls.$absolute.append(new Array(difference + 1).join(this._templates[0])); 25408 } else if (difference < 0) { 25409 this._controls.$absolute.children().slice(difference).remove(); 25410 } 25411 25412 this._controls.$absolute.find('.active').removeClass('active'); 25413 this._controls.$absolute.children().eq($.inArray(this.current(), this._pages)).addClass('active'); 25414 } 25415 }; 25416 25417 /** 25418 * Extends event data. 25419 * @protected 25420 * @param {Event} event - The event object which gets thrown. 25421 */ 25422 Navigation.prototype.onTrigger = function(event) { 25423 var settings = this._core.settings; 25424 25425 event.page = { 25426 index: $.inArray(this.current(), this._pages), 25427 count: this._pages.length, 25428 size: settings && (settings.center || settings.autoWidth || settings.dotsData 25429 ? 1 : settings.dotsEach || settings.items) 25430 }; 25431 }; 25432 25433 /** 25434 * Gets the current page position of the carousel. 25435 * @protected 25436 * @returns {Number} 25437 */ 25438 Navigation.prototype.current = function() { 25439 var current = this._core.relative(this._core.current()); 25440 return $.grep(this._pages, $.proxy(function(page, index) { 25441 return page.start <= current && page.end >= current; 25442 }, this)).pop(); 25443 }; 25444 25445 /** 25446 * Gets the current succesor/predecessor position. 25447 * @protected 25448 * @returns {Number} 25449 */ 25450 Navigation.prototype.getPosition = function(successor) { 25451 var position, length, 25452 settings = this._core.settings; 25453 25454 if (settings.slideBy == 'page') { 25455 position = $.inArray(this.current(), this._pages); 25456 length = this._pages.length; 25457 successor ? ++position : --position;
vendor: 5,678 bytes, lines 25458-25682
25458 position = this._pages[((position % length) + length) % length].start; 25459 } else { 25460 position = this._core.relative(this._core.current()); 25461 length = this._core.items().length; 25462 successor ? position += settings.slideBy : position -= settings.slideBy; 25463 } 25464 25465 return position; 25466 }; 25467 25468 /** 25469 * Slides to the next item or page. 25470 * @public 25471 * @param {Number} [speed=false] - The time in milliseconds for the transition. 25472 */ 25473 Navigation.prototype.next = function(speed) { 25474 $.proxy(this._overrides.to, this._core)(this.getPosition(true), speed); 25475 }; 25476 25477 /** 25478 * Slides to the previous item or page. 25479 * @public 25480 * @param {Number} [speed=false] - The time in milliseconds for the transition. 25481 */ 25482 Navigation.prototype.prev = function(speed) { 25483 $.proxy(this._overrides.to, this._core)(this.getPosition(false), speed); 25484 }; 25485 25486 /** 25487 * Slides to the specified item or page. 25488 * @public 25489 * @param {Number} position - The position of the item or page. 25490 * @param {Number} [speed] - The time in milliseconds for the transition. 25491 * @param {Boolean} [standard=false] - Whether to use the standard behaviour or not. 25492 */ 25493 Navigation.prototype.to = function(position, speed, standard) { 25494 var length; 25495 25496 if (!standard) { 25497 length = this._pages.length; 25498 $.proxy(this._overrides.to, this._core)(this._pages[((position % length) + length) % length].start, speed); 25499 } else { 25500 $.proxy(this._overrides.to, this._core)(position, speed); 25501 } 25502 }; 25503 25504 $.fn.owlCarousel.Constructor.Plugins.Navigation = Navigation; 25505 25506})(window.Zepto || window.jQuery, window, document); 25507 25508/** 25509 * Hash Plugin 25510 * @version 2.0.0-beta.3 25511 * @author Artus Kolanowski 25512 * @license The MIT License (MIT) 25513 */ 25514;(function($, window, document, undefined) { 25515 'use strict'; 25516 25517 /** 25518 * Creates the hash plugin. 25519 * @class The Hash Plugin 25520 * @param {Owl} carousel - The Owl Carousel 25521 */ 25522 var Hash = function(carousel) { 25523 /** 25524 * Reference to the core. 25525 * @protected 25526 * @type {Owl} 25527 */ 25528 this._core = carousel; 25529 25530 /** 25531 * Hash index for the items. 25532 * @protected 25533 * @type {Object} 25534 */ 25535 this._hashes = {}; 25536 25537 /** 25538 * The carousel element. 25539 * @type {jQuery} 25540 */ 25541 this.$element = this._core.$element; 25542 25543 /** 25544 * All event handlers. 25545 * @protected 25546 * @type {Object} 25547 */ 25548 this._handlers = { 25549 /*'initialized.owl.carousel': $.proxy(function(e) { 25550 if (e.namespace && this._core.settings.startPosition === 'URLHash') { 25551 $(window).trigger('hashchange.owl.navigation'); 25552 } 25553 }, this),*/ 25554 'prepared.owl.carousel': $.proxy(function(e) { 25555 if (e.namespace) { 25556 var hash = $(e.content).find('[data-hash]').addBack('[data-hash]').attr('data-hash'); 25557 25558 if (!hash) { 25559 return; 25560 } 25561 25562 this._hashes[hash] = e.content; 25563 } 25564 }, this), 25565 'changed.owl.carousel': $.proxy(function(e) { 25566 if (e.namespace && e.property.name === 'position') { 25567 var current = this._core.items(this._core.relative(this._core.current())), 25568 hash = $.map(this._hashes, function(item, hash) { 25569 return item === current ? hash : null; 25570 }).join(); 25571 25572 if (!hash || window.location.hash.slice(1) === hash) { 25573 return; 25574 } 25575 25576 window.location.hash = hash; 25577 } 25578 }, this) 25579 }; 25580 25581 // set default options 25582 this._core.options = $.extend({}, Hash.Defaults, this._core.options); 25583 25584 // register the event handlers 25585 this.$element.on(this._handlers); 25586 25587 // register event listener for hash navigation 25588 /*$(window).on('hashchange.owl.navigation', $.proxy(function(e) { 25589 var hash = window.location.hash.substring(1), 25590 items = this._core.$stage.children(), 25591 position = this._hashes[hash] && items.index(this._hashes[hash]); 25592 25593 if (position === undefined || position === this._core.current()) { 25594 return; 25595 } 25596 25597 this._core.to(this._core.relative(position), false, true); 25598 }, this));*/ 25599 }; 25600 25601 /** 25602 * Default options. 25603 * @public 25604 */ 25605 Hash.Defaults = { 25606 URLhashListener: false 25607 }; 25608 25609 /** 25610 * Destroys the plugin. 25611 * @public 25612 */ 25613 Hash.prototype.destroy = function() { 25614 var handler, property; 25615 25616 $(window).off('hashchange.owl.navigation'); 25617 25618 for (handler in this._handlers) { 25619 this._core.$element.off(handler, this._handlers[handler]); 25620 } 25621 for (property in Object.getOwnPropertyNames(this)) { 25622 typeof this[property] != 'function' && (this[property] = null); 25623 } 25624 }; 25625 25626 $.fn.owlCarousel.Constructor.Plugins.Hash = Hash; 25627 25628})(window.Zepto || window.jQuery, window, document); 25629 25630/** 25631 * Support Plugin 25632 * 25633 * @version 2.0.0-beta.3 25634 * @author Vivid Planet Software GmbH 25635 * @author Artus Kolanowski 25636 * @license The MIT License (MIT) 25637 */ 25638;(function($, window, document, undefined) { 25639 25640 var style = $('<support>').get(0).style, 25641 prefixes = 'Webkit Moz O ms'.split(' '), 25642 events = { 25643 transition: { 25644 end: { 25645 WebkitTransition: 'webkitTransitionEnd', 25646 MozTransition: 'transitionend', 25647 OTransition: 'oTransitionEnd', 25648 transition: 'transitionend' 25649 } 25650 }, 25651 animation: { 25652 end: { 25653 WebkitAnimation: 'webkitAnimationEnd', 25654 MozAnimation: 'animationend', 25655 OAnimation: 'oAnimationEnd', 25656 animation: 'animationend' 25657 } 25658 } 25659 }, 25660 tests = { 25661 csstransforms: function() { 25662 return !!test('transform'); 25663 }, 25664 csstransforms3d: function() { 25665 return !!test('perspective'); 25666 }, 25667 csstransitions: function() { 25668 return !!test('transition'); 25669 }, 25670 cssanimations: function() { 25671 return !!test('animation'); 25672 } 25673 }; 25674 25675 function test(property, prefixed) { 25676 var result = false, 25677 upper = property.charAt(0).toUpperCase() + property.slice(1); 25678 25679 $.each((property + ' ' + prefixes.join(upper + ' ') + upper).split(' '), function(i, property) { 25680 if (style[property] !== undefined) { 25681 result = prefixed ? property : true; 25682 return false;
25683 } 25684 }); 25685 25686 return result; 25687 } 25688 25689 function prefixed(property) { 25690 return test(property, true); 25691 } 25692 25693 if (tests.csstransitions()) { 25694 /* jshint -W053 */ 25695 $.support.transition = new String(prefixed('transition')) 25696 $.support.transition.end = events.transition.end[ $.support.transition ]; 25697 } 25698 25699 if (tests.cssanimations()) { 25700 /* jshint -W053 */ 25701 $.support.animation = new String(prefixed('animation')) 25702 $.support.animation.end = events.animation.end[ $.support.animation ]; 25703 } 25704 25705 if (tests.csstransforms()) { 25706 /* jshint -W053 */ 25707 $.support.transform = new String(prefixed('transform')); 25708 $.support.transform3d = tests.csstransforms3d(); 25709 } 25710 25711})(window.Zepto || window.jQuery, window, document); 25712 25713(function(window, document, undefined) { 25714 25715 /** 25716 * Find the absolute position of an element 25717 */ 25718 var absPos = function(element) { 25719 var offsetLeft, offsetTop; 25720 offsetLeft = offsetTop = 0; 25721 if (element.offsetParent) { 25722 do { 25723 offsetLeft += element.offsetLeft; 25724 offsetTop += element.offsetTop; 25725 } while (element = element.offsetParent); 25726 } 25727 return [offsetLeft, offsetTop]; 25728 }; 25729 25730 /** 25731 * @constructor Progress Circle class 25732 * @param params.canvas Canvas on which the circles will be drawn. 25733 * @param params.minRadius Inner radius of the innermost circle, in px. 25734 * @param params.arcWidth Width of each circle(to be more accurate, ring). 25735 * @param params.gapWidth Space between each circle. 25736 * @param params.centerX X coordinate of the center of circles. 25737 * @param params.centerY Y coordinate of the center of circles. 25738 * @param params.infoLineBaseAngle Base angle of the info line. 25739 * @param params.infoLineAngleInterval Angles between the info lines. 25740 */ 25741 var ProgressCircle = function(params) { 25742 this.canvas = params.canvas; 25743 this.minRadius = params.minRadius || 15; 25744 this.arcWidth = params.arcWidth || 5; 25745 this.gapWidth = params.gapWidth || 3; 25746 this.centerX = params.centerX || this.canvas.width / 2; 25747 this.centerY = params.centerY || this.canvas.height / 2;
25748 this.infoLineLength = params.infoLineLength || 60; 25749 this.horizLineLength = params.horizLineLength || 10; 25750 this.infoLineAngleInterval = params.infoLineAngleInterval || Math.PI / 8; 25751 this.infoLineBaseAngle = params.infoLineBaseAngle || Math.PI / 6; 25752 25753 this.context = this.canvas.getContext('2d'); 25754 25755 this.width = this.canvas.width; 25756 this.height = this.canvas.height; 25757 25758 this.circles = []; 25759 this.runningCount = 0; 25760 }; 25761 25762 ProgressCircle.prototype = { 25763 constructor: ProgressCircle, 25764 25765 /** 25766 * @method Adds an progress monitor entry. 25767 * @param params.fillColor Color to fill in the circle. 25768 * @param params.outlineColor Color to outline the circle. 25769 * @param params.progressListener Callback function to fetch the progress. 25770 * @param params.infoListener Callback function to fetch the info. 25771 * @returns this 25772 */ 25773 addEntry: function(params) { 25774 this.circles.push(new Circle({ 25775 canvas: this.canvas, 25776 context: this.context, 25777 centerX: this.centerX, 25778 centerY: this.centerY, 25779 innerRadius: this.minRadius + this.circles.length * 25780 (this.gapWidth + this.arcWidth), 25781 arcWidth: this.arcWidth,
25782 infoLineLength: this.infoLineLength, 25783 horizLineLength: this.horizLineLength, 25784 25785 id: this.circles.length, 25786 fillColor: params.fillColor, 25787 outlineColor: params.outlineColor, 25788 progressListener: params.progressListener, 25789 infoListener: params.infoListener, 25790 infoLineAngle: this.infoLineBaseAngle + 25791 this.circles.length * this.infoLineAngleInterval, 25792 })); 25793 25794 return this; 25795 }, 25796 25797 /** 25798 * @method Starts the monitor and updates with the given interval. 25799 * @param interval Interval between updates, in millisecond. 25800 * @returns this 25801 */ 25802 start: function(interval) { 25803 var self = this; 25804 this.timer = setInterval(function() { 25805 self._update(); 25806 }, interval || 33); 25807 25808 return this; 25809 }, 25810 25811 /** 25812 * @method Stop the animation. 25813 */ 25814 stop: function() { 25815 clearTimeout(this.timer); 25816 }, 25817 25818 /** 25819 * @private 25820 * @method Call update on each circle and redraw them. 25821 * @returns this 25822 */ 25823 _update: function() { 25824 this._clear(); 25825 this.circles.forEach(function(circle, idx, array) { 25826 circle.update(); 25827 }); 25828 25829 return this; 25830 }, 25831 25832 /** 25833 * @private 25834 * @method Clear the canvas. 25835 * @returns this 25836 */ 25837 _clear: function() { 25838 this.context.clearRect(0, 0, this.canvas.width, this.canvas.height); 25839 25840 return this; 25841 }, 25842 25843 }; 25844 25845 /** 25846 * @private 25847 * @class Individual progress circle. 25848 * @param params.canvas Canvas on which the circle will be drawn. 25849 * @param params.context Context of the canvas. 25850 * @param params.innerRadius Inner radius of the circle, in px. 25851 * @param params.arcWidth Width of each arc(circle). 25852 * @param params.gapWidth Distance between each arc. 25853 * @param params.centerX X coordinate of the center of circles. 25854 * @param params.centerY Y coordinate of the center of circles. 25855 * @param params.fillColor Color to fill in the circle. 25856 * @param params.outlineColor Color to outline the circle. 25857 * @param params.progressListener Callback function to fetch the progress. 25858 * @param params.infoListener Callback function to fetch the info. 25859 * @param params.infoLineAngle Angle of info line. 25860 */ 25861 var Circle = function(params) { 25862 this.id = params.id; 25863 this.canvas = params.canvas; 25864 this.context = params.context; 25865 this.centerX = params.centerX; 25866 this.centerY = params.centerY; 25867 this.arcWidth = params.arcWidth; 25868 this.innerRadius = params.innerRadius || 0; 25869 this.fillColor = params.fillColor || '#fff'; 25870 this.outlineColor = params.outlineColor || this.fillColor; 25871 this.progressListener = params.progressListener;
25872 this.infoLineLength = params.infoLineLength || 250; 25873 this.horizLineLength = params.horizLineLength || 50; 25874 this.infoListener = params.infoListener; 25875 this.infoLineAngle = params.infoLineAngle; 25876 25877 this.outerRadius = this.innerRadius + this.arcWidth; 25878 25879 // If the info listener is not registered, then don't calculate 25880 // the related coordinates 25881 if (!this.infoListener) return; 25882 25883 // calculate the info-line turning points 25884 var angle = this.infoLineAngle, 25885 arcDistance = (this.innerRadius + this.outerRadius) / 2, 25886 25887 sinA = Math.sin(angle), 25888 cosA = Math.cos(angle); 25889 25890 this.infoLineStartX = this.centerX + sinA * arcDistance; 25891 this.infoLineStartY = this.centerY - cosA * arcDistance; 25892 25893 this.infoLineMidX = this.centerX + sinA * this.infoLineLength; 25894 this.infoLineMidY = this.centerY - cosA * this.infoLineLength; 25895 25896 this.infoLineEndX = this.infoLineMidX + 25897 (sinA < 0 ? -this.horizLineLength : this.horizLineLength); 25898 this.infoLineEndY = this.infoLineMidY; 25899 25900 var infoText = document.createElement('div'), 25901 style = infoText.style; 25902 25903 style.color = this.fillColor; 25904 style.position = 'absolute'; 25905 style.left = this.infoLineEndX + absPos(this.canvas)[0] + 'px'; 25906 // style.top will be calculated in the `drawInfo` method. Since 25907 // user may want to change the size of the font, so the top offset 25908 // must be updated in each loop. 25909 infoText.className = 'ProgressCircleInfo'; // For css styling 25910 infoText.id = 'progress_circle_info_' + this.id; 25911 document.body.appendChild(infoText); 25912 this.infoText = infoText; 25913 }; 25914 25915 Circle.prototype = { 25916 constructor: Circle, 25917 25918 update: function() { 25919 this.progress = this.progressListener(); 25920 this._draw(); 25921 25922 if (this.infoListener) { 25923 this.info = this.infoListener(); 25924 this._drawInfo(); 25925 } 25926 }, 25927 25928 /** 25929 * @private 25930 * @method Draw the circle on the canvas. 25931 * @returns this 25932 */ 25933 _draw: function() { 25934 var ctx = this.context, 25935 25936 ANGLE_OFFSET = -Math.PI / 2, 25937 25938 startAngle = 0 + ANGLE_OFFSET, 25939 endAngle= startAngle + this.progress * Math.PI * 2, 25940 25941 x = this.centerX, 25942 y = this.centerY, 25943 25944 innerRadius = this.innerRadius - this.arcWidth - 1, 25945 outerRadius = this.outerRadius - this.arcWidth - 1; 25946 25947 if ( innerRadius < 0 ) 25948 return; 25949 25950 ctx.fillStyle = this.fillColor; 25951 ctx.strokeStyle = this.outlineColor; 25952 25953 ctx.beginPath(); 25954 ctx.arc(x, y, innerRadius, startAngle, endAngle, false); 25955 ctx.arc(x, y, outerRadius, endAngle, startAngle, true); 25956 ctx.closePath(); 25957 ctx.stroke(); 25958 ctx.fill(); 25959 25960 return this; 25961 }, 25962 25963 /** 25964 * @private 25965 * @method Draw the info lines and info text. 25966 * @returns this 25967 */ 25968 _drawInfo: function() { 25969 25970 var pointList, lineHeight; 25971 25972 pointList = [ 25973 [this.infoLineStartX, this.infoLineStartY], 25974 [this.infoLineMidX, this.infoLineMidY], 25975 [this.infoLineEndX, this.infoLineEndY], 25976 ]; 25977 this._drawSegments(pointList, false); 25978 25979 this.infoText.innerHTML = this.info; 25980 25981 lineHeight = this.infoText.offsetHeight; 25982 this.infoText.style.top = this.infoLineEndY + 25983 absPos(this.canvas)[1] - lineHeight / 2 + 'px'; 25984 25985 return this; 25986 }, 25987 25988 /** 25989 * @private 25990 * @method Helper function to draw the segments 25991 * @param pointList An array of points in the form of [x, y]. 25992 * @param close Whether to connect the first and last point. 25993 */ 25994 _drawSegments: function(pointList, close) { 25995 var ctx = this.context; 25996 25997 ctx.beginPath(); 25998 ctx.moveTo(pointList[0][0], pointList[0][1]); 25999 for (var i = 1; i < pointList.length; ++i) { 26000 ctx.lineTo(pointList[i][0], pointList[i][1]); 26001 } 26002 26003 if (close) { 26004 ctx.closePath(); 26005 } 26006 ctx.stroke(); 26007 }, 26008 }; 26009 26010 window.ProgressCircle = ProgressCircle; 26011 26012})(window, document); 26013 26014 26015 26016 26017/* ========================================================= 26018 * jquery.vc_chart.js v1.0 26019 * ========================================================= 26020 * Copyright 2013 Wpbakery 26021 * 26022 * Jquery chart plugin for the Visual Composer. 26023 * ========================================================= */ 26024(function($){ 26025 /** 26026 * Pie chart animated. 26027 * @param element - DOM element 26028 * @param options - settings object. 26029 * @constructor 26030 */ 26031 var VcChart = function(element, options) { 26032 this.el = element; 26033 this.$el = $(this.el); 26034 var $this = this; 26035 $this.options = $.extend({ 26036 color: 'wpb_button', 26037 units: '', 26038 width: '', 26039 label_selector: '.vc_pie_chart_value', 26040 back_selector: '.vc_pie_chart_back', 26041 responsive: true 26042 }, options); 26043 $this.init(); 26044 }; 26045 VcChart.prototype = { 26046 constructor: VcChart, 26047 _progress_v: 0, 26048 animated: false, 26049 colors: { 26050 'wpb_button': 'rgba(247, 247, 247, 1)', 26051 'btn-primary': 'rgba(0, 136, 204, 1)', 26052 'btn-info': 'rgba(88, 185, 218, 1)', 26053 'btn-success': 'rgba(106, 177, 101, 1)', 26054 'btn-warning': 'rgba(255, 153, 0, 1)', 26055 'btn-danger': 'rgba(255, 103, 91, 1)', 26056 'btn-inverse': 'rgba(85, 85, 85, 1)' 26057 }, 26058 init: function() { 26059 this.setupColor(); 26060 this.value = this.$el.data('pie-value')/100; 26061 this.label_value = this.$el.data('pie-label-value') || this.$el.data('pie-value'); 26062 this.$wrapper = $('.vc_pie_wrapper', this.$el); 26063 this.$label = $(this.options.label_selector, this.$el); 26064 this.$back = $(this.options.back_selector, this.$el); 26065 this.$canvas = this.$el.find('canvas'); 26066 this.arcWidth = this.$el.data('pie-width') * 2; 26067 this.draw(); 26068 this.setWayPoint(); 26069 if(this.options.responsive === true) this.setResponsive(); 26070 if (UNCODE.isMobile) this._progress_v = this.value; 26071 }, 26072 setupColor: function() { 26073 // if(typeof this.colors[this.options.color] !== 'undefined') { 26074 // this.color = this.colors[this.options.color]; 26075 // } else if(typeof this.options.color === 'string' && this.options.color.match(/^rgba?\([^\)]+\)/)) { 26076 // this.color = this.options.color; 26077 // } else { 26078 // this.color = 'rgba(247, 247, 247, 0.2)'; 26079 // } 26080 if(typeof this.options.color !== 'undefined') { 26081 this.color = this.options.color; 26082 } else this.color = 'rgba(247, 247, 247, 0.2)'; 26083 26084 }, 26085 setResponsive: function() { 26086 var that = this; 26087 if (!UNCODE.isMobile) { 26088 $(window).resize(function(){ 26089 if(that.animated === true) that.circle.stop(); 26090 that.draw(true); 26091 }); 26092 } 26093 }, 26094 draw: function(redraw) { 26095 var w = this.$el.addClass('vc_ready').width() * 2, 26096 border_w = this.arcWidth, 26097 radius; 26098 if(!w) w = this.$el.parents(':visible').first().width()-2; 26099 //w = Math.round(w/100*80); 26100 //if (w < 250) w = 250; 26101 radius = w/2; 26102 this.$wrapper.css({"width" : (w / 2) + "px"}); 26103 this.$label.css({"width" : (w / 2), "height" : (w / 2), "line-height" : (w / 2)+"px"}); 26104 this.$back.css({"width" : (w / 2), "height" : (w / 2)}); 26105 this.$canvas.attr({"width" : w + "px", "height" : w + "px"}); 26106 this.$el.addClass('vc_ready'); 26107 this.circle = new ProgressCircle({ 26108 canvas: this.$canvas.get(0), 26109 minRadius: radius, 26110 arcWidth: border_w 26111 }); 26112 if(redraw === true && this.animated === true) { 26113 this._progress_v = this.value; 26114 this.circle.addEntry({ 26115 fillColor: this.color, 26116 progressListener: $.proxy(this.setProgress, this) 26117 }).start(); 26118 } 26119 }, 26120 setProgress: function() { 26121 if (this._progress_v >= this.value) { 26122 this.circle.stop(); 26123 this.animated = true; 26124 this.$label.html(this.label_value + this.options.units); 26125 return this._progress_v; 26126 } 26127 this._progress_v += 0.01; 26128 if (!isNaN(this.label_value)) { 26129 var label_value = this._progress_v/this.value*this.label_value; 26130 var val = Math.round(label_value) + this.options.units; 26131 this.$label.html(val); 26132 } else this.$label.html(this.label_value + this.options.units); 26133 return this._progress_v; 26134 }, 26135 animate: function() { 26136 if(this.animated !== true) { 26137 this.circle.addEntry({ 26138 fillColor: this.color, 26139 progressListener: $.proxy(this.setProgress, this) 26140 }).start(10); 26141 } 26142 }, 26143 setWayPoint: function() { 26144 if (typeof $.fn.waypoint !== 'undefined' && !UNCODE.isMobile) { 26145 this.$el.waypoint($.proxy(this.animate, this), { offset: '85%' }); 26146 } else { 26147 this.animate(); 26148 } 26149 } 26150 }; 26151 /** 26152 * jQuery plugin 26153 * @param option - object with settings 26154 * @return {*} 26155 */ 26156 $.fn.vcChat = function(option, value) { 26157 return this.each(function () { 26158 var $this = $(this), 26159 data = $this.data('vc_chart'), 26160 options = typeof option === 'object' ? option : { 26161 color: $this.data('pie-color'), 26162 units: $this.data('pie-units') 26163 }; 26164 if (typeof option == 'undefined') $this.data('vc_chart', (data = new VcChart(this, options))); 26165 if (typeof option == 'string') data[option](value); 26166 }); 26167 }; 26168 /** 26169 * Allows users to rewrite function inside theme. 26170 */ 26171 if ( typeof window['vc_pieChart'] !== 'function' ) { 26172 window.vc_pieChart = function() { 26173 $('.vc_pie_chart:visible:not(.vc_ready)').vcChat(); 26174 } 26175 } 26176 $(document).ready(function(){ 26177 !window.vc_iframe && vc_pieChart(); 26178 26179 /** 26180 * Tab and collapse integration. 26181 */ 26182 $('.nav-tabs a').on('shown.bs.tab', function(e){ 26183 var $cont = $(e.target).closest('.tab-container'), 26184 $active = $('.tab-pane.active', $cont); 26185 $('.vc_pie_chart:not(.vc_ready)', $active).vcChat(); 26186 }); 26187 26188 $('.panel-collapse').on('shown.bs.collapse', function (e) { 26189 $('.vc_pie_chart:not(.vc_ready)', e.target).vcChat(); 26190 }) 26191 }); 26192 26193})(window.jQuery); 26194 26195/* Progress bar 26196 ---------------------------------------------------------- */ 26197function uncode_progress_bar() { 26198 jQuery.each(jQuery('.vc_progress_bar'), function(index, val) { 26199 if (UNCODE.isUnmodalOpen && !val.closest('#unmodal-content')) { 26200 return; 26201 } 26202 if (!UNCODE.isMobile) { 26203 new Waypoint({ 26204 context: UNCODE.isUnmodalOpen ? document.getElementById('unmodal-content') : window, 26205 element: val, 26206 handler: function() { 26207 var element = jQuery(this.element); 26208 element.find('.vc_single_bar').each(function(index) { 26209 var $this = jQuery(this), 26210 bar = $this.find('.vc_bar'), 26211 val = bar.data('percentage-value'); 26212 setTimeout(function() { 26213 bar.css({ 26214 "width": val + '%' 26215 }); 26216 }, index * 200); 26217 }); 26218 }, 26219 offset: '80%' 26220 }); 26221 } else { 26222 var element = jQuery(val); 26223 element.find('.vc_single_bar').each(function(index) { 26224 var $this = jQuery(this), 26225 bar = $this.find('.vc_bar'), 26226 val = bar.data('percentage-value'); 26227 setTimeout(function() { 26228 bar.css({ 26229 "width": val + '%' 26230 }); 26231 }, index * 200); 26232 }); 26233 } 26234 }); 26235}; 26236uncode_progress_bar(); 26237 26238/*! 26239 * jquery.counterup.js 1.0 26240 * 26241 * Copyright 2013, Benjamin Intal http://gambit.ph @bfintal 26242 * Released under the GPL v2 License 26243 * 26244 * Date: Nov 26, 2013 26245 */ 26246(function($) { 26247 "use strict"; 26248 $.fn.counterUp = function(options) { 26249 // Defaults 26250 var settings = $.extend({ 26251 'time': 400, 26252 'delay': 10 26253 }, options); 26254 return this.each(function() { 26255 // Store the object 26256 var $this = $(this); 26257 var $settings = settings; 26258 var counterUpper = function() { 26259 var nums = []; 26260 var divisions = $settings.time / $settings.delay; 26261 var numReal = $this.attr('data-val'), 26262 num = numReal; 26263 var isComma = /[0-9]+,[0-9]+/.test(num); 26264 num = num.replace(/,/g, ''); 26265 var isInt = /^[0-9]+$/.test(num); 26266 var isFloat = /^[0-9]+\.[0-9]+$/.test(num); 26267 var decimalPlaces = isFloat ? (num.split('.')[1] || []).length : 0; 26268 // Generate list of incremental numbers to display 26269 for (var i = divisions; i >= 1; i--) { 26270 // Preserve as int if input was int 26271 var newNum = parseInt(num / divisions * i); 26272 // Preserve float if input was float 26273 if (isFloat) { 26274 newNum = parseFloat(num / divisions * i).toFixed(decimalPlaces); 26275 } 26276 // Preserve commas if input had commas 26277 if (isComma) { 26278 while (/(\d+)(\d{3})/.test(newNum.toString())) { 26279 newNum = newNum.toString().replace(/(\d+)(\d{3})/, '$1' + ',' + '$2'); 26280 } 26281 } 26282 nums.unshift(newNum); 26283 } 26284 nums.push(numReal); 26285 $this.data('counterup-nums', nums); 26286 $this.text('0'); 26287 // Updates the number until we're done 26288 var f = function() { 26289 if ($this.data('counterup-nums') != null) { 26290 $this.text($this.data('counterup-nums').shift()); 26291 if ($this.data('counterup-nums').length) { 26292 setTimeout($this.data('counterup-func'), $settings.delay); 26293 } else { 26294 delete $this.data('counterup-nums'); 26295 $this.data('counterup-nums', null); 26296 $this.data('counterup-func', null); 26297 } 26298 } 26299 }; 26300 $this.data('counterup-func', f); 26301 // Start the count up 26302 setTimeout($this.data('counterup-func'), $settings.delay); 26303 }; 26304 // Perform counts when the element gets into view 26305 new Waypoint({ 26306 context: UNCODE.isUnmodalOpen ? document.getElementById('unmodal-content') : window, 26307 element: this, 26308 handler: function() { 26309 counterUpper(); 26310 if (!UNCODE.isUnmodalOpen) { 26311 this.destroy(); 26312 } 26313 }, 26314 offset: '100%' 26315 }); 26316 }); 26317 }; 26318})(jQuery); 26319 26320/*! 26321 * The Final Countdown for jQuery v2.2.0 (http://hilios.github.io/jQuery.countdown/) 26322 * Copyright (c) 2016 Edson Hilios 26323 * 26324 * Permission is hereby granted, free of charge, to any person obtaining a copy of 26325 * this software and associated documentation files (the "Software"), to deal in 26326 * the Software without restriction, including without limitation the rights to 26327 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 26328 * the Software, and to permit persons to whom the Software is furnished to do so, 26329 * subject to the following conditions: 26330 * 26331 * The above copyright notice and this permission notice shall be included in all 26332 * copies or substantial portions of the Software. 26333 * 26334 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26335 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 26336 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 26337 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 26338 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 26339 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26340 */ 26341(function(factory) { 26342 "use strict"; 26343 if (typeof define === "function" && define.amd) { 26344 define([ "jquery" ], factory); 26345 } else { 26346 factory(jQuery); 26347 } 26348})(function($) { 26349 "use strict"; 26350 var instances = [], matchers = [], defaultOptions = { 26351 precision: 100, 26352 elapse: false, 26353 defer: false 26354 }; 26355 matchers.push(/^[0-9]*$/.source); 26356 matchers.push(/([0-9]{1,2}\/){2}[0-9]{4}( [0-9]{1,2}(:[0-9]{2}){2})?/.source); 26357 matchers.push(/[0-9]{4}([\/\-][0-9]{1,2}){2}( [0-9]{1,2}(:[0-9]{2}){2})?/.source); 26358 matchers = new RegExp(matchers.join("|")); 26359 function parseDateString(dateString) { 26360 if (dateString instanceof Date) { 26361 return dateString; 26362 } 26363 if (String(dateString).match(matchers)) { 26364 if (String(dateString).match(/^[0-9]*$/)) { 26365 dateString = Number(dateString); 26366 } 26367 if (String(dateString).match(/\-/)) { 26368 dateString = String(dateString).replace(/\-/g, "/"); 26369 } 26370 return new Date(dateString); 26371 } else { 26372 throw new Error("Couldn't cast `" + dateString + "` to a date object."); 26373 } 26374 } 26375 var DIRECTIVE_KEY_MAP = { 26376 Y: "years", 26377 m: "months", 26378 n: "daysToMonth", 26379 d: "daysToWeek", 26380 w: "weeks", 26381 W: "weeksToMonth", 26382 H: "hours", 26383 M: "minutes", 26384 S: "seconds", 26385 D: "totalDays", 26386 I: "totalHours", 26387 N: "totalMinutes", 26388 T: "totalSeconds" 26389 }; 26390 function escapedRegExp(str) { 26391 var sanitize = str.toString().replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1"); 26392 return new RegExp(sanitize); 26393 } 26394 function strftime(offsetObject) { 26395 return function(format) { 26396 var directives = format.match(/%(-|!)?[A-Z]{1}(:[^;]+;)?/gi); 26397 if (directives) { 26398 for (var i = 0, len = directives.length; i < len; ++i) { 26399 var directive = directives[i].match(/%(-|!)?([a-zA-Z]{1})(:[^;]+;)?/), regexp = escapedRegExp(directive[0]), modifier = directive[1] || "", plural = directive[3] || "", value = null; 26400 directive = directive[2]; 26401 if (DIRECTIVE_KEY_MAP.hasOwnProperty(directive)) { 26402 value = DIRECTIVE_KEY_MAP[directive]; 26403 value = Number(offsetObject[value]); 26404 } 26405 if (value !== null) { 26406 if (modifier === "!") { 26407 value = pluralize(plural, value); 26408 } 26409 if (modifier === "") { 26410 if (value < 10) { 26411 value = "0" + value.toString(); 26412 } 26413 } 26414 format = format.replace(regexp, value.toString()); 26415 } 26416 } 26417 } 26418 format = format.replace(/%%/, "%"); 26419 return format; 26420 }; 26421 } 26422 function pluralize(format, count) { 26423 var plural = "s", singular = ""; 26424 if (format) { 26425 format = format.rep
vendor: 8,618 bytes, lines 26425-26569
26425lace(/(:|;|\s)/gi, "").split(/\,/); 26426 if (format.length === 1) { 26427 plural = format[0]; 26428 } else { 26429 singular = format[0]; 26430 plural = format[1]; 26431 } 26432 } 26433 if (Math.abs(count) > 1) { 26434 return plural; 26435 } else { 26436 return singular; 26437 } 26438 } 26439 var Countdown = function(el, finalDate, options) { 26440 this.el = el; 26441 this.$el = $(el); 26442 this.interval = null; 26443 this.offset = {}; 26444 this.options = $.extend({}, defaultOptions); 26445 this.instanceNumber = instances.length; 26446 instances.push(this); 26447 this.$el.data("countdown-instance", this.instanceNumber); 26448 if (options) { 26449 if (typeof options === "function") { 26450 this.$el.on("update.countdown", options); 26451 this.$el.on("stoped.countdown", options); 26452 this.$el.on("finish.countdown", options); 26453 } else { 26454 this.options = $.extend({}, defaultOptions, options); 26455 } 26456 } 26457 this.setFinalDate(finalDate); 26458 if (this.options.defer === false) { 26459 this.start(); 26460 } 26461 }; 26462 $.extend(Countdown.prototype, { 26463 start: function() { 26464 if (this.interval !== null) { 26465 clearInterval(this.interval); 26466 } 26467 var self = this; 26468 this.update(); 26469 this.interval = setInterval(function() { 26470 self.update.call(self); 26471 }, this.options.precision); 26472 }, 26473 stop: function() { 26474 clearInterval(this.interval); 26475 this.interval = null; 26476 this.dispatchEvent("stoped"); 26477 }, 26478 toggle: function() { 26479 if (this.interval) { 26480 this.stop(); 26481 } else { 26482 this.start(); 26483 } 26484 }, 26485 pause: function() { 26486 this.stop(); 26487 }, 26488 resume: function() { 26489 this.start(); 26490 }, 26491 remove: function() { 26492 this.stop.call(this); 26493 instances[this.instanceNumber] = null; 26494 delete this.$el.data().countdownInstance; 26495 }, 26496 setFinalDate: function(value) { 26497 this.finalDate = parseDateString(value); 26498 }, 26499 update: function() { 26500 if (this.$el.closest("html").length === 0) { 26501 this.remove(); 26502 return; 26503 } 26504 var hasEventsAttached = $._data(this.el, "events") !== undefined, now = new Date(), newTotalSecsLeft; 26505 newTotalSecsLeft = this.finalDate.getTime() - now.getTime(); 26506 newTotalSecsLeft = Math.ceil(newTotalSecsLeft / 1e3); 26507 newTotalSecsLeft = !this.options.elapse && newTotalSecsLeft < 0 ? 0 : Math.abs(newTotalSecsLeft); 26508 if (this.totalSecsLeft === newTotalSecsLeft || !hasEventsAttached) { 26509 return; 26510 } else { 26511 this.totalSecsLeft = newTotalSecsLeft; 26512 } 26513 this.elapsed = now >= this.finalDate; 26514 this.offset = { 26515 seconds: this.totalSecsLeft % 60, 26516 minutes: Math.floor(this.totalSecsLeft / 60) % 60, 26517 hours: Math.floor(this.totalSecsLeft / 60 / 60) % 24, 26518 days: Math.floor(this.totalSecsLeft / 60 / 60 / 24) % 7, 26519 daysToWeek: Math.floor(this.totalSecsLeft / 60 / 60 / 24) % 7, 26520 daysToMonth: Math.floor(this.totalSecsLeft / 60 / 60 / 24 % 30.4368), 26521 weeks: Math.floor(this.totalSecsLeft / 60 / 60 / 24 / 7), 26522 weeksToMonth: Math.floor(this.totalSecsLeft / 60 / 60 / 24 / 7) % 4, 26523 months: Math.floor(this.totalSecsLeft / 60 / 60 / 24 / 30.4368), 26524 years: Math.abs(this.finalDate.getFullYear() - now.getFullYear()), 26525 totalDays: Math.floor(this.totalSecsLeft / 60 / 60 / 24), 26526 totalHours: Math.floor(this.totalSecsLeft / 60 / 60), 26527 totalMinutes: Math.floor(this.totalSecsLeft / 60), 26528 totalSeconds: this.totalSecsLeft 26529 }; 26530 if (!this.options.elapse && this.totalSecsLeft === 0) { 26531 this.stop(); 26532 this.dispatchEvent("finish"); 26533 } else { 26534 this.dispatchEvent("update"); 26535 } 26536 }, 26537 dispatchEvent: function(eventName) { 26538 var event = $.Event(eventName + ".countdown"); 26539 event.finalDate = this.finalDate; 26540 event.elapsed = this.elapsed; 26541 event.offset = $.extend({}, this.offset); 26542 event.strftime = strftime(this.offset); 26543 this.$el.trigger(event); 26544 } 26545 }); 26546 $.fn.countdown = function() { 26547 var argumentsArray = Array.prototype.slice.call(arguments, 0); 26548 return this.each(function() { 26549 var instanceNumber = $(this).data("countdown-instance"); 26550 if (instanceNumber !== undefined) { 26551 var instance = instances[instanceNumber], method = argumentsArray[0]; 26552 if (Countdown.prototype.hasOwnProperty(method)) { 26553 instance[method].apply(instance, argumentsArray.slice(1)); 26554 } else if (String(method).match(/^[$A-Z_][0-9A-Z_$]*$/i) === null) { 26555 instance.setFinalDate.call(instance, method); 26556 instance.start(); 26557 } else { 26558 $.error("Method %s does not exist on jQuery.countdown".replace(/\%s/gi, method)); 26559 } 26560 } else { 26561 new Countdown(this, argumentsArray[0], argumentsArray[1]); 26562 } 26563 }); 26564 }; 26565}); 26566 26567!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; 26568function getStyles(config){ 26569 // 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;
26569left: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+"}" 26570}; 26571 var ShareUtils; 26572 26573if ((!("classList" in document.documentElement)) && Object.defineProperty && typeof HTMLElement !== "undefined") { 26574 Object.defineProperty(HTMLElement.prototype, "classList", { 26575 get: function() { 26576 var ret, self, update; 26577 update = function(fn) { 26578 return function(value) { 26579 var classes, index; 26580 classes = self.className.split(/\s+/); 26581 index = classes.indexOf(value); 26582 fn(classes, index, value); 26583 self.className = classes.join(" "); 26584 }; 26585 }; 26586 self = this; 26587 ret = { 26588 add: update(function(classes, index, value) { 26589 ~index || classes.push(value); 26590 }), 26591 remove: update(function(classes, index) { 26592 ~index && classes.splice(index, 1); 26593 }), 26594 toggle: update(function(classes, index, value) { 26595 if (~index) { 26596 classes.splice(index, 1); 26597 } else { 26598 classes.push(value); 26599 } 26600 }), 26601 contains: function(value) { 26602 return !!~self.className.split(/\s+/).indexOf(value); 26603 }, 26604 item: function(i) { 26605 return self.className.split(/\s+/)[i] || null; 26606 } 26607 }; 26608 Object.defineProperty(ret, "length", { 26609 get: function() { 26610 return self.className.split(/\s+/).length; 26611 } 26612 }); 26613 return ret; 26614 } 26615 }); 26616} 26617 26618String.prototype.to_rfc3986 = function() { 26619 var tmp; 26620 tmp = encodeURIComponent(this); 26621 return tmp.replace(/[!'()*]/g, function(c) { 26622 return "%" + c.charCodeAt(0).toString(16); 26623 }); 26624}; 26625 26626ShareUtils = (function() { 26627 function ShareUtils() {} 26628 26629 ShareUtils.prototype.extend = function(to, from, overwrite) { 26630 var hasProp, prop; 26631 for (prop in from) { 26632 hasProp = to[prop] !== undefined; 26633 if (hasProp && typeof from[prop] === "object") { 26634 this.extend(to[prop], from[prop], overwrite); 26635 } else { 26636 if (overwrite || !hasProp) { 26637 to[prop] = from[prop]; 26638 } 26639 } 26640 } 26641 }; 26642 26643 ShareUtils.prototype.hide = function(el) { 26644 return el.style.display = "none"; 26645 }; 26646 26647 ShareUtils.prototype.show = function(el) { 26648 return el.style.display = "block"; 26649 }; 26650 26651 ShareUtils.prototype.has_class = function(el, class_name) { 26652 return el.classList.contains(class_name); 26653 }; 26654 26655 ShareUtils.prototype.add_class = function(el, class_name) { 26656 return el.classList.add(class_name); 26657 }; 26658 26659 ShareUtils.prototype.remove_class = function(el, class_name) { 26660 return el.classList.remove(class_name); 26661 }; 26662 26663 ShareUtils.prototype.is_encoded = function(str) { 26664 str = str.to_rfc3986(); 26665 return decodeURIComponent(str) !== str; 26666 }; 26667 26668 ShareUtils.prototype.encode = function(str) { 26669 if (typeof str === "undefined" || this.is_encoded(str)) { 26670 return str; 26671 } else { 26672 return str.to_rfc3986(); 26673 } 26674 }; 26675 26676 ShareUtils.prototype.popup = function(url, params) { 26677 var k, popup, qs, v; 26678 if (params == null) { 26679 params = {}; 26680 } 26681 popup = { 26682 width: 500, 26683 height: 350 26684 }; 26685 popup.top = (screen.height / 2) - (popup.height / 2); 26686 popup.left = (screen.width / 2) - (popup.width / 2); 26687 qs = ((function() { 26688 var _results; 26689 _results = []; 26690 for (k in params) { 26691 v = params[k]; 26692 _results.push("" + k + "=" + (this.encode(v))); 26693 } 26694 return _results; 26695 }).call(this)).join('&'); 26696 if (qs) { 26697 qs = "?" + qs; 26698 } 26699 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="
26699+ popup.width + ",height=" + popup.height); 26700 }; 26701 26702 return ShareUtils; 26703 26704})(); 26705var Share, 26706 __hasProp = {}.hasOwnProperty, 26707 __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; }; 26708 26709Share = (function(_super) { 26710 __extends(Share, _super); 26711 26712 function Share(element, options) { 26713 this.element = element; 26714 this.el = { 26715 head: document.getElementsByTagName('head')[0], 26716 body: document.getElementsByTagName('body')[0] 26717 }; 26718 this.config = { 26719 enabled_networks: 0, 26720 protocol: ['http', 'https'].indexOf(window.location.href.split(':')[0]) === -1 ? 'https://' : '//', 26721 url: window.location.href.replace("&", "%26"), 26722 caption: null, 26723 title: this.default_title(), 26724 image: this.default_image(), 26725 description: this.default_description(), 26726 ui: { 26727 flyout: 'top center', 26728 button_text: 'Share', 26729 button_font: true, 26730 icon_font: true 26731 }, 26732 networks: { 26733 twitter: { 26734 enabled: true, 26735 url: null, 26736 title: null, 26737 description: null 26738 }, 26739 facebook: { 26740 enabled: true, 26741 load_sdk: true, 26742 url: null, 26743 app_id: null, 26744 title: null, 26745 caption: null, 26746 description: null, 26747 image: null 26748 }, 26749 pinterest: { 26750 enabled: true, 26751 url: null, 26752 image: null, 26753 description: null 26754 }, 26755 reddit: { 26756 enabled: true, 26757 url: null, 26758 title: null 26759 }, 26760 linkedin: { 26761 enabled: true, 26762 url: null, 26763 title: null, 26764 description: null 26765 }, 26766 xing: { 26767 enabled: true, 26768 url: null, 26769 title: null, 26770 image: null, 26771 description: null 26772 }, 26773 whatsapp: { 26774 enabled: true, 26775 title: null, 26776 url: null 26777 }, 26778 email: { 26779 enabled: true, 26780 title: null, 26781 description: null, 26782 url: null 26783 } 26784 } 26785 }; 26786 this.setup(element, options); 26787 return this; 26788 } 26789 26790 Share.prototype.setup = function(element, opts) { 26791 var index, instance, instances, _i, _len; 26792 instances = document.querySelectorAll(element); 26793 this.extend(this.config, opts, true); 26794 this.set_global_configuration(); 26795 this.normalize_network_configuration(); 26796 if (this.config.ui.icon_font) { 26797 this.inject_icons(); 26798 } 26799 if (this.config.ui.button_font) { 26800 this.inject_fonts(); 26801 } 26802 if (this.config.networks.facebook.enabled && this.config.networks.facebook.load_sdk) { 26803 this.inject_facebook_sdk(); 26804 } 26805 for (index = _i = 0, _len = instances.length; _i < _len; index = ++_i) { 26806 instance = instances[index]; 26807 this.setup_instance(element, index); 26808 } 26809 }; 26810 26811 Share.prototype.setup_instance = function(element, index) { 26812 var button, instance, label, network, networks, _i, _len, _results, 26813 _this = this; 26814 instance = document.querySelectorAll(element)[index]; 26815 this.hide(instance); 26816 this.add_class(instance, "sharer-" + index); 26817 instance = document.querySelectorAll(element)[index]; 26818 this.inject_css(instance); 26819 this.inject_html(instance); 26820 this.show(instance); 26821 label = instance.getElementsByTagName("label")[0]; 26822 button = instance.getElementsByClassName("social")[0]; 26823 networks = instance.getElementsByTagName('li'); 26824 this.add_class(button, "networks-" + this.config.enabled_networks); 26825 label.addEventListener("click", function() { 26826 return _this.event_toggle(button); 26827 }); 26828 _this = this; 26829 _results = []; 26830 for (index = _i = 0, _len = networks.length; _i < _len; index = ++_i) { 26831 network = networks[index]; 26832 _results.push(network.addEventListener("click", function() { 26833 _this.event_network(instance, this); 26834 return _this.event_close(button); 26835 })); 26836 } 26837 return _results; 26838 }; 26839 26840 Share.prototype.event_toggle = function(button) { 26841 if (this.has_class(button, "active")) { 26842 return this.event_close(button); 26843 } else { 26844 return this.event_open(button); 26845 } 26846 }; 26847 26848 Share.prototype.event_open = function(button) { 26849 if (this.has_class(button, "load")) { 26850 this.remove_class(button, "load"); 26851 } 26852 return this.add_class(button, "active"); 26853 }; 26854 26855 Share.prototype.event_close = function(button) { 26856 return this.remove_class(button, "active"); 26857 }; 26858 26859 Share.prototype.event_network = function(instance, network) { 26860 var name; 26861 name = network.getAttribute("data-network"); 26862 this.hook("before", name, instance);
26863 this["network_" + name](); 26864 return this.hook("after", name, instance); 26865 }; 26866 26867 Share.prototype.open = function() { 26868 return this["public"]("open"); 26869 }; 26870 26871 Share.prototype.close = function() { 26872 return this["public"]("close"); 26873 }; 26874 26875 Share.prototype.toggle = function() { 26876 return this["public"]("toggle"); 26877 }; 26878 26879 Share.prototype["public"] = function(action) { 26880 var button, index, instance, _i, _len, _ref, _results; 26881 _ref = document.querySelectorAll(this.element); 26882 _results = []; 26883 for (index = _i = 0, _len = _ref.length; _i < _len; index = ++_i) { 26884 instance = _ref[index]; 26885 button = instance.getElementsByClassName("social")[0]; 26886 _results.push(this["event_" + action](button)); 26887 } 26888 return _results; 26889 }; 26890 26891 Share.prototype.network_facebook = function() { 26892 if (this.config.networks.facebook.load_sdk) { 26893 if (!window.FB) { 26894 return console.error("The Facebook JS SDK hasn't loaded yet."); 26895 } 26896 return FB.ui({ 26897 method: 'feed', 26898 name: this.config.networks.facebook.title, 26899 link: this.config.networks.facebook.url, 26900 picture: this.config.networks.facebook.image, 26901 caption: this.config.networks.facebook.caption, 26902 description: this.config.networks.facebook.description 26903 }); 26904 } else { 26905 return this.popup('https://www.facebook.com/sharer/sharer.php', { 26906 u: this.config.networks.facebook.url 26907 }); 26908 } 26909 }; 26910 26911 Share.prototype.network_twitter = function() { 26912 return this.popup('https://twitter.com/intent/tweet', { 26913 text: this.config.networks.twitter.title, 26914 url: this.config.networks.twitter.url 26915 }); 26916 }; 26917 26918 Share.prototype.network_pinterest = function() { 26919 return this.popup('https://www.pinterest.com/pin/create/button', { 26920 url: this.config.networks.pinterest.url, 26921 media: this.config.networks.pinterest.image, 26922 description: this.config.networks.pinterest.description 26923 }); 26924 }; 26925 26926 Share.prototype.network_linkedin = function() { 26927 return this.popup('https://www.linkedin.com/shareArticle', { 26928 url: this.config.networks.linkedin.url, 26929 title: this.config.networks.linkedin.title, 26930 summary: this.config.networks.linkedin.description 26931 }); 26932 } 26933 26934 Share.prototype.network_xing = function() { 26935 return this.popup('https://www.xing.com/spi/shares/new', { 26936 url: this.config.networks.xing.url, 26937 image: this.config.networks.xing.image, 26938 title: this.config.networks.xing.title, 26939 summary: this.config.networks.xing.description 26940 }); 26941 } 26942 26943 Share.prototype.network_whatsapp = function() { 26944 return this.popup('https://api.whatsapp.com/send', { 26945 text: this.config.networks.whatsapp.title + '%20' + this.config.networks.whatsapp.url, 26946 }); 26947 } 26948 26949 Share.prototype.network_email = function() { 26950 return this.popup('mailto:', { 26951 subject: this.config.networks.email.title, 26952 body: this.config.networks.email.url + '%0A%0A' + this.config.networks.email.description, 26953 }); 26954 }; 26955 26956 Share.prototype.inject_icons = function() { 26957 // return this.inject_stylesheet("https://www.sharebutton.co/fonts/v2/entypo.min.css"); 26958 }; 26959 26960 Share.prototype.inject_fonts = function() { 26961 // return this.inject_stylesheet("http://fonts.googleapis.com/css?family=Lato:900&text=" + this.config.ui.button_text); 26962 }; 26963 26964 Share.prototype.inject_stylesheet = function(url) { 26965 var link; 26966 if (!this.el.head.querySelector("link[href=\"" + url + "\"]")) { 26967 link = document.createElement("link"); 26968 link.setAttribute("rel", "stylesheet"); 26969 link.setAttribute("href", url); 26970 return this.el.head.appendChild(link); 26971 } 26972 }; 26973 26974 Share.prototype.inject_css = function(instance) { 26975 var css, meta, selector, style; 26976 selector = "." + (instance.getAttribute('class').split(" ").join(".")); 26977 if (!this.el.head.querySelector("meta[name='sharer" + selector + "']")) { 26978 this.config.selector = selector; 26979 css = getStyles(this.config); 26980 style = document.createElement("style"); 26981 style.type = "text/css"; 26982 if (style.styleSheet) { 26983 style.styleSheet.cssText = css; 26984 } else { 26985 style.appendChild(document.createTextNode(css)); 26986 } 26987 this.el.head.appendChild(style); 26988 delete this.config.selector; 26989 meta = document.createElement("meta"); 26990 meta.setAttribute("name", "sharer" + selector); 26991 return this.el.head.appendChild(meta); 26992 } 26993 }; 26994 26995 Share.prototype.inject_html = function(instance) { 26996 //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>"; 26997 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>"; 26998 }; 26999 27000 Share.prototype.inject_facebook_sdk = function() { 27001 var fb_root, script; 27002 if (!window.FB && this.config.networks.facebook.app_id && !this.el.body.querySelector('#fb-root')) { 27003 script = document.createElement("script"); 27004 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')"; 27005 fb_root = document.createElement("div"); 27006 fb_root.id = "fb-root"; 27007 this.el.body.appendChild(fb_root); 27008 return this.el.body.appendChild(script); 27009 } 27010 }; 27011 27012 Share.prototype.hook = function(type, network, instance) { 27013 var fn, opts; 27014 fn = this.config.networks[network][type]; 27015 if (typeof fn === "function") { 27016 opts = fn.call(this.config.networks[network], instance); 27017 if (opts !== void 0) { 27018 opts = this.normalize_filter_config_updates(opts); 27019 this.extend(this.config.networks[network], opts, true); 27020 this.normalize_network_configuration(); 27021 } 27022 } 27023 }; 27024 27025 Share.prototype.default_title = function() { 27026 var content; 27027 if (content = document.querySelector('meta[property="og:title"]') || document.querySelector('meta[name="twitter:title"]')) { 27028 return encodeURIComponent(content.getAttribute('content')); 27029 } else if (content = document.querySelector('title')) { 27030 return encodeURIComponent(content.innerText); 27031 } 27032 }; 27033 27034 Share.prototype.default_image = function() { 27035 var content; 27036 if (content = document.querySelector('meta[property="og:image"]') || document.querySelector('meta[name="twitter:image"]')) { 27037 return content.getAttribute('content'); 27038 } 27039 }; 27040 27041 Share.prototype.default_description = function() { 27042 var content; 27043 if (content = document.querySelector('meta[property="og:description"]') || document.querySelector('meta[name="twitter:description"]') || document.querySelector('meta[name="description"]')) { 27044 return encodeURIComponent(content.getAttribute('content')); 27045 } else { 27046 return ''; 27047 } 27048 }; 27049 27050 Share.prototype.set_global_configuration = function() { 27051 var display, network, option, options, _ref, _results; 27052 _ref = this.config.networks; 27053 _results = []; 27054 for (network in _ref) { 27055 options = _ref[network]; 27056 for (option in options) { 27057 if (this.config.networks[network][option] == null) { 27058 this.config.networks[network][option] = this.config[option]; 27059 } 27060 } 27061 if (this.config.networks[network].enabled) { 27062 display = 'block'; 27063 this.config.enabled_networks += 1; 27064 } else { 27065 display = 'none'; 27066 } 27067 _results.push(this.config.networks[network].display = display); 27068 } 27069 return _results; 27070 }; 27071 27072 Share.prototype.normalize_network_configuration = function() { 27073 if (!this.config.networks.facebook.app_id) { 27074 this.config.networks.facebook.load_sdk = false;
27075 } 27076 if (!this.is_encoded(this.config.networks.twitter.description)) { 27077 this.config.networks.twitter.description = encodeURIComponent(this.config.networks.twitter.description); 27078 } 27079 if (typeof this.config.networks.facebook.app_id === 'number') { 27080 return this.config.networks.facebook.app_id = this.config.networks.facebook.app_id.toString(); 27081 } 27082 }; 27083 27084 Share.prototype.normalize_filter_config_updates = function(opts) { 27085 if (this.config.networks.facebook.app_id !== opts.app_id) { 27086 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."); 27087 delete opts.app_id; 27088 } 27089 if (this.config.networks.facebook.load_sdk !== opts.load_sdk) { 27090 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."); 27091 delete opts.app_id; 27092 } 27093 return opts; 27094 }; 27095 27096 return Share; 27097 27098})(ShareUtils); 27099 return Share; 27100}); 27101 27102// Generated by CoffeeScript 1.9.2 27103 27104// @license Sticky-kit v1.1.2 | WTFPL | Leaf Corcoran 2015 | http://leafo.net 27105 27106(function() { 27107 var $, win; 27108 27109 $ = this.jQuery || window.jQuery; 27110 27111 win = $(window); 27112 27113 $.fn.stick_in_parent = function(opts) { 27114 var doc, elm, enable_bottoming, fn, i, inner_scrolling, len, manual_spacer, offset_top, outer_width, parent_selector, recalc_every, sticky_class; 27115 if (opts == null) { 27116 opts = {}; 27117 } 27118 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; 27119 if (offset_top == null) { 27120 offset_top = 0; 27121 } 27122 if (parent_selector == null) { 27123 parent_selector = void 0; 27124 } 27125 if (inner_scrolling == null) { 27126 inner_scrolling = true; 27127 } 27128 if (sticky_class == null) { 27129 sticky_class = "is_stuck"; 27130 } 27131 doc = $(document); 27132 if (enable_bottoming == null) { 27133 enable_bottoming = true; 27134 } 27135 outer_width = function(el) { 27136 var _el, computed, w; 27137 if (window.getComputedStyle) { 27138 _el = el[0]; 27139 computed = window.getComputedStyle(el[0]); 27140 w = parseFloat(computed.getPropertyValue("width")) + parseFloat(computed.getPropertyValue("margin-left")) + parseFloat(computed.getPropertyValue("margin-right")); 27141 if (computed.getPropertyValue("box-sizing") !== "border-box") { 27142 w += parseFloat(computed.getPropertyValue("border-left-width")) + parseFloat(computed.getPropertyValue("border-right-width")) + parseFloat(computed.getPropertyValue("padding-left")) + parseFloat(computed.getPropertyValue("padding-right")); 27143 } 27144 return w; 27145 } else { 27146 return el.outerWidth(true); 27147 } 27148 }; 27149 fn = function(elm, padding_bottom, parent_top, parent_height, top, height, el_float, detached) { 27150 var bottomed, detach, fixed, last_pos, last_scroll_height, offset, parent, recalc, recalc_and_tick, recalc_counter, spacer, tick; 27151 if (elm.data("sticky_kit")) { 27152 return; 27153 } 27154 elm.data("sticky_kit", true); 27155 last_scroll_height = doc.height(); 27156 parent = elm.parent(); 27157 if (parent_selector != null) { 27158 parent = parent.closest(parent_selector); 27159 } 27160 if (!parent.length) { 27161 throw "failed to find stick parent"; 27162 } 27163 fixed = false; 27164 bottomed = false; 27165 spacer = manual_spacer != null ? manual_spacer && elm.closest(manual_spacer) : $("<div />"); 27166 if (spacer) { 27167 spacer.css('position', elm.css('position')); 27168 } 27169 recalc = function() { 27170 var border_top, padding_top, restore; 27171 if (detached) { 27172 return; 27173 } 27174 last_scroll_height = doc.height(); 27175 border_top = parseInt(parent.css("border-top-width"), 10); 27176 padding_top = parseInt(parent.css("padding-top"), 10); 27177 padding_bottom = parseInt(parent.css("padding-bottom"), 10); 27178 parent_top = parent.offset().top + border_top + padding_top; 27179 parent_height = parent.height(); 27180 if (fixed) { 27181 fixed = false;
vendor: 6,068 bytes, lines 27182-27376
27182 bottomed = false; 27183 if (manual_spacer == null) { 27184 elm.insertAfter(spacer); 27185 spacer.detach(); 27186 } 27187 elm.css({ 27188 position: "", 27189 top: "", 27190 width: "", 27191 bottom: "" 27192 }).removeClass(sticky_class); 27193 restore = true; 27194 } 27195 top = elm.offset().top - (parseInt(elm.css("margin-top"), 10) || 0) - offset_top; 27196 height = elm.outerHeight(true); 27197 el_float = elm.css("float"); 27198 if (spacer) { 27199 spacer.css({ 27200 width: outer_width(elm), 27201 height: height, 27202 display: elm.css("display"), 27203 "vertical-align": elm.css("vertical-align"), 27204 "float": el_float 27205 }); 27206 } 27207 if (restore) { 27208 return tick(); 27209 } 27210 }; 27211 recalc(); 27212 if (height === parent_height) { 27213 return; 27214 } 27215 last_pos = void 0; 27216 offset = offset_top; 27217 recalc_counter = recalc_every; 27218 tick = function() { 27219 var css, delta, recalced, scroll, will_bottom, win_height; 27220 if (detached) { 27221 return; 27222 } 27223 recalced = false; 27224 if (recalc_counter != null) { 27225 recalc_counter -= 1; 27226 if (recalc_counter <= 0) { 27227 recalc_counter = recalc_every; 27228 recalc(); 27229 recalced = true; 27230 } 27231 } 27232 if (!recalced && doc.height() !== last_scroll_height) { 27233 recalc(); 27234 recalced = true; 27235 } 27236 scroll = win.scrollTop(); 27237 if (last_pos != null) { 27238 delta = scroll - last_pos; 27239 } 27240 last_pos = scroll; 27241 if (fixed) { 27242 if (enable_bottoming) { 27243 will_bottom = scroll + height + offset > parent_height + parent_top; 27244 if (bottomed && !will_bottom) { 27245 bottomed = false; 27246 elm.css({ 27247 position: "fixed", 27248 bottom: "", 27249 top: offset 27250 }).trigger("sticky_kit:unbottom"); 27251 } 27252 } 27253 if (scroll < top) { 27254 fixed = false; 27255 offset = offset_top; 27256 if (manual_spacer == null) { 27257 if (el_float === "left" || el_float === "right") { 27258 elm.insertAfter(spacer); 27259 } 27260 spacer.detach(); 27261 } 27262 css = { 27263 position: "", 27264 width: "", 27265 top: "" 27266 }; 27267 elm.css(css).removeClass(sticky_class).trigger("sticky_kit:unstick"); 27268 } 27269 if (inner_scrolling) { 27270 win_height = win.height(); 27271 if (height + offset_top > win_height) { 27272 if (!bottomed) { 27273 offset -= delta; 27274 offset = Math.max(win_height - height, offset); 27275 offset = Math.min(offset_top, offset); 27276 if (fixed) { 27277 elm.css({ 27278 top: offset + "px" 27279 }); 27280 } 27281 } 27282 } 27283 } 27284 } else { 27285 if (scroll > top) { 27286 fixed = true; 27287 css = { 27288 position: "fixed", 27289 top: offset 27290 }; 27291 css.width = elm.css("box-sizing") === "border-box" ? elm.outerWidth() + "px" : elm.width() + "px"; 27292 elm.css(css).addClass(sticky_class); 27293 if (manual_spacer == null) { 27294 elm.after(spacer); 27295 if (el_float === "left" || el_float === "right") { 27296 spacer.append(elm); 27297 } 27298 } 27299 elm.trigger("sticky_kit:stick"); 27300 } 27301 } 27302 if (fixed && enable_bottoming) { 27303 if (will_bottom == null) { 27304 will_bottom = scroll + height + offset > parent_height + parent_top; 27305 } 27306 if (!bottomed && will_bottom) { 27307 bottomed = true; 27308 if (parent.css("position") === "static") { 27309 parent.css({ 27310 position: "relative" 27311 }); 27312 } 27313 return elm.css({ 27314 position: "absolute", 27315 bottom: padding_bottom, 27316 top: "auto" 27317 }).trigger("sticky_kit:bottom"); 27318 } 27319 } 27320 }; 27321 recalc_and_tick = function() { 27322 recalc(); 27323 return tick(); 27324 }; 27325 detach = function() { 27326 detached = true; 27327 win.off("touchmove", tick); 27328 win.off("scroll", tick); 27329 win.off("resize", recalc_and_tick); 27330 $(document.body).off("sticky_kit:recalc", recalc_and_tick); 27331 elm.off("sticky_kit:detach", detach); 27332 elm.removeData("sticky_kit"); 27333 elm.css({ 27334 position: "", 27335 bottom: "", 27336 top: "", 27337 width: "" 27338 }); 27339 parent.position("position", ""); 27340 if (fixed) { 27341 if (manual_spacer == null) { 27342 if (el_float === "left" || el_float === "right") { 27343 elm.insertAfter(spacer); 27344 } 27345 spacer.remove(); 27346 } 27347 return elm.removeClass(sticky_class); 27348 } 27349 }; 27350 win.on("touchmove", tick); 27351 win.on("scroll", tick); 27352 win.on("resize", recalc_and_tick); 27353 $(document.body).on("sticky_kit:recalc", recalc_and_tick); 27354 elm.on("sticky_kit:detach", detach); 27355 return setTimeout(tick, 0); 27356 }; 27357 for (i = 0, len = this.length; i < len; i++) { 27358 elm = this[i]; 27359 fn($(elm)); 27360 } 27361 return this; 27362 }; 27363 27364}).call(this); 27365/* ========================================================================== 27366 * bootstrap-tab-history.js 27367 * Author: Michael Narayan <[email protected]> 27368 * Repository: https://github.com/mnarayan01/bootstrap-tab-history/ 27369 * ========================================================================== 27370 * Licensed under the Apache License, Version 2.0 (the "License"); you may 27371 * not use this file except in compliance with the License. You may obtain a 27372 * copy of the License at 27373 * 27374 * http://www.apache.org/licenses/LICENSE-2.0 27375 * 27376 * Unless required by applicable law or agreed to in writing, softw
27376are 27377 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 27378 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 27379 * License for the specific language governing permissions and limitations 27380 * under the License. 27381 * ========================================================================== */ 27382 27383/* ========================================================================== */ 27384/* JSHint directives */ 27385/* */ 27386/* global BootstrapTabHistory: true */ 27387/* */ 27388/* global document */ 27389/* global jQuery */ 27390/* global history */ 27391/* global window */ 27392/* ========================================================================== */ 27393 27394/** 27395 * Integrate [HTML5 history state tracking](https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Manipulating_the_browser_history) 27396 * with [`bootstrap/tab.js`](http://getbootstrap.com/javascript/#tabs). To enable tracking on a tab element, simply set 27397 * the `data-tab-history` attribute to true (or a string denoting a tab grouping). 27398 * 27399 * See the README for additional information. 27400 * 27401 * Functionality based upon bootstrap/tab.js v3.1.0; reference it when making any changes. 27402 */ 27403 27404BootstrapTabHistory = { 27405 options: { 27406 /** 27407 * When the anchor portion of the URI is used to activate a tab, scroll down to the given offset, rather than the 27408 * element with the given `id` attribute. Set to null to disable. Only relevant if showTabsBasedOnAnchor is true. 27409 * 27410 * May be overriden on a per-element basis by the attribute `data-tab-history-anchor-y-offset`. 27411 * 27412 * @public 27413 * @type {?number} 27414 */ 27415 defaultAnchorYOffset: 0, 27416 /** 27417 * Either 'push' or 'replace', for whether to use `history.pushState` or `history.replaceState`, resp. 27418 * 27419 * May be overriden on a per-element basis by the attribute `data-tab-history-changer`. 27420 * 27421 * @public 27422 * @type {string} 27423 */ 27424 defaultChanger: 'replace', 27425 /** 27426 * If true, update the URL in onShownTab in the calls to `history.pushState` and `history.replaceState`. Otherwise, 27427 * `null` is passed as the third parameter to these calls. 27428 * 27429 * May be overriden on a per-element basis by the attribute `data-tab-history-update-url`. 27430 * 27431 * @public 27432 * @type {boolean} 27433 */ 27434 defaultUpdateURL: false, 27435 /** 27436 * Should the anchor portion of the loaded URI be used to activate a single tab if no history was present on page 27437 * load. 27438 * 27439 * @public 27440 * @type {boolean} 27441 */ 27442 showTabsBasedOnAnchor: true 27443 } 27444}; 27445 27446(function () { 27447 'use strict'; 27448 27449 jQuery(function () { 27450 if(history && history.pushState && history.replaceState) { 27451 var bootstrapTabHistory = history.state && history.state.bootstrapTabHistory; 27452 27453 if(bootstrapTabHistory) { 27454 showTabsBasedOnState(bootstrapTabHistory); 27455 } else { 27456 showTabsBasedOnAnchor(); 27457 } 27458 27459 backfillHistoryState(); 27460 27461 jQuery(document).on('shown.bs.tab show.bs.collapse', onShownTab); 27462 jQuery(window).on('popstate', onPopState); 27463 } else { 27464 showTabsBasedOnAnchor(); 27465 } 27466 }); 27467 27468 /** 27469 * Used to prevent onShownTab from registering shown events that we triggered via showTabsBasedOnState. 27470 * 27471 * @type {boolean} 27472 */ 27473 var showingTabsBasedOnState = false; 27474 27475 /** 27476 * Used to update `history.state` to reflect the default active tabs on initial page load. This supports proper 27477 * `history.back` handling when `data-tab-history-update-url` is true. 27478 */ 27479 function backfillHistoryState() { 27480 var newState = null; 27481 27482 jQuery('li.active > [data-tab-history], .panel-title.active [data-tab-history]').each(function () {//edited by Uncode 27483 var $activeTabElement = jQuery(this); 27484 var selector = getTabSelector($activeTabElement); 27485 27486 if(selector) { 27487 var tabGroup = getTabGroup($activeTabElement); 27488 27489 if(tabGroup) { 27490 newState = createNewHistoryState(newState || history.state, tabGroup, selector); 27491 } 27492 } 27493 }); 27494 27495 if(newState) { 27496 history.replaceState(newState, '', null); 27497 } 27498 } 27499 27500 /** 27501 * Clone the existing state, ensure its bootstrapTabHistory attribute is an Object, and add the provided tabGroup to 27502 * said bootstrapTabHistory attribute. 27503 * 27504 * @param {?object} existingState 27505 * @param {!string} tabGroup 27506 * @param {!string} selector 27507 * @returns {!object} 27508 */ 27509 function createNewHistoryState(existingState, tabGroup, selector) { 27510 // Clone history.state and ensure it has a bootstrapTabHistory entry. 27511 var newState = jQuery.extend(true, {}, existingState, { 27512 bootstrapTabHistory: {} 27513 }); 27514 27515 newState.bootstrapTabHistory[tabGroup] = selector; 27516 27517 return newState; 27518 } 27519 27520 /** 27521 * @param {jQuery} $tab
27522 * @returns {?string} 27523 */ 27524 function getTabGroup($tab) { 27525 return parseTruthyAttributeValue($tab.data('tab-history')); 27526 } 27527 27528 /** 27529 * @param {jQuery} $tab 27530 * @returns {?string} 27531 */ 27532 function getTabSelector($tab) { 27533 return $tab.data('target') || $tab.attr('href'); 27534 } 27535 27536 /** 27537 * Receives the `shown.bs.tab` event. Updates `history.state` as appropriate. 27538 * 27539 * @param {jQuery.Event} shownEvt 27540 */ 27541 function onShownTab(shownEvt) { 27542 if(!showingTabsBasedOnState) { 27543 var $activatedTab = jQuery(shownEvt.target); 27544 if ( $activatedTab.hasClass('panel-collapse') ) 27545 $activatedTab = $activatedTab.closest('.panel').find('a'); 27546 var selector = getTabSelector($activatedTab); 27547 27548 if(selector) { 27549 var tabGroup = getTabGroup($activatedTab); 27550 27551 if(tabGroup) { 27552 var historyChanger = $activatedTab.data('tab-history-changer') || BootstrapTabHistory.options.defaultChanger; 27553 var newState = createNewHistoryState(history.state, tabGroup, selector); 27554 var updateURL = (function ($activatedTab) { 27555 if(selector[0] === '#') { 27556 var elementUpdateURLOption = parseTruthyAttributeValue($activatedTab.data('tab-history-update-url')); 27557 27558 if(elementUpdateURLOption === undefined) { 27559 return BootstrapTabHistory.options.defaultUpdateURL; 27560 } else { 27561 return elementUpdateURLOption; 27562 } 27563 } else { 27564 return false; 27565 } 27566 })($activatedTab); 27567 27568 switch(historyChanger) { 27569 case 'push': 27570 history.pushState(newState, '', updateURL ? selector : null); 27571 break; 27572 case 'replace': 27573 history.replaceState(newState, '', updateURL ? selector : null); 27574 break; 27575 default: 27576 throw new Error('Unknown tab-history-changer: ' + historyChanger); 27577 } 27578 } 27579 } 27580 } 27581 } 27582 27583 /** 27584 * Receives the `popstate` event. Shows tabs based on the value of `history.state` as appropriate. 27585 */ 27586 function onPopState() { 27587 var bootstrapTabHistory = history.state && history.state.bootstrapTabHistory; 27588 27589 if(bootstrapTabHistory) { 27590 showTabsBasedOnState(bootstrapTabHistory); 27591 } 27592 } 27593 27594 /** 27595 * Returns the given value, _unless_ that value is an empty string, in which case `true` is returned. 27596 * 27597 * Rationale: HAML data attributes which are set to `true` are rendered as a blank string. 27598 * 27599 * @param {*} value 27600 * @returns {*} 27601 */ 27602 function parseTruthyAttributeValue(value) { 27603 if(value) { 27604 return value; 27605 } else if(value === '') { 27606 return true; 27607 } else { 27608 return value; 27609 } 27610 } 27611 27612 /** 27613 * Show tabs based upon the anchor component of `window.location`. 27614 */ 27615 function showTabsBasedOnAnchor() { 27616 if(BootstrapTabHistory.options.showTabsBasedOnAnchor) { 27617 var anchor = window.location && window.location.hash; 27618 27619 if(anchor) { 27620 var $tabElement = showTabForSelector(anchor); 27621 27622 if($tabElement && window.addEventListener && window.removeEventListener) { 27623 var anchorYOffset = (function ($tabElement) { 27624 var elementSetting = $tabElement.data('tab-history-anchor-y-offset'); 27625 27626 if(elementSetting === undefined) { 27627 return BootstrapTabHistory.options.defaultAnchorYOffset; 27628 } else { 27629 return elementSetting; 27630 } 27631 })($tabElement); 27632 27633 // HACK: This prevents scrolling to the tab on page load. This relies on the fact that we should never get 27634 // here on `history.forward`, `history.back`, or `location.reload`, since in all those situations the 27635 // `history.state` object should have been used (unless the browser did not support the modern History API). 27636 if(anchorYOffset || anchorYOffset === 0) { 27637 var scrollListener = function resetAnchorScroll () { 27638 window.removeEventListener('scroll', scrollListener); 27639 window.scrollTo(0, anchorYOffset); 27640 }; 27641 27642 window.addEventListener('scroll', scrollListener); 27643 } 27644 } 27645 } 27646 } 27647 } 27648 27649 /** 27650 * Show a tab which corresponds to the provided selector. 27651 * 27652 * @param {string} selector - A CSS selector. 27653 * @returns {?jQuery} - The tab which was found to show (even if said tab was already active). 27654 */ 27655 function showTabForSelector(selector) { 27656 var $tabElement = (function (selector) { 27657 var $ret = null; 27658 27659 jQuery('[data-toggle="tab"], [data-toggle="pill"], [data-toggle="collapse"]').each(function () { 27660 var $potentialTab = jQuery(this); 27661 27662 if(($potentialTab.attr('href') === selector || $potentialTab.data('target') === selector ) && getTabGroup($potentialTab)) { 27663 $ret = $potentialTab; 27664 return false;
vendor: 43,483 bytes, lines 27665-28881
27665 } else { 27666 return null; 27667 } 27668 }); 27669 27670 return $ret; 27671 })(selector); 27672 27673 if($tabElement) { 27674 if ( !$tabElement.parent().hasClass('active') ) { 27675 $tabElement.trigger('click'); 27676 } 27677 //$tabElement.tab('show'); 27678 } 27679 27680 return $tabElement; 27681 } 27682 27683 /** 27684 * Iterate through the provided set of tab tab groups, showing the tabs based on the stored selectors. 27685 * 27686 * @param {object} bootstrapTabHistory - Each of the values is passed to showTabForSelector; the keys are actually irrelevant. 27687 */ 27688 function showTabsBasedOnState(bootstrapTabHistory) { 27689 showingTabsBasedOnState = true; 27690 27691 try { 27692 for(var k in bootstrapTabHistory) { 27693 if(bootstrapTabHistory.hasOwnProperty(k)) { 27694 showTabForSelector(bootstrapTabHistory[k]); 27695 } 27696 } 27697 } finally { 27698 showingTabsBasedOnState = false; 27699 } 27700 } 27701})(); 27702 27703/*! 27704 * justifiedGallery - v3.8.1 27705 * http://miromannino.github.io/Justified-Gallery/ 27706 * Copyright (c) 2020 Miro Mannino 27707 * Licensed under the MIT license. 27708 */ 27709(function (factory) { 27710 if (typeof define === 'function' && define.amd) { 27711 // AMD. Register as an anonymous module. 27712 define(['jquery'], factory); 27713 } else if (typeof module === 'object' && module.exports) { 27714 // Node/CommonJS 27715 module.exports = function (root, jQuery) { 27716 if (jQuery === undefined) { 27717 // require('jQuery') returns a factory that requires window to 27718 // build a jQuery instance, we normalize how we use modules 27719 // that require this pattern but the window provided is a noop 27720 // if it's defined (how jquery works) 27721 if (typeof window !== 'undefined') { 27722 jQuery = require('jquery'); 27723 } 27724 else { 27725 jQuery = require('jquery')(root); 27726 } 27727 } 27728 factory(jQuery); 27729 return jQuery; 27730 }; 27731 } else { 27732 // Browser globals 27733 factory(jQuery); 27734 } 27735}(function ($) { 27736 27737 /** 27738 * Justified Gallery controller constructor 27739 * 27740 * @param $gallery the gallery to build 27741 * @param settings the settings (the defaults are in JustifiedGallery.defaults) 27742 * @constructor 27743 */ 27744 var JustifiedGallery = function ($gallery, settings) { 27745 27746 this.settings = settings; 27747 this.checkSettings(); 27748 27749 this.imgAnalyzerTimeout = null; 27750 this.entries = null; 27751 this.buildingRow = { 27752 entriesBuff: [], 27753 width: 0, 27754 height: 0, 27755 aspectRatio: 0 27756 }; 27757 this.lastFetchedEntry = null; 27758 this.lastAnalyzedIndex = -1; 27759 this.yield = { 27760 every: 2, // do a flush every n flushes (must be greater than 1) 27761 flushed: 0 // flushed rows without a yield 27762 }; 27763 this.border = settings.border >= 0 ? settings.border : settings.margins; 27764 this.maxRowHeight = this.retrieveMaxRowHeight(); 27765 this.suffixRanges = this.retrieveSuffixRanges(); 27766 this.offY = this.border; 27767 this.rows = 0; 27768 this.spinner = { 27769 phase: 0, 27770 timeSlot: 150, 27771 $el: $('<div class="jg-spinner"><span></span><span></span><span></span></div>'), 27772 intervalId: null 27773 }; 27774 this.scrollBarOn = false; 27775 this.checkWidthIntervalId = null; 27776 this.galleryWidth = $gallery.width(); 27777 this.$gallery = $gallery; 27778 27779 }; 27780 27781 /** @returns {String} the best suffix given the width and the height */ 27782 JustifiedGallery.prototype.getSuffix = function (width, height) { 27783 var longestSide, i; 27784 longestSide = (width > height) ? width : height; 27785 for (i = 0; i < this.suffixRanges.length; i++) { 27786 if (longestSide <= this.suffixRanges[i]) { 27787 return this.settings.sizeRangeSuffixes[this.suffixRanges[i]]; 27788 } 27789 } 27790 return this.settings.sizeRangeSuffixes[this.suffixRanges[i - 1]]; 27791 }; 27792 27793 /** 27794 * Remove the suffix from the string 27795 * 27796 * @returns {string} a new string without the suffix 27797 */ 27798 JustifiedGallery.prototype.removeSuffix = function (str, suffix) { 27799 return str.substring(0, str.length - suffix.length); 27800 }; 27801 27802 /** 27803 * @returns {boolean} a boolean to say if the suffix is contained in the str or not 27804 */ 27805 JustifiedGallery.prototype.endsWith = function (str, suffix) { 27806 return str.indexOf(suffix, str.length - suffix.length) !== -1; 27807 }; 27808 27809 /** 27810 * Get the used suffix of a particular url 27811 * 27812 * @param str 27813 * @returns {String} return the used suffix 27814 */ 27815 JustifiedGallery.prototype.getUsedSuffix = function (str) { 27816 for (var si in this.settings.sizeRangeSuffixes) { 27817 if (this.settings.sizeRangeSuffixes.hasOwnProperty(si)) { 27818 if (this.settings.sizeRangeSuffixes[si].length === 0) continue; 27819 if (this.endsWith(str, this.settings.sizeRangeSuffixes[si])) return this.settings.sizeRangeSuffixes[si]; 27820 } 27821 } 27822 return ''; 27823 }; 27824 27825 /** 27826 * Given an image src, with the width and the height, returns the new image src with the 27827 * best suffix to show the best quality thumbnail. 27828 * 27829 * @returns {String} the suffix to use 27830 */ 27831 JustifiedGallery.prototype.newSrc = function (imageSrc, imgWidth, imgHeight, image) { 27832 var newImageSrc; 27833 27834 if (this.settings.thumbnailPath) { 27835 newImageSrc = this.settings.thumbnailPath(imageSrc, imgWidth, imgHeight, image); 27836 } else { 27837 var matchRes = imageSrc.match(this.settings.extension); 27838 var ext = (matchRes !== null) ? matchRes[0] : ''; 27839 newImageSrc = imageSrc.replace(this.settings.extension, ''); 27840 newImageSrc = this.removeSuffix(newImageSrc, this.getUsedSuffix(newImageSrc)); 27841 newImageSrc += this.getSuffix(imgWidth, imgHeight) + ext; 27842 } 27843 27844 return newImageSrc; 27845 }; 27846 27847 /** 27848 * Shows the images that is in the given entry 27849 * 27850 * @param $entry the entry 27851 * @param callback the callback that is called when the show animation is finished 27852 */ 27853 JustifiedGallery.prototype.showImg = function ($entry, callback) { 27854 if (this.settings.cssAnimation) { 27855 $entry.addClass('jg-entry-visible'); 27856 if (callback) callback(); 27857 } else { 27858 $entry.stop().fadeTo(this.settings.imagesAnimationDuration, 1.0, callback); 27859 $entry.find(this.settings.imgSelector).stop().fadeTo(this.settings.imagesAnimationDuration, 1.0, callback); 27860 } 27861 }; 27862 27863 /** 27864 * Extract the image src form the image, looking from the 'safe-src', and if it can't be found, from the 27865 * 'src' attribute. It saves in the image data the 'jg.originalSrc' field, with the extracted src. 27866 * 27867 * @param $image the image to analyze 27868 * @returns {String} the extracted src 27869 */ 27870 JustifiedGallery.prototype.extractImgSrcFromImage = function ($image) { 27871 var imageSrc = $image.data('safe-src'); 27872 var imageSrcLoc = 'data-safe-src'; 27873 // Begin Uncode edit 27874 if (typeof imageSrc === 'undefined') { 27875 var imageCurrentSrc = $image[0].currentSrc; 27876 if (imageCurrentSrc) { 27877 imageSrc = imageCurrentSrc; 27878 } else { 27879 imageSrc = $image.attr('src'); 27880 } 27881 imageSrcLoc = 'src'; 27882 } 27883 // End Uncode edit 27884 $image.data('jg.originalSrc', imageSrc); // this is saved for the destroy method 27885 $image.data('jg.src', imageSrc); // this will change overtime 27886 $image.data('jg.originalSrcLoc', imageSrcLoc); // this is saved for the destroy method 27887 return imageSrc; 27888 }; 27889 27890 /** @returns {jQuery} the image in the given entry */ 27891 JustifiedGallery.prototype.imgFromEntry = function ($entry) { 27892 var $img = $entry.find(this.settings.imgSelector); 27893 if ($img.length === 0) $img = $entry.find('.t-entry-visual-cont img');//hacked by Uncode 27894 return $img.length === 0 ? null : $img; 27895 }; 27896 27897 /** @returns {jQuery} the caption in the given entry */ 27898 JustifiedGallery.prototype.captionFromEntry = function ($entry) { 27899 var $caption = $entry.find('> .jg-caption'); 27900 return $caption.length === 0 ? null : $caption; 27901 }; 27902 27903 /** 27904 * Display the entry 27905 * 27906 * @param {jQuery} $entry the entry to display 27907 * @param {int} x the x position where the entry must be positioned 27908 * @param y the y position where the entry must be positioned 27909 * @param imgWidth the image width 27910 * @param imgHeight the image height 27911 * @param rowHeight the row height of the row that owns the entry 27912 */ 27913 JustifiedGallery.prototype.displayEntry = function ($entry, x, y, imgWidth, imgHeight, rowHeight) { 27914 $entry.width(imgWidth); 27915 $entry.height(Math.floor(rowHeight));//hacked by Uncode 27916 $entry.css('top', Math.floor(y));//hacked by Uncode 27917 $entry.css('left', x); 27918 27919 var $image = this.imgFromEntry($entry); 27920 if ($image !== null) { 27921 $image.css('width', imgWidth); 27922 $image.css('height', imgHeight); 27923 $image.css('margin-left', - imgWidth / 2); 27924 $image.css('margin-top', - imgHeight / 2); 27925 27926 // Image reloading for an high quality of thumbnails 27927 var imageSrc = $image.data('jg.src'); 27928 if (imageSrc) { 27929 imageSrc = this.newSrc(imageSrc, imgWidth, imgHeight, $image[0]); 27930 27931 $image.one('error', function () { 27932 this.resetImgSrc($image); //revert to the original thumbnail 27933 }); 27934 27935 var loadNewImage = function () { 27936 // if (imageSrc !== newImageSrc) { 27937 $image.attr('src', imageSrc); 27938 // } 27939 }; 27940 27941 if ($entry.data('jg.loaded') === 'skipped' && imageSrc) { 27942 this.onImageEvent(imageSrc, (function() { 27943 this.showImg($entry, loadNewImage); //load the new image after the fadeIn 27944 $entry.data('jg.loaded', true); 27945 }).bind(this)); 27946 } else { 27947 this.showImg($entry, loadNewImage); //load the new image after the fadeIn 27948 } 27949 27950 } 27951 27952 } else { 27953 this.showImg($entry); 27954 } 27955 27956 this.displayEntryCaption($entry); 27957 }; 27958 27959 /** 27960 * Display the entry caption. If the caption element doesn't exists, it creates the caption using the 'alt' 27961 * or the 'title' attributes. 27962 * 27963 * @param {jQuery} $entry the entry to process 27964 */ 27965 JustifiedGallery.prototype.displayEntryCaption = function ($entry) { 27966 var $image = this.imgFromEntry($entry); 27967 if ($image !== null && this.settings.captions) { 27968 var $imgCaption = this.captionFromEntry($entry); 27969 27970 // Create it if it doesn't exists 27971 if ($imgCaption === null) { 27972 var caption = $image.attr('alt'); 27973 if (!this.isValidCaption(caption)) caption = $entry.attr('title'); 27974 if (this.isValidCaption(caption)) { // Create only we found something 27975 $imgCaption = $('<div class="jg-caption">' + caption + '</div>'); 27976 $entry.append($imgCaption); 27977 $entry.data('jg.createdCaption', true); 27978 } 27979 } 27980 27981 // Create events (we check again the $imgCaption because it can be still inexistent) 27982 if ($imgCaption !== null) { 27983 if (!this.settings.cssAnimation) $imgCaption.stop().fadeTo(0, this.settings.captionSettings.nonVisibleOpacity); 27984 this.addCaptionEventsHandlers($entry); 27985 } 27986 } else { 27987 this.removeCaptionEventsHandlers($entry); 27988 } 27989 }; 27990 27991 /** 27992 * Validates the caption 27993 * 27994 * @param caption The caption that should be validated 27995 * @return {boolean} Validation result 27996 */ 27997 JustifiedGallery.prototype.isValidCaption = function (caption) { 27998 return (typeof caption !== 'undefined' && caption.length > 0); 27999 }; 28000 28001 /** 28002 * The callback for the event 'mouseenter'. It assumes that the event currentTarget is an entry. 28003 * It shows the caption using jQuery (or using CSS if it is configured so) 28004 * 28005 * @param {Event} eventObject the event object 28006 */ 28007 JustifiedGallery.prototype.onEntryMouseEnterForCaption = function (eventObject) { 28008 var $caption = this.captionFromEntry($(eventObject.currentTarget)); 28009 if (this.settings.cssAnimation) { 28010 $caption.addClass('jg-caption-visible').removeClass('jg-caption-hidden'); 28011 } else { 28012 $caption.stop().fadeTo(this.settings.captionSettings.animationDuration, 28013 this.settings.captionSettings.visibleOpacity); 28014 } 28015 }; 28016 28017 /** 28018 * The callback for the event 'mouseleave'. It assumes that the event currentTarget is an entry. 28019 * It hides the caption using jQuery (or using CSS if it is configured so) 28020 * 28021 * @param {Event} eventObject the event object 28022 */ 28023 JustifiedGallery.prototype.onEntryMouseLeaveForCaption = function (eventObject) { 28024 var $caption = this.captionFromEntry($(eventObject.currentTarget)); 28025 if (this.settings.cssAnimation) { 28026 $caption.removeClass('jg-caption-visible').removeClass('jg-caption-hidden'); 28027 } else { 28028 $caption.stop().fadeTo(this.settings.captionSettings.animationDuration, 28029 this.settings.captionSettings.nonVisibleOpacity); 28030 } 28031 }; 28032 28033 /** 28034 * Add the handlers of the entry for the caption 28035 * 28036 * @param $entry the entry to modify 28037 */ 28038 JustifiedGallery.prototype.addCaptionEventsHandlers = function ($entry) { 28039 var captionMouseEvents = $entry.data('jg.captionMouseEvents'); 28040 if (typeof captionMouseEvents === 'undefined') { 28041 captionMouseEvents = { 28042 mouseenter: $.proxy(this.onEntryMouseEnterForCaption, this), 28043 mouseleave: $.proxy(this.onEntryMouseLeaveForCaption, this) 28044 }; 28045 $entry.on('mouseenter', undefined, undefined, captionMouseEvents.mouseenter); 28046 $entry.on('mouseleave', undefined, undefined, captionMouseEvents.mouseleave); 28047 $entry.data('jg.captionMouseEvents', captionMouseEvents); 28048 } 28049 }; 28050 28051 /** 28052 * Remove the handlers of the entry for the caption 28053 * 28054 * @param $entry the entry to modify 28055 */ 28056 JustifiedGallery.prototype.removeCaptionEventsHandlers = function ($entry) { 28057 var captionMouseEvents = $entry.data('jg.captionMouseEvents'); 28058 if (typeof captionMouseEvents !== 'undefined') { 28059 $entry.off('mouseenter', undefined, captionMouseEvents.mouseenter); 28060 $entry.off('mouseleave', undefined, captionMouseEvents.mouseleave); 28061 $entry.removeData('jg.captionMouseEvents'); 28062 } 28063 }; 28064 28065 /** 28066 * Clear the building row data to be used for a new row 28067 */ 28068 JustifiedGallery.prototype.clearBuildingRow = function () { 28069 this.buildingRow.entriesBuff = []; 28070 this.buildingRow.aspectRatio = 0; 28071 this.buildingRow.width = 0; 28072 }; 28073 28074 /** 28075 * Justify the building row, preparing it to 28076 * 28077 * @param isLastRow 28078 * @param hiddenRow undefined or false for normal behavior. hiddenRow = true to hide the row. 28079 * @returns a boolean to know if the row has been justified or not 28080 */ 28081 JustifiedGallery.prototype.prepareBuildingRow = function (isLastRow, hiddenRow) { 28082 var i, $entry, imgAspectRatio, newImgW, newImgH, justify = true; 28083 var minHeight = 0; 28084 var availableWidth = this.galleryWidth - 2 * this.border - ( 28085 (this.buildingRow.entriesBuff.length - 1) * this.settings.margins); 28086 var rowHeight = Math.floor( availableWidth / this.buildingRow.aspectRatio );//hacked by Uncode 28087 var defaultRowHeight = this.settings.rowHeight; 28088 var justifiable = this.buildingRow.width / availableWidth > this.settings.justifyThreshold; 28089 28090 //Skip the last row if we can't justify it and the lastRow == 'hide' 28091 if (hiddenRow || (isLastRow && this.settings.lastRow === 'hide' && !justifiable)) { 28092 for (i = 0; i < this.buildingRow.entriesBuff.length; i++) { 28093 $entry = this.buildingRow.entriesBuff[i]; 28094 if (this.settings.cssAnimation) 28095 $entry.removeClass('jg-entry-visible'); 28096 else { 28097 $entry.stop().fadeTo(0, 0.1); 28098 $entry.find('> img, > a > img').fadeTo(0, 0); 28099 } 28100 } 28101 return -1; 28102 } 28103 28104 // With lastRow = nojustify, justify if is justificable (the images will not become too big) 28105 if (isLastRow && !justifiable && this.settings.lastRow !== 'justify' && this.settings.lastRow !== 'hide') { 28106 justify = false; 28107 28108 if (this.rows > 0) { 28109 defaultRowHeight = (this.offY - this.border - this.settings.margins * this.rows) / this.rows; 28110 justify = defaultRowHeight * this.buildingRow.aspectRatio / availableWidth > this.settings.justifyThreshold; 28111 } 28112 } 28113 28114 for (i = 0; i < this.buildingRow.entriesBuff.length; i++) { 28115 $entry = this.buildingRow.entriesBuff[i]; 28116 imgAspectRatio = $entry.data('jg.width') / $entry.data('jg.height'); 28117 28118 if (justify) { 28119 newImgW = (i === this.buildingRow.entriesBuff.length - 1) ? availableWidth : rowHeight * imgAspectRatio; 28120 newImgH = rowHeight; 28121 } else { 28122 newImgW = defaultRowHeight * imgAspectRatio; 28123 newImgH = defaultRowHeight; 28124 } 28125 28126 availableWidth -= Math.round(newImgW); 28127 $entry.data('jg.jwidth', Math.round(newImgW)); 28128 $entry.data('jg.jheight', Math.ceil(newImgH)); 28129 if (i === 0 || minHeight > newImgH) minHeight = newImgH; 28130 } 28131 28132 this.buildingRow.height = minHeight; 28133 return justify; 28134 }; 28135 28136 /** 28137 * Flush a row: justify it, modify the gallery height accordingly to the row height 28138 * 28139 * @param isLastRow 28140 * @param hiddenRow undefined or false for normal behavior. hiddenRow = true to hide the row. 28141 */ 28142 JustifiedGallery.prototype.flushRow = function (isLastRow, hiddenRow) { 28143 var settings = this.settings; 28144 var $entry, buildingRowRes, offX = this.border, i; 28145 28146 buildingRowRes = this.prepareBuildingRow(isLastRow, hiddenRow); 28147 if (hiddenRow || (isLastRow && settings.lastRow === 'hide' && buildingRowRes === -1)) { 28148 this.clearBuildingRow(); 28149 return; 28150 } 28151 28152 if (this.maxRowHeight) { 28153 if (this.maxRowHeight < this.buildingRow.height) this.buildingRow.height = this.maxRowHeight; 28154 } 28155 28156 //Align last (unjustified) row 28157 if (isLastRow && (settings.lastRow === 'center' || settings.lastRow === 'right')) { 28158 var availableWidth = this.galleryWidth - 2 * this.border - (this.buildingRow.entriesBuff.length - 1) * settings.margins; 28159 28160 for (i = 0; i < this.buildingRow.entriesBuff.length; i++) { 28161 $entry = this.buildingRow.entriesBuff[i]; 28162 availableWidth -= $entry.data('jg.jwidth'); 28163 } 28164 28165 if (settings.lastRow === 'center') 28166 offX += Math.round(availableWidth / 2); 28167 else if (settings.lastRow === 'right') 28168 offX += availableWidth; 28169 } 28170 28171 var lastEntryIdx = this.buildingRow.entriesBuff.length - 1; 28172 for (i = 0; i <= lastEntryIdx; i++) { 28173 $entry = this.buildingRow.entriesBuff[this.settings.rtl ? lastEntryIdx - i : i]; 28174 this.displayEntry($entry, offX, this.offY, $entry.data('jg.jwidth'), $entry.data('jg.jheight'), this.buildingRow.height); 28175 offX += $entry.data('jg.jwidth') + settings.margins; 28176 } 28177 28178 //Gallery Height 28179 this.galleryHeightToSet = this.offY + this.buildingRow.height + this.border; 28180 this.setGalleryTempHeight(this.galleryHeightToSet + this.getSpinnerHeight()); 28181 28182 if (!isLastRow || (this.buildingRow.height <= settings.rowHeight && buildingRowRes)) { 28183 //Ready for a new row 28184 this.offY += this.buildingRow.height + settings.margins; 28185 this.rows += 1; 28186 this.clearBuildingRow(); 28187 this.settings.triggerEvent.call(this, 'jg.rowflush'); 28188 } 28189 }; 28190 28191 28192 // Scroll position not restoring: https://github.com/miromannino/Justified-Gallery/issues/221 28193 var galleryPrevStaticHeight = 0; 28194 28195 JustifiedGallery.prototype.rememberGalleryHeight = function () { 28196 galleryPrevStaticHeight = this.$gallery.height(); 28197 this.$gallery.height(galleryPrevStaticHeight); 28198 }; 28199 28200 // grow only 28201 JustifiedGallery.prototype.setGalleryTempHeight = function (height) { 28202 galleryPrevStaticHeight = Math.max(height, galleryPrevStaticHeight); 28203 this.$gallery.height(galleryPrevStaticHeight); 28204 }; 28205 28206 JustifiedGallery.prototype.setGalleryFinalHeight = function (height) { 28207 galleryPrevStaticHeight = height; 28208 this.$gallery.height(height); 28209 }; 28210 28211 /** 28212 * Checks the width of the gallery container, to know if a new justification is needed 28213 */ 28214 JustifiedGallery.prototype.checkWidth = function () { 28215 this.checkWidthIntervalId = setInterval($.proxy(function () { 28216 28217 // if the gallery is not currently visible, abort. 28218 if (!this.$gallery.is(":visible")) return; 28219 28220 var galleryWidth = parseFloat(this.$gallery.width()); 28221 if (Math.abs(galleryWidth - this.galleryWidth) > this.settings.refreshSensitivity) { 28222 this.galleryWidth = galleryWidth; 28223 this.rewind(); 28224 28225 this.rememberGalleryHeight(); 28226 28227 // Restart to analyze 28228 this.startImgAnalyzer(true); 28229 } 28230 }, this), this.settings.refreshTime); 28231 }; 28232 28233 /** 28234 * @returns {boolean} a boolean saying if the spinner is active or not 28235 */ 28236 JustifiedGallery.prototype.isSpinnerActive = function () { 28237 return this.spinner.intervalId !== null; 28238 }; 28239 28240 /** 28241 * @returns {int} the spinner height 28242 */ 28243 JustifiedGallery.prototype.getSpinnerHeight = function () { 28244 return this.spinner.$el.innerHeight(); 28245 }; 28246 28247 /** 28248 * Stops the spinner animation and modify the gallery height to exclude the spinner 28249 */ 28250 JustifiedGallery.prototype.stopLoadingSpinnerAnimation = function () { 28251 clearInterval(this.spinner.intervalId); 28252 this.spinner.intervalId = null; 28253 this.setGalleryTempHeight(this.$gallery.height() - this.getSpinnerHeight()); 28254 this.spinner.$el.detach(); 28255 }; 28256 28257 /** 28258 * Starts the spinner animation 28259 */ 28260 JustifiedGallery.prototype.startLoadingSpinnerAnimation = function () { 28261 var spinnerContext = this.spinner; 28262 var $spinnerPoints = spinnerContext.$el.find('span'); 28263 clearInterval(spinnerContext.intervalId); 28264 this.$gallery.append(spinnerContext.$el); 28265 this.setGalleryTempHeight(this.offY + this.buildingRow.height + this.getSpinnerHeight()); 28266 spinnerContext.intervalId = setInterval(function () { 28267 if (spinnerContext.phase < $spinnerPoints.length) { 28268 $spinnerPoints.eq(spinnerContext.phase).fadeTo(spinnerContext.timeSlot, 1); 28269 } else { 28270 $spinnerPoints.eq(spinnerContext.phase - $spinnerPoints.length).fadeTo(spinnerContext.timeSlot, 0); 28271 } 28272 spinnerContext.phase = (spinnerContext.phase + 1) % ($spinnerPoints.length * 2); 28273 }, spinnerContext.timeSlot); 28274 }; 28275 28276 /** 28277 * Rewind the image analysis to start from the first entry. 28278 */ 28279 JustifiedGallery.prototype.rewind = function () { 28280 this.lastFetchedEntry = null; 28281 this.lastAnalyzedIndex = -1; 28282 this.offY = this.border; 28283 this.rows = 0; 28284 this.clearBuildingRow(); 28285 }; 28286 28287 /** 28288 * @returns {String} `settings.selector` rejecting spinner element 28289 */ 28290 JustifiedGallery.prototype.getSelectorWithoutSpinner = function () { 28291 return this.settings.selector + ', div:not(.jg-spinner)'; 28292 }; 28293 28294 /** 28295 * @returns {Array} all entries matched by `settings.selector` 28296 */ 28297 JustifiedGallery.prototype.getAllEntries = function () { 28298 var selector = this.getSelectorWithoutSpinner(); 28299 return this.$gallery.children(selector).toArray(); 28300 }; 28301 28302 /** 28303 * Update the entries searching it from the justified gallery HTML element 28304 * 28305 * @param norewind if norewind only the new entries will be changed (i.e. randomized, sorted or filtered) 28306 * @returns {boolean} true if some entries has been founded 28307 */ 28308 JustifiedGallery.prototype.updateEntries = function (norewind) { 28309 var newEntries; 28310 28311 if (norewind && this.lastFetchedEntry != null) { 28312 var selector = this.getSelectorWithoutSpinner(); 28313 newEntries = $(this.lastFetchedEntry).nextAll(selector).toArray(); 28314 } else { 28315 this.entries = []; 28316 newEntries = this.getAllEntries(); 28317 } 28318 28319 if (newEntries.length > 0) { 28320 28321 // Sort or randomize 28322 if ($.isFunction(this.settings.sort)) { 28323 newEntries = this.sortArray(newEntries); 28324 } else if (this.settings.randomize) { 28325 newEntries = this.shuffleArray(newEntries); 28326 } 28327 this.lastFetchedEntry = newEntries[newEntries.length - 1]; 28328 28329 // Filter 28330 if (this.settings.filter) { 28331 newEntries = this.filterArray(newEntries); 28332 } else { 28333 this.resetFilters(newEntries); 28334 } 28335 28336 } 28337 28338 this.entries = this.entries.concat(newEntries); 28339 return true; 28340 }; 28341 28342 /** 28343 * Apply the entries order to the DOM, iterating the entries and appending the images 28344 * 28345 * @param entries the entries that has been modified and that must be re-ordered in the DOM 28346 */ 28347 JustifiedGallery.prototype.insertToGallery = function (entries) { 28348 var that = this; 28349 $.each(entries, function () { 28350 $(this).appendTo(that.$gallery); 28351 }); 28352 }; 28353 28354 /** 28355 * Shuffle the array using the Fisher-Yates shuffle algorithm 28356 * 28357 * @param a the array to shuffle 28358 * @return the shuffled array 28359 */ 28360 JustifiedGallery.prototype.shuffleArray = function (a) { 28361 var i, j, temp; 28362 for (i = a.length - 1; i > 0; i--) { 28363 j = Math.floor(Math.random() * (i + 1)); 28364 temp = a[i]; 28365 a[i] = a[j]; 28366 a[j] = temp; 28367 } 28368 this.insertToGallery(a); 28369 return a; 28370 }; 28371 28372 /** 28373 * Sort the array using settings.comparator as comparator 28374 * 28375 * @param a the array to sort (it is sorted) 28376 * @return the sorted array 28377 */ 28378 JustifiedGallery.prototype.sortArray = function (a) { 28379 a.sort(this.settings.sort); 28380 this.insertToGallery(a); 28381 return a; 28382 }; 28383 28384 /** 28385 * Reset the filters removing the 'jg-filtered' class from all the entries 28386 * 28387 * @param a the array to reset 28388 */ 28389 JustifiedGallery.prototype.resetFilters = function (a) { 28390 for (var i = 0; i < a.length; i++) $(a[i]).removeClass('jg-filtered'); 28391 }; 28392 28393 /** 28394 * Filter the entries considering theirs classes (if a string has been passed) or using a function for filtering. 28395 * 28396 * @param a the array to filter 28397 * @return the filtered array 28398 */ 28399 JustifiedGallery.prototype.filterArray = function (a) { 28400 var settings = this.settings; 28401 if ($.type(settings.filter) === 'string') { 28402 // Filter only keeping the entries passed in the string 28403 return a.filter(function (el) { 28404 var $el = $(el); 28405 if ($el.is(settings.filter)) { 28406 $el.removeClass('jg-filtered'); 28407 return true; 28408 } else { 28409 $el.addClass('jg-filtered').removeClass('jg-visible'); 28410 return false; 28411 } 28412 }); 28413 } else if ($.isFunction(settings.filter)) { 28414 // Filter using the passed function 28415 var filteredArr = a.filter(settings.filter); 28416 for (var i = 0; i < a.length; i++) { 28417 if (filteredArr.indexOf(a[i]) === -1) { 28418 $(a[i]).addClass('jg-filtered').removeClass('jg-visible'); 28419 } else { 28420 $(a[i]).removeClass('jg-filtered'); 28421 } 28422 } 28423 return filteredArr; 28424 } 28425 }; 28426 28427 /** 28428 * Revert the image src to the default value. 28429 */ 28430 JustifiedGallery.prototype.resetImgSrc = function ($img) { 28431 if ($img.data('jg.originalSrcLoc') === 'src') { 28432 $img.attr('src', $img.data('jg.originalSrc')); 28433 } else { 28434 $img.attr('src', ''); 28435 } 28436 }; 28437 28438 /** 28439 * Destroy the Justified Gallery instance. 28440 * 28441 * It clears all the css properties added in the style attributes. We doesn't backup the original 28442 * values for those css attributes, because it costs (performance) and because in general one 28443 * shouldn't use the style attribute for an uniform set of images (where we suppose the use of 28444 * classes). Creating a backup is also difficult because JG could be called multiple times and 28445 * with different style attributes. 28446 */ 28447 JustifiedGallery.prototype.destroy = function () { 28448 clearInterval(this.checkWidthIntervalId); 28449 this.stopImgAnalyzerStarter(); 28450 28451 // Get fresh entries list since filtered entries are absent in `this.entries` 28452 $.each(this.getAllEntries(), $.proxy(function (_, entry) { 28453 var $entry = $(entry); 28454 28455 // Reset entry style 28456 $entry.css('width', ''); 28457 $entry.css('height', ''); 28458 $entry.css('top', ''); 28459 $entry.css('left', ''); 28460 $entry.data('jg.loaded', undefined); 28461 $entry.removeClass('jg-entry jg-filtered jg-entry-visible'); 28462 28463 // Reset image style 28464 var $img = this.imgFromEntry($entry); 28465 if ($img) { 28466 $img.css('width', ''); 28467 $img.css('height', ''); 28468 $img.css('margin-left', ''); 28469 $img.css('margin-top', ''); 28470 this.resetImgSrc($img); 28471 $img.data('jg.originalSrc', undefined); 28472 $img.data('jg.originalSrcLoc', undefined); 28473 $img.data('jg.src', undefined); 28474 } 28475 28476 // Remove caption 28477 this.removeCaptionEventsHandlers($entry); 28478 var $caption = this.captionFromEntry($entry); 28479 if ($entry.data('jg.createdCaption')) { 28480 // remove also the caption element (if created by jg) 28481 $entry.data('jg.createdCaption', undefined); 28482 if ($caption !== null) $caption.remove(); 28483 } else { 28484 if ($caption !== null) $caption.fadeTo(0, 1); 28485 } 28486 28487 }, this)); 28488 28489 this.$gallery.css('height', ''); 28490 this.$gallery.removeClass('justified-gallery'); 28491 this.$gallery.data('jg.controller', undefined); 28492 this.settings.triggerEvent.call(this, 'jg.destroy'); 28493 }; 28494 28495 /** 28496 * Analyze the images and builds the rows. It returns if it found an image that is not loaded. 28497 * 28498 * @param isForResize if the image analyzer is called for resizing or not, to call a different callback at the end 28499 */ 28500 JustifiedGallery.prototype.analyzeImages = function (isForResize) { 28501 for (var i = this.lastAnalyzedIndex + 1; i < this.entries.length; i++) { 28502 var $entry = $(this.entries[i]); 28503 if ($entry.data('jg.loaded') === true || $entry.data('jg.loaded') === 'skipped') { 28504 var availableWidth = this.galleryWidth - 2 * this.border - ( 28505 (this.buildingRow.entriesBuff.length - 1) * this.settings.margins); 28506 var imgAspectRatio = $entry.data('jg.width') / $entry.data('jg.height'); 28507 28508 this.buildingRow.entriesBuff.push($entry); 28509 this.buildingRow.aspectRatio += imgAspectRatio; 28510 this.buildingRow.width += imgAspectRatio * this.settings.rowHeight; 28511 this.lastAnalyzedIndex = i; 28512 28513 if (availableWidth / (this.buildingRow.aspectRatio + imgAspectRatio) < this.settings.rowHeight) { 28514 this.flushRow(false, this.settings.maxRowsCount > 0 && this.rows === this.settings.maxRowsCount); 28515 28516 if (++this.yield.flushed >= this.yield.every) { 28517 this.startImgAnalyzer(isForResize); 28518 return; 28519 } 28520 } 28521 } else if ($entry.data('jg.loaded') !== 'error') { 28522 return; 28523 } 28524 } 28525 28526 // Last row flush (the row is not full) 28527 if (this.buildingRow.entriesBuff.length > 0) { 28528 this.flushRow(true, this.settings.maxRowsCount > 0 && this.rows === this.settings.maxRowsCount); 28529 } 28530 28531 if (this.isSpinnerActive()) { 28532 this.stopLoadingSpinnerAnimation(); 28533 } 28534 28535 /* Stop, if there is, the timeout to start the analyzeImages. 28536 This is because an image can be set loaded, and the timeout can be set, 28537 but this image can be analyzed yet. 28538 */ 28539 this.stopImgAnalyzerStarter(); 28540 28541 this.setGalleryFinalHeight(this.galleryHeightToSet); 28542 28543 //On complete callback 28544 this.settings.triggerEvent.call(this, isForResize ? 'jg.resize' : 'jg.complete'); 28545 }; 28546 28547 /** 28548 * Stops any ImgAnalyzer starter (that has an assigned timeout) 28549 */ 28550 JustifiedGallery.prototype.stopImgAnalyzerStarter = function () { 28551 this.yield.flushed = 0; 28552 if (this.imgAnalyzerTimeout !== null) { 28553 clearTimeout(this.imgAnalyzerTimeout); 28554 this.imgAnalyzerTimeout = null; 28555 } 28556 }; 28557 28558 /** 28559 * Starts the image analyzer. It is not immediately called to let the browser to update the view 28560 * 28561 * @param isForResize specifies if the image analyzer must be called for resizing or not 28562 */ 28563 JustifiedGallery.prototype.startImgAnalyzer = function (isForResize) { 28564 var that = this; 28565 this.stopImgAnalyzerStarter(); 28566 this.imgAnalyzerTimeout = setTimeout(function () { 28567 that.analyzeImages(isForResize); 28568 }, 0.001); // we can't start it immediately due to a IE different behaviour 28569 }; 28570 28571 /** 28572 * Checks if the image is loaded or not using another image object. We cannot use the 'complete' image property, 28573 * because some browsers, with a 404 set complete = true. 28574 * 28575 * @param imageSrc the image src to load 28576 * @param onLoad callback that is called when the image has been loaded 28577 * @param onError callback that is called in case of an error 28578 */ 28579 JustifiedGallery.prototype.onImageEvent = function (imageSrc, onLoad, onError) { 28580 if (!onLoad && !onError) return; 28581 28582 var memImage = new Image(); 28583 var $memImage = $(memImage); 28584 if (onLoad) { 28585 $memImage.one('load', function () { 28586 $memImage.off('load error'); 28587 onLoad(memImage); 28588 }); 28589 } 28590 if (onError) { 28591 $memImage.one('error', function () { 28592 $memImage.off('load error'); 28593 onError(memImage); 28594 }); 28595 } 28596 memImage.src = imageSrc; 28597 }; 28598 28599 /** 28600 * Init of Justified Gallery controlled 28601 * It analyzes all the entries starting theirs loading and calling the image analyzer (that works with loaded images) 28602 */ 28603 JustifiedGallery.prototype.init = function () { 28604 var imagesToLoad = false, skippedImages = false, that = this; 28605 $.each(this.entries, function (index, entry) { 28606 var $entry = $(entry); 28607 var $image = that.imgFromEntry($entry); 28608 28609 $entry.addClass('jg-entry'); 28610 28611 if ($entry.data('jg.loaded') !== true && $entry.data('jg.loaded') !== 'skipped') { 28612 28613 // Link Rel global overwrite 28614 if (that.settings.rel !== null) $entry.attr('rel', that.settings.rel); 28615 28616 // Link Target global overwrite 28617 if (that.settings.target !== null) $entry.attr('target', that.settings.target); 28618 28619 if ($image !== null) { 28620 28621 // Image src 28622 var imageSrc = that.extractImgSrcFromImage($image); 28623 28624 /* If we have the height and the width, we don't wait that the image is loaded, 28625 but we start directly with the justification */ 28626 if (that.settings.waitThumbnailsLoad === false || !imageSrc) { 28627 var width = parseFloat($image.attr('width')); 28628 var height = parseFloat($image.attr('height')); 28629 if ($image.prop('tagName') === 'svg') { 28630 width = parseFloat($image[0].getBBox().width); 28631 height = parseFloat($image[0].getBBox().height); 28632 } 28633 if (!isNaN(width) && !isNaN(height)) { 28634 $entry.data('jg.width', width); 28635 $entry.data('jg.height', height); 28636 $entry.data('jg.loaded', 'skipped'); 28637 skippedImages = true; 28638 that.startImgAnalyzer(false); 28639 return true; // continue 28640 } 28641 } 28642 28643 $entry.data('jg.loaded', false); 28644 imagesToLoad = true; 28645 28646 // Spinner start 28647 if (!that.isSpinnerActive()) that.startLoadingSpinnerAnimation(); 28648 28649 that.onImageEvent(imageSrc, function (loadImg) { // image loaded 28650 $entry.data('jg.width', loadImg.width); 28651 $entry.data('jg.height', loadImg.height); 28652 $entry.data('jg.loaded', true); 28653 that.startImgAnalyzer(false); 28654 }, function () { // image load error 28655 $entry.data('jg.loaded', 'error'); 28656 that.startImgAnalyzer(false); 28657 }); 28658 28659 } else { 28660 $entry.data('jg.loaded', true); 28661 $entry.data('jg.width', $entry.width() | parseFloat($entry.css('width')) | 1); 28662 $entry.data('jg.height', $entry.height() | parseFloat($entry.css('height')) | 1); 28663 } 28664 28665 } 28666 28667 }); 28668 28669 if (!imagesToLoad && !skippedImages) this.startImgAnalyzer(false); 28670 this.checkWidth(); 28671 }; 28672 28673 /** 28674 * Checks that it is a valid number. If a string is passed it is converted to a number 28675 * 28676 * @param settingContainer the object that contains the setting (to allow the conversion) 28677 * @param settingName the setting name 28678 */ 28679 JustifiedGallery.prototype.checkOrConvertNumber = function (settingContainer, settingName) { 28680 if ($.type(settingContainer[settingName]) === 'string') { 28681 settingContainer[settingName] = parseFloat(settingContainer[settingName]); 28682 } 28683 28684 if ($.type(settingContainer[settingName]) === 'number') { 28685 if (isNaN(settingContainer[settingName])) throw 'invalid number for ' + settingName; 28686 } else { 28687 throw settingName + ' must be a number'; 28688 } 28689 }; 28690 28691 /** 28692 * Checks the sizeRangeSuffixes and, if necessary, converts 28693 * its keys from string (e.g. old settings with 'lt100') to int. 28694 */ 28695 JustifiedGallery.prototype.checkSizeRangesSuffixes = function () { 28696 if ($.type(this.settings.sizeRangeSuffixes) !== 'object') { 28697 throw 'sizeRangeSuffixes must be defined and must be an object'; 28698 } 28699 28700 var suffixRanges = []; 28701 for (var rangeIdx in this.settings.sizeRangeSuffixes) { 28702 if (this.settings.sizeRangeSuffixes.hasOwnProperty(rangeIdx)) suffixRanges.push(rangeIdx); 28703 } 28704 28705 var newSizeRngSuffixes = { 0: '' }; 28706 for (var i = 0; i < suffixRanges.length; i++) { 28707 if ($.type(suffixRanges[i]) === 'string') { 28708 try { 28709 var numIdx = parseInt(suffixRanges[i].replace(/^[a-z]+/, ''), 10); 28710 newSizeRngSuffixes[numIdx] = this.settings.sizeRangeSuffixes[suffixRanges[i]]; 28711 } catch (e) { 28712 throw 'sizeRangeSuffixes keys must contains correct numbers (' + e + ')'; 28713 } 28714 } else { 28715 newSizeRngSuffixes[suffixRanges[i]] = this.settings.sizeRangeSuffixes[suffixRanges[i]]; 28716 } 28717 } 28718 28719 this.settings.sizeRangeSuffixes = newSizeRngSuffixes; 28720 }; 28721 28722 /** 28723 * check and convert the maxRowHeight setting 28724 * requires rowHeight to be already set 28725 * TODO: should be always called when only rowHeight is changed 28726 * @return number or null 28727 */ 28728 JustifiedGallery.prototype.retrieveMaxRowHeight = function () { 28729 var newMaxRowHeight = null; 28730 var rowHeight = this.settings.rowHeight; 28731 28732 if ($.type(this.settings.maxRowHeight) === 'string') { 28733 if (this.settings.maxRowHeight.match(/^[0-9]+%$/)) { 28734 newMaxRowHeight = rowHeight * parseFloat(this.settings.maxRowHeight.match(/^([0-9]+)%$/)[1]) / 100; 28735 } else { 28736 newMaxRowHeight = parseFloat(this.settings.maxRowHeight); 28737 } 28738 } else if ($.type(this.settings.maxRowHeight) === 'number') { 28739 newMaxRowHeight = this.settings.maxRowHeight; 28740 } else if (this.settings.maxRowHeight === false || this.settings.maxRowHeight == null) { 28741 return null; 28742 } else { 28743 throw 'maxRowHeight must be a number or a percentage'; 28744 } 28745 28746 // check if the converted value is not a number 28747 if (isNaN(newMaxRowHeight)) throw 'invalid number for maxRowHeight'; 28748 28749 // check values, maxRowHeight must be >= rowHeight 28750 if (newMaxRowHeight < rowHeight) newMaxRowHeight = rowHeight; 28751 28752 return newMaxRowHeight; 28753 }; 28754 28755 /** 28756 * Checks the settings 28757 */ 28758 JustifiedGallery.prototype.checkSettings = function () { 28759 this.checkSizeRangesSuffixes(); 28760 28761 this.checkOrConvertNumber(this.settings, 'rowHeight'); 28762 this.checkOrConvertNumber(this.settings, 'margins'); 28763 this.checkOrConvertNumber(this.settings, 'border'); 28764 this.checkOrConvertNumber(this.settings, 'maxRowsCount'); 28765 28766 var lastRowModes = [ 28767 'justify', 28768 'nojustify', 28769 'left', 28770 'center', 28771 'right', 28772 'hide' 28773 ]; 28774 if (lastRowModes.indexOf(this.settings.lastRow) === -1) { 28775 throw 'lastRow must be one of: ' + lastRowModes.join(', '); 28776 } 28777 28778 this.checkOrConvertNumber(this.settings, 'justifyThreshold'); 28779 if (this.settings.justifyThreshold < 0 || this.settings.justifyThreshold > 1) { 28780 throw 'justifyThreshold must be in the interval [0,1]'; 28781 } 28782 if ($.type(this.settings.cssAnimation) !== 'boolean') { 28783 throw 'cssAnimation must be a boolean'; 28784 } 28785 28786 if ($.type(this.settings.captions) !== 'boolean') throw 'captions must be a boolean'; 28787 this.checkOrConvertNumber(this.settings.captionSettings, 'animationDuration'); 28788 28789 this.checkOrConvertNumber(this.settings.captionSettings, 'visibleOpacity'); 28790 if (this.settings.captionSettings.visibleOpacity < 0 || 28791 this.settings.captionSettings.visibleOpacity > 1) { 28792 throw 'captionSettings.visibleOpacity must be in the interval [0, 1]'; 28793 } 28794 28795 this.checkOrConvertNumber(this.settings.captionSettings, 'nonVisibleOpacity'); 28796 if (this.settings.captionSettings.nonVisibleOpacity < 0 || 28797 this.settings.captionSettings.nonVisibleOpacity > 1) { 28798 throw 'captionSettings.nonVisibleOpacity must be in the interval [0, 1]'; 28799 } 28800 28801 this.checkOrConvertNumber(this.settings, 'imagesAnimationDuration'); 28802 this.checkOrConvertNumber(this.settings, 'refreshTime'); 28803 this.checkOrConvertNumber(this.settings, 'refreshSensitivity'); 28804 if ($.type(this.settings.randomize) !== 'boolean') throw 'randomize must be a boolean'; 28805 if ($.type(this.settings.selector) !== 'string') throw 'selector must be a string'; 28806 28807 if (this.settings.sort !== false && !$.isFunction(this.settings.sort)) { 28808 throw 'sort must be false or a comparison function'; 28809 } 28810 28811 if (this.settings.filter !== false && !$.isFunction(this.settings.filter) && 28812 $.type(this.settings.filter) !== 'string') { 28813 throw 'filter must be false, a string or a filter function'; 28814 } 28815 }; 28816 28817 /** 28818 * It brings all the indexes from the sizeRangeSuffixes and it orders them. They are then sorted and returned. 28819 * @returns {Array} sorted suffix ranges 28820 */ 28821 JustifiedGallery.prototype.retrieveSuffixRanges = function () { 28822 var suffixRanges = []; 28823 for (var rangeIdx in this.settings.sizeRangeSuffixes) { 28824 if (this.settings.sizeRangeSuffixes.hasOwnProperty(rangeIdx)) suffixRanges.push(parseInt(rangeIdx, 10)); 28825 } 28826 suffixRanges.sort(function (a, b) { return a > b ? 1 : a < b ? -1 : 0; }); 28827 return suffixRanges; 28828 }; 28829 28830 /** 28831 * Update the existing settings only changing some of them 28832 * 28833 * @param newSettings the new settings (or a subgroup of them) 28834 */ 28835 JustifiedGallery.prototype.updateSettings = function (newSettings) { 28836 // In this case Justified Gallery has been called again changing only some options 28837 this.settings = $.extend({}, this.settings, newSettings); 28838 this.checkSettings(); 28839 28840 // As reported in the settings: negative value = same as margins, 0 = disabled 28841 this.border = this.settings.border >= 0 ? this.settings.border : this.settings.margins; 28842 28843 this.maxRowHeight = this.retrieveMaxRowHeight(); 28844 this.suffixRanges = this.retrieveSuffixRanges(); 28845 }; 28846 28847 JustifiedGallery.prototype.defaults = { 28848 sizeRangeSuffixes: {}, /* e.g. Flickr configuration 28849 { 28850 100: '_t', // used when longest is less than 100px 28851 240: '_m', // used when longest is between 101px and 240px 28852 320: '_n', // ... 28853 500: '', 28854 640: '_z', 28855 1024: '_b' // used as else case because it is the last 28856 } 28857 */ 28858 thumbnailPath: undefined, /* If defined, sizeRangeSuffixes is not used, and this function is used to determine the 28859 path relative to a specific thumbnail size. The function should accept respectively three arguments: 28860 current path, width and height */ 28861 rowHeight: 120, // required? required to be > 0? 28862 maxRowHeight: false, // false or negative value to deactivate. Positive number to express the value in pixels, 28863 // A string '[0-9]+%' to express in percentage (e.g. 300% means that the row height 28864 // can't exceed 3 * rowHeight) 28865 maxRowsCount: 0, // maximum number of rows to be displayed (0 = disabled) 28866 margins: 1, 28867 border: -1, // negative value = same as margins, 0 = disabled, any other value to set the border 28868 28869 lastRow: 'nojustify', // ⦠which is the same as 'left', or can be 'justify', 'center', 'right' or 'hide' 28870 28871 justifyThreshold: 0.90, /* if row width / available space > 0.90 it will be always justified 28872 * (i.e. lastRow setting is not considered) */ 28873 waitThumbnailsLoad: true, 28874 captions: true, 28875 cssAnimation: true, 28876 imagesAnimationDuration: 500, // ignored with css animations 28877 captionSettings: { // ignored with css animations 28878 animationDuration: 500, 28879 visibleOpacity: 0.7, 28880 nonVisibleOpacity: 0.0 28881 },
28882 rel: null, // rewrite the rel of each analyzed links 28883 target: null, // rewrite the target of all links 28884 extension: /\.[^.\\/]+$/, // regexp to capture the extension of an image 28885 refreshTime: 200, // time interval (in ms) to check if the page changes its width 28886 refreshSensitivity: 0, // change in width allowed (in px) without re-building the gallery 28887 randomize: false, 28888 rtl: false, // right-to-left mode 28889 sort: false, /* 28890 - false: to do not sort 28891 - function: to sort them using the function as comparator (see Array.prototype.sort()) 28892 */ 28893 filter: false, /* 28894 - false, null or undefined: for a disabled filter 28895 - a string: an entry is kept if entry.is(filter string) returns true 28896 see jQuery's .is() function for further information 28897 - a function: invoked with arguments (entry, index, array). Return true to keep the entry, false otherwise. 28898 It follows the specifications of the Array.prototype.filter() function of JavaScript. 28899 */ 28900 selector: 'a', // The selector that is used to know what are the entries of the gallery 28901 imgSelector: '> img, > a > img, > svg, > a > svg', // The selector that is used to know what are the images of each entry 28902 triggerEvent: function (event) { // This is called to trigger events, the default behavior is to call $.trigger 28903 this.$gallery.trigger(event); // Consider that 'this' is this set to the JustifiedGallery object, so it can 28904 } // access to fields such as $gallery, useful to trigger events with jQuery. 28905 }; 28906 28907 28908 /** 28909 * Justified Gallery plugin for jQuery 28910 * 28911 * Events 28912 * - jg.complete : called when all the gallery has been created 28913 * - jg.resize : called when the gallery has been resized 28914 * - jg.rowflush : when a new row appears 28915 * 28916 * @param arg the action (or the settings) passed when the plugin is called 28917 * @returns {*} the object itself 28918 */ 28919 $.fn.justifiedGallery = function (arg) { 28920 return this.each(function (index, gallery) { 28921 28922 var $gallery = $(gallery); 28923 $gallery.addClass('justified-gallery'); 28924 28925 var controller = $gallery.data('jg.controller'); 28926 if (typeof controller === 'undefined') { 28927 // Create controller and assign it to the object data 28928 if (typeof arg !== 'undefined' && arg !== null && $.type(arg) !== 'object') { 28929 if (arg === 'destroy') return; // Just a call to an unexisting object 28930 throw 'The argument must be an object'; 28931 } 28932 controller = new JustifiedGallery($gallery, $.extend({}, JustifiedGallery.prototype.defaults, arg)); 28933 $gallery.data('jg.controller', controller); 28934 } else if (arg === 'norewind') { 28935 // In this case we don't rewind: we analyze only the latest images (e.g. to complete the last unfinished row 28936 // ... left to be more readable 28937 } else if (arg === 'destroy') { 28938 controller.destroy(); 28939 return; 28940 } else { 28941 // In this case Justified Gallery has been called again changing only some options 28942 controller.updateSettings(arg); 28943 controller.rewind(); 28944 } 28945 28946 // Update the entries list 28947 if (!controller.updateEntries(arg === 'norewind')) return; 28948 28949 // Init justified gallery 28950 controller.init(); 28951 28952 }); 28953 }; 28954 28955})); 28956 28957/*! 28958* Customized version of iScroll.js 0.0.1 28959* It fixes bugs affecting its integration with fullpage.js 28960*/ 28961/*! iScroll v5.2.0 ~ (c) 2008-2016 Matteo Spinelli ~ http://cubiq.org/license */ 28962(function (window, document, Math) { 28963var rAF = window.requestAnimationFrame || 28964 window.webkitRequestAnimationFrame || 28965 window.mozRequestAnimationFrame || 28966 window.oRequestAnimationFrame || 28967 window.msRequestAnimationFrame || 28968 function (callback) { window.setTimeout(callback, 1000 / 60); }; 28969 28970var utils = (function () { 28971 var me = {}; 28972 28973 var _elementStyle = document.createElement('div').style; 28974 var _vendor = (function () { 28975 var vendors = ['t', 'webkitT', 'MozT', 'msT', 'OT'], 28976 transform, 28977 i = 0, 28978 l = vendors.length; 28979 28980 for ( ; i < l; i++ ) { 28981 transform = vendors[i] + 'ransform'; 28982 if ( transform in _elementStyle ) return vendors[i].substr(0, vendors[i].length-1); 28983 } 28984 28985 return false;
vendor: 5,154 bytes, lines 28986-29138
28986 })(); 28987 28988 function _prefixStyle (style) { 28989 if ( _vendor === false ) return false; 28990 if ( _vendor === '' ) return style; 28991 return _vendor + style.charAt(0).toUpperCase() + style.substr(1); 28992 } 28993 28994 me.getTime = Date.now || function getTime () { return new Date().getTime(); }; 28995 28996 me.extend = function (target, obj) { 28997 for ( var i in obj ) { 28998 target[i] = obj[i]; 28999 } 29000 }; 29001 29002 me.addEvent = function (el, type, fn, capture) { 29003 el.addEventListener(type, fn, !!capture); 29004 }; 29005 29006 me.removeEvent = function (el, type, fn, capture) { 29007 el.removeEventListener(type, fn, !!capture); 29008 }; 29009 29010 me.prefixPointerEvent = function (pointerEvent) { 29011 return window.MSPointerEvent ? 29012 'MSPointer' + pointerEvent.charAt(7).toUpperCase() + pointerEvent.substr(8): 29013 pointerEvent; 29014 }; 29015 29016 me.momentum = function (current, start, time, lowerMargin, wrapperSize, deceleration) { 29017 var distance = current - start, 29018 speed = Math.abs(distance) / time, 29019 destination, 29020 duration; 29021 29022 deceleration = deceleration === undefined ? 0.0006 : deceleration; 29023 29024 destination = current + ( speed * speed ) / ( 2 * deceleration ) * ( distance < 0 ? -1 : 1 ); 29025 duration = speed / deceleration; 29026 29027 if ( destination < lowerMargin ) { 29028 destination = wrapperSize ? lowerMargin - ( wrapperSize / 2.5 * ( speed / 8 ) ) : lowerMargin; 29029 distance = Math.abs(destination - current); 29030 duration = distance / speed; 29031 } else if ( destination > 0 ) { 29032 destination = wrapperSize ? wrapperSize / 2.5 * ( speed / 8 ) : 0; 29033 distance = Math.abs(current) + destination; 29034 duration = distance / speed; 29035 } 29036 29037 return { 29038 destination: Math.round(destination), 29039 duration: duration 29040 }; 29041 }; 29042 29043 var _transform = _prefixStyle('transform'); 29044 29045 me.extend(me, { 29046 hasTransform: _transform !== false, 29047 hasPerspective: _prefixStyle('perspective') in _elementStyle, 29048 hasTouch: 'ontouchstart' in window, 29049 hasPointer: !!(window.PointerEvent || window.MSPointerEvent), // IE10 is prefixed 29050 hasTransition: _prefixStyle('transition') in _elementStyle 29051 }); 29052 29053 /* 29054 This should find all Android browsers lower than build 535.19 (both stock browser and webview) 29055 - galaxy S2 is ok 29056 - 2.3.6 : `AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1` 29057 - 4.0.4 : `AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30` 29058 - galaxy S3 is badAndroid (stock brower, webview) 29059 `AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30` 29060 - galaxy S4 is badAndroid (stock brower, webview) 29061 `AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30` 29062 - galaxy S5 is OK 29063 `AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Mobile Safari/537.36 (Chrome/)` 29064 - galaxy S6 is OK 29065 `AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Mobile Safari/537.36 (Chrome/)` 29066 */ 29067 me.isBadAndroid = (function() { 29068 var appVersion = window.navigator.appVersion; 29069 // Android browser is not a chrome browser. 29070 if (/Android/.test(appVersion) && !(/Chrome\/\d/.test(appVersion))) { 29071 var safariVersion = appVersion.match(/Safari\/(\d+.\d)/); 29072 if(safariVersion && typeof safariVersion === "object" && safariVersion.length >= 2) { 29073 return parseFloat(safariVersion[1]) < 535.19; 29074 } else { 29075 return true; 29076 } 29077 } else { 29078 return false; 29079 } 29080 })(); 29081 29082 me.extend(me.style = {}, { 29083 transform: _transform, 29084 transitionTimingFunction: _prefixStyle('transitionTimingFunction'), 29085 transitionDuration: _prefixStyle('transitionDuration'), 29086 transitionDelay: _prefixStyle('transitionDelay'), 29087 transformOrigin: _prefixStyle('transformOrigin') 29088 }); 29089 29090 me.hasClass = function (e, c) { 29091 var re = new RegExp("(^|\\s)" + c + "(\\s|$)"); 29092 return re.test(e.className); 29093 }; 29094 29095 me.addClass = function (e, c) { 29096 if ( me.hasClass(e, c) ) { 29097 return; 29098 } 29099 29100 var newclass = e.className.split(' '); 29101 newclass.push(c); 29102 e.className = newclass.join(' '); 29103 }; 29104 29105 me.removeClass = function (e, c) { 29106 if ( !me.hasClass(e, c) ) { 29107 return; 29108 } 29109 29110 var re = new RegExp("(^|\\s)" + c + "(\\s|$)", 'g'); 29111 e.className = e.className.replace(re, ' '); 29112 }; 29113 29114 me.offset = function (el) { 29115 var left = -el.offsetLeft, 29116 top = -el.offsetTop; 29117 29118 // jshint -W084 29119 while (el = el.offsetParent) { 29120 left -= el.offsetLeft; 29121 top -= el.offsetTop; 29122 } 29123 // jshint +W084 29124 29125 return { 29126 left: left, 29127 top: top 29128 }; 29129 }; 29130 29131 me.preventDefaultException = function (el, exceptions) { 29132 for ( var i in exceptions ) { 29133 if ( exceptions[i].test(el[i]) ) { 29134 return true; 29135 } 29136 } 29137 29138 return false;
vendor: 5,660 bytes, lines 29139-29304
29139 }; 29140 29141 me.extend(me.eventType = {}, { 29142 touchstart: 1, 29143 touchmove: 1, 29144 touchend: 1, 29145 29146 mousedown: 2, 29147 mousemove: 2, 29148 mouseup: 2, 29149 29150 pointerdown: 3, 29151 pointermove: 3, 29152 pointerup: 3, 29153 29154 MSPointerDown: 3, 29155 MSPointerMove: 3, 29156 MSPointerUp: 3 29157 }); 29158 29159 me.extend(me.ease = {}, { 29160 quadratic: { 29161 style: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)', 29162 fn: function (k) { 29163 return k * ( 2 - k ); 29164 } 29165 }, 29166 circular: { 29167 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) 29168 fn: function (k) { 29169 return Math.sqrt( 1 - ( --k * k ) ); 29170 } 29171 }, 29172 back: { 29173 style: 'cubic-bezier(0.175, 0.885, 0.32, 1.275)', 29174 fn: function (k) { 29175 var b = 4; 29176 return ( k = k - 1 ) * k * ( ( b + 1 ) * k + b ) + 1; 29177 } 29178 }, 29179 bounce: { 29180 style: '', 29181 fn: function (k) { 29182 if ( ( k /= 1 ) < ( 1 / 2.75 ) ) { 29183 return 7.5625 * k * k; 29184 } else if ( k < ( 2 / 2.75 ) ) { 29185 return 7.5625 * ( k -= ( 1.5 / 2.75 ) ) * k + 0.75; 29186 } else if ( k < ( 2.5 / 2.75 ) ) { 29187 return 7.5625 * ( k -= ( 2.25 / 2.75 ) ) * k + 0.9375; 29188 } else { 29189 return 7.5625 * ( k -= ( 2.625 / 2.75 ) ) * k + 0.984375; 29190 } 29191 } 29192 }, 29193 elastic: { 29194 style: '', 29195 fn: function (k) { 29196 var f = 0.22, 29197 e = 0.4; 29198 29199 if ( k === 0 ) { return 0; } 29200 if ( k == 1 ) { return 1; } 29201 29202 return ( e * Math.pow( 2, - 10 * k ) * Math.sin( ( k - f / 4 ) * ( 2 * Math.PI ) / f ) + 1 ); 29203 } 29204 } 29205 }); 29206 29207 me.tap = function (e, eventName) { 29208 var ev = document.createEvent('Event'); 29209 ev.initEvent(eventName, true, true); 29210 ev.pageX = e.pageX; 29211 ev.pageY = e.pageY; 29212 e.target.dispatchEvent(ev); 29213 }; 29214 29215 me.click = function (e) { 29216 var target = e.target, 29217 ev; 29218 29219 if ( !(/(SELECT|INPUT|TEXTAREA)/i).test(target.tagName) ) { 29220 // https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/initMouseEvent 29221 // initMouseEvent is deprecated. 29222 ev = document.createEvent(window.MouseEvent ? 'MouseEvents' : 'Event'); 29223 ev.initEvent('click', true, true); 29224 ev.view = e.view || window; 29225 ev.detail = 1; 29226 ev.screenX = target.screenX || 0; 29227 ev.screenY = target.screenY || 0; 29228 ev.clientX = target.clientX || 0; 29229 ev.clientY = target.clientY || 0; 29230 ev.ctrlKey = !!e.ctrlKey; 29231 ev.altKey = !!e.altKey; 29232 ev.shiftKey = !!e.shiftKey; 29233 ev.metaKey = !!e.metaKey; 29234 ev.button = 0; 29235 ev.relatedTarget = null; 29236 ev._constructed = true; 29237 target.dispatchEvent(ev); 29238 } 29239 }; 29240 29241 return me; 29242})(); 29243function IScroll (el, options) { 29244 this.wrapper = typeof el == 'string' ? document.querySelector(el) : el; 29245 this.scroller = this.wrapper.children[0]; 29246 this.scrollerStyle = this.scroller.style; // cache style for better performance 29247 29248 this.options = { 29249 29250 resizeScrollbars: true, 29251 29252 mouseWheelSpeed: 20, 29253 29254 snapThreshold: 0.334, 29255 29256// INSERT POINT: OPTIONS 29257 disablePointer : !utils.hasPointer, 29258 disableTouch : utils.hasPointer || !utils.hasTouch, 29259 disableMouse : utils.hasPointer || utils.hasTouch, 29260 startX: 0, 29261 startY: 0, 29262 scrollY: true, 29263 directionLockThreshold: 5, 29264 momentum: true, 29265 29266 bounce: true, 29267 bounceTime: 600, 29268 bounceEasing: '', 29269 29270 preventDefault: true, 29271 preventDefaultException: { tagName: /^(INPUT|TEXTAREA|BUTTON|SELECT|LABEL)$/ }, 29272 29273 HWCompositing: true, 29274 useTransition: true, 29275 useTransform: true, 29276 bindToWrapper: typeof window.onmousedown === "undefined" 29277 }; 29278 29279 for ( var i in options ) { 29280 this.options[i] = options[i]; 29281 } 29282 29283 // Normalize options 29284 this.translateZ = this.options.HWCompositing && utils.hasPerspective ? ' translateZ(0)' : ''; 29285 29286 this.options.useTransition = utils.hasTransition && this.options.useTransition; 29287 this.options.useTransform = utils.hasTransform && this.options.useTransform; 29288 29289 this.options.eventPassthrough = this.options.eventPassthrough === true ? 'vertical' : this.options.eventPassthrough; 29290 this.options.preventDefault = !this.options.eventPassthrough && this.options.preventDefault; 29291 29292 // If you want eventPassthrough I have to lock one of the axes 29293 this.options.scrollY = this.options.eventPassthrough == 'vertical' ? false : this.options.scrollY; 29294 this.options.scrollX = this.options.eventPassthrough == 'horizontal' ? false : this.options.scrollX; 29295 29296 // With eventPassthrough we also need lockDirection mechanism 29297 this.options.freeScroll = this.options.freeScroll && !this.options.eventPassthrough; 29298 this.options.directionLockThreshold = this.options.eventPassthrough ? 0 : this.options.directionLockThreshold; 29299 29300 this.options.bounceEasing = typeof this.options.bounceEasing == 'string' ? utils.ease[this.options.bounceEasing] || utils.ease.circular : this.options.bounceEasing; 29301 29302 this.options.resizePolling = this.options.resizePolling === undefined ? 60 : this.options.resizePolling; 29303 29304 if ( this.options.tap === true ) {
vendor: 4,893 bytes, lines 29305-29476
29305 this.options.tap = 'tap'; 29306 } 29307 29308 // https://github.com/cubiq/iscroll/issues/1029 29309 if (!this.options.useTransition && !this.options.useTransform) { 29310 if(!(/relative|absolute/i).test(this.scrollerStyle.position)) { 29311 this.scrollerStyle.position = "relative"; 29312 } 29313 } 29314 29315 if ( this.options.shrinkScrollbars == 'scale' ) { 29316 this.options.useTransition = false; 29317 } 29318 29319 this.options.invertWheelDirection = this.options.invertWheelDirection ? -1 : 1; 29320 29321// INSERT POINT: NORMALIZATION 29322 29323 // Some defaults 29324 this.x = 0; 29325 this.y = 0; 29326 this.directionX = 0; 29327 this.directionY = 0; 29328 this._events = {}; 29329 29330// INSERT POINT: DEFAULTS 29331 29332 this._init(); 29333 this.refresh(); 29334 29335 this.scrollTo(this.options.startX, this.options.startY); 29336 this.enable(); 29337} 29338 29339IScroll.prototype = { 29340 version: '5.2.0', 29341 29342 _init: function () { 29343 this._initEvents(); 29344 29345 if ( this.options.scrollbars || this.options.indicators ) { 29346 this._initIndicators(); 29347 } 29348 29349 if ( this.options.mouseWheel ) { 29350 this._initWheel(); 29351 } 29352 29353 if ( this.options.snap ) { 29354 this._initSnap(); 29355 } 29356 29357 if ( this.options.keyBindings ) { 29358 this._initKeys(); 29359 } 29360 29361// INSERT POINT: _init 29362 29363 }, 29364 29365 destroy: function () { 29366 this._initEvents(true); 29367 clearTimeout(this.resizeTimeout); 29368 this.resizeTimeout = null; 29369 this._execEvent('destroy'); 29370 }, 29371 29372 _transitionEnd: function (e) { 29373 if ( e.target != this.scroller || !this.isInTransition ) { 29374 return; 29375 } 29376 29377 this._transitionTime(); 29378 if ( !this.resetPosition(this.options.bounceTime) ) { 29379 this.isInTransition = false; 29380 this._execEvent('scrollEnd'); 29381 } 29382 }, 29383 29384 _start: function (e) { 29385 // React to left mouse button only 29386 if ( utils.eventType[e.type] != 1 ) { 29387 // for button property 29388 // http://unixpapa.com/js/mouse.html 29389 var button; 29390 if (!e.which) { 29391 /* IE case */ 29392 button = (e.button < 2) ? 0 : 29393 ((e.button == 4) ? 1 : 2); 29394 } else { 29395 /* All others */ 29396 button = e.button; 29397 } 29398 if ( button !== 0 ) { 29399 return; 29400 } 29401 } 29402 29403 if ( !this.enabled || (this.initiated && utils.eventType[e.type] !== this.initiated) ) { 29404 return; 29405 } 29406 29407 if ( this.options.preventDefault && !utils.isBadAndroid && !utils.preventDefaultException(e.target, this.options.preventDefaultException) ) { 29408 e.preventDefault(); 29409 } 29410 29411 var point = e.touches ? e.touches[0] : e, 29412 pos; 29413 29414 this.initiated = utils.eventType[e.type]; 29415 this.moved = false; 29416 this.distX = 0; 29417 this.distY = 0; 29418 this.directionX = 0; 29419 this.directionY = 0; 29420 this.directionLocked = 0; 29421 29422 this.startTime = utils.getTime(); 29423 29424 if ( this.options.useTransition && this.isInTransition ) { 29425 this._transitionTime(); 29426 this.isInTransition = false; 29427 pos = this.getComputedPosition(); 29428 this._translate(Math.round(pos.x), Math.round(pos.y)); 29429 this._execEvent('scrollEnd'); 29430 } else if ( !this.options.useTransition && this.isAnimating ) { 29431 this.isAnimating = false; 29432 this._execEvent('scrollEnd'); 29433 } 29434 29435 this.startX = this.x; 29436 this.startY = this.y; 29437 this.absStartX = this.x; 29438 this.absStartY = this.y; 29439 this.pointX = point.pageX; 29440 this.pointY = point.pageY; 29441 29442 this._execEvent('beforeScrollStart'); 29443 }, 29444 29445 _move: function (e) { 29446 if ( !this.enabled || utils.eventType[e.type] !== this.initiated ) { 29447 return; 29448 } 29449 29450 if ( this.options.preventDefault ) { // increases performance on Android? TODO: check! 29451 e.preventDefault(); 29452 } 29453 29454 var point = e.touches ? e.touches[0] : e, 29455 deltaX = point.pageX - this.pointX, 29456 deltaY = point.pageY - this.pointY, 29457 timestamp = utils.getTime(), 29458 newX, newY, 29459 absDistX, absDistY; 29460 29461 this.pointX = point.pageX; 29462 this.pointY = point.pageY; 29463 29464 this.distX += deltaX; 29465 this.distY += deltaY; 29466 absDistX = Math.abs(this.distX); 29467 absDistY = Math.abs(this.distY); 29468 29469 // We need to move at least 10 pixels for the scrolling to initiate 29470 if ( timestamp - this.endTime > 300 && (absDistX < 10 && absDistY < 10) ) { 29471 return; 29472 } 29473 29474 // If you are scrolling in one direction lock the other 29475 if ( !this.directionLocked && !this.options.freeScroll ) { 29476 if ( absDistX > absDistY + this.options.directionLockThreshold ) {
vendor: 6,057 bytes, lines 29477-29663
29477 this.directionLocked = 'h'; // lock horizontally 29478 } else if ( absDistY >= absDistX + this.options.directionLockThreshold ) { 29479 this.directionLocked = 'v'; // lock vertically 29480 } else { 29481 this.directionLocked = 'n'; // no lock 29482 } 29483 } 29484 29485 if ( this.directionLocked == 'h' ) { 29486 if ( this.options.eventPassthrough == 'vertical' ) { 29487 e.preventDefault(); 29488 } else if ( this.options.eventPassthrough == 'horizontal' ) { 29489 this.initiated = false; 29490 return; 29491 } 29492 29493 deltaY = 0; 29494 } else if ( this.directionLocked == 'v' ) { 29495 if ( this.options.eventPassthrough == 'horizontal' ) { 29496 e.preventDefault(); 29497 } else if ( this.options.eventPassthrough == 'vertical' ) { 29498 this.initiated = false; 29499 return; 29500 } 29501 29502 deltaX = 0; 29503 } 29504 29505 deltaX = this.hasHorizontalScroll ? deltaX : 0; 29506 deltaY = this.hasVerticalScroll ? deltaY : 0; 29507 29508 newX = this.x + deltaX; 29509 newY = this.y + deltaY; 29510 29511 // Slow down if outside of the boundaries 29512 if ( newX > 0 || newX < this.maxScrollX ) { 29513 newX = this.options.bounce ? this.x + deltaX / 3 : newX > 0 ? 0 : this.maxScrollX; 29514 } 29515 if ( newY > 0 || newY < this.maxScrollY ) { 29516 newY = this.options.bounce ? this.y + deltaY / 3 : newY > 0 ? 0 : this.maxScrollY; 29517 } 29518 29519 this.directionX = deltaX > 0 ? -1 : deltaX < 0 ? 1 : 0; 29520 this.directionY = deltaY > 0 ? -1 : deltaY < 0 ? 1 : 0; 29521 29522 if ( !this.moved ) { 29523 this._execEvent('scrollStart'); 29524 } 29525 29526 this.moved = true; 29527 29528 this._translate(newX, newY); 29529 29530/* REPLACE START: _move */ 29531 29532 if ( timestamp - this.startTime > 300 ) { 29533 this.startTime = timestamp; 29534 this.startX = this.x; 29535 this.startY = this.y; 29536 } 29537 29538/* REPLACE END: _move */ 29539 29540 }, 29541 29542 _end: function (e) { 29543 if ( !this.enabled || utils.eventType[e.type] !== this.initiated ) { 29544 return; 29545 } 29546 29547 if ( this.options.preventDefault && !utils.preventDefaultException(e.target, this.options.preventDefaultException) ) { 29548 e.preventDefault(); 29549 } 29550 29551 var point = e.changedTouches ? e.changedTouches[0] : e, 29552 momentumX, 29553 momentumY, 29554 duration = utils.getTime() - this.startTime, 29555 newX = Math.round(this.x), 29556 newY = Math.round(this.y), 29557 distanceX = Math.abs(newX - this.startX), 29558 distanceY = Math.abs(newY - this.startY), 29559 time = 0, 29560 easing = ''; 29561 29562 this.isInTransition = 0; 29563 this.initiated = 0; 29564 this.endTime = utils.getTime(); 29565 29566 // reset if we are outside of the boundaries 29567 if ( this.resetPosition(this.options.bounceTime) ) { 29568 return; 29569 } 29570 29571 this.scrollTo(newX, newY); // ensures that the last position is rounded 29572 29573 // we scrolled less than 10 pixels 29574 if ( !this.moved ) { 29575 if ( this.options.tap ) { 29576 utils.tap(e, this.options.tap); 29577 } 29578 29579 if ( this.options.click ) { 29580 utils.click(e); 29581 } 29582 29583 this._execEvent('scrollCancel'); 29584 return; 29585 } 29586 29587 if ( this._events.flick && duration < 200 && distanceX < 100 && distanceY < 100 ) { 29588 this._execEvent('flick'); 29589 return; 29590 } 29591 29592 // start momentum animation if needed 29593 if ( this.options.momentum && duration < 300 ) { 29594 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 }; 29595 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 }; 29596 newX = momentumX.destination; 29597 newY = momentumY.destination; 29598 time = Math.max(momentumX.duration, momentumY.duration); 29599 this.isInTransition = 1; 29600 } 29601 29602 29603 if ( this.options.snap ) { 29604 var snap = this._nearestSnap(newX, newY); 29605 this.currentPage = snap; 29606 time = this.options.snapSpeed || Math.max( 29607 Math.max( 29608 Math.min(Math.abs(newX - snap.x), 1000), 29609 Math.min(Math.abs(newY - snap.y), 1000) 29610 ), 300); 29611 newX = snap.x; 29612 newY = snap.y; 29613 29614 this.directionX = 0; 29615 this.directionY = 0; 29616 easing = this.options.bounceEasing; 29617 } 29618 29619// INSERT POINT: _end 29620 29621 if ( newX != this.x || newY != this.y ) { 29622 // change easing function when scroller goes out of the boundaries 29623 if ( newX > 0 || newX < this.maxScrollX || newY > 0 || newY < this.maxScrollY ) { 29624 easing = utils.ease.quadratic; 29625 } 29626 29627 this.scrollTo(newX, newY, time, easing); 29628 return; 29629 } 29630 29631 this._execEvent('scrollEnd'); 29632 }, 29633 29634 _resize: function () { 29635 var that = this; 29636 29637 clearTimeout(this.resizeTimeout); 29638 29639 this.resizeTimeout = setTimeout(function () { 29640 that.refresh(); 29641 }, this.options.resizePolling); 29642 }, 29643 29644 resetPosition: function (time) { 29645 var x = this.x, 29646 y = this.y; 29647 29648 time = time || 0; 29649 29650 if ( !this.hasHorizontalScroll || this.x > 0 ) { 29651 x = 0; 29652 } else if ( this.x < this.maxScrollX ) { 29653 x = this.maxScrollX; 29654 } 29655 29656 if ( !this.hasVerticalScroll || this.y > 0 ) { 29657 y = 0; 29658 } else if ( this.y < this.maxScrollY ) { 29659 y = this.maxScrollY; 29660 } 29661 29662 if ( x == this.x && y == this.y ) { 29663 return false;
vendor: 5,509 bytes, lines 29664-29868
29664 } 29665 29666 this.scrollTo(x, y, time, this.options.bounceEasing); 29667 29668 return true; 29669 }, 29670 29671 disable: function () { 29672 this.enabled = false; 29673 }, 29674 29675 enable: function () { 29676 this.enabled = true; 29677 }, 29678 29679 refresh: function () { 29680 var rf = this.wrapper.offsetHeight; // Force reflow 29681 29682 this.wrapperWidth = this.wrapper.clientWidth; 29683 this.wrapperHeight = this.wrapper.clientHeight; 29684 29685/* REPLACE START: refresh */ 29686 29687 this.scrollerWidth = this.scroller.offsetWidth; 29688 this.scrollerHeight = this.scroller.offsetHeight; 29689 29690 this.maxScrollX = this.wrapperWidth - this.scrollerWidth; 29691 this.maxScrollY = this.wrapperHeight - this.scrollerHeight; 29692 29693/* REPLACE END: refresh */ 29694 29695 this.hasHorizontalScroll = this.options.scrollX && this.maxScrollX < 0; 29696 this.hasVerticalScroll = this.options.scrollY && this.maxScrollY < 0; 29697 29698 if ( !this.hasHorizontalScroll ) { 29699 this.maxScrollX = 0; 29700 this.scrollerWidth = this.wrapperWidth; 29701 } 29702 29703 if ( !this.hasVerticalScroll ) { 29704 this.maxScrollY = 0; 29705 this.scrollerHeight = this.wrapperHeight; 29706 } 29707 29708 this.endTime = 0; 29709 this.directionX = 0; 29710 this.directionY = 0; 29711 29712 this.wrapperOffset = utils.offset(this.wrapper); 29713 29714 this._execEvent('refresh'); 29715 29716 this.resetPosition(); 29717 29718// INSERT POINT: _refresh 29719 29720 }, 29721 29722 29723 on: function (type, fn) { 29724 if ( !this._events[type] ) { 29725 this._events[type] = []; 29726 } 29727 29728 this._events[type].push(fn); 29729 }, 29730 29731 off: function (type, fn) { 29732 if ( !this._events[type] ) { 29733 return; 29734 } 29735 29736 var index = this._events[type].indexOf(fn); 29737 29738 if ( index > -1 ) { 29739 this._events[type].splice(index, 1); 29740 } 29741 }, 29742 29743 _execEvent: function (type) { 29744 if ( !this._events[type] ) { 29745 return; 29746 } 29747 29748 var i = 0, 29749 l = this._events[type].length; 29750 29751 if ( !l ) { 29752 return; 29753 } 29754 29755 for ( ; i < l; i++ ) { 29756 this._events[type][i].apply(this, [].slice.call(arguments, 1)); 29757 } 29758 }, 29759 29760 scrollBy: function (x, y, time, easing) { 29761 x = this.x + x; 29762 y = this.y + y; 29763 time = time || 0; 29764 29765 this.scrollTo(x, y, time, easing); 29766 }, 29767 29768 scrollTo: function (x, y, time, easing) { 29769 easing = easing || utils.ease.circular; 29770 29771 this.isInTransition = this.options.useTransition && time > 0; 29772 var transitionType = this.options.useTransition && easing.style; 29773 if ( !time || transitionType ) { 29774 if(transitionType) { 29775 this._transitionTimingFunction(easing.style); 29776 this._transitionTime(time); 29777 } 29778 this._translate(x, y); 29779 } else { 29780 this._animate(x, y, time, easing.fn); 29781 } 29782 }, 29783 29784 scrollToElement: function (el, time, offsetX, offsetY, easing) { 29785 el = el.nodeType ? el : this.scroller.querySelector(el); 29786 29787 if ( !el ) { 29788 return; 29789 } 29790 29791 var pos = utils.offset(el); 29792 29793 pos.left -= this.wrapperOffset.left; 29794 pos.top -= this.wrapperOffset.top; 29795 29796 // if offsetX/Y are true we center the element to the screen 29797 if ( offsetX === true ) { 29798 offsetX = Math.round(el.offsetWidth / 2 - this.wrapper.offsetWidth / 2); 29799 } 29800 if ( offsetY === true ) { 29801 offsetY = Math.round(el.offsetHeight / 2 - this.wrapper.offsetHeight / 2); 29802 } 29803 29804 pos.left -= offsetX || 0; 29805 pos.top -= offsetY || 0; 29806 29807 pos.left = pos.left > 0 ? 0 : pos.left < this.maxScrollX ? this.maxScrollX : pos.left; 29808 pos.top = pos.top > 0 ? 0 : pos.top < this.maxScrollY ? this.maxScrollY : pos.top; 29809 29810 time = time === undefined || time === null || time === 'auto' ? Math.max(Math.abs(this.x-pos.left), Math.abs(this.y-pos.top)) : time; 29811 29812 this.scrollTo(pos.left, pos.top, time, easing); 29813 }, 29814 29815 _transitionTime: function (time) { 29816 if (!this.options.useTransition) { 29817 return; 29818 } 29819 time = time || 0; 29820 var durationProp = utils.style.transitionDuration; 29821 if(!durationProp) { 29822 return; 29823 } 29824 29825 this.scrollerStyle[durationProp] = time + 'ms'; 29826 29827 if ( !time && utils.isBadAndroid ) { 29828 this.scrollerStyle[durationProp] = '0.0001ms'; 29829 // remove 0.0001ms 29830 var self = this; 29831 rAF(function() { 29832 if(self.scrollerStyle[durationProp] === '0.0001ms') { 29833 self.scrollerStyle[durationProp] = '0s'; 29834 } 29835 }); 29836 } 29837 29838 29839 if ( this.indicators ) { 29840 for ( var i = this.indicators.length; i--; ) { 29841 this.indicators[i].transitionTime(time); 29842 } 29843 } 29844 29845 29846// INSERT POINT: _transitionTime 29847 29848 }, 29849 29850 _transitionTimingFunction: function (easing) { 29851 this.scrollerStyle[utils.style.transitionTimingFunction] = easing; 29852 29853 29854 if ( this.indicators ) { 29855 for ( var i = this.indicators.length; i--; ) { 29856 this.indicators[i].transitionTimingFunction(easing); 29857 } 29858 } 29859 29860 29861// INSERT POINT: _transitionTimingFunction 29862 29863 }, 29864 29865 _translate: function (x, y) { 29866 //Uncode addition 29867 if ( (" " + this.wrapper.className + " ").replace(/[\n\t]/g, " ").indexOf(" no-scrolloverflow ") > -1 ) 29868 return false;
vendor: 9,939 bytes, lines 29869-30180
29869 29870 if ( this.options.useTransform ) { 29871 29872/* REPLACE START: _translate */ 29873 29874 this.scrollerStyle[utils.style.transform] = 'translate(' + x + 'px,' + y + 'px)' + this.translateZ; 29875 29876/* REPLACE END: _translate */ 29877 29878 } else { 29879 x = Math.round(x); 29880 y = Math.round(y); 29881 this.scrollerStyle.left = x + 'px'; 29882 this.scrollerStyle.top = y + 'px'; 29883 } 29884 29885 this.x = x; 29886 this.y = y; 29887 29888 29889 if ( this.indicators ) { 29890 for ( var i = this.indicators.length; i--; ) { 29891 this.indicators[i].updatePosition(); 29892 } 29893 } 29894 29895 //Uncode addition 29896 var uncodevent = new CustomEvent('fp-slide-scroll'); 29897 window.dispatchEvent(uncodevent); 29898 29899// INSERT POINT: _translate 29900 29901 }, 29902 29903 _initEvents: function (remove) { 29904 var eventType = remove ? utils.removeEvent : utils.addEvent, 29905 target = this.options.bindToWrapper ? this.wrapper : window; 29906 29907 eventType(window, 'orientationchange', this); 29908 eventType(window, 'resize', this); 29909 29910 if ( this.options.click ) { 29911 eventType(this.wrapper, 'click', this, true); 29912 } 29913 29914 if ( !this.options.disableMouse ) { 29915 eventType(this.wrapper, 'mousedown', this); 29916 eventType(target, 'mousemove', this); 29917 eventType(target, 'mousecancel', this); 29918 eventType(target, 'mouseup', this); 29919 } 29920 29921 if ( utils.hasPointer && !this.options.disablePointer ) { 29922 eventType(this.wrapper, utils.prefixPointerEvent('pointerdown'), this); 29923 eventType(target, utils.prefixPointerEvent('pointermove'), this); 29924 eventType(target, utils.prefixPointerEvent('pointercancel'), this); 29925 eventType(target, utils.prefixPointerEvent('pointerup'), this); 29926 } 29927 29928 if ( utils.hasTouch && !this.options.disableTouch ) { 29929 eventType(this.wrapper, 'touchstart', this); 29930 eventType(target, 'touchmove', this); 29931 eventType(target, 'touchcancel', this); 29932 eventType(target, 'touchend', this); 29933 } 29934 29935 eventType(this.scroller, 'transitionend', this); 29936 eventType(this.scroller, 'webkitTransitionEnd', this); 29937 eventType(this.scroller, 'oTransitionEnd', this); 29938 eventType(this.scroller, 'MSTransitionEnd', this); 29939 }, 29940 29941 getComputedPosition: function () { 29942 var matrix = window.getComputedStyle(this.scroller, null), 29943 x, y; 29944 29945 if ( this.options.useTransform ) { 29946 matrix = matrix[utils.style.transform].split(')')[0].split(', '); 29947 x = +(matrix[12] || matrix[4]); 29948 y = +(matrix[13] || matrix[5]); 29949 } else { 29950 x = +matrix.left.replace(/[^-\d.]/g, ''); 29951 y = +matrix.top.replace(/[^-\d.]/g, ''); 29952 } 29953 29954 return { x: x, y: y }; 29955 }, 29956 _initIndicators: function () { 29957 var interactive = this.options.interactiveScrollbars, 29958 customStyle = typeof this.options.scrollbars != 'string', 29959 indicators = [], 29960 indicator; 29961 29962 var that = this; 29963 29964 this.indicators = []; 29965 29966 if ( this.options.scrollbars ) { 29967 // Vertical scrollbar 29968 if ( this.options.scrollY ) { 29969 indicator = { 29970 el: createDefaultScrollbar('v', interactive, this.options.scrollbars), 29971 interactive: interactive, 29972 defaultScrollbars: true, 29973 customStyle: customStyle, 29974 resize: this.options.resizeScrollbars, 29975 shrink: this.options.shrinkScrollbars, 29976 fade: this.options.fadeScrollbars, 29977 listenX: false 29978 }; 29979 29980 this.wrapper.appendChild(indicator.el); 29981 indicators.push(indicator); 29982 } 29983 29984 // Horizontal scrollbar 29985 if ( this.options.scrollX ) { 29986 indicator = { 29987 el: createDefaultScrollbar('h', interactive, this.options.scrollbars), 29988 interactive: interactive, 29989 defaultScrollbars: true, 29990 customStyle: customStyle, 29991 resize: this.options.resizeScrollbars, 29992 shrink: this.options.shrinkScrollbars, 29993 fade: this.options.fadeScrollbars, 29994 listenY: false 29995 }; 29996 29997 this.wrapper.appendChild(indicator.el); 29998 indicators.push(indicator); 29999 } 30000 } 30001 30002 if ( this.options.indicators ) { 30003 // TODO: check concat compatibility 30004 indicators = indicators.concat(this.options.indicators); 30005 } 30006 30007 for ( var i = indicators.length; i--; ) { 30008 this.indicators.push( new Indicator(this, indicators[i]) ); 30009 } 30010 30011 // TODO: check if we can use array.map (wide compatibility and performance issues) 30012 function _indicatorsMap (fn) { 30013 if (that.indicators) { 30014 for ( var i = that.indicators.length; i--; ) { 30015 fn.call(that.indicators[i]); 30016 } 30017 } 30018 } 30019 30020 if ( this.options.fadeScrollbars ) { 30021 this.on('scrollEnd', function () { 30022 _indicatorsMap(function () { 30023 this.fade(); 30024 }); 30025 }); 30026 30027 this.on('scrollCancel', function () { 30028 _indicatorsMap(function () { 30029 this.fade(); 30030 }); 30031 }); 30032 30033 this.on('scrollStart', function () { 30034 _indicatorsMap(function () { 30035 this.fade(1); 30036 }); 30037 }); 30038 30039 this.on('beforeScrollStart', function () { 30040 _indicatorsMap(function () { 30041 this.fade(1, true); 30042 }); 30043 }); 30044 } 30045 30046 30047 this.on('refresh', function () { 30048 _indicatorsMap(function () { 30049 this.refresh(); 30050 }); 30051 }); 30052 30053 this.on('destroy', function () { 30054 _indicatorsMap(function () { 30055 this.destroy(); 30056 }); 30057 30058 delete this.indicators; 30059 }); 30060 }, 30061 30062 _initWheel: function () { 30063 utils.addEvent(this.wrapper, 'wheel', this); 30064 utils.addEvent(this.wrapper, 'mousewheel', this); 30065 utils.addEvent(this.wrapper, 'DOMMouseScroll', this); 30066 30067 this.on('destroy', function () { 30068 clearTimeout(this.wheelTimeout); 30069 this.wheelTimeout = null; 30070 utils.removeEvent(this.wrapper, 'wheel', this); 30071 utils.removeEvent(this.wrapper, 'mousewheel', this); 30072 utils.removeEvent(this.wrapper, 'DOMMouseScroll', this); 30073 }); 30074 }, 30075 30076 _wheel: function (e) { 30077 if ( !this.enabled ) { 30078 return; 30079 } 30080 30081 var wheelDeltaX, wheelDeltaY, 30082 newX, newY, 30083 that = this; 30084 30085 if ( this.wheelTimeout === undefined ) { 30086 that._execEvent('scrollStart'); 30087 } 30088 30089 // Execute the scrollEnd event after 400ms the wheel stopped scrolling 30090 clearTimeout(this.wheelTimeout); 30091 this.wheelTimeout = setTimeout(function () { 30092 if(!that.options.snap) { 30093 that._execEvent('scrollEnd'); 30094 } 30095 that.wheelTimeout = undefined; 30096 }, 400); 30097 30098 if ( 'deltaX' in e ) { 30099 if (e.deltaMode === 1) { 30100 wheelDeltaX = -e.deltaX * this.options.mouseWheelSpeed; 30101 wheelDeltaY = -e.deltaY * this.options.mouseWheelSpeed; 30102 } else { 30103 wheelDeltaX = -e.deltaX; 30104 wheelDeltaY = -e.deltaY; 30105 } 30106 } else if ( 'wheelDeltaX' in e ) { 30107 wheelDeltaX = e.wheelDeltaX / 120 * this.options.mouseWheelSpeed; 30108 wheelDeltaY = e.wheelDeltaY / 120 * this.options.mouseWheelSpeed; 30109 } else if ( 'wheelDelta' in e ) { 30110 wheelDeltaX = wheelDeltaY = e.wheelDelta / 120 * this.options.mouseWheelSpeed; 30111 } else if ( 'detail' in e ) { 30112 wheelDeltaX = wheelDeltaY = -e.detail / 3 * this.options.mouseWheelSpeed; 30113 } else { 30114 return; 30115 } 30116 30117 wheelDeltaX *= this.options.invertWheelDirection; 30118 wheelDeltaY *= this.options.invertWheelDirection; 30119 30120 if ( !this.hasVerticalScroll ) { 30121 wheelDeltaX = wheelDeltaY; 30122 wheelDeltaY = 0; 30123 } 30124 30125 if ( this.options.snap ) { 30126 newX = this.currentPage.pageX; 30127 newY = this.currentPage.pageY; 30128 30129 if ( wheelDeltaX > 0 ) { 30130 newX--; 30131 } else if ( wheelDeltaX < 0 ) { 30132 newX++; 30133 } 30134 30135 if ( wheelDeltaY > 0 ) { 30136 newY--; 30137 } else if ( wheelDeltaY < 0 ) { 30138 newY++; 30139 } 30140 30141 this.goToPage(newX, newY); 30142 30143 return; 30144 } 30145 30146 newX = this.x + Math.round(this.hasHorizontalScroll ? wheelDeltaX : 0); 30147 newY = this.y + Math.round(this.hasVerticalScroll ? wheelDeltaY : 0); 30148 30149 this.directionX = wheelDeltaX > 0 ? -1 : wheelDeltaX < 0 ? 1 : 0; 30150 this.directionY = wheelDeltaY > 0 ? -1 : wheelDeltaY < 0 ? 1 : 0; 30151 30152 if ( newX > 0 ) { 30153 newX = 0; 30154 } else if ( newX < this.maxScrollX ) { 30155 newX = this.maxScrollX; 30156 } 30157 30158 if ( newY > 0 ) { 30159 newY = 0; 30160 } else if ( newY < this.maxScrollY ) { 30161 newY = this.maxScrollY; 30162 } 30163 30164 this.scrollTo(newX, newY, 0); 30165 30166// INSERT POINT: _wheel 30167 }, 30168 30169 _initSnap: function () { 30170 this.currentPage = {}; 30171 30172 if ( typeof this.options.snap == 'string' ) { 30173 this.options.snap = this.scroller.querySelectorAll(this.options.snap); 30174 } 30175 30176 this.on('refresh', function () { 30177 var i = 0, l, 30178 m = 0, n, 30179 cx, cy, 30180 x = 0, y,
vendor: 7,339 bytes, lines 30181-30434
30181 stepX = this.options.snapStepX || this.wrapperWidth, 30182 stepY = this.options.snapStepY || this.wrapperHeight, 30183 el; 30184 30185 this.pages = []; 30186 30187 if ( !this.wrapperWidth || !this.wrapperHeight || !this.scrollerWidth || !this.scrollerHeight ) { 30188 return; 30189 } 30190 30191 if ( this.options.snap === true ) { 30192 cx = Math.round( stepX / 2 ); 30193 cy = Math.round( stepY / 2 ); 30194 30195 while ( x > -this.scrollerWidth ) { 30196 this.pages[i] = []; 30197 l = 0; 30198 y = 0; 30199 30200 while ( y > -this.scrollerHeight ) { 30201 this.pages[i][l] = { 30202 x: Math.max(x, this.maxScrollX), 30203 y: Math.max(y, this.maxScrollY), 30204 width: stepX, 30205 height: stepY, 30206 cx: x - cx, 30207 cy: y - cy 30208 }; 30209 30210 y -= stepY; 30211 l++; 30212 } 30213 30214 x -= stepX; 30215 i++; 30216 } 30217 } else { 30218 el = this.options.snap; 30219 l = el.length; 30220 n = -1; 30221 30222 for ( ; i < l; i++ ) { 30223 if ( i === 0 || el[i].offsetLeft <= el[i-1].offsetLeft ) { 30224 m = 0; 30225 n++; 30226 } 30227 30228 if ( !this.pages[m] ) { 30229 this.pages[m] = []; 30230 } 30231 30232 x = Math.max(-el[i].offsetLeft, this.maxScrollX); 30233 y = Math.max(-el[i].offsetTop, this.maxScrollY); 30234 cx = x - Math.round(el[i].offsetWidth / 2); 30235 cy = y - Math.round(el[i].offsetHeight / 2); 30236 30237 this.pages[m][n] = { 30238 x: x, 30239 y: y, 30240 width: el[i].offsetWidth, 30241 height: el[i].offsetHeight, 30242 cx: cx, 30243 cy: cy 30244 }; 30245 30246 if ( x > this.maxScrollX ) { 30247 m++; 30248 } 30249 } 30250 } 30251 30252 this.goToPage(this.currentPage.pageX || 0, this.currentPage.pageY || 0, 0); 30253 30254 // Update snap threshold if needed 30255 if ( this.options.snapThreshold % 1 === 0 ) { 30256 this.snapThresholdX = this.options.snapThreshold; 30257 this.snapThresholdY = this.options.snapThreshold; 30258 } else { 30259 this.snapThresholdX = Math.round(this.pages[this.currentPage.pageX][this.currentPage.pageY].width * this.options.snapThreshold); 30260 this.snapThresholdY = Math.round(this.pages[this.currentPage.pageX][this.currentPage.pageY].height * this.options.snapThreshold); 30261 } 30262 }); 30263 30264 this.on('flick', function () { 30265 var time = this.options.snapSpeed || Math.max( 30266 Math.max( 30267 Math.min(Math.abs(this.x - this.startX), 1000), 30268 Math.min(Math.abs(this.y - this.startY), 1000) 30269 ), 300); 30270 30271 this.goToPage( 30272 this.currentPage.pageX + this.directionX, 30273 this.currentPage.pageY + this.directionY, 30274 time 30275 ); 30276 }); 30277 }, 30278 30279 _nearestSnap: function (x, y) { 30280 if ( !this.pages.length ) { 30281 return { x: 0, y: 0, pageX: 0, pageY: 0 }; 30282 } 30283 30284 var i = 0, 30285 l = this.pages.length, 30286 m = 0; 30287 30288 // Check if we exceeded the snap threshold 30289 if ( Math.abs(x - this.absStartX) < this.snapThresholdX && 30290 Math.abs(y - this.absStartY) < this.snapThresholdY ) { 30291 return this.currentPage; 30292 } 30293 30294 if ( x > 0 ) { 30295 x = 0; 30296 } else if ( x < this.maxScrollX ) { 30297 x = this.maxScrollX; 30298 } 30299 30300 if ( y > 0 ) { 30301 y = 0; 30302 } else if ( y < this.maxScrollY ) { 30303 y = this.maxScrollY; 30304 } 30305 30306 for ( ; i < l; i++ ) { 30307 if ( x >= this.pages[i][0].cx ) { 30308 x = this.pages[i][0].x; 30309 break; 30310 } 30311 } 30312 30313 l = this.pages[i].length; 30314 30315 for ( ; m < l; m++ ) { 30316 if ( y >= this.pages[0][m].cy ) { 30317 y = this.pages[0][m].y; 30318 break; 30319 } 30320 } 30321 30322 if ( i == this.currentPage.pageX ) { 30323 i += this.directionX; 30324 30325 if ( i < 0 ) { 30326 i = 0; 30327 } else if ( i >= this.pages.length ) { 30328 i = this.pages.length - 1; 30329 } 30330 30331 x = this.pages[i][0].x; 30332 } 30333 30334 if ( m == this.currentPage.pageY ) { 30335 m += this.directionY; 30336 30337 if ( m < 0 ) { 30338 m = 0; 30339 } else if ( m >= this.pages[0].length ) { 30340 m = this.pages[0].length - 1; 30341 } 30342 30343 y = this.pages[0][m].y; 30344 } 30345 30346 return { 30347 x: x, 30348 y: y, 30349 pageX: i, 30350 pageY: m 30351 }; 30352 }, 30353 30354 goToPage: function (x, y, time, easing) { 30355 easing = easing || this.options.bounceEasing; 30356 30357 if ( x >= this.pages.length ) { 30358 x = this.pages.length - 1; 30359 } else if ( x < 0 ) { 30360 x = 0; 30361 } 30362 30363 if ( y >= this.pages[x].length ) { 30364 y = this.pages[x].length - 1; 30365 } else if ( y < 0 ) { 30366 y = 0; 30367 } 30368 30369 var posX = this.pages[x][y].x, 30370 posY = this.pages[x][y].y; 30371 30372 time = time === undefined ? this.options.snapSpeed || Math.max( 30373 Math.max( 30374 Math.min(Math.abs(posX - this.x), 1000), 30375 Math.min(Math.abs(posY - this.y), 1000) 30376 ), 300) : time; 30377 30378 this.currentPage = { 30379 x: posX, 30380 y: posY, 30381 pageX: x, 30382 pageY: y 30383 }; 30384 30385 this.scrollTo(posX, posY, time, easing); 30386 }, 30387 30388 next: function (time, easing) { 30389 var x = this.currentPage.pageX, 30390 y = this.currentPage.pageY; 30391 30392 x++; 30393 30394 if ( x >= this.pages.length && this.hasVerticalScroll ) { 30395 x = 0; 30396 y++; 30397 } 30398 30399 this.goToPage(x, y, time, easing); 30400 }, 30401 30402 prev: function (time, easing) { 30403 var x = this.currentPage.pageX, 30404 y = this.currentPage.pageY; 30405 30406 x--; 30407 30408 if ( x < 0 && this.hasVerticalScroll ) { 30409 x = 0; 30410 y--; 30411 } 30412 30413 this.goToPage(x, y, time, easing); 30414 }, 30415 30416 _initKeys: function (e) { 30417 // default key bindings 30418 var keys = { 30419 pageUp: 33, 30420 pageDown: 34, 30421 end: 35, 30422 home: 36, 30423 left: 37, 30424 up: 38, 30425 right: 39, 30426 down: 40 30427 }; 30428 var i; 30429 30430 // if you give me characters I give you keycode 30431 if ( typeof this.options.keyBindings == 'object' ) { 30432 for ( i in this.options.keyBindings ) { 30433 if ( typeof this.options.keyBindings[i] == 'string' ) { 30434 this.options.keyBindings[i] = this.options.keyBindings[i].toUpperCase().charCo
vendor: 11,097 bytes, lines 30434-30787
30434deAt(0); 30435 } 30436 } 30437 } else { 30438 this.options.keyBindings = {}; 30439 } 30440 30441 for ( i in keys ) { 30442 this.options.keyBindings[i] = this.options.keyBindings[i] || keys[i]; 30443 } 30444 30445 utils.addEvent(window, 'keydown', this); 30446 30447 this.on('destroy', function () { 30448 utils.removeEvent(window, 'keydown', this); 30449 }); 30450 }, 30451 30452 _key: function (e) { 30453 if ( !this.enabled ) { 30454 return; 30455 } 30456 30457 var snap = this.options.snap, // we are using this alot, better to cache it 30458 newX = snap ? this.currentPage.pageX : this.x, 30459 newY = snap ? this.currentPage.pageY : this.y, 30460 now = utils.getTime(), 30461 prevTime = this.keyTime || 0, 30462 acceleration = 0.250, 30463 pos; 30464 30465 if ( this.options.useTransition && this.isInTransition ) { 30466 pos = this.getComputedPosition(); 30467 30468 this._translate(Math.round(pos.x), Math.round(pos.y)); 30469 this.isInTransition = false; 30470 } 30471 30472 this.keyAcceleration = now - prevTime < 200 ? Math.min(this.keyAcceleration + acceleration, 50) : 0; 30473 30474 switch ( e.keyCode ) { 30475 case this.options.keyBindings.pageUp: 30476 if ( this.hasHorizontalScroll && !this.hasVerticalScroll ) { 30477 newX += snap ? 1 : this.wrapperWidth; 30478 } else { 30479 newY += snap ? 1 : this.wrapperHeight; 30480 } 30481 break; 30482 case this.options.keyBindings.pageDown: 30483 if ( this.hasHorizontalScroll && !this.hasVerticalScroll ) { 30484 newX -= snap ? 1 : this.wrapperWidth; 30485 } else { 30486 newY -= snap ? 1 : this.wrapperHeight; 30487 } 30488 break; 30489 case this.options.keyBindings.end: 30490 newX = snap ? this.pages.length-1 : this.maxScrollX; 30491 newY = snap ? this.pages[0].length-1 : this.maxScrollY; 30492 break; 30493 case this.options.keyBindings.home: 30494 newX = 0; 30495 newY = 0; 30496 break; 30497 case this.options.keyBindings.left: 30498 newX += snap ? -1 : 5 + this.keyAcceleration>>0; 30499 break; 30500 case this.options.keyBindings.up: 30501 newY += snap ? 1 : 5 + this.keyAcceleration>>0; 30502 break; 30503 case this.options.keyBindings.right: 30504 newX -= snap ? -1 : 5 + this.keyAcceleration>>0; 30505 break; 30506 case this.options.keyBindings.down: 30507 newY -= snap ? 1 : 5 + this.keyAcceleration>>0; 30508 break; 30509 default: 30510 return; 30511 } 30512 30513 if ( snap ) { 30514 this.goToPage(newX, newY); 30515 return; 30516 } 30517 30518 if ( newX > 0 ) { 30519 newX = 0; 30520 this.keyAcceleration = 0; 30521 } else if ( newX < this.maxScrollX ) { 30522 newX = this.maxScrollX; 30523 this.keyAcceleration = 0; 30524 } 30525 30526 if ( newY > 0 ) { 30527 newY = 0; 30528 this.keyAcceleration = 0; 30529 } else if ( newY < this.maxScrollY ) { 30530 newY = this.maxScrollY; 30531 this.keyAcceleration = 0; 30532 } 30533 30534 this.scrollTo(newX, newY, 0); 30535 30536 this.keyTime = now; 30537 }, 30538 30539 _animate: function (destX, destY, duration, easingFn) { 30540 var that = this, 30541 startX = this.x, 30542 startY = this.y, 30543 startTime = utils.getTime(), 30544 destTime = startTime + duration; 30545 30546 function step () { 30547 var now = utils.getTime(), 30548 newX, newY, 30549 easing; 30550 30551 if ( now >= destTime ) { 30552 that.isAnimating = false; 30553 that._translate(destX, destY); 30554 30555 if ( !that.resetPosition(that.options.bounceTime) ) { 30556 that._execEvent('scrollEnd'); 30557 } 30558 30559 return; 30560 } 30561 30562 now = ( now - startTime ) / duration; 30563 easing = easingFn(now); 30564 newX = ( destX - startX ) * easing + startX; 30565 newY = ( destY - startY ) * easing + startY; 30566 that._translate(newX, newY); 30567 30568 if ( that.isAnimating ) { 30569 rAF(step); 30570 } 30571 } 30572 30573 this.isAnimating = true; 30574 step(); 30575 }, 30576 handleEvent: function (e) { 30577 switch ( e.type ) { 30578 case 'touchstart': 30579 case 'pointerdown': 30580 case 'MSPointerDown': 30581 case 'mousedown': 30582 this._start(e); 30583 break; 30584 case 'touchmove': 30585 case 'pointermove': 30586 case 'MSPointerMove': 30587 case 'mousemove': 30588 this._move(e); 30589 break; 30590 case 'touchend': 30591 case 'pointerup': 30592 case 'MSPointerUp': 30593 case 'mouseup': 30594 case 'touchcancel': 30595 case 'pointercancel': 30596 case 'MSPointerCancel': 30597 case 'mousecancel': 30598 this._end(e); 30599 break; 30600 case 'orientationchange': 30601 case 'resize': 30602 this._resize(); 30603 break; 30604 case 'transitionend': 30605 case 'webkitTransitionEnd': 30606 case 'oTransitionEnd': 30607 case 'MSTransitionEnd': 30608 this._transitionEnd(e); 30609 break; 30610 case 'wheel': 30611 case 'DOMMouseScroll': 30612 case 'mousewheel': 30613 this._wheel(e); 30614 break; 30615 case 'keydown': 30616 this._key(e); 30617 break; 30618 case 'click': 30619 if ( this.enabled && !e._constructed ) { 30620 e.preventDefault(); 30621 e.stopPropagation(); 30622 } 30623 break; 30624 } 30625 } 30626}; 30627function createDefaultScrollbar (direction, interactive, type) { 30628 var scrollbar = document.createElement('div'), 30629 indicator = document.createElement('div'); 30630 30631 if ( type === true ) { 30632 scrollbar.style.cssText = 'position:absolute;z-index:9999'; 30633 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'; 30634 } 30635 30636 indicator.className = 'iScrollIndicator'; 30637 30638 if ( direction == 'h' ) { 30639 if ( type === true ) { 30640 scrollbar.style.cssText += ';height:7px;left:2px;right:2px;bottom:0'; 30641 indicator.style.height = '100%'; 30642 } 30643 scrollbar.className = 'iScrollHorizontalScrollbar'; 30644 } else { 30645 if ( type === true ) { 30646 scrollbar.style.cssText += ';width:7px;bottom:2px;top:2px;right:1px'; 30647 indicator.style.width = '100%'; 30648 } 30649 scrollbar.className = 'iScrollVerticalScrollbar'; 30650 } 30651 30652 scrollbar.style.cssText += ';overflow:hidden'; 30653 30654 if ( !interactive ) { 30655 scrollbar.style.pointerEvents = 'none'; 30656 } 30657 30658 scrollbar.appendChild(indicator); 30659 30660 return scrollbar; 30661} 30662 30663function Indicator (scroller, options) { 30664 this.wrapper = typeof options.el == 'string' ? document.querySelector(options.el) : options.el; 30665 this.wrapperStyle = this.wrapper.style; 30666 this.indicator = this.wrapper.children[0]; 30667 this.indicatorStyle = this.indicator.style; 30668 this.scroller = scroller; 30669 30670 this.options = { 30671 listenX: true, 30672 listenY: true, 30673 interactive: false, 30674 resize: true, 30675 defaultScrollbars: false, 30676 shrink: false, 30677 fade: false, 30678 speedRatioX: 0, 30679 speedRatioY: 0 30680 }; 30681 30682 for ( var i in options ) { 30683 this.options[i] = options[i]; 30684 } 30685 30686 this.sizeRatioX = 1; 30687 this.sizeRatioY = 1; 30688 this.maxPosX = 0; 30689 this.maxPosY = 0; 30690 30691 if ( this.options.interactive ) { 30692 if ( !this.options.disableTouch ) { 30693 utils.addEvent(this.indicator, 'touchstart', this); 30694 utils.addEvent(window, 'touchend', this); 30695 } 30696 if ( !this.options.disablePointer ) { 30697 utils.addEvent(this.indicator, utils.prefixPointerEvent('pointerdown'), this); 30698 utils.addEvent(window, utils.prefixPointerEvent('pointerup'), this); 30699 } 30700 if ( !this.options.disableMouse ) { 30701 utils.addEvent(this.indicator, 'mousedown', this); 30702 utils.addEvent(window, 'mouseup', this); 30703 } 30704 } 30705 30706 if ( this.options.fade ) { 30707 this.wrapperStyle[utils.style.transform] = this.scroller.translateZ; 30708 var durationProp = utils.style.transitionDuration; 30709 if(!durationProp) { 30710 return; 30711 } 30712 this.wrapperStyle[durationProp] = utils.isBadAndroid ? '0.0001ms' : '0ms'; 30713 // remove 0.0001ms 30714 var self = this; 30715 if(utils.isBadAndroid) { 30716 rAF(function() { 30717 if(self.wrapperStyle[durationProp] === '0.0001ms') { 30718 self.wrapperStyle[durationProp] = '0s'; 30719 } 30720 }); 30721 } 30722 this.wrapperStyle.opacity = '0'; 30723 } 30724} 30725 30726Indicator.prototype = { 30727 handleEvent: function (e) { 30728 switch ( e.type ) { 30729 case 'touchstart': 30730 case 'pointerdown': 30731 case 'MSPointerDown': 30732 case 'mousedown': 30733 this._start(e); 30734 break; 30735 case 'touchmove': 30736 case 'pointermove': 30737 case 'MSPointerMove': 30738 case 'mousemove': 30739 this._move(e); 30740 break; 30741 case 'touchend': 30742 case 'pointerup': 30743 case 'MSPointerUp': 30744 case 'mouseup': 30745 case 'touchcancel': 30746 case 'pointercancel': 30747 case 'MSPointerCancel': 30748 case 'mousecancel': 30749 this._end(e); 30750 break; 30751 } 30752 }, 30753 30754 destroy: function () { 30755 if ( this.options.fadeScrollbars ) { 30756 clearTimeout(this.fadeTimeout); 30757 this.fadeTimeout = null; 30758 } 30759 if ( this.options.interactive ) { 30760 utils.removeEvent(this.indicator, 'touchstart', this); 30761 utils.removeEvent(this.indicator, utils.prefixPointerEvent('pointerdown'), this); 30762 utils.removeEvent(this.indicator, 'mousedown', this); 30763 30764 utils.removeEvent(window, 'touchmove', this); 30765 utils.removeEvent(window, utils.prefixPointerEvent('pointermove'), this); 30766 utils.removeEvent(window, 'mousemove', this); 30767 30768 utils.removeEvent(window, 'touchend', this); 30769 utils.removeEvent(window, utils.prefixPointerEvent('pointerup'), this); 30770 utils.removeEvent(window, 'mouseup', this); 30771 } 30772 30773 if ( this.options.defaultScrollbars ) { 30774 this.wrapper.parentNode.removeChild(this.wrapper); 30775 } 30776 }, 30777 30778 _start: function (e) { 30779 var point = e.touches ? e.touches[0] : e; 30780 30781 e.preventDefault(); 30782 e.stopPropagation(); 30783 30784 this.transitionTime(); 30785 30786 this.initiated = true; 30787 this.moved = false;
vendor: 9,615 bytes, lines 30788-31046
30788 this.lastPointX = point.pageX; 30789 this.lastPointY = point.pageY; 30790 30791 this.startTime = utils.getTime(); 30792 30793 if ( !this.options.disableTouch ) { 30794 utils.addEvent(window, 'touchmove', this); 30795 } 30796 if ( !this.options.disablePointer ) { 30797 utils.addEvent(window, utils.prefixPointerEvent('pointermove'), this); 30798 } 30799 if ( !this.options.disableMouse ) { 30800 utils.addEvent(window, 'mousemove', this); 30801 } 30802 30803 this.scroller._execEvent('beforeScrollStart'); 30804 }, 30805 30806 _move: function (e) { 30807 var point = e.touches ? e.touches[0] : e, 30808 deltaX, deltaY, 30809 newX, newY, 30810 timestamp = utils.getTime(); 30811 30812 if ( !this.moved ) { 30813 this.scroller._execEvent('scrollStart'); 30814 } 30815 30816 this.moved = true; 30817 30818 deltaX = point.pageX - this.lastPointX; 30819 this.lastPointX = point.pageX; 30820 30821 deltaY = point.pageY - this.lastPointY; 30822 this.lastPointY = point.pageY; 30823 30824 newX = this.x + deltaX; 30825 newY = this.y + deltaY; 30826 30827 this._pos(newX, newY); 30828 30829// INSERT POINT: indicator._move 30830 30831 e.preventDefault(); 30832 e.stopPropagation(); 30833 }, 30834 30835 _end: function (e) { 30836 if ( !this.initiated ) { 30837 return; 30838 } 30839 30840 this.initiated = false; 30841 30842 e.preventDefault(); 30843 e.stopPropagation(); 30844 30845 utils.removeEvent(window, 'touchmove', this); 30846 utils.removeEvent(window, utils.prefixPointerEvent('pointermove'), this); 30847 utils.removeEvent(window, 'mousemove', this); 30848 30849 if ( this.scroller.options.snap ) { 30850 var snap = this.scroller._nearestSnap(this.scroller.x, this.scroller.y); 30851 30852 var time = this.options.snapSpeed || Math.max( 30853 Math.max( 30854 Math.min(Math.abs(this.scroller.x - snap.x), 1000), 30855 Math.min(Math.abs(this.scroller.y - snap.y), 1000) 30856 ), 300); 30857 30858 if ( this.scroller.x != snap.x || this.scroller.y != snap.y ) { 30859 this.scroller.directionX = 0; 30860 this.scroller.directionY = 0; 30861 this.scroller.currentPage = snap; 30862 this.scroller.scrollTo(snap.x, snap.y, time, this.scroller.options.bounceEasing); 30863 } 30864 } 30865 30866 if ( this.moved ) { 30867 this.scroller._execEvent('scrollEnd'); 30868 } 30869 }, 30870 30871 transitionTime: function (time) { 30872 time = time || 0; 30873 var durationProp = utils.style.transitionDuration; 30874 if(!durationProp) { 30875 return; 30876 } 30877 30878 this.indicatorStyle[durationProp] = time + 'ms'; 30879 30880 if ( !time && utils.isBadAndroid ) { 30881 this.indicatorStyle[durationProp] = '0.0001ms'; 30882 // remove 0.0001ms 30883 var self = this; 30884 rAF(function() { 30885 if(self.indicatorStyle[durationProp] === '0.0001ms') { 30886 self.indicatorStyle[durationProp] = '0s'; 30887 } 30888 }); 30889 } 30890 }, 30891 30892 transitionTimingFunction: function (easing) { 30893 this.indicatorStyle[utils.style.transitionTimingFunction] = easing; 30894 }, 30895 30896 refresh: function () { 30897 this.transitionTime(); 30898 30899 if ( this.options.listenX && !this.options.listenY ) { 30900 this.indicatorStyle.display = this.scroller.hasHorizontalScroll ? 'block' : 'none'; 30901 } else if ( this.options.listenY && !this.options.listenX ) { 30902 this.indicatorStyle.display = this.scroller.hasVerticalScroll ? 'block' : 'none'; 30903 } else { 30904 this.indicatorStyle.display = this.scroller.hasHorizontalScroll || this.scroller.hasVerticalScroll ? 'block' : 'none'; 30905 } 30906 30907 if ( this.scroller.hasHorizontalScroll && this.scroller.hasVerticalScroll ) { 30908 utils.addClass(this.wrapper, 'iScrollBothScrollbars'); 30909 utils.removeClass(this.wrapper, 'iScrollLoneScrollbar'); 30910 30911 if ( this.options.defaultScrollbars && this.options.customStyle ) { 30912 if ( this.options.listenX ) { 30913 this.wrapper.style.right = '8px'; 30914 } else { 30915 this.wrapper.style.bottom = '8px'; 30916 } 30917 } 30918 } else { 30919 utils.removeClass(this.wrapper, 'iScrollBothScrollbars'); 30920 utils.addClass(this.wrapper, 'iScrollLoneScrollbar'); 30921 30922 if ( this.options.defaultScrollbars && this.options.customStyle ) { 30923 if ( this.options.listenX ) { 30924 this.wrapper.style.right = '2px'; 30925 } else { 30926 this.wrapper.style.bottom = '2px'; 30927 } 30928 } 30929 } 30930 30931 var r = this.wrapper.offsetHeight; // force refresh 30932 30933 if ( this.options.listenX ) { 30934 this.wrapperWidth = this.wrapper.clientWidth; 30935 if ( this.options.resize ) { 30936 this.indicatorWidth = Math.max(Math.round(this.wrapperWidth * this.wrapperWidth / (this.scroller.scrollerWidth || this.wrapperWidth || 1)), 8); 30937 this.indicatorStyle.width = this.indicatorWidth + 'px'; 30938 } else { 30939 this.indicatorWidth = this.indicator.clientWidth; 30940 } 30941 30942 this.maxPosX = this.wrapperWidth - this.indicatorWidth; 30943 30944 if ( this.options.shrink == 'clip' ) { 30945 this.minBoundaryX = -this.indicatorWidth + 8; 30946 this.maxBoundaryX = this.wrapperWidth - 8; 30947 } else { 30948 this.minBoundaryX = 0; 30949 this.maxBoundaryX = this.maxPosX; 30950 } 30951 30952 this.sizeRatioX = this.options.speedRatioX || (this.scroller.maxScrollX && (this.maxPosX / this.scroller.maxScrollX)); 30953 } 30954 30955 if ( this.options.listenY ) { 30956 this.wrapperHeight = this.wrapper.clientHeight; 30957 if ( this.options.resize ) { 30958 this.indicatorHeight = Math.max(Math.round(this.wrapperHeight * this.wrapperHeight / (this.scroller.scrollerHeight || this.wrapperHeight || 1)), 8); 30959 this.indicatorStyle.height = this.indicatorHeight + 'px'; 30960 } else { 30961 this.indicatorHeight = this.indicator.clientHeight; 30962 } 30963 30964 this.maxPosY = this.wrapperHeight - this.indicatorHeight; 30965 30966 if ( this.options.shrink == 'clip' ) { 30967 this.minBoundaryY = -this.indicatorHeight + 8; 30968 this.maxBoundaryY = this.wrapperHeight - 8; 30969 } else { 30970 this.minBoundaryY = 0; 30971 this.maxBoundaryY = this.maxPosY; 30972 } 30973 30974 this.maxPosY = this.wrapperHeight - this.indicatorHeight; 30975 this.sizeRatioY = this.options.speedRatioY || (this.scroller.maxScrollY && (this.maxPosY / this.scroller.maxScrollY)); 30976 } 30977 30978 this.updatePosition(); 30979 }, 30980 30981 updatePosition: function () { 30982 var x = this.options.listenX && Math.round(this.sizeRatioX * this.scroller.x) || 0, 30983 y = this.options.listenY && Math.round(this.sizeRatioY * this.scroller.y) || 0; 30984 30985 if ( !this.options.ignoreBoundaries ) { 30986 if ( x < this.minBoundaryX ) { 30987 if ( this.options.shrink == 'scale' ) { 30988 this.width = Math.max(this.indicatorWidth + x, 8); 30989 this.indicatorStyle.width = this.width + 'px'; 30990 } 30991 x = this.minBoundaryX; 30992 } else if ( x > this.maxBoundaryX ) { 30993 if ( this.options.shrink == 'scale' ) { 30994 this.width = Math.max(this.indicatorWidth - (x - this.maxPosX), 8); 30995 this.indicatorStyle.width = this.width + 'px'; 30996 x = this.maxPosX + this.indicatorWidth - this.width; 30997 } else { 30998 x = this.maxBoundaryX; 30999 } 31000 } else if ( this.options.shrink == 'scale' && this.width != this.indicatorWidth ) { 31001 this.width = this.indicatorWidth; 31002 this.indicatorStyle.width = this.width + 'px'; 31003 } 31004 31005 if ( y < this.minBoundaryY ) { 31006 if ( this.options.shrink == 'scale' ) { 31007 this.height = Math.max(this.indicatorHeight + y * 3, 8); 31008 this.indicatorStyle.height = this.height + 'px'; 31009 } 31010 y = this.minBoundaryY; 31011 } else if ( y > this.maxBoundaryY ) { 31012 if ( this.options.shrink == 'scale' ) { 31013 this.height = Math.max(this.indicatorHeight - (y - this.maxPosY) * 3, 8); 31014 this.indicatorStyle.height = this.height + 'px'; 31015 y = this.maxPosY + this.indicatorHeight - this.height; 31016 } else { 31017 y = this.maxBoundaryY; 31018 } 31019 } else if ( this.options.shrink == 'scale' && this.height != this.indicatorHeight ) { 31020 this.height = this.indicatorHeight; 31021 this.indicatorStyle.height = this.height + 'px'; 31022 } 31023 } 31024 31025 this.x = x; 31026 this.y = y; 31027 31028 if ( this.scroller.options.useTransform ) { 31029 this.indicatorStyle[utils.style.transform] = 'translate(' + x + 'px,' + y + 'px)' + this.scroller.translateZ; 31030 } else { 31031 this.indicatorStyle.left = x + 'px'; 31032 this.indicatorStyle.top = y + 'px'; 31033 } 31034 }, 31035 31036 _pos: function (x, y) { 31037 if ( x < 0 ) { 31038 x = 0; 31039 } else if ( x > this.maxPosX ) { 31040 x = this.maxPosX; 31041 } 31042 31043 if ( y < 0 ) { 31044 y = 0; 31045 } else if ( y > this.maxPosY ) { 31046 y = this.maxPosY;
31047 } 31048 31049 x = this.options.listenX ? Math.round(x / this.sizeRatioX) : this.scroller.x; 31050 y = this.options.listenY ? Math.round(y / this.sizeRatioY) : this.scroller.y; 31051 31052 this.scroller.scrollTo(x, y); 31053 }, 31054 31055 fade: function (val, hold) { 31056 if ( hold && !this.visible ) { 31057 return; 31058 } 31059 31060 clearTimeout(this.fadeTimeout); 31061 this.fadeTimeout = null; 31062 31063 var time = val ? 250 : 500, 31064 delay = val ? 0 : 300; 31065 31066 val = val ? '1' : '0'; 31067 31068 this.wrapperStyle[utils.style.transitionDuration] = time + 'ms'; 31069 31070 this.fadeTimeout = setTimeout((function (val) { 31071 this.wrapperStyle.opacity = val; 31072 this.visible = +val; 31073 }).bind(this, val), delay); 31074 } 31075}; 31076 31077IScroll.utils = utils; 31078 31079if ( typeof module != 'undefined' && module.exports ) { 31080 module.exports = IScroll; 31081} else if ( typeof define == 'function' && define.amd ) { 31082 define( function () { return IScroll; } ); 31083} else { 31084 window.IScroll = IScroll; 31085} 31086 31087})(window, document, Math); 31088/*! 31089 * fullPage 2.9.4 31090 * https://github.com/alvarotrigo/fullPage.js 31091 * @license MIT licensed 31092 * 31093 * Copyright (C) 2015 alvarotrigo.com - A project by Alvaro Trigo 31094 */ 31095(function(global, factory) { 31096 'use strict'; 31097 if (typeof define === 'function' && define.amd) { 31098 define(['jquery'], function($) { 31099 return factory($, global, global.document, global.Math); 31100 }); 31101 } else if (typeof exports === "object" && exports) { 31102 module.exports = factory(require('jquery'), global, global.document, global.Math); 31103 } else { 31104 factory(jQuery, global, global.document, global.Math); 31105 } 31106})(typeof window !== 'undefined' ? window : this, function($, window, document, Math, undefined) { 31107 'use strict'; 31108 31109 // keeping central set of classnames and selectors 31110 var WRAPPER = 'fullpage-wrapper'; 31111 var WRAPPER_SEL = '.' + WRAPPER; 31112 31113 // slimscroll 31114 var SCROLLABLE = 'fp-scrollable'; 31115 var SCROLLABLE_SEL = '.' + SCROLLABLE; 31116 31117 // util 31118 var RESPONSIVE = 'fp-responsive'; 31119 var NO_TRANSITION = 'fp-notransition'; 31120 var DESTROYED = 'fp-destroyed'; 31121 var ENABLED = 'fp-enabled'; 31122 var VIEWING_PREFIX = 'fp-viewing'; 31123 var ACTIVE = 'active'; 31124 var ACTIVE_SEL = '.' + ACTIVE; 31125 var COMPLETELY = 'fp-completely'; 31126 var COMPLETELY_SEL = '.' + COMPLETELY; 31127 31128 // section 31129 var SECTION_DEFAULT_SEL = '.section'; 31130 var SECTION = 'fp-section'; 31131 var SECTION_SEL = '.' + SECTION; 31132 var SECTION_ACTIVE_SEL = SECTION_SEL + ACTIVE_SEL; 31133 var SECTION_FIRST_SEL = SECTION_SEL + ':first'; 31134 var SECTION_LAST_SEL = SECTION_SEL + ':last'; 31135 var TABLE_CELL = 'fp-tableCell'; 31136 var TABLE_CELL_SEL = '.' + TABLE_CELL; 31137 var AUTO_HEIGHT = 'fp-auto-height'; 31138 var AUTO_HEIGHT_SEL = '.fp-auto-height'; 31139 var NORMAL_SCROLL = 'fp-normal-scroll'; 31140 var NORMAL_SCROLL_SEL = '.fp-normal-scroll'; 31141 31142 // section nav 31143 var SECTION_NAV = 'fp-nav'; 31144 var SECTION_NAV_SEL = '#' + SECTION_NAV; 31145 var SECTION_NAV_TOOLTIP = 'fp-tooltip'; 31146 var SECTION_NAV_TOOLTIP_SEL='.'+SECTION_NAV_TOOLTIP; 31147 var SHOW_ACTIVE_TOOLTIP = 'fp-show-active'; 31148 31149 // slide 31150 var SLIDE_DEFAULT_SEL = '.slide'; 31151 var SLIDE = 'fp-slide'; 31152 var SLIDE_SEL = '.' + SLIDE; 31153 var SLIDE_ACTIVE_SEL = SLIDE_SEL + ACTIVE_SEL; 31154 var SLIDES_WRAPPER = 'fp-slides'; 31155 var SLIDES_WRAPPER_SEL = '.' + SLIDES_WRAPPER; 31156 var SLIDES_CONTAINER = 'fp-slidesContainer'; 31157 var SLIDES_CONTAINER_SEL = '.' + SLIDES_CONTAINER; 31158 var TABLE = 'fp-table'; 31159 31160 // slide nav 31161 var SLIDES_NAV = 'fp-slidesNav'; 31162 var SLIDES_NAV_SEL = '.' + SLIDES_NAV; 31163 var SLIDES_NAV_LINK_SEL = SLIDES_NAV_SEL + ' a'; 31164 var SLIDES_ARROW = 'fp-controlArrow'; 31165 var SLIDES_ARROW_SEL = '.' + SLIDES_ARROW; 31166 var SLIDES_PREV = 'fp-prev'; 31167 var SLIDES_PREV_SEL = '.' + SLIDES_PREV; 31168 var SLIDES_ARROW_PREV = SLIDES_ARROW + ' ' + SLIDES_PREV; 31169 var SLIDES_ARROW_PREV_SEL = SLIDES_ARROW_SEL + SLIDES_PREV_SEL; 31170 var SLIDES_NEXT = 'fp-next';
31171 var SLIDES_NEXT_SEL = '.' + SLIDES_NEXT; 31172 var SLIDES_ARROW_NEXT = SLIDES_ARROW + ' ' + SLIDES_NEXT; 31173 var SLIDES_ARROW_NEXT_SEL = SLIDES_ARROW_SEL + SLIDES_NEXT_SEL; 31174 31175 var $window = $(window); 31176 var $document = $(document); 31177 31178 // Default options for iScroll.js used when using scrollOverflow 31179 var iscrollOptions = { 31180 scrollbars: true, 31181 mouseWheel: true, 31182 hideScrollbars: false, 31183 fadeScrollbars: false, 31184 disableMouse: true, 31185 interactiveScrollbars: true, 31186 bounce: false, 31187 }; 31188 31189 $.fn.fullpage = function(options) { 31190 //only once my friend! 31191 if($('html').hasClass(ENABLED)){ displayWarnings(); return; } 31192 31193 // common jQuery objects 31194 var $htmlBody = $('html, body'); 31195 var $body = $('body'); 31196 31197 var FP = $.fn.fullpage; 31198 31199 // Creating some defaults, extending them with any options that were provided 31200 options = $.extend({ 31201 //navigation 31202 menu: false, 31203 anchors:[], 31204 lockAnchors: false, 31205 navigation: false, 31206 navigationPosition: 'right', 31207 navigationTooltips: [], 31208 showActiveTooltip: false, 31209 slidesNavigation: false, 31210 slidesNavPosition: 'bottom', 31211 scrollBar: false, 31212 hybrid: false, 31213 31214 //scrolling 31215 css3: true, 31216 scrollingSpeed: 700, 31217 autoScrolling: true, 31218 fitToSection: true, 31219 fitToSectionDelay: 1000, 31220 easing: 'easeInOutCubic', 31221 easingcss3: 'ease', 31222 loopBottom: false, 31223 loopTop: false, 31224 loopHorizontal: true, 31225 continuousVertical: false, 31226 continuousHorizontal: false, 31227 scrollHorizontally: false, 31228 interlockedSlides: false, 31229 dragAndMove: false, 31230 offsetSections: false, 31231 resetSliders: false, 31232 fadingEffect: false, 31233 normalScrollElements: null, 31234 scrollOverflow: false, 31235 scrollOverflowReset: false, 31236 scrollOverflowHandler: iscrollHandler, 31237 scrollOverflowOptions: null, 31238 touchSensitivity: 5, 31239 normalScrollElementTouchThreshold: 5, 31240 bigSectionsDestination: null, 31241 31242 //Accessibility 31243 keyboardScrolling: true, 31244 animateAnchor: true, 31245 recordHistory: true, 31246 31247 //design 31248 controlArrows: true, 31249 controlArrowColor: '#fff', 31250 verticalCentered: true, 31251 sectionsColor : [], 31252 paddingTop: 0, 31253 paddingBottom: 0, 31254 fixedElements: null, 31255 responsive: 0, //backwards compabitility with responsiveWiddth 31256 responsiveWidth: 0, 31257 responsiveHeight: 0, 31258 responsiveSlides: false, 31259 parallax: false, 31260 parallaxOptions: { 31261 type: 'reveal', 31262 percentage: 62, 31263 property: 'translate' 31264 }, 31265 31266 //Custom selectors 31267 sectionSelector: SECTION_DEFAULT_SEL, 31268 slideSelector: SLIDE_DEFAULT_SEL, 31269 31270 //events 31271 afterLoad: null, 31272 onLeave: null, 31273 afterRender: null, 31274 afterResize: null, 31275 afterReBuild: null, 31276 afterSlideLoad: null, 31277 onSlideLeave: null, 31278 afterResponsive: null, 31279 31280 lazyLoading: true 31281 }, options); 31282 31283 //flag to avoid very fast sliding for landscape sliders 31284 var slideMoving = false; 31285 31286 var isTouchDevice = navigator.userAgent.match(/(iPhone|iPod|iPad|Android|playbook|silk|BlackBerry|BB10|Windows Phone|Tizen|Bada|webOS|IEMobile|Opera Mini)/); 31287 var isTouch = (('ontouchstart' in window) || (navigator.msMaxTouchPoints > 0) || (navigator.maxTouchPoints)); 31288 var container = $(this); 31289 var windowsHeight = $window.height(); 31290 var isResizing = false; 31291 var isWindowFocused = true; 31292 var lastScrolledDestiny; 31293 var lastScrolledSlide; 31294 var canScroll = true; 31295 var scrollings = []; 31296 var controlPressed; 31297 var startingSection; 31298 var isScrollAllowed = {}; 31299 isScrollAllowed.m = { 'up':true, 'down':true, 'left':true, 'right':true }; 31300 isScrollAllowed.k = $.extend(true,{}, isScrollAllowed.m); 31301 var MSPointer = getMSPointer(); 31302 var events = { 31303 touchmove: 'ontouchmove' in window ? 'touchmove' : MSPointer.move, 31304 touchstart: 'ontouchstart' in window ? 'touchstart' : MSPointer.down 31305 }; 31306 31307 //cheks for passive event support 31308 //added by Uncode from new fullPage updates 31309 var g_supportsPassive = false;
31310 try { 31311 var opts = Object.defineProperty({}, 'passive', { 31312 get: function() { 31313 g_supportsPassive = true; 31314 } 31315 }); 31316 window.addEventListener("testPassive", null, opts); 31317 window.removeEventListener("testPassive", null, opts); 31318 } catch (e) {} 31319 31320 //timeouts 31321 var resizeId; 31322 var afterSectionLoadsId; 31323 var afterSlideLoadsId; 31324 var scrollId; 31325 var scrollId2; 31326 var keydownId; 31327 var originals = $.extend(true, {}, options); //deep copy 31328 31329 //Uncode addition 31330 var $masthead = $('#masthead'); 31331 var hideMenu = !$('body').hasClass('vmenu') && $('body').hasClass('uncode-fp-menu-hide') ? true : false; 31332 var menuHeight = $masthead.hasClass('menu-transparent') || hideMenu ? 0 : UNCODE.menuHeight; 31333 var bodyBorder = UNCODE.bodyBorder; 31334 var adminBarHeight = UNCODE.adminBarHeight; 31335 31336 displayWarnings(); 31337 31338 //fixing bug in iScroll with links: https://github.com/cubiq/iscroll/issues/783 31339 iscrollOptions.click = isTouch; // see #2035 31340 31341 //extending iScroll options with the user custom ones 31342 iscrollOptions = $.extend(iscrollOptions, options.scrollOverflowOptions); 31343 31344 //easeInOutCubic animation included in the plugin 31345 $.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;}}); 31346 31347 /** 31348 * Sets the autoScroll option. 31349 * It changes the scroll bar visibility and the history of the site as a result. 31350 */ 31351 function setAutoScrolling(value, type){ 31352 //removing the transformation 31353 if(!value){ 31354 silentScroll(0); 31355 } 31356 31357 setVariableState('autoScrolling', value, type); 31358 31359 var element = $(SECTION_ACTIVE_SEL); 31360 31361 if(options.autoScrolling && !options.scrollBar){ 31362 $htmlBody.css({ 31363 'overflow' : 'hidden !important', 31364 'height' : '100%' 31365 }); 31366 31367 //Uncode addition 31368 //setRecordHistory(originals.recordHistory, 'internal'); 31369 31370 //for IE touch devices 31371 container.css({ 31372 '-ms-touch-action': 'none', 31373 'touch-action': 'none' 31374 }); 31375 31376 if(element.length){ 31377 //moving the container up 31378 silentScroll(element.position().top); 31379 } 31380 31381 }else{ 31382 $htmlBody.css({ 31383 'overflow' : 'visible !important', 31384 'height' : 'initial' 31385 }); 31386 31387 //Uncode addition 31388 //setRecordHistory(false, 'internal'); 31389 31390 //for IE touch devices 31391 container.css({ 31392 '-ms-touch-action': '', 31393 'touch-action': '' 31394 }); 31395 31396 //scrolling the page to the section with no animation 31397 if (element.length) { 31398 $htmlBody.scrollTop(element.position().top); 31399 } 31400 } 31401 } 31402 31403 /** 31404 * Defines wheter to record the history for each hash change in the URL. 31405 */ 31406 function setRecordHistory(value, type){ 31407 setVariableState('recordHistory', value, type); 31408 } 31409 31410 /** 31411 * Defines the scrolling speed 31412 */ 31413 function setScrollingSpeed(value, type){ 31414 setVariableState('scrollingSpeed', value, type); 31415 } 31416 31417 /** 31418 * Sets fitToSection 31419 */ 31420 function setFitToSection(value, type){ 31421 setVariableState('fitToSection', value, type); 31422 } 31423 31424 /** 31425 * Sets lockAnchors 31426 */ 31427 function setLockAnchors(value){ 31428 options.lockAnchors = value; 31429 } 31430 31431 /** 31432 * Adds or remove the possiblity of scrolling through sections by using the mouse wheel or the trackpad. 31433 */ 31434 function setMouseWheelScrolling(value){ 31435 if(value){ 31436 addMouseWheelHandler(); 31437 addMiddleWheelHandler(); 31438 }else{ 31439 removeMouseWheelHandler(); 31440 removeMiddleWheelHandler(); 31441 } 31442 } 31443 31444 /** 31445 * Adds or remove the possibility of scrolling through sections by using the mouse wheel/trackpad or touch gestures. 31446 * Optionally a second parameter can be used to specify the direction for which the action will be applied. 31447 * 31448 * @param directions string containing the direction or directions separated by comma. 31449 */ 31450 function setAllowScrolling(value, directions){ 31451 if(typeof directions !== 'undefined'){ 31452 directions = directions.replace(/ /g,'').split(','); 31453 31454 $.each(directions, function (index, direction){ 31455 setIsScrollAllowed(value, direction, 'm'); 31456 }); 31457 } 31458 else if(value){ 31459 setMouseWheelScrolling(true); 31460 addTouchHandler(); 31461 }else{ 31462 setMouseWheelScrolling(false); 31463 removeTouchHandler(); 31464 } 31465 } 31466 31467 /** 31468 * Adds or remove the possibility of scrolling through sections by using the keyboard arrow keys 31469 */ 31470 function setKeyboardScrolling(value, directions){ 31471 if(typeof directions !== 'undefined'){ 31472 directions = directions.replace(/ /g,'').split(','); 31473 31474 $.each(directions, function (index, direction){ 31475 setIsScrollAllowed(value, direction, 'k'); 31476 }); 31477 }else{ 31478 options.keyboardScrolling = value; 31479 } 31480 } 31481 31482 /** 31483 * Moves the page up one section. 31484 */ 31485 function moveSectionUp(){ 31486 var prev = $(SECTION_ACTIVE_SEL).prev(SECTION_SEL); 31487 31488 //looping to the bottom if there's no more sections above 31489 if (!prev.length && (options.loopTop || options.continuousVertical)) {
31490 prev = $(SECTION_SEL).last(); 31491 } 31492 31493 if (prev.length) { 31494 scrollPage(prev, null, true); 31495 } 31496 } 31497 31498 /** 31499 * Moves the page down one section. 31500 */ 31501 function moveSectionDown(){ 31502 var next = $(SECTION_ACTIVE_SEL).next(SECTION_SEL); 31503 31504 //looping to the top if there's no more sections below 31505 if(!next.length && 31506 (options.loopBottom || options.continuousVertical)){ 31507 next = $(SECTION_SEL).first(); 31508 } 31509 31510 if(next.length){ 31511 scrollPage(next, null, false); 31512 } 31513 } 31514 31515 /** 31516 * Moves the page to the given section and slide with no animation. 31517 * Anchors or index positions can be used as params. 31518 */ 31519 function silentMoveTo(sectionAnchor, slideAnchor){ 31520 setScrollingSpeed (0, 'internal'); 31521 moveTo(sectionAnchor, slideAnchor); 31522 setScrollingSpeed (originals.scrollingSpeed, 'internal'); 31523 } 31524 31525 /** 31526 * Moves the page to the given section and slide. 31527 * Anchors or index positions can be used as params. 31528 */ 31529 function moveTo(sectionAnchor, slideAnchor){ 31530 var destiny = getSectionByAnchor(sectionAnchor); 31531 31532 if (typeof slideAnchor !== 'undefined'){ 31533 scrollPageAndSlide(sectionAnchor, slideAnchor); 31534 }else if(destiny.length > 0){ 31535 scrollPage(destiny); 31536 } 31537 } 31538 31539 /** 31540 * Slides right the slider of the active section. 31541 * Optional `section` param. 31542 */ 31543 function moveSlideRight(section){ 31544 moveSlide('right', section); 31545 } 31546 31547 /** 31548 * Slides left the slider of the active section. 31549 * Optional `section` param. 31550 */ 31551 function moveSlideLeft(section){ 31552 moveSlide('left', section); 31553 } 31554 31555 /** 31556 * When resizing is finished, we adjust the slides sizes and positions 31557 */ 31558 function reBuild(resizing){ 31559 if(container.hasClass(DESTROYED)){ return; } //nothing to do if the plugin was destroyed 31560 31561 isResizing = true; 31562 31563 windowsHeight = $window.height(); //updating global var 31564 31565 $(SECTION_SEL).each(function(){ 31566 var slidesWrap = $(this).find(SLIDES_WRAPPER_SEL); 31567 var slides = $(this).find(SLIDE_SEL); 31568 31569 //adjusting the height of the table-cell for IE and Firefox 31570 if(options.verticalCentered){ 31571 $(this).find(TABLE_CELL_SEL).css('height', getTableHeight($(this)) + 'px'); 31572 } 31573 31574 $(this).css('height', windowsHeight + 'px'); 31575 31576 //resizing the scrolling divs 31577 if(options.scrollOverflow){ 31578 if(slides.length){ 31579 slides.each(function(){ 31580 createScrollBar($(this)); 31581 }); 31582 }else{ 31583 createScrollBar($(this)); 31584 } 31585 } 31586 31587 //adjusting the position fo the FULL WIDTH slides... 31588 if (slides.length > 1) { 31589 landscapeScroll(slidesWrap, slidesWrap.find(SLIDE_ACTIVE_SEL)); 31590 } 31591 }); 31592 31593 var activeSection = $(SECTION_ACTIVE_SEL); 31594 var sectionIndex = activeSection.index(SECTION_SEL); 31595 31596 //isn't it the first section? 31597 if(sectionIndex){ 31598 //adjusting the position for the current section 31599 silentMoveTo(sectionIndex + 1); 31600 } 31601 31602 isResizing = false; 31603 // Uncode change 31604 // $.isFunction( options.afterResize ) && resizing && options.afterResize.call(container); 31605 $.isFunction( options.afterResize ) && resizing && options.afterResize.call(container, getTableHeight()); 31606 $.isFunction( options.afterReBuild ) && !resizing && options.afterReBuild.call(container); 31607 } 31608 31609 /** 31610 * Turns fullPage.js to normal scrolling mode when the viewport `width` or `height` 31611 * are smaller than the set limit values. 31612 */ 31613 function setResponsive(active){ 31614 var isResponsive = $body.hasClass(RESPONSIVE); 31615 31616 if(active){ 31617 if(!isResponsive){ 31618 setAutoScrolling(false, 'internal'); 31619 setFitToSection(false, 'internal'); 31620 $(SECTION_NAV_SEL).hide(); 31621 $body.addClass(RESPONSIVE); 31622 $.isFunction( options.afterResponsive ) && options.afterResponsive.call( container, active); 31623 } 31624 } 31625 else if(isResponsive){ 31626 setAutoScrolling(originals.autoScrolling, 'internal'); 31627 setFitToSection(originals.autoScrolling, 'internal'); 31628 $(SECTION_NAV_SEL).show(); 31629 $body.removeClass(RESPONSIVE); 31630 $.isFunction( options.afterResponsive ) && options.afterResponsive.call( container, active); 31631 } 31632 } 31633 31634 if($(this).length){ 31635 //public functions 31636 FP.setAutoScrolling = setAutoScrolling; 31637 FP.setRecordHistory = setRecordHistory; 31638 FP.setScrollingSpeed = setScrollingSpeed; 31639 FP.setFitToSection = setFitToSection; 31640 FP.setLockAnchors = setLockAnchors; 31641 FP.setMouseWheelScrolling = setMouseWheelScrolling; 31642 FP.setAllowScrolling = setAllowScrolling; 31643 FP.setKeyboardScrolling = setKeyboardScrolling; 31644 FP.moveSectionUp = moveSectionUp; 31645 FP.moveSectionDown = moveSectionDown; 31646 FP.silentMoveTo = silentMoveTo; 31647 FP.moveTo = moveTo; 31648 FP.moveSlideRight = moveSlideRight; 31649 FP.moveSlideLeft = moveSlideLeft; 31650 FP.fitToSection = fitToSection; 31651 FP.reBuild = reBuild; 31652 FP.setResponsive = setResponsive; 31653 FP.destroy = destroy; 31654 31655 init(); 31656 31657 bindEvents(); 31658 } 31659
31660 function init(){ 31661 //if css3 is not supported, it will use jQuery animations 31662 if(options.css3){ 31663 options.css3 = support3d(); 31664 } 31665 31666 options.scrollBar = options.scrollBar || options.hybrid; 31667 31668 setOptionsFromDOM(); 31669 prepareDom(); 31670 setAllowScrolling(true); 31671 setAutoScrolling(options.autoScrolling, 'internal'); 31672 responsive(); 31673 31674 //setting the class for the body element 31675 setBodyClass(); 31676 31677 //Uncode addition 31678 // if(document.readyState === 'complete'){ 31679 // scrollToAnchor(); 31680 // } 31681 // $window.on('load', scrollToAnchor); 31682 } 31683 31684 function bindEvents(){ 31685 $window 31686 //when scrolling... 31687 //.on('scroll', scrollHandler) 31688 31689 //detecting any change on the URL to scroll to the given anchor link 31690 //(a way to detect back history button as we play with the hashes on the URL) 31691 .on('hashchange', hashChangeHandler) 31692 31693 //when opening a new tab (ctrl + t), `control` won't be pressed when coming back. 31694 .blur(blurHandler) 31695 31696 //when resizing the site, we adjust the heights of the sections, slimScroll... 31697 .resize(resizeHandler); 31698 31699 $document 31700 //Sliding with arrow keys, both, vertical and horizontal 31701 .keydown(keydownHandler) 31702 31703 //to prevent scrolling while zooming 31704 .keyup(keyUpHandler) 31705 31706 //Scrolls to the section when clicking the navigation bullet 31707 .on('click touchstart', SECTION_NAV_SEL + ' a', sectionBulletHandler) 31708 31709 //Scrolls the slider to the given slide destination for the given section 31710 .on('click touchstart', SLIDES_NAV_LINK_SEL, slideBulletHandler) 31711 31712 .on('click', SECTION_NAV_TOOLTIP_SEL, tooltipTextHandler); 31713 31714 //Scrolling horizontally when clicking on the slider controls. 31715 $(SECTION_SEL).on('click touchstart', SLIDES_ARROW_SEL, slideArrowHandler); 31716 31717 /** 31718 * Applying normalScroll elements. 31719 * Ignoring the scrolls over the specified selectors. 31720 */ 31721 if(options.normalScrollElements){ 31722 $document.on('mouseenter', options.normalScrollElements, function () { 31723 setMouseWheelScrolling(false); 31724 }); 31725 31726 $document.on('mouseleave', options.normalScrollElements, function(){ 31727 setMouseWheelScrolling(true); 31728 }); 31729 } 31730 } 31731 31732 /** 31733 * Setting options from DOM elements if they are not provided. 31734 */ 31735 function setOptionsFromDOM(){ 31736 var sections = container.find(options.sectionSelector); 31737 31738 //no anchors option? Checking for them in the DOM attributes 31739 if(!options.anchors.length){ 31740 options.anchors = sections.filter('[data-anchor]').map(function(){ 31741 return $(this).data('anchor').toString(); 31742 }).get(); 31743 } 31744 31745 //no tooltips option? Checking for them in the DOM attributes 31746 if(!options.navigationTooltips.length){ 31747 options.navigationTooltips = sections.filter('[data-tooltip]').map(function(){ 31748 return $(this).data('tooltip').toString(); 31749 }).get(); 31750 } 31751 } 31752 31753 /** 31754 * Works over the DOM structure to set it up for the current fullpage options. 31755 */ 31756 function prepareDom(){ 31757 container.css({ 31758 'height': '100%', 31759 'position': 'relative' 31760 }); 31761 31762 //adding a class to recognize the container internally in the code 31763 container.addClass(WRAPPER); 31764 $('html').addClass(ENABLED); 31765 31766 windowsHeight = $window.height(); 31767 31768 container.removeClass(DESTROYED); //in case it was destroyed before initializing it again 31769 31770 addInternalSelectors(); 31771 31772 //styling the sections / slides / menu 31773 $(SECTION_SEL).each(function(index){ 31774 var section = $(this); 31775 var slides = section.find(SLIDE_SEL); 31776 var numSlides = slides.length; 31777 31778 styleSection(section, index); 31779 styleMenu(section, index); 31780 31781 // if there's any slide 31782 if (numSlides > 0) { 31783 styleSlides(section, slides, numSlides); 31784 }else{ 31785 if(options.verticalCentered){ 31786 addTableClass(section); 31787 } 31788 } 31789 }); 31790 31791 //fixed elements need to be moved out of the plugin container due to problems with CSS3. 31792 if(options.fixedElements && options.css3){ 31793 $(options.fixedElements).appendTo($body); 31794 } 31795 31796 //vertical centered of the navigation + active bullet 31797 if(options.navigation){ 31798 addVerticalNavigation(); 31799 } 31800 31801 enableYoutubeAPI(); 31802 31803 if(options.scrollOverflow){ 31804 if(document.readyState === 'complete'){ 31805 createScrollBarHandler(); 31806 } 31807 //after DOM and images are loaded 31808 $window.on('load', createScrollBarHandler); 31809 }else{ 31810 afterRenderActions(); 31811 } 31812 } 31813 31814 /** 31815 * Styles the horizontal slides for a section. 31816 */ 31817 function styleSlides(section, slides, numSlides){ 31818 var sliderWidth = numSlides * 100; 31819 var slideWidth = 100 / numSlides; 31820 31821 slides.wrapAll('<div class="' + SLIDES_CONTAINER + '" />'); 31822 slides.parent().wrap('<div class="' + SLIDES_WRAPPER + '" />'); 31823 31824 section.find(SLIDES_CONTAINER_SEL).css('width', sliderWidth + '%'); 31825 31826 if(numSlides > 1){ 31827 if(options.controlArrows){ 31828 createSlideArrows(section); 31829 } 31830 31831 if(options.slidesNavigation){ 31832 addSlidesNavigation(section, numSlides); 31833 } 31834 } 31835 31836 slides.each(function(index) { 31837 $(this).css('width', slideWidth + '%'); 31838 31839 if(options.verticalCentered){ 31840 addTableClass($(this)); 31841 } 31842 }); 31843 31844 var startingSlide = section.find(SLIDE_ACTIVE_SEL); 31845 31846 //if the slide won't be an starting point, the default will be the first one 31847 //the active section isn't the first one? Is not the first slide of the first section? Then we load that section/sl
31847ide by default. 31848 if( startingSlide.length && ($(SECTION_ACTIVE_SEL).index(SECTION_SEL) !== 0 || ($(SECTION_ACTIVE_SEL).index(SECTION_SEL) === 0 && startingSlide.index() !== 0))){ 31849 silentLandscapeScroll(startingSlide, 'internal'); 31850 }else{ 31851 slides.eq(0).addClass(ACTIVE); 31852 } 31853 } 31854 31855 /** 31856 * Styling vertical sections 31857 */ 31858 function styleSection(section, index){ 31859 //if no active section is defined, the 1st one will be the default one 31860 if(!index && $(SECTION_ACTIVE_SEL).length === 0) { 31861 section.addClass(ACTIVE); 31862 } 31863 startingSection = $(SECTION_ACTIVE_SEL); 31864 31865 section.css('height', windowsHeight + 'px'); 31866 31867 if(options.paddingTop){ 31868 section.css('padding-top', options.paddingTop); 31869 } 31870 31871 if(options.paddingBottom){ 31872 section.css('padding-bottom', options.paddingBottom); 31873 } 31874 31875 if (typeof options.sectionsColor[index] !== 'undefined') { 31876 section.css('background-color', options.sectionsColor[index]); 31877 } 31878 31879 if (typeof options.anchors[index] !== 'undefined') { 31880 section.attr('data-anchor', options.anchors[index]); 31881 } 31882 } 31883 31884 /** 31885 * Sets the data-anchor attributes to the menu elements and activates the current one. 31886 */ 31887 function styleMenu(section, index){ 31888 if (typeof options.anchors[index] !== 'undefined') { 31889 //activating the menu / nav element on load 31890 if(section.hasClass(ACTIVE)){ 31891 activateMenuAndNav(options.anchors[index], index); 31892 } 31893 } 31894 31895 //moving the menu outside the main container if it is inside (avoid problems with fixed positions when using CSS3 tranforms) 31896 if(options.menu && options.css3 && $(options.menu).closest(WRAPPER_SEL).length){ 31897 $(options.menu).appendTo($body); 31898 } 31899 } 31900 31901 /** 31902 * Adds internal classes to be able to provide customizable selectors 31903 * keeping the link with the style sheet. 31904 */ 31905 function addInternalSelectors(){ 31906 container.find(options.sectionSelector).addClass(SECTION); 31907 container.find(options.slideSelector).addClass(SLIDE); 31908 } 31909 31910 /** 31911 * Creates the control arrows for the given section 31912 */ 31913 function createSlideArrows(section){ 31914 section.find(SLIDES_WRAPPER_SEL).after('<div class="' + SLIDES_ARROW_PREV + '"></div><div class="' + SLIDES_ARROW_NEXT + '"></div>'); 31915 31916 if(options.controlArrowColor!='#fff'){ 31917 section.find(SLIDES_ARROW_NEXT_SEL).css('border-color', 'transparent transparent transparent '+options.controlArrowColor); 31918 section.find(SLIDES_ARROW_PREV_SEL).css('border-color', 'transparent '+ options.controlArrowColor + ' transparent transparent'); 31919 } 31920 31921 if(!options.loopHorizontal){ 31922 section.find(SLIDES_ARROW_PREV_SEL).hide(); 31923 } 31924 } 31925 31926 /** 31927 * Creates a vertical navigation bar. 31928 */ 31929 function addVerticalNavigation(){ 31930 $body.append('<div id="' + SECTION_NAV + '"><ul></ul></div>'); 31931 var nav = $(SECTION_NAV_SEL); 31932 31933 nav.addClass(function() { 31934 return options.showActiveTooltip ? SHOW_ACTIVE_TOOLTIP + ' ' + options.navigationPosition : options.navigationPosition; 31935 }); 31936 31937 for (var i = 0; i < $(SECTION_SEL).length; i++) { 31938 var link = ''; 31939 if (options.anchors.length) { 31940 link = options.anchors[i]; 31941 } 31942 31943 var li = '<li><a href="#' + link + '"><span></span></a>'; 31944 31945 // Only add tooltip if needed (defined by user) 31946 var tooltip = options.navigationTooltips[i]; 31947 31948 if (typeof tooltip !== 'undefined' && tooltip !== '') { 31949 li += '<div class="' + SECTION_NAV_TOOLTIP + ' ' + options.navigationPosition + '">' + tooltip + '</div>'; 31950 } 31951 31952 li += '</li>'; 31953 31954 nav.find('ul').append(li); 31955 } 31956 31957 //centering it vertically 31958 $(SECTION_NAV_SEL).css('margin-top', '-' + ($(SECTION_NAV_SEL).height()/2) + 'px'); 31959 31960 //activating the current active section 31961 $(SECTION_NAV_SEL).find('li').eq($(SECTION_ACTIVE_SEL).index(SECTION_SEL)).find('a').addClass(ACTIVE); 31962 } 31963 31964 /** 31965 * Creates the slim scroll scrollbar for the sections and slides inside them. 31966 */ 31967 function createScrollBarHandler(){ 31968 $(SECTION_SEL).each(function(){ 31969 var slides = $(this).find(SLIDE_SEL); 31970 31971 if(slides.length){ 31972 slides.each(function(){ 31973 createScrollBar($(this)); 31974 }); 31975 }else{ 31976 createScrollBar($(this)); 31977 } 31978 31979 }); 31980 afterRenderActions(); 31981 } 31982 31983 /*
31984 * Enables the Youtube videos API so we can control their flow if necessary. 31985 */ 31986 function enableYoutubeAPI(){ 31987 container.find('iframe[src*="youtube.com/embed/"]').each(function(){ 31988 addURLParam($(this), 'enablejsapi=1'); 31989 }); 31990 } 31991 31992 /** 31993 * Adds a new parameter and its value to the `src` of a given element 31994 */ 31995 function addURLParam(element, newParam){ 31996 var originalSrc = element.attr('src'); 31997 element.attr('src', originalSrc + getUrlParamSign(originalSrc) + newParam); 31998 } 31999 32000 /* 32001 * Returns the prefix sign to use for a new parameter in an existen URL. 32002 * 32003 * @return {String} ? | & 32004 */ 32005 function getUrlParamSign(url){ 32006 return ( !/\?/.test( url ) ) ? '?' : '&'; 32007 } 32008 32009 /** 32010 * Actions and callbacks to fire afterRender 32011 */ 32012 function afterRenderActions(){ 32013 var section = $(SECTION_ACTIVE_SEL); 32014 32015 section.addClass(COMPLETELY); 32016 32017 if(options.scrollOverflowHandler.afterRender){ 32018 options.scrollOverflowHandler.afterRender(section); 32019 } 32020 lazyLoad(section); 32021 playMedia(section); 32022 options.scrollOverflowHandler.afterLoad(); 32023 32024 if(isDestinyTheStartingSection()){ 32025 $.isFunction( options.afterLoad ) && options.afterLoad.call(section, section.data('anchor'), (section.index(SECTION_SEL) + 1)); 32026 } 32027 32028 // Uncode change 32029 // $.isFunction( options.afterRender ) && options.afterRender.call(container); 32030 $.isFunction( options.afterRender ) && options.afterRender.call(container, getTableHeight()); 32031 } 32032 32033 /** 32034 * Determines if the URL anchor destiny is the starting section (the one using 'active' class before initialization) 32035 */ 32036 function isDestinyTheStartingSection(){ 32037 var anchors = window.location.hash.replace('#', '').split('/'); 32038 var destinationSection = getSectionByAnchor(decodeURIComponent(anchors[0])); 32039 32040 return !destinationSection.length || destinationSection.length && destinationSection.index() === startingSection.index(); 32041 } 32042 32043 32044 var isScrolling = false; 32045 var lastScroll = 0; 32046 32047 //when scrolling... 32048 function scrollHandler(){ 32049 var currentSection; 32050 32051 if(!options.autoScrolling || options.scrollBar){ 32052 var currentScroll = $window.scrollTop(); 32053 var scrollDirection = getScrollDirection(currentScroll); 32054 var visibleSectionIndex = 0; 32055 var screen_mid = currentScroll + ($window.height() / 2.0); 32056 var isAtBottom = $body.height() - $window.height() === currentScroll; 32057 var sections = document.querySelectorAll(SECTION_SEL); 32058 32059 //when using `auto-height` for a small last section it won't be centered in the viewport 32060 if(isAtBottom){ 32061 visibleSectionIndex = sections.length - 1; 32062 } 32063 //is at top? when using `auto-height` for a small first section it won't be centered in the viewport 32064 else if(!currentScroll){ 32065 visibleSectionIndex = 0; 32066 } 32067 32068 //taking the section which is showing more content in the viewport 32069 else{ 32070 for (var i = 0; i < sections.length; ++i) { 32071 var section = sections[i]; 32072 32073 // Pick the the last section which passes the middle line of the screen. 32074 if (section.offsetTop <= screen_mid) 32075 { 32076 visibleSectionIndex = i; 32077 } 32078 } 32079 } 32080 32081 if(isCompletelyInViewPort(scrollDirection)){ 32082 if(!$(SECTION_ACTIVE_SEL).hasClass(COMPLETELY)){ 32083 $(SECTION_ACTIVE_SEL).addClass(COMPLETELY).siblings().removeClass(COMPLETELY); 32084 } 32085 } 32086 32087 //geting the last one, the current one on the screen 32088 currentSection = $(sections).eq(visibleSectionIndex); 32089 32090 //setting the visible section as active when manually scrolling 32091 //executing only once the first time we reach the section 32092 if(!currentSection.hasClass(ACTIVE)){ 32093 isScrolling = true; 32094 var leavingSection = $(SECTION_ACTIVE_SEL); 32095 var leavingSectionIndex = leavingSection.index(SECTION_SEL) + 1; 32096 var yMovement = getYmovement(currentSection); 32097 var anchorLink = currentSection.data('anchor'); 32098 var sectionIndex = currentSection.index(SECTION_SEL) + 1; 32099 var activeSlide = currentSection.find(SLIDE_ACTIVE_SEL); 32100 var slideIndex; 32101 var slideAnchorLink; 32102 32103 if(activeSlide.length){ 32104 slideAnchorLink = activeSlide.data('anchor'); 32105 slideIndex = activeSlide.index(); 32106 } 32107 32108 if(canScroll){ 32109 currentSection.addClass(ACTIVE).siblings().removeClass(ACTIVE); 32110 32111 $.isFunction( options.onLeave ) && options.onLeave.call( leavingSection, leavingSectionIndex, sectionIndex, yMovement); 32112 $.isFunction( options.afterLoad ) && options.afterLoad.call( currentSection, anchorLink, sectionIndex); 32113 32114 stopMedia(leavingSection); 32115 lazyLoad(currentSection); 32116 playMedia(currentSection); 32117 32118 activateMenuAndNav(anchorLink, sectionIndex - 1); 32119 32120 if(options.anchors.length){ 32121 //needed to enter in hashChange event when using the menu with anchor links 32122 lastScrolledDestiny = anchorLink; 32123 } 32124 setState(slideIndex, slideAnchorLink, anchorLink, sectionIndex); 32125 } 32126 32127 //small timeout in order to avoid entering in hashChange event when scrolling is not finished yet 32128 clearTimeout(scrollId); 32129 scrollId = setTimeout(function(){ 32130 isScrolling = false;
32131 }, 100); 32132 } 32133 32134 if(options.fitToSection){ 32135 //for the auto adjust of the viewport to fit a whole section 32136 clearTimeout(scrollId2); 32137 32138 scrollId2 = setTimeout(function(){ 32139 //checking it again in case it changed during the delay 32140 if(options.fitToSection){ 32141 fitToSection(); 32142 } 32143 }, options.fitToSectionDelay); 32144 } 32145 } 32146 } 32147 32148 /** 32149 * Fits the site to the nearest active section 32150 */ 32151 function fitToSection(){ 32152 //checking fitToSection again in case it was set to false before the timeout delay 32153 if(canScroll){ 32154 //allows to scroll to an active section and 32155 //if the section is already active, we prevent firing callbacks 32156 isResizing = true; 32157 32158 scrollPage($(SECTION_ACTIVE_SEL)); 32159 isResizing = false; 32160 } 32161 } 32162 32163 /** 32164 * Determines whether the active section has seen in its whole or not. 32165 */ 32166 function isCompletelyInViewPort(movement){ 32167 var top = $(SECTION_ACTIVE_SEL).position().top; 32168 var bottom = top + $window.height(); 32169 32170 if(movement == 'up'){ 32171 return bottom >= ($window.scrollTop() + $window.height()); 32172 } 32173 return top <= $window.scrollTop(); 32174 } 32175 32176 /** 32177 * Gets the directon of the the scrolling fired by the scroll event. 32178 */ 32179 function getScrollDirection(currentScroll){ 32180 var direction = currentScroll > lastScroll ? 'down' : 'up'; 32181 32182 lastScroll = currentScroll; 32183 32184 //needed for auto-height sections to determine if we want to scroll to the top or bottom of the destination 32185 previousDestTop = currentScroll; 32186 32187 return direction; 32188 } 32189 32190 /** 32191 * Determines the way of scrolling up or down: 32192 * by 'automatically' scrolling a section or by using the default and normal scrolling. 32193 */ 32194 function scrolling(type, scrollable){ 32195 if (!isScrollAllowed.m[type]){ 32196 return; 32197 } 32198 var check = (type === 'down') ? 'bottom' : 'top'; 32199 var scrollSection = (type === 'down') ? moveSectionDown : moveSectionUp; 32200 32201 if(scrollable.length > 0 ){ 32202 //is the scrollbar at the start/end of the scroll? 32203 if(options.scrollOverflowHandler.isScrolled(check, scrollable)){ 32204 scrollSection(); 32205 }else{ 32206 return true; 32207 } 32208 }else{ 32209 // moved up/down 32210 scrollSection(); 32211 } 32212 } 32213 32214 /* 32215 * Preventing bouncing in iOS #2285 32216 */ 32217 function preventBouncing(event){ 32218 var e = event.originalEvent; 32219 if(!checkParentForNormalScrollElement(event.target) && options.autoScrolling && isReallyTouch(e) && isScrollAllowed.m.up){ 32220 //preventing the easing on iOS devices 32221 event.preventDefault(); 32222 } 32223 } 32224 32225 var touchStartY = 0; 32226 var touchStartX = 0; 32227 var touchEndY = 0; 32228 var touchEndX = 0; 32229 32230 /* Detecting touch events 32231 32232 * As we are changing the top property of the page on scrolling, we can not use the traditional way to detect it. 32233 * This way, the touchstart and the touch moves shows an small difference between them which is the 32234 * used one to determine the direction. 32235 */ 32236 function touchMoveHandler(event){ 32237 var e = event.originalEvent; 32238 var activeSection = $(e.target).closest(SECTION_SEL); 32239 32240 // additional: if one of the normalScrollElements isn't within options.normalScrollElementTouchThreshold hops up the DOM chain 32241 if (!checkParentForNormalScrollElement(event.target) && isReallyTouch(e) ) { 32242 32243 if(options.autoScrolling){ 32244 //preventing the easing on iOS devices 32245 event.preventDefault(); 32246 } 32247 32248 var scrollable = options.scrollOverflowHandler.scrollable(activeSection); 32249 var touchEvents = getEventsPage(e); 32250 32251 touchEndY = touchEvents.y; 32252 touchEndX = touchEvents.x; 32253 32254 //if movement in the X axys is greater than in the Y and the currect section has slides... 32255 if (activeSection.find(SLIDES_WRAPPER_SEL).length && Math.abs(touchStartX - touchEndX) > (Math.abs(touchStartY - touchEndY))) { 32256 32257 //is the movement greater than the minimum resistance to scroll? 32258 if (!slideMoving && Math.abs(touchStartX - touchEndX) > ($window.outerWidth() / 100 * options.touchSensitivity)) { 32259 if (touchStartX > touchEndX) { 32260 if(isScrollAllowed.m.right){ 32261 moveSlideRight(activeSection); //next 32262 } 32263 } else { 32264 if(isScrollAllowed.m.left){ 32265 moveSlideLeft(activeSection); //prev 32266 } 32267 } 32268 } 32269 } 32270 32271 //vertical scrolling (only when autoScrolling is enabled) 32272 else if(options.autoScrolling && canScroll){ 32273 32274 //is the movement greater than the minimum resistance to scroll? 32275 if (Math.abs(touchStartY - touchEndY) > ($window.height() / 100 * options.touchSensitivity)) { 32276 if (touchStartY > touchEndY) { 32277 scrolling('down', scrollable); 32278 } else if (touchEndY > touchStartY) { 32279 scrolling('up', scrollable); 32280 } 32281 } 32282 } 32283 } 32284 } 32285 32286 /** 32287 * recursive function to loop up the parent nodes to check if one of them exists in options.normalScrollElements 32288 * Currently works well for iOS - Android might need some testing 32289 * @param {Element} el target element / jquery selector (in subsequent nodes) 32290 * @param {int} hop current hop compared to options.normalScrollElementTouchThreshold 32291 * @return {boolean} true if there is a match to options.normalScrollElements 32292 */ 32293 function checkParentForNormalScrollElement (el, hop) { 32294 hop = hop || 0; 32295 var parent = $(el).parent(); 32296 32297 if (hop < options.normalScrollElementTouchThreshold && 32298 parent.is(options.normalScrollElements) ) { 32299 return true; 32300 } else if (hop == options.normalScrollElementTouchThreshold) { 32301 return false;
32302 } else { 32303 return checkParentForNormalScrollElement(parent, ++hop); 32304 } 32305 } 32306 32307 /** 32308 * As IE >= 10 fires both touch and mouse events when using a mouse in a touchscreen 32309 * this way we make sure that is really a touch event what IE is detecting. 32310 */ 32311 function isReallyTouch(e){ 32312 //if is not IE || IE is detecting `touch` or `pen` 32313 return typeof e.pointerType === 'undefined' || e.pointerType != 'mouse'; 32314 } 32315 32316 /** 32317 * Handler for the touch start event. 32318 */ 32319 function touchStartHandler(event){ 32320 var e = event.originalEvent; 32321 32322 //stopping the auto scroll to adjust to a section 32323 if(options.fitToSection){ 32324 $htmlBody.stop(); 32325 } 32326 32327 if(isReallyTouch(e)){ 32328 var touchEvents = getEventsPage(e); 32329 touchStartY = touchEvents.y; 32330 touchStartX = touchEvents.x; 32331 } 32332 } 32333 32334 /** 32335 * Gets the average of the last `number` elements of the given array. 32336 */ 32337 function getAverage(elements, number){ 32338 var sum = 0; 32339 32340 //taking `number` elements from the end to make the average, if there are not enought, 1 32341 var lastElements = elements.slice(Math.max(elements.length - number, 1)); 32342 32343 for(var i = 0; i < lastElements.length; i++){ 32344 sum = sum + lastElements[i]; 32345 } 32346 32347 return Math.ceil(sum/number); 32348 } 32349 32350 /** 32351 * Detecting mousewheel scrolling 32352 * 32353 * http://blogs.sitepointstatic.com/examples/tech/mouse-wheel/index.html 32354 * http://www.sitepoint.com/html5-javascript-mouse-wheel/ 32355 */ 32356 var prevTime = new Date().getTime(); 32357 32358 function MouseWheelHandler(e) { 32359 var curTime = new Date().getTime(); 32360 var isNormalScroll = $(COMPLETELY_SEL).hasClass(NORMAL_SCROLL); 32361 32362 //autoscrolling and not zooming? 32363 if(options.autoScrolling && !controlPressed && !isNormalScroll){ 32364 // cross-browser wheel delta 32365 e = e || window.event; 32366 var value = e.wheelDelta || -e.deltaY || -e.detail; 32367 var delta = Math.max(-1, Math.min(1, value)); 32368 32369 var horizontalDetection = typeof e.wheelDeltaX !== 'undefined' || typeof e.deltaX !== 'undefined'; 32370 var isScrollingVertically = (Math.abs(e.wheelDeltaX) < Math.abs(e.wheelDelta)) || (Math.abs(e.deltaX ) < Math.abs(e.deltaY) || !horizontalDetection); 32371 32372 //Limiting the array to 150 (lets not waste memory!) 32373 if(scrollings.length > 149){ 32374 scrollings.shift(); 32375 } 32376 32377 //keeping record of the previous scrollings 32378 scrollings.push(Math.abs(value)); 32379 32380 //preventing to scroll the site on mouse wheel when scrollbar is present 32381 if(options.scrollBar){ 32382 e.preventDefault ? e.preventDefault() : e.returnValue = false; 32383 } 32384 32385 var activeSection = $(SECTION_ACTIVE_SEL); 32386 var scrollable = options.scrollOverflowHandler.scrollable(activeSection); 32387 32388 //time difference between the last scroll and the current one 32389 var timeDiff = curTime-prevTime; 32390 prevTime = curTime; 32391 32392 //haven't they scrolled in a while? 32393 //(enough to be consider a different scrolling action to scroll another section) 32394 if(timeDiff > 200){ 32395 //emptying the array, we dont care about old scrollings for our averages 32396 scrollings = []; 32397 } 32398 32399 if(canScroll){ 32400 var averageEnd = getAverage(scrollings, 10); 32401 var averageMiddle = getAverage(scrollings, 70); 32402 var isAccelerating = averageEnd >= averageMiddle; 32403 32404 //to avoid double swipes... 32405 if(isAccelerating && isScrollingVertically){ 32406 //scrolling down? 32407 if (delta < 0) { 32408 scrolling('down', scrollable); 32409 32410 //scrolling up? 32411 }else { 32412 scrolling('up', scrollable); 32413 } 32414 } 32415 } 32416 32417 return false;
32418 } 32419 32420 if(options.fitToSection){ 32421 //stopping the auto scroll to adjust to a section 32422 $htmlBody.stop(); 32423 } 32424 } 32425 32426 /** 32427 * Slides a slider to the given direction. 32428 * Optional `section` param. 32429 */ 32430 function moveSlide(direction, section){ 32431 var activeSection = typeof section === 'undefined' ? $(SECTION_ACTIVE_SEL) : section; 32432 var slides = activeSection.find(SLIDES_WRAPPER_SEL); 32433 var numSlides = slides.find(SLIDE_SEL).length; 32434 32435 // more than one slide needed and nothing should be sliding 32436 if (!slides.length || slideMoving || numSlides < 2) { 32437 return; 32438 } 32439 32440 var currentSlide = slides.find(SLIDE_ACTIVE_SEL); 32441 var destiny = null; 32442 32443 if(direction === 'left'){ 32444 destiny = currentSlide.prev(SLIDE_SEL); 32445 }else{ 32446 destiny = currentSlide.next(SLIDE_SEL); 32447 } 32448 32449 //isn't there a next slide in the secuence? 32450 if(!destiny.length){ 32451 //respect loopHorizontal settin 32452 if (!options.loopHorizontal) return; 32453 32454 if(direction === 'left'){ 32455 destiny = currentSlide.siblings(':last'); 32456 }else{ 32457 destiny = currentSlide.siblings(':first'); 32458 } 32459 } 32460 32461 slideMoving = true; 32462 32463 landscapeScroll(slides, destiny, direction); 32464 } 32465 32466 /** 32467 * Maintains the active slides in the viewport 32468 * (Because the `scroll` animation might get lost with some actions, such as when using continuousVertical) 32469 */ 32470 function keepSlidesPosition(){ 32471 $(SLIDE_ACTIVE_SEL).each(function(){ 32472 silentLandscapeScroll($(this), 'internal'); 32473 }); 32474 } 32475 32476 var previousDestTop = 0; 32477 /** 32478 * Returns the destination Y position based on the scrolling direction and 32479 * the height of the section. 32480 */ 32481 function getDestinationPosition(element){ 32482 var elemPosition = element.position(); 32483 32484 //top of the desination will be at the top of the viewport 32485 var position = elemPosition.top; 32486 var isScrollingDown = elemPosition.top > previousDestTop; 32487 var sectionBottom = position - windowsHeight + element.outerHeight(); 32488 var bigSectionsDestination = options.bigSectionsDestination; 32489 32490 //Uncode addition 32491 var containerH = container.outerHeight(); 32492 var containerPosition = container.offset(); 32493 32494 //########### Commented by Uncode - START ########### 32495 //is the destination element bigger than the viewport? 32496 // if(element.outerHeight() > windowsHeight){ 32497 // //scrolling up? 32498 // if(!isScrollingDown && !bigSectionsDestination || bigSectionsDestination === 'bottom' ){ 32499 // position = sectionBottom; 32500 // } 32501 // } 32502 32503 // //sections equal or smaller than the viewport height && scrolling down? || is resizing and its in the last section 32504 // else if(isScrollingDown || (isResizing && element.is(':last-child')) ){ 32505 // //The bottom of the destination will be at the bottom of the viewport 32506 // position = sectionBottom; 32507 // } 32508 //########### Commented by Uncode - END ########### 32509 32510 //Uncode addition 32511 if ( !$masthead.hasClass('menu-transparent') && $('body').hasClass('uncode-fp-menu-shrink') && !element.is(':first-child') ) 32512 position += 18; 32513 if ( ( containerH + menuHeight + bodyBorder + adminBarHeight - windowsHeight ) < position || ( isResizing && element.is(':last-child') ) ) { 32514 position = sectionBottom + menuHeight + bodyBorder*2 + adminBarHeight; 32515 } 32516 32517 /* 32518 Keeping record of the last scrolled position to determine the scrolling direction. 32519 No conventional methods can be used as the scroll bar might not be present 32520 AND the section might not be active if it is auto-height and didnt reach the middle 32521 of the viewport. 32522 */ 32523 previousDestTop = position; 32524 return position; 32525 } 32526 32527 /** 32528 * Scrolls the site to the given element and scrolls to the slide if a callback is given. 32529 */ 32530 function scrollPage(element, callback, isMovementUp){ 32531 if(typeof element === 'undefined'){ return; } //there's no element to scroll, leaving the function 32532 32533 var dtop = getDestinationPosition(element); 32534 var slideAnchorLink; 32535 var slideIndex; 32536 32537 //local variables 32538 var v = { 32539 element: element, 32540 callback: callback, 32541 isMovementUp: isMovementUp, 32542 dtop: dtop, 32543 yMovement: getYmovement(element), 32544 anchorLink: element.data('anchor'), 32545 sectionIndex: element.index(SECTION_SEL), 32546 activeSlide: element.find(SLIDE_ACTIVE_SEL), 32547 activeSection: $(SECTION_ACTIVE_SEL), 32548 leavingSection: $(SECTION_ACTIVE_SEL).index(SECTION_SEL) + 1, 32549 32550 //caching the value of isResizing at the momment the function is called 32551 //because it will be checked later inside a setTimeout and the value might change 32552 localIsResizing: isResizing 32553 }; 32554 32555 //quiting when destination scroll is the same as the current one 32556 if((v.activeSection.is(element) && !isResizing) || (options.scrollBar && $window.scrollTop() === v.dtop && !element.hasClass(AUTO_HEIGHT) )){ return; } 32557 32558 if(v.activeSlide.length){ 32559 slideAnchorLink = v.activeSlide.data('anchor'); 32560 slideIndex = v.activeSlide.index(); 32561 } 32562 32563 // If continuousVertical && we need to wrap around 32564 if (options.autoScrolling && options.continuousVertical && typeof (v.isMovementUp) !== "undefined" && 32565 ((!v.isMovementUp && v.yMovement == 'up') || // Intending to scroll down but about to go up or 32566 (v.isMovementUp && v.yMovement == 'down'))) { // intending to scroll up but about to go down 32567 32568 v = createInfiniteSections(v); 32569 } 32570 32571 //callback (onLeave) if the site is not just resizing and readjusting the slides 32572 if($.isFunction(options.onLeave) && !v.localIsResizing){ 32573 if(options.onLeave.call(v.activeSection, v.leavingSection, (v.sectionIndex + 1), v.yMovement) === false){ 32574 return; 32575 } 32576 } 32577 32578 //pausing media of the leaving section (if we are not just resizing, as destinatino will be the same one) 32579 if(!v.localIsResizing){ 32580 stopMedia(v.activeSection); 32581 } 32582 32583 options.scrollOverflowHandler.beforeLeave(); 32584 element.addClass(ACTIVE).siblings().removeClass(ACTIVE); 32585 lazyLoad(element); 32586 options.scrollOverflowHandler.onLeave(); 32587 32588 32589 //preventing from activating the MouseWheelHandler event 32590 //more than once if the page is scrolling 32591 canScroll = false;
32592 32593 setState(slideIndex, slideAnchorLink, v.anchorLink, v.sectionIndex); 32594 32595 performMovement(v); 32596 32597 //flag to avoid callingn `scrollPage()` twice in case of using anchor links 32598 lastScrolledDestiny = v.anchorLink; 32599 32600 //avoid firing it twice (as it does also on scroll) 32601 activateMenuAndNav(v.anchorLink, v.sectionIndex); 32602 } 32603 32604 /** 32605 * Performs the vertical movement (by CSS3 or by jQuery) 32606 */ 32607 function performMovement(v){ 32608 // using CSS3 translate functionality 32609 if (options.css3 && options.autoScrolling && !options.scrollBar) { 32610 32611 // The first section can have a negative value in iOS 10. Not quite sure why: -0.0142822265625 32612 // that's why we round it to 0. 32613 var translate3d = 'translate3d(0px, -' + Math.round(v.dtop) + 'px, 0px)'; 32614 transformContainer(translate3d, true); 32615 32616 //even when the scrollingSpeed is 0 there's a little delay, which might cause the 32617 //scrollingSpeed to change in case of using silentMoveTo(); 32618 if(options.scrollingSpeed){ 32619 clearTimeout(afterSectionLoadsId); 32620 afterSectionLoadsId = setTimeout(function () { 32621 afterSectionLoads(v); 32622 }, options.scrollingSpeed); 32623 }else{ 32624 afterSectionLoads(v); 32625 } 32626 } 32627 32628 // using jQuery animate 32629 else{ 32630 var scrollSettings = getScrollSettings(v); 32631 32632 $(scrollSettings.element).animate( 32633 scrollSettings.options, 32634 options.scrollingSpeed, options.easing).promise().done(function () { //only one single callback in case of animating `html, body` 32635 if(options.scrollBar){ 32636 32637 /* Hack! 32638 The timeout prevents setting the most dominant section in the viewport as "active" when the user 32639 scrolled to a smaller section by using the mousewheel (auto scrolling) rather than draging the scroll bar. 32640 32641 When using scrollBar:true It seems like the scroll events still getting propagated even after the scrolling animation has finished. 32642 */ 32643 setTimeout(function(){ 32644 afterSectionLoads(v); 32645 },30); 32646 }else{ 32647 afterSectionLoads(v); 32648 } 32649 }); 32650 } 32651 } 32652 32653 /** 32654 * Gets the scrolling settings depending on the plugin autoScrolling option 32655 */ 32656 function getScrollSettings(v){ 32657 var scroll = {}; 32658 32659 if(options.autoScrolling && !options.scrollBar){ 32660 scroll.options = { 'top': -v.dtop}; 32661 scroll.element = WRAPPER_SEL; 32662 }else{ 32663 scroll.options = { 'scrollTop': v.dtop}; 32664 scroll.element = 'html, body'; 32665 } 32666 32667 return scroll; 32668 } 32669 32670 /** 32671 * Adds sections before or after the current one to create the infinite effect. 32672 */ 32673 function createInfiniteSections(v){ 32674 // Scrolling down 32675 if (!v.isMovementUp) { 32676 // Move all previous sections to after the active section 32677 $(SECTION_ACTIVE_SEL).after(v.activeSection.prevAll(SECTION_SEL).get().reverse()); 32678 } 32679 else { // Scrolling up 32680 // Move all next sections to before the active section 32681 $(SECTION_ACTIVE_SEL).before(v.activeSection.nextAll(SECTION_SEL)); 32682 } 32683 32684 // Maintain the displayed position (now that we changed the element order) 32685 silentScroll($(SECTION_ACTIVE_SEL).position().top); 32686 32687 // Maintain the active slides visible in the viewport 32688 keepSlidesPosition(); 32689 32690 // save for later the elements that still need to be reordered 32691 v.wrapAroundElements = v.activeSection; 32692 32693 // Recalculate animation variables 32694 v.dtop = v.element.position().top; 32695 v.yMovement = getYmovement(v.element); 32696 32697 return v; 32698 } 32699 32700 /** 32701 * Fix section order after continuousVertical changes have been animated 32702 */ 32703 function continuousVerticalFixSectionOrder (v) {
32704 // If continuousVertical is in effect (and autoScrolling would also be in effect then), 32705 // finish moving the elements around so the direct navigation will function more simply 32706 if (!v.wrapAroundElements || !v.wrapAroundElements.length) { 32707 return; 32708 } 32709 32710 if (v.isMovementUp) { 32711 $(SECTION_FIRST_SEL).before(v.wrapAroundElements); 32712 } 32713 else { 32714 $(SECTION_LAST_SEL).after(v.wrapAroundElements); 32715 } 32716 32717 silentScroll($(SECTION_ACTIVE_SEL).position().top); 32718 32719 // Maintain the active slides visible in the viewport 32720 keepSlidesPosition(); 32721 } 32722 32723 32724 /** 32725 * Actions to do once the section is loaded. 32726 */ 32727 function afterSectionLoads (v){ 32728 continuousVerticalFixSectionOrder(v); 32729 32730 //callback (afterLoad) if the site is not just resizing and readjusting the slides 32731 $.isFunction(options.afterLoad) && !v.localIsResizing && options.afterLoad.call(v.element, v.anchorLink, (v.sectionIndex + 1)); 32732 options.scrollOverflowHandler.afterLoad(); 32733 32734 if(!v.localIsResizing){ 32735 playMedia(v.element); 32736 } 32737 32738 v.element.addClass(COMPLETELY).siblings().removeClass(COMPLETELY); 32739 32740 canScroll = true; 32741 32742 $.isFunction(v.callback) && v.callback.call(this); 32743 } 32744 32745 /** 32746 * Sets the value for the given attribute from the `data-` attribute with the same suffix 32747 * ie: data-srcset ==> srcset | data-src ==> src 32748 */ 32749 function setSrc(element, attribute){ 32750 element 32751 .attr(attribute, element.data(attribute)) 32752 .removeAttr('data-' + attribute); 32753 } 32754 32755 /** 32756 * Lazy loads image, video and audio elements. 32757 */ 32758 function lazyLoad(destiny){ 32759 if (!options.lazyLoading){ 32760 return; 32761 } 32762 32763 var panel = getSlideOrSection(destiny); 32764 var element; 32765 32766 panel.find('img[data-src], img[data-srcset], source[data-src], audio[data-src], iframe[data-src]').each(function(){ 32767 element = $(this); 32768 32769 $.each(['src', 'srcset'], function(index, type){ 32770 var attribute = element.attr('data-' + type); 32771 if(typeof attribute !== 'undefined' && attribute){ 32772 setSrc(element, type); 32773 } 32774 }); 32775 32776 if(element.is('source')){ 32777 element.closest('video').get(0).load(); 32778 } 32779 }); 32780 } 32781 32782 /** 32783 * Plays video and audio elements. 32784 */ 32785 function playMedia(destiny){ 32786 var panel = getSlideOrSection(destiny); 32787 32788 //playing HTML5 media elements 32789 panel.find('video, audio').each(function(){ 32790 var element = $(this).get(0); 32791 32792 if( element.hasAttribute('data-autoplay') && typeof element.play === 'function' ) { 32793 element.play(); 32794 } 32795 }); 32796 32797 //youtube videos 32798 panel.find('iframe[src*="youtube.com/embed/"]').each(function(){ 32799 var element = $(this).get(0); 32800 32801 if ( element.hasAttribute('data-autoplay') ){ 32802 playYoutube(element); 32803 } 32804 32805 //in case the URL was not loaded yet. On page load we need time for the new URL (with the API string) to load. 32806 element.onload = function() { 32807 if ( element.hasAttribute('data-autoplay') ){ 32808 playYoutube(element); 32809 } 32810 }; 32811 }); 32812 } 32813 32814 /** 32815 * Plays a youtube video 32816 */ 32817 function playYoutube(element){ 32818 element.contentWindow.postMessage('{"event":"command","func":"playVideo","args":""}', '*'); 32819 } 32820 32821 /** 32822 * Stops video and audio elements. 32823 */ 32824 function stopMedia(destiny){ 32825 var panel = getSlideOrSection(destiny); 32826 32827 //stopping HTML5 media elements 32828 panel.find('video, audio').each(function(){ 32829 var element = $(this).get(0); 32830 32831 if( !element.hasAttribute('data-keepplaying') && typeof element.pause === 'function' ) { 32832 element.pause(); 32833 } 32834 }); 32835 32836 //youtube videos 32837 panel.find('iframe[src*="youtube.com/embed/"]').each(function(){ 32838 var element = $(this).get(0); 32839 32840 if( /youtube\.com\/embed\//.test($(this).attr('src')) && !element.hasAttribute('data-keepplaying')){ 32841 $(this).get(0).contentWindow.postMessage('{"event":"command","func":"pauseVideo","args":""}','*'); 32842 } 32843 }); 32844 } 32845 32846 /** 32847 * Gets the active slide (or section) for the given section 32848 */ 32849 function getSlideOrSection(destiny){ 32850 var slide = destiny.find(SLIDE_ACTIVE_SEL); 32851 if( slide.length ) { 32852 destiny = $(slide); 32853 } 32854 32855 return destiny; 32856 } 32857 32858 /**
32859 * Scrolls to the anchor in the URL when loading the site 32860 */ 32861 function scrollToAnchor(){ 32862 //getting the anchor link in the URL and deleting the `#` 32863 var value = window.location.hash.replace('#', '').split('/'); 32864 var sectionAnchor = decodeURIComponent(value[0]); 32865 var slideAnchor = decodeURIComponent(value[1]); 32866 32867 if(sectionAnchor){ //if theres any # 32868 if(options.animateAnchor){ 32869 scrollPageAndSlide(sectionAnchor, slideAnchor); 32870 }else{ 32871 silentMoveTo(sectionAnchor, slideAnchor); 32872 } 32873 } 32874 } 32875 32876 /** 32877 * Detecting any change on the URL to scroll to the given anchor link 32878 * (a way to detect back history button as we play with the hashes on the URL) 32879 */ 32880 function hashChangeHandler(){ 32881 if(!isScrolling && !options.lockAnchors){ 32882 var value = window.location.hash.replace('#', '').split('/'); 32883 var sectionAnchor = decodeURIComponent(value[0]); 32884 var slideAnchor = decodeURIComponent(value[1]); 32885 32886 //when moving to a slide in the first section for the first time (first time to add an anchor to the URL) 32887 var isFirstSlideMove = (typeof lastScrolledDestiny === 'undefined'); 32888 var isFirstScrollMove = (typeof lastScrolledDestiny === 'undefined' && typeof slideAnchor === 'undefined' && !slideMoving); 32889 32890 32891 if(sectionAnchor.length){ 32892 /*in order to call scrollpage() only once for each destination at a time 32893 It is called twice for each scroll otherwise, as in case of using anchorlinks `hashChange` 32894 event is fired on every scroll too.*/ 32895 if ((sectionAnchor && sectionAnchor !== lastScrolledDestiny) && !isFirstSlideMove || isFirstScrollMove || (!slideMoving && lastScrolledSlide != slideAnchor )) { 32896 scrollPageAndSlide(sectionAnchor, slideAnchor); 32897 } 32898 } 32899 } 32900 } 32901 32902 //Sliding with arrow keys, both, vertical and horizontal 32903 function keydownHandler(e) { 32904 32905 clearTimeout(keydownId); 32906 32907 var activeElement = $(':focus'); 32908 32909 if(!activeElement.is('textarea') && !activeElement.is('input') && !activeElement.is('select') && 32910 activeElement.attr('contentEditable') !== "true" && activeElement.attr('contentEditable') !== '' && 32911 options.keyboardScrolling && options.autoScrolling){ 32912 var keyCode = e.which; 32913 32914 //preventing the scroll with arrow keys & spacebar & Page Up & Down keys 32915 var keyControls = [40, 38, 32, 33, 34]; 32916 if($.inArray(keyCode, keyControls) > -1){ 32917 e.preventDefault(); 32918 } 32919 32920 controlPressed = e.ctrlKey; 32921 32922 keydownId = setTimeout(function(){ 32923 onkeydown(e); 32924 },150); 32925 } 32926 } 32927 32928 function tooltipTextHandler(){ 32929 $(this).prev().trigger('click'); 32930 } 32931 32932 //to prevent scrolling while zooming 32933 function keyUpHandler(e){ 32934 if(isWindowFocused){ //the keyup gets fired on new tab ctrl + t in Firefox 32935 controlPressed = e.ctrlKey; 32936 } 32937 } 32938 32939 //binding the mousemove when the mouse's middle button is released 32940 function mouseDownHandler(e){ 32941 //middle button 32942 if (e.which == 2){ 32943 oldPageY = e.pageY; 32944 container.on('mousemove', mouseMoveHandler); 32945 } 32946 } 32947 32948 //unbinding the mousemove when the mouse's middle button is released 32949 function mouseUpHandler(e){ 32950 //middle button 32951 if (e.which == 2){ 32952 container.off('mousemove'); 32953 } 32954 } 32955 32956 //Scrolling horizontally when clicking on the slider controls. 32957 function slideArrowHandler(){ 32958 var section = $(this).closest(SECTION_SEL); 32959 32960 if ($(this).hasClass(SLIDES_PREV)) { 32961 if(isScrollAllowed.m.left){ 32962 moveSlideLeft(section); 32963 } 32964 } else { 32965 if(isScrollAllowed.m.right){ 32966 moveSlideRight(section); 32967 } 32968 } 32969 } 32970 32971 //when opening a new tab (ctrl + t), `control` won't be pressed when coming back. 32972 function blurHandler(){ 32973 isWindowFocused = false;
32974 controlPressed = false; 32975 } 32976 32977 //Scrolls to the section when clicking the navigation bullet 32978 function sectionBulletHandler(e){ 32979 e.preventDefault(); 32980 var index = $(this).parent().index(); 32981 scrollPage($(SECTION_SEL).eq(index)); 32982 } 32983 32984 //Scrolls the slider to the given slide destination for the given section 32985 function slideBulletHandler(e){ 32986 e.preventDefault(); 32987 var slides = $(this).closest(SECTION_SEL).find(SLIDES_WRAPPER_SEL); 32988 var destiny = slides.find(SLIDE_SEL).eq($(this).closest('li').index()); 32989 32990 landscapeScroll(slides, destiny); 32991 } 32992 32993 /** 32994 * Keydown event 32995 */ 32996 function onkeydown(e){ 32997 var shiftPressed = e.shiftKey; 32998 32999 //do nothing if we can not scroll or we are not using horizotnal key arrows. 33000 if(!canScroll && [37,39].indexOf(e.which) < 0){ 33001 return; 33002 } 33003 33004 switch (e.which) { 33005 //up 33006 case 38: 33007 case 33: 33008 if(isScrollAllowed.k.up){ 33009 moveSectionUp(); 33010 } 33011 break; 33012 33013 //down 33014 case 32: //spacebar 33015 if(shiftPressed && isScrollAllowed.k.up){ 33016 moveSectionUp(); 33017 break; 33018 } 33019 /* falls through */ 33020 case 40: 33021 case 34: 33022 if(isScrollAllowed.k.down){ 33023 moveSectionDown(); 33024 } 33025 break; 33026 33027 //Home 33028 case 36: 33029 if(isScrollAllowed.k.up){ 33030 moveTo(1); 33031 } 33032 break; 33033 33034 //End 33035 case 35: 33036 if(isScrollAllowed.k.down){ 33037 moveTo( $(SECTION_SEL).length ); 33038 } 33039 break; 33040 33041 //left 33042 case 37: 33043 if(isScrollAllowed.k.left){ 33044 moveSlideLeft(); 33045 } 33046 break; 33047 33048 //right 33049 case 39: 33050 if(isScrollAllowed.k.right){ 33051 moveSlideRight(); 33052 } 33053 break; 33054 33055 default: 33056 return; // exit this handler for other keys 33057 } 33058 } 33059 33060 /** 33061 * Detecting the direction of the mouse movement. 33062 * Used only for the middle button of the mouse. 33063 */ 33064 var oldPageY = 0; 33065 function mouseMoveHandler(e){ 33066 if(canScroll){ 33067 // moving up 33068 if (e.pageY < oldPageY && isScrollAllowed.m.up){ 33069 moveSectionUp(); 33070 } 33071 33072 // moving down 33073 else if(e.pageY > oldPageY && isScrollAllowed.m.down){ 33074 moveSectionDown(); 33075 } 33076 } 33077 oldPageY = e.pageY; 33078 } 33079 33080 /** 33081 * Scrolls horizontal sliders. 33082 */ 33083 function landscapeScroll(slides, destiny, direction){ 33084 var section = slides.closest(SECTION_SEL); 33085 var v = { 33086 slides: slides, 33087 destiny: destiny, 33088 direction: direction, 33089 destinyPos: destiny.position(), 33090 slideIndex: destiny.index(), 33091 section: section, 33092 sectionIndex: section.index(SECTION_SEL), 33093 anchorLink: section.data('anchor'), 33094 slidesNav: section.find(SLIDES_NAV_SEL), 33095 slideAnchor: getAnchor(destiny), 33096 prevSlide: section.find(SLIDE_ACTIVE_SEL), 33097 prevSlideIndex: section.find(SLIDE_ACTIVE_SEL).index(), 33098 33099 //caching the value of isResizing at the momment the function is called 33100 //because it will be checked later inside a setTimeout and the value might change 33101 localIsResizing: isResizing 33102 }; 33103 v.xMovement = getXmovement(v.prevSlideIndex, v.slideIndex); 33104 v.direction = v.direction ? v.direction : v.xMovement; 33105 33106 //important!! Only do it when not resizing 33107 if(!v.localIsResizing){ 33108 //preventing from scrolling to the next/prev section when using scrollHorizontally 33109 canScroll = false;
33110 } 33111 33112 if(options.onSlideLeave){ 33113 33114 //if the site is not just resizing and readjusting the slides 33115 if(!v.localIsResizing && v.xMovement!=='none'){ 33116 if($.isFunction( options.onSlideLeave )){ 33117 if(options.onSlideLeave.call( v.prevSlide, v.anchorLink, (v.sectionIndex + 1), v.prevSlideIndex, v.xMovement, v.slideIndex ) === false){ 33118 slideMoving = false; 33119 return; 33120 } 33121 } 33122 } 33123 } 33124 33125 destiny.addClass(ACTIVE).siblings().removeClass(ACTIVE); 33126 33127 if(!v.localIsResizing){ 33128 stopMedia(v.prevSlide); 33129 lazyLoad(destiny); 33130 } 33131 33132 if(!options.loopHorizontal && options.controlArrows){ 33133 //hidding it for the fist slide, showing for the rest 33134 section.find(SLIDES_ARROW_PREV_SEL).toggle(v.slideIndex!==0); 33135 33136 //hidding it for the last slide, showing for the rest 33137 section.find(SLIDES_ARROW_NEXT_SEL).toggle(!destiny.is(':last-child')); 33138 } 33139 33140 //only changing the URL if the slides are in the current section (not for resize re-adjusting) 33141 if(section.hasClass(ACTIVE) && !v.localIsResizing){ 33142 setState(v.slideIndex, v.slideAnchor, v.anchorLink, v.sectionIndex); 33143 } 33144 33145 performHorizontalMove(slides, v, true); 33146 } 33147 33148 33149 function afterSlideLoads(v){ 33150 activeSlidesNavigation(v.slidesNav, v.slideIndex); 33151 33152 //if the site is not just resizing and readjusting the slides 33153 if(!v.localIsResizing){ 33154 $.isFunction( options.afterSlideLoad ) && options.afterSlideLoad.call( v.destiny, v.anchorLink, (v.sectionIndex + 1), v.slideAnchor, v.slideIndex); 33155 33156 //needs to be inside the condition to prevent problems with continuousVertical and scrollHorizontally 33157 //and to prevent double scroll right after a windows resize 33158 canScroll = true; 33159 33160 playMedia(v.destiny); 33161 } 33162 33163 //letting them slide again 33164 slideMoving = false; 33165 } 33166 33167 /** 33168 * Performs the horizontal movement. (CSS3 or jQuery) 33169 * 33170 * @param fireCallback {Bool} - determines whether or not to fire the callback 33171 */ 33172 function performHorizontalMove(slides, v, fireCallback){ 33173 var destinyPos = v.destinyPos; 33174 33175 if(options.css3){ 33176 var translate3d = 'translate3d(-' + Math.round(destinyPos.left) + 'px, 0px, 0px)'; 33177 33178 addAnimation(slides.find(SLIDES_CONTAINER_SEL)).css(getTransforms(translate3d), v); 33179 33180 afterSlideLoadsId = setTimeout(function(){ 33181 fireCallback && afterSlideLoads(v); 33182 }, options.scrollingSpeed, options.easing); 33183 }else{ 33184 slides.animate({ 33185 scrollLeft : Math.round(destinyPos.left) 33186 }, options.scrollingSpeed, options.easing, function() { 33187 33188 fireCallback && afterSlideLoads(v); 33189 }); 33190 } 33191 } 33192 33193 /** 33194 * Sets the state for the horizontal bullet navigations. 33195 */ 33196 function activeSlidesNavigation(slidesNav, slideIndex){ 33197 slidesNav.find(ACTIVE_SEL).removeClass(ACTIVE); 33198 slidesNav.find('li').eq(slideIndex).find('a').addClass(ACTIVE); 33199 } 33200 33201 var previousHeight = windowsHeight; 33202 33203 //when resizing the site, we adjust the heights of the sections, slimScroll... 33204 function resizeHandler(){ 33205 //checking if it needs to get responsive 33206 responsive(); 33207 33208 // rebuild immediately on touch devices 33209 if (isTouchDevice) { 33210 var activeElement = $(document.activeElement); 33211 33212 //if the keyboard is NOT visible 33213 if (!activeElement.is('textarea') && !activeElement.is('input') && !activeElement.is('select')) { 33214 var currentHeight = $window.height(); 33215 33216 //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) 33217 if( Math.abs(currentHeight - previousHeight) > (20 * Math.max(previousHeight, currentHeight) / 100) ){ 33218 reBuild(true); 33219 previousHeight = currentHeight; 33220 } 33221 } 33222 }else{ 33223 //in order to call the functions only when the resize is finished 33224 //http://stackoverflow.com/questions/4298612/jquery-how-to-call-resize-event-only-once-its-finished-resizing 33225 clearTimeout(resizeId); 33226 33227 resizeId = setTimeout(function(){ 33228 reBuild(true); 33229 }, 350); 33230 } 33231 } 33232 33233 /** 33234 * Checks if the site needs to get responsive and disables autoScrolling if so. 33235 * A class `fp-responsive` is added to the plugin's container in case the user wants to use it for his own responsive CSS. 33236 */ 33237 function responsive(){ 33238 var widthLimit = options.responsive || options.responsiveWidth; //backwards compatiblity 33239 var heightLimit = options.responsiveHeight; 33240 33241 //only calculating what we need. Remember its called on the resize event. 33242 var isBreakingPointWidth = widthLimit && $window.outerWidth() < widthLimit; 33243 var isBreakingPointHeight = heightLimit && $window.height() < heightLimit; 33244 33245 if(widthLimit && heightLimit){ 33246 setResponsive(isBreakingPointWidth || isBreakingPointHeight); 33247 } 33248 else if(widthLimit){ 33249 setResponsive(isBreakingPointWidth); 33250 } 33251 else if(heightLimit){ 33252 setResponsive(isBreakingPointHeight); 33253 } 33254 } 33255 33256 /** 33257 * Adds transition animations for the given element 33258 */ 33259 function addAnimation(container, element){ 33260 var transition = 'all ' + options.scrollingSpeed + 'ms ' + options.easingcss3; 33261 33262 container.removeClass(NO_TRANSITION); 33263 return container.css({
33264 '-webkit-transition': transition, 33265 'transition': transition 33266 }); 33267 } 33268 33269 /** 33270 * Remove transition animations for the given element 33271 */ 33272 function removeAnimation(element){ 33273 return element.addClass(NO_TRANSITION); 33274 } 33275 33276 /** 33277 * Activating the vertical navigation bullets according to the given slide name. 33278 */ 33279 function activateNavDots(name, sectionIndex){ 33280 if(options.navigation){ 33281 $(SECTION_NAV_SEL).find(ACTIVE_SEL).removeClass(ACTIVE); 33282 if(name){ 33283 $(SECTION_NAV_SEL).find('a[href="#' + name + '"]').addClass(ACTIVE); 33284 }else{ 33285 $(SECTION_NAV_SEL).find('li').eq(sectionIndex).find('a').addClass(ACTIVE); 33286 } 33287 } 33288 } 33289 33290 /** 33291 * Activating the website main menu elements according to the given slide name. 33292 */ 33293 function activateMenuElement(name){ 33294 if(options.menu){ 33295 $(options.menu).find(ACTIVE_SEL).removeClass(ACTIVE); 33296 $(options.menu).find('[data-menuanchor="'+name+'"]').addClass(ACTIVE); 33297 } 33298 } 33299 33300 /** 33301 * Sets to active the current menu and vertical nav items. 33302 */ 33303 function activateMenuAndNav(anchor, index){ 33304 activateMenuElement(anchor); 33305 activateNavDots(anchor, index); 33306 } 33307 33308 /** 33309 * Retuns `up` or `down` depending on the scrolling movement to reach its destination 33310 * from the current section. 33311 */ 33312 function getYmovement(destiny){ 33313 var fromIndex = $(SECTION_ACTIVE_SEL).index(SECTION_SEL); 33314 var toIndex = destiny.index(SECTION_SEL); 33315 if( fromIndex == toIndex){ 33316 return 'none'; 33317 } 33318 if(fromIndex > toIndex){ 33319 return 'up'; 33320 } 33321 return 'down'; 33322 } 33323 33324 /** 33325 * Retuns `right` or `left` depending on the scrolling movement to reach its destination 33326 * from the current slide. 33327 */ 33328 function getXmovement(fromIndex, toIndex){ 33329 if( fromIndex == toIndex){ 33330 return 'none'; 33331 } 33332 if(fromIndex > toIndex){ 33333 return 'left'; 33334 } 33335 return 'right'; 33336 } 33337 33338 /** 33339 * Checks if the element needs scrollbar and if the user wants to apply it. 33340 * If so it creates it. 33341 * 33342 * @param {Object} element jQuery object of the section or slide 33343 */ 33344 function createScrollBar(element){ 33345 //User doesn't want scrollbar here? Sayonara baby! 33346 if(element.hasClass('fp-noscroll')) return; 33347 33348 //needed to make `scrollHeight` work under Opera 12 33349 element.css('overflow', 'hidden'); 33350 33351 var scrollOverflowHandler = options.scrollOverflowHandler; 33352 var wrap = scrollOverflowHandler.wrapContent(); 33353 //in case element is a slide 33354 var section = element.closest(SECTION_SEL); 33355 var scrollable = scrollOverflowHandler.scrollable(element); 33356 var contentHeight; 33357 33358 //if there was scroll, the contentHeight will be the one in the scrollable section 33359 if(scrollable.length){ 33360 contentHeight = scrollOverflowHandler.scrollHeight(element); 33361 }else{ 33362 contentHeight = element.get(0).scrollHeight; 33363 if(options.verticalCentered){ 33364 contentHeight = element.find(TABLE_CELL_SEL).get(0).scrollHeight; 33365 } 33366 } 33367 33368 var scrollHeight = windowsHeight - parseInt(section.css('padding-bottom')) - parseInt(section.css('padding-top')); 33369 33370 //needs scroll? 33371 if ( contentHeight > scrollHeight) { 33372 //did we already have an scrollbar ? Updating it 33373 if(scrollable.length){ 33374 scrollOverflowHandler.update(element, scrollHeight); 33375 } 33376 //creating the scrolling 33377 else{ 33378 if(options.verticalCentered){ 33379 element.find(TABLE_CELL_SEL).wrapInner(wrap); 33380 }else{ 33381 element.wrapInner(wrap); 33382 } 33383 scrollOverflowHandler.create(element, scrollHeight); 33384 } 33385 } 33386 //removing the scrolling when it is not necessary anymore 33387 else{ 33388 scrollOverflowHandler.remove(element); 33389 } 33390 33391 //undo 33392 element.css('overflow', ''); 33393 } 33394 33395 function addTableClass(element){ 33396 //In case we are styling for the 2nd time as in with reponsiveSlides 33397 if(!element.hasClass(TABLE)){ 33398 element.addClass(TABLE).wrapInner('<div class="' + TABLE_CELL + '" style="height:' + getTableHeight(element) + 'px;" />'); 33399 } 33400 } 33401 33402 function getTableHeight(element){ 33403 var sectionHeight = windowsHeight; 33404 33405 if(options.paddingTop || options.paddingBottom){ 33406 var section = element; 33407 if(!section.hasClass(SECTION)){ 33408 section = element.closest(SECTION_SEL); 33409 } 33410 33411 var paddings = parseInt(section.css('padding-top')) + parseInt(section.css('padding-bottom')); 33412 sectionHeight = (windowsHeight - paddings); 33413 } 33414 33415 return sectionHeight; 33416 } 33417 33418 /** 33419 * Adds a css3 transform property to the container class with or without animation depending on the animated param. 33420 */ 33421 function transformContainer(translate3d, animated){ 33422 if(animated){ 33423 addAnimation(container); 33424 }else{ 33425 removeAnimation(container); 33426 } 33427 33428 container.css(getTransforms(translate3d)); 33429 33430 //syncronously removing the class after the animation has been applied. 33431 setTimeout(function(){ 33432 container.removeClass(NO_TRANSITION); 33433 },10); 33434 } 33435 33436 /** 33437 * Gets a section by its anchor / index 33438 */ 33439 function getSectionByAnchor(sectionAnchor){ 33440 if(!sectionAnchor) return []; 33441 33442 var section = container.find(SECTION_SEL + '[data-anchor="'+sectionAnchor+'"]'); 33443 if(!section.length){ 33444 section = $(SECTION_SEL).eq( sectionAnchor -1); 33445 } 33446 33447 return section; 33448 } 33449 33450 /** 33451 * Gets a slide inside a given section by its anchor / index 33452 */ 33453 function getSlideByAnchor(slideAnchor, section){ 33454 var slides = section.find(SLIDES_WRAPPER_SEL); 33455 var slide = slides.find(SLIDE_SEL + '[data-anchor="'+slideAnchor+'"]'); 33456
33457 if(!slide.length){ 33458 slide = slides.find(SLIDE_SEL).eq(slideAnchor); 33459 } 33460 33461 return slide; 33462 } 33463 33464 /** 33465 * Scrolls to the given section and slide anchors 33466 */ 33467 function scrollPageAndSlide(destiny, slide){ 33468 var section = getSectionByAnchor(destiny); 33469 33470 //do nothing if there's no section with the given anchor name 33471 if(!section.length) return; 33472 33473 //default slide 33474 if (typeof slide === 'undefined') { 33475 slide = 0; 33476 } 33477 33478 //we need to scroll to the section and then to the slide 33479 if (destiny !== lastScrolledDestiny && !section.hasClass(ACTIVE)){ 33480 scrollPage(section, function(){ 33481 scrollSlider(section, slide); 33482 }); 33483 } 33484 //if we were already in the section 33485 else{ 33486 scrollSlider(section, slide); 33487 } 33488 } 33489 33490 /** 33491 * Scrolls the slider to the given slide destination for the given section 33492 */ 33493 function scrollSlider(section, slideAnchor){ 33494 if(typeof slideAnchor !== 'undefined'){ 33495 var slides = section.find(SLIDES_WRAPPER_SEL); 33496 var destiny = getSlideByAnchor(slideAnchor, section); 33497 33498 if(destiny.length){ 33499 landscapeScroll(slides, destiny); 33500 } 33501 } 33502 } 33503 33504 /** 33505 * Creates a landscape navigation bar with dots for horizontal sliders. 33506 */ 33507 function addSlidesNavigation(section, numSlides){ 33508 section.append('<div class="' + SLIDES_NAV + '"><ul></ul></div>'); 33509 var nav = section.find(SLIDES_NAV_SEL); 33510 33511 //top or bottom 33512 nav.addClass(options.slidesNavPosition); 33513 33514 for(var i=0; i< numSlides; i++){ 33515 nav.find('ul').append('<li><a href="#"><span></span></a></li>'); 33516 } 33517 33518 //centering it 33519 nav.css('margin-left', '-' + (nav.width()/2) + 'px'); 33520 33521 nav.find('li').first().find('a').addClass(ACTIVE); 33522 } 33523 33524 33525 /** 33526 * Sets the state of the website depending on the active section/slide. 33527 * It changes the URL hash when needed and updates the body class. 33528 */ 33529 function setState(slideIndex, slideAnchor, anchorLink, sectionIndex){ 33530 var sectionHash = ''; 33531 33532 if(options.anchors.length && !options.lockAnchors){ 33533 33534 //isn't it the first slide? 33535 if(slideIndex){ 33536 if(typeof anchorLink !== 'undefined'){ 33537 sectionHash = anchorLink; 33538 } 33539 33540 //slide without anchor link? We take the index instead. 33541 if(typeof slideAnchor === 'undefined'){ 33542 slideAnchor = slideIndex; 33543 } 33544 33545 lastScrolledSlide = slideAnchor; 33546 setUrlHash(sectionHash + '/' + slideAnchor); 33547 33548 //first slide won't have slide anchor, just the section one 33549 }else if(typeof slideIndex !== 'undefined'){ 33550 lastScrolledSlide = slideAnchor; 33551 setUrlHash(anchorLink); 33552 } 33553 33554 //section without slides 33555 else{ 33556 setUrlHash(anchorLink); 33557 } 33558 } 33559 33560 setBodyClass(); 33561 } 33562 33563 /** 33564 * Sets the URL hash. 33565 */ 33566 function setUrlHash(url){ 33567 //Uncode addition 33568 if ( typeof SiteParameters.slide_footer != 'undefined' && url == SiteParameters.slide_footer ) 33569 return false; 33570 33571 if(options.recordHistory){ 33572 location.hash = url; 33573 }else{ 33574 //Uncode addition 33575 //Mobile Chrome doesn't work the normal way, so... lets use HTML5 for phones :) 33576 // if(isTouchDevice || isTouch){ 33577 // window.history.replaceState(undefined, undefined, '#' + url); 33578 // }else{ 33579 // var baseUrl = window.location.href.split('#')[0]; 33580 // window.location.replace( baseUrl + '#' + url ); 33581 // } 33582 return false;
33583 } 33584 } 33585 33586 /** 33587 * Gets the anchor for the given slide / section. Its index will be used if there's none. 33588 */ 33589 function getAnchor(element){ 33590 var anchor = element.data('anchor'); 33591 var index = element.index(); 33592 33593 //Slide without anchor link? We take the index instead. 33594 if(typeof anchor === 'undefined'){ 33595 anchor = index; 33596 } 33597 33598 return anchor; 33599 } 33600 33601 /** 33602 * Sets a class for the body of the page depending on the active section / slide 33603 */ 33604 function setBodyClass(){ 33605 var section = $(SECTION_ACTIVE_SEL); 33606 var slide = section.find(SLIDE_ACTIVE_SEL); 33607 33608 var sectionAnchor = getAnchor(section); 33609 var slideAnchor = getAnchor(slide); 33610 33611 var text = String(sectionAnchor); 33612 33613 if(slide.length){ 33614 text = text + '-' + slideAnchor; 33615 } 33616 33617 //changing slash for dash to make it a valid CSS style 33618 text = text.replace('/', '-').replace('#',''); 33619 33620 //removing previous anchor classes 33621 var classRe = new RegExp('\\b\\s?' + VIEWING_PREFIX + '-[^\\s]+\\b', "g"); 33622 $body[0].className = $body[0].className.replace(classRe, ''); 33623 33624 //adding the current anchor 33625 $body.addClass(VIEWING_PREFIX + '-' + text); 33626 } 33627 33628 /** 33629 * Checks for translate3d support 33630 * @return boolean 33631 * http://stackoverflow.com/questions/5661671/detecting-transform-translate3d-support 33632 */ 33633 function support3d() { 33634 var el = document.createElement('p'), 33635 has3d, 33636 transforms = { 33637 'webkitTransform':'-webkit-transform', 33638 'OTransform':'-o-transform', 33639 'msTransform':'-ms-transform', 33640 'MozTransform':'-moz-transform', 33641 'transform':'transform' 33642 }; 33643 33644 // Add it to the body to get the computed style. 33645 document.body.insertBefore(el, null); 33646 33647 for (var t in transforms) { 33648 if (el.style[t] !== undefined) { 33649 el.style[t] = 'translate3d(1px,1px,1px)'; 33650 has3d = window.getComputedStyle(el).getPropertyValue(transforms[t]); 33651 } 33652 } 33653 33654 document.body.removeChild(el); 33655 33656 return (has3d !== undefined && has3d.length > 0 && has3d !== 'none'); 33657 } 33658 33659 /** 33660 * Removes the auto scrolling action fired by the mouse wheel and trackpad. 33661 * After this function is called, the mousewheel and trackpad movements won't scroll through sections. 33662 */ 33663 function removeMouseWheelHandler(){ 33664 if (document.addEventListener) { 33665 document.removeEventListener('mousewheel', MouseWheelHandler, false); //IE9, Chrome, Safari, Oper 33666 document.removeEventListener('wheel', MouseWheelHandler, false); //Firefox 33667 document.removeEventListener('MozMousePixelScroll', MouseWheelHandler, false); //old Firefox 33668 } else { 33669 document.detachEvent('onmousewheel', MouseWheelHandler); //IE 6/7/8 33670 } 33671 } 33672 33673 /** 33674 * Adds the auto scrolling action for the mouse wheel and trackpad. 33675 * After this function is called, the mousewheel and trackpad movements will scroll through sections 33676 * https://developer.mozilla.org/en-US/docs/Web/Events/wheel 33677 */ 33678 function addMouseWheelHandler(){ 33679 var prefix = ''; 33680 var _addEventListener; 33681 33682 if (window.addEventListener){ 33683 _addEventListener = "addEventListener"; 33684 }else{ 33685 _addEventListener = "attachEvent"; 33686 prefix = 'on'; 33687 } 33688 33689 // detect available wheel event 33690 var support = 'onwheel' in document.createElement('div') ? 'wheel' : // Modern browsers support "wheel" 33691 document.onmousewheel !== undefined ? 'mousewheel' : // Webkit and IE support at least "mousewheel" 33692 'DOMMouseScroll'; // let's assume that remaining browsers are older Firefox 33693 var passiveEvent = g_supportsPassive ? {passive: false }
33693: false; 33694 33695 33696 if(support == 'DOMMouseScroll'){ 33697 document[ _addEventListener ](prefix + 'MozMousePixelScroll', MouseWheelHandler, passiveEvent); 33698 } 33699 33700 //handle MozMousePixelScroll in older Firefox 33701 else{ 33702 document[ _addEventListener ](prefix + support, MouseWheelHandler, passiveEvent); 33703 } 33704 } 33705 33706 /** 33707 * Binding the mousemove when the mouse's middle button is pressed 33708 */ 33709 function addMiddleWheelHandler(){ 33710 container 33711 .on('mousedown', mouseDownHandler) 33712 .on('mouseup', mouseUpHandler); 33713 } 33714 33715 /** 33716 * Unbinding the mousemove when the mouse's middle button is released 33717 */ 33718 function removeMiddleWheelHandler(){ 33719 container 33720 .off('mousedown', mouseDownHandler) 33721 .off('mouseup', mouseUpHandler); 33722 } 33723 33724 /** 33725 * Adds the possibility to auto scroll through sections on touch devices. 33726 */ 33727 function addTouchHandler(){ 33728 if(isTouchDevice || isTouch){ 33729 if(options.autoScrolling){ 33730 $body.off(events.touchmove).on(events.touchmove, preventBouncing); 33731 } 33732 33733 $(WRAPPER_SEL) 33734 .off(events.touchstart).on(events.touchstart, touchStartHandler) 33735 .off(events.touchmove).on(events.touchmove, touchMoveHandler); 33736 } 33737 } 33738 33739 /** 33740 * Removes the auto scrolling for touch devices. 33741 */ 33742 function removeTouchHandler(){ 33743 if(isTouchDevice || isTouch){ 33744 $(WRAPPER_SEL) 33745 .off(events.touchstart) 33746 .off(events.touchmove); 33747 } 33748 } 33749 33750 /* 33751 * Returns and object with Microsoft pointers (for IE<11 and for IE >= 11) 33752 * http://msdn.microsoft.com/en-us/library/ie/dn304886(v=vs.85).aspx 33753 */ 33754 function getMSPointer(){ 33755 var pointer; 33756 33757 //IE >= 11 & rest of browsers 33758 if(window.PointerEvent){ 33759 pointer = { down: 'pointerdown', move: 'pointermove'}; 33760 } 33761 33762 //IE < 11 33763 else{ 33764 pointer = { down: 'MSPointerDown', move: 'MSPointerMove'}; 33765 } 33766 33767 return pointer; 33768 } 33769 33770 /** 33771 * Gets the pageX and pageY properties depending on the browser. 33772 * https://github.com/alvarotrigo/fullPage.js/issues/194#issuecomment-34069854 33773 */ 33774 function getEventsPage(e){ 33775 var events = []; 33776 33777 events.y = (typeof e.pageY !== 'undefined' && (e.pageY || e.pageX) ? e.pageY : e.touches[0].pageY); 33778 events.x = (typeof e.pageX !== 'undefined' && (e.pageY || e.pageX) ? e.pageX : e.touches[0].pageX); 33779 33780 //in touch devices with scrollBar:true, e.pageY is detected, but we have to deal with touch events. #1008 33781 if(isTouch && isReallyTouch(e) && options.scrollBar){ 33782 events.y = e.touches[0].pageY; 33783 events.x = e.touches[0].pageX; 33784 } 33785 33786 return events; 33787 } 33788 33789 /** 33790 * Slides silently (with no animation) the active slider to the given slide. 33791 * @param noCallback {bool} true or defined -> no callbacks 33792 */ 33793 function silentLandscapeScroll(activeSlide, noCallbacks){ 33794 setScrollingSpeed (0, 'internal'); 33795 33796 if(typeof noCallbacks !== 'undefined'){ 33797 //preventing firing callbacks afterSlideLoad etc. 33798 isResizing = true; 33799 } 33800 33801 landscapeScroll(activeSlide.closest(SLIDES_WRAPPER_SEL), activeSlide); 33802 33803 if(typeof noCallbacks !== 'undefined'){ 33804 isResizing = false; 33805 } 33806 33807 setScrollingSpeed(originals.scrollingSpeed, 'internal'); 33808 } 33809 33810 /** 33811 * Scrolls silently (with no animation) the page to the given Y position. 33812 */ 33813 function silentScroll(top){ 33814 // The first section can have a negative value in iOS 10. Not quite sure why: -0.0142822265625 33815 // that's why we round it to 0. 33816 var roundedTop = Math.round(top); 33817 33818 if (options.css3 && options.autoScrolling && !options.scrollBar){ 33819 var translate3d = 'translate3d(0px, -' + roundedTop + 'px, 0px)'; 33820 transformContainer(translate3d, false); 33821 } 33822 else if(options.autoScrolling && !options.scrollBar){ 33823 container.css('top', -roundedTop); 33824 } 33825 else{ 33826 $htmlBody.scrollTop(roundedTop); 33827 } 33828 } 33829 33830 /** 33831 * Returns the cross-browser transform string. 33832 */ 33833 function getTransforms(translate3d){ 33834 return {
33835 '-webkit-transform': translate3d, 33836 '-moz-transform': translate3d, 33837 '-ms-transform':translate3d, 33838 'transform': translate3d 33839 }; 33840 } 33841 33842 /** 33843 * Allowing or disallowing the mouse/swipe scroll in a given direction. (not for keyboard) 33844 * @type m (mouse) or k (keyboard) 33845 */ 33846 function setIsScrollAllowed(value, direction, type){ 33847 switch (direction){ 33848 case 'up': isScrollAllowed[type].up = value; break; 33849 case 'down': isScrollAllowed[type].down = value; break; 33850 case 'left': isScrollAllowed[type].left = value; break; 33851 case 'right': isScrollAllowed[type].right = value; break; 33852 case 'all': 33853 if(type == 'm'){ 33854 setAllowScrolling(value); 33855 }else{ 33856 setKeyboardScrolling(value); 33857 } 33858 } 33859 } 33860 33861 /* 33862 * Destroys fullpage.js plugin events and optinally its html markup and styles 33863 */ 33864 function destroy(all){ 33865 setAutoScrolling(false, 'internal'); 33866 setAllowScrolling(false); 33867 setKeyboardScrolling(false); 33868 container.addClass(DESTROYED); 33869 33870 clearTimeout(afterSlideLoadsId); 33871 clearTimeout(afterSectionLoadsId); 33872 clearTimeout(resizeId); 33873 clearTimeout(scrollId); 33874 clearTimeout(scrollId2); 33875 33876 $window 33877 .off('scroll', scrollHandler) 33878 .off('hashchange', hashChangeHandler) 33879 .off('resize', resizeHandler); 33880 33881 $document 33882 .off('click touchstart', SECTION_NAV_SEL + ' a') 33883 .off('mouseenter', SECTION_NAV_SEL + ' li') 33884 .off('mouseleave', SECTION_NAV_SEL + ' li') 33885 .off('click touchstart', SLIDES_NAV_LINK_SEL) 33886 .off('mouseover', options.normalScrollElements) 33887 .off('mouseout', options.normalScrollElements); 33888 33889 $(SECTION_SEL) 33890 .off('click touchstart', SLIDES_ARROW_SEL); 33891 33892 clearTimeout(afterSlideLoadsId); 33893 clearTimeout(afterSectionLoadsId); 33894 33895 //lets make a mess! 33896 if(all){ 33897 destroyStructure(); 33898 } 33899 } 33900 33901 /* 33902 * Removes inline styles added by fullpage.js 33903 */ 33904 function destroyStructure(){ 33905 //reseting the `top` or `translate` properties to 0 33906 silentScroll(0); 33907 33908 //loading all the lazy load content 33909 container.find('img[data-src], source[data-src], audio[data-src], iframe[data-src]').each(function(){ 33910 setSrc($(this), 'src'); 33911 }); 33912 33913 container.find('img[data-srcset]').each(function(){ 33914 setSrc($(this), 'srcset'); 33915 }); 33916 33917 $(SECTION_NAV_SEL + ', ' + SLIDES_NAV_SEL + ', ' + SLIDES_ARROW_SEL).remove(); 33918 33919 //removing inline styles 33920 $(SECTION_SEL).css( { 33921 'height': '', 33922 'background-color' : '', 33923 'padding': '' 33924 }); 33925 33926 $(SLIDE_SEL).css( { 33927 'width': '' 33928 }); 33929 33930 container.css({ 33931 'height': '', 33932 'position': '', 33933 '-ms-touch-action': '', 33934 'touch-action': '' 33935 }); 33936 33937 $htmlBody.css({ 33938 'overflow': '', 33939 'height': '' 33940 }); 33941 33942 // remove .fp-enabled class 33943 $('html').removeClass(ENABLED); 33944 33945 // remove .fp-responsive class 33946 $body.removeClass(RESPONSIVE); 33947 33948 // remove all of the .fp-viewing- classes 33949 $.each($body.get(0).className.split(/\s+/), function (index, className) { 33950 if (className.indexOf(VIEWING_PREFIX) === 0) { 33951 $body.removeClass(className); 33952 } 33953 }); 33954 33955 //removing added classes 33956 $(SECTION_SEL + ', ' + SLIDE_SEL).each(function(){ 33957 options.scrollOverflowHandler.remove($(this)); 33958 $(this).removeClass(TABLE + ' ' + ACTIVE); 33959 }); 33960 33961 removeAnimation(container); 33962 33963 //Unwrapping content 33964 container.find(TABLE_CELL_SEL + ', ' + SLIDES_CONTAINER_SEL + ', ' + SLIDES_WRAPPER_SEL).each(function(){ 33965 //unwrap not being use in case there's no child element inside and its just text 33966 $(this).replaceWith(this.childNodes); 33967 }); 33968 33969 //removing the applied transition from the fullpage wrapper 33970 container.css({
33971 '-webkit-transition': 'none', 33972 'transition': 'none' 33973 }); 33974 33975 //scrolling the page to the top with no animation 33976 $htmlBody.scrollTop(0); 33977 33978 //removing selectors 33979 var usedSelectors = [SECTION, SLIDE, SLIDES_CONTAINER]; 33980 $.each(usedSelectors, function(index, value){ 33981 $('.' + value).removeClass(value); 33982 }); 33983 } 33984 33985 /* 33986 * Sets the state for a variable with multiple states (original, and temporal) 33987 * Some variables such as `autoScrolling` or `recordHistory` might change automatically its state when using `responsive` or `autoScrolling:false`. 33988 * This function is used to keep track of both states, the original and the temporal one. 33989 * If type is not 'internal', then we assume the user is globally changing the variable. 33990 */ 33991 function setVariableState(variable, value, type){ 33992 options[variable] = value; 33993 if(type !== 'internal'){ 33994 originals[variable] = value; 33995 } 33996 } 33997 33998 /** 33999 * Displays warnings 34000 */ 34001 function displayWarnings(){ 34002 var extensions = ['fadingEffect', 'continuousHorizontal', 'scrollHorizontally', 'interlockedSlides', 'resetSliders', 'responsiveSlides', 'offsetSections', 'dragAndMove', 'scrollOverflowReset', 'parallax']; 34003 //UNCODE.addition 34004 // if($('html').hasClass(ENABLED)){ 34005 // showError('error', 'Fullpage.js can only be initialized once and you are doing it multiple times!'); 34006 // return; 34007 // } 34008 34009 // Disable mutually exclusive settings 34010 //UNCODE.addition 34011 // if (options.continuousVertical && 34012 // (options.loopTop || options.loopBottom)) { 34013 // options.continuousVertical = false;
34014 // showError('warn', 'Option `loopTop/loopBottom` is mutually exclusive with `continuousVertical`; `continuousVertical` disabled'); 34015 // } 34016 34017 // if(options.scrollBar && options.scrollOverflow){ 34018 // showError('warn', 'Option `scrollBar` is mutually exclusive with `scrollOverflow`. Sections with scrollOverflow might not work well in Firefox'); 34019 // } 34020 34021 // if(options.continuousVertical && (options.scrollBar || !options.autoScrolling)){ 34022 // options.continuousVertical = false; 34023 // showError('warn', 'Scroll bars (`scrollBar:true` or `autoScrolling:false`) are mutually exclusive with `continuousVertical`; `continuousVertical` disabled'); 34024 // } 34025 34026 //using extensions? Wrong file! 34027 $.each(extensions, function(index, extension){ 34028 //is the option set to true? 34029 if(options[extension]){ 34030 showError('warn', 'fullpage.js extensions require jquery.fullpage.extensions.min.js file instead of the usual jquery.fullpage.js. Requested: '+ extension); 34031 } 34032 }); 34033 34034 //anchors can not have the same value as any element ID or NAME 34035 $.each(options.anchors, function(index, name){ 34036 34037 //case insensitive selectors (http://stackoverflow.com/a/19465187/1081396) 34038 var nameAttr = $document.find('[name]').filter(function() { 34039 return $(this).attr('name') && $(this).attr('name').toLowerCase() == name.toLowerCase(); 34040 }); 34041 34042 var idAttr = $document.find('[id]').filter(function() { 34043 return $(this).attr('id') && $(this).attr('id').toLowerCase() == name.toLowerCase(); 34044 }); 34045 34046 if(idAttr.length || nameAttr.length ){ 34047 showError('error', 'data-anchor tags can not have the same value as any `id` element on the site (or `name` element for IE).'); 34048 idAttr.length && showError('error', '"' + name + '" is is being used by another element `id` property'); 34049 nameAttr.length && showError('error', '"' + name + '" is is being used by another element `name` property'); 34050 } 34051 }); 34052 } 34053 34054 /** 34055 * Shows a message in the console of the given type. 34056 */ 34057 function showError(type, text){ 34058 console && console[type] && console[type]('fullPage: ' + text); 34059 } 34060 34061 }; //end of $.fn.fullpage 34062 34063 if(typeof IScroll !== 'undefined'){ 34064 /* 34065 * Turns iScroll `mousewheel` option off dynamically 34066 * https://github.com/cubiq/iscroll/issues/1036 34067 */ 34068 IScroll.prototype.wheelOn = function () { 34069 this.wrapper.addEventListener('wheel', this); 34070 this.wrapper.addEventListener('mousewheel', this); 34071 this.wrapper.addEventListener('DOMMouseScroll', this); 34072 }; 34073 34074 /* 34075 * Turns iScroll `mousewheel` option on dynamically 34076 * https://github.com/cubiq/iscroll/issues/1036 34077 */ 34078 IScroll.prototype.wheelOff = function () { 34079 this.wrapper.removeEventListener('wheel', this); 34080 this.wrapper.removeEventListener('mousewheel', this); 34081 this.wrapper.removeEventListener('DOMMouseScroll', this); 34082 }; 34083 } 34084 34085 /** 34086 * An object to handle overflow scrolling. 34087 * This uses jquery.slimScroll to accomplish overflow scrolling. 34088 * It is possible to pass in an alternate scrollOverflowHandler 34089 * to the fullpage.js option that implements the same functions 34090 * as this handler. 34091 * 34092 * @type {Object} 34093 */ 34094 var iscrollHandler = { 34095 refreshId: null, 34096 iScrollInstances: [], 34097 34098 // Enables or disables the mouse wheel for the active section or all slides in it 34099 toggleWheel: function(value){ 34100 var scrollable = $(SECTION_ACTIVE_SEL).find(SCROLLABLE_SEL); 34101 scrollable.each(function(){ 34102 var iScrollInstance = $(this).data('iscrollInstance'); 34103 if(typeof iScrollInstance !== 'undefined' && iScrollInstance){ 34104 if(value){ 34105 iScrollInstance.wheelOn(); 34106 } 34107 else{ 34108 iScrollInstance.wheelOff(); 34109 } 34110 } 34111 }); 34112 }, 34113 34114 /** 34115 * Turns off iScroll for the destination section. 34116 * When scrolling very fast on some trackpads (and Apple laptops) the inertial scrolling would
34117 * scroll the destination section/slide before the sections animations ends. 34118 */ 34119 onLeave: function(){ 34120 iscrollHandler.toggleWheel(false); 34121 }, 34122 34123 // Turns off iScroll for the leaving section 34124 beforeLeave: function(){ 34125 iscrollHandler.onLeave() 34126 }, 34127 34128 // Turns on iScroll on section load 34129 afterLoad: function(){ 34130 iscrollHandler.toggleWheel(true); 34131 }, 34132 34133 /** 34134 * Called when overflow scrolling is needed for a section. 34135 * 34136 * @param {Object} element jQuery object containing current section 34137 * @param {Number} scrollHeight Current window height in pixels 34138 */ 34139 create: function(element, scrollHeight) { 34140 var scrollable = element.find(SCROLLABLE_SEL); 34141 34142 scrollable.height(scrollHeight); 34143 scrollable.each(function() { 34144 var $this = $(this); 34145 var iScrollInstance = $this.data('iscrollInstance'); 34146 if (iScrollInstance) { 34147 $.each(iscrollHandler.iScrollInstances, function(){ 34148 $(this).destroy(); 34149 }); 34150 } 34151 34152 iScrollInstance = new IScroll($this.get(0), iscrollOptions); 34153 iscrollHandler.iScrollInstances.push(iScrollInstance); 34154 34155 //off by default until the section gets active 34156 iScrollInstance.wheelOff(); 34157 34158 $this.data('iscrollInstance', iScrollInstance); 34159 }); 34160 }, 34161 34162 /** 34163 * Return a boolean depending on whether the scrollable element is a 34164 * the end or at the start of the scrolling depending on the given type. 34165 * 34166 * @param {String} type Either 'top' or 'bottom' 34167 * @param {Object} scrollable jQuery object for the scrollable element 34168 * @return {Boolean} 34169 */ 34170 isScrolled: function(type, scrollable) { 34171 var scroller = scrollable.data('iscrollInstance'); 34172 34173 //no scroller? 34174 if (!scroller) { 34175 return true; 34176 } 34177 34178 //Uncode addition 34179 var uncode_body_borders = parseFloat($('.body-borders').attr('data-border')) || 0; 34180 //End Uncode addition 34181 34182 if (type === 'top') { 34183 return scroller.y >= 0 && !scrollable.scrollTop(); 34184 } else if (type === 'bottom') { 34185 //Uncode change 34186 // return (0 - scroller.y) + scrollable.scrollTop() + 1 + scrollable.innerHeight() >= scrollable[0].scrollHeight; 34187 return (0 - scroller.y) + scrollable.scrollTop() + 1 + ( uncode_body_borders * 2 ) + scrollable.innerHeight() >= scrollable[0].scrollHeight; 34188 //End Uncode change 34189 } 34190 }, 34191 34192 /** 34193 * Returns the scrollable element for the given section. 34194 * If there are landscape slides, will only return a scrollable element 34195 * if it is in the active slide. 34196 * 34197 * @param {Object} activeSection jQuery object containing current section 34198 * @return {Boolean} 34199 */ 34200 scrollable: function(activeSection){ 34201 // if there are landscape slides, we check if the scrolling bar is in the current one or not 34202 if (activeSection.find(SLIDES_WRAPPER_SEL).length) { 34203 return activeSection.find(SLIDE_ACTIVE_SEL).find(SCROLLABLE_SEL); 34204 } 34205 return activeSection.find(SCROLLABLE_SEL); 34206 }, 34207 34208 /** 34209 * Returns the scroll height of the wrapped content. 34210 * If this is larger than the window height minus section padding, 34211 * overflow scrolling is needed. 34212 * 34213 * @param {Object} element jQuery object containing current section 34214 * @return {Number} 34215 */ 34216 scrollHeight: function(element) { 34217 return element.find(SCROLLABLE_SEL).children().first().get(0).scrollHeight; 34218 }, 34219 34220 /** 34221 * Called when overflow scrolling is no longer needed for a section. 34222 * 34223 * @param {Object}
34223 element jQuery object containing current section 34224 */ 34225 remove: function(element) { 34226 var scrollable = element.find(SCROLLABLE_SEL); 34227 if (scrollable.length) { 34228 var iScrollInstance = scrollable.data('iscrollInstance'); 34229 iScrollInstance.destroy(); 34230 34231 scrollable.data('iscrollInstance', null); 34232 } 34233 element.find(SCROLLABLE_SEL).children().first().children().first().unwrap().unwrap(); 34234 }, 34235 34236 /** 34237 * Called when overflow scrolling has already been setup but the 34238 * window height has potentially changed. 34239 * 34240 * @param {Object} element jQuery object containing current section 34241 * @param {Number} scrollHeight Current window height in pixels 34242 */ 34243 update: function(element, scrollHeight) { 34244 //using a timeout in order to execute the refresh function only once when `update` is called multiple times in a 34245 //short period of time. 34246 //it also comes on handy because iScroll requires the use of timeout when using `refresh`. 34247 clearTimeout(iscrollHandler.refreshId); 34248 iscrollHandler.refreshId = setTimeout(function(){ 34249 $.each(iscrollHandler.iScrollInstances, function(){ 34250 $(this).get(0).refresh(); 34251 }); 34252 }, 150); 34253 34254 //updating the wrappers height 34255 element.find(SCROLLABLE_SEL).css('height', scrollHeight + 'px').parent().css('height', scrollHeight + 'px'); 34256 }, 34257 34258 /** 34259 * Called to get any additional elements needed to wrap the section 34260 * content in order to facilitate overflow scrolling. 34261 * 34262 * @return {String|Object} Can be a string containing HTML, 34263 * a DOM element, or jQuery object. 34264 */ 34265 wrapContent: function() { 34266 return '<div class="' + SCROLLABLE + '"><div class="fp-scroller"></div></div>'; 34267 } 34268 }; 34269}); 34270 34271(function (global, factory) { 34272 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : 34273 typeof define === 'function' && define.amd ? define(['exports'], factory) : 34274 (global = global || self, factory(global.window = global.window || {})); 34275}(this, (function (exports) { 'use strict'; 34276 34277 /*! 34278 * ScrollTrigger 3.8.0 34279 * https://greensock.com 34280 * 34281 * @license Copyright 2008-2021, GreenSock. All rights reserved. 34282 * Subject to the terms at https://greensock.com/standard-license or for 34283 * Club GreenSock members, the agreement issued with that membership. 34284 * @author: Jack Doyle, [email protected] 34285 */ 34286 var gsap, 34287 _coreInitted, 34288 _win, 34289 _doc, 34290 _docEl, 34291 _body, 34292 _root, 34293 _resizeDelay, 34294 _raf, 34295 _request, 34296 _toArray, 34297 _clamp, 34298 _time2, 34299 _syncInterval, 34300 _refreshing, 34301 _pointerIsDown, 34302 _transformProp, 34303 _i, 34304 _prevWidth, 34305 _prevHeight, 34306 _autoRefresh, 34307 _sort, 34308 _suppressOverwrites, 34309 _ignoreResize, 34310 _limitCallbacks, 34311 _startup = 1, 34312 _proxies = [], 34313 _scrollers = [], 34314 _getTime = Date.now, 34315 _time1 = _getTime(), 34316 _lastScrollTime = 0, 34317 _enabled = 1, 34318 _passThrough = function _passThrough(v) { 34319 return v; 34320 }, 34321 _getTarget = function _getTarget(t) { 34322 return _toArray(t)[0] || (_isString(t) ? console.warn("Element not found:", t) : null); 34323 }, 34324 _round = function _round(value) { 34325 return Math.round(value * 100000) / 100000 || 0; 34326 }, 34327 _windowExists = function _windowExists() { 34328 return typeof window !== "undefined"; 34329 }, 34330 _getGSAP = function _getGSAP() { 34331 return gsap || _windowExists() && (gsap = window.gsap) && gsap.registerPlugin && gsap; 34332 }, 34333 _isViewport = function _isViewport(e) { 34334 return !!~_root.indexOf(e); 34335 }, 34336 _getProxyProp = function _getProxyProp(element, property) { 34337 return ~_proxies.indexOf(element) && _proxies[_proxies.indexOf(element) + 1][property]; 34338 }, 34339 _getScrollFunc = function _getScrollFunc(element, _ref) { 34340 var s = _ref.s, 34341 sc = _ref.sc; 34342 34343 var i = _scrollers.indexOf(element), 34344 offset = sc === _vertical.sc ? 1 : 2; 34345 34346 !~i && (i = _scrollers.push(element) - 1); 34347 return _scrollers[i + offset] || (_scrollers[i + offset] = _getProxyProp(element, s) || (_isViewport(element) ? sc : function (value) { 34348 return arguments.length ? element[s] = value : element[s]; 34349 })); 34350 }, 34351 _getBoundsFunc = function _getBoundsFunc(element) { 34352 return _getProxyProp(element, "getBoundingClientRect") || (_isViewport(element) ? function () { 34353 _winOffsets.width = _win.innerWidth; 34354 _winOffsets.height = _win.innerHeight; 34355 return _winOffsets; 34356 } : function () { 34357 return _getBounds(element); 34358 }); 34359 }, 34360 _getSizeFunc = function _getSizeFunc(scroller, isViewport, _ref2) { 34361 var d = _ref2.d, 34362 d2 = _ref2.d2, 34363 a = _ref2.a; 34364 return (a = _getProxyProp(scroller, "getBoundingClientRect")) ? function () { 34365 return a()[d]; 34366 } : function () { 34367 return (isViewport ? _win["inner" + d2] : scroller["client" + d2]) || 0; 34368 }; 34369 }, 34370 _getOffsetsFunc = function _getOffsetsFunc(element, isViewport) { 34371 return !isViewport || ~_proxies.indexOf(element) ? _getBoundsFunc(element) : function () { 34372 return _winOffsets; 34373 }; 34374 }, 34375 _maxScroll = function _maxScroll(element, _ref3) { 34376 var s = _ref3.s, 34377 d2 = _ref3.d2, 34378 d = _ref3.d, 34379 a = _ref3.a; 34380 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]; 34381 }, 34382 _iterateAutoRefresh = function _iterateAutoRefresh(func, events) { 34383 for (var i = 0; i < _autoRefresh.length; i += 3) {
vendor: 5,689 bytes, lines 34384-34588
34384 (!events || ~events.indexOf(_autoRefresh[i + 1])) && func(_autoRefresh[i], _autoRefresh[i + 1], _autoRefresh[i + 2]); 34385 } 34386 }, 34387 _isString = function _isString(value) { 34388 return typeof value === "string"; 34389 }, 34390 _isFunction = function _isFunction(value) { 34391 return typeof value === "function"; 34392 }, 34393 _isNumber = function _isNumber(value) { 34394 return typeof value === "number"; 34395 }, 34396 _isObject = function _isObject(value) { 34397 return typeof value === "object"; 34398 }, 34399 _callIfFunc = function _callIfFunc(value) { 34400 return _isFunction(value) && value(); 34401 }, 34402 _combineFunc = function _combineFunc(f1, f2) { 34403 return function () { 34404 var result1 = _callIfFunc(f1), 34405 result2 = _callIfFunc(f2); 34406 34407 return function () { 34408 _callIfFunc(result1); 34409 34410 _callIfFunc(result2); 34411 }; 34412 }; 34413 }, 34414 _endAnimation = function _endAnimation(animation, reversed, pause) { 34415 return animation && animation.progress(reversed ? 0 : 1) && pause && animation.pause(); 34416 }, 34417 _callback = function _callback(self, func) { 34418 var result = func(self); 34419 result && result.totalTime && (self.callbackAnimation = result); 34420 }, 34421 _abs = Math.abs, 34422 _scrollLeft = "scrollLeft", 34423 _scrollTop = "scrollTop", 34424 _left = "left", 34425 _top = "top", 34426 _right = "right", 34427 _bottom = "bottom", 34428 _width = "width", 34429 _height = "height", 34430 _Right = "Right", 34431 _Left = "Left", 34432 _Top = "Top", 34433 _Bottom = "Bottom", 34434 _padding = "padding", 34435 _margin = "margin", 34436 _Width = "Width", 34437 _Height = "Height", 34438 _px = "px", 34439 _horizontal = { 34440 s: _scrollLeft, 34441 p: _left, 34442 p2: _Left, 34443 os: _right, 34444 os2: _Right, 34445 d: _width, 34446 d2: _Width, 34447 a: "x", 34448 sc: function sc(value) { 34449 return arguments.length ? _win.scrollTo(value, _vertical.sc()) : _win.pageXOffset || _doc[_scrollLeft] || _docEl[_scrollLeft] || _body[_scrollLeft] || 0; 34450 } 34451 }, 34452 _vertical = { 34453 s: _scrollTop, 34454 p: _top, 34455 p2: _Top, 34456 os: _bottom, 34457 os2: _Bottom, 34458 d: _height, 34459 d2: _Height, 34460 a: "y", 34461 op: _horizontal, 34462 sc: function sc(value) { 34463 return arguments.length ? _win.scrollTo(_horizontal.sc(), value) : _win.pageYOffset || _doc[_scrollTop] || _docEl[_scrollTop] || _body[_scrollTop] || 0; 34464 } 34465 }, 34466 _getComputedStyle = function _getComputedStyle(element) { 34467 return _win.getComputedStyle(element); 34468 }, 34469 _makePositionable = function _makePositionable(element) { 34470 var position = _getComputedStyle(element).position; 34471 34472 element.style.position = position === "absolute" || position === "fixed" ? position : "relative"; 34473 }, 34474 _setDefaults = function _setDefaults(obj, defaults) { 34475 for (var p in defaults) { 34476 p in obj || (obj[p] = defaults[p]); 34477 } 34478 34479 return obj; 34480 }, 34481 _getBounds = function _getBounds(element, withoutTransforms) { 34482 var tween = withoutTransforms && _getComputedStyle(element)[_transformProp] !== "matrix(1, 0, 0, 1, 0, 0)" && gsap.to(element, { 34483 x: 0, 34484 y: 0, 34485 xPercent: 0, 34486 yPercent: 0, 34487 rotation: 0, 34488 rotationX: 0, 34489 rotationY: 0, 34490 scale: 1, 34491 skewX: 0, 34492 skewY: 0 34493 }).progress(1), 34494 bounds = element.getBoundingClientRect(); 34495 tween && tween.progress(0).kill(); 34496 return bounds; 34497 }, 34498 _getSize = function _getSize(element, _ref4) { 34499 var d2 = _ref4.d2; 34500 return element["offset" + d2] || element["client" + d2] || 0; 34501 }, 34502 _getLabelRatioArray = function _getLabelRatioArray(timeline) { 34503 var a = [], 34504 labels = timeline.labels, 34505 duration = timeline.duration(), 34506 p; 34507 34508 for (p in labels) { 34509 a.push(labels[p] / duration); 34510 } 34511 34512 return a; 34513 }, 34514 _getClosestLabel = function _getClosestLabel(animation) { 34515 return function (value) { 34516 return gsap.utils.snap(_getLabelRatioArray(animation), value); 34517 }; 34518 }, 34519 _snapDirectional = function _snapDirectional(snapIncrementOrArray) { 34520 var snap = gsap.utils.snap(snapIncrementOrArray), 34521 a = Array.isArray(snapIncrementOrArray) && snapIncrementOrArray.slice(0).sort(function (a, b) { 34522 return a - b; 34523 }); 34524 return a ? function (value, direction) { 34525 var i; 34526 34527 if (!direction) { 34528 return snap(value); 34529 } 34530 34531 if (direction > 0) { 34532 value -= 1e-4; 34533 34534 for (i = 0; i < a.length; i++) { 34535 if (a[i] >= value) { 34536 return a[i]; 34537 } 34538 } 34539 34540 return a[i - 1]; 34541 } else { 34542 i = a.length; 34543 value += 1e-4; 34544 34545 while (i--) { 34546 if (a[i] <= value) { 34547 return a[i]; 34548 } 34549 } 34550 } 34551 34552 return a[0]; 34553 } : function (value, direction) { 34554 var snapped = snap(value); 34555 return !direction || Math.abs(snapped - value) < 0.001 || snapped - value < 0 === direction < 0 ? snapped : snap(direction < 0 ? value - snapIncrementOrArray : value + snapIncrementOrArray); 34556 }; 34557 }, 34558 _getLabelAtDirection = function _getLabelAtDirection(timeline) { 34559 return function (value, st) { 34560 return _snapDirectional(_getLabelRatioArray(timeline))(value, st.direction); 34561 }; 34562 }, 34563 _multiListener = function _multiListener(func, element, types, callback) { 34564 return types.split(",").forEach(function (type) { 34565 return func(element, type, callback); 34566 }); 34567 }, 34568 _addListener = function _addListener(element, type, func) { 34569 return element.addEventListener(type, func, { 34570 passive: true 34571 }); 34572 }, 34573 _removeListener = function _removeListener(element, type, func) { 34574 return element.removeEventListener(type, func); 34575 }, 34576 _markerDefaults = { 34577 startColor: "green", 34578 endColor: "red", 34579 indent: 0, 34580 fontSize: "16px", 34581 fontWeight: "normal" 34582 }, 34583 _defaults = { 34584 toggleActions: "play", 34585 anticipatePin: 0 34586 }, 34587 _keywords = { 34588 top: 0,
34589 left: 0, 34590 center: 0.5, 34591 bottom: 1, 34592 right: 1 34593 }, 34594 _offsetToPx = function _offsetToPx(value, size) { 34595 if (_isString(value)) { 34596 var eqIndex = value.indexOf("="), 34597 relative = ~eqIndex ? +(value.charAt(eqIndex - 1) + 1) * parseFloat(value.substr(eqIndex + 1)) : 0; 34598 34599 if (~eqIndex) { 34600 value.indexOf("%") > eqIndex && (relative *= size / 100); 34601 value = value.substr(0, eqIndex - 1); 34602 } 34603 34604 value = relative + (value in _keywords ? _keywords[value] * size : ~value.indexOf("%") ? parseFloat(value) * size / 100 : parseFloat(value) || 0); 34605 } 34606 34607 return value; 34608 }, 34609 _createMarker = function _createMarker(type, name, container, direction, _ref5, offset, matchWidthEl, containerAnimation) { 34610 var startColor = _ref5.startColor, 34611 endColor = _ref5.endColor, 34612 fontSize = _ref5.fontSize, 34613 indent = _ref5.indent, 34614 fontWeight = _ref5.fontWeight; 34615 34616 var e = _doc.createElement("div"), 34617 useFixedPosition = _isViewport(container) || _getProxyProp(container, "pinType") === "fixed", 34618 isScroller = type.indexOf("scroller") !== -1, 34619 parent = useFixedPosition ? _body : container, 34620 isStart = type.indexOf("start") !== -1, 34621 color = isStart ? startColor : endColor, 34622 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;"; 34623 34624 css += "position:" + ((isScroller || containerAnimation) && useFixedPosition ? "fixed;" : "absolute;"); 34625 (isScroller || containerAnimation || !useFixedPosition) && (css += (direction === _vertical ? _right : _bottom) + ":" + (offset + parseFloat(indent)) + "px;"); 34626 matchWidthEl && (css += "box-sizing:border-box;text-align:left;width:" + matchWidthEl.offsetWidth + "px;"); 34627 e._isStart = isStart; 34628 e.setAttribute("class", "gsap-marker-" + type + (name ? " marker-" + name : "")); 34629 e.style.cssText = css; 34630 e.innerText = name || name === 0 ? type + "-" + name : type; 34631 parent.children[0] ? parent.insertBefore(e, parent.children[0]) : parent.appendChild(e); 34632 e._offset = e["offset" + direction.op.d2]; 34633 34634 _positionMarker(e, 0, direction, isStart); 34635 34636 return e; 34637 }, 34638 _positionMarker = function _positionMarker(marker, start, direction, flipped) { 34639 var vars = { 34640 display: "block" 34641 }, 34642 side = direction[flipped ? "os2" : "p2"], 34643 oppositeSide = direction[flipped ? "p2" : "os2"]; 34644 marker._isFlipped = flipped; 34645 vars[direction.a + "Percent"] = flipped ? -100 : 0; 34646 vars[direction.a] = flipped ? "1px" : 0; 34647 vars["border" + side + _Width] = 1; 34648 vars["border" + oppositeSide + _Width] = 0; 34649 vars[direction.p] = start + "px"; 34650 gsap.set(marker, vars); 34651 }, 34652 _triggers = [], 34653 _ids = {}, 34654 _sync = function _sync() { 34655 return _getTime() - _lastScrollTime > 20 && _updateAll(); 34656 }, 34657 _onScroll = function _onScroll() { 34658 var time = _getTime(); 34659 34660 if (_lastScrollTime !== time) { 34661 _updateAll(); 34662 34663 _lastScrollTime || _dispatch("scrollStart"); 34664 _lastScrollTime = time; 34665 } else if (!_request) { 34666 _request = _raf(_updateAll); 34667 } 34668 }, 34669 _onResize = function _onResize() { 34670 return !_refreshing && !_ignoreResize && !_doc.fullscreenElement && _resizeDelay.restart(true); 34671 }, 34672 _listeners = {}, 34673 _emptyArray = [], 34674 _media = [], 34675 _creatingMedia, 34676 _lastMediaTick, 34677 _onMediaChange = function _onMediaChange(e) { 34678 var tick = gsap.ticker.frame, 34679 matches = [], 34680 i = 0, 34681 index; 34682 34683 if (_lastMediaTick !== tick || _startup) { 34684 _revertAll(); 34685 34686 for (; i < _media.length; i += 4) { 34687 index = _win.matchMedia(_media[i]).matches; 34688 34689 if (index !== _media[i + 3]) { 34690 _media[i + 3] = index; 34691 index ? matches.push(i) : _revertAll(1, _media[i]) || _isFunction(_media[i + 2]) && _media[i + 2](); 34692 } 34693 } 34694 34695 _revertRecorded(); 34696 34697 for (i = 0; i < matches.length; i++) { 34698 index = matches[i]; 34699 _creatingMedia = _media[index]; 34700 _media[index + 2] = _media[index + 1](e); 34701 } 34702 34703 _creatingMedia = 0; 34704 _coreInitted && _refreshAll(0, 1); 34705 _lastMediaTick = tick; 34706 34707 _dispatch("matchMedia"); 34708 } 34709 }, 34710 _softRefresh = function _softRefresh() { 34711 return _removeListener(ScrollTrigger, "scrollEnd", _softRefresh) || _refreshAll(true); 34712 }, 34713 _dispatch = function _dispatch(type) { 34714 return _listeners[type] && _listeners[type].map(function (f) { 34715 return f(); 34716 }) || _emptyArray; 34717 }, 34718 _savedStyles = [], 34719 _revertRecorded = function _revertRecorded(media) { 34720 for (var i = 0; i < _savedStyles.length; i += 5) { 34721 if (!media || _savedStyles[i + 4] === media) { 34722 _savedStyles[i].style.cssText = _savedStyles[i + 1]; 34723 _savedStyles[i].getBBox && _savedStyles[i].setAttribute("transform", _savedStyles[i + 2] || ""); 34724 _savedStyles[i + 3].uncache = 1; 34725 } 34726 } 34727 }, 34728 _revertAll = function _revertAll(kill, media) { 34729 var trigger; 34730 34731 for (_i = 0; _i < _triggers.length; _i++) { 34732 trigger = _triggers[_i]; 34733 34734 if (!media || trigger.media === media) { 34735 if (kill) { 34736 trigger.kill(1); 34737 } else { 34738 trigger.revert(); 34739 } 34740 } 34741 } 34742 34743 media && _revertRecorded(media); 34744 media || _dispatch("revert"); 34745 }, 34746 _clearScrollMemory = function _clearScrollMemory() {
vendor: 10,266 bytes, lines 34747-35081
34747 return _scrollers.forEach(function (obj) { 34748 return typeof obj === "function" && (obj.rec = 0); 34749 }); 34750 }, 34751 _refreshingAll, 34752 _refreshAll = function _refreshAll(force, skipRevert) { 34753 if (_lastScrollTime && !force) { 34754 _addListener(ScrollTrigger, "scrollEnd", _softRefresh); 34755 34756 return; 34757 } 34758 34759 _refreshingAll = true; 34760 34761 var refreshInits = _dispatch("refreshInit"); 34762 34763 _sort && ScrollTrigger.sort(); 34764 skipRevert || _revertAll(); 34765 34766 _triggers.forEach(function (t) { 34767 return t.refresh(); 34768 }); 34769 34770 refreshInits.forEach(function (result) { 34771 return result && result.render && result.render(-1); 34772 }); 34773 34774 _clearScrollMemory(); 34775 34776 _resizeDelay.pause(); 34777 34778 _refreshingAll = false; 34779 34780 _dispatch("refresh"); 34781 }, 34782 _lastScroll = 0, 34783 _direction = 1, 34784 _updateAll = function _updateAll() { 34785 if (!_refreshingAll) { 34786 var l = _triggers.length, 34787 time = _getTime(), 34788 recordVelocity = time - _time1 >= 50, 34789 scroll = l && _triggers[0].scroll(); 34790 34791 _direction = _lastScroll > scroll ? -1 : 1; 34792 _lastScroll = scroll; 34793 34794 if (recordVelocity) { 34795 if (_lastScrollTime && !_pointerIsDown && time - _lastScrollTime > 200) { 34796 _lastScrollTime = 0; 34797 34798 _dispatch("scrollEnd"); 34799 } 34800 34801 _time2 = _time1; 34802 _time1 = time; 34803 } 34804 34805 if (_direction < 0) { 34806 _i = l; 34807 34808 while (_i-- > 0) { 34809 _triggers[_i] && _triggers[_i].update(0, recordVelocity); 34810 } 34811 34812 _direction = 1; 34813 } else { 34814 for (_i = 0; _i < l; _i++) { 34815 _triggers[_i] && _triggers[_i].update(0, recordVelocity); 34816 } 34817 } 34818 34819 _request = 0; 34820 } 34821 }, 34822 _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"], 34823 _stateProps = _propNamesToCopy.concat([_width, _height, "boxSizing", "max" + _Width, "max" + _Height, "position", _margin, _padding, _padding + _Top, _padding + _Right, _padding + _Bottom, _padding + _Left]), 34824 _swapPinOut = function _swapPinOut(pin, spacer, state) { 34825 _setState(state); 34826 34827 var cache = pin._gsap; 34828 34829 if (cache.spacerIsNative) { 34830 _setState(cache.spacerState); 34831 } else if (pin.parentNode === spacer) { 34832 var parent = spacer.parentNode; 34833 34834 if (parent) { 34835 parent.insertBefore(pin, spacer); 34836 parent.removeChild(spacer); 34837 } 34838 } 34839 }, 34840 _swapPinIn = function _swapPinIn(pin, spacer, cs, spacerState) { 34841 if (pin.parentNode !== spacer) { 34842 var i = _propNamesToCopy.length, 34843 spacerStyle = spacer.style, 34844 pinStyle = pin.style, 34845 p; 34846 34847 while (i--) { 34848 p = _propNamesToCopy[i]; 34849 spacerStyle[p] = cs[p]; 34850 } 34851 34852 spacerStyle.position = cs.position === "absolute" ? "absolute" : "relative"; 34853 cs.display === "inline" && (spacerStyle.display = "inline-block"); 34854 pinStyle[_bottom] = pinStyle[_right] = "auto"; 34855 spacerStyle.overflow = "visible"; 34856 spacerStyle.boxSizing = "border-box"; 34857 spacerStyle[_width] = _getSize(pin, _horizontal) + _px; 34858 spacerStyle[_height] = _getSize(pin, _vertical) + _px; 34859 spacerStyle[_padding] = pinStyle[_margin] = pinStyle[_top] = pinStyle[_left] = "0"; 34860 34861 _setState(spacerState); 34862 34863 pinStyle[_width] = pinStyle["max" + _Width] = cs[_width]; 34864 pinStyle[_height] = pinStyle["max" + _Height] = cs[_height]; 34865 pinStyle[_padding] = cs[_padding]; 34866 pin.parentNode.insertBefore(spacer, pin); 34867 spacer.appendChild(pin); 34868 } 34869 }, 34870 _capsExp = /([A-Z])/g, 34871 _setState = function _setState(state) { 34872 if (state) { 34873 var style = state.t.style, 34874 l = state.length, 34875 i = 0, 34876 p, 34877 value; 34878 (state.t._gsap || gsap.core.getCache(state.t)).uncache = 1; 34879 34880 for (; i < l; i += 2) { 34881 value = state[i + 1]; 34882 p = state[i]; 34883 34884 if (value) { 34885 style[p] = value; 34886 } else if (style[p]) { 34887 style.removeProperty(p.replace(_capsExp, "-$1").toLowerCase()); 34888 } 34889 } 34890 } 34891 }, 34892 _getState = function _getState(element) { 34893 var l = _stateProps.length, 34894 style = element.style, 34895 state = [], 34896 i = 0; 34897 34898 for (; i < l; i++) { 34899 state.push(_stateProps[i], style[_stateProps[i]]); 34900 } 34901 34902 state.t = element; 34903 return state; 34904 }, 34905 _copyState = function _copyState(state, override, omitOffsets) { 34906 var result = [], 34907 l = state.length, 34908 i = omitOffsets ? 8 : 0, 34909 p; 34910 34911 for (; i < l; i += 2) { 34912 p = state[i]; 34913 result.push(p, p in override ? override[p] : state[i + 1]); 34914 } 34915 34916 result.t = state.t; 34917 return result; 34918 }, 34919 _winOffsets = { 34920 left: 0, 34921 top: 0 34922 }, 34923 _parsePosition = function _parsePosition(value, trigger, scrollerSize, direction, scroll, marker, markerScroller, self, scrollerBounds, borderWidth, useFixedPosition, scrollerMax, containerAnimation) { 34924 _isFunction(value) && (value = value(self)); 34925 34926 if (_isString(value) && value.substr(0, 3) === "max") { 34927 value = scrollerMax + (value.charAt(4) === "=" ? _offsetToPx("0" + value.substr(3), scrollerSize) : 0); 34928 } 34929 34930 var time = containerAnimation ? containerAnimation.time() : 0, 34931 p1, 34932 p2, 34933 element; 34934 containerAnimation && containerAnimation.seek(0); 34935 34936 if (!_isNumber(value)) { 34937 _isFunction(trigger) && (trigger = trigger(self)); 34938 var offsets = value.split(" "), 34939 bounds, 34940 localOffset, 34941 globalOffset, 34942 display; 34943 element = _getTarget(trigger) || _body; 34944 bounds = _getBounds(element) || {}; 34945 34946 if ((!bounds || !bounds.left && !bounds.top) && _getComputedStyle(element).display === "none") { 34947 display = element.style.display; 34948 element.style.display = "block"; 34949 bounds = _getBounds(element); 34950 display ? element.style.display = display : element.style.removeProperty("display"); 34951 } 34952 34953 localOffset = _offsetToPx(offsets[0], bounds[direction.d]); 34954 globalOffset = _offsetToPx(offsets[1] || "0", scrollerSize); 34955 value = bounds[direction.p] - scrollerBounds[direction.p] - borderWidth + localOffset + scroll - globalOffset; 34956 markerScroller && _positionMarker(markerScroller, globalOffset, direction, scrollerSize - globalOffset < 20 || markerScroller._isStart && globalOffset > 20); 34957 scrollerSize -= scrollerSize - globalOffset; 34958 } else if (markerScroller) { 34959 _positionMarker(markerScroller, scrollerSize, direction, true); 34960 } 34961 34962 if (marker) { 34963 var position = value + scrollerSize, 34964 isStart = marker._isStart; 34965 p1 = "scroll" + direction.d2; 34966 34967 _positionMarker(marker, position, direction, isStart && position > 20 || !isStart && (useFixedPosition ? Math.max(_body[p1], _docEl[p1]) : marker.parentNode[p1]) <= position + 1); 34968 34969 if (useFixedPosition) { 34970 scrollerBounds = _getBounds(markerScroller); 34971 useFixedPosition && (marker.style[direction.op.p] = scrollerBounds[direction.op.p] - direction.op.m - marker._offset + _px); 34972 } 34973 } 34974 34975 if (containerAnimation && element) { 34976 p1 = _getBounds(element); 34977 containerAnimation.seek(scrollerMax); 34978 p2 = _getBounds(element); 34979 containerAnimation._caScrollDist = p1[direction.p] - p2[direction.p]; 34980 value = value / containerAnimation._caScrollDist * scrollerMax; 34981 } 34982 34983 containerAnimation && containerAnimation.seek(time); 34984 return containerAnimation ? value : Math.round(value); 34985 }, 34986 _prefixExp = /(?:webkit|moz|length|cssText|inset)/i, 34987 _reparent = function _reparent(element, parent, top, left) { 34988 if (element.parentNode !== parent) { 34989 var style = element.style, 34990 p, 34991 cs; 34992 34993 if (parent === _body) { 34994 element._stOrig = style.cssText; 34995 cs = _getComputedStyle(element); 34996 34997 for (p in cs) { 34998 if (!+p && !_prefixExp.test(p) && cs[p] && typeof style[p] === "string" && p !== "0") { 34999 style[p] = cs[p]; 35000 } 35001 } 35002 35003 style.top = top; 35004 style.left = left; 35005 } else { 35006 style.cssText = element._stOrig; 35007 } 35008 35009 gsap.core.getCache(element).uncache = 1; 35010 parent.appendChild(element); 35011 } 35012 }, 35013 _getTweenCreator = function _getTweenCreator(scroller, direction) { 35014 var getScroll = _getScrollFunc(scroller, direction), 35015 prop = "_scroll" + direction.p2, 35016 lastScroll1, 35017 lastScroll2, 35018 getTween = function getTween(scrollTo, vars, initialValue, change1, change2) { 35019 var tween = getTween.tween, 35020 onComplete = vars.onComplete, 35021 modifiers = {}; 35022 tween && tween.kill(); 35023 lastScroll1 = Math.round(initialValue); 35024 vars[prop] = scrollTo; 35025 vars.modifiers = modifiers; 35026 35027 modifiers[prop] = function (value) { 35028 value = _round(getScroll()); 35029 35030 if (value !== lastScroll1 && value !== lastScroll2 && Math.abs(value - lastScroll1) > 2) { 35031 tween.kill(); 35032 getTween.tween = 0; 35033 } else { 35034 value = initialValue + change1 * tween.ratio + change2 * tween.ratio * tween.ratio; 35035 } 35036 35037 lastScroll2 = lastScroll1; 35038 return lastScroll1 = _round(value); 35039 }; 35040 35041 vars.onComplete = function () { 35042 getTween.tween = 0; 35043 onComplete && onComplete.call(tween); 35044 }; 35045 35046 tween = getTween.tween = gsap.to(scroller, vars); 35047 return tween; 35048 }; 35049 35050 scroller[prop] = getScroll; 35051 scroller.addEventListener("wheel", function () { 35052 return getTween.tween && getTween.tween.kill() && (getTween.tween = 0); 35053 }, { 35054 passive: true 35055 }); 35056 return getTween; 35057 }; 35058 35059 _horizontal.op = _vertical; 35060 var ScrollTrigger = function () { 35061 function ScrollTrigger(vars, animation) { 35062 _coreInitted || ScrollTrigger.register(gsap) || console.warn("Please gsap.registerPlugin(ScrollTrigger)"); 35063 this.init(vars, animation); 35064 } 35065 35066 var _proto = ScrollTrigger.prototype; 35067 35068 _proto.init = function init(vars, animation) { 35069 this.progress = this.start = 0; 35070 this.vars && this.kill(1); 35071 35072 if (!_enabled) { 35073 this.update = this.refresh = this.kill = _passThrough; 35074 return; 35075 } 35076 35077 vars = _setDefaults(_isString(vars) || _isNumber(vars) || vars.nodeType ? { 35078 trigger: vars 35079 } : vars, _defaults); 35080 35081 var _vars = vars,
35082 onUpdate = _vars.onUpdate, 35083 toggleClass = _vars.toggleClass, 35084 id = _vars.id, 35085 onToggle = _vars.onToggle, 35086 onRefresh = _vars.onRefresh, 35087 scrub = _vars.scrub, 35088 trigger = _vars.trigger, 35089 pin = _vars.pin, 35090 pinSpacing = _vars.pinSpacing, 35091 invalidateOnRefresh = _vars.invalidateOnRefresh, 35092 anticipatePin = _vars.anticipatePin, 35093 onScrubComplete = _vars.onScrubComplete, 35094 onSnapComplete = _vars.onSnapComplete, 35095 once = _vars.once, 35096 snap = _vars.snap, 35097 pinReparent = _vars.pinReparent, 35098 pinSpacer = _vars.pinSpacer, 35099 containerAnimation = _vars.containerAnimation, 35100 fastScrollEnd = _vars.fastScrollEnd, 35101 preventOverlaps = _vars.preventOverlaps, 35102 direction = vars.horizontal || vars.containerAnimation && vars.horizontal !== false ? _horizontal : _vertical, 35103 isToggle = !scrub && scrub !== 0, 35104 scroller = _getTarget(vars.scroller || _win), 35105 scrollerCache = gsap.core.getCache(scroller), 35106 isViewport = _isViewport(scroller), 35107 useFixedPosition = ("pinType" in vars ? vars.pinType : _getProxyProp(scroller, "pinType") || isViewport && "fixed") === "fixed", 35108 callbacks = [vars.onEnter, vars.onLeave, vars.onEnterBack, vars.onLeaveBack], 35109 toggleActions = isToggle && vars.toggleActions.split(" "), 35110 markers = "markers" in vars ? vars.markers : _defaults.markers, 35111 borderWidth = isViewport ? 0 : parseFloat(_getComputedStyle(scroller)["border" + direction.p2 + _Width]) || 0, 35112 self = this, 35113 onRefreshInit = vars.onRefreshInit && function () { 35114 return vars.onRefreshInit(self); 35115 }, 35116 getScrollerSize = _getSizeFunc(scroller, isViewport, direction), 35117 getScrollerOffsets = _getOffsetsFunc(scroller, isViewport), 35118 lastSnap = 0, 35119 scrollFunc = _getScrollFunc(scroller, direction), 35120 tweenTo, 35121 pinCache, 35122 snapFunc, 35123 scroll1, 35124 scroll2, 35125 start, 35126 end, 35127 markerStart, 35128 markerEnd, 35129 markerStartTrigger, 35130 markerEndTrigger, 35131 markerVars, 35132 change, 35133 pinOriginalState, 35134 pinActiveState, 35135 pinState, 35136 spacer, 35137 offset, 35138 pinGetter, 35139 pinSetter, 35140 pinStart, 35141 pinChange, 35142 spacingStart, 35143 spacerState, 35144 markerStartSetter, 35145 markerEndSetter, 35146 cs, 35147 snap1, 35148 snap2, 35149 scrubTween, 35150 scrubSmooth, 35151 snapDurClamp, 35152 snapDelayedCall, 35153 prevProgress, 35154 prevScroll, 35155 prevAnimProgress, 35156 caMarkerSetter; 35157 35158 self.media = _creatingMedia; 35159 anticipatePin *= 45; 35160 self.scroller = scroller; 35161 self.scroll = containerAnimation ? containerAnimation.time.bind(containerAnimation) : scrollFunc; 35162 scroll1 = scrollFunc(); 35163 self.vars = vars; 35164 animation = animation || vars.animation; 35165 "refreshPriority" in vars && (_sort = 1); 35166 scrollerCache.tweenScroll = scrollerCache.tweenScroll || { 35167 top: _getTweenCreator(scroller, _vertical), 35168 left: _getTweenCreator(scroller, _horizontal) 35169 }; 35170 self.tweenTo = tweenTo = scrollerCache.tweenScroll[direction.p]; 35171 35172 if (animation) { 35173 animation.vars.lazy = false; 35174 animation._initted || animation.vars.immediateRender !== false && vars.immediateRender !== false && animation.render(0, true, true); 35175 self.animation = animation.pause(); 35176 animation.scrollTrigger = self; 35177 scrubSmooth = _isNumber(scrub) && scrub; 35178 scrubSmooth && (scrubTween = gsap.to(animation, { 35179 ease: "power3", 35180 duration: scrubSmooth, 35181 onComplete: function onComplete() { 35182 return onScrubComplete && onScrubComplete(self); 35183 } 35184 })); 35185 snap1 = 0; 35186 id || (id = animation.vars.id); 35187 } 35188 35189 _triggers.push(self); 35190 35191 if (snap) { 35192 if (!_isObject(snap) || snap.push) { 35193 snap = { 35194 snapTo: snap 35195 }; 35196 } 35197 35198 "scrollBehavior" in _body.style && gsap.set(isViewport ? [_body, _docEl] : scroller, { 35199 scrollBehavior: "auto" 35200 }); 35201 snapFunc = _isFunction(snap.snapTo) ? snap.snapTo : snap.snapTo === "labels" ? _getClosestLabel(animation) : snap.snapTo === "labelsDirectional" ? _getLabelAtDirection(animation) : snap.directional !== false ? function (value, st) { 35202 return _snapDirectional(snap.snapTo)(value, st.direction); 35203 } : gsap.utils.snap(snap.snapTo); 35204 snapDurClamp = snap.duration || { 35205 min: 0.1, 35206 max: 2 35207 }; 35208 snapDurClamp = _isObject(snapDurClamp) ? _clamp(snapDurClamp.min, snapDurClamp.max) : _clamp(snapDurClamp, snapDurClamp); 35209 snapDelayedCall = gsap.delayedCall(snap.delay || scrubSmooth / 2 || 0.1, function () { 35210 if (Math.abs(self.getVelocity()) < 10 && !_pointerIsDown && lastSnap !== scrollFunc()) { 35211 var totalProgress = animation && !isToggle ? animation.totalProgress() : self.progress, 35212 velocity = (totalProgress - snap2) / (_getTime() - _time2) * 1000 || 0, 35213 change1 = gsap.utils.clamp(-self.progress, 1 - self.progress, _abs(velocity / 2) * velocity / 0.185), 35214 naturalEnd = self.progress + (snap.inertia === false ? 0 : change1), 35215 endValue = _clamp(0, 1, snapFunc(naturalEnd, self)), 35216 scroll = scrollFunc(), 35217 endScroll = Math.round(start + endValue * change), 35218 _snap = snap, 35219 onStart = _snap.onStart, 35220 _onInterrupt = _snap.onInterrupt, 35221 _onComplete = _snap.onComplete, 35222 tween = tweenTo.tween; 35223 35224 if (scroll <= end && scroll >= start && endScroll !== scroll) { 35225 if (tween && !tween._initted && tween.data <= _abs(endScroll - scroll)) { 35226 return; 35227 } 35228 35229 if (snap.inertia === false) { 35230 change1 = endValue - self.progress; 35231 } 35232 35233 tweenTo(endScroll, { 35234 duration: snapDurClamp(_abs(Math.max(_abs(naturalEnd - totalProgress), _abs(endValue - totalProgress)) * 0.185 / velocity / 0.05 || 0)), 35235 ease: snap.ease || "power3", 35236 data: _abs(endScroll - scroll), 35237 onInterrupt: function onInterrupt() { 35238 return snapDelayedCall.restart(true) && _onInterrupt && _onInterrupt(self); 35239 }, 35240 onComplete: function onComplete() { 35241 lastSnap = scrollFunc(); 35242 snap1 = snap2 = animation && !isToggle ? animation.totalProgress() : self.progress; 35243 onSnapComplete && onSnapComplete(self); 35244 _onComplete && _onComplete(self); 35245 } 35246 }, scroll, change1 * change, endScroll - scroll - change1 * change); 35247 onStart && onStart(self, tweenTo.tween); 35248 } 35249 } else if (self.isActive) { 35250 snapDelayedCall.restart(true); 35251 } 35252 }).pause(); 35253 } 35254 35255 id && (_ids[id] = self); 35256 trigger = self.trigger = _getTarget(trigger || pin); 35257 pin = pin === true ? trigger : _getTarget(pin); 35258 _isString(toggleClass) && (toggleClass = { 35259 targets: trigger, 35260 className: toggleClass 35261 }); 35262 35263 if (pin) { 35264 pinSpacing === false || pinSpacing === _margin || (pinSpacing = !pinSpacing && _getComputedStyle(pin.parentNode).display === "flex" ? false : _padding); 35265 self.pin = pin; 35266 vars.force3D !== false && gsap.set(pin, {
35267 force3D: true 35268 }); 35269 pinCache = gsap.core.getCache(pin); 35270 35271 if (!pinCache.spacer) { 35272 if (pinSpacer) { 35273 pinSpacer = _getTarget(pinSpacer); 35274 pinSpacer && !pinSpacer.nodeType && (pinSpacer = pinSpacer.current || pinSpacer.nativeElement); 35275 pinCache.spacerIsNative = !!pinSpacer; 35276 pinSpacer && (pinCache.spacerState = _getState(pinSpacer)); 35277 } 35278 35279 pinCache.spacer = spacer = pinSpacer || _doc.createElement("div"); 35280 spacer.classList.add("pin-spacer"); 35281 id && spacer.classList.add("pin-spacer-" + id); 35282 pinCache.pinState = pinOriginalState = _getState(pin); 35283 } else { 35284 pinOriginalState = pinCache.pinState; 35285 } 35286 35287 self.spacer = spacer = pinCache.spacer; 35288 cs = _getComputedStyle(pin); 35289 spacingStart = cs[pinSpacing + direction.os2]; 35290 pinGetter = gsap.getProperty(pin); 35291 pinSetter = gsap.quickSetter(pin, direction.a, _px); 35292 35293 _swapPinIn(pin, spacer, cs); 35294 35295 pinState = _getState(pin); 35296 } 35297 35298 if (markers) { 35299 markerVars = _isObject(markers) ? _setDefaults(markers, _markerDefaults) : _markerDefaults; 35300 markerStartTrigger = _createMarker("scroller-start", id, scroller, direction, markerVars, 0); 35301 markerEndTrigger = _createMarker("scroller-end", id, scroller, direction, markerVars, 0, markerStartTrigger); 35302 offset = markerStartTrigger["offset" + direction.op.d2]; 35303 markerStart = _createMarker("start", id, scroller, direction, markerVars, offset, 0, containerAnimation); 35304 markerEnd = _createMarker("end", id, scroller, direction, markerVars, offset, 0, containerAnimation); 35305 containerAnimation && (caMarkerSetter = gsap.quickSetter([markerStart, markerEnd], direction.a, _px)); 35306 35307 if (!useFixedPosition && !(_proxies.length && _getProxyProp(scroller, "fixedMarkers") === true)) { 35308 _makePositionable(isViewport ? _body : scroller); 35309 35310 gsap.set([markerStartTrigger, markerEndTrigger], { 35311 force3D: true 35312 }); 35313 markerStartSetter = gsap.quickSetter(markerStartTrigger, direction.a, _px); 35314 markerEndSetter = gsap.quickSetter(markerEndTrigger, direction.a, _px); 35315 } 35316 } 35317 35318 if (containerAnimation) { 35319 var oldOnUpdate = containerAnimation.vars.onUpdate, 35320 oldParams = containerAnimation.vars.onUpdateParams; 35321 containerAnimation.eventCallback("onUpdate", function () { 35322 self.update(0, 0, 1); 35323 oldOnUpdate && oldOnUpdate.apply(oldParams || []); 35324 }); 35325 } 35326 35327 self.previous = function () { 35328 return _triggers[_triggers.indexOf(self) - 1]; 35329 }; 35330 35331 self.next = function () { 35332 return _triggers[_triggers.indexOf(self) + 1]; 35333 }; 35334 35335 self.revert = function (revert) { 35336 var r = revert !== false || !self.enabled, 35337 prevRefreshing = _refreshing; 35338 35339 if (r !== self.isReverted) { 35340 if (r) { 35341 self.scroll.rec || (self.scroll.rec = scrollFunc()); 35342 prevScroll = Math.max(scrollFunc(), self.scroll.rec || 0); 35343 prevProgress = self.progress; 35344 prevAnimProgress = animation && animation.progress(); 35345 } 35346 35347 markerStart && [markerStart, markerEnd, markerStartTrigger, markerEndTrigger].forEach(function (m) { 35348 return m.style.display = r ? "none" : "block"; 35349 }); 35350 r && (_refreshing = 1); 35351 self.update(r); 35352 _refreshing = prevRefreshing; 35353 pin && (r ? _swapPinOut(pin, spacer, pinOriginalState) : (!pinReparent || !self.isActive) && _swapPinIn(pin, spacer, _getComputedStyle(pin), spacerState)); 35354 self.isReverted = r; 35355 } 35356 }; 35357 35358 self.refresh = function (soft, force) { 35359 if ((_refreshing || !self.enabled) && !force) { 35360 return; 35361 } 35362 35363 if (pin && soft && _lastScrollTime) { 35364 _addListener(ScrollTrigger, "scrollEnd", _softRefresh); 35365 35366 return; 35367 } 35368 35369 _refreshing = 1; 35370 scrubTween && scrubTween.pause(); 35371 invalidateOnRefresh && animation && animation.progress(0).invalidate(); 35372 self.isReverted || self.revert(); 35373 35374 var size = getScrollerSize(), 35375 scrollerBounds = getScrollerOffsets(),
35376 max = containerAnimation ? containerAnimation.duration() : _maxScroll(scroller, direction), 35377 offset = 0, 35378 otherPinOffset = 0, 35379 parsedEnd = vars.end, 35380 parsedEndTrigger = vars.endTrigger || trigger, 35381 parsedStart = vars.start || (vars.start === 0 || !trigger ? 0 : pin ? "0 0" : "0 100%"), 35382 pinnedContainer = vars.pinnedContainer && _getTarget(vars.pinnedContainer), 35383 triggerIndex = trigger && Math.max(0, _triggers.indexOf(self)) || 0, 35384 i = triggerIndex, 35385 cs, 35386 bounds, 35387 scroll, 35388 isVertical, 35389 override, 35390 curTrigger, 35391 curPin, 35392 oppositeScroll, 35393 initted, 35394 revertedPins; 35395 35396 while (i--) { 35397 curTrigger = _triggers[i]; 35398 curTrigger.end || curTrigger.refresh(0, 1) || (_refreshing = 1); 35399 curPin = curTrigger.pin; 35400 35401 if (curPin && (curPin === trigger || curPin === pin) && !curTrigger.isReverted) { 35402 revertedPins || (revertedPins = []); 35403 revertedPins.unshift(curTrigger); 35404 curTrigger.revert(); 35405 } 35406 } 35407 35408 _isFunction(parsedStart) && (parsedStart = parsedStart(self)); 35409 start = _parsePosition(parsedStart, trigger, size, direction, scrollFunc(), markerStart, markerStartTrigger, self, scrollerBounds, borderWidth, useFixedPosition, max, containerAnimation) || (pin ? -0.001 : 0); 35410 _isFunction(parsedEnd) && (parsedEnd = parsedEnd(self)); 35411 35412 if (_isString(parsedEnd) && !parsedEnd.indexOf("+=")) { 35413 if (~parsedEnd.indexOf(" ")) { 35414 parsedEnd = (_isString(parsedStart) ? parsedStart.split(" ")[0] : "") + parsedEnd; 35415 } else { 35416 offset = _offsetToPx(parsedEnd.substr(2), size); 35417 parsedEnd = _isString(parsedStart) ? parsedStart : start + offset; 35418 parsedEndTrigger = trigger; 35419 } 35420 } 35421 35422 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; 35423 change = end - start || (start -= 0.01) && 0.001; 35424 offset = 0; 35425 i = triggerIndex; 35426 35427 while (i--) { 35428 curTrigger = _triggers[i]; 35429 curPin = curTrigger.pin; 35430 35431 if (curPin && curTrigger.start - curTrigger._pinPush < start && !containerAnimation) { 35432 cs = curTrigger.end - curTrigger.start; 35433 (curPin === trigger || curPin === pinnedContainer) && !_isNumber(parsedStart) && (offset += cs); 35434 curPin === pin && (otherPinOffset += cs); 35435 } 35436 } 35437 35438 start += offset; 35439 end += offset; 35440 self._pinPush = otherPinOffset; 35441 35442 if (markerStart && offset) { 35443 cs = {}; 35444 cs[direction.a] = "+=" + offset; 35445 pinnedContainer && (cs[direction.p] = "-=" + scrollFunc()); 35446 gsap.set([markerStart, markerEnd], cs); 35447 } 35448 35449 if (pin) { 35450 cs = _getComputedStyle(pin); 35451 isVertical = direction === _vertical; 35452 scroll = scrollFunc(); 35453 pinStart = parseFloat(pinGetter(direction.a)) + otherPinOffset; 35454 !max && end > 1 && ((isViewport ? _body : scroller).style["overflow-" + direction.a] = "scroll"); 35455 35456 _swapPinIn(pin, spacer, cs); 35457 35458 pinState = _getState(pin); 35459 bounds = _getBounds(pin, true); 35460 oppositeScroll = useFixedPosition && _getScrollFunc(scroller, isVertical ? _horizontal : _vertical)(); 35461 35462 if (pinSpacing) { 35463 spacerState = [pinSpacing + direction.os2, change + otherPinOffset + _px]; 35464 spacerState.t = spacer; 35465 i = pinSpacing === _padding ? _getSize(pin, direction) + change + otherPinOffset : 0; 35466 i && spacerState.push(direction.d, i + _px); 35467 35468 _setState(spacerState); 35469 35470 useFixedPosition && scrollFunc(prevScroll); 35471 } 35472 35473 if (useFixedPosition) { 35474 override = { 35475 top: bounds.top + (isVertical ? scroll - start : oppositeScroll) + _px, 35476 left: bounds.left + (isVertical ? oppositeScroll : scroll - start) + _px, 35477 boxSizing: "border-box", 35478 position: "fixed" 35479 }; 35480 override[_width] = override["max" + _Width] = Math.ceil(bounds.width) + _px; 35481 override[_height] = override["max" + _Height] = Math.ceil(bounds.height) + _px; 35482 override[_margin] = override[_margin + _Top] = override[_margin + _Right] = override[_margin + _Bottom] = override[_margin + _Left] = "0"; 35483 override[_padding] = cs[_padding]; 35484 override[_padding + _Top] = cs[_padding + _Top]; 35485 override[_padding + _Right] = cs[_padding + _Right]; 35486 override[_padding + _Bottom] = cs[_padding + _Bottom]; 35487 override[_padding + _Left] = cs[_padding + _Left]; 35488 pinActiveState = _copyState(pinOriginalState, override, pinReparent); 35489 } 35490 35491 if (animation) { 35492 initted = animation._initted; 35493 35494 _suppressOverwrites(1); 35495 35496 animation.render(animation.duration(), true, true); 35497 pinChange = pinGetter(direction.a) - pinStart + change + otherPinOffset; 35498 change !== pinChange && pinActiveState.splice(pinActiveState.length - 2, 2); 35499 animation.render(0, true, true); 35500 initted || animation.invalidate(); 35501 35502 _suppressOverwrites(0); 35503 } else { 35504 pinChange = change; 35505 } 35506 } else if (trigger && scrollFunc() && !containerAnimation) { 35507 bounds = trigger.parentNode; 35508 35509 while (bounds && bounds !== _body) { 35510 if (bounds._pinOffset) { 35511 start -= bounds._pinOffset; 35512 end -= bounds._pinOffset; 35513 } 35514 35515 bounds = bounds.parentNode; 35516 } 35517 } 35518 35519 revertedPins && revertedPins.forEach(function (t) { 35520 return t.revert(false); 35521 }); 35522 self.start = start; 35523 self.end = end; 35524 scroll1 = scroll2 = scrollFunc(); 35525 35526 if (!containerAnimation) { 35527 scroll1 < prevScroll && scrollFunc(prevScroll); 35528 self.scroll.rec = 0; 35529 } 35530 35531 self.revert(false); 35532 _refreshing = 0; 35533 animation && isToggle && animation._initted && animation.progress() !== prevAnimProgress && animation.progress(prevAnimProgress, true).render(animation.time(), true, true); 35534 35535 if (prevProgress !== self.progress) { 35536 animation && !isToggle && animation.totalProgress(prevProgress, true); 35537 self.progress = prevProgress; 35538 self.update(0, 0, 1); 35539 } 35540 35541 pin && pinSpacing && (spacer._pinOffset = Math.round(self.progress * pinChange)); 35542 onRefresh && onRefresh(self); 35543 }; 35544 35545 self.getVelocity = function () { 35546 return (scrollFunc() - scroll2) / (_getTime() - _time2) * 1000 || 0; 35547 }; 35548 35549 self.endAnimation = function () {
vendor: 8,601 bytes, lines 35550-35788
35550 _endAnimation(self.callbackAnimation); 35551 35552 if (animation) { 35553 scrubTween ? scrubTween.progress(1) : !animation.paused() ? _endAnimation(animation, animation.reversed()) : isToggle || _endAnimation(animation, self.direction < 0, 1); 35554 } 35555 }; 35556 35557 self.getTrailing = function (name) { 35558 var i = _triggers.indexOf(self), 35559 a = self.direction > 0 ? _triggers.slice(0, i).reverse() : _triggers.slice(i + 1); 35560 35561 return _isString(name) ? a.filter(function (t) { 35562 return t.vars.preventOverlaps === name; 35563 }) : a; 35564 }; 35565 35566 self.update = function (reset, recordVelocity, forceFake) { 35567 if (containerAnimation && !forceFake && !reset) { 35568 return; 35569 } 35570 35571 var scroll = self.scroll(), 35572 p = reset ? 0 : (scroll - start) / change, 35573 clipped = p < 0 ? 0 : p > 1 ? 1 : p || 0, 35574 prevProgress = self.progress, 35575 isActive, 35576 wasActive, 35577 toggleState, 35578 action, 35579 stateChanged, 35580 toggled, 35581 isAtMax, 35582 isTakingAction; 35583 35584 if (recordVelocity) { 35585 scroll2 = scroll1; 35586 scroll1 = containerAnimation ? scrollFunc() : scroll; 35587 35588 if (snap) { 35589 snap2 = snap1; 35590 snap1 = animation && !isToggle ? animation.totalProgress() : clipped; 35591 } 35592 } 35593 35594 anticipatePin && !clipped && pin && !_refreshing && !_startup && _lastScrollTime && start < scroll + (scroll - scroll2) / (_getTime() - _time2) * anticipatePin && (clipped = 0.0001); 35595 35596 if (clipped !== prevProgress && self.enabled) { 35597 isActive = self.isActive = !!clipped && clipped < 1; 35598 wasActive = !!prevProgress && prevProgress < 1; 35599 toggled = isActive !== wasActive; 35600 stateChanged = toggled || !!clipped !== !!prevProgress; 35601 self.direction = clipped > prevProgress ? 1 : -1; 35602 self.progress = clipped; 35603 35604 if (stateChanged && !_refreshing) { 35605 toggleState = clipped && !prevProgress ? 0 : clipped === 1 ? 1 : prevProgress === 1 ? 2 : 3; 35606 35607 if (isToggle) { 35608 action = !toggled && toggleActions[toggleState + 1] !== "none" && toggleActions[toggleState + 1] || toggleActions[toggleState]; 35609 isTakingAction = animation && (action === "complete" || action === "reset" || action in animation); 35610 } 35611 } 35612 35613 preventOverlaps && toggled && (isTakingAction || scrub || !animation) && (_isFunction(preventOverlaps) ? preventOverlaps(self) : self.getTrailing(preventOverlaps).forEach(function (t) { 35614 return t.endAnimation(); 35615 })); 35616 35617 if (!isToggle) { 35618 if (scrubTween && !_refreshing && !_startup) { 35619 scrubTween.vars.totalProgress = clipped; 35620 scrubTween.invalidate().restart(); 35621 } else if (animation) { 35622 animation.totalProgress(clipped, !!_refreshing); 35623 } 35624 } 35625 35626 if (pin) { 35627 reset && pinSpacing && (spacer.style[pinSpacing + direction.os2] = spacingStart); 35628 35629 if (!useFixedPosition) { 35630 pinSetter(pinStart + pinChange * clipped); 35631 } else if (stateChanged) { 35632 isAtMax = !reset && clipped > prevProgress && end + 1 > scroll && scroll + 1 >= _maxScroll(scroller, direction); 35633 35634 if (pinReparent) { 35635 if (!reset && (isActive || isAtMax)) { 35636 var bounds = _getBounds(pin, true), 35637 _offset = scroll - start; 35638 35639 _reparent(pin, _body, bounds.top + (direction === _vertical ? _offset : 0) + _px, bounds.left + (direction === _vertical ? 0 : _offset) + _px); 35640 } else { 35641 _reparent(pin, spacer); 35642 } 35643 } 35644 35645 _setState(isActive || isAtMax ? pinActiveState : pinState); 35646 35647 pinChange !== change && clipped < 1 && isActive || pinSetter(pinStart + (clipped === 1 && !isAtMax ? pinChange : 0)); 35648 } 35649 } 35650 35651 snap && !tweenTo.tween && !_refreshing && !_startup && snapDelayedCall.restart(true); 35652 toggleClass && (toggled || once && clipped && (clipped < 1 || !_limitCallbacks)) && _toArray(toggleClass.targets).forEach(function (el) { 35653 return el.classList[isActive || once ? "add" : "remove"](toggleClass.className); 35654 }); 35655 onUpdate && !isToggle && !reset && onUpdate(self); 35656 35657 if (stateChanged && !_refreshing) { 35658 if (isToggle) { 35659 if (isTakingAction) { 35660 if (action === "complete") { 35661 animation.pause().totalProgress(1); 35662 } else if (action === "reset") { 35663 animation.restart(true).pause(); 35664 } else if (action === "restart") { 35665 animation.restart(true); 35666 } else { 35667 animation[action](); 35668 } 35669 } 35670 35671 onUpdate && onUpdate(self); 35672 } 35673 35674 if (toggled || !_limitCallbacks) { 35675 onToggle && toggled && _callback(self, onToggle); 35676 callbacks[toggleState] && _callback(self, callbacks[toggleState]); 35677 once && (clipped === 1 ? self.kill(false, 1) : callbacks[toggleState] = 0); 35678 35679 if (!toggled) { 35680 toggleState = clipped === 1 ? 1 : 3; 35681 callbacks[toggleState] && _callback(self, callbacks[toggleState]); 35682 } 35683 } 35684 35685 if (fastScrollEnd && !isActive && Math.abs(self.getVelocity()) > (_isNumber(fastScrollEnd) ? fastScrollEnd : 2500)) { 35686 _endAnimation(self.callbackAnimation); 35687 35688 scrubTween ? scrubTween.progress(1) : _endAnimation(animation, !clipped, 1); 35689 } 35690 } else if (isToggle && onUpdate && !_refreshing) { 35691 onUpdate(self); 35692 } 35693 } 35694 35695 if (markerEndSetter) { 35696 var n = containerAnimation ? scroll / containerAnimation.duration() * (containerAnimation._caScrollDist || 0) : scroll; 35697 markerStartSetter(n + (markerStartTrigger._isFlipped ? 1 : 0)); 35698 markerEndSetter(n); 35699 } 35700 35701 caMarkerSetter && caMarkerSetter(-scroll / containerAnimation.duration() * (containerAnimation._caScrollDist || 0)); 35702 }; 35703 35704 self.enable = function (reset, refresh) { 35705 if (!self.enabled) { 35706 self.enabled = true; 35707 35708 _addListener(scroller, "resize", _onResize); 35709 35710 _addListener(scroller, "scroll", _onScroll); 35711 35712 onRefreshInit && _addListener(ScrollTrigger, "refreshInit", onRefreshInit); 35713 35714 if (reset !== false) { 35715 self.progress = prevProgress = 0; 35716 scroll1 = scroll2 = lastSnap = scrollFunc(); 35717 } 35718 35719 refresh !== false && self.refresh(); 35720 } 35721 }; 35722 35723 self.getTween = function (snap) { 35724 return snap && tweenTo ? tweenTo.tween : scrubTween; 35725 }; 35726 35727 self.disable = function (reset, allowAnimation) { 35728 if (self.enabled) { 35729 reset !== false && self.revert(); 35730 self.enabled = self.isActive = false; 35731 allowAnimation || scrubTween && scrubTween.pause(); 35732 prevScroll = 0; 35733 pinCache && (pinCache.uncache = 1); 35734 onRefreshInit && _removeListener(ScrollTrigger, "refreshInit", onRefreshInit); 35735 35736 if (snapDelayedCall) { 35737 snapDelayedCall.pause(); 35738 tweenTo.tween && tweenTo.tween.kill() && (tweenTo.tween = 0); 35739 } 35740 35741 if (!isViewport) { 35742 var i = _triggers.length; 35743 35744 while (i--) { 35745 if (_triggers[i].scroller === scroller && _triggers[i] !== self) { 35746 return; 35747 } 35748 } 35749 35750 _removeListener(scroller, "resize", _onResize); 35751 35752 _removeListener(scroller, "scroll", _onScroll); 35753 } 35754 } 35755 }; 35756 35757 self.kill = function (revert, allowAnimation) { 35758 self.disable(revert, allowAnimation); 35759 scrubTween && scrubTween.kill(); 35760 id && delete _ids[id]; 35761 35762 var i = _triggers.indexOf(self); 35763 35764 _triggers.splice(i, 1); 35765 35766 i === _i && _direction > 0 && _i--; 35767 i = 0; 35768 35769 _triggers.forEach(function (t) { 35770 return t.scroller === self.scroller && (i = 1); 35771 }); 35772 35773 i || (self.scroll.rec = 0); 35774 35775 if (animation) { 35776 animation.scrollTrigger = null; 35777 revert && animation.render(-1); 35778 allowAnimation || animation.kill(); 35779 } 35780 35781 markerStart && [markerStart, markerEnd, markerStartTrigger, markerEndTrigger].forEach(function (m) { 35782 return m.parentNode && m.parentNode.removeChild(m); 35783 }); 35784 35785 if (pin) { 35786 pinCache && (pinCache.uncache = 1); 35787 i = 0; 35788
35789 _triggers.forEach(function (t) { 35790 return t.pin === pin && i++; 35791 }); 35792 35793 i || (pinCache.spacer = 0); 35794 } 35795 }; 35796 35797 self.enable(false, false); 35798 !animation || !animation.add || change ? self.refresh() : gsap.delayedCall(0.01, function () { 35799 return start || end || self.refresh(); 35800 }) && (change = 0.01) && (start = end = 0); 35801 }; 35802 35803 ScrollTrigger.register = function register(core) { 35804 if (!_coreInitted) { 35805 gsap = core || _getGSAP(); 35806 35807 if (_windowExists() && window.document) { 35808 _win = window; 35809 _doc = document; 35810 _docEl = _doc.documentElement; 35811 _body = _doc.body; 35812 } 35813 35814 if (gsap) { 35815 _toArray = gsap.utils.toArray; 35816 _clamp = gsap.utils.clamp; 35817 _suppressOverwrites = gsap.core.suppressOverwrites || _passThrough; 35818 gsap.core.globals("ScrollTrigger", ScrollTrigger); 35819 35820 if (_body) { 35821 _raf = _win.requestAnimationFrame || function (f) { 35822 return setTimeout(f, 16); 35823 }; 35824 35825 _addListener(_win, "wheel", _onScroll); 35826 35827 _root = [_win, _doc, _docEl, _body]; 35828 35829 _addListener(_doc, "scroll", _onScroll); 35830 35831 var bodyStyle = _body.style, 35832 border = bodyStyle.borderTopStyle, 35833 bounds; 35834 bodyStyle.borderTopStyle = "solid"; 35835 bounds = _getBounds(_body); 35836 _vertical.m = Math.round(bounds.top + _vertical.sc()) || 0; 35837 _horizontal.m = Math.round(bounds.left + _horizontal.sc()) || 0; 35838 border ? bodyStyle.borderTopStyle = border : bodyStyle.removeProperty("border-top-style"); 35839 _syncInterval = setInterval(_sync, 200); 35840 gsap.delayedCall(0.5, function () { 35841 return _startup = 0; 35842 }); 35843 35844 _addListener(_doc, "touchcancel", _passThrough); 35845 35846 _addListener(_body, "touchstart", _passThrough); 35847 35848 _multiListener(_addListener, _doc, "pointerdown,touchstart,mousedown", function () { 35849 return _pointerIsDown = 1; 35850 }); 35851 35852 _multiListener(_addListener, _doc, "pointerup,touchend,mouseup", function () { 35853 return _pointerIsDown = 0; 35854 }); 35855 35856 _transformProp = gsap.utils.checkPrefix("transform"); 35857 35858 _stateProps.push(_transformProp); 35859 35860 _coreInitted = _getTime(); 35861 _resizeDelay = gsap.delayedCall(0.2, _refreshAll).pause(); 35862 _autoRefresh = [_doc, "visibilitychange", function () { 35863 var w = _win.innerWidth, 35864 h = _win.innerHeight; 35865 35866 if (_doc.hidden) { 35867 _prevWidth = w; 35868 _prevHeight = h; 35869 } else if (_prevWidth !== w || _prevHeight !== h) { 35870 _onResize(); 35871 } 35872 }, _doc, "DOMContentLoaded", _refreshAll, _win, "load", function () { 35873 return _lastScrollTime || _refreshAll(); 35874 }, _win, "resize", _onResize]; 35875 35876 _iterateAutoRefresh(_addListener); 35877 } 35878 } 35879 } 35880 35881 return _coreInitted; 35882 }; 35883 35884 ScrollTrigger.defaults = function defaults(config) { 35885 for (var p in config) { 35886 _defaults[p] = config[p]; 35887 } 35888 }; 35889 35890 ScrollTrigger.kill = function kill() { 35891 _enabled = 0; 35892 35893 _triggers.slice(0).forEach(function (trigger) { 35894 return trigger.kill(1); 35895 }); 35896 }; 35897 35898 ScrollTrigger.config = function config(vars) { 35899 "limitCallbacks" in vars && (_limitCallbacks = !!vars.limitCallbacks); 35900 var ms = vars.syncInterval; 35901 ms && clearInterval(_syncInterval) || (_syncInterval = ms) && setInterval(_sync, ms); 35902 35903 if ("autoRefreshEvents" in vars) { 35904 _iterateAutoRefresh(_removeListener) || _iterateAutoRefresh(_addListener, vars.autoRefreshEvents || "none"); 35905 _ignoreResize = (vars.autoRefreshEvents + "").indexOf("resize") === -1; 35906 } 35907 }; 35908 35909 ScrollTrigger.scrollerProxy = function scrollerProxy(target, vars) { 35910 var t = _getTarget(target), 35911 i = _scrollers.indexOf(t), 35912 isViewport = _isViewport(t); 35913 35914 if (~i) { 35915 _scrollers.splice(i, isViewport ? 6 : 2); 35916 } 35917 35918 isViewport ? _proxies.unshift(_win, vars, _body, vars, _docEl, vars) : _proxies.unshift(t, vars); 35919 }; 35920 35921 ScrollTrigger.matchMedia = function matchMedia(vars) { 35922 var mq, p, i, func, result; 35923 35924 for (p in vars) { 35925 i = _media.indexOf(p); 35926 func = vars[p]; 35927 _creatingMedia = p; 35928 35929 if (p === "all") { 35930 func(); 35931 } else { 35932 mq = _win.matchMedia(p); 35933 35934 if (mq) { 35935 mq.matches && (result = func()); 35936 35937 if (~i) { 35938 _media[i + 1] = _combineFunc(_media[i + 1], func); 35939 _media[i + 2] = _combineFunc(_media[i + 2], result); 35940 } else { 35941 i = _media.length; 35942 35943 _media.push(p, func, result); 35944 35945 mq.addListener ? mq.addListener(_onMediaChange) : mq.addEventListener("change", _onMediaChange); 35946 } 35947 35948 _media[i + 3] = mq.matches; 35949 } 35950 } 35951 35952 _creatingMedia = 0; 35953 } 35954 35955 return _media; 35956 }; 35957 35958 ScrollTrigger.clearMatchMedia = function clearMatchMedia(query) { 35959 query || (_media.length = 0); 35960 query = _media.indexOf(query); 35961 query >= 0 && _media.splice(query, 4); 35962 }; 35963 35964 ScrollTrigger.isInViewport = function isInViewport(element, ratio, horizontal) { 35965 var bounds = (_isString(element) ? _getTarget(element) : element).getBoundingClientRect(), 35966 offset = bounds[horizontal ? _width : _height] * ratio || 0; 35967 return horizontal ? bounds.right - offset > 0 && bounds.left + offset < _win.innerWidth : bounds.bottom - offset > 0 && bounds.top + offset < _win.innerHeight; 35968 }; 35969 35970 ScrollTrigger.positionInViewport = function positionInViewport(element, referencePoint, horizontal) { 35971 _isString(element) && (element = _getTarget(element)); 35972 var bounds = element.getBoundingClientRect(), 35973 size = bounds[horizontal ? _width : _height], 35974 offset = referencePoint == null ? size / 2 : referencePoint in _keywords ? _keywords[referencePoint] * size : ~referencePoint.indexOf("%") ? parseFloat(referencePoint) * size / 100 : parseFloat(referencePoint) || 0; 35975 return horizontal ? (bounds.left + offset) / _win.innerWidth : (bounds.top + offset) / _win.innerHeight; 35976 }; 35977 35978 return ScrollTrigger; 35979 }(); 35980 ScrollTrigger.version = "3.8.0"; 35981 35982 ScrollTrigger.saveStyles = function (targets) {
35983 return targets ? _toArray(targets).forEach(function (target) { 35984 if (target && target.style) { 35985 var i = _savedStyles.indexOf(target); 35986 35987 i >= 0 && _savedStyles.splice(i, 5); 35988 35989 _savedStyles.push(target, target.style.cssText, target.getBBox && target.getAttribute("transform"), gsap.core.getCache(target), _creatingMedia); 35990 } 35991 }) : _savedStyles; 35992 }; 35993 35994 ScrollTrigger.revert = function (soft, media) { 35995 return _revertAll(!soft, media); 35996 }; 35997 35998 ScrollTrigger.create = function (vars, animation) { 35999 return new ScrollTrigger(vars, animation); 36000 }; 36001 36002 ScrollTrigger.refresh = function (safe) { 36003 return safe ? _onResize() : (_coreInitted || ScrollTrigger.register()) && _refreshAll(true); 36004 }; 36005 36006 ScrollTrigger.update = _updateAll; 36007 ScrollTrigger.clearScrollMemory = _clearScrollMemory; 36008 36009 ScrollTrigger.maxScroll = function (element, horizontal) { 36010 return _maxScroll(element, horizontal ? _horizontal : _vertical); 36011 }; 36012 36013 ScrollTrigger.getScrollFunc = function (element, horizontal) { 36014 return _getScrollFunc(_getTarget(element), horizontal ? _horizontal : _vertical); 36015 }; 36016 36017 ScrollTrigger.getById = function (id) { 36018 return _ids[id]; 36019 }; 36020 36021 ScrollTrigger.getAll = function () { 36022 return _triggers.slice(0); 36023 }; 36024 36025 ScrollTrigger.isScrolling = function () { 36026 return !!_lastScrollTime; 36027 }; 36028 36029 ScrollTrigger.snapDirectional = _snapDirectional; 36030 36031 ScrollTrigger.addEventListener = function (type, callback) { 36032 var a = _listeners[type] || (_listeners[type] = []); 36033 ~a.indexOf(callback) || a.push(callback); 36034 }; 36035 36036 ScrollTrigger.removeEventListener = function (type, callback) { 36037 var a = _listeners[type], 36038 i = a && a.indexOf(callback); 36039 i >= 0 && a.splice(i, 1); 36040 }; 36041 36042 ScrollTrigger.batch = function (targets, vars) { 36043 var result = [], 36044 varsCopy = {}, 36045 interval = vars.interval || 0.016, 36046 batchMax = vars.batchMax || 1e9, 36047 proxyCallback = function proxyCallback(type, callback) { 36048 var elements = [], 36049 triggers = [], 36050 delay = gsap.delayedCall(interval, function () { 36051 callback(elements, triggers); 36052 elements = []; 36053 triggers = []; 36054 }).pause(); 36055 return function (self) { 36056 elements.length || delay.restart(true); 36057 elements.push(self.trigger); 36058 triggers.push(self); 36059 batchMax <= elements.length && delay.progress(1); 36060 }; 36061 }, 36062 p; 36063 36064 for (p in vars) { 36065 varsCopy[p] = p.substr(0, 2) === "on" && _isFunction(vars[p]) && p !== "onRefreshInit" ? proxyCallback(p, vars[p]) : vars[p]; 36066 } 36067 36068 if (_isFunction(batchMax)) { 36069 batchMax = batchMax(); 36070 36071 _addListener(ScrollTrigger, "refresh", function () { 36072 return batchMax = vars.batchMax(); 36073 }); 36074 } 36075 36076 _toArray(targets).forEach(function (target) { 36077 var config = {}; 36078 36079 for (p in varsCopy) { 36080 config[p] = varsCopy[p]; 36081 } 36082 36083 config.trigger = target; 36084 result.push(ScrollTrigger.create(config)); 36085 }); 36086 36087 return result; 36088 }; 36089 36090 ScrollTrigger.sort = function (func) { 36091 return _triggers.sort(func || function (a, b) { 36092 return (a.vars.refreshPriority || 0) * -1e6 + a.start - (b.start + (b.vars.refreshPriority || 0) * -1e6); 36093 }); 36094 }; 36095 36096 _getGSAP() && gsap.registerPlugin(ScrollTrigger); 36097 36098 exports.ScrollTrigger = ScrollTrigger; 36099 exports.default = ScrollTrigger; 36100 36101 Object.defineProperty(exports, '__esModule', { value: true }); 36102 36103}))); 36104 36105/* ======================================================================== 36106 * Bootstrap: collapse.js v3.1.1 36107 * http://getbootstrap.com/javascript/#collapse 36108 * ======================================================================== 36109 * Copyright 2011-2014 Twitter, Inc. 36110 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 36111 * ======================================================================== */ 36112 36113 36114+function ($) { 36115 'use strict'; 36116 36117 // COLLAPSE PUBLIC CLASS DEFINITION 36118 // ================================ 36119 36120 var Collapse = function (element, options) { 36121 this.$element = $(element) 36122 this.options = $.extend({}, Collapse.DEFAULTS, options) 36123 this.transitioning = null 36124 36125 if (this.options.parent) this.$parent = $(this.options.parent) 36126 if (this.options.toggle) this.toggle() 36127 } 36128 36129 Collapse.DEFAULTS = { 36130 toggle: true 36131 } 36132 36133 Collapse.prototype.dimension = function () { 36134 var hasWidth = this.$element.hasClass('width') 36135 return hasWidth ? 'width' : 'height' 36136 } 36137 36138 Collapse.prototype.show = function () { 36139 if (this.transitioning || this.$element.hasClass('in')) return 36140 36141 var startEvent = $.Event('show.bs.collapse') 36142 this.$element.trigger(startEvent) 36143 if (startEvent.isDefaultPrevented()) return 36144 36145 var actives = this.$parent && this.$parent.find('> .panel > .in') 36146 36147 if (actives && actives.length) { 36148 var hasData = actives.data('bs.collapse') 36149 if (hasData && hasData.transitioning) return 36150 //START UNCODE EDIT 36151 var parentNoToggle = this.$parent.data('no-toggle') 36152 if (!parentNoToggle) { 36153 actives.collapse('hide') 36154 } 36155 //END UNCODE EDIT 36156 hasData || actives.data('bs.collapse', null) 36157 } 36158 36159 var dimension = this.dimension() 36160 36161 this.$element 36162 .removeClass('collapse') 36163 .addClass('collapsing')[dimension](0) 36164 36165 this.transitioning = 1 36166 36167 var complete = function (e) { 36168 if (e && e.target != this.$element[0]) return 36169 this.$element 36170 .removeClass('collapsing') 36171 .addClass('collapse in')[dimension]('auto') 36172 this.transitioning = 0 36173 this.$element.trigger('shown.bs.collapse') 36174 } 36175 36176 if (!$.support.transition) return complete.call(this) 36177 36178 var scrollSize = $.camelCase(['scroll', dimension].join('-')) 36179 36180 this.$element 36181 .one($.support.transition.end, $.proxy(complete, this)) 36182 .emulateTransitionEnd(350)[dimension](this.$element[0][scrollSize]) 36183 } 36184 36185 Collapse.prototype.hide = function () { 36186 if (this.transitioning || !this.$element.hasClass('in')) return 36187 36188 var startEvent = $.Event('hide.bs.collapse') 36189 this.$element.trigger(startEvent) 36190 if (startEvent.isDefaultPrevented()) return 36191 36192 var dimension = this.dimension() 36193 36194 this.$element[dimension](this.$element[dimension]())[0].offsetHeight 36195 36196 this.$element 36197 .addClass('collapsing') 36198 .removeClass('collapse') 36199 .removeClass('in') 36200 36201 this.transitioning = 1 36202 36203 var complete = function (e) { 36204 if (e && e.target != this.$element[0]) return 36205 this.transitioning = 0 36206 this.$element 36207 .trigger('hidden.bs.collapse') 36208 .removeClass('collapsing') 36209 .addClass('collapse') 36210 } 36211 36212 if (!$.support.transition) return complete.call(this) 36213 36214 this.$element 36215 [dimension](0) 36216 .one($.support.transition.end, $.proxy(complete, this)) 36217 .emulateTransitionEnd(350) 36218 } 36219 36220 Collapse.prototype.toggle = function () { 36221 this[this.$element.hasClass('in') ? 'hide' : 'show']() 36222 } 36223 36224 36225 // COLLAPSE PLUGIN DEFINITION 36226 // ========================== 36227 36228 var old = $.fn.collapse 36229 36230 $.fn.collapse = function (option) { 36231 return this.each(function () { 36232 var $this = $(this) 36233 var data = $this.data('bs.collapse') 36234 var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option) 36235 36236 if (!data && options.toggle && option == 'show') option = !option 36237 if (!data) $this.data('bs.collapse', (data = new Collapse(this, options))) 36238 if (typeof option == 'string') data[option]() 36239 }) 36240 } 36241 36242 $.fn.collapse.Constructor = Collapse 36243 36244 36245 // COLLAPSE NO CONFLICT 36246 // ==================== 36247 36248 $.fn.collapse.noConflict = function () { 36249 $.fn.collapse = old 36250 return this 36251 } 36252 36253 36254 // COLLAPSE DATA-API 36255 // ================= 36256 36257 $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) { 36258 var $this = $(this), href 36259 var target = $this.attr('data-target') 36260 || e.preventDefault() 36261 || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7 36262 //Edited by Uncode to replace ID in panel [START] 36263 var _target = href.replace(/^#/, ""); 36264 if ( $('[data-id="' + _target + '"]').length ) { 36265 var $target = $('[data-id="' + _target + '"]') 36266 } else { 36267 var $target = $(target) 36268 } 36269 //Edited by Uncode to replace ID in panel [END] 36270 var data = $target.data('bs.collapse') 36271 var option = data ? 'toggle' : $this.data() 36272 var parent = $this.attr('data-parent') 36273 var $parent = parent && $(parent) 36274 36275 if (!data || !data.transitioning) { 36276 if ($parent) $parent.find('[data-toggle="collapse"][data-parent="' + parent + '"]').not($this).addClass('collapsed') 36277 $this[$target.hasClass('in') ? 'addClass' : 'removeClass']('collapsed') 36278 } 36279 36280 $target.collapse(option) 36281 }) 36282 36283}(jQuery); 36284 36285/* ======================================================================== 36286 * Bootstrap: tab.js v3.1.1 36287 * http://getbootstrap.com/javascript/#tabs 36288 * ======================================================================== 36289 * Copyright 2011-2014 Twitter, Inc. 36290 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 36291 * ======================================================================== */ 36292 36293 36294+function ($) { 36295 'use strict'; 36296 36297 // TAB CLASS DEFINITION 36298 // ==================== 36299 36300 var Tab = function (element) { 36301 this.element = $(element) 36302 } 36303 36304 Tab.prototype.show = function () { 36305 var $this = this.element 36306 var $ul = $this.closest('ul:not(.dropdown-menu)') 36307 var selector = $this.data('target') 36308 36309 if (!selector) { 36310 selector = $this.attr('href') 36311 selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7 36312 } 36313 36314 if ($this.parent('li').hasClass('active')) return 36315 36316 var previous = $ul.find('.active:last a')[0] 36317 var e = $.Event('show.bs.tab', { 36318 relatedTarget: previous 36319 }) 36320 36321 $this.trigger(e) 36322 36323 if (e.isDefaultPrevented()) return 36324 36325 //Edited by Uncode to replace ID in panel [START] 36326 var _target = selector.replace(/^#/, ""); 36327 if ( $('[data-id="' + _target + '"]').length ) 36328 var $target = $('[data-id="' + _target + '"]') 36329 else 36330 var $target = $(selector) 36331 //Edited by Uncode to replace ID in panel [END] 36332 36333 this.activate($this.parent('li'), $ul) 36334 this.activate($target, $target.parent(), function () { 36335 $this.trigger({ 36336 type: 'shown.bs.tab', 36337 relatedTarget: previous 36338 }) 36339 }) 36340 } 36341 36342 Tab.prototype.activate = function (element, container, callback) { 36343 var $active = container.find('> .active').add(container.find('> .active > .active')) 36344 var transition = callback 36345 && $.support.transition 36346 && $active.hasClass('fade') 36347 36348 function next() { 36349 $active 36350 .removeClass('active') 36351 .find('> .dropdown-menu > .active') 36352 .removeClass('active') 36353 36354 $active 36355 .find('.tab-excerpt').slideUp(); 36356 36357 element.addClass('active') 36358 $('.tab-excerpt', element).slideDown(); 36359 36360 //if (transition) { 36361 element[0].offsetWidth // reflow for transition 36362 element.add($active).addClass('in') 36363 /*} else { 36364 element.removeClass('fade') 36365 }*/ 36366 36367 if (element.parent('.dropdown-menu')) { 36368 element.closest('li.dropdown').addClass('active') 36369 } 36370 36371 callback && callback() 36372 } 36373 36374 transition ? 36375 $active 36376 .one($.support.transition.end, next) 36377 .emulateTransitionEnd(150) : 36378 next() 36379 36380 $active.removeClass('in') 36381 } 36382 36383 36384 // TAB PLUGIN DEFINITION 36385 // ===================== 36386 36387 var old = $.fn.tab 36388 36389 $.fn.tab = function ( option ) { 36390 return this.each(function () { 36391 var $this = $(this) 36392 var data = $this.data('bs.tab') 36393 36394 if (!data) $this.data('bs.tab', (data = new Tab(this))) 36395 if (typeof option == 'string') data[option]() 36396 }) 36397 } 36398 36399 $.fn.tab.Constructor = Tab 36400 36401 36402 // TAB NO CONFLICT 36403 // =============== 36404 36405 $.fn.tab.noConflict = function () { 36406 $.fn.tab = old 36407 return this 36408 } 36409 36410 36411 // TAB DATA-API 36412 // ============ 36413 36414 $(document).on('click.bs.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) { 36415 e.preventDefault() 36416 $(this).tab('show') 36417 }) 36418 36419}(jQuery); 36420 36421/* ======================================================================== 36422 * Bootstrap: tooltip.js v3.1.1 36423 * http://getbootstrap.com/javascript/#tooltip 36424 * Inspired by the original jQuery.tipsy by Jason Frame 36425 * ======================================================================== 36426 * Copyright 2011-2014 Twitter, Inc. 36427 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 36428 * ======================================================================== */ 36429 36430 36431+function ($) { 36432 'use strict'; 36433 36434 // TOOLTIP PUBLIC CLASS DEFINITION 36435 // =============================== 36436 36437 var Tooltip = function (element, options) { 36438 this.type = 36439 this.options = 36440 this.enabled = 36441 this.timeout = 36442 this.hoverState = 36443 this.$element = null 36444 36445 this.init('tooltip', element, options) 36446 } 36447 36448 Tooltip.DEFAULTS = { 36449 animation: true, 36450 placement: 'top', 36451 selector: false, 36452 template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>', 36453 trigger: 'hover focus', 36454 title: '', 36455 delay: 0, 36456 html: false, 36457 container: false, 36458 viewport: { 36459 selector: 'body', 36460 padding: 0 36461 } 36462 } 36463 36464 Tooltip.prototype.init = function (type, element, options) { 36465 this.enabled = true 36466 this.type = type 36467 this.$element = $(element) 36468 this.options = this.getOptions(options) 36469 this.$viewport = this.options.viewport && $(this.options.viewport.selector || this.options.viewport) 36470 36471 var triggers = this.options.trigger.split(' ') 36472 36473 for (var i = triggers.length; i--;) { 36474 var trigger = triggers[i] 36475 36476 if (trigger == 'click') { 36477 this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this)) 36478 } else if (trigger != 'manual') { 36479 var eventIn = trigger == 'hover' ? 'mouseenter' : 'focusin' 36480 var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout' 36481 36482 this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this)) 36483 this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this)) 36484 } 36485 } 36486 36487 this.options.selector ? 36488 (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) : 36489 this.fixTitle() 36490 } 36491 36492 Tooltip.prototype.getDefaults = function () { 36493 return Tooltip.DEFAULTS 36494 } 36495 36496 Tooltip.prototype.getOptions = function (options) { 36497 options = $.extend({}, this.getDefaults(), this.$element.data(), options) 36498 36499 if (options.delay && typeof options.delay == 'number') { 36500 options.delay = { 36501 show: options.delay, 36502 hide: options.delay 36503 } 36504 } 36505 36506 return options 36507 } 36508 36509 Tooltip.prototype.getDelegateOptions = function () { 36510 var options = {} 36511 var defaults = this.getDefaults() 36512 36513 this._options && $.each(this._options, function (key, value) { 36514 if (defaults[key] != value) options[key] = value 36515 }) 36516 36517 return options 36518 } 36519 36520 Tooltip.prototype.enter = function (obj) { 36521 var self = obj instanceof this.constructor ? 36522 obj : $(obj.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type) 36523 36524 clearTimeout(self.timeout) 36525 36526 self.hoverState = 'in' 36527 36528 if (!self.options.delay || !self.options.delay.show) return self.show() 36529 36530 self.timeout = setTimeout(function () { 36531 if (self.hoverState == 'in') self.show() 36532 }, self.options.delay.show) 36533 } 36534 36535 Tooltip.prototype.leave = function (obj) { 36536 var self = obj instanceof this.constructor ? 36537 obj : $(obj.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type) 36538 36539 clearTimeout(self.timeout) 36540 36541 self.hoverState = 'out' 36542 36543 if (!self.options.delay || !self.options.delay.hide) return self.hide() 36544 36545 self.timeout = setTimeout(function () { 36546 if (self.hoverState == 'out') self.hide() 36547 }, self.options.delay.hide) 36548 } 36549 36550 Tooltip.prototype.show = function () { 36551 var e = $.Event('show.bs.' + this.type) 36552 36553 if (this.hasContent() && this.enabled) { 36554 this.$element.trigger(e) 36555 36556 if (e.isDefaultPrevented()) return 36557 var that = this; 36558 36559 var $tip = this.tip() 36560 36561 this.setContent() 36562 36563 if (this.options.animation) $tip.addClass('fade') 36564 36565 var placement = typeof this.options.placement == 'function' ? 36566 this.options.placement.call(this, $tip[0], this.$element[0]) : 36567 this.options.placement 36568 36569 var autoToken = /\s?auto?\s?/i 36570 var autoPlace = autoToken.test(placement) 36571 if (autoPlace) placement = placement.replace(autoToken, '') || 'top' 36572 36573 $tip 36574 .detach() 36575 .cs
36575s({ top: 0, left: 0, display: 'block' }) 36576 .addClass(placement) 36577 36578 this.options.container ? $tip.appendTo($(document).find(this.options.container)) : $tip.insertAfter(this.$element) 36579 36580 var pos = this.getPosition() 36581 var actualWidth = $tip[0].offsetWidth 36582 var actualHeight = $tip[0].offsetHeight 36583 36584 if (autoPlace) { 36585 var orgPlacement = placement 36586 var $parent = this.$element.parent() 36587 var parentDim = this.getPosition($parent) 36588 36589 placement = placement == 'bottom' && pos.top + pos.height + actualHeight - parentDim.scroll > parentDim.height ? 'top' : 36590 placement == 'top' && pos.top - parentDim.scroll - actualHeight < 0 ? 'bottom' : 36591 placement == 'right' && pos.right + actualWidth > parentDim.width ? 'left' : 36592 placement == 'left' && pos.left - actualWidth < parentDim.left ? 'right' : 36593 placement 36594 36595 $tip 36596 .removeClass(orgPlacement) 36597 .addClass(placement) 36598 } 36599 36600 var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight) 36601 36602 this.applyPlacement(calculatedOffset, placement) 36603 this.hoverState = null 36604 36605 var complete = function() { 36606 that.$element.trigger('shown.bs.' + that.type) 36607 } 36608 36609 $.support.transition && this.$tip.hasClass('fade') ? 36610 $tip 36611 .one($.support.transition.end, complete) 36612 .emulateTransitionEnd(150) : 36613 complete() 36614 } 36615 } 36616 36617 Tooltip.prototype.applyPlacement = function (offset, placement) { 36618 var $tip = this.tip() 36619 var width = $tip[0].offsetWidth 36620 var height = $tip[0].offsetHeight 36621 36622 // manually read margins because getBoundingClientRect includes difference 36623 var marginTop = parseInt($tip.css('margin-top'), 10) 36624 var marginLeft = parseInt($tip.css('margin-left'), 10) 36625 36626 // we must check for NaN for ie 8/9 36627 if (isNaN(marginTop)) marginTop = 0 36628 if (isNaN(marginLeft)) marginLeft = 0 36629 36630 offset.top = offset.top + marginTop 36631 offset.left = offset.left + marginLeft 36632 36633 // $.fn.offset doesn't round pixel values 36634 // so we use setOffset directly with our own function B-0 36635 $.offset.setOffset($tip[0], $.extend({ 36636 using: function (props) { 36637 $tip.css({ 36638 top: Math.round(props.top), 36639 left: Math.round(props.left) 36640 }) 36641 } 36642 }, offset), 0) 36643 36644 $tip.addClass('in') 36645 36646 // check to see if placing tip in new offset caused the tip to resize itself 36647 var actualWidth = $tip[0].offsetWidth 36648 var actualHeight = $tip[0].offsetHeight 36649 36650 if (placement == 'top' && actualHeight != height) { 36651 offset.top = offset.top + height - actualHeight 36652 } 36653 36654 var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight) 36655 36656 if (delta.left) offset.left += delta.left 36657 else offset.top += delta.top 36658 36659 var arrowDelta = delta.left ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight 36660 var arrowPosition = delta.left ? 'left' : 'top' 36661 var arrowOffsetPosition = delta.left ? 'offsetWidth' : 'offsetHeight' 36662 36663 $tip.offset(offset) 36664 this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], arrowPosition) 36665 } 36666 36667 Tooltip.prototype.replaceArrow = function (delta, dimension, position) { 36668 this.arrow().css(position, delta ? (50 * (1 - delta / dimension) + '%') : '') 36669 } 36670 36671 Tooltip.prototype.setContent = function () { 36672 var $tip = this.tip() 36673 var title = this.getTitle() 36674 36675 $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title) 36676 $tip.removeClass('fade in top bottom left right') 36677 } 36678 36679 Tooltip.prototype.hide = function () { 36680 var that = this 36681 var $tip = this.tip() 36682 var e = $.Event('hide.bs.' + this.type) 36683 36684 function complete() { 36685 if (that.hoverState != 'in') $tip.detach() 36686 that.$element.trigger('hidden.bs.' + that.type) 36687 } 36688 36689 this.$element.trigger(e) 36690 36691 if (e.isDefaultPrevented()) return 36692 36693 $tip.removeClass('in') 36694 36695 $.support.transition && this.$tip.hasClass('fade') ? 36696 $tip 36697 .one($.support.transition.end, complete) 36698 .emulateTransitionEnd(150) : 36699 complete() 36700 36701 this.hoverState = null 36702 36703 return this 36704 } 36705 36706 Tooltip.prototype.fixTitle = function () { 36707 var $e = this.$element 36708 if ($e.attr('title') || typeof($e.attr('data-original-title')) != 'string') { 36709 $e.attr('data-original-title', $e.attr('title') || '').attr('title', '') 36710 } 36711 } 36712 36713 Tooltip.prototype.hasContent = function () { 36714 return this.getTitle() 36715 } 36716 36717 Tooltip.prototype.getPosition = function ($element) { 36718 $element = $element || this.$element 36719 var el = $element[0] 36720 var isBody = el.tagName == 'BODY' 36721 return $.extend({}, (typeof el.getBoundingClientRect == 'function') ? el.getBoundingClientRect() : null, { 36722 scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop(), 36723 width: isBody ? $(window).width() : $element.outerWidth(), 36724 height: isBody ? $(window).height() : $element.outerHeight() 36725 }, isBody ? {top: 0, left: 0} : $element.offset()) 36726 } 36727 36728 Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) { 36729 return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } : 36730 placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } : 36731 placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } : 36732 /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width } 36733 36734 } 36735 36736 Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) { 36737 var delta = { top: 0, left: 0 } 36738 if (!this.$viewport) return delta 36739 36740 var viewportPadding = this.options.viewport && this.options.viewport.padding || 0 36741 var viewportDimensions = this.getPosition(this.$viewport) 36742 36743 if (/right|left/.test(placement)) { 36744 var topEdgeOffset = pos.top - viewportPadding - viewportDimensions.scroll 36745 var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight 36746 if (topEdgeOffset < viewportDimensions.top) { // top overflow 36747 delta.top = viewportDimensions.top - topEdgeOffset 36748 } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow 36749 delta.top = viewportDimensions.top + viewportDimensions.height - bottom
36749EdgeOffset 36750 } 36751 } else { 36752 var leftEdgeOffset = pos.left - viewportPadding 36753 var rightEdgeOffset = pos.left + viewportPadding + actualWidth 36754 if (leftEdgeOffset < viewportDimensions.left) { // left overflow 36755 delta.left = viewportDimensions.left - leftEdgeOffset 36756 } else if (rightEdgeOffset > viewportDimensions.width) { // right overflow 36757 delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset 36758 } 36759 } 36760 36761 return delta 36762 } 36763 36764 Tooltip.prototype.getTitle = function () { 36765 var title 36766 var $e = this.$element 36767 var o = this.options 36768 36769 title = $e.attr('data-original-title') 36770 || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title) 36771 36772 return title 36773 } 36774 36775 Tooltip.prototype.tip = function () { 36776 return this.$tip = this.$tip || $(this.options.template) 36777 } 36778 36779 Tooltip.prototype.arrow = function () { 36780 return this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow') 36781 } 36782 36783 Tooltip.prototype.validate = function () { 36784 if (!this.$element[0].parentNode) { 36785 this.hide() 36786 this.$element = null 36787 this.options = null 36788 } 36789 } 36790 36791 Tooltip.prototype.enable = function () { 36792 this.enabled = true 36793 } 36794 36795 Tooltip.prototype.disable = function () { 36796 this.enabled = false 36797 } 36798 36799 Tooltip.prototype.toggleEnabled = function () { 36800 this.enabled = !this.enabled 36801 } 36802 36803 Tooltip.prototype.toggle = function (e) { 36804 var self = e ? $(e.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type) : this 36805 self.tip().hasClass('in') ? self.leave(self) : self.enter(self) 36806 } 36807 36808 Tooltip.prototype.destroy = function () { 36809 clearTimeout(this.timeout) 36810 this.hide().$element.off('.' + this.type).removeData('bs.' + this.type) 36811 } 36812 36813 36814 // TOOLTIP PLUGIN DEFINITION 36815 // ========================= 36816 36817 var old = $.fn.tooltip 36818 36819 $.fn.tooltip = function (option) { 36820 return this.each(function () { 36821 var $this = $(this) 36822 var data = $this.data('bs.tooltip') 36823 var options = typeof option == 'object' && option 36824 36825 if (!data && option == 'destroy') return 36826 if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options))) 36827 if (typeof option == 'string') data[option]() 36828 }) 36829 } 36830 36831 $.fn.tooltip.Constructor = Tooltip 36832 36833 36834 // TOOLTIP NO CONFLICT 36835 // =================== 36836 36837 $.fn.tooltip.noConflict = function () { 36838 $.fn.tooltip = old 36839 return this 36840 } 36841 36842}(jQuery); 36843 36844/* ======================================================================== 36845 * Bootstrap: transition.js v3.1.1 36846 * http://getbootstrap.com/javascript/#transitions 36847 * ======================================================================== 36848 * Copyright 2011-2014 Twitter, Inc. 36849 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 36850 * ======================================================================== */ 36851 36852 36853+function ($) { 36854 'use strict'; 36855 36856 // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/) 36857 // ============================================================ 36858 36859 function transitionEnd() { 36860 var el = document.createElement('bootstrap') 36861 36862 var transEndEventNames = { 36863 WebkitTransition : 'webkitTransitionEnd', 36864 MozTransition : 'transitionend', 36865 OTransition : 'oTransitionEnd otransitionend', 36866 transition : 'transitionend' 36867 } 36868 36869 for (var name in transEndEventNames) { 36870 if (el.style[name] !== undefined) { 36871 return { end: transEndEventNames[name] } 36872 } 36873 } 36874 36875 return false // explicit for ie8 ( ._.) 36876 } 36877 36878 // http://blog.alexmaccaw.com/css-transitions 36879 $.fn.emulateTransitionEnd = function (duration) { 36880 var called = false, $el = this 36881 $(this).one($.support.transition.end, function () { called = true }) 36882 var callback = function () { if (!called) $($el).trigger($.support.transition.end) } 36883 setTimeout(callback, duration) 36884 return this 36885 } 36886 36887 $(function () { 36888 $.support.transition = transitionEnd() 36889 }) 36890 36891}(jQuery); 36892 36893 36894// ------------------------------------------ 36895// Rellax.js 36896// Buttery smooth parallax library 36897// Copyright (c) 2016 Moe Amaya (@moeamaya) 36898// MIT license 36899// 36900// Thanks to Paraxify.js and Jaime Cabllero 36901// for parallax concepts 36902// ------------------------------------------ 36903 36904(function (root, factory) { 36905 if (typeof define === 'function' && define.amd) { 36906 // AMD. Register as an anonymous module. 36907 define([], factory); 36908 } else if (typeof module === 'object' && module.exports) { 36909 // Node. Does not work with strict CommonJS, but 36910 // only CommonJS-like environments that support module.exports, 36911 // like Node. 36912 module.exports = factory(); 36913 } else { 36914 // Browser globals (root is window) 36915 root.Rellax = factory(); 36916 } 36917}(typeof window !== "undefined" ? window : global, function () { 36918 var Rellax = function(el, options){ 36919 "use strict"; 36920 36921 var self = Object.create(Rellax.prototype); 36922 36923 var posY = 0; 36924 var screenY = 0; 36925 var posX = 0; 36926 var screenX = 0; 36927 var blocks = []; 36928 var pause = true; 36929 36930 // check what requestAnimationFrame to use, and if 36931 // it's not supported, use the onscroll event 36932 var loop = window.requestAnimationFrame || 36933 window.webkitRequestAnimationFrame || 36934 window.mozRequestAnimationFrame || 36935 window.msRequestAnimationFrame || 36936 window.oRequestAnimationFrame || 36937 function(callback){ return setTimeout(callback, 1000 / 60); }; 36938 36939 // store the id for later use 36940 var loopId = null; 36941 36942 // Test via a getter in the options object to see if the passive property is accessed 36943 var supportsPassive = false;
vendor: 10,724 bytes, lines 36944-37245
36944 try { 36945 var opts = Object.defineProperty({}, 'passive', { 36946 get: function() { 36947 supportsPassive = true; 36948 } 36949 }); 36950 window.addEventListener("testPassive", null, opts); 36951 window.removeEventListener("testPassive", null, opts); 36952 } catch (e) {} 36953 36954 // check what cancelAnimation method to use 36955 var clearLoop = window.cancelAnimationFrame || window.mozCancelAnimationFrame || clearTimeout; 36956 36957 // check which transform property to use 36958 var transformProp = window.transformProp || (function(){ 36959 var testEl = document.createElement('div'); 36960 if (testEl.style.transform === null) { 36961 var vendors = ['Webkit', 'Moz', 'ms']; 36962 for (var vendor in vendors) { 36963 if (testEl.style[ vendors[vendor] + 'Transform' ] !== undefined) { 36964 return vendors[vendor] + 'Transform'; 36965 } 36966 } 36967 } 36968 return 'transform'; 36969 })(); 36970 36971 // Default Settings 36972 self.options = { 36973 speed: -2, 36974 verticalSpeed: null, 36975 horizontalSpeed: null, 36976 breakpoints: [576, 768, 1201], 36977 center: false, 36978 wrapper: null, 36979 relativeToWrapper: false, 36980 round: true, 36981 vertical: true, 36982 horizontal: false, 36983 verticalScrollAxis: "y", 36984 horizontalScrollAxis: "x", 36985 callback: function() {}, 36986 }; 36987 36988 // User defined options (might have more in the future) 36989 if (options){ 36990 Object.keys(options).forEach(function(key){ 36991 self.options[key] = options[key]; 36992 }); 36993 } 36994 36995 function validateCustomBreakpoints () { 36996 if (self.options.breakpoints.length === 3 && Array.isArray(self.options.breakpoints)) { 36997 var isAscending = true; 36998 var isNumerical = true; 36999 var lastVal; 37000 self.options.breakpoints.forEach(function (i) { 37001 if (typeof i !== 'number') isNumerical = false; 37002 if (lastVal !== null) { 37003 if (i < lastVal) isAscending = false; 37004 } 37005 lastVal = i; 37006 }); 37007 if (isAscending && isNumerical) return; 37008 } 37009 // revert defaults if set incorrectly 37010 self.options.breakpoints = [576, 768, 1201]; 37011 console.warn("Rellax: You must pass an array of 3 numbers in ascending order to the breakpoints option. Defaults reverted"); 37012 } 37013 37014 if (options && options.breakpoints) { 37015 validateCustomBreakpoints(); 37016 } 37017 37018 // By default, rellax class 37019 if (!el) { 37020 el = '.rellax'; 37021 } 37022 37023 // check if el is a className or a node 37024 var elements = typeof el === 'string' ? document.querySelectorAll(el) : [el]; 37025 37026 // Now query selector 37027 if (elements.length > 0) { 37028 self.elems = elements; 37029 } 37030 37031 // The elements don't exist 37032 else { 37033 console.warn("Rellax: The elements you're trying to select don't exist."); 37034 return; 37035 } 37036 37037 // Has a wrapper and it exists 37038 if (self.options.wrapper) { 37039 if (!self.options.wrapper.nodeType) { 37040 var wrapper = document.querySelector(self.options.wrapper); 37041 37042 if (wrapper) { 37043 self.options.wrapper = wrapper; 37044 } else { 37045 console.warn("Rellax: The wrapper you're trying to use doesn't exist."); 37046 return; 37047 } 37048 } 37049 } 37050 37051 // set a placeholder for the current breakpoint 37052 var currentBreakpoint; 37053 37054 // helper to determine current breakpoint 37055 var getCurrentBreakpoint = function (w) { 37056 var bp = self.options.breakpoints; 37057 if (w < bp[0]) return 'xs'; 37058 if (w >= bp[0] && w < bp[1]) return 'sm'; 37059 if (w >= bp[1] && w < bp[2]) return 'md'; 37060 return 'lg'; 37061 }; 37062 37063 // Get and cache initial position of all elements 37064 var cacheBlocks = function() { 37065 for (var i = 0; i < self.elems.length; i++){ 37066 var block = createBlock(self.elems[i]); 37067 blocks.push(block); 37068 } 37069 }; 37070 37071 37072 // Let's kick this script off 37073 // Build array for cached element values 37074 var init = function() { 37075 for (var i = 0; i < blocks.length; i++){ 37076 self.elems[i].style.cssText = blocks[i].style; 37077 } 37078 37079 blocks = []; 37080 37081 screenY = window.innerHeight; 37082 screenX = window.innerWidth; 37083 currentBreakpoint = getCurrentBreakpoint(screenX); 37084 37085 setPosition(); 37086 37087 cacheBlocks(); 37088 37089 animate(); 37090 37091 // If paused, unpause and set listener for window resizing events 37092 if (pause) { 37093 window.addEventListener('resize', init); 37094 pause = false; 37095 // Start the loop 37096 update(); 37097 } 37098 }; 37099 37100 // We want to cache the parallax blocks' 37101 // values: base, top, height, speed 37102 // el: is dom object, return: el cache values 37103 var createBlock = function(el) { 37104 var dataPercentage = el.getAttribute( 'data-rellax-percentage' ); 37105 var dataSpeed = el.getAttribute( 'data-rellax-speed' ); 37106 var dataXsSpeed = el.getAttribute( 'data-rellax-xs-speed' ); 37107 var dataMobileSpeed = el.getAttribute( 'data-rellax-mobile-speed' ); 37108 var dataTabletSpeed = el.getAttribute( 'data-rellax-tablet-speed' ); 37109 var dataDesktopSpeed = el.getAttribute( 'data-rellax-desktop-speed' ); 37110 var dataVerticalSpeed = el.getAttribute('data-rellax-vertical-speed'); 37111 var dataHorizontalSpeed = el.getAttribute('data-rellax-horizontal-speed'); 37112 var dataVericalScrollAxis = el.getAttribute('data-rellax-vertical-scroll-axis'); 37113 var dataHorizontalScrollAxis = el.getAttribute('data-rellax-horizontal-scroll-axis'); 37114 var dataZindex = el.getAttribute( 'data-rellax-zindex' ) || 0; 37115 var dataMin = el.getAttribute( 'data-rellax-min' ); 37116 var dataMax = el.getAttribute( 'data-rellax-max' ); 37117 var dataMinX = el.getAttribute('data-rellax-min-x'); 37118 var dataMaxX = el.getAttribute('data-rellax-max-x'); 37119 var dataMinY = el.getAttribute('data-rellax-min-y'); 37120 var dataMaxY = el.getAttribute('data-rellax-max-y'); 37121 var mapBreakpoints; 37122 var breakpoints = true; 37123 37124 if (!dataXsSpeed && !dataMobileSpeed && !dataTabletSpeed && !dataDesktopSpeed) { 37125 breakpoints = false; 37126 } else { 37127 mapBreakpoints = { 37128 'xs': dataXsSpeed, 37129 'sm': dataMobileSpeed, 37130 'md': dataTabletSpeed, 37131 'lg': dataDesktopSpeed 37132 }; 37133 } 37134 37135 // initializing at scrollY = 0 (top of browser), scrollX = 0 (left of browser) 37136 // ensures elements are positioned based on HTML layout. 37137 // 37138 // If the element has the percentage attribute, the posY and posX needs to be 37139 // the current scroll position's value, so that the elements are still positioned based on HTML layout 37140 var wrapperPosY = self.options.wrapper ? self.options.wrapper.scrollTop : (window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop); 37141 // If the option relativeToWrapper is true, use the wrappers offset to top, subtracted from the current page scroll. 37142 if (self.options.relativeToWrapper) { 37143 var scrollPosY = (window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop); 37144 wrapperPosY = scrollPosY - self.options.wrapper.offsetTop; 37145 } 37146 var posY = self.options.vertical ? ( dataPercentage || self.options.center ? wrapperPosY : 0 ) : 0; 37147 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; 37148 37149 var blockTop = posY + el.getBoundingClientRect().top; 37150 var blockHeight = el.clientHeight || el.offsetHeight || el.scrollHeight; 37151 37152 var blockLeft = posX + el.getBoundingClientRect().left; 37153 var blockWidth = el.clientWidth || el.offsetWidth || el.scrollWidth; 37154 37155 // apparently parallax equation everyone uses 37156 var percentageY = dataPercentage ? dataPercentage : (posY - blockTop + screenY) / (blockHeight + screenY); 37157 var percentageX = dataPercentage ? dataPercentage : (posX - blockLeft + screenX) / (blockWidth + screenX); 37158 if(self.options.center){ percentageX = 0.5; percentageY = 0.5; } 37159 37160 // Optional individual block speed as data attr, otherwise global speed 37161 var speed = (breakpoints && mapBreakpoints[currentBreakpoint] !== null) ? Number(mapBreakpoints[currentBreakpoint]) : (dataSpeed ? dataSpeed : self.options.speed); 37162 var verticalSpeed = dataVerticalSpeed ? dataVerticalSpeed : self.options.verticalSpeed; 37163 var horizontalSpeed = dataHorizontalSpeed ? dataHorizontalSpeed : self.options.horizontalSpeed; 37164 37165 // Optional individual block movement axis direction as data attr, otherwise global movement direction 37166 var verticalScrollAxis = dataVericalScrollAxis ? dataVericalScrollAxis : self.options.verticalScrollAxis; 37167 var horizontalScrollAxis = dataHorizontalScrollAxis ? dataHorizontalScrollAxis : self.options.horizontalScrollAxis; 37168 37169 var bases = updatePosition(percentageX, percentageY, speed, verticalSpeed, horizontalSpeed); 37170 37171 // ~~Store non-translate3d transforms~~ 37172 // Store inline styles and extract transforms 37173 var style = el.style.cssText; 37174 var transform = ''; 37175 37176 // Check if there's an inline styled transform 37177 var searchResult = /transform\s*:/i.exec(style); 37178 if (searchResult) { 37179 // Get the index of the transform 37180 var index = searchResult.index; 37181 37182 // Trim the style to the transform point and get the following semi-colon index 37183 var trimmedStyle = style.slice(index); 37184 var delimiter = trimmedStyle.indexOf(';'); 37185 37186 // Remove "transform" string and save the attribute 37187 if (delimiter) { 37188 transform = " " + trimmedStyle.slice(11, delimiter).replace(/\s/g,''); 37189 } else { 37190 transform = " " + trimmedStyle.slice(11).replace(/\s/g,''); 37191 } 37192 } 37193 37194 return { 37195 baseX: bases.x, 37196 baseY: bases.y, 37197 top: blockTop, 37198 left: blockLeft, 37199 height: blockHeight, 37200 width: blockWidth, 37201 speed: speed, 37202 verticalSpeed: verticalSpeed, 37203 horizontalSpeed: horizontalSpeed, 37204 verticalScrollAxis: verticalScrollAxis, 37205 horizontalScrollAxis: horizontalScrollAxis, 37206 style: style, 37207 transform: transform, 37208 zindex: dataZindex, 37209 min: dataMin, 37210 max: dataMax, 37211 minX: dataMinX, 37212 maxX: dataMaxX, 37213 minY: dataMinY, 37214 maxY: dataMaxY 37215 }; 37216 }; 37217 37218 // set scroll position (posY, posX) 37219 // side effect method is not ideal, but okay for now 37220 // returns true if the scroll changed, false if nothing happened 37221 var setPosition = function() { 37222 var oldY = posY; 37223 var oldX = posX; 37224 37225 posY = self.options.wrapper ? self.options.wrapper.scrollTop : (document.documentElement || document.body.parentNode || document.body).scrollTop || window.pageYOffset; 37226 posX = self.options.wrapper ? self.options.wrapper.scrollLeft : (document.documentElement || document.body.parentNode || document.body).scrollLeft || window.pageXOffset; 37227 // If option relativeToWrapper is true, use relative wrapper value instead. 37228 if (self.options.relativeToWrapper) { 37229 var scrollPosY = (document.documentElement || document.body.parentNode || document.body).scrollTop || window.pageYOffset; 37230 posY = scrollPosY - self.options.wrapper.offsetTop; 37231 } 37232 37233 37234 if (oldY != posY && self.options.vertical) { 37235 // scroll changed, return true 37236 return true; 37237 } 37238 37239 if (oldX != posX && self.options.horizontal) { 37240 // scroll changed, return true 37241 return true; 37242 } 37243 37244 // scroll did not change 37245 return false;
37246 }; 37247 37248 // Ahh a pure function, gets new transform value 37249 // based on scrollPosition and speed 37250 // Allow for decimal pixel values 37251 var updatePosition = function(percentageX, percentageY, speed, verticalSpeed, horizontalSpeed) { 37252 var result = {}; 37253 var valueX = ((horizontalSpeed ? horizontalSpeed : speed) * (100 * (1 - percentageX))); 37254 var valueY = ((verticalSpeed ? verticalSpeed : speed) * (100 * (1 - percentageY))); 37255 37256 result.x = self.options.round ? Math.round(valueX) : Math.round(valueX * 100) / 100; 37257 result.y = self.options.round ? Math.round(valueY) : Math.round(valueY * 100) / 100; 37258 37259 return result; 37260 }; 37261 37262 // Remove event listeners and loop again 37263 var deferredUpdate = function() { 37264 window.removeEventListener('resize', deferredUpdate); 37265 window.removeEventListener('orientationchange', deferredUpdate); 37266 (self.options.wrapper ? self.options.wrapper : window).removeEventListener('scroll', deferredUpdate); 37267 (self.options.wrapper ? self.options.wrapper : document).removeEventListener('touchmove', deferredUpdate); 37268 37269 // loop again 37270 loopId = loop(update); 37271 }; 37272 37273 // Loop 37274 var update = function() { 37275 if (setPosition() && pause === false) { 37276 animate(); 37277 37278 // loop again 37279 loopId = loop(update); 37280 } else { 37281 loopId = null; 37282 37283 // Don't animate until we get a position updating event 37284 window.addEventListener('resize', deferredUpdate); 37285 window.addEventListener('orientationchange', deferredUpdate); 37286 (self.options.wrapper ? self.options.wrapper : window).addEventListener('scroll', deferredUpdate, supportsPassive ? { passive: true } : false); 37287 (self.options.wrapper ? self.options.wrapper : document).addEventListener('touchmove', deferredUpdate, supportsPassive ? { passive: true } : false); 37288 } 37289 }; 37290 37291 // Transform3d on parallax element 37292 var animate = function() { 37293 var positions; 37294 for (var i = 0; i < self.elems.length; i++){ 37295 // Determine relevant movement directions 37296 var verticalScrollAxis = blocks[i].verticalScrollAxis.toLowerCase(); 37297 var horizontalScrollAxis = blocks[i].horizontalScrollAxis.toLowerCase(); 37298 var verticalScrollX = verticalScrollAxis.indexOf("x") != -1 ? posY : 0; 37299 var verticalScrollY = verticalScrollAxis.indexOf("y") != -1 ? posY : 0; 37300 var horizontalScrollX = horizontalScrollAxis.indexOf("x") != -1 ? posX : 0; 37301 var horizontalScrollY = horizontalScrollAxis.indexOf("y") != -1 ? posX : 0; 37302 37303 var percentageY = ((verticalScrollY + horizontalScrollY - blocks[i].top + screenY) / (blocks[i].height + screenY)); 37304 var percentageX = ((verticalScrollX + horizontalScrollX - blocks[i].left + screenX) / (blocks[i].width + screenX)); 37305 37306 // Subtracting initialize value, so element stays in same spot as HTML 37307 positions = updatePosition(percentageX, percentageY, blocks[i].speed, blocks[i].verticalSpeed, blocks[i].horizontalSpeed); 37308 var positionY = positions.y - blocks[i].baseY; 37309 var positionX = positions.x - blocks[i].baseX; 37310 37311 // The next two "if" blocks go like this: 37312 // Check if a limit is defined (first "min", then "max"); 37313 // Check if we need to change the Y or the X 37314 // (Currently working only if just one of the axes is enabled) 37315 // Then, check if the new position is inside the allowed limit 37316 // If so, use new position. If not, set position to limit. 37317 37318 // Check if a min limit is defined 37319 if (blocks[i].min !== null) { 37320 if (self.options.vertical && !self.options.horizontal) { 37321 positionY = positionY <= blocks[i].min ? blocks[i].min : positionY; 37322 } 37323 if (self.options.horizontal && !self.options.vertical) { 37324 positionX = positionX <= blocks[i].min ? blocks[i].min : positionX; 37325 } 37326 } 37327 37328 // Check if directional min limits are defined 37329 if (blocks[i].minY != null) { 37330 positionY = positionY <= blocks[i].minY ? blocks[i].minY : positionY; 37331 } 37332 if (blocks[i].minX != null) { 37333 positionX = positionX <= blocks[i].minX ? blocks[i].minX : positionX; 37334 } 37335 37336 // Check if a max limit is defined 37337 if (blocks[i].max !== null) { 37338 if (self.options.vertical && !self.options.horizontal) { 37339 positionY = positionY >= blocks[i].max ? blocks[i].max : positionY; 37340 } 37341 if (self.options.horizontal && !self.options.vertical) { 37342 positionX = positionX >= blocks[i].max ? blocks[i].max : positionX; 37343 } 37344 } 37345 37346 // Check if directional max limits are defined 37347 if (blocks[i].maxY != null) { 37348 positionY = positionY >= blocks[i].maxY ? blocks[i].maxY : positionY; 37349 } 37350 if (blocks[i].maxX != null) { 37351 positionX = positionX >= blocks[i].maxX ? blocks[i].maxX : positionX; 37352 } 37353 37354 var zindex = blocks[i].zindex; 37355 37356 // Move that element 37357 // (Set the new translation and append initial inline transforms.) 37358 var translate = 'translate3d(' + (self.options.horizontal ? positionX : '0') + 'px,' + (self.options.vertical ? positionY : '0') + 'px,' + zindex + 'px) ' + blocks[i].transform; 37359 self.elems[i].style[transformProp] = translate; 37360 } 37361 self.options.callback(positions); 37362 }; 37363 37364 self.destroy = function() { 37365 for (var i = 0; i < self.elems.length; i++){ 37366 self.elems[i].style.cssText = blocks[i].style; 37367 } 37368 37369 // Remove resize event listener if not pause, and pause 37370 if (!pause) { 37371 window.removeEventListener('resize', init); 37372 pause = true; 37373 } 37374 37375 // Clear the animation loop to prevent possible memory leak 37376 clearLoop(loopId); 37377 loopId = null; 37378 }; 37379 37380 // Init 37381 init(); 37382 37383 // Allow to recalculate the initial values whenever we want 37384 self.refresh = init; 37385 37386 return self; 37387 }; 37388 return Rellax; 37389})); 37390 37391/* 37392 * OKVideo by OKFocus v2.3.2 37393 * http://okfoc.us 37394 * 37395 * Copyright 2014, OKFocus 37396 * Licensed under the MIT license. 37397 * 37398 */ 37399var player, OKEvents, options, videoWidth, videoHeight, YTplayers, youtubePlayers = new Array(); 37400// youtube player ready 37401function onYouTubeIframeAPIReady() { 37402 YTplayers = new Array(); 37403 jQuery('.uncode-video-container.video').each(function() { 37404 var playerY; 37405 if (jQuery(this).attr('data-provider') == 'youtube') { 37406 var id = jQuery(this).attr('data-id'), 37407 start = jQuery(this).attr('data-start'), 37408 end = jQuery(this).attr('data-end'); 37409 start = typeof start && start !== null ? start : 0; 37410 end = typeof end && end !== null ? end : 0; 37411 options = jQuery(window).data('okoptions-' + id); 37412 if ( typeof options === 'undefined' ) { 37413 return true; 37414 } 37415 options.time = jQuery(this).attr('data-t'); 37416 playerY = new YT.Player('okplayer-' + id, { 37417 videoId: options.video ? options.video.id : null, 37418 playerVars: { 37419 'autohide': 1, 37420 'autoplay': jQuery(this).hasClass('is-no-control') ? options.autoplay : 0, //options.autoplay, 37421 'disablekb': 1, 37422 'cc_load_policy': options.captions, 37423 'controls': 0, 37424 'enablejsapi': 1, 37425 'fs': 0, 37426 'modestbranding': 1, 37427 'origin': window.location.origin || (window.location.protocol + '//' + window.location.hostname), 37428 'iv_load_policy': options.annotations, 37429 'loop': options.loop, 37430 'showinfo': 0, 37431 'rel': 0, 37432 'wmode': 'opaque', 37433 'hd': options.hd, 37434 'mute': 1, 37435 'start': start, 37436 'end': end 37437 }, 37438 events: { 37439 'onReady': OKEvents.yt.ready, 37440 'onStateChange': OKEvents.yt.onStateChange, 37441 'onError': OKEvents.yt.error 37442 } 37443 }); 37444 YTplayers[id] = playerY; 37445 playerY.videoId = id; 37446 } 37447 37448 }); 37449} 37450// vimeo player ready 37451function vimeoPlayerReady(id) { 37452 options = jQuery(window).data('okoptions-' + id); 37453 if ( typeof options === 'undefined' ) { 37454 return true; 37455 }
37456 var jIframe = options.jobject, 37457 iframe = jIframe[0]; 37458 37459 jIframe.attr('src', jIframe.data('src')); 37460 var playerV = new Vimeo.Player(iframe); 37461 // hide player until Vimeo hides controls... 37462 playerV.on('loaded', function(e) { 37463 OKEvents.v.onReady(iframe); 37464 var carouselContainer = jQuery(iframe).closest('.owl-carousel'); 37465 if (carouselContainer.length) { 37466 UNCODE.owlPlayVideo(carouselContainer); 37467 } 37468 // "Do not try to add listeners or call functions before receiving this event." 37469 if (OKEvents.utils.isMobile()) { 37470 // mobile devices cannot listen for play event 37471 OKEvents.v.onPlay(playerV); 37472 } else { 37473 playerV.on('play', function(){ 37474 OKEvents.v.onPlay(playerV); 37475 jQuery(window).trigger('okevents.v.play', [playerV]); 37476 }); 37477 playerV.on('pause', function(){ 37478 OKEvents.v.onPause; 37479 jQuery(window).trigger('okevents.v.pause', [playerV]); 37480 }); 37481 playerV.on('ended', function(){ 37482 OKEvents.v.onFinish 37483 jQuery(window).trigger('okevents.v.ended', [playerV]); 37484 }); 37485 } 37486 if (options.time != null) { 37487 var optsTimeStr = (options.time).replace('t=', ''), 37488 timeV = ''; 37489 37490 if ( /[a-zA-Z]/g.test(optsTimeStr) ) { 37491 var timeArr = optsTimeStr.split(/([^\d.-])/); 37492 for ( var i = 0; i < timeArr.length; i++ ) { 37493 if ( timeArr[i] === 'h' ) { 37494 timeV += parseFloat(timeArr[i-1]) * 3600; 37495 } else if ( timeArr[i] === 'm' ) { 37496 timeV += parseFloat(timeArr[i-1]) * 60; 37497 } else if ( timeArr[i] === 's' ) { 37498 timeV += parseFloat(timeArr[i-1]); 37499 } 37500 } 37501 } else { 37502 timeV = optsTimeStr; 37503 } 37504 37505 playerV.setCurrentTime(timeV); 37506 } 37507 37508 playerV.setVolume(0); 37509 playerV.play(); 37510 jQuery(iframe).css({ 37511 visibility: 'visible', 37512 opacity: 1 37513 }); 37514 jQuery(iframe).closest('.uncode-video-container:not(.t-entry-drop)').css('opacity', '1'); 37515 jQuery(iframe).closest('#page-header').addClass('video-started'); 37516 jQuery(iframe).closest('.background-wrapper').find('.block-bg-blend-mode.not-ie').css('opacity', '1'); 37517 37518 jQuery(window).trigger('okevents.v.loaded', [playerV]); 37519 }); 37520} 37521OKEvents = { 37522 yt: { 37523 ready: function(event) { 37524 var id = event.target.videoId, 37525 $video = jQuery('#okplayer-' + id), 37526 options = jQuery(window).data('okoptions-' + id); 37527 if ( typeof options === 'undefined' ) { 37528 return true; 37529 } 37530 youtubePlayers[id] = event.target; 37531 event.target.setVolume(options.volume); 37532 if (options.autoplay === 1) { 37533 if (options.playlist.list) { 37534 player.loadPlaylist(options.playlist.list, options.playlist.index, options.playlist.startSeconds, options.playlist.suggestedQuality); 37535 } else { 37536 var inCarousel = $video.closest('.owl-item'); 37537 if (!inCarousel.length || (inCarousel.length && inCarousel.hasClass('active'))) { 37538 if (options.time != null) { 37539 event.target.seekTo(parseInt(options.time)); 37540 } 37541 event.target.playVideo(); 37542 } else { 37543 event.target.pauseVideo(); 37544 } 37545 } 37546 } 37547 OKEvents.utils.isFunction(options.onReady) && options.onReady(event.target); 37548 37549 $video.closest('[data-provider]').on('uncode-resume', function(){ 37550 if (options.time != null) { 37551 event.target.seekTo(parseInt(options.time)).playVideo(); 37552 } else { 37553 event.target.seekTo(0).playVideo(); 37554 } 37555 }); 37556 37557 $video.closest('[data-provider]').on('uncode-pause', function(){ 37558 if (options.time != null) { 37559 event.target.seekTo(parseInt(options.time)).pauseVideo(); 37560 } else { 37561 event.target.seekTo(0).pauseVideo(); 37562 } 37563 }); 37564 jQuery(window).trigger('okevents.y.loaded', [event]); 37565 }, 37566 onStateChange: function(event) { 37567 var id = event.target.videoId, 37568 $video = jQuery('#okplayer-' + id), 37569 options = jQuery(window).data('okoptions-' + id); 37570 if ( typeof options === 'undefined' ) { 37571 return true; 37572 } 37573 youtubePlayers[id] = event.target; 37574 event.target.setVolume(options.volume); 37575 var $fluid = $video.closest('.fluid-object'), 37576 $tmb = $video.closest('.tmb'), 37577 setTime; 37578 switch (event.data) { 37579 case -1: 37580 OKEvents.utils.isFunction(options.unstarted) && options.unstarted(); 37581 break; 37582 case 0: 37583 OKEvents.utils.isFunction(options.onFinished) && options.onFinished(); 37584 options.loop && event.target.playVideo(); 37585 break; 37586 case 1: 37587 OKEvents.utils.isFunction(options.onPlay) && options.onPlay(); 37588 setTimeout(function() { 37589 UNCODE.initVideoComponent(document.body, '.uncode-video-container.video:not(.drop-move), .uncode-video-container.self-video:not(.drop-move)'); 37590 jQuery('#okplayer-' + id).closest('.uncode-video-container:not(.t-entry-drop)').css('opacity', '1'); 37591 jQuery('#okplayer-' + id).closest('#page-header').addClass('video-started'); 37592 jQuery('#okplayer-' + id).closest('.background-wrapper').find('.block-bg-blend-mode.not-ie').css('opacity', '1'); 37593 }, 300); 37594 break; 37595 case 2: 37596 OKEvents.utils.isFunction(options.onPause) && options.onPause(); 37597 break; 37598 case 3: 37599 OKEvents.utils.isFunction(options.buffering) && options.buffering(); 37600 break; 37601 case 5: 37602 OKEvents.utils.isFunction(options.cued) && options.cued(); 37603 break; 37604 default:
37605 throw "OKVideo: received invalid data from YT player."; 37606 } 37607 37608 jQuery(window).trigger('okevents.y.change', [event]); 37609 }, 37610 error: function(event) { 37611 throw event; 37612 } 37613 }, 37614 v: { 37615 onReady: function(target) { 37616 if ( typeof options === 'undefined' ) { 37617 return true; 37618 } 37619 OKEvents.utils.isFunction(options.onReady) && options.onReady(target); 37620 }, 37621 onPlay: function(player) { 37622 if ( typeof options === 'undefined' ) { 37623 return true; 37624 } 37625 if (!OKEvents.utils.isMobile()) player.setVolume(options.volume); 37626 OKEvents.utils.isFunction(options.onPlay) && options.onPlay(); 37627 jQuery(player.element).closest('.uncode-video-container:not(.t-entry-drop)').css('opacity', '1'); 37628 jQuery(player.element).closest('#page-header').addClass('video-started'); 37629 jQuery(player.element).closest('.background-wrapper').find('.block-bg-blend-mode.not-ie').css('opacity', '1'); 37630 }, 37631 onPause: function() { 37632 if ( typeof options === 'undefined' ) { 37633 return true; 37634 } 37635 OKEvents.utils.isFunction(options.onPause) && options.onPause(); 37636 }, 37637 onFinish: function() { 37638 if ( typeof options === 'undefined' ) { 37639 return true; 37640 } 37641 OKEvents.utils.isFunction(options.onFinish) && options.onFinish(); 37642 } 37643 }, 37644 utils: { 37645 isFunction: function(func) { 37646 if (typeof func === 'function') { 37647 return true; 37648 } else { 37649 return false; 37650 } 37651 }, 37652 isMobile: function() { 37653 if (navigator.userAgent.match(/(iPhone|iPod|iPad|Android|BlackBerry)/)) { 37654 return true; 37655 } else { 37656 return false; 37657 } 37658 } 37659 } 37660}; 37661 37662/** 37663 * vivus - JavaScript library to make drawing animation on SVG 37664 * @version v0.4.4 37665 * @link https://github.com/maxwellito/vivus 37666 * @license MIT 37667 */ 37668 37669'use strict'; 37670 37671(function () { 37672 37673 'use strict'; 37674 37675/** 37676 * Pathformer 37677 * Beta version 37678 * 37679 * Take any SVG version 1.1 and transform 37680 * child elements to 'path' elements 37681 * 37682 * This code is purely forked from 37683 * https://github.com/Waest/SVGPathConverter 37684 */ 37685 37686/** 37687 * Class constructor 37688 * 37689 * @param {DOM|String} element Dom element of the SVG or id of it 37690 */ 37691function Pathformer(element) { 37692 // Test params 37693 if (typeof element === 'undefined') { 37694 throw new Error('Pathformer [constructor]: "element" parameter is required'); 37695 } 37696 37697 // Set the element 37698 if (element.constructor === String) { 37699 element = document.getElementById(element); 37700 if (!element) { 37701 throw new Error('Pathformer [constructor]: "element" parameter is not related to an existing ID'); 37702 } 37703 } 37704 if (element instanceof window.SVGElement || 37705 element instanceof window.SVGGElement || 37706 /^svg$/i.test(element.nodeName)) { 37707 this.el = element; 37708 } else { 37709 throw new Error('Pathformer [constructor]: "element" parameter must be a string or a SVGelement'); 37710 } 37711 37712 // Start 37713 this.scan(element); 37714} 37715 37716/** 37717 * List of tags which can be transformed 37718 * to path elements 37719 * 37720 * @type {Array} 37721 */ 37722Pathformer.prototype.TYPES = ['line', 'ellipse', 'circle', 'polygon', 'polyline', 'rect']; 37723 37724/** 37725 * List of attribute names which contain 37726 * data. This array list them to check if 37727 * they contain bad values, like percentage. 37728 * 37729 * @type {Array} 37730 */ 37731Pathformer.prototype.ATTR_WATCH = ['cx', 'cy', 'points', 'r', 'rx', 'ry', 'x', 'x1', 'x2', 'y', '
vendor: 24,640 bytes, lines 37731-38529
37731y1', 'y2']; 37732 37733/** 37734 * Finds the elements compatible for transform 37735 * and apply the liked method 37736 * 37737 * @param {object} options Object from the constructor 37738 */ 37739Pathformer.prototype.scan = function (svg) { 37740 var fn, element, pathData, pathDom, 37741 elements = svg.querySelectorAll(this.TYPES.join(',')); 37742 37743 for (var i = 0; i < elements.length; i++) { 37744 element = elements[i]; 37745 fn = this[element.tagName.toLowerCase() + 'ToPath']; 37746 pathData = fn(this.parseAttr(element.attributes)); 37747 pathDom = this.pathMaker(element, pathData); 37748 element.parentNode.replaceChild(pathDom, element); 37749 } 37750}; 37751 37752 37753/** 37754 * Read `line` element to extract and transform 37755 * data, to make it ready for a `path` object. 37756 * 37757 * @param {DOMelement} element Line element to transform 37758 * @return {object} Data for a `path` element 37759 */ 37760Pathformer.prototype.lineToPath = function (element) { 37761 var newElement = {}, 37762 x1 = element.x1 || 0, 37763 y1 = element.y1 || 0, 37764 x2 = element.x2 || 0, 37765 y2 = element.y2 || 0; 37766 37767 newElement.d = 'M' + x1 + ',' + y1 + 'L' + x2 + ',' + y2; 37768 return newElement; 37769}; 37770 37771/** 37772 * Read `rect` element to extract and transform 37773 * data, to make it ready for a `path` object. 37774 * The radius-border is not taken in charge yet. 37775 * (your help is more than welcomed) 37776 * 37777 * @param {DOMelement} element Rect element to transform 37778 * @return {object} Data for a `path` element 37779 */ 37780Pathformer.prototype.rectToPath = function (element) { 37781 var newElement = {}, 37782 x = parseFloat(element.x) || 0, 37783 y = parseFloat(element.y) || 0, 37784 width = parseFloat(element.width) || 0, 37785 height = parseFloat(element.height) || 0; 37786 37787 if (element.rx || element.ry) { 37788 var rx = parseInt(element.rx, 10) || -1, 37789 ry = parseInt(element.ry, 10) || -1; 37790 rx = Math.min(Math.max(rx < 0 ? ry : rx, 0), width/2); 37791 ry = Math.min(Math.max(ry < 0 ? rx : ry, 0), height/2); 37792 37793 newElement.d = 'M ' + (x + rx) + ',' + y + ' ' + 37794 'L ' + (x + width - rx) + ',' + y + ' ' + 37795 'A ' + rx + ',' + ry + ',0,0,1,' + (x + width) + ',' + (y + ry) + ' ' + 37796 'L ' + (x + width) + ',' + (y + height - ry) + ' ' + 37797 'A ' + rx + ',' + ry + ',0,0,1,' + (x + width - rx) + ',' + (y + height) + ' ' + 37798 'L ' + (x + rx) + ',' + (y + height) + ' ' + 37799 'A ' + rx + ',' + ry + ',0,0,1,' + x + ',' + (y + height - ry) + ' ' + 37800 'L ' + x + ',' + (y + ry) + ' ' + 37801 'A ' + rx + ',' + ry + ',0,0,1,' + (x + rx) + ',' + y; 37802 } 37803 else { 37804 newElement.d = 'M' + x + ' ' + y + ' ' + 37805 'L' + (x + width) + ' ' + y + ' ' + 37806 'L' + (x + width) + ' ' + (y + height) + ' ' + 37807 'L' + x + ' ' + (y + height) + ' Z'; 37808 } 37809 return newElement; 37810}; 37811 37812/** 37813 * Read `polyline` element to extract and transform 37814 * data, to make it ready for a `path` object. 37815 * 37816 * @param {DOMelement} element Polyline element to transform 37817 * @return {object} Data for a `path` element 37818 */ 37819Pathformer.prototype.polylineToPath = function (element) { 37820 var newElement = {}, 37821 points = element.points.trim().split(' '), 37822 i, path; 37823 37824 // Reformatting if points are defined without commas 37825 if (element.points.indexOf(',') === -1) { 37826 var formattedPoints = []; 37827 for (i = 0; i < points.length; i+=2) { 37828 formattedPoints.push(points[i] + ',' + points[i+1]); 37829 } 37830 points = formattedPoints; 37831 } 37832 37833 // Generate the path.d value 37834 path = 'M' + points[0]; 37835 for(i = 1; i < points.length; i++) { 37836 if (points[i].indexOf(',') !== -1) { 37837 path += 'L' + points[i]; 37838 } 37839 } 37840 newElement.d = path; 37841 return newElement; 37842}; 37843 37844/** 37845 * Read `polygon` element to extract and transform 37846 * data, to make it ready for a `path` object. 37847 * This method rely on polylineToPath, because the 37848 * logic is similar. The path created is just closed, 37849 * so it needs an 'Z' at the end. 37850 * 37851 * @param {DOMelement} element Polygon element to transform 37852 * @return {object} Data for a `path` element 37853 */ 37854Pathformer.prototype.polygonToPath = function (element) { 37855 var newElement = Pathformer.prototype.polylineToPath(element); 37856 37857 newElement.d += 'Z'; 37858 return newElement; 37859}; 37860 37861/** 37862 * Read `ellipse` element to extract and transform 37863 * data, to make it ready for a `path` object. 37864 * 37865 * @param {DOMelement} element ellipse element to transform 37866 * @return {object} Data for a `path` element 37867 */ 37868Pathformer.prototype.ellipseToPath = function (element) { 37869 var newElement = {}, 37870 rx = parseFloat(element.rx) || 0, 37871 ry = parseFloat(element.ry) || 0, 37872 cx = parseFloat(element.cx) || 0, 37873 cy = parseFloat(element.cy) || 0, 37874 startX = cx - rx, 37875 startY = cy, 37876 endX = parseFloat(cx) + parseFloat(rx), 37877 endY = cy; 37878 37879 newElement.d = 'M' + startX + ',' + startY + 37880 'A' + rx + ',' + ry + ' 0,1,1 ' + endX + ',' + endY + 37881 'A' + rx + ',' + ry + ' 0,1,1 ' + startX + ',' + endY; 37882 return newElement; 37883}; 37884 37885/** 37886 * Read `circle` element to extract and transform 37887 * data, to make it ready for a `path` object. 37888 * 37889 * @param {DOMelement} element Circle element to transform 37890 * @return {object} Data for a `path` element 37891 */ 37892Pathformer.prototype.circleToPath = function (element) { 37893 var newElement = {}, 37894 r = parseFloat(element.r) || 0, 37895 cx = parseFloat(element.cx) || 0, 37896 cy = parseFloat(element.cy) || 0, 37897 startX = cx - r, 37898 startY = cy, 37899 endX = parseFloat(cx) + parseFloat(r), 37900 endY = cy; 37901 37902 newElement.d = 'M' + startX + ',' + startY + 37903 'A' + r + ',' + r + ' 0,1,1 ' + endX + ',' + endY + 37904 'A' + r + ',' + r + ' 0,1,1 ' + startX + ',' + endY; 37905 return newElement; 37906}; 37907 37908/** 37909 * Create `path` elements form original element 37910 * and prepared objects 37911 * 37912 * @param {DOMelement} element Original element to transform 37913 * @param {object} pathData Path data (from `toPath` methods) 37914 * @return {DOMelement} Path element 37915 */ 37916Pathformer.prototype.pathMaker = function (element, pathData) { 37917 var i, attr, pathTag = document.createElementNS('http://www.w3.org/2000/svg','path'); 37918 for(i = 0; i < element.attributes.length; i++) { 37919 attr = element.attributes[i]; 37920 if (this.ATTR_WATCH.indexOf(attr.name) === -1) { 37921 pathTag.setAttribute(attr.name, attr.value); 37922 } 37923 } 37924 for(i in pathData) { 37925 pathTag.setAttribute(i, pathData[i]); 37926 } 37927 return pathTag; 37928}; 37929 37930/** 37931 * Parse attributes of a DOM element to 37932 * get an object of attribute => value 37933 * 37934 * @param {NamedNodeMap} attributes Attributes object from DOM element to parse 37935 * @return {object} Object of attributes 37936 */ 37937Pathformer.prototype.parseAttr = function (element) { 37938 var attr, output = {}; 37939 for (var i = 0; i < element.length; i++) { 37940 attr = element[i]; 37941 // Check if no data attribute contains '%', or the transformation is impossible 37942 if (this.ATTR_WATCH.indexOf(attr.name) !== -1 && attr.value.indexOf('%') !== -1) { 37943 throw new Error('Pathformer [parseAttr]: a SVG shape got values in percentage. This cannot be transformed into \'path\' tags. Please use \'viewBox\'.'); 37944 } 37945 output[attr.name] = attr.value; 37946 } 37947 return output; 37948}; 37949 37950 'use strict'; 37951 37952var setupEnv, requestAnimFrame, cancelAnimFrame, parsePositiveInt; 37953 37954/** 37955 * Vivus 37956 * Beta version 37957 * 37958 * Take any SVG and make the animation 37959 * to give give the impression of live drawing 37960 * 37961 * This in more than just inspired from codrops 37962 * At that point, it's a pure fork. 37963 */ 37964 37965/** 37966 * Class constructor 37967 * option structure 37968 * type: 'delayed'|'sync'|'oneByOne'|'script' (to know if the items must be drawn synchronously or not, default: delayed) 37969 * duration: <int> (in frames) 37970 * start: 'inViewport'|'manual'|'autostart' (start automatically the animation, default: inViewport) 37971 * delay: <int> (delay between the drawing of first and last path) 37972 * dashGap <integer> whitespace extra margin between dashes 37973 * pathTimingFunction <function> timing animation function for each path element of the SVG 37974 * animTimingFunction <function> timing animation function for the complete SVG 37975 * forceRender <boolean> force the browser to re-render all updated path items 37976 * selfDestroy <boolean> removes all extra styling on the SVG, and leaves it as original 37977 * 37978 * The attribute 'type' is by default on 'delayed'. 37979 * - 'delayed' 37980 * all paths are draw at the same time but with a 37981 * little delay between them before start 37982 * - 'sync' 37983 * all path are start and finish at the same time 37984 * - 'oneByOne' 37985 * only one path is draw at the time 37986 * the end of the first one will trigger the draw 37987 * of the next one 37988 * 37989 * All these values can be overwritten individually 37990 * for each path item in the SVG 37991 * The value of frames will always take the advantage of 37992 * the duration value. 37993 * If you fail somewhere, an error will be thrown. 37994 * Good luck. 37995 * 37996 * @constructor 37997 * @this {Vivus} 37998 * @param {DOM|String} element Dom element of the SVG or id of it 37999 * @param {Object} options Options about the animation 38000 * @param {Function} callback Callback for the end of the animation 38001 */ 38002function Vivus (element, options, callback) { 38003 38004 setupEnv(); 38005 38006 // Setup 38007 this.isReady = false; 38008 this.setElement(element, options); 38009 this.setOptions(options); 38010 this.setCallback(callback); 38011 38012 if (this.isReady) { 38013 this.init(); 38014 } 38015} 38016 38017/** 38018 * Timing functions 38019 ************************************** 38020 * 38021 * Default functions to help developers. 38022 * It always take a number as parameter (between 0 to 1) then 38023 * return a number (between 0 and 1) 38024 */ 38025Vivus.LINEAR = function (x) {return x;}; 38026Vivus.EASE = function (x) {return -Math.cos(x * Math.PI) / 2 + 0.5;}; 38027Vivus.EASE_OUT = function (x) {return 1 - Math.pow(1-x, 3);}; 38028Vivus.EASE_IN = function (x) {return Math.pow(x, 3);}; 38029Vivus.EASE_OUT_BOUNCE = function (x) { 38030 var base = -Math.cos(x * (0.5 * Math.PI)) + 1, 38031 rate = Math.pow(base,1.5), 38032 rateR = Math.pow(1 - x, 2), 38033 progress = -Math.abs(Math.cos(rate * (2.5 * Math.PI) )) + 1; 38034 return (1- rateR) + (progress * rateR); 38035}; 38036 38037 38038/** 38039 * Setters 38040 ************************************** 38041 */ 38042 38043/** 38044 * Check and set the element in the instance 38045 * The method will not return anything, but will throw an 38046 * error if the parameter is invalid 38047 * 38048 * @param {DOM|String} element SVG Dom element or id of it 38049 */ 38050Vivus.prototype.setElement = function (element, options) { 38051 var onLoad, self; 38052 38053 // Basic check 38054 if (typeof element === 'undefined') { 38055 throw new Error('Vivus [constructor]: "element" parameter is required'); 38056 } 38057 38058 // Set the element 38059 if (element.constructor === String) { 38060 element = document.getElementById(element); 38061 if (!element) { 38062 throw new Error('Vivus [constructor]: "element" parameter is not related to an existing ID'); 38063 } 38064 } 38065 this.parentEl = element; 38066 38067 // Load the SVG with XMLHttpRequest and extract the SVG 38068 if (options && options.file) { 38069 var self = this; 38070 onLoad = function (e) { 38071 var domSandbox = document.createElement('div'); 38072 domSandbox.innerHTML = this.responseText; 38073 38074 var svgTag = domSandbox.querySelector('svg'); 38075 if (!svgTag) { 38076 throw new Error('Vivus [load]: Cannot find the SVG in the loaded file : ' + options.file); 38077 } 38078 38079 self.el = svgTag 38080 self.el.setAttribute('width', '100%'); 38081 self.el.setAttribute('height', '100%'); 38082 self.parentEl.appendChild(self.el) 38083 self.isReady = true; 38084 self.init(); 38085 self = null; 38086 } 38087 38088 var oReq = new window.XMLHttpRequest(); 38089 oReq.addEventListener('load', onLoad); 38090 oReq.open('GET', options.file); 38091 oReq.send(); 38092 return; 38093 } 38094 38095 switch (element.constructor) { 38096 case window.SVGSVGElement: 38097 case window.SVGElement: 38098 case window.SVGGElement: 38099 this.el = element; 38100 this.isReady = true; 38101 break; 38102 38103 case window.HTMLObjectElement: 38104 self = this; 38105 onLoad = function (e) { 38106 if (self.isReady) { 38107 return; 38108 } 38109 self.el = element.contentDocument && element.contentDocument.querySelector('svg'); 38110 if (!self.el && e) { 38111 throw new Error('Vivus [constructor]: object loaded does not contain any SVG'); 38112 } 38113 else if (self.el) { 38114 if (element.getAttribute('built-by-vivus')) { 38115 self.parentEl.insertBefore(self.el, element); 38116 self.parentEl.removeChild(element); 38117 self.el.setAttribute('width', '100%'); 38118 self.el.setAttribute('height', '100%'); 38119 } 38120 self.isReady = true; 38121 self.init(); 38122 self = null; 38123 } 38124 }; 38125 38126 if (!onLoad()) { 38127 element.addEventListener('load', onLoad); 38128 } 38129 break; 38130 38131 default: 38132 throw new Error('Vivus [constructor]: "element" parameter is not valid (or miss the "file" attribute)'); 38133 } 38134}; 38135 38136/** 38137 * Set up user option to the instance 38138 * The method will not return anything, but will throw an 38139 * error if the parameter is invalid 38140 * 38141 * @param {object} options Object from the constructor 38142 */ 38143Vivus.prototype.setOptions = function (options) { 38144 var allowedTypes = ['delayed', 'sync', 'async', 'nsync', 'oneByOne', 'scenario', 'scenario-sync']; 38145 var allowedStarts = ['inViewport', 'manual', 'autostart']; 38146 38147 // Basic check 38148 if (options !== undefined && options.constructor !== Object) { 38149 throw new Error('Vivus [constructor]: "options" parameter must be an object'); 38150 } 38151 else { 38152 options = options || {}; 38153 } 38154 38155 // Set the animation type 38156 if (options.type && allowedTypes.indexOf(options.type) === -1) { 38157 throw new Error('Vivus [constructor]: ' + options.type + ' is not an existing animation `type`'); 38158 } 38159 else { 38160 this.type = options.type || allowedTypes[0]; 38161 } 38162 38163 // Set the start type 38164 if (options.start && allowedStarts.indexOf(options.start) === -1) { 38165 throw new Error('Vivus [constructor]: ' + options.start + ' is not an existing `start` option'); 38166 } 38167 else { 38168 this.start = options.start || allowedStarts[0]; 38169 } 38170 38171 this.isIE = (window.navigator.userAgent.indexOf('MSIE') !== -1 || window.navigator.userAgent.indexOf('Trident/') !== -1 || window.navigator.userAgent.indexOf('Edge/') !== -1 ); 38172 this.duration = parsePositiveInt(options.duration, 120); 38173 this.delay = parsePositiveInt(options.delay, null); 38174 //Uncode addition 38175 this.delayStart = parsePositiveInt(options.delayStart, null); 38176 //#END 38177 this.dashGap = parsePositiveInt(options.dashGap, 1); 38178 this.forceRender = options.hasOwnProperty('forceRender') ? !!options.forceRender : this.isIE; 38179 this.reverseStack = !!options.reverseStack; 38180 this.selfDestroy = !!options.selfDestroy; 38181 this.onReady = options.onReady; 38182 this.map = []; 38183 this.frameLength = this.currentFrame = this.delayUnit = this.speed = this.handle = null; 38184 38185 this.ignoreInvisible = options.hasOwnProperty('ignoreInvisible') ? !!options.ignoreInvisible : false; 38186 38187 this.animTimingFunction = options.animTimingFunction || Vivus.LINEAR; 38188 this.pathTimingFunction = options.pathTimingFunction || Vivus.LINEAR; 38189 38190 if (this.delay >= this.duration) { 38191 throw new Error('Vivus [constructor]: delay must be shorter than duration'); 38192 } 38193}; 38194 38195/** 38196 * Set up callback to the instance 38197 * The method will not return enything, but will throw an 38198 * error if the parameter is invalid 38199 * 38200 * @param {Function} callback Callback for the animation end 38201 */ 38202Vivus.prototype.setCallback = function (callback) { 38203 // Basic check 38204 if (!!callback && callback.constructor !== Function) { 38205 throw new Error('Vivus [constructor]: "callback" parameter must be a function'); 38206 } 38207 this.callback = callback || function () {}; 38208}; 38209 38210 38211/** 38212 * Core 38213 ************************************** 38214 */ 38215 38216/** 38217 * Map the svg, path by path. 38218 * The method return nothing, it just fill the 38219 * `map` array. Each item in this array represent 38220 * a path element from the SVG, with informations for 38221 * the animation. 38222 * 38223 * ``` 38224 * [ 38225 * { 38226 * el: <DOMobj> the path element 38227 * length: <number> length of the path line 38228 * startAt: <number> time start of the path animation (in frames) 38229 * duration: <number> path animation duration (in frames) 38230 * }, 38231 * ... 38232 * ] 38233 * ``` 38234 * 38235 */ 38236Vivus.prototype.mapping = function () { 38237 var i, paths, path, pAttrs, pathObj, totalLength, lengthMeter, timePoint; 38238 timePoint = totalLength = lengthMeter = 0; 38239 paths = this.el.querySelectorAll('path'); 38240 38241 for (i = 0; i < paths.length; i++) { 38242 path = paths[i]; 38243 if (this.isInvisible(path)) { 38244 continue; 38245 } 38246 pathObj = { 38247 el: path, 38248 length: Math.ceil(path.getTotalLength()) 38249 }; 38250 // Test if the path length is correct 38251 if (isNaN(pathObj.length)) { 38252 if (window.console && console.warn) { 38253 console.warn('Vivus [mapping]: cannot retrieve a path element length', path); 38254 } 38255 continue; 38256 } 38257 this.map.push(pathObj); 38258 path.style.strokeDasharray = pathObj.length + ' ' + (pathObj.length + this.dashGap * 2); 38259 path.style.strokeDashoffset = pathObj.length + this.dashGap; 38260 pathObj.length += this.dashGap; 38261 totalLength += pathObj.length; 38262 38263 this.renderPath(i); 38264 } 38265 38266 totalLength = totalLength === 0 ? 1 : totalLength; 38267 this.delay = this.delay === null ? this.duration / 3 : this.delay; 38268 this.delayUnit = this.delay / (paths.length > 1 ? paths.length - 1 : 1); 38269 38270 // Reverse stack if asked 38271 if (this.reverseStack) { 38272 this.map.reverse(); 38273 } 38274 38275 for (i = 0; i < this.map.length; i++) { 38276 pathObj = this.map[i]; 38277 38278 switch (this.type) { 38279 case 'delayed': 38280 pathObj.startAt = this.delayUnit * i; 38281 pathObj.duration = this.duration - this.delay; 38282 break; 38283 38284 case 'oneByOne': 38285 pathObj.startAt = lengthMeter / totalLength * this.duration; 38286 pathObj.duration = pathObj.length / totalLength * this.duration; 38287 break; 38288 38289 case 'sync': 38290 case 'async': 38291 case 'nsync': 38292 pathObj.startAt = 0; 38293 pathObj.duration = this.duration; 38294 break; 38295 38296 case 'scenario-sync': 38297 path = pathObj.el; 38298 pAttrs = this.parseAttr(path); 38299 pathObj.startAt = timePoint + (parsePositiveInt(pAttrs['data-delay'], this.delayUnit) || 0); 38300 pathObj.duration = parsePositiveInt(pAttrs['data-duration'], this.duration); 38301 timePoint = pAttrs['data-async'] !== undefined ? pathObj.startAt : pathObj.startAt + pathObj.duration; 38302 this.frameLength = Math.max(this.frameLength, (pathObj.startAt + pathObj.duration)); 38303 break; 38304 38305 case 'scenario': 38306 path = pathObj.el; 38307 pAttrs = this.parseAttr(path); 38308 pathObj.startAt = parsePositiveInt(pAttrs['data-start'], this.delayUnit) || 0; 38309 pathObj.duration = parsePositiveInt(pAttrs['data-duration'], this.duration); 38310 this.frameLength = Math.max(this.frameLength, (pathObj.startAt + pathObj.duration)); 38311 break; 38312 } 38313 lengthMeter += pathObj.length; 38314 this.frameLength = this.frameLength || this.duration; 38315 } 38316}; 38317 38318/** 38319 * Interval method to draw the SVG from current 38320 * position of the animation. It update the value of 38321 * `currentFrame` and re-trace the SVG. 38322 * 38323 * It use this.handle to store the requestAnimationFrame 38324 * and clear it one the animation is stopped. So this 38325 * attribute can be used to know if the animation is 38326 * playing. 38327 * 38328 * Once the animation at the end, this method will 38329 * trigger the Vivus callback. 38330 * 38331 */ 38332Vivus.prototype.drawer = function () { 38333 var self = this; 38334 this.currentFrame += this.speed; 38335 38336 if (this.currentFrame <= 0) { 38337 this.stop(); 38338 this.reset(); 38339 } else if (this.currentFrame >= this.frameLength) { 38340 this.stop(); 38341 this.currentFrame = this.frameLength; 38342 this.trace(); 38343 if (this.selfDestroy) { 38344 this.destroy(); 38345 } 38346 } else { 38347 this.trace(); 38348 this.handle = requestAnimFrame(function () { 38349 self.drawer(); 38350 }); 38351 return; 38352 } 38353 38354 this.callback(this); 38355 if (this.instanceCallback) { 38356 this.instanceCallback(this); 38357 this.instanceCallback = null; 38358 } 38359}; 38360 38361/** 38362 * Draw the SVG at the current instant from the 38363 * `currentFrame` value. Here is where most of the magic is. 38364 * The trick is to use the `strokeDashoffset` style property. 38365 * 38366 * For optimisation reasons, a new property called `progress` 38367 * is added in each item of `map`. This one contain the current 38368 * progress of the path element. Only if the new value is different 38369 * the new value will be applied to the DOM element. This 38370 * method save a lot of resources to re-render the SVG. And could 38371 * be improved if the animation couldn't be played forward. 38372 * 38373 */ 38374Vivus.prototype.trace = function () { 38375 var i, progress, path, currentFrame; 38376 currentFrame = this.animTimingFunction(this.currentFrame / this.frameLength) * this.frameLength; 38377 for (i = 0; i < this.map.length; i++) { 38378 path = this.map[i]; 38379 progress = (currentFrame - path.startAt) / path.duration; 38380 progress = this.pathTimingFunction(Math.max(0, Math.min(1, progress))); 38381 if (path.progress !== progress) { 38382 path.progress = progress; 38383 path.el.style.strokeDashoffset = Math.floor(path.length * (1 - progress)); 38384 this.renderPath(i); 38385 } 38386 } 38387}; 38388 38389/** 38390 * Method forcing the browser to re-render a path element 38391 * from it's index in the map. Depending on the `forceRender` 38392 * value. 38393 * The trick is to replace the path element by it's clone. 38394 * This practice is not recommended because it's asking more 38395 * ressources, too much DOM manupulation.. 38396 * but it's the only way to let the magic happen on IE. 38397 * By default, this fallback is only applied on IE. 38398 * 38399 * @param {Number} index Path index 38400 */ 38401Vivus.prototype.renderPath = function (index) { 38402 if (this.forceRender && this.map && this.map[index]) { 38403 var pathObj = this.map[index], 38404 newPath = pathObj.el.cloneNode(true); 38405 pathObj.el.parentNode.replaceChild(newPath, pathObj.el); 38406 pathObj.el = newPath; 38407 } 38408}; 38409 38410/** 38411 * When the SVG object is loaded and ready, 38412 * this method will continue the initialisation. 38413 * 38414 * This this mainly due to the case of passing an 38415 * object tag in the constructor. It will wait 38416 * the end of the loading to initialise. 38417 * 38418 */ 38419Vivus.prototype.init = function () { 38420 // Set object variables 38421 this.frameLength = 0; 38422 this.currentFrame = 0; 38423 this.map = []; 38424 38425 // Start 38426 new Pathformer(this.el); 38427 this.mapping(); 38428 this.starter(); 38429 38430 if (this.onReady) { 38431 this.onReady(this); 38432 } 38433}; 38434 38435/** 38436 * Trigger to start of the animation. 38437 * Depending on the `start` value, a different script 38438 * will be applied. 38439 * 38440 * If the `start` value is not valid, an error will be thrown. 38441 * Even if technically, this is impossible. 38442 * 38443 */ 38444Vivus.prototype.starter = function () { 38445 switch (this.start) { 38446 case 'manual': 38447 return; 38448 38449 case 'autostart': 38450 this.play(); 38451 break; 38452 38453 case 'inViewport': 38454 var self = this, 38455 listener = function () { 38456 if (self.isInViewport(self.parentEl, 1)) { 38457 self.play(); 38458 window.removeEventListener('scroll', listener); 38459 //Uncode addition 38460 window.removeEventListener('fp-slide-changed', listener); 38461 window.removeEventListener('fp-slide-scroll', listener); 38462 //#END 38463 } 38464 }; 38465 window.addEventListener('scroll', listener); 38466 //Uncode addition 38467 window.addEventListener('fp-slide-changed', listener); 38468 window.addEventListener('fp-slide-scroll', listener); 38469 //#END 38470 listener(); 38471 break; 38472 } 38473}; 38474 38475 38476/** 38477 * Controls 38478 ************************************** 38479 */ 38480 38481/** 38482 * Get the current status of the animation between 38483 * three different states: 'start', 'progress', 'end'. 38484 * @return {string} Instance status 38485 */ 38486Vivus.prototype.getStatus = function () { 38487 return this.currentFrame === 0 ? 'start' : this.currentFrame === this.frameLength ? 'end' : 'progress'; 38488}; 38489 38490/** 38491 * Reset the instance to the initial state : undraw 38492 * Be careful, it just reset the animation, if you're 38493 * playing the animation, this won't stop it. But just 38494 * make it start from start. 38495 * 38496 */ 38497Vivus.prototype.reset = function () { 38498 return this.setFrameProgress(0); 38499}; 38500 38501/** 38502 * Set the instance to the final state : drawn 38503 * Be careful, it just set the animation, if you're 38504 * playing the animation on rewind, this won't stop it. 38505 * But just make it start from the end. 38506 * 38507 */ 38508Vivus.prototype.finish = function () { 38509 return this.setFrameProgress(1); 38510}; 38511 38512/** 38513 * Set the level of progress of the drawing. 38514 * 38515 * @param {number} progress Level of progress to set 38516 */ 38517Vivus.prototype.setFrameProgress = function (progress) { 38518 progress = Math.min(1, Math.max(0, progress)); 38519 this.currentFrame = Math.round(this.frameLength * progress); 38520 this.trace(); 38521 return this; 38522}; 38523 38524/** 38525 * Play the animation at the desired speed. 38526 * Speed must be a valid number (no zero). 38527 * By default, the speed value is 1. 38528 * But a negative value is accepted to go forward. 38529 *
38530 * And works with float too. 38531 * But don't forget we are in JavaScript, se be nice 38532 * with him and give him a 1/2^x value. 38533 * 38534 * @param {number} speed Animation speed [optional] 38535 */ 38536Vivus.prototype.play = function (speed, callback) { 38537 this.instanceCallback = null; 38538 38539 if (speed && typeof speed === 'function') { 38540 this.instanceCallback = speed; // first parameter is actually the callback function 38541 speed = null; 38542 } 38543 else if (speed && typeof speed !== 'number') { 38544 throw new Error('Vivus [play]: invalid speed'); 38545 } 38546 // if the first parameter wasn't the callback, check if the seconds was 38547 if (callback && typeof(callback) === 'function' && !this.instanceCallback) { 38548 this.instanceCallback = callback; 38549 } 38550 38551 38552 this.speed = speed || 1; 38553 //Uncode addition 38554 if (!this.handle) { 38555 var $this = this, 38556 delay = (this.delayStart != null) ? this.delayStart : 0; 38557 setTimeout(function() { 38558 $this.drawer(); 38559 }, delay); 38560 } 38561 //#END 38562 return this; 38563}; 38564 38565/** 38566 * Stop the current animation, if on progress. 38567 * Should not trigger any error. 38568 * 38569 */ 38570Vivus.prototype.stop = function () { 38571 if (this.handle) { 38572 cancelAnimFrame(this.handle); 38573 this.handle = null; 38574 } 38575 return this; 38576}; 38577 38578/** 38579 * Destroy the instance. 38580 * Remove all bad styling attributes on all 38581 * path tags 38582 * 38583 */ 38584Vivus.prototype.destroy = function () { 38585 this.stop(); 38586 var i, path; 38587 for (i = 0; i < this.map.length; i++) { 38588 path = this.map[i]; 38589 path.el.style.strokeDashoffset = null; 38590 path.el.style.strokeDasharray = null; 38591 this.renderPath(i); 38592 } 38593}; 38594 38595 38596/** 38597 * Utils methods 38598 * include methods from Codrops 38599 ************************************** 38600 */ 38601 38602/** 38603 * Method to best guess if a path should added into 38604 * the animation or not. 38605 * 38606 * 1. Use the `data-vivus-ignore` attribute if set 38607 * 2. Check if the instance must ignore invisible paths 38608 * 3. Check if the path is visible 38609 * 38610 * For now the visibility checking is unstable. 38611 * It will be used for a beta phase. 38612 * 38613 * Other improvments are planned. Like detecting 38614 * is the path got a stroke or a valid opacity. 38615 */ 38616Vivus.prototype.isInvisible = function (el) { 38617 var rect, 38618 ignoreAttr = el.getAttribute('data-ignore'); 38619 38620 if (ignoreAttr !== null) { 38621 return ignoreAttr !== 'false'; 38622 } 38623 38624 if (this.ignoreInvisible) { 38625 rect = el.getBoundingClientRect(); 38626 return !rect.width && !rect.height; 38627 } 38628 else { 38629 return false; 38630 } 38631}; 38632 38633/** 38634 * Parse attributes of a DOM element to 38635 * get an object of {attributeName => attributeValue} 38636 * 38637 * @param {object} element DOM element to parse 38638 * @return {object} Object of attributes 38639 */ 38640Vivus.prototype.parseAttr = function (element) { 38641 var attr, output = {}; 38642 if (element && element.attributes) { 38643 for (var i = 0; i < element.attributes.length; i++) { 38644 attr = element.attributes[i]; 38645 output[attr.name] = attr.value; 38646 } 38647 } 38648 return output; 38649}; 38650 38651/** 38652 * Reply if an element is in the page viewport 38653 * 38654 * @param {object} el Element to observe 38655 * @param {number} h Percentage of height 38656 * @return {boolean} 38657 */ 38658Vivus.prototype.isInViewport = function (el, h) { 38659 var scrolled = this.scrollY(), 38660 viewed = scrolled + this.getViewportH(), 38661 elBCR = el.getBoundingClientRect(), 38662 elHeight = elBCR.height, 38663 elTop = scrolled + elBCR.top, 38664 elBottom = elTop + elHeight; 38665 38666 // if 0, the element is considered in the viewport as soon as it enters. 38667 // if 1, the element is considered in the viewport only when it's fully inside 38668 // value in percentage (1 >= h >= 0) 38669 h = h || 0; 38670 38671 return (elTop + elHeight * h) <= viewed && (elBottom) >= scrolled; 38672}; 38673 38674 38675/** 38676 * Get the viewport height in pixels 38677 * 38678 * @return {integer} Viewport height 38679 */ 38680Vivus.prototype.getViewportH = function () { 38681 var client = this.docElem.clientHeight, 38682 inner = window.innerHeight; 38683 38684 if (client < inner) { 38685 return inner; 38686 } 38687 else { 38688 return client; 38689 } 38690}; 38691 38692/** 38693 * Get the page Y offset 38694 * 38695 * @return {integer} Page Y offset 38696 */ 38697Vivus.prototype.scrollY = function () { 38698 return window.pageYOffset || this.docElem.scrollTop; 38699}; 38700 38701setupEnv = function () { 38702 38703 if (Vivus.prototype.docElem) { 38704 return; 38705 } 38706 38707 /** 38708 * Alias for document element 38709 * 38710 * @type {DOMelement} 38711 */ 38712 Vivus.prototype.docElem = window.document.documentElement; 38713 38714 /** 38715 * Alias for `requestAnimationFrame` or 38716 * `setTimeout` function for deprecated browsers. 38717 * 38718 */ 38719 requestAnimFrame = (function () { 38720 return ( 38721 window.requestAnimationFrame || 38722 window.webkitRequestAnimationFrame || 38723 window.mozRequestAnimationFrame || 38724 window.oRequestAnimationFrame || 38725 window.msRequestAnimationFrame || 38726 function(/* function */ callback){ 38727 return window.setTimeout(callback, 1000 / 60); 38728 } 38729 ); 38730 })(); 38731 38732 /** 38733 * Alias for `cancelAnimationFrame` or 38734 * `cancelTimeout` function for deprecated browsers. 38735 * 38736 */ 38737 cancelAnimFrame = (function () { 38738 return ( 38739 window.cancelAnimationFrame || 38740 window.webkitCancelAnimationFrame || 38741 window.mozCancelAnimationFrame || 38742 window.oCancelAnimationFrame || 38743 window.msCancelAnimationFrame || 38744 function(id){ 38745 return window.clearTimeout(id); 38746 } 38747 ); 38748 })(); 38749}; 38750 38751/** 38752 * Parse string to integer. 38753 * If the number is not positive or null 38754 * the method will return the default value 38755 * or 0 if undefined 38756 * 38757 * @param {string} value String to parse 38758 * @param {*}
38758 defaultValue Value to return if the result parsed is invalid 38759 * @return {number} 38760 * 38761 */ 38762parsePositiveInt = function (value, defaultValue) { 38763 var output = parseInt(value, 10); 38764 return (output >= 0) ? output : defaultValue; 38765}; 38766 38767 38768 if (typeof define === 'function' && define.amd) { 38769 // AMD. Register as an anonymous module. 38770 define([], function() { 38771 return Vivus; 38772 }); 38773 } else if (typeof exports === 'object') { 38774 // Node. Does not work with strict CommonJS, but 38775 // only CommonJS-like environments that support module.exports, 38776 // like Node. 38777 module.exports = Vivus; 38778 } else { 38779 // Browser globals 38780 window.Vivus = Vivus; 38781 } 38782 38783}());
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.