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 var $vmenu = $('body.vmenu .vmenu-container'); 12471 if ( ! $vmenu.length && UNCODE.wwidth > UNCODE.mediaQuery ) { 12472 $(window).on('scroll' + eNamespace + ' orientationchange' + eNamespace, $.proxy(this.winResize, this)); 12473 } 12474 12475 if (this.opts.subIndicators) { 12476 this.$subArrow = $('<span/>').addClass('sub-arrow'); 12477 if (this.opts.subIndicatorsText) { 12478 this.$subArrow.html(this.opts.subIndicatorsText); 12479 } 12480 } 12481 12482 // make sure mouse detection is enabled 12483 initMouseDetection(); 12484 } 12485 12486 // init sub menus 12487 this.$firstSub = this.$root.find('ul').each(function() { self.menuInit($(this)); }).eq(0); 12488 12489 this.$firstLink = this.$root.find('a').eq(0); 12490 12491 // find current item 12492 if (this.opts.markCurrentItem) { 12493 var reDefaultDoc = /(index|default)\.[^#\?\/]*/i, 12494 reHash = /#.*/, 12495 locHref = window.location.href.replace(reDefaultDoc, ''), 12496 locHrefNoHash = locHref.replace(reHash, ''); 12497 this.$root.find('a').each(function() { 12498 var href = this.href.replace(reDefaultDoc, ''), 12499 $this = $(this); 12500 if (href == locHref || href == locHrefNoHash) { 12501 $this.addClass('current'); 12502 if (self.opts.markCurrentTree) { 12503 $this.parents('li').each(function() { 12504 var $this = $(this); 12505 if ($this.dataSM('sub')) { 12506 $this.children('a').addClass('current'); 12507 } 12508 }); 12509 } 12510 } 12511 }); 12512 } 12513 }, 12514 destroy: function() { 12515 this.menuHideAll(); 12516 this.$root 12517 .removeData('smartmenus') 12518 .removeAttr('data-smartmenus-id') 12519 .removeDataSM('level') 12520 .unbind('.smartmenus') 12521 .undelegate('.smartmenus'); 12522 var eNamespace = '.smartmenus' + this.rootId; 12523 $(document).unbind(eNamespace); 12524 $(window).unbind(eNamespace); 12525 if (this.opts.subIndicators) { 12526 this.$subArrow = null; 12527 } 12528 var self = this; 12529 $.each(this.subMenus, function() { 12530 if (this.hasClass('mega-menu')) { 12531 this.find('ul').removeDataSM('in-mega'); 12532 } 12533 if (this.dataSM('shown-before')) { 12534 if (IElt8) { 12535 this.children().css({ styleFloat: '', width: '' }); 12536 } 12537 if (self.opts.subMenusMinWidth || self.opts.subMenusMaxWidth) { 12538 if (!IE6) { 12539 this.css({ width: '', minWidth: '', maxWidth: '' }).removeClass('sm-nowrap'); 12540 } else { 12541 this.css({ width: '', overflowX: '', overflowY: '' }).children().children('a').css('white-space', ''); 12542 } 12543 } 12544 if (this.dataSM('scroll-arrows')) { 12545 this.dataSM('scroll-arrows').remove(); 12546 } 12547 this.css({ zIndex: '', top: '', left: '', marginLeft: '', marginTop: '', display: '' }); 12548 } 12549 if (self.opts.subIndicators) { 12550 this.dataSM('parent-a').removeClass('has-submenu').children('span.sub-arrow').remove(); 12551 } 12552 this.removeDataSM('shown-before') 12553 .removeDataSM('ie-shim') 12554 .removeDataSM('scroll-arrows') 12555 .removeDataSM('parent-a') 12556 .removeDataSM('level') 12557 .removeDataSM('beforefirstshowfired') 12558 .parent().removeDataSM('sub'); 12559 }); 12560 if (this.opts.markCurrentItem) { 12561 this.$root.find('a.current').removeClass('current'); 12562 } 12563 this.$root = null; 12564 this.$firstLink = null; 12565 this.$firstSub = null; 12566 if (this.$disableOverlay) { 12567 this.$disableOverlay.remove(); 12568 this.$disableOverlay = null; 12569 } 12570 menuTrees.splice($.inArray(this, menuTrees), 1); 12571 }, 12572 disable: function(noOverlay) { 12573 if (!this.disabled) { 12574 this.menuHideAll(); 12575 // display overlay over the menu to prevent interaction 12576 if (!noOverlay && !this.opts.isPopup && this.$root.is(':visible')) { 12577 var pos = this.$root.offset(); 12578 this.$disableOverlay = $('<div class="sm-jquery-disable-overlay"/>').css({ 12579 position: 'absolute', 12580 top: pos.top, 12581 left: pos.left, 12582 width: this.$root.outerWidth(), 12583 height: this.$root.outerHeight(),
12584 zIndex: this.getStartZIndex() + 1, 12585 opacity: 0 12586 }).appendTo(document.body); 12587 } 12588 this.disabled = true; 12589 } 12590 }, 12591 docClick: function(e) { 12592 // hide on any click outside the menu or on a menu link 12593 if (this.visibleSubMenus.length && !$.contains(this.$root[0], e.target) || $(e.target).is('a')) { 12594 this.menuHideAll($(e.target)); 12595 } 12596 }, 12597 docTouchEnd: function(e) { 12598 if (!this.lastTouch) { 12599 return; 12600 } 12601 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))) { 12602 if (this.hideTimeout) { 12603 clearTimeout(this.hideTimeout); 12604 this.hideTimeout = 0; 12605 } 12606 // hide with a delay to prevent triggering accidental unwanted click on some page element 12607 var self = this; 12608 this.hideTimeout = setTimeout(function() { self.menuHideAll($(e.target)); }, 350); 12609 } 12610 this.lastTouch = null; 12611 }, 12612 docTouchMove: function(e) { 12613 if (!this.lastTouch) { 12614 return; 12615 } 12616 var touchPoint = e.originalEvent.touches[0]; 12617 this.lastTouch.x2 = touchPoint.pageX; 12618 this.lastTouch.y2 = touchPoint.pageY; 12619 }, 12620 docTouchStart: function(e) { 12621 var touchPoint = e.originalEvent.touches[0]; 12622 this.lastTouch = { x1: touchPoint.pageX, y1: touchPoint.pageY, target: touchPoint.target }; 12623 }, 12624 enable: function() { 12625 if (this.disabled) { 12626 if (this.$disableOverlay) { 12627 this.$disableOverlay.remove(); 12628 this.$disableOverlay = null; 12629 } 12630 this.disabled = false; 12631 } 12632 }, 12633 getHeight: function($elm) { 12634 return this.getOffset($elm, true); 12635 }, 12636 // returns precise width/height float values in IE9+, FF4+, recent WebKit 12637 // http://vadikom.com/dailies/offsetwidth-offsetheight-useless-in-ie9-firefox4/ 12638 getOffset: function($elm, height) { 12639 var old, 12640 $win = $(window), 12641 winW = $win.width(); 12642 if ($elm.css('display') == 'none') { 12643 old = { position: $elm[0].style.position, visibility: $elm[0].style.visibility }; 12644 $elm.css({ position: 'absolute', visibility: 'hidden' }).show(); 12645 if ( 12646 ($('body').hasClass('menu-mobile-off-canvas') && winW < 960 && $elm.closest('.main-menu-container').length) 12647 || 12648 ($('body').hasClass('vmenu-offcanvas-overlay') && winW >= 960 && $elm.closest('.main-menu-container').length && !$elm.closest('.menu-horizontal-inner').length) 12649 ) { 12650 $elm.closest('li').addClass('smartmenu-open-item'); 12651 } 12652 } 12653 var defaultView = $elm[0].ownerDocument.defaultView, 12654 compStyle = defaultView && defaultView.getComputedStyle && defaultView.getComputedStyle($elm[0], null), 12655 val = compStyle && parseFloat(compStyle[height ? 'height' : 'width']); 12656 if (val) { 12657 val += parseFloat(compStyle[height ? 'paddingTop' : 'paddingLeft']) 12658 + parseFloat(compStyle[height ? 'paddingBottom' : 'paddingRight']) 12659 + parseInt(compStyle[height ? 'borderTopWidth' : 'borderLeftWidth']) 12660 + parseInt(compStyle[height ? 'borderBottomWidth' : 'borderRightWidth']); 12661 } else { 12662 val = height ? $elm[0].offsetHeight : $elm[0].offsetWidth; 12663 } 12664 if (old) { 12665 $elm.hide().css(old); 12666 } 12667 return val; 12668 }, 12669 getWidth: function($elm) { 12670 return this.getOffset($elm); 12671 }, 12672 getStartZIndex: function() { 12673 var zIndex = parseInt(this.$root.css('z-index')); 12674 return !isNaN(zIndex) ? zIndex : 1; 12675 }, 12676 handleEvents: function() { 12677 return !this.disabled && this.isCSSOn(); 12678 }, 12679 handleItemEvents: function($a) { 12680 return this.handleEvents() && !this.isLinkInMegaMenu($a); 12681 }, 12682 isCollapsible: function() { 12683 return this.$firstSub.css('position') == 'static'; 12684 }, 12685 isCSSOn: function() { 12686 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'; 12687 }, 12688 isFixed: function() { 12689 return this.$root.css('position') == 'fixed'; 12690 }, 12691 isLinkInMegaMenu: function($a) { 12692 return !$a.parent().parent().dataSM('level'); 12693 }, 12694 isTouchMode: function() { 12695 return !mouse || this.isCollapsible(); 12696 }, 12697 itemActivate: function($a) { 12698 var $li = $a.parent(), 12699 $ul = $li.parent(), 12700 level = $ul.dataSM('level'); 12701 // 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 12702 if (level > 1 && (!this.activatedItems[level - 2] || this.activatedItems[level - 2][0] != $ul.dataSM('parent-a')[0])) { 12703 var self = this; 12704 $($ul.parentsUntil('[data-smartmenus-id]', 'ul').get().reverse()).add($ul).each(function() { 12705 self.itemActivate($(this).dataSM('parent-a')); 12706 }); 12707 } 12708 // hide any visible deeper level sub menus 12709 if (this.visibleSubMenus.length > level) { 12710 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--) { 12711 //if ( !this.visibleSubMenus[i].closest('.menu-accordion').length ) { 12712 this.menuHide(this.visibleSubMenus[i]); 12713 //} 12714 } 12715 } 12716 // save new active item and sub menu for this level 12717 this.activatedItems[level - 1] = $a; 12718 this.visibleSubMenus[level - 1] = $ul; 12719 if (this.$root.triggerHandler('activate.smapi', $a[0]) === false) { 12720 return; 12721 } 12722 // show the sub menu if this item has one 12723 var $sub = $li.dataSM('sub'); 12724 if ($sub && (this.isTouchMode() || (!this.opts.showOnClick || this.clickActivated))) { 12725 this.menuShow($sub); 12726 } 12727 }, 12728 itemBlur: function(e) { 12729 var $a = $(e.currentTarget); 12730 if (!this.handleItemEvents($a)) { 12731 return; 12732 } 12733 this.$root.triggerHandler('blur.smapi', $a[0]); 12734 }, 12735 itemClick: function(e) { 12736 var $a = $(e.currentTarget); 12737 12738 if (!this.handleItemEvents($a)) { 12739 return; 12740 } 12741 $a.removeDataSM('mousedown'); 12742 if (this.$root.triggerHandler('click.smapi', $a[0]) === false) { 12743 return false;
12744 } 12745 var $sub = $a.parent().dataSM('sub'); 12746 if (this.isTouchMode()) { 12747 // undo fix: prevent the address bar on iPhone from sliding down when expanding a sub menu 12748 if ($a.dataSM('href')) { 12749 $a.attr('href', $a.dataSM('href')).removeDataSM('href'); 12750 } 12751 // if the sub is not visible 12752 if ($sub && (!$sub.dataSM('shown-before') || !$sub.is(':visible'))) { 12753 // try to activate the item and show the sub 12754 this.itemActivate($a); 12755 // if "itemActivate" showed the sub, prevent the click so that the link is not loaded 12756 // 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 12757 if ($sub.is(':visible')) { 12758 return false; 12759 } 12760 } 12761 } else if (this.opts.showOnClick && $a.parent().parent().dataSM('level') == 1 && $sub) { 12762 this.clickActivated = true; 12763 this.menuShow($sub); 12764 return false; 12765 } 12766 if ($a.hasClass('disabled')) { 12767 return false; 12768 } 12769 if (this.$root.triggerHandler('select.smapi', $a[0]) === false) { 12770 return false; 12771 } 12772 }, 12773 itemDown: function(e) { 12774 var $a = $(e.currentTarget); 12775 if (!this.handleItemEvents($a)) { 12776 return; 12777 } 12778 $a.dataSM('mousedown', true); 12779 }, 12780 itemEnter: function(e) { 12781 var $a = $(e.currentTarget); 12782 if (!this.handleItemEvents($a)) { 12783 return; 12784 } 12785 if (!this.isTouchMode()) { 12786 if (this.showTimeout) { 12787 clearTimeout(this.showTimeout); 12788 this.showTimeout = 0; 12789 } 12790 var self = this; 12791 this.showTimeout = setTimeout(function() { self.itemActivate($a); }, this.opts.showOnClick && $a.parent().parent().dataSM('level') == 1 ? 1 : this.opts.showTimeout); 12792 } 12793 this.$root.triggerHandler('mouseenter.smapi', $a[0]); 12794 }, 12795 itemFocus: function(e) { 12796 var $a = $(e.currentTarget); 12797 if (!this.handleItemEvents($a)) { 12798 return; 12799 } 12800 // 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 12801 if ((!this.isTouchMode() || !$a.dataSM('mousedown')) && (!this.activatedItems.length || this.activatedItems[this.activatedItems.length - 1][0] != $a[0])) { 12802 this.itemActivate($a); 12803 } 12804 this.$root.triggerHandler('focus.smapi', $a[0]); 12805 }, 12806 itemLeave: function(e) { 12807 var $a = $(e.currentTarget); 12808 if (!this.handleItemEvents($a)) { 12809 return; 12810 } 12811 if (!this.isTouchMode()) { 12812 if ($a[0].blur) { 12813 $a[0].blur(); 12814 } 12815 if (this.showTimeout) { 12816 clearTimeout(this.showTimeout); 12817 this.showTimeout = 0; 12818 } 12819 } 12820 $a.removeDataSM('mousedown'); 12821 this.$root.triggerHandler('mouseleave.smapi', $a[0]); 12822 }, 12823 itemTouchEnd: function(e) { 12824 var $a = $(e.currentTarget); 12825 if (!this.handleItemEvents($a)) { 12826 return; 12827 } 12828 // prevent the address bar on iPhone from sliding down when expanding a sub menu 12829 var $sub = $a.parent().dataSM('sub'); 12830 if ($a.attr('href').charAt(0) !== '#' && $sub && (!$sub.dataSM('shown-before') || !$sub.is(':visible'))) { 12831 $a.dataSM('href', $a.attr('href')); 12832 $a.attr('href', '#'); 12833 } 12834 }, 12835 menuFixLayout: function($ul) { 12836 // fixes a menu that is being shown for the first time 12837 if (!$ul.dataSM('shown-before')) { 12838 $ul.hide().dataSM('shown-before', true); 12839 // fix the layout of the items in IE<8 12840 if (IElt8) { 12841 $ul.children().css({ styleFloat: 'left', width: '100%' }); 12842 } 12843 } 12844 }, 12845 menuHide: function($sub) { 12846 if (this.$root.triggerHandler('beforehide.smapi', $sub[0]) === false) { 12847 return; 12848 } 12849 $sub.stop(true, true); 12850 if ($sub.is(':visible')) { 12851 var complete = function() { 12852 // unset z-index 12853 if (IElt9) { 12854 $sub.parent().css('z-index', ''); 12855 } else { 12856 $sub.css('z-index', ''); 12857 } 12858 }; 12859 // if sub is collapsible (mobile view) 12860 if (this.isCollapsible()) { 12861 if (this.opts.collapsibleHideFunction) { 12862 this.opts.collapsibleHideFunction.call(this, $sub, complete); 12863 } else { 12864 $sub.hide(this.opts.collapsibleHideDuration, complete); 12865 } 12866 } else { 12867 if (this.opts.hideFunction) { 12868 this.opts.hideFunction.call(this, $sub, complete); 12869 } else { 12870 $sub.hide(this.opts.hideDuration, complete); 12871 } 12872 } 12873 // remove IE iframe shim 12874 if ($sub.dataSM('ie-shim')) { 12875 $sub.dataSM('ie-shim').remove(); 12876 } 12877 // deactivate scrolling if it is activated for this sub 12878 if ($sub.dataSM('scroll')) { 12879 $sub.unbind('.smartmenus_scroll').removeDataSM('scroll').dataSM('scroll-arrows').hide(); 12880 } 12881 // unhighlight parent item 12882 $sub.dataSM('parent-a').removeClass('highlighted'); 12883 var level = $sub.dataSM('level'); 12884 this.activatedItems.splice(level - 1, 1); 12885 this.visibleSubMenus.splice(level - 1, 1); 12886 this.$root.triggerHandler('hide.smapi', $sub[0]); 12887 } 12888 }, 12889 menuHideAll: function($item) { 12890 if ($item != undefined && $item.parent().hasClass('menu-item') && !$item.parent().hasClass('menu-item-has-children')) return; 12891 var $win = $(window), 12892 winW = $win.width(); 12893 if (this.showTimeout) { 12894 clearTimeout(this.showTimeout); 12895 this.showTimeout = 0; 12896 } 12897 // hide all subs 12898 for (var i = this.visibleSubMenus.length - 1; i > 0; i--) { 12899 if ( this.visibleSubMenus[i].closest('.smartmenu-open-item').length ) { 12900 if ( $item != undefined && $item.closest('.smartmenu-open-item').length ) { 12901 this.menuHide(this.visibleSubMenus[i]); 12902 $(this.visibleSubMenus[i]).closest('.smartmenu-open-item').removeClass('smartmenu-open-item'); 12903 } else { 12904 return; 12905 } 12906 } else { 12907 //if ( !this.visibleSubMenus[i].closest('.menu-accordion').length ) { 12908 this.menuHide(this.visibleSubMenus[i]); 12909 //} 12910 } 12911 } 12912 // hide root if it's popup 12913 if (this.opts.isPopup) { 12914 this.$root.stop(true, true); 12915 if (this.$root.is(':visible')) { 12916 if (this.opts.hideFunction) { 12917 this.opts.hideFunction.call(this, this.$root); 12918 } else { 12919 this.$root.hide(this.opts.hideDuration); 12920 } 12921 // remove IE iframe shim 12922 if (this.$root.dataSM('ie-shim')) { 12923 this.$root.dataSM('ie-shim').remove(); 12924 } 12925 } 12926 } 12927 this.activatedItems = []; 12928 this.visibleSubMenus = []; 12929 this.clickActivated = false;
12930 // reset z-index increment 12931 this.zIndexInc = 0; 12932 }, 12933 menuIframeShim: function($ul) { 12934 // create iframe shim for the menu 12935 if (IE && this.opts.overlapControlsInIE && !$ul.dataSM('ie-shim')) { 12936 $ul.dataSM('ie-shim', $('<iframe/>').attr({ src: 'javascript:0', tabindex: -9 }) 12937 .css({ position: 'absolute', top: 'auto', left: '0', opacity: 0, border: '0' }) 12938 ); 12939 } 12940 }, 12941 menuInit: function($ul) { 12942 if (!$ul.dataSM('in-mega')) { 12943 this.subMenus.push($ul); 12944 // mark UL's in mega drop downs (if any) so we can neglect them 12945 if ($ul.hasClass('mega-menu')) { 12946 $ul.find('ul').dataSM('in-mega', true); 12947 } 12948 // get level (much faster than, for example, using parentsUntil) 12949 var level = 2, 12950 par = $ul[0]; 12951 while (par != null && par.parentNode != null && ( par = par.parentNode.parentNode) != this.$root[0]) { 12952 level++; 12953 } 12954 // cache stuff 12955 $ul.dataSM('parent-a', $ul.prevAll('a').eq(-1)) 12956 .dataSM('level', level) 12957 .parent().dataSM('sub', $ul); 12958 // add sub indicator to parent item 12959 if (this.opts.subIndicators) { 12960 $ul.dataSM('parent-a').addClass('has-submenu')[this.opts.subIndicatorsPos](this.$subArrow.clone()); 12961 } 12962 } 12963 }, 12964 menuPosition: function($sub) { 12965 var fixIE = $('html.ie').length; 12966 // if (fixIE) { 12967 // var $rowParent = $($sub).closest('.main-menu-container'); 12968 // $rowParent.height($rowParent.height()); 12969 // } 12970 var $a = $sub.dataSM('parent-a'), 12971 $li = $sub.parent(), 12972 $ul = $sub.parent().parent(), 12973 // $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'), 12974 $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'), 12975 level = $sub.dataSM('level'), 12976 subW = this.getWidth($sub), 12977 subH = this.getHeight($sub), 12978 itemOffset = $a.offset(), 12979 itemX = itemOffset.left, 12980 itemY = itemOffset.top, 12981 itemW = this.getWidth($a), 12982 itemH = this.getHeight($a), 12983 $win = $(window), 12984 winX = $win.scrollLeft(), 12985 winY = $win.scrollTop(), 12986 winW = $win.width(), 12987 winH = $win.height(), 12988 containerW = $container.width(), 12989 containerOffsetX = containerW + ((winW - containerW) / 2), 12990 horizontalParent = $ul.hasClass('sm') && !$ul.hasClass('sm-vertical'), 12991 subOffsetX = level == 2 ? this.opts.mainMenuSubOffsetX : this.opts.subMenusSubOffsetX, 12992 subOffsetY = level == 2 ? this.opts.mainMenuSubOffsetY : this.opts.subMenusSubOffsetY, 12993 x, y, leftPos; 12994 12995 if (horizontalParent) { 12996 x = this.opts.rightToLeftSubMenus ? itemW - subW - subOffsetX : subOffsetX; 12997 y = this.opts.bottomToTopSubMenus ? -subH - subOffsetY : itemH + subOffsetY; 12998 } else { 12999 x = this.opts.rightToLeftSubMenus ? subOffsetX - subW : subW - subOffsetX; 13000 y = this.opts.bottomToTopSubMenus ? itemH - subOffsetY - subH : subOffsetY; 13001 } 13002 if (this.opts.keepInViewport && !this.isCollapsible()) { 13003 if (this.isFixed()) { 13004 itemX -= winX; 13005 itemY -= winY; 13006 winX = winY = 0; 13007 } 13008 var absX = itemX + x, 13009 absY = itemY + y; 13010 if (this.opts.rightToLeftSubMenus && absX < winX) { 13011 x = horizontalParent ? winX - absX + x : itemW - subOffsetX; 13012 } else if (!this.opts.rightToLeftSubMenus && absX + subW > winX + containerOffsetX ) { 13013 x = horizontalParent ? winX + containerOffsetX - subW - absX + x : subOffsetX - subW; 13014 } 13015 if (!horizontalParent) { 13016 if (subH < winH && absY + subH > winY + winH) { 13017 y += winY + winH - subH - absY; 13018 } else if (subH >= winH || absY < winY) { 13019 y += winY - absY; 13020 } 13021 } 13022 // do we need scrolling? 13023 // 0.49 added for the sake of IE9/FF4+ where we might be dealing with float numbers for "subH" 13024 if (mouse && (horizontalParent && (absY + subH > winY + winH + 0.49 || absY < winY) || !horizontalParent && subH > winH + 0.49)) { 13025 var self = this; 13026 if (!$sub.dataSM('scroll-arrows')) { 13027 $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]]) 13028 .bind({ 13029 mouseenter: function() { self.menuScroll($sub, $(this).hasClass('scroll-up')); }, 13030 mouseleave: function(e) { 13031 self.menuScrollStop($sub); 13032 self.menuScrollOut($sub, e); 13033 }, 13034 'mousewheel DOMMouseScroll': function(e) { e.preventDefault(); } 13035 }) 13036 .insertAfter($sub) 13037 ); 13038 } 13039 // bind events to show/hide arrows on hover and save scrolling data for this sub 13040 var vportY = winY - (itemY + itemH); 13041 $sub.dataSM('scroll', { 13042 vportY: vportY, 13043 subH: subH, 13044 winH: winH, 13045 step: 1 13046 }) 13047 .bind({ 13048 'mouseover.smartmenus_scroll': function(e) { self.menuScrollOver($sub, e); }, 13049 'mouseout.smartmenus_scroll': function(e) { self.menuScrollOut($sub, e); }, 13050 'mousewheel.smartmenus_scroll DOMMouseScroll.smartmenus_scroll': function(e) { self.menuScrollMousewheel($sub, e); } 13051 }) 13052 .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
13052StartZIndex() + this.zIndexInc }) 13053 .eq(0).css('margin-top', vportY).end() 13054 .eq(1).css('margin-top', vportY + winH - this.getHeight($sub.dataSM('scroll-arrows').eq(1))).end() 13055 .eq(horizontalParent && this.opts.bottomToTopSubMenus ? 0 : 1).show(); 13056 } 13057 } 13058 if ( !$sub.closest('.menu-accordion').length ) { 13059 var rightPos = 'auto'; 13060 if ( $sub.closest('.grid-filters').length ) { 13061 if ( $sub.closest('.text-right').length ) { 13062 leftPos = '0px'; 13063 rightPos = 'auto'; 13064 } else { 13065 leftPos = 'auto'; 13066 rightPos = '0px'; 13067 } 13068 x = 0; 13069 } else { 13070 if ( $sub.hasClass('mega-menu-inner') ) { 13071 $sub.css({ width: containerW}); 13072 leftPos = -1 * (parseFloat($sub.closest('ul.menu-smart').offset().left) - parseFloat($sub.closest('.row-menu').offset().left)); 13073 if ( ! $('body').hasClass('megamenu-side-to-side') ) { 13074 leftPos += parseFloat($sub.closest('.row-menu-inner').css('paddingLeft')); 13075 } 13076 x = 0; 13077 } else { 13078 leftPos = (level > 2 ? $li.position().left - parseFloat($li.closest('ul').css('paddingLeft')) : $li.position().left ) + 'px'; 13079 x = (level > 2 && x >= 0) ? x + 1 : x - 1; 13080 } 13081 } 13082 } 13083 13084 // $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) }); 13085 $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) }); 13086 // IE iframe shim 13087 this.menuIframeShim($sub); 13088 if ($sub.dataSM('ie-shim')) { 13089 $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) }); 13090 } 13091 }, 13092 menuScroll: function($sub, up, wheel) { 13093 var y = parseFloat($sub.css('margin-top')), 13094 scroll = $sub.dataSM('scroll'), 13095 navH = $('.navbar-main').outerHeight(), 13096 end = scroll.vportY + (up ? navH + 54 : scroll.winH - scroll.subH), 13097 step = wheel || !this.opts.scrollAccelerate ? this.opts.scrollStep : Math.floor($sub.dataSM('scroll').step); 13098 $sub.add($sub.dataSM('ie-shim')).css('margin-top', Math.abs(end - y) > step ? y + (up ? step : -step) : end); 13099 y = parseFloat($sub.css('margin-top')); 13100 // show opposite arrow if appropriate 13101 if (up && y + scroll.subH > scroll.vportY + scroll.winH || !up && y < scroll.vportY) { 13102 $sub.dataSM('scroll-arrows').eq(up ? 1 : 0).show(); 13103 } 13104 // accelerate when not using mousewheel to scroll 13105 if (!wheel && this.opts.scrollAccelerate && $sub.dataSM('scroll').step < this.opts.scrollStep) { 13106 $sub.dataSM('scroll').step += 0.5; 13107 } 13108 // "y" and "end" might be float numbers in IE9/FF4+ so this weird way to check is used 13109 if (Math.abs(y - end) < 1) { 13110 $sub.dataSM('scroll-arrows').eq(up ? 0 : 1).hide(); 13111 $sub.dataSM('scroll').step = 1; 13112 } else if (!wheel) { 13113 var self = this; 13114 this.scrollTimeout = setTimeout(function() { self.menuScroll($sub, up); }, this.opts.scrollInterval); 13115 } 13116 }, 13117 menuScrollMousewheel: function($sub, e) { 13118 var $closestSub = $(e.target).closest('ul'); 13119 while ($closestSub.dataSM('in-mega')) { 13120 $closestSub = $closestSub.parent().closest('ul'); 13121 } 13122 if ($closestSub[0] == $sub[0]) { 13123 var up = (e.originalEvent.wheelDelta || -e.originalEvent.detail) > 0; 13124 if ($sub.dataSM('scroll-arrows').eq(up ? 0 : 1).is(':visible')) { 13125 this.menuScroll($sub, up, true); 13126 } 13127 } 13128 if ( ! $sub.hasClass('mega-menu-inner') ) { 13129 e.preventDefault(); 13130 } 13131 }, 13132 menuScrollOut: function($sub, e) { 13133 var reClass = /^scroll-(up|down)/, 13134 $closestSub = $(e.relatedTarget).closest('ul'); 13135 while ($closestSub.dataSM('in-mega')) { 13136 $closestSub = $closestSub.parent().closest('ul'); 13137 } 13138 if (!reClass.test((e.relatedTarget || '').className) && ($sub[0] != e.relatedTarget && !$.contains($sub[0], e.relatedTarget) || $closestSub[0] != $sub[0])) { 13139 $sub.dataSM('scroll-arrows').css('visibility', 'hidden'); 13140 } 13141 }, 13142 menuScrollOver: function($sub, e) { 13143 var reClass = /^scroll-(up|down)/, 13144 $closestSub = $(e.target).closest('ul'); 13145 while ($closestSub.dataSM('in-mega')) { 13146 $closestSub = $closestSub.parent().closest('ul'); 13147 } 13148 if (!reClass.test(e.target.className) && $closestSub[0] == $sub[0]) { 13149 $sub.dataSM('scroll-arrows').css('visibility', 'visible'); 13150 } 13151 }, 13152 menuScrollStop: function($sub) { 13153 if (this.scrollTimeout) { 13154 clearTimeout(this.scrollTimeout); 13155 this.scrollTimeout = 0; 13156 $sub.dataSM('scroll').step = 1; 13157 } 13158 }, 13159 menuShow: function($sub) { 13160 if (!$sub.dataSM('beforefirstshowfired')) { 13161 $sub.dataSM('beforefirstshowfired', true); 13162 if (this.$root.triggerHandler('beforefirstshow.smapi', $sub[0]) === false) { 13163 return; 13164 } 13165 } 13166 if (this.$root.triggerHandler('beforeshow.smapi', $sub[0]) === false) { 13167 return; 13168 } 13169 this.menuFixLayout($sub); 13170 $sub.stop(true, true); 13171 if (!$sub.is(':visible')) { 13172 $sub.css({ 13173 'visibility': 'visible', 13174 'pointer-events': 'auto', 13175 }); 13176 // set z-index - for IE < 9 set it to the parent LI
13177 var zIndex = this.getStartZIndex() + (++this.zIndexInc); 13178 if (IElt9) { 13179 $sub.parent().css('z-index', zIndex); 13180 } else { 13181 $sub.css('z-index', zIndex); 13182 } 13183 // highlight parent item 13184 if (this.opts.keepHighlighted || this.isCollapsible()) { 13185 if ($sub.dataSM('parent-a').attr('data-type') != 'title') 13186 $sub.dataSM('parent-a').addClass('highlighted'); 13187 } 13188 // min/max-width fix - no way to rely purely on CSS as all UL's are nested 13189 if (this.opts.subMenusMinWidth || this.opts.subMenusMaxWidth) { 13190 if (!IElt8) { 13191 $sub.css({ width: ($sub.hasClass('mega-menu-inner')) ? $('.box-container').outerWidth() + 'px' : 'auto', minWidth: '', maxWidth: '' }).addClass('sm-nowrap'); 13192 if (this.opts.subMenusMinWidth) { 13193 $sub.css('min-width', this.opts.subMenusMinWidth); 13194 } 13195 if (this.opts.subMenusMaxWidth) { 13196 var noMaxWidth = this.getWidth($sub); 13197 if ( ! $sub.hasClass('mega-menu-inner') ) { 13198 $sub.css('max-width', this.opts.subMenusMaxWidth); 13199 } 13200 if (noMaxWidth > this.getWidth($sub)) { 13201 $sub.removeClass('sm-nowrap').css('width', this.opts.subMenusMaxWidth); 13202 } 13203 } 13204 // IE6,7 13205 } else { 13206 $sub.children().css('styleFloat', 'none'); 13207 if (IE6) { 13208 $sub.width(this.opts.subMenusMinWidth ? this.opts.subMenusMinWidth : 1) 13209 .children().children('a').css('white-space', 'nowrap'); 13210 } else { // IE7 13211 $sub.css({ width: ($sub.hasClass('mega-menu-inner')) ? $('.box-container').outerWidth() + 'px' : 'auto', minWidth: '', maxWidth: '' }).addClass('sm-nowrap'); 13212 if (this.opts.subMenusMinWidth) { 13213 $sub.css('min-width', this.opts.subMenusMinWidth); 13214 } 13215 } 13216 if (this.opts.subMenusMaxWidth) { 13217 var noMaxWidth = $sub.width(); 13218 if (IE6) { 13219 var maxWidth = $sub.css({ width: this.opts.subMenusMaxWidth, overflowX: 'hidden', overflowY: 'hidden' }).width(); 13220 if (noMaxWidth > maxWidth) { 13221 $sub.css({ width: maxWidth, overflowX: 'visible', overflowY: 'visible' }).children().children('a').css('white-space', ''); 13222 } else { 13223 $sub.css({ width: noMaxWidth, overflowX: 'visible', overflowY: 'visible' }); 13224 } 13225 } else { // IE7 13226 if ( ! $sub.hasClass('mega-menu-inner') ) { 13227 $sub.css('max-width', this.opts.subMenusMaxWidth); 13228 } 13229 if (noMaxWidth > $sub.width()) { 13230 $sub.removeClass('sm-nowrap').css('width', this.opts.subMenusMaxWidth); 13231 } else { 13232 $sub.width(noMaxWidth); 13233 } 13234 } 13235 } else { 13236 $sub.width($sub.width()); 13237 } 13238 $sub.children().css('styleFloat', 'left'); 13239 } 13240 } 13241 if ( $sub.hasClass('mega-menu-inner') && $('body').hasClass('scrollable-megamenu') && UNCODE.wwidth > UNCODE.mediaQuery ) { 13242 var $nav = $('.navbar-main'), 13243 navH = 0, 13244 navTop = 0, 13245 $vmenu = $('body.vmenu .vmenu-container, body.menu-overlay .vmenu-container'), 13246 $offcanvas = $('body.menu-offcanvas .vmenu-container'); 13247 if ( $nav.length && typeof $nav[0] !== 'undefined' ) { 13248 var navRect = $nav[0].getBoundingClientRect(); 13249 navH = navRect.height; 13250 navTop = navRect.top; 13251 } 13252 if ( ! $vmenu.length && ! $offcanvas.length ) { 13253 $sub.css({ maxHeight: UNCODE.wheight - navH }); 13254 } 13255 } 13256 this.menuPosition($sub); 13257 // insert IE iframe shim 13258 if ($sub.dataSM('ie-shim')) { 13259 $sub.dataSM('ie-shim').insertBefore($sub); 13260 } 13261 var complete = function() { 13262 // fix: "overflow: hidden;" is not reset on animation complete in jQuery < 1.9.0 in Chrome when global "box-sizing: border-box;" is used 13263 $sub.css('overflow', ''); 13264 }; 13265 // if sub is collapsible (mobile view) 13266 if (this.isCollapsible()) { 13267 if (this.opts.collapsibleShowFunction) { 13268 this.opts.collapsibleShowFunction.call(this, $sub, complete); 13269 } else { 13270 $sub.show(this.opts.collapsibleShowDuration, complete); 13271 } 13272 } else { 13273 if (this.opts.showFunction) { 13274 this.opts.showFunction.call(this, $sub, complete); 13275 } else { 13276 $sub.show(this.opts.showDuration, complete); 13277 } 13278 } 13279 // save new sub menu for this level 13280 this.visibleSubMenus[$sub.dataSM('level') - 1] = $sub; 13281 this.$root.triggerHandler('show.smapi', $sub[0]); 13282 } 13283 }, 13284 popupHide: function(noHideTimeout) { 13285 if (this.hideTimeout) { 13286 clearTimeout(this.hideTimeout); 13287 this.hideTimeout = 0; 13288 } 13289 var self = this; 13290 this.hideTimeout = setTimeout(function() { 13291 self.menuHideAll(); 13292 }, noHideTimeout ? 1 : this.opts.hideTimeout); 13293 }, 13294 popupShow: function(left, top) { 13295 if (!this.opts.isPopup) { 13296 alert('SmartMenus jQuery Error:\n\nIf you want to show this menu via the "popupShow" method, set the isPopup:true option.'); 13297 return; 13298 } 13299 if (this.hideTimeout) { 13300 clearTimeout(this.hideTimeout); 13301 this.hideTimeout = 0; 13302 } 13303 this.menuFixLayout(this.$root); 13304 this.$root.stop(true, true); 13305 if (!this.$root.is(':visible')) { 13306 this.$root.css({ left: left, top: top }); 13307 // IE iframe shim 13308 this.menuIframeShim(this.$root); 13309 if (this.$root.dataSM('ie-shim')) { 13310 this.$root.dataSM('ie-shim').css({ zIndex: this.$root.css('z-index'), width: this.getWidth(this.$root), height: this.getHeight(this.$root), left
13310: left, top: top }).insertBefore(this.$root); 13311 } 13312 // show menu 13313 if (this.opts.showFunction) { 13314 this.opts.showFunction.call(this, this.$root); 13315 } else { 13316 this.$root.show(this.opts.showDuration); 13317 } 13318 this.visibleSubMenus[0] = this.$root; 13319 } 13320 }, 13321 refresh: function() { 13322 this.menuHideAll(); 13323 this.$root.find('ul').each(function() { 13324 var $this = $(this); 13325 if ($this.dataSM('scroll-arrows')) { 13326 $this.dataSM('scroll-arrows').remove(); 13327 } 13328 }) 13329 .removeDataSM('in-mega') 13330 .removeDataSM('shown-before') 13331 .removeDataSM('ie-shim') 13332 .removeDataSM('scroll-arrows') 13333 .removeDataSM('parent-a') 13334 .removeDataSM('level') 13335 .removeDataSM('beforefirstshowfired'); 13336 this.$root.find('a.has-submenu').removeClass('has-submenu') 13337 .parent().removeDataSM('sub'); 13338 if (this.opts.subIndicators) { 13339 this.$root.find('span.sub-arrow').remove(); 13340 } 13341 if (this.opts.markCurrentItem) { 13342 this.$root.find('a.current').removeClass('current'); 13343 } 13344 this.subMenus = []; 13345 this.init(true); 13346 }, 13347 rootOut: function(e) { 13348 if (!this.handleEvents() || this.isTouchMode() || e.target == this.$root[0]) { 13349 return; 13350 } 13351 if (this.hideTimeout) { 13352 clearTimeout(this.hideTimeout); 13353 this.hideTimeout = 0; 13354 } 13355 if (!this.opts.showOnClick || !this.opts.hideOnClick) { 13356 var self = this; 13357 this.hideTimeout = setTimeout(function() { self.menuHideAll(); }, this.opts.hideTimeout); 13358 } 13359 }, 13360 rootOver: function(e) { 13361 if (!this.handleEvents() || this.isTouchMode() || e.target == this.$root[0]) { 13362 return; 13363 } 13364 if (this.hideTimeout) { 13365 clearTimeout(this.hideTimeout); 13366 this.hideTimeout = 0; 13367 } 13368 }, 13369 winResize: function(e) { 13370 if (!this.handleEvents()) { 13371 // we still need to resize the disable overlay if it's visible 13372 if (this.$disableOverlay) { 13373 var pos = this.$root.offset(); 13374 this.$disableOverlay.css({ 13375 top: pos.top, 13376 left: pos.left, 13377 width: this.$root.outerWidth(), 13378 height: this.$root.outerHeight() 13379 }); 13380 } 13381 return; 13382 } 13383 // hide sub menus on resize - on mobile do it only on orientation change 13384 if (!this.isCollapsible() && (!('onorientationchange' in window) || e.type == 'orientationchange')) { 13385 if (this.activatedItems.length) { 13386 this.activatedItems[this.activatedItems.length - 1][0].blur(); 13387 } 13388 this.menuHideAll(); 13389 } 13390 } 13391 } 13392 }); 13393 13394 $.fn.dataSM = function(key, val) { 13395 if (val) { 13396 return this.data(key + '_smartmenus', val); 13397 } 13398 return this.data(key + '_smartmenus'); 13399 } 13400 13401 $.fn.removeDataSM = function(key) { 13402 return this.removeData(key + '_smartmenus'); 13403 } 13404 13405 $.fn.smartmenus = function(options) { 13406 if (typeof options == 'string') { 13407 var args = arguments, 13408 method = options; 13409 Array.prototype.shift.call(args); 13410 return this.each(function() { 13411 var smartmenus = $(this).data('smartmenus'); 13412 if (smartmenus && smartmenus[method]) { 13413 smartmenus[method].apply(smartmenus, args); 13414 } 13415 }); 13416 } 13417 var opts = $.extend({}, $.fn.smartmenus.defaults, options); 13418 return this.each(function() { 13419 new $.SmartMenus(this, opts); 13420 }); 13421 } 13422 13423 // default settings 13424 $.fn.smartmenus.defaults = { 13425 isPopup: false, // is this a popup menu (can be shown via the popupShow/popupHide methods) or a permanent menu bar 13426 mainMenuSubOffsetX: 0, // pixels offset from default position
13427 mainMenuSubOffsetY: 0, // pixels offset from default position 13428 subMenusSubOffsetX: 0, // pixels offset from default position 13429 subMenusSubOffsetY: 0, // pixels offset from default position 13430 subMenusMinWidth: false, //'10em', // min-width for the sub menus (any CSS unit) - if set, the fixed width set in CSS will be ignored 13431 subMenusMaxWidth: false, //'20em', // max-width for the sub menus (any CSS unit) - if set, the fixed width set in CSS will be ignored 13432 subIndicators: true, // create sub menu indicators - creates a SPAN and inserts it in the A 13433 subIndicatorsPos: 'prepend', // position of the SPAN relative to the menu item content ('prepend', 'append') 13434 subIndicatorsText: '+', // [optionally] add text in the SPAN (e.g. '+') (you may want to check the CSS for the sub indicators too) 13435 scrollStep: 30, // pixels step when scrolling long sub menus that do not fit in the viewport height 13436 scrollInterval: 30, // interval between each scrolling step 13437 scrollAccelerate: true, // accelerate scrolling or use a fixed step 13438 showTimeout: 250, // timeout before showing the sub menus 13439 hideTimeout: 500, // timeout before hiding the sub menus 13440 showDuration: 0, // duration for show animation - set to 0 for no animation - matters only if showFunction:null 13441 showFunction: null, // custom function to use when showing a sub menu (the default is the jQuery 'show') 13442 // don't forget to call complete() at the end of whatever you do 13443 // e.g.: function($ul, complete) { $ul.fadeIn(250, complete); } 13444 hideDuration: 0, // duration for hide animation - set to 0 for no animation - matters only if hideFunction:null 13445 hideFunction: function($ul, complete) { $ul.fadeOut(200, complete); }, // custom function to use when hiding a sub menu (the default is the jQuery 'hide') 13446 // don't forget to call complete() at the end of whatever you do 13447 // e.g.: function($ul, complete) { $ul.fadeOut(250, complete); } 13448 collapsibleShowDuration:0, // duration for show animation for collapsible sub menus - matters only if collapsibleShowFunction:null 13449 collapsibleShowFunction:function($ul, complete) { $ul.slideDown(200, complete); }, // custom function to use when showing a collapsible sub menu 13450 // (i.e. when mobile styles are used to make the sub menus collapsible) 13451 collapsibleHideDuration:0, // duration for hide animation for collapsible sub menus - matters only if collapsibleHideFunction:null 13452 collapsibleHideFunction:function($ul, complete) { $ul.slideUp(200, complete); }, // custom function to use when hiding a collapsible sub menu 13453 // (i.e. when mobile styles are used to make the sub menus collapsible) 13454 showOnClick: false, // show the first-level sub menus onclick instead of onmouseover (matters only for mouse input) 13455 hideOnClick: true, // hide the sub menus on click/tap anywhere on the page 13456 keepInViewport: true, // reposition the sub menus if needed to make sure they always appear inside the viewport 13457 keepHighlighted: true, // keep all ancestor items of the current sub menu highlighted (adds the 'highlighted' class to the A's) 13458 markCurrentItem: false, // automatically add the 'current' class to the A element of the item linking to the current URL 13459 markCurrentTree: true, // add the 'current' class also to the A elements of all ancestor items of the current item 13460 rightToLeftSubMenus: false, // right to left display of the sub menus (check the CSS for the sub indicators' position) 13461 bottomToTopSubMenus: false, // bottom to top display of the sub menus 13462 overlapControlsInIE: true // make sure sub menus appear on top of special OS controls in IE (i.e. SELECT, OBJECT, EMBED, etc.) 13463 }; 13464 13465})(jQuery); 13466/* 13467 * jQuery Easing v1.4.1 - http://gsgd.co.uk/sandbox/jquery/easing/ 13468 * Open source under the BSD License. 13469 * Copyright © 2008 George McGinley Smith 13470 * All rights reserved. 13471 * https://raw.github.com/gdsmith/jquery.easing/master/LICENSE 13472*/ 13473 13474/* globals jQuery, define, module, require */ 13475(function (factory) { 13476 if (typeof define === "function" && define.amd) { 13477 define(['jquery'], function ($) { 13478 return factory($); 13479 }); 13480 } else if (typeof module === "object" && typeof module.exports === "object") { 13481 module.exports = factory(require('jquery')); 13482 } else { 13483 factory(jQuery); 13484 } 13485})(function($){ 13486 13487 // Preserve the original jQuery "swing" easing as "jswing" 13488 if (typeof $.easing !== 'undefined') { 13489 $.easing['jswing'] = $.easing['swing']; 13490 } 13491 13492 var pow = Math.pow, 13493 sqrt = Math.sqrt, 13494 sin = Math.sin, 13495 cos = Math.cos, 13496 PI = Math.PI,
13497 c1 = 1.70158, 13498 c2 = c1 * 1.525, 13499 c3 = c1 + 1, 13500 c4 = ( 2 * PI ) / 3, 13501 c5 = ( 2 * PI ) / 4.5; 13502 13503 // x is the fraction of animation progress, in the range 0..1 13504 function bounceOut(x) { 13505 var n1 = 7.5625, 13506 d1 = 2.75; 13507 if ( x < 1/d1 ) { 13508 return n1*x*x; 13509 } else if ( x < 2/d1 ) { 13510 return n1*(x-=(1.5/d1))*x + .75; 13511 } else if ( x < 2.5/d1 ) { 13512 return n1*(x-=(2.25/d1))*x + .9375; 13513 } else { 13514 return n1*(x-=(2.625/d1))*x + .984375; 13515 } 13516 } 13517 13518 $.extend( $.easing, { 13519 def: 'easeOutQuad', 13520 swing: function (x) { 13521 return $.easing[$.easing.def](x); 13522 }, 13523 easeInQuad: function (x) { 13524 return x * x; 13525 }, 13526 easeOutQuad: function (x) { 13527 return 1 - ( 1 - x ) * ( 1 - x ); 13528 }, 13529 easeInOutQuad: function (x) { 13530 return x < 0.5 ? 13531 2 * x * x : 13532 1 - pow( -2 * x + 2, 2 ) / 2; 13533 }, 13534 easeInCubic: function (x) { 13535 return x * x * x; 13536 }, 13537 easeOutCubic: function (x) { 13538 return 1 - pow( 1 - x, 3 ); 13539 }, 13540 easeInOutCubic: function (x) { 13541 return x < 0.5 ? 13542 4 * x * x * x : 13543 1 - pow( -2 * x + 2, 3 ) / 2; 13544 }, 13545 easeInQuart: function (x) { 13546 return x * x * x * x; 13547 }, 13548 easeOutQuart: function (x) { 13549 return 1 - pow( 1 - x, 4 ); 13550 }, 13551 easeInOutQuart: function (x) { 13552 return x < 0.5 ? 13553 8 * x * x * x * x : 13554 1 - pow( -2 * x + 2, 4 ) / 2; 13555 }, 13556 easeInQuint: function (x) { 13557 return x * x * x * x * x; 13558 }, 13559 easeOutQuint: function (x) { 13560 return 1 - pow( 1 - x, 5 ); 13561 }, 13562 easeInOutQuint: function (x) { 13563 return x < 0.5 ? 13564 16 * x * x * x * x * x : 13565 1 - pow( -2 * x + 2, 5 ) / 2; 13566 }, 13567 easeInSine: function (x) { 13568 return 1 - cos( x * PI/2 ); 13569 }, 13570 easeOutSine: function (x) { 13571 return sin( x * PI/2 ); 13572 }, 13573 easeInOutSine: function (x) { 13574 return -( cos( PI * x ) - 1 ) / 2; 13575 }, 13576 easeInExpo: function (x) { 13577 return x === 0 ? 0 : pow( 2, 10 * x - 10 ); 13578 }, 13579 easeOutExpo: function (x) { 13580 return x === 1 ? 1 : 1 - pow( 2, -10 * x ); 13581 }, 13582 easeInOutExpo: function (x) { 13583 return x === 0 ? 0 : x === 1 ? 1 : x < 0.5 ? 13584 pow( 2, 20 * x - 10 ) / 2 : 13585 ( 2 - pow( 2, -20 * x + 10 ) ) / 2; 13586 }, 13587 easeInCirc: function (x) { 13588 return 1 - sqrt( 1 - pow( x, 2 ) ); 13589 }, 13590 easeOutCirc: function (x) { 13591 return sqrt( 1 - pow( x - 1, 2 ) ); 13592 }, 13593 easeInOutCirc: function (x) { 13594 return x < 0.5 ? 13595 ( 1 - sqrt( 1 - pow( 2 * x, 2 ) ) ) / 2 : 13596 ( sqrt( 1 - pow( -2 * x + 2, 2 ) ) + 1 ) / 2; 13597 }, 13598 easeInElastic: function (x) { 13599 return x === 0 ? 0 : x === 1 ? 1 : 13600 -pow( 2, 10 * x - 10 ) * sin( ( x * 10 - 10.75 ) * c4 ); 13601 }, 13602 easeOutElastic: function (x) { 13603 return x === 0 ? 0 : x === 1 ? 1 : 13604 pow( 2, -10 * x ) * sin( ( x * 10 - 0.75 ) * c4 ) + 1; 13605 }, 13606 easeInOutElastic: function (x) { 13607 return x === 0 ? 0 : x === 1 ? 1 : x < 0.5 ? 13608 -( pow( 2, 20 * x - 10 ) * sin( ( 20 * x - 11.125 ) * c5 )) / 2 : 13609 pow( 2, -20 * x + 10 ) * sin( ( 20 * x - 11.125 ) * c5 ) / 2 + 1; 13610 }, 13611 easeInBack: function (x) { 13612 return c3 * x * x * x - c1 * x * x; 13613 }, 13614 easeOutBack: function (x) { 13615 return 1 + c3 * pow( x - 1, 3 ) + c1 * pow( x - 1, 2 ); 13616 }, 13617 easeInOutBack: function (x) { 13618 return x < 0.5 ? 13619 ( pow( 2 * x, 2 ) * ( ( c2 + 1 ) * 2 * x - c2 ) ) / 2 : 13620 ( pow( 2 * x - 2, 2 ) *( ( c2 + 1 ) * ( x * 2 - 2 ) + c2 ) + 2 ) / 2; 13621 }, 13622 easeInBounce: function (x) { 13623 return 1 - bounceOut( 1 - x ); 13624 }, 13625 easeOutBounce: bounceOut, 13626 easeInOutBounce: function (x) { 13627 return x < 0.5 ? 13628 ( 1 - bounceOut( 1 - 2 * x ) ) / 2 : 13629 ( 1 + bounceOut( 2 * x - 1 ) ) / 2; 13630 } 13631 }); 13632 return $; 13633}); 13634 13635/*! Copyright (c) 2011 Brandon Aaron (http://brandonaaron.net) 13636 * Licensed under the MIT License (LICENSE.txt). 13637 * 13638 * Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers. 13639 * Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix. 13640 * Thanks to: Seamus Leahy for adding deltaX and deltaY 13641 * 13642 * Version: 3.0.6 13643 * 13644 * Requires: 1.2.2+ 13645 */ 13646(function($) { 13647 var types = ['DOMMouseScroll', 'mousewheel']; 13648 if ($.event.fixHooks) { 13649 for (var i = types.length; i;) { 13650 $.event.fixHooks[types[--i]] = $.event.mouseHooks; 13651 } 13652 } 13653 $.event.special.mousewheel = { 13654 setup: function() { 13655 if (this.addEventListener) { 13656 for (var i = types.length; i;) { 13657 this.addEventListener(types[--i], handler, false); 13658 } 13659 } else { 13660 this.onmousewheel = handler; 13661 } 13662 }, 13663 teardown: function() { 13664 if (this.removeEventListener) { 13665 for (var i = types.length; i;) { 13666 this.removeEventListener(types[--i], handler, false); 13667 } 13668 } else { 13669 this.onmousewheel = null; 13670 } 13671 } 13672 }; 13673 $.fn.extend({ 13674 mousewheel: function(fn) { 13675 return fn ? this.bind("mousewheel", fn) : this.trigger("mousewheel"); 13676 }, 13677 unmousewheel: function(fn) { 13678 return this.unbind("mousewheel", fn); 13679 } 13680 }); 13681 13682 function handler(event) { 13683 var orgEvent = event || window.event, 13684 args = [].slice.call(arguments, 1), 13685 delta = 0, 13686 returnValue = true, 13687 deltaX = 0, 13688 deltaY = 0; 13689 event = $.event.fix(orgEvent); 13690 event.type = "mousewheel"; 13691 // Old school scrollwheel delta 13692 if (orgEvent.wheelDelta) { 13693 delta = orgEvent.wheelDelta / 120; 13694 } 13695 if (orgEvent.detail) { 13696 delta = -orgEvent.detail / 3; 13697 } 13698 // New school multidimensional scroll (touchpads) deltas 13699 deltaY = delta; 13700 // Gecko 13701 if (orgEvent.axis !== undefined && orgEvent.axis === orgEvent.HORIZONTAL_AXIS) { 13702 deltaY = 0; 13703 deltaX = -1 * delta; 13704 } 13705 // Webkit 13706 if (orgEvent.wheelDeltaY !== undefined) { 13707 deltaY = orgEvent.wheelDeltaY / 120; 13708 } 13709 if (orgEvent.wheelDeltaX !== undefined) { 13710 deltaX = -1 * orgEvent.wheelDeltaX / 120; 13711 } 13712 // Add event and delta to the front of the arguments 13713 args.unshift(event, delta, deltaX, deltaY); 13714 return ($.event.dispatch || $.event.handle).apply(this, args); 13715 } 13716})(jQuery); 13717/** 13718 * jQuery iLightBox - Revolutionary Lightbox Plugin 13719 * http://www.ilightbox.net/ 13720 * 13721 * @version: 2.2.4 - October 14, 2017 13722 * 13723 * @author: iProDev (Hemn Chawroka) 13724 * http://www.iprodev.com/ 13725 * 13726 */ 13727(function($, window, undefined) { 13728 13729 var extensions = { 13730 flash: ['swf'], 13731 image: ['bmp', 'gif', 'jpeg', 'jpg', 'png', 'tiff', 'tif', 'jfif', 'jpe', 'webp'], 13732 iframe: ['asp', 'aspx', 'cgi', 'cfm', 'htm', 'html', 'jsp', 'php', 'pl', 'php3', 'php4', 'php5', 'phtml', 'rb', 'rhtml', 'shtml', 'txt'], 13733 video: ['avi', 'mov', 'mpg', 'mpeg', 'movie', 'mp4', 'webm', 'ogv', 'ogg', '3gp', 'm4v'] 13734 }, 13735 13736 // Global DOM elements 13737 $win = $(window), 13738 $doc = $(document), 13739
13740 // Support indicators 13741 browser, 13742 transform, 13743 gpuAcceleration, 13744 fullScreenApi = '', 13745 userAgent = navigator.userAgent || navigator.vendor || window.opera, 13746 supportTouch = "ontouchstart" in window || navigator.msMaxTouchPoints || (navigator.maxTouchPoints && navigator.userAgent.indexOf('Windows') > -1), 13747 ishybrid = navigator.maxTouchPoints && navigator.userAgent.indexOf('Windows') > -1, 13748 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)), 13749 13750 // Events 13751 clickEvent = ishybrid ? "itap.iLightBox click.iLightBox" : supportTouch ? "itap.iLightBox" : "click.iLightBox", 13752 touchStartEvent = ishybrid ? "touchstart.iLightBox mousedown.iLightBox" : supportTouch ? "touchstart.iLightBox" : "mousedown.iLightBox", 13753 touchStopEvent = ishybrid ? "touchend.iLightBox mouseup.iLightBox" : supportTouch ? "touchend.iLightBox" : "mouseup.iLightBox", 13754 touchMoveEvent = ishybrid ? "touchmove.iLightBox mousemove.iLightBox" : supportTouch ? "touchmove.iLightBox" : "mousemove.iLightBox", 13755 13756 // Math shorthands 13757 abs = Math.abs, 13758 sqrt = Math.sqrt, 13759 round = Math.round, 13760 max = Math.max, 13761 min = Math.min, 13762 floor = Math.floor, 13763 random = Math.random, 13764 13765 pluginspages = { 13766 quicktime: 'http://www.apple.com/quicktime/download', 13767 flash: 'http://www.adobe.com/go/getflash' 13768 }, 13769 13770 iLightBox = function(el, options, items, instant) { 13771 var iL = this; 13772 13773 iL.options = options, 13774 iL.selector = options.selector || el, 13775 iL.context = document, 13776 iL.instant = instant; 13777 13778 if (items.length < 1) iL.attachItems(); 13779 else iL.items = items; 13780 13781 iL.vars = { 13782 total: iL.items.length, 13783 start: 0, 13784 current: null, 13785 next: null, 13786 prev: null, 13787 BODY: $('body'), 13788 loadRequests: 0, 13789 overlay: $('<div class="ilightbox-overlay"></div>'), 13790 loader: $('<div class="ilightbox-loader"><div></div></div>'), 13791 toolbar: $('<div class="ilightbox-toolbar"></div>'), 13792 innerToolbar: $('<div class="ilightbox-inner-toolbar"></div>'), 13793 title: $('<div class="ilightbox-title"></div>'), 13794 closeButton: $('<a class="ilightbox-close" title="' + iL.options.text.close + '"></a>'), 13795 fullScreenButton: $('<a class="ilightbox-fullscreen" title="' + iL.options.text.enterFullscreen + '"></a>'), 13796 innerPlayButton: $('<a class="ilightbox-play" title="' + iL.options.text.slideShow + '"></a>'), 13797 innerNextButton: $('<a class="ilightbox-next-button" title="' + iL.options.text.next + '"></a>'), 13798 innerPrevButton: $('<a class="ilightbox-prev-button" title="' + iL.options.text.previous + '"></a>'), 13799 holder: $('<div class="ilightbox-holder' + (supportTouch ? ' supportTouch' : '') + '" ondragstart="return false;"><div class="ilightbox-container"></div></div>'), 13800 nextPhoto: $('<div class="ilightbox-holder' + (supportTouch ? ' supportTouch' : '') + ' ilightbox-next" ondragstart="return false;"><div class="ilightbox-container"></div></div>'), 13801 prevPhoto: $('<div class="ilightbox-holder' + (supportTouch ? ' supportTouch' : '') + ' ilightbox-prev" ondragstart="return false;"><div class="ilightbox-container"></div></div>'), 13802 nextButton: $('<a class="ilightbox-button ilightbox-next-button" ondragstart="return false;" title="' + iL.options.text.next + '"><span></span></a>'), 13803 prevButton: $('<a class="ilightbox-button ilightbox-prev-button" ondragstart="return false;" title="' + iL.options.text.previous + '"><span></span></a>'),
13804 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>'), 13805 thumbs: false, 13806 nextLock: false, 13807 prevLock: false, 13808 hashLock: false, 13809 isMobile: false, 13810 mobileMaxWidth: 980, 13811 isInFullScreen: false, 13812 isSwipe: false, 13813 mouseID: 0, 13814 cycleID: 0, 13815 isPaused: 0, 13816 captionHeight: 39, 13817 }; 13818 13819 // Hideable elements with mousemove event 13820 iL.vars.hideableElements = iL.vars.nextButton.add(iL.vars.prevButton); 13821 13822 iL.normalizeItems(); 13823 13824 //Check necessary plugins 13825 iL.availPlugins(); 13826 13827 //Set startFrom 13828 iL.options.startFrom = (iL.options.startFrom > 0 && iL.options.startFrom >= iL.vars.total) ? iL.vars.total - 1 : iL.options.startFrom; 13829 13830 //If randomStart 13831 iL.options.startFrom = (iL.options.randomStart) ? floor(random() * iL.vars.total) : iL.options.startFrom; 13832 iL.vars.start = iL.options.startFrom; 13833 13834 if (instant) iL.instantCall(); 13835 else iL.patchItemsEvents(); 13836 13837 if (iL.options.linkId) { 13838 iL.hashChangeHandler(); 13839 $win.iLightBoxHashChange(function() { 13840 iL.hashChangeHandler(); 13841 }); 13842 } 13843 13844 if (supportTouch) { 13845 var RegExp = /(click|mouseenter|mouseleave|mouseover|mouseout)/ig, 13846 replace = "itap"; 13847 iL.options.caption.show = iL.options.caption.show.replace(RegExp, replace), 13848 iL.options.caption.hide = iL.options.caption.hide.replace(RegExp, replace), 13849 iL.options.social.show = iL.options.social.show.replace(RegExp, replace), 13850 iL.options.social.hide = iL.options.social.hide.replace(RegExp, replace); 13851 } 13852 13853 if (iL.options.controls.arrows || $(window).width() < UNCODE.mediaQuery) { 13854 $.extend(iL.options.styles, { 13855 nextOffsetX: ($(window).width() > UNCODE.mediaQuery) ? 36 : 4, 13856 prevOffsetX: ($(window).width() > UNCODE.mediaQuery) ? 36 : 4, 13857 nextOpacity: 0, 13858 prevOpacity: 0 13859 }); 13860 } 13861 }; 13862 13863 //iLightBox helpers 13864 iLightBox.prototype = { 13865 showLoader: function() { 13866 var iL = this; 13867 iL.vars.loadRequests += 1; 13868 if (iL.options.path.toLowerCase() == "horizontal") iL.vars.loader.addClass('ilightbox-show').stop().animate({ 13869 //top: '-30px' 13870 opacity: '1' 13871 }, iL.options.show.speed, 'easeOutCirc'); 13872 else iL.vars.loader.addClass('ilightbox-show').stop().animate({ 13873 //left: '-30px' 13874 opacity: '1' 13875 }, iL.options.show.speed, 'easeOutCirc'); 13876 }, 13877 13878 hideLoader: function() { 13879 var iL = this; 13880 iL.vars.loadRequests -= 1; 13881 iL.vars.loadRequests = (iL.vars.loadRequests < 0) ? 0 : iL.vars.loadRequests; 13882 if (iL.options.path.toLowerCase() == "horizontal") { 13883 if (iL.vars.loadRequests <= 0) iL.vars.loader.removeClass('ilightbox-show').stop().animate({ 13884 //top: '-192px' 13885 opacity: '0' 13886 }, iL.options.show.speed, 'easeInCirc'); 13887 } else { 13888 if (iL.vars.loadRequests <= 0) iL.vars.loader.removeClass('ilightbox-show').stop().animate({ 13889 //left: '-192px' 13890 opacity: '0' 13891 }, iL.options.show.speed, 'easeInCirc'); 13892 } 13893 }, 13894 13895 createUI: function() { 13896 var iL = this; 13897 13898 iL.ui = { 13899 currentElement: iL.vars.holder, 13900 nextElement: iL.vars.nextPhoto, 13901 prevElement: iL.vars.prevPhoto, 13902 currentItem: iL.vars.current, 13903 nextItem: iL.vars.next, 13904 prevItem: iL.vars.prev, 13905 hide: function() { 13906 iL.closeAction(); 13907 }, 13908 refresh: function() { 13909 (arguments.length > 0) ? iL.repositionPhoto(true): iL.repositionPhoto(); 13910 }, 13911 fullscreen: function() { 13912 iL.fullScreenAction(); 13913 } 13914 }; 13915 }, 13916 13917 attachItems: function() { 13918 var iL = this, 13919 itemsObject = new Array(), 13920 items = new Array(); 13921 13922 $(iL.selector, iL.context).each(function() { 13923 var t = $(this), 13924 URL = t.attr(iL.options.attr) || null, 13925 options = t.data("options") && eval("({" + t.data("options") + "})") || {}, 13926 caption = t.data('caption'), 13927 title = t.data('title'), 13928 type = t.data('type') || getTypeByExtension(URL), 13929 clone = t.data('lbox-clone') || false; 13930 13931 //Uncode addition ##START## 13932 if (type === false) { 13933 return; 13934 } 13935 //Uncode addition ##END## 13936 13937 if (t.data('lbox-clone') != undefined) return; 13938 13939 //Uncode addition ##START## 13940 if ( typeof t.attr('data-album') != 'undefined' && t.attr('data-album') != '' ) { 13941 var ALBUM_URLS = JSON.parse(t.attr('data-album')), 13942 URL_i, 13943 URLS_LENGHT = ALBUM_URLS.length; 13944 13945 for (URL_i = 0; URL_i < URLS_LENGHT; URL_i++) { 13946 if ( typeof ALBUM_URLS[URL_i].url !== 'undefined' && ALBUM_URLS[URL_i].url != '' ) { 13947 var item_opts = 'width:' + ALBUM_URLS[URL_i].width + ',height:' + ALBUM_URLS[URL_i].height + ',thumbnail: \'' + ALBUM_URLS[URL_i].thumbnail + '\''; 13948 item_opts = item_opts && eval("({" + item_opts + "})") || {}, 13949 items.push({ 13950 URL: ALBUM_URLS[URL_i].url, 13951 caption: ALBUM_URLS[URL_i].caption, 13952 title: ALBUM_URLS[URL_i].title, 13953 type: getTypeByExtension(ALBUM_URLS[URL_i].url), 13954 options: item_opts, 13955 clone: clone 13956 }); 13957 var newT = t; 13958 newT.attr('href',ALBUM_URLS[URL_i].url); 13959 if (!iL.instant) itemsObject.push(newT); 13960 } 13961 } 13962 } else { 13963 //Uncode addition ##END## 13964 items.push({ 13965 URL: URL, 13966 caption: caption, 13967 title: title, 13968 type: type, 13969 options: options, 13970 clone: clone 13971 }); 13972 } 13973 13974 13975 if (iL.vars != undefined) iL.vars.total = items.length; 13976 13977 if (!iL.instant) itemsObject.push(t); 13978 }); 13979 13980 iL.items = items, 13981 iL.itemsObject = itemsObject; 13982 13983 }, 13984 13985 normalizeItems: function() { 13986 var iL = this, 13987 newItems = new Array(); 13988 13989 $.each(iL.items, function(key, val) { 13990 13991 if (typeof val == "string") val = { 13992 url: val 13993 }; 13994 13995 var URL = val.url || val.URL || null, 13996 options = val.options || {}, 13997 caption = val.caption || null, 13998 title = val.title || null, 13999 type = (val.type) ? val.type.toLowerCase() : getTypeByExtension(URL), 14000 ext = (typeof URL != 'object') ? getExtension(URL) : ''; 14001 14002 options.thumbnail = options.thumbnail || ((type == "image") ? URL : null),
14003 options.videoType = options.videoType || null, 14004 options.skin = options.skin || iL.options.skin, 14005 options.width = options.width || null, 14006 options.height = options.height || null, 14007 options.mousewheel = (typeof options.mousewheel != 'undefined') ? options.mousewheel : true, 14008 options.swipe = (typeof options.swipe != 'undefined') ? options.swipe : true, 14009 options.social = (typeof options.social != 'undefined') ? options.social : iL.options.social.buttons && $.extend({}, {}, iL.options.social.buttons); 14010 14011 if (type == "video") { 14012 options.html5video = (typeof options.html5video != 'undefined') ? options.html5video : {}; 14013 14014 options.html5video.webm = options.html5video.webm || options.html5video.WEBM || null; 14015 options.html5video.controls = (typeof options.html5video.controls != 'undefined') ? options.html5video.controls : "controls"; 14016 options.html5video.preload = options.html5video.preload || "metadata"; 14017 options.html5video.autoplay = (typeof options.html5video.autoplay != 'undefined') ? options.html5video.autoplay : false; 14018 //UNCODE addition 14019 options.html5video.loop = (typeof options.html5video.loop != 'undefined') ? options.html5video.loop : false; 14020 } 14021 14022 if (!options.width || !options.height) { 14023 if (type == "video") options.width = 1280, options.height = 720; 14024 else if (type == "iframe") options.width = '100%', options.height = '90%'; 14025 else if (type == "flash") options.width = 1280, options.height = 720; 14026 } 14027 14028 delete val.url; 14029 val.index = key; 14030 val.URL = URL; 14031 val.caption = caption; 14032 val.title = title; 14033 val.type = type; 14034 val.options = options; 14035 val.ext = ext; 14036 14037 newItems.push(val); 14038 }); 14039 14040 iL.items = newItems; 14041 }, 14042 14043 instantCall: function() { 14044 var iL = this, 14045 key = iL.vars.start; 14046 14047 iL.vars.current = key; 14048 iL.vars.next = (iL.items[key + 1]) ? key + 1 : null; 14049 iL.vars.prev = (iL.items[key - 1]) ? key - 1 : null; 14050 14051 iL.addContents(); 14052 iL.patchEvents(); 14053 }, 14054 14055 addContents: function() { 14056 var iL = this, 14057 vars = iL.vars, 14058 opts = iL.options, 14059 viewport = getViewport(), 14060 path = opts.path.toLowerCase(), 14061 recognizingItems = vars.total > 0 && iL.items.filter(function(e, i, arr) { 14062 return ['image', 'flash', 'video'].indexOf(e.type) === -1 && typeof e.recognized === 'undefined' && (opts.smartRecognition || e.options.smartRecognition); 14063 }), 14064 needRecognition = recognizingItems.length > 0; 14065 14066 if (opts.mobileOptimizer && !opts.innerToolbar) 14067 vars.isMobile = viewport.width <= vars.mobileMaxWidth; 14068 14069 vars.overlay.addClass(opts.skin).hide().css('opacity', opts.overlay.opacity); 14070 14071 if (opts.linkId) 14072 vars.overlay[0].setAttribute('linkid', opts.linkId); 14073 14074 //Add Toolbar Buttons 14075 if (opts.controls.toolbar) { 14076 vars.toolbar.addClass(opts.skin).append(vars.closeButton); 14077 if (opts.controls.fullscreen) 14078 vars.toolbar.append(vars.fullScreenButton); 14079 if (opts.controls.slideshow) 14080 vars.toolbar.append(vars.innerPlayButton); 14081 if (vars.total > 1) 14082 vars.toolbar.append(vars.innerPrevButton).append(vars.innerNextButton); 14083 } 14084 14085 //Append elements to body 14086 vars.BODY.addClass('ilightbox-noscroll').append(vars.overlay).append(vars.loader).append(vars.holder).append(vars.nextPhoto).append(vars.prevPhoto); 14087 14088 if (!opts.innerToolbar) 14089 vars.BODY.append(vars.toolbar); 14090 if (opts.controls.arrows) 14091 vars.BODY.append(vars.nextButton).append(vars.prevButton); 14092 14093 if (opts.controls.thumbnail && vars.total > 1) { 14094 vars.BODY.append(vars.thumbnails); 14095 vars.thumbnails.addClass(opts.skin).addClass('ilightbox-' + path); 14096 $('div.ilightbox-thumbnails-grid', vars.thumbnails).empty(); 14097 vars.thumbs = true; 14098 } 14099 14100 //Configure loader and arrows 14101 var loaderCss = (opts.path.toLowerCase() == "horizontal") ? { 14102 left: parseInt((viewport.width / 2) - (vars.loader.outerWidth() / 2)) 14103 } : { 14104 top: parseInt((viewport.height / 2) - (vars.loader.outerHeight() / 2)) 14105 }; 14106 vars.loader.addClass(opts.skin).css(loaderCss); 14107 vars.nextButton.add(vars.prevButton).addClass(opts.skin); 14108 if (path == "horizontal") 14109 vars.loader.add(vars.nextButton).add(vars.prevButton).addClass('horizontal'); 14110 14111 // Configure arrow buttons 14112 vars.BODY[vars.isMobile ? 'addClass' : 'removeClass']('isMobile'); 14113 14114 if (!opts.infinite) { 14115 vars.prevButton.add(vars.prevButton).add(vars.innerPrevButton).add(vars.innerNextButton).removeClass('disabled'); 14116 14117 if (vars.current == 0) 14118 vars.prevButton.add(vars.innerPrevButton).addClass('disabled'); 14119 if (vars.current >= vars.total - 1) 14120 vars.nextButton.add(vars.innerNextButton).addClass('disabled'); 14121 } 14122 14123 if (opts.show.effect) { 14124 vars.overlay.stop().fadeIn(opts.show.speed); 14125 vars.toolbar.stop().fadeIn(opts.show.speed); 14126 } else { 14127 vars.overlay.show(); 14128 vars.toolbar.show(); 14129 } 14130 14131 var length = recognizingItems.length; 14132 if (needRecognition) { 14133 iL.showLoader(); 14134 14135 $.each(recognizingItems, function(key, val) { 14136 var resultFnc = function(result) { 14137 var key = -1, 14138 filter = iL.items.filter(function(e, i, arr) { 14139 if (e.URL == result.url) 14140 key = i; 14141 14142 return e.URL == result.url; 14143 }), 14144 self = iL.items[key]; 14145 14146 if (result) 14147 $.extend(true, self, { 14148 URL: result.source, 14149 type: result.type, 14150 recognized: true, 14151 options: { 14152 html5video: result.html5video, 14153 width: (result.type == "image") ? 0 : (result.width || self.width), 14154 height: (result.type == "image") ? 0 : (result.height || self.height), 14155 thumbnail: self.options.thumbnail || result.thumbnail 14156 } 14157 }); 14158 14159 length--; 14160 14161 if (length == 0) { 14162 iL.hideLoader(); 14163 14164 vars.dontGenerateThumbs = false;
14165 iL.generateThumbnails(); 14166 14167 if (opts.show.effect) 14168 setTimeout(function() { 14169 iL.generateBoxes(); 14170 }, opts.show.speed); 14171 else 14172 iL.generateBoxes(); 14173 } 14174 }; 14175 14176 iL.ogpRecognition(this, resultFnc); 14177 }); 14178 } 14179 else { 14180 if (opts.show.effect) 14181 setTimeout(function() { 14182 iL.generateBoxes(); 14183 }, opts.show.speed); 14184 else 14185 iL.generateBoxes(); 14186 } 14187 14188 iL.createUI(); 14189 14190 window.iLightBox = { 14191 close: function() { 14192 iL.closeAction(); 14193 }, 14194 fullscreen: function() { 14195 iL.fullScreenAction(); 14196 }, 14197 moveNext: function() { 14198 iL.moveTo('next'); 14199 }, 14200 movePrev: function() { 14201 iL.moveTo('prev'); 14202 }, 14203 goTo: function(index) { 14204 iL.goTo(index); 14205 }, 14206 refresh: function() { 14207 iL.refresh(); 14208 }, 14209 reposition: function() { 14210 (arguments.length > 0) ? iL.repositionPhoto(true): iL.repositionPhoto(); 14211 }, 14212 setOption: function(options) { 14213 iL.setOption(options); 14214 }, 14215 destroy: function() { 14216 iL.closeAction(); 14217 iL.dispatchItemsEvents(); 14218 } 14219 }; 14220 14221 if (opts.linkId) { 14222 vars.hashLock = true; 14223 window.location.hash = opts.linkId + '/' + vars.current; 14224 setTimeout(function() { 14225 vars.hashLock = false; 14226 }, 55); 14227 } 14228 14229 if (!opts.slideshow.startPaused) { 14230 iL.resume(); 14231 vars.innerPlayButton.removeClass('ilightbox-play').addClass('ilightbox-pause'); 14232 } 14233 14234 //Trigger the onOpen callback 14235 if (typeof iL.options.callback.onOpen == 'function') iL.options.callback.onOpen.call(iL); 14236 }, 14237 14238 loadContent: function(obj, opt, speed) { 14239 var iL = this, 14240 holder, item; 14241 14242 iL.createUI(); 14243 14244 obj.speed = speed || iL.options.effects.loadedFadeSpeed; 14245 14246 if (opt == 'current') { 14247 if (!obj.options.mousewheel) iL.vars.lockWheel = true; 14248 else iL.vars.lockWheel = false; 14249 14250 if (!obj.options.swipe) iL.vars.lockSwipe = true; 14251 else iL.vars.lockSwipe = false; 14252 } 14253 14254 switch (opt) { 14255 case 'current': 14256 holder = iL.vars.holder, item = iL.vars.current; 14257 break; 14258 case 'next': 14259 holder = iL.vars.nextPhoto, item = iL.vars.next; 14260 break; 14261 case 'prev': 14262 holder = iL.vars.prevPhoto, item = iL.vars.prev; 14263 break; 14264 } 14265 14266 holder.removeAttr('style class').addClass('ilightbox-holder' + (supportTouch ? ' supportTouch' : '')).addClass(obj.options.skin); 14267 $('div.ilightbox-inner-toolbar', holder).remove(); 14268 14269 if (obj.title || iL.options.innerToolbar) { 14270 var innerToolbar = iL.vars.innerToolbar.clone(); 14271 if (obj.title && iL.options.show.title) { 14272 var title = iL.vars.title.clone(); 14273 title.empty().html(obj.title); 14274 innerToolbar.append(title); 14275 } 14276 if (iL.options.innerToolbar) { 14277 innerToolbar.append((iL.vars.total > 1) ? iL.vars.toolbar.clone() : iL.vars.toolbar); 14278 } 14279 holder.prepend(innerToolbar); 14280 } 14281 14282 //console.warn('loadContent', arguments); 14283 14284 iL.loadSwitcher(obj, holder, item, opt); 14285 }, 14286 14287 loadSwitcher: function(obj, holder, item, opt) { 14288 var iL = this, 14289 opts = iL.options, 14290 api = { 14291 element: holder, 14292 position: item 14293 }; 14294 14295 switch (obj.type) { 14296 case 'image': 14297 //Trigger the onBeforeLoad callback 14298 if (typeof opts.callback.onBeforeLoad == 'function') opts.callback.onBeforeLoad.call(iL, iL.ui, item); 14299 if (typeof obj.options.onBeforeLoad == 'function') obj.options.onBeforeLoad.call(iL, api); 14300 14301 iL.loadImage(obj.URL, function(img) { 14302 //Trigger the onAfterLoad callback 14303 if (typeof opts.callback.onAfterLoad == 'function') opts.callback.onAfterLoad.call(iL, iL.ui, item); 14304 if (typeof obj.options.onAfterLoad == 'function') obj.options.onAfterLoad.call(iL, api); 14305 14306 var width = (img) ? img.width : 400, 14307 height = (img) ? img.height : 200; 14308 14309 holder.data({ 14310 naturalWidth: width, 14311 naturalHeight: height 14312 }); 14313 14314 $('div.ilightbox-container', holder).empty().append((img) ? '<img src="' + obj.URL + '" class="ilightbox-image" />' : '<span class="ilightbox-alert">' + opts.errors.loadImage + '</span>'); 14315 14316 //Trigger the onRender callback 14317 if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item); 14318 if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api); 14319 14320 iL.configureHolder(obj, opt, holder); 14321 }); 14322 14323 break; 14324
14325 case 'video': 14326 holder.data({ 14327 naturalWidth: obj.options.width, 14328 naturalHeight: obj.options.height 14329 }); 14330 14331 if (opt === 'current') { 14332 iL.addContent(holder, obj); 14333 14334 //Trigger the onRender callback 14335 if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item); 14336 if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api); 14337 } else { 14338 $('div.ilightbox-container', holder).empty(); 14339 } 14340 14341 iL.configureHolder(obj, opt, holder); 14342 14343 break; 14344 14345 case 'iframe': 14346 //iL.showLoader(); 14347 holder.data({ 14348 naturalWidth: obj.options.width, 14349 naturalHeight: obj.options.height 14350 }); 14351 14352 iL.configureHolder(obj, opt, holder); 14353 14354 if (opt === 'current') { 14355 var el = iL.addContent(holder, obj); 14356 14357 //Trigger the onRender callback 14358 if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item); 14359 if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api); 14360 14361 //Trigger the onBeforeLoad callback 14362 if (typeof opts.callback.onBeforeLoad == 'function') opts.callback.onBeforeLoad.call(iL, iL.ui, item); 14363 if (typeof obj.options.onBeforeLoad == 'function') obj.options.onBeforeLoad.call(iL, api); 14364 14365 el.bind('load', function() { 14366 //Trigger the onAfterLoad callback 14367 if (typeof opts.callback.onAfterLoad == 'function') opts.callback.onAfterLoad.call(iL, iL.ui, item); 14368 if (typeof obj.options.onAfterLoad == 'function') obj.options.onAfterLoad.call(iL, api); 14369 14370 //iL.hideLoader(); 14371 el.unbind('load'); 14372 }); 14373 } else { 14374 $('div.ilightbox-container', holder).empty(); 14375 } 14376 14377 break; 14378 14379 case 'inline': 14380 var el = $(obj.URL), 14381 content = iL.addContent(holder, obj), 14382 images = findImageInElement(holder); 14383 14384 holder.data({ 14385 naturalWidth: (iL.items[item].options.width || el.outerWidth()), 14386 naturalHeight: (iL.items[item].options.height || el.outerHeight()) 14387 }); 14388 content.children().eq(0).show(); 14389 14390 //Trigger the onRender callback 14391 if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item); 14392 if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api); 14393 14394 //Trigger the onBeforeLoad callback 14395 if (typeof opts.callback.onBeforeLoad == 'function') opts.callback.onBeforeLoad.call(iL, iL.ui, item); 14396 if (typeof obj.options.onBeforeLoad == 'function') obj.options.onBeforeLoad.call(iL, api); 14397 14398 iL.loadImage(images, function() { 14399 //Trigger the onAfterLoad callback 14400 if (typeof opts.callback.onAfterLoad == 'function') opts.callback.onAfterLoad.call(iL, iL.ui, item); 14401 if (typeof obj.options.onAfterLoad == 'function') obj.options.onAfterLoad.call(iL, api); 14402 14403 iL.configureHolder(obj, opt, holder); 14404 }); 14405 14406 break; 14407 14408 case 'flash': 14409 var el = iL.addContent(holder, obj); 14410 14411 holder.data({ 14412 naturalWidth: (iL.items[item].options.width || el.outerWidth()), 14413 naturalHeight: (iL.items[item].options.height || el.outerHeight()) 14414 }); 14415 14416 //Trigger the onRender callback 14417 if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item); 14418 if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api); 14419 14420 iL.configureHolder(obj, opt, holder); 14421 14422 break; 14423 14424 case 'ajax': 14425 var ajax = obj.options.ajax || {}; 14426 //Trigger the onBeforeLoad callback 14427 if (typeof opts.callback.onBeforeLoad == 'function') opts.callback.onBeforeLoad.call(iL, iL.ui, item); 14428 if (typeof obj.options.onBeforeLoad == 'function') obj.options.onBeforeLoad.call(iL, api); 14429 14430 iL.showLoader(); 14431 $.ajax({ 14432 url: obj.URL || opts.ajaxSetup.url, 14433 data: ajax.data || null, 14434 dataType: ajax.dataType || "html", 14435 type: ajax.type || opts.ajaxSetup.type, 14436 cache: ajax.cache || opts.ajaxSetup.cache, 14437 crossDomain: ajax.crossDomain || opts.ajaxSetup.crossDomain, 14438 global: ajax.global || opts.ajaxSetup.global, 14439 ifModified: ajax.ifModified || opts.ajaxSetup.ifModified, 14440 username: ajax.username || opts.ajaxSetup.username, 14441 password: ajax.password || opts.ajaxSetup.password, 14442 beforeSend: ajax.beforeSend || opts.ajaxSetup.beforeSend, 14443 complete: ajax.complete || opts.ajaxSetup.complete, 14444 success: function(data, textStatus, jqXHR) { 14445 iL.hideLoader(); 14446 14447 var el = $(data), 14448 container = $('div.ilightbox-container', holder), 14449 elWidth = iL.items[item].options.width || parseInt(el[0].getAttribute('width')), 14450 elHeight = iL.items[item].options.height || parseInt(el[0].getAttribute('height')), 14451 css = (el[0].getAttribute('width') && el[0].getAttribute('height')) ? { 14452 'overflow': 'hidden' 14453 } : {}; 14454 14455 container.empty().append($('<div class="ilightbox-wrapper"></div>').css(css).html(el)); 14456 holder.show().data({
14457 naturalWidth: (elWidth || container.outerWidth()), 14458 naturalHeight: (elHeight || container.outerHeight()) 14459 }).hide(); 14460 14461 //Trigger the onRender callback 14462 if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item); 14463 if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api); 14464 14465 var images = findImageInElement(holder); 14466 iL.loadImage(images, function() { 14467 //Trigger the onAfterLoad callback 14468 if (typeof opts.callback.onAfterLoad == 'function') opts.callback.onAfterLoad.call(iL, iL.ui, item); 14469 if (typeof obj.options.onAfterLoad == 'function') obj.options.onAfterLoad.call(iL, api); 14470 14471 iL.configureHolder(obj, opt, holder); 14472 }); 14473 14474 opts.ajaxSetup.success(data, textStatus, jqXHR); 14475 if (typeof ajax.success == 'function') ajax.success(data, textStatus, jqXHR); 14476 }, 14477 error: function(jqXHR, textStatus, errorThrown) { 14478 //Trigger the onAfterLoad callback 14479 if (typeof opts.callback.onAfterLoad == 'function') opts.callback.onAfterLoad.call(iL, iL.ui, item); 14480 if (typeof obj.options.onAfterLoad == 'function') obj.options.onAfterLoad.call(iL, api); 14481 14482 iL.hideLoader(); 14483 $('div.ilightbox-container', holder).empty().append('<span class="ilightbox-alert">' + opts.errors.loadContents + '</span>'); 14484 iL.configureHolder(obj, opt, holder); 14485 14486 opts.ajaxSetup.error(jqXHR, textStatus, errorThrown); 14487 if (typeof ajax.error == 'function') ajax.error(jqXHR, textStatus, errorThrown); 14488 } 14489 }); 14490 14491 break; 14492 14493 case 'html': 14494 var object = obj.URL, 14495 el 14496 container = $('div.ilightbox-container', holder); 14497 14498 if (object[0].nodeName) el = object.clone(); 14499 else { 14500 var dom = $(object); 14501 if (dom.selector) el = $('<div>' + dom + '</div>'); 14502 else el = dom; 14503 } 14504 14505 var elWidth = iL.items[item].options.width || parseInt(el.attr('width')), 14506 elHeight = iL.items[item].options.height || parseInt(el.attr('height')); 14507 14508 iL.addContent(holder, obj); 14509 14510 el.appendTo(document.documentElement).hide(); 14511 14512 //Trigger the onRender callback 14513 if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item); 14514 if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api); 14515 14516 var images = findImageInElement(holder); 14517 14518 //Trigger the onBeforeLoad callback 14519 if (typeof opts.callback.onBeforeLoad == 'function') opts.callback.onBeforeLoad.call(iL, iL.ui, item); 14520 if (typeof obj.options.onBeforeLoad == 'function') obj.options.onBeforeLoad.call(iL, api); 14521 14522 iL.loadImage(images, function() { 14523 //Trigger the onAfterLoad callback 14524 if (typeof opts.callback.onAfterLoad == 'function') opts.callback.onAfterLoad.call(iL, iL.ui, item); 14525 if (typeof obj.options.onAfterLoad == 'function') obj.options.onAfterLoad.call(iL, api); 14526 14527 holder.show().data({ 14528 naturalWidth: (elWidth || container.outerWidth()), 14529 naturalHeight: (elHeight || container.outerHeight()) 14530 }).hide(); 14531 el.remove(); 14532 14533 iL.configureHolder(obj, opt, holder); 14534 }); 14535 14536 break; 14537 } 14538 }, 14539 14540 configureHolder: function(obj, opt, holder) { 14541 var iL = this, 14542 vars = iL.vars, 14543 opts = iL.options; 14544 14545 if (opt != "current")(opt == "next") ? holder.addClass('ilightbox-next') : holder.addClass('ilightbox-prev'); 14546 14547 if (opt == "current") 14548 var item = vars.current; 14549 else if (opt == "next") 14550 var opacity = opts.styles.nextOpacity, 14551 item = vars.next; 14552 else 14553 var opacity = opts.styles.prevOpacity, 14554 item = vars.prev; 14555 14556 var api = { 14557 element: holder, 14558 position: item 14559 }; 14560 14561 iL.items[item].options.width = iL.items[item].options.width || 0, 14562 iL.items[item].options.height = iL.items[item].options.height || 0; 14563 14564 if (opt == "current") { 14565 if (opts.show.effect) holder.css(transform, gpuAcceleration).fadeIn(obj.speed, function() { 14566 holder.css(transform, ''); 14567 if (obj.caption) { 14568 iL.setCaption(obj, holder); 14569 var caption = $('div.ilightbox-caption', holder), 14570 percent = parseInt((caption.outerHeight() / holder.outerHeight()) * 100); 14571 if (opts.caption.start & percent <= 50) caption.fadeIn(opts.effects.fade
14571Speed); 14572 } 14573 14574 var social = obj.options.social; 14575 if (social) { 14576 iL.setSocial(social, obj.URL, holder); 14577 if (opts.social.start) $('div.ilightbox-social', holder).fadeIn(opts.effects.fadeSpeed); 14578 } 14579 14580 //Generate thumbnails 14581 iL.generateThumbnails(); 14582 14583 //Trigger the onShow callback 14584 if (typeof opts.callback.onShow == 'function') opts.callback.onShow.call(iL, iL.ui, item); 14585 if (typeof obj.options.onShow == 'function') obj.options.onShow.call(iL, api); 14586 }); 14587 else { 14588 holder.show(); 14589 14590 //Generate thumbnails 14591 iL.generateThumbnails(); 14592 14593 //Trigger the onShow callback 14594 if (typeof opts.callback.onShow == 'function') opts.callback.onShow.call(iL, iL.ui, item); 14595 if (typeof obj.options.onShow == 'function') obj.options.onShow.call(iL, api); 14596 } 14597 } else { 14598 if (opts.show.effect) holder.fadeTo(obj.speed, opacity, function() { 14599 if (opt == "next") vars.nextLock = false; 14600 else vars.prevLock = false; 14601 14602 //Generate thumbnails 14603 iL.generateThumbnails(); 14604 14605 //Trigger the onShow callback 14606 if (typeof opts.callback.onShow == 'function') opts.callback.onShow.call(iL, iL.ui, item); 14607 if (typeof obj.options.onShow == 'function') obj.options.onShow.call(iL, api); 14608 }); 14609 else { 14610 holder.css({ 14611 opacity: opacity 14612 }).show(); 14613 if (opt == "next") vars.nextLock = false; 14614 else vars.prevLock = false; 14615 14616 //Generate thumbnails 14617 iL.generateThumbnails(); 14618 14619 //Trigger the onShow callback 14620 if (typeof opts.callback.onShow == 'function') opts.callback.onShow.call(iL, iL.ui, item); 14621 if (typeof obj.options.onShow == 'function') obj.options.onShow.call(iL, api); 14622 } 14623 } 14624 14625 setTimeout(function() { 14626 iL.repositionPhoto(); 14627 }, 0); 14628 }, 14629 14630 generateBoxes: function() { 14631 var iL = this, 14632 vars = iL.vars, 14633 opts = iL.options; 14634 14635 if (opts.infinite && vars.total >= 3) { 14636 if (vars.current == vars.total - 1) vars.next = 0; 14637 if (vars.current == 0) vars.prev = vars.total - 1; 14638 } else opts.infinite = false; 14639 14640 //UNCODE addition 14641 if ( typeof iL.items[vars.current] == 'undefined' ) 14642 vars.current = 0; 14643 14644 iL.loadContent(iL.items[vars.current], 'current', opts.show.speed); 14645 14646 if (iL.items[vars.next]) iL.loadContent(iL.items[vars.next], 'next', opts.show.speed); 14647 if (iL.items[vars.prev]) iL.loadContent(iL.items[vars.prev], 'prev', opts.show.speed); 14648 }, 14649 14650 generateThumbnails: function() { 14651 var iL = this, 14652 vars = iL.vars, 14653 opts = iL.options, 14654 timeOut = null; 14655 14656 if (vars.thumbs && !iL.vars.dontGenerateThumbs) { 14657 var thumbnails = vars.thumbnails, 14658 container = $('div.ilightbox-thumbnails-container', thumbnails), 14659 grid = $('div.ilightbox-thumbnails-grid', container), 14660 i = 0; 14661 14662 grid.removeAttr('style').empty(); 14663 14664 $.each(iL.items, function(key, val) { 14665 var isActive = (vars.current == key) ? 'ilightbox-active' : '', 14666 opacity = (vars.current == key) ? opts.thumbnails.activeOpacity : opts.thumbnails.normalOpacity, 14667 thumb = val.options.thumbnail, 14668 thumbnail = $('<div class="ilightbox-thumbnail"></div>'), 14669 icon = $('<div class="ilightbox-thumbnail-icon"></div>'); 14670 14671 thumbnail.css({ 14672 opacity: 0 14673 }).addClass(isActive); 14674 14675 if ((val.type == "video" || val.type == "flash") && typeof val.options.icon == 'undefined') { 14676 icon.addClass('ilightbox-thumbnail-video'); 14677 thumbnail.append(icon); 14678 } else if (val.options.icon) { 14679 icon.addClass('ilightbox-thumbnail-' + val.options.icon); 14680 thumbnail.append(icon); 14681 } 14682 14683 if (thumb) iL.loadImage(thumb, function(img) { 14684 i++; 14685 if (img) thumbnail.data({ 14686 naturalWidth: img.width, 14687 naturalHeight: img.height 14688 }).append('<img src="' + thumb + '" border="0" />'); 14689 else thumbnail.data({ 14690 naturalWidth: opts.thumbnails.maxWidth, 14691 naturalHeight: opts.thumbnails.maxHeight 14692 }); 14693 14694 clearTimeout(timeOut); 14695 timeOut = setTimeout(function() { 14696 iL.positionThumbnails(thumbnails, container, grid); 14697 }, 20); 14698 setTimeout(function() { 14699 thumbnail.fadeTo(opts.effects.loadedFadeSpeed, opacity); 14700 }, i * 20); 14701 }); 14702 14703 grid.append(thumbnail); 14704 }); 14705 iL.vars.dontGenerateThumbs = true; 14706 } 14707 }, 14708
14709 positionThumbnails: function(thumbnails, container, grid) { 14710 var iL = this, 14711 vars = iL.vars, 14712 opts = iL.options, 14713 viewport = getViewport(), 14714 path = opts.path.toLowerCase(); 14715 14716 if (!thumbnails) thumbnails = vars.thumbnails; 14717 if (!container) container = $('div.ilightbox-thumbnails-container', thumbnails); 14718 if (!grid) grid = $('div.ilightbox-thumbnails-grid', container); 14719 14720 var thumbs = $('.ilightbox-thumbnail', grid), 14721 widthAvail = (path == 'horizontal') ? viewport.width - opts.styles.pageOffsetX : thumbs.eq(0).outerWidth() - opts.styles.pageOffsetX, 14722 heightAvail = (path == 'horizontal') ? thumbs.eq(0).outerHeight() - opts.styles.pageOffsetY : viewport.height - opts.styles.pageOffsetY, 14723 gridWidth = (path == 'horizontal') ? 0 : widthAvail, 14724 gridHeight = (path == 'horizontal') ? heightAvail : 0, 14725 active = $('.ilightbox-active', grid), 14726 gridCss = {}, 14727 css = {}; 14728 14729 if (arguments.length < 3) { 14730 thumbs.css({ 14731 opacity: opts.thumbnails.normalOpacity 14732 }); 14733 active.css({ 14734 opacity: opts.thumbnails.activeOpacity 14735 }); 14736 } 14737 14738 thumbs.each(function(i) { 14739 var t = $(this), 14740 data = t.data(), 14741 width = (path == 'horizontal') ? 0 : opts.thumbnails.maxWidth; 14742 height = (path == 'horizontal') ? opts.thumbnails.maxHeight : 0; 14743 dims = iL.getNewDimenstions(width, height, data.naturalWidth, data.naturalHeight, true); 14744 14745 t.css({ 14746 width: dims.width, 14747 height: dims.height 14748 }); 14749 if (path == 'horizontal') t.css({ 14750 'float': 'left' 14751 }); 14752 14753 (path == 'horizontal') ? ( 14754 gridWidth += t.outerWidth() 14755 ) : ( 14756 gridHeight += t.outerHeight() 14757 ); 14758 }); 14759 14760 gridCss = { 14761 width: gridWidth, 14762 height: gridHeight 14763 }; 14764 14765 grid.css(gridCss); 14766 14767 gridCss = {}; 14768 14769 var gridOffset = grid.offset(), 14770 activeOffset = (active.length) ? active.offset() : { 14771 top: parseInt(heightAvail / 2), 14772 left: parseInt(widthAvail / 2) 14773 }; 14774 14775 gridOffset.top = (gridOffset.top - $doc.scrollTop()), 14776 gridOffset.left = (gridOffset.left - $doc.scrollLeft()), 14777 activeOffset.top = (activeOffset.top - gridOffset.top - $doc.scrollTop()), 14778 activeOffset.left = (activeOffset.left - gridOffset.left - $doc.scrollLeft()); 14779 14780 (path == 'horizontal') ? ( 14781 gridCss.top = 0, 14782 gridCss.left = parseInt((widthAvail / 2) - activeOffset.left - (active.outerWidth() / 2)) 14783 ) : ( 14784 gridCss.top = parseInt(((heightAvail / 2) - activeOffset.top - (active.outerHeight() / 2))), 14785 gridCss.left = 0 14786 ); 14787 14788 if (arguments.length < 3) grid.stop().animate(gridCss, opts.effects.repositionSpeed, 'easeOutCirc'); 14789 else grid.css(gridCss); 14790 }, 14791 14792 loadImage: function(image, callback) { 14793 if (!$.isArray(image)) image = [image]; 14794 14795 var iL = this, 14796 length = image.length; 14797 14798 if (length > 0) { 14799 iL.showLoader(); 14800 $.each(image, function(index, value) { 14801 var img = new Image(); 14802 img.onload = function() { 14803 length -= 1; 14804 if (length == 0) { 14805 iL.hideLoader(); 14806 callback(img); 14807 } 14808 }; 14809 img.onerror = img.onabort = function() { 14810 length -= 1; 14811 if (length == 0) { 14812 iL.hideLoader(); 14813 callback(false); 14814 } 14815 }; 14816 img.src = image[index]; 14817 }); 14818 } else callback(false); 14819 }, 14820 14821 patchItemsEvents: function() { 14822 var iL = this, 14823 vars = iL.vars, 14824 clickEvent = ishybrid ? "itap.iL click.iL" : supportTouch ? "itap.iL" : "click.iL", 14825 vEvent = ishybrid ? "click.iL itap.iL" : supportTouch ? "click.iL" : "itap.iL"; 14826 14827 if (iL.context && iL.selector) { 14828 var $items = $(iL.selector, iL.context); 14829 14830 $(iL.context).on(clickEvent, iL.selector, function() { 14831 var $this = $(this), 14832 //UNCODE addition 14833 key = typeof $(this).data('lb-index') !== '' && $(this).closest('.owl-item').length ? $(this).data('lb-index') : $items.index($this); 14834 if (UNCODE.isMobile) { 14835 var isCarousel = $this.closest('.owl-carousel'); 14836 if (isCarousel.length) { 14837 if (isCarousel.hasClass('owl-translating')) return false; 14838 } 14839 } 14840 14841 vars.current = key; 14842 vars.next = iL.items[key + 1] ? key + 1 : null; 14843 vars.prev = iL.items[key - 1] ? key - 1 : null; 14844 14845 //UNCODE addition 14846 if ( vars.BODY.hasClass('fp-slide-scrolling') ) 14847 return false;
14848 14849 iL.addContents(); 14850 iL.patchEvents(); 14851 14852 return false; 14853 }).on(vEvent, iL.selector, function() { 14854 return false; 14855 }); 14856 } else 14857 $.each(iL.itemsObject, function(key, val) { 14858 val.on(clickEvent, function() { 14859 vars.current = key; 14860 vars.next = iL.items[key + 1] ? key + 1 : null; 14861 vars.prev = iL.items[key - 1] ? key - 1 : null; 14862 14863 iL.addContents(); 14864 iL.patchEvents(); 14865 14866 return false; 14867 }).on(vEvent, function() { 14868 return false; 14869 }); 14870 }); 14871 }, 14872 14873 dispatchItemsEvents: function() { 14874 var iL = this, 14875 vars = iL.vars, 14876 opts = iL.options; 14877 14878 if (iL.context && iL.selector) 14879 $(iL.context).off('.iL', iL.selector); 14880 else 14881 $.each(iL.itemsObject, function(key, val) { 14882 val.off('.iL'); 14883 }); 14884 }, 14885 14886 refresh: function() { 14887 var iL = this; 14888 14889 iL.dispatchItemsEvents(); 14890 iL.attachItems(); 14891 iL.normalizeItems(); 14892 iL.patchItemsEvents(); 14893 }, 14894 14895 patchEvents: function() { 14896 var iL = this, 14897 vars = iL.vars, 14898 opts = iL.options, 14899 path = opts.path.toLowerCase(), 14900 holders = $('.ilightbox-holder'), 14901 fullscreenEvent = fullScreenApi.fullScreenEventName + '.iLightBox', 14902 durationThreshold = 1000, 14903 horizontalDistanceThreshold = 14904 verticalDistanceThreshold = 100, 14905 buttonsArray = [vars.nextButton[0], vars.prevButton[0], vars.nextButton[0].firstChild, vars.prevButton[0].firstChild]; 14906 14907 $win.bind('resize.iLightBox', function() { 14908 var viewport = getViewport(); 14909 14910 if (opts.mobileOptimizer && !opts.innerToolbar) vars.isMobile = viewport.width <= vars.mobileMaxWidth; 14911 vars.BODY[vars.isMobile ? 'addClass' : 'removeClass']('isMobile'); 14912 14913 iL.repositionPhoto(null); 14914 if (supportTouch) { 14915 clearTimeout(vars.setTime); 14916 vars.setTime = setTimeout(function() { 14917 var scrollTop = getScrollXY().y; 14918 window.scrollTo(0, scrollTop - 30); 14919 window.scrollTo(0, scrollTop + 30); 14920 window.scrollTo(0, scrollTop); 14921 }, 2000); 14922 } 14923 if (vars.thumbs) iL.positionThumbnails(); 14924 }).bind('keydown.iLightBox', function(event) { 14925 if (opts.controls.keyboard) { 14926 switch (event.keyCode) { 14927 case 13: 14928 if (event.shiftKey && opts.keyboard.shift_enter) iL.fullScreenAction(); 14929 break; 14930 case 27: 14931 if (opts.keyboard.esc) iL.closeAction(); 14932 break; 14933 case 37: 14934 if (opts.keyboard.left && !vars.lockKey) iL.moveTo('prev'); 14935 break; 14936 case 38: 14937 if (opts.keyboard.up && !vars.lockKey) iL.moveTo('prev'); 14938 break; 14939 case 39: 14940 if (opts.keyboard.right && !vars.lockKey) iL.moveTo('next'); 14941 break; 14942 case 40: 14943 if (opts.keyboard.down && !vars.lockKey) iL.moveTo('next'); 14944 break; 14945 } 14946 } 14947 }); 14948 14949 if (fullScreenApi.supportsFullScreen) $win.bind(fullscreenEvent, function() { 14950 iL.doFullscreen(); 14951 }); 14952 14953 var holderEventsArr = [opts.caption.show + '.iLightBox', opts.caption.hide + '.iLightBox', opts.social.show + '.iLightBox', opts.social.hide + '.iLightBox'].filter(function(e, i, arr) { 14954 return arr.lastIndexOf(e) === i; 14955 }), 14956 holderEvents = ""; 14957 14958 $.each(holderEventsArr, function(key, val) { 14959 if (key != 0) holderEvents += ' '; 14960 holderEvents += val; 14961 }); 14962 14963 $doc.on(clickEvent, '.ilightbox-overlay', function() { 14964 if (opts.overlay.blur) iL.closeAction(); 14965 }).on(clickEvent, '.ilightbox-next, .ilightbox-next-button', function() { 14966 iL.moveTo('next'); 14967 }).on(clickEvent, '.ilightbox-prev, .ilightbox-prev-button', function() { 14968 iL.moveTo('prev'); 14969 }).on(clickEvent, '.ilightbox-thumbnail', function() { 14970 var t = $(this), 14971 thumbs = $('.ilightbox-thumbnail', vars.thumbnails), 14972 index = thumbs.index(t); 14973 14974 if (index != vars.current) iL.goTo(index); 14975 }).on(holderEvents, '.ilightbox-holder:not(.ilightbox-next, .ilightbox-prev)', function(e) { 14976 var caption = $('div.ilightbox-caption', vars.holder), 14977 social = $('div.ilightbox-social', vars.holder), 14978 fadeSpeed = opts.effects.fadeSpeed; 14979 14980 if (vars.nextLock || vars.prevLock) { 14981 if (e.type == opts.caption.show && !caption.is(':visible')) caption.fadeIn(fadeSpeed); 14982 else if (e.type == opts.caption.hide && caption.is(':visible')) caption.fadeOut(fadeSpeed); 14983 14984 if (e.type == opts.social.show && !social.is(':visible')) social.fadeIn(fadeSpeed); 14985 else if (e.type == opts.social.hide && social.is(':visible')) social.fadeOut(fadeSpeed); 14986 } else { 14987 if (e.type == opts.caption.show && !caption.is(':visible')) caption.stop().fadeIn(fadeSpeed); 14988 else if (e.type == opts.caption.hide && caption.is(':visible')) caption.stop().fadeOut(fadeSpeed); 14989 14990 if (e.type == opts.social.show && !social.is(':visible')) social.stop().fadeIn(fadeSpeed); 14991 else if (e.type == opts.social.hide && social.is(':visible')) social.stop().fadeOut(fadeSpeed); 14992 } 14993 }).on('mouseenter.iLightBox mouseleave.iLightBox', '.ilightbox-wrapper', function(e) { 14994 if (e.type == 'mouseenter') vars.lockWheel = true; 14995 else vars.lockWheel = false;
14996 }).on(clickEvent, '.ilightbox-toolbar a.ilightbox-close, .ilightbox-toolbar a.ilightbox-fullscreen, .ilightbox-toolbar a.ilightbox-play, .ilightbox-toolbar a.ilightbox-pause', function() { 14997 var t = $(this); 14998 14999 if (t.hasClass('ilightbox-fullscreen')) iL.fullScreenAction(); 15000 else if (t.hasClass('ilightbox-play')) { 15001 iL.resume(); 15002 t.addClass('ilightbox-pause').removeClass('ilightbox-play'); 15003 } else if (t.hasClass('ilightbox-pause')) { 15004 iL.pause(); 15005 t.addClass('ilightbox-play').removeClass('ilightbox-pause'); 15006 } else iL.closeAction(); 15007 }).on(touchMoveEvent, '.ilightbox-overlay, .ilightbox-thumbnails-container', function(e) { 15008 // prevent scrolling 15009 e.preventDefault(); 15010 }); 15011 15012 function mouseMoveHandler(e) { 15013 if (!vars.isMobile) { 15014 if (!vars.mouseID) { 15015 vars.hideableElements.show(); 15016 } 15017 15018 vars.mouseID = clearTimeout(vars.mouseID); 15019 15020 if (buttonsArray.indexOf(e.target) === -1) 15021 vars.mouseID = setTimeout(function() { 15022 vars.hideableElements.hide(); 15023 vars.mouseID = clearTimeout(vars.mouseID); 15024 }, 3000); 15025 } 15026 } 15027 15028 if (opts.controls.arrows && !supportTouch) $doc.on('mousemove.iLightBox', mouseMoveHandler); 15029 15030 if (opts.controls.slideshow && opts.slideshow.pauseOnHover) $doc.on('mouseenter.iLightBox mouseleave.iLightBox', '.ilightbox-holder:not(.ilightbox-next, .ilightbox-prev)', function(e) { 15031 if (e.type == 'mouseenter' && vars.cycleID) iL.pause(); 15032 else if (e.type == 'mouseleave' && vars.isPaused) iL.resume(); 15033 }); 15034 15035 var switchers = $('.ilightbox-overlay, .ilightbox-holder, .ilightbox-thumbnails'), 15036 delay = false; 15037 15038 if (opts.controls.mousewheel) switchers.on('mousewheel.iLightBox', function(event, delta) { 15039 event.preventDefault(); 15040 if (delay) return; 15041 delay = true; 15042 if (!vars.lockWheel) { 15043 event.preventDefault(); 15044 if (delta < 0) { 15045 iL.moveTo('next'); 15046 } else if (delta > 0) { 15047 iL.moveTo('prev'); 15048 } 15049 } 15050 setTimeout(function(){
15051 delay = false; 15052 }, 2000); 15053 }); 15054 15055 if (opts.controls.swipe) holders.on(touchStartEvent, function(event) { 15056 if (vars.nextLock || vars.prevLock || vars.total == 1 || vars.lockSwipe) return; 15057 15058 vars.BODY.addClass('ilightbox-closedhand'); 15059 15060 var data = event.originalEvent.touches ? event.originalEvent.touches[0] : event, 15061 scrollTop = $doc.scrollTop(), 15062 scrollLeft = $doc.scrollLeft(), 15063 offsets = [ 15064 holders.eq(0).offset(), 15065 holders.eq(1).offset(), 15066 holders.eq(2).offset() 15067 ], 15068 offSet = [{ 15069 top: offsets[0].top - scrollTop, 15070 left: offsets[0].left - scrollLeft 15071 }, { 15072 top: offsets[1].top - scrollTop, 15073 left: offsets[1].left - scrollLeft 15074 }, { 15075 top: offsets[2].top - scrollTop, 15076 left: offsets[2].left - scrollLeft 15077 }], 15078 start = { 15079 time: (new Date()).getTime(), 15080 coords: [data.pageX - scrollLeft, data.pageY - scrollTop] 15081 }, 15082 stop; 15083 15084 function moveEachHandler(i) { 15085 var t = $(this), 15086 offset = offSet[i], 15087 scroll = [(start.coords[0] - stop.coords[0]), (start.coords[1] - stop.coords[1])]; 15088 15089 t[0].style[path == "horizontal" ? 'left' : 'top'] = (path == "horizontal" ? offset.left - scroll[0] : offset.top - scroll[1]) + 'px'; 15090 } 15091 15092 function moveHandler(event) { 15093 15094 if (!start) return; 15095 15096 var data = event.originalEvent.touches ? event.originalEvent.touches[0] : event; 15097 15098 stop = { 15099 time: (new Date()).getTime(), 15100 coords: [data.pageX - scrollLeft, data.pageY - scrollTop] 15101 }; 15102 15103 holders.each(moveEachHandler); 15104 15105 // prevent scrolling 15106 event.preventDefault(); 15107 } 15108 15109 function repositionHolders() { 15110 holders.each(function() { 15111 var t = $(this), 15112 offset = t.data('offset') || { 15113 top: t.offset().top - scrollTop, 15114 left: t.offset().left - scrollLeft 15115 }, 15116 top = offset.top, 15117 left = offset.left; 15118 15119 t.css(transform, gpuAcceleration).stop().animate({ 15120 top: top, 15121 left: left 15122 }, 500, 'easeOutCirc', function() { 15123 t.css(transform, ''); 15124 }); 15125 }); 15126 } 15127 15128 holders.bind(touchMoveEvent, moveHandler); 15129 $doc.one(touchStopEvent, function(event) { 15130 holders.unbind(touchMoveEvent, moveHandler); 15131 15132 vars.BODY.removeClass('ilightbox-closedhand'); 15133 15134 if (start && stop) { 15135 if (path == "horizontal" && stop.time - start.time < durationThreshold && abs(start.coords[0] - stop.coords[0]) > horizontalDistanceThreshold && abs(start.coords[1] - stop.coords[1]) < verticalDistanceThreshold) { 15136 if (start.coords[0] > stop.coords[0]) { 15137 if (vars.current == vars.total - 1 && !opts.infinite) repositionHolders(); 15138 else { 15139 vars.isSwipe = true; 15140 iL.moveTo('next'); 15141 } 15142 } else { 15143 if (vars.current == 0 && !opts.infinite) repositionHolders(); 15144 else { 15145 vars.isSwipe = true; 15146 iL.moveTo('prev'); 15147 } 15148 } 15149 } 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) { 15150 if (start.coords[1] > stop.coords[1]) { 15151 if (vars.current == vars.total - 1 && !opts.infinite) repositionHolders(); 15152 else { 15153 vars.isSwipe = true; 15154 iL.moveTo('next'); 15155 } 15156 } else { 15157 if (vars.current == 0 && !opts.infinite) repositionHolders(); 15158 else { 15159 vars.isSwipe = true; 15160 iL.moveTo('prev'); 15161 } 15162 } 15163 } else repositionHolders(); 15164 } 15165 start = stop = undefined; 15166 }); 15167 }); 15168 15169 }, 15170 15171 goTo: function(index) { 15172 var iL = this, 15173 vars = iL.vars, 15174 opts = iL.options, 15175 diff = (index - vars.current); 15176 15177 if (opts.infinite) { 15178 if (index == vars.total - 1 && vars.current == 0) diff = -1; 15179 if (vars.current == vars.total - 1 && index == 0) diff = 1; 15180 } 15181 15182 if (diff == 1) iL.moveTo('next'); 15183 else if (diff == -1) iL.moveTo('prev'); 15184 else { 15185 15186 if (vars.nextLock || vars.prevLock) return false; 15187 15188 //Trigger the onBeforeChange callback 15189 if (typeof opts.callback.onBeforeChange == 'function') opts.callback.onBeforeChange.call(iL, iL.ui); 15190 15191 if (opts.linkId) { 15192 vars.hashLock = true; 15193 window.location.hash = opts.linkId + '/' + index; 15194 } 15195 15196 if (iL.items[index]) { 15197 if (!iL.items[index].options.mousewheel) vars.lockWheel = true; 15198 else iL.vars.lockWheel = false;
15199 15200 if (!iL.items[index].options.swipe) vars.lockSwipe = true; 15201 else vars.lockSwipe = false; 15202 } 15203 15204 $.each([vars.holder, vars.nextPhoto, vars.prevPhoto], function(key, val) { 15205 val.css(transform, gpuAcceleration).fadeOut(opts.effects.loadedFadeSpeed); 15206 }); 15207 15208 vars.current = index; 15209 vars.next = index + 1; 15210 vars.prev = index - 1; 15211 15212 iL.createUI(); 15213 15214 setTimeout(function() { 15215 iL.generateBoxes(); 15216 }, opts.effects.loadedFadeSpeed + 50); 15217 15218 $('.ilightbox-thumbnail', vars.thumbnails).removeClass('ilightbox-active').eq(index).addClass('ilightbox-active'); 15219 iL.positionThumbnails(); 15220 15221 if (opts.linkId) setTimeout(function() { 15222 vars.hashLock = false; 15223 }, 55); 15224 15225 // Configure arrow buttons 15226 if (!opts.infinite) { 15227 vars.nextButton.add(vars.prevButton).add(vars.innerPrevButton).add(vars.innerNextButton).removeClass('disabled'); 15228 15229 if (vars.current == 0) { 15230 vars.prevButton.add(vars.innerPrevButton).addClass('disabled'); 15231 } 15232 if (vars.current >= vars.total - 1) { 15233 vars.nextButton.add(vars.innerNextButton).addClass('disabled'); 15234 } 15235 } 15236 15237 // Reset next cycle timeout 15238 iL.resetCycle(); 15239 15240 //Trigger the onAfterChange callback 15241 if (typeof opts.callback.onAfterChange == 'function') opts.callback.onAfterChange.call(iL, iL.ui); 15242 } 15243 }, 15244 15245 moveTo: function(side) { 15246 var iL = this, 15247 vars = iL.vars, 15248 opts = iL.options, 15249 path = opts.path.toLowerCase(), 15250 viewport = getViewport(), 15251 switchSpeed = opts.effects.switchSpeed; 15252 15253 if (vars.nextLock || vars.prevLock) return false; 15254 else { 15255 15256 var item = (side == "next") ? vars.next : vars.prev; 15257 15258 if (opts.linkId) { 15259 vars.hashLock = true; 15260 window.location.hash = opts.linkId + '/' + item; 15261 } 15262 15263 if (side == "next") { 15264 if (!iL.items[item]) return false; 15265 var firstHolder = vars.nextPhoto, 15266 secondHolder = vars.holder, 15267 lastHolder = vars.prevPhoto, 15268 firstClass = 'ilightbox-prev', 15269 secondClass = 'ilightbox-next'; 15270 } else if (side == "prev") { 15271 if (!iL.items[item]) return false; 15272 var firstHolder = vars.prevPhoto, 15273 secondHolder = vars.holder, 15274 lastHolder = vars.nextPhoto, 15275 firstClass = 'ilightbox-next', 15276 secondClass = 'ilightbox-prev'; 15277 } 15278 15279 //Trigger the onBeforeChange callback 15280 if (typeof opts.callback.onBeforeChange == 'function') 15281 opts.callback.onBeforeChange.call(iL, iL.ui); 15282 15283 (side == "next") ? vars.nextLock = true: vars.prevLock = true; 15284 15285 var captionFirst = $('div.ilightbox-caption', secondHolder), 15286 socialFirst = $('div.ilightbox-social', secondHolder); 15287 15288 if (captionFirst.length) 15289 captionFirst.stop().fadeOut(switchSpeed, function() { 15290 $(this).remove(); 15291 }); 15292 if (socialFirst.length) 15293 socialFirst.stop().fadeOut(switchSpeed, function() { 15294 $(this).remove(); 15295 }); 15296 15297 if (iL.items[item].caption) { 15298 iL.setCaption(iL.items[item], firstHolder); 15299 var caption = $('div.ilightbox-caption', firstHolder), 15300 percent = parseInt((caption.outerHeight() / firstHolder.outerHeight()) * 100); 15301 if (opts.caption.start && percent <= 50) caption.fadeIn(switchSpeed); 15302 } 15303 15304 var social = iL.items[item].options.social; 15305 if (social) { 15306 iL.setSocial(social, iL.items[item].URL, firstHolder); 15307 if (opts.social.start) $('div.ilightbox-social', firstHolder).fadeIn(opts.effects.fadeSpeed); 15308 } 15309 15310 $.each([firstHolder, secondHolder, lastHolder], function(key, val) { 15311 val.removeClass('ilightbox-next ilightbox-prev'); 15312 }); 15313 15314 var firstOffset = firstHolder.data('offset'), 15315 winW = (viewport.width - (opts.styles.pageOffsetX)), 15316 winH = (viewport.height - (opts.styles.pageOffsetY)), 15317 width = firstOffset.newDims.width, 15318 height = firstOffset.newDims.height, 15319 thumbsOffset = firstOffset.thumbsOffset, 15320 diff = firstOffset.diff, 15321 top = parseInt((winH / 2) - (height / 2) - diff.H - (thumbsOffset.H / 2)), 15322 left = parseInt((winW / 2) - (width / 2) - diff.W - (thumbsOffset.W / 2)); 15323 15324 var secondOffset = secondHolder.data('offset'), 15325 object = secondOffset.object; 15326 15327 /*if (object.item.caption && !isNaN(width) && !isNaN(height) && UNCODE.wwidth > UNCODE.mediaQuery) { 15328 var objRatio = width / height; 15329 height = height - vars.captionHeight; 15330 width = height * objRatio; 15331 top = path == 'horizontal' ? parseInt((winH / 2) - (height / 2) - diff.H - (thumbsOffset.H / 2)) : top, 15332 left = parseInt((winW / 2) - (width / 2) - diff.W - (thumbsOffset.W / 2)); 15333 }*/ 15334 15335 firstHolder.show().css(transform, gpuAcceleration).animate({ 15336 top: top, 15337 left: left, 15338 opacity: 1 15339 }, switchSpeed, (vars.isSwipe) ? 'easeOutCirc' : 'easeInOutCirc', function() { 15340 firstHolder.css(transform, ''); 15341 }); 15342 15343 $('div.ilightbox-container', firstHolder).animate({ 15344 width: width, 15345 height: height 15346 }, switchSpeed, (vars.isSwipe) ? 'easeOutCirc' : 'easeInOutCirc'); 15347 15348 diff = secondOffset.diff; 15349 15350 width = secondOffset.newDims.width, 15351 height = secondOffset.newDims.height; 15352 15353 width = parseInt(width * opts.styles[side == 'next' ? 'prevScale' : 'nextScale']), 15354 height = parseInt(height * opts.styles[side == 'next' ? 'prevScale' : 'nextScale']), 15355 top = (path == 'horizontal') ? parseInt((winH / 2) - object.offsetY - (height / 2) - diff.H - (thumbsOffset.H / 2)) : parseInt(winH - object.offsetX - diff.H - (thumbsOffset.H / 2)); 15356 15357 if (side == 'prev') 15358 left = (path == 'horizontal') ? parseInt(winW - object.offsetX - diff.W - (thumbsOffset.W / 2)) : parseInt((winW / 2) - (width / 2) - diff.W - object.offsetY - (thumbsOffset.W / 2)); 15359 else { 15360 top = (path == 'horizontal') ? top : parseInt(object.offsetX - diff.H - height - (thumbsOffset.H / 2)), 15361 left = (path == 'horizontal') ? parseInt(object.offsetX - diff.W - width - (thumbsOffset.W / 2)) : parseInt((winW / 2) - object.offsetY - (width / 2) - diff.W - (thumbsOffset.W / 2)); 15362 } 15363 15364 /*if (object.item.caption && !isNaN(width) && !isNaN(height) && UNCODE.wwidth > UNCODE.mediaQuery) { 15365 var objRatio = width / height; 15366 height = height - vars.captionHeight; 15367 width = height * objRatio; 15368 top = path == 'horizontal' ? parseInt((winH / 2) - (height / 2) - diff.H - (thumbsOffset.H / 2)) : top; 15369 }*/ 15370 15371 $('div.ilightbox-container', secondHolder).animate({ 15372 width: width, 15373 height: height 15374 }, switchSpeed, (vars.isSwipe) ? 'easeOutCirc' : 'easeInOutCirc'); 15375 15376 secondHolder.addClass(firstClass).css(transform, gpuAcceleration).animate({ 15377 top: top, 15378 left: left, 15379 opacity: opts.styles.prevOpacity, 15380 }, switchSpeed, (vars.isSwipe) ? 'easeOutCirc' : 'easeInOutCirc', function() { 15381 secondHolder.css(transform, ''); 15382
15383 $('.ilightbox-thumbnail', vars.thumbnails).removeClass('ilightbox-active').eq(item).addClass('ilightbox-active'); 15384 iL.positionThumbnails(); 15385 15386 if (iL.items[item]) { 15387 if (!iL.items[item].options.mousewheel) vars.lockWheel = true; 15388 else vars.lockWheel = false; 15389 15390 if (!iL.items[item].options.swipe) vars.lockSwipe = true; 15391 else vars.lockSwipe = false; 15392 } 15393 15394 vars.isSwipe = false; 15395 15396 // Remove iframe & video from previous slide 15397 if (['iframe', 'video'].indexOf(iL.items[vars.current].type) !== -1) { 15398 $('div.ilightbox-container', secondHolder).empty(); 15399 } 15400 15401 if (side == "next") { 15402 vars.nextPhoto = lastHolder, 15403 vars.prevPhoto = secondHolder, 15404 vars.holder = firstHolder; 15405 15406 vars.nextPhoto.hide(); 15407 15408 vars.next = vars.next + 1, 15409 vars.prev = vars.current, 15410 vars.current = vars.current + 1; 15411 15412 if (opts.infinite) { 15413 if (vars.current > vars.total - 1) vars.current = 0; 15414 if (vars.current == vars.total - 1) vars.next = 0; 15415 if (vars.current == 0) vars.prev = vars.total - 1; 15416 } 15417 15418 iL.createUI(); 15419 15420 if (!iL.items[vars.next]) 15421 vars.nextLock = false; 15422 else 15423 iL.loadContent(iL.items[vars.next], 'next'); 15424 } else { 15425 vars.prevPhoto = lastHolder; 15426 vars.nextPhoto = secondHolder; 15427 vars.holder = firstHolder; 15428 15429 vars.prevPhoto.hide(); 15430 15431 vars.next = vars.current; 15432 vars.current = vars.prev; 15433 vars.prev = vars.current - 1; 15434 15435 if (opts.infinite) { 15436 if (vars.current == vars.total - 1) vars.next = 0; 15437 if (vars.current == 0) vars.prev = vars.total - 1; 15438 } 15439 15440 iL.createUI(); 15441 15442 if (!iL.items[vars.prev]) 15443 vars.prevLock = false; 15444 else 15445 iL.loadContent(iL.items[vars.prev], 'prev'); 15446 } 15447 15448 // Add iframe & video content for current slide 15449 if (['iframe', 'video'].indexOf(iL.items[vars.current].type) !== -1) { 15450 iL.loadContent(iL.items[vars.current], 'current'); 15451 } 15452 15453 if (opts.linkId) setTimeout(function() { 15454 vars.hashLock = false; 15455 }, 55); 15456 15457 // Configure arrow buttons 15458 if (!opts.infinite) { 15459 vars.nextButton.add(vars.prevButton).add(vars.innerPrevButton).add(vars.innerNextButton).removeClass('disabled'); 15460 15461 if (vars.current == 0) 15462 vars.prevButton.add(vars.innerPrevButton).addClass('disabled'); 15463 if (vars.current >= vars.total - 1) 15464 vars.nextButton.add(vars.innerNextButton).addClass('disabled'); 15465 } 15466 15467 iL.repositionPhoto(); 15468 15469 // Reset next cycle timeout 15470 iL.resetCycle(); 15471 15472 //Trigger the onAfterChange callback 15473 if (typeof opts.callback.onAfterChange == 'function') 15474 opts.callback.onAfterChange.call(iL, iL.ui); 15475 }); 15476 15477 top = (path == 'horizontal') ? getPixel(lastHolder, 'top') : ((side == "next") ? parseInt(-(winH / 2) - lastHolder.outerHeight()) : parseInt(top * 2)), 15478 left = (path == 'horizontal') ? ((side == "next") ? parseInt(-(winW / 2) - lastHolder.outerWidth()) : parseInt(left * 2)) : getPixel(lastHolder, 'left'); 15479 15480 lastHolder.css(transform, gpuAcceleration).animate({ 15481 top: top, 15482 left: left, 15483 opacity: opts.styles.nextOpacity 15484 }, switchSpeed, (vars.isSwipe) ? 'easeOutCirc' : 'easeInOutCirc', function() { 15485 lastHolder.css(transform, ''); 15486 }).addClass(secondClass); 15487 } 15488 }, 15489 15490 setCaption: function(obj, target) { 15491 var iL = this, 15492 caption = $('<div class="ilightbox-caption"></div>'); 15493 15494 if (obj.caption) { 15495 caption.html(obj.caption); 15496 $('div.ilightbox-container', target).append(caption); 15497 } 15498 }, 15499 15500 normalizeSocial: function(obj, url) { 15501 var iL = this, 15502 vars = iL.vars, 15503 opts = iL.options, 15504 baseURL = window.location.href; 15505 15506 $.each(obj, function(key, value) { 15507 if (!value) 15508 return true; 15509 15510 var item = key.toLowerCase(), 15511 source, text; 15512 15513 switch (item) { 15514 case 'facebook': 15515 source = "http://www.facebook.com/share.php?v=4&src=bm&u={URL}", 15516 text = "Share on Facebook"; 15517 break; 15518 case 'twitter': 15519 source = "http://twitter.com/home?status={URL}", 15520 text = "Share on Twitter"; 15521 break; 15522 case 'digg': 15523 source = "http://digg.com/submit?phase=2&url={URL}", 15524 text = "Share on Digg"; 15525 break; 15526 case 'reddit': 15527 source = "http://reddit.com/submit?url={URL}", 15528 text = "Share on reddit"; 15529 break; 15530 } 15531 15532 obj[key] = { 15533 URL: value.URL && absolutizeURI(baseURL, value.URL) || opts.linkId && window.location.href || typeof url !== 'string' && baseURL || url && absolutizeURI(baseURL, url) || baseURL, 15534 source: value.source || source || value.URL && absolutizeURI(baseURL, value.URL) || url && absolutizeURI(baseURL, url), 15535 text: value.text || text || "Share on " + key, 15536 width: (typeof(value.width) != 'undefined' && !isNaN(value.width)) ? parseInt(value.width) : 640, 15537 height: value.height || 360 15538 }; 15539 15540 }); 15541 15542 return obj; 15543 }, 15544 15545 setSocial: function(obj, url, target) { 15546 var iL = this, 15547 socialBar = $('<div class="ilightbox-social"></div>'), 15548 buttons = '<ul>'; 15549 15550 obj = iL.normalizeSocial(obj, url); 15551 15552 $.each(obj, function(key, value) { 15553 var item = key.toLowerCase(), 15554 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, '+')); 15555 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>'; 15556 }); 15557 15558 buttons += '</ul>'; 15559 15560 socialBar.html(buttons); 15561 $('div.ilightbox-container', target).append(socialBar); 15562 }, 15563 15564 fullScreenAction: function() { 15565 var iL = this, 15566 vars = iL.vars; 15567 15568 if (fullScreenApi.supportsFullScreen) { 15569 if (fullScreenApi.isFullScreen()) fullScreenApi.cancelFullScreen(document.documentElement); 15570 else fullScreenApi.requestFullScreen(document.documentElement); 15571 } else { 15572 iL.doFullscreen(); 15573 } 15574 }, 15575 15576 doFullscreen: function() { 15577 var iL = this, 15578 vars = iL.vars, 15579 viewport = getViewport(), 15580 opts = iL.options; 15581 15582 if (opts.fullAlone) { 15583 var currentHolder = vars.holder, 15584 current = iL.items[vars.current], 15585 windowWidth = viewport.width, 15586 windowHeight = viewport.height, 15587 elements = [currentHolder, vars.nextPhoto, vars.prevPhoto, vars.nextButton, vars.prevButton, vars.overlay, vars.toolbar, vars.thumbnails, vars.loader], 15588 hideElements = [vars.nextPhoto, vars.prevPhoto, vars.nextButton, vars.prevButton, vars.loader, vars.thumbnails]; 15589 15590 if (!vars.isInFullScreen) { 15591 vars.isInFullScreen = vars.lockKey = vars.lockWheel = vars.lockSwipe = true; 15592 vars.overlay.css({ 15593 opacity: 1 15594 }); 15595 15596 $.each(hideElements, function(i, element) { 15597 element.hide(); 15598 }); 15599 15600 vars.fullScreenButton.attr('title', opts.text.exitFullscreen); 15601 15602 if (opts.fullStretchTypes.indexOf(current.type) != -1) currentHolder.data({
15603 naturalWidthOld: currentHolder.data('naturalWidth'), 15604 naturalHeightOld: currentHolder.data('naturalHeight'), 15605 naturalWidth: windowWidth, 15606 naturalHeight: windowHeight 15607 }); 15608 else { 15609 var viewport = current.options.fullViewPort || opts.fullViewPort || '', 15610 newWidth = windowWidth, 15611 newHeight = windowHeight, 15612 width = currentHolder.data('naturalWidth'), 15613 height = currentHolder.data('naturalHeight'); 15614 15615 if (viewport.toLowerCase() == 'fill') { 15616 newHeight = (newWidth / width) * height; 15617 15618 if (newHeight < windowHeight) { 15619 newWidth = (windowHeight / height) * width, 15620 newHeight = windowHeight; 15621 } 15622 } else if (viewport.toLowerCase() == 'fit') { 15623 var dims = iL.getNewDimenstions(newWidth, newHeight, width, height, true); 15624 15625 newWidth = dims.width, 15626 newHeight = dims.height; 15627 } else if (viewport.toLowerCase() == 'stretch') { 15628 newWidth = newWidth, 15629 newHeight = newHeight; 15630 } else { 15631 var scale = (width > newWidth || height > newHeight) ? true : false, 15632 dims = iL.getNewDimenstions(newWidth, newHeight, width, height, scale); 15633 newWidth = dims.width, 15634 newHeight = dims.height; 15635 } 15636 15637 currentHolder.data({ 15638 naturalWidthOld: currentHolder.data('naturalWidth'), 15639 naturalHeightOld: currentHolder.data('naturalHeight'), 15640 naturalWidth: newWidth, 15641 naturalHeight: newHeight 15642 }); 15643 } 15644 15645 $.each(elements, function(key, val) { 15646 val.addClass('ilightbox-fullscreen'); 15647 }); 15648 15649 //Trigger the onEnterFullScreen callback 15650 if (typeof opts.callback.onEnterFullScreen == 'function') opts.callback.onEnterFullScreen.call(iL, iL.ui); 15651 } else { 15652 vars.isInFullScreen = vars.lockKey = vars.lockWheel = vars.lockSwipe = false; 15653 vars.overlay.css({ 15654 opacity: iL.options.overlay.opacity 15655 }); 15656 15657 $.each(hideElements, function(i, element) { 15658 element.show(); 15659 }); 15660 15661 vars.fullScreenButton.attr('title', opts.text.enterFullscreen); 15662 15663 currentHolder.data({ 15664 naturalWidth: currentHolder.data('naturalWidthOld'), 15665 naturalHeight: currentHolder.data('naturalHeightOld'), 15666 naturalWidthOld: null, 15667 naturalHeightOld: null 15668 }); 15669 15670 $.each(elements, function(key, val) { 15671 val.removeClass('ilightbox-fullscreen'); 15672 }); 15673 15674 //Trigger the onExitFullScreen callback 15675 if (typeof opts.callback.onExitFullScreen == 'function') opts.callback.onExitFullScreen.call(iL, iL.ui); 15676 } 15677 } else { 15678 if (!vars.isInFullScreen) vars.isInFullScreen = true; 15679 else vars.isInFullScreen = false; 15680 } 15681 iL.repositionPhoto(true); 15682 }, 15683 15684 closeAction: function() { 15685 var iL = this, 15686 vars = iL.vars, 15687 opts = iL.options; 15688 15689 $win.unbind('.iLightBox'); 15690 $doc.off('.iLightBox'); 15691 15692 if (vars.isInFullScreen) fullScreenApi.cancelFullScreen(document.documentElement); 15693 15694 $('.ilightbox-overlay, .ilightbox-holder, .ilightbox-thumbnails').off('.iLightBox'); 15695 15696 if (opts.hide.effect) vars.overlay.stop().fadeOut(opts.hide.speed, function() { 15697 vars.overlay.remove(); 15698 vars.BODY.removeClass('ilightbox-noscroll').off('.iLightBox'); 15699 }); 15700 else { 15701 vars.overlay.remove(); 15702 vars.BODY.removeClass('ilightbox-noscroll').off('.iLightBox'); 15703 } 15704 15705 var fadeOuts = [vars.toolbar, vars.holder, vars.nextPhoto, vars.prevPhoto, vars.nextButton, vars.prevButton, vars.loader, vars.thumbnails]; 15706 15707 $.each(fadeOuts, function(i, element) { 15708 element.removeAttr('style').remove(); 15709 }); 15710 15711 vars.dontGenerateThumbs = vars.isInFullScreen = false; 15712 15713 window.iLightBox = null; 15714 15715 if (opts.linkId) { 15716 vars.hashLock = true; 15717 removeHash(); 15718 setTimeout(function() { 15719 vars.hashLock = false; 15720 }, 55); 15721 } 15722 15723 vars.nextButton.add(vars.prevButton).add(vars.innerPrevButton).add(vars.innerNextButton).removeClass('disabled'); 15724 15725 //Trigger the onHide callback 15726 if (typeof opts.callback.onHide == 'function') opts.callback.onHide.call(iL, iL.ui); 15727 }, 15728 15729 repositionPhoto: function() { 15730 var iL = this, 15731 vars = iL.vars, 15732 opts = iL.options, 15733 path = opts.path.toLowerCase(), 15734 viewport = getViewport(), 15735 winWidth = viewport.width, 15736 winHeight = viewport.height; 15737 15738 if (viewport.width < UNCODE.mediaQuery) opts.styles.nextOffsetX = 0; 15739 15740 var thumbsOffsetW = (vars.isInFullScreen && opts.fullAlone || vars.isMobile) ? 0 : ((path == 'horizontal') ? 0 : vars.thumbnails.outerWidth()), 15741 thumbsOffsetH = vars.isMobile ? vars.toolbar.outerHeight() : ((vars.isInFullScreen && opts.fullAlone) ? 0 : ((path == 'horizontal') ? vars.thumbnails.outerHeight() : 0)), 15742 width = (vars.isInFullScreen && opts.fullAlone) ? winWidth : (winWidth - (opts.styles.pageOffsetX)), 15743 height = (vars.isInFullScreen && opts.fullAlone) ? winHeight : (winHeight - (opts.styles.pageOffsetY)), 15744 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, 15745 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))); 15746 15747 var elObject = { 15748 type: 'current', 15749 width: width, 15750 height: height, 15751 item: iL.items[vars.current], 15752 offsetW: offsetW, 15753 offsetH: offsetH,
15754 thumbsOffsetW: thumbsOffsetW, 15755 thumbsOffsetH: thumbsOffsetH, 15756 animate: arguments.length, 15757 holder: vars.holder 15758 }; 15759 15760 iL.repositionEl(elObject); 15761 15762 if (iL.items[vars.next]) { 15763 elObject = $.extend(elObject, { 15764 type: 'next', 15765 item: iL.items[vars.next], 15766 offsetX: opts.styles.nextOffsetX, 15767 offsetY: opts.styles.nextOffsetY, 15768 holder: vars.nextPhoto 15769 }); 15770 15771 iL.repositionEl(elObject); 15772 } 15773 15774 if (iL.items[vars.prev]) { 15775 elObject = $.extend(elObject, { 15776 type: 'prev', 15777 item: iL.items[vars.prev], 15778 offsetX: opts.styles.nextOffsetX, 15779 offsetY: opts.styles.prevOffsetY, 15780 holder: vars.prevPhoto 15781 }); 15782 15783 iL.repositionEl(elObject); 15784 } 15785 15786 var loaderCss = (path == "horizontal") ? { 15787 left: parseInt((width / 2) - (vars.loader.outerWidth() / 2)) 15788 } : { 15789 top: parseInt((height / 2) - (vars.loader.outerHeight() / 2)) 15790 }; 15791 vars.loader.css(loaderCss); 15792 }, 15793 15794 repositionEl: function(obj) { 15795 var iL = this, 15796 vars = iL.vars, 15797 opts = iL.options, 15798 path = opts.path.toLowerCase(), 15799 widthAvail = (obj.type == 'current') ? ((vars.isInFullScreen && opts.fullAlone) ? obj.width : (obj.width - obj.offsetW)) : (obj.width - obj.offsetW), 15800 heightAvail = (obj.type == 'current') ? ((vars.isInFullScreen && opts.fullAlone) ? obj.height : (obj.height - obj.offsetH)) : (obj.height - obj.offsetH), 15801 itemParent = obj.item, 15802 item = obj.item.options, 15803 holder = obj.holder, 15804 offsetX = obj.offsetX || 0, 15805 offsetY = obj.offsetY || 0, 15806 //Uncode change ##START## 15807 toolbarHeight = $('.ilightbox-inner-toolbar', holder).length ? parseInt( $('.ilightbox-inner-toolbar', holder).outerHeight() ) : 0, 15808 //Uncode change ##END## 15809 thumbsOffsetW = obj.thumbsOffsetW, 15810 thumbsOffsetH = obj.thumbsOffsetH; 15811 15812 if (obj.type == 'current') { 15813 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); 15814 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); 15815 } else { 15816 if (typeof item.width == 'number' && item.width) widthAvail = (item.width > widthAvail) ? widthAvail : item.width; 15817 if (typeof item.height == 'number' && item.height) heightAvail = (item.height > heightAvail) ? heightAvail : item.height; 15818 } 15819 15820 15821 //Uncode change ##START## 15822 heightAvail = parseInt(heightAvail - toolbarHeight); 15823 // heightAvail = parseInt(heightAvail - $('.ilightbox-inner-toolbar', holder).outerHeight()); 15824 //Uncode change ##END## 15825 15826 var width = (typeof item.width == 'string' && item.width.indexOf('%') != -1) ? percentToValue(parseInt(item.width.replace('%', '')), obj.width) : holder.data('naturalWidth'), 15827 height = (typeof item.height == 'string' && item.height.indexOf('%') != -1) ? percentToValue(parseInt(item.height.replace('%', '')), obj.height) : holder.data('naturalHeight'); 15828 15829 var dims = ((typeof item.width == 'string' && item.width.indexOf('%') != -1 || typeof item.height == 'string' && item.height.indexOf('%') != -1) ? { 15830 width: width, 15831 height: height 15832 } : iL.getNewDimenstions(widthAvail, heightAvail, width, height)), 15833 newDims = $.extend({}, dims, {}); 15834 15835 if (obj.type == 'prev' || obj.type == 'next') 15836 width = parseInt(dims.width * ((obj.type == 'next') ? opts.styles.nextScale : opts.styles.prevScale)), 15837 height = parseInt(dims.height * ((obj.type == 'next') ? opts.styles.nextScale : opts.styles.prevScale)); 15838 else 15839 width = dims.width, 15840 height = dims.height; 15841 15842 var widthDiff = parseInt((getPixel(holder, 'padding-left') + getPixel(holder, 'padding-right') + getPixel(holder, 'border-left-width') + getPixel(holder, 'border-right-width')) / 2), 15843 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); 15844 15845 switch (obj.type) { 15846 case 'current': 15847 var top = parseInt((obj.height / 2) - (height / 2) - heightDiff - (thumbsOffsetH / 2)), 15848 left = parseInt((obj.width / 2) - (width / 2) - widthDiff - (thumbsOffsetW / 2)); 15849 break; 15850
15851 case 'next': 15852 var top = (path == 'horizontal') ? parseInt((obj.height / 2) - offsetY - (height / 2) - heightDiff - (thumbsOffsetH / 2)) : parseInt(obj.height - offsetX - heightDiff - (thumbsOffsetH / 2)), 15853 left = (path == 'horizontal') ? parseInt(obj.width - offsetX - widthDiff - (thumbsOffsetW / 2)) : parseInt((obj.width / 2) - (width / 2) - widthDiff - offsetY - (thumbsOffsetW / 2)); 15854 break; 15855 15856 case 'prev': 15857 var top = (path == 'horizontal') ? parseInt((obj.height / 2) - offsetY - (height / 2) - heightDiff - (thumbsOffsetH / 2)) : parseInt(offsetX - heightDiff - height - (thumbsOffsetH / 2)), 15858 left = (path == 'horizontal') ? parseInt(offsetX - widthDiff - width - (thumbsOffsetW / 2)) : parseInt((obj.width / 2) - offsetY - (width / 2) - widthDiff - (thumbsOffsetW / 2)); 15859 break; 15860 } 15861 15862 holder.data('offset', { 15863 top: top, 15864 left: left, 15865 newDims: newDims, 15866 diff: { 15867 W: widthDiff, 15868 H: heightDiff 15869 }, 15870 thumbsOffset: { 15871 W: thumbsOffsetW, 15872 H: thumbsOffsetH 15873 }, 15874 object: obj 15875 }); 15876 15877 var opacityMobile; 15878 if ( isMobile ) { 15879 opacityMobile = { 15880 opacity: 1, 15881 top: top, 15882 left: left 15883 }; 15884 } else { 15885 opacityMobile = { 15886 top: top, 15887 left: left 15888 }; 15889 } 15890 15891 if (obj.animate > 0 && opts.effects.reposition) { 15892 holder.css(transform, gpuAcceleration).stop().animate( 15893 opacityMobile, 15894 opts.effects.repositionSpeed, 'easeOutCirc', function() { 15895 holder.css(transform, ''); 15896 }); 15897 $('div.ilightbox-container', holder).stop().animate({ 15898 width: width, 15899 height: height 15900 }, opts.effects.repositionSpeed, 'easeOutCirc'); 15901 $('div.ilightbox-inner-toolbar', holder).stop().animate({ 15902 width: width 15903 }, opts.effects.repositionSpeed, 'easeOutCirc', function() { 15904 $(this).css('overflow', 'visible'); 15905 }); 15906 } else { 15907 holder.css(opacityMobile); 15908 $('div.ilightbox-container', holder).css({ 15909 width: width, 15910 height: height 15911 }); 15912 $('div.ilightbox-inner-toolbar', holder).css({ 15913 width: width 15914 }); 15915 } 15916 }, 15917 15918 15919 resume: function(priority) { 15920 var iL = this, 15921 vars = iL.vars, 15922 opts = iL.options; 15923 15924 if (!opts.slideshow.pauseTime || opts.controls.slideshow && vars.total <= 1 || priority < vars.isPaused) { 15925 return; 15926 } 15927 15928 vars.isPaused = 0; 15929 15930 if (vars.cycleID) { 15931 vars.cycleID = clearTimeout(vars.cycleID); 15932 } 15933 15934 vars.cycleID = setTimeout(function() { 15935 if (vars.current == vars.total - 1) iL.goTo(0); 15936 else iL.moveTo('next'); 15937 }, opts.slideshow.pauseTime); 15938 }, 15939 15940 pause: function(priority) { 15941 var iL = this, 15942 vars = iL.vars, 15943 opts = iL.options; 15944 15945 if (priority < vars.isPaused) { 15946 return; 15947 } 15948 15949 vars.isPaused = priority || 100; 15950 15951 if (vars.cycleID) { 15952 vars.cycleID = clearTimeout(vars.cycleID); 15953 } 15954 }, 15955 15956 resetCycle: function() { 15957 var iL = this, 15958 vars = iL.vars, 15959 opts = iL.options; 15960 15961 if (opts.controls.slideshow && vars.cycleID && !vars.isPaused) { 15962 iL.resume(); 15963 } 15964 }, 15965 15966 getNewDimenstions: function(width, height, width_old, height_old, thumb) { 15967 var iL = this; 15968 15969 if (!width) factor = height / height_old; 15970 else if (!height) factor = width / width_old; 15971 else factor = min(width / width_old, height / height_old); 15972 15973 if (!thumb) { 15974 if (factor > iL.options.maxScale) factor = iL.options.maxScale; 15975 else if (factor < iL.options.minScale) factor = iL.options.minScale; 15976 } 15977 15978 var final_width = (iL.options.keepAspectRatio) ? round(width_old * factor) : width, 15979 final_height = (iL.options.keepAspectRatio) ? round(height_old * factor) : height; 15980 15981 return { 15982 width: final_width, 15983 height: final_height, 15984 ratio: factor 15985 }; 15986 }, 15987 15988 setOption: function(options) { 15989 var iL = this; 15990 15991 iL.options = $.extend(true, iL.options, options || {}); 15992 iL.refresh(); 15993 }, 15994 15995 availPlugins: function() { 15996 var iL = this, 15997 testEl = document.createElement("video"); 15998 15999 iL.plugins = { 16000 flash: !isMobile, 16001 quicktime: (parseInt(PluginDetect.getVersion("QuickTime")) >= 0) ? true : false, 16002 html5H264: !!(testEl.canPlayType && testEl.canPlayType('video/mp4').replace(/no/, '')), 16003 html5WebM: !!(testEl.canPlayType && testEl.canPlayType('video/webm').replace(/no/, '')), 16004 html5Vorbis: !!(testEl.canPlayType && testEl.canPlayType('video/ogg').replace(/no/, '')), 16005 html5QuickTime: !!(testEl.canPlayType && testEl.canPlayType('video/quicktime').replace(/no/, '')) 16006 }; 16007 }, 16008 16009 addContent: function(element, obj) { 16010 var iL = this, 16011 el; 16012 16013 switch (obj.type) { 16014 case 'video': 16015 var HTML5 = false, 16016 videoType = obj.videoType, 16017 html5video = obj.options.html5video; 16018 16019 if (((videoType == 'video/mp4' || obj.ext == 'mp4' || obj.ext == 'm4v') || html5video.h264) && iL.plugins.html5H264) 16020 obj.ext = 'mp4', 16021 obj.URL = html5video.h264 || obj.URL; 16022 else if (html5video.webm && iL.plugins.html5WebM) 16023 obj.ext = 'webm', 16024 obj.URL = html5video.webm || obj.URL; 16025 else if (html5video.ogg && iL.plugins.html5Vorbis) 16026 obj.ext = 'ogv', 16027 obj.URL = html5video.ogg || obj.URL; 16028 16029 if (iL.plugins.html5H264 && (videoType == 'video/mp4' || obj.ext == 'mp4' || obj.ext == 'm4v')) HTML5 = true, videoType = "video/mp4"; 16030 else if (iL.plugins.html5WebM && (videoType == 'video/webm' || obj.ext == 'webm')) HTML5 = true, videoType = "video/webm"; 16031 else if (iL.plugins.html5Vorbis && (videoType == 'video/ogg' || obj.ext == 'ogv')) HTML5 = true, videoType = "video/ogg"; 16032 else if (iL.plugins.html5QuickTime && (videoType == 'video/quicktime' || obj.ext == 'mov' || obj.ext == 'qt')) HTML5 = true, videoType = "video/quicktime"; 16033 16034 if (HTML5) { 16035 el = $('<video />
16035', { 16036 "width": "100%", 16037 "height": "100%", 16038 "preload": html5video.preload, 16039 "autoplay": html5video.autoplay, 16040 "loop": html5video.loop, 16041 "poster": html5video.poster, 16042 "controls": html5video.controls, 16043 "controlslist": "nodownload" 16044 }).append($('<source />', { 16045 "src": obj.URL, 16046 "type": videoType 16047 })); 16048 } else { 16049 if (!iL.plugins.quicktime) el = $('<span />', { 16050 "class": "ilightbox-alert", 16051 html: iL.options.errors.missingPlugin.replace('{pluginspage}', pluginspages.quicktime).replace('{type}', 'QuickTime') 16052 }); 16053 else { 16054 16055 el = $('<object />', { 16056 "type": "video/quicktime", 16057 "pluginspage": pluginspages.quicktime 16058 }).attr({ 16059 "data": obj.URL, 16060 "width": "100%", 16061 "height": "100%" 16062 }).append($('<param />', { 16063 "name": "src", 16064 "value": obj.URL 16065 })).append($('<param />', { 16066 "name": "autoplay", 16067 "value": "false" 16068 })).append($('<param />', { 16069 "name": "loop", 16070 "value": "false" 16071 })).append($('<param />', { 16072 "name": "scale", 16073 "value": "tofit" 16074 })); 16075 16076 if (browser.msie) el = QT_GenerateOBJECTText(obj.URL, '100%', '100%', '', 'SCALE', 'tofit', 'AUTOPLAY', 'false', 'LOOP', 'false'); 16077 } 16078 } 16079 16080 break; 16081 16082 case 'flash': 16083 if (!iL.plugins.flash) el = $('<span />', { 16084 "class": "ilightbox-alert", 16085 html: iL.options.errors.missingPlugin.replace('{pluginspage}', pluginspages.flash).replace('{type}', 'Adobe Flash player') 16086 }); 16087 else { 16088 var flashvars = "", 16089 i = 0; 16090 16091 if (obj.options.flashvars) $.each(obj.options.flashvars, function(k, v) { 16092 if (i != 0) flashvars += "&"; 16093 flashvars += k + "=" + encodeURIComponent(v); 16094 i++; 16095 }); 16096 else flashvars = null; 16097 16098 el = $('<embed />').attr({ 16099 "type": "application/x-shockwave-flash", 16100 "src": obj.URL, 16101 "width": (typeof obj.options.width == 'number' && obj.options.width && iL.options.minScale == '1' && iL.options.maxScale == '1') ? obj.options.width : "100%", 16102 "height": (typeof obj.options.height == 'number' && obj.options.height && iL.options.minScale == '1' && iL.options.maxScale == '1') ? obj.options.height : "100%", 16103 "quality": "high", 16104 "bgcolor": "#000000", 16105 "play": "true", 16106 "loop": "true", 16107 "menu": "true", 16108 "wmode": "transparent", 16109 "scale": "showall", 16110 "allowScriptAccess": "always", 16111 "allowFullScreen": "true", 16112 "flashvars": flashvars, 16113 "fullscreen": "yes" 16114 }); 16115 } 16116 16117 break; 16118 16119 case 'iframe': 16120 el = $('<iframe />').attr({ 16121 "width": (typeof obj.options.width == 'number' && obj.options.width && iL.options.minScale == '1' && iL.options.maxScale == '1') ? obj.options.width : "100%", 16122 "height": (typeof obj.options.height == 'number' && obj.options.height && iL.options.minScale == '1' && iL.options.maxScale == '1') ? obj.options.height : "100%", 16123 src: obj.URL, 16124 frameborder: 0, 16125 'hspace': 0, 16126 'vspace': 0, 16127 'scrolling': supportTouch ? 'auto' : 'scroll', 16128 'webkitAllowFullScreen': '', 16129 'mozallowfullscreen': '', 16130 'allowFullScreen': '' 16131 }); 16132 16133 break; 16134 16135 case 'inline': 16136 el = $('<div class="ilightbox-wrapper"></div>').html($(obj.URL).clone(true)); 16137 16138 break; 16139 16140 case 'html': 16141 var object = obj.URL, 16142 el; 16143 16144 if (object[0].nodeName) { 16145 el = $('<div class="ilightbox-wrapper"></div>').html(object); 16146 } else { 16147 var dom = $(obj.URL), 16148 html = (dom.selector) ? $('<div>' + dom + '</div>') : dom; 16149 el = $('<div class="ilightbox-wrapper"></div>').html(html); 16150 } 16151 16152 break; 16153 } 16154 16155 $('div.ilightbox-container', element).empty().html(el); 16156 16157 // For fixing Chrome about just playing the video for first time 16158 if (el[0].tagName.toLowerCase() === 'video' && browser.webkit) setTimeout(function() { 16159 var src = el[0].currentSrc + '?' + floor(random() * 30000); 16160 el[0].currentSrc = src; 16161 el[0].src = src; 16162 }); 16163 16164 return el; 16165 }, 16166 16167 ogpRecognition: function(obj, callback) { 16168 var iL = this, 16169 url = obj.URL; 16170 16171 iL.showLoader(); 16172 doAjax(url, function(data) { 16173 iL.hideLoader(); 16174 if (data) { 16175 var object = new Object(); 16176 16177 object.length = false, 16178 object.url = data.url; 16179 16180 if (data.status == 200) { 16181 var result = data.results, 16182 type = result.type, 16183 source = result.source; 16184 16185 object.source = source.src, 16186 object.width = source.width && parseInt(source.width) || 0, 16187 object.height = source.height && parseInt(source.height) || 0, 16188 object.type = type, 16189 object.thumbnail = source.thumbnail || result.images && result.images[0], 16190 object.html5video = result.html5video || {}, 16191 object.length = true; 16192 16193 if (source.type == 'application/x-shockwave-flash') object.type = "flash"; 16194 else if (source.type.indexOf("video/") != -1) object.type = "video"; 16195 else if (source.type.indexOf("/html") != -1) object.type = "iframe"; 16196 else if (source.type.indexOf("image/") != -1) object.type = "image"; 16197 16198 } else if (typeof data.response != 'undefined') 16199 throw data.response; 16200 16201 callback.call(this, object.length ? object : false); 16202 } 16203 }); 16204 }, 16205 16206 hashChangeHandler: function(url) { 16207 var iL = this, 16208 vars = iL.vars, 16209 opts = iL.options, 16210 URL = url || window.location.href, 16211 hash = parseURI(URL).hash, 16212 split = hash.split('/'), 16213 index = split[1]; 16214 16215 if (vars.hashLock || ('#' + opts.linkId != split[0] && hash.length > 1)) return; 16216 16217 if (index) { 16218 var target = split[1] || 0; 16219 if (iL.items[target]) {
16220 var overlay = $('.ilightbox-overlay'); 16221 if (overlay.length && overlay.attr('linkid') == opts.linkId) { 16222 iL.goTo(target); 16223 } else { 16224 iL.itemsObject[target].trigger(ishybrid ? "itap click" : supportTouch ? 'itap' : 'click'); 16225 //iL.goTo(target); 16226 } 16227 } else { 16228 var overlay = $('.ilightbox-overlay'); 16229 if (overlay.length) iL.closeAction(); 16230 } 16231 } else { 16232 var overlay = $('.ilightbox-overlay'); 16233 if (overlay.length) iL.closeAction(); 16234 } 16235 } 16236 }; 16237 16238 /** 16239 * Parse style to pixels. 16240 * 16241 * @param {Object} $element jQuery object with element. 16242 * @param {Property} property CSS property to get the pixels from. 16243 * 16244 * @return {Int} 16245 */ 16246 function getPixel($element, property) { 16247 return parseInt($element.css(property), 10) || 0; 16248 } 16249 16250 /** 16251 * Make sure that number is within the limits. 16252 * 16253 * @param {Number} number 16254 * @param {Number} min 16255 * @param {Number} max 16256 * 16257 * @return {Number} 16258 */ 16259 function within(number, min, max) { 16260 return number < min ? min : number > max ? max : number; 16261 } 16262 16263 /** 16264 * Get viewport/window size (width and height). 16265 * 16266 * @return {Object} 16267 */ 16268 function getViewport() { 16269 var e = window, 16270 a = 'inner'; 16271 if (!('innerWidth' in window)) { 16272 a = 'client'; 16273 e = document.documentElement || document.body; 16274 } 16275 return { 16276 width: e[a + 'Width'], 16277 height: e[a + 'Height'] 16278 } 16279 } 16280 16281 /** 16282 * Remove hash tag from the URL 16283 * 16284 * @return {Void} 16285 */ 16286 function removeHash() { 16287 var scroll = getScrollXY(); 16288 16289 //UNCODE change 16290 // window.location.hash = ""; 16291 // history.pushState("", document.title, window.location.pathname + window.location.search); 16292 history.replaceState({}, document.title, window.location.pathname + window.location.search); 16293 16294 // Restore the scroll offset, should be flicker free 16295 window.scrollTo(scroll.x, scroll.y); 16296 } 16297 16298 /** 16299 * Do the ajax requests with callback. 16300 * 16301 * @param {String} url 16302 * @param {Function} callback 16303 * 16304 * @return {Void} 16305 */ 16306 function doAjax(url, callback) { 16307 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'); 16308 $.ajax({ 16309 url: url, 16310 dataType: 'jsonp' 16311 }); 16312 16313 iLCallback = function(data) { 16314 callback.call(this, data); 16315 }; 16316 } 16317 16318 /** 16319 * Find image from DOM elements 16320 * 16321 * @param {Element} element 16322 * 16323 * @return {Void} 16324 */ 16325 function findImageInElement(element) { 16326 var elements = $('*', element), 16327 imagesArr = new Array(); 16328 16329 elements.each(function() { 16330 var url = "", 16331 element = this; 16332 16333 if ($(element).css("background-image") != "none") { 16334 url = $(element).css("background-image"); 16335 } else if (typeof($(element).attr("src")) != "undefined" && element.nodeName.toLowerCase() == "img") { 16336 url = $(element).attr("src"); 16337 } 16338 16339 if (url.indexOf("gradient") == -1) { 16340 url = url.replace(/url\(\"/g, ""); 16341 url = url.replace(/url\(/g, ""); 16342 url = url.replace(/\"\)/g, ""); 16343 url = url.replace(/\)/g, ""); 16344 16345 var urls = url.split(","); 16346 16347 for (var i = 0; i < urls.length; i++) { 16348 if (urls[i].length > 0 && $.inArray(urls[i], imagesArr) == -1) { 16349 var extra = ""; 16350 if (browser.msie && browser.version < 9) { 16351 extra = "?" + floor(random() * 3000); 16352 } 16353 imagesArr.push(urls[i] + extra); 16354 } 16355 } 16356 } 16357 }); 16358 16359 return imagesArr; 16360 } 16361 16362 /** 16363 * Get file extension. 16364 * 16365 * @param {String} URL 16366 * 16367 * @return {String} 16368 */ 16369 function getExtension(URL) { 16370 if (URL !== null) { 16371 //UNCODE: fix issue to detect media type with query strings 16372 var ext = URL.indexOf('?') !== -1 ? URL.split('?')[0] : URL; 16373 ext = ext.split('.').pop().toLowerCase(); 16374 16375 return ext; 16376 } 16377 } 16378 16379 /** 16380 * Get type via extension. 16381 * 16382 * @param {String} URL 16383 * 16384 * @return {String} 16385 */ 16386 function getTypeByExtension(URL) { 16387 var type, 16388 ext = getExtension(URL); 16389 16390 //Uncode addition ##START## 16391 if (URL == undefined) { 16392 return false; 16393 } 16394 //Uncode addition ##END## 16395 16396 if (extensions.image.indexOf(ext) !== -1) type = 'image'; 16397 else if (extensions.flash.indexOf(ext) !== -1) type = 'flash'; 16398 else if (extensions.video.indexOf(ext) !== -1) type = 'video'; 16399 else if (ext.substring(0, 1) == "#") type = 'inline'; //Uncode addition 16400 else type = 'iframe'; 16401 16402 return type; 16403 } 16404 16405 /** 16406 * Return value from percent of a number. 16407 * 16408 * @param {Number} percent 16409 * @param {Number} total 16410 * 16411 * @return {Number} 16412 */ 16413 function percentToValue(percent, total) { 16414 return parseInt((total / 100) * percent); 16415 } 16416 16417 /** 16418 * A JavaScript equivalent of PHPâs parse_url. 16419 * 16420 * @param {String} url The URL to parse. 16421 * 16422 * @return {Mixed} 16423 */ 16424 function parseURI(url) { 16425 var m = String(url).replace(/^\s+|\s+$/g, '').match(/^([^:\/?#]+:)?(\/\/(?:[^:@]*(?::[^:@]*)?@)?(([^:\/?#]*)(?::(\d*))?))?([^?#]*)(\?[^#]*)?(#[\s\S]*)?/); 16426 // authority = '//' + user + ':' + pass '@' + hostname + ':' port 16427 return (m ? { 16428 href: m[0] || '', 16429 protocol: m[1] || '', 16430 authority: m[2] || '', 16431 host: m[3] || '', 16432 hostname: m[4] || '', 16433 port: m[5] || '', 16434 pathname: m[6] || '', 16435 search: m[7] || '', 16436 hash: m[8] || '' 16437 } : null); 16438 } 16439 16440 /** 16441 * Gets the absolute URI. 16442 * 16443 * @param {String} href The relative URL. 16444 * @param {String} base The base URL. 16445 * 16446 * @return {String} The absolute URL. 16447 */ 16448 function absolutizeURI(base, href) { // RFC 3986 16449 var iL = this; 16450 16451 function removeDotSegments(input) { 16452 var output = []; 16453 input.replace(/^(\.\.?(\/|$))+/, '') 16454 .replace(/\/(\.(\/|$))+/g, '/') 16455 .replace(/\/\.\.$/, '/../') 16456 .replace(/\/?[^\/]*/g, function(p) { 16457 if (p === '/..') { 16458 output.pop(); 16459 } else { 16460 output.push(p); 16461 } 16462 }); 16463 return output.join('').replace(/^\//, input.charAt(0) === '/' ? '/' : ''); 16464 } 16465 16466 href = parseURI(href || ''); 16467 base = parseURI(base || ''); 16468 16469 return !href || !base ? null : (href.protocol || base.protocol) + 16470 (href.protocol || href.authority ? href.authority : base.authority) + 16471 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)) + 16472 (href.protocol || href.authority || href.pathname ? href.search : (href.search || base.search)) + 16473 href.hash; 16474 } 16475 16476 /** 16477 * A JavaScript equivalent of PHPâs version_compare. 16478 * 16479 * @param {String} v1 16480 * @param {String} v2 16481 * @param {String} operator
16482 * 16483 * @return {Boolean} 16484 */ 16485 function version_compare(v1, v2, operator) { 16486 this.php_js = this.php_js || {}; 16487 this.php_js.ENV = this.php_js.ENV || {}; 16488 var i = 0, 16489 x = 0, 16490 compare = 0, 16491 vm = { 16492 'dev': -6, 16493 'alpha': -5, 16494 'a': -5, 16495 'beta': -4, 16496 'b': -4, 16497 'RC': -3, 16498 'rc': -3, 16499 '#': -2, 16500 'p': 1, 16501 'pl': 1 16502 }, 16503 prepVersion = function(v) { 16504 v = ('' + v).replace(/[_\-+]/g, '.'); 16505 v = v.replace(/([^.\d]+)/g, '.$1.').replace(/\.{2,}/g, '.'); 16506 return (!v.length ? [-8] : v.split('.')); 16507 }, 16508 numVersion = function(v) { 16509 return !v ? 0 : (isNaN(v) ? vm[v] || -7 : parseInt(v, 10)); 16510 }; 16511 v1 = prepVersion(v1); 16512 v2 = prepVersion(v2); 16513 x = max(v1.length, v2.length); 16514 for (i = 0; i < x; i++) { 16515 if (v1[i] == v2[i]) { 16516 continue; 16517 } 16518 v1[i] = numVersion(v1[i]); 16519 v2[i] = numVersion(v2[i]); 16520 if (v1[i] < v2[i]) { 16521 compare = -1; 16522 break; 16523 } else if (v1[i] > v2[i]) { 16524 compare = 1; 16525 break; 16526 } 16527 } 16528 if (!operator) { 16529 return compare; 16530 } 16531 16532 switch (operator) { 16533 case '>': 16534 case 'gt': 16535 return (compare > 0); 16536 case '>=': 16537 case 'ge': 16538 return (compare >= 0); 16539 case '<=': 16540 case 'le': 16541 return (compare <= 0); 16542 case '==': 16543 case '=': 16544 case 'eq': 16545 return (compare === 0); 16546 case '<>': 16547 case '!=': 16548 case 'ne': 16549 return (compare !== 0); 16550 case '': 16551 case '<': 16552 case 'lt': 16553 return (compare < 0); 16554 default: 16555 return null; 16556 } 16557 } 16558 16559 16560 // Begin the iLightBox plugin 16561 $.fn.iLightBox = function() { 16562 16563 var args = arguments, 16564 opt = ($.isPlainObject(args[0])) ? args[0] : args[1], 16565 items = ($.isArray(args[0]) || typeof args[0] == 'string') ? args[0] : args[1]; 16566 16567 if (!opt) opt = {}; 16568 16569 // Default options. Play carefully. 16570 var options = $.extend(true, { 16571 attr: 'href', 16572 path: 'vertical', 16573 skin: 'dark', 16574 linkId: false, 16575 infinite: false, 16576 startFrom: 0, 16577 randomStart: false, 16578 keepAspectRatio: true, 16579 maxScale: 1, 16580 minScale: .2, 16581 innerToolbar: false, 16582 smartRecognition: false, 16583 mobileOptimizer: true, 16584 fullAlone: true, 16585 fullViewPort: null, 16586 fullStretchTypes: 'flash, video', 16587 overlay: { 16588 blur: true, 16589 opacity: .85 16590 }, 16591 controls: { 16592 arrows: false, 16593 slideshow: false, 16594 toolbar: true, 16595 fullscreen: true, 16596 thumbnail: true, 16597 keyboard: true, 16598 mousewheel: true, 16599 swipe: true 16600 }, 16601 keyboard: { 16602 left: true, // previous 16603 right: true, // next 16604 up: true, // previous 16605 down: true, // next 16606 esc: true, // close 16607 shift_enter: true // fullscreen 16608 }, 16609 show: { 16610 effect: true, 16611 speed: 300, 16612 title: true 16613 }, 16614 hide: { 16615 effect: true, 16616 speed: 300 16617 }, 16618 caption: { 16619 start: true, 16620 show: 'mouseenter', 16621 hide: 'mouseleave' 16622 }, 16623 social: { 16624 start: true, 16625 show: 'mouseenter', 16626 hide: 'mouseleave',
16627 buttons: false 16628 }, 16629 styles: { 16630 pageOffsetX: 0, 16631 pageOffsetY: 0, 16632 nextOffsetX: 45, 16633 nextOffsetY: 0, 16634 nextOpacity: 1, 16635 nextScale: 1, 16636 prevOffsetX: 45, 16637 prevOffsetY: 0, 16638 prevOpacity: 1, 16639 prevScale: 1 16640 }, 16641 thumbnails: { 16642 maxWidth: 120, 16643 maxHeight: 80, 16644 normalOpacity: 1, 16645 activeOpacity: .6 16646 }, 16647 effects: { 16648 reposition: true, 16649 repositionSpeed: 200, 16650 switchSpeed: 500, 16651 loadedFadeSpeed: 180, 16652 fadeSpeed: 200 16653 }, 16654 slideshow: { 16655 pauseTime: 5000, 16656 pauseOnHover: false, 16657 startPaused: true 16658 }, 16659 text: { 16660 close: "Press Esc to close", 16661 enterFullscreen: "Enter Fullscreen (Shift+Enter)", 16662 exitFullscreen: "Exit Fullscreen (Shift+Enter)", 16663 slideShow: "Slideshow", 16664 next: "Next", 16665 previous: "Previous" 16666 }, 16667 errors: { 16668 loadImage: "An error occurred when trying to load photo.", 16669 loadContents: "An error occurred when trying to load contents.", 16670 missingPlugin: "The content your are attempting to view requires the <a href='{pluginspage}' target='_blank'>{type} plugin<\/a>." 16671 }, 16672 ajaxSetup: { 16673 url: '', 16674 beforeSend: function(jqXHR, settings) {}, 16675 cache: false, 16676 complete: function(jqXHR, textStatus) {}, 16677 crossDomain: false, 16678 error: function(jqXHR, textStatus, errorThrown) {}, 16679 success: function(data, textStatus, jqXHR) {}, 16680 global: true, 16681 ifModified: false, 16682 username: null, 16683 password: null, 16684 type: 'GET' 16685 }, 16686 callback: {} 16687 }, opt); 16688 16689 var instant = ($.isArray(items) || typeof items == 'string') ? true : false; 16690 16691 items = $.isArray(items) ? items : new Array(); 16692 16693 if (typeof args[0] == 'string') items[0] = args[0]; 16694 16695 if (version_compare($.fn.jquery, '1.8', '>=')) { 16696 var iLB = new iLightBox($(this), options, items, instant); 16697 return { 16698 close: function() { 16699 iLB.closeAction(); 16700 }, 16701 fullscreen: function() { 16702 iLB.fullScreenAction(); 16703 }, 16704 moveNext: function() { 16705 iLB.moveTo('next'); 16706 }, 16707 movePrev: function() { 16708 iLB.moveTo('prev'); 16709 }, 16710 goTo: function(index) { 16711 iLB.goTo(index); 16712 }, 16713 refresh: function() { 16714 iLB.refresh(); 16715 }, 16716 reposition: function() { 16717 (arguments.length > 0) ? iLB.repositionPhoto(true): iLB.repositionPhoto(); 16718 }, 16719 setOption: function(options) { 16720 iLB.setOption(options); 16721 }, 16722 destroy: function() { 16723 iLB.closeAction(); 16724 iLB.dispatchItemsEvents(); 16725 } 16726 }; 16727 } else { 16728 throw "The jQuery version that was loaded is too old. iLightBox requires jQuery 1.8+"; 16729 } 16730 16731 }; 16732 16733 16734 $.iLightBox = function() { 16735 return $.fn.iLightBox(arguments[0], arguments[1]); 16736 }; 16737 16738 function getScrollXY() { 16739 var scrOfX = 0, 16740 scrOfY = 0; 16741 if (typeof(window.pageYOffset) == 'number') { 16742 //Netscape compliant 16743 scrOfY = window.pageYOffset; 16744 scrOfX = window.pageXOffset; 16745 } else if (document.body && (document.body.scrollLeft || document.body.scrollTop)) { 16746 //DOM compliant 16747 scrOfY = document.body.scrollTop; 16748 scrOfX = document.body.scrollLeft; 16749 } else if (document.documentElement && (document.documentElement.scrollLeft || document.documentElement.scrollTop)) { 16750 //IE6 standards compliant mode 16751 scrOfY = document.documentElement.scrollTop; 16752 scrOfX = document.documentElement.scrollLeft; 16753 } 16754 return { 16755 x: scrOfX, 16756 y: scrOfY 16757 }; 16758 } 16759 16760 (function() { 16761 // add new event shortcuts 16762 $.each(("touchstart touchmove touchend " + 16763 "tap taphold " + 16764 "swipe swipeleft swiperight " + 16765 "scrollstart scrollstop").split(" "), function(i, name) { 16766 16767 $.fn[name] = function(fn) { 16768 return fn ? this.bind(name, fn) : this.trigger(name); 16769 }; 16770 16771 // jQuery < 1.8 16772 // if ($.attrFn) { 16773 // $.attrFn[name] = true; 16774 // } 16775 }); 16776 16777 var tapSettings = { 16778 startEvent: 'touchstart.iTap', 16779 endEvent: 'touchend.iTap' 16780 }; 16781 16782 // tap Event: 16783 $.event.special.itap = { 16784 setup: function() { 16785 16786 var self = this, 16787 $self = $(this), 16788 start, stop; 16789 16790 $self.bind(tapSettings.startEvent, function(event) { 16791 start = getScrollXY(); 16792 16793 $self.one(tapSettings.endEvent, function(event) { 16794 stop = getScrollXY(); 16795 16796 var orgEvent = event || window.event; 16797 event = $.event.fix(orgEvent); 16798 event.type = "itap"; 16799 16800 if ((start && stop) && (start.x == stop.x && start.y == stop.y))($.event.dispatch || $.event.handle).call(self, event); 16801 16802 start = stop = undefined; 16803 }); 16804 }); 16805 }, 16806 16807 teardown: function() { 16808 $(this).unbind(tapSettings.startEvent); 16809 } 16810 }; 16811 }()); 16812 16813 16814 //Fullscreen API 16815 (function() { 16816 fullScreenApi = { 16817 supportsFullScreen: false, 16818 isFullScreen: function() { 16819 return false;
16820 }, 16821 requestFullScreen: function() {}, 16822 cancelFullScreen: function() {}, 16823 fullScreenEventName: '', 16824 prefix: '' 16825 }, 16826 browserPrefixes = 'webkit moz o ms khtml'.split(' '); 16827 16828 // check for native support 16829 if (typeof document.cancelFullScreen != 'undefined') { 16830 fullScreenApi.supportsFullScreen = true; 16831 } else { 16832 // check for fullscreen support by vendor prefix 16833 for (var i = 0, il = browserPrefixes.length; i < il; i++) { 16834 fullScreenApi.prefix = browserPrefixes[i]; 16835 16836 if (typeof document[fullScreenApi.prefix + 'CancelFullScreen'] != 'undefined') { 16837 fullScreenApi.supportsFullScreen = true; 16838 16839 break; 16840 } 16841 } 16842 } 16843 16844 // update methods to do something useful 16845 if (fullScreenApi.supportsFullScreen) { 16846 fullScreenApi.fullScreenEventName = fullScreenApi.prefix + 'fullscreenchange'; 16847 16848 fullScreenApi.isFullScreen = function() { 16849 switch (this.prefix) { 16850 case '': 16851 return document.fullScreen; 16852 case 'webkit': 16853 return document.webkitIsFullScreen; 16854 default: 16855 return document[this.prefix + 'FullScreen']; 16856 } 16857 } 16858 fullScreenApi.requestFullScreen = function(el) { 16859 return (this.prefix === '') ? el.requestFullScreen() : el[this.prefix + 'RequestFullScreen'](); 16860 } 16861 fullScreenApi.cancelFullScreen = function(el) { 16862 return (this.prefix === '') ? document.cancelFullScreen() : document[this.prefix + 'CancelFullScreen'](); 16863 } 16864 } 16865 }()); 16866 16867 // Browser detect 16868 (function() { 16869 function uaMatch(ua) { 16870 ua = ua.toLowerCase(); 16871 16872 var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || 16873 /(webkit)[ \/]([\w.]+)/.exec(ua) || 16874 /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || 16875 /(msie) ([\w.]+)/.exec(ua) || 16876 ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || []; 16877 16878 return { 16879 browser: match[1] || "", 16880 version: match[2] || "0" 16881 }; 16882 } 16883 16884 var matched = uaMatch(navigator.userAgent); 16885 browser = {}; 16886 16887 if (matched.browser) { 16888 browser[matched.browser] = true; 16889 browser.version = matched.version; 16890 } 16891 16892 // Chrome is Webkit, but Webkit is also Safari. 16893 if (browser.chrome) { 16894 browser.webkit = true; 16895 } else if (browser.webkit) { 16896 browser.safari = true; 16897 } 16898 }()); 16899 16900 // Feature detects 16901 (function() { 16902 var prefixes = ['', 'webkit', 'moz', 'ms', 'o']; 16903 var el = document.createElement('div'); 16904 16905 function testProp(prop) { 16906 for (var p = 0, pl = prefixes.length; p < pl; p++) { 16907 var prefixedProp = prefixes[p] ? prefixes[p] + prop.charAt(0).toUpperCase() + prop.slice(1) : prop; 16908 if (el.style[prefixedProp] !== undefined) { 16909 return prefixedProp; 16910 } 16911 } 16912 } 16913 16914 // Global support indicators 16915 transform = testProp('transform') || ''; 16916 gpuAcceleration = testProp('perspective') ? 'translateZ(0) ' : ''; 16917 }()); 16918 16919 16920 /* 16921 PluginDetect v0.7.9 16922 www.pinlady.net/PluginDetect/license/ 16923 [ getVersion onWindowLoaded BetterIE ] 16924 [ Flash QuickTime Shockwave ] 16925 */ 16926 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;
16926d++){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);
16926d.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)}
16926c.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;
16926if(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(); 16927 16928 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)}; 16929 16930 16931 /* 16932 jQuery hashchange event v1.3 16933 https://github.com/cowboy/jquery-hashchange 16934 Copyright (c) 2010 "Cowboy" Ben Alman 16935 Dual licensed under the MIT and GPL licenses. 16936 */ 16937 (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= 16938 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|| 16939 "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;
16939a!==d&&(b.title=k.title,b.open(),e&&b.write('<script>document.domain="'+e+'"\x3c/script>'),b.close(),c.location.hash=a)}}();return h}()})(); 16940 16941 if (!Array.prototype.filter) { 16942 Array.prototype.filter = function(fun /*, thisp */ ) { 16943 "use strict"; 16944 16945 if (this == null) 16946 throw new TypeError(); 16947 16948 var t = Object(this); 16949 var len = t.length >>> 0; 16950 if (typeof fun != "function") 16951 throw new TypeError(); 16952 16953 var res = []; 16954 var thisp = arguments[1]; 16955 for (var i = 0; i < len; i++) { 16956 if (i in t) { 16957 var val = t[i]; // in case fun mutates this 16958 if (fun.call(thisp, val, i, t)) 16959 res.push(val); 16960 } 16961 } 16962 16963 return res; 16964 }; 16965 } 16966 16967 if (!Array.prototype.indexOf) { 16968 Array.prototype.indexOf = function(searchElement, fromIndex) { 16969 var k; 16970 16971 if (this == null) { 16972 throw new TypeError('"this" is null or not defined'); 16973 } 16974 16975 var O = Object(this); 16976 16977 var len = O.length >>> 0; 16978 16979 if (len === 0) { 16980 return -1; 16981 } 16982 16983 var n = +fromIndex || 0; 16984 16985 if (abs(n) === Infinity) { 16986 n = 0; 16987 } 16988 16989 if (n >= len) { 16990 return -1; 16991 } 16992 16993 k = max(n >= 0 ? n : len - abs(n), 0); 16994 16995 while (k < len) { 16996 var kValue; 16997 if (k in O && O[k] === searchElement) { 16998 return k; 16999 } 17000 k++; 17001 } 17002 return -1; 17003 }; 17004 } 17005 17006 if (!Array.prototype.lastIndexOf) { 17007 Array.prototype.lastIndexOf = function(searchElement /*, fromIndex*/ ) { 17008 "use strict"; 17009 17010 if (this == null) 17011 throw new TypeError(); 17012 17013 var t = Object(this); 17014 var len = t.length >>> 0; 17015 if (len === 0) 17016 return -1; 17017 17018 var n = len; 17019 if (arguments.length > 1) { 17020 n = Number(arguments[1]); 17021 if (n != n) 17022 n = 0; 17023 else if (n != 0 && n != (1 / 0) && n != -(1 / 0)) 17024 n = (n > 0 || -1) * floor(abs(n)); 17025 } 17026 17027 var k = n >= 0 ? min(n, len - 1) : len - abs(n); 17028 17029 for (; k >= 0; k--) { 17030 if (k in t && t[k] === searchElement) 17031 return k; 17032 } 17033 return -1; 17034 }; 17035 } 17036})(jQuery, this); 17037 17038/*! 17039 * lightgallery | 2.5.0 | June 13th 2022 17040 * http://www.lightgalleryjs.com/ 17041 * Copyright (c) 2020 Sachin Neravath; 17042 * @license GPLv3 17043 */ 17044 17045(function (global, factory) { 17046 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 17047 typeof define === 'function' && define.amd ? define(factory) : 17048 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lightGallery = factory()); 17049}(this, (function () { 'use strict'; 17050 17051 /*! ***************************************************************************** 17052 Copyright (c) Microsoft Corporation. 17053 17054 Permission to use, copy, modify, and/or distribute this software for any 17055 purpose with or without fee is hereby granted. 17056 17057 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 17058 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 17059 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 17060 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 17061 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 17062 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17063 PERFORMANCE OF THIS SOFTWARE. 17064 ***************************************************************************** */ 17065 17066 var __assign = function() { 17067 __assign = Object.assign || function __assign(t) { 17068 for (var s, i = 1, n = arguments.length; i < n; i++) { 17069 s = arguments[i]; 17070 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 17071 } 17072 return t; 17073 }; 17074 return __assign.apply(this, arguments); 17075 }; 17076 17077 function __spreadArrays() { 17078 for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; 17079 for (var r = Array(s), k = 0, i = 0; i < il; i++) 17080 for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) 17081 r[k] = a[j]; 17082 return r; 17083 } 17084 17085 /** 17086 * List of lightGallery events 17087 * All events should be documented here 17088 * Below interfaces are used to build the website documentations 17089 * */ 17090 var lGEvents = { 17091 afterAppendSlide: 'lgAfterAppendSlide', 17092 init: 'lgInit', 17093 hasVideo: 'lgHasVideo', 17094 containerResize: 'lgContainerResize', 17095 updateSlides: 'lgUpdateSlides', 17096 afterAppendSubHtml: 'lgAfterAppendSubHtml', 17097 beforeOpen: 'lgBeforeOpen', 17098 afterOpen: 'lgAfterOpen', 17099 slideItemLoad: 'lgSlideItemLoad', 17100 beforeSlide: 'lgBeforeSlide', 17101 afterSlide: 'lgAfterSlide', 17102 posterClick: 'lgPosterClick', 17103 dragStart: 'lgDragStart', 17104 dragMove: 'lgDragMove', 17105 dragEnd: 'lgDragEnd', 17106 beforeNextSlide: 'lgBeforeNextSlide', 17107 beforePrevSlide: 'lgBeforePrevSlide', 17108 beforeClose: 'lgBeforeClose', 17109 afterClose: 'lgAfterClose', 17110 rotateLeft: 'lgRotateLeft', 17111 rotateRight: 'lgRotateRight', 17112 flipHorizontal: 'lgFlipHorizontal', 17113 flipVertical: 'lgFlipVertical', 17114 autoplay: 'lgAutoplay', 17115 autoplayStart: 'lgAutoplayStart', 17116 autoplayStop: 'lgAutoplayStop', 17117 }; 17118 17119 var lightGalleryCoreSettings = { 17120 mode: 'lg-slide', 17121 easing: 'ease', 17122 speed: 400, 17123 licenseKey: '0000-0000-000-0000', 17124 height: '100%', 17125 width: '100%', 17126 addClass: '', 17127 startClass: 'lg-start-zoom', 17128 backdropDuration: 300, 17129 container: '', 17130 startAnimationDuration: 400, 17131 zoomFromOrigin: true, 17132 hideBarsDelay: 0, 17133 showBarsAfter: 10000, 17134 slideDelay: 0, 17135 supportLegacyBrowser: true, 17136 allowMediaOverlap: false, 17137 videoMaxSize: '1280-720', 17138 loadYouTubePoster: true, 17139 defaultCaptionHeight: 0, 17140 ariaLabelledby: '', 17141 ariaDescribedby: '', 17142 resetScrollPosition: true, 17143 hideScrollbar: false, 17144 closable: true, 17145 swipeToClose: true, 17146 closeOnTap: true, 17147 showCloseIcon: true, 17148 showMaximizeIcon: false, 17149 loop: true, 17150 escKey: true, 17151 keyPress: true, 17152 trapFocus: true, 17153 controls: true, 17154 slideEndAnimation: true, 17155 hideControlOnEnd: false,
vendor: 15,066 bytes, lines 17156-17703
17156 mousewheel: false, 17157 getCaptionFromTitleOrAlt: true, 17158 appendSubHtmlTo: '.lg-sub-html', 17159 subHtmlSelectorRelative: false, 17160 preload: 2, 17161 numberOfSlideItemsInDom: 10, 17162 selector: '', 17163 selectWithin: '', 17164 nextHtml: '', 17165 prevHtml: '', 17166 index: 0, 17167 iframeWidth: '100%', 17168 iframeHeight: '100%', 17169 iframeMaxWidth: '100%', 17170 iframeMaxHeight: '100%', 17171 download: true, 17172 counter: true, 17173 appendCounterTo: '.lg-toolbar', 17174 swipeThreshold: 50, 17175 enableSwipe: true, 17176 enableDrag: true, 17177 dynamic: false, 17178 dynamicEl: [], 17179 extraProps: [], 17180 exThumbImage: '', 17181 isMobile: undefined, 17182 mobileSettings: { 17183 controls: false, 17184 showCloseIcon: false, 17185 download: false, 17186 }, 17187 plugins: [], 17188 strings: { 17189 closeGallery: 'Close gallery', 17190 toggleMaximize: 'Toggle maximize', 17191 previousSlide: 'Previous slide', 17192 nextSlide: 'Next slide', 17193 download: 'Download', 17194 playVideo: 'Play video', 17195 }, 17196 }; 17197 17198 function initLgPolyfills() { 17199 (function () { 17200 if (typeof window.CustomEvent === 'function') 17201 return false; 17202 function CustomEvent(event, params) { 17203 params = params || { 17204 bubbles: false, 17205 cancelable: false, 17206 detail: null, 17207 }; 17208 var evt = document.createEvent('CustomEvent'); 17209 evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail); 17210 return evt; 17211 } 17212 window.CustomEvent = CustomEvent; 17213 })(); 17214 (function () { 17215 if (!Element.prototype.matches) { 17216 Element.prototype.matches = 17217 Element.prototype.msMatchesSelector || 17218 Element.prototype.webkitMatchesSelector; 17219 } 17220 })(); 17221 } 17222 var lgQuery = /** @class */ (function () { 17223 function lgQuery(selector) { 17224 this.cssVenderPrefixes = [ 17225 'TransitionDuration', 17226 'TransitionTimingFunction', 17227 'Transform', 17228 'Transition', 17229 ]; 17230 this.selector = this._getSelector(selector); 17231 this.firstElement = this._getFirstEl(); 17232 return this; 17233 } 17234 lgQuery.generateUUID = function () { 17235 return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { 17236 var r = (Math.random() * 16) | 0, v = c == 'x' ? r : (r & 0x3) | 0x8; 17237 return v.toString(16); 17238 }); 17239 }; 17240 lgQuery.prototype._getSelector = function (selector, context) { 17241 if (context === void 0) { context = document; } 17242 if (typeof selector !== 'string') { 17243 return selector; 17244 } 17245 context = context || document; 17246 var fl = selector.substring(0, 1); 17247 if (fl === '#') { 17248 return context.querySelector(selector); 17249 } 17250 else { 17251 return context.querySelectorAll(selector); 17252 } 17253 }; 17254 lgQuery.prototype._each = function (func) { 17255 if (!this.selector) { 17256 return this; 17257 } 17258 if (this.selector.length !== undefined) { 17259 [].forEach.call(this.selector, func); 17260 } 17261 else { 17262 func(this.selector, 0); 17263 } 17264 return this; 17265 }; 17266 lgQuery.prototype._setCssVendorPrefix = function (el, cssProperty, value) { 17267 // prettier-ignore 17268 var property = cssProperty.replace(/-([a-z])/gi, function (s, group1) { 17269 return group1.toUpperCase(); 17270 }); 17271 if (this.cssVenderPrefixes.indexOf(property) !== -1) { 17272 el.style[property.charAt(0).toLowerCase() + property.slice(1)] = value; 17273 el.style['webkit' + property] = value; 17274 el.style['moz' + property] = value; 17275 el.style['ms' + property] = value; 17276 el.style['o' + property] = value; 17277 } 17278 else { 17279 el.style[property] = value; 17280 } 17281 }; 17282 lgQuery.prototype._getFirstEl = function () { 17283 if (this.selector && this.selector.length !== undefined) { 17284 return this.selector[0]; 17285 } 17286 else { 17287 return this.selector; 17288 } 17289 }; 17290 lgQuery.prototype.isEventMatched = function (event, eventName) { 17291 var eventNamespace = eventName.split('.'); 17292 return event 17293 .split('.') 17294 .filter(function (e) { return e; }) 17295 .every(function (e) { 17296 return eventNamespace.indexOf(e) !== -1; 17297 }); 17298 }; 17299 lgQuery.prototype.attr = function (attr, value) { 17300 if (value === undefined) { 17301 if (!this.firstElement) { 17302 return ''; 17303 } 17304 return this.firstElement.getAttribute(attr); 17305 } 17306 this._each(function (el) { 17307 el.setAttribute(attr, value); 17308 }); 17309 return this; 17310 }; 17311 lgQuery.prototype.find = function (selector) { 17312 return $LG(this._getSelector(selector, this.selector)); 17313 }; 17314 lgQuery.prototype.first = function () { 17315 if (this.selector && this.selector.length !== undefined) { 17316 return $LG(this.selector[0]); 17317 } 17318 else { 17319 return $LG(this.selector); 17320 } 17321 }; 17322 lgQuery.prototype.eq = function (index) { 17323 return $LG(this.selector[index]); 17324 }; 17325 lgQuery.prototype.parent = function () { 17326 return $LG(this.selector.parentElement); 17327 }; 17328 lgQuery.prototype.get = function () { 17329 return this._getFirstEl(); 17330 }; 17331 lgQuery.prototype.removeAttr = function (attributes) { 17332 var attrs = attributes.split(' '); 17333 this._each(function (el) { 17334 attrs.forEach(function (attr) { return el.removeAttribute(attr); }); 17335 }); 17336 return this; 17337 }; 17338 lgQuery.prototype.wrap = function (className) { 17339 if (!this.firstElement) { 17340 return this; 17341 } 17342 var wrapper = document.createElement('div'); 17343 wrapper.className = className; 17344 this.firstElement.parentNode.insertBefore(wrapper, this.firstElement); 17345 this.firstElement.parentNode.removeChild(this.firstElement); 17346 wrapper.appendChild(this.firstElement); 17347 return this; 17348 }; 17349 lgQuery.prototype.addClass = function (classNames) { 17350 if (classNames === void 0) { classNames = ''; } 17351 this._each(function (el) { 17352 // IE doesn't support multiple arguments 17353 classNames.split(' ').forEach(function (className) { 17354 if (className) { 17355 el.classList.add(className); 17356 } 17357 }); 17358 }); 17359 return this; 17360 }; 17361 lgQuery.prototype.removeClass = function (classNames) { 17362 this._each(function (el) { 17363 // IE doesn't support multiple arguments 17364 classNames.split(' ').forEach(function (className) { 17365 if (className) { 17366 el.classList.remove(className); 17367 } 17368 }); 17369 }); 17370 return this; 17371 }; 17372 lgQuery.prototype.hasClass = function (className) { 17373 if (!this.firstElement) { 17374 return false; 17375 } 17376 return this.firstElement.classList.contains(className); 17377 }; 17378 lgQuery.prototype.hasAttribute = function (attribute) { 17379 if (!this.firstElement) { 17380 return false; 17381 } 17382 return this.firstElement.hasAttribute(attribute); 17383 }; 17384 lgQuery.prototype.toggleClass = function (className) { 17385 if (!this.firstElement) { 17386 return this; 17387 } 17388 if (this.hasClass(className)) { 17389 this.removeClass(className); 17390 } 17391 else { 17392 this.addClass(className); 17393 } 17394 return this; 17395 }; 17396 lgQuery.prototype.css = function (property, value) { 17397 var _this = this; 17398 this._each(function (el) { 17399 _this._setCssVendorPrefix(el, property, value); 17400 }); 17401 return this; 17402 }; 17403 // Need to pass separate namespaces for separate elements 17404 lgQuery.prototype.on = function (events, listener) { 17405 var _this = this; 17406 if (!this.selector) { 17407 return this; 17408 } 17409 events.split(' ').forEach(function (event) { 17410 if (!Array.isArray(lgQuery.eventListeners[event])) { 17411 lgQuery.eventListeners[event] = []; 17412 } 17413 lgQuery.eventListeners[event].push(listener); 17414 _this.selector.addEventListener(event.split('.')[0], listener); 17415 }); 17416 return this; 17417 }; 17418 // @todo - test this 17419 lgQuery.prototype.once = function (event, listener) { 17420 var _this = this; 17421 this.on(event, function () { 17422 _this.off(event); 17423 listener(event); 17424 }); 17425 return this; 17426 }; 17427 lgQuery.prototype.off = function (event) { 17428 var _this = this; 17429 if (!this.selector) { 17430 return this; 17431 } 17432 Object.keys(lgQuery.eventListeners).forEach(function (eventName) { 17433 if (_this.isEventMatched(event, eventName)) { 17434 lgQuery.eventListeners[eventName].forEach(function (listener) { 17435 _this.selector.removeEventListener(eventName.split('.')[0], listener); 17436 }); 17437 lgQuery.eventListeners[eventName] = []; 17438 } 17439 }); 17440 return this; 17441 }; 17442 lgQuery.prototype.trigger = function (event, detail) { 17443 if (!this.firstElement) { 17444 return this; 17445 } 17446 var customEvent = new CustomEvent(event.split('.')[0], { 17447 detail: detail || null, 17448 }); 17449 this.firstElement.dispatchEvent(customEvent); 17450 return this; 17451 }; 17452 // Does not support IE 17453 lgQuery.prototype.load = function (url) { 17454 var _this = this; 17455 fetch(url) 17456 .then(function (res) { return res.text(); }) 17457 .then(function (html) { 17458 _this.selector.innerHTML = html; 17459 }); 17460 return this; 17461 }; 17462 lgQuery.prototype.html = function (html) { 17463 if (html === undefined) { 17464 if (!this.firstElement) { 17465 return ''; 17466 } 17467 return this.firstElement.innerHTML; 17468 } 17469 this._each(function (el) { 17470 el.innerHTML = html; 17471 }); 17472 return this; 17473 }; 17474 lgQuery.prototype.append = function (html) { 17475 this._each(function (el) { 17476 if (typeof html === 'string') { 17477 el.insertAdjacentHTML('beforeend', html); 17478 } 17479 else { 17480 el.appendChild(html); 17481 } 17482 }); 17483 return this; 17484 }; 17485 lgQuery.prototype.prepend = function (html) { 17486 this._each(function (el) { 17487 el.insertAdjacentHTML('afterbegin', html); 17488 }); 17489 return this; 17490 }; 17491 lgQuery.prototype.remove = function () { 17492 this._each(function (el) { 17493 el.parentNode.removeChild(el); 17494 }); 17495 return this; 17496 }; 17497 lgQuery.prototype.empty = function () { 17498 this._each(function (el) { 17499 el.innerHTML = ''; 17500 }); 17501 return this; 17502 }; 17503 lgQuery.prototype.scrollTop = function (scrollTop) { 17504 if (scrollTop !== undefined) { 17505 document.body.scrollTop = scrollTop; 17506 document.documentElement.scrollTop = scrollTop; 17507 return this; 17508 } 17509 else { 17510 return (window.pageYOffset || 17511 document.documentElement.scrollTop || 17512 document.body.scrollTop || 17513 0); 17514 } 17515 }; 17516 lgQuery.prototype.scrollLeft = function (scrollLeft) { 17517 if (scrollLeft !== undefined) { 17518 document.body.scrollLeft = scrollLeft; 17519 document.documentElement.scrollLeft = scrollLeft; 17520 return this; 17521 } 17522 else { 17523 return (window.pageXOffset || 17524 document.documentElement.scrollLeft || 17525 document.body.scrollLeft || 17526 0); 17527 } 17528 }; 17529 lgQuery.prototype.offset = function () { 17530 if (!this.firstElement) { 17531 return { 17532 left: 0, 17533 top: 0, 17534 }; 17535 } 17536 var rect = this.firstElement.getBoundingClientRect(); 17537 var bodyMarginLeft = $LG('body').style().marginLeft; 17538 // Minus body margin - https://stackoverflow.com/questions/30711548/is-getboundingclientrect-left-returning-a-wrong-value 17539 return { 17540 left: rect.left - parseFloat(bodyMarginLeft) + this.scrollLeft(), 17541 top: rect.top + this.scrollTop(), 17542 }; 17543 }; 17544 lgQuery.prototype.style = function () { 17545 if (!this.firstElement) { 17546 return {}; 17547 } 17548 return (this.firstElement.currentStyle || 17549 window.getComputedStyle(this.firstElement)); 17550 }; 17551 // Width without padding and border even if box-sizing is used. 17552 lgQuery.prototype.width = function () { 17553 var style = this.style(); 17554 return (this.firstElement.clientWidth - 17555 parseFloat(style.paddingLeft) - 17556 parseFloat(style.paddingRight)); 17557 }; 17558 // Height without padding and border even if box-sizing is used. 17559 lgQuery.prototype.height = function () { 17560 var style = this.style(); 17561 return (this.firstElement.clientHeight - 17562 parseFloat(style.paddingTop) - 17563 parseFloat(style.paddingBottom)); 17564 }; 17565 lgQuery.eventListeners = {}; 17566 return lgQuery; 17567 }()); 17568 function $LG(selector) { 17569 initLgPolyfills(); 17570 return new lgQuery(selector); 17571 } 17572 17573 var defaultDynamicOptions = [ 17574 'src', 17575 'sources', 17576 'subHtml', 17577 'subHtmlUrl', 17578 'html', 17579 'video', 17580 'poster', 17581 'slideName', 17582 'responsive', 17583 'srcset', 17584 'sizes', 17585 'iframe', 17586 'downloadUrl', 17587 'download', 17588 'width', 17589 'facebookShareUrl', 17590 'tweetText', 17591 'iframeTitle', 17592 'twitterShareUrl', 17593 'pinterestShareUrl', 17594 'pinterestText', 17595 'fbHtml', 17596 'disqusIdentifier', 17597 'disqusUrl', 17598 ]; 17599 // Convert html data-attribute to camalcase 17600 function convertToData(attr) { 17601 // FInd a way for lgsize 17602 if (attr === 'href') { 17603 return 'src'; 17604 } 17605 attr = attr.replace('data-', ''); 17606 attr = attr.charAt(0).toLowerCase() + attr.slice(1); 17607 attr = attr.replace(/-([a-z])/g, function (g) { return g[1].toUpperCase(); }); 17608 return attr; 17609 } 17610 var utils = { 17611 /** 17612 * get possible width and height from the lgSize attribute. Used for ZoomFromOrigin option 17613 */ 17614 //Uncode edit ##START## 17615 getSize: function (el, container, spacing, defaultLgSize, galleryItem) { 17616 // getSize: function (el, container, spacing, defaultLgSize) { 17617 //Uncode edit ##END## 17618 if (spacing === void 0) { spacing = 0; } 17619 var LGel = $LG(el); 17620 var lgSize = LGel.attr('data-lg-size') || defaultLgSize; 17621 //Uncode edit ##START## 17622 if ( typeof galleryItem.size && galleryItem.size != null ) { 17623 lgSize = galleryItem.size; 17624 } 17625 //Uncode edit ##END## 17626 if (!lgSize) { 17627 return; 17628 } 17629 var isResponsiveSizes = lgSize.split(','); 17630 // if at-least two viewport sizes are available 17631 if (isResponsiveSizes[1]) { 17632 var wWidth = window.innerWidth; 17633 for (var i = 0; i < isResponsiveSizes.length; i++) { 17634 var size_1 = isResponsiveSizes[i]; 17635 var responsiveWidth = parseInt(size_1.split('-')[2], 10); 17636 if (responsiveWidth > wWidth) { 17637 lgSize = size_1; 17638 break; 17639 } 17640 // take last item as last option 17641 if (i === isResponsiveSizes.length - 1) { 17642 lgSize = size_1; 17643 } 17644 } 17645 } 17646 var size = lgSize.split('-'); 17647 var width = parseInt(size[0], 10); 17648 var height = parseInt(size[1], 10); 17649 var cWidth = container.width(); 17650 var cHeight = container.height() - spacing; 17651 var maxWidth = Math.min(cWidth, width); 17652 var maxHeight = Math.min(cHeight, height); 17653 var ratio = Math.min(maxWidth / width, maxHeight / height); 17654 return { width: width * ratio, height: height * ratio }; 17655 }, 17656 /** 17657 * @desc Get transform value based on the imageSize. Used for ZoomFromOrigin option 17658 * @param {jQuery Element} 17659 * @returns {String} Transform CSS string 17660 */ 17661 getTransform: function (el, container, top, bottom, imageSize) { 17662 if (!imageSize) { 17663 return; 17664 } 17665 var LGel = $LG(el).find('img').first(); 17666 if (!LGel.get()) { 17667 return; 17668 } 17669 var containerRect = container.get().getBoundingClientRect(); 17670 var wWidth = containerRect.width; 17671 // using innerWidth to include mobile safari bottom bar 17672 var wHeight = container.height() - (top + bottom); 17673 var elWidth = LGel.width(); 17674 var elHeight = LGel.height(); 17675 var elStyle = LGel.style(); 17676 var x = (wWidth - elWidth) / 2 - 17677 LGel.offset().left + 17678 (parseFloat(elStyle.paddingLeft) || 0) + 17679 (parseFloat(elStyle.borderLeft) || 0) + 17680 $LG(window).scrollLeft() + 17681 containerRect.left; 17682 var y = (wHeight - elHeight) / 2 - 17683 LGel.offset().top + 17684 (parseFloat(elStyle.paddingTop) || 0) + 17685 (parseFloat(elStyle.borderTop) || 0) + 17686 $LG(window).scrollTop() + 17687 top; 17688 var scX = elWidth / imageSize.width; 17689 var scY = elHeight / imageSize.height; 17690 var transform = 'translate3d(' + 17691 (x *= -1) + 17692 'px, ' + 17693 (y *= -1) + 17694 'px, 0) scale3d(' + 17695 scX + 17696 ', ' + 17697 scY + 17698 ', 1)'; 17699 return transform; 17700 }, 17701 getIframeMarkup: function (iframeWidth, iframeHeight, iframeMaxWidth, iframeMaxHeight, src, iframeTitle) { 17702 var title = iframeTitle ? 'title="' + iframeTitle + '"' : ''; 17703 return "<div class=\"lg-video-cont lg-has-iframe\" style=\"width:"
vendor: 2,803 bytes, lines 17703-17775
17703+ iframeWidth + "; max-width:" + iframeMaxWidth + "; height: " + iframeHeight + "; max-height:" + iframeMaxHeight + "\">\n <iframe class=\"lg-object\" frameborder=\"0\" " + title + " src=\"" + src + "\" allowfullscreen=\"true\"></iframe>\n </div>"; 17704 }, 17705 getImgMarkup: function (index, src, altAttr, srcset, sizes, sources) { 17706 var srcsetAttr = srcset ? "srcset=\"" + srcset + "\"" : ''; 17707 var sizesAttr = sizes ? "sizes=\"" + sizes + "\"" : ''; 17708 var imgMarkup = "<img " + altAttr + " " + srcsetAttr + " " + sizesAttr + " class=\"lg-object lg-image\" data-index=\"" + index + "\" src=\"" + src + "\" />"; 17709 var sourceTag = ''; 17710 if (sources) { 17711 var sourceObj = typeof sources === 'string' ? JSON.parse(sources) : sources; 17712 sourceTag = sourceObj.map(function (source) { 17713 var attrs = ''; 17714 Object.keys(source).forEach(function (key) { 17715 // Do not remove the first space as it is required to separate the attributes 17716 attrs += " " + key + "=\"" + source[key] + "\""; 17717 }); 17718 return "<source " + attrs + "></source>"; 17719 }); 17720 } 17721 return "" + sourceTag + imgMarkup; 17722 }, 17723 // Get src from responsive src 17724 getResponsiveSrc: function (srcItms) { 17725 var rsWidth = []; 17726 var rsSrc = []; 17727 var src = ''; 17728 for (var i = 0; i < srcItms.length; i++) { 17729 var _src = srcItms[i].split(' '); 17730 // Manage empty space 17731 if (_src[0] === '') { 17732 _src.splice(0, 1); 17733 } 17734 rsSrc.push(_src[0]); 17735 rsWidth.push(_src[1]); 17736 } 17737 var wWidth = window.innerWidth; 17738 for (var j = 0; j < rsWidth.length; j++) { 17739 if (parseInt(rsWidth[j], 10) > wWidth) { 17740 src = rsSrc[j]; 17741 break; 17742 } 17743 } 17744 return src; 17745 }, 17746 isImageLoaded: function (img) { 17747 if (!img) 17748 return false; 17749 // During the onload event, IE correctly identifies any images that 17750 // werenât downloaded as not complete. Others should too. Gecko-based 17751 // browsers act like NS4 in that they report this incorrectly. 17752 if (!img.complete) { 17753 return false; 17754 } 17755 // However, they do have two very useful properties: naturalWidth and 17756 // naturalHeight. These give the true size of the image. If it failed 17757 // to load, either of these should be zero. 17758 if (img.naturalWidth === 0) { 17759 return false; 17760 } 17761 // No other way of checking: assume itâs ok. 17762 return true; 17763 }, 17764 getVideoPosterMarkup: function (_poster, dummyImg, videoContStyle, playVideoString, _isVideo) { 17765 var videoClass = ''; 17766 if (_isVideo && _isVideo.youtube) { 17767 videoClass = 'lg-has-youtube'; 17768 } 17769 else if (_isVideo && _isVideo.vimeo) { 17770 videoClass = 'lg-has-vimeo'; 17771 } 17772 else { 17773 videoClass = 'lg-has-html5'; 17774 } 17775 return "<div class=\"lg-video-cont " + videoClass + "\" style=\"" + videoContStyle + "\">\n <div class=\"lg-video-play-button\">
vendor: 5,030 bytes, lines 17775-17886
17775\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>"; 17776 }, 17777 getFocusableElements: function (container) { 17778 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])'); 17779 var visibleElements = [].filter.call(elements, function (element) { 17780 var style = window.getComputedStyle(element); 17781 return style.display !== 'none' && style.visibility !== 'hidden'; 17782 }); 17783 return visibleElements; 17784 }, 17785 /** 17786 * @desc Create dynamic elements array from gallery items when dynamic option is false 17787 * It helps to avoid frequent DOM interaction 17788 * and avoid multiple checks for dynamic elments 17789 * 17790 * @returns {Array} dynamicEl 17791 */ 17792 getDynamicOptions: function (items, extraProps, getCaptionFromTitleOrAlt, exThumbImage) { 17793 var dynamicElements = []; 17794 var availableDynamicOptions = __spreadArrays(defaultDynamicOptions, extraProps); 17795 [].forEach.call(items, function (item) { 17796 var dynamicEl = {}; 17797 for (var i = 0; i < item.attributes.length; i++) { 17798 var attr = item.attributes[i]; 17799 if (attr.specified) { 17800 var dynamicAttr = convertToData(attr.name); 17801 var label = ''; 17802 if (availableDynamicOptions.indexOf(dynamicAttr) > -1) { 17803 label = dynamicAttr; 17804 } 17805 if (label) { 17806 dynamicEl[label] = attr.value; 17807 } 17808 } 17809 } 17810 var currentItem = $LG(item); 17811 var alt = currentItem.find('img').first().attr('alt'); 17812 var title = currentItem.attr('title'); 17813 //Uncode edit ##START## 17814 // var thumb = exThumbImage 17815 var thumb = exThumbImage && currentItem.attr(exThumbImage) 17816 //Uncode edit ##END## 17817 ? currentItem.attr(exThumbImage) 17818 : currentItem.find('img').first().attr('src'); 17819 dynamicEl.thumb = thumb; 17820 //Uncode edit ##START## 17821 if (getCaptionFromTitleOrAlt && !dynamicEl.subHtml) { 17822 // dynamicEl.subHtml = title || alt || ''; 17823 dynamicEl.subHtml = title || ''; 17824 } 17825 // dynamicEl.alt = alt || title || ''; 17826 dynamicEl.alt = title || ''; 17827 var inlineType = currentItem.attr('data-type'); 17828 dynamicEl.type = inlineType; 17829 //Uncode edit ##END## 17830 dynamicElements.push(dynamicEl); 17831 }); 17832 return dynamicElements; 17833 }, 17834 isMobile: function () { 17835 return /iPhone|iPad|iPod|Android/i.test(navigator.userAgent); 17836 }, 17837 /** 17838 * @desc Check the given src is video 17839 * @param {String} src 17840 * @return {Object} video type 17841 * Ex:{ youtube : ["//www.youtube.com/watch?v=c0asJgSyxcY", "c0asJgSyxcY"] } 17842 * 17843 * @todo - this information can be moved to dynamicEl to avoid frequent calls 17844 */ 17845 isVideo: function (src, isHTML5VIdeo, index) { 17846 if (!src || src.match(/\.(mp4|m4v|ogg|webm)$/) ) { 17847 if (isHTML5VIdeo) { 17848 return { 17849 html5: true, 17850 }; 17851 } 17852 else { 17853 console.warn('lightGallery :- data-src is not provided on slide item ' + 17854 (index + 1) + 17855 '. Please make sure the selector property is properly configured. More info - https://www.lightgalleryjs.com/demos/html-markup/'); 17856 return; 17857 } 17858 } 17859 var youtube = src.match(/\/\/(?:www\.)?youtu(?:\.be|be\.com|be-nocookie\.com)\/(?:watch\?v=|embed\/)?([a-z0-9\-\_\%]+)([\&|?][\S]*)*/i); 17860 var vimeo = src.match(/\/\/(?:www\.)?(?:player\.)?vimeo.com\/(?:video\/)?([0-9a-z\-_]+)(.*)?/i); 17861 var wistia = src.match(/https?:\/\/(.+)?(wistia\.com|wi\.st)\/(medias|embed)\/([0-9a-z\-_]+)(.*)/); 17862 if (youtube) { 17863 return { 17864 youtube: youtube, 17865 }; 17866 } 17867 else if (vimeo) { 17868 return { 17869 vimeo: vimeo, 17870 }; 17871 } 17872 else if (wistia) { 17873 return { 17874 wistia: wistia, 17875 }; 17876 } 17877 }, 17878 }; 17879 17880 // @ref - https://stackoverflow.com/questions/3971841/how-to-resize-images-proportionally-keeping-the-aspect-ratio 17881 // @ref - https://2ality.com/2017/04/setting-up-multi-platform-packages.html 17882 // Unique id for each gallery 17883 var lgId = 0; 17884 var LightGallery = /** @class */ (function () { 17885 function LightGallery(element, options) { 17886 this.lgOpened = false;
vendor: 4,563 bytes, lines 17887-18021
17887 this.index = 0; 17888 // lightGallery modules 17889 this.plugins = []; 17890 // false when lightGallery load first slide content; 17891 this.lGalleryOn = false; 17892 // True when a slide animation is in progress 17893 this.lgBusy = false; 17894 this.currentItemsInDom = []; 17895 // Scroll top value before lightGallery is opened 17896 this.prevScrollTop = 0; 17897 this.bodyPaddingRight = 0; 17898 this.isDummyImageRemoved = false; 17899 this.dragOrSwipeEnabled = false; 17900 this.mediaContainerPosition = { 17901 top: 0, 17902 bottom: 0, 17903 }; 17904 if (!element) { 17905 return this; 17906 } 17907 lgId++; 17908 this.lgId = lgId; 17909 this.el = element; 17910 this.LGel = $LG(element); 17911 this.generateSettings(options); 17912 this.buildModules(); 17913 // When using dynamic mode, ensure dynamicEl is an array 17914 if (this.settings.dynamic && 17915 this.settings.dynamicEl !== undefined && 17916 !Array.isArray(this.settings.dynamicEl)) { 17917 throw 'When using dynamic mode, you must also define dynamicEl as an Array.'; 17918 } 17919 this.galleryItems = this.getItems(); 17920 this.normalizeSettings(); 17921 // Gallery items 17922 this.init(); 17923 //Uncode edit ##START## 17924 // this.validateLicense(); 17925 //Uncode edit ##END## 17926 return this; 17927 } 17928 LightGallery.prototype.generateSettings = function (options) { 17929 // lightGallery settings 17930 this.settings = __assign(__assign({}, lightGalleryCoreSettings), options); 17931 if (this.settings.isMobile && 17932 typeof this.settings.isMobile === 'function' 17933 ? this.settings.isMobile() 17934 : utils.isMobile()) { 17935 var mobileSettings = __assign(__assign({}, this.settings.mobileSettings), this.settings.mobileSettings); 17936 this.settings = __assign(__assign({}, this.settings), mobileSettings); 17937 } 17938 }; 17939 LightGallery.prototype.normalizeSettings = function () { 17940 if (this.settings.slideEndAnimation) { 17941 this.settings.hideControlOnEnd = false; 17942 } 17943 if (!this.settings.closable) { 17944 this.settings.swipeToClose = false; 17945 } 17946 // And reset it on close to get the correct value next time 17947 this.zoomFromOrigin = this.settings.zoomFromOrigin; 17948 // At the moment, Zoom from image doesn't support dynamic options 17949 // @todo add zoomFromOrigin support for dynamic images 17950 if (this.settings.dynamic) { 17951 this.zoomFromOrigin = false; 17952 } 17953 if (!this.settings.container) { 17954 this.settings.container = document.body; 17955 } 17956 // settings.preload should not be grater than $item.length 17957 this.settings.preload = Math.min(this.settings.preload, this.galleryItems.length); 17958 }; 17959 LightGallery.prototype.init = function () { 17960 var _this = this; 17961 this.addSlideVideoInfo(this.galleryItems); 17962 this.buildStructure(); 17963 this.LGel.trigger(lGEvents.init, { 17964 instance: this, 17965 }); 17966 if (this.settings.keyPress) { 17967 this.keyPress(); 17968 } 17969 setTimeout(function () { 17970 _this.enableDrag(); 17971 _this.enableSwipe(); 17972 _this.triggerPosterClick(); 17973 }, 50); 17974 this.arrow(); 17975 if (this.settings.mousewheel) { 17976 this.mousewheel(); 17977 } 17978 if (!this.settings.dynamic) { 17979 this.openGalleryOnItemClick(); 17980 } 17981 }; 17982 LightGallery.prototype.openGalleryOnItemClick = function () { 17983 var _this = this; 17984 var _loop_1 = function (index) { 17985 var element = this_1.items[index]; 17986 var $element = $LG(element); 17987 // Using different namespace for click because click event should not unbind if selector is same object('this') 17988 // @todo manage all event listners - should have namespace that represent element 17989 var uuid = lgQuery.generateUUID(); 17990 $element 17991 .attr('data-lg-id', uuid) 17992 .on("click.lgcustom-item-" + uuid, function (e) { 17993 e.preventDefault(); 17994 var currentItemIndex = _this.settings.index || index; 17995 _this.openGallery(currentItemIndex, element); 17996 }); 17997 }; 17998 var this_1 = this; 17999 // Using for loop instead of using bubbling as the items can be any html element. 18000 for (var index = 0; index < this.items.length; index++) { 18001 _loop_1(index); 18002 } 18003 }; 18004 /** 18005 * Module constructor 18006 * Modules are build incrementally. 18007 * Gallery should be opened only once all the modules are initialized. 18008 * use moduleBuildTimeout to make sure this 18009 */ 18010 LightGallery.prototype.buildModules = function () { 18011 var _this = this; 18012 this.settings.plugins.forEach(function (plugin) { 18013 _this.plugins.push(new plugin(_this, $LG)); 18014 }); 18015 }; 18016 LightGallery.prototype.validateLicense = function () { 18017 if (!this.settings.licenseKey) { 18018 console.warn('Please provide a valid license key'); 18019 } 18020 else if (this.settings.licenseKey === '0000-0000-000-0000') { 18021 console.warn("lightGallery: " + this.settings.licenseKey + " license key is not val
vendor: 17,473 bytes, lines 18021-18435
18021id for production use"); 18022 } 18023 }; 18024 LightGallery.prototype.getSlideItem = function (index) { 18025 return $LG(this.getSlideItemId(index)); 18026 }; 18027 LightGallery.prototype.getSlideItemId = function (index) { 18028 return "#lg-item-" + this.lgId + "-" + index; 18029 }; 18030 LightGallery.prototype.getIdName = function (id) { 18031 return id + "-" + this.lgId; 18032 }; 18033 LightGallery.prototype.getElementById = function (id) { 18034 return $LG("#" + this.getIdName(id)); 18035 }; 18036 LightGallery.prototype.manageSingleSlideClassName = function () { 18037 if (this.galleryItems.length < 2) { 18038 this.outer.addClass('lg-single-item'); 18039 } 18040 else { 18041 this.outer.removeClass('lg-single-item'); 18042 } 18043 }; 18044 LightGallery.prototype.buildStructure = function () { 18045 var _this = this; 18046 var container = this.$container && this.$container.get(); 18047 if (container) { 18048 return; 18049 } 18050 var controls = ''; 18051 var subHtmlCont = ''; 18052 // Create controls 18053 if (this.settings.controls) { 18054 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>"; 18055 } 18056 if (this.settings.appendSubHtmlTo !== '.lg-item') { 18057 subHtmlCont = 18058 '<div class="lg-sub-html" role="status" aria-live="polite"></div>'; 18059 } 18060 var addClasses = ''; 18061 if (this.settings.allowMediaOverlap) { 18062 // Do not remove space before last single quote 18063 addClasses += 'lg-media-overlap '; 18064 } 18065 var ariaLabelledby = this.settings.ariaLabelledby 18066 ? 'aria-labelledby="' + this.settings.ariaLabelledby + '"' 18067 : ''; 18068 var ariaDescribedby = this.settings.ariaDescribedby 18069 ? 'aria-describedby="' + this.settings.ariaDescribedby + '"' 18070 : ''; 18071 var containerClassName = "lg-container " + this.settings.addClass + " " + (document.body !== this.settings.container ? 'lg-inline' : ''); 18072 var closeIcon = this.settings.closable && this.settings.showCloseIcon 18073 ? "<button type=\"button\" aria-label=\"" + this.settings.strings['closeGallery'] + "\" id=\"" + this.getIdName('lg-close') + "\" class=\"lg-close lg-icon\"></button>" 18074 : ''; 18075 var maximizeIcon = this.settings.showMaximizeIcon 18076 ? "<button type=\"button\" aria-label=\"" + this.settings.strings['toggleMaximize'] + "\" id=\"" + this.getIdName('lg-maximize') + "\" class=\"lg-maximize lg-icon\"></button>" 18077 : ''; 18078 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' 18079 ? subHtmlCont 18080 : '') + "\n <div id=\"" + this.getIdName('lg-components') + "\" class=\"lg-components\">\n " + (this.settings.appendSubHtmlTo === '.lg-sub-html' 18081 ? subHtmlCont 18082 : '') + "\n </div>\n </div>\n </div>\n "; 18083 $LG(this.settings.container).append(template); 18084 if (document.body !== this.settings.container) { 18085 $LG(this.settings.container).css('position', 'relative'); 18086 } 18087 this.outer = this.getElementById('lg-outer'); 18088 this.$lgComponents = this.getElementById('lg-components'); 18089 this.$backdrop = this.getElementById('lg-backdrop'); 18090 this.$container = this.getElementById('lg-container'); 18091 this.$inner = this.getElementById('lg-inner'); 18092 this.$content = this.getElementById('lg-content'); 18093 this.$toolbar = this.getElementById('lg-toolbar'); 18094 this.$backdrop.css('transition-duration', this.settings.backdropDuration + 'ms'); 18095 var outerClassNames = this.settings.mode + " "; 18096 this.manageSingleSlideClassName(); 18097 if (this.settings.enableDrag) { 18098 outerClassNames += 'lg-grab '; 18099 } 18100 this.outer.addClass(outerClassNames); 18101 this.$inner.css('transition-timing-function', this.settings.easing); 18102 this.$inner.css('transition-duration', this.settings.speed + 'ms'); 18103 if (this.settings.download) { 18104 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>"); 18105 } 18106 this.counter(); 18107 $LG(window).on("resize.lg.global" + this.lgId + " orientationchange.lg.global" + this.lgId, function () { 18108 _this.refreshOnResize(); 18109 }); 18110 this.hideBars(); 18111 this.manageCloseGallery(); 18112 this.toggleMaximize(); 18113 this.initModules(); 18114 }; 18115 LightGallery.prototype.refreshOnResize = function () { 18116 if (this.lgOpened) { 18117 var currentGalleryItem = this.galleryItems[this.index]; 18118 var __slideVideoInfo = currentGalleryItem.__slideVideoInfo; 18119 this.mediaContainerPosition = this.getMediaContainerPosition(); 18120 var _a = this.mediaContainerPosition, top_1 = _a.top, bottom = _a.bottom; 18121 //Uncode edit ##START## 18122 this.currentImageSize = utils.getSize(this.items[this.index], this.outer, top_1 + bottom, __slideVideoInfo && this.settings.videoMaxSize, this.galleryItems[this.index]); 18123 // this.currentImageSize = utils.getSize(this.items[this.index], this.outer, top_1 + bottom, __slideVideoInfo && this.settings.videoMaxSize); 18124 //Uncode edit ##END## 18125 if (__slideVideoInfo) { 18126 this.resizeVideoSlide(this.index, this.currentImageSize); 18127 } 18128 if (this.zoomFromOrigin && !this.isDummyImageRemoved) { 18129 var imgStyle = this.getDummyImgStyles(this.currentImageSize); 18130 this.outer 18131 .find('.lg-current .lg-dummy-img') 18132 .first() 18133 .attr('style', imgStyle); 18134 } 18135 this.LGel.trigger(lGEvents.containerResize); 18136 } 18137 }; 18138 LightGallery.prototype.resizeVideoSlide = function (index, imageSize) { 18139 var lgVideoStyle = this.getVideoContStyle(imageSize); 18140 var currentSlide = this.getSlideItem(index); 18141 currentSlide.find('.lg-video-cont').attr('style', lgVideoStyle); 18142 }; 18143 /** 18144 * Update slides dynamically. 18145 * Add, edit or delete slides dynamically when lightGallery is opened. 18146 * Modify the current gallery items and pass it via updateSlides method 18147 * @note 18148 * - Do not mutate existing lightGallery items directly. 18149 * - Always pass new list of gallery items 18150 * - You need to take care of thumbnails outside the gallery if any 18151 * - user this method only if you want to update slides when the gallery is opened. Otherwise, use `refresh()` method. 18152 * @param items Gallery items 18153 * @param index After the update operation, which slide gallery should navigate to 18154 * @category lGPublicMethods 18155 * @example 18156 * const plugin = lightGallery(); 18157 * 18158 * // Adding slides dynamically 18159 * let galleryItems = [ 18160 * // Access existing lightGallery items 18161 * // galleryItems are automatically generated internally from the gallery HTML markup 18162 * // or directly from galleryItems when dynamic gallery is used 18163 * ...plugin.galleryItems, 18164 * ...[ 18165 * { 18166 * src: 'img/img-1.png', 18167 * thumb: 'img/thumb1.png', 18168 * }, 18169 * ], 18170 * ]; 18171 * plugin.updateSlides( 18172 * galleryItems, 18173 * plugin.index, 18174 * ); 18175 * 18176 * 18177 * // Remove slides dynamically 18178 * galleryItems = JSON.parse( 18179 * JSON.stringify(updateSlideInstance.galleryItems), 18180 * ); 18181 * galleryItems.shift(); 18182 * updateSlideInstance.updateSlides(galleryItems, 1); 18183 * @see <a href="/demos/update-slides/">Demo</a> 18184 */ 18185 LightGallery.prototype.updateSlides = function (items, index) { 18186 if (this.index > items.length - 1) { 18187 this.index = items.length - 1; 18188 } 18189 if (items.length === 1) { 18190 this.index = 0; 18191 } 18192 if (!items.length) { 18193 this.closeGallery(); 18194 return; 18195 } 18196 var currentSrc = this.galleryItems[index].src; 18197 this.galleryItems = items; 18198 this.updateControls(); 18199 this.$inner.empty(); 18200 this.currentItemsInDom = []; 18201 var _index = 0; 18202 // Find the current index based on source value of the slide 18203 this.galleryItems.some(function (galleryItem, itemIndex) { 18204 if (galleryItem.src === currentSrc) { 18205 _index = itemIndex; 18206 return true; 18207 } 18208 return false; 18209 }); 18210 this.currentItemsInDom = this.organizeSlideItems(_index, -1); 18211 this.loadContent(_index, true); 18212 this.getSlideItem(_index).addClass('lg-current'); 18213 this.index = _index; 18214 this.updateCurrentCounter(_index); 18215 this.LGel.trigger(lGEvents.updateSlides); 18216 }; 18217 // Get gallery items based on multiple conditions 18218 LightGallery.prototype.getItems = function () { 18219 // Gallery items 18220 this.items = []; 18221 if (!this.settings.dynamic) { 18222 if (this.settings.selector === 'this') { 18223 this.items.push(this.el); 18224 } 18225 else if (this.settings.selector) { 18226 if (typeof this.settings.selector === 'string') { 18227 if (this.settings.selectWithin) { 18228 var selectWithin = $LG(this.settings.selectWithin); 18229 this.items = selectWithin 18230 .find(this.settings.selector) 18231 .get(); 18232 } 18233 else { 18234 this.items = this.el.querySelectorAll(this.settings.selector); 18235 } 18236 } 18237 else { 18238 this.items = this.settings.selector; 18239 } 18240 } 18241 else { 18242 this.items = this.el.children; 18243 } 18244 return utils.getDynamicOptions(this.items, this.settings.extraProps, this.settings.getCaptionFromTitleOrAlt, this.settings.exThumbImage); 18245 } 18246 else { 18247 return this.settings.dynamicEl || []; 18248 } 18249 }; 18250 LightGallery.prototype.shouldHideScrollbar = function () { 18251 return (this.settings.hideScrollbar && 18252 document.body === this.settings.container); 18253 }; 18254 LightGallery.prototype.hideScrollbar = function () { 18255 if (!this.shouldHideScrollbar()) { 18256 return; 18257 } 18258 this.bodyPaddingRight = parseFloat($LG('body').style().paddingRight); 18259 var bodyRect = document.documentElement.getBoundingClientRect(); 18260 var scrollbarWidth = window.innerWidth - bodyRect.width; 18261 $LG(document.body).css('padding-right', scrollbarWidth + this.bodyPaddingRight + 'px'); 18262 $LG(document.body).addClass('lg-overlay-open'); 18263 }; 18264 LightGallery.prototype.resetScrollBar = function () { 18265 if (!this.shouldHideScrollbar()) { 18266 return; 18267 } 18268 $LG(document.body).css('padding-right', this.bodyPaddingRight + 'px'); 18269 $LG(document.body).removeClass('lg-overlay-open'); 18270 }; 18271 /** 18272 * Open lightGallery. 18273 * Open gallery with specific slide by passing index of the slide as parameter. 18274 * @category lGPublicMethods 18275 * @param {Number} index - index of the slide 18276 * @param {HTMLElement} element - Which image lightGallery should zoom from 18277 * 18278 * @example 18279 * const $dynamicGallery = document.getElementById('dynamic-gallery-demo'); 18280 * const dynamicGallery = lightGallery($dynamicGallery, { 18281 * dynamic: true, 18282 * dynamicEl: [ 18283 * { 18284 * src: 'img/1.jpg', 18285 * thumb: 'img/thumb-1.jpg', 18286 * subHtml: '<h4>Image 1 title</h4><p>Image 1 descriptions.</p>', 18287 * }, 18288 * ... 18289 * ], 18290 * }); 18291 * $dynamicGallery.addEventListener('click', function () { 18292 * // Starts with third item.(Optional). 18293 * // This is useful if you want use dynamic mode with 18294 * // custom thumbnails (thumbnails outside gallery), 18295 * dynamicGallery.openGallery(2); 18296 * }); 18297 * 18298 */ 18299 LightGallery.prototype.openGallery = function (index, element) { 18300 var _this = this; 18301 if (index === void 0) { index = this.settings.index; } 18302 // prevent accidental double execution 18303 if (this.lgOpened) 18304 return; 18305 this.lgOpened = true; 18306 this.outer.removeClass('lg-hide-items'); 18307 this.hideScrollbar(); 18308 // Add display block, but still has opacity 0 18309 this.$container.addClass('lg-show'); 18310 var itemsToBeInsertedToDom = this.getItemsToBeInsertedToDom(index, index); 18311 this.currentItemsInDom = itemsToBeInsertedToDom; 18312 var items = ''; 18313 itemsToBeInsertedToDom.forEach(function (item) { 18314 items = items + ("<div id=\"" + item + "\" class=\"lg-item\"></div>"); 18315 }); 18316 this.$inner.append(items); 18317 this.addHtml(index); 18318 var transform = ''; 18319 this.mediaContainerPosition = this.getMediaContainerPosition(); 18320 var _a = this.mediaContainerPosition, top = _a.top, bottom = _a.bottom; 18321 if (!this.settings.allowMediaOverlap) { 18322 this.setMediaContainerPosition(top, bottom); 18323 } 18324 var __slideVideoInfo = this.galleryItems[index].__slideVideoInfo; 18325 if (this.zoomFromOrigin && element) { 18326 //Uncode edit ##START## 18327 this.currentImageSize = utils.getSize(element, this.outer, top + bottom, __slideVideoInfo && this.settings.videoMaxSize, this.galleryItems[this.index]); 18328 // this.currentImageSize = utils.getSize(element, this.outer, top + bottom, __slideVideoInfo && this.settings.videoMaxSize); 18329 //Uncode edit ##END## 18330 transform = utils.getTransform(element, this.outer, top, bottom, this.currentImageSize); 18331 } 18332 if (!this.zoomFromOrigin || !transform) { 18333 this.outer.addClass(this.settings.startClass); 18334 this.getSlideItem(index).removeClass('lg-complete'); 18335 } 18336 var timeout = this.settings.zoomFromOrigin 18337 ? 100 18338 : this.settings.backdropDuration; 18339 setTimeout(function () { 18340 _this.outer.addClass('lg-components-open'); 18341 }, timeout); 18342 this.index = index; 18343 //Uncode edit ##START## 18344 // this.LGel.trigger(lGEvents.beforeOpen); 18345 this.LGel.trigger(lGEvents.beforeOpen, { 18346 galleryItems: this.galleryItems, 18347 items: this.items, 18348 outer: this.outer, 18349 }); 18350 //Uncode edit ##END## 18351 // add class lg-current to remove initial transition 18352 this.getSlideItem(index).addClass('lg-current'); 18353 this.lGalleryOn = false; 18354 // Store the current scroll top value to scroll back after closing the gallery.. 18355 this.prevScrollTop = $LG(window).scrollTop(); 18356 setTimeout(function () { 18357 // Need to check both zoomFromOrigin and transform values as we need to set set the 18358 // default opening animation if user missed to add the lg-size attribute 18359 if (_this.zoomFromOrigin && transform) { 18360 var currentSlide_1 = _this.getSlideItem(index); 18361 currentSlide_1.css('transform', transform); 18362 setTimeout(function () { 18363 currentSlide_1 18364 .addClass('lg-start-progress lg-start-end-progress') 18365 .css('transition-duration', _this.settings.startAnimationDuration + 'ms'); 18366 _this.outer.addClass('lg-zoom-from-image'); 18367 }); 18368 setTimeout(function () { 18369 currentSlide_1.css('transform', 'translate3d(0, 0, 0)'); 18370 }, 100); 18371 } 18372 setTimeout(function () { 18373 _this.$backdrop.addClass('in'); 18374 _this.$container.addClass('lg-show-in'); 18375 }, 10); 18376 setTimeout(function () { 18377 if (_this.settings.trapFocus && 18378 document.body === _this.settings.container) { 18379 _this.trapFocus(); 18380 } 18381 }, _this.settings.backdropDuration + 50); 18382 // lg-visible class resets gallery opacity to 1 18383 if (!_this.zoomFromOrigin || !transform) { 18384 setTimeout(function () { 18385 _this.outer.addClass('lg-visible'); 18386 }, _this.settings.backdropDuration); 18387 } 18388 // initiate slide function 18389 _this.slide(index, false, false, false); 18390 _this.LGel.trigger(lGEvents.afterOpen); 18391 }); 18392 if (document.body === this.settings.container) { 18393 $LG('html').addClass('lg-on'); 18394 } 18395 }; 18396 /** 18397 * Note - Changing the position of the media on every slide transition creates a flickering effect. 18398 * Therefore, The height of the caption is calculated dynamically, only once based on the first slide caption. 18399 * if you have dynamic captions for each media, 18400 * you can provide an appropriate height for the captions via allowMediaOverlap option 18401 */ 18402 LightGallery.prototype.getMediaContainerPosition = function () { 18403 if (this.settings.allowMediaOverlap) { 18404 return { 18405 top: 0, 18406 bottom: 0, 18407 }; 18408 } 18409 var top = this.$toolbar.get().clientHeight || 0; 18410 var subHtml = this.outer.find('.lg-components .lg-sub-html').get(); 18411 var captionHeight = this.settings.defaultCaptionHeight || 18412 (subHtml && subHtml.clientHeight) || 18413 0; 18414 var thumbContainer = this.outer.find('.lg-thumb-outer').get(); 18415 var thumbHeight = thumbContainer ? thumbContainer.clientHeight : 0; 18416 var bottom = thumbHeight + captionHeight; 18417 //Uncode edit ##START## 18418 bottom = bottom < 55 ? 55 : bottom; 18419 //Uncode edit ##END## 18420 return { 18421 top: top, 18422 bottom: bottom, 18423 }; 18424 }; 18425 LightGallery.prototype.setMediaContainerPosition = function (top, bottom) { 18426 if (top === void 0) { top = 0; } 18427 if (bottom === void 0) { bottom = 0; } 18428 this.$content.css('top', top + 'px').css('bottom', bottom + 'px'); 18429 }; 18430 LightGallery.prototype.hideBars = function () { 18431 var _this = this; 18432 // Hide controllers if mouse doesn't move for some period 18433 setTimeout(function () { 18434 _this.outer.removeClass('lg-hide-items'); 18435 if (_this.settings.hideBarsDelay > 0) {
vendor: 4,223 bytes, lines 18436-18566
18436 _this.outer.on('mousemove.lg click.lg touchstart.lg', function () { 18437 _this.outer.removeClass('lg-hide-items'); 18438 clearTimeout(_this.hideBarTimeout); 18439 // Timeout will be cleared on each slide movement also 18440 _this.hideBarTimeout = setTimeout(function () { 18441 _this.outer.addClass('lg-hide-items'); 18442 }, _this.settings.hideBarsDelay); 18443 }); 18444 _this.outer.trigger('mousemove.lg'); 18445 } 18446 }, this.settings.showBarsAfter); 18447 }; 18448 LightGallery.prototype.initPictureFill = function ($img) { 18449 if (this.settings.supportLegacyBrowser) { 18450 try { 18451 picturefill({ 18452 elements: [$img.get()], 18453 }); 18454 } 18455 catch (e) { 18456 console.warn('lightGallery :- If you want srcset or picture tag to be supported for older browser please include picturefil javascript library in your document.'); 18457 } 18458 } 18459 }; 18460 /** 18461 * @desc Create image counter 18462 * Ex: 1/10 18463 */ 18464 LightGallery.prototype.counter = function () { 18465 if (this.settings.counter) { 18466 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>"; 18467 this.outer.find(this.settings.appendCounterTo).append(counterHtml); 18468 } 18469 }; 18470 /** 18471 * @desc add sub-html into the slide 18472 * @param {Number} index - index of the slide 18473 */ 18474 LightGallery.prototype.addHtml = function (index) { 18475 var subHtml; 18476 var subHtmlUrl; 18477 if (this.galleryItems[index].subHtmlUrl) { 18478 subHtmlUrl = this.galleryItems[index].subHtmlUrl; 18479 } 18480 else { 18481 subHtml = this.galleryItems[index].subHtml; 18482 } 18483 if (!subHtmlUrl) { 18484 if (subHtml) { 18485 // get first letter of sub-html 18486 // if first letter starts with . or # get the html form the jQuery object 18487 var fL = subHtml.substring(0, 1); 18488 if (fL === '.' || fL === '#') { 18489 if (this.settings.subHtmlSelectorRelative && 18490 !this.settings.dynamic) { 18491 subHtml = $LG(this.items) 18492 .eq(index) 18493 .find(subHtml) 18494 .first() 18495 .html(); 18496 } 18497 else { 18498 subHtml = $LG(subHtml).first().html(); 18499 } 18500 } 18501 } 18502 else { 18503 subHtml = ''; 18504 } 18505 } 18506 if (this.settings.appendSubHtmlTo !== '.lg-item') { 18507 if (subHtmlUrl) { 18508 this.outer.find('.lg-sub-html').load(subHtmlUrl); 18509 } 18510 else { 18511 this.outer.find('.lg-sub-html').html(subHtml); 18512 } 18513 } 18514 else { 18515 var currentSlide = $LG(this.getSlideItemId(index)); 18516 if (subHtmlUrl) { 18517 currentSlide.load(subHtmlUrl); 18518 } 18519 else { 18520 currentSlide.append("<div class=\"lg-sub-html\">" + subHtml + "</div>"); 18521 } 18522 } 18523 // Add lg-empty-html class if title doesn't exist 18524 if (typeof subHtml !== 'undefined' && subHtml !== null) { 18525 if (subHtml === '') { 18526 this.outer 18527 .find(this.settings.appendSubHtmlTo) 18528 .addClass('lg-empty-html'); 18529 } 18530 else { 18531 this.outer 18532 .find(this.settings.appendSubHtmlTo) 18533 .removeClass('lg-empty-html'); 18534 } 18535 } 18536 this.LGel.trigger(lGEvents.afterAppendSubHtml, { 18537 index: index, 18538 }); 18539 }; 18540 /** 18541 * @desc Preload slides 18542 * @param {Number} index - index of the slide 18543 * @todo preload not working for the first slide, Also, should work for the first and last slide as well 18544 */ 18545 LightGallery.prototype.preload = function (index) { 18546 for (var i = 1; i <= this.settings.preload; i++) { 18547 if (i >= this.galleryItems.length - index) { 18548 break; 18549 } 18550 this.loadContent(index + i, false); 18551 } 18552 for (var j = 1; j <= this.settings.preload; j++) { 18553 if (index - j < 0) { 18554 break; 18555 } 18556 this.loadContent(index - j, false); 18557 } 18558 }; 18559 LightGallery.prototype.getDummyImgStyles = function (imageSize) { 18560 if (!imageSize) 18561 return ''; 18562 return "width:" + imageSize.width + "px;\n margin-left: -" + imageSize.width / 2 + "px;\n margin-top: -" + imageSize.height / 2 + "px;\n height:" + imageSize.height + "px"; 18563 }; 18564 LightGallery.prototype.getVideoContStyle = function (imageSize) { 18565 if (!imageSize) 18566 return '';
18567 return "width:" + imageSize.width + "px;\n height:" + imageSize.height + "px"; 18568 }; 18569 LightGallery.prototype.getDummyImageContent = function ($currentSlide, index, alt) { 18570 var $currentItem; 18571 if (!this.settings.dynamic) { 18572 $currentItem = $LG(this.items).eq(index); 18573 } 18574 if ($currentItem) { 18575 var _dummyImgSrc = void 0; 18576 if (!this.settings.exThumbImage) { 18577 _dummyImgSrc = $currentItem.find('img').first().attr('src'); 18578 } 18579 else { 18580 _dummyImgSrc = $currentItem.attr(this.settings.exThumbImage); 18581 } 18582 if (!_dummyImgSrc) 18583 return ''; 18584 var imgStyle = this.getDummyImgStyles(this.currentImageSize); 18585 var dummyImgContent = "<img " + alt + " style=\"" + imgStyle + "\" class=\"lg-dummy-img\" src=\"" + _dummyImgSrc + "\" />"; 18586 $currentSlide.addClass('lg-first-slide'); 18587 this.outer.addClass('lg-first-slide-loading'); 18588 return dummyImgContent; 18589 } 18590 return ''; 18591 }; 18592 LightGallery.prototype.setImgMarkup = function (src, $currentSlide, index) { 18593 var currentGalleryItem = this.galleryItems[index]; 18594 var alt = currentGalleryItem.alt, srcset = currentGalleryItem.srcset, sizes = currentGalleryItem.sizes, sources = currentGalleryItem.sources; 18595 // Use the thumbnail as dummy image which will be resized to actual image size and 18596 // displayed on top of actual image 18597 var imgContent = ''; 18598 var altAttr = alt ? 'alt="' + alt + '"' : ''; 18599 if (this.isFirstSlideWithZoomAnimation()) { 18600 imgContent = this.getDummyImageContent($currentSlide, index, altAttr); 18601 } 18602 else { 18603 imgContent = utils.getImgMarkup(index, src, altAttr, srcset, sizes, sources); 18604 } 18605 var imgMarkup = "<picture class=\"lg-img-wrap\"> " + imgContent + "</picture>"; 18606 $currentSlide.prepend(imgMarkup); 18607 }; 18608 LightGallery.prototype.onSlideObjectLoad = function ($slide, isHTML5VideoWithoutPoster, onLoad, onError) { 18609 var mediaObject = $slide.find('.lg-object').first(); 18610 if (utils.isImageLoaded(mediaObject.get()) || 18611 isHTML5VideoWithoutPoster) { 18612 onLoad(); 18613 } 18614 else { 18615 mediaObject.on('load.lg error.lg', function () { 18616 onLoad && onLoad(); 18617 }); 18618 mediaObject.on('error.lg', function () { 18619 onError && onError(); 18620 }); 18621 } 18622 }; 18623 /** 18624 * 18625 * @param $el Current slide item 18626 * @param index 18627 * @param delay Delay is 0 except first time 18628 * @param speed Speed is same as delay, except it is 0 if gallery is opened via hash plugin 18629 * @param isFirstSlide 18630 */ 18631 LightGallery.prototype.onLgObjectLoad = function (currentSlide, index, delay, speed, isFirstSlide, isHTML5VideoWithoutPoster) { 18632 var _this = this; 18633 //Uncode edit ##START## 18634 var $item = _this.galleryItems[index], 18635 type = $item.type; 18636 18637 if ( typeof $item.src !== 'undefined' ) { 18638 var inline_id = $item.src.replace('#', ''), 18639 $inline = document.getElementById(inline_id), 18640 inline_html; 18641 18642 if ( type === 'inline' && inline_id != null && typeof $inline !== 'undefined' ) { 18643 inline_html = $inline.innerHTML; 18644 } else { 18645 inline_html = ''; 18646 } 18647 } 18648 //Uncode edit ##END## 18649 this.onSlideObjectLoad(currentSlide, true, function () { 18650 _this.triggerSlideItemLoad(currentSlide, index, delay, speed, isFirstSlide); 18651 }, function () { 18652 currentSlide.addClass('lg-complete lg-complete_'); 18653 //Uncode edit ##START## 18654 // currentSlide.html('<span class="lg-error-msg">Oops... Failed to load content...</span>'); 18655 if ( inline_html !== '' ) { 18656 currentSlide.html(inline_html); 18657 } else { 18658 currentSlide.html('<span class="lg-error-msg">Oops... Failed to load content...</span>'); 18659 } 18660 //Uncode edit ##END## 18661 }); 18662 }; 18663 LightGallery.prototype.triggerSlideItemLoad = function ($currentSlide, index, delay, speed, isFirstSlide) { 18664 var _this = this; 18665 var currentGalleryItem = this.galleryItems[index]; 18666 // Adding delay for video slides without poster for better performance and user experience 18667 // Videos should start playing once once the gallery is completely loaded 18668 var _speed = isFirstSlide &&
vendor: 3,676 bytes, lines 18669-18757
18669 this.getSlideType(currentGalleryItem) === 'video' && 18670 !currentGalleryItem.poster 18671 ? speed 18672 : 0; 18673 setTimeout(function () { 18674 $currentSlide.addClass('lg-complete lg-complete_'); 18675 _this.LGel.trigger(lGEvents.slideItemLoad, { 18676 index: index, 18677 delay: delay || 0, 18678 isFirstSlide: isFirstSlide, 18679 }); 18680 }, _speed); 18681 }; 18682 LightGallery.prototype.isFirstSlideWithZoomAnimation = function () { 18683 return !!(!this.lGalleryOn && 18684 this.zoomFromOrigin && 18685 this.currentImageSize); 18686 }; 18687 // Add video slideInfo 18688 LightGallery.prototype.addSlideVideoInfo = function (items) { 18689 var _this = this; 18690 items.forEach(function (element, index) { 18691 element.__slideVideoInfo = utils.isVideo(element.src, !!element.video, index); 18692 if (element.__slideVideoInfo && 18693 _this.settings.loadYouTubePoster && 18694 !element.poster && 18695 element.__slideVideoInfo.youtube) { 18696 element.poster = "//img.youtube.com/vi/" + element.__slideVideoInfo.youtube[1] + "/maxresdefault.jpg"; 18697 } 18698 }); 18699 }; 18700 /** 18701 * Load slide content into slide. 18702 * This is used to load content into slides that is not visible too 18703 * @param {Number} index - index of the slide. 18704 * @param {Boolean} rec - if true call loadcontent() function again. 18705 */ 18706 LightGallery.prototype.loadContent = function (index, rec) { 18707 var _this = this; 18708 var currentGalleryItem = this.galleryItems[index]; 18709 var $currentSlide = $LG(this.getSlideItemId(index)); 18710 var poster = currentGalleryItem.poster, srcset = currentGalleryItem.srcset, sizes = currentGalleryItem.sizes, sources = currentGalleryItem.sources; 18711 var src = currentGalleryItem.src; 18712 var video = currentGalleryItem.video; 18713 var _html5Video = video && typeof video === 'string' ? JSON.parse(video) : video; 18714 if (currentGalleryItem.responsive) { 18715 var srcDyItms = currentGalleryItem.responsive.split(','); 18716 src = utils.getResponsiveSrc(srcDyItms) || src; 18717 } 18718 var videoInfo = currentGalleryItem.__slideVideoInfo; 18719 var lgVideoStyle = ''; 18720 var iframe = !!currentGalleryItem.iframe; 18721 var isFirstSlide = !this.lGalleryOn; 18722 // delay for adding complete class. it is 0 except first time. 18723 var delay = 0; 18724 if (isFirstSlide) { 18725 if (this.zoomFromOrigin && this.currentImageSize) { 18726 delay = this.settings.startAnimationDuration + 10; 18727 } 18728 else { 18729 delay = this.settings.backdropDuration + 10; 18730 } 18731 } 18732 if (!$currentSlide.hasClass('lg-loaded')) { 18733 if (videoInfo) { 18734 var _a = this.mediaContainerPosition, top_2 = _a.top, bottom = _a.bottom; 18735 //Uncode edit ##START## 18736 var videoSize = utils.getSize(this.items[index], this.outer, top_2 + bottom, videoInfo && this.settings.videoMaxSize, this.galleryItems[this.index]); 18737 // var videoSize = utils.getSize(this.items[index], this.outer, top_2 + bottom, videoInfo && this.settings.videoMaxSize); 18738 //Uncode edit ##END## 18739 lgVideoStyle = this.getVideoContStyle(videoSize); 18740 } 18741 if (iframe) { 18742 var markup = utils.getIframeMarkup(this.settings.iframeWidth, this.settings.iframeHeight, this.settings.iframeMaxWidth, this.settings.iframeMaxHeight, src, currentGalleryItem.iframeTitle); 18743 $currentSlide.prepend(markup); 18744 } 18745 else if (poster) { 18746 var dummyImg = ''; 18747 var hasStartAnimation = isFirstSlide && 18748 this.zoomFromOrigin && 18749 this.currentImageSize; 18750 if (hasStartAnimation) { 18751 dummyImg = this.getDummyImageContent($currentSlide, index, ''); 18752 } 18753 var markup = utils.getVideoPosterMarkup(poster, dummyImg || '', lgVideoStyle, this.settings.strings['playVideo'], videoInfo); 18754 $currentSlide.prepend(markup); 18755 } 18756 //Uncode edit ##START## 18757 // else if (videoInfo) {
18758 else if (videoInfo || this.getSlideType(currentGalleryItem) === 'audio') { 18759 if (! _html5Video) { 18760 var markup = "<div class=\"lg-video-cont \" style=\"" + lgVideoStyle + "\"></div>"; 18761 } 18762 //Uncode edit ##END## 18763 $currentSlide.prepend(markup); 18764 } 18765 else { 18766 //Uncode edit ##START## 18767 var $item = _this.galleryItems[index], 18768 type = $item.type; 18769 18770 if ( typeof $item.src !== 'undefined' ) { 18771 var inline_id = $item.src.replace('#', ''), 18772 $inline = document.getElementById(inline_id), 18773 inline_html; 18774 18775 if ( type === 'inline' && inline_id != null && typeof $inline !== 'undefined' ) { 18776 inline_html = $inline.innerHTML; 18777 } else { 18778 inline_html = ''; 18779 } 18780 } 18781 if ( inline_html !== '' ) { 18782 $currentSlide.html(inline_html); 18783 } else { 18784 this.setImgMarkup(src, $currentSlide, index); 18785 if (srcset || sources) { 18786 var $img = $currentSlide.find('.lg-object'); 18787 this.initPictureFill($img); 18788 } 18789 } 18790 /*this.setImgMarkup(src, $currentSlide, index); 18791 if (srcset || sources) { 18792 var $img = $currentSlide.find('.lg-object'); 18793 this.initPictureFill($img); 18794 }*/ 18795 //Uncode edit ##END## 18796 } 18797 if (poster || videoInfo) { 18798 this.LGel.trigger(lGEvents.hasVideo, { 18799 index: index, 18800 src: src, 18801 html5Video: _html5Video, 18802 hasPoster: !!poster, 18803 }); 18804 } 18805 this.LGel.trigger(lGEvents.afterAppendSlide, { index: index }); 18806 if (this.lGalleryOn && 18807 this.settings.appendSubHtmlTo === '.lg-item') { 18808 this.addHtml(index); 18809 } 18810 } 18811 // For first time add some delay for displaying the start animation. 18812 var _speed = 0; 18813 // Do not change the delay value because it is required for zoom plugin. 18814 // If gallery opened from direct url (hash) speed value should be 0 18815 if (delay && !$LG(document.body).hasClass('lg-from-hash')) { 18816 _speed = delay; 18817 } 18818 // Only for first slide and zoomFromOrigin is enabled 18819 if (this.isFirstSlideWithZoomAnimation()) { 18820 setTimeout(function () { 18821 $currentSlide 18822 .removeClass('lg-start-end-progress lg-start-progress') 18823 .removeAttr('style'); 18824 }, this.settings.startAnimationDuration + 100); 18825 if (!$currentSlide.hasClass('lg-loaded')) { 18826 setTimeout(function () { 18827 if (_this.getSlideType(currentGalleryItem) === 'image') { 18828 var alt = currentGalleryItem.alt; 18829 var altAttr = alt ? 'alt="' + alt + '"' : ''; 18830 $currentSlide 18831 .find('.lg-img-wrap') 18832 .append(utils.getImgMarkup(index, src, altAttr, srcset, sizes, currentGalleryItem.sources)); 18833 if (srcset || sources) { 18834 var $img = $currentSlide.find('.lg-object'); 18835 _this.initPictureFill($img); 18836 } 18837 } 18838 if (_this.getSlideType(currentGalleryItem) === 'image' || 18839 (_this.getSlideType(currentGalleryItem) === 'video' && 18840 poster)) { 18841 _this.onLgObjectLoad($currentSlide, index, delay, _speed, true, false); 18842 // load remaining slides once the slide is completely loaded 18843 _this.onSlideObjectLoad($currentSlide, !!(videoInfo && videoInfo.html5 && !poster), function () { 18844 _this.loadContentOnFirstSlideLoad(index, $currentSlide, _speed); 18845 }, function () { 18846 _this.loadContentOnFirstSlideLoad(index, $currentSlide, _speed); 18847 }); 18848 } 18849 }, this.settings.startAnimationDuration + 100); 18850 } 18851 } 18852 // SLide content has been added to dom 18853 $currentSlide.addClass('lg-loaded'); 18854 if (!this.isFirstSlideWithZoomAnimation() || 18855 (this.getSlideType(currentGalleryItem) === 'video' && !poster)) { 18856 //Uncode edit ##START## 18857 // this.onLgObjectLoad($currentSlide, index, delay, _speed, isFirstSlide, !!(videoInfo && videoInfo.html5 && !poster)); 18858 this.onLgObjectLoad($currentSlide, index, delay, _speed, isFirstSlide, !!( (videoInfo && videoInfo.html5 && !poster) || this.get
vendor: 31,133 bytes, lines 18858-19782
18858SlideType(currentGalleryItem) === 'audio')); 18859 //Uncode edit ##END## 18860 } 18861 // When gallery is opened once content is loaded (second time) need to add lg-complete class for css styling 18862 if ((!this.zoomFromOrigin || !this.currentImageSize) && 18863 $currentSlide.hasClass('lg-complete_') && 18864 !this.lGalleryOn) { 18865 setTimeout(function () { 18866 $currentSlide.addClass('lg-complete'); 18867 }, this.settings.backdropDuration); 18868 } 18869 // Content loaded 18870 // Need to set lGalleryOn before calling preload function 18871 this.lGalleryOn = true; 18872 if (rec === true) { 18873 if (!$currentSlide.hasClass('lg-complete_')) { 18874 $currentSlide 18875 .find('.lg-object') 18876 .first() 18877 .on('load.lg error.lg', function () { 18878 _this.preload(index); 18879 }); 18880 } 18881 else { 18882 this.preload(index); 18883 } 18884 } 18885 }; 18886 /** 18887 * @desc Remove dummy image content and load next slides 18888 * Called only for the first time if zoomFromOrigin animation is enabled 18889 * @param index 18890 * @param $currentSlide 18891 * @param speed 18892 */ 18893 LightGallery.prototype.loadContentOnFirstSlideLoad = function (index, $currentSlide, speed) { 18894 var _this = this; 18895 setTimeout(function () { 18896 $currentSlide.find('.lg-dummy-img').remove(); 18897 $currentSlide.removeClass('lg-first-slide'); 18898 _this.outer.removeClass('lg-first-slide-loading'); 18899 _this.isDummyImageRemoved = true; 18900 _this.preload(index); 18901 }, speed + 300); 18902 }; 18903 LightGallery.prototype.getItemsToBeInsertedToDom = function (index, prevIndex, numberOfItems) { 18904 var _this = this; 18905 if (numberOfItems === void 0) { numberOfItems = 0; } 18906 var itemsToBeInsertedToDom = []; 18907 // Minimum 2 items should be there 18908 var possibleNumberOfItems = Math.max(numberOfItems, 3); 18909 possibleNumberOfItems = Math.min(possibleNumberOfItems, this.galleryItems.length); 18910 var prevIndexItem = "lg-item-" + this.lgId + "-" + prevIndex; 18911 if (this.galleryItems.length <= 3) { 18912 this.galleryItems.forEach(function (_element, index) { 18913 itemsToBeInsertedToDom.push("lg-item-" + _this.lgId + "-" + index); 18914 }); 18915 return itemsToBeInsertedToDom; 18916 } 18917 if (index < (this.galleryItems.length - 1) / 2) { 18918 for (var idx = index; idx > index - possibleNumberOfItems / 2 && idx >= 0; idx--) { 18919 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + idx); 18920 } 18921 var numberOfExistingItems = itemsToBeInsertedToDom.length; 18922 for (var idx = 0; idx < possibleNumberOfItems - numberOfExistingItems; idx++) { 18923 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + (index + idx + 1)); 18924 } 18925 } 18926 else { 18927 for (var idx = index; idx <= this.galleryItems.length - 1 && 18928 idx < index + possibleNumberOfItems / 2; idx++) { 18929 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + idx); 18930 } 18931 var numberOfExistingItems = itemsToBeInsertedToDom.length; 18932 for (var idx = 0; idx < possibleNumberOfItems - numberOfExistingItems; idx++) { 18933 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + (index - idx - 1)); 18934 } 18935 } 18936 if (this.settings.loop) { 18937 if (index === this.galleryItems.length - 1) { 18938 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + 0); 18939 } 18940 else if (index === 0) { 18941 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + (this.galleryItems.length - 1)); 18942 } 18943 } 18944 if (itemsToBeInsertedToDom.indexOf(prevIndexItem) === -1) { 18945 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + prevIndex); 18946 } 18947 return itemsToBeInsertedToDom; 18948 }; 18949 LightGallery.prototype.organizeSlideItems = function (index, prevIndex) { 18950 var _this = this; 18951 var itemsToBeInsertedToDom = this.getItemsToBeInsertedToDom(index, prevIndex, this.settings.numberOfSlideItemsInDom); 18952 itemsToBeInsertedToDom.forEach(function (item) { 18953 if (_this.currentItemsInDom.indexOf(item) === -1) { 18954 _this.$inner.append("<div id=\"" + item + "\" class=\"lg-item\"></div>"); 18955 } 18956 }); 18957 this.currentItemsInDom.forEach(function (item) { 18958 if (itemsToBeInsertedToDom.indexOf(item) === -1) { 18959 $LG("#" + item).remove(); 18960 } 18961 }); 18962 return itemsToBeInsertedToDom; 18963 }; 18964 /** 18965 * Get previous index of the slide 18966 */ 18967 LightGallery.prototype.getPreviousSlideIndex = function () { 18968 var prevIndex = 0; 18969 try { 18970 var currentItemId = this.outer 18971 .find('.lg-current') 18972 .first() 18973 .attr('id'); 18974 prevIndex = parseInt(currentItemId.split('-')[3]) || 0; 18975 } 18976 catch (error) { 18977 prevIndex = 0; 18978 } 18979 return prevIndex; 18980 }; 18981 LightGallery.prototype.setDownloadValue = function (index) { 18982 if (this.settings.download) { 18983 var currentGalleryItem = this.galleryItems[index]; 18984 var hideDownloadBtn = currentGalleryItem.downloadUrl === false || 18985 currentGalleryItem.downloadUrl === 'false'; 18986 if (hideDownloadBtn) { 18987 this.outer.addClass('lg-hide-download'); 18988 } 18989 else { 18990 var $download = this.getElementById('lg-download'); 18991 this.outer.removeClass('lg-hide-download'); 18992 $download.attr('href', currentGalleryItem.downloadUrl || 18993 currentGalleryItem.src); 18994 if (currentGalleryItem.download) { 18995 //Uncode edit ##START## 18996 if ( typeof currentGalleryItem.video !== 'undefined' && currentGalleryItem.video ) { 18997 var currentVideo = JSON.parse( currentGalleryItem.video ), 18998 download_name = currentVideo.source[0].src; 18999 $download.attr('href', download_name).removeAttr('download'); 19000 } else { 19001 var download_url = currentGalleryItem.downloadUrl || currentGalleryItem.src, 19002 download_name = download_url.substring(download_url.lastIndexOf('/')+1); 19003 $download.attr('download', download_name); 19004 } 19005 // $download.attr('download', currentGalleryItem.download); 19006 //Uncode edit ##END## 19007 } 19008 } 19009 } 19010 }; 19011 LightGallery.prototype.makeSlideAnimation = function (direction, currentSlideItem, previousSlideItem) { 19012 var _this = this; 19013 if (this.lGalleryOn) { 19014 previousSlideItem.addClass('lg-slide-progress'); 19015 } 19016 setTimeout(function () { 19017 // remove all transitions 19018 _this.outer.addClass('lg-no-trans'); 19019 _this.outer 19020 .find('.lg-item') 19021 .removeClass('lg-prev-slide lg-next-slide'); 19022 if (direction === 'prev') { 19023 //prevslide 19024 currentSlideItem.addClass('lg-prev-slide'); 19025 previousSlideItem.addClass('lg-next-slide'); 19026 } 19027 else { 19028 // next slide 19029 currentSlideItem.addClass('lg-next-slide'); 19030 previousSlideItem.addClass('lg-prev-slide'); 19031 } 19032 // give 50 ms for browser to add/remove class 19033 setTimeout(function () { 19034 _this.outer.find('.lg-item').removeClass('lg-current'); 19035 currentSlideItem.addClass('lg-current'); 19036 // reset all transitions 19037 _this.outer.removeClass('lg-no-trans'); 19038 }, 50); 19039 }, this.lGalleryOn ? this.settings.slideDelay : 0); 19040 }; 19041 /** 19042 * Goto a specific slide. 19043 * @param {Number} index - index of the slide 19044 * @param {Boolean} fromTouch - true if slide function called via touch event or mouse drag 19045 * @param {Boolean} fromThumb - true if slide function called via thumbnail click 19046 * @param {String} direction - Direction of the slide(next/prev) 19047 * @category lGPublicMethods 19048 * @example 19049 * const plugin = lightGallery(); 19050 * // to go to 3rd slide 19051 * plugin.slide(2); 19052 * 19053 */ 19054 LightGallery.prototype.slide = function (index, fromTouch, fromThumb, direction) { 19055 var _this = this; 19056 var prevIndex = this.getPreviousSlideIndex(); 19057 this.currentItemsInDom = this.organizeSlideItems(index, prevIndex); 19058 // Prevent multiple call, Required for hsh plugin 19059 if (this.lGalleryOn && prevIndex === index) { 19060 return; 19061 } 19062 var numberOfGalleryItems = this.galleryItems.length; 19063 if (!this.lgBusy) { 19064 if (this.settings.counter) { 19065 this.updateCurrentCounter(index); 19066 } 19067 var currentSlideItem = this.getSlideItem(index); 19068 var previousSlideItem_1 = this.getSlideItem(prevIndex); 19069 var currentGalleryItem = this.galleryItems[index]; 19070 var videoInfo = currentGalleryItem.__slideVideoInfo; 19071 this.outer.attr('data-lg-slide-type', this.getSlideType(currentGalleryItem)); 19072 this.setDownloadValue(index); 19073 if (videoInfo) { 19074 var _a = this.mediaContainerPosition, top_3 = _a.top, bottom = _a.bottom; 19075 //Uncode edit ##START## 19076 var videoSize = utils.getSize(this.items[index], this.outer, top_3 + bottom, videoInfo && this.settings.videoMaxSize, this.galleryItems[this.index]); 19077 // var videoSize = utils.getSize(this.items[index], this.outer, top_3 + bottom, videoInfo && this.settings.videoMaxSize); 19078 //Uncode edit ##END## 19079 this.resizeVideoSlide(index, videoSize); 19080 } 19081 this.LGel.trigger(lGEvents.beforeSlide, { 19082 prevIndex: prevIndex, 19083 index: index, 19084 fromTouch: !!fromTouch, 19085 fromThumb: !!fromThumb, 19086 //Uncode edit ##START## 19087 currentSlide: currentSlideItem, 19088 previousSlide: previousSlideItem_1, 19089 info: currentGalleryItem, 19090 item: this.items[index] 19091 //Uncode edit ##END## 19092 }); 19093 this.lgBusy = true; 19094 clearTimeout(this.hideBarTimeout); 19095 this.arrowDisable(index); 19096 if (!direction) { 19097 if (index < prevIndex) { 19098 direction = 'prev'; 19099 } 19100 else if (index > prevIndex) { 19101 direction = 'next'; 19102 } 19103 } 19104 if (!fromTouch) { 19105 this.makeSlideAnimation(direction, currentSlideItem, previousSlideItem_1); 19106 } 19107 else { 19108 this.outer 19109 .find('.lg-item') 19110 .removeClass('lg-prev-slide lg-current lg-next-slide'); 19111 var touchPrev = void 0; 19112 var touchNext = void 0; 19113 if (numberOfGalleryItems > 2) { 19114 touchPrev = index - 1; 19115 touchNext = index + 1; 19116 if (index === 0 && prevIndex === numberOfGalleryItems - 1) { 19117 // next slide 19118 touchNext = 0; 19119 touchPrev = numberOfGalleryItems - 1; 19120 } 19121 else if (index === numberOfGalleryItems - 1 && 19122 prevIndex === 0) { 19123 // prev slide 19124 touchNext = 0; 19125 touchPrev = numberOfGalleryItems - 1; 19126 } 19127 } 19128 else { 19129 touchPrev = 0; 19130 touchNext = 1; 19131 } 19132 if (direction === 'prev') { 19133 this.getSlideItem(touchNext).addClass('lg-next-slide'); 19134 } 19135 else { 19136 this.getSlideItem(touchPrev).addClass('lg-prev-slide'); 19137 } 19138 currentSlideItem.addClass('lg-current'); 19139 } 19140 // Do not put load content in set timeout as it needs to load immediately when the gallery is opened 19141 if (!this.lGalleryOn) { 19142 this.loadContent(index, true); 19143 } 19144 else { 19145 setTimeout(function () { 19146 _this.loadContent(index, true); 19147 // Add title if this.settings.appendSubHtmlTo === lg-sub-html 19148 if (_this.settings.appendSubHtmlTo !== '.lg-item') { 19149 _this.addHtml(index); 19150 } 19151 }, this.settings.speed + 50 + (fromTouch ? 0 : this.settings.slideDelay)); 19152 } 19153 setTimeout(function () { 19154 _this.lgBusy = false; 19155 previousSlideItem_1.removeClass('lg-slide-progress'); 19156 _this.LGel.trigger(lGEvents.afterSlide, { 19157 prevIndex: prevIndex, 19158 index: index, 19159 fromTouch: fromTouch, 19160 fromThumb: fromThumb, 19161 }); 19162 }, (this.lGalleryOn ? this.settings.speed + 100 : 100) + (fromTouch ? 0 : this.settings.slideDelay)); 19163 } 19164 this.index = index; 19165 }; 19166 LightGallery.prototype.updateCurrentCounter = function (index) { 19167 this.getElementById('lg-counter-current').html(index + 1 + ''); 19168 }; 19169 LightGallery.prototype.updateCounterTotal = function () { 19170 this.getElementById('lg-counter-all').html(this.galleryItems.length + ''); 19171 }; 19172 LightGallery.prototype.getSlideType = function (item) { 19173 if (item.__slideVideoInfo) { 19174 return 'video'; 19175 } 19176 else if (item.iframe) { 19177 return 'iframe'; 19178 } 19179 //Uncode edit ##START## 19180 else if (typeof item.src !== '' && item.src.search(/.mp3|.m4a/i) > -1) { 19181 return 'audio'; 19182 } 19183 //Uncode edit ##END## 19184 else { 19185 return 'image'; 19186 } 19187 }; 19188 LightGallery.prototype.touchMove = function (startCoords, endCoords, e) { 19189 var distanceX = endCoords.pageX - startCoords.pageX; 19190 var distanceY = endCoords.pageY - startCoords.pageY; 19191 var allowSwipe = false; 19192 if (this.swipeDirection) { 19193 allowSwipe = true; 19194 } 19195 else { 19196 if (Math.abs(distanceX) > 15) { 19197 this.swipeDirection = 'horizontal'; 19198 allowSwipe = true; 19199 } 19200 else if (Math.abs(distanceY) > 15) { 19201 this.swipeDirection = 'vertical'; 19202 allowSwipe = true; 19203 } 19204 } 19205 if (!allowSwipe) { 19206 return; 19207 } 19208 var $currentSlide = this.getSlideItem(this.index); 19209 if (this.swipeDirection === 'horizontal') { 19210 e === null || e === void 0 ? void 0 : e.preventDefault(); 19211 // reset opacity and transition duration 19212 this.outer.addClass('lg-dragging'); 19213 // move current slide 19214 this.setTranslate($currentSlide, distanceX, 0); 19215 // move next and prev slide with current slide 19216 var width = $currentSlide.get().offsetWidth; 19217 var slideWidthAmount = (width * 15) / 100; 19218 var gutter = slideWidthAmount - Math.abs((distanceX * 10) / 100); 19219 this.setTranslate(this.outer.find('.lg-prev-slide').first(), -width + distanceX - gutter, 0); 19220 this.setTranslate(this.outer.find('.lg-next-slide').first(), width + distanceX + gutter, 0); 19221 } 19222 else if (this.swipeDirection === 'vertical') { 19223 if (this.settings.swipeToClose) { 19224 e === null || e === void 0 ? void 0 : e.preventDefault(); 19225 this.$container.addClass('lg-dragging-vertical'); 19226 var opacity = 1 - Math.abs(distanceY) / window.innerHeight; 19227 this.$backdrop.css('opacity', opacity); 19228 var scale = 1 - Math.abs(distanceY) / (window.innerWidth * 2); 19229 this.setTranslate($currentSlide, 0, distanceY, scale, scale); 19230 if (Math.abs(distanceY) > 100) { 19231 this.outer 19232 .addClass('lg-hide-items') 19233 .removeClass('lg-components-open'); 19234 } 19235 } 19236 } 19237 }; 19238 LightGallery.prototype.touchEnd = function (endCoords, startCoords, event) { 19239 var _this = this; 19240 var distance; 19241 // keep slide animation for any mode while dragg/swipe 19242 if (this.settings.mode !== 'lg-slide') { 19243 this.outer.addClass('lg-slide'); 19244 } 19245 // set transition duration 19246 setTimeout(function () { 19247 _this.$container.removeClass('lg-dragging-vertical'); 19248 _this.outer 19249 .removeClass('lg-dragging lg-hide-items') 19250 .addClass('lg-components-open'); 19251 var triggerClick = true; 19252 if (_this.swipeDirection === 'horizontal') { 19253 distance = endCoords.pageX - startCoords.pageX; 19254 var distanceAbs = Math.abs(endCoords.pageX - startCoords.pageX); 19255 if (distance < 0 && 19256 distanceAbs > _this.settings.swipeThreshold) { 19257 _this.goToNextSlide(true); 19258 triggerClick = false; 19259 } 19260 else if (distance > 0 && 19261 distanceAbs > _this.settings.swipeThreshold) { 19262 _this.goToPrevSlide(true); 19263 triggerClick = false; 19264 } 19265 } 19266 else if (_this.swipeDirection === 'vertical') { 19267 distance = Math.abs(endCoords.pageY - startCoords.pageY); 19268 if (_this.settings.closable && 19269 _this.settings.swipeToClose && 19270 distance > 100) { 19271 _this.closeGallery(); 19272 return; 19273 } 19274 else { 19275 _this.$backdrop.css('opacity', 1); 19276 } 19277 } 19278 _this.outer.find('.lg-item').removeAttr('style'); 19279 if (triggerClick && 19280 Math.abs(endCoords.pageX - startCoords.pageX) < 5) { 19281 // Trigger click if distance is less than 5 pix 19282 var target = $LG(event.target); 19283 if (_this.isPosterElement(target)) { 19284 _this.LGel.trigger(lGEvents.posterClick); 19285 } 19286 } 19287 _this.swipeDirection = undefined; 19288 }); 19289 // remove slide class once drag/swipe is completed if mode is not slide 19290 setTimeout(function () { 19291 if (!_this.outer.hasClass('lg-dragging') && 19292 _this.settings.mode !== 'lg-slide') { 19293 _this.outer.removeClass('lg-slide'); 19294 } 19295 }, this.settings.speed + 100); 19296 }; 19297 LightGallery.prototype.enableSwipe = function () { 19298 var _this = this; 19299 var startCoords = {}; 19300 var endCoords = {}; 19301 var isMoved = false; 19302 var isSwiping = false; 19303 if (this.settings.enableSwipe) { 19304 this.$inner.on('touchstart.lg', function (e) { 19305 _this.dragOrSwipeEnabled = true; 19306 var $item = _this.getSlideItem(_this.index); 19307 if (($LG(e.target).hasClass('lg-item') || 19308 $item.get().contains(e.target)) && 19309 !_this.outer.hasClass('lg-zoomed') && 19310 !_this.lgBusy && 19311 e.targetTouches.length === 1) { 19312 isSwiping = true; 19313 _this.touchAction = 'swipe'; 19314 _this.manageSwipeClass(); 19315 startCoords = { 19316 pageX: e.targetTouches[0].pageX, 19317 pageY: e.targetTouches[0].pageY, 19318 }; 19319 } 19320 }); 19321 this.$inner.on('touchmove.lg', function (e) { 19322 if (isSwiping && 19323 _this.touchAction === 'swipe' && 19324 e.targetTouches.length === 1) { 19325 endCoords = { 19326 pageX: e.targetTouches[0].pageX, 19327 pageY: e.targetTouches[0].pageY, 19328 }; 19329 _this.touchMove(startCoords, endCoords, e); 19330 isMoved = true; 19331 } 19332 }); 19333 this.$inner.on('touchend.lg', function (event) { 19334 if (_this.touchAction === 'swipe') { 19335 if (isMoved) { 19336 isMoved = false; 19337 _this.touchEnd(endCoords, startCoords, event); 19338 } 19339 else if (isSwiping) { 19340 var target = $LG(event.target); 19341 if (_this.isPosterElement(target)) { 19342 _this.LGel.trigger(lGEvents.posterClick); 19343 } 19344 } 19345 _this.touchAction = undefined; 19346 isSwiping = false; 19347 } 19348 }); 19349 } 19350 }; 19351 LightGallery.prototype.enableDrag = function () { 19352 var _this = this; 19353 var startCoords = {}; 19354 var endCoords = {}; 19355 var isDraging = false; 19356 var isMoved = false; 19357 if (this.settings.enableDrag) { 19358 this.outer.on('mousedown.lg', function (e) { 19359 _this.dragOrSwipeEnabled = true; 19360 var $item = _this.getSlideItem(_this.index); 19361 if ($LG(e.target).hasClass('lg-item') || 19362 $item.get().contains(e.target)) { 19363 if (!_this.outer.hasClass('lg-zoomed') && !_this.lgBusy) { 19364 e.preventDefault(); 19365 if (!_this.lgBusy) { 19366 _this.manageSwipeClass(); 19367 startCoords = { 19368 pageX: e.pageX, 19369 pageY: e.pageY, 19370 }; 19371 isDraging = true; 19372 // ** Fix for webkit cursor issue https://code.google.com/p/chromium/issues/detail?id=26723 19373 _this.outer.get().scrollLeft += 1; 19374 _this.outer.get().scrollLeft -= 1; 19375 // * 19376 _this.outer 19377 .removeClass('lg-grab') 19378 .addClass('lg-grabbing'); 19379 _this.LGel.trigger(lGEvents.dragStart); 19380 } 19381 } 19382 } 19383 }); 19384 $LG(window).on("mousemove.lg.global" + this.lgId, function (e) { 19385 if (isDraging && _this.lgOpened) { 19386 isMoved = true; 19387 endCoords = { 19388 pageX: e.pageX, 19389 pageY: e.pageY, 19390 }; 19391 _this.touchMove(startCoords, endCoords); 19392 _this.LGel.trigger(lGEvents.dragMove); 19393 } 19394 }); 19395 $LG(window).on("mouseup.lg.global" + this.lgId, function (event) { 19396 if (!_this.lgOpened) { 19397 return; 19398 } 19399 var target = $LG(event.target); 19400 if (isMoved) { 19401 isMoved = false; 19402 _this.touchEnd(endCoords, startCoords, event); 19403 _this.LGel.trigger(lGEvents.dragEnd); 19404 } 19405 else if (_this.isPosterElement(target)) { 19406 _this.LGel.trigger(lGEvents.posterClick); 19407 } 19408 // Prevent execution on click 19409 if (isDraging) { 19410 isDraging = false; 19411 _this.outer.removeClass('lg-grabbing').addClass('lg-grab'); 19412 } 19413 }); 19414 } 19415 }; 19416 LightGallery.prototype.triggerPosterClick = function () { 19417 var _this = this; 19418 this.$inner.on('click.lg', function (event) { 19419 if (!_this.dragOrSwipeEnabled && 19420 _this.isPosterElement($LG(event.target))) { 19421 _this.LGel.trigger(lGEvents.posterClick); 19422 } 19423 }); 19424 }; 19425 LightGallery.prototype.manageSwipeClass = function () { 19426 var _touchNext = this.index + 1; 19427 var _touchPrev = this.index - 1; 19428 if (this.settings.loop && this.galleryItems.length > 2) { 19429 if (this.index === 0) { 19430 _touchPrev = this.galleryItems.length - 1; 19431 } 19432 else if (this.index === this.galleryItems.length - 1) { 19433 _touchNext = 0; 19434 } 19435 } 19436 this.outer.find('.lg-item').removeClass('lg-next-slide lg-prev-slide'); 19437 if (_touchPrev > -1) { 19438 this.getSlideItem(_touchPrev).addClass('lg-prev-slide'); 19439 } 19440 this.getSlideItem(_touchNext).addClass('lg-next-slide'); 19441 }; 19442 /** 19443 * Go to next slide 19444 * @param {Boolean} fromTouch - true if slide function called via touch event 19445 * @category lGPublicMethods 19446 * @example 19447 * const plugin = lightGallery(); 19448 * plugin.goToNextSlide(); 19449 * @see <a href="/demos/methods/">Demo</a> 19450 */ 19451 LightGallery.prototype.goToNextSlide = function (fromTouch) { 19452 var _this = this; 19453 var _loop = this.settings.loop; 19454 if (fromTouch && this.galleryItems.length < 3) { 19455 _loop = false; 19456 } 19457 if (!this.lgBusy) { 19458 if (this.index + 1 < this.galleryItems.length) { 19459 this.index++; 19460 this.LGel.trigger(lGEvents.beforeNextSlide, { 19461 index: this.index, 19462 }); 19463 this.slide(this.index, !!fromTouch, false, 'next'); 19464 } 19465 else { 19466 if (_loop) { 19467 this.index = 0; 19468 this.LGel.trigger(lGEvents.beforeNextSlide, { 19469 index: this.index, 19470 }); 19471 this.slide(this.index, !!fromTouch, false, 'next'); 19472 } 19473 else if (this.settings.slideEndAnimation && !fromTouch) { 19474 this.outer.addClass('lg-right-end'); 19475 setTimeout(function () { 19476 _this.outer.removeClass('lg-right-end'); 19477 }, 400); 19478 } 19479 } 19480 } 19481 }; 19482 /** 19483 * Go to previous slides 19484 * @param {Boolean} fromTouch - true if slide function called via touch event 19485 * @category lGPublicMethods 19486 * @example 19487 * const plugin = lightGallery({}); 19488 * plugin.goToPrevSlide(); 19489 * @see <a href="/demos/methods/">Demo</a> 19490 * 19491 */ 19492 LightGallery.prototype.goToPrevSlide = function (fromTouch) { 19493 var _this = this; 19494 var _loop = this.settings.loop; 19495 if (fromTouch && this.galleryItems.length < 3) { 19496 _loop = false; 19497 } 19498 if (!this.lgBusy) { 19499 if (this.index > 0) { 19500 this.index--; 19501 this.LGel.trigger(lGEvents.beforePrevSlide, { 19502 index: this.index, 19503 fromTouch: fromTouch, 19504 }); 19505 this.slide(this.index, !!fromTouch, false, 'prev'); 19506 } 19507 else { 19508 if (_loop) { 19509 this.index = this.galleryItems.length - 1; 19510 this.LGel.trigger(lGEvents.beforePrevSlide, { 19511 index: this.index, 19512 fromTouch: fromTouch, 19513 }); 19514 this.slide(this.index, !!fromTouch, false, 'prev'); 19515 } 19516 else if (this.settings.slideEndAnimation && !fromTouch) { 19517 this.outer.addClass('lg-left-end'); 19518 setTimeout(function () { 19519 _this.outer.removeClass('lg-left-end'); 19520 }, 400); 19521 } 19522 } 19523 } 19524 }; 19525 LightGallery.prototype.keyPress = function () { 19526 var _this = this; 19527 $LG(window).on("keydown.lg.global" + this.lgId, function (e) { 19528 if (_this.lgOpened && 19529 _this.settings.escKey === true && 19530 e.keyCode === 27) { 19531 e.preventDefault(); 19532 if (_this.settings.allowMediaOverlap && 19533 _this.outer.hasClass('lg-can-toggle') && 19534 _this.outer.hasClass('lg-components-open')) { 19535 _this.outer.removeClass('lg-components-open'); 19536 } 19537 else { 19538 _this.closeGallery(); 19539 } 19540 } 19541 if (_this.lgOpened && _this.galleryItems.length > 1) { 19542 if (e.keyCode === 37) { 19543 e.preventDefault(); 19544 _this.goToPrevSlide(); 19545 } 19546 if (e.keyCode === 39) { 19547 e.preventDefault(); 19548 _this.goToNextSlide(); 19549 } 19550 } 19551 }); 19552 }; 19553 LightGallery.prototype.arrow = function () { 19554 var _this = this; 19555 this.getElementById('lg-prev').on('click.lg', function () { 19556 _this.goToPrevSlide(); 19557 }); 19558 this.getElementById('lg-next').on('click.lg', function () { 19559 _this.goToNextSlide(); 19560 }); 19561 }; 19562 LightGallery.prototype.arrowDisable = function (index) { 19563 // Disable arrows if settings.hideControlOnEnd is true 19564 if (!this.settings.loop && this.settings.hideControlOnEnd) { 19565 var $prev = this.getElementById('lg-prev'); 19566 var $next = this.getElementById('lg-next'); 19567 if (index + 1 === this.galleryItems.length) { 19568 $next.attr('disabled', 'disabled').addClass('disabled'); 19569 } 19570 else { 19571 $next.removeAttr('disabled').removeClass('disabled'); 19572 } 19573 if (index === 0) { 19574 $prev.attr('disabled', 'disabled').addClass('disabled'); 19575 } 19576 else { 19577 $prev.removeAttr('disabled').removeClass('disabled'); 19578 } 19579 } 19580 }; 19581 LightGallery.prototype.setTranslate = function ($el, xValue, yValue, scaleX, scaleY) { 19582 if (scaleX === void 0) { scaleX = 1; } 19583 if (scaleY === void 0) { scaleY = 1; } 19584 $el.css('transform', 'translate3d(' + 19585 xValue + 19586 'px, ' + 19587 yValue + 19588 'px, 0px) scale3d(' + 19589 scaleX + 19590 ', ' + 19591 scaleY + 19592 ', 1)'); 19593 }; 19594 LightGallery.prototype.mousewheel = function () { 19595 var _this = this; 19596 var lastCall = 0; 19597 this.outer.on('wheel.lg', function (e) { 19598 if (!e.deltaY || _this.galleryItems.length < 2) { 19599 return; 19600 } 19601 e.preventDefault(); 19602 var now = new Date().getTime(); 19603 if (now - lastCall < 1000) { 19604 return; 19605 } 19606 lastCall = now; 19607 if (e.deltaY > 0) { 19608 _this.goToNextSlide(); 19609 } 19610 else if (e.deltaY < 0) { 19611 _this.goToPrevSlide(); 19612 } 19613 }); 19614 }; 19615 LightGallery.prototype.isSlideElement = function (target) { 19616 return (target.hasClass('lg-outer') || 19617 target.hasClass('lg-item') || 19618 target.hasClass('lg-img-wrap')); 19619 }; 19620 LightGallery.prototype.isPosterElement = function (target) { 19621 var playButton = this.getSlideItem(this.index) 19622 .find('.lg-video-play-button') 19623 .get(); 19624 return (target.hasClass('lg-video-poster') || 19625 target.hasClass('lg-video-play-button') || 19626 (playButton && playButton.contains(target.get()))); 19627 }; 19628 /** 19629 * Maximize minimize inline gallery. 19630 * @category lGPublicMethods 19631 */ 19632 LightGallery.prototype.toggleMaximize = function () { 19633 var _this = this; 19634 this.getElementById('lg-maximize').on('click.lg', function () { 19635 _this.$container.toggleClass('lg-inline'); 19636 _this.refreshOnResize(); 19637 }); 19638 }; 19639 LightGallery.prototype.invalidateItems = function () { 19640 for (var index = 0; index < this.items.length; index++) { 19641 var element = this.items[index]; 19642 var $element = $LG(element); 19643 $element.off("click.lgcustom-item-" + $element.attr('data-lg-id')); 19644 } 19645 }; 19646 LightGallery.prototype.trapFocus = function () { 19647 var _this = this; 19648 this.$container.get().focus({ 19649 preventScroll: true, 19650 }); 19651 $LG(window).on("keydown.lg.global" + this.lgId, function (e) { 19652 if (!_this.lgOpened) { 19653 return; 19654 } 19655 var isTabPressed = e.key === 'Tab' || e.keyCode === 9; 19656 if (!isTabPressed) { 19657 return; 19658 } 19659 var focusableEls = utils.getFocusableElements(_this.$container.get()); 19660 var firstFocusableEl = focusableEls[0]; 19661 var lastFocusableEl = focusableEls[focusableEls.length - 1]; 19662 if (e.shiftKey) { 19663 if (document.activeElement === firstFocusableEl) { 19664 lastFocusableEl.focus(); 19665 e.preventDefault(); 19666 } 19667 } 19668 else { 19669 if (document.activeElement === lastFocusableEl) { 19670 firstFocusableEl.focus(); 19671 e.preventDefault(); 19672 } 19673 } 19674 }); 19675 }; 19676 LightGallery.prototype.manageCloseGallery = function () { 19677 var _this = this; 19678 if (!this.settings.closable) 19679 return; 19680 var mousedown = false; 19681 this.getElementById('lg-close').on('click.lg', function () { 19682 _this.closeGallery(); 19683 }); 19684 if (this.settings.closeOnTap) { 19685 // If you drag the slide and release outside gallery gets close on chrome 19686 // for preventing this check mousedown and mouseup happened on .lg-item or lg-outer 19687 this.outer.on('mousedown.lg', function (e) { 19688 var target = $LG(e.target); 19689 if (_this.isSlideElement(target)) { 19690 mousedown = true; 19691 } 19692 else { 19693 mousedown = false; 19694 } 19695 }); 19696 this.outer.on('mousemove.lg', function () { 19697 mousedown = false; 19698 }); 19699 this.outer.on('mouseup.lg', function (e) { 19700 var target = $LG(e.target); 19701 if (_this.isSlideElement(target) && mousedown) { 19702 if (!_this.outer.hasClass('lg-dragging')) { 19703 _this.closeGallery(); 19704 } 19705 } 19706 }); 19707 } 19708 }; 19709 /** 19710 * Close lightGallery if it is opened. 19711 * 19712 * @description If closable is false in the settings, you need to pass true via closeGallery method to force close gallery 19713 * @return returns the estimated time to close gallery completely including the close animation duration 19714 * @category lGPublicMethods 19715 * @example 19716 * const plugin = lightGallery(); 19717 * plugin.closeGallery(); 19718 * 19719 */ 19720 LightGallery.prototype.closeGallery = function (force) { 19721 var _this = this; 19722 if (!this.lgOpened || (!this.settings.closable && !force)) { 19723 return 0; 19724 } 19725 this.LGel.trigger(lGEvents.beforeClose); 19726 if (this.settings.resetScrollPosition && !this.settings.hideScrollbar) { 19727 $LG(window).scrollTop(this.prevScrollTop); 19728 } 19729 var currentItem = this.items[this.index]; 19730 var transform; 19731 if (this.zoomFromOrigin && currentItem) { 19732 var _a = this.mediaContainerPosition, top_4 = _a.top, bottom = _a.bottom; 19733 var _b = this.galleryItems[this.index], __slideVideoInfo = _b.__slideVideoInfo, poster = _b.poster; 19734 //Uncode edit ##START## 19735 var imageSize = utils.getSize(currentItem, this.outer, top_4 + bottom, __slideVideoInfo && poster && this.settings.videoMaxSize, this.galleryItems[this.index]); 19736 // var imageSize = utils.getSize(currentItem, this.outer, top_4 + bottom, __slideVideoInfo && poster && this.settings.videoMaxSize); 19737 //Uncode edit ##END## 19738 transform = utils.getTransform(currentItem, this.outer, top_4, bottom, imageSize); 19739 } 19740 if (this.zoomFromOrigin && transform) { 19741 this.outer.addClass('lg-closing lg-zoom-from-image'); 19742 this.getSlideItem(this.index) 19743 .addClass('lg-start-end-progress') 19744 .css('transition-duration', this.settings.startAnimationDuration + 'ms') 19745 .css('transform', transform); 19746 } 19747 else { 19748 this.outer.addClass('lg-hide-items'); 19749 // lg-zoom-from-image is used for setting the opacity to 1 if zoomFromOrigin is true 19750 // If the closing item doesn't have the lg-size attribute, remove this class to avoid the closing css conflicts 19751 this.outer.removeClass('lg-zoom-from-image'); 19752 } 19753 // Unbind all events added by lightGallery 19754 // @todo 19755 //this.$el.off('.lg.tm'); 19756 this.destroyModules(); 19757 this.lGalleryOn = false; 19758 this.isDummyImageRemoved = false; 19759 this.zoomFromOrigin = this.settings.zoomFromOrigin; 19760 clearTimeout(this.hideBarTimeout); 19761 this.hideBarTimeout = false; 19762 $LG('html').removeClass('lg-on'); 19763 this.outer.removeClass('lg-visible lg-components-open'); 19764 // Resetting opacity to 0 isd required as vertical swipe to close function adds inline opacity. 19765 this.$backdrop.removeClass('in').css('opacity', 0); 19766 var removeTimeout = this.zoomFromOrigin && transform 19767 ? Math.max(this.settings.startAnimationDuration, this.settings.backdropDuration) 19768 : this.settings.backdropDuration; 19769 this.$container.removeClass('lg-show-in'); 19770 // Once the closign animation is completed and gallery is invisible 19771 setTimeout(function () { 19772 if (_this.zoomFromOrigin && transform) { 19773 _this.outer.removeClass('lg-zoom-from-image'); 19774 } 19775 _this.$container.removeClass('lg-show'); 19776 // Reset scrollbar 19777 _this.resetScrollBar(); 19778 // Need to remove inline opacity as it is used in the stylesheet as well 19779 _this.$backdrop 19780 .removeAttr('style') 19781 .css('transition-duration', _this.settings.backdropDuration + 'ms'); 19782 _this.outer.removeClass("lg-closing " + _this.settings.startClass);
vendor: 6,259 bytes, lines 19783-19986
19783 _this.getSlideItem(_this.index).removeClass('lg-start-end-progress'); 19784 _this.$inner.empty(); 19785 if (_this.lgOpened) { 19786 _this.LGel.trigger(lGEvents.afterClose, { 19787 instance: _this, 19788 }); 19789 } 19790 if (_this.$container.get()) { 19791 _this.$container.get().blur(); 19792 } 19793 _this.lgOpened = false; 19794 }, removeTimeout + 100); 19795 return removeTimeout + 100; 19796 }; 19797 LightGallery.prototype.initModules = function () { 19798 this.plugins.forEach(function (module) { 19799 try { 19800 module.init(); 19801 } 19802 catch (err) { 19803 console.warn("lightGallery:- make sure lightGallery module is properly initiated"); 19804 } 19805 }); 19806 }; 19807 LightGallery.prototype.destroyModules = function (destroy) { 19808 this.plugins.forEach(function (module) { 19809 try { 19810 if (destroy) { 19811 module.destroy(); 19812 } 19813 else { 19814 module.closeGallery && module.closeGallery(); 19815 } 19816 } 19817 catch (err) { 19818 console.warn("lightGallery:- make sure lightGallery module is properly destroyed"); 19819 } 19820 }); 19821 }; 19822 /** 19823 * Refresh lightGallery with new set of children. 19824 * 19825 * @description This is useful to update the gallery when the child elements are changed without calling destroy method. 19826 * 19827 * If you are using dynamic mode, you can pass the modified array of dynamicEl as the first parameter to refresh the dynamic gallery 19828 * @see <a href="/demos/dynamic-mode/">Demo</a> 19829 * @category lGPublicMethods 19830 * @example 19831 * const plugin = lightGallery(); 19832 * // Delete or add children, then call 19833 * plugin.refresh(); 19834 * 19835 */ 19836 LightGallery.prototype.refresh = function (galleryItems) { 19837 if (!this.settings.dynamic) { 19838 this.invalidateItems(); 19839 } 19840 if (galleryItems) { 19841 this.galleryItems = galleryItems; 19842 } 19843 else { 19844 this.galleryItems = this.getItems(); 19845 } 19846 this.updateControls(); 19847 this.openGalleryOnItemClick(); 19848 this.LGel.trigger(lGEvents.updateSlides); 19849 }; 19850 LightGallery.prototype.updateControls = function () { 19851 this.addSlideVideoInfo(this.galleryItems); 19852 this.updateCounterTotal(); 19853 this.manageSingleSlideClassName(); 19854 }; 19855 /** 19856 * Destroy lightGallery. 19857 * Destroy lightGallery and its plugin instances completely 19858 * 19859 * @description This method also calls CloseGallery function internally. Returns the time takes to completely close and destroy the instance. 19860 * In case if you want to re-initialize lightGallery right after destroying it, initialize it only once the destroy process is completed. 19861 * You can use refresh method most of the times. 19862 * @category lGPublicMethods 19863 * @example 19864 * const plugin = lightGallery(); 19865 * plugin.destroy(); 19866 * 19867 */ 19868 LightGallery.prototype.destroy = function () { 19869 var _this = this; 19870 var closeTimeout = this.closeGallery(true); 19871 setTimeout(function () { 19872 _this.destroyModules(true); 19873 if (!_this.settings.dynamic) { 19874 _this.invalidateItems(); 19875 } 19876 $LG(window).off(".lg.global" + _this.lgId); 19877 _this.LGel.off('.lg'); 19878 _this.$container.remove(); 19879 }, closeTimeout); 19880 return closeTimeout; 19881 }; 19882 return LightGallery; 19883 }()); 19884 19885 function lightGallery(el, options) { 19886 return new LightGallery(el, options); 19887 } 19888 19889 return lightGallery; 19890 19891}))); 19892 19893/*! 19894 * lightgallery | 2.5.0 | June 13th 2022 19895 * http://www.lightgalleryjs.com/ 19896 * Copyright (c) 2020 Sachin Neravath; 19897 * @license GPLv3 19898 */ 19899 19900(function (global, factory) { 19901 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 19902 typeof define === 'function' && define.amd ? define(factory) : 19903 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lgZoom = factory()); 19904}(this, (function () { 'use strict'; 19905 19906 /*! ***************************************************************************** 19907 Copyright (c) Microsoft Corporation. 19908 19909 Permission to use, copy, modify, and/or distribute this software for any 19910 purpose with or without fee is hereby granted. 19911 19912 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 19913 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 19914 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 19915 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 19916 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 19917 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 19918 PERFORMANCE OF THIS SOFTWARE. 19919 ***************************************************************************** */ 19920 19921 var __assign = function() { 19922 __assign = Object.assign || function __assign(t) { 19923 for (var s, i = 1, n = arguments.length; i < n; i++) { 19924 s = arguments[i]; 19925 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 19926 } 19927 return t; 19928 }; 19929 return __assign.apply(this, arguments); 19930 }; 19931 19932 var zoomSettings = { 19933 scale: 1, 19934 zoom: true, 19935 actualSize: true, 19936 showZoomInOutIcons: false, 19937 actualSizeIcons: { 19938 zoomIn: 'lg-zoom-in', 19939 zoomOut: 'lg-zoom-out', 19940 }, 19941 enableZoomAfter: 300, 19942 zoomPluginStrings: { 19943 zoomIn: 'Zoom in', 19944 zoomOut: 'Zoom out', 19945 viewActualSize: 'View actual size', 19946 }, 19947 }; 19948 19949 /** 19950 * List of lightGallery events 19951 * All events should be documented here 19952 * Below interfaces are used to build the website documentations 19953 * */ 19954 var lGEvents = { 19955 afterAppendSlide: 'lgAfterAppendSlide', 19956 init: 'lgInit', 19957 hasVideo: 'lgHasVideo', 19958 containerResize: 'lgContainerResize', 19959 updateSlides: 'lgUpdateSlides', 19960 afterAppendSubHtml: 'lgAfterAppendSubHtml', 19961 beforeOpen: 'lgBeforeOpen', 19962 afterOpen: 'lgAfterOpen', 19963 slideItemLoad: 'lgSlideItemLoad', 19964 beforeSlide: 'lgBeforeSlide', 19965 afterSlide: 'lgAfterSlide', 19966 posterClick: 'lgPosterClick', 19967 dragStart: 'lgDragStart', 19968 dragMove: 'lgDragMove', 19969 dragEnd: 'lgDragEnd', 19970 beforeNextSlide: 'lgBeforeNextSlide', 19971 beforePrevSlide: 'lgBeforePrevSlide', 19972 beforeClose: 'lgBeforeClose', 19973 afterClose: 'lgAfterClose', 19974 rotateLeft: 'lgRotateLeft', 19975 rotateRight: 'lgRotateRight', 19976 flipHorizontal: 'lgFlipHorizontal', 19977 flipVertical: 'lgFlipVertical', 19978 autoplay: 'lgAutoplay', 19979 autoplayStart: 'lgAutoplayStart', 19980 autoplayStop: 'lgAutoplayStop', 19981 }; 19982 19983 var Zoom = /** @class */ (function () { 19984 function Zoom(instance, $LG) { 19985 // get lightGallery core plugin instance 19986 this.core = instance;
19987 this.$LG = $LG; 19988 this.settings = __assign(__assign({}, zoomSettings), this.core.settings); 19989 return this; 19990 } 19991 // Append Zoom controls. Actual size, Zoom-in, Zoom-out 19992 Zoom.prototype.buildTemplates = function () { 19993 var zoomIcons = this.settings.showZoomInOutIcons 19994 ? "<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>" 19995 : ''; 19996 if (this.settings.actualSize) { 19997 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>"; 19998 } 19999 this.core.outer.addClass('lg-use-transition-for-zoom'); 20000 this.core.$toolbar.first().append(zoomIcons); 20001 }; 20002 /** 20003 * @desc Enable zoom option only once the image is completely loaded 20004 * If zoomFromOrigin is true, Zoom is enabled once the dummy image has been inserted 20005 * 20006 * Zoom styles are defined under lg-zoomable CSS class. 20007 */ 20008 Zoom.prototype.enableZoom = function (event) { 20009 var _this = this; 20010 // delay will be 0 except first time 20011 var _speed = this.settings.enableZoomAfter + event.detail.delay; 20012 // set _speed value 0 if gallery opened from direct url and if it is first slide 20013 if (this.$LG('body').first().hasClass('lg-from-hash') && 20014 event.detail.delay) { 20015 // will execute only once 20016 _speed = 0; 20017 } 20018 else { 20019 // Remove lg-from-hash to enable starting animation. 20020 this.$LG('body').first().removeClass('lg-from-hash'); 20021 } 20022 this.zoomableTimeout = setTimeout(function () { 20023 if (!_this.isImageSlide()) { 20024 return; 20025 } 20026 _this.core.getSlideItem(event.detail.index).addClass('lg-zoomable'); 20027 if (event.detail.index === _this.core.index) { 20028 _this.setZoomEssentials(); 20029 } 20030 }, _speed + 30); 20031 }; 20032 Zoom.prototype.enableZoomOnSlideItemLoad = function () { 20033 // Add zoomable class 20034 this.core.LGel.on(lGEvents.slideItemLoad + ".zoom", this.enableZoom.bind(this)); 20035 }; 20036 Zoom.prototype.getModifier = function (rotateValue, axis, el) { 20037 var originalRotate = rotateValue; 20038 rotateValue = Math.abs(rotateValue); 20039 var transformValues = this.getCurrentTransform(el); 20040 if (!transformValues) { 20041 return 1; 20042 } 20043 var modifier = 1; 20044 if (axis === 'X') { 20045 var flipHorizontalValue = Math.sign(parseFloat(transformValues[0])); 20046 if (rotateValue === 0 || rotateValue === 180) { 20047 modifier = 1; 20048 } 20049 else if (rotateValue === 90) { 20050 if ((originalRotate === -90 && flipHorizontalValue === 1) || 20051 (originalRotate === 90 && flipHorizontalValue === -1)) { 20052 modifier = -1; 20053 } 20054 else { 20055 modifier = 1; 20056 } 20057 } 20058 modifier = modifier * flipHorizontalValue; 20059 } 20060 else { 20061 var flipVerticalValue = Math.sign(parseFloat(transformValues[3])); 20062 if (rotateValue === 0 || rotateValue === 180) { 20063 modifier = 1; 20064 } 20065 else if (rotateValue === 90) { 20066 var sinX = parseFloat(transformValues[1]); 20067 var sinMinusX = parseFloat(transformValues[2]); 20068 modifier = Math.sign(sinX * sinMinusX * originalRotate * flipVerticalValue); 20069 } 20070 modifier = modifier * flipVerticalValue; 20071 } 20072 return modifier; 20073 }; 20074 Zoom.prototype.getImageSize = function ($image, rotateValue, axis) { 20075 var imageSizes = { 20076 y: 'offsetHeight', 20077 x: 'offsetWidth', 20078 }; 20079 if (Math.abs(rotateValue) === 90) { 20080 // Swap axis 20081 if (axis === 'x') { 20082 axis = 'y'; 20083 } 20084 else { 20085 axis = 'x'; 20086 } 20087 } 20088 return $image[imageSizes[axis]]; 20089 }; 20090 Zoom.prototype.getDragCords = function (e, rotateValue) { 20091 if (rotateValue === 90) { 20092 return { 20093 x: e.pageY, 20094 y: e.pageX, 20095 }; 20096 } 20097 else { 20098 return { 20099 x: e.pageX, 20100 y: e.pageY, 20101 }; 20102 } 20103 }; 20104 Zoom.prototype.getSwipeCords = function (e, rotateValue) { 20105 var x = e.targetTouches[0].pageX; 20106 var y = e.targetTouches[0].pageY; 20107 if (rotateValue === 90) { 20108 return { 20109 x: y, 20110 y: x, 20111 }; 20112 } 20113 else { 20114 return { 20115 x: x, 20116 y: y, 20117 }; 20118 } 20119 }; 20120 Zoom.prototype.getDragAllowedAxises = function (rotateValue, scale) { 20121 scale = scale || this.scale || 1; 20122 var allowY = this.imageYSize * scale > this.containerRect.height; 20123 var allowX = this.imageXSize * scale > this.containerRect.width; 20124 if (rotateValue === 90) { 20125 return { 20126 allowX: allowY, 20127 allowY: allowX, 20128 }; 20129 } 20130 else { 20131 return { 20132 allowX: allowX, 20133 allowY: allowY, 20134 }; 20135 } 20136 }; 20137 /** 20138 * 20139 * @param {Element} el 20140 * @return matrix(cos(X), sin(X), -sin(X), cos(X), 0, 0); 20141 * Get the current transform value 20142 */ 20143 Zoom.prototype.getCurrentTransform = function (el) { 20144 if (!el) { 20145 return; 20146 } 20147 var st = window.getComputedStyle(el, null); 20148 var tm = st.getPropertyValue('-webkit-transform') || 20149 st.getPropertyValue('-moz-transform') || 20150 st.getPropertyValue('-ms-transform') || 20151 st.getPropertyValue('-o-transform') || 20152 st.getPropertyValue('transform') || 20153 'none'; 20154 if (tm !== 'none') { 20155 return tm.split('(')[1].split(')')[0].split(','); 20156 } 20157 return; 20158 }; 20159 Zoom.prototype.getCurrentRotation = function (el) { 20160 if (!el) { 20161 return 0; 20162 } 20163 var values = this.getCurrentTransform(el); 20164 if (values) { 20165 return Math.round(Math.atan2(parseFloat(values[1]), parseFloat(values[0])) * 20166 (180 / Math.PI)); 20167 // If you want rotate in 360 20168 //return (angle < 0 ? angle + 360 : angle); 20169 } 20170 return 0; 20171 }; 20172 Zoom.prototype.setZoomEssentials = function () { 20173 var $image = this.core 20174 .getSlideItem(this.core.index) 20175 .find('.lg-image') 20176 .first(); 20177 var rotateEl = this.core 20178 .getSlideItem(this.core.index) 20179 .find('.lg-img-rotate') 20180 .first() 20181 .get(); 20182 this.rotateValue = this.getCurrentRotation(rotateEl); 20183 this.imageYSize = this.getImageSize($image.get(), this.rotateValue, 'y'); 20184 this.imageXSize = this.getImageSize($image.get(), this.rotateValue, 'x'); 20185 this.containerRect = this.core.outer.get().getBoundingClientRect(); 20186 this.modifierX = this.getModifier(this.rotateValue, 'X', rotateEl); 20187 this.modifierY = this.getModifier(this.rotateValue, 'Y', rotateEl); 20188 }; 20189 /** 20190 * @desc Image zoom 20191 * Translate the wrap and scale the image to get better user experience 20192 * 20193 * @param {String} scale - Zoom decrement/increment value 20194 */ 20195 Zoom.prototype.zoomImage = function (scale) { 20196 // Find offset manually to avoid issue after zoom 20197 var offsetX = (this.containerRect.width - this.imageXSize) / 2 + 20198 this.containerRect.left; 20199 var _a = this.core.mediaContainerPosition, top = _a.top, bottom = _a.bottom; 20200 var topBottomSpacing = Math.abs(top - bottom) / 2; 20201 var offsetY = (this.containerRect.height - 20202 this.imageYSize - 20203 topBottomSpacing * this.modifierX) / 20204 2 + 20205 this.scrollTop + 20206 this.containerRect.top; 20207 var originalX; 20208 var originalY; 20209 if (scale === 1) { 20210 this.positionChanged = false;
20211 } 20212 var dragAllowedAxises = this.getDragAllowedAxises(Math.abs(this.rotateValue), scale); 20213 var allowY = dragAllowedAxises.allowY, allowX = dragAllowedAxises.allowX; 20214 if (this.positionChanged) { 20215 originalX = this.left / (this.scale - 1); 20216 originalY = this.top / (this.scale - 1); 20217 this.pageX = Math.abs(originalX) + offsetX; 20218 this.pageY = Math.abs(originalY) + offsetY; 20219 this.positionChanged = false; 20220 } 20221 var possibleSwipeCords = this.getPossibleSwipeDragCords(this.rotateValue, scale); 20222 var _x = offsetX - this.pageX; 20223 var _y = offsetY - this.pageY; 20224 var x = (scale - 1) * _x; 20225 var y = (scale - 1) * _y; 20226 if (allowX) { 20227 if (this.isBeyondPossibleLeft(x, possibleSwipeCords.minX)) { 20228 x = possibleSwipeCords.minX; 20229 } 20230 else if (this.isBeyondPossibleRight(x, possibleSwipeCords.maxX)) { 20231 x = possibleSwipeCords.maxX; 20232 } 20233 } 20234 else { 20235 if (scale > 1) { 20236 if (x < possibleSwipeCords.minX) { 20237 x = possibleSwipeCords.minX; 20238 } 20239 else if (x > possibleSwipeCords.maxX) { 20240 x = possibleSwipeCords.maxX; 20241 } 20242 } 20243 }
20244 if (allowY) { 20245 if (this.isBeyondPossibleTop(y, possibleSwipeCords.minY)) { 20246 y = possibleSwipeCords.minY; 20247 } 20248 else if (this.isBeyondPossibleBottom(y, possibleSwipeCords.maxY)) { 20249 y = possibleSwipeCords.maxY; 20250 } 20251 } 20252 else { 20253 // If the translate value based on index of beyond the viewport, utilize the available space to prevent image being cut out 20254 if (scale > 1) { 20255 //If image goes beyond viewport top, use the minim possible translate value 20256 if (y < possibleSwipeCords.minY) { 20257 y = possibleSwipeCords.minY; 20258 } 20259 else if (y > possibleSwipeCords.maxY) { 20260 y = possibleSwipeCords.maxY; 20261 } 20262 } 20263 } 20264 this.setZoomStyles({ 20265 x: x, 20266 y: y, 20267 scale: scale, 20268 }); 20269 }; 20270 /** 20271 * @desc apply scale3d to image and translate to image wrap 20272 * @param {style} X,Y and scale 20273 */ 20274 Zoom.prototype.setZoomStyles = function (style) { 20275 var $image = this.core 20276 .getSlideItem(this.core.index) 20277 .find('.lg-image') 20278 .first(); 20279 var $dummyImage = this.core.outer 20280 .find('.lg-current .lg-dummy-img') 20281 .first(); 20282 var $imageWrap = $image.parent(); 20283 this.scale = style.scale; 20284 $image.css('transform', 'scale3d(' + style.scale + ', ' + style.scale + ', 1)'); 20285 $dummyImage.css('transform', 'scale3d(' + style.scale + ', ' + style.scale + ', 1)'); 20286 var transform = 'translate3d(' + style.x + 'px, ' + style.y + 'px, 0)'; 20287 $imageWrap.css('transform', transform); 20288 this.left = style.x; 20289 this.top = style.y; 20290 }; 20291 /** 20292 * @param index - Index of the current slide 20293 * @param event - event will be available only if the function is called on clicking/taping the imags 20294 */ 20295 Zoom.prototype.setActualSize = function (index, event) { 20296 var _this = this; 20297 // Allow zoom only on image 20298 if (!this.isImageSlide() || 20299 this.core.outer.hasClass('lg-first-slide-loading')) { 20300 return; 20301 } 20302 var scale = this.getCurrentImageActualSizeScale(); 20303 if (this.core.outer.hasClass('lg-zoomed')) { 20304 this.scale = 1; 20305 } 20306 else { 20307 this.scale = this.getScale(scale); 20308 } 20309 this.setPageCords(event); 20310 this.beginZoom(this.scale); 20311 this.zoomImage(this.scale); 20312 setTimeout(function () { 20313 _this.core.outer.removeClass('lg-grabbing').addClass('lg-grab'); 20314 }, 10); 20315 }; 20316 Zoom.prototype.getNaturalWidth = function (index) { 20317 var $image = this.core.getSlideItem(index).find('.lg-image').first(); 20318 var naturalWidth = this.core.galleryItems[index].width; 20319 return naturalWidth 20320 ? parseFloat(naturalWidth) 20321 : $image.get().naturalWidth; 20322 }; 20323 Zoom.prototype.getActualSizeScale = function (naturalWidth, width) { 20324 var _scale; 20325 var scale;
20326 if (naturalWidth > width) { 20327 _scale = naturalWidth / width; 20328 scale = _scale || 2; 20329 } 20330 else { 20331 scale = 1; 20332 } 20333 return scale; 20334 }; 20335 Zoom.prototype.getCurrentImageActualSizeScale = function () { 20336 var $image = this.core 20337 .getSlideItem(this.core.index) 20338 .find('.lg-image') 20339 .first(); 20340 var width = $image.get().offsetWidth; 20341 var naturalWidth = this.getNaturalWidth(this.core.index) || width; 20342 return this.getActualSizeScale(naturalWidth, width); 20343 }; 20344 Zoom.prototype.getPageCords = function (event) { 20345 var cords = {}; 20346 if (event) { 20347 cords.x = event.pageX || event.targetTouches[0].pageX; 20348 cords.y = event.pageY || event.targetTouches[0].pageY; 20349 } 20350 else { 20351 var containerRect = this.core.outer.get().getBoundingClientRect(); 20352 cords.x = containerRect.width / 2 + containerRect.left; 20353 cords.y = 20354 containerRect.height / 2 + this.scrollTop + containerRect.top; 20355 } 20356 return cords; 20357 }; 20358 Zoom.prototype.setPageCords = function (event) { 20359 var pageCords = this.getPageCords(event); 20360 this.pageX = pageCords.x; 20361 this.pageY = pageCords.y; 20362 }; 20363 // If true, zoomed - in else zoomed out 20364 Zoom.prototype.beginZoom = function (scale) { 20365 this.core.outer.removeClass('lg-zoom-drag-transition lg-zoom-dragging'); 20366 if (scale > 1) { 20367 this.core.outer.addClass('lg-zoomed'); 20368 var $actualSize = this.core.getElementById('lg-actual-size'); 20369 $actualSize 20370 .removeClass(this.settings.actualSizeIcons.zoomIn) 20371 .addClass(this.settings.actualSizeIcons.zoomOut); 20372 } 20373 else { 20374 this.resetZoom(); 20375 } 20376 return scale > 1; 20377 }; 20378 Zoom.prototype.getScale = function (scale) { 20379 var actualSizeScale = this.getCurrentImageActualSizeScale(); 20380 if (scale < 1) { 20381 scale = 1; 20382 } 20383 else if (scale > actualSizeScale) { 20384 scale = actualSizeScale; 20385 } 20386 return scale; 20387 }; 20388 Zoom.prototype.init = function () { 20389 var _this = this; 20390 if (!this.settings.zoom) { 20391 return; 20392 } 20393 this.buildTemplates(); 20394 this.enableZoomOnSlideItemLoad(); 20395 var tapped = null; 20396 this.core.outer.on('dblclick.lg', function (event) { 20397 if (!_this.$LG(event.target).hasClass('lg-image')) { 20398 return; 20399 } 20400 _this.setActualSize(_this.core.index, event); 20401 }); 20402 this.core.outer.on('touchstart.lg', function (event) { 20403 var $target = _this.$LG(event.target); 20404 if (event.targetTouches.length === 1 && 20405 $target.hasClass('lg-image')) { 20406 if (!tapped) { 20407 tapped = setTimeout(function () { 20408 tapped = null; 20409 }, 300); 20410 } 20411 else { 20412 clearTimeout(tapped); 20413 tapped = null; 20414 event.preventDefault(); 20415 _this.setActualSize(_this.core.index, event); 20416 } 20417 } 20418 }); 20419 // Update zoom on resize and orientationchange 20420 this.core.LGel.on(lGEvents.containerResize + ".zoom " + lGEvents.rotateRight + ".zoom " + lGEvents.rotateLeft + ".zoom " + lGEvents.flipHorizontal + ".zoom " + lGEvents.flipVertical + ".zoom", function () { 20421 if (!_this.core.lgOpened || !_this.isImageSlide()) 20422 return; 20423 _this.setPageCords(); 20424 _this.setZoomEssentials(); 20425 _this.zoomImage(_this.scale); 20426 }); 20427 // Update zoom on resize and orientationchange 20428 this.$LG(window).on("scroll.lg.zoom.global" + this.core.lgId, function () { 20429 if (!_this.core.lgOpened) 20430 return; 20431 _this.scrollTop = _this.$LG(window).scrollTop(); 20432 }); 20433 this.core.getElementById('lg-zoom-out').on('click.lg', function () { 20434 if (_this.core.outer.find('.lg-current .lg-image').get()) { 20435 _this.scale -= _this.settings.scale; 20436 _this.scale = _this.getScale(_this.scale); 20437 _this.beginZoom(_this.scale); 20438 _this.zoomImage(_this.scale); 20439 } 20440 }); 20441 this.core.getElementById('lg-zoom-in').on('click.lg', function () { 20442 _this.zoomIn(); 20443 }); 20444 this.core.getElementById('lg-actual-size').on('click.lg', function () { 20445 _this.setActualSize(_this.core.index); 20446 }); 20447 this.core.LGel.on(lGEvents.beforeOpen + ".zoom", function () { 20448 _this.core.outer.find('.lg-item').removeClass('lg-zoomable'); 20449 }); 20450 this.core.LGel.on(lGEvents.afterOpen + ".zoom", function () { 20451 _this.scrollTop = _this.$LG(window).scrollTop(); 20452 // Set the initial value center 20453 _this.pageX = _this.core.outer.width() / 2;
20454 _this.pageY = _this.core.outer.height() / 2 + _this.scrollTop; 20455 _this.scale = 1; 20456 }); 20457 // Reset zoom on slide change 20458 this.core.LGel.on(lGEvents.afterSlide + ".zoom", function (event) { 20459 var prevIndex = event.detail.prevIndex; 20460 _this.scale = 1; 20461 _this.positionChanged = false; 20462 _this.resetZoom(prevIndex); 20463 if (_this.isImageSlide()) { 20464 _this.setZoomEssentials(); 20465 } 20466 }); 20467 // Drag option after zoom 20468 this.zoomDrag(); 20469 this.pinchZoom(); 20470 this.zoomSwipe(); 20471 // Store the zoomable timeout value just to clear it while closing 20472 this.zoomableTimeout = false; 20473 this.positionChanged = false; 20474 }; 20475 Zoom.prototype.zoomIn = function (scale) { 20476 // Allow zoom only on image 20477 if (!this.isImageSlide()) { 20478 return; 20479 } 20480 if (scale) { 20481 this.scale = scale; 20482 } 20483 else { 20484 this.scale += this.settings.scale; 20485 } 20486 this.scale = this.getScale(this.scale); 20487 this.beginZoom(this.scale); 20488 this.zoomImage(this.scale); 20489 }; 20490 // Reset zoom effect 20491 Zoom.prototype.resetZoom = function (index) { 20492 this.core.outer.removeClass('lg-zoomed lg-zoom-drag-transition'); 20493 var $actualSize = this.core.getElementById('lg-actual-size'); 20494 var $item = this.core.getSlideItem(index !== undefined ? index : this.core.index); 20495 $actualSize 20496 .removeClass(this.settings.actualSizeIcons.zoomOut) 20497 .addClass(this.settings.actualSizeIcons.zoomIn); 20498 $item.find('.lg-img-wrap').first().removeAttr('style'); 20499 $item.find('.lg-image').first().removeAttr('style'); 20500 this.scale = 1; 20501 this.left = 0; 20502 this.top = 0; 20503 // Reset pagx pagy values to center 20504 this.setPageCords(); 20505 }; 20506 Zoom.prototype.getTouchDistance = function (e) { 20507 return Math.sqrt((e.targetTouches[0].pageX - e.targetTouches[1].pageX) * 20508 (e.targetTouches[0].pageX - e.targetTouches[1].pageX) + 20509 (e.targetTouches[0].pageY - e.targetTouches[1].pageY) * 20510 (e.targetTouches[0].pageY - e.targetTouches[1].pageY)); 20511 }; 20512 Zoom.prototype.pinchZoom = function () { 20513 var _this = this; 20514 var startDist = 0; 20515 var pinchStarted = false; 20516 var initScale = 1; 20517 var $item = this.core.getSlideItem(this.core.index); 20518 this.core.$inner.on('touchstart.lg', function (e) { 20519 $item = _this.core.getSlideItem(_this.core.index); 20520 if (!_this.isImageSlide()) { 20521 return; 20522 } 20523 if (e.targetTouches.length === 2 && 20524 !_this.core.outer.hasClass('lg-first-slide-loading') && 20525 (_this.$LG(e.target).hasClass('lg-item') || 20526 $item.get().contains(e.target))) { 20527 initScale = _this.scale || 1; 20528 _this.core.outer.removeClass('lg-zoom-drag-transition lg-zoom-dragging'); 20529 _this.core.touchAction = 'pinch'; 20530 startDist = _this.getTouchDistance(e); 20531 } 20532 }); 20533 this.core.$inner.on('touchmove.lg', function (e) { 20534 if (e.targetTouches.length === 2 && 20535 _this.core.touchAction === 'pinch' && 20536 (_this.$LG(e.target).hasClass('lg-item') || 20537 $item.get().contains(e.target))) { 20538 e.preventDefault(); 20539 var endDist = _this.getTouchDistance(e); 20540 var distance = startDist - endDist; 20541 if (!pinchStarted && Math.abs(distance) > 5) { 20542 pinchStarted = true; 20543 } 20544 if (pinchStarted) { 20545 _this.scale = Math.max(1, initScale + -distance * 0.008); 20546 _this.zoomImage(_this.scale); 20547 } 20548 } 20549 }); 20550 this.core.$inner.on('touchend.lg', function (e) { 20551 if (_this.core.touchAction === 'pinch' && 20552 (_this.$LG(e.target).hasClass('lg-item') || 20553 $item.get().contains(e.target))) { 20554 pinchStarted = false; 20555 startDist = 0; 20556 if (_this.scale <= 1) { 20557 _this.resetZoom(); 20558 } 20559 else { 20560 _this.scale = _this.getScale(_this.scale); 20561 _this.zoomImage(_this.scale); 20562 _this.core.outer.addClass('lg-zoomed'); 20563 } 20564 _this.core.touchAction = undefined; 20565 } 20566 }); 20567 }; 20568 Zoom.prototype.touchendZoom = function (startCoords, endCoords, allowX, allowY, touchDuration, rotateValue) { 20569 var distanceXnew = endCoords.x - startCoords.x; 20570 var distanceYnew = endCoords.y - startCoords.y; 20571 var speedX = Math.abs(distanceXnew) / touchDuration + 1; 20572 var speedY = Math.abs(distanceYnew) / touchDuration + 1; 20573 if (speedX > 2) { 20574 speedX += 1; 20575 } 20576 if (speedY > 2) { 20577 speedY += 1; 20578 } 20579 distanceXnew = distanceXnew * speedX; 20580 distanceYnew = distanceYnew * speedY; 20581 var _LGel = this.core 20582 .getSlideItem(this.core.index) 20583 .find('.lg-img-wrap') 20584 .first(); 20585 var distance = {}; 20586 distance.x = this.left + distanceXnew * this.modifierX; 20587 distance.y = this.top + distanceYnew * this.modifierY; 20588 var possibleSwipeCords = this.getPossibleSwipeDragCords(rotateValue); 20589 if (Math.abs(distanceXnew) > 15 || Math.abs(distanceYnew) > 15) { 20590 if (allowY) { 20591 if (this.isBeyondPossibleTop(distance.y, possibleSwipeCords.minY)) { 20592 distance.y = possibleSwipeCords.minY; 20593 } 20594 else if (this.isBeyondPossibleBottom(distance.y, possibleSwipeCords.maxY)) { 20595 distance.y = possibleSwipeCords.maxY; 20596 } 20597 } 20598 if (allowX) { 20599 if (this.isBeyondPossibleLeft(distance.x, possibleSwipeCords.minX)) { 20600 distance.x = possibleSwipeCords.minX; 20601 } 20602 else if (this.isBeyondPossibleRight(distance.x, possibleSwipeCords.maxX)) { 20603 distance.x = possibleSwipeCords.maxX; 20604 } 20605 } 20606 if (allowY) { 20607 this.top = distance.y; 20608 } 20609 else { 20610 distance.y = this.top; 20611 } 20612 if (allowX) { 20613 this.left = distance.x; 20614 } 20615 else { 20616 distance.x = this.left; 20617 } 20618 this.setZoomSwipeStyles(_LGel, distance); 20619 this.positionChanged = true; 20620 } 20621 }; 20622 Zoom.prototype.getZoomSwipeCords = function (startCoords, endCoords, allowX, allowY, possibleSwipeCords) { 20623 var distance = {}; 20624 if (allowY) { 20625 distance.y = 20626 this.top + (endCoords.y - startCoords.y) * this.modifierY; 20627 if (this.isBeyondPossibleTop(distance.y, possibleSwipeCords.minY)) { 20628 var diffMinY = possibleSwipeCords.minY - distance.y; 20629 distance.y = possibleSwipeCords.minY - diffMinY / 6; 20630 } 20631 else if (this.isBeyondPossibleBottom(distance.y, possibleSwipeCords.maxY)) { 20632 var diffMaxY = distance.y - possibleSwipeCords.maxY; 20633 distance.y = possibleSwipeCords.maxY + diffMaxY / 6; 20634 } 20635 } 20636 else { 20637 distance.y = this.top; 20638 }
20639 if (allowX) { 20640 distance.x = 20641 this.left + (endCoords.x - startCoords.x) * this.modifierX; 20642 if (this.isBeyondPossibleLeft(distance.x, possibleSwipeCords.minX)) { 20643 var diffMinX = possibleSwipeCords.minX - distance.x; 20644 distance.x = possibleSwipeCords.minX - diffMinX / 6; 20645 } 20646 else if (this.isBeyondPossibleRight(distance.x, possibleSwipeCords.maxX)) { 20647 var difMaxX = distance.x - possibleSwipeCords.maxX; 20648 distance.x = possibleSwipeCords.maxX + difMaxX / 6; 20649 } 20650 } 20651 else { 20652 distance.x = this.left; 20653 } 20654 return distance; 20655 }; 20656 Zoom.prototype.isBeyondPossibleLeft = function (x, minX) { 20657 return x >= minX; 20658 }; 20659 Zoom.prototype.isBeyondPossibleRight = function (x, maxX) { 20660 return x <= maxX; 20661 }; 20662 Zoom.prototype.isBeyondPossibleTop = function (y, minY) { 20663 return y >= minY; 20664 }; 20665 Zoom.prototype.isBeyondPossibleBottom = function (y, maxY) { 20666 return y <= maxY; 20667 }; 20668 Zoom.prototype.isImageSlide = function () { 20669 var currentItem = this.core.galleryItems[this.core.index]; 20670 return this.core.getSlideType(currentItem) === 'image'; 20671 }; 20672 Zoom.prototype.getPossibleSwipeDragCords = function (rotateValue, scale) { 20673 var dataScale = scale || this.scale || 1; 20674 var elDataScale = Math.abs(dataScale); 20675 var _a = this.core.mediaContainerPosition, top = _a.top, bottom = _a.bottom; 20676 var topBottomSpacing = Math.abs(top - bottom) / 2; 20677 var minY = (this.imageYSize - this.containerRect.height) / 2 + 20678 topBottomSpacing * this.modifierX; 20679 var maxY = this.containerRect.height - this.imageYSize * elDataScale + minY; 20680 var minX = (this.imageXSize - this.containerRect.width) / 2; 20681 var maxX = this.containerRect.width - this.imageXSize * elDataScale + minX; 20682 var possibleSwipeCords = { 20683 minY: minY, 20684 maxY: maxY, 20685 minX: minX, 20686 maxX: maxX, 20687 }; 20688 if (Math.abs(rotateValue) === 90) { 20689 possibleSwipeCords = { 20690 minY: minX, 20691 maxY: maxX, 20692 minX: minY, 20693 maxX: maxY, 20694 }; 20695 } 20696 return possibleSwipeCords; 20697 }; 20698 Zoom.prototype.setZoomSwipeStyles = function (LGel, distance) { 20699 LGel.css('transform', 'translate3d(' + distance.x + 'px, ' + distance.y + 'px, 0)'); 20700 }; 20701 Zoom.prototype.zoomSwipe = function () { 20702 var _this = this; 20703 var startCoords = {}; 20704 var endCoords = {}; 20705 var isMoved = false; 20706 // Allow x direction drag 20707 var allowX = false; 20708 // Allow Y direction drag 20709 var allowY = false; 20710 var startTime = new Date(); 20711 var endTime = new Date(); 20712 var possibleSwipeCords; 20713 var _LGel; 20714 var $item = this.core.getSlideItem(this.core.index); 20715 this.core.$inner.on('touchstart.lg', function (e) { 20716 // Allow zoom only on image 20717 if (!_this.isImageSlide()) { 20718 return; 20719 } 20720 $item = _this.core.getSlideItem(_this.core.index); 20721 if ((_this.$LG(e.target).hasClass('lg-item') || 20722 $item.get().contains(e.target)) && 20723 e.targetTouches.length === 1 && 20724 _this.core.outer.hasClass('lg-zoomed')) { 20725 e.preventDefault(); 20726 startTime = new Date(); 20727 _this.core.touchAction = 'zoomSwipe'; 20728 _LGel = _this.core 20729 .getSlideItem(_this.core.index) 20730 .find('.lg-img-wrap') 20731 .first(); 20732 var dragAllowedAxises = _this.getDragAllowedAxises(Math.abs(_this.rotateValue)); 20733 allowY = dragAllowedAxises.allowY; 20734 allowX = dragAllowedAxises.allowX; 20735 if (allowX || allowY) { 20736 startCoords = _this.getSwipeCords(e, Math.abs(_this.rotateValue)); 20737 } 20738 possibleSwipeCords = _this.getPossibleSwipeDragCords(_this.rotateValue); 20739 // reset opacity and transition duration 20740 _this.core.outer.addClass('lg-zoom-dragging lg-zoom-drag-transition'); 20741 } 20742 }); 20743 this.core.$inner.on('touchmove.lg', function (e) { 20744 if (e.targetTouches.length === 1 && 20745 _this.core.touchAction === 'zoomSwipe' && 20746 (_this.$LG(e.target).hasClass('lg-item') || 20747 $item.get().contains(e.target))) { 20748 e.preventDefault(); 20749 _this.core.touchAction = 'zoomSwipe'; 20750 endCoords = _this.getSwipeCords(e, Math.abs(_this.rotateValue)); 20751 var distance = _this.getZoomSwipeCords(startCoords, endCoords, allowX, allowY, possibleSwipeCords); 20752 if (Math.abs(endCoords.x - startCoords.x) > 15 || 20753 Math.abs(endCoords.y - startCoords.y) > 15) { 20754 isMoved = true; 20755 _this.setZoomSwipeStyles(_LGel, distance); 20756 } 20757 } 20758 }); 20759 this.core.$inner.on('touchend.lg', function (e) { 20760 if (_this.core.touchAction === 'zoomSwipe' && 20761 (_this.$LG(e.target).hasClass('lg-item') || 20762 $item.get().contains(e.target))) { 20763 _this.core.touchAction = undefined; 20764 _this.core.outer.removeClass('lg-zoom-dragging'); 20765 if (!isMoved) { 20766 return; 20767 } 20768 isMoved = false;
20769 endTime = new Date(); 20770 var touchDuration = endTime.valueOf() - startTime.valueOf(); 20771 _this.touchendZoom(startCoords, endCoords, allowX, allowY, touchDuration, _this.rotateValue); 20772 } 20773 }); 20774 }; 20775 Zoom.prototype.zoomDrag = function () { 20776 var _this = this; 20777 var startCoords = {}; 20778 var endCoords = {}; 20779 var isDragging = false; 20780 var isMoved = false; 20781 // Allow x direction drag 20782 var allowX = false; 20783 // Allow Y direction drag 20784 var allowY = false; 20785 var startTime; 20786 var endTime; 20787 var possibleSwipeCords; 20788 var _LGel; 20789 this.core.outer.on('mousedown.lg.zoom', function (e) { 20790 // Allow zoom only on image 20791 if (!_this.isImageSlide()) { 20792 return; 20793 } 20794 var $item = _this.core.getSlideItem(_this.core.index); 20795 if (_this.$LG(e.target).hasClass('lg-item') || 20796 $item.get().contains(e.target)) { 20797 startTime = new Date(); 20798 _LGel = _this.core 20799 .getSlideItem(_this.core.index) 20800 .find('.lg-img-wrap') 20801 .first(); 20802 var dragAllowedAxises = _this.getDragAllowedAxises(Math.abs(_this.rotateValue)); 20803 allowY = dragAllowedAxises.allowY; 20804 allowX = dragAllowedAxises.allowX; 20805 if (_this.core.outer.hasClass('lg-zoomed')) { 20806 if (_this.$LG(e.target).hasClass('lg-object') && 20807 (allowX || allowY)) { 20808 e.preventDefault(); 20809 startCoords = _this.getDragCords(e, Math.abs(_this.rotateValue)); 20810 possibleSwipeCords = _this.getPossibleSwipeDragCords(_this.rotateValue); 20811 isDragging = true; 20812 // ** Fix for webkit cursor issue https://code.google.com/p/chromium/issues/detail?id=26723 20813 _this.core.outer.get().scrollLeft += 1; 20814 _this.core.outer.get().scrollLeft -= 1; 20815 _this.core.outer 20816 .removeClass('lg-grab') 20817 .addClass('lg-grabbing lg-zoom-drag-transition lg-zoom-dragging'); 20818 // reset opacity and transition duration 20819 } 20820 } 20821 } 20822 }); 20823 this.$LG(window).on("mousemove.lg.zoom.global" + this.core.lgId, function (e) { 20824 if (isDragging) { 20825 isMoved = true; 20826 endCoords = _this.getDragCords(e, Math.abs(_this.rotateValue)); 20827 var distance = _this.getZoomSwipeCords(startCoords, endCoords, allowX, allowY, possibleSwipeCords); 20828 _this.setZoomSwipeStyles(_LGel, distance); 20829 } 20830 }); 20831 this.$LG(window).on("mouseup.lg.zoom.global" + this.core.lgId, function (e) { 20832 if (isDragging) { 20833 endTime = new Date(); 20834 isDragging = false; 20835 _this.core.outer.removeClass('lg-zoom-dragging'); 20836 // Fix for chrome mouse move on click 20837 if (isMoved && 20838 (startCoords.x !== endCoords.x || 20839 startCoords.y !== endCoords.y)) { 20840 endCoords = _this.getDragCords(e, Math.abs(_this.rotateValue)); 20841 var touchDuration = endTime.valueOf() - startTime.valueOf(); 20842 _this.touchendZoom(startCoords, endCoords, allowX, allowY, touchDuration, _this.rotateValue); 20843 } 20844 isMoved = false; 20845 } 20846 _this.core.outer.removeClass('lg-grabbing').addClass('lg-grab'); 20847 }); 20848 }; 20849 Zoom.prototype.closeGallery = function () { 20850 this.resetZoom(); 20851 }; 20852 Zoom.prototype.destroy = function () { 20853 // Unbind all events added by lightGallery zoom plugin 20854 this.$LG(window).off(".lg.zoom.global" + this.core.lgId); 20855 this.core.LGel.off('.lg.zoom'); 20856 this.core.LGel.off('.zoom'); 20857 clearTimeout(this.zoomableTimeout); 20858 this.zoomableTimeout = false; 20859 }; 20860 return Zoom; 20861 }()); 20862 20863 return Zoom; 20864 20865}))); 20866/*! 20867 * lightgallery | 2.5.0 | June 13th 2022 20868 * http://www.lightgalleryjs.com/ 20869 * Copyright (c) 2020 Sachin Neravath; 20870 * @license GPLv3 20871 */ 20872 20873(function (global, factory) { 20874 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 20875 typeof define === 'function' && define.amd ? define(factory) : 20876 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lgFullscreen = factory()); 20877}(this, (function () { 'use strict'; 20878 20879 /*! ***************************************************************************** 20880 Copyright (c) Microsoft Corporation. 20881 20882 Permission to use, copy, modify, and/or distribute this software for any 20883 purpose with or without fee is hereby granted. 20884 20885 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 20886 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 20887 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 20888 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 20889 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 20890 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 20891 PERFORMANCE OF THIS SOFTWARE. 20892 ***************************************************************************** */ 20893 20894 var __assign = function() { 20895 __assign = Object.assign || function __assign(t) { 20896 for (var s, i = 1, n = arguments.length; i < n; i++) { 20897 s = arguments[i]; 20898 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 20899 } 20900 return t; 20901 }; 20902 return __assign.apply(this, arguments); 20903 }; 20904 20905 var fullscreenSettings = { 20906 fullScreen: true, 20907 fullscreenPluginStrings: { 20908 toggleFullscreen: 'Toggle Fullscreen', 20909 }, 20910 }; 20911 20912 var FullScreen = /** @class */ (function () { 20913 function FullScreen(instance, $LG) { 20914 // get lightGallery core plugin instance 20915 this.core = instance;
20916 this.$LG = $LG; 20917 // extend module default settings with lightGallery core settings 20918 this.settings = __assign(__assign({}, fullscreenSettings), this.core.settings); 20919 return this; 20920 } 20921 FullScreen.prototype.init = function () { 20922 var fullScreen = ''; 20923 if (this.settings.fullScreen) { 20924 // check for fullscreen browser support 20925 if (!document.fullscreenEnabled && 20926 !document.webkitFullscreenEnabled && 20927 !document.mozFullScreenEnabled && 20928 !document.msFullscreenEnabled) { 20929 return; 20930 } 20931 else { 20932 fullScreen = "<button type=\"button\" aria-label=\"" + this.settings.fullscreenPluginStrings['toggleFullscreen'] + "\" class=\"lg-fullscreen lg-icon\"></button>"; 20933 this.core.$toolbar.append(fullScreen); 20934 this.fullScreen(); 20935 } 20936 } 20937 }; 20938 FullScreen.prototype.isFullScreen = function () { 20939 return (document.fullscreenElement || 20940 document.mozFullScreenElement || 20941 document.webkitFullscreenElement || 20942 document.msFullscreenElement); 20943 }; 20944 FullScreen.prototype.requestFullscreen = function () { 20945 var el = document.documentElement; 20946 if (el.requestFullscreen) { 20947 el.requestFullscreen(); 20948 } 20949 else if (el.msRequestFullscreen) { 20950 el.msRequestFullscreen(); 20951 } 20952 else if (el.mozRequestFullScreen) { 20953 el.mozRequestFullScreen(); 20954 } 20955 else if (el.webkitRequestFullscreen) { 20956 el.webkitRequestFullscreen(); 20957 } 20958 }; 20959 FullScreen.prototype.exitFullscreen = function () { 20960 if (document.exitFullscreen) { 20961 document.exitFullscreen(); 20962 } 20963 else if (document.msExitFullscreen) { 20964 document.msExitFullscreen(); 20965 } 20966 else if (document.mozCancelFullScreen) { 20967 document.mozCancelFullScreen(); 20968 } 20969 else if (document.webkitExitFullscreen) { 20970 document.webkitExitFullscreen(); 20971 } 20972 }; 20973 // https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Using_full_screen_mode 20974 FullScreen.prototype.fullScreen = function () { 20975 var _this = this; 20976 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 () { 20977 if (!_this.core.lgOpened) 20978 return; 20979 _this.core.outer.toggleClass('lg-fullscreen-on'); 20980 }); 20981 this.core.outer 20982 .find('.lg-fullscreen') 20983 .first() 20984 .on('click.lg', function () { 20985 if (_this.isFullScreen()) { 20986 _this.exitFullscreen(); 20987 } 20988 else { 20989 _this.requestFullscreen(); 20990 } 20991 }); 20992 }; 20993 FullScreen.prototype.closeGallery = function () { 20994 // exit from fullscreen if activated 20995 if (this.isFullScreen()) { 20996 this.exitFullscreen(); 20997 } 20998 }; 20999 FullScreen.prototype.destroy = function () { 21000 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); 21001 }; 21002 return FullScreen; 21003 }()); 21004 21005 return FullScreen; 21006 21007}))); 21008 21009/*! 21010 * lightgallery | 2.5.0 | June 13th 2022 21011 * http://www.lightgalleryjs.com/ 21012 * Copyright (c) 2020 Sachin Neravath; 21013 * @license GPLv3 21014 */ 21015 21016(function (global, factory) { 21017 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 21018 typeof define === 'function' && define.amd ? define(factory) : 21019 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lgHash = factory()); 21020}(this, (function () { 'use strict'; 21021 21022 /*! ***************************************************************************** 21023 Copyright (c) Microsoft Corporation. 21024 21025 Permission to use, copy, modify, and/or distribute this software for any 21026 purpose with or without fee is hereby granted. 21027 21028 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 21029 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 21030 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 21031 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 21032 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 21033 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 21034 PERFORMANCE OF THIS SOFTWARE. 21035 ***************************************************************************** */ 21036 21037 var __assign = function() { 21038 __assign = Object.assign || function __assign(t) { 21039 for (var s, i = 1, n = arguments.length; i < n; i++) { 21040 s = arguments[i]; 21041 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 21042 } 21043 return t; 21044 }; 21045 return __assign.apply(this, arguments); 21046 }; 21047 21048 /** 21049 * List of lightGallery events 21050 * All events should be documented here 21051 * Below interfaces are used to build the website documentations 21052 * */ 21053 var lGEvents = { 21054 afterAppendSlide: 'lgAfterAppendSlide', 21055 init: 'lgInit', 21056 hasVideo: 'lgHasVideo', 21057 containerResize: 'lgContainerResize', 21058 updateSlides: 'lgUpdateSlides', 21059 afterAppendSubHtml: 'lgAfterAppendSubHtml', 21060 beforeOpen: 'lgBeforeOpen', 21061 afterOpen: 'lgAfterOpen', 21062 slideItemLoad: 'lgSlideItemLoad', 21063 beforeSlide: 'lgBeforeSlide', 21064 afterSlide: 'lgAfterSlide', 21065 posterClick: 'lgPosterClick', 21066 dragStart: 'lgDragStart', 21067 dragMove: 'lgDragMove', 21068 dragEnd: 'lgDragEnd', 21069 beforeNextSlide: 'lgBeforeNextSlide', 21070 beforePrevSlide: 'lgBeforePrevSlide', 21071 beforeClose: 'lgBeforeClose', 21072 afterClose: 'lgAfterClose', 21073 rotateLeft: 'lgRotateLeft', 21074 rotateRight: 'lgRotateRight', 21075 flipHorizontal: 'lgFlipHorizontal', 21076 flipVertical: 'lgFlipVertical', 21077 autoplay: 'lgAutoplay', 21078 autoplayStart: 'lgAutoplayStart', 21079 autoplayStop: 'lgAutoplayStop', 21080 }; 21081 21082 var hashSettings = { 21083 hash: true, 21084 galleryId: '1', 21085 customSlideName: false, 21086 }; 21087 21088 var Hash = /** @class */ (function () { 21089 function Hash(instance, $LG) { 21090 // get lightGallery core plugin instance 21091 this.core = instance;
21092 this.$LG = $LG; 21093 // extend module default settings with lightGallery core settings 21094 this.settings = __assign(__assign({}, hashSettings), this.core.settings); 21095 return this; 21096 } 21097 Hash.prototype.init = function () { 21098 var _this = this; 21099 if (!this.settings.hash) { 21100 return; 21101 } 21102 this.oldHash = window.location.hash; 21103 setTimeout(function () { 21104 _this.buildFromHash(); 21105 }, 100); 21106 // Change hash value on after each slide transition 21107 this.core.LGel.on(lGEvents.afterSlide + ".hash", this.onAfterSlide.bind(this)); 21108 this.core.LGel.on(lGEvents.afterClose + ".hash", this.onCloseAfter.bind(this)); 21109 // Listen hash change and change the slide according to slide value 21110 this.$LG(window).on("hashchange.lg.hash.global" + this.core.lgId, this.onHashchange.bind(this)); 21111 }; 21112 Hash.prototype.onAfterSlide = function (event) { 21113 var slideName = this.core.galleryItems[event.detail.index].slideName; 21114 slideName = this.settings.customSlideName 21115 ? slideName || event.detail.index 21116 : event.detail.index; 21117 if (history.replaceState) { 21118 history.replaceState(null, '', window.location.pathname + 21119 window.location.search + 21120 '#lg=' + 21121 this.settings.galleryId + 21122 '&slide=' + 21123 slideName); 21124 } 21125 else { 21126 window.location.hash = 21127 'lg=' + this.settings.galleryId + '&slide=' + slideName; 21128 } 21129 }; 21130 /** 21131 * Get index of the slide from custom slideName. Has to be a public method. Used in hash plugin 21132 * @param {String} hash 21133 * @returns {Number} Index of the slide. 21134 */ 21135 Hash.prototype.getIndexFromUrl = function (hash) { 21136 if (hash === void 0) { hash = window.location.hash; } 21137 var slideName = hash.split('&slide=')[1]; 21138 var _idx = 0; 21139 if (this.settings.customSlideName) { 21140 for (var index = 0; index < this.core.galleryItems.length; index++) { 21141 var dynamicEl = this.core.galleryItems[index]; 21142 if (dynamicEl.slideName === slideName) { 21143 _idx = index; 21144 break; 21145 } 21146 } 21147 } 21148 else { 21149 _idx = parseInt(slideName, 10); 21150 } 21151 return isNaN(_idx) ? 0 : _idx; 21152 }; 21153 // Build Gallery if gallery id exist in the URL 21154 Hash.prototype.buildFromHash = function () { 21155 // if dynamic option is enabled execute immediately 21156 var _hash = window.location.hash; 21157 //Uncode edit ##START## 21158 // if (_hash.indexOf('lg=' + this.settings.galleryId) > 0) { 21159 if (_hash.indexOf('lg=' + this.settings.galleryId + '&') > 0) { 21160 //Uncode edit ##END## 21161 // This class is used to remove the initial animation if galleryId present in the URL 21162 this.$LG(document.body).addClass('lg-from-hash'); 21163 var index = this.getIndexFromUrl(_hash); 21164 this.core.openGallery(index); 21165 return true; 21166 } 21167 }; 21168 Hash.prototype.onCloseAfter = function () { 21169 // Reset to old hash value 21170 if (this.oldHash && 21171 this.oldHash.indexOf('lg=' + this.settings.galleryId) < 0) { 21172 if (history.replaceState) { 21173 history.replaceState(null, '', this.oldHash); 21174 } 21175 else { 21176 window.location.hash = this.oldHash; 21177 } 21178 } 21179 else { 21180 if (history.replaceState) { 21181 history.replaceState(null, document.title, window.location.pathname + window.location.search); 21182 } 21183 else { 21184 window.location.hash = ''; 21185 } 21186 } 21187 }; 21188 Hash.prototype.onHashchange = function () { 21189 if (!this.core.lgOpened) 21190 return; 21191 var _hash = window.location.hash; 21192 var index = this.getIndexFromUrl(_hash); 21193 // it galleryId doesn't exist in the url close the gallery 21194 if (_hash.indexOf('lg=' + this.settings.galleryId) > -1) { 21195 this.core.slide(index, false, false); 21196 } 21197 else if (this.core.lGalleryOn) { 21198 this.core.closeGallery(); 21199 } 21200 }; 21201 Hash.prototype.closeGallery = function () { 21202 if (this.settings.hash) { 21203 this.$LG(document.body).removeClass('lg-from-hash'); 21204 } 21205 }; 21206 Hash.prototype.destroy = function () { 21207 this.core.LGel.off('.lg.hash'); 21208 this.core.LGel.off('.hash'); 21209 this.$LG(window).off("hashchange.lg.hash.global" + this.core.lgId); 21210 }; 21211 return Hash; 21212 }()); 21213 21214 return Hash; 21215 21216}))); 21217/*! 21218 * lightgallery | 2.5.0 | June 13th 2022 21219 * http://www.lightgalleryjs.com/ 21220 * Copyright (c) 2020 Sachin Neravath; 21221 * @license GPLv3 21222 */ 21223 21224(function (global, factory) { 21225 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 21226 typeof define === 'function' && define.amd ? define(factory) : 21227 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lgShare = factory()); 21228}(this, (function () { 'use strict'; 21229 21230 /*! ***************************************************************************** 21231 Copyright (c) Microsoft Corporation. 21232 21233 Permission to use, copy, modify, and/or distribute this software for any 21234 purpose with or without fee is hereby granted. 21235 21236 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 21237 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 21238 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 21239 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 21240 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 21241 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 21242 PERFORMANCE OF THIS SOFTWARE. 21243 ***************************************************************************** */ 21244 21245 var __assign = function() { 21246 __assign = Object.assign || function __assign(t) { 21247 for (var s, i = 1, n = arguments.length; i < n; i++) { 21248 s = arguments[i]; 21249 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 21250 } 21251 return t; 21252 }; 21253 return __assign.apply(this, arguments); 21254 }; 21255 21256 function __spreadArrays() { 21257 for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; 21258 for (var r = Array(s), k = 0, i = 0; i < il; i++) 21259 for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) 21260 r[k] = a[j]; 21261 return r; 21262 } 21263 21264 var shareSettings = { 21265 share: true, 21266 facebook: true, 21267 facebookDropdownText: 'Facebook', 21268 twitter: true, 21269 twitterDropdownText: 'Twitter', 21270 pinterest: true, 21271 pinterestDropdownText: 'Pinterest', 21272 additionalShareOptions: [], 21273 sharePluginStrings: { share: 'Share' }, 21274 }; 21275 21276 function getFacebookShareLink(galleryItem) { 21277 var facebookBaseUrl = '//www.facebook.com/sharer/sharer.php?u='; 21278 return (facebookBaseUrl + 21279 encodeURIComponent(galleryItem.facebookShareUrl || window.location.href)); 21280 } 21281 21282 function getTwitterShareLink(galleryItem) { 21283 var twitterBaseUrl = '//twitter.com/intent/tweet?text='; 21284 var url = encodeURIComponent(galleryItem.twitterShareUrl || window.location.href); 21285 var text = galleryItem.tweetText;
21286 return twitterBaseUrl + text + '&url=' + url; 21287 } 21288 21289 function getPinterestShareLink(galleryItem) { 21290 var pinterestBaseUrl = 'http://www.pinterest.com/pin/create/button/?url='; 21291 var description = galleryItem.pinterestText; 21292 var media = encodeURIComponent(galleryItem.src); 21293 var url = encodeURIComponent(galleryItem.pinterestShareUrl || window.location.href); 21294 return (pinterestBaseUrl + 21295 url + 21296 '&media=' + 21297 media + 21298 '&description=' + 21299 description); 21300 } 21301 21302 /** 21303 * List of lightGallery events 21304 * All events should be documented here 21305 * Below interfaces are used to build the website documentations 21306 * */ 21307 var lGEvents = { 21308 afterAppendSlide: 'lgAfterAppendSlide', 21309 init: 'lgInit', 21310 hasVideo: 'lgHasVideo', 21311 containerResize: 'lgContainerResize', 21312 updateSlides: 'lgUpdateSlides', 21313 afterAppendSubHtml: 'lgAfterAppendSubHtml', 21314 beforeOpen: 'lgBeforeOpen', 21315 afterOpen: 'lgAfterOpen', 21316 slideItemLoad: 'lgSlideItemLoad', 21317 beforeSlide: 'lgBeforeSlide', 21318 afterSlide: 'lgAfterSlide', 21319 posterClick: 'lgPosterClick', 21320 dragStart: 'lgDragStart', 21321 dragMove: 'lgDragMove', 21322 dragEnd: 'lgDragEnd', 21323 beforeNextSlide: 'lgBeforeNextSlide', 21324 beforePrevSlide: 'lgBeforePrevSlide', 21325 beforeClose: 'lgBeforeClose', 21326 afterClose: 'lgAfterClose', 21327 rotateLeft: 'lgRotateLeft', 21328 rotateRight: 'lgRotateRight', 21329 flipHorizontal: 'lgFlipHorizontal', 21330 flipVertical: 'lgFlipVertical', 21331 autoplay: 'lgAutoplay', 21332 autoplayStart: 'lgAutoplayStart', 21333 autoplayStop: 'lgAutoplayStop', 21334 }; 21335 21336 var Share = /** @class */ (function () { 21337 function Share(instance) { 21338 this.shareOptions = []; 21339 // get lightGallery core plugin instance 21340 this.core = instance; 21341 // extend module default settings with lightGallery core settings 21342 this.settings = __assign(__assign({}, shareSettings), this.core.settings); 21343 return this; 21344 } 21345 Share.prototype.init = function () { 21346 if (!this.settings.share) { 21347 return; 21348 } 21349 this.shareOptions = __spreadArrays(this.getDefaultShareOptions(), this.settings.additionalShareOptions); 21350 this.setLgShareMarkup(); 21351 this.core.outer 21352 .find('.lg-share .lg-dropdown') 21353 .append(this.getShareListHtml()); 21354 this.core.LGel.on(lGEvents.afterSlide + ".share", this.onAfterSlide.bind(this)); 21355 }; 21356 Share.prototype.getShareListHtml = function () { 21357 var shareHtml = ''; 21358 this.shareOptions.forEach(function (shareOption) { 21359 shareHtml += shareOption.dropdownHTML; 21360 }); 21361 return shareHtml; 21362 }; 21363 Share.prototype.setLgShareMarkup = function () { 21364 var _this = this; 21365 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>"); 21366 this.core.outer.append('<div class="lg-dropdown-overlay"></div>'); 21367 var $shareButton = this.core.outer.find('.lg-share'); 21368 $shareButton.first().on('click.lg', function () { 21369 _this.core.outer.toggleClass('lg-dropdown-active'); 21370 if (_this.core.outer.hasClass('lg-dropdown-active')) { 21371 _this.core.outer.attr('aria-expanded', true); 21372 } 21373 else { 21374 _this.core.outer.attr('aria-expanded', false); 21375 } 21376 }); 21377 this.core.outer 21378 .find('.lg-dropdown-overlay') 21379 .first() 21380 .on('click.lg', function () { 21381 _this.core.outer.removeClass('lg-dropdown-active'); 21382 _this.core.outer.attr('aria-expanded', false); 21383 }); 21384 }; 21385 Share.prototype.onAfterSlide = function (event) { 21386 var _this = this; 21387 var index = event.detail.index; 21388 var currentItem = this.core.galleryItems[index]; 21389 setTimeout(function () { 21390 _this.shareOptions.forEach(function (shareOption) { 21391 var selector = shareOption.selector; 21392 _this.core.outer 21393 .find(selector) 21394 .attr('href', shareOption.generateLink(currentItem)); 21395 }); 21396 }, 100); 21397 }; 21398 Share.prototype.getShareListItemHTML = function (type, text) { 21399 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>"; 21400 }; 21401 Share.prototype.getDefaultShareOptions = function () { 21402 return __spreadArrays((this.settings.facebook 21403 ? [ 21404 { 21405 type: 'facebook', 21406 generateLink: getFacebookShareLink,
21407 dropdownHTML: this.getShareListItemHTML('facebook', this.settings.facebookDropdownText), 21408 selector: '.lg-share-facebook', 21409 }, 21410 ] 21411 : []), (this.settings.twitter 21412 ? [ 21413 { 21414 type: 'twitter', 21415 generateLink: getTwitterShareLink, 21416 dropdownHTML: this.getShareListItemHTML('twitter', this.settings.twitterDropdownText), 21417 selector: '.lg-share-twitter', 21418 }, 21419 ] 21420 : []), (this.settings.pinterest 21421 ? [ 21422 { 21423 type: 'pinterest', 21424 generateLink: getPinterestShareLink, 21425 dropdownHTML: this.getShareListItemHTML('pinterest', this.settings.pinterestDropdownText), 21426 selector: '.lg-share-pinterest', 21427 }, 21428 ] 21429 : [])); 21430 }; 21431 Share.prototype.destroy = function () { 21432 this.core.outer.find('.lg-dropdown-overlay').remove(); 21433 this.core.outer.find('.lg-share').remove(); 21434 this.core.LGel.off('.lg.share'); 21435 this.core.LGel.off('.share'); 21436 }; 21437 return Share; 21438 }()); 21439 21440 return Share; 21441 21442}))); 21443/*! 21444 * lightgallery | 2.5.0 | June 13th 2022 21445 * http://www.lightgalleryjs.com/ 21446 * Copyright (c) 2020 Sachin Neravath; 21447 * @license GPLv3 21448 */ 21449 21450(function (global, factory) { 21451 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 21452 typeof define === 'function' && define.amd ? define(factory) : 21453 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lgThumbnail = factory()); 21454}(this, (function () { 'use strict'; 21455 21456 /*! ***************************************************************************** 21457 Copyright (c) Microsoft Corporation. 21458 21459 Permission to use, copy, modify, and/or distribute this software for any 21460 purpose with or without fee is hereby granted. 21461 21462 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 21463 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 21464 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 21465 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 21466 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 21467 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 21468 PERFORMANCE OF THIS SOFTWARE. 21469 ***************************************************************************** */ 21470 21471 var __assign = function() { 21472 __assign = Object.assign || function __assign(t) { 21473 for (var s, i = 1, n = arguments.length; i < n; i++) { 21474 s = arguments[i]; 21475 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 21476 } 21477 return t; 21478 }; 21479 return __assign.apply(this, arguments); 21480 }; 21481 21482 var thumbnailsSettings = { 21483 thumbnail: true, 21484 animateThumb: true, 21485 currentPagerPosition: 'middle', 21486 alignThumbnails: 'middle', 21487 thumbWidth: 100, 21488 thumbHeight: '80px', 21489 thumbMargin: 5, 21490 appendThumbnailsTo: '.lg-components', 21491 toggleThumb: false, 21492 enableThumbDrag: true, 21493 enableThumbSwipe: true, 21494 thumbnailSwipeThreshold: 10, 21495 loadYouTubeThumbnail: true, 21496 youTubeThumbSize: 1, 21497 thumbnailPluginStrings: { 21498 toggleThumbnails: 'Toggle thumbnails', 21499 }, 21500 }; 21501 21502 /** 21503 * List of lightGallery events 21504 * All events should be documented here 21505 * Below interfaces are used to build the website documentations 21506 * */ 21507 var lGEvents = { 21508 afterAppendSlide: 'lgAfterAppendSlide', 21509 init: 'lgInit', 21510 hasVideo: 'lgHasVideo', 21511 containerResize: 'lgContainerResize', 21512 updateSlides: 'lgUpdateSlides', 21513 afterAppendSubHtml: 'lgAfterAppendSubHtml', 21514 beforeOpen: 'lgBeforeOpen', 21515 afterOpen: 'lgAfterOpen', 21516 slideItemLoad: 'lgSlideItemLoad', 21517 beforeSlide: 'lgBeforeSlide', 21518 afterSlide: 'lgAfterSlide', 21519 posterClick: 'lgPosterClick', 21520 dragStart: 'lgDragStart', 21521 dragMove: 'lgDragMove', 21522 dragEnd: 'lgDragEnd', 21523 beforeNextSlide: 'lgBeforeNextSlide', 21524 beforePrevSlide: 'lgBeforePrevSlide', 21525 beforeClose: 'lgBeforeClose', 21526 afterClose: 'lgAfterClose', 21527 rotateLeft: 'lgRotateLeft', 21528 rotateRight: 'lgRotateRight', 21529 flipHorizontal: 'lgFlipHorizontal', 21530 flipVertical: 'lgFlipVertical', 21531 autoplay: 'lgAutoplay', 21532 autoplayStart: 'lgAutoplayStart', 21533 autoplayStop: 'lgAutoplayStop', 21534 }; 21535 21536 var Thumbnail = /** @class */ (function () { 21537 function Thumbnail(instance, $LG) { 21538 this.thumbOuterWidth = 0; 21539 this.thumbTotalWidth = 0; 21540 this.translateX = 0; 21541 this.thumbClickable = false;
21542 // get lightGallery core plugin instance 21543 this.core = instance; 21544 this.$LG = $LG; 21545 return this; 21546 } 21547 Thumbnail.prototype.init = function () { 21548 // extend module default settings with lightGallery core settings 21549 this.settings = __assign(__assign({}, thumbnailsSettings), this.core.settings); 21550 this.thumbOuterWidth = 0; 21551 this.thumbTotalWidth = 21552 this.core.galleryItems.length * 21553 (this.settings.thumbWidth + this.settings.thumbMargin); 21554 // Thumbnail animation value 21555 this.translateX = 0; 21556 this.setAnimateThumbStyles(); 21557 if (!this.core.settings.allowMediaOverlap) { 21558 this.settings.toggleThumb = false; 21559 } 21560 if (this.settings.thumbnail) { 21561 this.build(); 21562 if (this.settings.animateThumb) { 21563 if (this.settings.enableThumbDrag) { 21564 this.enableThumbDrag(); 21565 } 21566 if (this.settings.enableThumbSwipe) { 21567 this.enableThumbSwipe(); 21568 } 21569 this.thumbClickable = false; 21570 } 21571 else { 21572 this.thumbClickable = true; 21573 } 21574 this.toggleThumbBar(); 21575 this.thumbKeyPress(); 21576 } 21577 }; 21578 Thumbnail.prototype.build = function () { 21579 var _this = this; 21580 this.setThumbMarkup(); 21581 this.manageActiveClassOnSlideChange(); 21582 this.$lgThumb.first().on('click.lg touchend.lg', function (e) { 21583 var $target = _this.$LG(e.target); 21584 if (!$target.hasAttribute('data-lg-item-id')) { 21585 return; 21586 } 21587 setTimeout(function () { 21588 // In IE9 and bellow touch does not support 21589 // Go to slide if browser does not support css transitions 21590 if (_this.thumbClickable && !_this.core.lgBusy) { 21591 var index = parseInt($target.attr('data-lg-item-id')); 21592 _this.core.slide(index, false, true, false); 21593 } 21594 }, 50); 21595 }); 21596 //Uncode edit ##START## 21597 // this.core.LGel.on(lGEvents.beforeSlide + ".thumb", function (event) { 21598 this.core.LGel.on(lGEvents.beforeSlide, function (event) { 21599 //Uncode edit ##END## 21600 var index = event.detail.index; 21601 _this.animateThumb(index); 21602 }); 21603 //Uncode edit ##START## 21604 // this.core.LGel.on(lGEvents.beforeOpen + ".thumb", function () { 21605 this.core.LGel.on(lGEvents.beforeOpen, function () { 21606 //Uncode edit ##END## 21607 _this.thumbOuterWidth = _this.core.outer.get().offsetWidth; 21608 }); 21609 //Uncode edit ##START## 21610 // this.core.LGel.on(lGEvents.updateSlides + ".thumb", function () { 21611 this.core.LGel.on(lGEvents.updateSlides, function () { 21612 //Uncode edit ##END## 21613 _this.rebuildThumbnails(); 21614 }); 21615 //Uncode edit ##START## 21616 // this.core.LGel.on(lGEvents.containerResize + ".thumb", function () { 21617 this.core.LGel.on(lGEvents.containerResize, function () { 21618 //Uncode edit ##END## 21619 if (!_this.core.lgOpened) 21620 return; 21621 setTimeout(function () { 21622 _this.thumbOuterWidth = _this.core.outer.get().offsetWidth; 21623 _this.animateThumb(_this.core.index); 21624 _this.thumbOuterWidth = _this.core.outer.get().offsetWidth; 21625 }, 50); 21626 }); 21627 }; 21628 Thumbnail.prototype.setThumbMarkup = function () { 21629 var thumbOuterClassNames = 'lg-thumb-outer '; 21630 if (this.settings.alignThumbnails) { 21631 thumbOuterClassNames += "lg-thumb-align-" + this.settings.alignThumbnails; 21632 } 21633 var html = "<div class=\"" + thumbOuterClassNames + "\">\n <div class=\"lg-thumb lg-group\">\n </div>\n </div>"; 21634 this.core.outer.addClass('lg-has-thumb'); 21635 if (this.settings.appendThumbnailsTo === '.lg-components') { 21636 this.core.$lgComponents.append(html); 21637 } 21638 else { 21639 this.core.outer.append(html); 21640 } 21641 this.$thumbOuter = this.core.outer.find('.lg-thumb-outer').first(); 21642 this.$lgThumb = this.core.outer.find('.lg-thumb').first(); 21643 if (this.settings.animateThumb) { 21644 this.core.outer 21645 .find('.lg-thumb') 21646 .css('transition-duration', this.core.settings.speed + 'ms') 21647 .css('width', this.thumbTotalWidth + 'px') 21648 .css('position', 'relative'); 21649 } 21650 this.setThumbItemHtml(this.core.galleryItems); 21651 }; 21652 Thumbnail.prototype.enableThumbDrag = function () { 21653 var _this = this; 21654 var thumbDragUtils = { 21655 cords: { 21656 startX: 0, 21657 endX: 0, 21658 }, 21659 isMoved: false, 21660 newTranslateX: 0, 21661 startTime: new Date(), 21662 endTime: new Date(), 21663 touchMoveTime: 0, 21664 }; 21665 var isDragging = false;
21666 this.$thumbOuter.addClass('lg-grab'); 21667 this.core.outer 21668 .find('.lg-thumb') 21669 .first() 21670 .on('mousedown.lg.thumb', function (e) { 21671 if (_this.thumbTotalWidth > _this.thumbOuterWidth) { 21672 // execute only on .lg-object 21673 e.preventDefault(); 21674 thumbDragUtils.cords.startX = e.pageX; 21675 thumbDragUtils.startTime = new Date(); 21676 _this.thumbClickable = false; 21677 isDragging = true; 21678 // ** Fix for webkit cursor issue https://code.google.com/p/chromium/issues/detail?id=26723 21679 _this.core.outer.get().scrollLeft += 1; 21680 _this.core.outer.get().scrollLeft -= 1; 21681 // * 21682 _this.$thumbOuter 21683 .removeClass('lg-grab') 21684 .addClass('lg-grabbing'); 21685 } 21686 }); 21687 this.$LG(window).on("mousemove.lg.thumb.global" + this.core.lgId, function (e) { 21688 if (!_this.core.lgOpened) 21689 return; 21690 if (isDragging) { 21691 thumbDragUtils.cords.endX = e.pageX; 21692 thumbDragUtils = _this.onThumbTouchMove(thumbDragUtils); 21693 } 21694 }); 21695 this.$LG(window).on("mouseup.lg.thumb.global" + this.core.lgId, function () { 21696 if (!_this.core.lgOpened) 21697 return; 21698 if (thumbDragUtils.isMoved) { 21699 thumbDragUtils = _this.onThumbTouchEnd(thumbDragUtils); 21700 } 21701 else { 21702 _this.thumbClickable = true; 21703 } 21704 if (isDragging) { 21705 isDragging = false; 21706 _this.$thumbOuter.removeClass('lg-grabbing').addClass('lg-grab'); 21707 } 21708 }); 21709 }; 21710 Thumbnail.prototype.enableThumbSwipe = function () { 21711 var _this = this; 21712 var thumbDragUtils = { 21713 cords: { 21714 startX: 0, 21715 endX: 0, 21716 }, 21717 isMoved: false, 21718 newTranslateX: 0, 21719 startTime: new Date(), 21720 endTime: new Date(), 21721 touchMoveTime: 0, 21722 }; 21723 this.$lgThumb.on('touchstart.lg', function (e) { 21724 if (_this.thumbTotalWidth > _this.thumbOuterWidth) { 21725 e.preventDefault(); 21726 thumbDragUtils.cords.startX = e.targetTouches[0].pageX; 21727 _this.thumbClickable = false; 21728 thumbDragUtils.startTime = new Date(); 21729 } 21730 }); 21731 this.$lgThumb.on('touchmove.lg', function (e) { 21732 if (_this.thumbTotalWidth > _this.thumbOuterWidth) { 21733 e.preventDefault(); 21734 thumbDragUtils.cords.endX = e.targetTouches[0].pageX; 21735 thumbDragUtils = _this.onThumbTouchMove(thumbDragUtils); 21736 } 21737 }); 21738 this.$lgThumb.on('touchend.lg', function () { 21739 if (thumbDragUtils.isMoved) { 21740 thumbDragUtils = _this.onThumbTouchEnd(thumbDragUtils); 21741 } 21742 else { 21743 _this.thumbClickable = true; 21744 } 21745 }); 21746 }; 21747 // Rebuild thumbnails 21748 Thumbnail.prototype.rebuildThumbnails = function () { 21749 var _this = this; 21750 // Remove transitions 21751 this.$thumbOuter.addClass('lg-rebuilding-thumbnails'); 21752 setTimeout(function () { 21753 _this.thumbTotalWidth = 21754 _this.core.galleryItems.length * 21755 (_this.settings.thumbWidth + _this.settings.thumbMargin); 21756 _this.$lgThumb.css('width', _this.thumbTotalWidth + 'px'); 21757 _this.$lgThumb.empty(); 21758 _this.setThumbItemHtml(_this.core.galleryItems); 21759 _this.animateThumb(_this.core.index); 21760 }, 50); 21761 setTimeout(function () { 21762 _this.$thumbOuter.removeClass('lg-rebuilding-thumbnails'); 21763 }, 200); 21764 }; 21765 // @ts-check 21766 Thumbnail.prototype.setTranslate = function (value) { 21767 this.$lgThumb.css('transform', 'translate3d(-' + value + 'px, 0px, 0px)'); 21768 }; 21769 Thumbnail.prototype.getPossibleTransformX = function (left) { 21770 if (left > this.thumbTotalWidth - this.thumbOuterWidth) { 21771 left = this.thumbTotalWidth - this.thumbOuterWidth; 21772 } 21773 if (left < 0) { 21774 left = 0; 21775 } 21776 return left; 21777 }; 21778 Thumbnail.prototype.animateThumb = function (index) { 21779 this.$lgThumb.css('transition-duration', this.core.settings.speed + 'ms'); 21780 if (this.settings.animateThumb) { 21781 var position = 0; 21782 switch (this.settings.currentPagerPosition) { 21783 case 'left': 21784 position = 0; 21785 break; 21786 case 'middle': 21787 position = 21788 this.thumbOuterWidth / 2 - this.settings.thumbWidth / 2; 21789 break; 21790 case 'right': 21791 position = this.thumbOuterWidth - this.settings.thumbWidth; 21792 } 21793 this.translateX = 21794 (this.settings.thumbWidth + this.settings.thumbMargin) * index - 21795 1 - 21796 position; 21797 if (this.translateX > this.thumbTotalWidth - this.thumbOuterWidth) { 21798 this.translateX = this.thumbTotalWidth - this.thumbOuterWidth; 21799 } 21800 if (this.translateX < 0) { 21801 this.translateX = 0; 21802 } 21803 this.setTranslate(this.translateX); 21804 } 21805 };
21806 Thumbnail.prototype.onThumbTouchMove = function (thumbDragUtils) { 21807 thumbDragUtils.newTranslateX = this.translateX; 21808 thumbDragUtils.isMoved = true; 21809 thumbDragUtils.touchMoveTime = new Date().valueOf(); 21810 thumbDragUtils.newTranslateX -= 21811 thumbDragUtils.cords.endX - thumbDragUtils.cords.startX; 21812 thumbDragUtils.newTranslateX = this.getPossibleTransformX(thumbDragUtils.newTranslateX); 21813 // move current slide 21814 this.setTranslate(thumbDragUtils.newTranslateX); 21815 this.$thumbOuter.addClass('lg-dragging'); 21816 return thumbDragUtils; 21817 }; 21818 Thumbnail.prototype.onThumbTouchEnd = function (thumbDragUtils) { 21819 thumbDragUtils.isMoved = false; 21820 thumbDragUtils.endTime = new Date(); 21821 this.$thumbOuter.removeClass('lg-dragging'); 21822 var touchDuration = thumbDragUtils.endTime.valueOf() - 21823 thumbDragUtils.startTime.valueOf(); 21824 var distanceXnew = thumbDragUtils.cords.endX - thumbDragUtils.cords.startX; 21825 var speedX = Math.abs(distanceXnew) / touchDuration; 21826 // Some magical numbers 21827 // Can be improved 21828 if (speedX > 0.15 && 21829 thumbDragUtils.endTime.valueOf() - thumbDragUtils.touchMoveTime < 30) { 21830 speedX += 1; 21831 if (speedX > 2) { 21832 speedX += 1; 21833 } 21834 speedX = 21835 speedX + 21836 speedX * (Math.abs(distanceXnew) / this.thumbOuterWidth); 21837 this.$lgThumb.css('transition-duration', Math.min(speedX - 1, 2) + 'settings'); 21838 distanceXnew = distanceXnew * speedX; 21839 this.translateX = this.getPossibleTransformX(this.translateX - distanceXnew); 21840 this.setTranslate(this.translateX); 21841 } 21842 else { 21843 this.translateX = thumbDragUtils.newTranslateX; 21844 } 21845 if (Math.abs(thumbDragUtils.cords.endX - thumbDragUtils.cords.startX) < 21846 this.settings.thumbnailSwipeThreshold) { 21847 this.thumbClickable = true; 21848 } 21849 return thumbDragUtils; 21850 }; 21851 Thumbnail.prototype.getThumbHtml = function (thumb, index) { 21852 var slideVideoInfo = this.core.galleryItems[index].__slideVideoInfo || {}; 21853 var thumbImg; 21854 if (slideVideoInfo.youtube) { 21855 if (this.settings.loadYouTubeThumbnail) { 21856 thumbImg = 21857 '//img.youtube.com/vi/' + 21858 slideVideoInfo.youtube[1] + 21859 '/' + 21860 this.settings.youTubeThumbSize + 21861 '.jpg'; 21862 } 21863 else { 21864 thumbImg = thumb; 21865 } 21866 } 21867 else { 21868 thumbImg = thumb; 21869 } 21870 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>"; 21871 }; 21872 Thumbnail.prototype.getThumbItemHtml = function (items) { 21873 var thumbList = ''; 21874 for (var i = 0; i < items.length; i++) { 21875 thumbList += this.getThumbHtml(items[i].thumb, i); 21876 } 21877 return thumbList; 21878 }; 21879 Thumbnail.prototype.setThumbItemHtml = function (items) { 21880 var thumbList = this.getThumbItemHtml(items); 21881 this.$lgThumb.html(thumbList); 21882 }; 21883 Thumbnail.prototype.setAnimateThumbStyles = function () { 21884 if (this.settings.animateThumb) { 21885 this.core.outer.addClass('lg-animate-thumb'); 21886 } 21887 }; 21888 // Manage thumbnail active calss
21889 Thumbnail.prototype.manageActiveClassOnSlideChange = function () { 21890 var _this = this; 21891 // manage active class for thumbnail 21892 //Uncode edit ##START## 21893 // this.core.LGel.on(lGEvents.beforeSlide + ".thumb", function (event) { 21894 this.core.LGel.on(lGEvents.beforeSlide, function (event) { 21895 //Uncode edit ##END## 21896 var $thumb = _this.core.outer.find('.lg-thumb-item'); 21897 var index = event.detail.index; 21898 $thumb.removeClass('active'); 21899 $thumb.eq(index).addClass('active'); 21900 }); 21901 }; 21902 // Toggle thumbnail bar 21903 Thumbnail.prototype.toggleThumbBar = function () { 21904 var _this = this; 21905 if (this.settings.toggleThumb) { 21906 this.core.outer.addClass('lg-can-toggle'); 21907 this.core.$toolbar.append('<button type="button" aria-label="' + 21908 this.settings.thumbnailPluginStrings['toggleThumbnails'] + 21909 '" class="lg-toggle-thumb lg-icon"></button>'); 21910 this.core.outer 21911 .find('.lg-toggle-thumb') 21912 .first() 21913 .on('click.lg', function () { 21914 _this.core.outer.toggleClass('lg-components-open'); 21915 }); 21916 } 21917 }; 21918 Thumbnail.prototype.thumbKeyPress = function () { 21919 var _this = this; 21920 this.$LG(window).on("keydown.lg.thumb.global" + this.core.lgId, function (e) { 21921 if (!_this.core.lgOpened || !_this.settings.toggleThumb) 21922 return; 21923 if (e.keyCode === 38) { 21924 e.preventDefault(); 21925 _this.core.outer.addClass('lg-components-open'); 21926 } 21927 else if (e.keyCode === 40) { 21928 e.preventDefault(); 21929 _this.core.outer.removeClass('lg-components-open'); 21930 } 21931 }); 21932 }; 21933 Thumbnail.prototype.destroy = function () { 21934 if (this.settings.thumbnail) { 21935 this.$LG(window).off(".lg.thumb.global" + this.core.lgId); 21936 this.core.LGel.off('.lg.thumb'); 21937 this.core.LGel.off('.thumb'); 21938 this.$thumbOuter.remove(); 21939 this.core.outer.removeClass('lg-has-thumb'); 21940 } 21941 }; 21942 return Thumbnail; 21943 }()); 21944 21945 return Thumbnail; 21946 21947}))); 21948/*! 21949 * lightgallery | 2.5.0 | June 13th 2022 21950 * http://www.lightgalleryjs.com/ 21951 * Copyright (c) 2020 Sachin Neravath; 21952 * @license GPLv3 21953 */ 21954 21955(function (global, factory) { 21956 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 21957 typeof define === 'function' && define.amd ? define(factory) : 21958 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lgVideo = factory()); 21959}(this, (function () { 'use strict'; 21960 21961 /*! ***************************************************************************** 21962 Copyright (c) Microsoft Corporation. 21963 21964 Permission to use, copy, modify, and/or distribute this software for any 21965 purpose with or without fee is hereby granted. 21966 21967 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 21968 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 21969 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 21970 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 21971 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 21972 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 21973 PERFORMANCE OF THIS SOFTWARE. 21974 ***************************************************************************** */ 21975 21976 var __assign = function() { 21977 __assign = Object.assign || function __assign(t) { 21978 for (var s, i = 1, n = arguments.length; i < n; i++) { 21979 s = arguments[i]; 21980 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 21981 } 21982 return t; 21983 }; 21984 return __assign.apply(this, arguments); 21985 }; 21986 21987 var videoSettings = { 21988 autoplayFirstVideo: true, 21989 youTubePlayerParams: false, 21990 vimeoPlayerParams: false, 21991 wistiaPlayerParams: false, 21992 gotoNextSlideOnVideoEnd: true, 21993 autoplayVideoOnSlide: false, 21994 videojs: false, 21995 videojsTheme: '', 21996 videojsOptions: {}, 21997 }; 21998 21999 /** 22000 * List of lightGallery events 22001 * All events should be documented here 22002 * Below interfaces are used to build the website documentations 22003 * */ 22004 var lGEvents = { 22005 afterAppendSlide: 'lgAfterAppendSlide', 22006 init: 'lgInit', 22007 hasVideo: 'lgHasVideo', 22008 containerResize: 'lgContainerResize', 22009 updateSlides: 'lgUpdateSlides', 22010 afterAppendSubHtml: 'lgAfterAppendSubHtml', 22011 beforeOpen: 'lgBeforeOpen', 22012 afterOpen: 'lgAfterOpen', 22013 slideItemLoad: 'lgSlideItemLoad', 22014 beforeSlide: 'lgBeforeSlide', 22015 afterSlide: 'lgAfterSlide', 22016 posterClick: 'lgPosterClick', 22017 dragStart: 'lgDragStart', 22018 dragMove: 'lgDragMove', 22019 dragEnd: 'lgDragEnd', 22020 beforeNextSlide: 'lgBeforeNextSlide', 22021 beforePrevSlide: 'lgBeforePrevSlide', 22022 beforeClose: 'lgBeforeClose', 22023 afterClose: 'lgAfterClose', 22024 rotateLeft: 'lgRotateLeft', 22025 rotateRight: 'lgRotateRight', 22026 flipHorizontal: 'lgFlipHorizontal', 22027 flipVertical: 'lgFlipVertical', 22028 autoplay: 'lgAutoplay', 22029 autoplayStart: 'lgAutoplayStart', 22030 autoplayStop: 'lgAutoplayStop', 22031 }; 22032 22033 var param = function (obj) { 22034 return Object.keys(obj) 22035 .map(function (k) { 22036 return encodeURIComponent(k) + '=' + encodeURIComponent(obj[k]); 22037 }) 22038 .join('&'); 22039 }; 22040 var getVimeoURLParams = function (defaultParams, videoInfo) { 22041 if (!videoInfo || !videoInfo.vimeo) 22042 return '';
22043 var urlParams = videoInfo.vimeo[2] || ''; 22044 var defaultPlayerParams = defaultParams && Object.keys(defaultParams).length !== 0 22045 ? '&' + param(defaultParams) 22046 : ''; 22047 // Support private video 22048 var urlWithHash = videoInfo.vimeo[0].split('/').pop() || ''; 22049 var urlWithHashWithParams = urlWithHash.split('?')[0] || ''; 22050 var hash = urlWithHashWithParams.split('#')[0]; 22051 var isPrivate = videoInfo.vimeo[1] !== hash; 22052 if (isPrivate) { 22053 urlParams = urlParams.replace("/" + hash, ''); 22054 } 22055 urlParams = 22056 urlParams[0] == '?' ? '&' + urlParams.slice(1) : urlParams || ''; 22057 // For vimeo last params gets priority if duplicates found 22058 // Uncode edit ##START## 22059 var vimeoPlayerParams = '?autoplay=0'; 22060 if ( videoInfo.autoplay !== '' ) { 22061 vimeoPlayerParams = vimeoPlayerParams.replace(new RegExp('([?&])autoplay=(.*?)(&|$)'), '$1$3' ); 22062 vimeoPlayerParams = vimeoPlayerParams.replace(new RegExp('([?&])autoplay(&|$)'), '$1$2' ); 22063 } else { 22064 if ( typeof SiteParameters !== 'undefined' && typeof SiteParameters.vimeoPlayerParams !== 'undefined' && SiteParameters.vimeoPlayerParams !== '' ) { 22065 vimeoPlayerParams = SiteParameters.vimeoPlayerParams; 22066 } 22067 } 22068 if ( videoInfo.muted !== '' ) { 22069 vimeoPlayerParams += '&muted=' + (videoInfo.muted === 'yes'); 22070 } else { 22071 if ( urlParams.indexOf('muted=') < 0 && vimeoPlayerParams.indexOf('muted=') < 0 ) { 22072 vimeoPlayerParams += '&muted=1'; 22073 } 22074 } 22075 // var vimeoPlayerParams = "?autoplay=0&muted=1" + (isPrivate ? "&h=" + hash : '') + defaultPlayerParams + urlParams; 22076 vimeoPlayerParams += (isPrivate ? "&h=" + hash : '') + defaultPlayerParams + urlParams; 22077 // Uncode edit ##END## 22078 return vimeoPlayerParams; 22079 }; 22080 22081 /** 22082 * Video module for lightGallery 22083 * Supports HTML5, YouTube, Vimeo, wistia videos 22084 * 22085 * 22086 * @ref Wistia 22087 * https://wistia.com/support/integrations/wordpress(How to get url) 22088 * https://wistia.com/support/developers/embed-options#using-embed-options 22089 * https://wistia.com/support/developers/player-api 22090 * https://wistia.com/support/developers/construct-an-embed-code 22091 * http://jsfiddle.net/xvnm7xLm/ 22092 * https://developer.mozilla.org/en-US/docs/Web/HTML/Element/video 22093 * https://wistia.com/support/embed-and-share/sharing-videos 22094 * https://private-sharing.wistia.com/medias/mwhrulrucj 22095 * 22096 * @ref Youtube 22097 * https://developers.google.com/youtube/player_parameters#enablejsapi 22098 * https://developers.google.com/youtube/iframe_api_reference 22099 * https://developer.chrome.com/blog/autoplay/#iframe-delegation 22100 * 22101 * @ref Vimeo 22102 * https://stackoverflow.com/questions/10488943/easy-way-to-get-vimeo-id-from-a-vimeo-url 22103 * https://vimeo.zendesk.com/hc/en-us/articles/360000121668-Starting-playback-at-a-specific-timecode 22104 * https://vimeo.zendesk.com/hc/en-us/articles/360001494447-Using-Player-Parameters 22105 */ 22106 var Video = /** @class */ (function () { 22107 function Video(instance) { 22108 // get lightGallery core plugin instance 22109 this.core = instance; 22110 this.settings = __assign(__assign({}, videoSettings), this.core.settings); 22111 return this; 22112 } 22113 Video.prototype.init = function () { 22114 var _this = this; 22115 /** 22116 * Event triggered when video url found without poster 22117 * Append video HTML 22118 * Play if autoplayFirstVideo is true 22119 */ 22120 this.core.LGel.on(lGEvents.hasVideo + ".video", this.onHasVideo.bind(this)); 22121 this.core.LGel.on(lGEvents.posterClick + ".video", function () { 22122 var $el = _this.core.getSlideItem(_this.core.index); 22123 _this.loadVideoOnPosterClick($el); 22124 }); 22125 this.core.LGel.on(lGEvents.slideItemLoad + ".video", this.onSlideItemLoad.bind(this)); 22126 // @desc fired immediately before each slide transition. 22127 this.core.LGel.on(lGEvents.beforeSlide + ".video", this.onBeforeSlide.bind(this)); 22128 // @desc fired immediately after each slide transition. 22129 this.core.LGel.on(lGEvents.afterSlide + ".video", this.onAfterSlide.bind(this)); 22130 }; 22131 /** 22132 * @desc Event triggered when a slide is completely loaded 22133 * 22134 * @param {Event} event - lightGalley custom event 22135 */ 22136 Video.prototype.onSlideItemLoad = function (event) { 22137 var _this = this; 22138 var _a = event.detail, isFirstSlide = _a.isFirstSlide, index = _a.index; 22139 // Should check the active slide as well as user may have moved to different slide before the first slide is loaded 22140 if (this.settings.autoplayFirstVideo && 22141 isFirstSlide && 22142 index === this.core.index) { 22143 // Delay is just for the transition effect on video load 22144 setTimeout(function () { 22145 _this.loadAndPlayVideo(index); 22146 }, 200); 22147 } 22148 // Should not call on first slide. should check only if the slide is active 22149 if (!isFirstSlide && 22150 this.settings.autoplayVideoOnSlide && 22151 index === this.core.index) { 22152 setTimeout(function () { 22153 _this.loadAndPlayVideo(index); 22154 }, 500); 22155 } 22156 }; 22157 /** 22158 * @desc Event triggered when video url or poster found 22159 * Append video HTML is poster is not given 22160 * Play if autoplayFirstVideo is true 22161 * 22162 * @param {Event} event - Javascript Event object. 22163 */ 22164 Video.prototype.onHasVideo = function (event) { 22165 var _a = event.detail, index = _a.index, src = _a.src, html5Video = _a.html5Video, hasPoster = _a.hasPoster; 22166 if (!hasPoster) { 22167 // All functions are called separately if poster exist in loadVideoOnPosterClick function 22168 this.appendVideos(this.core.getSlideItem(index), { 22169 src: src, 22170 addClass: 'lg-object', 22171 index: index, 22172 html5Video: html5Video, 22173 // Uncode edit ##START## 22174 autoplay: event.target.getAttribute('data-lb-autoplay'), 22175 muted: event.target.getAttribute('data-lb-muted'), 22176 // Uncode edit ##END## 22177 }); 22178 // Automatically navigate to next slide once video reaches the end. 22179 this.gotoNextSlideOnVideoEnd(src, index); 22180 } 22181 }; 22182 /** 22183 * @desc fired immediately before each slide transition. 22184 * Pause the previous video 22185 * Hide the download button if the slide contains YouTube, Vimeo, or Wistia videos. 22186 * 22187 * @param {Event} event - Javascript Event object. 22188 * @param {number} prevIndex - Previous index of the slide. 22189 * @param {number} index - Current index of the slide 22190 */ 22191 Video.prototype.onBeforeSlide = function (event) { 22192 if (this.core.lGalleryOn) { 22193 var prevIndex = event.detail.prevIndex; 22194 this.pauseVideo(prevIndex); 22195 } 22196 // Uncode edit ##START## 22197 var _a = event.detail, index = _a.index; 22198 var $slide = this.core.getSlideItem(index); 22199
22200 var iframe = $slide.selector.querySelector('iframe'); 22201 if ( iframe != null ) { 22202 22203 var data_play = iframe.getAttribute('data-autoplay'); 22204 if ( typeof data_play !== 'undefined' && data_play === '1' ) { 22205 this.loadAndPlayVideo(index); 22206 22207 var videoInfo = this.core.galleryItems[index].__slideVideoInfo || {}, 22208 $videoElement = this.core.getSlideItem(index).find('.lg-video-object').first(); 22209 if (videoInfo.vimeo) { 22210 var vimeoPlayer = new Vimeo.Player($videoElement.get()); 22211 vimeoPlayer.on('play', function () { 22212 vimeoPlayer.setCurrentTime(0); 22213 }); 22214 } else if ( videoInfo.youtube ) { 22215 try { 22216 $videoElement.get().contentWindow.postMessage("{\"event\":\"command\",\"func\":\"seekTo\",\"args\":[0, true]}", '*'); 22217 } 22218 catch (e) { 22219 console.warn(e); 22220 } 22221 } 22222 } 22223 } 22224 // Uncode edit ##END## 22225 }; 22226 /** 22227 * @desc fired immediately after each slide transition. 22228 * Play video if autoplayVideoOnSlide option is enabled. 22229 * 22230 * @param {Event} event - Javascript Event object. 22231 * @param {number} prevIndex - Previous index of the slide. 22232 * @param {number} index - Current index of the slide 22233 * @todo should check on onSlideLoad as well if video is not loaded on after slide 22234 */ 22235 Video.prototype.onAfterSlide = function (event) { 22236 var _this = this; 22237 var _a = event.detail, index = _a.index, prevIndex = _a.prevIndex; 22238 // Do not call on first slide 22239 var $slide = this.core.getSlideItem(index); 22240 if (this.settings.autoplayVideoOnSlide && index !== prevIndex) { 22241 if ($slide.hasClass('lg-complete')) { 22242 setTimeout(function () { 22243 _this.loadAndPlayVideo(index); 22244 }, 100); 22245 } 22246 } 22247 }; 22248 Video.prototype.loadAndPlayVideo = function (index) { 22249 var $slide = this.core.getSlideItem(index); 22250 var currentGalleryItem = this.core.galleryItems[index]; 22251 if (currentGalleryItem.poster) { 22252 this.loadVideoOnPosterClick($slide, true); 22253 } 22254 else { 22255 //Uncode edit ##START## 22256 // this.playVideo(index); 22257 var iframe = $slide.selector.querySelector('iframe'); 22258 if ( iframe != null ) { 22259 var data_play = iframe.getAttribute('data-autoplay'); 22260 if ( typeof data_play !== 'undefined' ) { 22261 if ( data_play === '1' && this.core.index == index ) { 22262 this.playVideo(index); 22263 } else { 22264 this.pauseVideo(index); 22265 } 22266 } 22267 } 22268 //Uncode edit ##END## 22269 } 22270 }; 22271 /** 22272 * Play HTML5, Youtube, Vimeo or Wistia videos in a particular slide. 22273 * @param {number} index - Index of the slide 22274 */ 22275 Video.prototype.playVideo = function (index) { 22276 this.controlVideo(index, 'play'); 22277 }; 22278 /** 22279 * Pause HTML5, Youtube, Vimeo or Wistia videos in a particular slide. 22280 * @param {number} index - Index of the slide 22281 */ 22282 Video.prototype.pauseVideo = function (index) { 22283 this.controlVideo(index, 'pause'); 22284 }; 22285 // Uncode edit ##START## 22286 //Video.prototype.getVideoHtml = function (src, addClass, index, html5Video) { 22287 Video.prototype.getVideoHtml = function (src, addClass, index, html5Video, autoplay, muted) { 22288 // Uncode edit ##END## 22289 var video = ''; 22290 var videoInfo = this.core.galleryItems[index] 22291 .__slideVideoInfo || {}; 22292 var currentGalleryItem = this.core.galleryItems[index]; 22293 var videoTitle = currentGalleryItem.title || currentGalleryItem.alt; 22294 videoTitle = videoTitle ? 'title="' + videoTitle + '"' : ''; 22295 var commonIframeProps = "allowtransparency=\"true\"\n frameborder=\"0\"\n scrolling=\"no\"\n allowfullscreen\n mozallowfullscreen\n webkitallowfullscreen\n oallowfullscreen\n msallowfullscreen"; 22296 if (videoInfo.youtube) { 22297 var videoId = 'lg-youtube' + index; 22298 var slideUrlParams = videoInfo.youtube[2] 22299 ? videoInfo.youtube[2] + '&' 22300 : ''; 22301 // For youtube first parms gets priority if duplicates found 22302 // Uncode edit ##START## 22303 // var youTubePlayerParams = "?" + slideUrlParams + "wmode=opaque&autoplay=0&mute=1&enablejsapi=1"; 22304 var youTubePlayerParams = "?" + slideUrlParams + "wmode=opaque&enablejsapi=1"; 22305 if ( ( slideUrlParams.indexOf('autoplay=') < 0 && youTubePlayerParams.indexOf('autoplay=') < 0 ) ) { 22306 youTubePlayerParams += '&autoplay=0'; 22307 } 22308 if ( slideUrlParams.indexOf('mute=') < 0 && youTubePlayerParams.indexOf('mute=') < 0 ) { 22309 youTubePlayerParams += '&mute=1'; 22310 } 22311 var data_video = ''; 22312 if ( autoplay !== '' ) { 22313 //youTubePlayerParams = youTubePlayerParams.replace(new RegExp('([?&])autoplay=(.*?)(&|$)'), '$1autoplay=' + (autoplay === 'yes' ? 1 : 0) + '$3' ); 22314 youTubePlayerParams = youTubePlayerParams.replace(new RegExp('([?&])autoplay=(.*?)(&|$)'), '$1$3' ); 22315 youTubePlayerParams = youTubePlayerParams.replace(new RegExp('([?&])autoplay'), '$1' ); 22316 data_video = ' data-autoplay="' + (autoplay === 'yes' ? 1 : 0) + '"'; 22317 } 22318 // if ( muted !== '' ) { 22319 // youTubePlayerParams = youTubePlayerParams.replace(new RegExp('([?&])mute=(.*?)(&|$)'), '$1mute=' + (muted === 'yes' ? 1 : 0) + '$3' ); 22320 // } 22321 youTubePlayerParams = youTubePlayerParams.replace(new RegExp('([?&])mute=(.*?)(&|$)'), '$1$3' ); 22322 22323 youTubePlayerParams = youTubePlayerParams.replace('??', '?'); 22324 // Uncode edit ##END## 22325 var playerParams = youTubePlayerParams + 22326 (this.settings.youTubePlayerParams 22327 ? '&' + param(this.settings.youTubePlayerParams) 22328 : ''); 22329 // Uncode edit ##START## 22330 // 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>"; 22331 var nocookie = typeof SiteParameters.uncode_nocookie !== 'undefined' ? SiteParameters.uncode_nocookie : ''; 22332 video = "<iframe allow=\"autoplay\"" + data_video + " id=" + videoId + " class=\"lg-video-object lg-youtube " + addClass + "\" " + videoTitle + " src=\"//www.youtube" + nocookie + ".com/embed/" + (videoInfo.youtube[1] + playerParams) + "\" " + commonIframeProps + "></iframe>"; 22333 var tag = document.createElement('script'); 22334 tag.src = "//www.youtube.com/player_api"; 22335 var firstScriptTag = document.getElementsByTagName('script')[0]; 22336 firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); 22337 22338 // Replace the 'ytplayer' element with an <iframe> and 22339 // YouTube player after the API code downloads. 22340 var ytIframeplayer, 22341 setMute = muted === 'yes' ? 0 : 100; 22342 window.onYouTubePlayerAPIReady = function() { 22343 ytIframeplayer = new YT.Player(videoId, { 22344 videoId: videoInfo.youtube[1], 22345 events: { 22346 'onReady': function (event) { 22347 event.target.setVolume(setMute); 22348 } 22349 } 22350 }); 22351 } 22352 // Uncode edit ##END## 22353 } 22354 else if (videoInfo.vimeo) { 22355 var videoId = 'lg-vimeo' + index; 22356 // Uncode edit ##START## 22357 videoInfo.autoplay = autoplay; 22358 videoInfo.muted = muted; 22359 // Uncode edit ##END## 22360 var playerParams = getVimeoURLParams(this.settings.vimeoPlayerParams, videoInfo); 22361 // Uncode edit ##START## 22362 // 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>"; 22363 var data_video = ''; 22364 if ( autoplay !== '' ) { 22365 data_video = ' data-autoplay="' + (autoplay === 'yes' ? 1 : 0) + '"'; 22366 } 22367 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>"; 22368 // Uncode edit ##END## 22369 } 22370 else if (videoInfo.wistia) { 22371 var wistiaId = 'lg-wistia' + index; 22372 var playerParams = param(this.settings.wistiaPlayerParams); 22373 playerParams = playerParams ? '?' + playerParams : ''; 22374 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>"; 22375 } 22376 else if (videoInfo.html5) { 22377 var html5VideoMarkup = ''; 22378 for (var i = 0; i < html5Video.source.length; i++) { 22379 html5VideoMarkup += "<source src=\"" + html5Video.source[i].src + "\" type=\"" + html5Video.source[i].type + "\">"; 22380 } 22381 if (html5Video.tracks) { 22382 var _loop_1 = function (i) { 22383 var trackAttributes = ''; 22384 var track = html5Video.tracks[i]; 22385 Object.keys(track || {}
22385).forEach(function (key) { 22386 trackAttributes += key + "=\"" + track[key] + "\" "; 22387 }); 22388 html5VideoMarkup += "<track " + trackAttributes + ">"; 22389 }; 22390 for (var i = 0; i < html5Video.tracks.length; i++) { 22391 _loop_1(i); 22392 } 22393 } 22394 var html5VideoAttrs_1 = ''; 22395 var videoAttributes_1 = html5Video.attributes || {}; 22396 Object.keys(videoAttributes_1 || {}).forEach(function (key) { 22397 html5VideoAttrs_1 += key + "=\"" + videoAttributes_1[key] + "\" "; 22398 }); 22399 video = "<video class=\"lg-video-object lg-html5 " + (this.settings.videojs && this.settings.videojsTheme 22400 ? this.settings.videojsTheme + ' ' 22401 : '') + " " + (this.settings.videojs ? ' video-js' : '') + "\" " + html5VideoAttrs_1 + ">\n " + html5VideoMarkup + "\n Your browser does not support HTML5 video.\n </video>"; 22402 } 22403 return video; 22404 }; 22405 /** 22406 * @desc - Append videos to the slide 22407 * 22408 * @param {HTMLElement} el - slide element 22409 * @param {Object} videoParams - Video parameters, Contains src, class, index, htmlVideo 22410 */ 22411 Video.prototype.appendVideos = function (el, videoParams) { 22412 var _a; 22413 // Uncode edit ##START## 22414 // var videoHtml = this.getVideoHtml(videoParams.src, videoParams.addClass, videoParams.index, videoParams.html5Video); 22415 var videoHtml = this.getVideoHtml(videoParams.src, videoParams.addClass, videoParams.index, videoParams.html5Video, videoParams.autoplay, videoParams.muted); 22416 // Uncode edit ##END## 22417 el.find('.lg-video-cont').append(videoHtml); 22418 var $videoElement = el.find('.lg-video-object').first(); 22419 if (videoParams.html5Video) { 22420 $videoElement.on('mousedown.lg.video', function (e) { 22421 e.stopPropagation(); 22422 }); 22423 } 22424 if (this.settings.videojs && ((_a = this.core.galleryItems[videoParams.index].__slideVideoInfo) === null || _a === void 0 ? void 0 : _a.html5)) { 22425 try { 22426 return videojs($videoElement.get(), this.settings.videojsOptions); 22427 } 22428 catch (e) { 22429 console.warn('lightGallery:- Make sure you have included videojs'); 22430 } 22431 } 22432 }; 22433 Video.prototype.gotoNextSlideOnVideoEnd = function (src, index) { 22434 var _this = this; 22435 var $videoElement = this.core 22436 .getSlideItem(index) 22437 .find('.lg-video-object') 22438 .first(); 22439 var videoInfo = this.core.galleryItems[index].__slideVideoInfo || {}; 22440 if (this.settings.gotoNextSlideOnVideoEnd) { 22441 if (videoInfo.html5) { 22442 $videoElement.on('ended', function () { 22443 _this.core.goToNextSlide(); 22444 }); 22445 } 22446 else if (videoInfo.vimeo) { 22447 try { 22448 // https://github.com/vimeo/player.js/#ended 22449 new Vimeo.Player($videoElement.get()).on('ended', function () { 22450 _this.core.goToNextSlide(); 22451 }); 22452 } 22453 catch (e) { 22454 console.warn('lightGallery:- Make sure you have included //github.com/vimeo/player.js'); 22455 } 22456 } 22457 else if (videoInfo.wistia) { 22458 try { 22459 window._wq = window._wq || []; 22460 // @todo Event is gettign triggered multiple times 22461 window._wq.push({ 22462 id: $videoElement.attr('id'), 22463 onReady: function (video) { 22464 video.bind('end', function () { 22465 _this.core.goToNextSlide(); 22466 }); 22467 }, 22468 }); 22469 } 22470 catch (e) { 22471 console.warn('lightGallery:- Make sure you have included //fast.wistia.com/assets/external/E-v1.js'); 22472 } 22473 } 22474 } 22475 }; 22476 Video.prototype.controlVideo = function (index, action) { 22477 var $videoElement = this.core 22478 .getSlideItem(index) 22479 .find('.lg-video-object') 22480 .first(); 22481 var videoInfo = this.core.galleryItems[index].__slideVideoInfo || {}; 22482 if (!$videoElement.get()) 22483 return; 22484 if (videoInfo.youtube) { 22485 try { 22486 $videoElement.get().contentWindow.postMessage("{\"event\":\"command\",\"func\":\"" + action + "Video\",\"args\":\"\"}", '*'); 22487 } 22488 catch (e) { 22489 console.warn("lightGallery:- " + e); 22490 } 22491 } 22492 else if (videoInfo.vimeo) { 22493 try { 22494 new Vimeo.Player($videoElement.get())[action](); 22495 } 22496 catch (e) { 22497 console.warn('lightGallery:- Make sure you have included //github.com/vimeo/player.js'); 22498 } 22499 } 22500 else if (videoInfo.html5) { 22501 if (this.settings.videojs) { 22502 try { 22503 videojs($videoElement.get())[action](); 22504 } 22505 catch (e) { 22506 console.warn('lightGallery:- Make sure you have included videojs'); 22507 } 22508 } 22509 else { 22510 $videoElement.get()[action](); 22511 } 22512 } 22513 else if (videoInfo.wistia) { 22514 try { 22515 window._wq = window._wq || []; 22516 // @todo Find a way to destroy wistia player instance 22517 window._wq.push({ 22518 id: $videoElement.attr('id'), 22519 onReady: function (video) { 22520 video[action](); 22521 }, 22522 }); 22523 } 22524 catch (e) { 22525 console.warn('lightGallery:- Make sure you have included //fast.wistia.com/assets/external/E-v1.js'); 22526 } 22527 } 22528 }; 22529 Video.prototype.loadVideoOnPosterClick = function ($el, forcePlay) { 22530 var _this = this; 22531 // check slide has poster 22532 if (!$el.hasClass('lg-video-loaded')) { 22533 // check already video element present
22534 if (!$el.hasClass('lg-has-video')) { 22535 $el.addClass('lg-has-video'); 22536 var _html = void 0; 22537 var _src = this.core.galleryItems[this.core.index].src; 22538 var video = this.core.galleryItems[this.core.index].video; 22539 if (video) { 22540 _html = 22541 typeof video === 'string' ? JSON.parse(video) : video; 22542 } 22543 var videoJsPlayer_1 = this.appendVideos($el, { 22544 src: _src, 22545 addClass: '', 22546 index: this.core.index, 22547 html5Video: _html, 22548 }); 22549 this.gotoNextSlideOnVideoEnd(_src, this.core.index); 22550 var $tempImg = $el.find('.lg-object').first().get(); 22551 // @todo make sure it is working 22552 $el.find('.lg-video-cont').first().append($tempImg); 22553 $el.addClass('lg-video-loading'); 22554 videoJsPlayer_1 && 22555 videoJsPlayer_1.ready(function () { 22556 videoJsPlayer_1.on('loadedmetadata', function () { 22557 _this.onVideoLoadAfterPosterClick($el, _this.core.index); 22558 }); 22559 }); 22560 $el.find('.lg-video-object') 22561 .first() 22562 .on('load.lg error.lg loadedmetadata.lg', function () { 22563 setTimeout(function () { 22564 _this.onVideoLoadAfterPosterClick($el, _this.core.index); 22565 }, 50); 22566 }); 22567 } 22568 else { 22569 this.playVideo(this.core.index); 22570 } 22571 } 22572 else if (forcePlay) { 22573 this.playVideo(this.core.index); 22574 } 22575 }; 22576 Video.prototype.onVideoLoadAfterPosterClick = function ($el, index) { 22577 $el.addClass('lg-video-loaded'); 22578 this.playVideo(index); 22579 }; 22580 Video.prototype.destroy = function () { 22581 this.core.LGel.off('.lg.video'); 22582 this.core.LGel.off('.video'); 22583 }; 22584 return Video; 22585 }()); 22586 22587 return Video; 22588 22589}))); 22590 22591 22592/*! @vimeo/player v2.17.1 | (c) 2022 Vimeo | MIT License | https://github.com/vimeo/player.js */ 22593!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:{}}
22593),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 22593
22593var 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)}
22593},{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 22593-23800
22593))}(),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}); 22594 22595/** 22596 * Owl carousel 22597 * @version 2.0.0-beta.3 22598 * @author Bartosz Wojciechowski 22599 * @license The MIT License (MIT) 22600 * @todo Lazy Load Icon 22601 * @todo prevent animationend bubling 22602 * @todo itemsScaleUp 22603 * @todo Test Zepto 22604 * @todo stagePadding calculate wrong active classes 22605 */ 22606;(function($, window, document, undefined) { 22607 22608 /** 22609 * Creates a carousel. 22610 * @class The Owl Carousel. 22611 * @public 22612 * @param {HTMLElement|jQuery} element - The element to create the carousel for. 22613 * @param {Object} [options] - The options 22614 */ 22615 function Owl(element, options) { 22616 22617 /** 22618 * Current settings for the carousel. 22619 * @public 22620 */ 22621 this.settings = null; 22622 22623 /** 22624 * Current options set by the caller including defaults. 22625 * @public 22626 */ 22627 this.options = $.extend({}, Owl.Defaults, options); 22628 22629 /** 22630 * Plugin element. 22631 * @public 22632 */ 22633 this.$element = $(element); 22634 22635 /** 22636 * Proxied event handlers. 22637 * @protected 22638 */ 22639 this._handlers = {}; 22640 22641 /** 22642 * References to the running plugins of this carousel. 22643 * @protected 22644 */ 22645 this._plugins = {}; 22646 22647 /** 22648 * Currently suppressed events to prevent them from beeing retriggered. 22649 * @protected 22650 */ 22651 this._supress = {}; 22652 22653 /** 22654 * Absolute current position. 22655 * @protected 22656 */ 22657 this._current = null; 22658 22659 /** 22660 * Animation speed in milliseconds. 22661 * @protected 22662 */ 22663 this._speed = null; 22664 22665 /** 22666 * Coordinates of all items in pixel. 22667 * @todo The name of this member is missleading. 22668 * @protected 22669 */ 22670 this._coordinates = []; 22671 22672 /** 22673 * Current breakpoint. 22674 * @todo Real media queries would be nice. 22675 * @protected 22676 */ 22677 this._breakpoint = null; 22678 22679 /** 22680 * Current width of the plugin element. 22681 */ 22682 this._width = null; 22683 22684 /** 22685 * All real items. 22686 * @protected 22687 */ 22688 this._items = []; 22689 22690 /** 22691 * All cloned items. 22692 * @protected 22693 */ 22694 this._clones = []; 22695 22696 /** 22697 * Merge values of all items. 22698 * @todo Maybe this could be part of a plugin. 22699 * @protected 22700 */ 22701 this._mergers = []; 22702 22703 /** 22704 * Widths of all items. 22705 */ 22706 this._widths = []; 22707 22708 /** 22709 * Invalidated parts within the update process. 22710 * @protected 22711 */ 22712 this._invalidated = {}; 22713 22714 /** 22715 * Ordered list of workers for the update process. 22716 * @protected 22717 */ 22718 this._pipe = []; 22719 22720 /** 22721 * Current state information for the drag operation. 22722 * @todo #261 22723 * @protected 22724 */ 22725 this._drag = { 22726 time: null, 22727 target: null, 22728 pointer: null, 22729 stage: { 22730 start: null, 22731 current: null 22732 }, 22733 direction: null 22734 }; 22735 22736 /** 22737 * Current state information and their tags. 22738 * @type {Object} 22739 * @protected 22740 */ 22741 this._states = { 22742 current: {}, 22743 tags: { 22744 'initializing': [ 'busy' ], 22745 'animating': [ 'busy' ], 22746 'dragging': [ 'interacting' ] 22747 } 22748 }; 22749 22750 $.each([ 'onResize', 'onThrottledResize' ], $.proxy(function(i, handler) { 22751 this._handlers[handler] = $.proxy(this[handler], this); 22752 }, this)); 22753 22754 $.each(Owl.Plugins, $.proxy(function(key, plugin) { 22755 this._plugins[key.charAt(0).toLowerCase() + key.slice(1)] 22756 = new plugin(this); 22757 }, this)); 22758 22759 $.each(Owl.Workers, $.proxy(function(priority, worker) { 22760 this._pipe.push({ 22761 'filter': worker.filter, 22762 'run': $.proxy(worker.run, this) 22763 }); 22764 }, this)); 22765 22766 this.setup(); 22767 this.initialize(); 22768 } 22769 22770 /** 22771 * Default options for the carousel. 22772 * @public 22773 */ 22774 Owl.Defaults = { 22775 items: 3, 22776 loop: false, 22777 center: false, 22778 rewind: false, 22779 22780 mouseDrag: true, 22781 touchDrag: true, 22782 pullDrag: true, 22783 freeDrag: false, 22784 22785 margin: 0, 22786 stagePadding: 0, 22787 22788 merge: false, 22789 mergeFit: true, 22790 autoWidth: false, 22791 22792 startPosition: 0, 22793 rtl: false, 22794 22795 smartSpeed: 250, 22796 fluidSpeed: false, 22797 dragEndSpeed: false, 22798 22799 responsive: {}, 22800 responsiveRefreshRate: 200, 22801 responsiveBaseElement: window, 22802 22803 fallbackEasing: 'swing', 22804 22805 info: false, 22806 22807 nestedItemSelector: false, 22808 itemElement: 'div', 22809 stageElement: 'div', 22810 22811 refreshClass: 'owl-refresh', 22812 loadedClass: 'owl-loaded', 22813 loadingClass: 'owl-loading', 22814 rtlClass: 'owl-rtl', 22815 responsiveClass: 'owl-responsive', 22816 dragClass: 'owl-drag', 22817 itemClass: 'owl-item', 22818 stageClass: 'owl-stage', 22819 stageOuterClass: 'owl-stage-outer', 22820 grabClass: 'owl-grab' 22821 }; 22822 22823 /** 22824 * Enumeration for width. 22825 * @public 22826 * @readonly 22827 * @enum {String} 22828 */ 22829 Owl.Width = { 22830 Default: 'default', 22831 Inner: 'inner', 22832 Outer: 'outer' 22833 }; 22834 22835 /** 22836 * Enumeration for types. 22837 * @public 22838 * @readonly 22839 * @enum {String} 22840 */ 22841 Owl.Type = { 22842 Event: 'event', 22843 State: 'state' 22844 }; 22845 22846 /** 22847 * Contains all registered plugins. 22848 * @public 22849 */ 22850 Owl.Plugins = {}; 22851 22852 /** 22853 * List of workers involved in the update process. 22854 */ 22855 Owl.Workers = [ { 22856 filter: [ 'width', 'settings' ], 22857 run: function() { 22858 this._width = (this.$element.closest('.px-gutter').length) ? 12 * Math.ceil(this.$element.width() / 12) : this.$element.width(); 22859 //this._width = (UNCODE.isMobile) ? this.$element.width() : 12 * Math.ceil(this.$element.width() / 12); 22860 } 22861 }, { 22862 filter: [ 'width', 'items', 'settings' ], 22863 run: function(cache) { 22864 cache.current = this._items && this._items[this.relative(this._current)]; 22865 } 22866 }, { 22867 filter: [ 'items', 'settings' ], 22868 run: function() { 22869 this.$stage.children('.cloned').remove(); 22870 } 22871 }, { 22872 filter: [ 'width', 'items', 'settings' ], 22873 run: function(cache) { 22874 var margin = this.settings.margin || '', 22875 grid = !this.settings.autoWidth, 22876 rtl = this.settings.rtl, 22877 css = { 22878 'width': 'auto', 22879 'margin-left': rtl ? margin : '', 22880 'margin-right': rtl ? '' : margin 22881 }; 22882 22883 !grid && this.$stage.children().css(css); 22884 22885 cache.css = css; 22886 } 22887 }, { 22888 filter: [ 'width', 'items', 'settings' ], 22889 run: function(cache) { 22890 //UNCODE edit to fix Chrome stage padding issue 22891 var width = Math.round((this.width() / this.settings.items).toFixed(3) - this.settings.margin), 22892 merge = null, 22893 iterator = this._items.length, 22894 grid = !this.settings.autoWidth, 22895 widths = []; 22896 22897 cache.items = { 22898 merge: false, 22899 width: width 22900 }; 22901 22902 while (iterator--) { 22903 merge = this._mergers[iterator]; 22904 merge = this.settings.mergeFit && Math.min(merge, this.settings.items) || merge; 22905 22906 cache.items.merge = merge > 1 || cache.items.merge; 22907 22908 widths[iterator] = !grid ? this._items[iterator].width() : width * merge; 22909 } 22910 22911 this._widths = widths; 22912 } 22913 }, { 22914 filter: [ 'items', 'settings' ], 22915 run: function() { 22916 var clones = [], 22917 items = this._items, 22918 settings = this.settings, 22919 view = Math.max(settings.items * 2, 4), 22920 size = Math.ceil(items.length / 2) * 2, 22921 repeat = settings.loop && items.length ? settings.rewind ? view : Math.max(view, size) : 0, 22922 append = '', 22923 prepend = ''; 22924 22925 repeat /= 2; 22926 22927 while (repeat--) { 22928 clones.push(this.normalize(clones.length / 2, true)); 22929 append = append + items[clones[clones.length - 1]][0].outerHTML; 22930 clones.push(this.normalize(items.length - 1 - (clones.length - 1) / 2, true)); 22931 prepend = items[clones[clones.length - 1]][0].outerHTML + prepend; 22932 } 22933 22934 this._clones = clones; 22935 22936 // var appendVideo = $(append).find('.uncode-video-container'); 22937 // if (appendVideo.length) { 22938 // appendVideo.attr('data-id', Math.round(Math.random() * 100000)); 22939 // } 22940 // var prependVideo = $(prepend).find('.uncode-video-container'); 22941 // if (prependVideo.length) { 22942 // prependVideo.attr('data-id', Math.round(Math.random() * 100000)); 22943 // } 22944 $(append).addClass('cloned').appendTo(this.$stage); 22945 $(prepend).addClass('cloned').prependTo(this.$stage); 22946 } 22947 }, { 22948 filter: [ 'width', 'items', 'settings' ], 22949 run: function() { 22950 var rtl = this.settings.rtl ? 1 : -1, 22951 size = this._clones.length + this._items.length, 22952 iterator = -1, 22953 previous = 0, 22954 current = 0, 22955 coordinates = []; 22956 22957 while (++iterator < size) { 22958 previous = coordinates[iterator - 1] || 0; 22959 current = this._widths[this.relative(iterator)] + this.settings.margin; 22960 coordinates.push(previous + current * rtl); 22961 } 22962 22963 this._coordinates = coordinates; 22964 } 22965 }, { 22966 filter: [ 'width', 'items', 'settings' ], 22967 run: function() { 22968 var stagePadding = (this._width < 480 && this.settings.stagePadding > 0) ? 41 : (this._width * this.settings.stagePadding) / 200, 22969 padding = stagePadding, 22970 coordinates = this._coordinates, 22971 css = { 22972 'width': Math.ceil(Math.abs(coordinates[coordinates.length - 1])) + padding * 2, 22973 'padding-left': padding || '', 22974 'padding-right': padding || '' 22975 }; 22976 22977 this.$stage.css(css); 22978 } 22979 }, { 22980 filter: [ 'width', 'items', 'settings' ], 22981 run: function(cache) { 22982 var iterator = this._coordinates.length, 22983 grid = !this.settings.autoWidth, 22984 items = this.$stage.children(); 22985 22986 if (grid && cache.items.merge) { 22987 while (iterator--) { 22988 cache.css.width = this._widths[this.relative(iterator)]; 22989 items.eq(iterator).css(cache.css); 22990 } 22991 } else if (grid) { 22992 cache.css.width = cache.items.width; 22993 items.css(cache.css); 22994 } 22995 } 22996 }, { 22997 filter: [ 'items' ], 22998 run: function() { 22999 this._coordinates.length < 1 && this.$stage.removeAttr('style'); 23000 } 23001 }, { 23002 filter: [ 'width', 'items', 'settings' ], 23003 run: function(cache) { 23004 cache.current = cache.current ? this.$stage.children().index(cache.current) : 0; 23005 cache.current = Math.max(this.minimum(), Math.min(this.maximum(), cache.current)); 23006 this.reset(cache.current); 23007 } 23008 }, { 23009 filter: [ 'position' ], 23010 run: function() { 23011 this.animate(this.coordinates(this._current)); 23012 } 23013 }, { 23014 filter: [ 'width', 'position', 'items', 'settings' ], 23015 run: function() { 23016 var stagePadding = (this._width < 480 && this.settings.stagePadding > 0) ? 41 : (this._width * this.settings.stagePadding) / 200, 23017 rtl = this.settings.rtl ? 1 : -1, 23018 padding = this.settings.stagePadding * 2, 23019 begin = this.coordinates(this.current()) + padding, 23020 end = begin + this.width() * rtl, 23021 inner, outer, matches = [], i, n; 23022 23023 for (i = 0, n = this._coordinates.length; i < n; i++) { 23024 inner = this._coordinates[i - 1] || 0; 23025 outer = Math.abs(this._coordinates[i]) + padding * rtl; 23026 23027 if ((this.op(inner, '<=', begin) && (this.op(inner, '>', end))) 23028 || (this.op(outer, '<', begin) && this.op(outer, '>', end))) { 23029 matches.push(i); 23030 } 23031 } 23032 23033 this.$stage.children('.active').removeClass('active'); 23034 this.$stage.children(':eq(' + matches.join('), :eq(') + ')').addClass('active'); 23035 23036 if (this.settings.center) { 23037 this.$stage.children('.center').removeClass('center'); 23038 this.$stage.children().eq(this.current()).addClass('center'); 23039 } 23040 } 23041 } ]; 23042 23043 /** 23044 * Initializes the carousel. 23045 * @protected 23046 */ 23047 Owl.prototype.initialize = function() { 23048 this.enter('initializing'); 23049 this.trigger('initialize'); 23050 23051 this.$element.toggleClass(this.settings.rtlClass, this.settings.rtl); 23052 23053 if (this.settings.autoWidth && !this.is('pre-loading')) { 23054 var imgs, nestedSelector, width; 23055 imgs = this.$element.find('img'); 23056 nestedSelector = this.settings.nestedItemSelector ? '.' + this.settings.nestedItemSelector : undefined; 23057 width = this.$element.children(nestedSelector).width(); 23058 23059 if (imgs.length && width <= 0) { 23060 this.preloadAutoWidthImages(imgs); 23061 } 23062 } 23063 23064 this.$element.addClass(this.options.loadingClass); 23065 23066 // create stage 23067 this.$stage = $('<' + this.settings.stageElement + ' class="' + this.settings.stageClass + '"/>') 23068 .wrap('<div class="' + this.settings.stageOuterClass + '"/>'); 23069 23070 // append stage 23071 this.$element.append(this.$stage.parent()); 23072 23073 // append content 23074 this.replace(this.$element.children().not(this.$stage.parent())); 23075 23076 // check visibility 23077 if (this.$element.is(':visible')) { 23078 // update view 23079 this.refresh(); 23080 } else { 23081 // invalidate width 23082 this.invalidate('width'); 23083 } 23084 23085 this.$element 23086 .removeClass(this.options.loadingClass) 23087 .addClass(this.options.loadedClass); 23088 23089 // register event handlers 23090 this.registerEventHandlers(); 23091 23092 this.leave('initializing'); 23093 this.trigger('initialized'); 23094 }; 23095 23096 /** 23097 * Setups the current settings. 23098 * @todo Remove responsive classes. Why should adaptive designs be brought into IE8? 23099 * @todo Support for media queries by using `matchMedia` would be nice. 23100 * @public 23101 */ 23102 Owl.prototype.setup = function() { 23103 var viewport = this.viewport(), 23104 overwrites = this.options.responsive, 23105 match = -1, 23106 settings = null; 23107 23108 if (!overwrites) { 23109 settings = $.extend({}, this.options); 23110 } else { 23111 $.each(overwrites, function(breakpoint) { 23112 if (breakpoint <= viewport && breakpoint > match) { 23113 match = Number(breakpoint); 23114 } 23115 }); 23116 23117 settings = $.extend({}, this.options, overwrites[match]); 23118 delete settings.responsive; 23119 23120 // responsive class 23121 if (settings.responsiveClass) { 23122 this.$element.attr('class', 23123 this.$element.attr('class').replace(new RegExp('(' + this.options.responsiveClass + '-)\\S+\\s', 'g'), '$1' + match) 23124 ); 23125 } 23126 } 23127 23128 if (this.settings === null || this._breakpoint !== match) { 23129 this.trigger('change', { property: { name: 'settings', value: settings } }); 23130 this._breakpoint = match; 23131 this.settings = settings; 23132 this.invalidate('settings'); 23133 this.trigger('changed', { property: { name: 'settings', value: this.settings } }); 23134 } 23135 }; 23136 23137 /** 23138 * Updates option logic if necessery. 23139 * @protected 23140 */ 23141 Owl.prototype.optionsLogic = function() { 23142 if (this.settings.autoWidth) { 23143 this.settings.stagePadding = false; 23144 this.settings.merge = false; 23145 } 23146 }; 23147 23148 /** 23149 * Prepares an item before add. 23150 * @todo Rename event parameter `content` to `item`. 23151 * @protected 23152 * @returns {jQuery|HTMLElement} - The item container. 23153 */ 23154 Owl.prototype.prepare = function(item, index) { 23155 var event = this.trigger('prepare', { content: item }); 23156 if (!event.data) { 23157 event.data = $('<' + this.settings.itemElement + '/>') 23158 .addClass(this.options.itemClass).attr('data-index', index + 1).append(item) 23159 } 23160 23161 this.trigger('prepared', { content: event.data }); 23162 23163 return event.data; 23164 }; 23165 23166 /** 23167 * Updates the view. 23168 * @public 23169 */ 23170 Owl.prototype.update = function() { 23171 var i = 0, 23172 n = this._pipe.length, 23173 filter = $.proxy(function(p) { return this[p] }, this._invalidated), 23174 cache = {}; 23175 23176 while (i < n) { 23177 if (this._invalidated.all || $.grep(this._pipe[i].filter, filter).length > 0) { 23178 this._pipe[i].run(cache); 23179 } 23180 i++; 23181 } 23182 23183 this._invalidated = {}; 23184 23185 !this.is('valid') && this.enter('valid'); 23186 }; 23187 23188 /** 23189 * Gets the width of the view. 23190 * @public 23191 * @param {Owl.Width} [dimension=Owl.Width.Default] - The dimension to return. 23192 * @returns {Number} - The width of the view in pixel. 23193 */ 23194 Owl.prototype.width = function(dimension) { 23195 dimension = dimension || Owl.Width.Default; 23196 var stagePadding = (this._width < 480 && this.settings.stagePadding > 0) ? 41 : (this._width * this.settings.stagePadding) / 200; 23197 switch (dimension) { 23198 case Owl.Width.Inner: 23199 case Owl.Width.Outer: 23200 return this._width; 23201 default: 23202 return this._width - stagePadding * 2 + this.settings.margin; 23203 } 23204 }; 23205 23206 /** 23207 * Refreshes the carousel primarily for adaptive purposes. 23208 * @public 23209 */ 23210 Owl.prototype.refresh = function() { 23211 this.enter('refreshing'); 23212 this.trigger('refresh'); 23213 23214 this.setup(); 23215 23216 this.optionsLogic(); 23217 23218 this.$element.addClass(this.options.refreshClass); 23219 23220 this.update(); 23221 23222 this.$element.removeClass(this.options.refreshClass); 23223 23224 this.leave('refreshing'); 23225 this.trigger('refreshed'); 23226 }; 23227 23228 /** 23229 * Checks window `resize` event. 23230 * @protected 23231 */ 23232 Owl.prototype.onThrottledResize = function() { 23233 window.clearTimeout(this.resizeTimer); 23234 this.resizeTimer = window.setTimeout(this._handlers.onResize, this.settings.responsiveRefreshRate); 23235 }; 23236 23237 /** 23238 * Checks window `resize` event. 23239 * @protected 23240 */ 23241 Owl.prototype.onResize = function() { 23242 if (!this._items.length) { 23243 return false; 23244 } 23245 23246 if (this._width === this.$element.width()) { 23247 return false; 23248 } 23249 23250 if (!this.$element.is(':visible')) { 23251 return false; 23252 } 23253 23254 this.enter('resizing'); 23255 23256 if (this.trigger('resize').isDefaultPrevented()) { 23257 this.leave('resizing'); 23258 return false; 23259 } 23260 23261 this.invalidate('width'); 23262 23263 this.refresh(); 23264 23265 this.leave('resizing'); 23266 this.trigger('resized'); 23267 }; 23268 23269 /** 23270 * Registers event handlers. 23271 * @todo Check `msPointerEnabled` 23272 * @todo #261 23273 * @protected 23274 */ 23275 Owl.prototype.registerEventHandlers = function() { 23276 if ($.support.transition) { 23277 this.$stage.on($.support.transition.end + '.owl.core', $.proxy(this.onTransitionEnd, this)); 23278 } 23279 23280 if (this.settings.responsive !== false) { 23281 this.on(window, 'resize', this._handlers.onThrottledResize); 23282 } 23283 23284 if (this.settings.mouseDrag) { 23285 this.$element.addClass(this.options.dragClass); 23286 this.$stage.on('mousedown.owl.core', $.proxy(this.onDragStart, this)); 23287 this.$stage.on('dragstart.owl.core selectstart.owl.core', function() { return false }); 23288 } 23289 23290 if (this.settings.touchDrag){ 23291 this.$stage.on('touchstart.owl.core', $.proxy(this.onDragStart, this)); 23292 this.$stage.on('touchcancel.owl.core', $.proxy(this.onDragEnd, this)); 23293 } 23294 }; 23295 23296 /** 23297 * Handles `touchstart` and `mousedown` events. 23298 * @todo Horizontal swipe threshold as option 23299 * @todo #261 23300 * @protected 23301 * @param {Event} event - The event arguments. 23302 */ 23303 Owl.prototype.onDragStart = function(event) { 23304 var stage = null; 23305 23306 if (event.which === 3) { 23307 return; 23308 } 23309 23310 if ($.support.transform) { 23311 stage = this.$stage.css('transform').replace(/.*\(|\)| /g, '').split(','); 23312 stage = { 23313 x: stage[stage.length === 16 ? 12 : 4], 23314 y: stage[stage.length === 16 ? 13 : 5] 23315 }; 23316 } else { 23317 stage = this.$stage.position(); 23318 stage = { 23319 x: this.settings.rtl ? 23320 stage.left + this.$stage.width() - this.width() + this.settings.margin : 23321 stage.left, 23322 y: stage.top 23323 }; 23324 } 23325 23326 if (this.is('animating')) { 23327 $.support.transform ? this.animate(stage.x) : this.$stage.stop() 23328 this.invalidate('position'); 23329 } 23330 23331 this.$element.toggleClass(this.options.grabClass, event.type === 'mousedown'); 23332 23333 this.speed(0); 23334 23335 this._drag.time = new Date().getTime(); 23336 this._drag.target = $(event.target); 23337 this._drag.stage.start = stage; 23338 this._drag.stage.current = stage; 23339 this._drag.pointer = this.pointer(event); 23340 23341 $(document).on('mouseup.owl.core touchend.owl.core', $.proxy(this.onDragEnd, this)); 23342 23343 $(document).one('mousemove.owl.core touchmove.owl.core', $.proxy(function(event) { 23344 var delta = this.difference(this._drag.pointer, this.pointer(event)); 23345 23346 $(document).on('mousemove.owl.core touchmove.owl.core', $.proxy(this.onDragMove, this)); 23347 23348 if (Math.abs(delta.x) < Math.abs(delta.y) && this.is('valid')) { 23349 return; 23350 } 23351 23352 event.preventDefault(); 23353 23354 this.enter('dragging'); 23355 this.trigger('drag'); 23356 }, this)); 23357 }; 23358 23359 /** 23360 * Handles the `touchmove` and `mousemove` events. 23361 * @todo #261 23362 * @protected 23363 * @param {Event} event - The event arguments. 23364 */ 23365 Owl.prototype.onDragMove = function(event) { 23366 var minimum = null, 23367 maximum = null, 23368 pull = null, 23369 delta = this.difference(this._drag.pointer, this.pointer(event)), 23370 stage = this.difference(this._drag.stage.start, delta); 23371 23372 if (!this.is('dragging')) { 23373 return; 23374 } 23375 23376 event.preventDefault(); 23377 23378 if (this.settings.loop) { 23379 minimum = this.coordinates(this.minimum()); 23380 maximum = this.coordinates(this.maximum() + 1) - minimum; 23381 stage.x = (((stage.x - minimum) % maximum + maximum) % maximum) + minimum; 23382 } else { 23383 minimum = this.settings.rtl ? this.coordinates(this.maximum()) : this.coordinates(this.minimum()); 23384 maximum = this.settings.rtl ? this.coordinates(this.minimum()) : this.coordinates(this.maximum()); 23385 pull = this.settings.pullDrag ? -1 * delta.x / 5 : 0; 23386 stage.x = Math.max(Math.min(stage.x, minimum + pull), maximum + pull); 23387 } 23388 23389 this._drag.stage.current = stage; 23390 23391 this.animate(stage.x); 23392 }; 23393 23394 /** 23395 * Handles the `touchend` and `mouseup` events. 23396 * @todo #261 23397 * @todo Threshold for click event 23398 * @protected 23399 * @param {Event} event - The event arguments. 23400 */ 23401 Owl.prototype.onDragEnd = function(event) { 23402 var delta = this.difference(this._drag.pointer, this.pointer(event)), 23403 stage = this._drag.stage.current, 23404 direction = delta.x > 0 ^ this.settings.rtl ? 'left' : 'right'; 23405 23406 $(document).off('.owl.core'); 23407 23408 this.$element.removeClass(this.options.grabClass); 23409 23410 if (delta.x !== 0 && this.is('dragging') || !this.is('valid')) { 23411 this.speed(this.settings.dragEndSpeed || this.settings.smartSpeed); 23412 this.current(this.closest(stage.x, delta.x !== 0 ? direction : this._drag.direction)); 23413 this.invalidate('position'); 23414 this.update(); 23415 23416 this._drag.direction = direction; 23417 23418 if (Math.abs(delta.x) > 3 || new Date().getTime() - this._drag.time > 300) { 23419 this._drag.target.one('click.owl.core', function() { return false; }); 23420 } 23421 } 23422 23423 if (!this.is('dragging')) { 23424 return; 23425 } 23426 23427 this.leave('dragging'); 23428 this.trigger('dragged'); 23429 }; 23430 23431 /** 23432 * Gets absolute position of the closest item for a coordinate. 23433 * @todo Setting `freeDrag` makes `closest` not reusable. See #165. 23434 * @protected 23435 * @param {Number} coordinate - The coordinate in pixel. 23436 * @param {String} direction - The direction to check for the closest item. Ether `left` or `right`. 23437 * @return {Number} - The absolute position of the closest item. 23438 */ 23439 Owl.prototype.closest = function(coordinate, direction) { 23440 var position = -1, 23441 pull = 30, 23442 width = this.width(), 23443 coordinates = this.coordinates(); 23444 23445 if (!this.settings.freeDrag) { 23446 // check closest item 23447 $.each(coordinates, $.proxy(function(index, value) { 23448 if (coordinate > value - pull && coordinate < value + pull) { 23449 position = index; 23450 } else if (this.op(coordinate, '<', value) 23451 && this.op(coordinate, '>', coordinates[index + 1] || value - width)) { 23452 position = direction === 'left' ? index + 1 : index; 23453 } 23454 return position === -1; 23455 }, this)); 23456 } 23457 23458 if (!this.settings.loop) { 23459 // non loop boundries 23460 if (this.op(coordinate, '>', coordinates[this.minimum()])) { 23461 position = coordinate = this.minimum(); 23462 } else if (this.op(coordinate, '<', coordinates[this.maximum()])) { 23463 position = coordinate = this.maximum(); 23464 } 23465 } 23466 23467 return position; 23468 }; 23469 23470 /** 23471 * Animates the stage. 23472 * @todo #270 23473 * @public 23474 * @param {Number} coordinate - The coordinate in pixels. 23475 */ 23476 Owl.prototype.animate = function(coordinate) { 23477 var animate = this.speed() > 0; 23478 23479 this.is('animating') && this.onTransitionEnd(); 23480 23481 if (animate) { 23482 this.enter('animating'); 23483 this.trigger('translate'); 23484 } 23485 23486 if ($.support.transform3d && $.support.transition) { 23487 this.$stage.css({ 23488 transform: 'translate3d(' + coordinate + 'px,0px,0px)', 23489 transition: (this.speed() / 1000) + 's' 23490 }); 23491 } else if (animate) { 23492 this.$stage.animate({ 23493 left: coordinate + 'px' 23494 }, this.speed(), this.settings.fallbackEasing, $.proxy(this.onTransitionEnd, this)); 23495 } else { 23496 this.$stage.css({ 23497 left: coordinate + 'px' 23498 }); 23499 } 23500 }; 23501 23502 /** 23503 * Checks whether the carousel is in a specific state or not. 23504 * @param {String} state - The state to check. 23505 * @returns {Boolean} - The flag which indicates if the carousel is busy. 23506 */ 23507 Owl.prototype.is = function(state) { 23508 return this._states.current[state] && this._states.current[state] > 0; 23509 }; 23510 23511 /** 23512 * Sets the absolute position of the current item. 23513 * @public 23514 * @param {Number} [position] - The new absolute position or nothing to leave it unchanged. 23515 * @returns {Number} - The absolute position of the current item. 23516 */ 23517 Owl.prototype.current = function(position) { 23518 if (position === undefined) { 23519 return this._current; 23520 } 23521 23522 if (this._items.length === 0) { 23523 return undefined; 23524 } 23525 23526 position = this.normalize(position); 23527 23528 if (this._current !== position) { 23529 var event = this.trigger('change', { property: { name: 'position', value: position } }); 23530 23531 if (event.data !== undefined) { 23532 position = this.normalize(event.data); 23533 } 23534 23535 this._current = position; 23536 23537 this.invalidate('position'); 23538 23539 this.trigger('changed', { property: { name: 'position', value: this._current } }); 23540 } 23541 23542 return this._current; 23543 }; 23544 23545 /** 23546 * Invalidates the given part of the update routine. 23547 * @param {String} [part] - The part to invalidate. 23548 * @returns {Array.<String>} - The invalidated parts. 23549 */ 23550 Owl.prototype.invalidate = function(part) { 23551 if ($.type(part) === 'string') { 23552 this._invalidated[part] = true; 23553 this.is('valid') && this.leave('valid'); 23554 } 23555 return $.map(this._invalidated, function(v, i) { return i }); 23556 }; 23557 23558 /** 23559 * Resets the absolute position of the current item. 23560 * @public 23561 * @param {Number} position - The absolute position of the new item. 23562 */ 23563 Owl.prototype.reset = function(position) { 23564 position = this.normalize(position); 23565 23566 if (position === undefined) { 23567 return; 23568 } 23569 23570 this._speed = 0; 23571 this._current = position; 23572 23573 this.suppress([ 'translate', 'translated' ]); 23574 23575 this.animate(this.coordinates(position)); 23576 23577 this.release([ 'translate', 'translated' ]); 23578 }; 23579 23580 /** 23581 * Normalizes an absolute or a relative position of an item. 23582 * @public 23583 * @param {Number} position - The absolute or relative position to normalize. 23584 * @param {Boolean} [relative=false] - Whether the given position is relative or not. 23585 * @returns {Number} - The normalized position. 23586 */ 23587 Owl.prototype.normalize = function(position, relative) { 23588 var n = this._items.length, 23589 m = relative ? 0 : this._clones.length; 23590 23591 if (!$.isNumeric(position) || n < 1) { 23592 position = undefined; 23593 } else if (position < 0 || position >= n + m) { 23594 position = ((position - m / 2) % n + n) % n + m / 2; 23595 } 23596 23597 return position; 23598 }; 23599 23600 /** 23601 * Converts an absolute position of an item into a relative one. 23602 * @public 23603 * @param {Number} position - The absolute position to convert. 23604 * @returns {Number} - The converted position. 23605 */ 23606 Owl.prototype.relative = function(position) { 23607 position -= this._clones.length / 2; 23608 return this.normalize(position, true); 23609 }; 23610 23611 /** 23612 * Gets the maximum position for the current item. 23613 * @public 23614 * @param {Boolean} [relative=false] - Whether to return an absolute position or a relative position. 23615 * @returns {Number} 23616 */ 23617 Owl.prototype.maximum = function(relative) { 23618 var settings = this.settings, 23619 maximum = this._coordinates.length, 23620 boundary = Math.abs(this._coordinates[maximum - 1]) - this._width, 23621 i = -1, j; 23622 23623 if (settings.loop) { 23624 maximum = this._clones.length / 2 + this._items.length - 1; 23625 } else if (settings.autoWidth || settings.merge) { 23626 // binary search 23627 while (maximum - i > 1) { 23628 Math.abs(this._coordinates[j = maximum + i >> 1]) < boundary 23629 ? i = j : maximum = j; 23630 } 23631 } else if (settings.center) { 23632 maximum = this._items.length - 1; 23633 } else { 23634 maximum = this._items.length - settings.items; 23635 } 23636 23637 if (relative) { 23638 maximum -= this._clones.length / 2; 23639 } 23640 23641 return Math.max(maximum, 0); 23642 }; 23643 23644 /** 23645 * Gets the minimum position for the current item. 23646 * @public 23647 * @param {Boolean} [relative=false] - Whether to return an absolute position or a relative position. 23648 * @returns {Number} 23649 */ 23650 Owl.prototype.minimum = function(relative) { 23651 return relative ? 0 : this._clones.length / 2; 23652 }; 23653 23654 /** 23655 * Gets an item at the specified relative position. 23656 * @public 23657 * @param {Number} [position] - The relative position of the item. 23658 * @return {jQuery|Array.<jQuery>} - The item at the given position or all items if no position was given. 23659 */ 23660 Owl.prototype.items = function(position) { 23661 if (position === undefined) { 23662 return this._items.slice(); 23663 } 23664 23665 position = this.normalize(position, true); 23666 return this._items[position]; 23667 }; 23668 23669 /** 23670 * Gets an item at the specified relative position. 23671 * @public 23672 * @param {Number} [position] - The relative position of the item. 23673 * @return {jQuery|Array.<jQuery>} - The item at the given position or all items if no position was given. 23674 */ 23675 Owl.prototype.mergers = function(position) { 23676 if (position === undefined) { 23677 return this._mergers.slice(); 23678 } 23679 23680 position = this.normalize(position, true); 23681 return this._mergers[position]; 23682 }; 23683 23684 /** 23685 * Gets the absolute positions of clones for an item. 23686 * @public 23687 * @param {Number} [position] - The relative position of the item. 23688 * @returns {Array.<Number>} - The absolute positions of clones for the item or all if no position was given. 23689 */ 23690 Owl.prototype.clones = function(position) { 23691 var odd = this._clones.length / 2, 23692 even = odd + this._items.length, 23693 map = function(index) { return index % 2 === 0 ? even + index / 2 : odd - (index + 1) / 2 }; 23694 23695 if (position === undefined) { 23696 return $.map(this._clones, function(v, i) { return map(i) }); 23697 } 23698 23699 return $.map(this._clones, function(v, i) { return v === position ? map(i) : null }); 23700 }; 23701 23702 /** 23703 * Sets the current animation speed. 23704 * @public 23705 * @param {Number} [speed] - The animation speed in milliseconds or nothing to leave it unchanged. 23706 * @returns {Number} - The current animation speed in milliseconds. 23707 */ 23708 Owl.prototype.speed = function(speed) { 23709 if (speed !== undefined) { 23710 this._speed = speed; 23711 } 23712 23713 return this._speed; 23714 }; 23715 23716 /** 23717 * Gets the coordinate of an item. 23718 * @todo The name of this method is missleanding. 23719 * @public 23720 * @param {Number} position - The absolute position of the item within `minimum()` and `maximum()`. 23721 * @returns {Number|Array.<Number>} - The coordinate of the item in pixel or all coordinates. 23722 */ 23723 Owl.prototype.coordinates = function(position) { 23724 var coordinate = null; 23725 23726 if (position === undefined) { 23727 return $.map(this._coordinates, $.proxy(function(coordinate, index) { 23728 return this.coordinates(index); 23729 }, this)); 23730 } 23731 23732 if (this.settings.center) { 23733 coordinate = this._coordinates[position]; 23734 coordinate += (this.width() - coordinate + (this._coordinates[position - 1] || 0)) / 2 * (this.settings.rtl ? -1 : 1); 23735 } else { 23736 coordinate = this._coordinates[position - 1] || 0; 23737 } 23738 23739 return coordinate; 23740 }; 23741 23742 /** 23743 * Calculates the speed for a translation. 23744 * @protected 23745 * @param {Number} from - The absolute position of the start item. 23746 * @param {Number} to - The absolute position of the target item. 23747 * @param {Number} [factor=undefined] - The time factor in milliseconds. 23748 * @returns {Number} - The time in milliseconds for the translation. 23749 */ 23750 Owl.prototype.duration = function(from, to, factor) { 23751 return Math.min(Math.max(Math.abs(to - from), 1), 6) * Math.abs((factor || this.settings.smartSpeed)); 23752 }; 23753 23754 /** 23755 * Slides to the specified item. 23756 * @public 23757 * @param {Number} position - The position of the item. 23758 * @param {Number} [speed] - The time in milliseconds for the transition. 23759 */ 23760 Owl.prototype.to = function(position, speed) { 23761 var current = this.current(), 23762 revert = null, 23763 distance = position - this.relative(current), 23764 direction = (distance > 0) - (distance < 0), 23765 items = this._items.length, 23766 minimum = this.minimum(), 23767 maximum = this.maximum(); 23768 23769 if (this.settings.loop) { 23770 if (!this.settings.rewind && Math.abs(distance) > items / 2) { 23771 distance += direction * -1 * items; 23772 } 23773 23774 position = current + distance; 23775 revert = ((position - minimum) % items + items) % items + minimum; 23776 23777 if (revert !== position && revert - distance <= maximum && revert - distance > 0) { 23778 current = revert - distance; 23779 position = revert; 23780 this.reset(current); 23781 } 23782 } else if (this.settings.rewind) { 23783 maximum += 1; 23784 position = (position % maximum + maximum) % maximum; 23785 } else { 23786 position = Math.max(minimum, Math.min(maximum, position)); 23787 } 23788 23789 this.speed(this.duration(current, position, speed)); 23790 this.current(position); 23791 23792 if (this.$element.is(':visible')) { 23793 this.update(); 23794 } 23795 }; 23796 23797 /** 23798 * Slides to the next item. 23799 * @public 23800 * @param {Number}
vendor: 12,284 bytes, lines 23800-24220
23800 [speed] - The time in milliseconds for the transition. 23801 */ 23802 Owl.prototype.next = function(speed) { 23803 speed = speed || false; 23804 this.to(this.relative(this.current()) + 1, speed); 23805 }; 23806 23807 /** 23808 * Slides to the previous item. 23809 * @public 23810 * @param {Number} [speed] - The time in milliseconds for the transition. 23811 */ 23812 Owl.prototype.prev = function(speed) { 23813 speed = speed || false; 23814 this.to(this.relative(this.current()) - 1, speed); 23815 }; 23816 23817 /** 23818 * Handles the end of an animation. 23819 * @protected 23820 * @param {Event} event - The event arguments. 23821 */ 23822 Owl.prototype.onTransitionEnd = function(event) { 23823 23824 // if css2 animation then event object is undefined 23825 if (event !== undefined) { 23826 event.stopPropagation(); 23827 23828 // Catch only owl-stage transitionEnd event 23829 if ((event.target || event.srcElement || event.originalTarget) !== this.$stage.get(0)) { 23830 return false; 23831 } 23832 } 23833 23834 this.leave('animating'); 23835 this.trigger('translated'); 23836 }; 23837 23838 /** 23839 * Gets viewport width. 23840 * @protected 23841 * @return {Number} - The width in pixel. 23842 */ 23843 Owl.prototype.viewport = function() { 23844 var width; 23845 if (this.options.responsiveBaseElement !== window) { 23846 width = $(this.options.responsiveBaseElement).width(); 23847 } else if (window.innerWidth) { 23848 width = window.innerWidth; 23849 } else if (document.documentElement && document.documentElement.clientWidth) { 23850 width = document.documentElement.clientWidth; 23851 } else { 23852 throw 'Can not detect viewport width.'; 23853 } 23854 23855 return width; 23856 }; 23857 23858 /** 23859 * Replaces the current content. 23860 * @public 23861 * @param {HTMLElement|jQuery|String} content - The new content. 23862 */ 23863 Owl.prototype.replace = function(content) { 23864 this.$stage.empty(); 23865 this._items = []; 23866 23867 if (content) { 23868 content = (content instanceof jQuery) ? content : $(content); 23869 } 23870 23871 if (this.settings.nestedItemSelector) { 23872 content = content.find('.' + this.settings.nestedItemSelector); 23873 } 23874 23875 content.filter(function() { 23876 return this.nodeType === 1; 23877 }).each($.proxy(function(index, item) { 23878 item = this.prepare(item, index); 23879 this.$stage.append(item); 23880 this._items.push(item); 23881 this._mergers.push(item.find('[data-merge]').addBack('[data-merge]').attr('data-merge') * 1 || 1); 23882 }, this)); 23883 23884 this.reset($.isNumeric(this.settings.startPosition) ? this.settings.startPosition : 0); 23885 23886 this.invalidate('items'); 23887 }; 23888 23889 /** 23890 * Adds an item. 23891 * @todo Use `item` instead of `content` for the event arguments. 23892 * @public 23893 * @param {HTMLElement|jQuery|String} content - The item content to add. 23894 * @param {Number} [position] - The relative position at which to insert the item otherwise the item will be added to the end. 23895 */ 23896 Owl.prototype.add = function(content, position) { 23897 var current = this.relative(this._current); 23898 23899 position = position === undefined ? this._items.length : this.normalize(position, true); 23900 content = content instanceof jQuery ? content : $(content); 23901 23902 this.trigger('add', { content: content, position: position }); 23903 23904 content = this.prepare(content, this._items[current].index()); 23905 23906 if (this._items.length === 0 || position === this._items.length) { 23907 this._items.length === 0 && this.$stage.append(content); 23908 this._items.length !== 0 && this._items[position - 1].after(content); 23909 this._items.push(content); 23910 this._mergers.push(content.find('[data-merge]').andSelf('[data-merge]').attr('data-merge') * 1 || 1); 23911 } else { 23912 this._items[position].before(content); 23913 this._items.splice(position, 0, content); 23914 this._mergers.splice(position, 0, content.find('[data-merge]').andSelf('[data-merge]').attr('data-merge') * 1 || 1); 23915 } 23916 23917 this._items[current] && this.reset(this._items[current].index()); 23918 23919 this.invalidate('items'); 23920 23921 this.trigger('added', { content: content, position: position }); 23922 }; 23923 23924 /** 23925 * Removes an item by its position. 23926 * @todo Use `item` instead of `content` for the event arguments. 23927 * @public 23928 * @param {Number} position - The relative position of the item to remove. 23929 */ 23930 Owl.prototype.remove = function(position) { 23931 position = this.normalize(position, true); 23932 23933 if (position === undefined) { 23934 return; 23935 } 23936 23937 this.trigger('remove', { content: this._items[position], position: position }); 23938 23939 this._items[position].remove(); 23940 this._items.splice(position, 1); 23941 this._mergers.splice(position, 1); 23942 23943 this.invalidate('items'); 23944 23945 this.trigger('removed', { content: null, position: position }); 23946 }; 23947 23948 /** 23949 * Preloads images with auto width. 23950 * @todo Replace by a more generic approach 23951 * @protected 23952 */ 23953 Owl.prototype.preloadAutoWidthImages = function(images) { 23954 images.each($.proxy(function(i, element) { 23955 this.enter('pre-loading'); 23956 element = $(element); 23957 $(new Image()).one('load', $.proxy(function(e) { 23958 element.attr('src', e.target.src); 23959 element.css('opacity', 1); 23960 this.leave('pre-loading'); 23961 !this.is('pre-loading') && !this.is('initializing') && this.refresh(); 23962 }, this)).attr('src', element.attr('src') || element.attr('data-src') || element.attr('data-src-retina')); 23963 }, this)); 23964 }; 23965 23966 /** 23967 * Destroys the carousel. 23968 * @public 23969 */ 23970 Owl.prototype.destroy = function() { 23971 23972 this.$element.off('.owl.core'); 23973 this.$stage.off('.owl.core'); 23974 $(document).off('.owl.core'); 23975 23976 if (this.settings.responsive !== false) { 23977 window.clearTimeout(this.resizeTimer); 23978 this.off(window, 'resize', this._handlers.onThrottledResize); 23979 } 23980 23981 for (var i in this._plugins) { 23982 this._plugins[i].destroy(); 23983 } 23984 23985 this.$stage.children('.cloned').remove(); 23986 23987 this.$stage.unwrap(); 23988 this.$stage.children().contents().unwrap(); 23989 this.$stage.children().unwrap(); 23990 23991 this.$element 23992 .removeClass(this.options.refreshClass) 23993 .removeClass(this.options.loadingClass) 23994 .removeClass(this.options.loadedClass) 23995 .removeClass(this.options.rtlClass) 23996 .removeClass(this.options.dragClass) 23997 .removeClass(this.options.grabClass) 23998 .attr('class', this.$element.attr('class').replace(new RegExp(this.options.responsiveClass + '-\\S+\\s', 'g'), '')) 23999 .removeData('owl.carousel'); 24000 }; 24001 24002 /** 24003 * Operators to calculate right-to-left and left-to-right. 24004 * @protected 24005 * @param {Number} [a] - The left side operand. 24006 * @param {String} [o] - The operator. 24007 * @param {Number} [b] - The right side operand. 24008 */ 24009 Owl.prototype.op = function(a, o, b) { 24010 var rtl = this.settings.rtl; 24011 switch (o) { 24012 case '<': 24013 return rtl ? a > b : a < b; 24014 case '>': 24015 return rtl ? a < b : a > b; 24016 case '>=': 24017 return rtl ? a <= b : a >= b; 24018 case '<=': 24019 return rtl ? a >= b : a <= b; 24020 default: 24021 break; 24022 } 24023 }; 24024 24025 /** 24026 * Attaches to an internal event. 24027 * @protected 24028 * @param {HTMLElement} element - The event source. 24029 * @param {String} event - The event name. 24030 * @param {Function} listener - The event handler to attach. 24031 * @param {Boolean} capture - Wether the event should be handled at the capturing phase or not. 24032 */ 24033 Owl.prototype.on = function(element, event, listener, capture) { 24034 if (element.addEventListener) { 24035 element.addEventListener(event, listener, capture); 24036 } else if (element.attachEvent) { 24037 element.attachEvent('on' + event, listener); 24038 } 24039 }; 24040 24041 /** 24042 * Detaches from an internal event. 24043 * @protected 24044 * @param {HTMLElement} element - The event source. 24045 * @param {String} event - The event name. 24046 * @param {Function} listener - The attached event handler to detach. 24047 * @param {Boolean} capture - Wether the attached event handler was registered as a capturing listener or not. 24048 */ 24049 Owl.prototype.off = function(element, event, listener, capture) { 24050 if (element.removeEventListener) { 24051 element.removeEventListener(event, listener, capture); 24052 } else if (element.detachEvent) { 24053 element.detachEvent('on' + event, listener); 24054 } 24055 }; 24056 24057 /** 24058 * Triggers a public event. 24059 * @todo Remove `status`, `relatedTarget` should be used instead. 24060 * @protected 24061 * @param {String} name - The event name. 24062 * @param {*} [data=null] - The event data. 24063 * @param {String} [namespace=carousel] - The event namespace. 24064 * @param {String} [state] - The state which is associated with the event. 24065 * @param {Boolean} [enter=false] - Indicates if the call enters the specified state or not. 24066 * @returns {Event} - The event arguments. 24067 */ 24068 Owl.prototype.trigger = function(name, data, namespace, state, enter) { 24069 var status = { 24070 item: { count: this._items.length, index: this.current() } 24071 }, handler = $.camelCase( 24072 $.grep([ 'on', name, namespace ], function(v) { return v }) 24073 .join('-').toLowerCase() 24074 ), event = $.Event( 24075 [ name, 'owl', namespace || 'carousel' ].join('.').toLowerCase(), 24076 $.extend({ relatedTarget: this }, status, data) 24077 ); 24078 24079 if (!this._supress[name]) { 24080 $.each(this._plugins, function(name, plugin) { 24081 if (plugin.onTrigger) { 24082 plugin.onTrigger(event); 24083 } 24084 }); 24085 24086 this.register({ type: Owl.Type.Event, name: name }); 24087 this.$element.trigger(event); 24088 24089 if (this.settings && typeof this.settings[handler] === 'function') { 24090 this.settings[handler].call(this, event); 24091 } 24092 } 24093 24094 return event; 24095 }; 24096 24097 /** 24098 * Enters a state. 24099 * @param name - The state name. 24100 */ 24101 Owl.prototype.enter = function(name) { 24102 $.each([ name ].concat(this._states.tags[name] || []), $.proxy(function(i, name) { 24103 if (this._states.current[name] === undefined) { 24104 this._states.current[name] = 0; 24105 } 24106 24107 this._states.current[name]++; 24108 }, this)); 24109 }; 24110 24111 /** 24112 * Leaves a state. 24113 * @param name - The state name. 24114 */ 24115 Owl.prototype.leave = function(name) { 24116 $.each([ name ].concat(this._states.tags[name] || []), $.proxy(function(i, name) { 24117 this._states.current[name]--; 24118 }, this)); 24119 }; 24120 24121 /** 24122 * Registers an event or state. 24123 * @public 24124 * @param {Object} object - The event or state to register. 24125 */ 24126 Owl.prototype.register = function(object) { 24127 if (object.type === Owl.Type.Event) { 24128 if (!$.event.special[object.name]) { 24129 $.event.special[object.name] = {}; 24130 } 24131 24132 if (!$.event.special[object.name].owl) { 24133 var _default = $.event.special[object.name]._default; 24134 $.event.special[object.name]._default = function(e) { 24135 if (_default && _default.apply && (!e.namespace || e.namespace.indexOf('owl') === -1)) { 24136 return _default.apply(this, arguments); 24137 } 24138 return e.namespace && e.namespace.indexOf('owl') > -1; 24139 }; 24140 $.event.special[object.name].owl = true; 24141 } 24142 } else if (object.type === Owl.Type.State) { 24143 if (!this._states.tags[object.name]) { 24144 this._states.tags[object.name] = object.tags; 24145 } else { 24146 this._states.tags[object.name] = this._states.tags[object.name].concat(object.tags); 24147 } 24148 24149 this._states.tags[object.name] = $.grep(this._states.tags[object.name], $.proxy(function(tag, i) { 24150 return $.inArray(tag, this._states.tags[object.name]) === i; 24151 }, this)); 24152 } 24153 }; 24154 24155 /** 24156 * Suppresses events. 24157 * @protected 24158 * @param {Array.<String>} events - The events to suppress. 24159 */ 24160 Owl.prototype.suppress = function(events) { 24161 $.each(events, $.proxy(function(index, event) { 24162 this._supress[event] = true; 24163 }, this)); 24164 }; 24165 24166 /** 24167 * Releases suppressed events. 24168 * @protected 24169 * @param {Array.<String>} events - The events to release. 24170 */ 24171 Owl.prototype.release = function(events) { 24172 $.each(events, $.proxy(function(index, event) { 24173 delete this._supress[event]; 24174 }, this)); 24175 }; 24176 24177 /** 24178 * Gets unified pointer coordinates from event. 24179 * @todo #261 24180 * @protected 24181 * @param {Event} - The `mousedown` or `touchstart` event. 24182 * @returns {Object} - Contains `x` and `y` coordinates of current pointer position. 24183 */ 24184 Owl.prototype.pointer = function(event) { 24185 var result = { x: null, y: null }; 24186 24187 event = event.originalEvent || event || window.event; 24188 24189 event = event.touches && event.touches.length ? 24190 event.touches[0] : event.changedTouches && event.changedTouches.length ? 24191 event.changedTouches[0] : event; 24192 24193 if (event.pageX) { 24194 result.x = event.pageX; 24195 result.y = event.pageY; 24196 } else { 24197 result.x = event.clientX; 24198 result.y = event.clientY; 24199 } 24200 24201 return result; 24202 }; 24203 24204 /** 24205 * Gets the difference of two vectors. 24206 * @todo #261 24207 * @protected 24208 * @param {Object} - The first vector. 24209 * @param {Object} - The second vector. 24210 * @returns {Object} - The difference. 24211 */ 24212 Owl.prototype.difference = function(first, second) { 24213 return { 24214 x: first.x - second.x, 24215 y: first.y - second.y 24216 }; 24217 }; 24218 24219 /** 24220 * The jQuery Plugin for the Owl Carousel
vendor: 32,216 bytes, lines 24221-25503
24221 * @todo Navigation plugin `next` and `prev` 24222 * @public 24223 */ 24224 $.fn.owlCarousel = function(option) { 24225 var args = Array.prototype.slice.call(arguments, 1); 24226 24227 return this.each(function() { 24228 var $this = $(this), 24229 data = $this.data('owl.carousel'); 24230 24231 if (!data) { 24232 data = new Owl(this, typeof option == 'object' && option); 24233 $this.data('owl.carousel', data); 24234 24235 $.each([ 24236 'next', 'prev', 'to', 'destroy', 'refresh', 'replace', 'add', 'remove' 24237 ], function(i, event) { 24238 data.register({ type: Owl.Type.Event, name: event }); 24239 data.$element.on(event + '.owl.carousel.core', $.proxy(function(e) { 24240 if (e.namespace && e.relatedTarget !== this) { 24241 this.suppress([ event ]); 24242 data[event].apply(this, [].slice.call(arguments, 1)); 24243 this.release([ event ]); 24244 } 24245 }, data)); 24246 }); 24247 } 24248 24249 if (typeof option == 'string' && option.charAt(0) !== '_') { 24250 data[option].apply(data, args); 24251 } 24252 }); 24253 }; 24254 24255 /** 24256 * The constructor for the jQuery Plugin 24257 * @public 24258 */ 24259 $.fn.owlCarousel.Constructor = Owl; 24260 24261})(window.Zepto || window.jQuery, window, document); 24262 24263/** 24264 * AutoRefresh Plugin 24265 * @version 2.0.0-beta.3 24266 * @author Artus Kolanowski 24267 * @license The MIT License (MIT) 24268 */ 24269;(function($, window, document, undefined) { 24270 24271 /** 24272 * Creates the auto refresh plugin. 24273 * @class The Auto Refresh Plugin 24274 * @param {Owl} carousel - The Owl Carousel 24275 */ 24276 var AutoRefresh = function(carousel) { 24277 /** 24278 * Reference to the core. 24279 * @protected 24280 * @type {Owl} 24281 */ 24282 this._core = carousel; 24283 24284 /** 24285 * Refresh interval. 24286 * @protected 24287 * @type {number} 24288 */ 24289 this._interval = null; 24290 24291 /** 24292 * Whether the element is currently visible or not. 24293 * @protected 24294 * @type {Boolean} 24295 */ 24296 this._visible = null; 24297 24298 /** 24299 * All event handlers. 24300 * @protected 24301 * @type {Object} 24302 */ 24303 this._handlers = { 24304 'initialized.owl.carousel': $.proxy(function(e) { 24305 if (e.namespace && this._core.settings.autoRefresh) { 24306 this.watch(); 24307 } 24308 }, this) 24309 }; 24310 24311 // set default options 24312 this._core.options = $.extend({}, AutoRefresh.Defaults, this._core.options); 24313 24314 // register event handlers 24315 this._core.$element.on(this._handlers); 24316 }; 24317 24318 /** 24319 * Default options. 24320 * @public 24321 */ 24322 AutoRefresh.Defaults = { 24323 autoRefresh: true, 24324 autoRefreshInterval: 500 24325 }; 24326 24327 /** 24328 * Watches the element. 24329 */ 24330 AutoRefresh.prototype.watch = function() { 24331 if (this._interval) { 24332 return; 24333 } 24334 24335 this._visible = this._core.$element.is(':visible'); 24336 this._interval = window.setInterval($.proxy(this.refresh, this), this._core.settings.autoRefreshInterval); 24337 }; 24338 24339 /** 24340 * Refreshes the element. 24341 */ 24342 AutoRefresh.prototype.refresh = function() { 24343 if (this._core.$element.is(':visible') === this._visible) { 24344 return; 24345 } 24346 24347 this._visible = !this._visible; 24348 24349 this._core.$element.toggleClass('owl-hidden', !this._visible); 24350 24351 this._visible && (this._core.invalidate('width') && this._core.refresh()); 24352 }; 24353 24354 /** 24355 * Destroys the plugin. 24356 */ 24357 AutoRefresh.prototype.destroy = function() { 24358 var handler, property; 24359 24360 window.clearInterval(this._interval); 24361 24362 for (handler in this._handlers) { 24363 this._core.$element.off(handler, this._handlers[handler]); 24364 } 24365 for (property in Object.getOwnPropertyNames(this)) { 24366 typeof this[property] != 'function' && (this[property] = null); 24367 } 24368 }; 24369 24370 $.fn.owlCarousel.Constructor.Plugins.AutoRefresh = AutoRefresh; 24371 24372})(window.Zepto || window.jQuery, window, document); 24373 24374/** 24375 * Lazy Plugin 24376 * @version 2.0.0-beta.3 24377 * @author Bartosz Wojciechowski 24378 * @license The MIT License (MIT) 24379 */ 24380;(function($, window, document, undefined) { 24381 24382 /** 24383 * Creates the lazy plugin. 24384 * @class The Lazy Plugin 24385 * @param {Owl} carousel - The Owl Carousel 24386 */ 24387 var Lazy = function(carousel) { 24388 24389 /** 24390 * Reference to the core. 24391 * @protected 24392 * @type {Owl} 24393 */ 24394 this._core = carousel; 24395 24396 /** 24397 * Already loaded items. 24398 * @protected 24399 * @type {Array.<jQuery>} 24400 */ 24401 this._loaded = []; 24402 24403 /** 24404 * Event handlers. 24405 * @protected 24406 * @type {Object} 24407 */ 24408 this._handlers = { 24409 'initialized.owl.carousel change.owl.carousel': $.proxy(function(e) { 24410 if (!e.namespace) { 24411 return; 24412 } 24413 24414 if (!this._core.settings || !this._core.settings.lazyLoad) { 24415 return; 24416 } 24417 24418 if ((e.property && e.property.name == 'position') || e.type == 'initialized') { 24419 var settings = this._core.settings, 24420 n = (settings.center && Math.ceil(settings.items / 2) || settings.items), 24421 i = ((settings.center && n * -1) || 0), 24422 position = ((e.property && e.property.value) || this._core.current()) + i, 24423 clones = this._core.clones().length, 24424 load = $.proxy(function(i, v) { this.load(v) }, this); 24425 24426 while (i++ < n) { 24427 this.load(clones / 2 + this._core.relative(position)); 24428 clones && $.each(this._core.clones(this._core.relative(position)), load); 24429 position++; 24430 } 24431 } 24432 }, this) 24433 }; 24434 24435 // set the default options 24436 this._core.options = $.extend({}, Lazy.Defaults, this._core.options); 24437 24438 // register event handler 24439 this._core.$element.on(this._handlers); 24440 } 24441 24442 /** 24443 * Default options. 24444 * @public 24445 */ 24446 Lazy.Defaults = { 24447 lazyLoad: false 24448 } 24449 24450 /** 24451 * Loads all resources of an item at the specified position. 24452 * @param {Number} position - The absolute position of the item. 24453 * @protected 24454 */ 24455 Lazy.prototype.load = function(position) { 24456 var $item = this._core.$stage.children().eq(position), 24457 $elements = $item && $item.find('.owl-lazy'); 24458 24459 if (!$elements || $.inArray($item.get(0), this._loaded) > -1) { 24460 return; 24461 } 24462 24463 $elements.each($.proxy(function(index, element) { 24464 var $element = $(element), image, 24465 url = (window.devicePixelRatio > 1 && $element.attr('data-src-retina')) || $element.attr('data-src'); 24466 24467 this._core.trigger('load', { element: $element, url: url }, 'lazy'); 24468 24469 if ($element.is('img')) { 24470 $element.one('load.owl.lazy', $.proxy(function() { 24471 $element.css('opacity', 1); 24472 this._core.trigger('loaded', { element: $element, url: url }, 'lazy'); 24473 }, this)).attr('src', url); 24474 } else { 24475 image = new Image(); 24476 image.onload = $.proxy(function() { 24477 $element.css({ 24478 'background-image': 'url(' + url + ')', 24479 'opacity': '1' 24480 }); 24481 this._core.trigger('loaded', { element: $element, url: url }, 'lazy'); 24482 }, this); 24483 image.src = url; 24484 } 24485 }, this)); 24486 24487 this._loaded.push($item.get(0)); 24488 } 24489 24490 /** 24491 * Destroys the plugin. 24492 * @public 24493 */ 24494 Lazy.prototype.destroy = function() { 24495 var handler, property; 24496 24497 for (handler in this.handlers) { 24498 this._core.$element.off(handler, this.handlers[handler]); 24499 } 24500 for (property in Object.getOwnPropertyNames(this)) { 24501 typeof this[property] != 'function' && (this[property] = null); 24502 } 24503 }; 24504 24505 $.fn.owlCarousel.Constructor.Plugins.Lazy = Lazy; 24506 24507})(window.Zepto || window.jQuery, window, document); 24508 24509/** 24510 * AutoHeight Plugin 24511 * @version 2.0.0-beta.3 24512 * @author Bartosz Wojciechowski 24513 * @license The MIT License (MIT) 24514 */ 24515;(function($, window, document, undefined) { 24516 24517 /** 24518 * Creates the auto height plugin. 24519 * @class The Auto Height Plugin 24520 * @param {Owl} carousel - The Owl Carousel 24521 */ 24522 var AutoHeight = function(carousel) { 24523 /** 24524 * Reference to the core. 24525 * @protected 24526 * @type {Owl} 24527 */ 24528 this._core = carousel; 24529 24530 /** 24531 * All event handlers. 24532 * @protected 24533 * @type {Object} 24534 */ 24535 this._handlers = { 24536 'initialized.owl.carousel refreshed.owl.carousel': $.proxy(function(e) { 24537 if (e.namespace && this._core.settings.autoHeight) { 24538 this.update(); 24539 } 24540 }, this), 24541 'changed.owl.carousel': $.proxy(function(e) { 24542 if (e.namespace && this._core.settings.autoHeight && e.property.name == 'position'){ 24543 this.update(); 24544 } 24545 }, this), 24546 'loaded.owl.lazy': $.proxy(function(e) { 24547 if (e.namespace && this._core.settings.autoHeight 24548 && e.element.closest('.' + this._core.settings.itemClass).index() === this._core.current()) { 24549 this.update(); 24550 } 24551 }, this) 24552 }; 24553 24554 // set default options 24555 this._core.options = $.extend({}, AutoHeight.Defaults, this._core.options); 24556 24557 // register event handlers 24558 this._core.$element.on(this._handlers); 24559 }; 24560 24561 /** 24562 * Default options. 24563 * @public 24564 */ 24565 AutoHeight.Defaults = { 24566 autoHeight: false, 24567 autoHeightClass: 'owl-height' 24568 }; 24569 24570 /** 24571 * Updates the view. 24572 */ 24573 AutoHeight.prototype.update = function() { 24574 var start = this._core._current, 24575 end = start + this._core.settings.items, 24576 visible = this._core.$stage.children().toArray().slice(start, end); 24577 heights = [], 24578 maxheight = 0; 24579 24580 $.each(visible, function(index, item) { 24581 heights.push($(item).height()); 24582 }); 24583 24584 maxheight = Math.max.apply(null, heights); 24585 24586 this._core.$stage.parent() 24587 .height(maxheight) 24588 .addClass(this._core.settings.autoHeightClass); 24589 }; 24590 24591 AutoHeight.prototype.destroy = function() { 24592 var handler, property; 24593 24594 for (handler in this._handlers) { 24595 this._core.$element.off(handler, this._handlers[handler]); 24596 } 24597 for (property in Object.getOwnPropertyNames(this)) { 24598 typeof this[property] != 'function' && (this[property] = null); 24599 } 24600 }; 24601 24602 $.fn.owlCarousel.Constructor.Plugins.AutoHeight = AutoHeight; 24603 24604})(window.Zepto || window.jQuery, window, document); 24605 24606/** 24607 * Video Plugin 24608 * @version 2.0.0-beta.3 24609 * @author Bartosz Wojciechowski 24610 * @license The MIT License (MIT) 24611 */ 24612;(function($, window, document, undefined) { 24613 24614 /** 24615 * Creates the video plugin. 24616 * @class The Video Plugin 24617 * @param {Owl} carousel - The Owl Carousel 24618 */ 24619 var Video = function(carousel) { 24620 /** 24621 * Reference to the core. 24622 * @protected 24623 * @type {Owl} 24624 */ 24625 this._core = carousel; 24626 24627 /** 24628 * Cache all video URLs. 24629 * @protected 24630 * @type {Object} 24631 */ 24632 this._videos = {}; 24633 24634 /** 24635 * Current playing item. 24636 * @protected 24637 * @type {jQuery} 24638 */ 24639 this._playing = null; 24640 24641 /** 24642 * All event handlers. 24643 * @todo The cloned content removale is too late 24644 * @protected 24645 * @type {Object} 24646 */ 24647 this._handlers = { 24648 'initialized.owl.carousel': $.proxy(function(e) { 24649 if (e.namespace) { 24650 this._core.register({ type: 'state', name: 'playing', tags: [ 'interacting' ] }); 24651 } 24652 }, this), 24653 'resize.owl.carousel': $.proxy(function(e) { 24654 if (e.namespace && this._core.settings.video && this.isInFullScreen()) { 24655 e.preventDefault(); 24656 } 24657 }, this), 24658 'refreshed.owl.carousel': $.proxy(function(e) { 24659 if (e.namespace && this._core.is('resizing')) { 24660 this._core.$stage.find('.cloned .owl-video-frame').remove(); 24661 } 24662 }, this), 24663 'changed.owl.carousel': $.proxy(function(e) { 24664 if (e.namespace && e.property.name === 'position' && this._playing) { 24665 this.stop(); 24666 } 24667 }, this), 24668 'prepared.owl.carousel': $.proxy(function(e) { 24669 if (!e.namespace) { 24670 return; 24671 } 24672 24673 var $element = $(e.content).find('.owl-video'); 24674 24675 if ($element.length) { 24676 $element.css('display', 'none'); 24677 this.fetch($element, $(e.content)); 24678 } 24679 }, this) 24680 }; 24681 24682 // set default options 24683 this._core.options = $.extend({}, Video.Defaults, this._core.options); 24684 24685 // register event handlers 24686 this._core.$element.on(this._handlers); 24687 24688 this._core.$element.on('click.owl.video', '.owl-video-play-icon', $.proxy(function(e) { 24689 this.play(e); 24690 }, this)); 24691 }; 24692 24693 /** 24694 * Default options. 24695 * @public 24696 */ 24697 Video.Defaults = { 24698 video: false, 24699 videoHeight: false, 24700 videoWidth: false 24701 }; 24702 24703 /** 24704 * Gets the video ID and the type (YouTube/Vimeo only). 24705 * @protected 24706 * @param {jQuery} target - The target containing the video data. 24707 * @param {jQuery} item - The item containing the video. 24708 */ 24709 Video.prototype.fetch = function(target, item) { 24710 var type = target.attr('data-vimeo-id') ? 'vimeo' : 'youtube', 24711 id = target.attr('data-vimeo-id') || target.attr('data-youtube-id'), 24712 width = target.attr('data-width') || this._core.settings.videoWidth, 24713 height = target.attr('data-height') || this._core.settings.videoHeight, 24714 url = target.attr('href'); 24715 24716 if (url) { 24717 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+)?/); 24718 24719 if (id[3].indexOf('youtu') > -1) { 24720 type = 'youtube'; 24721 } else if (id[3].indexOf('vimeo') > -1) { 24722 type = 'vimeo'; 24723 } else { 24724 throw new Error('Video URL not supported.'); 24725 } 24726 id = id[6]; 24727 } else { 24728 throw new Error('Missing video URL.'); 24729 } 24730 24731 this._videos[url] = { 24732 type: type, 24733 id: id, 24734 width: width, 24735 height: height 24736 }; 24737 24738 item.attr('data-video', url); 24739 24740 this.thumbnail(target, this._videos[url]); 24741 }; 24742 24743 /** 24744 * Creates video thumbnail. 24745 * @protected 24746 * @param {jQuery} target - The target containing the video data. 24747 * @param {Object} info - The video info object. 24748 * @see `fetch` 24749 */ 24750 Video.prototype.thumbnail = function(target, video) { 24751 var tnLink, 24752 icon, 24753 path, 24754 dimensions = video.width && video.height ? 'style="width:' + video.width + 'px;height:' + video.height + 'px;"' : '', 24755 customTn = target.find('img'), 24756 srcType = 'src', 24757 lazyClass = '', 24758 settings = this._core.settings, 24759 create = function(path) { 24760 icon = '<div class="owl-video-play-icon"></div>'; 24761 24762 if (settings.lazyLoad) { 24763 tnLink = '<div class="owl-video-tn ' + lazyClass + '" ' + srcType + '="' + path + '"></div>'; 24764 } else { 24765 tnLink = '<div class="owl-video-tn" style="opacity:1;background-image:url(' + path + ')"></div>'; 24766 } 24767 target.after(tnLink); 24768 target.after(icon); 24769 }; 24770 24771 // wrap video content into owl-video-wrapper div 24772 target.wrap('<div class="owl-video-wrapper"' + dimensions + '></div>'); 24773 24774 if (this._core.settings.lazyLoad) { 24775 srcType = 'data-src'; 24776 lazyClass = 'owl-lazy'; 24777 } 24778 24779 // custom thumbnail 24780 if (customTn.length) { 24781 create(customTn.attr(srcType)); 24782 customTn.remove(); 24783 return false; 24784 } 24785 24786 if (video.type === 'youtube') { 24787 path = "//img.youtube.com/vi/" + video.id + "/hqdefault.jpg"; 24788 create(path); 24789 } else if (video.type === 'vimeo') { 24790 $.ajax({ 24791 type: 'GET', 24792 url: '//vimeo.com/api/v2/video/' + video.id + '.json', 24793 jsonp: 'callback', 24794 dataType: 'jsonp', 24795 success: function(data) { 24796 path = data[0].thumbnail_large; 24797 create(path); 24798 } 24799 }); 24800 } 24801 }; 24802 24803 /** 24804 * Stops the current video. 24805 * @public 24806 */ 24807 Video.prototype.stop = function() { 24808 this._core.trigger('stop', null, 'video'); 24809 this._playing.find('.owl-video-frame').remove(); 24810 this._playing.removeClass('owl-video-playing'); 24811 this._playing = null; 24812 this._core.leave('playing'); 24813 this._core.trigger('stopped', null, 'video'); 24814 }; 24815 24816 /** 24817 * Starts the current video. 24818 * @public 24819 * @param {Event} event - The event arguments. 24820 */ 24821 Video.prototype.play = function(event) { 24822 var target = $(event.target), 24823 item = target.closest('.' + this._core.settings.itemClass), 24824 video = this._videos[item.attr('data-video')], 24825 width = video.width || '100%', 24826 height = video.height || this._core.$stage.height(), 24827 html; 24828 24829 if (this._playing) { 24830 return; 24831 } 24832 24833 this._core.enter('playing'); 24834 this._core.trigger('play', null, 'video'); 24835 24836 item = this._core.items(this._core.relative(item.index())); 24837 24838 this._core.reset(item.index()); 24839 24840 if (video.type === 'youtube') { 24841 html = '<iframe width="' + width + '" height="' + height + '" src="//www.youtube.com/embed/' + 24842 video.id + '?autoplay=1&v=' + video.id + '" frameborder="0" allowfullscreen></iframe>'; 24843 } else if (video.type === 'vimeo') { 24844 html = '<iframe src="//player.vimeo.com/video/' + video.id + 24845 '?autoplay=1" width="' + width + '" height="' + height + 24846 '" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>'; 24847 } 24848 24849 $('<div class="owl-video-frame">' + html + '</div>').insertAfter(item.find('.owl-video')); 24850 24851 this._playing = item.addClass('owl-video-playing'); 24852 }; 24853 24854 /** 24855 * Checks whether an video is currently in full screen mode or not. 24856 * @todo Bad style because looks like a readonly method but changes members. 24857 * @protected 24858 * @returns {Boolean} 24859 */ 24860 Video.prototype.isInFullScreen = function() { 24861 var element = document.fullscreenElement || document.mozFullScreenElement || 24862 document.webkitFullscreenElement; 24863 24864 return element && $(element).parent().hasClass('owl-video-frame'); 24865 }; 24866 24867 /** 24868 * Destroys the plugin. 24869 */ 24870 Video.prototype.destroy = function() { 24871 var handler, property; 24872 24873 this._core.$element.off('click.owl.video'); 24874 24875 for (handler in this._handlers) { 24876 this._core.$element.off(handler, this._handlers[handler]); 24877 } 24878 for (property in Object.getOwnPropertyNames(this)) { 24879 typeof this[property] != 'function' && (this[property] = null); 24880 } 24881 }; 24882 24883 $.fn.owlCarousel.Constructor.Plugins.Video = Video; 24884 24885})(window.Zepto || window.jQuery, window, document); 24886 24887/** 24888 * Animate Plugin 24889 * @version 2.0.0-beta.3 24890 * @author Bartosz Wojciechowski 24891 * @license The MIT License (MIT) 24892 */ 24893;(function($, window, document, undefined) { 24894 24895 /** 24896 * Creates the animate plugin. 24897 * @class The Navigation Plugin 24898 * @param {Owl} scope - The Owl Carousel 24899 */ 24900 var Animate = function(scope) { 24901 this.core = scope; 24902 this.core.options = $.extend({}, Animate.Defaults, this.core.options); 24903 this.swapping = true; 24904 this.previous = undefined; 24905 this.next = undefined; 24906 24907 this.handlers = { 24908 'change.owl.carousel': $.proxy(function(e) { 24909 if (e.namespace && e.property.name == 'position') { 24910 this.previous = this.core.current(); 24911 this.next = e.property.value; 24912 } 24913 }, this), 24914 'drag.owl.carousel dragged.owl.carousel translated.owl.carousel': $.proxy(function(e) { 24915 if (e.namespace) { 24916 this.swapping = e.type == 'translated'; 24917 } 24918 }, this), 24919 'translate.owl.carousel': $.proxy(function(e) { 24920 if (e.namespace && this.swapping && (this.core.options.animateOut || this.core.options.animateIn)) { 24921 this.swap(); 24922 } 24923 }, this) 24924 }; 24925 24926 this.core.$element.on(this.handlers); 24927 }; 24928 24929 /** 24930 * Default options. 24931 * @public 24932 */ 24933 Animate.Defaults = { 24934 animateOut: false, 24935 animateIn: false 24936 }; 24937 24938 /** 24939 * Toggles the animation classes whenever an translations starts. 24940 * @protected 24941 * @returns {Boolean|undefined} 24942 */ 24943 Animate.prototype.swap = function() { 24944 24945 if (this.core.settings.items !== 1) { 24946 return; 24947 } 24948 24949 if (!$.support.animation || !$.support.transition) { 24950 return; 24951 } 24952 24953 this.core.speed(0); 24954 24955 var left, 24956 clear = $.proxy(this.clear, this), 24957 previous = this.core.$stage.children().eq(this.previous), 24958 next = this.core.$stage.children().eq(this.next), 24959 incoming = this.core.settings.animateIn, 24960 outgoing = this.core.settings.animateOut; 24961 24962 if (this.core.current() === this.previous) { 24963 return; 24964 } 24965 24966 if (outgoing) { 24967 left = this.core.coordinates(this.previous) - this.core.coordinates(this.next); 24968 previous.css( { 'left': left + 'px' } ) 24969 .addClass('animated owl-animated-out') 24970 .addClass(outgoing) 24971 .on($.support.animation.end, clear); 24972 } 24973 24974 if (incoming) { 24975 next.addClass('animated owl-animated-in') 24976 .addClass(incoming) 24977 .on($.support.animation.end, clear); 24978 } 24979 }; 24980 24981 Animate.prototype.clear = function(e) { 24982 if ($(e.target).hasClass('animated')) { 24983 $(e.target).css( { 'left': '' } ) 24984 .removeClass('animated owl-animated-out owl-animated-in') 24985 .removeClass(this.core.settings.animateIn) 24986 .removeClass(this.core.settings.animateOut); 24987 this.core.onTransitionEnd(); 24988 } 24989 }; 24990 24991 /** 24992 * Destroys the plugin. 24993 * @public 24994 */ 24995 Animate.prototype.destroy = function() { 24996 var handler, property; 24997 24998 for (handler in this.handlers) { 24999 this.core.$element.off(handler, this.handlers[handler]); 25000 } 25001 for (property in Object.getOwnPropertyNames(this)) { 25002 typeof this[property] != 'function' && (this[property] = null); 25003 } 25004 }; 25005 25006 $.fn.owlCarousel.Constructor.Plugins.Animate = Animate; 25007 25008})(window.Zepto || window.jQuery, window, document); 25009 25010/** 25011 * Autoplay Plugin 25012 * @version 2.0.0-beta.3 25013 * @author Bartosz Wojciechowski 25014 * @author Artus Kolanowski 25015 * @license The MIT License (MIT) 25016 */ 25017;(function($, window, document, undefined) { 25018 25019 /** 25020 * Creates the autoplay plugin. 25021 * @class The Autoplay Plugin 25022 * @param {Owl} scope - The Owl Carousel 25023 */ 25024 var Autoplay = function(carousel) { 25025 /** 25026 * Reference to the core. 25027 * @protected 25028 * @type {Owl} 25029 */ 25030 this._core = carousel; 25031 25032 /** 25033 * The autoplay interval. 25034 * @type {Number} 25035 */ 25036 this._interval = null; 25037 25038 /** 25039 * Indicates whenever the autoplay is paused. 25040 * @type {Boolean} 25041 */ 25042 this._paused = false; 25043 25044 /** 25045 * All event handlers. 25046 * @protected 25047 * @type {Object} 25048 */ 25049 this._handlers = { 25050 'changed.owl.carousel': $.proxy(function(e) { 25051 if (e.namespace && e.property.name === 'settings') { 25052 if (this._core.settings.autoplay) { 25053 this.play(); 25054 } else { 25055 this.stop(); 25056 } 25057 } 25058 }, this), 25059 'initialized.owl.carousel': $.proxy(function(e) { 25060 if (e.namespace && this._core.settings.autoplay) { 25061 this.play(); 25062 } 25063 }, this), 25064 'play.owl.autoplay': $.proxy(function(e, t, s) { 25065 if (e.namespace) { 25066 this.play(t, s); 25067 } 25068 }, this), 25069 'stop.owl.autoplay': $.proxy(function(e) { 25070 if (e.namespace) { 25071 this.stop(); 25072 } 25073 }, this), 25074 'mouseover.owl.autoplay': $.proxy(function() { 25075 if (this._core.settings.autoplayHoverPause && this._core.is('rotating')) { 25076 this.pause(); 25077 } 25078 }, this), 25079 'mouseleave.owl.autoplay': $.proxy(function() { 25080 if (this._core.settings.autoplayHoverPause && this._core.is('rotating')) { 25081 this.play(); 25082 } 25083 }, this) 25084 }; 25085 25086 // register event handlers 25087 this._core.$element.on(this._handlers); 25088 25089 // set default options 25090 this._core.options = $.extend({}, Autoplay.Defaults, this._core.options); 25091 }; 25092 25093 /** 25094 * Default options. 25095 * @public 25096 */ 25097 Autoplay.Defaults = { 25098 autoplay: false, 25099 autoplayTimeout: 5000, 25100 autoplayHoverPause: false, 25101 autoplaySpeed: false 25102 }; 25103 25104 /** 25105 * Starts the autoplay. 25106 * @public 25107 * @param {Number} [timeout] - The interval before the next animation starts. 25108 * @param {Number} [speed] - The animation speed for the animations. 25109 */ 25110 Autoplay.prototype.play = function(timeout, speed) { 25111 this._paused = false; 25112 25113 if (this._core.is('rotating')) { 25114 return; 25115 } 25116 25117 this._core.enter('rotating'); 25118 25119 this._interval = window.setInterval($.proxy(function() { 25120 if (this._paused || this._core.is('busy') || this._core.is('interacting') || document.hidden) { 25121 return; 25122 } 25123 this._core.next(speed || this._core.settings.autoplaySpeed); 25124 }, this), timeout || this._core.settings.autoplayTimeout); 25125 }; 25126 25127 /** 25128 * Stops the autoplay. 25129 * @public 25130 */ 25131 Autoplay.prototype.stop = function() { 25132 if (!this._core.is('rotating')) { 25133 return; 25134 } 25135 25136 window.clearInterval(this._interval); 25137 this._core.leave('rotating'); 25138 }; 25139 25140 /** 25141 * Stops the autoplay. 25142 * @public 25143 */ 25144 Autoplay.prototype.pause = function() { 25145 if (!this._core.is('rotating')) { 25146 return; 25147 } 25148 25149 this._paused = true; 25150 }; 25151 25152 /** 25153 * Destroys the plugin. 25154 */ 25155 Autoplay.prototype.destroy = function() { 25156 var handler, property; 25157 25158 this.stop(); 25159 25160 for (handler in this._handlers) { 25161 this._core.$element.off(handler, this._handlers[handler]); 25162 } 25163 for (property in Object.getOwnPropertyNames(this)) { 25164 typeof this[property] != 'function' && (this[property] = null); 25165 } 25166 }; 25167 25168 $.fn.owlCarousel.Constructor.Plugins.autoplay = Autoplay; 25169 25170})(window.Zepto || window.jQuery, window, document); 25171 25172/** 25173 * Navigation Plugin 25174 * @version 2.0.0-beta.3 25175 * @author Artus Kolanowski 25176 * @license The MIT License (MIT) 25177 */ 25178;(function($, window, document, undefined) { 25179 'use strict'; 25180 25181 /** 25182 * Creates the navigation plugin. 25183 * @class The Navigation Plugin 25184 * @param {Owl} carousel - The Owl Carousel. 25185 */ 25186 var Navigation = function(carousel) { 25187 /** 25188 * Reference to the core. 25189 * @protected 25190 * @type {Owl} 25191 */ 25192 this._core = carousel; 25193 25194 /** 25195 * Indicates whether the plugin is initialized or not. 25196 * @protected 25197 * @type {Boolean} 25198 */ 25199 this._initialized = false; 25200 25201 /** 25202 * The current paging indexes. 25203 * @protected 25204 * @type {Array} 25205 */ 25206 this._pages = []; 25207 25208 /** 25209 * All DOM elements of the user interface. 25210 * @protected 25211 * @type {Object} 25212 */ 25213 this._controls = {}; 25214 25215 /** 25216 * Markup for an indicator. 25217 * @protected 25218 * @type {Array.<String>} 25219 */ 25220 this._templates = []; 25221 25222 /** 25223 * The carousel element. 25224 * @type {jQuery} 25225 */ 25226 this.$element = this._core.$element; 25227 25228 /** 25229 * Overridden methods of the carousel. 25230 * @protected 25231 * @type {Object} 25232 */ 25233 this._overrides = { 25234 next: this._core.next, 25235 prev: this._core.prev, 25236 to: this._core.to 25237 }; 25238 25239 /** 25240 * All event handlers. 25241 * @protected 25242 * @type {Object} 25243 */ 25244 this._handlers = { 25245 'prepared.owl.carousel': $.proxy(function(e) { 25246 if (e.namespace && this._core.settings.dotsData) { 25247 this._templates.push('<div class="' + this._core.settings.dotClass + '">' + 25248 $(e.content).find('[data-dot]').andSelf('[data-dot]').attr('data-dot') + '</div>'); 25249 } 25250 }, this), 25251 'added.owl.carousel': $.proxy(function(e) { 25252 if (e.namespace && this._core.settings.dotsData) { 25253 this._templates.splice(e.position, 0, this._templates.pop()); 25254 } 25255 }, this), 25256 'remove.owl.carousel': $.proxy(function(e) { 25257 if (e.namespace && this._core.settings.dotsData) { 25258 this._templates.splice(e.position, 1); 25259 } 25260 }, this), 25261 'changed.owl.carousel': $.proxy(function(e) { 25262 if (e.namespace && e.property.name == 'position') { 25263 this.draw(); 25264 } 25265 }, this), 25266 'initialized.owl.carousel': $.proxy(function(e) { 25267 if (e.namespace && !this._initialized) { 25268 this._core.trigger('initialize', null, 'navigation'); 25269 this.initialize(); 25270 this.update(); 25271 this.draw(); 25272 this._initialized = true; 25273 this._core.trigger('initialized', null, 'navigation'); 25274 } 25275 }, this), 25276 'refreshed.owl.carousel': $.proxy(function(e) { 25277 if (e.namespace && this._initialized) { 25278 this._core.trigger('refresh', null, 'navigation'); 25279 this.update(); 25280 this.draw(); 25281 this._core.trigger('refreshed', null, 'navigation'); 25282 } 25283 }, this) 25284 }; 25285 25286 // set default options 25287 this._core.options = $.extend({}, Navigation.Defaults, this._core.options); 25288 25289 // register event handlers 25290 this.$element.on(this._handlers); 25291 }; 25292 25293 /** 25294 * Default options. 25295 * @public 25296 * @todo Rename `slideBy` to `navBy` 25297 */ 25298 Navigation.Defaults = { 25299 nav: false, 25300 navText: [ 'prev', 'next' ], 25301 navSpeed: false, 25302 navElement: 'div', 25303 navContainer: false, 25304 navContainerClass: 'owl-nav', 25305 navClass: [ 'owl-prev', 'owl-next' ], 25306 slideBy: 1, 25307 dotClass: 'owl-dot', 25308 dotsClass: 'owl-dots', 25309 dots: true, 25310 dotsEach: false, 25311 dotsData: false, 25312 dotsSpeed: false, 25313 dotsContainer: false 25314 }; 25315 25316 /** 25317 * Initializes the layout of the plugin and extends the carousel. 25318 * @protected 25319 */ 25320 Navigation.prototype.initialize = function() { 25321 var override, 25322 settings = this._core.settings; 25323 25324 // create DOM structure for relative navigation 25325 this._controls.$relative = (settings.navContainer ? $(settings.navContainer) 25326 : $('<div>').addClass(settings.navContainerClass).appendTo(this.$element)).addClass('disabled'); 25327 25328 this._controls.$previous = $('<' + settings.navElement + '>') 25329 .addClass(settings.navClass[0]) 25330 .html(settings.navText[0]) 25331 .prependTo(this._controls.$relative) 25332 .on('click', $.proxy(function(e) { 25333 this.prev(settings.navSpeed); 25334 }, this)); 25335 this._controls.$next = $('<' + settings.navElement + '>') 25336 .addClass(settings.navClass[1]) 25337 .html(settings.navText[1]) 25338 .appendTo(this._controls.$relative) 25339 .on('click', $.proxy(function(e) { 25340 this.next(settings.navSpeed); 25341 }, this)); 25342 25343 // create DOM structure for absolute navigation 25344 if (!settings.dotsData) { 25345 this._templates = [ $('<div>') 25346 .addClass(settings.dotClass) 25347 .append($('<span>')) 25348 .prop('outerHTML') ]; 25349 } 25350 25351 this._controls.$absolute = (settings.dotsContainer ? $(settings.dotsContainer) 25352 : $('<div>').addClass(settings.dotsClass).appendTo(this.$element)).addClass('disabled'); 25353 25354 this._controls.$absolute.on('click', 'div', $.proxy(function(e) { 25355 var index = $(e.target).parent().is(this._controls.$absolute) 25356 ? $(e.target).index() : $(e.target).parent().index(); 25357 25358 e.preventDefault(); 25359 25360 this.to(index, settings.dotsSpeed); 25361 }, this)); 25362 25363 // override public methods of the carousel 25364 for (override in this._overrides) { 25365 this._core[override] = $.proxy(this[override], this); 25366 } 25367 }; 25368 25369 /** 25370 * Destroys the plugin. 25371 * @protected 25372 */ 25373 Navigation.prototype.destroy = function() { 25374 var handler, control, property, override; 25375 25376 for (handler in this._handlers) { 25377 this.$element.off(handler, this._handlers[handler]); 25378 } 25379 for (control in this._controls) { 25380 this._controls[control].remove(); 25381 } 25382 for (override in this.overides) { 25383 this._core[override] = this._overrides[override]; 25384 } 25385 for (property in Object.getOwnPropertyNames(this)) { 25386 typeof this[property] != 'function' && (this[property] = null); 25387 } 25388 }; 25389 25390 /** 25391 * Updates the internal state. 25392 * @protected 25393 */ 25394 Navigation.prototype.update = function() { 25395 var i, j, k, 25396 lower = this._core.clones().length / 2, 25397 upper = lower + this._core.items().length, 25398 maximum = this._core.maximum(true), 25399 settings = this._core.settings, 25400 size = settings.center || settings.autoWidth || settings.dotsData 25401 ? 1 : settings.dotsEach || settings.items; 25402 25403 if (settings.slideBy !== 'page') { 25404 settings.slideBy = Math.min(settings.slideBy, settings.items); 25405 } 25406 25407 if (settings.dots || settings.slideBy == 'page') { 25408 this._pages = []; 25409 25410 for (i = lower, j = 0, k = 0; i < upper; i++) { 25411 if (j >= size || j === 0) { 25412 this._pages.push({ 25413 start: Math.min(maximum, i - lower), 25414 end: i - lower + size - 1 25415 }); 25416 if (Math.min(maximum, i - lower) === maximum) { 25417 break; 25418 } 25419 j = 0, ++k; 25420 } 25421 j += this._core.mergers(this._core.relative(i)); 25422 } 25423 } 25424 }; 25425 25426 /** 25427 * Draws the user interface. 25428 * @todo The option `dotsData` wont work. 25429 * @protected 25430 */ 25431 Navigation.prototype.draw = function() { 25432 var difference, 25433 settings = this._core.settings, 25434 disabled = this._core.items().length <= settings.items, 25435 index = this._core.relative(this._core.current()), 25436 loop = settings.loop || settings.rewind; 25437 25438 this._controls.$relative.toggleClass('disabled', !settings.nav || disabled); 25439 25440 if (settings.nav) { 25441 this._controls.$previous.toggleClass('disabled', !loop && index <= this._core.minimum(true)); 25442 this._controls.$next.toggleClass('disabled', !loop && index >= this._core.maximum(true)); 25443 } 25444 25445 this._controls.$absolute.toggleClass('disabled', !settings.dots || disabled); 25446 25447 if (settings.dots) { 25448 difference = this._pages.length - this._controls.$absolute.children().length; 25449 25450 if (settings.dotsData && difference !== 0) { 25451 this._controls.$absolute.html(this._templates.join('')); 25452 } else if (difference > 0) { 25453 this._controls.$absolute.append(new Array(difference + 1).join(this._templates[0])); 25454 } else if (difference < 0) { 25455 this._controls.$absolute.children().slice(difference).remove(); 25456 } 25457 25458 this._controls.$absolute.find('.active').removeClass('active'); 25459 this._controls.$absolute.children().eq($.inArray(this.current(), this._pages)).addClass('active'); 25460 } 25461 }; 25462 25463 /** 25464 * Extends event data. 25465 * @protected 25466 * @param {Event} event - The event object which gets thrown. 25467 */ 25468 Navigation.prototype.onTrigger = function(event) { 25469 var settings = this._core.settings; 25470 25471 event.page = { 25472 index: $.inArray(this.current(), this._pages), 25473 count: this._pages.length, 25474 size: settings && (settings.center || settings.autoWidth || settings.dotsData 25475 ? 1 : settings.dotsEach || settings.items) 25476 }; 25477 }; 25478 25479 /** 25480 * Gets the current page position of the carousel. 25481 * @protected 25482 * @returns {Number} 25483 */ 25484 Navigation.prototype.current = function() { 25485 var current = this._core.relative(this._core.current()); 25486 return $.grep(this._pages, $.proxy(function(page, index) { 25487 return page.start <= current && page.end >= current; 25488 }, this)).pop(); 25489 }; 25490 25491 /** 25492 * Gets the current succesor/predecessor position. 25493 * @protected 25494 * @returns {Number} 25495 */ 25496 Navigation.prototype.getPosition = function(successor) { 25497 var position, length, 25498 settings = this._core.settings; 25499 25500 if (settings.slideBy == 'page') { 25501 position = $.inArray(this.current(), this._pages); 25502 length = this._pages.length; 25503 successor ? ++position : --position;
vendor: 5,678 bytes, lines 25504-25728
25504 position = this._pages[((position % length) + length) % length].start; 25505 } else { 25506 position = this._core.relative(this._core.current()); 25507 length = this._core.items().length; 25508 successor ? position += settings.slideBy : position -= settings.slideBy; 25509 } 25510 25511 return position; 25512 }; 25513 25514 /** 25515 * Slides to the next item or page. 25516 * @public 25517 * @param {Number} [speed=false] - The time in milliseconds for the transition. 25518 */ 25519 Navigation.prototype.next = function(speed) { 25520 $.proxy(this._overrides.to, this._core)(this.getPosition(true), speed); 25521 }; 25522 25523 /** 25524 * Slides to the previous item or page. 25525 * @public 25526 * @param {Number} [speed=false] - The time in milliseconds for the transition. 25527 */ 25528 Navigation.prototype.prev = function(speed) { 25529 $.proxy(this._overrides.to, this._core)(this.getPosition(false), speed); 25530 }; 25531 25532 /** 25533 * Slides to the specified item or page. 25534 * @public 25535 * @param {Number} position - The position of the item or page. 25536 * @param {Number} [speed] - The time in milliseconds for the transition. 25537 * @param {Boolean} [standard=false] - Whether to use the standard behaviour or not. 25538 */ 25539 Navigation.prototype.to = function(position, speed, standard) { 25540 var length; 25541 25542 if (!standard) { 25543 length = this._pages.length; 25544 $.proxy(this._overrides.to, this._core)(this._pages[((position % length) + length) % length].start, speed); 25545 } else { 25546 $.proxy(this._overrides.to, this._core)(position, speed); 25547 } 25548 }; 25549 25550 $.fn.owlCarousel.Constructor.Plugins.Navigation = Navigation; 25551 25552})(window.Zepto || window.jQuery, window, document); 25553 25554/** 25555 * Hash Plugin 25556 * @version 2.0.0-beta.3 25557 * @author Artus Kolanowski 25558 * @license The MIT License (MIT) 25559 */ 25560;(function($, window, document, undefined) { 25561 'use strict'; 25562 25563 /** 25564 * Creates the hash plugin. 25565 * @class The Hash Plugin 25566 * @param {Owl} carousel - The Owl Carousel 25567 */ 25568 var Hash = function(carousel) { 25569 /** 25570 * Reference to the core. 25571 * @protected 25572 * @type {Owl} 25573 */ 25574 this._core = carousel; 25575 25576 /** 25577 * Hash index for the items. 25578 * @protected 25579 * @type {Object} 25580 */ 25581 this._hashes = {}; 25582 25583 /** 25584 * The carousel element. 25585 * @type {jQuery} 25586 */ 25587 this.$element = this._core.$element; 25588 25589 /** 25590 * All event handlers. 25591 * @protected 25592 * @type {Object} 25593 */ 25594 this._handlers = { 25595 /*'initialized.owl.carousel': $.proxy(function(e) { 25596 if (e.namespace && this._core.settings.startPosition === 'URLHash') { 25597 $(window).trigger('hashchange.owl.navigation'); 25598 } 25599 }, this),*/ 25600 'prepared.owl.carousel': $.proxy(function(e) { 25601 if (e.namespace) { 25602 var hash = $(e.content).find('[data-hash]').addBack('[data-hash]').attr('data-hash'); 25603 25604 if (!hash) { 25605 return; 25606 } 25607 25608 this._hashes[hash] = e.content; 25609 } 25610 }, this), 25611 'changed.owl.carousel': $.proxy(function(e) { 25612 if (e.namespace && e.property.name === 'position') { 25613 var current = this._core.items(this._core.relative(this._core.current())), 25614 hash = $.map(this._hashes, function(item, hash) { 25615 return item === current ? hash : null; 25616 }).join(); 25617 25618 if (!hash || window.location.hash.slice(1) === hash) { 25619 return; 25620 } 25621 25622 window.location.hash = hash; 25623 } 25624 }, this) 25625 }; 25626 25627 // set default options 25628 this._core.options = $.extend({}, Hash.Defaults, this._core.options); 25629 25630 // register the event handlers 25631 this.$element.on(this._handlers); 25632 25633 // register event listener for hash navigation 25634 /*$(window).on('hashchange.owl.navigation', $.proxy(function(e) { 25635 var hash = window.location.hash.substring(1), 25636 items = this._core.$stage.children(), 25637 position = this._hashes[hash] && items.index(this._hashes[hash]); 25638 25639 if (position === undefined || position === this._core.current()) { 25640 return; 25641 } 25642 25643 this._core.to(this._core.relative(position), false, true); 25644 }, this));*/ 25645 }; 25646 25647 /** 25648 * Default options. 25649 * @public 25650 */ 25651 Hash.Defaults = { 25652 URLhashListener: false 25653 }; 25654 25655 /** 25656 * Destroys the plugin. 25657 * @public 25658 */ 25659 Hash.prototype.destroy = function() { 25660 var handler, property; 25661 25662 $(window).off('hashchange.owl.navigation'); 25663 25664 for (handler in this._handlers) { 25665 this._core.$element.off(handler, this._handlers[handler]); 25666 } 25667 for (property in Object.getOwnPropertyNames(this)) { 25668 typeof this[property] != 'function' && (this[property] = null); 25669 } 25670 }; 25671 25672 $.fn.owlCarousel.Constructor.Plugins.Hash = Hash; 25673 25674})(window.Zepto || window.jQuery, window, document); 25675 25676/** 25677 * Support Plugin 25678 * 25679 * @version 2.0.0-beta.3 25680 * @author Vivid Planet Software GmbH 25681 * @author Artus Kolanowski 25682 * @license The MIT License (MIT) 25683 */ 25684;(function($, window, document, undefined) { 25685 25686 var style = $('<support>').get(0).style, 25687 prefixes = 'Webkit Moz O ms'.split(' '), 25688 events = { 25689 transition: { 25690 end: { 25691 WebkitTransition: 'webkitTransitionEnd', 25692 MozTransition: 'transitionend', 25693 OTransition: 'oTransitionEnd', 25694 transition: 'transitionend' 25695 } 25696 }, 25697 animation: { 25698 end: { 25699 WebkitAnimation: 'webkitAnimationEnd', 25700 MozAnimation: 'animationend', 25701 OAnimation: 'oAnimationEnd', 25702 animation: 'animationend' 25703 } 25704 } 25705 }, 25706 tests = { 25707 csstransforms: function() { 25708 return !!test('transform'); 25709 }, 25710 csstransforms3d: function() { 25711 return !!test('perspective'); 25712 }, 25713 csstransitions: function() { 25714 return !!test('transition'); 25715 }, 25716 cssanimations: function() { 25717 return !!test('animation'); 25718 } 25719 }; 25720 25721 function test(property, prefixed) { 25722 var result = false, 25723 upper = property.charAt(0).toUpperCase() + property.slice(1); 25724 25725 $.each((property + ' ' + prefixes.join(upper + ' ') + upper).split(' '), function(i, property) { 25726 if (style[property] !== undefined) { 25727 result = prefixed ? property : true; 25728 return false;
25729 } 25730 }); 25731 25732 return result; 25733 } 25734 25735 function prefixed(property) { 25736 return test(property, true); 25737 } 25738 25739 if (tests.csstransitions()) { 25740 /* jshint -W053 */ 25741 $.support.transition = new String(prefixed('transition')) 25742 $.support.transition.end = events.transition.end[ $.support.transition ]; 25743 } 25744 25745 if (tests.cssanimations()) { 25746 /* jshint -W053 */ 25747 $.support.animation = new String(prefixed('animation')) 25748 $.support.animation.end = events.animation.end[ $.support.animation ]; 25749 } 25750 25751 if (tests.csstransforms()) { 25752 /* jshint -W053 */ 25753 $.support.transform = new String(prefixed('transform')); 25754 $.support.transform3d = tests.csstransforms3d(); 25755 } 25756 25757})(window.Zepto || window.jQuery, window, document); 25758 25759(function(window, document, undefined) { 25760 25761 /** 25762 * Find the absolute position of an element 25763 */ 25764 var absPos = function(element) { 25765 var offsetLeft, offsetTop; 25766 offsetLeft = offsetTop = 0; 25767 if (element.offsetParent) { 25768 do { 25769 offsetLeft += element.offsetLeft; 25770 offsetTop += element.offsetTop; 25771 } while (element = element.offsetParent); 25772 } 25773 return [offsetLeft, offsetTop]; 25774 }; 25775 25776 /** 25777 * @constructor Progress Circle class 25778 * @param params.canvas Canvas on which the circles will be drawn. 25779 * @param params.minRadius Inner radius of the innermost circle, in px. 25780 * @param params.arcWidth Width of each circle(to be more accurate, ring). 25781 * @param params.gapWidth Space between each circle. 25782 * @param params.centerX X coordinate of the center of circles. 25783 * @param params.centerY Y coordinate of the center of circles. 25784 * @param params.infoLineBaseAngle Base angle of the info line. 25785 * @param params.infoLineAngleInterval Angles between the info lines. 25786 */ 25787 var ProgressCircle = function(params) { 25788 this.canvas = params.canvas; 25789 this.minRadius = params.minRadius || 15; 25790 this.arcWidth = params.arcWidth || 5; 25791 this.gapWidth = params.gapWidth || 3; 25792 this.centerX = params.centerX || this.canvas.width / 2; 25793 this.centerY = params.centerY || this.canvas.height / 2;
25794 this.infoLineLength = params.infoLineLength || 60; 25795 this.horizLineLength = params.horizLineLength || 10; 25796 this.infoLineAngleInterval = params.infoLineAngleInterval || Math.PI / 8; 25797 this.infoLineBaseAngle = params.infoLineBaseAngle || Math.PI / 6; 25798 25799 this.context = this.canvas.getContext('2d'); 25800 25801 this.width = this.canvas.width; 25802 this.height = this.canvas.height; 25803 25804 this.circles = []; 25805 this.runningCount = 0; 25806 }; 25807 25808 ProgressCircle.prototype = { 25809 constructor: ProgressCircle, 25810 25811 /** 25812 * @method Adds an progress monitor entry. 25813 * @param params.fillColor Color to fill in the circle. 25814 * @param params.outlineColor Color to outline the circle. 25815 * @param params.progressListener Callback function to fetch the progress. 25816 * @param params.infoListener Callback function to fetch the info. 25817 * @returns this 25818 */ 25819 addEntry: function(params) { 25820 this.circles.push(new Circle({ 25821 canvas: this.canvas, 25822 context: this.context, 25823 centerX: this.centerX, 25824 centerY: this.centerY, 25825 innerRadius: this.minRadius + this.circles.length * 25826 (this.gapWidth + this.arcWidth), 25827 arcWidth: this.arcWidth,
25828 infoLineLength: this.infoLineLength, 25829 horizLineLength: this.horizLineLength, 25830 25831 id: this.circles.length, 25832 fillColor: params.fillColor, 25833 outlineColor: params.outlineColor, 25834 progressListener: params.progressListener, 25835 infoListener: params.infoListener, 25836 infoLineAngle: this.infoLineBaseAngle + 25837 this.circles.length * this.infoLineAngleInterval, 25838 })); 25839 25840 return this; 25841 }, 25842 25843 /** 25844 * @method Starts the monitor and updates with the given interval. 25845 * @param interval Interval between updates, in millisecond. 25846 * @returns this 25847 */ 25848 start: function(interval) { 25849 var self = this; 25850 this.timer = setInterval(function() { 25851 self._update(); 25852 }, interval || 33); 25853 25854 return this; 25855 }, 25856 25857 /** 25858 * @method Stop the animation. 25859 */ 25860 stop: function() { 25861 clearTimeout(this.timer); 25862 }, 25863 25864 /** 25865 * @private 25866 * @method Call update on each circle and redraw them. 25867 * @returns this 25868 */ 25869 _update: function() { 25870 this._clear(); 25871 this.circles.forEach(function(circle, idx, array) { 25872 circle.update(); 25873 }); 25874 25875 return this; 25876 }, 25877 25878 /** 25879 * @private 25880 * @method Clear the canvas. 25881 * @returns this 25882 */ 25883 _clear: function() { 25884 this.context.clearRect(0, 0, this.canvas.width, this.canvas.height); 25885 25886 return this; 25887 }, 25888 25889 }; 25890 25891 /** 25892 * @private 25893 * @class Individual progress circle. 25894 * @param params.canvas Canvas on which the circle will be drawn. 25895 * @param params.context Context of the canvas. 25896 * @param params.innerRadius Inner radius of the circle, in px. 25897 * @param params.arcWidth Width of each arc(circle). 25898 * @param params.gapWidth Distance between each arc. 25899 * @param params.centerX X coordinate of the center of circles. 25900 * @param params.centerY Y coordinate of the center of circles. 25901 * @param params.fillColor Color to fill in the circle. 25902 * @param params.outlineColor Color to outline the circle. 25903 * @param params.progressListener Callback function to fetch the progress. 25904 * @param params.infoListener Callback function to fetch the info. 25905 * @param params.infoLineAngle Angle of info line. 25906 */ 25907 var Circle = function(params) { 25908 this.id = params.id; 25909 this.canvas = params.canvas; 25910 this.context = params.context; 25911 this.centerX = params.centerX; 25912 this.centerY = params.centerY; 25913 this.arcWidth = params.arcWidth; 25914 this.innerRadius = params.innerRadius || 0; 25915 this.fillColor = params.fillColor || '#fff'; 25916 this.outlineColor = params.outlineColor || this.fillColor; 25917 this.progressListener = params.progressListener;
25918 this.infoLineLength = params.infoLineLength || 250; 25919 this.horizLineLength = params.horizLineLength || 50; 25920 this.infoListener = params.infoListener; 25921 this.infoLineAngle = params.infoLineAngle; 25922 25923 this.outerRadius = this.innerRadius + this.arcWidth; 25924 25925 // If the info listener is not registered, then don't calculate 25926 // the related coordinates 25927 if (!this.infoListener) return; 25928 25929 // calculate the info-line turning points 25930 var angle = this.infoLineAngle, 25931 arcDistance = (this.innerRadius + this.outerRadius) / 2, 25932 25933 sinA = Math.sin(angle), 25934 cosA = Math.cos(angle); 25935 25936 this.infoLineStartX = this.centerX + sinA * arcDistance; 25937 this.infoLineStartY = this.centerY - cosA * arcDistance; 25938 25939 this.infoLineMidX = this.centerX + sinA * this.infoLineLength; 25940 this.infoLineMidY = this.centerY - cosA * this.infoLineLength; 25941 25942 this.infoLineEndX = this.infoLineMidX + 25943 (sinA < 0 ? -this.horizLineLength : this.horizLineLength); 25944 this.infoLineEndY = this.infoLineMidY; 25945 25946 var infoText = document.createElement('div'), 25947 style = infoText.style; 25948 25949 style.color = this.fillColor; 25950 style.position = 'absolute'; 25951 style.left = this.infoLineEndX + absPos(this.canvas)[0] + 'px'; 25952 // style.top will be calculated in the `drawInfo` method. Since 25953 // user may want to change the size of the font, so the top offset 25954 // must be updated in each loop. 25955 infoText.className = 'ProgressCircleInfo'; // For css styling 25956 infoText.id = 'progress_circle_info_' + this.id; 25957 document.body.appendChild(infoText); 25958 this.infoText = infoText; 25959 }; 25960 25961 Circle.prototype = { 25962 constructor: Circle, 25963 25964 update: function() { 25965 this.progress = this.progressListener(); 25966 this._draw(); 25967 25968 if (this.infoListener) { 25969 this.info = this.infoListener(); 25970 this._drawInfo(); 25971 } 25972 }, 25973 25974 /** 25975 * @private 25976 * @method Draw the circle on the canvas. 25977 * @returns this 25978 */ 25979 _draw: function() { 25980 var ctx = this.context, 25981 25982 ANGLE_OFFSET = -Math.PI / 2, 25983 25984 startAngle = 0 + ANGLE_OFFSET, 25985 endAngle= startAngle + this.progress * Math.PI * 2, 25986 25987 x = this.centerX, 25988 y = this.centerY, 25989 25990 innerRadius = this.innerRadius - this.arcWidth - 1, 25991 outerRadius = this.outerRadius - this.arcWidth - 1; 25992 25993 if ( innerRadius < 0 ) 25994 return; 25995 25996 ctx.fillStyle = this.fillColor; 25997 ctx.strokeStyle = this.outlineColor; 25998 25999 ctx.beginPath(); 26000 ctx.arc(x, y, innerRadius, startAngle, endAngle, false); 26001 ctx.arc(x, y, outerRadius, endAngle, startAngle, true); 26002 ctx.closePath(); 26003 ctx.stroke(); 26004 ctx.fill(); 26005 26006 return this; 26007 }, 26008 26009 /** 26010 * @private 26011 * @method Draw the info lines and info text. 26012 * @returns this 26013 */ 26014 _drawInfo: function() { 26015 26016 var pointList, lineHeight; 26017 26018 pointList = [ 26019 [this.infoLineStartX, this.infoLineStartY], 26020 [this.infoLineMidX, this.infoLineMidY], 26021 [this.infoLineEndX, this.infoLineEndY], 26022 ]; 26023 this._drawSegments(pointList, false); 26024 26025 this.infoText.innerHTML = this.info; 26026 26027 lineHeight = this.infoText.offsetHeight; 26028 this.infoText.style.top = this.infoLineEndY + 26029 absPos(this.canvas)[1] - lineHeight / 2 + 'px'; 26030 26031 return this; 26032 }, 26033 26034 /** 26035 * @private 26036 * @method Helper function to draw the segments 26037 * @param pointList An array of points in the form of [x, y]. 26038 * @param close Whether to connect the first and last point. 26039 */ 26040 _drawSegments: function(pointList, close) { 26041 var ctx = this.context; 26042 26043 ctx.beginPath(); 26044 ctx.moveTo(pointList[0][0], pointList[0][1]); 26045 for (var i = 1; i < pointList.length; ++i) { 26046 ctx.lineTo(pointList[i][0], pointList[i][1]); 26047 } 26048 26049 if (close) { 26050 ctx.closePath(); 26051 } 26052 ctx.stroke(); 26053 }, 26054 }; 26055 26056 window.ProgressCircle = ProgressCircle; 26057 26058})(window, document); 26059 26060 26061 26062 26063/* ========================================================= 26064 * jquery.vc_chart.js v1.0 26065 * ========================================================= 26066 * Copyright 2013 Wpbakery 26067 * 26068 * Jquery chart plugin for the Visual Composer. 26069 * ========================================================= */ 26070(function($){ 26071 /** 26072 * Pie chart animated. 26073 * @param element - DOM element 26074 * @param options - settings object. 26075 * @constructor 26076 */ 26077 var VcChart = function(element, options) { 26078 this.el = element; 26079 this.$el = $(this.el); 26080 var $this = this; 26081 $this.options = $.extend({ 26082 color: 'wpb_button', 26083 units: '', 26084 width: '', 26085 label_selector: '.vc_pie_chart_value', 26086 back_selector: '.vc_pie_chart_back', 26087 responsive: true 26088 }, options); 26089 $this.init(); 26090 }; 26091 VcChart.prototype = { 26092 constructor: VcChart, 26093 _progress_v: 0, 26094 animated: false, 26095 colors: { 26096 'wpb_button': 'rgba(247, 247, 247, 1)', 26097 'btn-primary': 'rgba(0, 136, 204, 1)', 26098 'btn-info': 'rgba(88, 185, 218, 1)', 26099 'btn-success': 'rgba(106, 177, 101, 1)', 26100 'btn-warning': 'rgba(255, 153, 0, 1)', 26101 'btn-danger': 'rgba(255, 103, 91, 1)', 26102 'btn-inverse': 'rgba(85, 85, 85, 1)' 26103 }, 26104 init: function() { 26105 this.setupColor(); 26106 this.value = this.$el.data('pie-value')/100; 26107 this.label_value = this.$el.data('pie-label-value') || this.$el.data('pie-value'); 26108 this.$wrapper = $('.vc_pie_wrapper', this.$el); 26109 this.$label = $(this.options.label_selector, this.$el); 26110 this.$back = $(this.options.back_selector, this.$el); 26111 this.$canvas = this.$el.find('canvas'); 26112 this.arcWidth = this.$el.data('pie-width') * 2; 26113 this.draw(); 26114 this.setWayPoint(); 26115 if(this.options.responsive === true) this.setResponsive(); 26116 if (UNCODE.isMobile) this._progress_v = this.value; 26117 }, 26118 setupColor: function() { 26119 // if(typeof this.colors[this.options.color] !== 'undefined') { 26120 // this.color = this.colors[this.options.color]; 26121 // } else if(typeof this.options.color === 'string' && this.options.color.match(/^rgba?\([^\)]+\)/)) { 26122 // this.color = this.options.color; 26123 // } else { 26124 // this.color = 'rgba(247, 247, 247, 0.2)'; 26125 // } 26126 if(typeof this.options.color !== 'undefined') { 26127 this.color = this.options.color; 26128 } else this.color = 'rgba(247, 247, 247, 0.2)'; 26129 26130 }, 26131 setResponsive: function() { 26132 var that = this; 26133 if (!UNCODE.isMobile) { 26134 $(window).resize(function(){ 26135 if(that.animated === true) that.circle.stop(); 26136 that.draw(true); 26137 }); 26138 } 26139 }, 26140 draw: function(redraw) { 26141 var w = this.$el.addClass('vc_ready').width() * 2, 26142 border_w = this.arcWidth, 26143 radius; 26144 if(!w) w = this.$el.parents(':visible').first().width()-2; 26145 //w = Math.round(w/100*80); 26146 //if (w < 250) w = 250; 26147 radius = w/2; 26148 this.$wrapper.css({"width" : (w / 2) + "px"}); 26149 this.$label.css({"width" : (w / 2), "height" : (w / 2), "line-height" : (w / 2)+"px"}); 26150 this.$back.css({"width" : (w / 2), "height" : (w / 2)}); 26151 this.$canvas.attr({"width" : w + "px", "height" : w + "px"}); 26152 this.$el.addClass('vc_ready'); 26153 this.circle = new ProgressCircle({ 26154 canvas: this.$canvas.get(0), 26155 minRadius: radius, 26156 arcWidth: border_w 26157 }); 26158 if(redraw === true && this.animated === true) { 26159 this._progress_v = this.value; 26160 this.circle.addEntry({ 26161 fillColor: this.color, 26162 progressListener: $.proxy(this.setProgress, this) 26163 }).start(); 26164 } 26165 }, 26166 setProgress: function() { 26167 if (this._progress_v >= this.value) { 26168 this.circle.stop(); 26169 this.animated = true; 26170 this.$label.html(this.label_value + this.options.units); 26171 return this._progress_v; 26172 } 26173 this._progress_v += 0.01; 26174 if (!isNaN(this.label_value)) { 26175 var label_value = this._progress_v/this.value*this.label_value; 26176 var val = Math.round(label_value) + this.options.units; 26177 this.$label.html(val); 26178 } else this.$label.html(this.label_value + this.options.units); 26179 return this._progress_v; 26180 }, 26181 animate: function() { 26182 if(this.animated !== true) { 26183 this.circle.addEntry({ 26184 fillColor: this.color, 26185 progressListener: $.proxy(this.setProgress, this) 26186 }).start(10); 26187 } 26188 }, 26189 setWayPoint: function() { 26190 if (typeof $.fn.waypoint !== 'undefined' && !UNCODE.isMobile) { 26191 this.$el.waypoint($.proxy(this.animate, this), { offset: '85%' }); 26192 } else { 26193 this.animate(); 26194 } 26195 } 26196 }; 26197 /** 26198 * jQuery plugin 26199 * @param option - object with settings 26200 * @return {*} 26201 */ 26202 $.fn.vcChat = function(option, value) { 26203 return this.each(function () { 26204 var $this = $(this), 26205 data = $this.data('vc_chart'), 26206 options = typeof option === 'object' ? option : { 26207 color: $this.data('pie-color'), 26208 units: $this.data('pie-units') 26209 }; 26210 if (typeof option == 'undefined') $this.data('vc_chart', (data = new VcChart(this, options))); 26211 if (typeof option == 'string') data[option](value); 26212 }); 26213 }; 26214 /** 26215 * Allows users to rewrite function inside theme. 26216 */ 26217 if ( typeof window['vc_pieChart'] !== 'function' ) { 26218 window.vc_pieChart = function() { 26219 $('.vc_pie_chart:visible:not(.vc_ready)').vcChat(); 26220 } 26221 } 26222 $(document).ready(function(){ 26223 !window.vc_iframe && vc_pieChart(); 26224 26225 /** 26226 * Tab and collapse integration. 26227 */ 26228 $('.nav-tabs a').on('shown.bs.tab', function(e){ 26229 var $cont = $(e.target).closest('.tab-container'), 26230 $active = $('.tab-pane.active', $cont); 26231 $('.vc_pie_chart:not(.vc_ready)', $active).vcChat(); 26232 }); 26233 26234 $('.panel-collapse').on('shown.bs.collapse', function (e) { 26235 $('.vc_pie_chart:not(.vc_ready)', e.target).vcChat(); 26236 }) 26237 }); 26238 26239})(window.jQuery); 26240 26241/* Progress bar 26242 ---------------------------------------------------------- */ 26243function uncode_progress_bar() { 26244 jQuery.each(jQuery('.vc_progress_bar'), function(index, val) { 26245 if (UNCODE.isUnmodalOpen && !val.closest('#unmodal-content')) { 26246 return; 26247 } 26248 if (!UNCODE.isMobile) { 26249 new Waypoint({ 26250 context: UNCODE.isUnmodalOpen ? document.getElementById('unmodal-content') : window, 26251 element: val, 26252 handler: function() { 26253 var element = jQuery(this.element); 26254 element.find('.vc_single_bar').each(function(index) { 26255 var $this = jQuery(this), 26256 bar = $this.find('.vc_bar'), 26257 val = bar.data('percentage-value'); 26258 setTimeout(function() { 26259 bar.css({ 26260 "width": val + '%' 26261 }); 26262 }, index * 200); 26263 }); 26264 }, 26265 offset: '80%' 26266 }); 26267 } else { 26268 var element = jQuery(val); 26269 element.find('.vc_single_bar').each(function(index) { 26270 var $this = jQuery(this), 26271 bar = $this.find('.vc_bar'), 26272 val = bar.data('percentage-value'); 26273 setTimeout(function() { 26274 bar.css({ 26275 "width": val + '%' 26276 }); 26277 }, index * 200); 26278 }); 26279 } 26280 }); 26281}; 26282uncode_progress_bar(); 26283 26284/*! 26285 * jquery.counterup.js 1.0 26286 * 26287 * Copyright 2013, Benjamin Intal http://gambit.ph @bfintal 26288 * Released under the GPL v2 License 26289 * 26290 * Date: Nov 26, 2013 26291 */ 26292(function($) { 26293 "use strict"; 26294 $.fn.counterUp = function(options) { 26295 // Defaults 26296 var settings = $.extend({ 26297 'time': 400, 26298 'delay': 10 26299 }, options); 26300 return this.each(function() { 26301 // Store the object 26302 var $this = $(this); 26303 var $settings = settings; 26304 var counterUpper = function() { 26305 var nums = []; 26306 var divisions = $settings.time / $settings.delay; 26307 var numReal = $this.attr('data-val'), 26308 num = numReal; 26309 var isComma = /[0-9]+,[0-9]+/.test(num); 26310 num = num.replace(/,/g, ''); 26311 var isInt = /^[0-9]+$/.test(num); 26312 var isFloat = /^[0-9]+\.[0-9]+$/.test(num); 26313 var decimalPlaces = isFloat ? (num.split('.')[1] || []).length : 0; 26314 // Generate list of incremental numbers to display 26315 for (var i = divisions; i >= 1; i--) { 26316 // Preserve as int if input was int 26317 var newNum = parseInt(num / divisions * i); 26318 // Preserve float if input was float 26319 if (isFloat) { 26320 newNum = parseFloat(num / divisions * i).toFixed(decimalPlaces); 26321 } 26322 // Preserve commas if input had commas 26323 if (isComma) { 26324 while (/(\d+)(\d{3})/.test(newNum.toString())) { 26325 newNum = newNum.toString().replace(/(\d+)(\d{3})/, '$1' + ',' + '$2'); 26326 } 26327 } 26328 nums.unshift(newNum); 26329 } 26330 nums.push(numReal); 26331 $this.data('counterup-nums', nums); 26332 $this.text('0'); 26333 // Updates the number until we're done 26334 var f = function() { 26335 if ($this.data('counterup-nums') != null) { 26336 $this.text($this.data('counterup-nums').shift()); 26337 if ($this.data('counterup-nums').length) { 26338 setTimeout($this.data('counterup-func'), $settings.delay); 26339 } else { 26340 delete $this.data('counterup-nums'); 26341 $this.data('counterup-nums', null); 26342 $this.data('counterup-func', null); 26343 } 26344 } 26345 }; 26346 $this.data('counterup-func', f); 26347 // Start the count up 26348 setTimeout($this.data('counterup-func'), $settings.delay); 26349 }; 26350 // Perform counts when the element gets into view 26351 new Waypoint({ 26352 context: UNCODE.isUnmodalOpen ? document.getElementById('unmodal-content') : window, 26353 element: this, 26354 handler: function() { 26355 counterUpper(); 26356 if (!UNCODE.isUnmodalOpen) { 26357 this.destroy(); 26358 } 26359 }, 26360 offset: '100%' 26361 }); 26362 }); 26363 }; 26364})(jQuery); 26365 26366/*! 26367 * The Final Countdown for jQuery v2.2.0 (http://hilios.github.io/jQuery.countdown/) 26368 * Copyright (c) 2016 Edson Hilios 26369 * 26370 * Permission is hereby granted, free of charge, to any person obtaining a copy of 26371 * this software and associated documentation files (the "Software"), to deal in 26372 * the Software without restriction, including without limitation the rights to 26373 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 26374 * the Software, and to permit persons to whom the Software is furnished to do so, 26375 * subject to the following conditions: 26376 * 26377 * The above copyright notice and this permission notice shall be included in all 26378 * copies or substantial portions of the Software. 26379 * 26380 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26381 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 26382 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 26383 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 26384 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 26385 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26386 */ 26387(function(factory) { 26388 "use strict"; 26389 if (typeof define === "function" && define.amd) { 26390 define([ "jquery" ], factory); 26391 } else { 26392 factory(jQuery); 26393 } 26394})(function($) { 26395 "use strict"; 26396 var instances = [], matchers = [], defaultOptions = { 26397 precision: 100, 26398 elapse: false, 26399 defer: false 26400 }; 26401 matchers.push(/^[0-9]*$/.source); 26402 matchers.push(/([0-9]{1,2}\/){2}[0-9]{4}( [0-9]{1,2}(:[0-9]{2}){2})?/.source); 26403 matchers.push(/[0-9]{4}([\/\-][0-9]{1,2}){2}( [0-9]{1,2}(:[0-9]{2}){2})?/.source); 26404 matchers = new RegExp(matchers.join("|")); 26405 function parseDateString(dateString) { 26406 if (dateString instanceof Date) { 26407 return dateString; 26408 } 26409 if (String(dateString).match(matchers)) { 26410 if (String(dateString).match(/^[0-9]*$/)) { 26411 dateString = Number(dateString); 26412 } 26413 if (String(dateString).match(/\-/)) { 26414 dateString = String(dateString).replace(/\-/g, "/"); 26415 } 26416 return new Date(dateString); 26417 } else { 26418 throw new Error("Couldn't cast `" + dateString + "` to a date object."); 26419 } 26420 } 26421 var DIRECTIVE_KEY_MAP = { 26422 Y: "years", 26423 m: "months", 26424 n: "daysToMonth", 26425 d: "daysToWeek", 26426 w: "weeks", 26427 W: "weeksToMonth", 26428 H: "hours", 26429 M: "minutes", 26430 S: "seconds", 26431 D: "totalDays", 26432 I: "totalHours", 26433 N: "totalMinutes", 26434 T: "totalSeconds" 26435 }; 26436 function escapedRegExp(str) { 26437 var sanitize = str.toString().replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1"); 26438 return new RegExp(sanitize); 26439 } 26440 function strftime(offsetObject) { 26441 return function(format) { 26442 var directives = format.match(/%(-|!)?[A-Z]{1}(:[^;]+;)?/gi); 26443 if (directives) { 26444 for (var i = 0, len = directives.length; i < len; ++i) { 26445 var directive = directives[i].match(/%(-|!)?([a-zA-Z]{1})(:[^;]+;)?/), regexp = escapedRegExp(directive[0]), modifier = directive[1] || "", plural = directive[3] || "", value = null; 26446 directive = directive[2]; 26447 if (DIRECTIVE_KEY_MAP.hasOwnProperty(directive)) { 26448 value = DIRECTIVE_KEY_MAP[directive]; 26449 value = Number(offsetObject[value]); 26450 } 26451 if (value !== null) { 26452 if (modifier === "!") { 26453 value = pluralize(plural, value); 26454 } 26455 if (modifier === "") { 26456 if (value < 10) { 26457 value = "0" + value.toString(); 26458 } 26459 } 26460 format = format.replace(regexp, value.toString()); 26461 } 26462 } 26463 } 26464 format = format.replace(/%%/, "%"); 26465 return format; 26466 }; 26467 } 26468 function pluralize(format, count) { 26469 var plural = "s", singular = ""; 26470 if (format) { 26471 format = format.rep
vendor: 8,618 bytes, lines 26471-26615
26471lace(/(:|;|\s)/gi, "").split(/\,/); 26472 if (format.length === 1) { 26473 plural = format[0]; 26474 } else { 26475 singular = format[0]; 26476 plural = format[1]; 26477 } 26478 } 26479 if (Math.abs(count) > 1) { 26480 return plural; 26481 } else { 26482 return singular; 26483 } 26484 } 26485 var Countdown = function(el, finalDate, options) { 26486 this.el = el; 26487 this.$el = $(el); 26488 this.interval = null; 26489 this.offset = {}; 26490 this.options = $.extend({}, defaultOptions); 26491 this.instanceNumber = instances.length; 26492 instances.push(this); 26493 this.$el.data("countdown-instance", this.instanceNumber); 26494 if (options) { 26495 if (typeof options === "function") { 26496 this.$el.on("update.countdown", options); 26497 this.$el.on("stoped.countdown", options); 26498 this.$el.on("finish.countdown", options); 26499 } else { 26500 this.options = $.extend({}, defaultOptions, options); 26501 } 26502 } 26503 this.setFinalDate(finalDate); 26504 if (this.options.defer === false) { 26505 this.start(); 26506 } 26507 }; 26508 $.extend(Countdown.prototype, { 26509 start: function() { 26510 if (this.interval !== null) { 26511 clearInterval(this.interval); 26512 } 26513 var self = this; 26514 this.update(); 26515 this.interval = setInterval(function() { 26516 self.update.call(self); 26517 }, this.options.precision); 26518 }, 26519 stop: function() { 26520 clearInterval(this.interval); 26521 this.interval = null; 26522 this.dispatchEvent("stoped"); 26523 }, 26524 toggle: function() { 26525 if (this.interval) { 26526 this.stop(); 26527 } else { 26528 this.start(); 26529 } 26530 }, 26531 pause: function() { 26532 this.stop(); 26533 }, 26534 resume: function() { 26535 this.start(); 26536 }, 26537 remove: function() { 26538 this.stop.call(this); 26539 instances[this.instanceNumber] = null; 26540 delete this.$el.data().countdownInstance; 26541 }, 26542 setFinalDate: function(value) { 26543 this.finalDate = parseDateString(value); 26544 }, 26545 update: function() { 26546 if (this.$el.closest("html").length === 0) { 26547 this.remove(); 26548 return; 26549 } 26550 var hasEventsAttached = $._data(this.el, "events") !== undefined, now = new Date(), newTotalSecsLeft; 26551 newTotalSecsLeft = this.finalDate.getTime() - now.getTime(); 26552 newTotalSecsLeft = Math.ceil(newTotalSecsLeft / 1e3); 26553 newTotalSecsLeft = !this.options.elapse && newTotalSecsLeft < 0 ? 0 : Math.abs(newTotalSecsLeft); 26554 if (this.totalSecsLeft === newTotalSecsLeft || !hasEventsAttached) { 26555 return; 26556 } else { 26557 this.totalSecsLeft = newTotalSecsLeft; 26558 } 26559 this.elapsed = now >= this.finalDate; 26560 this.offset = { 26561 seconds: this.totalSecsLeft % 60, 26562 minutes: Math.floor(this.totalSecsLeft / 60) % 60, 26563 hours: Math.floor(this.totalSecsLeft / 60 / 60) % 24, 26564 days: Math.floor(this.totalSecsLeft / 60 / 60 / 24) % 7, 26565 daysToWeek: Math.floor(this.totalSecsLeft / 60 / 60 / 24) % 7, 26566 daysToMonth: Math.floor(this.totalSecsLeft / 60 / 60 / 24 % 30.4368), 26567 weeks: Math.floor(this.totalSecsLeft / 60 / 60 / 24 / 7), 26568 weeksToMonth: Math.floor(this.totalSecsLeft / 60 / 60 / 24 / 7) % 4, 26569 months: Math.floor(this.totalSecsLeft / 60 / 60 / 24 / 30.4368), 26570 years: Math.abs(this.finalDate.getFullYear() - now.getFullYear()), 26571 totalDays: Math.floor(this.totalSecsLeft / 60 / 60 / 24), 26572 totalHours: Math.floor(this.totalSecsLeft / 60 / 60), 26573 totalMinutes: Math.floor(this.totalSecsLeft / 60), 26574 totalSeconds: this.totalSecsLeft 26575 }; 26576 if (!this.options.elapse && this.totalSecsLeft === 0) { 26577 this.stop(); 26578 this.dispatchEvent("finish"); 26579 } else { 26580 this.dispatchEvent("update"); 26581 } 26582 }, 26583 dispatchEvent: function(eventName) { 26584 var event = $.Event(eventName + ".countdown"); 26585 event.finalDate = this.finalDate; 26586 event.elapsed = this.elapsed; 26587 event.offset = $.extend({}, this.offset); 26588 event.strftime = strftime(this.offset); 26589 this.$el.trigger(event); 26590 } 26591 }); 26592 $.fn.countdown = function() { 26593 var argumentsArray = Array.prototype.slice.call(arguments, 0); 26594 return this.each(function() { 26595 var instanceNumber = $(this).data("countdown-instance"); 26596 if (instanceNumber !== undefined) { 26597 var instance = instances[instanceNumber], method = argumentsArray[0]; 26598 if (Countdown.prototype.hasOwnProperty(method)) { 26599 instance[method].apply(instance, argumentsArray.slice(1)); 26600 } else if (String(method).match(/^[$A-Z_][0-9A-Z_$]*$/i) === null) { 26601 instance.setFinalDate.call(instance, method); 26602 instance.start(); 26603 } else { 26604 $.error("Method %s does not exist on jQuery.countdown".replace(/\%s/gi, method)); 26605 } 26606 } else { 26607 new Countdown(this, argumentsArray[0], argumentsArray[1]); 26608 } 26609 }); 26610 }; 26611}); 26612 26613!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; 26614function getStyles(config){ 26615 // 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;
26615left: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+"}" 26616}; 26617 var ShareUtils; 26618 26619if ((!("classList" in document.documentElement)) && Object.defineProperty && typeof HTMLElement !== "undefined") { 26620 Object.defineProperty(HTMLElement.prototype, "classList", { 26621 get: function() { 26622 var ret, self, update; 26623 update = function(fn) { 26624 return function(value) { 26625 var classes, index; 26626 classes = self.className.split(/\s+/); 26627 index = classes.indexOf(value); 26628 fn(classes, index, value); 26629 self.className = classes.join(" "); 26630 }; 26631 }; 26632 self = this; 26633 ret = { 26634 add: update(function(classes, index, value) { 26635 ~index || classes.push(value); 26636 }), 26637 remove: update(function(classes, index) { 26638 ~index && classes.splice(index, 1); 26639 }), 26640 toggle: update(function(classes, index, value) { 26641 if (~index) { 26642 classes.splice(index, 1); 26643 } else { 26644 classes.push(value); 26645 } 26646 }), 26647 contains: function(value) { 26648 return !!~self.className.split(/\s+/).indexOf(value); 26649 }, 26650 item: function(i) { 26651 return self.className.split(/\s+/)[i] || null; 26652 } 26653 }; 26654 Object.defineProperty(ret, "length", { 26655 get: function() { 26656 return self.className.split(/\s+/).length; 26657 } 26658 }); 26659 return ret; 26660 } 26661 }); 26662} 26663 26664String.prototype.to_rfc3986 = function() { 26665 var tmp; 26666 tmp = encodeURIComponent(this); 26667 return tmp.replace(/[!'()*]/g, function(c) { 26668 return "%" + c.charCodeAt(0).toString(16); 26669 }); 26670}; 26671 26672ShareUtils = (function() { 26673 function ShareUtils() {} 26674 26675 ShareUtils.prototype.extend = function(to, from, overwrite) { 26676 var hasProp, prop; 26677 for (prop in from) { 26678 hasProp = to[prop] !== undefined; 26679 if (hasProp && typeof from[prop] === "object") { 26680 this.extend(to[prop], from[prop], overwrite); 26681 } else { 26682 if (overwrite || !hasProp) { 26683 to[prop] = from[prop]; 26684 } 26685 } 26686 } 26687 }; 26688 26689 ShareUtils.prototype.hide = function(el) { 26690 return el.style.display = "none"; 26691 }; 26692 26693 ShareUtils.prototype.show = function(el) { 26694 return el.style.display = "block"; 26695 }; 26696 26697 ShareUtils.prototype.has_class = function(el, class_name) { 26698 return el.classList.contains(class_name); 26699 }; 26700 26701 ShareUtils.prototype.add_class = function(el, class_name) { 26702 return el.classList.add(class_name); 26703 }; 26704 26705 ShareUtils.prototype.remove_class = function(el, class_name) { 26706 return el.classList.remove(class_name); 26707 }; 26708 26709 ShareUtils.prototype.is_encoded = function(str) { 26710 str = str.to_rfc3986(); 26711 return decodeURIComponent(str) !== str; 26712 }; 26713 26714 ShareUtils.prototype.encode = function(str) { 26715 if (typeof str === "undefined" || this.is_encoded(str)) { 26716 return str; 26717 } else { 26718 return str.to_rfc3986(); 26719 } 26720 }; 26721 26722 ShareUtils.prototype.popup = function(url, params) { 26723 var k, popup, qs, v; 26724 if (params == null) { 26725 params = {}; 26726 } 26727 popup = { 26728 width: 500, 26729 height: 350 26730 }; 26731 popup.top = (screen.height / 2) - (popup.height / 2); 26732 popup.left = (screen.width / 2) - (popup.width / 2); 26733 qs = ((function() { 26734 var _results; 26735 _results = []; 26736 for (k in params) { 26737 v = params[k]; 26738 _results.push("" + k + "=" + (this.encode(v))); 26739 } 26740 return _results; 26741 }).call(this)).join('&'); 26742 if (qs) { 26743 qs = "?" + qs; 26744 } 26745 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="
26745+ popup.width + ",height=" + popup.height); 26746 }; 26747 26748 return ShareUtils; 26749 26750})(); 26751var Share, 26752 __hasProp = {}.hasOwnProperty, 26753 __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; }; 26754 26755Share = (function(_super) { 26756 __extends(Share, _super); 26757 26758 function Share(element, options) { 26759 this.element = element; 26760 this.el = { 26761 head: document.getElementsByTagName('head')[0], 26762 body: document.getElementsByTagName('body')[0] 26763 }; 26764 this.config = { 26765 enabled_networks: 0, 26766 protocol: ['http', 'https'].indexOf(window.location.href.split(':')[0]) === -1 ? 'https://' : '//', 26767 url: window.location.href.replace("&", "%26"), 26768 caption: null, 26769 title: this.default_title(), 26770 image: this.default_image(), 26771 description: this.default_description(), 26772 ui: { 26773 flyout: 'top center', 26774 button_text: 'Share', 26775 button_font: true, 26776 icon_font: true 26777 }, 26778 networks: { 26779 twitter: { 26780 enabled: true, 26781 url: null, 26782 title: null, 26783 description: null 26784 }, 26785 facebook: { 26786 enabled: true, 26787 load_sdk: true, 26788 url: null, 26789 app_id: null, 26790 title: null, 26791 caption: null, 26792 description: null, 26793 image: null 26794 }, 26795 pinterest: { 26796 enabled: true, 26797 url: null, 26798 image: null, 26799 description: null 26800 }, 26801 reddit: { 26802 enabled: true, 26803 url: null, 26804 title: null 26805 }, 26806 linkedin: { 26807 enabled: true, 26808 url: null, 26809 title: null, 26810 description: null 26811 }, 26812 xing: { 26813 enabled: true, 26814 url: null, 26815 title: null, 26816 image: null, 26817 description: null 26818 }, 26819 whatsapp: { 26820 enabled: true, 26821 title: null, 26822 url: null 26823 }, 26824 email: { 26825 enabled: true, 26826 title: null, 26827 description: null, 26828 url: null 26829 } 26830 } 26831 }; 26832 this.setup(element, options); 26833 return this; 26834 } 26835 26836 Share.prototype.setup = function(element, opts) { 26837 var index, instance, instances, _i, _len; 26838 instances = document.querySelectorAll(element); 26839 this.extend(this.config, opts, true); 26840 this.set_global_configuration(); 26841 this.normalize_network_configuration(); 26842 if (this.config.ui.icon_font) { 26843 this.inject_icons(); 26844 } 26845 if (this.config.ui.button_font) { 26846 this.inject_fonts(); 26847 } 26848 if (this.config.networks.facebook.enabled && this.config.networks.facebook.load_sdk) { 26849 this.inject_facebook_sdk(); 26850 } 26851 for (index = _i = 0, _len = instances.length; _i < _len; index = ++_i) { 26852 instance = instances[index]; 26853 this.setup_instance(element, index); 26854 } 26855 }; 26856 26857 Share.prototype.setup_instance = function(element, index) { 26858 var button, instance, label, network, networks, _i, _len, _results, 26859 _this = this; 26860 instance = document.querySelectorAll(element)[index]; 26861 this.hide(instance); 26862 this.add_class(instance, "sharer-" + index); 26863 instance = document.querySelectorAll(element)[index]; 26864 this.inject_css(instance); 26865 this.inject_html(instance); 26866 this.show(instance); 26867 label = instance.getElementsByTagName("label")[0]; 26868 button = instance.getElementsByClassName("social")[0]; 26869 networks = instance.getElementsByTagName('li'); 26870 this.add_class(button, "networks-" + this.config.enabled_networks); 26871 label.addEventListener("click", function() { 26872 return _this.event_toggle(button); 26873 }); 26874 _this = this; 26875 _results = []; 26876 for (index = _i = 0, _len = networks.length; _i < _len; index = ++_i) { 26877 network = networks[index]; 26878 _results.push(network.addEventListener("click", function() { 26879 _this.event_network(instance, this); 26880 return _this.event_close(button); 26881 })); 26882 } 26883 return _results; 26884 }; 26885 26886 Share.prototype.event_toggle = function(button) { 26887 if (this.has_class(button, "active")) { 26888 return this.event_close(button); 26889 } else { 26890 return this.event_open(button); 26891 } 26892 }; 26893 26894 Share.prototype.event_open = function(button) { 26895 if (this.has_class(button, "load")) { 26896 this.remove_class(button, "load"); 26897 } 26898 return this.add_class(button, "active"); 26899 }; 26900 26901 Share.prototype.event_close = function(button) { 26902 return this.remove_class(button, "active"); 26903 }; 26904 26905 Share.prototype.event_network = function(instance, network) { 26906 var name; 26907 name = network.getAttribute("data-network"); 26908 this.hook("before", name, instance);
26909 this["network_" + name](); 26910 return this.hook("after", name, instance); 26911 }; 26912 26913 Share.prototype.open = function() { 26914 return this["public"]("open"); 26915 }; 26916 26917 Share.prototype.close = function() { 26918 return this["public"]("close"); 26919 }; 26920 26921 Share.prototype.toggle = function() { 26922 return this["public"]("toggle"); 26923 }; 26924 26925 Share.prototype["public"] = function(action) { 26926 var button, index, instance, _i, _len, _ref, _results; 26927 _ref = document.querySelectorAll(this.element); 26928 _results = []; 26929 for (index = _i = 0, _len = _ref.length; _i < _len; index = ++_i) { 26930 instance = _ref[index]; 26931 button = instance.getElementsByClassName("social")[0]; 26932 _results.push(this["event_" + action](button)); 26933 } 26934 return _results; 26935 }; 26936 26937 Share.prototype.network_facebook = function() { 26938 if (this.config.networks.facebook.load_sdk) { 26939 if (!window.FB) { 26940 return console.error("The Facebook JS SDK hasn't loaded yet."); 26941 } 26942 return FB.ui({ 26943 method: 'feed', 26944 name: this.config.networks.facebook.title, 26945 link: this.config.networks.facebook.url, 26946 picture: this.config.networks.facebook.image, 26947 caption: this.config.networks.facebook.caption, 26948 description: this.config.networks.facebook.description 26949 }); 26950 } else { 26951 return this.popup('https://www.facebook.com/sharer/sharer.php', { 26952 u: this.config.networks.facebook.url 26953 }); 26954 } 26955 }; 26956 26957 Share.prototype.network_twitter = function() { 26958 return this.popup('https://twitter.com/intent/tweet', { 26959 text: this.config.networks.twitter.title, 26960 url: this.config.networks.twitter.url 26961 }); 26962 }; 26963 26964 Share.prototype.network_pinterest = function() { 26965 return this.popup('https://www.pinterest.com/pin/create/button', { 26966 url: this.config.networks.pinterest.url, 26967 media: this.config.networks.pinterest.image, 26968 description: this.config.networks.pinterest.description 26969 }); 26970 }; 26971 26972 Share.prototype.network_linkedin = function() { 26973 return this.popup('https://www.linkedin.com/shareArticle', { 26974 url: this.config.networks.linkedin.url, 26975 title: this.config.networks.linkedin.title, 26976 summary: this.config.networks.linkedin.description 26977 }); 26978 } 26979 26980 Share.prototype.network_xing = function() { 26981 return this.popup('https://www.xing.com/spi/shares/new', { 26982 url: this.config.networks.xing.url, 26983 image: this.config.networks.xing.image, 26984 title: this.config.networks.xing.title, 26985 summary: this.config.networks.xing.description 26986 }); 26987 } 26988 26989 Share.prototype.network_whatsapp = function() { 26990 return this.popup('https://api.whatsapp.com/send', { 26991 text: this.config.networks.whatsapp.title + '%20' + this.config.networks.whatsapp.url, 26992 }); 26993 } 26994 26995 Share.prototype.network_email = function() { 26996 return this.popup('mailto:', { 26997 subject: this.config.networks.email.title, 26998 body: this.config.networks.email.url + '%0A%0A' + this.config.networks.email.description, 26999 }); 27000 }; 27001 27002 Share.prototype.inject_icons = function() { 27003 // return this.inject_stylesheet("https://www.sharebutton.co/fonts/v2/entypo.min.css"); 27004 }; 27005 27006 Share.prototype.inject_fonts = function() { 27007 // return this.inject_stylesheet("http://fonts.googleapis.com/css?family=Lato:900&text=" + this.config.ui.button_text); 27008 }; 27009 27010 Share.prototype.inject_stylesheet = function(url) { 27011 var link; 27012 if (!this.el.head.querySelector("link[href=\"" + url + "\"]")) { 27013 link = document.createElement("link"); 27014 link.setAttribute("rel", "stylesheet"); 27015 link.setAttribute("href", url); 27016 return this.el.head.appendChild(link); 27017 } 27018 }; 27019 27020 Share.prototype.inject_css = function(instance) { 27021 var css, meta, selector, style; 27022 selector = "." + (instance.getAttribute('class').split(" ").join(".")); 27023 if (!this.el.head.querySelector("meta[name='sharer" + selector + "']")) { 27024 this.config.selector = selector; 27025 css = getStyles(this.config); 27026 style = document.createElement("style"); 27027 style.type = "text/css"; 27028 if (style.styleSheet) { 27029 style.styleSheet.cssText = css; 27030 } else { 27031 style.appendChild(document.createTextNode(css)); 27032 } 27033 this.el.head.appendChild(style); 27034 delete this.config.selector; 27035 meta = document.createElement("meta"); 27036 meta.setAttribute("name", "sharer" + selector); 27037 return this.el.head.appendChild(meta); 27038 } 27039 }; 27040 27041 Share.prototype.inject_html = function(instance) { 27042 //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>"; 27043 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>"; 27044 }; 27045 27046 Share.prototype.inject_facebook_sdk = function() { 27047 var fb_root, script; 27048 if (!window.FB && this.config.networks.facebook.app_id && !this.el.body.querySelector('#fb-root')) { 27049 script = document.createElement("script"); 27050 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')"; 27051 fb_root = document.createElement("div"); 27052 fb_root.id = "fb-root"; 27053 this.el.body.appendChild(fb_root); 27054 return this.el.body.appendChild(script); 27055 } 27056 }; 27057 27058 Share.prototype.hook = function(type, network, instance) { 27059 var fn, opts; 27060 fn = this.config.networks[network][type]; 27061 if (typeof fn === "function") { 27062 opts = fn.call(this.config.networks[network], instance); 27063 if (opts !== void 0) { 27064 opts = this.normalize_filter_config_updates(opts); 27065 this.extend(this.config.networks[network], opts, true); 27066 this.normalize_network_configuration(); 27067 } 27068 } 27069 }; 27070 27071 Share.prototype.default_title = function() { 27072 var content; 27073 if (content = document.querySelector('meta[property="og:title"]') || document.querySelector('meta[name="twitter:title"]')) { 27074 return encodeURIComponent(content.getAttribute('content')); 27075 } else if (content = document.querySelector('title')) { 27076 return encodeURIComponent(content.innerText); 27077 } 27078 }; 27079 27080 Share.prototype.default_image = function() { 27081 var content; 27082 if (content = document.querySelector('meta[property="og:image"]') || document.querySelector('meta[name="twitter:image"]')) { 27083 return content.getAttribute('content'); 27084 } 27085 }; 27086 27087 Share.prototype.default_description = function() { 27088 var content; 27089 if (content = document.querySelector('meta[property="og:description"]') || document.querySelector('meta[name="twitter:description"]') || document.querySelector('meta[name="description"]')) { 27090 return encodeURIComponent(content.getAttribute('content')); 27091 } else { 27092 return ''; 27093 } 27094 }; 27095 27096 Share.prototype.set_global_configuration = function() { 27097 var display, network, option, options, _ref, _results; 27098 _ref = this.config.networks; 27099 _results = []; 27100 for (network in _ref) { 27101 options = _ref[network]; 27102 for (option in options) { 27103 if (this.config.networks[network][option] == null) { 27104 this.config.networks[network][option] = this.config[option]; 27105 } 27106 } 27107 if (this.config.networks[network].enabled) { 27108 display = 'block'; 27109 this.config.enabled_networks += 1; 27110 } else { 27111 display = 'none'; 27112 } 27113 _results.push(this.config.networks[network].display = display); 27114 } 27115 return _results; 27116 }; 27117 27118 Share.prototype.normalize_network_configuration = function() { 27119 if (!this.config.networks.facebook.app_id) { 27120 this.config.networks.facebook.load_sdk = false;
27121 } 27122 if (!this.is_encoded(this.config.networks.twitter.description)) { 27123 this.config.networks.twitter.description = encodeURIComponent(this.config.networks.twitter.description); 27124 } 27125 if (typeof this.config.networks.facebook.app_id === 'number') { 27126 return this.config.networks.facebook.app_id = this.config.networks.facebook.app_id.toString(); 27127 } 27128 }; 27129 27130 Share.prototype.normalize_filter_config_updates = function(opts) { 27131 if (this.config.networks.facebook.app_id !== opts.app_id) { 27132 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."); 27133 delete opts.app_id; 27134 } 27135 if (this.config.networks.facebook.load_sdk !== opts.load_sdk) { 27136 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."); 27137 delete opts.app_id; 27138 } 27139 return opts; 27140 }; 27141 27142 return Share; 27143 27144})(ShareUtils); 27145 return Share; 27146}); 27147 27148// Generated by CoffeeScript 1.9.2 27149 27150// @license Sticky-kit v1.1.2 | WTFPL | Leaf Corcoran 2015 | http://leafo.net 27151 27152(function() { 27153 var $, win; 27154 27155 $ = this.jQuery || window.jQuery; 27156 27157 win = $(window); 27158 27159 $.fn.stick_in_parent = function(opts) { 27160 var doc, elm, enable_bottoming, fn, i, inner_scrolling, len, manual_spacer, offset_top, outer_width, parent_selector, recalc_every, sticky_class; 27161 if (opts == null) { 27162 opts = {}; 27163 } 27164 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; 27165 if (offset_top == null) { 27166 offset_top = 0; 27167 } 27168 if (parent_selector == null) { 27169 parent_selector = void 0; 27170 } 27171 if (inner_scrolling == null) { 27172 inner_scrolling = true; 27173 } 27174 if (sticky_class == null) { 27175 sticky_class = "is_stuck"; 27176 } 27177 doc = $(document); 27178 if (enable_bottoming == null) { 27179 enable_bottoming = true; 27180 } 27181 outer_width = function(el) { 27182 var _el, computed, w; 27183 if (window.getComputedStyle) { 27184 _el = el[0]; 27185 computed = window.getComputedStyle(el[0]); 27186 w = parseFloat(computed.getPropertyValue("width")) + parseFloat(computed.getPropertyValue("margin-left")) + parseFloat(computed.getPropertyValue("margin-right")); 27187 if (computed.getPropertyValue("box-sizing") !== "border-box") { 27188 w += parseFloat(computed.getPropertyValue("border-left-width")) + parseFloat(computed.getPropertyValue("border-right-width")) + parseFloat(computed.getPropertyValue("padding-left")) + parseFloat(computed.getPropertyValue("padding-right")); 27189 } 27190 return w; 27191 } else { 27192 return el.outerWidth(true); 27193 } 27194 }; 27195 fn = function(elm, padding_bottom, parent_top, parent_height, top, height, el_float, detached) { 27196 var bottomed, detach, fixed, last_pos, last_scroll_height, offset, parent, recalc, recalc_and_tick, recalc_counter, spacer, tick; 27197 if (elm.data("sticky_kit")) { 27198 return; 27199 } 27200 elm.data("sticky_kit", true); 27201 last_scroll_height = doc.height(); 27202 parent = elm.parent(); 27203 if (parent_selector != null) { 27204 parent = parent.closest(parent_selector); 27205 } 27206 if (!parent.length) { 27207 throw "failed to find stick parent"; 27208 } 27209 fixed = false; 27210 bottomed = false; 27211 spacer = manual_spacer != null ? manual_spacer && elm.closest(manual_spacer) : $("<div />"); 27212 if (spacer) { 27213 spacer.css('position', elm.css('position')); 27214 } 27215 recalc = function() { 27216 var border_top, padding_top, restore; 27217 if (detached) { 27218 return; 27219 } 27220 last_scroll_height = doc.height(); 27221 border_top = parseInt(parent.css("border-top-width"), 10); 27222 padding_top = parseInt(parent.css("padding-top"), 10); 27223 padding_bottom = parseInt(parent.css("padding-bottom"), 10); 27224 parent_top = parent.offset().top + border_top + padding_top; 27225 parent_height = parent.height(); 27226 if (fixed) { 27227 fixed = false;
vendor: 6,068 bytes, lines 27228-27422
27228 bottomed = false; 27229 if (manual_spacer == null) { 27230 elm.insertAfter(spacer); 27231 spacer.detach(); 27232 } 27233 elm.css({ 27234 position: "", 27235 top: "", 27236 width: "", 27237 bottom: "" 27238 }).removeClass(sticky_class); 27239 restore = true; 27240 } 27241 top = elm.offset().top - (parseInt(elm.css("margin-top"), 10) || 0) - offset_top; 27242 height = elm.outerHeight(true); 27243 el_float = elm.css("float"); 27244 if (spacer) { 27245 spacer.css({ 27246 width: outer_width(elm), 27247 height: height, 27248 display: elm.css("display"), 27249 "vertical-align": elm.css("vertical-align"), 27250 "float": el_float 27251 }); 27252 } 27253 if (restore) { 27254 return tick(); 27255 } 27256 }; 27257 recalc(); 27258 if (height === parent_height) { 27259 return; 27260 } 27261 last_pos = void 0; 27262 offset = offset_top; 27263 recalc_counter = recalc_every; 27264 tick = function() { 27265 var css, delta, recalced, scroll, will_bottom, win_height; 27266 if (detached) { 27267 return; 27268 } 27269 recalced = false; 27270 if (recalc_counter != null) { 27271 recalc_counter -= 1; 27272 if (recalc_counter <= 0) { 27273 recalc_counter = recalc_every; 27274 recalc(); 27275 recalced = true; 27276 } 27277 } 27278 if (!recalced && doc.height() !== last_scroll_height) { 27279 recalc(); 27280 recalced = true; 27281 } 27282 scroll = win.scrollTop(); 27283 if (last_pos != null) { 27284 delta = scroll - last_pos; 27285 } 27286 last_pos = scroll; 27287 if (fixed) { 27288 if (enable_bottoming) { 27289 will_bottom = scroll + height + offset > parent_height + parent_top; 27290 if (bottomed && !will_bottom) { 27291 bottomed = false; 27292 elm.css({ 27293 position: "fixed", 27294 bottom: "", 27295 top: offset 27296 }).trigger("sticky_kit:unbottom"); 27297 } 27298 } 27299 if (scroll < top) { 27300 fixed = false; 27301 offset = offset_top; 27302 if (manual_spacer == null) { 27303 if (el_float === "left" || el_float === "right") { 27304 elm.insertAfter(spacer); 27305 } 27306 spacer.detach(); 27307 } 27308 css = { 27309 position: "", 27310 width: "", 27311 top: "" 27312 }; 27313 elm.css(css).removeClass(sticky_class).trigger("sticky_kit:unstick"); 27314 } 27315 if (inner_scrolling) { 27316 win_height = win.height(); 27317 if (height + offset_top > win_height) { 27318 if (!bottomed) { 27319 offset -= delta; 27320 offset = Math.max(win_height - height, offset); 27321 offset = Math.min(offset_top, offset); 27322 if (fixed) { 27323 elm.css({ 27324 top: offset + "px" 27325 }); 27326 } 27327 } 27328 } 27329 } 27330 } else { 27331 if (scroll > top) { 27332 fixed = true; 27333 css = { 27334 position: "fixed", 27335 top: offset 27336 }; 27337 css.width = elm.css("box-sizing") === "border-box" ? elm.outerWidth() + "px" : elm.width() + "px"; 27338 elm.css(css).addClass(sticky_class); 27339 if (manual_spacer == null) { 27340 elm.after(spacer); 27341 if (el_float === "left" || el_float === "right") { 27342 spacer.append(elm); 27343 } 27344 } 27345 elm.trigger("sticky_kit:stick"); 27346 } 27347 } 27348 if (fixed && enable_bottoming) { 27349 if (will_bottom == null) { 27350 will_bottom = scroll + height + offset > parent_height + parent_top; 27351 } 27352 if (!bottomed && will_bottom) { 27353 bottomed = true; 27354 if (parent.css("position") === "static") { 27355 parent.css({ 27356 position: "relative" 27357 }); 27358 } 27359 return elm.css({ 27360 position: "absolute", 27361 bottom: padding_bottom, 27362 top: "auto" 27363 }).trigger("sticky_kit:bottom"); 27364 } 27365 } 27366 }; 27367 recalc_and_tick = function() { 27368 recalc(); 27369 return tick(); 27370 }; 27371 detach = function() { 27372 detached = true; 27373 win.off("touchmove", tick); 27374 win.off("scroll", tick); 27375 win.off("resize", recalc_and_tick); 27376 $(document.body).off("sticky_kit:recalc", recalc_and_tick); 27377 elm.off("sticky_kit:detach", detach); 27378 elm.removeData("sticky_kit"); 27379 elm.css({ 27380 position: "", 27381 bottom: "", 27382 top: "", 27383 width: "" 27384 }); 27385 parent.position("position", ""); 27386 if (fixed) { 27387 if (manual_spacer == null) { 27388 if (el_float === "left" || el_float === "right") { 27389 elm.insertAfter(spacer); 27390 } 27391 spacer.remove(); 27392 } 27393 return elm.removeClass(sticky_class); 27394 } 27395 }; 27396 win.on("touchmove", tick); 27397 win.on("scroll", tick); 27398 win.on("resize", recalc_and_tick); 27399 $(document.body).on("sticky_kit:recalc", recalc_and_tick); 27400 elm.on("sticky_kit:detach", detach); 27401 return setTimeout(tick, 0); 27402 }; 27403 for (i = 0, len = this.length; i < len; i++) { 27404 elm = this[i]; 27405 fn($(elm)); 27406 } 27407 return this; 27408 }; 27409 27410}).call(this); 27411/* ========================================================================== 27412 * bootstrap-tab-history.js 27413 * Author: Michael Narayan <[email protected]> 27414 * Repository: https://github.com/mnarayan01/bootstrap-tab-history/ 27415 * ========================================================================== 27416 * Licensed under the Apache License, Version 2.0 (the "License"); you may 27417 * not use this file except in compliance with the License. You may obtain a 27418 * copy of the License at 27419 * 27420 * http://www.apache.org/licenses/LICENSE-2.0 27421 * 27422 * Unless required by applicable law or agreed to in writing, softw
27422are 27423 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 27424 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 27425 * License for the specific language governing permissions and limitations 27426 * under the License. 27427 * ========================================================================== */ 27428 27429/* ========================================================================== */ 27430/* JSHint directives */ 27431/* */ 27432/* global BootstrapTabHistory: true */ 27433/* */ 27434/* global document */ 27435/* global jQuery */ 27436/* global history */ 27437/* global window */ 27438/* ========================================================================== */ 27439 27440/** 27441 * Integrate [HTML5 history state tracking](https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Manipulating_the_browser_history) 27442 * with [`bootstrap/tab.js`](http://getbootstrap.com/javascript/#tabs). To enable tracking on a tab element, simply set 27443 * the `data-tab-history` attribute to true (or a string denoting a tab grouping). 27444 * 27445 * See the README for additional information. 27446 * 27447 * Functionality based upon bootstrap/tab.js v3.1.0; reference it when making any changes. 27448 */ 27449 27450BootstrapTabHistory = { 27451 options: { 27452 /** 27453 * When the anchor portion of the URI is used to activate a tab, scroll down to the given offset, rather than the 27454 * element with the given `id` attribute. Set to null to disable. Only relevant if showTabsBasedOnAnchor is true. 27455 * 27456 * May be overriden on a per-element basis by the attribute `data-tab-history-anchor-y-offset`. 27457 * 27458 * @public 27459 * @type {?number} 27460 */ 27461 defaultAnchorYOffset: 0, 27462 /** 27463 * Either 'push' or 'replace', for whether to use `history.pushState` or `history.replaceState`, resp. 27464 * 27465 * May be overriden on a per-element basis by the attribute `data-tab-history-changer`. 27466 * 27467 * @public 27468 * @type {string} 27469 */ 27470 defaultChanger: 'replace', 27471 /** 27472 * If true, update the URL in onShownTab in the calls to `history.pushState` and `history.replaceState`. Otherwise, 27473 * `null` is passed as the third parameter to these calls. 27474 * 27475 * May be overriden on a per-element basis by the attribute `data-tab-history-update-url`. 27476 * 27477 * @public 27478 * @type {boolean} 27479 */ 27480 defaultUpdateURL: false, 27481 /** 27482 * Should the anchor portion of the loaded URI be used to activate a single tab if no history was present on page 27483 * load. 27484 * 27485 * @public 27486 * @type {boolean} 27487 */ 27488 showTabsBasedOnAnchor: true 27489 } 27490}; 27491 27492(function () { 27493 'use strict'; 27494 27495 jQuery(function () { 27496 if(history && history.pushState && history.replaceState) { 27497 var bootstrapTabHistory = history.state && history.state.bootstrapTabHistory; 27498 27499 if(bootstrapTabHistory) { 27500 showTabsBasedOnState(bootstrapTabHistory); 27501 } else { 27502 showTabsBasedOnAnchor(); 27503 } 27504 27505 backfillHistoryState(); 27506 27507 jQuery(document).on('shown.bs.tab show.bs.collapse', onShownTab); 27508 jQuery(window).on('popstate', onPopState); 27509 } else { 27510 showTabsBasedOnAnchor(); 27511 } 27512 }); 27513 27514 /** 27515 * Used to prevent onShownTab from registering shown events that we triggered via showTabsBasedOnState. 27516 * 27517 * @type {boolean} 27518 */ 27519 var showingTabsBasedOnState = false; 27520 27521 /** 27522 * Used to update `history.state` to reflect the default active tabs on initial page load. This supports proper 27523 * `history.back` handling when `data-tab-history-update-url` is true. 27524 */ 27525 function backfillHistoryState() { 27526 var newState = null; 27527 27528 jQuery('li.active > [data-tab-history], .panel-title.active [data-tab-history]').each(function () {//edited by Uncode 27529 var $activeTabElement = jQuery(this); 27530 var selector = getTabSelector($activeTabElement); 27531 27532 if(selector) { 27533 var tabGroup = getTabGroup($activeTabElement); 27534 27535 if(tabGroup) { 27536 newState = createNewHistoryState(newState || history.state, tabGroup, selector); 27537 } 27538 } 27539 }); 27540 27541 if(newState) { 27542 history.replaceState(newState, '', null); 27543 } 27544 } 27545 27546 /** 27547 * Clone the existing state, ensure its bootstrapTabHistory attribute is an Object, and add the provided tabGroup to 27548 * said bootstrapTabHistory attribute. 27549 * 27550 * @param {?object} existingState 27551 * @param {!string} tabGroup 27552 * @param {!string} selector 27553 * @returns {!object} 27554 */ 27555 function createNewHistoryState(existingState, tabGroup, selector) { 27556 // Clone history.state and ensure it has a bootstrapTabHistory entry. 27557 var newState = jQuery.extend(true, {}, existingState, { 27558 bootstrapTabHistory: {} 27559 }); 27560 27561 newState.bootstrapTabHistory[tabGroup] = selector; 27562 27563 return newState; 27564 } 27565 27566 /** 27567 * @param {jQuery} $tab
27568 * @returns {?string} 27569 */ 27570 function getTabGroup($tab) { 27571 return parseTruthyAttributeValue($tab.data('tab-history')); 27572 } 27573 27574 /** 27575 * @param {jQuery} $tab 27576 * @returns {?string} 27577 */ 27578 function getTabSelector($tab) { 27579 return $tab.data('target') || $tab.attr('href'); 27580 } 27581 27582 /** 27583 * Receives the `shown.bs.tab` event. Updates `history.state` as appropriate. 27584 * 27585 * @param {jQuery.Event} shownEvt 27586 */ 27587 function onShownTab(shownEvt) { 27588 if(!showingTabsBasedOnState) { 27589 var $activatedTab = jQuery(shownEvt.target); 27590 if ( $activatedTab.hasClass('panel-collapse') ) 27591 $activatedTab = $activatedTab.closest('.panel').find('a'); 27592 var selector = getTabSelector($activatedTab); 27593 27594 if(selector) { 27595 var tabGroup = getTabGroup($activatedTab); 27596 27597 if(tabGroup) { 27598 var historyChanger = $activatedTab.data('tab-history-changer') || BootstrapTabHistory.options.defaultChanger; 27599 var newState = createNewHistoryState(history.state, tabGroup, selector); 27600 var updateURL = (function ($activatedTab) { 27601 if(selector[0] === '#') { 27602 var elementUpdateURLOption = parseTruthyAttributeValue($activatedTab.data('tab-history-update-url')); 27603 27604 if(elementUpdateURLOption === undefined) { 27605 return BootstrapTabHistory.options.defaultUpdateURL; 27606 } else { 27607 return elementUpdateURLOption; 27608 } 27609 } else { 27610 return false; 27611 } 27612 })($activatedTab); 27613 27614 switch(historyChanger) { 27615 case 'push': 27616 history.pushState(newState, '', updateURL ? selector : null); 27617 break; 27618 case 'replace': 27619 history.replaceState(newState, '', updateURL ? selector : null); 27620 break; 27621 default: 27622 throw new Error('Unknown tab-history-changer: ' + historyChanger); 27623 } 27624 } 27625 } 27626 } 27627 } 27628 27629 /** 27630 * Receives the `popstate` event. Shows tabs based on the value of `history.state` as appropriate. 27631 */ 27632 function onPopState() { 27633 var bootstrapTabHistory = history.state && history.state.bootstrapTabHistory; 27634 27635 if(bootstrapTabHistory) { 27636 showTabsBasedOnState(bootstrapTabHistory); 27637 } 27638 } 27639 27640 /** 27641 * Returns the given value, _unless_ that value is an empty string, in which case `true` is returned. 27642 * 27643 * Rationale: HAML data attributes which are set to `true` are rendered as a blank string. 27644 * 27645 * @param {*} value 27646 * @returns {*} 27647 */ 27648 function parseTruthyAttributeValue(value) { 27649 if(value) { 27650 return value; 27651 } else if(value === '') { 27652 return true; 27653 } else { 27654 return value; 27655 } 27656 } 27657 27658 /** 27659 * Show tabs based upon the anchor component of `window.location`. 27660 */ 27661 function showTabsBasedOnAnchor() { 27662 if(BootstrapTabHistory.options.showTabsBasedOnAnchor) { 27663 var anchor = window.location && window.location.hash; 27664 27665 if(anchor) { 27666 var $tabElement = showTabForSelector(anchor); 27667 27668 if($tabElement && window.addEventListener && window.removeEventListener) { 27669 var anchorYOffset = (function ($tabElement) { 27670 var elementSetting = $tabElement.data('tab-history-anchor-y-offset'); 27671 27672 if(elementSetting === undefined) { 27673 return BootstrapTabHistory.options.defaultAnchorYOffset; 27674 } else { 27675 return elementSetting; 27676 } 27677 })($tabElement); 27678 27679 // HACK: This prevents scrolling to the tab on page load. This relies on the fact that we should never get 27680 // here on `history.forward`, `history.back`, or `location.reload`, since in all those situations the 27681 // `history.state` object should have been used (unless the browser did not support the modern History API). 27682 if(anchorYOffset || anchorYOffset === 0) { 27683 var scrollListener = function resetAnchorScroll () { 27684 window.removeEventListener('scroll', scrollListener); 27685 window.scrollTo(0, anchorYOffset); 27686 }; 27687 27688 window.addEventListener('scroll', scrollListener); 27689 } 27690 } 27691 } 27692 } 27693 } 27694 27695 /** 27696 * Show a tab which corresponds to the provided selector. 27697 * 27698 * @param {string} selector - A CSS selector. 27699 * @returns {?jQuery} - The tab which was found to show (even if said tab was already active). 27700 */ 27701 function showTabForSelector(selector) { 27702 var $tabElement = (function (selector) { 27703 var $ret = null; 27704 27705 jQuery('[data-toggle="tab"], [data-toggle="pill"], [data-toggle="collapse"]').each(function () { 27706 var $potentialTab = jQuery(this); 27707 27708 if(($potentialTab.attr('href') === selector || $potentialTab.data('target') === selector ) && getTabGroup($potentialTab)) { 27709 $ret = $potentialTab; 27710 return false;
vendor: 43,483 bytes, lines 27711-28927
27711 } else { 27712 return null; 27713 } 27714 }); 27715 27716 return $ret; 27717 })(selector); 27718 27719 if($tabElement) { 27720 if ( !$tabElement.parent().hasClass('active') ) { 27721 $tabElement.trigger('click'); 27722 } 27723 //$tabElement.tab('show'); 27724 } 27725 27726 return $tabElement; 27727 } 27728 27729 /** 27730 * Iterate through the provided set of tab tab groups, showing the tabs based on the stored selectors. 27731 * 27732 * @param {object} bootstrapTabHistory - Each of the values is passed to showTabForSelector; the keys are actually irrelevant. 27733 */ 27734 function showTabsBasedOnState(bootstrapTabHistory) { 27735 showingTabsBasedOnState = true; 27736 27737 try { 27738 for(var k in bootstrapTabHistory) { 27739 if(bootstrapTabHistory.hasOwnProperty(k)) { 27740 showTabForSelector(bootstrapTabHistory[k]); 27741 } 27742 } 27743 } finally { 27744 showingTabsBasedOnState = false; 27745 } 27746 } 27747})(); 27748 27749/*! 27750 * justifiedGallery - v3.8.1 27751 * http://miromannino.github.io/Justified-Gallery/ 27752 * Copyright (c) 2020 Miro Mannino 27753 * Licensed under the MIT license. 27754 */ 27755(function (factory) { 27756 if (typeof define === 'function' && define.amd) { 27757 // AMD. Register as an anonymous module. 27758 define(['jquery'], factory); 27759 } else if (typeof module === 'object' && module.exports) { 27760 // Node/CommonJS 27761 module.exports = function (root, jQuery) { 27762 if (jQuery === undefined) { 27763 // require('jQuery') returns a factory that requires window to 27764 // build a jQuery instance, we normalize how we use modules 27765 // that require this pattern but the window provided is a noop 27766 // if it's defined (how jquery works) 27767 if (typeof window !== 'undefined') { 27768 jQuery = require('jquery'); 27769 } 27770 else { 27771 jQuery = require('jquery')(root); 27772 } 27773 } 27774 factory(jQuery); 27775 return jQuery; 27776 }; 27777 } else { 27778 // Browser globals 27779 factory(jQuery); 27780 } 27781}(function ($) { 27782 27783 /** 27784 * Justified Gallery controller constructor 27785 * 27786 * @param $gallery the gallery to build 27787 * @param settings the settings (the defaults are in JustifiedGallery.defaults) 27788 * @constructor 27789 */ 27790 var JustifiedGallery = function ($gallery, settings) { 27791 27792 this.settings = settings; 27793 this.checkSettings(); 27794 27795 this.imgAnalyzerTimeout = null; 27796 this.entries = null; 27797 this.buildingRow = { 27798 entriesBuff: [], 27799 width: 0, 27800 height: 0, 27801 aspectRatio: 0 27802 }; 27803 this.lastFetchedEntry = null; 27804 this.lastAnalyzedIndex = -1; 27805 this.yield = { 27806 every: 2, // do a flush every n flushes (must be greater than 1) 27807 flushed: 0 // flushed rows without a yield 27808 }; 27809 this.border = settings.border >= 0 ? settings.border : settings.margins; 27810 this.maxRowHeight = this.retrieveMaxRowHeight(); 27811 this.suffixRanges = this.retrieveSuffixRanges(); 27812 this.offY = this.border; 27813 this.rows = 0; 27814 this.spinner = { 27815 phase: 0, 27816 timeSlot: 150, 27817 $el: $('<div class="jg-spinner"><span></span><span></span><span></span></div>'), 27818 intervalId: null 27819 }; 27820 this.scrollBarOn = false; 27821 this.checkWidthIntervalId = null; 27822 this.galleryWidth = $gallery.width(); 27823 this.$gallery = $gallery; 27824 27825 }; 27826 27827 /** @returns {String} the best suffix given the width and the height */ 27828 JustifiedGallery.prototype.getSuffix = function (width, height) { 27829 var longestSide, i; 27830 longestSide = (width > height) ? width : height; 27831 for (i = 0; i < this.suffixRanges.length; i++) { 27832 if (longestSide <= this.suffixRanges[i]) { 27833 return this.settings.sizeRangeSuffixes[this.suffixRanges[i]]; 27834 } 27835 } 27836 return this.settings.sizeRangeSuffixes[this.suffixRanges[i - 1]]; 27837 }; 27838 27839 /** 27840 * Remove the suffix from the string 27841 * 27842 * @returns {string} a new string without the suffix 27843 */ 27844 JustifiedGallery.prototype.removeSuffix = function (str, suffix) { 27845 return str.substring(0, str.length - suffix.length); 27846 }; 27847 27848 /** 27849 * @returns {boolean} a boolean to say if the suffix is contained in the str or not 27850 */ 27851 JustifiedGallery.prototype.endsWith = function (str, suffix) { 27852 return str.indexOf(suffix, str.length - suffix.length) !== -1; 27853 }; 27854 27855 /** 27856 * Get the used suffix of a particular url 27857 * 27858 * @param str 27859 * @returns {String} return the used suffix 27860 */ 27861 JustifiedGallery.prototype.getUsedSuffix = function (str) { 27862 for (var si in this.settings.sizeRangeSuffixes) { 27863 if (this.settings.sizeRangeSuffixes.hasOwnProperty(si)) { 27864 if (this.settings.sizeRangeSuffixes[si].length === 0) continue; 27865 if (this.endsWith(str, this.settings.sizeRangeSuffixes[si])) return this.settings.sizeRangeSuffixes[si]; 27866 } 27867 } 27868 return ''; 27869 }; 27870 27871 /** 27872 * Given an image src, with the width and the height, returns the new image src with the 27873 * best suffix to show the best quality thumbnail. 27874 * 27875 * @returns {String} the suffix to use 27876 */ 27877 JustifiedGallery.prototype.newSrc = function (imageSrc, imgWidth, imgHeight, image) { 27878 var newImageSrc; 27879 27880 if (this.settings.thumbnailPath) { 27881 newImageSrc = this.settings.thumbnailPath(imageSrc, imgWidth, imgHeight, image); 27882 } else { 27883 var matchRes = imageSrc.match(this.settings.extension); 27884 var ext = (matchRes !== null) ? matchRes[0] : ''; 27885 newImageSrc = imageSrc.replace(this.settings.extension, ''); 27886 newImageSrc = this.removeSuffix(newImageSrc, this.getUsedSuffix(newImageSrc)); 27887 newImageSrc += this.getSuffix(imgWidth, imgHeight) + ext; 27888 } 27889 27890 return newImageSrc; 27891 }; 27892 27893 /** 27894 * Shows the images that is in the given entry 27895 * 27896 * @param $entry the entry 27897 * @param callback the callback that is called when the show animation is finished 27898 */ 27899 JustifiedGallery.prototype.showImg = function ($entry, callback) { 27900 if (this.settings.cssAnimation) { 27901 $entry.addClass('jg-entry-visible'); 27902 if (callback) callback(); 27903 } else { 27904 $entry.stop().fadeTo(this.settings.imagesAnimationDuration, 1.0, callback); 27905 $entry.find(this.settings.imgSelector).stop().fadeTo(this.settings.imagesAnimationDuration, 1.0, callback); 27906 } 27907 }; 27908 27909 /** 27910 * Extract the image src form the image, looking from the 'safe-src', and if it can't be found, from the 27911 * 'src' attribute. It saves in the image data the 'jg.originalSrc' field, with the extracted src. 27912 * 27913 * @param $image the image to analyze 27914 * @returns {String} the extracted src 27915 */ 27916 JustifiedGallery.prototype.extractImgSrcFromImage = function ($image) { 27917 var imageSrc = $image.data('safe-src'); 27918 var imageSrcLoc = 'data-safe-src'; 27919 // Begin Uncode edit 27920 if (typeof imageSrc === 'undefined') { 27921 var imageCurrentSrc = $image[0].currentSrc; 27922 if (imageCurrentSrc) { 27923 imageSrc = imageCurrentSrc; 27924 } else { 27925 imageSrc = $image.attr('src'); 27926 } 27927 imageSrcLoc = 'src'; 27928 } 27929 // End Uncode edit 27930 $image.data('jg.originalSrc', imageSrc); // this is saved for the destroy method 27931 $image.data('jg.src', imageSrc); // this will change overtime 27932 $image.data('jg.originalSrcLoc', imageSrcLoc); // this is saved for the destroy method 27933 return imageSrc; 27934 }; 27935 27936 /** @returns {jQuery} the image in the given entry */ 27937 JustifiedGallery.prototype.imgFromEntry = function ($entry) { 27938 var $img = $entry.find(this.settings.imgSelector); 27939 if ($img.length === 0) $img = $entry.find('.t-entry-visual-cont img');//hacked by Uncode 27940 return $img.length === 0 ? null : $img; 27941 }; 27942 27943 /** @returns {jQuery} the caption in the given entry */ 27944 JustifiedGallery.prototype.captionFromEntry = function ($entry) { 27945 var $caption = $entry.find('> .jg-caption'); 27946 return $caption.length === 0 ? null : $caption; 27947 }; 27948 27949 /** 27950 * Display the entry 27951 * 27952 * @param {jQuery} $entry the entry to display 27953 * @param {int} x the x position where the entry must be positioned 27954 * @param y the y position where the entry must be positioned 27955 * @param imgWidth the image width 27956 * @param imgHeight the image height 27957 * @param rowHeight the row height of the row that owns the entry 27958 */ 27959 JustifiedGallery.prototype.displayEntry = function ($entry, x, y, imgWidth, imgHeight, rowHeight) { 27960 $entry.width(imgWidth); 27961 $entry.height(Math.floor(rowHeight));//hacked by Uncode 27962 $entry.css('top', Math.floor(y));//hacked by Uncode 27963 $entry.css('left', x); 27964 27965 var $image = this.imgFromEntry($entry); 27966 if ($image !== null) { 27967 $image.css('width', imgWidth); 27968 $image.css('height', imgHeight); 27969 $image.css('margin-left', - imgWidth / 2); 27970 $image.css('margin-top', - imgHeight / 2); 27971 27972 // Image reloading for an high quality of thumbnails 27973 var imageSrc = $image.data('jg.src'); 27974 if (imageSrc) { 27975 imageSrc = this.newSrc(imageSrc, imgWidth, imgHeight, $image[0]); 27976 27977 $image.one('error', function () { 27978 this.resetImgSrc($image); //revert to the original thumbnail 27979 }); 27980 27981 var loadNewImage = function () { 27982 // if (imageSrc !== newImageSrc) { 27983 $image.attr('src', imageSrc); 27984 // } 27985 }; 27986 27987 if ($entry.data('jg.loaded') === 'skipped' && imageSrc) { 27988 this.onImageEvent(imageSrc, (function() { 27989 this.showImg($entry, loadNewImage); //load the new image after the fadeIn 27990 $entry.data('jg.loaded', true); 27991 }).bind(this)); 27992 } else { 27993 this.showImg($entry, loadNewImage); //load the new image after the fadeIn 27994 } 27995 27996 } 27997 27998 } else { 27999 this.showImg($entry); 28000 } 28001 28002 this.displayEntryCaption($entry); 28003 }; 28004 28005 /** 28006 * Display the entry caption. If the caption element doesn't exists, it creates the caption using the 'alt' 28007 * or the 'title' attributes. 28008 * 28009 * @param {jQuery} $entry the entry to process 28010 */ 28011 JustifiedGallery.prototype.displayEntryCaption = function ($entry) { 28012 var $image = this.imgFromEntry($entry); 28013 if ($image !== null && this.settings.captions) { 28014 var $imgCaption = this.captionFromEntry($entry); 28015 28016 // Create it if it doesn't exists 28017 if ($imgCaption === null) { 28018 var caption = $image.attr('alt'); 28019 if (!this.isValidCaption(caption)) caption = $entry.attr('title'); 28020 if (this.isValidCaption(caption)) { // Create only we found something 28021 $imgCaption = $('<div class="jg-caption">' + caption + '</div>'); 28022 $entry.append($imgCaption); 28023 $entry.data('jg.createdCaption', true); 28024 } 28025 } 28026 28027 // Create events (we check again the $imgCaption because it can be still inexistent) 28028 if ($imgCaption !== null) { 28029 if (!this.settings.cssAnimation) $imgCaption.stop().fadeTo(0, this.settings.captionSettings.nonVisibleOpacity); 28030 this.addCaptionEventsHandlers($entry); 28031 } 28032 } else { 28033 this.removeCaptionEventsHandlers($entry); 28034 } 28035 }; 28036 28037 /** 28038 * Validates the caption 28039 * 28040 * @param caption The caption that should be validated 28041 * @return {boolean} Validation result 28042 */ 28043 JustifiedGallery.prototype.isValidCaption = function (caption) { 28044 return (typeof caption !== 'undefined' && caption.length > 0); 28045 }; 28046 28047 /** 28048 * The callback for the event 'mouseenter'. It assumes that the event currentTarget is an entry. 28049 * It shows the caption using jQuery (or using CSS if it is configured so) 28050 * 28051 * @param {Event} eventObject the event object 28052 */ 28053 JustifiedGallery.prototype.onEntryMouseEnterForCaption = function (eventObject) { 28054 var $caption = this.captionFromEntry($(eventObject.currentTarget)); 28055 if (this.settings.cssAnimation) { 28056 $caption.addClass('jg-caption-visible').removeClass('jg-caption-hidden'); 28057 } else { 28058 $caption.stop().fadeTo(this.settings.captionSettings.animationDuration, 28059 this.settings.captionSettings.visibleOpacity); 28060 } 28061 }; 28062 28063 /** 28064 * The callback for the event 'mouseleave'. It assumes that the event currentTarget is an entry. 28065 * It hides the caption using jQuery (or using CSS if it is configured so) 28066 * 28067 * @param {Event} eventObject the event object 28068 */ 28069 JustifiedGallery.prototype.onEntryMouseLeaveForCaption = function (eventObject) { 28070 var $caption = this.captionFromEntry($(eventObject.currentTarget)); 28071 if (this.settings.cssAnimation) { 28072 $caption.removeClass('jg-caption-visible').removeClass('jg-caption-hidden'); 28073 } else { 28074 $caption.stop().fadeTo(this.settings.captionSettings.animationDuration, 28075 this.settings.captionSettings.nonVisibleOpacity); 28076 } 28077 }; 28078 28079 /** 28080 * Add the handlers of the entry for the caption 28081 * 28082 * @param $entry the entry to modify 28083 */ 28084 JustifiedGallery.prototype.addCaptionEventsHandlers = function ($entry) { 28085 var captionMouseEvents = $entry.data('jg.captionMouseEvents'); 28086 if (typeof captionMouseEvents === 'undefined') { 28087 captionMouseEvents = { 28088 mouseenter: $.proxy(this.onEntryMouseEnterForCaption, this), 28089 mouseleave: $.proxy(this.onEntryMouseLeaveForCaption, this) 28090 }; 28091 $entry.on('mouseenter', undefined, undefined, captionMouseEvents.mouseenter); 28092 $entry.on('mouseleave', undefined, undefined, captionMouseEvents.mouseleave); 28093 $entry.data('jg.captionMouseEvents', captionMouseEvents); 28094 } 28095 }; 28096 28097 /** 28098 * Remove the handlers of the entry for the caption 28099 * 28100 * @param $entry the entry to modify 28101 */ 28102 JustifiedGallery.prototype.removeCaptionEventsHandlers = function ($entry) { 28103 var captionMouseEvents = $entry.data('jg.captionMouseEvents'); 28104 if (typeof captionMouseEvents !== 'undefined') { 28105 $entry.off('mouseenter', undefined, captionMouseEvents.mouseenter); 28106 $entry.off('mouseleave', undefined, captionMouseEvents.mouseleave); 28107 $entry.removeData('jg.captionMouseEvents'); 28108 } 28109 }; 28110 28111 /** 28112 * Clear the building row data to be used for a new row 28113 */ 28114 JustifiedGallery.prototype.clearBuildingRow = function () { 28115 this.buildingRow.entriesBuff = []; 28116 this.buildingRow.aspectRatio = 0; 28117 this.buildingRow.width = 0; 28118 }; 28119 28120 /** 28121 * Justify the building row, preparing it to 28122 * 28123 * @param isLastRow 28124 * @param hiddenRow undefined or false for normal behavior. hiddenRow = true to hide the row. 28125 * @returns a boolean to know if the row has been justified or not 28126 */ 28127 JustifiedGallery.prototype.prepareBuildingRow = function (isLastRow, hiddenRow) { 28128 var i, $entry, imgAspectRatio, newImgW, newImgH, justify = true; 28129 var minHeight = 0; 28130 var availableWidth = this.galleryWidth - 2 * this.border - ( 28131 (this.buildingRow.entriesBuff.length - 1) * this.settings.margins); 28132 var rowHeight = Math.floor( availableWidth / this.buildingRow.aspectRatio );//hacked by Uncode 28133 var defaultRowHeight = this.settings.rowHeight; 28134 var justifiable = this.buildingRow.width / availableWidth > this.settings.justifyThreshold; 28135 28136 //Skip the last row if we can't justify it and the lastRow == 'hide' 28137 if (hiddenRow || (isLastRow && this.settings.lastRow === 'hide' && !justifiable)) { 28138 for (i = 0; i < this.buildingRow.entriesBuff.length; i++) { 28139 $entry = this.buildingRow.entriesBuff[i]; 28140 if (this.settings.cssAnimation) 28141 $entry.removeClass('jg-entry-visible'); 28142 else { 28143 $entry.stop().fadeTo(0, 0.1); 28144 $entry.find('> img, > a > img').fadeTo(0, 0); 28145 } 28146 } 28147 return -1; 28148 } 28149 28150 // With lastRow = nojustify, justify if is justificable (the images will not become too big) 28151 if (isLastRow && !justifiable && this.settings.lastRow !== 'justify' && this.settings.lastRow !== 'hide') { 28152 justify = false; 28153 28154 if (this.rows > 0) { 28155 defaultRowHeight = (this.offY - this.border - this.settings.margins * this.rows) / this.rows; 28156 justify = defaultRowHeight * this.buildingRow.aspectRatio / availableWidth > this.settings.justifyThreshold; 28157 } 28158 } 28159 28160 for (i = 0; i < this.buildingRow.entriesBuff.length; i++) { 28161 $entry = this.buildingRow.entriesBuff[i]; 28162 imgAspectRatio = $entry.data('jg.width') / $entry.data('jg.height'); 28163 28164 if (justify) { 28165 newImgW = (i === this.buildingRow.entriesBuff.length - 1) ? availableWidth : rowHeight * imgAspectRatio; 28166 newImgH = rowHeight; 28167 } else { 28168 newImgW = defaultRowHeight * imgAspectRatio; 28169 newImgH = defaultRowHeight; 28170 } 28171 28172 availableWidth -= Math.round(newImgW); 28173 $entry.data('jg.jwidth', Math.round(newImgW)); 28174 $entry.data('jg.jheight', Math.ceil(newImgH)); 28175 if (i === 0 || minHeight > newImgH) minHeight = newImgH; 28176 } 28177 28178 this.buildingRow.height = minHeight; 28179 return justify; 28180 }; 28181 28182 /** 28183 * Flush a row: justify it, modify the gallery height accordingly to the row height 28184 * 28185 * @param isLastRow 28186 * @param hiddenRow undefined or false for normal behavior. hiddenRow = true to hide the row. 28187 */ 28188 JustifiedGallery.prototype.flushRow = function (isLastRow, hiddenRow) { 28189 var settings = this.settings; 28190 var $entry, buildingRowRes, offX = this.border, i; 28191 28192 buildingRowRes = this.prepareBuildingRow(isLastRow, hiddenRow); 28193 if (hiddenRow || (isLastRow && settings.lastRow === 'hide' && buildingRowRes === -1)) { 28194 this.clearBuildingRow(); 28195 return; 28196 } 28197 28198 if (this.maxRowHeight) { 28199 if (this.maxRowHeight < this.buildingRow.height) this.buildingRow.height = this.maxRowHeight; 28200 } 28201 28202 //Align last (unjustified) row 28203 if (isLastRow && (settings.lastRow === 'center' || settings.lastRow === 'right')) { 28204 var availableWidth = this.galleryWidth - 2 * this.border - (this.buildingRow.entriesBuff.length - 1) * settings.margins; 28205 28206 for (i = 0; i < this.buildingRow.entriesBuff.length; i++) { 28207 $entry = this.buildingRow.entriesBuff[i]; 28208 availableWidth -= $entry.data('jg.jwidth'); 28209 } 28210 28211 if (settings.lastRow === 'center') 28212 offX += Math.round(availableWidth / 2); 28213 else if (settings.lastRow === 'right') 28214 offX += availableWidth; 28215 } 28216 28217 var lastEntryIdx = this.buildingRow.entriesBuff.length - 1; 28218 for (i = 0; i <= lastEntryIdx; i++) { 28219 $entry = this.buildingRow.entriesBuff[this.settings.rtl ? lastEntryIdx - i : i]; 28220 this.displayEntry($entry, offX, this.offY, $entry.data('jg.jwidth'), $entry.data('jg.jheight'), this.buildingRow.height); 28221 offX += $entry.data('jg.jwidth') + settings.margins; 28222 } 28223 28224 //Gallery Height 28225 this.galleryHeightToSet = this.offY + this.buildingRow.height + this.border; 28226 this.setGalleryTempHeight(this.galleryHeightToSet + this.getSpinnerHeight()); 28227 28228 if (!isLastRow || (this.buildingRow.height <= settings.rowHeight && buildingRowRes)) { 28229 //Ready for a new row 28230 this.offY += this.buildingRow.height + settings.margins; 28231 this.rows += 1; 28232 this.clearBuildingRow(); 28233 this.settings.triggerEvent.call(this, 'jg.rowflush'); 28234 } 28235 }; 28236 28237 28238 // Scroll position not restoring: https://github.com/miromannino/Justified-Gallery/issues/221 28239 var galleryPrevStaticHeight = 0; 28240 28241 JustifiedGallery.prototype.rememberGalleryHeight = function () { 28242 galleryPrevStaticHeight = this.$gallery.height(); 28243 this.$gallery.height(galleryPrevStaticHeight); 28244 }; 28245 28246 // grow only 28247 JustifiedGallery.prototype.setGalleryTempHeight = function (height) { 28248 galleryPrevStaticHeight = Math.max(height, galleryPrevStaticHeight); 28249 this.$gallery.height(galleryPrevStaticHeight); 28250 }; 28251 28252 JustifiedGallery.prototype.setGalleryFinalHeight = function (height) { 28253 galleryPrevStaticHeight = height; 28254 this.$gallery.height(height); 28255 }; 28256 28257 /** 28258 * Checks the width of the gallery container, to know if a new justification is needed 28259 */ 28260 JustifiedGallery.prototype.checkWidth = function () { 28261 this.checkWidthIntervalId = setInterval($.proxy(function () { 28262 28263 // if the gallery is not currently visible, abort. 28264 if (!this.$gallery.is(":visible")) return; 28265 28266 var galleryWidth = parseFloat(this.$gallery.width()); 28267 if (Math.abs(galleryWidth - this.galleryWidth) > this.settings.refreshSensitivity) { 28268 this.galleryWidth = galleryWidth; 28269 this.rewind(); 28270 28271 this.rememberGalleryHeight(); 28272 28273 // Restart to analyze 28274 this.startImgAnalyzer(true); 28275 } 28276 }, this), this.settings.refreshTime); 28277 }; 28278 28279 /** 28280 * @returns {boolean} a boolean saying if the spinner is active or not 28281 */ 28282 JustifiedGallery.prototype.isSpinnerActive = function () { 28283 return this.spinner.intervalId !== null; 28284 }; 28285 28286 /** 28287 * @returns {int} the spinner height 28288 */ 28289 JustifiedGallery.prototype.getSpinnerHeight = function () { 28290 return this.spinner.$el.innerHeight(); 28291 }; 28292 28293 /** 28294 * Stops the spinner animation and modify the gallery height to exclude the spinner 28295 */ 28296 JustifiedGallery.prototype.stopLoadingSpinnerAnimation = function () { 28297 clearInterval(this.spinner.intervalId); 28298 this.spinner.intervalId = null; 28299 this.setGalleryTempHeight(this.$gallery.height() - this.getSpinnerHeight()); 28300 this.spinner.$el.detach(); 28301 }; 28302 28303 /** 28304 * Starts the spinner animation 28305 */ 28306 JustifiedGallery.prototype.startLoadingSpinnerAnimation = function () { 28307 var spinnerContext = this.spinner; 28308 var $spinnerPoints = spinnerContext.$el.find('span'); 28309 clearInterval(spinnerContext.intervalId); 28310 this.$gallery.append(spinnerContext.$el); 28311 this.setGalleryTempHeight(this.offY + this.buildingRow.height + this.getSpinnerHeight()); 28312 spinnerContext.intervalId = setInterval(function () { 28313 if (spinnerContext.phase < $spinnerPoints.length) { 28314 $spinnerPoints.eq(spinnerContext.phase).fadeTo(spinnerContext.timeSlot, 1); 28315 } else { 28316 $spinnerPoints.eq(spinnerContext.phase - $spinnerPoints.length).fadeTo(spinnerContext.timeSlot, 0); 28317 } 28318 spinnerContext.phase = (spinnerContext.phase + 1) % ($spinnerPoints.length * 2); 28319 }, spinnerContext.timeSlot); 28320 }; 28321 28322 /** 28323 * Rewind the image analysis to start from the first entry. 28324 */ 28325 JustifiedGallery.prototype.rewind = function () { 28326 this.lastFetchedEntry = null; 28327 this.lastAnalyzedIndex = -1; 28328 this.offY = this.border; 28329 this.rows = 0; 28330 this.clearBuildingRow(); 28331 }; 28332 28333 /** 28334 * @returns {String} `settings.selector` rejecting spinner element 28335 */ 28336 JustifiedGallery.prototype.getSelectorWithoutSpinner = function () { 28337 return this.settings.selector + ', div:not(.jg-spinner)'; 28338 }; 28339 28340 /** 28341 * @returns {Array} all entries matched by `settings.selector` 28342 */ 28343 JustifiedGallery.prototype.getAllEntries = function () { 28344 var selector = this.getSelectorWithoutSpinner(); 28345 return this.$gallery.children(selector).toArray(); 28346 }; 28347 28348 /** 28349 * Update the entries searching it from the justified gallery HTML element 28350 * 28351 * @param norewind if norewind only the new entries will be changed (i.e. randomized, sorted or filtered) 28352 * @returns {boolean} true if some entries has been founded 28353 */ 28354 JustifiedGallery.prototype.updateEntries = function (norewind) { 28355 var newEntries; 28356 28357 if (norewind && this.lastFetchedEntry != null) { 28358 var selector = this.getSelectorWithoutSpinner(); 28359 newEntries = $(this.lastFetchedEntry).nextAll(selector).toArray(); 28360 } else { 28361 this.entries = []; 28362 newEntries = this.getAllEntries(); 28363 } 28364 28365 if (newEntries.length > 0) { 28366 28367 // Sort or randomize 28368 if ($.isFunction(this.settings.sort)) { 28369 newEntries = this.sortArray(newEntries); 28370 } else if (this.settings.randomize) { 28371 newEntries = this.shuffleArray(newEntries); 28372 } 28373 this.lastFetchedEntry = newEntries[newEntries.length - 1]; 28374 28375 // Filter 28376 if (this.settings.filter) { 28377 newEntries = this.filterArray(newEntries); 28378 } else { 28379 this.resetFilters(newEntries); 28380 } 28381 28382 } 28383 28384 this.entries = this.entries.concat(newEntries); 28385 return true; 28386 }; 28387 28388 /** 28389 * Apply the entries order to the DOM, iterating the entries and appending the images 28390 * 28391 * @param entries the entries that has been modified and that must be re-ordered in the DOM 28392 */ 28393 JustifiedGallery.prototype.insertToGallery = function (entries) { 28394 var that = this; 28395 $.each(entries, function () { 28396 $(this).appendTo(that.$gallery); 28397 }); 28398 }; 28399 28400 /** 28401 * Shuffle the array using the Fisher-Yates shuffle algorithm 28402 * 28403 * @param a the array to shuffle 28404 * @return the shuffled array 28405 */ 28406 JustifiedGallery.prototype.shuffleArray = function (a) { 28407 var i, j, temp; 28408 for (i = a.length - 1; i > 0; i--) { 28409 j = Math.floor(Math.random() * (i + 1)); 28410 temp = a[i]; 28411 a[i] = a[j]; 28412 a[j] = temp; 28413 } 28414 this.insertToGallery(a); 28415 return a; 28416 }; 28417 28418 /** 28419 * Sort the array using settings.comparator as comparator 28420 * 28421 * @param a the array to sort (it is sorted) 28422 * @return the sorted array 28423 */ 28424 JustifiedGallery.prototype.sortArray = function (a) { 28425 a.sort(this.settings.sort); 28426 this.insertToGallery(a); 28427 return a; 28428 }; 28429 28430 /** 28431 * Reset the filters removing the 'jg-filtered' class from all the entries 28432 * 28433 * @param a the array to reset 28434 */ 28435 JustifiedGallery.prototype.resetFilters = function (a) { 28436 for (var i = 0; i < a.length; i++) $(a[i]).removeClass('jg-filtered'); 28437 }; 28438 28439 /** 28440 * Filter the entries considering theirs classes (if a string has been passed) or using a function for filtering. 28441 * 28442 * @param a the array to filter 28443 * @return the filtered array 28444 */ 28445 JustifiedGallery.prototype.filterArray = function (a) { 28446 var settings = this.settings; 28447 if ($.type(settings.filter) === 'string') { 28448 // Filter only keeping the entries passed in the string 28449 return a.filter(function (el) { 28450 var $el = $(el); 28451 if ($el.is(settings.filter)) { 28452 $el.removeClass('jg-filtered'); 28453 return true; 28454 } else { 28455 $el.addClass('jg-filtered').removeClass('jg-visible'); 28456 return false; 28457 } 28458 }); 28459 } else if ($.isFunction(settings.filter)) { 28460 // Filter using the passed function 28461 var filteredArr = a.filter(settings.filter); 28462 for (var i = 0; i < a.length; i++) { 28463 if (filteredArr.indexOf(a[i]) === -1) { 28464 $(a[i]).addClass('jg-filtered').removeClass('jg-visible'); 28465 } else { 28466 $(a[i]).removeClass('jg-filtered'); 28467 } 28468 } 28469 return filteredArr; 28470 } 28471 }; 28472 28473 /** 28474 * Revert the image src to the default value. 28475 */ 28476 JustifiedGallery.prototype.resetImgSrc = function ($img) { 28477 if ($img.data('jg.originalSrcLoc') === 'src') { 28478 $img.attr('src', $img.data('jg.originalSrc')); 28479 } else { 28480 $img.attr('src', ''); 28481 } 28482 }; 28483 28484 /** 28485 * Destroy the Justified Gallery instance. 28486 * 28487 * It clears all the css properties added in the style attributes. We doesn't backup the original 28488 * values for those css attributes, because it costs (performance) and because in general one 28489 * shouldn't use the style attribute for an uniform set of images (where we suppose the use of 28490 * classes). Creating a backup is also difficult because JG could be called multiple times and 28491 * with different style attributes. 28492 */ 28493 JustifiedGallery.prototype.destroy = function () { 28494 clearInterval(this.checkWidthIntervalId); 28495 this.stopImgAnalyzerStarter(); 28496 28497 // Get fresh entries list since filtered entries are absent in `this.entries` 28498 $.each(this.getAllEntries(), $.proxy(function (_, entry) { 28499 var $entry = $(entry); 28500 28501 // Reset entry style 28502 $entry.css('width', ''); 28503 $entry.css('height', ''); 28504 $entry.css('top', ''); 28505 $entry.css('left', ''); 28506 $entry.data('jg.loaded', undefined); 28507 $entry.removeClass('jg-entry jg-filtered jg-entry-visible'); 28508 28509 // Reset image style 28510 var $img = this.imgFromEntry($entry); 28511 if ($img) { 28512 $img.css('width', ''); 28513 $img.css('height', ''); 28514 $img.css('margin-left', ''); 28515 $img.css('margin-top', ''); 28516 this.resetImgSrc($img); 28517 $img.data('jg.originalSrc', undefined); 28518 $img.data('jg.originalSrcLoc', undefined); 28519 $img.data('jg.src', undefined); 28520 } 28521 28522 // Remove caption 28523 this.removeCaptionEventsHandlers($entry); 28524 var $caption = this.captionFromEntry($entry); 28525 if ($entry.data('jg.createdCaption')) { 28526 // remove also the caption element (if created by jg) 28527 $entry.data('jg.createdCaption', undefined); 28528 if ($caption !== null) $caption.remove(); 28529 } else { 28530 if ($caption !== null) $caption.fadeTo(0, 1); 28531 } 28532 28533 }, this)); 28534 28535 this.$gallery.css('height', ''); 28536 this.$gallery.removeClass('justified-gallery'); 28537 this.$gallery.data('jg.controller', undefined); 28538 this.settings.triggerEvent.call(this, 'jg.destroy'); 28539 }; 28540 28541 /** 28542 * Analyze the images and builds the rows. It returns if it found an image that is not loaded. 28543 * 28544 * @param isForResize if the image analyzer is called for resizing or not, to call a different callback at the end 28545 */ 28546 JustifiedGallery.prototype.analyzeImages = function (isForResize) { 28547 for (var i = this.lastAnalyzedIndex + 1; i < this.entries.length; i++) { 28548 var $entry = $(this.entries[i]); 28549 if ($entry.data('jg.loaded') === true || $entry.data('jg.loaded') === 'skipped') { 28550 var availableWidth = this.galleryWidth - 2 * this.border - ( 28551 (this.buildingRow.entriesBuff.length - 1) * this.settings.margins); 28552 var imgAspectRatio = $entry.data('jg.width') / $entry.data('jg.height'); 28553 28554 this.buildingRow.entriesBuff.push($entry); 28555 this.buildingRow.aspectRatio += imgAspectRatio; 28556 this.buildingRow.width += imgAspectRatio * this.settings.rowHeight; 28557 this.lastAnalyzedIndex = i; 28558 28559 if (availableWidth / (this.buildingRow.aspectRatio + imgAspectRatio) < this.settings.rowHeight) { 28560 this.flushRow(false, this.settings.maxRowsCount > 0 && this.rows === this.settings.maxRowsCount); 28561 28562 if (++this.yield.flushed >= this.yield.every) { 28563 this.startImgAnalyzer(isForResize); 28564 return; 28565 } 28566 } 28567 } else if ($entry.data('jg.loaded') !== 'error') { 28568 return; 28569 } 28570 } 28571 28572 // Last row flush (the row is not full) 28573 if (this.buildingRow.entriesBuff.length > 0) { 28574 this.flushRow(true, this.settings.maxRowsCount > 0 && this.rows === this.settings.maxRowsCount); 28575 } 28576 28577 if (this.isSpinnerActive()) { 28578 this.stopLoadingSpinnerAnimation(); 28579 } 28580 28581 /* Stop, if there is, the timeout to start the analyzeImages. 28582 This is because an image can be set loaded, and the timeout can be set, 28583 but this image can be analyzed yet. 28584 */ 28585 this.stopImgAnalyzerStarter(); 28586 28587 this.setGalleryFinalHeight(this.galleryHeightToSet); 28588 28589 //On complete callback 28590 this.settings.triggerEvent.call(this, isForResize ? 'jg.resize' : 'jg.complete'); 28591 }; 28592 28593 /** 28594 * Stops any ImgAnalyzer starter (that has an assigned timeout) 28595 */ 28596 JustifiedGallery.prototype.stopImgAnalyzerStarter = function () { 28597 this.yield.flushed = 0; 28598 if (this.imgAnalyzerTimeout !== null) { 28599 clearTimeout(this.imgAnalyzerTimeout); 28600 this.imgAnalyzerTimeout = null; 28601 } 28602 }; 28603 28604 /** 28605 * Starts the image analyzer. It is not immediately called to let the browser to update the view 28606 * 28607 * @param isForResize specifies if the image analyzer must be called for resizing or not 28608 */ 28609 JustifiedGallery.prototype.startImgAnalyzer = function (isForResize) { 28610 var that = this; 28611 this.stopImgAnalyzerStarter(); 28612 this.imgAnalyzerTimeout = setTimeout(function () { 28613 that.analyzeImages(isForResize); 28614 }, 0.001); // we can't start it immediately due to a IE different behaviour 28615 }; 28616 28617 /** 28618 * Checks if the image is loaded or not using another image object. We cannot use the 'complete' image property, 28619 * because some browsers, with a 404 set complete = true. 28620 * 28621 * @param imageSrc the image src to load 28622 * @param onLoad callback that is called when the image has been loaded 28623 * @param onError callback that is called in case of an error 28624 */ 28625 JustifiedGallery.prototype.onImageEvent = function (imageSrc, onLoad, onError) { 28626 if (!onLoad && !onError) return; 28627 28628 var memImage = new Image(); 28629 var $memImage = $(memImage); 28630 if (onLoad) { 28631 $memImage.one('load', function () { 28632 $memImage.off('load error'); 28633 onLoad(memImage); 28634 }); 28635 } 28636 if (onError) { 28637 $memImage.one('error', function () { 28638 $memImage.off('load error'); 28639 onError(memImage); 28640 }); 28641 } 28642 memImage.src = imageSrc; 28643 }; 28644 28645 /** 28646 * Init of Justified Gallery controlled 28647 * It analyzes all the entries starting theirs loading and calling the image analyzer (that works with loaded images) 28648 */ 28649 JustifiedGallery.prototype.init = function () { 28650 var imagesToLoad = false, skippedImages = false, that = this; 28651 $.each(this.entries, function (index, entry) { 28652 var $entry = $(entry); 28653 var $image = that.imgFromEntry($entry); 28654 28655 $entry.addClass('jg-entry'); 28656 28657 if ($entry.data('jg.loaded') !== true && $entry.data('jg.loaded') !== 'skipped') { 28658 28659 // Link Rel global overwrite 28660 if (that.settings.rel !== null) $entry.attr('rel', that.settings.rel); 28661 28662 // Link Target global overwrite 28663 if (that.settings.target !== null) $entry.attr('target', that.settings.target); 28664 28665 if ($image !== null) { 28666 28667 // Image src 28668 var imageSrc = that.extractImgSrcFromImage($image); 28669 28670 /* If we have the height and the width, we don't wait that the image is loaded, 28671 but we start directly with the justification */ 28672 if (that.settings.waitThumbnailsLoad === false || !imageSrc) { 28673 var width = parseFloat($image.attr('width')); 28674 var height = parseFloat($image.attr('height')); 28675 if ($image.prop('tagName') === 'svg') { 28676 width = parseFloat($image[0].getBBox().width); 28677 height = parseFloat($image[0].getBBox().height); 28678 } 28679 if (!isNaN(width) && !isNaN(height)) { 28680 $entry.data('jg.width', width); 28681 $entry.data('jg.height', height); 28682 $entry.data('jg.loaded', 'skipped'); 28683 skippedImages = true; 28684 that.startImgAnalyzer(false); 28685 return true; // continue 28686 } 28687 } 28688 28689 $entry.data('jg.loaded', false); 28690 imagesToLoad = true; 28691 28692 // Spinner start 28693 if (!that.isSpinnerActive()) that.startLoadingSpinnerAnimation(); 28694 28695 that.onImageEvent(imageSrc, function (loadImg) { // image loaded 28696 $entry.data('jg.width', loadImg.width); 28697 $entry.data('jg.height', loadImg.height); 28698 $entry.data('jg.loaded', true); 28699 that.startImgAnalyzer(false); 28700 }, function () { // image load error 28701 $entry.data('jg.loaded', 'error'); 28702 that.startImgAnalyzer(false); 28703 }); 28704 28705 } else { 28706 $entry.data('jg.loaded', true); 28707 $entry.data('jg.width', $entry.width() | parseFloat($entry.css('width')) | 1); 28708 $entry.data('jg.height', $entry.height() | parseFloat($entry.css('height')) | 1); 28709 } 28710 28711 } 28712 28713 }); 28714 28715 if (!imagesToLoad && !skippedImages) this.startImgAnalyzer(false); 28716 this.checkWidth(); 28717 }; 28718 28719 /** 28720 * Checks that it is a valid number. If a string is passed it is converted to a number 28721 * 28722 * @param settingContainer the object that contains the setting (to allow the conversion) 28723 * @param settingName the setting name 28724 */ 28725 JustifiedGallery.prototype.checkOrConvertNumber = function (settingContainer, settingName) { 28726 if ($.type(settingContainer[settingName]) === 'string') { 28727 settingContainer[settingName] = parseFloat(settingContainer[settingName]); 28728 } 28729 28730 if ($.type(settingContainer[settingName]) === 'number') { 28731 if (isNaN(settingContainer[settingName])) throw 'invalid number for ' + settingName; 28732 } else { 28733 throw settingName + ' must be a number'; 28734 } 28735 }; 28736 28737 /** 28738 * Checks the sizeRangeSuffixes and, if necessary, converts 28739 * its keys from string (e.g. old settings with 'lt100') to int. 28740 */ 28741 JustifiedGallery.prototype.checkSizeRangesSuffixes = function () { 28742 if ($.type(this.settings.sizeRangeSuffixes) !== 'object') { 28743 throw 'sizeRangeSuffixes must be defined and must be an object'; 28744 } 28745 28746 var suffixRanges = []; 28747 for (var rangeIdx in this.settings.sizeRangeSuffixes) { 28748 if (this.settings.sizeRangeSuffixes.hasOwnProperty(rangeIdx)) suffixRanges.push(rangeIdx); 28749 } 28750 28751 var newSizeRngSuffixes = { 0: '' }; 28752 for (var i = 0; i < suffixRanges.length; i++) { 28753 if ($.type(suffixRanges[i]) === 'string') { 28754 try { 28755 var numIdx = parseInt(suffixRanges[i].replace(/^[a-z]+/, ''), 10); 28756 newSizeRngSuffixes[numIdx] = this.settings.sizeRangeSuffixes[suffixRanges[i]]; 28757 } catch (e) { 28758 throw 'sizeRangeSuffixes keys must contains correct numbers (' + e + ')'; 28759 } 28760 } else { 28761 newSizeRngSuffixes[suffixRanges[i]] = this.settings.sizeRangeSuffixes[suffixRanges[i]]; 28762 } 28763 } 28764 28765 this.settings.sizeRangeSuffixes = newSizeRngSuffixes; 28766 }; 28767 28768 /** 28769 * check and convert the maxRowHeight setting 28770 * requires rowHeight to be already set 28771 * TODO: should be always called when only rowHeight is changed 28772 * @return number or null 28773 */ 28774 JustifiedGallery.prototype.retrieveMaxRowHeight = function () { 28775 var newMaxRowHeight = null; 28776 var rowHeight = this.settings.rowHeight; 28777 28778 if ($.type(this.settings.maxRowHeight) === 'string') { 28779 if (this.settings.maxRowHeight.match(/^[0-9]+%$/)) { 28780 newMaxRowHeight = rowHeight * parseFloat(this.settings.maxRowHeight.match(/^([0-9]+)%$/)[1]) / 100; 28781 } else { 28782 newMaxRowHeight = parseFloat(this.settings.maxRowHeight); 28783 } 28784 } else if ($.type(this.settings.maxRowHeight) === 'number') { 28785 newMaxRowHeight = this.settings.maxRowHeight; 28786 } else if (this.settings.maxRowHeight === false || this.settings.maxRowHeight == null) { 28787 return null; 28788 } else { 28789 throw 'maxRowHeight must be a number or a percentage'; 28790 } 28791 28792 // check if the converted value is not a number 28793 if (isNaN(newMaxRowHeight)) throw 'invalid number for maxRowHeight'; 28794 28795 // check values, maxRowHeight must be >= rowHeight 28796 if (newMaxRowHeight < rowHeight) newMaxRowHeight = rowHeight; 28797 28798 return newMaxRowHeight; 28799 }; 28800 28801 /** 28802 * Checks the settings 28803 */ 28804 JustifiedGallery.prototype.checkSettings = function () { 28805 this.checkSizeRangesSuffixes(); 28806 28807 this.checkOrConvertNumber(this.settings, 'rowHeight'); 28808 this.checkOrConvertNumber(this.settings, 'margins'); 28809 this.checkOrConvertNumber(this.settings, 'border'); 28810 this.checkOrConvertNumber(this.settings, 'maxRowsCount'); 28811 28812 var lastRowModes = [ 28813 'justify', 28814 'nojustify', 28815 'left', 28816 'center', 28817 'right', 28818 'hide' 28819 ]; 28820 if (lastRowModes.indexOf(this.settings.lastRow) === -1) { 28821 throw 'lastRow must be one of: ' + lastRowModes.join(', '); 28822 } 28823 28824 this.checkOrConvertNumber(this.settings, 'justifyThreshold'); 28825 if (this.settings.justifyThreshold < 0 || this.settings.justifyThreshold > 1) { 28826 throw 'justifyThreshold must be in the interval [0,1]'; 28827 } 28828 if ($.type(this.settings.cssAnimation) !== 'boolean') { 28829 throw 'cssAnimation must be a boolean'; 28830 } 28831 28832 if ($.type(this.settings.captions) !== 'boolean') throw 'captions must be a boolean'; 28833 this.checkOrConvertNumber(this.settings.captionSettings, 'animationDuration'); 28834 28835 this.checkOrConvertNumber(this.settings.captionSettings, 'visibleOpacity'); 28836 if (this.settings.captionSettings.visibleOpacity < 0 || 28837 this.settings.captionSettings.visibleOpacity > 1) { 28838 throw 'captionSettings.visibleOpacity must be in the interval [0, 1]'; 28839 } 28840 28841 this.checkOrConvertNumber(this.settings.captionSettings, 'nonVisibleOpacity'); 28842 if (this.settings.captionSettings.nonVisibleOpacity < 0 || 28843 this.settings.captionSettings.nonVisibleOpacity > 1) { 28844 throw 'captionSettings.nonVisibleOpacity must be in the interval [0, 1]'; 28845 } 28846 28847 this.checkOrConvertNumber(this.settings, 'imagesAnimationDuration'); 28848 this.checkOrConvertNumber(this.settings, 'refreshTime'); 28849 this.checkOrConvertNumber(this.settings, 'refreshSensitivity'); 28850 if ($.type(this.settings.randomize) !== 'boolean') throw 'randomize must be a boolean'; 28851 if ($.type(this.settings.selector) !== 'string') throw 'selector must be a string'; 28852 28853 if (this.settings.sort !== false && !$.isFunction(this.settings.sort)) { 28854 throw 'sort must be false or a comparison function'; 28855 } 28856 28857 if (this.settings.filter !== false && !$.isFunction(this.settings.filter) && 28858 $.type(this.settings.filter) !== 'string') { 28859 throw 'filter must be false, a string or a filter function'; 28860 } 28861 }; 28862 28863 /** 28864 * It brings all the indexes from the sizeRangeSuffixes and it orders them. They are then sorted and returned. 28865 * @returns {Array} sorted suffix ranges 28866 */ 28867 JustifiedGallery.prototype.retrieveSuffixRanges = function () { 28868 var suffixRanges = []; 28869 for (var rangeIdx in this.settings.sizeRangeSuffixes) { 28870 if (this.settings.sizeRangeSuffixes.hasOwnProperty(rangeIdx)) suffixRanges.push(parseInt(rangeIdx, 10)); 28871 } 28872 suffixRanges.sort(function (a, b) { return a > b ? 1 : a < b ? -1 : 0; }); 28873 return suffixRanges; 28874 }; 28875 28876 /** 28877 * Update the existing settings only changing some of them 28878 * 28879 * @param newSettings the new settings (or a subgroup of them) 28880 */ 28881 JustifiedGallery.prototype.updateSettings = function (newSettings) { 28882 // In this case Justified Gallery has been called again changing only some options 28883 this.settings = $.extend({}, this.settings, newSettings); 28884 this.checkSettings(); 28885 28886 // As reported in the settings: negative value = same as margins, 0 = disabled 28887 this.border = this.settings.border >= 0 ? this.settings.border : this.settings.margins; 28888 28889 this.maxRowHeight = this.retrieveMaxRowHeight(); 28890 this.suffixRanges = this.retrieveSuffixRanges(); 28891 }; 28892 28893 JustifiedGallery.prototype.defaults = { 28894 sizeRangeSuffixes: {}, /* e.g. Flickr configuration 28895 { 28896 100: '_t', // used when longest is less than 100px 28897 240: '_m', // used when longest is between 101px and 240px 28898 320: '_n', // ... 28899 500: '', 28900 640: '_z', 28901 1024: '_b' // used as else case because it is the last 28902 } 28903 */ 28904 thumbnailPath: undefined, /* If defined, sizeRangeSuffixes is not used, and this function is used to determine the 28905 path relative to a specific thumbnail size. The function should accept respectively three arguments: 28906 current path, width and height */ 28907 rowHeight: 120, // required? required to be > 0? 28908 maxRowHeight: false, // false or negative value to deactivate. Positive number to express the value in pixels, 28909 // A string '[0-9]+%' to express in percentage (e.g. 300% means that the row height 28910 // can't exceed 3 * rowHeight) 28911 maxRowsCount: 0, // maximum number of rows to be displayed (0 = disabled) 28912 margins: 1, 28913 border: -1, // negative value = same as margins, 0 = disabled, any other value to set the border 28914 28915 lastRow: 'nojustify', // ⦠which is the same as 'left', or can be 'justify', 'center', 'right' or 'hide' 28916 28917 justifyThreshold: 0.90, /* if row width / available space > 0.90 it will be always justified 28918 * (i.e. lastRow setting is not considered) */ 28919 waitThumbnailsLoad: true, 28920 captions: true, 28921 cssAnimation: true, 28922 imagesAnimationDuration: 500, // ignored with css animations 28923 captionSettings: { // ignored with css animations 28924 animationDuration: 500, 28925 visibleOpacity: 0.7, 28926 nonVisibleOpacity: 0.0 28927 },
28928 rel: null, // rewrite the rel of each analyzed links 28929 target: null, // rewrite the target of all links 28930 extension: /\.[^.\\/]+$/, // regexp to capture the extension of an image 28931 refreshTime: 200, // time interval (in ms) to check if the page changes its width 28932 refreshSensitivity: 0, // change in width allowed (in px) without re-building the gallery 28933 randomize: false, 28934 rtl: false, // right-to-left mode 28935 sort: false, /* 28936 - false: to do not sort 28937 - function: to sort them using the function as comparator (see Array.prototype.sort()) 28938 */ 28939 filter: false, /* 28940 - false, null or undefined: for a disabled filter 28941 - a string: an entry is kept if entry.is(filter string) returns true 28942 see jQuery's .is() function for further information 28943 - a function: invoked with arguments (entry, index, array). Return true to keep the entry, false otherwise. 28944 It follows the specifications of the Array.prototype.filter() function of JavaScript. 28945 */ 28946 selector: 'a', // The selector that is used to know what are the entries of the gallery 28947 imgSelector: '> img, > a > img, > svg, > a > svg', // The selector that is used to know what are the images of each entry 28948 triggerEvent: function (event) { // This is called to trigger events, the default behavior is to call $.trigger 28949 this.$gallery.trigger(event); // Consider that 'this' is this set to the JustifiedGallery object, so it can 28950 } // access to fields such as $gallery, useful to trigger events with jQuery. 28951 }; 28952 28953 28954 /** 28955 * Justified Gallery plugin for jQuery 28956 * 28957 * Events 28958 * - jg.complete : called when all the gallery has been created 28959 * - jg.resize : called when the gallery has been resized 28960 * - jg.rowflush : when a new row appears 28961 * 28962 * @param arg the action (or the settings) passed when the plugin is called 28963 * @returns {*} the object itself 28964 */ 28965 $.fn.justifiedGallery = function (arg) { 28966 return this.each(function (index, gallery) { 28967 28968 var $gallery = $(gallery); 28969 $gallery.addClass('justified-gallery'); 28970 28971 var controller = $gallery.data('jg.controller'); 28972 if (typeof controller === 'undefined') { 28973 // Create controller and assign it to the object data 28974 if (typeof arg !== 'undefined' && arg !== null && $.type(arg) !== 'object') { 28975 if (arg === 'destroy') return; // Just a call to an unexisting object 28976 throw 'The argument must be an object'; 28977 } 28978 controller = new JustifiedGallery($gallery, $.extend({}, JustifiedGallery.prototype.defaults, arg)); 28979 $gallery.data('jg.controller', controller); 28980 } else if (arg === 'norewind') { 28981 // In this case we don't rewind: we analyze only the latest images (e.g. to complete the last unfinished row 28982 // ... left to be more readable 28983 } else if (arg === 'destroy') { 28984 controller.destroy(); 28985 return; 28986 } else { 28987 // In this case Justified Gallery has been called again changing only some options 28988 controller.updateSettings(arg); 28989 controller.rewind(); 28990 } 28991 28992 // Update the entries list 28993 if (!controller.updateEntries(arg === 'norewind')) return; 28994 28995 // Init justified gallery 28996 controller.init(); 28997 28998 }); 28999 }; 29000 29001})); 29002 29003/*! 29004* Customized version of iScroll.js 0.0.1 29005* It fixes bugs affecting its integration with fullpage.js 29006*/ 29007/*! iScroll v5.2.0 ~ (c) 2008-2016 Matteo Spinelli ~ http://cubiq.org/license */ 29008(function (window, document, Math) { 29009var rAF = window.requestAnimationFrame || 29010 window.webkitRequestAnimationFrame || 29011 window.mozRequestAnimationFrame || 29012 window.oRequestAnimationFrame || 29013 window.msRequestAnimationFrame || 29014 function (callback) { window.setTimeout(callback, 1000 / 60); }; 29015 29016var utils = (function () { 29017 var me = {}; 29018 29019 var _elementStyle = document.createElement('div').style; 29020 var _vendor = (function () { 29021 var vendors = ['t', 'webkitT', 'MozT', 'msT', 'OT'], 29022 transform, 29023 i = 0, 29024 l = vendors.length; 29025 29026 for ( ; i < l; i++ ) { 29027 transform = vendors[i] + 'ransform'; 29028 if ( transform in _elementStyle ) return vendors[i].substr(0, vendors[i].length-1); 29029 } 29030 29031 return false;
vendor: 5,154 bytes, lines 29032-29184
29032 })(); 29033 29034 function _prefixStyle (style) { 29035 if ( _vendor === false ) return false; 29036 if ( _vendor === '' ) return style; 29037 return _vendor + style.charAt(0).toUpperCase() + style.substr(1); 29038 } 29039 29040 me.getTime = Date.now || function getTime () { return new Date().getTime(); }; 29041 29042 me.extend = function (target, obj) { 29043 for ( var i in obj ) { 29044 target[i] = obj[i]; 29045 } 29046 }; 29047 29048 me.addEvent = function (el, type, fn, capture) { 29049 el.addEventListener(type, fn, !!capture); 29050 }; 29051 29052 me.removeEvent = function (el, type, fn, capture) { 29053 el.removeEventListener(type, fn, !!capture); 29054 }; 29055 29056 me.prefixPointerEvent = function (pointerEvent) { 29057 return window.MSPointerEvent ? 29058 'MSPointer' + pointerEvent.charAt(7).toUpperCase() + pointerEvent.substr(8): 29059 pointerEvent; 29060 }; 29061 29062 me.momentum = function (current, start, time, lowerMargin, wrapperSize, deceleration) { 29063 var distance = current - start, 29064 speed = Math.abs(distance) / time, 29065 destination, 29066 duration; 29067 29068 deceleration = deceleration === undefined ? 0.0006 : deceleration; 29069 29070 destination = current + ( speed * speed ) / ( 2 * deceleration ) * ( distance < 0 ? -1 : 1 ); 29071 duration = speed / deceleration; 29072 29073 if ( destination < lowerMargin ) { 29074 destination = wrapperSize ? lowerMargin - ( wrapperSize / 2.5 * ( speed / 8 ) ) : lowerMargin; 29075 distance = Math.abs(destination - current); 29076 duration = distance / speed; 29077 } else if ( destination > 0 ) { 29078 destination = wrapperSize ? wrapperSize / 2.5 * ( speed / 8 ) : 0; 29079 distance = Math.abs(current) + destination; 29080 duration = distance / speed; 29081 } 29082 29083 return { 29084 destination: Math.round(destination), 29085 duration: duration 29086 }; 29087 }; 29088 29089 var _transform = _prefixStyle('transform'); 29090 29091 me.extend(me, { 29092 hasTransform: _transform !== false, 29093 hasPerspective: _prefixStyle('perspective') in _elementStyle, 29094 hasTouch: 'ontouchstart' in window, 29095 hasPointer: !!(window.PointerEvent || window.MSPointerEvent), // IE10 is prefixed 29096 hasTransition: _prefixStyle('transition') in _elementStyle 29097 }); 29098 29099 /* 29100 This should find all Android browsers lower than build 535.19 (both stock browser and webview) 29101 - galaxy S2 is ok 29102 - 2.3.6 : `AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1` 29103 - 4.0.4 : `AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30` 29104 - galaxy S3 is badAndroid (stock brower, webview) 29105 `AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30` 29106 - galaxy S4 is badAndroid (stock brower, webview) 29107 `AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30` 29108 - galaxy S5 is OK 29109 `AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Mobile Safari/537.36 (Chrome/)` 29110 - galaxy S6 is OK 29111 `AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Mobile Safari/537.36 (Chrome/)` 29112 */ 29113 me.isBadAndroid = (function() { 29114 var appVersion = window.navigator.appVersion; 29115 // Android browser is not a chrome browser. 29116 if (/Android/.test(appVersion) && !(/Chrome\/\d/.test(appVersion))) { 29117 var safariVersion = appVersion.match(/Safari\/(\d+.\d)/); 29118 if(safariVersion && typeof safariVersion === "object" && safariVersion.length >= 2) { 29119 return parseFloat(safariVersion[1]) < 535.19; 29120 } else { 29121 return true; 29122 } 29123 } else { 29124 return false; 29125 } 29126 })(); 29127 29128 me.extend(me.style = {}, { 29129 transform: _transform, 29130 transitionTimingFunction: _prefixStyle('transitionTimingFunction'), 29131 transitionDuration: _prefixStyle('transitionDuration'), 29132 transitionDelay: _prefixStyle('transitionDelay'), 29133 transformOrigin: _prefixStyle('transformOrigin') 29134 }); 29135 29136 me.hasClass = function (e, c) { 29137 var re = new RegExp("(^|\\s)" + c + "(\\s|$)"); 29138 return re.test(e.className); 29139 }; 29140 29141 me.addClass = function (e, c) { 29142 if ( me.hasClass(e, c) ) { 29143 return; 29144 } 29145 29146 var newclass = e.className.split(' '); 29147 newclass.push(c); 29148 e.className = newclass.join(' '); 29149 }; 29150 29151 me.removeClass = function (e, c) { 29152 if ( !me.hasClass(e, c) ) { 29153 return; 29154 } 29155 29156 var re = new RegExp("(^|\\s)" + c + "(\\s|$)", 'g'); 29157 e.className = e.className.replace(re, ' '); 29158 }; 29159 29160 me.offset = function (el) { 29161 var left = -el.offsetLeft, 29162 top = -el.offsetTop; 29163 29164 // jshint -W084 29165 while (el = el.offsetParent) { 29166 left -= el.offsetLeft; 29167 top -= el.offsetTop; 29168 } 29169 // jshint +W084 29170 29171 return { 29172 left: left, 29173 top: top 29174 }; 29175 }; 29176 29177 me.preventDefaultException = function (el, exceptions) { 29178 for ( var i in exceptions ) { 29179 if ( exceptions[i].test(el[i]) ) { 29180 return true; 29181 } 29182 } 29183 29184 return false;
vendor: 5,660 bytes, lines 29185-29350
29185 }; 29186 29187 me.extend(me.eventType = {}, { 29188 touchstart: 1, 29189 touchmove: 1, 29190 touchend: 1, 29191 29192 mousedown: 2, 29193 mousemove: 2, 29194 mouseup: 2, 29195 29196 pointerdown: 3, 29197 pointermove: 3, 29198 pointerup: 3, 29199 29200 MSPointerDown: 3, 29201 MSPointerMove: 3, 29202 MSPointerUp: 3 29203 }); 29204 29205 me.extend(me.ease = {}, { 29206 quadratic: { 29207 style: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)', 29208 fn: function (k) { 29209 return k * ( 2 - k ); 29210 } 29211 }, 29212 circular: { 29213 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) 29214 fn: function (k) { 29215 return Math.sqrt( 1 - ( --k * k ) ); 29216 } 29217 }, 29218 back: { 29219 style: 'cubic-bezier(0.175, 0.885, 0.32, 1.275)', 29220 fn: function (k) { 29221 var b = 4; 29222 return ( k = k - 1 ) * k * ( ( b + 1 ) * k + b ) + 1; 29223 } 29224 }, 29225 bounce: { 29226 style: '', 29227 fn: function (k) { 29228 if ( ( k /= 1 ) < ( 1 / 2.75 ) ) { 29229 return 7.5625 * k * k; 29230 } else if ( k < ( 2 / 2.75 ) ) { 29231 return 7.5625 * ( k -= ( 1.5 / 2.75 ) ) * k + 0.75; 29232 } else if ( k < ( 2.5 / 2.75 ) ) { 29233 return 7.5625 * ( k -= ( 2.25 / 2.75 ) ) * k + 0.9375; 29234 } else { 29235 return 7.5625 * ( k -= ( 2.625 / 2.75 ) ) * k + 0.984375; 29236 } 29237 } 29238 }, 29239 elastic: { 29240 style: '', 29241 fn: function (k) { 29242 var f = 0.22, 29243 e = 0.4; 29244 29245 if ( k === 0 ) { return 0; } 29246 if ( k == 1 ) { return 1; } 29247 29248 return ( e * Math.pow( 2, - 10 * k ) * Math.sin( ( k - f / 4 ) * ( 2 * Math.PI ) / f ) + 1 ); 29249 } 29250 } 29251 }); 29252 29253 me.tap = function (e, eventName) { 29254 var ev = document.createEvent('Event'); 29255 ev.initEvent(eventName, true, true); 29256 ev.pageX = e.pageX; 29257 ev.pageY = e.pageY; 29258 e.target.dispatchEvent(ev); 29259 }; 29260 29261 me.click = function (e) { 29262 var target = e.target, 29263 ev; 29264 29265 if ( !(/(SELECT|INPUT|TEXTAREA)/i).test(target.tagName) ) { 29266 // https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/initMouseEvent 29267 // initMouseEvent is deprecated. 29268 ev = document.createEvent(window.MouseEvent ? 'MouseEvents' : 'Event'); 29269 ev.initEvent('click', true, true); 29270 ev.view = e.view || window; 29271 ev.detail = 1; 29272 ev.screenX = target.screenX || 0; 29273 ev.screenY = target.screenY || 0; 29274 ev.clientX = target.clientX || 0; 29275 ev.clientY = target.clientY || 0; 29276 ev.ctrlKey = !!e.ctrlKey; 29277 ev.altKey = !!e.altKey; 29278 ev.shiftKey = !!e.shiftKey; 29279 ev.metaKey = !!e.metaKey; 29280 ev.button = 0; 29281 ev.relatedTarget = null; 29282 ev._constructed = true; 29283 target.dispatchEvent(ev); 29284 } 29285 }; 29286 29287 return me; 29288})(); 29289function IScroll (el, options) { 29290 this.wrapper = typeof el == 'string' ? document.querySelector(el) : el; 29291 this.scroller = this.wrapper.children[0]; 29292 this.scrollerStyle = this.scroller.style; // cache style for better performance 29293 29294 this.options = { 29295 29296 resizeScrollbars: true, 29297 29298 mouseWheelSpeed: 20, 29299 29300 snapThreshold: 0.334, 29301 29302// INSERT POINT: OPTIONS 29303 disablePointer : !utils.hasPointer, 29304 disableTouch : utils.hasPointer || !utils.hasTouch, 29305 disableMouse : utils.hasPointer || utils.hasTouch, 29306 startX: 0, 29307 startY: 0, 29308 scrollY: true, 29309 directionLockThreshold: 5, 29310 momentum: true, 29311 29312 bounce: true, 29313 bounceTime: 600, 29314 bounceEasing: '', 29315 29316 preventDefault: true, 29317 preventDefaultException: { tagName: /^(INPUT|TEXTAREA|BUTTON|SELECT|LABEL)$/ }, 29318 29319 HWCompositing: true, 29320 useTransition: true, 29321 useTransform: true, 29322 bindToWrapper: typeof window.onmousedown === "undefined" 29323 }; 29324 29325 for ( var i in options ) { 29326 this.options[i] = options[i]; 29327 } 29328 29329 // Normalize options 29330 this.translateZ = this.options.HWCompositing && utils.hasPerspective ? ' translateZ(0)' : ''; 29331 29332 this.options.useTransition = utils.hasTransition && this.options.useTransition; 29333 this.options.useTransform = utils.hasTransform && this.options.useTransform; 29334 29335 this.options.eventPassthrough = this.options.eventPassthrough === true ? 'vertical' : this.options.eventPassthrough; 29336 this.options.preventDefault = !this.options.eventPassthrough && this.options.preventDefault; 29337 29338 // If you want eventPassthrough I have to lock one of the axes 29339 this.options.scrollY = this.options.eventPassthrough == 'vertical' ? false : this.options.scrollY; 29340 this.options.scrollX = this.options.eventPassthrough == 'horizontal' ? false : this.options.scrollX; 29341 29342 // With eventPassthrough we also need lockDirection mechanism 29343 this.options.freeScroll = this.options.freeScroll && !this.options.eventPassthrough; 29344 this.options.directionLockThreshold = this.options.eventPassthrough ? 0 : this.options.directionLockThreshold; 29345 29346 this.options.bounceEasing = typeof this.options.bounceEasing == 'string' ? utils.ease[this.options.bounceEasing] || utils.ease.circular : this.options.bounceEasing; 29347 29348 this.options.resizePolling = this.options.resizePolling === undefined ? 60 : this.options.resizePolling; 29349 29350 if ( this.options.tap === true ) {
vendor: 4,893 bytes, lines 29351-29522
29351 this.options.tap = 'tap'; 29352 } 29353 29354 // https://github.com/cubiq/iscroll/issues/1029 29355 if (!this.options.useTransition && !this.options.useTransform) { 29356 if(!(/relative|absolute/i).test(this.scrollerStyle.position)) { 29357 this.scrollerStyle.position = "relative"; 29358 } 29359 } 29360 29361 if ( this.options.shrinkScrollbars == 'scale' ) { 29362 this.options.useTransition = false; 29363 } 29364 29365 this.options.invertWheelDirection = this.options.invertWheelDirection ? -1 : 1; 29366 29367// INSERT POINT: NORMALIZATION 29368 29369 // Some defaults 29370 this.x = 0; 29371 this.y = 0; 29372 this.directionX = 0; 29373 this.directionY = 0; 29374 this._events = {}; 29375 29376// INSERT POINT: DEFAULTS 29377 29378 this._init(); 29379 this.refresh(); 29380 29381 this.scrollTo(this.options.startX, this.options.startY); 29382 this.enable(); 29383} 29384 29385IScroll.prototype = { 29386 version: '5.2.0', 29387 29388 _init: function () { 29389 this._initEvents(); 29390 29391 if ( this.options.scrollbars || this.options.indicators ) { 29392 this._initIndicators(); 29393 } 29394 29395 if ( this.options.mouseWheel ) { 29396 this._initWheel(); 29397 } 29398 29399 if ( this.options.snap ) { 29400 this._initSnap(); 29401 } 29402 29403 if ( this.options.keyBindings ) { 29404 this._initKeys(); 29405 } 29406 29407// INSERT POINT: _init 29408 29409 }, 29410 29411 destroy: function () { 29412 this._initEvents(true); 29413 clearTimeout(this.resizeTimeout); 29414 this.resizeTimeout = null; 29415 this._execEvent('destroy'); 29416 }, 29417 29418 _transitionEnd: function (e) { 29419 if ( e.target != this.scroller || !this.isInTransition ) { 29420 return; 29421 } 29422 29423 this._transitionTime(); 29424 if ( !this.resetPosition(this.options.bounceTime) ) { 29425 this.isInTransition = false; 29426 this._execEvent('scrollEnd'); 29427 } 29428 }, 29429 29430 _start: function (e) { 29431 // React to left mouse button only 29432 if ( utils.eventType[e.type] != 1 ) { 29433 // for button property 29434 // http://unixpapa.com/js/mouse.html 29435 var button; 29436 if (!e.which) { 29437 /* IE case */ 29438 button = (e.button < 2) ? 0 : 29439 ((e.button == 4) ? 1 : 2); 29440 } else { 29441 /* All others */ 29442 button = e.button; 29443 } 29444 if ( button !== 0 ) { 29445 return; 29446 } 29447 } 29448 29449 if ( !this.enabled || (this.initiated && utils.eventType[e.type] !== this.initiated) ) { 29450 return; 29451 } 29452 29453 if ( this.options.preventDefault && !utils.isBadAndroid && !utils.preventDefaultException(e.target, this.options.preventDefaultException) ) { 29454 e.preventDefault(); 29455 } 29456 29457 var point = e.touches ? e.touches[0] : e, 29458 pos; 29459 29460 this.initiated = utils.eventType[e.type]; 29461 this.moved = false; 29462 this.distX = 0; 29463 this.distY = 0; 29464 this.directionX = 0; 29465 this.directionY = 0; 29466 this.directionLocked = 0; 29467 29468 this.startTime = utils.getTime(); 29469 29470 if ( this.options.useTransition && this.isInTransition ) { 29471 this._transitionTime(); 29472 this.isInTransition = false; 29473 pos = this.getComputedPosition(); 29474 this._translate(Math.round(pos.x), Math.round(pos.y)); 29475 this._execEvent('scrollEnd'); 29476 } else if ( !this.options.useTransition && this.isAnimating ) { 29477 this.isAnimating = false; 29478 this._execEvent('scrollEnd'); 29479 } 29480 29481 this.startX = this.x; 29482 this.startY = this.y; 29483 this.absStartX = this.x; 29484 this.absStartY = this.y; 29485 this.pointX = point.pageX; 29486 this.pointY = point.pageY; 29487 29488 this._execEvent('beforeScrollStart'); 29489 }, 29490 29491 _move: function (e) { 29492 if ( !this.enabled || utils.eventType[e.type] !== this.initiated ) { 29493 return; 29494 } 29495 29496 if ( this.options.preventDefault ) { // increases performance on Android? TODO: check! 29497 e.preventDefault(); 29498 } 29499 29500 var point = e.touches ? e.touches[0] : e, 29501 deltaX = point.pageX - this.pointX, 29502 deltaY = point.pageY - this.pointY, 29503 timestamp = utils.getTime(), 29504 newX, newY, 29505 absDistX, absDistY; 29506 29507 this.pointX = point.pageX; 29508 this.pointY = point.pageY; 29509 29510 this.distX += deltaX; 29511 this.distY += deltaY; 29512 absDistX = Math.abs(this.distX); 29513 absDistY = Math.abs(this.distY); 29514 29515 // We need to move at least 10 pixels for the scrolling to initiate 29516 if ( timestamp - this.endTime > 300 && (absDistX < 10 && absDistY < 10) ) { 29517 return; 29518 } 29519 29520 // If you are scrolling in one direction lock the other 29521 if ( !this.directionLocked && !this.options.freeScroll ) { 29522 if ( absDistX > absDistY + this.options.directionLockThreshold ) {
vendor: 6,057 bytes, lines 29523-29709
29523 this.directionLocked = 'h'; // lock horizontally 29524 } else if ( absDistY >= absDistX + this.options.directionLockThreshold ) { 29525 this.directionLocked = 'v'; // lock vertically 29526 } else { 29527 this.directionLocked = 'n'; // no lock 29528 } 29529 } 29530 29531 if ( this.directionLocked == 'h' ) { 29532 if ( this.options.eventPassthrough == 'vertical' ) { 29533 e.preventDefault(); 29534 } else if ( this.options.eventPassthrough == 'horizontal' ) { 29535 this.initiated = false; 29536 return; 29537 } 29538 29539 deltaY = 0; 29540 } else if ( this.directionLocked == 'v' ) { 29541 if ( this.options.eventPassthrough == 'horizontal' ) { 29542 e.preventDefault(); 29543 } else if ( this.options.eventPassthrough == 'vertical' ) { 29544 this.initiated = false; 29545 return; 29546 } 29547 29548 deltaX = 0; 29549 } 29550 29551 deltaX = this.hasHorizontalScroll ? deltaX : 0; 29552 deltaY = this.hasVerticalScroll ? deltaY : 0; 29553 29554 newX = this.x + deltaX; 29555 newY = this.y + deltaY; 29556 29557 // Slow down if outside of the boundaries 29558 if ( newX > 0 || newX < this.maxScrollX ) { 29559 newX = this.options.bounce ? this.x + deltaX / 3 : newX > 0 ? 0 : this.maxScrollX; 29560 } 29561 if ( newY > 0 || newY < this.maxScrollY ) { 29562 newY = this.options.bounce ? this.y + deltaY / 3 : newY > 0 ? 0 : this.maxScrollY; 29563 } 29564 29565 this.directionX = deltaX > 0 ? -1 : deltaX < 0 ? 1 : 0; 29566 this.directionY = deltaY > 0 ? -1 : deltaY < 0 ? 1 : 0; 29567 29568 if ( !this.moved ) { 29569 this._execEvent('scrollStart'); 29570 } 29571 29572 this.moved = true; 29573 29574 this._translate(newX, newY); 29575 29576/* REPLACE START: _move */ 29577 29578 if ( timestamp - this.startTime > 300 ) { 29579 this.startTime = timestamp; 29580 this.startX = this.x; 29581 this.startY = this.y; 29582 } 29583 29584/* REPLACE END: _move */ 29585 29586 }, 29587 29588 _end: function (e) { 29589 if ( !this.enabled || utils.eventType[e.type] !== this.initiated ) { 29590 return; 29591 } 29592 29593 if ( this.options.preventDefault && !utils.preventDefaultException(e.target, this.options.preventDefaultException) ) { 29594 e.preventDefault(); 29595 } 29596 29597 var point = e.changedTouches ? e.changedTouches[0] : e, 29598 momentumX, 29599 momentumY, 29600 duration = utils.getTime() - this.startTime, 29601 newX = Math.round(this.x), 29602 newY = Math.round(this.y), 29603 distanceX = Math.abs(newX - this.startX), 29604 distanceY = Math.abs(newY - this.startY), 29605 time = 0, 29606 easing = ''; 29607 29608 this.isInTransition = 0; 29609 this.initiated = 0; 29610 this.endTime = utils.getTime(); 29611 29612 // reset if we are outside of the boundaries 29613 if ( this.resetPosition(this.options.bounceTime) ) { 29614 return; 29615 } 29616 29617 this.scrollTo(newX, newY); // ensures that the last position is rounded 29618 29619 // we scrolled less than 10 pixels 29620 if ( !this.moved ) { 29621 if ( this.options.tap ) { 29622 utils.tap(e, this.options.tap); 29623 } 29624 29625 if ( this.options.click ) { 29626 utils.click(e); 29627 } 29628 29629 this._execEvent('scrollCancel'); 29630 return; 29631 } 29632 29633 if ( this._events.flick && duration < 200 && distanceX < 100 && distanceY < 100 ) { 29634 this._execEvent('flick'); 29635 return; 29636 } 29637 29638 // start momentum animation if needed 29639 if ( this.options.momentum && duration < 300 ) { 29640 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 }; 29641 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 }; 29642 newX = momentumX.destination; 29643 newY = momentumY.destination; 29644 time = Math.max(momentumX.duration, momentumY.duration); 29645 this.isInTransition = 1; 29646 } 29647 29648 29649 if ( this.options.snap ) { 29650 var snap = this._nearestSnap(newX, newY); 29651 this.currentPage = snap; 29652 time = this.options.snapSpeed || Math.max( 29653 Math.max( 29654 Math.min(Math.abs(newX - snap.x), 1000), 29655 Math.min(Math.abs(newY - snap.y), 1000) 29656 ), 300); 29657 newX = snap.x; 29658 newY = snap.y; 29659 29660 this.directionX = 0; 29661 this.directionY = 0; 29662 easing = this.options.bounceEasing; 29663 } 29664 29665// INSERT POINT: _end 29666 29667 if ( newX != this.x || newY != this.y ) { 29668 // change easing function when scroller goes out of the boundaries 29669 if ( newX > 0 || newX < this.maxScrollX || newY > 0 || newY < this.maxScrollY ) { 29670 easing = utils.ease.quadratic; 29671 } 29672 29673 this.scrollTo(newX, newY, time, easing); 29674 return; 29675 } 29676 29677 this._execEvent('scrollEnd'); 29678 }, 29679 29680 _resize: function () { 29681 var that = this; 29682 29683 clearTimeout(this.resizeTimeout); 29684 29685 this.resizeTimeout = setTimeout(function () { 29686 that.refresh(); 29687 }, this.options.resizePolling); 29688 }, 29689 29690 resetPosition: function (time) { 29691 var x = this.x, 29692 y = this.y; 29693 29694 time = time || 0; 29695 29696 if ( !this.hasHorizontalScroll || this.x > 0 ) { 29697 x = 0; 29698 } else if ( this.x < this.maxScrollX ) { 29699 x = this.maxScrollX; 29700 } 29701 29702 if ( !this.hasVerticalScroll || this.y > 0 ) { 29703 y = 0; 29704 } else if ( this.y < this.maxScrollY ) { 29705 y = this.maxScrollY; 29706 } 29707 29708 if ( x == this.x && y == this.y ) { 29709 return false;
vendor: 5,509 bytes, lines 29710-29914
29710 } 29711 29712 this.scrollTo(x, y, time, this.options.bounceEasing); 29713 29714 return true; 29715 }, 29716 29717 disable: function () { 29718 this.enabled = false; 29719 }, 29720 29721 enable: function () { 29722 this.enabled = true; 29723 }, 29724 29725 refresh: function () { 29726 var rf = this.wrapper.offsetHeight; // Force reflow 29727 29728 this.wrapperWidth = this.wrapper.clientWidth; 29729 this.wrapperHeight = this.wrapper.clientHeight; 29730 29731/* REPLACE START: refresh */ 29732 29733 this.scrollerWidth = this.scroller.offsetWidth; 29734 this.scrollerHeight = this.scroller.offsetHeight; 29735 29736 this.maxScrollX = this.wrapperWidth - this.scrollerWidth; 29737 this.maxScrollY = this.wrapperHeight - this.scrollerHeight; 29738 29739/* REPLACE END: refresh */ 29740 29741 this.hasHorizontalScroll = this.options.scrollX && this.maxScrollX < 0; 29742 this.hasVerticalScroll = this.options.scrollY && this.maxScrollY < 0; 29743 29744 if ( !this.hasHorizontalScroll ) { 29745 this.maxScrollX = 0; 29746 this.scrollerWidth = this.wrapperWidth; 29747 } 29748 29749 if ( !this.hasVerticalScroll ) { 29750 this.maxScrollY = 0; 29751 this.scrollerHeight = this.wrapperHeight; 29752 } 29753 29754 this.endTime = 0; 29755 this.directionX = 0; 29756 this.directionY = 0; 29757 29758 this.wrapperOffset = utils.offset(this.wrapper); 29759 29760 this._execEvent('refresh'); 29761 29762 this.resetPosition(); 29763 29764// INSERT POINT: _refresh 29765 29766 }, 29767 29768 29769 on: function (type, fn) { 29770 if ( !this._events[type] ) { 29771 this._events[type] = []; 29772 } 29773 29774 this._events[type].push(fn); 29775 }, 29776 29777 off: function (type, fn) { 29778 if ( !this._events[type] ) { 29779 return; 29780 } 29781 29782 var index = this._events[type].indexOf(fn); 29783 29784 if ( index > -1 ) { 29785 this._events[type].splice(index, 1); 29786 } 29787 }, 29788 29789 _execEvent: function (type) { 29790 if ( !this._events[type] ) { 29791 return; 29792 } 29793 29794 var i = 0, 29795 l = this._events[type].length; 29796 29797 if ( !l ) { 29798 return; 29799 } 29800 29801 for ( ; i < l; i++ ) { 29802 this._events[type][i].apply(this, [].slice.call(arguments, 1)); 29803 } 29804 }, 29805 29806 scrollBy: function (x, y, time, easing) { 29807 x = this.x + x; 29808 y = this.y + y; 29809 time = time || 0; 29810 29811 this.scrollTo(x, y, time, easing); 29812 }, 29813 29814 scrollTo: function (x, y, time, easing) { 29815 easing = easing || utils.ease.circular; 29816 29817 this.isInTransition = this.options.useTransition && time > 0; 29818 var transitionType = this.options.useTransition && easing.style; 29819 if ( !time || transitionType ) { 29820 if(transitionType) { 29821 this._transitionTimingFunction(easing.style); 29822 this._transitionTime(time); 29823 } 29824 this._translate(x, y); 29825 } else { 29826 this._animate(x, y, time, easing.fn); 29827 } 29828 }, 29829 29830 scrollToElement: function (el, time, offsetX, offsetY, easing) { 29831 el = el.nodeType ? el : this.scroller.querySelector(el); 29832 29833 if ( !el ) { 29834 return; 29835 } 29836 29837 var pos = utils.offset(el); 29838 29839 pos.left -= this.wrapperOffset.left; 29840 pos.top -= this.wrapperOffset.top; 29841 29842 // if offsetX/Y are true we center the element to the screen 29843 if ( offsetX === true ) { 29844 offsetX = Math.round(el.offsetWidth / 2 - this.wrapper.offsetWidth / 2); 29845 } 29846 if ( offsetY === true ) { 29847 offsetY = Math.round(el.offsetHeight / 2 - this.wrapper.offsetHeight / 2); 29848 } 29849 29850 pos.left -= offsetX || 0; 29851 pos.top -= offsetY || 0; 29852 29853 pos.left = pos.left > 0 ? 0 : pos.left < this.maxScrollX ? this.maxScrollX : pos.left; 29854 pos.top = pos.top > 0 ? 0 : pos.top < this.maxScrollY ? this.maxScrollY : pos.top; 29855 29856 time = time === undefined || time === null || time === 'auto' ? Math.max(Math.abs(this.x-pos.left), Math.abs(this.y-pos.top)) : time; 29857 29858 this.scrollTo(pos.left, pos.top, time, easing); 29859 }, 29860 29861 _transitionTime: function (time) { 29862 if (!this.options.useTransition) { 29863 return; 29864 } 29865 time = time || 0; 29866 var durationProp = utils.style.transitionDuration; 29867 if(!durationProp) { 29868 return; 29869 } 29870 29871 this.scrollerStyle[durationProp] = time + 'ms'; 29872 29873 if ( !time && utils.isBadAndroid ) { 29874 this.scrollerStyle[durationProp] = '0.0001ms'; 29875 // remove 0.0001ms 29876 var self = this; 29877 rAF(function() { 29878 if(self.scrollerStyle[durationProp] === '0.0001ms') { 29879 self.scrollerStyle[durationProp] = '0s'; 29880 } 29881 }); 29882 } 29883 29884 29885 if ( this.indicators ) { 29886 for ( var i = this.indicators.length; i--; ) { 29887 this.indicators[i].transitionTime(time); 29888 } 29889 } 29890 29891 29892// INSERT POINT: _transitionTime 29893 29894 }, 29895 29896 _transitionTimingFunction: function (easing) { 29897 this.scrollerStyle[utils.style.transitionTimingFunction] = easing; 29898 29899 29900 if ( this.indicators ) { 29901 for ( var i = this.indicators.length; i--; ) { 29902 this.indicators[i].transitionTimingFunction(easing); 29903 } 29904 } 29905 29906 29907// INSERT POINT: _transitionTimingFunction 29908 29909 }, 29910 29911 _translate: function (x, y) { 29912 //Uncode addition 29913 if ( (" " + this.wrapper.className + " ").replace(/[\n\t]/g, " ").indexOf(" no-scrolloverflow ") > -1 ) 29914 return false;
vendor: 9,939 bytes, lines 29915-30226
29915 29916 if ( this.options.useTransform ) { 29917 29918/* REPLACE START: _translate */ 29919 29920 this.scrollerStyle[utils.style.transform] = 'translate(' + x + 'px,' + y + 'px)' + this.translateZ; 29921 29922/* REPLACE END: _translate */ 29923 29924 } else { 29925 x = Math.round(x); 29926 y = Math.round(y); 29927 this.scrollerStyle.left = x + 'px'; 29928 this.scrollerStyle.top = y + 'px'; 29929 } 29930 29931 this.x = x; 29932 this.y = y; 29933 29934 29935 if ( this.indicators ) { 29936 for ( var i = this.indicators.length; i--; ) { 29937 this.indicators[i].updatePosition(); 29938 } 29939 } 29940 29941 //Uncode addition 29942 var uncodevent = new CustomEvent('fp-slide-scroll'); 29943 window.dispatchEvent(uncodevent); 29944 29945// INSERT POINT: _translate 29946 29947 }, 29948 29949 _initEvents: function (remove) { 29950 var eventType = remove ? utils.removeEvent : utils.addEvent, 29951 target = this.options.bindToWrapper ? this.wrapper : window; 29952 29953 eventType(window, 'orientationchange', this); 29954 eventType(window, 'resize', this); 29955 29956 if ( this.options.click ) { 29957 eventType(this.wrapper, 'click', this, true); 29958 } 29959 29960 if ( !this.options.disableMouse ) { 29961 eventType(this.wrapper, 'mousedown', this); 29962 eventType(target, 'mousemove', this); 29963 eventType(target, 'mousecancel', this); 29964 eventType(target, 'mouseup', this); 29965 } 29966 29967 if ( utils.hasPointer && !this.options.disablePointer ) { 29968 eventType(this.wrapper, utils.prefixPointerEvent('pointerdown'), this); 29969 eventType(target, utils.prefixPointerEvent('pointermove'), this); 29970 eventType(target, utils.prefixPointerEvent('pointercancel'), this); 29971 eventType(target, utils.prefixPointerEvent('pointerup'), this); 29972 } 29973 29974 if ( utils.hasTouch && !this.options.disableTouch ) { 29975 eventType(this.wrapper, 'touchstart', this); 29976 eventType(target, 'touchmove', this); 29977 eventType(target, 'touchcancel', this); 29978 eventType(target, 'touchend', this); 29979 } 29980 29981 eventType(this.scroller, 'transitionend', this); 29982 eventType(this.scroller, 'webkitTransitionEnd', this); 29983 eventType(this.scroller, 'oTransitionEnd', this); 29984 eventType(this.scroller, 'MSTransitionEnd', this); 29985 }, 29986 29987 getComputedPosition: function () { 29988 var matrix = window.getComputedStyle(this.scroller, null), 29989 x, y; 29990 29991 if ( this.options.useTransform ) { 29992 matrix = matrix[utils.style.transform].split(')')[0].split(', '); 29993 x = +(matrix[12] || matrix[4]); 29994 y = +(matrix[13] || matrix[5]); 29995 } else { 29996 x = +matrix.left.replace(/[^-\d.]/g, ''); 29997 y = +matrix.top.replace(/[^-\d.]/g, ''); 29998 } 29999 30000 return { x: x, y: y }; 30001 }, 30002 _initIndicators: function () { 30003 var interactive = this.options.interactiveScrollbars, 30004 customStyle = typeof this.options.scrollbars != 'string', 30005 indicators = [], 30006 indicator; 30007 30008 var that = this; 30009 30010 this.indicators = []; 30011 30012 if ( this.options.scrollbars ) { 30013 // Vertical scrollbar 30014 if ( this.options.scrollY ) { 30015 indicator = { 30016 el: createDefaultScrollbar('v', interactive, this.options.scrollbars), 30017 interactive: interactive, 30018 defaultScrollbars: true, 30019 customStyle: customStyle, 30020 resize: this.options.resizeScrollbars, 30021 shrink: this.options.shrinkScrollbars, 30022 fade: this.options.fadeScrollbars, 30023 listenX: false 30024 }; 30025 30026 this.wrapper.appendChild(indicator.el); 30027 indicators.push(indicator); 30028 } 30029 30030 // Horizontal scrollbar 30031 if ( this.options.scrollX ) { 30032 indicator = { 30033 el: createDefaultScrollbar('h', interactive, this.options.scrollbars), 30034 interactive: interactive, 30035 defaultScrollbars: true, 30036 customStyle: customStyle, 30037 resize: this.options.resizeScrollbars, 30038 shrink: this.options.shrinkScrollbars, 30039 fade: this.options.fadeScrollbars, 30040 listenY: false 30041 }; 30042 30043 this.wrapper.appendChild(indicator.el); 30044 indicators.push(indicator); 30045 } 30046 } 30047 30048 if ( this.options.indicators ) { 30049 // TODO: check concat compatibility 30050 indicators = indicators.concat(this.options.indicators); 30051 } 30052 30053 for ( var i = indicators.length; i--; ) { 30054 this.indicators.push( new Indicator(this, indicators[i]) ); 30055 } 30056 30057 // TODO: check if we can use array.map (wide compatibility and performance issues) 30058 function _indicatorsMap (fn) { 30059 if (that.indicators) { 30060 for ( var i = that.indicators.length; i--; ) { 30061 fn.call(that.indicators[i]); 30062 } 30063 } 30064 } 30065 30066 if ( this.options.fadeScrollbars ) { 30067 this.on('scrollEnd', function () { 30068 _indicatorsMap(function () { 30069 this.fade(); 30070 }); 30071 }); 30072 30073 this.on('scrollCancel', function () { 30074 _indicatorsMap(function () { 30075 this.fade(); 30076 }); 30077 }); 30078 30079 this.on('scrollStart', function () { 30080 _indicatorsMap(function () { 30081 this.fade(1); 30082 }); 30083 }); 30084 30085 this.on('beforeScrollStart', function () { 30086 _indicatorsMap(function () { 30087 this.fade(1, true); 30088 }); 30089 }); 30090 } 30091 30092 30093 this.on('refresh', function () { 30094 _indicatorsMap(function () { 30095 this.refresh(); 30096 }); 30097 }); 30098 30099 this.on('destroy', function () { 30100 _indicatorsMap(function () { 30101 this.destroy(); 30102 }); 30103 30104 delete this.indicators; 30105 }); 30106 }, 30107 30108 _initWheel: function () { 30109 utils.addEvent(this.wrapper, 'wheel', this); 30110 utils.addEvent(this.wrapper, 'mousewheel', this); 30111 utils.addEvent(this.wrapper, 'DOMMouseScroll', this); 30112 30113 this.on('destroy', function () { 30114 clearTimeout(this.wheelTimeout); 30115 this.wheelTimeout = null; 30116 utils.removeEvent(this.wrapper, 'wheel', this); 30117 utils.removeEvent(this.wrapper, 'mousewheel', this); 30118 utils.removeEvent(this.wrapper, 'DOMMouseScroll', this); 30119 }); 30120 }, 30121 30122 _wheel: function (e) { 30123 if ( !this.enabled ) { 30124 return; 30125 } 30126 30127 var wheelDeltaX, wheelDeltaY, 30128 newX, newY, 30129 that = this; 30130 30131 if ( this.wheelTimeout === undefined ) { 30132 that._execEvent('scrollStart'); 30133 } 30134 30135 // Execute the scrollEnd event after 400ms the wheel stopped scrolling 30136 clearTimeout(this.wheelTimeout); 30137 this.wheelTimeout = setTimeout(function () { 30138 if(!that.options.snap) { 30139 that._execEvent('scrollEnd'); 30140 } 30141 that.wheelTimeout = undefined; 30142 }, 400); 30143 30144 if ( 'deltaX' in e ) { 30145 if (e.deltaMode === 1) { 30146 wheelDeltaX = -e.deltaX * this.options.mouseWheelSpeed; 30147 wheelDeltaY = -e.deltaY * this.options.mouseWheelSpeed; 30148 } else { 30149 wheelDeltaX = -e.deltaX; 30150 wheelDeltaY = -e.deltaY; 30151 } 30152 } else if ( 'wheelDeltaX' in e ) { 30153 wheelDeltaX = e.wheelDeltaX / 120 * this.options.mouseWheelSpeed; 30154 wheelDeltaY = e.wheelDeltaY / 120 * this.options.mouseWheelSpeed; 30155 } else if ( 'wheelDelta' in e ) { 30156 wheelDeltaX = wheelDeltaY = e.wheelDelta / 120 * this.options.mouseWheelSpeed; 30157 } else if ( 'detail' in e ) { 30158 wheelDeltaX = wheelDeltaY = -e.detail / 3 * this.options.mouseWheelSpeed; 30159 } else { 30160 return; 30161 } 30162 30163 wheelDeltaX *= this.options.invertWheelDirection; 30164 wheelDeltaY *= this.options.invertWheelDirection; 30165 30166 if ( !this.hasVerticalScroll ) { 30167 wheelDeltaX = wheelDeltaY; 30168 wheelDeltaY = 0; 30169 } 30170 30171 if ( this.options.snap ) { 30172 newX = this.currentPage.pageX; 30173 newY = this.currentPage.pageY; 30174 30175 if ( wheelDeltaX > 0 ) { 30176 newX--; 30177 } else if ( wheelDeltaX < 0 ) { 30178 newX++; 30179 } 30180 30181 if ( wheelDeltaY > 0 ) { 30182 newY--; 30183 } else if ( wheelDeltaY < 0 ) { 30184 newY++; 30185 } 30186 30187 this.goToPage(newX, newY); 30188 30189 return; 30190 } 30191 30192 newX = this.x + Math.round(this.hasHorizontalScroll ? wheelDeltaX : 0); 30193 newY = this.y + Math.round(this.hasVerticalScroll ? wheelDeltaY : 0); 30194 30195 this.directionX = wheelDeltaX > 0 ? -1 : wheelDeltaX < 0 ? 1 : 0; 30196 this.directionY = wheelDeltaY > 0 ? -1 : wheelDeltaY < 0 ? 1 : 0; 30197 30198 if ( newX > 0 ) { 30199 newX = 0; 30200 } else if ( newX < this.maxScrollX ) { 30201 newX = this.maxScrollX; 30202 } 30203 30204 if ( newY > 0 ) { 30205 newY = 0; 30206 } else if ( newY < this.maxScrollY ) { 30207 newY = this.maxScrollY; 30208 } 30209 30210 this.scrollTo(newX, newY, 0); 30211 30212// INSERT POINT: _wheel 30213 }, 30214 30215 _initSnap: function () { 30216 this.currentPage = {}; 30217 30218 if ( typeof this.options.snap == 'string' ) { 30219 this.options.snap = this.scroller.querySelectorAll(this.options.snap); 30220 } 30221 30222 this.on('refresh', function () { 30223 var i = 0, l, 30224 m = 0, n, 30225 cx, cy, 30226 x = 0, y,
vendor: 7,339 bytes, lines 30227-30480
30227 stepX = this.options.snapStepX || this.wrapperWidth, 30228 stepY = this.options.snapStepY || this.wrapperHeight, 30229 el; 30230 30231 this.pages = []; 30232 30233 if ( !this.wrapperWidth || !this.wrapperHeight || !this.scrollerWidth || !this.scrollerHeight ) { 30234 return; 30235 } 30236 30237 if ( this.options.snap === true ) { 30238 cx = Math.round( stepX / 2 ); 30239 cy = Math.round( stepY / 2 ); 30240 30241 while ( x > -this.scrollerWidth ) { 30242 this.pages[i] = []; 30243 l = 0; 30244 y = 0; 30245 30246 while ( y > -this.scrollerHeight ) { 30247 this.pages[i][l] = { 30248 x: Math.max(x, this.maxScrollX), 30249 y: Math.max(y, this.maxScrollY), 30250 width: stepX, 30251 height: stepY, 30252 cx: x - cx, 30253 cy: y - cy 30254 }; 30255 30256 y -= stepY; 30257 l++; 30258 } 30259 30260 x -= stepX; 30261 i++; 30262 } 30263 } else { 30264 el = this.options.snap; 30265 l = el.length; 30266 n = -1; 30267 30268 for ( ; i < l; i++ ) { 30269 if ( i === 0 || el[i].offsetLeft <= el[i-1].offsetLeft ) { 30270 m = 0; 30271 n++; 30272 } 30273 30274 if ( !this.pages[m] ) { 30275 this.pages[m] = []; 30276 } 30277 30278 x = Math.max(-el[i].offsetLeft, this.maxScrollX); 30279 y = Math.max(-el[i].offsetTop, this.maxScrollY); 30280 cx = x - Math.round(el[i].offsetWidth / 2); 30281 cy = y - Math.round(el[i].offsetHeight / 2); 30282 30283 this.pages[m][n] = { 30284 x: x, 30285 y: y, 30286 width: el[i].offsetWidth, 30287 height: el[i].offsetHeight, 30288 cx: cx, 30289 cy: cy 30290 }; 30291 30292 if ( x > this.maxScrollX ) { 30293 m++; 30294 } 30295 } 30296 } 30297 30298 this.goToPage(this.currentPage.pageX || 0, this.currentPage.pageY || 0, 0); 30299 30300 // Update snap threshold if needed 30301 if ( this.options.snapThreshold % 1 === 0 ) { 30302 this.snapThresholdX = this.options.snapThreshold; 30303 this.snapThresholdY = this.options.snapThreshold; 30304 } else { 30305 this.snapThresholdX = Math.round(this.pages[this.currentPage.pageX][this.currentPage.pageY].width * this.options.snapThreshold); 30306 this.snapThresholdY = Math.round(this.pages[this.currentPage.pageX][this.currentPage.pageY].height * this.options.snapThreshold); 30307 } 30308 }); 30309 30310 this.on('flick', function () { 30311 var time = this.options.snapSpeed || Math.max( 30312 Math.max( 30313 Math.min(Math.abs(this.x - this.startX), 1000), 30314 Math.min(Math.abs(this.y - this.startY), 1000) 30315 ), 300); 30316 30317 this.goToPage( 30318 this.currentPage.pageX + this.directionX, 30319 this.currentPage.pageY + this.directionY, 30320 time 30321 ); 30322 }); 30323 }, 30324 30325 _nearestSnap: function (x, y) { 30326 if ( !this.pages.length ) { 30327 return { x: 0, y: 0, pageX: 0, pageY: 0 }; 30328 } 30329 30330 var i = 0, 30331 l = this.pages.length, 30332 m = 0; 30333 30334 // Check if we exceeded the snap threshold 30335 if ( Math.abs(x - this.absStartX) < this.snapThresholdX && 30336 Math.abs(y - this.absStartY) < this.snapThresholdY ) { 30337 return this.currentPage; 30338 } 30339 30340 if ( x > 0 ) { 30341 x = 0; 30342 } else if ( x < this.maxScrollX ) { 30343 x = this.maxScrollX; 30344 } 30345 30346 if ( y > 0 ) { 30347 y = 0; 30348 } else if ( y < this.maxScrollY ) { 30349 y = this.maxScrollY; 30350 } 30351 30352 for ( ; i < l; i++ ) { 30353 if ( x >= this.pages[i][0].cx ) { 30354 x = this.pages[i][0].x; 30355 break; 30356 } 30357 } 30358 30359 l = this.pages[i].length; 30360 30361 for ( ; m < l; m++ ) { 30362 if ( y >= this.pages[0][m].cy ) { 30363 y = this.pages[0][m].y; 30364 break; 30365 } 30366 } 30367 30368 if ( i == this.currentPage.pageX ) { 30369 i += this.directionX; 30370 30371 if ( i < 0 ) { 30372 i = 0; 30373 } else if ( i >= this.pages.length ) { 30374 i = this.pages.length - 1; 30375 } 30376 30377 x = this.pages[i][0].x; 30378 } 30379 30380 if ( m == this.currentPage.pageY ) { 30381 m += this.directionY; 30382 30383 if ( m < 0 ) { 30384 m = 0; 30385 } else if ( m >= this.pages[0].length ) { 30386 m = this.pages[0].length - 1; 30387 } 30388 30389 y = this.pages[0][m].y; 30390 } 30391 30392 return { 30393 x: x, 30394 y: y, 30395 pageX: i, 30396 pageY: m 30397 }; 30398 }, 30399 30400 goToPage: function (x, y, time, easing) { 30401 easing = easing || this.options.bounceEasing; 30402 30403 if ( x >= this.pages.length ) { 30404 x = this.pages.length - 1; 30405 } else if ( x < 0 ) { 30406 x = 0; 30407 } 30408 30409 if ( y >= this.pages[x].length ) { 30410 y = this.pages[x].length - 1; 30411 } else if ( y < 0 ) { 30412 y = 0; 30413 } 30414 30415 var posX = this.pages[x][y].x, 30416 posY = this.pages[x][y].y; 30417 30418 time = time === undefined ? this.options.snapSpeed || Math.max( 30419 Math.max( 30420 Math.min(Math.abs(posX - this.x), 1000), 30421 Math.min(Math.abs(posY - this.y), 1000) 30422 ), 300) : time; 30423 30424 this.currentPage = { 30425 x: posX, 30426 y: posY, 30427 pageX: x, 30428 pageY: y 30429 }; 30430 30431 this.scrollTo(posX, posY, time, easing); 30432 }, 30433 30434 next: function (time, easing) { 30435 var x = this.currentPage.pageX, 30436 y = this.currentPage.pageY; 30437 30438 x++; 30439 30440 if ( x >= this.pages.length && this.hasVerticalScroll ) { 30441 x = 0; 30442 y++; 30443 } 30444 30445 this.goToPage(x, y, time, easing); 30446 }, 30447 30448 prev: function (time, easing) { 30449 var x = this.currentPage.pageX, 30450 y = this.currentPage.pageY; 30451 30452 x--; 30453 30454 if ( x < 0 && this.hasVerticalScroll ) { 30455 x = 0; 30456 y--; 30457 } 30458 30459 this.goToPage(x, y, time, easing); 30460 }, 30461 30462 _initKeys: function (e) { 30463 // default key bindings 30464 var keys = { 30465 pageUp: 33, 30466 pageDown: 34, 30467 end: 35, 30468 home: 36, 30469 left: 37, 30470 up: 38, 30471 right: 39, 30472 down: 40 30473 }; 30474 var i; 30475 30476 // if you give me characters I give you keycode 30477 if ( typeof this.options.keyBindings == 'object' ) { 30478 for ( i in this.options.keyBindings ) { 30479 if ( typeof this.options.keyBindings[i] == 'string' ) { 30480 this.options.keyBindings[i] = this.options.keyBindings[i].toUpperCase().charCo
vendor: 11,097 bytes, lines 30480-30833
30480deAt(0); 30481 } 30482 } 30483 } else { 30484 this.options.keyBindings = {}; 30485 } 30486 30487 for ( i in keys ) { 30488 this.options.keyBindings[i] = this.options.keyBindings[i] || keys[i]; 30489 } 30490 30491 utils.addEvent(window, 'keydown', this); 30492 30493 this.on('destroy', function () { 30494 utils.removeEvent(window, 'keydown', this); 30495 }); 30496 }, 30497 30498 _key: function (e) { 30499 if ( !this.enabled ) { 30500 return; 30501 } 30502 30503 var snap = this.options.snap, // we are using this alot, better to cache it 30504 newX = snap ? this.currentPage.pageX : this.x, 30505 newY = snap ? this.currentPage.pageY : this.y, 30506 now = utils.getTime(), 30507 prevTime = this.keyTime || 0, 30508 acceleration = 0.250, 30509 pos; 30510 30511 if ( this.options.useTransition && this.isInTransition ) { 30512 pos = this.getComputedPosition(); 30513 30514 this._translate(Math.round(pos.x), Math.round(pos.y)); 30515 this.isInTransition = false; 30516 } 30517 30518 this.keyAcceleration = now - prevTime < 200 ? Math.min(this.keyAcceleration + acceleration, 50) : 0; 30519 30520 switch ( e.keyCode ) { 30521 case this.options.keyBindings.pageUp: 30522 if ( this.hasHorizontalScroll && !this.hasVerticalScroll ) { 30523 newX += snap ? 1 : this.wrapperWidth; 30524 } else { 30525 newY += snap ? 1 : this.wrapperHeight; 30526 } 30527 break; 30528 case this.options.keyBindings.pageDown: 30529 if ( this.hasHorizontalScroll && !this.hasVerticalScroll ) { 30530 newX -= snap ? 1 : this.wrapperWidth; 30531 } else { 30532 newY -= snap ? 1 : this.wrapperHeight; 30533 } 30534 break; 30535 case this.options.keyBindings.end: 30536 newX = snap ? this.pages.length-1 : this.maxScrollX; 30537 newY = snap ? this.pages[0].length-1 : this.maxScrollY; 30538 break; 30539 case this.options.keyBindings.home: 30540 newX = 0; 30541 newY = 0; 30542 break; 30543 case this.options.keyBindings.left: 30544 newX += snap ? -1 : 5 + this.keyAcceleration>>0; 30545 break; 30546 case this.options.keyBindings.up: 30547 newY += snap ? 1 : 5 + this.keyAcceleration>>0; 30548 break; 30549 case this.options.keyBindings.right: 30550 newX -= snap ? -1 : 5 + this.keyAcceleration>>0; 30551 break; 30552 case this.options.keyBindings.down: 30553 newY -= snap ? 1 : 5 + this.keyAcceleration>>0; 30554 break; 30555 default: 30556 return; 30557 } 30558 30559 if ( snap ) { 30560 this.goToPage(newX, newY); 30561 return; 30562 } 30563 30564 if ( newX > 0 ) { 30565 newX = 0; 30566 this.keyAcceleration = 0; 30567 } else if ( newX < this.maxScrollX ) { 30568 newX = this.maxScrollX; 30569 this.keyAcceleration = 0; 30570 } 30571 30572 if ( newY > 0 ) { 30573 newY = 0; 30574 this.keyAcceleration = 0; 30575 } else if ( newY < this.maxScrollY ) { 30576 newY = this.maxScrollY; 30577 this.keyAcceleration = 0; 30578 } 30579 30580 this.scrollTo(newX, newY, 0); 30581 30582 this.keyTime = now; 30583 }, 30584 30585 _animate: function (destX, destY, duration, easingFn) { 30586 var that = this, 30587 startX = this.x, 30588 startY = this.y, 30589 startTime = utils.getTime(), 30590 destTime = startTime + duration; 30591 30592 function step () { 30593 var now = utils.getTime(), 30594 newX, newY, 30595 easing; 30596 30597 if ( now >= destTime ) { 30598 that.isAnimating = false; 30599 that._translate(destX, destY); 30600 30601 if ( !that.resetPosition(that.options.bounceTime) ) { 30602 that._execEvent('scrollEnd'); 30603 } 30604 30605 return; 30606 } 30607 30608 now = ( now - startTime ) / duration; 30609 easing = easingFn(now); 30610 newX = ( destX - startX ) * easing + startX; 30611 newY = ( destY - startY ) * easing + startY; 30612 that._translate(newX, newY); 30613 30614 if ( that.isAnimating ) { 30615 rAF(step); 30616 } 30617 } 30618 30619 this.isAnimating = true; 30620 step(); 30621 }, 30622 handleEvent: function (e) { 30623 switch ( e.type ) { 30624 case 'touchstart': 30625 case 'pointerdown': 30626 case 'MSPointerDown': 30627 case 'mousedown': 30628 this._start(e); 30629 break; 30630 case 'touchmove': 30631 case 'pointermove': 30632 case 'MSPointerMove': 30633 case 'mousemove': 30634 this._move(e); 30635 break; 30636 case 'touchend': 30637 case 'pointerup': 30638 case 'MSPointerUp': 30639 case 'mouseup': 30640 case 'touchcancel': 30641 case 'pointercancel': 30642 case 'MSPointerCancel': 30643 case 'mousecancel': 30644 this._end(e); 30645 break; 30646 case 'orientationchange': 30647 case 'resize': 30648 this._resize(); 30649 break; 30650 case 'transitionend': 30651 case 'webkitTransitionEnd': 30652 case 'oTransitionEnd': 30653 case 'MSTransitionEnd': 30654 this._transitionEnd(e); 30655 break; 30656 case 'wheel': 30657 case 'DOMMouseScroll': 30658 case 'mousewheel': 30659 this._wheel(e); 30660 break; 30661 case 'keydown': 30662 this._key(e); 30663 break; 30664 case 'click': 30665 if ( this.enabled && !e._constructed ) { 30666 e.preventDefault(); 30667 e.stopPropagation(); 30668 } 30669 break; 30670 } 30671 } 30672}; 30673function createDefaultScrollbar (direction, interactive, type) { 30674 var scrollbar = document.createElement('div'), 30675 indicator = document.createElement('div'); 30676 30677 if ( type === true ) { 30678 scrollbar.style.cssText = 'position:absolute;z-index:9999'; 30679 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'; 30680 } 30681 30682 indicator.className = 'iScrollIndicator'; 30683 30684 if ( direction == 'h' ) { 30685 if ( type === true ) { 30686 scrollbar.style.cssText += ';height:7px;left:2px;right:2px;bottom:0'; 30687 indicator.style.height = '100%'; 30688 } 30689 scrollbar.className = 'iScrollHorizontalScrollbar'; 30690 } else { 30691 if ( type === true ) { 30692 scrollbar.style.cssText += ';width:7px;bottom:2px;top:2px;right:1px'; 30693 indicator.style.width = '100%'; 30694 } 30695 scrollbar.className = 'iScrollVerticalScrollbar'; 30696 } 30697 30698 scrollbar.style.cssText += ';overflow:hidden'; 30699 30700 if ( !interactive ) { 30701 scrollbar.style.pointerEvents = 'none'; 30702 } 30703 30704 scrollbar.appendChild(indicator); 30705 30706 return scrollbar; 30707} 30708 30709function Indicator (scroller, options) { 30710 this.wrapper = typeof options.el == 'string' ? document.querySelector(options.el) : options.el; 30711 this.wrapperStyle = this.wrapper.style; 30712 this.indicator = this.wrapper.children[0]; 30713 this.indicatorStyle = this.indicator.style; 30714 this.scroller = scroller; 30715 30716 this.options = { 30717 listenX: true, 30718 listenY: true, 30719 interactive: false, 30720 resize: true, 30721 defaultScrollbars: false, 30722 shrink: false, 30723 fade: false, 30724 speedRatioX: 0, 30725 speedRatioY: 0 30726 }; 30727 30728 for ( var i in options ) { 30729 this.options[i] = options[i]; 30730 } 30731 30732 this.sizeRatioX = 1; 30733 this.sizeRatioY = 1; 30734 this.maxPosX = 0; 30735 this.maxPosY = 0; 30736 30737 if ( this.options.interactive ) { 30738 if ( !this.options.disableTouch ) { 30739 utils.addEvent(this.indicator, 'touchstart', this); 30740 utils.addEvent(window, 'touchend', this); 30741 } 30742 if ( !this.options.disablePointer ) { 30743 utils.addEvent(this.indicator, utils.prefixPointerEvent('pointerdown'), this); 30744 utils.addEvent(window, utils.prefixPointerEvent('pointerup'), this); 30745 } 30746 if ( !this.options.disableMouse ) { 30747 utils.addEvent(this.indicator, 'mousedown', this); 30748 utils.addEvent(window, 'mouseup', this); 30749 } 30750 } 30751 30752 if ( this.options.fade ) { 30753 this.wrapperStyle[utils.style.transform] = this.scroller.translateZ; 30754 var durationProp = utils.style.transitionDuration; 30755 if(!durationProp) { 30756 return; 30757 } 30758 this.wrapperStyle[durationProp] = utils.isBadAndroid ? '0.0001ms' : '0ms'; 30759 // remove 0.0001ms 30760 var self = this; 30761 if(utils.isBadAndroid) { 30762 rAF(function() { 30763 if(self.wrapperStyle[durationProp] === '0.0001ms') { 30764 self.wrapperStyle[durationProp] = '0s'; 30765 } 30766 }); 30767 } 30768 this.wrapperStyle.opacity = '0'; 30769 } 30770} 30771 30772Indicator.prototype = { 30773 handleEvent: function (e) { 30774 switch ( e.type ) { 30775 case 'touchstart': 30776 case 'pointerdown': 30777 case 'MSPointerDown': 30778 case 'mousedown': 30779 this._start(e); 30780 break; 30781 case 'touchmove': 30782 case 'pointermove': 30783 case 'MSPointerMove': 30784 case 'mousemove': 30785 this._move(e); 30786 break; 30787 case 'touchend': 30788 case 'pointerup': 30789 case 'MSPointerUp': 30790 case 'mouseup': 30791 case 'touchcancel': 30792 case 'pointercancel': 30793 case 'MSPointerCancel': 30794 case 'mousecancel': 30795 this._end(e); 30796 break; 30797 } 30798 }, 30799 30800 destroy: function () { 30801 if ( this.options.fadeScrollbars ) { 30802 clearTimeout(this.fadeTimeout); 30803 this.fadeTimeout = null; 30804 } 30805 if ( this.options.interactive ) { 30806 utils.removeEvent(this.indicator, 'touchstart', this); 30807 utils.removeEvent(this.indicator, utils.prefixPointerEvent('pointerdown'), this); 30808 utils.removeEvent(this.indicator, 'mousedown', this); 30809 30810 utils.removeEvent(window, 'touchmove', this); 30811 utils.removeEvent(window, utils.prefixPointerEvent('pointermove'), this); 30812 utils.removeEvent(window, 'mousemove', this); 30813 30814 utils.removeEvent(window, 'touchend', this); 30815 utils.removeEvent(window, utils.prefixPointerEvent('pointerup'), this); 30816 utils.removeEvent(window, 'mouseup', this); 30817 } 30818 30819 if ( this.options.defaultScrollbars ) { 30820 this.wrapper.parentNode.removeChild(this.wrapper); 30821 } 30822 }, 30823 30824 _start: function (e) { 30825 var point = e.touches ? e.touches[0] : e; 30826 30827 e.preventDefault(); 30828 e.stopPropagation(); 30829 30830 this.transitionTime(); 30831 30832 this.initiated = true; 30833 this.moved = false;
vendor: 9,615 bytes, lines 30834-31092
30834 this.lastPointX = point.pageX; 30835 this.lastPointY = point.pageY; 30836 30837 this.startTime = utils.getTime(); 30838 30839 if ( !this.options.disableTouch ) { 30840 utils.addEvent(window, 'touchmove', this); 30841 } 30842 if ( !this.options.disablePointer ) { 30843 utils.addEvent(window, utils.prefixPointerEvent('pointermove'), this); 30844 } 30845 if ( !this.options.disableMouse ) { 30846 utils.addEvent(window, 'mousemove', this); 30847 } 30848 30849 this.scroller._execEvent('beforeScrollStart'); 30850 }, 30851 30852 _move: function (e) { 30853 var point = e.touches ? e.touches[0] : e, 30854 deltaX, deltaY, 30855 newX, newY, 30856 timestamp = utils.getTime(); 30857 30858 if ( !this.moved ) { 30859 this.scroller._execEvent('scrollStart'); 30860 } 30861 30862 this.moved = true; 30863 30864 deltaX = point.pageX - this.lastPointX; 30865 this.lastPointX = point.pageX; 30866 30867 deltaY = point.pageY - this.lastPointY; 30868 this.lastPointY = point.pageY; 30869 30870 newX = this.x + deltaX; 30871 newY = this.y + deltaY; 30872 30873 this._pos(newX, newY); 30874 30875// INSERT POINT: indicator._move 30876 30877 e.preventDefault(); 30878 e.stopPropagation(); 30879 }, 30880 30881 _end: function (e) { 30882 if ( !this.initiated ) { 30883 return; 30884 } 30885 30886 this.initiated = false; 30887 30888 e.preventDefault(); 30889 e.stopPropagation(); 30890 30891 utils.removeEvent(window, 'touchmove', this); 30892 utils.removeEvent(window, utils.prefixPointerEvent('pointermove'), this); 30893 utils.removeEvent(window, 'mousemove', this); 30894 30895 if ( this.scroller.options.snap ) { 30896 var snap = this.scroller._nearestSnap(this.scroller.x, this.scroller.y); 30897 30898 var time = this.options.snapSpeed || Math.max( 30899 Math.max( 30900 Math.min(Math.abs(this.scroller.x - snap.x), 1000), 30901 Math.min(Math.abs(this.scroller.y - snap.y), 1000) 30902 ), 300); 30903 30904 if ( this.scroller.x != snap.x || this.scroller.y != snap.y ) { 30905 this.scroller.directionX = 0; 30906 this.scroller.directionY = 0; 30907 this.scroller.currentPage = snap; 30908 this.scroller.scrollTo(snap.x, snap.y, time, this.scroller.options.bounceEasing); 30909 } 30910 } 30911 30912 if ( this.moved ) { 30913 this.scroller._execEvent('scrollEnd'); 30914 } 30915 }, 30916 30917 transitionTime: function (time) { 30918 time = time || 0; 30919 var durationProp = utils.style.transitionDuration; 30920 if(!durationProp) { 30921 return; 30922 } 30923 30924 this.indicatorStyle[durationProp] = time + 'ms'; 30925 30926 if ( !time && utils.isBadAndroid ) { 30927 this.indicatorStyle[durationProp] = '0.0001ms'; 30928 // remove 0.0001ms 30929 var self = this; 30930 rAF(function() { 30931 if(self.indicatorStyle[durationProp] === '0.0001ms') { 30932 self.indicatorStyle[durationProp] = '0s'; 30933 } 30934 }); 30935 } 30936 }, 30937 30938 transitionTimingFunction: function (easing) { 30939 this.indicatorStyle[utils.style.transitionTimingFunction] = easing; 30940 }, 30941 30942 refresh: function () { 30943 this.transitionTime(); 30944 30945 if ( this.options.listenX && !this.options.listenY ) { 30946 this.indicatorStyle.display = this.scroller.hasHorizontalScroll ? 'block' : 'none'; 30947 } else if ( this.options.listenY && !this.options.listenX ) { 30948 this.indicatorStyle.display = this.scroller.hasVerticalScroll ? 'block' : 'none'; 30949 } else { 30950 this.indicatorStyle.display = this.scroller.hasHorizontalScroll || this.scroller.hasVerticalScroll ? 'block' : 'none'; 30951 } 30952 30953 if ( this.scroller.hasHorizontalScroll && this.scroller.hasVerticalScroll ) { 30954 utils.addClass(this.wrapper, 'iScrollBothScrollbars'); 30955 utils.removeClass(this.wrapper, 'iScrollLoneScrollbar'); 30956 30957 if ( this.options.defaultScrollbars && this.options.customStyle ) { 30958 if ( this.options.listenX ) { 30959 this.wrapper.style.right = '8px'; 30960 } else { 30961 this.wrapper.style.bottom = '8px'; 30962 } 30963 } 30964 } else { 30965 utils.removeClass(this.wrapper, 'iScrollBothScrollbars'); 30966 utils.addClass(this.wrapper, 'iScrollLoneScrollbar'); 30967 30968 if ( this.options.defaultScrollbars && this.options.customStyle ) { 30969 if ( this.options.listenX ) { 30970 this.wrapper.style.right = '2px'; 30971 } else { 30972 this.wrapper.style.bottom = '2px'; 30973 } 30974 } 30975 } 30976 30977 var r = this.wrapper.offsetHeight; // force refresh 30978 30979 if ( this.options.listenX ) { 30980 this.wrapperWidth = this.wrapper.clientWidth; 30981 if ( this.options.resize ) { 30982 this.indicatorWidth = Math.max(Math.round(this.wrapperWidth * this.wrapperWidth / (this.scroller.scrollerWidth || this.wrapperWidth || 1)), 8); 30983 this.indicatorStyle.width = this.indicatorWidth + 'px'; 30984 } else { 30985 this.indicatorWidth = this.indicator.clientWidth; 30986 } 30987 30988 this.maxPosX = this.wrapperWidth - this.indicatorWidth; 30989 30990 if ( this.options.shrink == 'clip' ) { 30991 this.minBoundaryX = -this.indicatorWidth + 8; 30992 this.maxBoundaryX = this.wrapperWidth - 8; 30993 } else { 30994 this.minBoundaryX = 0; 30995 this.maxBoundaryX = this.maxPosX; 30996 } 30997 30998 this.sizeRatioX = this.options.speedRatioX || (this.scroller.maxScrollX && (this.maxPosX / this.scroller.maxScrollX)); 30999 } 31000 31001 if ( this.options.listenY ) { 31002 this.wrapperHeight = this.wrapper.clientHeight; 31003 if ( this.options.resize ) { 31004 this.indicatorHeight = Math.max(Math.round(this.wrapperHeight * this.wrapperHeight / (this.scroller.scrollerHeight || this.wrapperHeight || 1)), 8); 31005 this.indicatorStyle.height = this.indicatorHeight + 'px'; 31006 } else { 31007 this.indicatorHeight = this.indicator.clientHeight; 31008 } 31009 31010 this.maxPosY = this.wrapperHeight - this.indicatorHeight; 31011 31012 if ( this.options.shrink == 'clip' ) { 31013 this.minBoundaryY = -this.indicatorHeight + 8; 31014 this.maxBoundaryY = this.wrapperHeight - 8; 31015 } else { 31016 this.minBoundaryY = 0; 31017 this.maxBoundaryY = this.maxPosY; 31018 } 31019 31020 this.maxPosY = this.wrapperHeight - this.indicatorHeight; 31021 this.sizeRatioY = this.options.speedRatioY || (this.scroller.maxScrollY && (this.maxPosY / this.scroller.maxScrollY)); 31022 } 31023 31024 this.updatePosition(); 31025 }, 31026 31027 updatePosition: function () { 31028 var x = this.options.listenX && Math.round(this.sizeRatioX * this.scroller.x) || 0, 31029 y = this.options.listenY && Math.round(this.sizeRatioY * this.scroller.y) || 0; 31030 31031 if ( !this.options.ignoreBoundaries ) { 31032 if ( x < this.minBoundaryX ) { 31033 if ( this.options.shrink == 'scale' ) { 31034 this.width = Math.max(this.indicatorWidth + x, 8); 31035 this.indicatorStyle.width = this.width + 'px'; 31036 } 31037 x = this.minBoundaryX; 31038 } else if ( x > this.maxBoundaryX ) { 31039 if ( this.options.shrink == 'scale' ) { 31040 this.width = Math.max(this.indicatorWidth - (x - this.maxPosX), 8); 31041 this.indicatorStyle.width = this.width + 'px'; 31042 x = this.maxPosX + this.indicatorWidth - this.width; 31043 } else { 31044 x = this.maxBoundaryX; 31045 } 31046 } else if ( this.options.shrink == 'scale' && this.width != this.indicatorWidth ) { 31047 this.width = this.indicatorWidth; 31048 this.indicatorStyle.width = this.width + 'px'; 31049 } 31050 31051 if ( y < this.minBoundaryY ) { 31052 if ( this.options.shrink == 'scale' ) { 31053 this.height = Math.max(this.indicatorHeight + y * 3, 8); 31054 this.indicatorStyle.height = this.height + 'px'; 31055 } 31056 y = this.minBoundaryY; 31057 } else if ( y > this.maxBoundaryY ) { 31058 if ( this.options.shrink == 'scale' ) { 31059 this.height = Math.max(this.indicatorHeight - (y - this.maxPosY) * 3, 8); 31060 this.indicatorStyle.height = this.height + 'px'; 31061 y = this.maxPosY + this.indicatorHeight - this.height; 31062 } else { 31063 y = this.maxBoundaryY; 31064 } 31065 } else if ( this.options.shrink == 'scale' && this.height != this.indicatorHeight ) { 31066 this.height = this.indicatorHeight; 31067 this.indicatorStyle.height = this.height + 'px'; 31068 } 31069 } 31070 31071 this.x = x; 31072 this.y = y; 31073 31074 if ( this.scroller.options.useTransform ) { 31075 this.indicatorStyle[utils.style.transform] = 'translate(' + x + 'px,' + y + 'px)' + this.scroller.translateZ; 31076 } else { 31077 this.indicatorStyle.left = x + 'px'; 31078 this.indicatorStyle.top = y + 'px'; 31079 } 31080 }, 31081 31082 _pos: function (x, y) { 31083 if ( x < 0 ) { 31084 x = 0; 31085 } else if ( x > this.maxPosX ) { 31086 x = this.maxPosX; 31087 } 31088 31089 if ( y < 0 ) { 31090 y = 0; 31091 } else if ( y > this.maxPosY ) { 31092 y = this.maxPosY;
31093 } 31094 31095 x = this.options.listenX ? Math.round(x / this.sizeRatioX) : this.scroller.x; 31096 y = this.options.listenY ? Math.round(y / this.sizeRatioY) : this.scroller.y; 31097 31098 this.scroller.scrollTo(x, y); 31099 }, 31100 31101 fade: function (val, hold) { 31102 if ( hold && !this.visible ) { 31103 return; 31104 } 31105 31106 clearTimeout(this.fadeTimeout); 31107 this.fadeTimeout = null; 31108 31109 var time = val ? 250 : 500, 31110 delay = val ? 0 : 300; 31111 31112 val = val ? '1' : '0'; 31113 31114 this.wrapperStyle[utils.style.transitionDuration] = time + 'ms'; 31115 31116 this.fadeTimeout = setTimeout((function (val) { 31117 this.wrapperStyle.opacity = val; 31118 this.visible = +val; 31119 }).bind(this, val), delay); 31120 } 31121}; 31122 31123IScroll.utils = utils; 31124 31125if ( typeof module != 'undefined' && module.exports ) { 31126 module.exports = IScroll; 31127} else if ( typeof define == 'function' && define.amd ) { 31128 define( function () { return IScroll; } ); 31129} else { 31130 window.IScroll = IScroll; 31131} 31132 31133})(window, document, Math); 31134/*! 31135 * fullPage 2.9.4 31136 * https://github.com/alvarotrigo/fullPage.js 31137 * @license MIT licensed 31138 * 31139 * Copyright (C) 2015 alvarotrigo.com - A project by Alvaro Trigo 31140 */ 31141(function(global, factory) { 31142 'use strict'; 31143 if (typeof define === 'function' && define.amd) { 31144 define(['jquery'], function($) { 31145 return factory($, global, global.document, global.Math); 31146 }); 31147 } else if (typeof exports === "object" && exports) { 31148 module.exports = factory(require('jquery'), global, global.document, global.Math); 31149 } else { 31150 factory(jQuery, global, global.document, global.Math); 31151 } 31152})(typeof window !== 'undefined' ? window : this, function($, window, document, Math, undefined) { 31153 'use strict'; 31154 31155 // keeping central set of classnames and selectors 31156 var WRAPPER = 'fullpage-wrapper'; 31157 var WRAPPER_SEL = '.' + WRAPPER; 31158 31159 // slimscroll 31160 var SCROLLABLE = 'fp-scrollable'; 31161 var SCROLLABLE_SEL = '.' + SCROLLABLE; 31162 31163 // util 31164 var RESPONSIVE = 'fp-responsive'; 31165 var NO_TRANSITION = 'fp-notransition'; 31166 var DESTROYED = 'fp-destroyed'; 31167 var ENABLED = 'fp-enabled'; 31168 var VIEWING_PREFIX = 'fp-viewing'; 31169 var ACTIVE = 'active'; 31170 var ACTIVE_SEL = '.' + ACTIVE; 31171 var COMPLETELY = 'fp-completely'; 31172 var COMPLETELY_SEL = '.' + COMPLETELY; 31173 31174 // section 31175 var SECTION_DEFAULT_SEL = '.section'; 31176 var SECTION = 'fp-section'; 31177 var SECTION_SEL = '.' + SECTION; 31178 var SECTION_ACTIVE_SEL = SECTION_SEL + ACTIVE_SEL; 31179 var SECTION_FIRST_SEL = SECTION_SEL + ':first'; 31180 var SECTION_LAST_SEL = SECTION_SEL + ':last'; 31181 var TABLE_CELL = 'fp-tableCell'; 31182 var TABLE_CELL_SEL = '.' + TABLE_CELL; 31183 var AUTO_HEIGHT = 'fp-auto-height'; 31184 var AUTO_HEIGHT_SEL = '.fp-auto-height'; 31185 var NORMAL_SCROLL = 'fp-normal-scroll'; 31186 var NORMAL_SCROLL_SEL = '.fp-normal-scroll'; 31187 31188 // section nav 31189 var SECTION_NAV = 'fp-nav'; 31190 var SECTION_NAV_SEL = '#' + SECTION_NAV; 31191 var SECTION_NAV_TOOLTIP = 'fp-tooltip'; 31192 var SECTION_NAV_TOOLTIP_SEL='.'+SECTION_NAV_TOOLTIP; 31193 var SHOW_ACTIVE_TOOLTIP = 'fp-show-active'; 31194 31195 // slide 31196 var SLIDE_DEFAULT_SEL = '.slide'; 31197 var SLIDE = 'fp-slide'; 31198 var SLIDE_SEL = '.' + SLIDE; 31199 var SLIDE_ACTIVE_SEL = SLIDE_SEL + ACTIVE_SEL; 31200 var SLIDES_WRAPPER = 'fp-slides'; 31201 var SLIDES_WRAPPER_SEL = '.' + SLIDES_WRAPPER; 31202 var SLIDES_CONTAINER = 'fp-slidesContainer'; 31203 var SLIDES_CONTAINER_SEL = '.' + SLIDES_CONTAINER; 31204 var TABLE = 'fp-table'; 31205 31206 // slide nav 31207 var SLIDES_NAV = 'fp-slidesNav'; 31208 var SLIDES_NAV_SEL = '.' + SLIDES_NAV; 31209 var SLIDES_NAV_LINK_SEL = SLIDES_NAV_SEL + ' a'; 31210 var SLIDES_ARROW = 'fp-controlArrow'; 31211 var SLIDES_ARROW_SEL = '.' + SLIDES_ARROW; 31212 var SLIDES_PREV = 'fp-prev'; 31213 var SLIDES_PREV_SEL = '.' + SLIDES_PREV; 31214 var SLIDES_ARROW_PREV = SLIDES_ARROW + ' ' + SLIDES_PREV; 31215 var SLIDES_ARROW_PREV_SEL = SLIDES_ARROW_SEL + SLIDES_PREV_SEL; 31216 var SLIDES_NEXT = 'fp-next';
31217 var SLIDES_NEXT_SEL = '.' + SLIDES_NEXT; 31218 var SLIDES_ARROW_NEXT = SLIDES_ARROW + ' ' + SLIDES_NEXT; 31219 var SLIDES_ARROW_NEXT_SEL = SLIDES_ARROW_SEL + SLIDES_NEXT_SEL; 31220 31221 var $window = $(window); 31222 var $document = $(document); 31223 31224 // Default options for iScroll.js used when using scrollOverflow 31225 var iscrollOptions = { 31226 scrollbars: true, 31227 mouseWheel: true, 31228 hideScrollbars: false, 31229 fadeScrollbars: false, 31230 disableMouse: true, 31231 interactiveScrollbars: true, 31232 bounce: false, 31233 }; 31234 31235 $.fn.fullpage = function(options) { 31236 //only once my friend! 31237 if($('html').hasClass(ENABLED)){ displayWarnings(); return; } 31238 31239 // common jQuery objects 31240 var $htmlBody = $('html, body'); 31241 var $body = $('body'); 31242 31243 var FP = $.fn.fullpage; 31244 31245 // Creating some defaults, extending them with any options that were provided 31246 options = $.extend({ 31247 //navigation 31248 menu: false, 31249 anchors:[], 31250 lockAnchors: false, 31251 navigation: false, 31252 navigationPosition: 'right', 31253 navigationTooltips: [], 31254 showActiveTooltip: false, 31255 slidesNavigation: false, 31256 slidesNavPosition: 'bottom', 31257 scrollBar: false, 31258 hybrid: false, 31259 31260 //scrolling 31261 css3: true, 31262 scrollingSpeed: 700, 31263 autoScrolling: true, 31264 fitToSection: true, 31265 fitToSectionDelay: 1000, 31266 easing: 'easeInOutCubic', 31267 easingcss3: 'ease', 31268 loopBottom: false, 31269 loopTop: false, 31270 loopHorizontal: true, 31271 continuousVertical: false, 31272 continuousHorizontal: false, 31273 scrollHorizontally: false, 31274 interlockedSlides: false, 31275 dragAndMove: false, 31276 offsetSections: false, 31277 resetSliders: false, 31278 fadingEffect: false, 31279 normalScrollElements: null, 31280 scrollOverflow: false, 31281 scrollOverflowReset: false, 31282 scrollOverflowHandler: iscrollHandler, 31283 scrollOverflowOptions: null, 31284 touchSensitivity: 5, 31285 normalScrollElementTouchThreshold: 5, 31286 bigSectionsDestination: null, 31287 31288 //Accessibility 31289 keyboardScrolling: true, 31290 animateAnchor: true, 31291 recordHistory: true, 31292 31293 //design 31294 controlArrows: true, 31295 controlArrowColor: '#fff', 31296 verticalCentered: true, 31297 sectionsColor : [], 31298 paddingTop: 0, 31299 paddingBottom: 0, 31300 fixedElements: null, 31301 responsive: 0, //backwards compabitility with responsiveWiddth 31302 responsiveWidth: 0, 31303 responsiveHeight: 0, 31304 responsiveSlides: false, 31305 parallax: false, 31306 parallaxOptions: { 31307 type: 'reveal', 31308 percentage: 62, 31309 property: 'translate' 31310 }, 31311 31312 //Custom selectors 31313 sectionSelector: SECTION_DEFAULT_SEL, 31314 slideSelector: SLIDE_DEFAULT_SEL, 31315 31316 //events 31317 afterLoad: null, 31318 onLeave: null, 31319 afterRender: null, 31320 afterResize: null, 31321 afterReBuild: null, 31322 afterSlideLoad: null, 31323 onSlideLeave: null, 31324 afterResponsive: null, 31325 31326 lazyLoading: true 31327 }, options); 31328 31329 //flag to avoid very fast sliding for landscape sliders 31330 var slideMoving = false; 31331 31332 var isTouchDevice = navigator.userAgent.match(/(iPhone|iPod|iPad|Android|playbook|silk|BlackBerry|BB10|Windows Phone|Tizen|Bada|webOS|IEMobile|Opera Mini)/); 31333 var isTouch = (('ontouchstart' in window) || (navigator.msMaxTouchPoints > 0) || (navigator.maxTouchPoints)); 31334 var container = $(this); 31335 var windowsHeight = $window.height(); 31336 var isResizing = false; 31337 var isWindowFocused = true; 31338 var lastScrolledDestiny; 31339 var lastScrolledSlide; 31340 var canScroll = true; 31341 var scrollings = []; 31342 var controlPressed; 31343 var startingSection; 31344 var isScrollAllowed = {}; 31345 isScrollAllowed.m = { 'up':true, 'down':true, 'left':true, 'right':true }; 31346 isScrollAllowed.k = $.extend(true,{}, isScrollAllowed.m); 31347 var MSPointer = getMSPointer(); 31348 var events = { 31349 touchmove: 'ontouchmove' in window ? 'touchmove' : MSPointer.move, 31350 touchstart: 'ontouchstart' in window ? 'touchstart' : MSPointer.down 31351 }; 31352 31353 //cheks for passive event support 31354 //added by Uncode from new fullPage updates 31355 var g_supportsPassive = false;
31356 try { 31357 var opts = Object.defineProperty({}, 'passive', { 31358 get: function() { 31359 g_supportsPassive = true; 31360 } 31361 }); 31362 window.addEventListener("testPassive", null, opts); 31363 window.removeEventListener("testPassive", null, opts); 31364 } catch (e) {} 31365 31366 //timeouts 31367 var resizeId; 31368 var afterSectionLoadsId; 31369 var afterSlideLoadsId; 31370 var scrollId; 31371 var scrollId2; 31372 var keydownId; 31373 var originals = $.extend(true, {}, options); //deep copy 31374 31375 //Uncode addition 31376 var $masthead = $('#masthead'); 31377 var hideMenu = !$('body').hasClass('vmenu') && $('body').hasClass('uncode-fp-menu-hide') ? true : false; 31378 var menuHeight = $masthead.hasClass('menu-transparent') || hideMenu ? 0 : UNCODE.menuHeight; 31379 var bodyBorder = UNCODE.bodyBorder; 31380 var adminBarHeight = UNCODE.adminBarHeight; 31381 31382 displayWarnings(); 31383 31384 //fixing bug in iScroll with links: https://github.com/cubiq/iscroll/issues/783 31385 iscrollOptions.click = isTouch; // see #2035 31386 31387 //extending iScroll options with the user custom ones 31388 iscrollOptions = $.extend(iscrollOptions, options.scrollOverflowOptions); 31389 31390 //easeInOutCubic animation included in the plugin 31391 $.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;}}); 31392 31393 /** 31394 * Sets the autoScroll option. 31395 * It changes the scroll bar visibility and the history of the site as a result. 31396 */ 31397 function setAutoScrolling(value, type){ 31398 //removing the transformation 31399 if(!value){ 31400 silentScroll(0); 31401 } 31402 31403 setVariableState('autoScrolling', value, type); 31404 31405 var element = $(SECTION_ACTIVE_SEL); 31406 31407 if(options.autoScrolling && !options.scrollBar){ 31408 $htmlBody.css({ 31409 'overflow' : 'hidden !important', 31410 'height' : '100%' 31411 }); 31412 31413 //Uncode addition 31414 //setRecordHistory(originals.recordHistory, 'internal'); 31415 31416 //for IE touch devices 31417 container.css({ 31418 '-ms-touch-action': 'none', 31419 'touch-action': 'none' 31420 }); 31421 31422 if(element.length){ 31423 //moving the container up 31424 silentScroll(element.position().top); 31425 } 31426 31427 }else{ 31428 $htmlBody.css({ 31429 'overflow' : 'visible !important', 31430 'height' : 'initial' 31431 }); 31432 31433 //Uncode addition 31434 //setRecordHistory(false, 'internal'); 31435 31436 //for IE touch devices 31437 container.css({ 31438 '-ms-touch-action': '', 31439 'touch-action': '' 31440 }); 31441 31442 //scrolling the page to the section with no animation 31443 if (element.length) { 31444 $htmlBody.scrollTop(element.position().top); 31445 } 31446 } 31447 } 31448 31449 /** 31450 * Defines wheter to record the history for each hash change in the URL. 31451 */ 31452 function setRecordHistory(value, type){ 31453 setVariableState('recordHistory', value, type); 31454 } 31455 31456 /** 31457 * Defines the scrolling speed 31458 */ 31459 function setScrollingSpeed(value, type){ 31460 setVariableState('scrollingSpeed', value, type); 31461 } 31462 31463 /** 31464 * Sets fitToSection 31465 */ 31466 function setFitToSection(value, type){ 31467 setVariableState('fitToSection', value, type); 31468 } 31469 31470 /** 31471 * Sets lockAnchors 31472 */ 31473 function setLockAnchors(value){ 31474 options.lockAnchors = value; 31475 } 31476 31477 /** 31478 * Adds or remove the possiblity of scrolling through sections by using the mouse wheel or the trackpad. 31479 */ 31480 function setMouseWheelScrolling(value){ 31481 if(value){ 31482 addMouseWheelHandler(); 31483 addMiddleWheelHandler(); 31484 }else{ 31485 removeMouseWheelHandler(); 31486 removeMiddleWheelHandler(); 31487 } 31488 } 31489 31490 /** 31491 * Adds or remove the possibility of scrolling through sections by using the mouse wheel/trackpad or touch gestures. 31492 * Optionally a second parameter can be used to specify the direction for which the action will be applied. 31493 * 31494 * @param directions string containing the direction or directions separated by comma. 31495 */ 31496 function setAllowScrolling(value, directions){ 31497 if(typeof directions !== 'undefined'){ 31498 directions = directions.replace(/ /g,'').split(','); 31499 31500 $.each(directions, function (index, direction){ 31501 setIsScrollAllowed(value, direction, 'm'); 31502 }); 31503 } 31504 else if(value){ 31505 setMouseWheelScrolling(true); 31506 addTouchHandler(); 31507 }else{ 31508 setMouseWheelScrolling(false); 31509 removeTouchHandler(); 31510 } 31511 } 31512 31513 /** 31514 * Adds or remove the possibility of scrolling through sections by using the keyboard arrow keys 31515 */ 31516 function setKeyboardScrolling(value, directions){ 31517 if(typeof directions !== 'undefined'){ 31518 directions = directions.replace(/ /g,'').split(','); 31519 31520 $.each(directions, function (index, direction){ 31521 setIsScrollAllowed(value, direction, 'k'); 31522 }); 31523 }else{ 31524 options.keyboardScrolling = value; 31525 } 31526 } 31527 31528 /** 31529 * Moves the page up one section. 31530 */ 31531 function moveSectionUp(){ 31532 var prev = $(SECTION_ACTIVE_SEL).prev(SECTION_SEL); 31533 31534 //looping to the bottom if there's no more sections above 31535 if (!prev.length && (options.loopTop || options.continuousVertical)) {
31536 prev = $(SECTION_SEL).last(); 31537 } 31538 31539 if (prev.length) { 31540 scrollPage(prev, null, true); 31541 } 31542 } 31543 31544 /** 31545 * Moves the page down one section. 31546 */ 31547 function moveSectionDown(){ 31548 var next = $(SECTION_ACTIVE_SEL).next(SECTION_SEL); 31549 31550 //looping to the top if there's no more sections below 31551 if(!next.length && 31552 (options.loopBottom || options.continuousVertical)){ 31553 next = $(SECTION_SEL).first(); 31554 } 31555 31556 if(next.length){ 31557 scrollPage(next, null, false); 31558 } 31559 } 31560 31561 /** 31562 * Moves the page to the given section and slide with no animation. 31563 * Anchors or index positions can be used as params. 31564 */ 31565 function silentMoveTo(sectionAnchor, slideAnchor){ 31566 setScrollingSpeed (0, 'internal'); 31567 moveTo(sectionAnchor, slideAnchor); 31568 setScrollingSpeed (originals.scrollingSpeed, 'internal'); 31569 } 31570 31571 /** 31572 * Moves the page to the given section and slide. 31573 * Anchors or index positions can be used as params. 31574 */ 31575 function moveTo(sectionAnchor, slideAnchor){ 31576 var destiny = getSectionByAnchor(sectionAnchor); 31577 31578 if (typeof slideAnchor !== 'undefined'){ 31579 scrollPageAndSlide(sectionAnchor, slideAnchor); 31580 }else if(destiny.length > 0){ 31581 scrollPage(destiny); 31582 } 31583 } 31584 31585 /** 31586 * Slides right the slider of the active section. 31587 * Optional `section` param. 31588 */ 31589 function moveSlideRight(section){ 31590 moveSlide('right', section); 31591 } 31592 31593 /** 31594 * Slides left the slider of the active section. 31595 * Optional `section` param. 31596 */ 31597 function moveSlideLeft(section){ 31598 moveSlide('left', section); 31599 } 31600 31601 /** 31602 * When resizing is finished, we adjust the slides sizes and positions 31603 */ 31604 function reBuild(resizing){ 31605 if(container.hasClass(DESTROYED)){ return; } //nothing to do if the plugin was destroyed 31606 31607 isResizing = true; 31608 31609 windowsHeight = $window.height(); //updating global var 31610 31611 $(SECTION_SEL).each(function(){ 31612 var slidesWrap = $(this).find(SLIDES_WRAPPER_SEL); 31613 var slides = $(this).find(SLIDE_SEL); 31614 31615 //adjusting the height of the table-cell for IE and Firefox 31616 if(options.verticalCentered){ 31617 $(this).find(TABLE_CELL_SEL).css('height', getTableHeight($(this)) + 'px'); 31618 } 31619 31620 $(this).css('height', windowsHeight + 'px'); 31621 31622 //resizing the scrolling divs 31623 if(options.scrollOverflow){ 31624 if(slides.length){ 31625 slides.each(function(){ 31626 createScrollBar($(this)); 31627 }); 31628 }else{ 31629 createScrollBar($(this)); 31630 } 31631 } 31632 31633 //adjusting the position fo the FULL WIDTH slides... 31634 if (slides.length > 1) { 31635 landscapeScroll(slidesWrap, slidesWrap.find(SLIDE_ACTIVE_SEL)); 31636 } 31637 }); 31638 31639 var activeSection = $(SECTION_ACTIVE_SEL); 31640 var sectionIndex = activeSection.index(SECTION_SEL); 31641 31642 //isn't it the first section? 31643 if(sectionIndex){ 31644 //adjusting the position for the current section 31645 silentMoveTo(sectionIndex + 1); 31646 } 31647 31648 isResizing = false; 31649 // Uncode change 31650 // $.isFunction( options.afterResize ) && resizing && options.afterResize.call(container); 31651 $.isFunction( options.afterResize ) && resizing && options.afterResize.call(container, getTableHeight()); 31652 $.isFunction( options.afterReBuild ) && !resizing && options.afterReBuild.call(container); 31653 } 31654 31655 /** 31656 * Turns fullPage.js to normal scrolling mode when the viewport `width` or `height` 31657 * are smaller than the set limit values. 31658 */ 31659 function setResponsive(active){ 31660 var isResponsive = $body.hasClass(RESPONSIVE); 31661 31662 if(active){ 31663 if(!isResponsive){ 31664 setAutoScrolling(false, 'internal'); 31665 setFitToSection(false, 'internal'); 31666 $(SECTION_NAV_SEL).hide(); 31667 $body.addClass(RESPONSIVE); 31668 $.isFunction( options.afterResponsive ) && options.afterResponsive.call( container, active); 31669 } 31670 } 31671 else if(isResponsive){ 31672 setAutoScrolling(originals.autoScrolling, 'internal'); 31673 setFitToSection(originals.autoScrolling, 'internal'); 31674 $(SECTION_NAV_SEL).show(); 31675 $body.removeClass(RESPONSIVE); 31676 $.isFunction( options.afterResponsive ) && options.afterResponsive.call( container, active); 31677 } 31678 } 31679 31680 if($(this).length){ 31681 //public functions 31682 FP.setAutoScrolling = setAutoScrolling; 31683 FP.setRecordHistory = setRecordHistory; 31684 FP.setScrollingSpeed = setScrollingSpeed; 31685 FP.setFitToSection = setFitToSection; 31686 FP.setLockAnchors = setLockAnchors; 31687 FP.setMouseWheelScrolling = setMouseWheelScrolling; 31688 FP.setAllowScrolling = setAllowScrolling; 31689 FP.setKeyboardScrolling = setKeyboardScrolling; 31690 FP.moveSectionUp = moveSectionUp; 31691 FP.moveSectionDown = moveSectionDown; 31692 FP.silentMoveTo = silentMoveTo; 31693 FP.moveTo = moveTo; 31694 FP.moveSlideRight = moveSlideRight; 31695 FP.moveSlideLeft = moveSlideLeft; 31696 FP.fitToSection = fitToSection; 31697 FP.reBuild = reBuild; 31698 FP.setResponsive = setResponsive; 31699 FP.destroy = destroy; 31700 31701 init(); 31702 31703 bindEvents(); 31704 } 31705
31706 function init(){ 31707 //if css3 is not supported, it will use jQuery animations 31708 if(options.css3){ 31709 options.css3 = support3d(); 31710 } 31711 31712 options.scrollBar = options.scrollBar || options.hybrid; 31713 31714 setOptionsFromDOM(); 31715 prepareDom(); 31716 setAllowScrolling(true); 31717 setAutoScrolling(options.autoScrolling, 'internal'); 31718 responsive(); 31719 31720 //setting the class for the body element 31721 setBodyClass(); 31722 31723 //Uncode addition 31724 // if(document.readyState === 'complete'){ 31725 // scrollToAnchor(); 31726 // } 31727 // $window.on('load', scrollToAnchor); 31728 } 31729 31730 function bindEvents(){ 31731 $window 31732 //when scrolling... 31733 //.on('scroll', scrollHandler) 31734 31735 //detecting any change on the URL to scroll to the given anchor link 31736 //(a way to detect back history button as we play with the hashes on the URL) 31737 .on('hashchange', hashChangeHandler) 31738 31739 //when opening a new tab (ctrl + t), `control` won't be pressed when coming back. 31740 .blur(blurHandler) 31741 31742 //when resizing the site, we adjust the heights of the sections, slimScroll... 31743 .resize(resizeHandler); 31744 31745 $document 31746 //Sliding with arrow keys, both, vertical and horizontal 31747 .keydown(keydownHandler) 31748 31749 //to prevent scrolling while zooming 31750 .keyup(keyUpHandler) 31751 31752 //Scrolls to the section when clicking the navigation bullet 31753 .on('click touchstart', SECTION_NAV_SEL + ' a', sectionBulletHandler) 31754 31755 //Scrolls the slider to the given slide destination for the given section 31756 .on('click touchstart', SLIDES_NAV_LINK_SEL, slideBulletHandler) 31757 31758 .on('click', SECTION_NAV_TOOLTIP_SEL, tooltipTextHandler); 31759 31760 //Scrolling horizontally when clicking on the slider controls. 31761 $(SECTION_SEL).on('click touchstart', SLIDES_ARROW_SEL, slideArrowHandler); 31762 31763 /** 31764 * Applying normalScroll elements. 31765 * Ignoring the scrolls over the specified selectors. 31766 */ 31767 if(options.normalScrollElements){ 31768 $document.on('mouseenter', options.normalScrollElements, function () { 31769 setMouseWheelScrolling(false); 31770 }); 31771 31772 $document.on('mouseleave', options.normalScrollElements, function(){ 31773 setMouseWheelScrolling(true); 31774 }); 31775 } 31776 } 31777 31778 /** 31779 * Setting options from DOM elements if they are not provided. 31780 */ 31781 function setOptionsFromDOM(){ 31782 var sections = container.find(options.sectionSelector); 31783 31784 //no anchors option? Checking for them in the DOM attributes 31785 if(!options.anchors.length){ 31786 options.anchors = sections.filter('[data-anchor]').map(function(){ 31787 return $(this).data('anchor').toString(); 31788 }).get(); 31789 } 31790 31791 //no tooltips option? Checking for them in the DOM attributes 31792 if(!options.navigationTooltips.length){ 31793 options.navigationTooltips = sections.filter('[data-tooltip]').map(function(){ 31794 return $(this).data('tooltip').toString(); 31795 }).get(); 31796 } 31797 } 31798 31799 /** 31800 * Works over the DOM structure to set it up for the current fullpage options. 31801 */ 31802 function prepareDom(){ 31803 container.css({ 31804 'height': '100%', 31805 'position': 'relative' 31806 }); 31807 31808 //adding a class to recognize the container internally in the code 31809 container.addClass(WRAPPER); 31810 $('html').addClass(ENABLED); 31811 31812 windowsHeight = $window.height(); 31813 31814 container.removeClass(DESTROYED); //in case it was destroyed before initializing it again 31815 31816 addInternalSelectors(); 31817 31818 //styling the sections / slides / menu 31819 $(SECTION_SEL).each(function(index){ 31820 var section = $(this); 31821 var slides = section.find(SLIDE_SEL); 31822 var numSlides = slides.length; 31823 31824 styleSection(section, index); 31825 styleMenu(section, index); 31826 31827 // if there's any slide 31828 if (numSlides > 0) { 31829 styleSlides(section, slides, numSlides); 31830 }else{ 31831 if(options.verticalCentered){ 31832 addTableClass(section); 31833 } 31834 } 31835 }); 31836 31837 //fixed elements need to be moved out of the plugin container due to problems with CSS3. 31838 if(options.fixedElements && options.css3){ 31839 $(options.fixedElements).appendTo($body); 31840 } 31841 31842 //vertical centered of the navigation + active bullet 31843 if(options.navigation){ 31844 addVerticalNavigation(); 31845 } 31846 31847 enableYoutubeAPI(); 31848 31849 if(options.scrollOverflow){ 31850 if(document.readyState === 'complete'){ 31851 createScrollBarHandler(); 31852 } 31853 //after DOM and images are loaded 31854 $window.on('load', createScrollBarHandler); 31855 }else{ 31856 afterRenderActions(); 31857 } 31858 } 31859 31860 /** 31861 * Styles the horizontal slides for a section. 31862 */ 31863 function styleSlides(section, slides, numSlides){ 31864 var sliderWidth = numSlides * 100; 31865 var slideWidth = 100 / numSlides; 31866 31867 slides.wrapAll('<div class="' + SLIDES_CONTAINER + '" />'); 31868 slides.parent().wrap('<div class="' + SLIDES_WRAPPER + '" />'); 31869 31870 section.find(SLIDES_CONTAINER_SEL).css('width', sliderWidth + '%'); 31871 31872 if(numSlides > 1){ 31873 if(options.controlArrows){ 31874 createSlideArrows(section); 31875 } 31876 31877 if(options.slidesNavigation){ 31878 addSlidesNavigation(section, numSlides); 31879 } 31880 } 31881 31882 slides.each(function(index) { 31883 $(this).css('width', slideWidth + '%'); 31884 31885 if(options.verticalCentered){ 31886 addTableClass($(this)); 31887 } 31888 }); 31889 31890 var startingSlide = section.find(SLIDE_ACTIVE_SEL); 31891 31892 //if the slide won't be an starting point, the default will be the first one 31893 //the active section isn't the first one? Is not the first slide of the first section? Then we load that section/sl
31893ide by default. 31894 if( startingSlide.length && ($(SECTION_ACTIVE_SEL).index(SECTION_SEL) !== 0 || ($(SECTION_ACTIVE_SEL).index(SECTION_SEL) === 0 && startingSlide.index() !== 0))){ 31895 silentLandscapeScroll(startingSlide, 'internal'); 31896 }else{ 31897 slides.eq(0).addClass(ACTIVE); 31898 } 31899 } 31900 31901 /** 31902 * Styling vertical sections 31903 */ 31904 function styleSection(section, index){ 31905 //if no active section is defined, the 1st one will be the default one 31906 if(!index && $(SECTION_ACTIVE_SEL).length === 0) { 31907 section.addClass(ACTIVE); 31908 } 31909 startingSection = $(SECTION_ACTIVE_SEL); 31910 31911 section.css('height', windowsHeight + 'px'); 31912 31913 if(options.paddingTop){ 31914 section.css('padding-top', options.paddingTop); 31915 } 31916 31917 if(options.paddingBottom){ 31918 section.css('padding-bottom', options.paddingBottom); 31919 } 31920 31921 if (typeof options.sectionsColor[index] !== 'undefined') { 31922 section.css('background-color', options.sectionsColor[index]); 31923 } 31924 31925 if (typeof options.anchors[index] !== 'undefined') { 31926 section.attr('data-anchor', options.anchors[index]); 31927 } 31928 } 31929 31930 /** 31931 * Sets the data-anchor attributes to the menu elements and activates the current one. 31932 */ 31933 function styleMenu(section, index){ 31934 if (typeof options.anchors[index] !== 'undefined') { 31935 //activating the menu / nav element on load 31936 if(section.hasClass(ACTIVE)){ 31937 activateMenuAndNav(options.anchors[index], index); 31938 } 31939 } 31940 31941 //moving the menu outside the main container if it is inside (avoid problems with fixed positions when using CSS3 tranforms) 31942 if(options.menu && options.css3 && $(options.menu).closest(WRAPPER_SEL).length){ 31943 $(options.menu).appendTo($body); 31944 } 31945 } 31946 31947 /** 31948 * Adds internal classes to be able to provide customizable selectors 31949 * keeping the link with the style sheet. 31950 */ 31951 function addInternalSelectors(){ 31952 container.find(options.sectionSelector).addClass(SECTION); 31953 container.find(options.slideSelector).addClass(SLIDE); 31954 } 31955 31956 /** 31957 * Creates the control arrows for the given section 31958 */ 31959 function createSlideArrows(section){ 31960 section.find(SLIDES_WRAPPER_SEL).after('<div class="' + SLIDES_ARROW_PREV + '"></div><div class="' + SLIDES_ARROW_NEXT + '"></div>'); 31961 31962 if(options.controlArrowColor!='#fff'){ 31963 section.find(SLIDES_ARROW_NEXT_SEL).css('border-color', 'transparent transparent transparent '+options.controlArrowColor); 31964 section.find(SLIDES_ARROW_PREV_SEL).css('border-color', 'transparent '+ options.controlArrowColor + ' transparent transparent'); 31965 } 31966 31967 if(!options.loopHorizontal){ 31968 section.find(SLIDES_ARROW_PREV_SEL).hide(); 31969 } 31970 } 31971 31972 /** 31973 * Creates a vertical navigation bar. 31974 */ 31975 function addVerticalNavigation(){ 31976 $body.append('<div id="' + SECTION_NAV + '"><ul></ul></div>'); 31977 var nav = $(SECTION_NAV_SEL); 31978 31979 nav.addClass(function() { 31980 return options.showActiveTooltip ? SHOW_ACTIVE_TOOLTIP + ' ' + options.navigationPosition : options.navigationPosition; 31981 }); 31982 31983 for (var i = 0; i < $(SECTION_SEL).length; i++) { 31984 var link = ''; 31985 if (options.anchors.length) { 31986 link = options.anchors[i]; 31987 } 31988 31989 var li = '<li><a href="#' + link + '"><span></span></a>'; 31990 31991 // Only add tooltip if needed (defined by user) 31992 var tooltip = options.navigationTooltips[i]; 31993 31994 if (typeof tooltip !== 'undefined' && tooltip !== '') { 31995 li += '<div class="' + SECTION_NAV_TOOLTIP + ' ' + options.navigationPosition + '">' + tooltip + '</div>'; 31996 } 31997 31998 li += '</li>'; 31999 32000 nav.find('ul').append(li); 32001 } 32002 32003 //centering it vertically 32004 $(SECTION_NAV_SEL).css('margin-top', '-' + ($(SECTION_NAV_SEL).height()/2) + 'px'); 32005 32006 //activating the current active section 32007 $(SECTION_NAV_SEL).find('li').eq($(SECTION_ACTIVE_SEL).index(SECTION_SEL)).find('a').addClass(ACTIVE); 32008 } 32009 32010 /** 32011 * Creates the slim scroll scrollbar for the sections and slides inside them. 32012 */ 32013 function createScrollBarHandler(){ 32014 $(SECTION_SEL).each(function(){ 32015 var slides = $(this).find(SLIDE_SEL); 32016 32017 if(slides.length){ 32018 slides.each(function(){ 32019 createScrollBar($(this)); 32020 }); 32021 }else{ 32022 createScrollBar($(this)); 32023 } 32024 32025 }); 32026 afterRenderActions(); 32027 } 32028 32029 /*
32030 * Enables the Youtube videos API so we can control their flow if necessary. 32031 */ 32032 function enableYoutubeAPI(){ 32033 container.find('iframe[src*="youtube.com/embed/"]').each(function(){ 32034 addURLParam($(this), 'enablejsapi=1'); 32035 }); 32036 } 32037 32038 /** 32039 * Adds a new parameter and its value to the `src` of a given element 32040 */ 32041 function addURLParam(element, newParam){ 32042 var originalSrc = element.attr('src'); 32043 element.attr('src', originalSrc + getUrlParamSign(originalSrc) + newParam); 32044 } 32045 32046 /* 32047 * Returns the prefix sign to use for a new parameter in an existen URL. 32048 * 32049 * @return {String} ? | & 32050 */ 32051 function getUrlParamSign(url){ 32052 return ( !/\?/.test( url ) ) ? '?' : '&'; 32053 } 32054 32055 /** 32056 * Actions and callbacks to fire afterRender 32057 */ 32058 function afterRenderActions(){ 32059 var section = $(SECTION_ACTIVE_SEL); 32060 32061 section.addClass(COMPLETELY); 32062 32063 if(options.scrollOverflowHandler.afterRender){ 32064 options.scrollOverflowHandler.afterRender(section); 32065 } 32066 lazyLoad(section); 32067 playMedia(section); 32068 options.scrollOverflowHandler.afterLoad(); 32069 32070 if(isDestinyTheStartingSection()){ 32071 $.isFunction( options.afterLoad ) && options.afterLoad.call(section, section.data('anchor'), (section.index(SECTION_SEL) + 1)); 32072 } 32073 32074 // Uncode change 32075 // $.isFunction( options.afterRender ) && options.afterRender.call(container); 32076 $.isFunction( options.afterRender ) && options.afterRender.call(container, getTableHeight()); 32077 } 32078 32079 /** 32080 * Determines if the URL anchor destiny is the starting section (the one using 'active' class before initialization) 32081 */ 32082 function isDestinyTheStartingSection(){ 32083 var anchors = window.location.hash.replace('#', '').split('/'); 32084 var destinationSection = getSectionByAnchor(decodeURIComponent(anchors[0])); 32085 32086 return !destinationSection.length || destinationSection.length && destinationSection.index() === startingSection.index(); 32087 } 32088 32089 32090 var isScrolling = false; 32091 var lastScroll = 0; 32092 32093 //when scrolling... 32094 function scrollHandler(){ 32095 var currentSection; 32096 32097 if(!options.autoScrolling || options.scrollBar){ 32098 var currentScroll = $window.scrollTop(); 32099 var scrollDirection = getScrollDirection(currentScroll); 32100 var visibleSectionIndex = 0; 32101 var screen_mid = currentScroll + ($window.height() / 2.0); 32102 var isAtBottom = $body.height() - $window.height() === currentScroll; 32103 var sections = document.querySelectorAll(SECTION_SEL); 32104 32105 //when using `auto-height` for a small last section it won't be centered in the viewport 32106 if(isAtBottom){ 32107 visibleSectionIndex = sections.length - 1; 32108 } 32109 //is at top? when using `auto-height` for a small first section it won't be centered in the viewport 32110 else if(!currentScroll){ 32111 visibleSectionIndex = 0; 32112 } 32113 32114 //taking the section which is showing more content in the viewport 32115 else{ 32116 for (var i = 0; i < sections.length; ++i) { 32117 var section = sections[i]; 32118 32119 // Pick the the last section which passes the middle line of the screen. 32120 if (section.offsetTop <= screen_mid) 32121 { 32122 visibleSectionIndex = i; 32123 } 32124 } 32125 } 32126 32127 if(isCompletelyInViewPort(scrollDirection)){ 32128 if(!$(SECTION_ACTIVE_SEL).hasClass(COMPLETELY)){ 32129 $(SECTION_ACTIVE_SEL).addClass(COMPLETELY).siblings().removeClass(COMPLETELY); 32130 } 32131 } 32132 32133 //geting the last one, the current one on the screen 32134 currentSection = $(sections).eq(visibleSectionIndex); 32135 32136 //setting the visible section as active when manually scrolling 32137 //executing only once the first time we reach the section 32138 if(!currentSection.hasClass(ACTIVE)){ 32139 isScrolling = true; 32140 var leavingSection = $(SECTION_ACTIVE_SEL); 32141 var leavingSectionIndex = leavingSection.index(SECTION_SEL) + 1; 32142 var yMovement = getYmovement(currentSection); 32143 var anchorLink = currentSection.data('anchor'); 32144 var sectionIndex = currentSection.index(SECTION_SEL) + 1; 32145 var activeSlide = currentSection.find(SLIDE_ACTIVE_SEL); 32146 var slideIndex; 32147 var slideAnchorLink; 32148 32149 if(activeSlide.length){ 32150 slideAnchorLink = activeSlide.data('anchor'); 32151 slideIndex = activeSlide.index(); 32152 } 32153 32154 if(canScroll){ 32155 currentSection.addClass(ACTIVE).siblings().removeClass(ACTIVE); 32156 32157 $.isFunction( options.onLeave ) && options.onLeave.call( leavingSection, leavingSectionIndex, sectionIndex, yMovement); 32158 $.isFunction( options.afterLoad ) && options.afterLoad.call( currentSection, anchorLink, sectionIndex); 32159 32160 stopMedia(leavingSection); 32161 lazyLoad(currentSection); 32162 playMedia(currentSection); 32163 32164 activateMenuAndNav(anchorLink, sectionIndex - 1); 32165 32166 if(options.anchors.length){ 32167 //needed to enter in hashChange event when using the menu with anchor links 32168 lastScrolledDestiny = anchorLink; 32169 } 32170 setState(slideIndex, slideAnchorLink, anchorLink, sectionIndex); 32171 } 32172 32173 //small timeout in order to avoid entering in hashChange event when scrolling is not finished yet 32174 clearTimeout(scrollId); 32175 scrollId = setTimeout(function(){ 32176 isScrolling = false;
32177 }, 100); 32178 } 32179 32180 if(options.fitToSection){ 32181 //for the auto adjust of the viewport to fit a whole section 32182 clearTimeout(scrollId2); 32183 32184 scrollId2 = setTimeout(function(){ 32185 //checking it again in case it changed during the delay 32186 if(options.fitToSection){ 32187 fitToSection(); 32188 } 32189 }, options.fitToSectionDelay); 32190 } 32191 } 32192 } 32193 32194 /** 32195 * Fits the site to the nearest active section 32196 */ 32197 function fitToSection(){ 32198 //checking fitToSection again in case it was set to false before the timeout delay 32199 if(canScroll){ 32200 //allows to scroll to an active section and 32201 //if the section is already active, we prevent firing callbacks 32202 isResizing = true; 32203 32204 scrollPage($(SECTION_ACTIVE_SEL)); 32205 isResizing = false; 32206 } 32207 } 32208 32209 /** 32210 * Determines whether the active section has seen in its whole or not. 32211 */ 32212 function isCompletelyInViewPort(movement){ 32213 var top = $(SECTION_ACTIVE_SEL).position().top; 32214 var bottom = top + $window.height(); 32215 32216 if(movement == 'up'){ 32217 return bottom >= ($window.scrollTop() + $window.height()); 32218 } 32219 return top <= $window.scrollTop(); 32220 } 32221 32222 /** 32223 * Gets the directon of the the scrolling fired by the scroll event. 32224 */ 32225 function getScrollDirection(currentScroll){ 32226 var direction = currentScroll > lastScroll ? 'down' : 'up'; 32227 32228 lastScroll = currentScroll; 32229 32230 //needed for auto-height sections to determine if we want to scroll to the top or bottom of the destination 32231 previousDestTop = currentScroll; 32232 32233 return direction; 32234 } 32235 32236 /** 32237 * Determines the way of scrolling up or down: 32238 * by 'automatically' scrolling a section or by using the default and normal scrolling. 32239 */ 32240 function scrolling(type, scrollable){ 32241 if (!isScrollAllowed.m[type]){ 32242 return; 32243 } 32244 var check = (type === 'down') ? 'bottom' : 'top'; 32245 var scrollSection = (type === 'down') ? moveSectionDown : moveSectionUp; 32246 32247 if(scrollable.length > 0 ){ 32248 //is the scrollbar at the start/end of the scroll? 32249 if(options.scrollOverflowHandler.isScrolled(check, scrollable)){ 32250 scrollSection(); 32251 }else{ 32252 return true; 32253 } 32254 }else{ 32255 // moved up/down 32256 scrollSection(); 32257 } 32258 } 32259 32260 /* 32261 * Preventing bouncing in iOS #2285 32262 */ 32263 function preventBouncing(event){ 32264 var e = event.originalEvent; 32265 if(!checkParentForNormalScrollElement(event.target) && options.autoScrolling && isReallyTouch(e) && isScrollAllowed.m.up){ 32266 //preventing the easing on iOS devices 32267 event.preventDefault(); 32268 } 32269 } 32270 32271 var touchStartY = 0; 32272 var touchStartX = 0; 32273 var touchEndY = 0; 32274 var touchEndX = 0; 32275 32276 /* Detecting touch events 32277 32278 * As we are changing the top property of the page on scrolling, we can not use the traditional way to detect it. 32279 * This way, the touchstart and the touch moves shows an small difference between them which is the 32280 * used one to determine the direction. 32281 */ 32282 function touchMoveHandler(event){ 32283 var e = event.originalEvent; 32284 var activeSection = $(e.target).closest(SECTION_SEL); 32285 32286 // additional: if one of the normalScrollElements isn't within options.normalScrollElementTouchThreshold hops up the DOM chain 32287 if (!checkParentForNormalScrollElement(event.target) && isReallyTouch(e) ) { 32288 32289 if(options.autoScrolling){ 32290 //preventing the easing on iOS devices 32291 event.preventDefault(); 32292 } 32293 32294 var scrollable = options.scrollOverflowHandler.scrollable(activeSection); 32295 var touchEvents = getEventsPage(e); 32296 32297 touchEndY = touchEvents.y; 32298 touchEndX = touchEvents.x; 32299 32300 //if movement in the X axys is greater than in the Y and the currect section has slides... 32301 if (activeSection.find(SLIDES_WRAPPER_SEL).length && Math.abs(touchStartX - touchEndX) > (Math.abs(touchStartY - touchEndY))) { 32302 32303 //is the movement greater than the minimum resistance to scroll? 32304 if (!slideMoving && Math.abs(touchStartX - touchEndX) > ($window.outerWidth() / 100 * options.touchSensitivity)) { 32305 if (touchStartX > touchEndX) { 32306 if(isScrollAllowed.m.right){ 32307 moveSlideRight(activeSection); //next 32308 } 32309 } else { 32310 if(isScrollAllowed.m.left){ 32311 moveSlideLeft(activeSection); //prev 32312 } 32313 } 32314 } 32315 } 32316 32317 //vertical scrolling (only when autoScrolling is enabled) 32318 else if(options.autoScrolling && canScroll){ 32319 32320 //is the movement greater than the minimum resistance to scroll? 32321 if (Math.abs(touchStartY - touchEndY) > ($window.height() / 100 * options.touchSensitivity)) { 32322 if (touchStartY > touchEndY) { 32323 scrolling('down', scrollable); 32324 } else if (touchEndY > touchStartY) { 32325 scrolling('up', scrollable); 32326 } 32327 } 32328 } 32329 } 32330 } 32331 32332 /** 32333 * recursive function to loop up the parent nodes to check if one of them exists in options.normalScrollElements 32334 * Currently works well for iOS - Android might need some testing 32335 * @param {Element} el target element / jquery selector (in subsequent nodes) 32336 * @param {int} hop current hop compared to options.normalScrollElementTouchThreshold 32337 * @return {boolean} true if there is a match to options.normalScrollElements 32338 */ 32339 function checkParentForNormalScrollElement (el, hop) { 32340 hop = hop || 0; 32341 var parent = $(el).parent(); 32342 32343 if (hop < options.normalScrollElementTouchThreshold && 32344 parent.is(options.normalScrollElements) ) { 32345 return true; 32346 } else if (hop == options.normalScrollElementTouchThreshold) { 32347 return false;
32348 } else { 32349 return checkParentForNormalScrollElement(parent, ++hop); 32350 } 32351 } 32352 32353 /** 32354 * As IE >= 10 fires both touch and mouse events when using a mouse in a touchscreen 32355 * this way we make sure that is really a touch event what IE is detecting. 32356 */ 32357 function isReallyTouch(e){ 32358 //if is not IE || IE is detecting `touch` or `pen` 32359 return typeof e.pointerType === 'undefined' || e.pointerType != 'mouse'; 32360 } 32361 32362 /** 32363 * Handler for the touch start event. 32364 */ 32365 function touchStartHandler(event){ 32366 var e = event.originalEvent; 32367 32368 //stopping the auto scroll to adjust to a section 32369 if(options.fitToSection){ 32370 $htmlBody.stop(); 32371 } 32372 32373 if(isReallyTouch(e)){ 32374 var touchEvents = getEventsPage(e); 32375 touchStartY = touchEvents.y; 32376 touchStartX = touchEvents.x; 32377 } 32378 } 32379 32380 /** 32381 * Gets the average of the last `number` elements of the given array. 32382 */ 32383 function getAverage(elements, number){ 32384 var sum = 0; 32385 32386 //taking `number` elements from the end to make the average, if there are not enought, 1 32387 var lastElements = elements.slice(Math.max(elements.length - number, 1)); 32388 32389 for(var i = 0; i < lastElements.length; i++){ 32390 sum = sum + lastElements[i]; 32391 } 32392 32393 return Math.ceil(sum/number); 32394 } 32395 32396 /** 32397 * Detecting mousewheel scrolling 32398 * 32399 * http://blogs.sitepointstatic.com/examples/tech/mouse-wheel/index.html 32400 * http://www.sitepoint.com/html5-javascript-mouse-wheel/ 32401 */ 32402 var prevTime = new Date().getTime(); 32403 32404 function MouseWheelHandler(e) { 32405 var curTime = new Date().getTime(); 32406 var isNormalScroll = $(COMPLETELY_SEL).hasClass(NORMAL_SCROLL); 32407 32408 //autoscrolling and not zooming? 32409 if(options.autoScrolling && !controlPressed && !isNormalScroll){ 32410 // cross-browser wheel delta 32411 e = e || window.event; 32412 var value = e.wheelDelta || -e.deltaY || -e.detail; 32413 var delta = Math.max(-1, Math.min(1, value)); 32414 32415 var horizontalDetection = typeof e.wheelDeltaX !== 'undefined' || typeof e.deltaX !== 'undefined'; 32416 var isScrollingVertically = (Math.abs(e.wheelDeltaX) < Math.abs(e.wheelDelta)) || (Math.abs(e.deltaX ) < Math.abs(e.deltaY) || !horizontalDetection); 32417 32418 //Limiting the array to 150 (lets not waste memory!) 32419 if(scrollings.length > 149){ 32420 scrollings.shift(); 32421 } 32422 32423 //keeping record of the previous scrollings 32424 scrollings.push(Math.abs(value)); 32425 32426 //preventing to scroll the site on mouse wheel when scrollbar is present 32427 if(options.scrollBar){ 32428 e.preventDefault ? e.preventDefault() : e.returnValue = false; 32429 } 32430 32431 var activeSection = $(SECTION_ACTIVE_SEL); 32432 var scrollable = options.scrollOverflowHandler.scrollable(activeSection); 32433 32434 //time difference between the last scroll and the current one 32435 var timeDiff = curTime-prevTime; 32436 prevTime = curTime; 32437 32438 //haven't they scrolled in a while? 32439 //(enough to be consider a different scrolling action to scroll another section) 32440 if(timeDiff > 200){ 32441 //emptying the array, we dont care about old scrollings for our averages 32442 scrollings = []; 32443 } 32444 32445 if(canScroll){ 32446 var averageEnd = getAverage(scrollings, 10); 32447 var averageMiddle = getAverage(scrollings, 70); 32448 var isAccelerating = averageEnd >= averageMiddle; 32449 32450 //to avoid double swipes... 32451 if(isAccelerating && isScrollingVertically){ 32452 //scrolling down? 32453 if (delta < 0) { 32454 scrolling('down', scrollable); 32455 32456 //scrolling up? 32457 }else { 32458 scrolling('up', scrollable); 32459 } 32460 } 32461 } 32462 32463 return false;
32464 } 32465 32466 if(options.fitToSection){ 32467 //stopping the auto scroll to adjust to a section 32468 $htmlBody.stop(); 32469 } 32470 } 32471 32472 /** 32473 * Slides a slider to the given direction. 32474 * Optional `section` param. 32475 */ 32476 function moveSlide(direction, section){ 32477 var activeSection = typeof section === 'undefined' ? $(SECTION_ACTIVE_SEL) : section; 32478 var slides = activeSection.find(SLIDES_WRAPPER_SEL); 32479 var numSlides = slides.find(SLIDE_SEL).length; 32480 32481 // more than one slide needed and nothing should be sliding 32482 if (!slides.length || slideMoving || numSlides < 2) { 32483 return; 32484 } 32485 32486 var currentSlide = slides.find(SLIDE_ACTIVE_SEL); 32487 var destiny = null; 32488 32489 if(direction === 'left'){ 32490 destiny = currentSlide.prev(SLIDE_SEL); 32491 }else{ 32492 destiny = currentSlide.next(SLIDE_SEL); 32493 } 32494 32495 //isn't there a next slide in the secuence? 32496 if(!destiny.length){ 32497 //respect loopHorizontal settin 32498 if (!options.loopHorizontal) return; 32499 32500 if(direction === 'left'){ 32501 destiny = currentSlide.siblings(':last'); 32502 }else{ 32503 destiny = currentSlide.siblings(':first'); 32504 } 32505 } 32506 32507 slideMoving = true; 32508 32509 landscapeScroll(slides, destiny, direction); 32510 } 32511 32512 /** 32513 * Maintains the active slides in the viewport 32514 * (Because the `scroll` animation might get lost with some actions, such as when using continuousVertical) 32515 */ 32516 function keepSlidesPosition(){ 32517 $(SLIDE_ACTIVE_SEL).each(function(){ 32518 silentLandscapeScroll($(this), 'internal'); 32519 }); 32520 } 32521 32522 var previousDestTop = 0; 32523 /** 32524 * Returns the destination Y position based on the scrolling direction and 32525 * the height of the section. 32526 */ 32527 function getDestinationPosition(element){ 32528 var elemPosition = element.position(); 32529 32530 //top of the desination will be at the top of the viewport 32531 var position = elemPosition.top; 32532 var isScrollingDown = elemPosition.top > previousDestTop; 32533 var sectionBottom = position - windowsHeight + element.outerHeight(); 32534 var bigSectionsDestination = options.bigSectionsDestination; 32535 32536 //Uncode addition 32537 var containerH = container.outerHeight(); 32538 var containerPosition = container.offset(); 32539 32540 //########### Commented by Uncode - START ########### 32541 //is the destination element bigger than the viewport? 32542 // if(element.outerHeight() > windowsHeight){ 32543 // //scrolling up? 32544 // if(!isScrollingDown && !bigSectionsDestination || bigSectionsDestination === 'bottom' ){ 32545 // position = sectionBottom; 32546 // } 32547 // } 32548 32549 // //sections equal or smaller than the viewport height && scrolling down? || is resizing and its in the last section 32550 // else if(isScrollingDown || (isResizing && element.is(':last-child')) ){ 32551 // //The bottom of the destination will be at the bottom of the viewport 32552 // position = sectionBottom; 32553 // } 32554 //########### Commented by Uncode - END ########### 32555 32556 //Uncode addition 32557 if ( !$masthead.hasClass('menu-transparent') && $('body').hasClass('uncode-fp-menu-shrink') && !element.is(':first-child') ) 32558 position += 18; 32559 if ( ( containerH + menuHeight + bodyBorder + adminBarHeight - windowsHeight ) < position || ( isResizing && element.is(':last-child') ) ) { 32560 position = sectionBottom + menuHeight + bodyBorder*2 + adminBarHeight; 32561 } 32562 32563 /* 32564 Keeping record of the last scrolled position to determine the scrolling direction. 32565 No conventional methods can be used as the scroll bar might not be present 32566 AND the section might not be active if it is auto-height and didnt reach the middle 32567 of the viewport. 32568 */ 32569 previousDestTop = position; 32570 return position; 32571 } 32572 32573 /** 32574 * Scrolls the site to the given element and scrolls to the slide if a callback is given. 32575 */ 32576 function scrollPage(element, callback, isMovementUp){ 32577 if(typeof element === 'undefined'){ return; } //there's no element to scroll, leaving the function 32578 32579 var dtop = getDestinationPosition(element); 32580 var slideAnchorLink; 32581 var slideIndex; 32582 32583 //local variables 32584 var v = { 32585 element: element, 32586 callback: callback, 32587 isMovementUp: isMovementUp, 32588 dtop: dtop, 32589 yMovement: getYmovement(element), 32590 anchorLink: element.data('anchor'), 32591 sectionIndex: element.index(SECTION_SEL), 32592 activeSlide: element.find(SLIDE_ACTIVE_SEL), 32593 activeSection: $(SECTION_ACTIVE_SEL), 32594 leavingSection: $(SECTION_ACTIVE_SEL).index(SECTION_SEL) + 1, 32595 32596 //caching the value of isResizing at the momment the function is called 32597 //because it will be checked later inside a setTimeout and the value might change 32598 localIsResizing: isResizing 32599 }; 32600 32601 //quiting when destination scroll is the same as the current one 32602 if((v.activeSection.is(element) && !isResizing) || (options.scrollBar && $window.scrollTop() === v.dtop && !element.hasClass(AUTO_HEIGHT) )){ return; } 32603 32604 if(v.activeSlide.length){ 32605 slideAnchorLink = v.activeSlide.data('anchor'); 32606 slideIndex = v.activeSlide.index(); 32607 } 32608 32609 // If continuousVertical && we need to wrap around 32610 if (options.autoScrolling && options.continuousVertical && typeof (v.isMovementUp) !== "undefined" && 32611 ((!v.isMovementUp && v.yMovement == 'up') || // Intending to scroll down but about to go up or 32612 (v.isMovementUp && v.yMovement == 'down'))) { // intending to scroll up but about to go down 32613 32614 v = createInfiniteSections(v); 32615 } 32616 32617 //callback (onLeave) if the site is not just resizing and readjusting the slides 32618 if($.isFunction(options.onLeave) && !v.localIsResizing){ 32619 if(options.onLeave.call(v.activeSection, v.leavingSection, (v.sectionIndex + 1), v.yMovement) === false){ 32620 return; 32621 } 32622 } 32623 32624 //pausing media of the leaving section (if we are not just resizing, as destinatino will be the same one) 32625 if(!v.localIsResizing){ 32626 stopMedia(v.activeSection); 32627 } 32628 32629 options.scrollOverflowHandler.beforeLeave(); 32630 element.addClass(ACTIVE).siblings().removeClass(ACTIVE); 32631 lazyLoad(element); 32632 options.scrollOverflowHandler.onLeave(); 32633 32634 32635 //preventing from activating the MouseWheelHandler event 32636 //more than once if the page is scrolling 32637 canScroll = false;
32638 32639 setState(slideIndex, slideAnchorLink, v.anchorLink, v.sectionIndex); 32640 32641 performMovement(v); 32642 32643 //flag to avoid callingn `scrollPage()` twice in case of using anchor links 32644 lastScrolledDestiny = v.anchorLink; 32645 32646 //avoid firing it twice (as it does also on scroll) 32647 activateMenuAndNav(v.anchorLink, v.sectionIndex); 32648 } 32649 32650 /** 32651 * Performs the vertical movement (by CSS3 or by jQuery) 32652 */ 32653 function performMovement(v){ 32654 // using CSS3 translate functionality 32655 if (options.css3 && options.autoScrolling && !options.scrollBar) { 32656 32657 // The first section can have a negative value in iOS 10. Not quite sure why: -0.0142822265625 32658 // that's why we round it to 0. 32659 var translate3d = 'translate3d(0px, -' + Math.round(v.dtop) + 'px, 0px)'; 32660 transformContainer(translate3d, true); 32661 32662 //even when the scrollingSpeed is 0 there's a little delay, which might cause the 32663 //scrollingSpeed to change in case of using silentMoveTo(); 32664 if(options.scrollingSpeed){ 32665 clearTimeout(afterSectionLoadsId); 32666 afterSectionLoadsId = setTimeout(function () { 32667 afterSectionLoads(v); 32668 }, options.scrollingSpeed); 32669 }else{ 32670 afterSectionLoads(v); 32671 } 32672 } 32673 32674 // using jQuery animate 32675 else{ 32676 var scrollSettings = getScrollSettings(v); 32677 32678 $(scrollSettings.element).animate( 32679 scrollSettings.options, 32680 options.scrollingSpeed, options.easing).promise().done(function () { //only one single callback in case of animating `html, body` 32681 if(options.scrollBar){ 32682 32683 /* Hack! 32684 The timeout prevents setting the most dominant section in the viewport as "active" when the user 32685 scrolled to a smaller section by using the mousewheel (auto scrolling) rather than draging the scroll bar. 32686 32687 When using scrollBar:true It seems like the scroll events still getting propagated even after the scrolling animation has finished. 32688 */ 32689 setTimeout(function(){ 32690 afterSectionLoads(v); 32691 },30); 32692 }else{ 32693 afterSectionLoads(v); 32694 } 32695 }); 32696 } 32697 } 32698 32699 /** 32700 * Gets the scrolling settings depending on the plugin autoScrolling option 32701 */ 32702 function getScrollSettings(v){ 32703 var scroll = {}; 32704 32705 if(options.autoScrolling && !options.scrollBar){ 32706 scroll.options = { 'top': -v.dtop}; 32707 scroll.element = WRAPPER_SEL; 32708 }else{ 32709 scroll.options = { 'scrollTop': v.dtop}; 32710 scroll.element = 'html, body'; 32711 } 32712 32713 return scroll; 32714 } 32715 32716 /** 32717 * Adds sections before or after the current one to create the infinite effect. 32718 */ 32719 function createInfiniteSections(v){ 32720 // Scrolling down 32721 if (!v.isMovementUp) { 32722 // Move all previous sections to after the active section 32723 $(SECTION_ACTIVE_SEL).after(v.activeSection.prevAll(SECTION_SEL).get().reverse()); 32724 } 32725 else { // Scrolling up 32726 // Move all next sections to before the active section 32727 $(SECTION_ACTIVE_SEL).before(v.activeSection.nextAll(SECTION_SEL)); 32728 } 32729 32730 // Maintain the displayed position (now that we changed the element order) 32731 silentScroll($(SECTION_ACTIVE_SEL).position().top); 32732 32733 // Maintain the active slides visible in the viewport 32734 keepSlidesPosition(); 32735 32736 // save for later the elements that still need to be reordered 32737 v.wrapAroundElements = v.activeSection; 32738 32739 // Recalculate animation variables 32740 v.dtop = v.element.position().top; 32741 v.yMovement = getYmovement(v.element); 32742 32743 return v; 32744 } 32745 32746 /** 32747 * Fix section order after continuousVertical changes have been animated 32748 */ 32749 function continuousVerticalFixSectionOrder (v) {
32750 // If continuousVertical is in effect (and autoScrolling would also be in effect then), 32751 // finish moving the elements around so the direct navigation will function more simply 32752 if (!v.wrapAroundElements || !v.wrapAroundElements.length) { 32753 return; 32754 } 32755 32756 if (v.isMovementUp) { 32757 $(SECTION_FIRST_SEL).before(v.wrapAroundElements); 32758 } 32759 else { 32760 $(SECTION_LAST_SEL).after(v.wrapAroundElements); 32761 } 32762 32763 silentScroll($(SECTION_ACTIVE_SEL).position().top); 32764 32765 // Maintain the active slides visible in the viewport 32766 keepSlidesPosition(); 32767 } 32768 32769 32770 /** 32771 * Actions to do once the section is loaded. 32772 */ 32773 function afterSectionLoads (v){ 32774 continuousVerticalFixSectionOrder(v); 32775 32776 //callback (afterLoad) if the site is not just resizing and readjusting the slides 32777 $.isFunction(options.afterLoad) && !v.localIsResizing && options.afterLoad.call(v.element, v.anchorLink, (v.sectionIndex + 1)); 32778 options.scrollOverflowHandler.afterLoad(); 32779 32780 if(!v.localIsResizing){ 32781 playMedia(v.element); 32782 } 32783 32784 v.element.addClass(COMPLETELY).siblings().removeClass(COMPLETELY); 32785 32786 canScroll = true; 32787 32788 $.isFunction(v.callback) && v.callback.call(this); 32789 } 32790 32791 /** 32792 * Sets the value for the given attribute from the `data-` attribute with the same suffix 32793 * ie: data-srcset ==> srcset | data-src ==> src 32794 */ 32795 function setSrc(element, attribute){ 32796 element 32797 .attr(attribute, element.data(attribute)) 32798 .removeAttr('data-' + attribute); 32799 } 32800 32801 /** 32802 * Lazy loads image, video and audio elements. 32803 */ 32804 function lazyLoad(destiny){ 32805 if (!options.lazyLoading){ 32806 return; 32807 } 32808 32809 var panel = getSlideOrSection(destiny); 32810 var element; 32811 32812 panel.find('img[data-src], img[data-srcset], source[data-src], audio[data-src], iframe[data-src]').each(function(){ 32813 element = $(this); 32814 32815 $.each(['src', 'srcset'], function(index, type){ 32816 var attribute = element.attr('data-' + type); 32817 if(typeof attribute !== 'undefined' && attribute){ 32818 setSrc(element, type); 32819 } 32820 }); 32821 32822 if(element.is('source')){ 32823 element.closest('video').get(0).load(); 32824 } 32825 }); 32826 } 32827 32828 /** 32829 * Plays video and audio elements. 32830 */ 32831 function playMedia(destiny){ 32832 var panel = getSlideOrSection(destiny); 32833 32834 //playing HTML5 media elements 32835 panel.find('video, audio').each(function(){ 32836 var element = $(this).get(0); 32837 32838 if( element.hasAttribute('data-autoplay') && typeof element.play === 'function' ) { 32839 element.play(); 32840 } 32841 }); 32842 32843 //youtube videos 32844 panel.find('iframe[src*="youtube.com/embed/"]').each(function(){ 32845 var element = $(this).get(0); 32846 32847 if ( element.hasAttribute('data-autoplay') ){ 32848 playYoutube(element); 32849 } 32850 32851 //in case the URL was not loaded yet. On page load we need time for the new URL (with the API string) to load. 32852 element.onload = function() { 32853 if ( element.hasAttribute('data-autoplay') ){ 32854 playYoutube(element); 32855 } 32856 }; 32857 }); 32858 } 32859 32860 /** 32861 * Plays a youtube video 32862 */ 32863 function playYoutube(element){ 32864 element.contentWindow.postMessage('{"event":"command","func":"playVideo","args":""}', '*'); 32865 } 32866 32867 /** 32868 * Stops video and audio elements. 32869 */ 32870 function stopMedia(destiny){ 32871 var panel = getSlideOrSection(destiny); 32872 32873 //stopping HTML5 media elements 32874 panel.find('video, audio').each(function(){ 32875 var element = $(this).get(0); 32876 32877 if( !element.hasAttribute('data-keepplaying') && typeof element.pause === 'function' ) { 32878 element.pause(); 32879 } 32880 }); 32881 32882 //youtube videos 32883 panel.find('iframe[src*="youtube.com/embed/"]').each(function(){ 32884 var element = $(this).get(0); 32885 32886 if( /youtube\.com\/embed\//.test($(this).attr('src')) && !element.hasAttribute('data-keepplaying')){ 32887 $(this).get(0).contentWindow.postMessage('{"event":"command","func":"pauseVideo","args":""}','*'); 32888 } 32889 }); 32890 } 32891 32892 /** 32893 * Gets the active slide (or section) for the given section 32894 */ 32895 function getSlideOrSection(destiny){ 32896 var slide = destiny.find(SLIDE_ACTIVE_SEL); 32897 if( slide.length ) { 32898 destiny = $(slide); 32899 } 32900 32901 return destiny; 32902 } 32903 32904 /**
32905 * Scrolls to the anchor in the URL when loading the site 32906 */ 32907 function scrollToAnchor(){ 32908 //getting the anchor link in the URL and deleting the `#` 32909 var value = window.location.hash.replace('#', '').split('/'); 32910 var sectionAnchor = decodeURIComponent(value[0]); 32911 var slideAnchor = decodeURIComponent(value[1]); 32912 32913 if(sectionAnchor){ //if theres any # 32914 if(options.animateAnchor){ 32915 scrollPageAndSlide(sectionAnchor, slideAnchor); 32916 }else{ 32917 silentMoveTo(sectionAnchor, slideAnchor); 32918 } 32919 } 32920 } 32921 32922 /** 32923 * Detecting any change on the URL to scroll to the given anchor link 32924 * (a way to detect back history button as we play with the hashes on the URL) 32925 */ 32926 function hashChangeHandler(){ 32927 if(!isScrolling && !options.lockAnchors){ 32928 var value = window.location.hash.replace('#', '').split('/'); 32929 var sectionAnchor = decodeURIComponent(value[0]); 32930 var slideAnchor = decodeURIComponent(value[1]); 32931 32932 //when moving to a slide in the first section for the first time (first time to add an anchor to the URL) 32933 var isFirstSlideMove = (typeof lastScrolledDestiny === 'undefined'); 32934 var isFirstScrollMove = (typeof lastScrolledDestiny === 'undefined' && typeof slideAnchor === 'undefined' && !slideMoving); 32935 32936 32937 if(sectionAnchor.length){ 32938 /*in order to call scrollpage() only once for each destination at a time 32939 It is called twice for each scroll otherwise, as in case of using anchorlinks `hashChange` 32940 event is fired on every scroll too.*/ 32941 if ((sectionAnchor && sectionAnchor !== lastScrolledDestiny) && !isFirstSlideMove || isFirstScrollMove || (!slideMoving && lastScrolledSlide != slideAnchor )) { 32942 scrollPageAndSlide(sectionAnchor, slideAnchor); 32943 } 32944 } 32945 } 32946 } 32947 32948 //Sliding with arrow keys, both, vertical and horizontal 32949 function keydownHandler(e) { 32950 32951 clearTimeout(keydownId); 32952 32953 var activeElement = $(':focus'); 32954 32955 if(!activeElement.is('textarea') && !activeElement.is('input') && !activeElement.is('select') && 32956 activeElement.attr('contentEditable') !== "true" && activeElement.attr('contentEditable') !== '' && 32957 options.keyboardScrolling && options.autoScrolling){ 32958 var keyCode = e.which; 32959 32960 //preventing the scroll with arrow keys & spacebar & Page Up & Down keys 32961 var keyControls = [40, 38, 32, 33, 34]; 32962 if($.inArray(keyCode, keyControls) > -1){ 32963 e.preventDefault(); 32964 } 32965 32966 controlPressed = e.ctrlKey; 32967 32968 keydownId = setTimeout(function(){ 32969 onkeydown(e); 32970 },150); 32971 } 32972 } 32973 32974 function tooltipTextHandler(){ 32975 $(this).prev().trigger('click'); 32976 } 32977 32978 //to prevent scrolling while zooming 32979 function keyUpHandler(e){ 32980 if(isWindowFocused){ //the keyup gets fired on new tab ctrl + t in Firefox 32981 controlPressed = e.ctrlKey; 32982 } 32983 } 32984 32985 //binding the mousemove when the mouse's middle button is released 32986 function mouseDownHandler(e){ 32987 //middle button 32988 if (e.which == 2){ 32989 oldPageY = e.pageY; 32990 container.on('mousemove', mouseMoveHandler); 32991 } 32992 } 32993 32994 //unbinding the mousemove when the mouse's middle button is released 32995 function mouseUpHandler(e){ 32996 //middle button 32997 if (e.which == 2){ 32998 container.off('mousemove'); 32999 } 33000 } 33001 33002 //Scrolling horizontally when clicking on the slider controls. 33003 function slideArrowHandler(){ 33004 var section = $(this).closest(SECTION_SEL); 33005 33006 if ($(this).hasClass(SLIDES_PREV)) { 33007 if(isScrollAllowed.m.left){ 33008 moveSlideLeft(section); 33009 } 33010 } else { 33011 if(isScrollAllowed.m.right){ 33012 moveSlideRight(section); 33013 } 33014 } 33015 } 33016 33017 //when opening a new tab (ctrl + t), `control` won't be pressed when coming back. 33018 function blurHandler(){ 33019 isWindowFocused = false;
33020 controlPressed = false; 33021 } 33022 33023 //Scrolls to the section when clicking the navigation bullet 33024 function sectionBulletHandler(e){ 33025 e.preventDefault(); 33026 var index = $(this).parent().index(); 33027 scrollPage($(SECTION_SEL).eq(index)); 33028 } 33029 33030 //Scrolls the slider to the given slide destination for the given section 33031 function slideBulletHandler(e){ 33032 e.preventDefault(); 33033 var slides = $(this).closest(SECTION_SEL).find(SLIDES_WRAPPER_SEL); 33034 var destiny = slides.find(SLIDE_SEL).eq($(this).closest('li').index()); 33035 33036 landscapeScroll(slides, destiny); 33037 } 33038 33039 /** 33040 * Keydown event 33041 */ 33042 function onkeydown(e){ 33043 var shiftPressed = e.shiftKey; 33044 33045 //do nothing if we can not scroll or we are not using horizotnal key arrows. 33046 if(!canScroll && [37,39].indexOf(e.which) < 0){ 33047 return; 33048 } 33049 33050 switch (e.which) { 33051 //up 33052 case 38: 33053 case 33: 33054 if(isScrollAllowed.k.up){ 33055 moveSectionUp(); 33056 } 33057 break; 33058 33059 //down 33060 case 32: //spacebar 33061 if(shiftPressed && isScrollAllowed.k.up){ 33062 moveSectionUp(); 33063 break; 33064 } 33065 /* falls through */ 33066 case 40: 33067 case 34: 33068 if(isScrollAllowed.k.down){ 33069 moveSectionDown(); 33070 } 33071 break; 33072 33073 //Home 33074 case 36: 33075 if(isScrollAllowed.k.up){ 33076 moveTo(1); 33077 } 33078 break; 33079 33080 //End 33081 case 35: 33082 if(isScrollAllowed.k.down){ 33083 moveTo( $(SECTION_SEL).length ); 33084 } 33085 break; 33086 33087 //left 33088 case 37: 33089 if(isScrollAllowed.k.left){ 33090 moveSlideLeft(); 33091 } 33092 break; 33093 33094 //right 33095 case 39: 33096 if(isScrollAllowed.k.right){ 33097 moveSlideRight(); 33098 } 33099 break; 33100 33101 default: 33102 return; // exit this handler for other keys 33103 } 33104 } 33105 33106 /** 33107 * Detecting the direction of the mouse movement. 33108 * Used only for the middle button of the mouse. 33109 */ 33110 var oldPageY = 0; 33111 function mouseMoveHandler(e){ 33112 if(canScroll){ 33113 // moving up 33114 if (e.pageY < oldPageY && isScrollAllowed.m.up){ 33115 moveSectionUp(); 33116 } 33117 33118 // moving down 33119 else if(e.pageY > oldPageY && isScrollAllowed.m.down){ 33120 moveSectionDown(); 33121 } 33122 } 33123 oldPageY = e.pageY; 33124 } 33125 33126 /** 33127 * Scrolls horizontal sliders. 33128 */ 33129 function landscapeScroll(slides, destiny, direction){ 33130 var section = slides.closest(SECTION_SEL); 33131 var v = { 33132 slides: slides, 33133 destiny: destiny, 33134 direction: direction, 33135 destinyPos: destiny.position(), 33136 slideIndex: destiny.index(), 33137 section: section, 33138 sectionIndex: section.index(SECTION_SEL), 33139 anchorLink: section.data('anchor'), 33140 slidesNav: section.find(SLIDES_NAV_SEL), 33141 slideAnchor: getAnchor(destiny), 33142 prevSlide: section.find(SLIDE_ACTIVE_SEL), 33143 prevSlideIndex: section.find(SLIDE_ACTIVE_SEL).index(), 33144 33145 //caching the value of isResizing at the momment the function is called 33146 //because it will be checked later inside a setTimeout and the value might change 33147 localIsResizing: isResizing 33148 }; 33149 v.xMovement = getXmovement(v.prevSlideIndex, v.slideIndex); 33150 v.direction = v.direction ? v.direction : v.xMovement; 33151 33152 //important!! Only do it when not resizing 33153 if(!v.localIsResizing){ 33154 //preventing from scrolling to the next/prev section when using scrollHorizontally 33155 canScroll = false;
33156 } 33157 33158 if(options.onSlideLeave){ 33159 33160 //if the site is not just resizing and readjusting the slides 33161 if(!v.localIsResizing && v.xMovement!=='none'){ 33162 if($.isFunction( options.onSlideLeave )){ 33163 if(options.onSlideLeave.call( v.prevSlide, v.anchorLink, (v.sectionIndex + 1), v.prevSlideIndex, v.xMovement, v.slideIndex ) === false){ 33164 slideMoving = false; 33165 return; 33166 } 33167 } 33168 } 33169 } 33170 33171 destiny.addClass(ACTIVE).siblings().removeClass(ACTIVE); 33172 33173 if(!v.localIsResizing){ 33174 stopMedia(v.prevSlide); 33175 lazyLoad(destiny); 33176 } 33177 33178 if(!options.loopHorizontal && options.controlArrows){ 33179 //hidding it for the fist slide, showing for the rest 33180 section.find(SLIDES_ARROW_PREV_SEL).toggle(v.slideIndex!==0); 33181 33182 //hidding it for the last slide, showing for the rest 33183 section.find(SLIDES_ARROW_NEXT_SEL).toggle(!destiny.is(':last-child')); 33184 } 33185 33186 //only changing the URL if the slides are in the current section (not for resize re-adjusting) 33187 if(section.hasClass(ACTIVE) && !v.localIsResizing){ 33188 setState(v.slideIndex, v.slideAnchor, v.anchorLink, v.sectionIndex); 33189 } 33190 33191 performHorizontalMove(slides, v, true); 33192 } 33193 33194 33195 function afterSlideLoads(v){ 33196 activeSlidesNavigation(v.slidesNav, v.slideIndex); 33197 33198 //if the site is not just resizing and readjusting the slides 33199 if(!v.localIsResizing){ 33200 $.isFunction( options.afterSlideLoad ) && options.afterSlideLoad.call( v.destiny, v.anchorLink, (v.sectionIndex + 1), v.slideAnchor, v.slideIndex); 33201 33202 //needs to be inside the condition to prevent problems with continuousVertical and scrollHorizontally 33203 //and to prevent double scroll right after a windows resize 33204 canScroll = true; 33205 33206 playMedia(v.destiny); 33207 } 33208 33209 //letting them slide again 33210 slideMoving = false; 33211 } 33212 33213 /** 33214 * Performs the horizontal movement. (CSS3 or jQuery) 33215 * 33216 * @param fireCallback {Bool} - determines whether or not to fire the callback 33217 */ 33218 function performHorizontalMove(slides, v, fireCallback){ 33219 var destinyPos = v.destinyPos; 33220 33221 if(options.css3){ 33222 var translate3d = 'translate3d(-' + Math.round(destinyPos.left) + 'px, 0px, 0px)'; 33223 33224 addAnimation(slides.find(SLIDES_CONTAINER_SEL)).css(getTransforms(translate3d), v); 33225 33226 afterSlideLoadsId = setTimeout(function(){ 33227 fireCallback && afterSlideLoads(v); 33228 }, options.scrollingSpeed, options.easing); 33229 }else{ 33230 slides.animate({ 33231 scrollLeft : Math.round(destinyPos.left) 33232 }, options.scrollingSpeed, options.easing, function() { 33233 33234 fireCallback && afterSlideLoads(v); 33235 }); 33236 } 33237 } 33238 33239 /** 33240 * Sets the state for the horizontal bullet navigations. 33241 */ 33242 function activeSlidesNavigation(slidesNav, slideIndex){ 33243 slidesNav.find(ACTIVE_SEL).removeClass(ACTIVE); 33244 slidesNav.find('li').eq(slideIndex).find('a').addClass(ACTIVE); 33245 } 33246 33247 var previousHeight = windowsHeight; 33248 33249 //when resizing the site, we adjust the heights of the sections, slimScroll... 33250 function resizeHandler(){ 33251 //checking if it needs to get responsive 33252 responsive(); 33253 33254 // rebuild immediately on touch devices 33255 if (isTouchDevice) { 33256 var activeElement = $(document.activeElement); 33257 33258 //if the keyboard is NOT visible 33259 if (!activeElement.is('textarea') && !activeElement.is('input') && !activeElement.is('select')) { 33260 var currentHeight = $window.height(); 33261 33262 //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) 33263 if( Math.abs(currentHeight - previousHeight) > (20 * Math.max(previousHeight, currentHeight) / 100) ){ 33264 reBuild(true); 33265 previousHeight = currentHeight; 33266 } 33267 } 33268 }else{ 33269 //in order to call the functions only when the resize is finished 33270 //http://stackoverflow.com/questions/4298612/jquery-how-to-call-resize-event-only-once-its-finished-resizing 33271 clearTimeout(resizeId); 33272 33273 resizeId = setTimeout(function(){ 33274 reBuild(true); 33275 }, 350); 33276 } 33277 } 33278 33279 /** 33280 * Checks if the site needs to get responsive and disables autoScrolling if so. 33281 * A class `fp-responsive` is added to the plugin's container in case the user wants to use it for his own responsive CSS. 33282 */ 33283 function responsive(){ 33284 var widthLimit = options.responsive || options.responsiveWidth; //backwards compatiblity 33285 var heightLimit = options.responsiveHeight; 33286 33287 //only calculating what we need. Remember its called on the resize event. 33288 var isBreakingPointWidth = widthLimit && $window.outerWidth() < widthLimit; 33289 var isBreakingPointHeight = heightLimit && $window.height() < heightLimit; 33290 33291 if(widthLimit && heightLimit){ 33292 setResponsive(isBreakingPointWidth || isBreakingPointHeight); 33293 } 33294 else if(widthLimit){ 33295 setResponsive(isBreakingPointWidth); 33296 } 33297 else if(heightLimit){ 33298 setResponsive(isBreakingPointHeight); 33299 } 33300 } 33301 33302 /** 33303 * Adds transition animations for the given element 33304 */ 33305 function addAnimation(container, element){ 33306 var transition = 'all ' + options.scrollingSpeed + 'ms ' + options.easingcss3; 33307 33308 container.removeClass(NO_TRANSITION); 33309 return container.css({
33310 '-webkit-transition': transition, 33311 'transition': transition 33312 }); 33313 } 33314 33315 /** 33316 * Remove transition animations for the given element 33317 */ 33318 function removeAnimation(element){ 33319 return element.addClass(NO_TRANSITION); 33320 } 33321 33322 /** 33323 * Activating the vertical navigation bullets according to the given slide name. 33324 */ 33325 function activateNavDots(name, sectionIndex){ 33326 if(options.navigation){ 33327 $(SECTION_NAV_SEL).find(ACTIVE_SEL).removeClass(ACTIVE); 33328 if(name){ 33329 $(SECTION_NAV_SEL).find('a[href="#' + name + '"]').addClass(ACTIVE); 33330 }else{ 33331 $(SECTION_NAV_SEL).find('li').eq(sectionIndex).find('a').addClass(ACTIVE); 33332 } 33333 } 33334 } 33335 33336 /** 33337 * Activating the website main menu elements according to the given slide name. 33338 */ 33339 function activateMenuElement(name){ 33340 if(options.menu){ 33341 $(options.menu).find(ACTIVE_SEL).removeClass(ACTIVE); 33342 $(options.menu).find('[data-menuanchor="'+name+'"]').addClass(ACTIVE); 33343 } 33344 } 33345 33346 /** 33347 * Sets to active the current menu and vertical nav items. 33348 */ 33349 function activateMenuAndNav(anchor, index){ 33350 activateMenuElement(anchor); 33351 activateNavDots(anchor, index); 33352 } 33353 33354 /** 33355 * Retuns `up` or `down` depending on the scrolling movement to reach its destination 33356 * from the current section. 33357 */ 33358 function getYmovement(destiny){ 33359 var fromIndex = $(SECTION_ACTIVE_SEL).index(SECTION_SEL); 33360 var toIndex = destiny.index(SECTION_SEL); 33361 if( fromIndex == toIndex){ 33362 return 'none'; 33363 } 33364 if(fromIndex > toIndex){ 33365 return 'up'; 33366 } 33367 return 'down'; 33368 } 33369 33370 /** 33371 * Retuns `right` or `left` depending on the scrolling movement to reach its destination 33372 * from the current slide. 33373 */ 33374 function getXmovement(fromIndex, toIndex){ 33375 if( fromIndex == toIndex){ 33376 return 'none'; 33377 } 33378 if(fromIndex > toIndex){ 33379 return 'left'; 33380 } 33381 return 'right'; 33382 } 33383 33384 /** 33385 * Checks if the element needs scrollbar and if the user wants to apply it. 33386 * If so it creates it. 33387 * 33388 * @param {Object} element jQuery object of the section or slide 33389 */ 33390 function createScrollBar(element){ 33391 //User doesn't want scrollbar here? Sayonara baby! 33392 if(element.hasClass('fp-noscroll')) return; 33393 33394 //needed to make `scrollHeight` work under Opera 12 33395 element.css('overflow', 'hidden'); 33396 33397 var scrollOverflowHandler = options.scrollOverflowHandler; 33398 var wrap = scrollOverflowHandler.wrapContent(); 33399 //in case element is a slide 33400 var section = element.closest(SECTION_SEL); 33401 var scrollable = scrollOverflowHandler.scrollable(element); 33402 var contentHeight; 33403 33404 //if there was scroll, the contentHeight will be the one in the scrollable section 33405 if(scrollable.length){ 33406 contentHeight = scrollOverflowHandler.scrollHeight(element); 33407 }else{ 33408 contentHeight = element.get(0).scrollHeight; 33409 if(options.verticalCentered){ 33410 contentHeight = element.find(TABLE_CELL_SEL).get(0).scrollHeight; 33411 } 33412 } 33413 33414 var scrollHeight = windowsHeight - parseInt(section.css('padding-bottom')) - parseInt(section.css('padding-top')); 33415 33416 //needs scroll? 33417 if ( contentHeight > scrollHeight) { 33418 //did we already have an scrollbar ? Updating it 33419 if(scrollable.length){ 33420 scrollOverflowHandler.update(element, scrollHeight); 33421 } 33422 //creating the scrolling 33423 else{ 33424 if(options.verticalCentered){ 33425 element.find(TABLE_CELL_SEL).wrapInner(wrap); 33426 }else{ 33427 element.wrapInner(wrap); 33428 } 33429 scrollOverflowHandler.create(element, scrollHeight); 33430 } 33431 } 33432 //removing the scrolling when it is not necessary anymore 33433 else{ 33434 scrollOverflowHandler.remove(element); 33435 } 33436 33437 //undo 33438 element.css('overflow', ''); 33439 } 33440 33441 function addTableClass(element){ 33442 //In case we are styling for the 2nd time as in with reponsiveSlides 33443 if(!element.hasClass(TABLE)){ 33444 element.addClass(TABLE).wrapInner('<div class="' + TABLE_CELL + '" style="height:' + getTableHeight(element) + 'px;" />'); 33445 } 33446 } 33447 33448 function getTableHeight(element){ 33449 var sectionHeight = windowsHeight; 33450 33451 if(options.paddingTop || options.paddingBottom){ 33452 var section = element; 33453 if(!section.hasClass(SECTION)){ 33454 section = element.closest(SECTION_SEL); 33455 } 33456 33457 var paddings = parseInt(section.css('padding-top')) + parseInt(section.css('padding-bottom')); 33458 sectionHeight = (windowsHeight - paddings); 33459 } 33460 33461 return sectionHeight; 33462 } 33463 33464 /** 33465 * Adds a css3 transform property to the container class with or without animation depending on the animated param. 33466 */ 33467 function transformContainer(translate3d, animated){ 33468 if(animated){ 33469 addAnimation(container); 33470 }else{ 33471 removeAnimation(container); 33472 } 33473 33474 container.css(getTransforms(translate3d)); 33475 33476 //syncronously removing the class after the animation has been applied. 33477 setTimeout(function(){ 33478 container.removeClass(NO_TRANSITION); 33479 },10); 33480 } 33481 33482 /** 33483 * Gets a section by its anchor / index 33484 */ 33485 function getSectionByAnchor(sectionAnchor){ 33486 if(!sectionAnchor) return []; 33487 33488 var section = container.find(SECTION_SEL + '[data-anchor="'+sectionAnchor+'"]'); 33489 if(!section.length){ 33490 section = $(SECTION_SEL).eq( sectionAnchor -1); 33491 } 33492 33493 return section; 33494 } 33495 33496 /** 33497 * Gets a slide inside a given section by its anchor / index 33498 */ 33499 function getSlideByAnchor(slideAnchor, section){ 33500 var slides = section.find(SLIDES_WRAPPER_SEL); 33501 var slide = slides.find(SLIDE_SEL + '[data-anchor="'+slideAnchor+'"]'); 33502
33503 if(!slide.length){ 33504 slide = slides.find(SLIDE_SEL).eq(slideAnchor); 33505 } 33506 33507 return slide; 33508 } 33509 33510 /** 33511 * Scrolls to the given section and slide anchors 33512 */ 33513 function scrollPageAndSlide(destiny, slide){ 33514 var section = getSectionByAnchor(destiny); 33515 33516 //do nothing if there's no section with the given anchor name 33517 if(!section.length) return; 33518 33519 //default slide 33520 if (typeof slide === 'undefined') { 33521 slide = 0; 33522 } 33523 33524 //we need to scroll to the section and then to the slide 33525 if (destiny !== lastScrolledDestiny && !section.hasClass(ACTIVE)){ 33526 scrollPage(section, function(){ 33527 scrollSlider(section, slide); 33528 }); 33529 } 33530 //if we were already in the section 33531 else{ 33532 scrollSlider(section, slide); 33533 } 33534 } 33535 33536 /** 33537 * Scrolls the slider to the given slide destination for the given section 33538 */ 33539 function scrollSlider(section, slideAnchor){ 33540 if(typeof slideAnchor !== 'undefined'){ 33541 var slides = section.find(SLIDES_WRAPPER_SEL); 33542 var destiny = getSlideByAnchor(slideAnchor, section); 33543 33544 if(destiny.length){ 33545 landscapeScroll(slides, destiny); 33546 } 33547 } 33548 } 33549 33550 /** 33551 * Creates a landscape navigation bar with dots for horizontal sliders. 33552 */ 33553 function addSlidesNavigation(section, numSlides){ 33554 section.append('<div class="' + SLIDES_NAV + '"><ul></ul></div>'); 33555 var nav = section.find(SLIDES_NAV_SEL); 33556 33557 //top or bottom 33558 nav.addClass(options.slidesNavPosition); 33559 33560 for(var i=0; i< numSlides; i++){ 33561 nav.find('ul').append('<li><a href="#"><span></span></a></li>'); 33562 } 33563 33564 //centering it 33565 nav.css('margin-left', '-' + (nav.width()/2) + 'px'); 33566 33567 nav.find('li').first().find('a').addClass(ACTIVE); 33568 } 33569 33570 33571 /** 33572 * Sets the state of the website depending on the active section/slide. 33573 * It changes the URL hash when needed and updates the body class. 33574 */ 33575 function setState(slideIndex, slideAnchor, anchorLink, sectionIndex){ 33576 var sectionHash = ''; 33577 33578 if(options.anchors.length && !options.lockAnchors){ 33579 33580 //isn't it the first slide? 33581 if(slideIndex){ 33582 if(typeof anchorLink !== 'undefined'){ 33583 sectionHash = anchorLink; 33584 } 33585 33586 //slide without anchor link? We take the index instead. 33587 if(typeof slideAnchor === 'undefined'){ 33588 slideAnchor = slideIndex; 33589 } 33590 33591 lastScrolledSlide = slideAnchor; 33592 setUrlHash(sectionHash + '/' + slideAnchor); 33593 33594 //first slide won't have slide anchor, just the section one 33595 }else if(typeof slideIndex !== 'undefined'){ 33596 lastScrolledSlide = slideAnchor; 33597 setUrlHash(anchorLink); 33598 } 33599 33600 //section without slides 33601 else{ 33602 setUrlHash(anchorLink); 33603 } 33604 } 33605 33606 setBodyClass(); 33607 } 33608 33609 /** 33610 * Sets the URL hash. 33611 */ 33612 function setUrlHash(url){ 33613 //Uncode addition 33614 if ( typeof SiteParameters.slide_footer != 'undefined' && url == SiteParameters.slide_footer ) 33615 return false; 33616 33617 if(options.recordHistory){ 33618 location.hash = url; 33619 }else{ 33620 //Uncode addition 33621 //Mobile Chrome doesn't work the normal way, so... lets use HTML5 for phones :) 33622 // if(isTouchDevice || isTouch){ 33623 // window.history.replaceState(undefined, undefined, '#' + url); 33624 // }else{ 33625 // var baseUrl = window.location.href.split('#')[0]; 33626 // window.location.replace( baseUrl + '#' + url ); 33627 // } 33628 return false;
33629 } 33630 } 33631 33632 /** 33633 * Gets the anchor for the given slide / section. Its index will be used if there's none. 33634 */ 33635 function getAnchor(element){ 33636 var anchor = element.data('anchor'); 33637 var index = element.index(); 33638 33639 //Slide without anchor link? We take the index instead. 33640 if(typeof anchor === 'undefined'){ 33641 anchor = index; 33642 } 33643 33644 return anchor; 33645 } 33646 33647 /** 33648 * Sets a class for the body of the page depending on the active section / slide 33649 */ 33650 function setBodyClass(){ 33651 var section = $(SECTION_ACTIVE_SEL); 33652 var slide = section.find(SLIDE_ACTIVE_SEL); 33653 33654 var sectionAnchor = getAnchor(section); 33655 var slideAnchor = getAnchor(slide); 33656 33657 var text = String(sectionAnchor); 33658 33659 if(slide.length){ 33660 text = text + '-' + slideAnchor; 33661 } 33662 33663 //changing slash for dash to make it a valid CSS style 33664 text = text.replace('/', '-').replace('#',''); 33665 33666 //removing previous anchor classes 33667 var classRe = new RegExp('\\b\\s?' + VIEWING_PREFIX + '-[^\\s]+\\b', "g"); 33668 $body[0].className = $body[0].className.replace(classRe, ''); 33669 33670 //adding the current anchor 33671 $body.addClass(VIEWING_PREFIX + '-' + text); 33672 } 33673 33674 /** 33675 * Checks for translate3d support 33676 * @return boolean 33677 * http://stackoverflow.com/questions/5661671/detecting-transform-translate3d-support 33678 */ 33679 function support3d() { 33680 var el = document.createElement('p'), 33681 has3d, 33682 transforms = { 33683 'webkitTransform':'-webkit-transform', 33684 'OTransform':'-o-transform', 33685 'msTransform':'-ms-transform', 33686 'MozTransform':'-moz-transform', 33687 'transform':'transform' 33688 }; 33689 33690 // Add it to the body to get the computed style. 33691 document.body.insertBefore(el, null); 33692 33693 for (var t in transforms) { 33694 if (el.style[t] !== undefined) { 33695 el.style[t] = 'translate3d(1px,1px,1px)'; 33696 has3d = window.getComputedStyle(el).getPropertyValue(transforms[t]); 33697 } 33698 } 33699 33700 document.body.removeChild(el); 33701 33702 return (has3d !== undefined && has3d.length > 0 && has3d !== 'none'); 33703 } 33704 33705 /** 33706 * Removes the auto scrolling action fired by the mouse wheel and trackpad. 33707 * After this function is called, the mousewheel and trackpad movements won't scroll through sections. 33708 */ 33709 function removeMouseWheelHandler(){ 33710 if (document.addEventListener) { 33711 document.removeEventListener('mousewheel', MouseWheelHandler, false); //IE9, Chrome, Safari, Oper 33712 document.removeEventListener('wheel', MouseWheelHandler, false); //Firefox 33713 document.removeEventListener('MozMousePixelScroll', MouseWheelHandler, false); //old Firefox 33714 } else { 33715 document.detachEvent('onmousewheel', MouseWheelHandler); //IE 6/7/8 33716 } 33717 } 33718 33719 /** 33720 * Adds the auto scrolling action for the mouse wheel and trackpad. 33721 * After this function is called, the mousewheel and trackpad movements will scroll through sections 33722 * https://developer.mozilla.org/en-US/docs/Web/Events/wheel 33723 */ 33724 function addMouseWheelHandler(){ 33725 var prefix = ''; 33726 var _addEventListener; 33727 33728 if (window.addEventListener){ 33729 _addEventListener = "addEventListener"; 33730 }else{ 33731 _addEventListener = "attachEvent"; 33732 prefix = 'on'; 33733 } 33734 33735 // detect available wheel event 33736 var support = 'onwheel' in document.createElement('div') ? 'wheel' : // Modern browsers support "wheel" 33737 document.onmousewheel !== undefined ? 'mousewheel' : // Webkit and IE support at least "mousewheel" 33738 'DOMMouseScroll'; // let's assume that remaining browsers are older Firefox 33739 var passiveEvent = g_supportsPassive ? {passive: false }
33739: false; 33740 33741 33742 if(support == 'DOMMouseScroll'){ 33743 document[ _addEventListener ](prefix + 'MozMousePixelScroll', MouseWheelHandler, passiveEvent); 33744 } 33745 33746 //handle MozMousePixelScroll in older Firefox 33747 else{ 33748 document[ _addEventListener ](prefix + support, MouseWheelHandler, passiveEvent); 33749 } 33750 } 33751 33752 /** 33753 * Binding the mousemove when the mouse's middle button is pressed 33754 */ 33755 function addMiddleWheelHandler(){ 33756 container 33757 .on('mousedown', mouseDownHandler) 33758 .on('mouseup', mouseUpHandler); 33759 } 33760 33761 /** 33762 * Unbinding the mousemove when the mouse's middle button is released 33763 */ 33764 function removeMiddleWheelHandler(){ 33765 container 33766 .off('mousedown', mouseDownHandler) 33767 .off('mouseup', mouseUpHandler); 33768 } 33769 33770 /** 33771 * Adds the possibility to auto scroll through sections on touch devices. 33772 */ 33773 function addTouchHandler(){ 33774 if(isTouchDevice || isTouch){ 33775 if(options.autoScrolling){ 33776 $body.off(events.touchmove).on(events.touchmove, preventBouncing); 33777 } 33778 33779 $(WRAPPER_SEL) 33780 .off(events.touchstart).on(events.touchstart, touchStartHandler) 33781 .off(events.touchmove).on(events.touchmove, touchMoveHandler); 33782 } 33783 } 33784 33785 /** 33786 * Removes the auto scrolling for touch devices. 33787 */ 33788 function removeTouchHandler(){ 33789 if(isTouchDevice || isTouch){ 33790 $(WRAPPER_SEL) 33791 .off(events.touchstart) 33792 .off(events.touchmove); 33793 } 33794 } 33795 33796 /* 33797 * Returns and object with Microsoft pointers (for IE<11 and for IE >= 11) 33798 * http://msdn.microsoft.com/en-us/library/ie/dn304886(v=vs.85).aspx 33799 */ 33800 function getMSPointer(){ 33801 var pointer; 33802 33803 //IE >= 11 & rest of browsers 33804 if(window.PointerEvent){ 33805 pointer = { down: 'pointerdown', move: 'pointermove'}; 33806 } 33807 33808 //IE < 11 33809 else{ 33810 pointer = { down: 'MSPointerDown', move: 'MSPointerMove'}; 33811 } 33812 33813 return pointer; 33814 } 33815 33816 /** 33817 * Gets the pageX and pageY properties depending on the browser. 33818 * https://github.com/alvarotrigo/fullPage.js/issues/194#issuecomment-34069854 33819 */ 33820 function getEventsPage(e){ 33821 var events = []; 33822 33823 events.y = (typeof e.pageY !== 'undefined' && (e.pageY || e.pageX) ? e.pageY : e.touches[0].pageY); 33824 events.x = (typeof e.pageX !== 'undefined' && (e.pageY || e.pageX) ? e.pageX : e.touches[0].pageX); 33825 33826 //in touch devices with scrollBar:true, e.pageY is detected, but we have to deal with touch events. #1008 33827 if(isTouch && isReallyTouch(e) && options.scrollBar){ 33828 events.y = e.touches[0].pageY; 33829 events.x = e.touches[0].pageX; 33830 } 33831 33832 return events; 33833 } 33834 33835 /** 33836 * Slides silently (with no animation) the active slider to the given slide. 33837 * @param noCallback {bool} true or defined -> no callbacks 33838 */ 33839 function silentLandscapeScroll(activeSlide, noCallbacks){ 33840 setScrollingSpeed (0, 'internal'); 33841 33842 if(typeof noCallbacks !== 'undefined'){ 33843 //preventing firing callbacks afterSlideLoad etc. 33844 isResizing = true; 33845 } 33846 33847 landscapeScroll(activeSlide.closest(SLIDES_WRAPPER_SEL), activeSlide); 33848 33849 if(typeof noCallbacks !== 'undefined'){ 33850 isResizing = false; 33851 } 33852 33853 setScrollingSpeed(originals.scrollingSpeed, 'internal'); 33854 } 33855 33856 /** 33857 * Scrolls silently (with no animation) the page to the given Y position. 33858 */ 33859 function silentScroll(top){ 33860 // The first section can have a negative value in iOS 10. Not quite sure why: -0.0142822265625 33861 // that's why we round it to 0. 33862 var roundedTop = Math.round(top); 33863 33864 if (options.css3 && options.autoScrolling && !options.scrollBar){ 33865 var translate3d = 'translate3d(0px, -' + roundedTop + 'px, 0px)'; 33866 transformContainer(translate3d, false); 33867 } 33868 else if(options.autoScrolling && !options.scrollBar){ 33869 container.css('top', -roundedTop); 33870 } 33871 else{ 33872 $htmlBody.scrollTop(roundedTop); 33873 } 33874 } 33875 33876 /** 33877 * Returns the cross-browser transform string. 33878 */ 33879 function getTransforms(translate3d){ 33880 return {
33881 '-webkit-transform': translate3d, 33882 '-moz-transform': translate3d, 33883 '-ms-transform':translate3d, 33884 'transform': translate3d 33885 }; 33886 } 33887 33888 /** 33889 * Allowing or disallowing the mouse/swipe scroll in a given direction. (not for keyboard) 33890 * @type m (mouse) or k (keyboard) 33891 */ 33892 function setIsScrollAllowed(value, direction, type){ 33893 switch (direction){ 33894 case 'up': isScrollAllowed[type].up = value; break; 33895 case 'down': isScrollAllowed[type].down = value; break; 33896 case 'left': isScrollAllowed[type].left = value; break; 33897 case 'right': isScrollAllowed[type].right = value; break; 33898 case 'all': 33899 if(type == 'm'){ 33900 setAllowScrolling(value); 33901 }else{ 33902 setKeyboardScrolling(value); 33903 } 33904 } 33905 } 33906 33907 /* 33908 * Destroys fullpage.js plugin events and optinally its html markup and styles 33909 */ 33910 function destroy(all){ 33911 setAutoScrolling(false, 'internal'); 33912 setAllowScrolling(false); 33913 setKeyboardScrolling(false); 33914 container.addClass(DESTROYED); 33915 33916 clearTimeout(afterSlideLoadsId); 33917 clearTimeout(afterSectionLoadsId); 33918 clearTimeout(resizeId); 33919 clearTimeout(scrollId); 33920 clearTimeout(scrollId2); 33921 33922 $window 33923 .off('scroll', scrollHandler) 33924 .off('hashchange', hashChangeHandler) 33925 .off('resize', resizeHandler); 33926 33927 $document 33928 .off('click touchstart', SECTION_NAV_SEL + ' a') 33929 .off('mouseenter', SECTION_NAV_SEL + ' li') 33930 .off('mouseleave', SECTION_NAV_SEL + ' li') 33931 .off('click touchstart', SLIDES_NAV_LINK_SEL) 33932 .off('mouseover', options.normalScrollElements) 33933 .off('mouseout', options.normalScrollElements); 33934 33935 $(SECTION_SEL) 33936 .off('click touchstart', SLIDES_ARROW_SEL); 33937 33938 clearTimeout(afterSlideLoadsId); 33939 clearTimeout(afterSectionLoadsId); 33940 33941 //lets make a mess! 33942 if(all){ 33943 destroyStructure(); 33944 } 33945 } 33946 33947 /* 33948 * Removes inline styles added by fullpage.js 33949 */ 33950 function destroyStructure(){ 33951 //reseting the `top` or `translate` properties to 0 33952 silentScroll(0); 33953 33954 //loading all the lazy load content 33955 container.find('img[data-src], source[data-src], audio[data-src], iframe[data-src]').each(function(){ 33956 setSrc($(this), 'src'); 33957 }); 33958 33959 container.find('img[data-srcset]').each(function(){ 33960 setSrc($(this), 'srcset'); 33961 }); 33962 33963 $(SECTION_NAV_SEL + ', ' + SLIDES_NAV_SEL + ', ' + SLIDES_ARROW_SEL).remove(); 33964 33965 //removing inline styles 33966 $(SECTION_SEL).css( { 33967 'height': '', 33968 'background-color' : '', 33969 'padding': '' 33970 }); 33971 33972 $(SLIDE_SEL).css( { 33973 'width': '' 33974 }); 33975 33976 container.css({ 33977 'height': '', 33978 'position': '', 33979 '-ms-touch-action': '', 33980 'touch-action': '' 33981 }); 33982 33983 $htmlBody.css({ 33984 'overflow': '', 33985 'height': '' 33986 }); 33987 33988 // remove .fp-enabled class 33989 $('html').removeClass(ENABLED); 33990 33991 // remove .fp-responsive class 33992 $body.removeClass(RESPONSIVE); 33993 33994 // remove all of the .fp-viewing- classes 33995 $.each($body.get(0).className.split(/\s+/), function (index, className) { 33996 if (className.indexOf(VIEWING_PREFIX) === 0) { 33997 $body.removeClass(className); 33998 } 33999 }); 34000 34001 //removing added classes 34002 $(SECTION_SEL + ', ' + SLIDE_SEL).each(function(){ 34003 options.scrollOverflowHandler.remove($(this)); 34004 $(this).removeClass(TABLE + ' ' + ACTIVE); 34005 }); 34006 34007 removeAnimation(container); 34008 34009 //Unwrapping content 34010 container.find(TABLE_CELL_SEL + ', ' + SLIDES_CONTAINER_SEL + ', ' + SLIDES_WRAPPER_SEL).each(function(){ 34011 //unwrap not being use in case there's no child element inside and its just text 34012 $(this).replaceWith(this.childNodes); 34013 }); 34014 34015 //removing the applied transition from the fullpage wrapper 34016 container.css({
34017 '-webkit-transition': 'none', 34018 'transition': 'none' 34019 }); 34020 34021 //scrolling the page to the top with no animation 34022 $htmlBody.scrollTop(0); 34023 34024 //removing selectors 34025 var usedSelectors = [SECTION, SLIDE, SLIDES_CONTAINER]; 34026 $.each(usedSelectors, function(index, value){ 34027 $('.' + value).removeClass(value); 34028 }); 34029 } 34030 34031 /* 34032 * Sets the state for a variable with multiple states (original, and temporal) 34033 * Some variables such as `autoScrolling` or `recordHistory` might change automatically its state when using `responsive` or `autoScrolling:false`. 34034 * This function is used to keep track of both states, the original and the temporal one. 34035 * If type is not 'internal', then we assume the user is globally changing the variable. 34036 */ 34037 function setVariableState(variable, value, type){ 34038 options[variable] = value; 34039 if(type !== 'internal'){ 34040 originals[variable] = value; 34041 } 34042 } 34043 34044 /** 34045 * Displays warnings 34046 */ 34047 function displayWarnings(){ 34048 var extensions = ['fadingEffect', 'continuousHorizontal', 'scrollHorizontally', 'interlockedSlides', 'resetSliders', 'responsiveSlides', 'offsetSections', 'dragAndMove', 'scrollOverflowReset', 'parallax']; 34049 //UNCODE.addition 34050 // if($('html').hasClass(ENABLED)){ 34051 // showError('error', 'Fullpage.js can only be initialized once and you are doing it multiple times!'); 34052 // return; 34053 // } 34054 34055 // Disable mutually exclusive settings 34056 //UNCODE.addition 34057 // if (options.continuousVertical && 34058 // (options.loopTop || options.loopBottom)) { 34059 // options.continuousVertical = false;
34060 // showError('warn', 'Option `loopTop/loopBottom` is mutually exclusive with `continuousVertical`; `continuousVertical` disabled'); 34061 // } 34062 34063 // if(options.scrollBar && options.scrollOverflow){ 34064 // showError('warn', 'Option `scrollBar` is mutually exclusive with `scrollOverflow`. Sections with scrollOverflow might not work well in Firefox'); 34065 // } 34066 34067 // if(options.continuousVertical && (options.scrollBar || !options.autoScrolling)){ 34068 // options.continuousVertical = false; 34069 // showError('warn', 'Scroll bars (`scrollBar:true` or `autoScrolling:false`) are mutually exclusive with `continuousVertical`; `continuousVertical` disabled'); 34070 // } 34071 34072 //using extensions? Wrong file! 34073 $.each(extensions, function(index, extension){ 34074 //is the option set to true? 34075 if(options[extension]){ 34076 showError('warn', 'fullpage.js extensions require jquery.fullpage.extensions.min.js file instead of the usual jquery.fullpage.js. Requested: '+ extension); 34077 } 34078 }); 34079 34080 //anchors can not have the same value as any element ID or NAME 34081 $.each(options.anchors, function(index, name){ 34082 34083 //case insensitive selectors (http://stackoverflow.com/a/19465187/1081396) 34084 var nameAttr = $document.find('[name]').filter(function() { 34085 return $(this).attr('name') && $(this).attr('name').toLowerCase() == name.toLowerCase(); 34086 }); 34087 34088 var idAttr = $document.find('[id]').filter(function() { 34089 return $(this).attr('id') && $(this).attr('id').toLowerCase() == name.toLowerCase(); 34090 }); 34091 34092 if(idAttr.length || nameAttr.length ){ 34093 showError('error', 'data-anchor tags can not have the same value as any `id` element on the site (or `name` element for IE).'); 34094 idAttr.length && showError('error', '"' + name + '" is is being used by another element `id` property'); 34095 nameAttr.length && showError('error', '"' + name + '" is is being used by another element `name` property'); 34096 } 34097 }); 34098 } 34099 34100 /** 34101 * Shows a message in the console of the given type. 34102 */ 34103 function showError(type, text){ 34104 console && console[type] && console[type]('fullPage: ' + text); 34105 } 34106 34107 }; //end of $.fn.fullpage 34108 34109 if(typeof IScroll !== 'undefined'){ 34110 /* 34111 * Turns iScroll `mousewheel` option off dynamically 34112 * https://github.com/cubiq/iscroll/issues/1036 34113 */ 34114 IScroll.prototype.wheelOn = function () { 34115 this.wrapper.addEventListener('wheel', this); 34116 this.wrapper.addEventListener('mousewheel', this); 34117 this.wrapper.addEventListener('DOMMouseScroll', this); 34118 }; 34119 34120 /* 34121 * Turns iScroll `mousewheel` option on dynamically 34122 * https://github.com/cubiq/iscroll/issues/1036 34123 */ 34124 IScroll.prototype.wheelOff = function () { 34125 this.wrapper.removeEventListener('wheel', this); 34126 this.wrapper.removeEventListener('mousewheel', this); 34127 this.wrapper.removeEventListener('DOMMouseScroll', this); 34128 }; 34129 } 34130 34131 /** 34132 * An object to handle overflow scrolling. 34133 * This uses jquery.slimScroll to accomplish overflow scrolling. 34134 * It is possible to pass in an alternate scrollOverflowHandler 34135 * to the fullpage.js option that implements the same functions 34136 * as this handler. 34137 * 34138 * @type {Object} 34139 */ 34140 var iscrollHandler = { 34141 refreshId: null, 34142 iScrollInstances: [], 34143 34144 // Enables or disables the mouse wheel for the active section or all slides in it 34145 toggleWheel: function(value){ 34146 var scrollable = $(SECTION_ACTIVE_SEL).find(SCROLLABLE_SEL); 34147 scrollable.each(function(){ 34148 var iScrollInstance = $(this).data('iscrollInstance'); 34149 if(typeof iScrollInstance !== 'undefined' && iScrollInstance){ 34150 if(value){ 34151 iScrollInstance.wheelOn(); 34152 } 34153 else{ 34154 iScrollInstance.wheelOff(); 34155 } 34156 } 34157 }); 34158 }, 34159 34160 /** 34161 * Turns off iScroll for the destination section. 34162 * When scrolling very fast on some trackpads (and Apple laptops) the inertial scrolling would
34163 * scroll the destination section/slide before the sections animations ends. 34164 */ 34165 onLeave: function(){ 34166 iscrollHandler.toggleWheel(false); 34167 }, 34168 34169 // Turns off iScroll for the leaving section 34170 beforeLeave: function(){ 34171 iscrollHandler.onLeave() 34172 }, 34173 34174 // Turns on iScroll on section load 34175 afterLoad: function(){ 34176 iscrollHandler.toggleWheel(true); 34177 }, 34178 34179 /** 34180 * Called when overflow scrolling is needed for a section. 34181 * 34182 * @param {Object} element jQuery object containing current section 34183 * @param {Number} scrollHeight Current window height in pixels 34184 */ 34185 create: function(element, scrollHeight) { 34186 var scrollable = element.find(SCROLLABLE_SEL); 34187 34188 scrollable.height(scrollHeight); 34189 scrollable.each(function() { 34190 var $this = $(this); 34191 var iScrollInstance = $this.data('iscrollInstance'); 34192 if (iScrollInstance) { 34193 $.each(iscrollHandler.iScrollInstances, function(){ 34194 $(this).destroy(); 34195 }); 34196 } 34197 34198 iScrollInstance = new IScroll($this.get(0), iscrollOptions); 34199 iscrollHandler.iScrollInstances.push(iScrollInstance); 34200 34201 //off by default until the section gets active 34202 iScrollInstance.wheelOff(); 34203 34204 $this.data('iscrollInstance', iScrollInstance); 34205 }); 34206 }, 34207 34208 /** 34209 * Return a boolean depending on whether the scrollable element is a 34210 * the end or at the start of the scrolling depending on the given type. 34211 * 34212 * @param {String} type Either 'top' or 'bottom' 34213 * @param {Object} scrollable jQuery object for the scrollable element 34214 * @return {Boolean} 34215 */ 34216 isScrolled: function(type, scrollable) { 34217 var scroller = scrollable.data('iscrollInstance'); 34218 34219 //no scroller? 34220 if (!scroller) { 34221 return true; 34222 } 34223 34224 //Uncode addition 34225 var uncode_body_borders = parseFloat($('.body-borders').attr('data-border')) || 0; 34226 //End Uncode addition 34227 34228 if (type === 'top') { 34229 return scroller.y >= 0 && !scrollable.scrollTop(); 34230 } else if (type === 'bottom') { 34231 //Uncode change 34232 // return (0 - scroller.y) + scrollable.scrollTop() + 1 + scrollable.innerHeight() >= scrollable[0].scrollHeight; 34233 return (0 - scroller.y) + scrollable.scrollTop() + 1 + ( uncode_body_borders * 2 ) + scrollable.innerHeight() >= scrollable[0].scrollHeight; 34234 //End Uncode change 34235 } 34236 }, 34237 34238 /** 34239 * Returns the scrollable element for the given section. 34240 * If there are landscape slides, will only return a scrollable element 34241 * if it is in the active slide. 34242 * 34243 * @param {Object} activeSection jQuery object containing current section 34244 * @return {Boolean} 34245 */ 34246 scrollable: function(activeSection){ 34247 // if there are landscape slides, we check if the scrolling bar is in the current one or not 34248 if (activeSection.find(SLIDES_WRAPPER_SEL).length) { 34249 return activeSection.find(SLIDE_ACTIVE_SEL).find(SCROLLABLE_SEL); 34250 } 34251 return activeSection.find(SCROLLABLE_SEL); 34252 }, 34253 34254 /** 34255 * Returns the scroll height of the wrapped content. 34256 * If this is larger than the window height minus section padding, 34257 * overflow scrolling is needed. 34258 * 34259 * @param {Object} element jQuery object containing current section 34260 * @return {Number} 34261 */ 34262 scrollHeight: function(element) { 34263 return element.find(SCROLLABLE_SEL).children().first().get(0).scrollHeight; 34264 }, 34265 34266 /** 34267 * Called when overflow scrolling is no longer needed for a section. 34268 * 34269 * @param {Object}
34269 element jQuery object containing current section 34270 */ 34271 remove: function(element) { 34272 var scrollable = element.find(SCROLLABLE_SEL); 34273 if (scrollable.length) { 34274 var iScrollInstance = scrollable.data('iscrollInstance'); 34275 iScrollInstance.destroy(); 34276 34277 scrollable.data('iscrollInstance', null); 34278 } 34279 element.find(SCROLLABLE_SEL).children().first().children().first().unwrap().unwrap(); 34280 }, 34281 34282 /** 34283 * Called when overflow scrolling has already been setup but the 34284 * window height has potentially changed. 34285 * 34286 * @param {Object} element jQuery object containing current section 34287 * @param {Number} scrollHeight Current window height in pixels 34288 */ 34289 update: function(element, scrollHeight) { 34290 //using a timeout in order to execute the refresh function only once when `update` is called multiple times in a 34291 //short period of time. 34292 //it also comes on handy because iScroll requires the use of timeout when using `refresh`. 34293 clearTimeout(iscrollHandler.refreshId); 34294 iscrollHandler.refreshId = setTimeout(function(){ 34295 $.each(iscrollHandler.iScrollInstances, function(){ 34296 $(this).get(0).refresh(); 34297 }); 34298 }, 150); 34299 34300 //updating the wrappers height 34301 element.find(SCROLLABLE_SEL).css('height', scrollHeight + 'px').parent().css('height', scrollHeight + 'px'); 34302 }, 34303 34304 /** 34305 * Called to get any additional elements needed to wrap the section 34306 * content in order to facilitate overflow scrolling. 34307 * 34308 * @return {String|Object} Can be a string containing HTML, 34309 * a DOM element, or jQuery object. 34310 */ 34311 wrapContent: function() { 34312 return '<div class="' + SCROLLABLE + '"><div class="fp-scroller"></div></div>'; 34313 } 34314 }; 34315}); 34316 34317(function (global, factory) { 34318 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : 34319 typeof define === 'function' && define.amd ? define(['exports'], factory) : 34320 (global = global || self, factory(global.window = global.window || {})); 34321}(this, (function (exports) { 'use strict'; 34322 34323 /*! 34324 * ScrollTrigger 3.8.0 34325 * https://greensock.com 34326 * 34327 * @license Copyright 2008-2021, GreenSock. All rights reserved. 34328 * Subject to the terms at https://greensock.com/standard-license or for 34329 * Club GreenSock members, the agreement issued with that membership. 34330 * @author: Jack Doyle, [email protected] 34331 */ 34332 var gsap, 34333 _coreInitted, 34334 _win, 34335 _doc, 34336 _docEl, 34337 _body, 34338 _root, 34339 _resizeDelay, 34340 _raf, 34341 _request, 34342 _toArray, 34343 _clamp, 34344 _time2, 34345 _syncInterval, 34346 _refreshing, 34347 _pointerIsDown, 34348 _transformProp, 34349 _i, 34350 _prevWidth, 34351 _prevHeight, 34352 _autoRefresh, 34353 _sort, 34354 _suppressOverwrites, 34355 _ignoreResize, 34356 _limitCallbacks, 34357 _startup = 1, 34358 _proxies = [], 34359 _scrollers = [], 34360 _getTime = Date.now, 34361 _time1 = _getTime(), 34362 _lastScrollTime = 0, 34363 _enabled = 1, 34364 _passThrough = function _passThrough(v) { 34365 return v; 34366 }, 34367 _getTarget = function _getTarget(t) { 34368 return _toArray(t)[0] || (_isString(t) ? console.warn("Element not found:", t) : null); 34369 }, 34370 _round = function _round(value) { 34371 return Math.round(value * 100000) / 100000 || 0; 34372 }, 34373 _windowExists = function _windowExists() { 34374 return typeof window !== "undefined"; 34375 }, 34376 _getGSAP = function _getGSAP() { 34377 return gsap || _windowExists() && (gsap = window.gsap) && gsap.registerPlugin && gsap; 34378 }, 34379 _isViewport = function _isViewport(e) { 34380 return !!~_root.indexOf(e); 34381 }, 34382 _getProxyProp = function _getProxyProp(element, property) { 34383 return ~_proxies.indexOf(element) && _proxies[_proxies.indexOf(element) + 1][property]; 34384 }, 34385 _getScrollFunc = function _getScrollFunc(element, _ref) { 34386 var s = _ref.s, 34387 sc = _ref.sc; 34388 34389 var i = _scrollers.indexOf(element), 34390 offset = sc === _vertical.sc ? 1 : 2; 34391 34392 !~i && (i = _scrollers.push(element) - 1); 34393 return _scrollers[i + offset] || (_scrollers[i + offset] = _getProxyProp(element, s) || (_isViewport(element) ? sc : function (value) { 34394 return arguments.length ? element[s] = value : element[s]; 34395 })); 34396 }, 34397 _getBoundsFunc = function _getBoundsFunc(element) { 34398 return _getProxyProp(element, "getBoundingClientRect") || (_isViewport(element) ? function () { 34399 _winOffsets.width = _win.innerWidth; 34400 _winOffsets.height = _win.innerHeight; 34401 return _winOffsets; 34402 } : function () { 34403 return _getBounds(element); 34404 }); 34405 }, 34406 _getSizeFunc = function _getSizeFunc(scroller, isViewport, _ref2) { 34407 var d = _ref2.d, 34408 d2 = _ref2.d2, 34409 a = _ref2.a; 34410 return (a = _getProxyProp(scroller, "getBoundingClientRect")) ? function () { 34411 return a()[d]; 34412 } : function () { 34413 return (isViewport ? _win["inner" + d2] : scroller["client" + d2]) || 0; 34414 }; 34415 }, 34416 _getOffsetsFunc = function _getOffsetsFunc(element, isViewport) { 34417 return !isViewport || ~_proxies.indexOf(element) ? _getBoundsFunc(element) : function () { 34418 return _winOffsets; 34419 }; 34420 }, 34421 _maxScroll = function _maxScroll(element, _ref3) { 34422 var s = _ref3.s, 34423 d2 = _ref3.d2, 34424 d = _ref3.d, 34425 a = _ref3.a; 34426 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]; 34427 }, 34428 _iterateAutoRefresh = function _iterateAutoRefresh(func, events) { 34429 for (var i = 0; i < _autoRefresh.length; i += 3) {
vendor: 5,689 bytes, lines 34430-34634
34430 (!events || ~events.indexOf(_autoRefresh[i + 1])) && func(_autoRefresh[i], _autoRefresh[i + 1], _autoRefresh[i + 2]); 34431 } 34432 }, 34433 _isString = function _isString(value) { 34434 return typeof value === "string"; 34435 }, 34436 _isFunction = function _isFunction(value) { 34437 return typeof value === "function"; 34438 }, 34439 _isNumber = function _isNumber(value) { 34440 return typeof value === "number"; 34441 }, 34442 _isObject = function _isObject(value) { 34443 return typeof value === "object"; 34444 }, 34445 _callIfFunc = function _callIfFunc(value) { 34446 return _isFunction(value) && value(); 34447 }, 34448 _combineFunc = function _combineFunc(f1, f2) { 34449 return function () { 34450 var result1 = _callIfFunc(f1), 34451 result2 = _callIfFunc(f2); 34452 34453 return function () { 34454 _callIfFunc(result1); 34455 34456 _callIfFunc(result2); 34457 }; 34458 }; 34459 }, 34460 _endAnimation = function _endAnimation(animation, reversed, pause) { 34461 return animation && animation.progress(reversed ? 0 : 1) && pause && animation.pause(); 34462 }, 34463 _callback = function _callback(self, func) { 34464 var result = func(self); 34465 result && result.totalTime && (self.callbackAnimation = result); 34466 }, 34467 _abs = Math.abs, 34468 _scrollLeft = "scrollLeft", 34469 _scrollTop = "scrollTop", 34470 _left = "left", 34471 _top = "top", 34472 _right = "right", 34473 _bottom = "bottom", 34474 _width = "width", 34475 _height = "height", 34476 _Right = "Right", 34477 _Left = "Left", 34478 _Top = "Top", 34479 _Bottom = "Bottom", 34480 _padding = "padding", 34481 _margin = "margin", 34482 _Width = "Width", 34483 _Height = "Height", 34484 _px = "px", 34485 _horizontal = { 34486 s: _scrollLeft, 34487 p: _left, 34488 p2: _Left, 34489 os: _right, 34490 os2: _Right, 34491 d: _width, 34492 d2: _Width, 34493 a: "x", 34494 sc: function sc(value) { 34495 return arguments.length ? _win.scrollTo(value, _vertical.sc()) : _win.pageXOffset || _doc[_scrollLeft] || _docEl[_scrollLeft] || _body[_scrollLeft] || 0; 34496 } 34497 }, 34498 _vertical = { 34499 s: _scrollTop, 34500 p: _top, 34501 p2: _Top, 34502 os: _bottom, 34503 os2: _Bottom, 34504 d: _height, 34505 d2: _Height, 34506 a: "y", 34507 op: _horizontal, 34508 sc: function sc(value) { 34509 return arguments.length ? _win.scrollTo(_horizontal.sc(), value) : _win.pageYOffset || _doc[_scrollTop] || _docEl[_scrollTop] || _body[_scrollTop] || 0; 34510 } 34511 }, 34512 _getComputedStyle = function _getComputedStyle(element) { 34513 return _win.getComputedStyle(element); 34514 }, 34515 _makePositionable = function _makePositionable(element) { 34516 var position = _getComputedStyle(element).position; 34517 34518 element.style.position = position === "absolute" || position === "fixed" ? position : "relative"; 34519 }, 34520 _setDefaults = function _setDefaults(obj, defaults) { 34521 for (var p in defaults) { 34522 p in obj || (obj[p] = defaults[p]); 34523 } 34524 34525 return obj; 34526 }, 34527 _getBounds = function _getBounds(element, withoutTransforms) { 34528 var tween = withoutTransforms && _getComputedStyle(element)[_transformProp] !== "matrix(1, 0, 0, 1, 0, 0)" && gsap.to(element, { 34529 x: 0, 34530 y: 0, 34531 xPercent: 0, 34532 yPercent: 0, 34533 rotation: 0, 34534 rotationX: 0, 34535 rotationY: 0, 34536 scale: 1, 34537 skewX: 0, 34538 skewY: 0 34539 }).progress(1), 34540 bounds = element.getBoundingClientRect(); 34541 tween && tween.progress(0).kill(); 34542 return bounds; 34543 }, 34544 _getSize = function _getSize(element, _ref4) { 34545 var d2 = _ref4.d2; 34546 return element["offset" + d2] || element["client" + d2] || 0; 34547 }, 34548 _getLabelRatioArray = function _getLabelRatioArray(timeline) { 34549 var a = [], 34550 labels = timeline.labels, 34551 duration = timeline.duration(), 34552 p; 34553 34554 for (p in labels) { 34555 a.push(labels[p] / duration); 34556 } 34557 34558 return a; 34559 }, 34560 _getClosestLabel = function _getClosestLabel(animation) { 34561 return function (value) { 34562 return gsap.utils.snap(_getLabelRatioArray(animation), value); 34563 }; 34564 }, 34565 _snapDirectional = function _snapDirectional(snapIncrementOrArray) { 34566 var snap = gsap.utils.snap(snapIncrementOrArray), 34567 a = Array.isArray(snapIncrementOrArray) && snapIncrementOrArray.slice(0).sort(function (a, b) { 34568 return a - b; 34569 }); 34570 return a ? function (value, direction) { 34571 var i; 34572 34573 if (!direction) { 34574 return snap(value); 34575 } 34576 34577 if (direction > 0) { 34578 value -= 1e-4; 34579 34580 for (i = 0; i < a.length; i++) { 34581 if (a[i] >= value) { 34582 return a[i]; 34583 } 34584 } 34585 34586 return a[i - 1]; 34587 } else { 34588 i = a.length; 34589 value += 1e-4; 34590 34591 while (i--) { 34592 if (a[i] <= value) { 34593 return a[i]; 34594 } 34595 } 34596 } 34597 34598 return a[0]; 34599 } : function (value, direction) { 34600 var snapped = snap(value); 34601 return !direction || Math.abs(snapped - value) < 0.001 || snapped - value < 0 === direction < 0 ? snapped : snap(direction < 0 ? value - snapIncrementOrArray : value + snapIncrementOrArray); 34602 }; 34603 }, 34604 _getLabelAtDirection = function _getLabelAtDirection(timeline) { 34605 return function (value, st) { 34606 return _snapDirectional(_getLabelRatioArray(timeline))(value, st.direction); 34607 }; 34608 }, 34609 _multiListener = function _multiListener(func, element, types, callback) { 34610 return types.split(",").forEach(function (type) { 34611 return func(element, type, callback); 34612 }); 34613 }, 34614 _addListener = function _addListener(element, type, func) { 34615 return element.addEventListener(type, func, { 34616 passive: true 34617 }); 34618 }, 34619 _removeListener = function _removeListener(element, type, func) { 34620 return element.removeEventListener(type, func); 34621 }, 34622 _markerDefaults = { 34623 startColor: "green", 34624 endColor: "red", 34625 indent: 0, 34626 fontSize: "16px", 34627 fontWeight: "normal" 34628 }, 34629 _defaults = { 34630 toggleActions: "play", 34631 anticipatePin: 0 34632 }, 34633 _keywords = { 34634 top: 0,
34635 left: 0, 34636 center: 0.5, 34637 bottom: 1, 34638 right: 1 34639 }, 34640 _offsetToPx = function _offsetToPx(value, size) { 34641 if (_isString(value)) { 34642 var eqIndex = value.indexOf("="), 34643 relative = ~eqIndex ? +(value.charAt(eqIndex - 1) + 1) * parseFloat(value.substr(eqIndex + 1)) : 0; 34644 34645 if (~eqIndex) { 34646 value.indexOf("%") > eqIndex && (relative *= size / 100); 34647 value = value.substr(0, eqIndex - 1); 34648 } 34649 34650 value = relative + (value in _keywords ? _keywords[value] * size : ~value.indexOf("%") ? parseFloat(value) * size / 100 : parseFloat(value) || 0); 34651 } 34652 34653 return value; 34654 }, 34655 _createMarker = function _createMarker(type, name, container, direction, _ref5, offset, matchWidthEl, containerAnimation) { 34656 var startColor = _ref5.startColor, 34657 endColor = _ref5.endColor, 34658 fontSize = _ref5.fontSize, 34659 indent = _ref5.indent, 34660 fontWeight = _ref5.fontWeight; 34661 34662 var e = _doc.createElement("div"), 34663 useFixedPosition = _isViewport(container) || _getProxyProp(container, "pinType") === "fixed", 34664 isScroller = type.indexOf("scroller") !== -1, 34665 parent = useFixedPosition ? _body : container, 34666 isStart = type.indexOf("start") !== -1, 34667 color = isStart ? startColor : endColor, 34668 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;"; 34669 34670 css += "position:" + ((isScroller || containerAnimation) && useFixedPosition ? "fixed;" : "absolute;"); 34671 (isScroller || containerAnimation || !useFixedPosition) && (css += (direction === _vertical ? _right : _bottom) + ":" + (offset + parseFloat(indent)) + "px;"); 34672 matchWidthEl && (css += "box-sizing:border-box;text-align:left;width:" + matchWidthEl.offsetWidth + "px;"); 34673 e._isStart = isStart; 34674 e.setAttribute("class", "gsap-marker-" + type + (name ? " marker-" + name : "")); 34675 e.style.cssText = css; 34676 e.innerText = name || name === 0 ? type + "-" + name : type; 34677 parent.children[0] ? parent.insertBefore(e, parent.children[0]) : parent.appendChild(e); 34678 e._offset = e["offset" + direction.op.d2]; 34679 34680 _positionMarker(e, 0, direction, isStart); 34681 34682 return e; 34683 }, 34684 _positionMarker = function _positionMarker(marker, start, direction, flipped) { 34685 var vars = { 34686 display: "block" 34687 }, 34688 side = direction[flipped ? "os2" : "p2"], 34689 oppositeSide = direction[flipped ? "p2" : "os2"]; 34690 marker._isFlipped = flipped; 34691 vars[direction.a + "Percent"] = flipped ? -100 : 0; 34692 vars[direction.a] = flipped ? "1px" : 0; 34693 vars["border" + side + _Width] = 1; 34694 vars["border" + oppositeSide + _Width] = 0; 34695 vars[direction.p] = start + "px"; 34696 gsap.set(marker, vars); 34697 }, 34698 _triggers = [], 34699 _ids = {}, 34700 _sync = function _sync() { 34701 return _getTime() - _lastScrollTime > 20 && _updateAll(); 34702 }, 34703 _onScroll = function _onScroll() { 34704 var time = _getTime(); 34705 34706 if (_lastScrollTime !== time) { 34707 _updateAll(); 34708 34709 _lastScrollTime || _dispatch("scrollStart"); 34710 _lastScrollTime = time; 34711 } else if (!_request) { 34712 _request = _raf(_updateAll); 34713 } 34714 }, 34715 _onResize = function _onResize() { 34716 return !_refreshing && !_ignoreResize && !_doc.fullscreenElement && _resizeDelay.restart(true); 34717 }, 34718 _listeners = {}, 34719 _emptyArray = [], 34720 _media = [], 34721 _creatingMedia, 34722 _lastMediaTick, 34723 _onMediaChange = function _onMediaChange(e) { 34724 var tick = gsap.ticker.frame, 34725 matches = [], 34726 i = 0, 34727 index; 34728 34729 if (_lastMediaTick !== tick || _startup) { 34730 _revertAll(); 34731 34732 for (; i < _media.length; i += 4) { 34733 index = _win.matchMedia(_media[i]).matches; 34734 34735 if (index !== _media[i + 3]) { 34736 _media[i + 3] = index; 34737 index ? matches.push(i) : _revertAll(1, _media[i]) || _isFunction(_media[i + 2]) && _media[i + 2](); 34738 } 34739 } 34740 34741 _revertRecorded(); 34742 34743 for (i = 0; i < matches.length; i++) { 34744 index = matches[i]; 34745 _creatingMedia = _media[index]; 34746 _media[index + 2] = _media[index + 1](e); 34747 } 34748 34749 _creatingMedia = 0; 34750 _coreInitted && _refreshAll(0, 1); 34751 _lastMediaTick = tick; 34752 34753 _dispatch("matchMedia"); 34754 } 34755 }, 34756 _softRefresh = function _softRefresh() { 34757 return _removeListener(ScrollTrigger, "scrollEnd", _softRefresh) || _refreshAll(true); 34758 }, 34759 _dispatch = function _dispatch(type) { 34760 return _listeners[type] && _listeners[type].map(function (f) { 34761 return f(); 34762 }) || _emptyArray; 34763 }, 34764 _savedStyles = [], 34765 _revertRecorded = function _revertRecorded(media) { 34766 for (var i = 0; i < _savedStyles.length; i += 5) { 34767 if (!media || _savedStyles[i + 4] === media) { 34768 _savedStyles[i].style.cssText = _savedStyles[i + 1]; 34769 _savedStyles[i].getBBox && _savedStyles[i].setAttribute("transform", _savedStyles[i + 2] || ""); 34770 _savedStyles[i + 3].uncache = 1; 34771 } 34772 } 34773 }, 34774 _revertAll = function _revertAll(kill, media) { 34775 var trigger; 34776 34777 for (_i = 0; _i < _triggers.length; _i++) { 34778 trigger = _triggers[_i]; 34779 34780 if (!media || trigger.media === media) { 34781 if (kill) { 34782 trigger.kill(1); 34783 } else { 34784 trigger.revert(); 34785 } 34786 } 34787 } 34788 34789 media && _revertRecorded(media); 34790 media || _dispatch("revert"); 34791 }, 34792 _clearScrollMemory = function _clearScrollMemory() {
vendor: 10,266 bytes, lines 34793-35127
34793 return _scrollers.forEach(function (obj) { 34794 return typeof obj === "function" && (obj.rec = 0); 34795 }); 34796 }, 34797 _refreshingAll, 34798 _refreshAll = function _refreshAll(force, skipRevert) { 34799 if (_lastScrollTime && !force) { 34800 _addListener(ScrollTrigger, "scrollEnd", _softRefresh); 34801 34802 return; 34803 } 34804 34805 _refreshingAll = true; 34806 34807 var refreshInits = _dispatch("refreshInit"); 34808 34809 _sort && ScrollTrigger.sort(); 34810 skipRevert || _revertAll(); 34811 34812 _triggers.forEach(function (t) { 34813 return t.refresh(); 34814 }); 34815 34816 refreshInits.forEach(function (result) { 34817 return result && result.render && result.render(-1); 34818 }); 34819 34820 _clearScrollMemory(); 34821 34822 _resizeDelay.pause(); 34823 34824 _refreshingAll = false; 34825 34826 _dispatch("refresh"); 34827 }, 34828 _lastScroll = 0, 34829 _direction = 1, 34830 _updateAll = function _updateAll() { 34831 if (!_refreshingAll) { 34832 var l = _triggers.length, 34833 time = _getTime(), 34834 recordVelocity = time - _time1 >= 50, 34835 scroll = l && _triggers[0].scroll(); 34836 34837 _direction = _lastScroll > scroll ? -1 : 1; 34838 _lastScroll = scroll; 34839 34840 if (recordVelocity) { 34841 if (_lastScrollTime && !_pointerIsDown && time - _lastScrollTime > 200) { 34842 _lastScrollTime = 0; 34843 34844 _dispatch("scrollEnd"); 34845 } 34846 34847 _time2 = _time1; 34848 _time1 = time; 34849 } 34850 34851 if (_direction < 0) { 34852 _i = l; 34853 34854 while (_i-- > 0) { 34855 _triggers[_i] && _triggers[_i].update(0, recordVelocity); 34856 } 34857 34858 _direction = 1; 34859 } else { 34860 for (_i = 0; _i < l; _i++) { 34861 _triggers[_i] && _triggers[_i].update(0, recordVelocity); 34862 } 34863 } 34864 34865 _request = 0; 34866 } 34867 }, 34868 _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"], 34869 _stateProps = _propNamesToCopy.concat([_width, _height, "boxSizing", "max" + _Width, "max" + _Height, "position", _margin, _padding, _padding + _Top, _padding + _Right, _padding + _Bottom, _padding + _Left]), 34870 _swapPinOut = function _swapPinOut(pin, spacer, state) { 34871 _setState(state); 34872 34873 var cache = pin._gsap; 34874 34875 if (cache.spacerIsNative) { 34876 _setState(cache.spacerState); 34877 } else if (pin.parentNode === spacer) { 34878 var parent = spacer.parentNode; 34879 34880 if (parent) { 34881 parent.insertBefore(pin, spacer); 34882 parent.removeChild(spacer); 34883 } 34884 } 34885 }, 34886 _swapPinIn = function _swapPinIn(pin, spacer, cs, spacerState) { 34887 if (pin.parentNode !== spacer) { 34888 var i = _propNamesToCopy.length, 34889 spacerStyle = spacer.style, 34890 pinStyle = pin.style, 34891 p; 34892 34893 while (i--) { 34894 p = _propNamesToCopy[i]; 34895 spacerStyle[p] = cs[p]; 34896 } 34897 34898 spacerStyle.position = cs.position === "absolute" ? "absolute" : "relative"; 34899 cs.display === "inline" && (spacerStyle.display = "inline-block"); 34900 pinStyle[_bottom] = pinStyle[_right] = "auto"; 34901 spacerStyle.overflow = "visible"; 34902 spacerStyle.boxSizing = "border-box"; 34903 spacerStyle[_width] = _getSize(pin, _horizontal) + _px; 34904 spacerStyle[_height] = _getSize(pin, _vertical) + _px; 34905 spacerStyle[_padding] = pinStyle[_margin] = pinStyle[_top] = pinStyle[_left] = "0"; 34906 34907 _setState(spacerState); 34908 34909 pinStyle[_width] = pinStyle["max" + _Width] = cs[_width]; 34910 pinStyle[_height] = pinStyle["max" + _Height] = cs[_height]; 34911 pinStyle[_padding] = cs[_padding]; 34912 pin.parentNode.insertBefore(spacer, pin); 34913 spacer.appendChild(pin); 34914 } 34915 }, 34916 _capsExp = /([A-Z])/g, 34917 _setState = function _setState(state) { 34918 if (state) { 34919 var style = state.t.style, 34920 l = state.length, 34921 i = 0, 34922 p, 34923 value; 34924 (state.t._gsap || gsap.core.getCache(state.t)).uncache = 1; 34925 34926 for (; i < l; i += 2) { 34927 value = state[i + 1]; 34928 p = state[i]; 34929 34930 if (value) { 34931 style[p] = value; 34932 } else if (style[p]) { 34933 style.removeProperty(p.replace(_capsExp, "-$1").toLowerCase()); 34934 } 34935 } 34936 } 34937 }, 34938 _getState = function _getState(element) { 34939 var l = _stateProps.length, 34940 style = element.style, 34941 state = [], 34942 i = 0; 34943 34944 for (; i < l; i++) { 34945 state.push(_stateProps[i], style[_stateProps[i]]); 34946 } 34947 34948 state.t = element; 34949 return state; 34950 }, 34951 _copyState = function _copyState(state, override, omitOffsets) { 34952 var result = [], 34953 l = state.length, 34954 i = omitOffsets ? 8 : 0, 34955 p; 34956 34957 for (; i < l; i += 2) { 34958 p = state[i]; 34959 result.push(p, p in override ? override[p] : state[i + 1]); 34960 } 34961 34962 result.t = state.t; 34963 return result; 34964 }, 34965 _winOffsets = { 34966 left: 0, 34967 top: 0 34968 }, 34969 _parsePosition = function _parsePosition(value, trigger, scrollerSize, direction, scroll, marker, markerScroller, self, scrollerBounds, borderWidth, useFixedPosition, scrollerMax, containerAnimation) { 34970 _isFunction(value) && (value = value(self)); 34971 34972 if (_isString(value) && value.substr(0, 3) === "max") { 34973 value = scrollerMax + (value.charAt(4) === "=" ? _offsetToPx("0" + value.substr(3), scrollerSize) : 0); 34974 } 34975 34976 var time = containerAnimation ? containerAnimation.time() : 0, 34977 p1, 34978 p2, 34979 element; 34980 containerAnimation && containerAnimation.seek(0); 34981 34982 if (!_isNumber(value)) { 34983 _isFunction(trigger) && (trigger = trigger(self)); 34984 var offsets = value.split(" "), 34985 bounds, 34986 localOffset, 34987 globalOffset, 34988 display; 34989 element = _getTarget(trigger) || _body; 34990 bounds = _getBounds(element) || {}; 34991 34992 if ((!bounds || !bounds.left && !bounds.top) && _getComputedStyle(element).display === "none") { 34993 display = element.style.display; 34994 element.style.display = "block"; 34995 bounds = _getBounds(element); 34996 display ? element.style.display = display : element.style.removeProperty("display"); 34997 } 34998 34999 localOffset = _offsetToPx(offsets[0], bounds[direction.d]); 35000 globalOffset = _offsetToPx(offsets[1] || "0", scrollerSize); 35001 value = bounds[direction.p] - scrollerBounds[direction.p] - borderWidth + localOffset + scroll - globalOffset; 35002 markerScroller && _positionMarker(markerScroller, globalOffset, direction, scrollerSize - globalOffset < 20 || markerScroller._isStart && globalOffset > 20); 35003 scrollerSize -= scrollerSize - globalOffset; 35004 } else if (markerScroller) { 35005 _positionMarker(markerScroller, scrollerSize, direction, true); 35006 } 35007 35008 if (marker) { 35009 var position = value + scrollerSize, 35010 isStart = marker._isStart; 35011 p1 = "scroll" + direction.d2; 35012 35013 _positionMarker(marker, position, direction, isStart && position > 20 || !isStart && (useFixedPosition ? Math.max(_body[p1], _docEl[p1]) : marker.parentNode[p1]) <= position + 1); 35014 35015 if (useFixedPosition) { 35016 scrollerBounds = _getBounds(markerScroller); 35017 useFixedPosition && (marker.style[direction.op.p] = scrollerBounds[direction.op.p] - direction.op.m - marker._offset + _px); 35018 } 35019 } 35020 35021 if (containerAnimation && element) { 35022 p1 = _getBounds(element); 35023 containerAnimation.seek(scrollerMax); 35024 p2 = _getBounds(element); 35025 containerAnimation._caScrollDist = p1[direction.p] - p2[direction.p]; 35026 value = value / containerAnimation._caScrollDist * scrollerMax; 35027 } 35028 35029 containerAnimation && containerAnimation.seek(time); 35030 return containerAnimation ? value : Math.round(value); 35031 }, 35032 _prefixExp = /(?:webkit|moz|length|cssText|inset)/i, 35033 _reparent = function _reparent(element, parent, top, left) { 35034 if (element.parentNode !== parent) { 35035 var style = element.style, 35036 p, 35037 cs; 35038 35039 if (parent === _body) { 35040 element._stOrig = style.cssText; 35041 cs = _getComputedStyle(element); 35042 35043 for (p in cs) { 35044 if (!+p && !_prefixExp.test(p) && cs[p] && typeof style[p] === "string" && p !== "0") { 35045 style[p] = cs[p]; 35046 } 35047 } 35048 35049 style.top = top; 35050 style.left = left; 35051 } else { 35052 style.cssText = element._stOrig; 35053 } 35054 35055 gsap.core.getCache(element).uncache = 1; 35056 parent.appendChild(element); 35057 } 35058 }, 35059 _getTweenCreator = function _getTweenCreator(scroller, direction) { 35060 var getScroll = _getScrollFunc(scroller, direction), 35061 prop = "_scroll" + direction.p2, 35062 lastScroll1, 35063 lastScroll2, 35064 getTween = function getTween(scrollTo, vars, initialValue, change1, change2) { 35065 var tween = getTween.tween, 35066 onComplete = vars.onComplete, 35067 modifiers = {}; 35068 tween && tween.kill(); 35069 lastScroll1 = Math.round(initialValue); 35070 vars[prop] = scrollTo; 35071 vars.modifiers = modifiers; 35072 35073 modifiers[prop] = function (value) { 35074 value = _round(getScroll()); 35075 35076 if (value !== lastScroll1 && value !== lastScroll2 && Math.abs(value - lastScroll1) > 2) { 35077 tween.kill(); 35078 getTween.tween = 0; 35079 } else { 35080 value = initialValue + change1 * tween.ratio + change2 * tween.ratio * tween.ratio; 35081 } 35082 35083 lastScroll2 = lastScroll1; 35084 return lastScroll1 = _round(value); 35085 }; 35086 35087 vars.onComplete = function () { 35088 getTween.tween = 0; 35089 onComplete && onComplete.call(tween); 35090 }; 35091 35092 tween = getTween.tween = gsap.to(scroller, vars); 35093 return tween; 35094 }; 35095 35096 scroller[prop] = getScroll; 35097 scroller.addEventListener("wheel", function () { 35098 return getTween.tween && getTween.tween.kill() && (getTween.tween = 0); 35099 }, { 35100 passive: true 35101 }); 35102 return getTween; 35103 }; 35104 35105 _horizontal.op = _vertical; 35106 var ScrollTrigger = function () { 35107 function ScrollTrigger(vars, animation) { 35108 _coreInitted || ScrollTrigger.register(gsap) || console.warn("Please gsap.registerPlugin(ScrollTrigger)"); 35109 this.init(vars, animation); 35110 } 35111 35112 var _proto = ScrollTrigger.prototype; 35113 35114 _proto.init = function init(vars, animation) { 35115 this.progress = this.start = 0; 35116 this.vars && this.kill(1); 35117 35118 if (!_enabled) { 35119 this.update = this.refresh = this.kill = _passThrough; 35120 return; 35121 } 35122 35123 vars = _setDefaults(_isString(vars) || _isNumber(vars) || vars.nodeType ? { 35124 trigger: vars 35125 } : vars, _defaults); 35126 35127 var _vars = vars,
35128 onUpdate = _vars.onUpdate, 35129 toggleClass = _vars.toggleClass, 35130 id = _vars.id, 35131 onToggle = _vars.onToggle, 35132 onRefresh = _vars.onRefresh, 35133 scrub = _vars.scrub, 35134 trigger = _vars.trigger, 35135 pin = _vars.pin, 35136 pinSpacing = _vars.pinSpacing, 35137 invalidateOnRefresh = _vars.invalidateOnRefresh, 35138 anticipatePin = _vars.anticipatePin, 35139 onScrubComplete = _vars.onScrubComplete, 35140 onSnapComplete = _vars.onSnapComplete, 35141 once = _vars.once, 35142 snap = _vars.snap, 35143 pinReparent = _vars.pinReparent, 35144 pinSpacer = _vars.pinSpacer, 35145 containerAnimation = _vars.containerAnimation, 35146 fastScrollEnd = _vars.fastScrollEnd, 35147 preventOverlaps = _vars.preventOverlaps, 35148 direction = vars.horizontal || vars.containerAnimation && vars.horizontal !== false ? _horizontal : _vertical, 35149 isToggle = !scrub && scrub !== 0, 35150 scroller = _getTarget(vars.scroller || _win), 35151 scrollerCache = gsap.core.getCache(scroller), 35152 isViewport = _isViewport(scroller), 35153 useFixedPosition = ("pinType" in vars ? vars.pinType : _getProxyProp(scroller, "pinType") || isViewport && "fixed") === "fixed", 35154 callbacks = [vars.onEnter, vars.onLeave, vars.onEnterBack, vars.onLeaveBack], 35155 toggleActions = isToggle && vars.toggleActions.split(" "), 35156 markers = "markers" in vars ? vars.markers : _defaults.markers, 35157 borderWidth = isViewport ? 0 : parseFloat(_getComputedStyle(scroller)["border" + direction.p2 + _Width]) || 0, 35158 self = this, 35159 onRefreshInit = vars.onRefreshInit && function () { 35160 return vars.onRefreshInit(self); 35161 }, 35162 getScrollerSize = _getSizeFunc(scroller, isViewport, direction), 35163 getScrollerOffsets = _getOffsetsFunc(scroller, isViewport), 35164 lastSnap = 0, 35165 scrollFunc = _getScrollFunc(scroller, direction), 35166 tweenTo, 35167 pinCache, 35168 snapFunc, 35169 scroll1, 35170 scroll2, 35171 start, 35172 end, 35173 markerStart, 35174 markerEnd, 35175 markerStartTrigger, 35176 markerEndTrigger, 35177 markerVars, 35178 change, 35179 pinOriginalState, 35180 pinActiveState, 35181 pinState, 35182 spacer, 35183 offset, 35184 pinGetter, 35185 pinSetter, 35186 pinStart, 35187 pinChange, 35188 spacingStart, 35189 spacerState, 35190 markerStartSetter, 35191 markerEndSetter, 35192 cs, 35193 snap1, 35194 snap2, 35195 scrubTween, 35196 scrubSmooth, 35197 snapDurClamp, 35198 snapDelayedCall, 35199 prevProgress, 35200 prevScroll, 35201 prevAnimProgress, 35202 caMarkerSetter; 35203 35204 self.media = _creatingMedia; 35205 anticipatePin *= 45; 35206 self.scroller = scroller; 35207 self.scroll = containerAnimation ? containerAnimation.time.bind(containerAnimation) : scrollFunc; 35208 scroll1 = scrollFunc(); 35209 self.vars = vars; 35210 animation = animation || vars.animation; 35211 "refreshPriority" in vars && (_sort = 1); 35212 scrollerCache.tweenScroll = scrollerCache.tweenScroll || { 35213 top: _getTweenCreator(scroller, _vertical), 35214 left: _getTweenCreator(scroller, _horizontal) 35215 }; 35216 self.tweenTo = tweenTo = scrollerCache.tweenScroll[direction.p]; 35217 35218 if (animation) { 35219 animation.vars.lazy = false; 35220 animation._initted || animation.vars.immediateRender !== false && vars.immediateRender !== false && animation.render(0, true, true); 35221 self.animation = animation.pause(); 35222 animation.scrollTrigger = self; 35223 scrubSmooth = _isNumber(scrub) && scrub; 35224 scrubSmooth && (scrubTween = gsap.to(animation, { 35225 ease: "power3", 35226 duration: scrubSmooth, 35227 onComplete: function onComplete() { 35228 return onScrubComplete && onScrubComplete(self); 35229 } 35230 })); 35231 snap1 = 0; 35232 id || (id = animation.vars.id); 35233 } 35234 35235 _triggers.push(self); 35236 35237 if (snap) { 35238 if (!_isObject(snap) || snap.push) { 35239 snap = { 35240 snapTo: snap 35241 }; 35242 } 35243 35244 "scrollBehavior" in _body.style && gsap.set(isViewport ? [_body, _docEl] : scroller, { 35245 scrollBehavior: "auto" 35246 }); 35247 snapFunc = _isFunction(snap.snapTo) ? snap.snapTo : snap.snapTo === "labels" ? _getClosestLabel(animation) : snap.snapTo === "labelsDirectional" ? _getLabelAtDirection(animation) : snap.directional !== false ? function (value, st) { 35248 return _snapDirectional(snap.snapTo)(value, st.direction); 35249 } : gsap.utils.snap(snap.snapTo); 35250 snapDurClamp = snap.duration || { 35251 min: 0.1, 35252 max: 2 35253 }; 35254 snapDurClamp = _isObject(snapDurClamp) ? _clamp(snapDurClamp.min, snapDurClamp.max) : _clamp(snapDurClamp, snapDurClamp); 35255 snapDelayedCall = gsap.delayedCall(snap.delay || scrubSmooth / 2 || 0.1, function () { 35256 if (Math.abs(self.getVelocity()) < 10 && !_pointerIsDown && lastSnap !== scrollFunc()) { 35257 var totalProgress = animation && !isToggle ? animation.totalProgress() : self.progress, 35258 velocity = (totalProgress - snap2) / (_getTime() - _time2) * 1000 || 0, 35259 change1 = gsap.utils.clamp(-self.progress, 1 - self.progress, _abs(velocity / 2) * velocity / 0.185), 35260 naturalEnd = self.progress + (snap.inertia === false ? 0 : change1), 35261 endValue = _clamp(0, 1, snapFunc(naturalEnd, self)), 35262 scroll = scrollFunc(), 35263 endScroll = Math.round(start + endValue * change), 35264 _snap = snap, 35265 onStart = _snap.onStart, 35266 _onInterrupt = _snap.onInterrupt, 35267 _onComplete = _snap.onComplete, 35268 tween = tweenTo.tween; 35269 35270 if (scroll <= end && scroll >= start && endScroll !== scroll) { 35271 if (tween && !tween._initted && tween.data <= _abs(endScroll - scroll)) { 35272 return; 35273 } 35274 35275 if (snap.inertia === false) { 35276 change1 = endValue - self.progress; 35277 } 35278 35279 tweenTo(endScroll, { 35280 duration: snapDurClamp(_abs(Math.max(_abs(naturalEnd - totalProgress), _abs(endValue - totalProgress)) * 0.185 / velocity / 0.05 || 0)), 35281 ease: snap.ease || "power3", 35282 data: _abs(endScroll - scroll), 35283 onInterrupt: function onInterrupt() { 35284 return snapDelayedCall.restart(true) && _onInterrupt && _onInterrupt(self); 35285 }, 35286 onComplete: function onComplete() { 35287 lastSnap = scrollFunc(); 35288 snap1 = snap2 = animation && !isToggle ? animation.totalProgress() : self.progress; 35289 onSnapComplete && onSnapComplete(self); 35290 _onComplete && _onComplete(self); 35291 } 35292 }, scroll, change1 * change, endScroll - scroll - change1 * change); 35293 onStart && onStart(self, tweenTo.tween); 35294 } 35295 } else if (self.isActive) { 35296 snapDelayedCall.restart(true); 35297 } 35298 }).pause(); 35299 } 35300 35301 id && (_ids[id] = self); 35302 trigger = self.trigger = _getTarget(trigger || pin); 35303 pin = pin === true ? trigger : _getTarget(pin); 35304 _isString(toggleClass) && (toggleClass = { 35305 targets: trigger, 35306 className: toggleClass 35307 }); 35308 35309 if (pin) { 35310 pinSpacing === false || pinSpacing === _margin || (pinSpacing = !pinSpacing && _getComputedStyle(pin.parentNode).display === "flex" ? false : _padding); 35311 self.pin = pin; 35312 vars.force3D !== false && gsap.set(pin, {
35313 force3D: true 35314 }); 35315 pinCache = gsap.core.getCache(pin); 35316 35317 if (!pinCache.spacer) { 35318 if (pinSpacer) { 35319 pinSpacer = _getTarget(pinSpacer); 35320 pinSpacer && !pinSpacer.nodeType && (pinSpacer = pinSpacer.current || pinSpacer.nativeElement); 35321 pinCache.spacerIsNative = !!pinSpacer; 35322 pinSpacer && (pinCache.spacerState = _getState(pinSpacer)); 35323 } 35324 35325 pinCache.spacer = spacer = pinSpacer || _doc.createElement("div"); 35326 spacer.classList.add("pin-spacer"); 35327 id && spacer.classList.add("pin-spacer-" + id); 35328 pinCache.pinState = pinOriginalState = _getState(pin); 35329 } else { 35330 pinOriginalState = pinCache.pinState; 35331 } 35332 35333 self.spacer = spacer = pinCache.spacer; 35334 cs = _getComputedStyle(pin); 35335 spacingStart = cs[pinSpacing + direction.os2]; 35336 pinGetter = gsap.getProperty(pin); 35337 pinSetter = gsap.quickSetter(pin, direction.a, _px); 35338 35339 _swapPinIn(pin, spacer, cs); 35340 35341 pinState = _getState(pin); 35342 } 35343 35344 if (markers) { 35345 markerVars = _isObject(markers) ? _setDefaults(markers, _markerDefaults) : _markerDefaults; 35346 markerStartTrigger = _createMarker("scroller-start", id, scroller, direction, markerVars, 0); 35347 markerEndTrigger = _createMarker("scroller-end", id, scroller, direction, markerVars, 0, markerStartTrigger); 35348 offset = markerStartTrigger["offset" + direction.op.d2]; 35349 markerStart = _createMarker("start", id, scroller, direction, markerVars, offset, 0, containerAnimation); 35350 markerEnd = _createMarker("end", id, scroller, direction, markerVars, offset, 0, containerAnimation); 35351 containerAnimation && (caMarkerSetter = gsap.quickSetter([markerStart, markerEnd], direction.a, _px)); 35352 35353 if (!useFixedPosition && !(_proxies.length && _getProxyProp(scroller, "fixedMarkers") === true)) { 35354 _makePositionable(isViewport ? _body : scroller); 35355 35356 gsap.set([markerStartTrigger, markerEndTrigger], { 35357 force3D: true 35358 }); 35359 markerStartSetter = gsap.quickSetter(markerStartTrigger, direction.a, _px); 35360 markerEndSetter = gsap.quickSetter(markerEndTrigger, direction.a, _px); 35361 } 35362 } 35363 35364 if (containerAnimation) { 35365 var oldOnUpdate = containerAnimation.vars.onUpdate, 35366 oldParams = containerAnimation.vars.onUpdateParams; 35367 containerAnimation.eventCallback("onUpdate", function () { 35368 self.update(0, 0, 1); 35369 oldOnUpdate && oldOnUpdate.apply(oldParams || []); 35370 }); 35371 } 35372 35373 self.previous = function () { 35374 return _triggers[_triggers.indexOf(self) - 1]; 35375 }; 35376 35377 self.next = function () { 35378 return _triggers[_triggers.indexOf(self) + 1]; 35379 }; 35380 35381 self.revert = function (revert) { 35382 var r = revert !== false || !self.enabled, 35383 prevRefreshing = _refreshing; 35384 35385 if (r !== self.isReverted) { 35386 if (r) { 35387 self.scroll.rec || (self.scroll.rec = scrollFunc()); 35388 prevScroll = Math.max(scrollFunc(), self.scroll.rec || 0); 35389 prevProgress = self.progress; 35390 prevAnimProgress = animation && animation.progress(); 35391 } 35392 35393 markerStart && [markerStart, markerEnd, markerStartTrigger, markerEndTrigger].forEach(function (m) { 35394 return m.style.display = r ? "none" : "block"; 35395 }); 35396 r && (_refreshing = 1); 35397 self.update(r); 35398 _refreshing = prevRefreshing; 35399 pin && (r ? _swapPinOut(pin, spacer, pinOriginalState) : (!pinReparent || !self.isActive) && _swapPinIn(pin, spacer, _getComputedStyle(pin), spacerState)); 35400 self.isReverted = r; 35401 } 35402 }; 35403 35404 self.refresh = function (soft, force) { 35405 if ((_refreshing || !self.enabled) && !force) { 35406 return; 35407 } 35408 35409 if (pin && soft && _lastScrollTime) { 35410 _addListener(ScrollTrigger, "scrollEnd", _softRefresh); 35411 35412 return; 35413 } 35414 35415 _refreshing = 1; 35416 scrubTween && scrubTween.pause(); 35417 invalidateOnRefresh && animation && animation.progress(0).invalidate(); 35418 self.isReverted || self.revert(); 35419 35420 var size = getScrollerSize(), 35421 scrollerBounds = getScrollerOffsets(),
35422 max = containerAnimation ? containerAnimation.duration() : _maxScroll(scroller, direction), 35423 offset = 0, 35424 otherPinOffset = 0, 35425 parsedEnd = vars.end, 35426 parsedEndTrigger = vars.endTrigger || trigger, 35427 parsedStart = vars.start || (vars.start === 0 || !trigger ? 0 : pin ? "0 0" : "0 100%"), 35428 pinnedContainer = vars.pinnedContainer && _getTarget(vars.pinnedContainer), 35429 triggerIndex = trigger && Math.max(0, _triggers.indexOf(self)) || 0, 35430 i = triggerIndex, 35431 cs, 35432 bounds, 35433 scroll, 35434 isVertical, 35435 override, 35436 curTrigger, 35437 curPin, 35438 oppositeScroll, 35439 initted, 35440 revertedPins; 35441 35442 while (i--) { 35443 curTrigger = _triggers[i]; 35444 curTrigger.end || curTrigger.refresh(0, 1) || (_refreshing = 1); 35445 curPin = curTrigger.pin; 35446 35447 if (curPin && (curPin === trigger || curPin === pin) && !curTrigger.isReverted) { 35448 revertedPins || (revertedPins = []); 35449 revertedPins.unshift(curTrigger); 35450 curTrigger.revert(); 35451 } 35452 } 35453 35454 _isFunction(parsedStart) && (parsedStart = parsedStart(self)); 35455 start = _parsePosition(parsedStart, trigger, size, direction, scrollFunc(), markerStart, markerStartTrigger, self, scrollerBounds, borderWidth, useFixedPosition, max, containerAnimation) || (pin ? -0.001 : 0); 35456 _isFunction(parsedEnd) && (parsedEnd = parsedEnd(self)); 35457 35458 if (_isString(parsedEnd) && !parsedEnd.indexOf("+=")) { 35459 if (~parsedEnd.indexOf(" ")) { 35460 parsedEnd = (_isString(parsedStart) ? parsedStart.split(" ")[0] : "") + parsedEnd; 35461 } else { 35462 offset = _offsetToPx(parsedEnd.substr(2), size); 35463 parsedEnd = _isString(parsedStart) ? parsedStart : start + offset; 35464 parsedEndTrigger = trigger; 35465 } 35466 } 35467 35468 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; 35469 change = end - start || (start -= 0.01) && 0.001; 35470 offset = 0; 35471 i = triggerIndex; 35472 35473 while (i--) { 35474 curTrigger = _triggers[i]; 35475 curPin = curTrigger.pin; 35476 35477 if (curPin && curTrigger.start - curTrigger._pinPush < start && !containerAnimation) { 35478 cs = curTrigger.end - curTrigger.start; 35479 (curPin === trigger || curPin === pinnedContainer) && !_isNumber(parsedStart) && (offset += cs); 35480 curPin === pin && (otherPinOffset += cs); 35481 } 35482 } 35483 35484 start += offset; 35485 end += offset; 35486 self._pinPush = otherPinOffset; 35487 35488 if (markerStart && offset) { 35489 cs = {}; 35490 cs[direction.a] = "+=" + offset; 35491 pinnedContainer && (cs[direction.p] = "-=" + scrollFunc()); 35492 gsap.set([markerStart, markerEnd], cs); 35493 } 35494 35495 if (pin) { 35496 cs = _getComputedStyle(pin); 35497 isVertical = direction === _vertical; 35498 scroll = scrollFunc(); 35499 pinStart = parseFloat(pinGetter(direction.a)) + otherPinOffset; 35500 !max && end > 1 && ((isViewport ? _body : scroller).style["overflow-" + direction.a] = "scroll"); 35501 35502 _swapPinIn(pin, spacer, cs); 35503 35504 pinState = _getState(pin); 35505 bounds = _getBounds(pin, true); 35506 oppositeScroll = useFixedPosition && _getScrollFunc(scroller, isVertical ? _horizontal : _vertical)(); 35507 35508 if (pinSpacing) { 35509 spacerState = [pinSpacing + direction.os2, change + otherPinOffset + _px]; 35510 spacerState.t = spacer; 35511 i = pinSpacing === _padding ? _getSize(pin, direction) + change + otherPinOffset : 0; 35512 i && spacerState.push(direction.d, i + _px); 35513 35514 _setState(spacerState); 35515 35516 useFixedPosition && scrollFunc(prevScroll); 35517 } 35518 35519 if (useFixedPosition) { 35520 override = { 35521 top: bounds.top + (isVertical ? scroll - start : oppositeScroll) + _px, 35522 left: bounds.left + (isVertical ? oppositeScroll : scroll - start) + _px, 35523 boxSizing: "border-box", 35524 position: "fixed" 35525 }; 35526 override[_width] = override["max" + _Width] = Math.ceil(bounds.width) + _px; 35527 override[_height] = override["max" + _Height] = Math.ceil(bounds.height) + _px; 35528 override[_margin] = override[_margin + _Top] = override[_margin + _Right] = override[_margin + _Bottom] = override[_margin + _Left] = "0"; 35529 override[_padding] = cs[_padding]; 35530 override[_padding + _Top] = cs[_padding + _Top]; 35531 override[_padding + _Right] = cs[_padding + _Right]; 35532 override[_padding + _Bottom] = cs[_padding + _Bottom]; 35533 override[_padding + _Left] = cs[_padding + _Left]; 35534 pinActiveState = _copyState(pinOriginalState, override, pinReparent); 35535 } 35536 35537 if (animation) { 35538 initted = animation._initted; 35539 35540 _suppressOverwrites(1); 35541 35542 animation.render(animation.duration(), true, true); 35543 pinChange = pinGetter(direction.a) - pinStart + change + otherPinOffset; 35544 change !== pinChange && pinActiveState.splice(pinActiveState.length - 2, 2); 35545 animation.render(0, true, true); 35546 initted || animation.invalidate(); 35547 35548 _suppressOverwrites(0); 35549 } else { 35550 pinChange = change; 35551 } 35552 } else if (trigger && scrollFunc() && !containerAnimation) { 35553 bounds = trigger.parentNode; 35554 35555 while (bounds && bounds !== _body) { 35556 if (bounds._pinOffset) { 35557 start -= bounds._pinOffset; 35558 end -= bounds._pinOffset; 35559 } 35560 35561 bounds = bounds.parentNode; 35562 } 35563 } 35564 35565 revertedPins && revertedPins.forEach(function (t) { 35566 return t.revert(false); 35567 }); 35568 self.start = start; 35569 self.end = end; 35570 scroll1 = scroll2 = scrollFunc(); 35571 35572 if (!containerAnimation) { 35573 scroll1 < prevScroll && scrollFunc(prevScroll); 35574 self.scroll.rec = 0; 35575 } 35576 35577 self.revert(false); 35578 _refreshing = 0; 35579 animation && isToggle && animation._initted && animation.progress() !== prevAnimProgress && animation.progress(prevAnimProgress, true).render(animation.time(), true, true); 35580 35581 if (prevProgress !== self.progress) { 35582 animation && !isToggle && animation.totalProgress(prevProgress, true); 35583 self.progress = prevProgress; 35584 self.update(0, 0, 1); 35585 } 35586 35587 pin && pinSpacing && (spacer._pinOffset = Math.round(self.progress * pinChange)); 35588 onRefresh && onRefresh(self); 35589 }; 35590 35591 self.getVelocity = function () { 35592 return (scrollFunc() - scroll2) / (_getTime() - _time2) * 1000 || 0; 35593 }; 35594 35595 self.endAnimation = function () {
vendor: 8,601 bytes, lines 35596-35834
35596 _endAnimation(self.callbackAnimation); 35597 35598 if (animation) { 35599 scrubTween ? scrubTween.progress(1) : !animation.paused() ? _endAnimation(animation, animation.reversed()) : isToggle || _endAnimation(animation, self.direction < 0, 1); 35600 } 35601 }; 35602 35603 self.getTrailing = function (name) { 35604 var i = _triggers.indexOf(self), 35605 a = self.direction > 0 ? _triggers.slice(0, i).reverse() : _triggers.slice(i + 1); 35606 35607 return _isString(name) ? a.filter(function (t) { 35608 return t.vars.preventOverlaps === name; 35609 }) : a; 35610 }; 35611 35612 self.update = function (reset, recordVelocity, forceFake) { 35613 if (containerAnimation && !forceFake && !reset) { 35614 return; 35615 } 35616 35617 var scroll = self.scroll(), 35618 p = reset ? 0 : (scroll - start) / change, 35619 clipped = p < 0 ? 0 : p > 1 ? 1 : p || 0, 35620 prevProgress = self.progress, 35621 isActive, 35622 wasActive, 35623 toggleState, 35624 action, 35625 stateChanged, 35626 toggled, 35627 isAtMax, 35628 isTakingAction; 35629 35630 if (recordVelocity) { 35631 scroll2 = scroll1; 35632 scroll1 = containerAnimation ? scrollFunc() : scroll; 35633 35634 if (snap) { 35635 snap2 = snap1; 35636 snap1 = animation && !isToggle ? animation.totalProgress() : clipped; 35637 } 35638 } 35639 35640 anticipatePin && !clipped && pin && !_refreshing && !_startup && _lastScrollTime && start < scroll + (scroll - scroll2) / (_getTime() - _time2) * anticipatePin && (clipped = 0.0001); 35641 35642 if (clipped !== prevProgress && self.enabled) { 35643 isActive = self.isActive = !!clipped && clipped < 1; 35644 wasActive = !!prevProgress && prevProgress < 1; 35645 toggled = isActive !== wasActive; 35646 stateChanged = toggled || !!clipped !== !!prevProgress; 35647 self.direction = clipped > prevProgress ? 1 : -1; 35648 self.progress = clipped; 35649 35650 if (stateChanged && !_refreshing) { 35651 toggleState = clipped && !prevProgress ? 0 : clipped === 1 ? 1 : prevProgress === 1 ? 2 : 3; 35652 35653 if (isToggle) { 35654 action = !toggled && toggleActions[toggleState + 1] !== "none" && toggleActions[toggleState + 1] || toggleActions[toggleState]; 35655 isTakingAction = animation && (action === "complete" || action === "reset" || action in animation); 35656 } 35657 } 35658 35659 preventOverlaps && toggled && (isTakingAction || scrub || !animation) && (_isFunction(preventOverlaps) ? preventOverlaps(self) : self.getTrailing(preventOverlaps).forEach(function (t) { 35660 return t.endAnimation(); 35661 })); 35662 35663 if (!isToggle) { 35664 if (scrubTween && !_refreshing && !_startup) { 35665 scrubTween.vars.totalProgress = clipped; 35666 scrubTween.invalidate().restart(); 35667 } else if (animation) { 35668 animation.totalProgress(clipped, !!_refreshing); 35669 } 35670 } 35671 35672 if (pin) { 35673 reset && pinSpacing && (spacer.style[pinSpacing + direction.os2] = spacingStart); 35674 35675 if (!useFixedPosition) { 35676 pinSetter(pinStart + pinChange * clipped); 35677 } else if (stateChanged) { 35678 isAtMax = !reset && clipped > prevProgress && end + 1 > scroll && scroll + 1 >= _maxScroll(scroller, direction); 35679 35680 if (pinReparent) { 35681 if (!reset && (isActive || isAtMax)) { 35682 var bounds = _getBounds(pin, true), 35683 _offset = scroll - start; 35684 35685 _reparent(pin, _body, bounds.top + (direction === _vertical ? _offset : 0) + _px, bounds.left + (direction === _vertical ? 0 : _offset) + _px); 35686 } else { 35687 _reparent(pin, spacer); 35688 } 35689 } 35690 35691 _setState(isActive || isAtMax ? pinActiveState : pinState); 35692 35693 pinChange !== change && clipped < 1 && isActive || pinSetter(pinStart + (clipped === 1 && !isAtMax ? pinChange : 0)); 35694 } 35695 } 35696 35697 snap && !tweenTo.tween && !_refreshing && !_startup && snapDelayedCall.restart(true); 35698 toggleClass && (toggled || once && clipped && (clipped < 1 || !_limitCallbacks)) && _toArray(toggleClass.targets).forEach(function (el) { 35699 return el.classList[isActive || once ? "add" : "remove"](toggleClass.className); 35700 }); 35701 onUpdate && !isToggle && !reset && onUpdate(self); 35702 35703 if (stateChanged && !_refreshing) { 35704 if (isToggle) { 35705 if (isTakingAction) { 35706 if (action === "complete") { 35707 animation.pause().totalProgress(1); 35708 } else if (action === "reset") { 35709 animation.restart(true).pause(); 35710 } else if (action === "restart") { 35711 animation.restart(true); 35712 } else { 35713 animation[action](); 35714 } 35715 } 35716 35717 onUpdate && onUpdate(self); 35718 } 35719 35720 if (toggled || !_limitCallbacks) { 35721 onToggle && toggled && _callback(self, onToggle); 35722 callbacks[toggleState] && _callback(self, callbacks[toggleState]); 35723 once && (clipped === 1 ? self.kill(false, 1) : callbacks[toggleState] = 0); 35724 35725 if (!toggled) { 35726 toggleState = clipped === 1 ? 1 : 3; 35727 callbacks[toggleState] && _callback(self, callbacks[toggleState]); 35728 } 35729 } 35730 35731 if (fastScrollEnd && !isActive && Math.abs(self.getVelocity()) > (_isNumber(fastScrollEnd) ? fastScrollEnd : 2500)) { 35732 _endAnimation(self.callbackAnimation); 35733 35734 scrubTween ? scrubTween.progress(1) : _endAnimation(animation, !clipped, 1); 35735 } 35736 } else if (isToggle && onUpdate && !_refreshing) { 35737 onUpdate(self); 35738 } 35739 } 35740 35741 if (markerEndSetter) { 35742 var n = containerAnimation ? scroll / containerAnimation.duration() * (containerAnimation._caScrollDist || 0) : scroll; 35743 markerStartSetter(n + (markerStartTrigger._isFlipped ? 1 : 0)); 35744 markerEndSetter(n); 35745 } 35746 35747 caMarkerSetter && caMarkerSetter(-scroll / containerAnimation.duration() * (containerAnimation._caScrollDist || 0)); 35748 }; 35749 35750 self.enable = function (reset, refresh) { 35751 if (!self.enabled) { 35752 self.enabled = true; 35753 35754 _addListener(scroller, "resize", _onResize); 35755 35756 _addListener(scroller, "scroll", _onScroll); 35757 35758 onRefreshInit && _addListener(ScrollTrigger, "refreshInit", onRefreshInit); 35759 35760 if (reset !== false) { 35761 self.progress = prevProgress = 0; 35762 scroll1 = scroll2 = lastSnap = scrollFunc(); 35763 } 35764 35765 refresh !== false && self.refresh(); 35766 } 35767 }; 35768 35769 self.getTween = function (snap) { 35770 return snap && tweenTo ? tweenTo.tween : scrubTween; 35771 }; 35772 35773 self.disable = function (reset, allowAnimation) { 35774 if (self.enabled) { 35775 reset !== false && self.revert(); 35776 self.enabled = self.isActive = false; 35777 allowAnimation || scrubTween && scrubTween.pause(); 35778 prevScroll = 0; 35779 pinCache && (pinCache.uncache = 1); 35780 onRefreshInit && _removeListener(ScrollTrigger, "refreshInit", onRefreshInit); 35781 35782 if (snapDelayedCall) { 35783 snapDelayedCall.pause(); 35784 tweenTo.tween && tweenTo.tween.kill() && (tweenTo.tween = 0); 35785 } 35786 35787 if (!isViewport) { 35788 var i = _triggers.length; 35789 35790 while (i--) { 35791 if (_triggers[i].scroller === scroller && _triggers[i] !== self) { 35792 return; 35793 } 35794 } 35795 35796 _removeListener(scroller, "resize", _onResize); 35797 35798 _removeListener(scroller, "scroll", _onScroll); 35799 } 35800 } 35801 }; 35802 35803 self.kill = function (revert, allowAnimation) { 35804 self.disable(revert, allowAnimation); 35805 scrubTween && scrubTween.kill(); 35806 id && delete _ids[id]; 35807 35808 var i = _triggers.indexOf(self); 35809 35810 _triggers.splice(i, 1); 35811 35812 i === _i && _direction > 0 && _i--; 35813 i = 0; 35814 35815 _triggers.forEach(function (t) { 35816 return t.scroller === self.scroller && (i = 1); 35817 }); 35818 35819 i || (self.scroll.rec = 0); 35820 35821 if (animation) { 35822 animation.scrollTrigger = null; 35823 revert && animation.render(-1); 35824 allowAnimation || animation.kill(); 35825 } 35826 35827 markerStart && [markerStart, markerEnd, markerStartTrigger, markerEndTrigger].forEach(function (m) { 35828 return m.parentNode && m.parentNode.removeChild(m); 35829 }); 35830 35831 if (pin) { 35832 pinCache && (pinCache.uncache = 1); 35833 i = 0; 35834
35835 _triggers.forEach(function (t) { 35836 return t.pin === pin && i++; 35837 }); 35838 35839 i || (pinCache.spacer = 0); 35840 } 35841 }; 35842 35843 self.enable(false, false); 35844 !animation || !animation.add || change ? self.refresh() : gsap.delayedCall(0.01, function () { 35845 return start || end || self.refresh(); 35846 }) && (change = 0.01) && (start = end = 0); 35847 }; 35848 35849 ScrollTrigger.register = function register(core) { 35850 if (!_coreInitted) { 35851 gsap = core || _getGSAP(); 35852 35853 if (_windowExists() && window.document) { 35854 _win = window; 35855 _doc = document; 35856 _docEl = _doc.documentElement; 35857 _body = _doc.body; 35858 } 35859 35860 if (gsap) { 35861 _toArray = gsap.utils.toArray; 35862 _clamp = gsap.utils.clamp; 35863 _suppressOverwrites = gsap.core.suppressOverwrites || _passThrough; 35864 gsap.core.globals("ScrollTrigger", ScrollTrigger); 35865 35866 if (_body) { 35867 _raf = _win.requestAnimationFrame || function (f) { 35868 return setTimeout(f, 16); 35869 }; 35870 35871 _addListener(_win, "wheel", _onScroll); 35872 35873 _root = [_win, _doc, _docEl, _body]; 35874 35875 _addListener(_doc, "scroll", _onScroll); 35876 35877 var bodyStyle = _body.style, 35878 border = bodyStyle.borderTopStyle, 35879 bounds; 35880 bodyStyle.borderTopStyle = "solid"; 35881 bounds = _getBounds(_body); 35882 _vertical.m = Math.round(bounds.top + _vertical.sc()) || 0; 35883 _horizontal.m = Math.round(bounds.left + _horizontal.sc()) || 0; 35884 border ? bodyStyle.borderTopStyle = border : bodyStyle.removeProperty("border-top-style"); 35885 _syncInterval = setInterval(_sync, 200); 35886 gsap.delayedCall(0.5, function () { 35887 return _startup = 0; 35888 }); 35889 35890 _addListener(_doc, "touchcancel", _passThrough); 35891 35892 _addListener(_body, "touchstart", _passThrough); 35893 35894 _multiListener(_addListener, _doc, "pointerdown,touchstart,mousedown", function () { 35895 return _pointerIsDown = 1; 35896 }); 35897 35898 _multiListener(_addListener, _doc, "pointerup,touchend,mouseup", function () { 35899 return _pointerIsDown = 0; 35900 }); 35901 35902 _transformProp = gsap.utils.checkPrefix("transform"); 35903 35904 _stateProps.push(_transformProp); 35905 35906 _coreInitted = _getTime(); 35907 _resizeDelay = gsap.delayedCall(0.2, _refreshAll).pause(); 35908 _autoRefresh = [_doc, "visibilitychange", function () { 35909 var w = _win.innerWidth, 35910 h = _win.innerHeight; 35911 35912 if (_doc.hidden) { 35913 _prevWidth = w; 35914 _prevHeight = h; 35915 } else if (_prevWidth !== w || _prevHeight !== h) { 35916 _onResize(); 35917 } 35918 }, _doc, "DOMContentLoaded", _refreshAll, _win, "load", function () { 35919 return _lastScrollTime || _refreshAll(); 35920 }, _win, "resize", _onResize]; 35921 35922 _iterateAutoRefresh(_addListener); 35923 } 35924 } 35925 } 35926 35927 return _coreInitted; 35928 }; 35929 35930 ScrollTrigger.defaults = function defaults(config) { 35931 for (var p in config) { 35932 _defaults[p] = config[p]; 35933 } 35934 }; 35935 35936 ScrollTrigger.kill = function kill() { 35937 _enabled = 0; 35938 35939 _triggers.slice(0).forEach(function (trigger) { 35940 return trigger.kill(1); 35941 }); 35942 }; 35943 35944 ScrollTrigger.config = function config(vars) { 35945 "limitCallbacks" in vars && (_limitCallbacks = !!vars.limitCallbacks); 35946 var ms = vars.syncInterval; 35947 ms && clearInterval(_syncInterval) || (_syncInterval = ms) && setInterval(_sync, ms); 35948 35949 if ("autoRefreshEvents" in vars) { 35950 _iterateAutoRefresh(_removeListener) || _iterateAutoRefresh(_addListener, vars.autoRefreshEvents || "none"); 35951 _ignoreResize = (vars.autoRefreshEvents + "").indexOf("resize") === -1; 35952 } 35953 }; 35954 35955 ScrollTrigger.scrollerProxy = function scrollerProxy(target, vars) { 35956 var t = _getTarget(target), 35957 i = _scrollers.indexOf(t), 35958 isViewport = _isViewport(t); 35959 35960 if (~i) { 35961 _scrollers.splice(i, isViewport ? 6 : 2); 35962 } 35963 35964 isViewport ? _proxies.unshift(_win, vars, _body, vars, _docEl, vars) : _proxies.unshift(t, vars); 35965 }; 35966 35967 ScrollTrigger.matchMedia = function matchMedia(vars) { 35968 var mq, p, i, func, result; 35969 35970 for (p in vars) { 35971 i = _media.indexOf(p); 35972 func = vars[p]; 35973 _creatingMedia = p; 35974 35975 if (p === "all") { 35976 func(); 35977 } else { 35978 mq = _win.matchMedia(p); 35979 35980 if (mq) { 35981 mq.matches && (result = func()); 35982 35983 if (~i) { 35984 _media[i + 1] = _combineFunc(_media[i + 1], func); 35985 _media[i + 2] = _combineFunc(_media[i + 2], result); 35986 } else { 35987 i = _media.length; 35988 35989 _media.push(p, func, result); 35990 35991 mq.addListener ? mq.addListener(_onMediaChange) : mq.addEventListener("change", _onMediaChange); 35992 } 35993 35994 _media[i + 3] = mq.matches; 35995 } 35996 } 35997 35998 _creatingMedia = 0; 35999 } 36000 36001 return _media; 36002 }; 36003 36004 ScrollTrigger.clearMatchMedia = function clearMatchMedia(query) { 36005 query || (_media.length = 0); 36006 query = _media.indexOf(query); 36007 query >= 0 && _media.splice(query, 4); 36008 }; 36009 36010 ScrollTrigger.isInViewport = function isInViewport(element, ratio, horizontal) { 36011 var bounds = (_isString(element) ? _getTarget(element) : element).getBoundingClientRect(), 36012 offset = bounds[horizontal ? _width : _height] * ratio || 0; 36013 return horizontal ? bounds.right - offset > 0 && bounds.left + offset < _win.innerWidth : bounds.bottom - offset > 0 && bounds.top + offset < _win.innerHeight; 36014 }; 36015 36016 ScrollTrigger.positionInViewport = function positionInViewport(element, referencePoint, horizontal) { 36017 _isString(element) && (element = _getTarget(element)); 36018 var bounds = element.getBoundingClientRect(), 36019 size = bounds[horizontal ? _width : _height], 36020 offset = referencePoint == null ? size / 2 : referencePoint in _keywords ? _keywords[referencePoint] * size : ~referencePoint.indexOf("%") ? parseFloat(referencePoint) * size / 100 : parseFloat(referencePoint) || 0; 36021 return horizontal ? (bounds.left + offset) / _win.innerWidth : (bounds.top + offset) / _win.innerHeight; 36022 }; 36023 36024 return ScrollTrigger; 36025 }(); 36026 ScrollTrigger.version = "3.8.0"; 36027 36028 ScrollTrigger.saveStyles = function (targets) {
36029 return targets ? _toArray(targets).forEach(function (target) { 36030 if (target && target.style) { 36031 var i = _savedStyles.indexOf(target); 36032 36033 i >= 0 && _savedStyles.splice(i, 5); 36034 36035 _savedStyles.push(target, target.style.cssText, target.getBBox && target.getAttribute("transform"), gsap.core.getCache(target), _creatingMedia); 36036 } 36037 }) : _savedStyles; 36038 }; 36039 36040 ScrollTrigger.revert = function (soft, media) { 36041 return _revertAll(!soft, media); 36042 }; 36043 36044 ScrollTrigger.create = function (vars, animation) { 36045 return new ScrollTrigger(vars, animation); 36046 }; 36047 36048 ScrollTrigger.refresh = function (safe) { 36049 return safe ? _onResize() : (_coreInitted || ScrollTrigger.register()) && _refreshAll(true); 36050 }; 36051 36052 ScrollTrigger.update = _updateAll; 36053 ScrollTrigger.clearScrollMemory = _clearScrollMemory; 36054 36055 ScrollTrigger.maxScroll = function (element, horizontal) { 36056 return _maxScroll(element, horizontal ? _horizontal : _vertical); 36057 }; 36058 36059 ScrollTrigger.getScrollFunc = function (element, horizontal) { 36060 return _getScrollFunc(_getTarget(element), horizontal ? _horizontal : _vertical); 36061 }; 36062 36063 ScrollTrigger.getById = function (id) { 36064 return _ids[id]; 36065 }; 36066 36067 ScrollTrigger.getAll = function () { 36068 return _triggers.slice(0); 36069 }; 36070 36071 ScrollTrigger.isScrolling = function () { 36072 return !!_lastScrollTime; 36073 }; 36074 36075 ScrollTrigger.snapDirectional = _snapDirectional; 36076 36077 ScrollTrigger.addEventListener = function (type, callback) { 36078 var a = _listeners[type] || (_listeners[type] = []); 36079 ~a.indexOf(callback) || a.push(callback); 36080 }; 36081 36082 ScrollTrigger.removeEventListener = function (type, callback) { 36083 var a = _listeners[type], 36084 i = a && a.indexOf(callback); 36085 i >= 0 && a.splice(i, 1); 36086 }; 36087 36088 ScrollTrigger.batch = function (targets, vars) { 36089 var result = [], 36090 varsCopy = {}, 36091 interval = vars.interval || 0.016, 36092 batchMax = vars.batchMax || 1e9, 36093 proxyCallback = function proxyCallback(type, callback) { 36094 var elements = [], 36095 triggers = [], 36096 delay = gsap.delayedCall(interval, function () { 36097 callback(elements, triggers); 36098 elements = []; 36099 triggers = []; 36100 }).pause(); 36101 return function (self) { 36102 elements.length || delay.restart(true); 36103 elements.push(self.trigger); 36104 triggers.push(self); 36105 batchMax <= elements.length && delay.progress(1); 36106 }; 36107 }, 36108 p; 36109 36110 for (p in vars) { 36111 varsCopy[p] = p.substr(0, 2) === "on" && _isFunction(vars[p]) && p !== "onRefreshInit" ? proxyCallback(p, vars[p]) : vars[p]; 36112 } 36113 36114 if (_isFunction(batchMax)) { 36115 batchMax = batchMax(); 36116 36117 _addListener(ScrollTrigger, "refresh", function () { 36118 return batchMax = vars.batchMax(); 36119 }); 36120 } 36121 36122 _toArray(targets).forEach(function (target) { 36123 var config = {}; 36124 36125 for (p in varsCopy) { 36126 config[p] = varsCopy[p]; 36127 } 36128 36129 config.trigger = target; 36130 result.push(ScrollTrigger.create(config)); 36131 }); 36132 36133 return result; 36134 }; 36135 36136 ScrollTrigger.sort = function (func) { 36137 return _triggers.sort(func || function (a, b) { 36138 return (a.vars.refreshPriority || 0) * -1e6 + a.start - (b.start + (b.vars.refreshPriority || 0) * -1e6); 36139 }); 36140 }; 36141 36142 _getGSAP() && gsap.registerPlugin(ScrollTrigger); 36143 36144 exports.ScrollTrigger = ScrollTrigger; 36145 exports.default = ScrollTrigger; 36146 36147 Object.defineProperty(exports, '__esModule', { value: true }); 36148 36149}))); 36150 36151/* ======================================================================== 36152 * Bootstrap: collapse.js v3.1.1 36153 * http://getbootstrap.com/javascript/#collapse 36154 * ======================================================================== 36155 * Copyright 2011-2014 Twitter, Inc. 36156 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 36157 * ======================================================================== */ 36158 36159 36160+function ($) { 36161 'use strict'; 36162 36163 // COLLAPSE PUBLIC CLASS DEFINITION 36164 // ================================ 36165 36166 var Collapse = function (element, options) { 36167 this.$element = $(element) 36168 this.options = $.extend({}, Collapse.DEFAULTS, options) 36169 this.transitioning = null 36170 36171 if (this.options.parent) this.$parent = $(this.options.parent) 36172 if (this.options.toggle) this.toggle() 36173 } 36174 36175 Collapse.DEFAULTS = { 36176 toggle: true 36177 } 36178 36179 Collapse.prototype.dimension = function () { 36180 var hasWidth = this.$element.hasClass('width') 36181 return hasWidth ? 'width' : 'height' 36182 } 36183 36184 Collapse.prototype.show = function () { 36185 if (this.transitioning || this.$element.hasClass('in')) return 36186 36187 var startEvent = $.Event('show.bs.collapse') 36188 this.$element.trigger(startEvent) 36189 if (startEvent.isDefaultPrevented()) return 36190 36191 var actives = this.$parent && this.$parent.find('> .panel > .in') 36192 36193 if (actives && actives.length) { 36194 var hasData = actives.data('bs.collapse') 36195 if (hasData && hasData.transitioning) return 36196 //START UNCODE EDIT 36197 var parentNoToggle = this.$parent.data('no-toggle') 36198 if (!parentNoToggle) { 36199 actives.collapse('hide') 36200 } 36201 //END UNCODE EDIT 36202 hasData || actives.data('bs.collapse', null) 36203 } 36204 36205 var dimension = this.dimension() 36206 36207 this.$element 36208 .removeClass('collapse') 36209 .addClass('collapsing')[dimension](0) 36210 36211 this.transitioning = 1 36212 36213 var complete = function (e) { 36214 if (e && e.target != this.$element[0]) return 36215 this.$element 36216 .removeClass('collapsing') 36217 .addClass('collapse in')[dimension]('auto') 36218 this.transitioning = 0 36219 this.$element.trigger('shown.bs.collapse') 36220 } 36221 36222 if (!$.support.transition) return complete.call(this) 36223 36224 var scrollSize = $.camelCase(['scroll', dimension].join('-')) 36225 36226 this.$element 36227 .one($.support.transition.end, $.proxy(complete, this)) 36228 .emulateTransitionEnd(350)[dimension](this.$element[0][scrollSize]) 36229 } 36230 36231 Collapse.prototype.hide = function () { 36232 if (this.transitioning || !this.$element.hasClass('in')) return 36233 36234 var startEvent = $.Event('hide.bs.collapse') 36235 this.$element.trigger(startEvent) 36236 if (startEvent.isDefaultPrevented()) return 36237 36238 var dimension = this.dimension() 36239 36240 this.$element[dimension](this.$element[dimension]())[0].offsetHeight 36241 36242 this.$element 36243 .addClass('collapsing') 36244 .removeClass('collapse') 36245 .removeClass('in') 36246 36247 this.transitioning = 1 36248 36249 var complete = function (e) { 36250 if (e && e.target != this.$element[0]) return 36251 this.transitioning = 0 36252 this.$element 36253 .trigger('hidden.bs.collapse') 36254 .removeClass('collapsing') 36255 .addClass('collapse') 36256 } 36257 36258 if (!$.support.transition) return complete.call(this) 36259 36260 this.$element 36261 [dimension](0) 36262 .one($.support.transition.end, $.proxy(complete, this)) 36263 .emulateTransitionEnd(350) 36264 } 36265 36266 Collapse.prototype.toggle = function () { 36267 this[this.$element.hasClass('in') ? 'hide' : 'show']() 36268 } 36269 36270 36271 // COLLAPSE PLUGIN DEFINITION 36272 // ========================== 36273 36274 var old = $.fn.collapse 36275 36276 $.fn.collapse = function (option) { 36277 return this.each(function () { 36278 var $this = $(this) 36279 var data = $this.data('bs.collapse') 36280 var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option) 36281 36282 if (!data && options.toggle && option == 'show') option = !option 36283 if (!data) $this.data('bs.collapse', (data = new Collapse(this, options))) 36284 if (typeof option == 'string') data[option]() 36285 }) 36286 } 36287 36288 $.fn.collapse.Constructor = Collapse 36289 36290 36291 // COLLAPSE NO CONFLICT 36292 // ==================== 36293 36294 $.fn.collapse.noConflict = function () { 36295 $.fn.collapse = old 36296 return this 36297 } 36298 36299 36300 // COLLAPSE DATA-API 36301 // ================= 36302 36303 $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) { 36304 var $this = $(this), href 36305 var target = $this.attr('data-target') 36306 || e.preventDefault() 36307 || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7 36308 //Edited by Uncode to replace ID in panel [START] 36309 var _target = href.replace(/^#/, ""); 36310 if ( $('[data-id="' + _target + '"]').length ) { 36311 var $target = $('[data-id="' + _target + '"]') 36312 } else { 36313 var $target = $(target) 36314 } 36315 //Edited by Uncode to replace ID in panel [END] 36316 var data = $target.data('bs.collapse') 36317 var option = data ? 'toggle' : $this.data() 36318 var parent = $this.attr('data-parent') 36319 var $parent = parent && $(parent) 36320 36321 if (!data || !data.transitioning) { 36322 if ($parent) $parent.find('[data-toggle="collapse"][data-parent="' + parent + '"]').not($this).addClass('collapsed') 36323 $this[$target.hasClass('in') ? 'addClass' : 'removeClass']('collapsed') 36324 } 36325 36326 $target.collapse(option) 36327 }) 36328 36329}(jQuery); 36330 36331/* ======================================================================== 36332 * Bootstrap: tab.js v3.1.1 36333 * http://getbootstrap.com/javascript/#tabs 36334 * ======================================================================== 36335 * Copyright 2011-2014 Twitter, Inc. 36336 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 36337 * ======================================================================== */ 36338 36339 36340+function ($) { 36341 'use strict'; 36342 36343 // TAB CLASS DEFINITION 36344 // ==================== 36345 36346 var Tab = function (element) { 36347 this.element = $(element) 36348 } 36349 36350 Tab.prototype.show = function () { 36351 var $this = this.element 36352 var $ul = $this.closest('ul:not(.dropdown-menu)') 36353 var selector = $this.data('target') 36354 36355 if (!selector) { 36356 selector = $this.attr('href') 36357 selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7 36358 } 36359 36360 if ($this.parent('li').hasClass('active')) return 36361 36362 var previous = $ul.find('.active:last a')[0] 36363 var e = $.Event('show.bs.tab', { 36364 relatedTarget: previous 36365 }) 36366 36367 $this.trigger(e) 36368 36369 if (e.isDefaultPrevented()) return 36370 36371 //Edited by Uncode to replace ID in panel [START] 36372 var _target = selector.replace(/^#/, ""); 36373 if ( $('[data-id="' + _target + '"]').length ) 36374 var $target = $('[data-id="' + _target + '"]') 36375 else 36376 var $target = $(selector) 36377 //Edited by Uncode to replace ID in panel [END] 36378 36379 this.activate($this.parent('li'), $ul) 36380 this.activate($target, $target.parent(), function () { 36381 $this.trigger({ 36382 type: 'shown.bs.tab', 36383 relatedTarget: previous 36384 }) 36385 }) 36386 } 36387 36388 Tab.prototype.activate = function (element, container, callback) { 36389 var $active = container.find('> .active').add(container.find('> .active > .active')) 36390 var transition = callback 36391 && $.support.transition 36392 && $active.hasClass('fade') 36393 36394 function next() { 36395 $active 36396 .removeClass('active') 36397 .find('> .dropdown-menu > .active') 36398 .removeClass('active') 36399 36400 $active 36401 .find('.tab-excerpt').slideUp(); 36402 36403 element.addClass('active') 36404 $('.tab-excerpt', element).slideDown(); 36405 36406 //if (transition) { 36407 element[0].offsetWidth // reflow for transition 36408 element.add($active).addClass('in') 36409 /*} else { 36410 element.removeClass('fade') 36411 }*/ 36412 36413 if (element.parent('.dropdown-menu')) { 36414 element.closest('li.dropdown').addClass('active') 36415 } 36416 36417 callback && callback() 36418 } 36419 36420 transition ? 36421 $active 36422 .one($.support.transition.end, next) 36423 .emulateTransitionEnd(150) : 36424 next() 36425 36426 $active.removeClass('in') 36427 } 36428 36429 36430 // TAB PLUGIN DEFINITION 36431 // ===================== 36432 36433 var old = $.fn.tab 36434 36435 $.fn.tab = function ( option ) { 36436 return this.each(function () { 36437 var $this = $(this) 36438 var data = $this.data('bs.tab') 36439 36440 if (!data) $this.data('bs.tab', (data = new Tab(this))) 36441 if (typeof option == 'string') data[option]() 36442 }) 36443 } 36444 36445 $.fn.tab.Constructor = Tab 36446 36447 36448 // TAB NO CONFLICT 36449 // =============== 36450 36451 $.fn.tab.noConflict = function () { 36452 $.fn.tab = old 36453 return this 36454 } 36455 36456 36457 // TAB DATA-API 36458 // ============ 36459 36460 $(document).on('click.bs.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) { 36461 e.preventDefault() 36462 $(this).tab('show') 36463 }) 36464 36465}(jQuery); 36466 36467/* ======================================================================== 36468 * Bootstrap: tooltip.js v3.1.1 36469 * http://getbootstrap.com/javascript/#tooltip 36470 * Inspired by the original jQuery.tipsy by Jason Frame 36471 * ======================================================================== 36472 * Copyright 2011-2014 Twitter, Inc. 36473 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 36474 * ======================================================================== */ 36475 36476 36477+function ($) { 36478 'use strict'; 36479 36480 // TOOLTIP PUBLIC CLASS DEFINITION 36481 // =============================== 36482 36483 var Tooltip = function (element, options) { 36484 this.type = 36485 this.options = 36486 this.enabled = 36487 this.timeout = 36488 this.hoverState = 36489 this.$element = null 36490 36491 this.init('tooltip', element, options) 36492 } 36493 36494 Tooltip.DEFAULTS = { 36495 animation: true, 36496 placement: 'top', 36497 selector: false, 36498 template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>', 36499 trigger: 'hover focus', 36500 title: '', 36501 delay: 0, 36502 html: false, 36503 container: false, 36504 viewport: { 36505 selector: 'body', 36506 padding: 0 36507 } 36508 } 36509 36510 Tooltip.prototype.init = function (type, element, options) { 36511 this.enabled = true 36512 this.type = type 36513 this.$element = $(element) 36514 this.options = this.getOptions(options) 36515 this.$viewport = this.options.viewport && $(this.options.viewport.selector || this.options.viewport) 36516 36517 var triggers = this.options.trigger.split(' ') 36518 36519 for (var i = triggers.length; i--;) { 36520 var trigger = triggers[i] 36521 36522 if (trigger == 'click') { 36523 this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this)) 36524 } else if (trigger != 'manual') { 36525 var eventIn = trigger == 'hover' ? 'mouseenter' : 'focusin' 36526 var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout' 36527 36528 this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this)) 36529 this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this)) 36530 } 36531 } 36532 36533 this.options.selector ? 36534 (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) : 36535 this.fixTitle() 36536 } 36537 36538 Tooltip.prototype.getDefaults = function () { 36539 return Tooltip.DEFAULTS 36540 } 36541 36542 Tooltip.prototype.getOptions = function (options) { 36543 options = $.extend({}, this.getDefaults(), this.$element.data(), options) 36544 36545 if (options.delay && typeof options.delay == 'number') { 36546 options.delay = { 36547 show: options.delay, 36548 hide: options.delay 36549 } 36550 } 36551 36552 return options 36553 } 36554 36555 Tooltip.prototype.getDelegateOptions = function () { 36556 var options = {} 36557 var defaults = this.getDefaults() 36558 36559 this._options && $.each(this._options, function (key, value) { 36560 if (defaults[key] != value) options[key] = value 36561 }) 36562 36563 return options 36564 } 36565 36566 Tooltip.prototype.enter = function (obj) { 36567 var self = obj instanceof this.constructor ? 36568 obj : $(obj.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type) 36569 36570 clearTimeout(self.timeout) 36571 36572 self.hoverState = 'in' 36573 36574 if (!self.options.delay || !self.options.delay.show) return self.show() 36575 36576 self.timeout = setTimeout(function () { 36577 if (self.hoverState == 'in') self.show() 36578 }, self.options.delay.show) 36579 } 36580 36581 Tooltip.prototype.leave = function (obj) { 36582 var self = obj instanceof this.constructor ? 36583 obj : $(obj.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type) 36584 36585 clearTimeout(self.timeout) 36586 36587 self.hoverState = 'out' 36588 36589 if (!self.options.delay || !self.options.delay.hide) return self.hide() 36590 36591 self.timeout = setTimeout(function () { 36592 if (self.hoverState == 'out') self.hide() 36593 }, self.options.delay.hide) 36594 } 36595 36596 Tooltip.prototype.show = function () { 36597 var e = $.Event('show.bs.' + this.type) 36598 36599 if (this.hasContent() && this.enabled) { 36600 this.$element.trigger(e) 36601 36602 if (e.isDefaultPrevented()) return 36603 var that = this; 36604 36605 var $tip = this.tip() 36606 36607 this.setContent() 36608 36609 if (this.options.animation) $tip.addClass('fade') 36610 36611 var placement = typeof this.options.placement == 'function' ? 36612 this.options.placement.call(this, $tip[0], this.$element[0]) : 36613 this.options.placement 36614 36615 var autoToken = /\s?auto?\s?/i 36616 var autoPlace = autoToken.test(placement) 36617 if (autoPlace) placement = placement.replace(autoToken, '') || 'top' 36618 36619 $tip 36620 .detach() 36621 .cs
36621s({ top: 0, left: 0, display: 'block' }) 36622 .addClass(placement) 36623 36624 this.options.container ? $tip.appendTo($(document).find(this.options.container)) : $tip.insertAfter(this.$element) 36625 36626 var pos = this.getPosition() 36627 var actualWidth = $tip[0].offsetWidth 36628 var actualHeight = $tip[0].offsetHeight 36629 36630 if (autoPlace) { 36631 var orgPlacement = placement 36632 var $parent = this.$element.parent() 36633 var parentDim = this.getPosition($parent) 36634 36635 placement = placement == 'bottom' && pos.top + pos.height + actualHeight - parentDim.scroll > parentDim.height ? 'top' : 36636 placement == 'top' && pos.top - parentDim.scroll - actualHeight < 0 ? 'bottom' : 36637 placement == 'right' && pos.right + actualWidth > parentDim.width ? 'left' : 36638 placement == 'left' && pos.left - actualWidth < parentDim.left ? 'right' : 36639 placement 36640 36641 $tip 36642 .removeClass(orgPlacement) 36643 .addClass(placement) 36644 } 36645 36646 var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight) 36647 36648 this.applyPlacement(calculatedOffset, placement) 36649 this.hoverState = null 36650 36651 var complete = function() { 36652 that.$element.trigger('shown.bs.' + that.type) 36653 } 36654 36655 $.support.transition && this.$tip.hasClass('fade') ? 36656 $tip 36657 .one($.support.transition.end, complete) 36658 .emulateTransitionEnd(150) : 36659 complete() 36660 } 36661 } 36662 36663 Tooltip.prototype.applyPlacement = function (offset, placement) { 36664 var $tip = this.tip() 36665 var width = $tip[0].offsetWidth 36666 var height = $tip[0].offsetHeight 36667 36668 // manually read margins because getBoundingClientRect includes difference 36669 var marginTop = parseInt($tip.css('margin-top'), 10) 36670 var marginLeft = parseInt($tip.css('margin-left'), 10) 36671 36672 // we must check for NaN for ie 8/9 36673 if (isNaN(marginTop)) marginTop = 0 36674 if (isNaN(marginLeft)) marginLeft = 0 36675 36676 offset.top = offset.top + marginTop 36677 offset.left = offset.left + marginLeft 36678 36679 // $.fn.offset doesn't round pixel values 36680 // so we use setOffset directly with our own function B-0 36681 $.offset.setOffset($tip[0], $.extend({ 36682 using: function (props) { 36683 $tip.css({ 36684 top: Math.round(props.top), 36685 left: Math.round(props.left) 36686 }) 36687 } 36688 }, offset), 0) 36689 36690 $tip.addClass('in') 36691 36692 // check to see if placing tip in new offset caused the tip to resize itself 36693 var actualWidth = $tip[0].offsetWidth 36694 var actualHeight = $tip[0].offsetHeight 36695 36696 if (placement == 'top' && actualHeight != height) { 36697 offset.top = offset.top + height - actualHeight 36698 } 36699 36700 var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight) 36701 36702 if (delta.left) offset.left += delta.left 36703 else offset.top += delta.top 36704 36705 var arrowDelta = delta.left ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight 36706 var arrowPosition = delta.left ? 'left' : 'top' 36707 var arrowOffsetPosition = delta.left ? 'offsetWidth' : 'offsetHeight' 36708 36709 $tip.offset(offset) 36710 this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], arrowPosition) 36711 } 36712 36713 Tooltip.prototype.replaceArrow = function (delta, dimension, position) { 36714 this.arrow().css(position, delta ? (50 * (1 - delta / dimension) + '%') : '') 36715 } 36716 36717 Tooltip.prototype.setContent = function () { 36718 var $tip = this.tip() 36719 var title = this.getTitle() 36720 36721 $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title) 36722 $tip.removeClass('fade in top bottom left right') 36723 } 36724 36725 Tooltip.prototype.hide = function () { 36726 var that = this 36727 var $tip = this.tip() 36728 var e = $.Event('hide.bs.' + this.type) 36729 36730 function complete() { 36731 if (that.hoverState != 'in') $tip.detach() 36732 that.$element.trigger('hidden.bs.' + that.type) 36733 } 36734 36735 this.$element.trigger(e) 36736 36737 if (e.isDefaultPrevented()) return 36738 36739 $tip.removeClass('in') 36740 36741 $.support.transition && this.$tip.hasClass('fade') ? 36742 $tip 36743 .one($.support.transition.end, complete) 36744 .emulateTransitionEnd(150) : 36745 complete() 36746 36747 this.hoverState = null 36748 36749 return this 36750 } 36751 36752 Tooltip.prototype.fixTitle = function () { 36753 var $e = this.$element 36754 if ($e.attr('title') || typeof($e.attr('data-original-title')) != 'string') { 36755 $e.attr('data-original-title', $e.attr('title') || '').attr('title', '') 36756 } 36757 } 36758 36759 Tooltip.prototype.hasContent = function () { 36760 return this.getTitle() 36761 } 36762 36763 Tooltip.prototype.getPosition = function ($element) { 36764 $element = $element || this.$element 36765 var el = $element[0] 36766 var isBody = el.tagName == 'BODY' 36767 return $.extend({}, (typeof el.getBoundingClientRect == 'function') ? el.getBoundingClientRect() : null, { 36768 scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop(), 36769 width: isBody ? $(window).width() : $element.outerWidth(), 36770 height: isBody ? $(window).height() : $element.outerHeight() 36771 }, isBody ? {top: 0, left: 0} : $element.offset()) 36772 } 36773 36774 Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) { 36775 return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } : 36776 placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } : 36777 placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } : 36778 /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width } 36779 36780 } 36781 36782 Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) { 36783 var delta = { top: 0, left: 0 } 36784 if (!this.$viewport) return delta 36785 36786 var viewportPadding = this.options.viewport && this.options.viewport.padding || 0 36787 var viewportDimensions = this.getPosition(this.$viewport) 36788 36789 if (/right|left/.test(placement)) { 36790 var topEdgeOffset = pos.top - viewportPadding - viewportDimensions.scroll 36791 var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight 36792 if (topEdgeOffset < viewportDimensions.top) { // top overflow 36793 delta.top = viewportDimensions.top - topEdgeOffset 36794 } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow 36795 delta.top = viewportDimensions.top + viewportDimensions.height - bottom
36795EdgeOffset 36796 } 36797 } else { 36798 var leftEdgeOffset = pos.left - viewportPadding 36799 var rightEdgeOffset = pos.left + viewportPadding + actualWidth 36800 if (leftEdgeOffset < viewportDimensions.left) { // left overflow 36801 delta.left = viewportDimensions.left - leftEdgeOffset 36802 } else if (rightEdgeOffset > viewportDimensions.width) { // right overflow 36803 delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset 36804 } 36805 } 36806 36807 return delta 36808 } 36809 36810 Tooltip.prototype.getTitle = function () { 36811 var title 36812 var $e = this.$element 36813 var o = this.options 36814 36815 title = $e.attr('data-original-title') 36816 || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title) 36817 36818 return title 36819 } 36820 36821 Tooltip.prototype.tip = function () { 36822 return this.$tip = this.$tip || $(this.options.template) 36823 } 36824 36825 Tooltip.prototype.arrow = function () { 36826 return this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow') 36827 } 36828 36829 Tooltip.prototype.validate = function () { 36830 if (!this.$element[0].parentNode) { 36831 this.hide() 36832 this.$element = null 36833 this.options = null 36834 } 36835 } 36836 36837 Tooltip.prototype.enable = function () { 36838 this.enabled = true 36839 } 36840 36841 Tooltip.prototype.disable = function () { 36842 this.enabled = false 36843 } 36844 36845 Tooltip.prototype.toggleEnabled = function () { 36846 this.enabled = !this.enabled 36847 } 36848 36849 Tooltip.prototype.toggle = function (e) { 36850 var self = e ? $(e.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type) : this 36851 self.tip().hasClass('in') ? self.leave(self) : self.enter(self) 36852 } 36853 36854 Tooltip.prototype.destroy = function () { 36855 clearTimeout(this.timeout) 36856 this.hide().$element.off('.' + this.type).removeData('bs.' + this.type) 36857 } 36858 36859 36860 // TOOLTIP PLUGIN DEFINITION 36861 // ========================= 36862 36863 var old = $.fn.tooltip 36864 36865 $.fn.tooltip = function (option) { 36866 return this.each(function () { 36867 var $this = $(this) 36868 var data = $this.data('bs.tooltip') 36869 var options = typeof option == 'object' && option 36870 36871 if (!data && option == 'destroy') return 36872 if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options))) 36873 if (typeof option == 'string') data[option]() 36874 }) 36875 } 36876 36877 $.fn.tooltip.Constructor = Tooltip 36878 36879 36880 // TOOLTIP NO CONFLICT 36881 // =================== 36882 36883 $.fn.tooltip.noConflict = function () { 36884 $.fn.tooltip = old 36885 return this 36886 } 36887 36888}(jQuery); 36889 36890/* ======================================================================== 36891 * Bootstrap: transition.js v3.1.1 36892 * http://getbootstrap.com/javascript/#transitions 36893 * ======================================================================== 36894 * Copyright 2011-2014 Twitter, Inc. 36895 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 36896 * ======================================================================== */ 36897 36898 36899+function ($) { 36900 'use strict'; 36901 36902 // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/) 36903 // ============================================================ 36904 36905 function transitionEnd() { 36906 var el = document.createElement('bootstrap') 36907 36908 var transEndEventNames = { 36909 WebkitTransition : 'webkitTransitionEnd', 36910 MozTransition : 'transitionend', 36911 OTransition : 'oTransitionEnd otransitionend', 36912 transition : 'transitionend' 36913 } 36914 36915 for (var name in transEndEventNames) { 36916 if (el.style[name] !== undefined) { 36917 return { end: transEndEventNames[name] } 36918 } 36919 } 36920 36921 return false // explicit for ie8 ( ._.) 36922 } 36923 36924 // http://blog.alexmaccaw.com/css-transitions 36925 $.fn.emulateTransitionEnd = function (duration) { 36926 var called = false, $el = this 36927 $(this).one($.support.transition.end, function () { called = true }) 36928 var callback = function () { if (!called) $($el).trigger($.support.transition.end) } 36929 setTimeout(callback, duration) 36930 return this 36931 } 36932 36933 $(function () { 36934 $.support.transition = transitionEnd() 36935 }) 36936 36937}(jQuery); 36938 36939 36940// ------------------------------------------ 36941// Rellax.js 36942// Buttery smooth parallax library 36943// Copyright (c) 2016 Moe Amaya (@moeamaya) 36944// MIT license 36945// 36946// Thanks to Paraxify.js and Jaime Cabllero 36947// for parallax concepts 36948// ------------------------------------------ 36949 36950(function (root, factory) { 36951 if (typeof define === 'function' && define.amd) { 36952 // AMD. Register as an anonymous module. 36953 define([], factory); 36954 } else if (typeof module === 'object' && module.exports) { 36955 // Node. Does not work with strict CommonJS, but 36956 // only CommonJS-like environments that support module.exports, 36957 // like Node. 36958 module.exports = factory(); 36959 } else { 36960 // Browser globals (root is window) 36961 root.Rellax = factory(); 36962 } 36963}(typeof window !== "undefined" ? window : global, function () { 36964 var Rellax = function(el, options){ 36965 "use strict"; 36966 36967 var self = Object.create(Rellax.prototype); 36968 36969 var posY = 0; 36970 var screenY = 0; 36971 var posX = 0; 36972 var screenX = 0; 36973 var blocks = []; 36974 var pause = true; 36975 36976 // check what requestAnimationFrame to use, and if 36977 // it's not supported, use the onscroll event 36978 var loop = window.requestAnimationFrame || 36979 window.webkitRequestAnimationFrame || 36980 window.mozRequestAnimationFrame || 36981 window.msRequestAnimationFrame || 36982 window.oRequestAnimationFrame || 36983 function(callback){ return setTimeout(callback, 1000 / 60); }; 36984 36985 // store the id for later use 36986 var loopId = null; 36987 36988 // Test via a getter in the options object to see if the passive property is accessed 36989 var supportsPassive = false;
vendor: 10,724 bytes, lines 36990-37291
36990 try { 36991 var opts = Object.defineProperty({}, 'passive', { 36992 get: function() { 36993 supportsPassive = true; 36994 } 36995 }); 36996 window.addEventListener("testPassive", null, opts); 36997 window.removeEventListener("testPassive", null, opts); 36998 } catch (e) {} 36999 37000 // check what cancelAnimation method to use 37001 var clearLoop = window.cancelAnimationFrame || window.mozCancelAnimationFrame || clearTimeout; 37002 37003 // check which transform property to use 37004 var transformProp = window.transformProp || (function(){ 37005 var testEl = document.createElement('div'); 37006 if (testEl.style.transform === null) { 37007 var vendors = ['Webkit', 'Moz', 'ms']; 37008 for (var vendor in vendors) { 37009 if (testEl.style[ vendors[vendor] + 'Transform' ] !== undefined) { 37010 return vendors[vendor] + 'Transform'; 37011 } 37012 } 37013 } 37014 return 'transform'; 37015 })(); 37016 37017 // Default Settings 37018 self.options = { 37019 speed: -2, 37020 verticalSpeed: null, 37021 horizontalSpeed: null, 37022 breakpoints: [576, 768, 1201], 37023 center: false, 37024 wrapper: null, 37025 relativeToWrapper: false, 37026 round: true, 37027 vertical: true, 37028 horizontal: false, 37029 verticalScrollAxis: "y", 37030 horizontalScrollAxis: "x", 37031 callback: function() {}, 37032 }; 37033 37034 // User defined options (might have more in the future) 37035 if (options){ 37036 Object.keys(options).forEach(function(key){ 37037 self.options[key] = options[key]; 37038 }); 37039 } 37040 37041 function validateCustomBreakpoints () { 37042 if (self.options.breakpoints.length === 3 && Array.isArray(self.options.breakpoints)) { 37043 var isAscending = true; 37044 var isNumerical = true; 37045 var lastVal; 37046 self.options.breakpoints.forEach(function (i) { 37047 if (typeof i !== 'number') isNumerical = false; 37048 if (lastVal !== null) { 37049 if (i < lastVal) isAscending = false; 37050 } 37051 lastVal = i; 37052 }); 37053 if (isAscending && isNumerical) return; 37054 } 37055 // revert defaults if set incorrectly 37056 self.options.breakpoints = [576, 768, 1201]; 37057 console.warn("Rellax: You must pass an array of 3 numbers in ascending order to the breakpoints option. Defaults reverted"); 37058 } 37059 37060 if (options && options.breakpoints) { 37061 validateCustomBreakpoints(); 37062 } 37063 37064 // By default, rellax class 37065 if (!el) { 37066 el = '.rellax'; 37067 } 37068 37069 // check if el is a className or a node 37070 var elements = typeof el === 'string' ? document.querySelectorAll(el) : [el]; 37071 37072 // Now query selector 37073 if (elements.length > 0) { 37074 self.elems = elements; 37075 } 37076 37077 // The elements don't exist 37078 else { 37079 console.warn("Rellax: The elements you're trying to select don't exist."); 37080 return; 37081 } 37082 37083 // Has a wrapper and it exists 37084 if (self.options.wrapper) { 37085 if (!self.options.wrapper.nodeType) { 37086 var wrapper = document.querySelector(self.options.wrapper); 37087 37088 if (wrapper) { 37089 self.options.wrapper = wrapper; 37090 } else { 37091 console.warn("Rellax: The wrapper you're trying to use doesn't exist."); 37092 return; 37093 } 37094 } 37095 } 37096 37097 // set a placeholder for the current breakpoint 37098 var currentBreakpoint; 37099 37100 // helper to determine current breakpoint 37101 var getCurrentBreakpoint = function (w) { 37102 var bp = self.options.breakpoints; 37103 if (w < bp[0]) return 'xs'; 37104 if (w >= bp[0] && w < bp[1]) return 'sm'; 37105 if (w >= bp[1] && w < bp[2]) return 'md'; 37106 return 'lg'; 37107 }; 37108 37109 // Get and cache initial position of all elements 37110 var cacheBlocks = function() { 37111 for (var i = 0; i < self.elems.length; i++){ 37112 var block = createBlock(self.elems[i]); 37113 blocks.push(block); 37114 } 37115 }; 37116 37117 37118 // Let's kick this script off 37119 // Build array for cached element values 37120 var init = function() { 37121 for (var i = 0; i < blocks.length; i++){ 37122 self.elems[i].style.cssText = blocks[i].style; 37123 } 37124 37125 blocks = []; 37126 37127 screenY = window.innerHeight; 37128 screenX = window.innerWidth; 37129 currentBreakpoint = getCurrentBreakpoint(screenX); 37130 37131 setPosition(); 37132 37133 cacheBlocks(); 37134 37135 animate(); 37136 37137 // If paused, unpause and set listener for window resizing events 37138 if (pause) { 37139 window.addEventListener('resize', init); 37140 pause = false; 37141 // Start the loop 37142 update(); 37143 } 37144 }; 37145 37146 // We want to cache the parallax blocks' 37147 // values: base, top, height, speed 37148 // el: is dom object, return: el cache values 37149 var createBlock = function(el) { 37150 var dataPercentage = el.getAttribute( 'data-rellax-percentage' ); 37151 var dataSpeed = el.getAttribute( 'data-rellax-speed' ); 37152 var dataXsSpeed = el.getAttribute( 'data-rellax-xs-speed' ); 37153 var dataMobileSpeed = el.getAttribute( 'data-rellax-mobile-speed' ); 37154 var dataTabletSpeed = el.getAttribute( 'data-rellax-tablet-speed' ); 37155 var dataDesktopSpeed = el.getAttribute( 'data-rellax-desktop-speed' ); 37156 var dataVerticalSpeed = el.getAttribute('data-rellax-vertical-speed'); 37157 var dataHorizontalSpeed = el.getAttribute('data-rellax-horizontal-speed'); 37158 var dataVericalScrollAxis = el.getAttribute('data-rellax-vertical-scroll-axis'); 37159 var dataHorizontalScrollAxis = el.getAttribute('data-rellax-horizontal-scroll-axis'); 37160 var dataZindex = el.getAttribute( 'data-rellax-zindex' ) || 0; 37161 var dataMin = el.getAttribute( 'data-rellax-min' ); 37162 var dataMax = el.getAttribute( 'data-rellax-max' ); 37163 var dataMinX = el.getAttribute('data-rellax-min-x'); 37164 var dataMaxX = el.getAttribute('data-rellax-max-x'); 37165 var dataMinY = el.getAttribute('data-rellax-min-y'); 37166 var dataMaxY = el.getAttribute('data-rellax-max-y'); 37167 var mapBreakpoints; 37168 var breakpoints = true; 37169 37170 if (!dataXsSpeed && !dataMobileSpeed && !dataTabletSpeed && !dataDesktopSpeed) { 37171 breakpoints = false; 37172 } else { 37173 mapBreakpoints = { 37174 'xs': dataXsSpeed, 37175 'sm': dataMobileSpeed, 37176 'md': dataTabletSpeed, 37177 'lg': dataDesktopSpeed 37178 }; 37179 } 37180 37181 // initializing at scrollY = 0 (top of browser), scrollX = 0 (left of browser) 37182 // ensures elements are positioned based on HTML layout. 37183 // 37184 // If the element has the percentage attribute, the posY and posX needs to be 37185 // the current scroll position's value, so that the elements are still positioned based on HTML layout 37186 var wrapperPosY = self.options.wrapper ? self.options.wrapper.scrollTop : (window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop); 37187 // If the option relativeToWrapper is true, use the wrappers offset to top, subtracted from the current page scroll. 37188 if (self.options.relativeToWrapper) { 37189 var scrollPosY = (window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop); 37190 wrapperPosY = scrollPosY - self.options.wrapper.offsetTop; 37191 } 37192 var posY = self.options.vertical ? ( dataPercentage || self.options.center ? wrapperPosY : 0 ) : 0; 37193 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; 37194 37195 var blockTop = posY + el.getBoundingClientRect().top; 37196 var blockHeight = el.clientHeight || el.offsetHeight || el.scrollHeight; 37197 37198 var blockLeft = posX + el.getBoundingClientRect().left; 37199 var blockWidth = el.clientWidth || el.offsetWidth || el.scrollWidth; 37200 37201 // apparently parallax equation everyone uses 37202 var percentageY = dataPercentage ? dataPercentage : (posY - blockTop + screenY) / (blockHeight + screenY); 37203 var percentageX = dataPercentage ? dataPercentage : (posX - blockLeft + screenX) / (blockWidth + screenX); 37204 if(self.options.center){ percentageX = 0.5; percentageY = 0.5; } 37205 37206 // Optional individual block speed as data attr, otherwise global speed 37207 var speed = (breakpoints && mapBreakpoints[currentBreakpoint] !== null) ? Number(mapBreakpoints[currentBreakpoint]) : (dataSpeed ? dataSpeed : self.options.speed); 37208 var verticalSpeed = dataVerticalSpeed ? dataVerticalSpeed : self.options.verticalSpeed; 37209 var horizontalSpeed = dataHorizontalSpeed ? dataHorizontalSpeed : self.options.horizontalSpeed; 37210 37211 // Optional individual block movement axis direction as data attr, otherwise global movement direction 37212 var verticalScrollAxis = dataVericalScrollAxis ? dataVericalScrollAxis : self.options.verticalScrollAxis; 37213 var horizontalScrollAxis = dataHorizontalScrollAxis ? dataHorizontalScrollAxis : self.options.horizontalScrollAxis; 37214 37215 var bases = updatePosition(percentageX, percentageY, speed, verticalSpeed, horizontalSpeed); 37216 37217 // ~~Store non-translate3d transforms~~ 37218 // Store inline styles and extract transforms 37219 var style = el.style.cssText; 37220 var transform = ''; 37221 37222 // Check if there's an inline styled transform 37223 var searchResult = /transform\s*:/i.exec(style); 37224 if (searchResult) { 37225 // Get the index of the transform 37226 var index = searchResult.index; 37227 37228 // Trim the style to the transform point and get the following semi-colon index 37229 var trimmedStyle = style.slice(index); 37230 var delimiter = trimmedStyle.indexOf(';'); 37231 37232 // Remove "transform" string and save the attribute 37233 if (delimiter) { 37234 transform = " " + trimmedStyle.slice(11, delimiter).replace(/\s/g,''); 37235 } else { 37236 transform = " " + trimmedStyle.slice(11).replace(/\s/g,''); 37237 } 37238 } 37239 37240 return { 37241 baseX: bases.x, 37242 baseY: bases.y, 37243 top: blockTop, 37244 left: blockLeft, 37245 height: blockHeight, 37246 width: blockWidth, 37247 speed: speed, 37248 verticalSpeed: verticalSpeed, 37249 horizontalSpeed: horizontalSpeed, 37250 verticalScrollAxis: verticalScrollAxis, 37251 horizontalScrollAxis: horizontalScrollAxis, 37252 style: style, 37253 transform: transform, 37254 zindex: dataZindex, 37255 min: dataMin, 37256 max: dataMax, 37257 minX: dataMinX, 37258 maxX: dataMaxX, 37259 minY: dataMinY, 37260 maxY: dataMaxY 37261 }; 37262 }; 37263 37264 // set scroll position (posY, posX) 37265 // side effect method is not ideal, but okay for now 37266 // returns true if the scroll changed, false if nothing happened 37267 var setPosition = function() { 37268 var oldY = posY; 37269 var oldX = posX; 37270 37271 posY = self.options.wrapper ? self.options.wrapper.scrollTop : (document.documentElement || document.body.parentNode || document.body).scrollTop || window.pageYOffset; 37272 posX = self.options.wrapper ? self.options.wrapper.scrollLeft : (document.documentElement || document.body.parentNode || document.body).scrollLeft || window.pageXOffset; 37273 // If option relativeToWrapper is true, use relative wrapper value instead. 37274 if (self.options.relativeToWrapper) { 37275 var scrollPosY = (document.documentElement || document.body.parentNode || document.body).scrollTop || window.pageYOffset; 37276 posY = scrollPosY - self.options.wrapper.offsetTop; 37277 } 37278 37279 37280 if (oldY != posY && self.options.vertical) { 37281 // scroll changed, return true 37282 return true; 37283 } 37284 37285 if (oldX != posX && self.options.horizontal) { 37286 // scroll changed, return true 37287 return true; 37288 } 37289 37290 // scroll did not change 37291 return false;
37292 }; 37293 37294 // Ahh a pure function, gets new transform value 37295 // based on scrollPosition and speed 37296 // Allow for decimal pixel values 37297 var updatePosition = function(percentageX, percentageY, speed, verticalSpeed, horizontalSpeed) { 37298 var result = {}; 37299 var valueX = ((horizontalSpeed ? horizontalSpeed : speed) * (100 * (1 - percentageX))); 37300 var valueY = ((verticalSpeed ? verticalSpeed : speed) * (100 * (1 - percentageY))); 37301 37302 result.x = self.options.round ? Math.round(valueX) : Math.round(valueX * 100) / 100; 37303 result.y = self.options.round ? Math.round(valueY) : Math.round(valueY * 100) / 100; 37304 37305 return result; 37306 }; 37307 37308 // Remove event listeners and loop again 37309 var deferredUpdate = function() { 37310 window.removeEventListener('resize', deferredUpdate); 37311 window.removeEventListener('orientationchange', deferredUpdate); 37312 (self.options.wrapper ? self.options.wrapper : window).removeEventListener('scroll', deferredUpdate); 37313 (self.options.wrapper ? self.options.wrapper : document).removeEventListener('touchmove', deferredUpdate); 37314 37315 // loop again 37316 loopId = loop(update); 37317 }; 37318 37319 // Loop 37320 var update = function() { 37321 if (setPosition() && pause === false) { 37322 animate(); 37323 37324 // loop again 37325 loopId = loop(update); 37326 } else { 37327 loopId = null; 37328 37329 // Don't animate until we get a position updating event 37330 window.addEventListener('resize', deferredUpdate); 37331 window.addEventListener('orientationchange', deferredUpdate); 37332 (self.options.wrapper ? self.options.wrapper : window).addEventListener('scroll', deferredUpdate, supportsPassive ? { passive: true } : false); 37333 (self.options.wrapper ? self.options.wrapper : document).addEventListener('touchmove', deferredUpdate, supportsPassive ? { passive: true } : false); 37334 } 37335 }; 37336 37337 // Transform3d on parallax element 37338 var animate = function() { 37339 var positions; 37340 for (var i = 0; i < self.elems.length; i++){ 37341 // Determine relevant movement directions 37342 var verticalScrollAxis = blocks[i].verticalScrollAxis.toLowerCase(); 37343 var horizontalScrollAxis = blocks[i].horizontalScrollAxis.toLowerCase(); 37344 var verticalScrollX = verticalScrollAxis.indexOf("x") != -1 ? posY : 0; 37345 var verticalScrollY = verticalScrollAxis.indexOf("y") != -1 ? posY : 0; 37346 var horizontalScrollX = horizontalScrollAxis.indexOf("x") != -1 ? posX : 0; 37347 var horizontalScrollY = horizontalScrollAxis.indexOf("y") != -1 ? posX : 0; 37348 37349 var percentageY = ((verticalScrollY + horizontalScrollY - blocks[i].top + screenY) / (blocks[i].height + screenY)); 37350 var percentageX = ((verticalScrollX + horizontalScrollX - blocks[i].left + screenX) / (blocks[i].width + screenX)); 37351 37352 // Subtracting initialize value, so element stays in same spot as HTML 37353 positions = updatePosition(percentageX, percentageY, blocks[i].speed, blocks[i].verticalSpeed, blocks[i].horizontalSpeed); 37354 var positionY = positions.y - blocks[i].baseY; 37355 var positionX = positions.x - blocks[i].baseX; 37356 37357 // The next two "if" blocks go like this: 37358 // Check if a limit is defined (first "min", then "max"); 37359 // Check if we need to change the Y or the X 37360 // (Currently working only if just one of the axes is enabled) 37361 // Then, check if the new position is inside the allowed limit 37362 // If so, use new position. If not, set position to limit. 37363 37364 // Check if a min limit is defined 37365 if (blocks[i].min !== null) { 37366 if (self.options.vertical && !self.options.horizontal) { 37367 positionY = positionY <= blocks[i].min ? blocks[i].min : positionY; 37368 } 37369 if (self.options.horizontal && !self.options.vertical) { 37370 positionX = positionX <= blocks[i].min ? blocks[i].min : positionX; 37371 } 37372 } 37373 37374 // Check if directional min limits are defined 37375 if (blocks[i].minY != null) { 37376 positionY = positionY <= blocks[i].minY ? blocks[i].minY : positionY; 37377 } 37378 if (blocks[i].minX != null) { 37379 positionX = positionX <= blocks[i].minX ? blocks[i].minX : positionX; 37380 } 37381 37382 // Check if a max limit is defined 37383 if (blocks[i].max !== null) { 37384 if (self.options.vertical && !self.options.horizontal) { 37385 positionY = positionY >= blocks[i].max ? blocks[i].max : positionY; 37386 } 37387 if (self.options.horizontal && !self.options.vertical) { 37388 positionX = positionX >= blocks[i].max ? blocks[i].max : positionX; 37389 } 37390 } 37391 37392 // Check if directional max limits are defined 37393 if (blocks[i].maxY != null) { 37394 positionY = positionY >= blocks[i].maxY ? blocks[i].maxY : positionY; 37395 } 37396 if (blocks[i].maxX != null) { 37397 positionX = positionX >= blocks[i].maxX ? blocks[i].maxX : positionX; 37398 } 37399 37400 var zindex = blocks[i].zindex; 37401 37402 // Move that element 37403 // (Set the new translation and append initial inline transforms.) 37404 var translate = 'translate3d(' + (self.options.horizontal ? positionX : '0') + 'px,' + (self.options.vertical ? positionY : '0') + 'px,' + zindex + 'px) ' + blocks[i].transform; 37405 self.elems[i].style[transformProp] = translate; 37406 } 37407 self.options.callback(positions); 37408 }; 37409 37410 self.destroy = function() { 37411 for (var i = 0; i < self.elems.length; i++){ 37412 self.elems[i].style.cssText = blocks[i].style; 37413 } 37414 37415 // Remove resize event listener if not pause, and pause 37416 if (!pause) { 37417 window.removeEventListener('resize', init); 37418 pause = true; 37419 } 37420 37421 // Clear the animation loop to prevent possible memory leak 37422 clearLoop(loopId); 37423 loopId = null; 37424 }; 37425 37426 // Init 37427 init(); 37428 37429 // Allow to recalculate the initial values whenever we want 37430 self.refresh = init; 37431 37432 return self; 37433 }; 37434 return Rellax; 37435})); 37436 37437/* 37438 * OKVideo by OKFocus v2.3.2 37439 * http://okfoc.us 37440 * 37441 * Copyright 2014, OKFocus 37442 * Licensed under the MIT license. 37443 * 37444 */ 37445var player, OKEvents, options, videoWidth, videoHeight, YTplayers, youtubePlayers = new Array(); 37446// youtube player ready 37447function onYouTubeIframeAPIReady() { 37448 YTplayers = new Array(); 37449 jQuery('.uncode-video-container.video').each(function() { 37450 var playerY; 37451 if (jQuery(this).attr('data-provider') == 'youtube') { 37452 var id = jQuery(this).attr('data-id'), 37453 start = jQuery(this).attr('data-start'), 37454 end = jQuery(this).attr('data-end'); 37455 start = typeof start && start !== null ? start : 0; 37456 end = typeof end && end !== null ? end : 0; 37457 options = jQuery(window).data('okoptions-' + id); 37458 if ( typeof options === 'undefined' ) { 37459 return true; 37460 } 37461 options.time = jQuery(this).attr('data-t'); 37462 playerY = new YT.Player('okplayer-' + id, { 37463 videoId: options.video ? options.video.id : null, 37464 playerVars: { 37465 'autohide': 1, 37466 'autoplay': jQuery(this).hasClass('is-no-control') ? options.autoplay : 0, //options.autoplay, 37467 'disablekb': 1, 37468 'cc_load_policy': options.captions, 37469 'controls': 0, 37470 'enablejsapi': 1, 37471 'fs': 0, 37472 'modestbranding': 1, 37473 'origin': window.location.origin || (window.location.protocol + '//' + window.location.hostname), 37474 'iv_load_policy': options.annotations, 37475 'loop': options.loop, 37476 'showinfo': 0, 37477 'rel': 0, 37478 'wmode': 'opaque', 37479 'hd': options.hd, 37480 'mute': 1, 37481 'start': start, 37482 'end': end 37483 }, 37484 events: { 37485 'onReady': OKEvents.yt.ready, 37486 'onStateChange': OKEvents.yt.onStateChange, 37487 'onError': OKEvents.yt.error 37488 } 37489 }); 37490 YTplayers[id] = playerY; 37491 playerY.videoId = id; 37492 } 37493 37494 }); 37495} 37496// vimeo player ready 37497function vimeoPlayerReady(id) { 37498 options = jQuery(window).data('okoptions-' + id); 37499 if ( typeof options === 'undefined' ) { 37500 return true; 37501 }
37502 var jIframe = options.jobject, 37503 iframe = jIframe[0]; 37504 37505 jIframe.attr('src', jIframe.data('src')); 37506 var playerV = new Vimeo.Player(iframe); 37507 // hide player until Vimeo hides controls... 37508 playerV.on('loaded', function(e) { 37509 OKEvents.v.onReady(iframe); 37510 var carouselContainer = jQuery(iframe).closest('.owl-carousel'); 37511 if (carouselContainer.length) { 37512 UNCODE.owlPlayVideo(carouselContainer); 37513 } 37514 // "Do not try to add listeners or call functions before receiving this event." 37515 if (OKEvents.utils.isMobile()) { 37516 // mobile devices cannot listen for play event 37517 OKEvents.v.onPlay(playerV); 37518 } else { 37519 playerV.on('play', function(){ 37520 OKEvents.v.onPlay(playerV); 37521 jQuery(window).trigger('okevents.v.play', [playerV]); 37522 }); 37523 playerV.on('pause', function(){ 37524 OKEvents.v.onPause; 37525 jQuery(window).trigger('okevents.v.pause', [playerV]); 37526 }); 37527 playerV.on('ended', function(){ 37528 OKEvents.v.onFinish 37529 jQuery(window).trigger('okevents.v.ended', [playerV]); 37530 }); 37531 } 37532 if (options.time != null) { 37533 var optsTimeStr = (options.time).replace('t=', ''), 37534 timeV = ''; 37535 37536 if ( /[a-zA-Z]/g.test(optsTimeStr) ) { 37537 var timeArr = optsTimeStr.split(/([^\d.-])/); 37538 for ( var i = 0; i < timeArr.length; i++ ) { 37539 if ( timeArr[i] === 'h' ) { 37540 timeV += parseFloat(timeArr[i-1]) * 3600; 37541 } else if ( timeArr[i] === 'm' ) { 37542 timeV += parseFloat(timeArr[i-1]) * 60; 37543 } else if ( timeArr[i] === 's' ) { 37544 timeV += parseFloat(timeArr[i-1]); 37545 } 37546 } 37547 } else { 37548 timeV = optsTimeStr; 37549 } 37550 37551 playerV.setCurrentTime(timeV); 37552 } 37553 37554 playerV.setVolume(0); 37555 playerV.play(); 37556 jQuery(iframe).css({ 37557 visibility: 'visible', 37558 opacity: 1 37559 }); 37560 jQuery(iframe).closest('.uncode-video-container:not(.t-entry-drop)').css('opacity', '1'); 37561 jQuery(iframe).closest('#page-header').addClass('video-started'); 37562 jQuery(iframe).closest('.background-wrapper').find('.block-bg-blend-mode.not-ie').css('opacity', '1'); 37563 37564 jQuery(window).trigger('okevents.v.loaded', [playerV]); 37565 }); 37566} 37567OKEvents = { 37568 yt: { 37569 ready: function(event) { 37570 var id = event.target.videoId, 37571 $video = jQuery('#okplayer-' + id), 37572 options = jQuery(window).data('okoptions-' + id); 37573 if ( typeof options === 'undefined' ) { 37574 return true; 37575 } 37576 youtubePlayers[id] = event.target; 37577 event.target.setVolume(options.volume); 37578 if (options.autoplay === 1) { 37579 if (options.playlist.list) { 37580 player.loadPlaylist(options.playlist.list, options.playlist.index, options.playlist.startSeconds, options.playlist.suggestedQuality); 37581 } else { 37582 var inCarousel = $video.closest('.owl-item'); 37583 if (!inCarousel.length || (inCarousel.length && inCarousel.hasClass('active'))) { 37584 if (options.time != null) { 37585 event.target.seekTo(parseInt(options.time)); 37586 } 37587 event.target.playVideo(); 37588 } else { 37589 event.target.pauseVideo(); 37590 } 37591 } 37592 } 37593 OKEvents.utils.isFunction(options.onReady) && options.onReady(event.target); 37594 37595 $video.closest('[data-provider]').on('uncode-resume', function(){ 37596 if (options.time != null) { 37597 event.target.seekTo(parseInt(options.time)).playVideo(); 37598 } else { 37599 event.target.seekTo(0).playVideo(); 37600 } 37601 }); 37602 37603 $video.closest('[data-provider]').on('uncode-pause', function(){ 37604 if (options.time != null) { 37605 event.target.seekTo(parseInt(options.time)).pauseVideo(); 37606 } else { 37607 event.target.seekTo(0).pauseVideo(); 37608 } 37609 }); 37610 jQuery(window).trigger('okevents.y.loaded', [event]); 37611 }, 37612 onStateChange: function(event) { 37613 var id = event.target.videoId, 37614 $video = jQuery('#okplayer-' + id), 37615 options = jQuery(window).data('okoptions-' + id); 37616 if ( typeof options === 'undefined' ) { 37617 return true; 37618 } 37619 youtubePlayers[id] = event.target; 37620 event.target.setVolume(options.volume); 37621 var $fluid = $video.closest('.fluid-object'), 37622 $tmb = $video.closest('.tmb'), 37623 setTime; 37624 switch (event.data) { 37625 case -1: 37626 OKEvents.utils.isFunction(options.unstarted) && options.unstarted(); 37627 break; 37628 case 0: 37629 OKEvents.utils.isFunction(options.onFinished) && options.onFinished(); 37630 options.loop && event.target.playVideo(); 37631 break; 37632 case 1: 37633 OKEvents.utils.isFunction(options.onPlay) && options.onPlay(); 37634 setTimeout(function() { 37635 UNCODE.initVideoComponent(document.body, '.uncode-video-container.video:not(.drop-move), .uncode-video-container.self-video:not(.drop-move)'); 37636 jQuery('#okplayer-' + id).closest('.uncode-video-container:not(.t-entry-drop)').css('opacity', '1'); 37637 jQuery('#okplayer-' + id).closest('#page-header').addClass('video-started'); 37638 jQuery('#okplayer-' + id).closest('.background-wrapper').find('.block-bg-blend-mode.not-ie').css('opacity', '1'); 37639 }, 300); 37640 break; 37641 case 2: 37642 OKEvents.utils.isFunction(options.onPause) && options.onPause(); 37643 break; 37644 case 3: 37645 OKEvents.utils.isFunction(options.buffering) && options.buffering(); 37646 break; 37647 case 5: 37648 OKEvents.utils.isFunction(options.cued) && options.cued(); 37649 break; 37650 default:
37651 throw "OKVideo: received invalid data from YT player."; 37652 } 37653 37654 jQuery(window).trigger('okevents.y.change', [event]); 37655 }, 37656 error: function(event) { 37657 throw event; 37658 } 37659 }, 37660 v: { 37661 onReady: function(target) { 37662 if ( typeof options === 'undefined' ) { 37663 return true; 37664 } 37665 OKEvents.utils.isFunction(options.onReady) && options.onReady(target); 37666 }, 37667 onPlay: function(player) { 37668 if ( typeof options === 'undefined' ) { 37669 return true; 37670 } 37671 if (!OKEvents.utils.isMobile()) player.setVolume(options.volume); 37672 OKEvents.utils.isFunction(options.onPlay) && options.onPlay(); 37673 jQuery(player.element).closest('.uncode-video-container:not(.t-entry-drop)').css('opacity', '1'); 37674 jQuery(player.element).closest('#page-header').addClass('video-started'); 37675 jQuery(player.element).closest('.background-wrapper').find('.block-bg-blend-mode.not-ie').css('opacity', '1'); 37676 }, 37677 onPause: function() { 37678 if ( typeof options === 'undefined' ) { 37679 return true; 37680 } 37681 OKEvents.utils.isFunction(options.onPause) && options.onPause(); 37682 }, 37683 onFinish: function() { 37684 if ( typeof options === 'undefined' ) { 37685 return true; 37686 } 37687 OKEvents.utils.isFunction(options.onFinish) && options.onFinish(); 37688 } 37689 }, 37690 utils: { 37691 isFunction: function(func) { 37692 if (typeof func === 'function') { 37693 return true; 37694 } else { 37695 return false; 37696 } 37697 }, 37698 isMobile: function() { 37699 if (navigator.userAgent.match(/(iPhone|iPod|iPad|Android|BlackBerry)/)) { 37700 return true; 37701 } else { 37702 return false; 37703 } 37704 } 37705 } 37706}; 37707 37708/** 37709 * vivus - JavaScript library to make drawing animation on SVG 37710 * @version v0.4.4 37711 * @link https://github.com/maxwellito/vivus 37712 * @license MIT 37713 */ 37714 37715'use strict'; 37716 37717(function () { 37718 37719 'use strict'; 37720 37721/** 37722 * Pathformer 37723 * Beta version 37724 * 37725 * Take any SVG version 1.1 and transform 37726 * child elements to 'path' elements 37727 * 37728 * This code is purely forked from 37729 * https://github.com/Waest/SVGPathConverter 37730 */ 37731 37732/** 37733 * Class constructor 37734 * 37735 * @param {DOM|String} element Dom element of the SVG or id of it 37736 */ 37737function Pathformer(element) { 37738 // Test params 37739 if (typeof element === 'undefined') { 37740 throw new Error('Pathformer [constructor]: "element" parameter is required'); 37741 } 37742 37743 // Set the element 37744 if (element.constructor === String) { 37745 element = document.getElementById(element); 37746 if (!element) { 37747 throw new Error('Pathformer [constructor]: "element" parameter is not related to an existing ID'); 37748 } 37749 } 37750 if (element instanceof window.SVGElement || 37751 element instanceof window.SVGGElement || 37752 /^svg$/i.test(element.nodeName)) { 37753 this.el = element; 37754 } else { 37755 throw new Error('Pathformer [constructor]: "element" parameter must be a string or a SVGelement'); 37756 } 37757 37758 // Start 37759 this.scan(element); 37760} 37761 37762/** 37763 * List of tags which can be transformed 37764 * to path elements 37765 * 37766 * @type {Array} 37767 */ 37768Pathformer.prototype.TYPES = ['line', 'ellipse', 'circle', 'polygon', 'polyline', 'rect']; 37769 37770/** 37771 * List of attribute names which contain 37772 * data. This array list them to check if 37773 * they contain bad values, like percentage. 37774 * 37775 * @type {Array} 37776 */ 37777Pathformer.prototype.ATTR_WATCH = ['cx', 'cy', 'points', 'r', 'rx', 'ry', 'x', 'x1', 'x2', 'y', '
vendor: 24,640 bytes, lines 37777-38575
37777y1', 'y2']; 37778 37779/** 37780 * Finds the elements compatible for transform 37781 * and apply the liked method 37782 * 37783 * @param {object} options Object from the constructor 37784 */ 37785Pathformer.prototype.scan = function (svg) { 37786 var fn, element, pathData, pathDom, 37787 elements = svg.querySelectorAll(this.TYPES.join(',')); 37788 37789 for (var i = 0; i < elements.length; i++) { 37790 element = elements[i]; 37791 fn = this[element.tagName.toLowerCase() + 'ToPath']; 37792 pathData = fn(this.parseAttr(element.attributes)); 37793 pathDom = this.pathMaker(element, pathData); 37794 element.parentNode.replaceChild(pathDom, element); 37795 } 37796}; 37797 37798 37799/** 37800 * Read `line` element to extract and transform 37801 * data, to make it ready for a `path` object. 37802 * 37803 * @param {DOMelement} element Line element to transform 37804 * @return {object} Data for a `path` element 37805 */ 37806Pathformer.prototype.lineToPath = function (element) { 37807 var newElement = {}, 37808 x1 = element.x1 || 0, 37809 y1 = element.y1 || 0, 37810 x2 = element.x2 || 0, 37811 y2 = element.y2 || 0; 37812 37813 newElement.d = 'M' + x1 + ',' + y1 + 'L' + x2 + ',' + y2; 37814 return newElement; 37815}; 37816 37817/** 37818 * Read `rect` element to extract and transform 37819 * data, to make it ready for a `path` object. 37820 * The radius-border is not taken in charge yet. 37821 * (your help is more than welcomed) 37822 * 37823 * @param {DOMelement} element Rect element to transform 37824 * @return {object} Data for a `path` element 37825 */ 37826Pathformer.prototype.rectToPath = function (element) { 37827 var newElement = {}, 37828 x = parseFloat(element.x) || 0, 37829 y = parseFloat(element.y) || 0, 37830 width = parseFloat(element.width) || 0, 37831 height = parseFloat(element.height) || 0; 37832 37833 if (element.rx || element.ry) { 37834 var rx = parseInt(element.rx, 10) || -1, 37835 ry = parseInt(element.ry, 10) || -1; 37836 rx = Math.min(Math.max(rx < 0 ? ry : rx, 0), width/2); 37837 ry = Math.min(Math.max(ry < 0 ? rx : ry, 0), height/2); 37838 37839 newElement.d = 'M ' + (x + rx) + ',' + y + ' ' + 37840 'L ' + (x + width - rx) + ',' + y + ' ' + 37841 'A ' + rx + ',' + ry + ',0,0,1,' + (x + width) + ',' + (y + ry) + ' ' + 37842 'L ' + (x + width) + ',' + (y + height - ry) + ' ' + 37843 'A ' + rx + ',' + ry + ',0,0,1,' + (x + width - rx) + ',' + (y + height) + ' ' + 37844 'L ' + (x + rx) + ',' + (y + height) + ' ' + 37845 'A ' + rx + ',' + ry + ',0,0,1,' + x + ',' + (y + height - ry) + ' ' + 37846 'L ' + x + ',' + (y + ry) + ' ' + 37847 'A ' + rx + ',' + ry + ',0,0,1,' + (x + rx) + ',' + y; 37848 } 37849 else { 37850 newElement.d = 'M' + x + ' ' + y + ' ' + 37851 'L' + (x + width) + ' ' + y + ' ' + 37852 'L' + (x + width) + ' ' + (y + height) + ' ' + 37853 'L' + x + ' ' + (y + height) + ' Z'; 37854 } 37855 return newElement; 37856}; 37857 37858/** 37859 * Read `polyline` element to extract and transform 37860 * data, to make it ready for a `path` object. 37861 * 37862 * @param {DOMelement} element Polyline element to transform 37863 * @return {object} Data for a `path` element 37864 */ 37865Pathformer.prototype.polylineToPath = function (element) { 37866 var newElement = {}, 37867 points = element.points.trim().split(' '), 37868 i, path; 37869 37870 // Reformatting if points are defined without commas 37871 if (element.points.indexOf(',') === -1) { 37872 var formattedPoints = []; 37873 for (i = 0; i < points.length; i+=2) { 37874 formattedPoints.push(points[i] + ',' + points[i+1]); 37875 } 37876 points = formattedPoints; 37877 } 37878 37879 // Generate the path.d value 37880 path = 'M' + points[0]; 37881 for(i = 1; i < points.length; i++) { 37882 if (points[i].indexOf(',') !== -1) { 37883 path += 'L' + points[i]; 37884 } 37885 } 37886 newElement.d = path; 37887 return newElement; 37888}; 37889 37890/** 37891 * Read `polygon` element to extract and transform 37892 * data, to make it ready for a `path` object. 37893 * This method rely on polylineToPath, because the 37894 * logic is similar. The path created is just closed, 37895 * so it needs an 'Z' at the end. 37896 * 37897 * @param {DOMelement} element Polygon element to transform 37898 * @return {object} Data for a `path` element 37899 */ 37900Pathformer.prototype.polygonToPath = function (element) { 37901 var newElement = Pathformer.prototype.polylineToPath(element); 37902 37903 newElement.d += 'Z'; 37904 return newElement; 37905}; 37906 37907/** 37908 * Read `ellipse` element to extract and transform 37909 * data, to make it ready for a `path` object. 37910 * 37911 * @param {DOMelement} element ellipse element to transform 37912 * @return {object} Data for a `path` element 37913 */ 37914Pathformer.prototype.ellipseToPath = function (element) { 37915 var newElement = {}, 37916 rx = parseFloat(element.rx) || 0, 37917 ry = parseFloat(element.ry) || 0, 37918 cx = parseFloat(element.cx) || 0, 37919 cy = parseFloat(element.cy) || 0, 37920 startX = cx - rx, 37921 startY = cy, 37922 endX = parseFloat(cx) + parseFloat(rx), 37923 endY = cy; 37924 37925 newElement.d = 'M' + startX + ',' + startY + 37926 'A' + rx + ',' + ry + ' 0,1,1 ' + endX + ',' + endY + 37927 'A' + rx + ',' + ry + ' 0,1,1 ' + startX + ',' + endY; 37928 return newElement; 37929}; 37930 37931/** 37932 * Read `circle` element to extract and transform 37933 * data, to make it ready for a `path` object. 37934 * 37935 * @param {DOMelement} element Circle element to transform 37936 * @return {object} Data for a `path` element 37937 */ 37938Pathformer.prototype.circleToPath = function (element) { 37939 var newElement = {}, 37940 r = parseFloat(element.r) || 0, 37941 cx = parseFloat(element.cx) || 0, 37942 cy = parseFloat(element.cy) || 0, 37943 startX = cx - r, 37944 startY = cy, 37945 endX = parseFloat(cx) + parseFloat(r), 37946 endY = cy; 37947 37948 newElement.d = 'M' + startX + ',' + startY + 37949 'A' + r + ',' + r + ' 0,1,1 ' + endX + ',' + endY + 37950 'A' + r + ',' + r + ' 0,1,1 ' + startX + ',' + endY; 37951 return newElement; 37952}; 37953 37954/** 37955 * Create `path` elements form original element 37956 * and prepared objects 37957 * 37958 * @param {DOMelement} element Original element to transform 37959 * @param {object} pathData Path data (from `toPath` methods) 37960 * @return {DOMelement} Path element 37961 */ 37962Pathformer.prototype.pathMaker = function (element, pathData) { 37963 var i, attr, pathTag = document.createElementNS('http://www.w3.org/2000/svg','path'); 37964 for(i = 0; i < element.attributes.length; i++) { 37965 attr = element.attributes[i]; 37966 if (this.ATTR_WATCH.indexOf(attr.name) === -1) { 37967 pathTag.setAttribute(attr.name, attr.value); 37968 } 37969 } 37970 for(i in pathData) { 37971 pathTag.setAttribute(i, pathData[i]); 37972 } 37973 return pathTag; 37974}; 37975 37976/** 37977 * Parse attributes of a DOM element to 37978 * get an object of attribute => value 37979 * 37980 * @param {NamedNodeMap} attributes Attributes object from DOM element to parse 37981 * @return {object} Object of attributes 37982 */ 37983Pathformer.prototype.parseAttr = function (element) { 37984 var attr, output = {}; 37985 for (var i = 0; i < element.length; i++) { 37986 attr = element[i]; 37987 // Check if no data attribute contains '%', or the transformation is impossible 37988 if (this.ATTR_WATCH.indexOf(attr.name) !== -1 && attr.value.indexOf('%') !== -1) { 37989 throw new Error('Pathformer [parseAttr]: a SVG shape got values in percentage. This cannot be transformed into \'path\' tags. Please use \'viewBox\'.'); 37990 } 37991 output[attr.name] = attr.value; 37992 } 37993 return output; 37994}; 37995 37996 'use strict'; 37997 37998var setupEnv, requestAnimFrame, cancelAnimFrame, parsePositiveInt; 37999 38000/** 38001 * Vivus 38002 * Beta version 38003 * 38004 * Take any SVG and make the animation 38005 * to give give the impression of live drawing 38006 * 38007 * This in more than just inspired from codrops 38008 * At that point, it's a pure fork. 38009 */ 38010 38011/** 38012 * Class constructor 38013 * option structure 38014 * type: 'delayed'|'sync'|'oneByOne'|'script' (to know if the items must be drawn synchronously or not, default: delayed) 38015 * duration: <int> (in frames) 38016 * start: 'inViewport'|'manual'|'autostart' (start automatically the animation, default: inViewport) 38017 * delay: <int> (delay between the drawing of first and last path) 38018 * dashGap <integer> whitespace extra margin between dashes 38019 * pathTimingFunction <function> timing animation function for each path element of the SVG 38020 * animTimingFunction <function> timing animation function for the complete SVG 38021 * forceRender <boolean> force the browser to re-render all updated path items 38022 * selfDestroy <boolean> removes all extra styling on the SVG, and leaves it as original 38023 * 38024 * The attribute 'type' is by default on 'delayed'. 38025 * - 'delayed' 38026 * all paths are draw at the same time but with a 38027 * little delay between them before start 38028 * - 'sync' 38029 * all path are start and finish at the same time 38030 * - 'oneByOne' 38031 * only one path is draw at the time 38032 * the end of the first one will trigger the draw 38033 * of the next one 38034 * 38035 * All these values can be overwritten individually 38036 * for each path item in the SVG 38037 * The value of frames will always take the advantage of 38038 * the duration value. 38039 * If you fail somewhere, an error will be thrown. 38040 * Good luck. 38041 * 38042 * @constructor 38043 * @this {Vivus} 38044 * @param {DOM|String} element Dom element of the SVG or id of it 38045 * @param {Object} options Options about the animation 38046 * @param {Function} callback Callback for the end of the animation 38047 */ 38048function Vivus (element, options, callback) { 38049 38050 setupEnv(); 38051 38052 // Setup 38053 this.isReady = false; 38054 this.setElement(element, options); 38055 this.setOptions(options); 38056 this.setCallback(callback); 38057 38058 if (this.isReady) { 38059 this.init(); 38060 } 38061} 38062 38063/** 38064 * Timing functions 38065 ************************************** 38066 * 38067 * Default functions to help developers. 38068 * It always take a number as parameter (between 0 to 1) then 38069 * return a number (between 0 and 1) 38070 */ 38071Vivus.LINEAR = function (x) {return x;}; 38072Vivus.EASE = function (x) {return -Math.cos(x * Math.PI) / 2 + 0.5;}; 38073Vivus.EASE_OUT = function (x) {return 1 - Math.pow(1-x, 3);}; 38074Vivus.EASE_IN = function (x) {return Math.pow(x, 3);}; 38075Vivus.EASE_OUT_BOUNCE = function (x) { 38076 var base = -Math.cos(x * (0.5 * Math.PI)) + 1, 38077 rate = Math.pow(base,1.5), 38078 rateR = Math.pow(1 - x, 2), 38079 progress = -Math.abs(Math.cos(rate * (2.5 * Math.PI) )) + 1; 38080 return (1- rateR) + (progress * rateR); 38081}; 38082 38083 38084/** 38085 * Setters 38086 ************************************** 38087 */ 38088 38089/** 38090 * Check and set the element in the instance 38091 * The method will not return anything, but will throw an 38092 * error if the parameter is invalid 38093 * 38094 * @param {DOM|String} element SVG Dom element or id of it 38095 */ 38096Vivus.prototype.setElement = function (element, options) { 38097 var onLoad, self; 38098 38099 // Basic check 38100 if (typeof element === 'undefined') { 38101 throw new Error('Vivus [constructor]: "element" parameter is required'); 38102 } 38103 38104 // Set the element 38105 if (element.constructor === String) { 38106 element = document.getElementById(element); 38107 if (!element) { 38108 throw new Error('Vivus [constructor]: "element" parameter is not related to an existing ID'); 38109 } 38110 } 38111 this.parentEl = element; 38112 38113 // Load the SVG with XMLHttpRequest and extract the SVG 38114 if (options && options.file) { 38115 var self = this; 38116 onLoad = function (e) { 38117 var domSandbox = document.createElement('div'); 38118 domSandbox.innerHTML = this.responseText; 38119 38120 var svgTag = domSandbox.querySelector('svg'); 38121 if (!svgTag) { 38122 throw new Error('Vivus [load]: Cannot find the SVG in the loaded file : ' + options.file); 38123 } 38124 38125 self.el = svgTag 38126 self.el.setAttribute('width', '100%'); 38127 self.el.setAttribute('height', '100%'); 38128 self.parentEl.appendChild(self.el) 38129 self.isReady = true; 38130 self.init(); 38131 self = null; 38132 } 38133 38134 var oReq = new window.XMLHttpRequest(); 38135 oReq.addEventListener('load', onLoad); 38136 oReq.open('GET', options.file); 38137 oReq.send(); 38138 return; 38139 } 38140 38141 switch (element.constructor) { 38142 case window.SVGSVGElement: 38143 case window.SVGElement: 38144 case window.SVGGElement: 38145 this.el = element; 38146 this.isReady = true; 38147 break; 38148 38149 case window.HTMLObjectElement: 38150 self = this; 38151 onLoad = function (e) { 38152 if (self.isReady) { 38153 return; 38154 } 38155 self.el = element.contentDocument && element.contentDocument.querySelector('svg'); 38156 if (!self.el && e) { 38157 throw new Error('Vivus [constructor]: object loaded does not contain any SVG'); 38158 } 38159 else if (self.el) { 38160 if (element.getAttribute('built-by-vivus')) { 38161 self.parentEl.insertBefore(self.el, element); 38162 self.parentEl.removeChild(element); 38163 self.el.setAttribute('width', '100%'); 38164 self.el.setAttribute('height', '100%'); 38165 } 38166 self.isReady = true; 38167 self.init(); 38168 self = null; 38169 } 38170 }; 38171 38172 if (!onLoad()) { 38173 element.addEventListener('load', onLoad); 38174 } 38175 break; 38176 38177 default: 38178 throw new Error('Vivus [constructor]: "element" parameter is not valid (or miss the "file" attribute)'); 38179 } 38180}; 38181 38182/** 38183 * Set up user option to the instance 38184 * The method will not return anything, but will throw an 38185 * error if the parameter is invalid 38186 * 38187 * @param {object} options Object from the constructor 38188 */ 38189Vivus.prototype.setOptions = function (options) { 38190 var allowedTypes = ['delayed', 'sync', 'async', 'nsync', 'oneByOne', 'scenario', 'scenario-sync']; 38191 var allowedStarts = ['inViewport', 'manual', 'autostart']; 38192 38193 // Basic check 38194 if (options !== undefined && options.constructor !== Object) { 38195 throw new Error('Vivus [constructor]: "options" parameter must be an object'); 38196 } 38197 else { 38198 options = options || {}; 38199 } 38200 38201 // Set the animation type 38202 if (options.type && allowedTypes.indexOf(options.type) === -1) { 38203 throw new Error('Vivus [constructor]: ' + options.type + ' is not an existing animation `type`'); 38204 } 38205 else { 38206 this.type = options.type || allowedTypes[0]; 38207 } 38208 38209 // Set the start type 38210 if (options.start && allowedStarts.indexOf(options.start) === -1) { 38211 throw new Error('Vivus [constructor]: ' + options.start + ' is not an existing `start` option'); 38212 } 38213 else { 38214 this.start = options.start || allowedStarts[0]; 38215 } 38216 38217 this.isIE = (window.navigator.userAgent.indexOf('MSIE') !== -1 || window.navigator.userAgent.indexOf('Trident/') !== -1 || window.navigator.userAgent.indexOf('Edge/') !== -1 ); 38218 this.duration = parsePositiveInt(options.duration, 120); 38219 this.delay = parsePositiveInt(options.delay, null); 38220 //Uncode addition 38221 this.delayStart = parsePositiveInt(options.delayStart, null); 38222 //#END 38223 this.dashGap = parsePositiveInt(options.dashGap, 1); 38224 this.forceRender = options.hasOwnProperty('forceRender') ? !!options.forceRender : this.isIE; 38225 this.reverseStack = !!options.reverseStack; 38226 this.selfDestroy = !!options.selfDestroy; 38227 this.onReady = options.onReady; 38228 this.map = []; 38229 this.frameLength = this.currentFrame = this.delayUnit = this.speed = this.handle = null; 38230 38231 this.ignoreInvisible = options.hasOwnProperty('ignoreInvisible') ? !!options.ignoreInvisible : false; 38232 38233 this.animTimingFunction = options.animTimingFunction || Vivus.LINEAR; 38234 this.pathTimingFunction = options.pathTimingFunction || Vivus.LINEAR; 38235 38236 if (this.delay >= this.duration) { 38237 throw new Error('Vivus [constructor]: delay must be shorter than duration'); 38238 } 38239}; 38240 38241/** 38242 * Set up callback to the instance 38243 * The method will not return enything, but will throw an 38244 * error if the parameter is invalid 38245 * 38246 * @param {Function} callback Callback for the animation end 38247 */ 38248Vivus.prototype.setCallback = function (callback) { 38249 // Basic check 38250 if (!!callback && callback.constructor !== Function) { 38251 throw new Error('Vivus [constructor]: "callback" parameter must be a function'); 38252 } 38253 this.callback = callback || function () {}; 38254}; 38255 38256 38257/** 38258 * Core 38259 ************************************** 38260 */ 38261 38262/** 38263 * Map the svg, path by path. 38264 * The method return nothing, it just fill the 38265 * `map` array. Each item in this array represent 38266 * a path element from the SVG, with informations for 38267 * the animation. 38268 * 38269 * ``` 38270 * [ 38271 * { 38272 * el: <DOMobj> the path element 38273 * length: <number> length of the path line 38274 * startAt: <number> time start of the path animation (in frames) 38275 * duration: <number> path animation duration (in frames) 38276 * }, 38277 * ... 38278 * ] 38279 * ``` 38280 * 38281 */ 38282Vivus.prototype.mapping = function () { 38283 var i, paths, path, pAttrs, pathObj, totalLength, lengthMeter, timePoint; 38284 timePoint = totalLength = lengthMeter = 0; 38285 paths = this.el.querySelectorAll('path'); 38286 38287 for (i = 0; i < paths.length; i++) { 38288 path = paths[i]; 38289 if (this.isInvisible(path)) { 38290 continue; 38291 } 38292 pathObj = { 38293 el: path, 38294 length: Math.ceil(path.getTotalLength()) 38295 }; 38296 // Test if the path length is correct 38297 if (isNaN(pathObj.length)) { 38298 if (window.console && console.warn) { 38299 console.warn('Vivus [mapping]: cannot retrieve a path element length', path); 38300 } 38301 continue; 38302 } 38303 this.map.push(pathObj); 38304 path.style.strokeDasharray = pathObj.length + ' ' + (pathObj.length + this.dashGap * 2); 38305 path.style.strokeDashoffset = pathObj.length + this.dashGap; 38306 pathObj.length += this.dashGap; 38307 totalLength += pathObj.length; 38308 38309 this.renderPath(i); 38310 } 38311 38312 totalLength = totalLength === 0 ? 1 : totalLength; 38313 this.delay = this.delay === null ? this.duration / 3 : this.delay; 38314 this.delayUnit = this.delay / (paths.length > 1 ? paths.length - 1 : 1); 38315 38316 // Reverse stack if asked 38317 if (this.reverseStack) { 38318 this.map.reverse(); 38319 } 38320 38321 for (i = 0; i < this.map.length; i++) { 38322 pathObj = this.map[i]; 38323 38324 switch (this.type) { 38325 case 'delayed': 38326 pathObj.startAt = this.delayUnit * i; 38327 pathObj.duration = this.duration - this.delay; 38328 break; 38329 38330 case 'oneByOne': 38331 pathObj.startAt = lengthMeter / totalLength * this.duration; 38332 pathObj.duration = pathObj.length / totalLength * this.duration; 38333 break; 38334 38335 case 'sync': 38336 case 'async': 38337 case 'nsync': 38338 pathObj.startAt = 0; 38339 pathObj.duration = this.duration; 38340 break; 38341 38342 case 'scenario-sync': 38343 path = pathObj.el; 38344 pAttrs = this.parseAttr(path); 38345 pathObj.startAt = timePoint + (parsePositiveInt(pAttrs['data-delay'], this.delayUnit) || 0); 38346 pathObj.duration = parsePositiveInt(pAttrs['data-duration'], this.duration); 38347 timePoint = pAttrs['data-async'] !== undefined ? pathObj.startAt : pathObj.startAt + pathObj.duration; 38348 this.frameLength = Math.max(this.frameLength, (pathObj.startAt + pathObj.duration)); 38349 break; 38350 38351 case 'scenario': 38352 path = pathObj.el; 38353 pAttrs = this.parseAttr(path); 38354 pathObj.startAt = parsePositiveInt(pAttrs['data-start'], this.delayUnit) || 0; 38355 pathObj.duration = parsePositiveInt(pAttrs['data-duration'], this.duration); 38356 this.frameLength = Math.max(this.frameLength, (pathObj.startAt + pathObj.duration)); 38357 break; 38358 } 38359 lengthMeter += pathObj.length; 38360 this.frameLength = this.frameLength || this.duration; 38361 } 38362}; 38363 38364/** 38365 * Interval method to draw the SVG from current 38366 * position of the animation. It update the value of 38367 * `currentFrame` and re-trace the SVG. 38368 * 38369 * It use this.handle to store the requestAnimationFrame 38370 * and clear it one the animation is stopped. So this 38371 * attribute can be used to know if the animation is 38372 * playing. 38373 * 38374 * Once the animation at the end, this method will 38375 * trigger the Vivus callback. 38376 * 38377 */ 38378Vivus.prototype.drawer = function () { 38379 var self = this; 38380 this.currentFrame += this.speed; 38381 38382 if (this.currentFrame <= 0) { 38383 this.stop(); 38384 this.reset(); 38385 } else if (this.currentFrame >= this.frameLength) { 38386 this.stop(); 38387 this.currentFrame = this.frameLength; 38388 this.trace(); 38389 if (this.selfDestroy) { 38390 this.destroy(); 38391 } 38392 } else { 38393 this.trace(); 38394 this.handle = requestAnimFrame(function () { 38395 self.drawer(); 38396 }); 38397 return; 38398 } 38399 38400 this.callback(this); 38401 if (this.instanceCallback) { 38402 this.instanceCallback(this); 38403 this.instanceCallback = null; 38404 } 38405}; 38406 38407/** 38408 * Draw the SVG at the current instant from the 38409 * `currentFrame` value. Here is where most of the magic is. 38410 * The trick is to use the `strokeDashoffset` style property. 38411 * 38412 * For optimisation reasons, a new property called `progress` 38413 * is added in each item of `map`. This one contain the current 38414 * progress of the path element. Only if the new value is different 38415 * the new value will be applied to the DOM element. This 38416 * method save a lot of resources to re-render the SVG. And could 38417 * be improved if the animation couldn't be played forward. 38418 * 38419 */ 38420Vivus.prototype.trace = function () { 38421 var i, progress, path, currentFrame; 38422 currentFrame = this.animTimingFunction(this.currentFrame / this.frameLength) * this.frameLength; 38423 for (i = 0; i < this.map.length; i++) { 38424 path = this.map[i]; 38425 progress = (currentFrame - path.startAt) / path.duration; 38426 progress = this.pathTimingFunction(Math.max(0, Math.min(1, progress))); 38427 if (path.progress !== progress) { 38428 path.progress = progress; 38429 path.el.style.strokeDashoffset = Math.floor(path.length * (1 - progress)); 38430 this.renderPath(i); 38431 } 38432 } 38433}; 38434 38435/** 38436 * Method forcing the browser to re-render a path element 38437 * from it's index in the map. Depending on the `forceRender` 38438 * value. 38439 * The trick is to replace the path element by it's clone. 38440 * This practice is not recommended because it's asking more 38441 * ressources, too much DOM manupulation.. 38442 * but it's the only way to let the magic happen on IE. 38443 * By default, this fallback is only applied on IE. 38444 * 38445 * @param {Number} index Path index 38446 */ 38447Vivus.prototype.renderPath = function (index) { 38448 if (this.forceRender && this.map && this.map[index]) { 38449 var pathObj = this.map[index], 38450 newPath = pathObj.el.cloneNode(true); 38451 pathObj.el.parentNode.replaceChild(newPath, pathObj.el); 38452 pathObj.el = newPath; 38453 } 38454}; 38455 38456/** 38457 * When the SVG object is loaded and ready, 38458 * this method will continue the initialisation. 38459 * 38460 * This this mainly due to the case of passing an 38461 * object tag in the constructor. It will wait 38462 * the end of the loading to initialise. 38463 * 38464 */ 38465Vivus.prototype.init = function () { 38466 // Set object variables 38467 this.frameLength = 0; 38468 this.currentFrame = 0; 38469 this.map = []; 38470 38471 // Start 38472 new Pathformer(this.el); 38473 this.mapping(); 38474 this.starter(); 38475 38476 if (this.onReady) { 38477 this.onReady(this); 38478 } 38479}; 38480 38481/** 38482 * Trigger to start of the animation. 38483 * Depending on the `start` value, a different script 38484 * will be applied. 38485 * 38486 * If the `start` value is not valid, an error will be thrown. 38487 * Even if technically, this is impossible. 38488 * 38489 */ 38490Vivus.prototype.starter = function () { 38491 switch (this.start) { 38492 case 'manual': 38493 return; 38494 38495 case 'autostart': 38496 this.play(); 38497 break; 38498 38499 case 'inViewport': 38500 var self = this, 38501 listener = function () { 38502 if (self.isInViewport(self.parentEl, 1)) { 38503 self.play(); 38504 window.removeEventListener('scroll', listener); 38505 //Uncode addition 38506 window.removeEventListener('fp-slide-changed', listener); 38507 window.removeEventListener('fp-slide-scroll', listener); 38508 //#END 38509 } 38510 }; 38511 window.addEventListener('scroll', listener); 38512 //Uncode addition 38513 window.addEventListener('fp-slide-changed', listener); 38514 window.addEventListener('fp-slide-scroll', listener); 38515 //#END 38516 listener(); 38517 break; 38518 } 38519}; 38520 38521 38522/** 38523 * Controls 38524 ************************************** 38525 */ 38526 38527/** 38528 * Get the current status of the animation between 38529 * three different states: 'start', 'progress', 'end'. 38530 * @return {string} Instance status 38531 */ 38532Vivus.prototype.getStatus = function () { 38533 return this.currentFrame === 0 ? 'start' : this.currentFrame === this.frameLength ? 'end' : 'progress'; 38534}; 38535 38536/** 38537 * Reset the instance to the initial state : undraw 38538 * Be careful, it just reset the animation, if you're 38539 * playing the animation, this won't stop it. But just 38540 * make it start from start. 38541 * 38542 */ 38543Vivus.prototype.reset = function () { 38544 return this.setFrameProgress(0); 38545}; 38546 38547/** 38548 * Set the instance to the final state : drawn 38549 * Be careful, it just set the animation, if you're 38550 * playing the animation on rewind, this won't stop it. 38551 * But just make it start from the end. 38552 * 38553 */ 38554Vivus.prototype.finish = function () { 38555 return this.setFrameProgress(1); 38556}; 38557 38558/** 38559 * Set the level of progress of the drawing. 38560 * 38561 * @param {number} progress Level of progress to set 38562 */ 38563Vivus.prototype.setFrameProgress = function (progress) { 38564 progress = Math.min(1, Math.max(0, progress)); 38565 this.currentFrame = Math.round(this.frameLength * progress); 38566 this.trace(); 38567 return this; 38568}; 38569 38570/** 38571 * Play the animation at the desired speed. 38572 * Speed must be a valid number (no zero). 38573 * By default, the speed value is 1. 38574 * But a negative value is accepted to go forward. 38575 *
38576 * And works with float too. 38577 * But don't forget we are in JavaScript, se be nice 38578 * with him and give him a 1/2^x value. 38579 * 38580 * @param {number} speed Animation speed [optional] 38581 */ 38582Vivus.prototype.play = function (speed, callback) { 38583 this.instanceCallback = null; 38584 38585 if (speed && typeof speed === 'function') { 38586 this.instanceCallback = speed; // first parameter is actually the callback function 38587 speed = null; 38588 } 38589 else if (speed && typeof speed !== 'number') { 38590 throw new Error('Vivus [play]: invalid speed'); 38591 } 38592 // if the first parameter wasn't the callback, check if the seconds was 38593 if (callback && typeof(callback) === 'function' && !this.instanceCallback) { 38594 this.instanceCallback = callback; 38595 } 38596 38597 38598 this.speed = speed || 1; 38599 //Uncode addition 38600 if (!this.handle) { 38601 var $this = this, 38602 delay = (this.delayStart != null) ? this.delayStart : 0; 38603 setTimeout(function() { 38604 $this.drawer(); 38605 }, delay); 38606 } 38607 //#END 38608 return this; 38609}; 38610 38611/** 38612 * Stop the current animation, if on progress. 38613 * Should not trigger any error. 38614 * 38615 */ 38616Vivus.prototype.stop = function () { 38617 if (this.handle) { 38618 cancelAnimFrame(this.handle); 38619 this.handle = null; 38620 } 38621 return this; 38622}; 38623 38624/** 38625 * Destroy the instance. 38626 * Remove all bad styling attributes on all 38627 * path tags 38628 * 38629 */ 38630Vivus.prototype.destroy = function () { 38631 this.stop(); 38632 var i, path; 38633 for (i = 0; i < this.map.length; i++) { 38634 path = this.map[i]; 38635 path.el.style.strokeDashoffset = null; 38636 path.el.style.strokeDasharray = null; 38637 this.renderPath(i); 38638 } 38639}; 38640 38641 38642/** 38643 * Utils methods 38644 * include methods from Codrops 38645 ************************************** 38646 */ 38647 38648/** 38649 * Method to best guess if a path should added into 38650 * the animation or not. 38651 * 38652 * 1. Use the `data-vivus-ignore` attribute if set 38653 * 2. Check if the instance must ignore invisible paths 38654 * 3. Check if the path is visible 38655 * 38656 * For now the visibility checking is unstable. 38657 * It will be used for a beta phase. 38658 * 38659 * Other improvments are planned. Like detecting 38660 * is the path got a stroke or a valid opacity. 38661 */ 38662Vivus.prototype.isInvisible = function (el) { 38663 var rect, 38664 ignoreAttr = el.getAttribute('data-ignore'); 38665 38666 if (ignoreAttr !== null) { 38667 return ignoreAttr !== 'false'; 38668 } 38669 38670 if (this.ignoreInvisible) { 38671 rect = el.getBoundingClientRect(); 38672 return !rect.width && !rect.height; 38673 } 38674 else { 38675 return false; 38676 } 38677}; 38678 38679/** 38680 * Parse attributes of a DOM element to 38681 * get an object of {attributeName => attributeValue} 38682 * 38683 * @param {object} element DOM element to parse 38684 * @return {object} Object of attributes 38685 */ 38686Vivus.prototype.parseAttr = function (element) { 38687 var attr, output = {}; 38688 if (element && element.attributes) { 38689 for (var i = 0; i < element.attributes.length; i++) { 38690 attr = element.attributes[i]; 38691 output[attr.name] = attr.value; 38692 } 38693 } 38694 return output; 38695}; 38696 38697/** 38698 * Reply if an element is in the page viewport 38699 * 38700 * @param {object} el Element to observe 38701 * @param {number} h Percentage of height 38702 * @return {boolean} 38703 */ 38704Vivus.prototype.isInViewport = function (el, h) { 38705 var scrolled = this.scrollY(), 38706 viewed = scrolled + this.getViewportH(), 38707 elBCR = el.getBoundingClientRect(), 38708 elHeight = elBCR.height, 38709 elTop = scrolled + elBCR.top, 38710 elBottom = elTop + elHeight; 38711 38712 // if 0, the element is considered in the viewport as soon as it enters. 38713 // if 1, the element is considered in the viewport only when it's fully inside 38714 // value in percentage (1 >= h >= 0) 38715 h = h || 0; 38716 38717 return (elTop + elHeight * h) <= viewed && (elBottom) >= scrolled; 38718}; 38719 38720 38721/** 38722 * Get the viewport height in pixels 38723 * 38724 * @return {integer} Viewport height 38725 */ 38726Vivus.prototype.getViewportH = function () { 38727 var client = this.docElem.clientHeight, 38728 inner = window.innerHeight; 38729 38730 if (client < inner) { 38731 return inner; 38732 } 38733 else { 38734 return client; 38735 } 38736}; 38737 38738/** 38739 * Get the page Y offset 38740 * 38741 * @return {integer} Page Y offset 38742 */ 38743Vivus.prototype.scrollY = function () { 38744 return window.pageYOffset || this.docElem.scrollTop; 38745}; 38746 38747setupEnv = function () { 38748 38749 if (Vivus.prototype.docElem) { 38750 return; 38751 } 38752 38753 /** 38754 * Alias for document element 38755 * 38756 * @type {DOMelement} 38757 */ 38758 Vivus.prototype.docElem = window.document.documentElement; 38759 38760 /** 38761 * Alias for `requestAnimationFrame` or 38762 * `setTimeout` function for deprecated browsers. 38763 * 38764 */ 38765 requestAnimFrame = (function () { 38766 return ( 38767 window.requestAnimationFrame || 38768 window.webkitRequestAnimationFrame || 38769 window.mozRequestAnimationFrame || 38770 window.oRequestAnimationFrame || 38771 window.msRequestAnimationFrame || 38772 function(/* function */ callback){ 38773 return window.setTimeout(callback, 1000 / 60); 38774 } 38775 ); 38776 })(); 38777 38778 /** 38779 * Alias for `cancelAnimationFrame` or 38780 * `cancelTimeout` function for deprecated browsers. 38781 * 38782 */ 38783 cancelAnimFrame = (function () { 38784 return ( 38785 window.cancelAnimationFrame || 38786 window.webkitCancelAnimationFrame || 38787 window.mozCancelAnimationFrame || 38788 window.oCancelAnimationFrame || 38789 window.msCancelAnimationFrame || 38790 function(id){ 38791 return window.clearTimeout(id); 38792 } 38793 ); 38794 })(); 38795}; 38796 38797/** 38798 * Parse string to integer. 38799 * If the number is not positive or null 38800 * the method will return the default value 38801 * or 0 if undefined 38802 * 38803 * @param {string} value String to parse 38804 * @param {*}
38804 defaultValue Value to return if the result parsed is invalid 38805 * @return {number} 38806 * 38807 */ 38808parsePositiveInt = function (value, defaultValue) { 38809 var output = parseInt(value, 10); 38810 return (output >= 0) ? output : defaultValue; 38811}; 38812 38813 38814 if (typeof define === 'function' && define.amd) { 38815 // AMD. Register as an anonymous module. 38816 define([], function() { 38817 return Vivus; 38818 }); 38819 } else if (typeof exports === 'object') { 38820 // Node. Does not work with strict CommonJS, but 38821 // only CommonJS-like environments that support module.exports, 38822 // like Node. 38823 module.exports = Vivus; 38824 } else { 38825 // Browser globals 38826 window.Vivus = Vivus; 38827 } 38828 38829}());
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.